![JAR search and dependency download from the Maven repository](/logo.png)
net.oneandone.stool.setup.UpgradeBuilder Maven / Gradle / Ivy
/**
* Copyright 1&1 Internet AG, https://github.com/1and1/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.oneandone.stool.setup;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import net.oneandone.inline.Console;
import net.oneandone.stool.cli.Import;
import net.oneandone.stool.cli.Main;
import net.oneandone.stool.configuration.Bedroom;
import net.oneandone.stool.configuration.StageConfiguration;
import net.oneandone.stool.configuration.StoolConfiguration;
import net.oneandone.stool.util.Logging;
import net.oneandone.stool.util.Session;
import net.oneandone.sushi.fs.file.FileNode;
import net.oneandone.sushi.util.Diff;
import net.oneandone.sushi.util.Separator;
import net.oneandone.sushi.util.Strings;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UpgradeBuilder {
private final Console console;
private final Home home;
private final FileNode from;
// assigned during upgrade:
private StoolConfiguration stoolRaw;
private Session session = null;
private String currentStage = null;
/** maps names to ids */
private Map stages = new HashMap<>();
public UpgradeBuilder(Console console, Home home, FileNode from) {
this.console = console;
this.home = home;
this.from = from;
}
public String version() throws IOException {
return from.join("version").readString().trim();
}
public void run(boolean withConfig) throws IOException {
String oldVersion;
String newVersion;
Upgrade stage33_34;
newVersion = Main.versionString(from.getWorld());
oldVersion = version();
if (!oldVersion.startsWith("3.3.")) {
throw new IOException("don't know how to upgrade " + oldVersion + " -> " + newVersion);
}
console.info.println("upgrade " + oldVersion + " -> " + newVersion);
stage33_34 = stage33_34();
all(withConfig, stool33_34(stage33_34), stage33_34);
}
private void all(boolean withConfig, Upgrade stoolMapper, Upgrade stageMapper) throws IOException {
String id;
FileNode stage;
Logging logging;
Import i;
String originalOwner;
if (withConfig) {
stool(from, stoolMapper);
} else {
stoolRaw = StoolConfiguration.load(home.gson(), home.dir);
}
logging = Logging.forHome(home.dir);
session = Session.load(false, home.dir, logging, "upgrade", console, home.dir.getWorld(), null, null);
if (!session.listWithoutSystem().isEmpty()) {
console.info.println("warning: ports of existing and not imported stages get lost.");
}
for (FileNode oldBackstage : from.join("backstages").list()) {
id = getId(oldBackstage.join("config.json"));
currentStage = oldBackstage.getName();
stages.put(currentStage, id); // always add, because ports file need everything
if (home.dir.join("backstages", id).isDirectory()) {
console.info.println("stage already imported, ignored: " + currentStage + " (" + id + ")");
continue;
}
if ("dashboard".equals(currentStage)) {
console.info.println("not imported: " + currentStage);
continue;
}
console.info.println("import " + oldBackstage);
stage = oldBackstage.join("anchor").resolveLink();
originalOwner = chown(stage, session.user);
i = new Import(session);
i.setUpgradeId(id);
i.dirs(stage.getAbsolute());
i.doRun();
transform(oldBackstage.join("config.json"), stage.join(".backstage/config.json"), stageMapper);
chown(stage, originalOwner);
}
ports();
bedroom();
}
private String chown(FileNode directory, String newOwner) throws IOException {
String was;
was = directory.getOwner().toString();
if (!was.equals(newOwner)) {
session.chown(newOwner, directory);
}
return was;
}
private void ports() throws IOException {
List entries;
List out;
String name;
String id;
out = new ArrayList<>();
for (String line : from.join("run/ports").readLines()) {
entries = Separator.SPACE.split(line);
name = entries.get(2);
id = stages.get(name);
if (id == null) {
console.info.println("note: garbage-collected from ports: " + name);
} else {
entries.add(3, id);
out.add(Separator.SPACE.join(entries));
}
}
home.dir.join("run/ports").writeLines(out);
}
private void bedroom() throws IOException {
Gson gson;
Bedroom old;
Bedroom next;
String id;
gson = home.gson();
old = Bedroom.loadOrCreate(gson, from);
next = Bedroom.loadOrCreate(gson, home.dir);
for (String name : old) {
id = stages.get(name);
if (id == null) {
throw new IllegalStateException(name);
}
next.add(gson, id);
}
}
private static String getId(FileNode config) throws IOException {
JsonObject json;
try (Reader src = config.newReader()) {
json = new JsonParser().parse(src).getAsJsonObject();
return json.get("id").getAsString();
}
}
private void stool(FileNode from, Upgrade stoolMapper) throws IOException {
String in;
String without;
String preliminary; // without the defaults
in = from.join("config.json").readString();
without = Transform.transform(in, new Upgrade() {
void defaultsRemove() {}
});
preliminary = Transform.transform(without, stoolMapper);
stoolRaw = home.gson().fromJson(preliminary, StoolConfiguration.class);
transform(in, home.dir.join("config.json"), stoolMapper);
}
private void transform(FileNode src, FileNode dest, Upgrade mapper) throws IOException {
transform(src.readString(), dest, mapper);
}
private void transform(String in, FileNode dest, Upgrade mapper) throws IOException {
String out;
console.verbose.println("upgrade " + dest.getAbsolute());
out = Transform.transform(in, mapper);
if (!in.equals(out)) {
console.info.println("M " + dest.getAbsolute());
console.info.println(Strings.indent(Diff.diff(in, out), " "));
dest.writeString(out);
}
}
//--
public Upgrade stool33_34(Upgrade stage33_34) {
return new Upgrade() {
void promptRemove() {
}
JsonElement defaultsTransform(JsonElement element) {
JsonObject result;
JsonObject obj;
String url;
JsonObject defaults;
result = new JsonObject();
obj = element.getAsJsonObject();
for (Map.Entry entry : obj.entrySet()) {
url = entry.getKey();
defaults = entry.getValue().getAsJsonObject();
result.add(url.isEmpty() ? "" : "svn:" + url, migrate(defaults));
}
return result;
}
String contactAdminRename() {
return "admin";
}
//--
private JsonObject migrate(JsonObject e) {
String str;
str = Transform.transform(Transform.toString(e), stage33_34);
return new JsonParser().parse(str).getAsJsonObject();
}
};
}
public Upgrade stage33_34() {
return new Upgrade() {
JsonElement extensionsTransform(JsonElement e) {
JsonObject extensions;
JsonObject logstash;
if (session == null) {
// in defaults -- handled in globals below
throw new IllegalStateException();
}
// in stage
extensions = e.getAsJsonObject();
extensions.remove("-pustefix.editor");
extensions.remove("+pustefix.editor");
logstash = new JsonObject();
logstash.add("output", new JsonPrimitive(""));
logstash.add("link", new JsonPrimitive(""));
extensions.add("-logstash", logstash);
return e;
}
void idRemove() {
}
void sslUrlRemove() {
}
void tomcatPermRemove() {
}
String suffixesRename() {
return "url";
}
JsonElement suffixesTransform(JsonElement e) {
String hostpath;
JsonArray array;
hostpath = "%h:%p";
if (session == null) {
// upgrade defaults - contains a string, not an array
array = new JsonArray();
for (String str : Separator.COMMA.split(e.getAsString())) {
array.add(str);
}
} else {
array = e.getAsJsonArray();
}
if (stoolRaw != null && stoolRaw.vhosts) {
hostpath = "%a.%s." + hostpath;
}
hostpath = hostpath + allSuffixes(array);
return new JsonPrimitive("(http|https)://" + hostpath );
}
JsonElement untilTransform(JsonElement e) {
String str;
str = e.getAsString();
if ("reserved".equals(str)) {
return new JsonPrimitive("never");
} else {
return e;
}
}
String untilRename() {
return "expire";
}
void global(JsonObject src, JsonObject dest) {
JsonArray array;
if (session == null) {
// this call is to upgrade defaults
dest.remove("pustefix.editor.version");
dest.remove("pustefix.editor.userdata");
} else {
array = new JsonArray();
array.add(new JsonPrimitive(StageConfiguration.NOTIFY_OWNER));
array.add(new JsonPrimitive(StageConfiguration.NOTIFY_CREATOR));
dest.add("notify", array);
dest.add("quota", new JsonPrimitive(10000));
dest.add("name", new JsonPrimitive(currentStage));
}
}
};
}
public static String allSuffixes(JsonArray array) {
int count;
String str;
StringBuilder builder;
builder = new StringBuilder();
count = 0;
for (JsonElement e : array) {
str = e.getAsString();
if (str.contains("[]")) {
throw new UnsupportedOperationException("don't know how to upgrade suffixes '" + str + "'");
}
if (count > 0) {
builder.append('|');
}
builder.append(str);
count++;
}
return count < 2 ? builder.toString() : "(" + builder.toString() + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy