3
0

Deprecate installer & use KBootstrap for updating

This commit is contained in:
Prototik
2015-06-16 23:30:52 +07:00
parent 44020ecc25
commit 01acbd4779
10 changed files with 298 additions and 208 deletions

View File

@ -34,13 +34,17 @@ public class KCauldron {
sCurrentVersion = version;
sBranch = manifest.getProperty("KCauldron-Branch");
sChannel = manifest.getProperty("KCauldron-Channel");
break;
}
manifest.clear();
}
} catch (Exception e) {
e.printStackTrace();
}
String home = System.getenv("KCAULDRON_HOME");
if (home != null) {
sServerLocation = new File(home);
}
}
private static String sCurrentVersion;

View File

@ -62,8 +62,8 @@ public class KCauldronCommand extends Command {
if (!testPermission(sender, CHECK))
return true;
sender.sendMessage(ChatColor.GREEN + "Initiated version check...");
new KVersionRetriever(new CommandSenderUpdateCallback(sender),
false);
KVersionRetriever.startServer(new CommandSenderUpdateCallback(
sender), false);
} else if ("update".equals(action)) {
KCauldronUpdater.initUpdate(sender, args.length > 1 ? args[1]
: null);

View File

@ -13,18 +13,14 @@ public class KCauldronConfig extends ConfigBase {
true, "Enable KCauldron command");
public BoolSetting updatecheckerEnable = new BoolSetting(this,
"updatechecker.enable", true, "Enable KCauldron update checker");
public BoolSetting updatecheckerDeleteOld = new BoolSetting(this,
"updatechecker.deleteOld", true, "Delete old version after update");
public StringSetting updatecheckerSymlinks = new StringSetting(this,
"updatechecker.symlinks", "", "(Re)create symlinks after update");
"updatechecker.symlinks", "KCauldron.jar", "(Re)create symlinks after update");
public BoolSetting updatecheckerAutoinstall = new BoolSetting(this,
"updatechecker.autoinstall", false, "Install updates without confirming");
public BoolSetting updatecheckerAutorestart = new BoolSetting(this,
"updatechecker.autorestart", false, "Restart server after updating without confirming (set restart script in spigot.yml)");
public BoolSetting updatecheckerQuite = new BoolSetting(this,
"updatechecker.quite", false, "Print less info during update");
public StringSetting updatecheckerInstallAs = new StringSetting(this,
"updatechecker.installAs", "", "Install new version with specified name");
public BoolSetting loggingMaterialInjection = new BoolSetting(this,
"logging.materialInjection", false, "Log material injection event");
@ -33,12 +29,10 @@ public class KCauldronConfig extends ConfigBase {
super("kcauldron.yml", "kc");
register(commandEnable);
register(updatecheckerEnable);
register(updatecheckerDeleteOld);
register(updatecheckerSymlinks);
register(updatecheckerAutoinstall);
register(updatecheckerAutorestart);
register(updatecheckerQuite);
register(updatecheckerInstallAs);
register(loggingMaterialInjection);
load();
}

View File

@ -3,6 +3,7 @@ package kcauldron.updater;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import kcauldron.KCauldron;
import kcauldron.updater.KVersionRetriever.IVersionCheckCallback;
import org.bukkit.ChatColor;
@ -14,38 +15,39 @@ public class CommandSenderUpdateCallback implements IVersionCheckCallback {
public CommandSenderUpdateCallback(CommandSender sender) {
mSender = new WeakReference<CommandSender>(sender);
}
protected CommandSender getSender() {
return mSender.get();
}
@Override
public void upToDate(String version) {
public void upToDate() {
CommandSender sender = mSender.get();
if (sender != null) {
sender.sendMessage(ChatColor.GREEN
+ "Running version of KCauldron is up-to-date: " + version);
+ "Running version of KCauldron is up-to-date: "
+ KCauldron.getCurrentVersion());
}
DefaultUpdateCallback.INSTANCE.upToDate(version);
DefaultUpdateCallback.INSTANCE.upToDate();
}
@Override
public void newVersion(String currentVersion, String newVersion) {
public void newVersion(String newVersion) {
CommandSender sender = mSender.get();
if (sender != null) {
newVersion(sender, currentVersion, newVersion);
newVersion(sender, KCauldron.getCurrentVersion(), newVersion);
}
DefaultUpdateCallback.INSTANCE.newVersion(currentVersion, newVersion);
DefaultUpdateCallback.INSTANCE.newVersion(newVersion);
}
public static void newVersion(CommandSender sender, String currentVersion, String newVersion) {
public static void newVersion(CommandSender sender, String currentVersion,
String newVersion) {
sender.sendMessage(new String[] {
ChatColor.YELLOW + "Found new version of KCauldron: "
+ newVersion,
ChatColor.YELLOW + "Current is " + currentVersion,
ChatColor.YELLOW + "Type '" + ChatColor.BLUE
+ "/kc update" + ChatColor.YELLOW
+ "' to update" });
ChatColor.YELLOW + "Type '" + ChatColor.BLUE + "/kc update"
+ ChatColor.YELLOW + "' to update" });
}
@Override

View File

@ -41,15 +41,15 @@ public class DefaultUpdateCallback implements IVersionCheckCallback {
}
@Override
public void upToDate(String version) {
public void upToDate() {
mHasUpdate = false;
mCurrentVersion = version;
mCurrentVersion = KCauldron.getCurrentVersion();
mNewVersion = null;
}
@Override
public void newVersion(String currentVersion, String newVersion) {
mCurrentVersion = currentVersion;
public void newVersion(String newVersion) {
mCurrentVersion = KCauldron.getCurrentVersion();
mNewVersion = newVersion;
if (!mHasUpdate) {
Bukkit.getConsoleSender().sendMessage(

View File

@ -1,10 +1,14 @@
package kcauldron.updater;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import kcauldron.KCauldron;
import kcauldron.updater.KVersionRetriever.IVersionCheckCallback;
import net.minecraft.server.MinecraftServer;
import org.apache.http.HttpResponse;
@ -15,9 +19,9 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import com.google.common.base.Splitter;
import com.google.common.base.Joiner;
public class KCauldronUpdater implements Runnable {
public class KCauldronUpdater implements Runnable, IVersionCheckCallback {
private static final class LatestVersionCallback extends
CommandSenderUpdateCallback {
public LatestVersionCallback(CommandSender sender) {
@ -25,17 +29,17 @@ public class KCauldronUpdater implements Runnable {
}
@Override
public void newVersion(String currentVersion, String newVersion) {
public void newVersion(String newVersion) {
startUpdate(getSender(), newVersion);
}
@Override
public void upToDate(String version) {
public void upToDate() {
KCauldron.sUpdateInProgress = false;
CommandSender sender = getSender();
if (sender != null) {
sender.sendMessage(ChatColor.DARK_PURPLE + "Current version ("
+ version + ") is up to date");
+ KCauldron.getCurrentVersion() + ") is up to date");
}
}
@ -56,7 +60,8 @@ public class KCauldronUpdater implements Runnable {
if (version == null) {
sender.sendMessage(ChatColor.DARK_PURPLE
+ "Fetching latest version...");
new KVersionRetriever(new LatestVersionCallback(sender), false);
KVersionRetriever.startServer(new LatestVersionCallback(sender),
false);
} else {
startUpdate(sender, version);
}
@ -85,78 +90,66 @@ public class KCauldronUpdater implements Runnable {
@Override
public void run() {
if (!MinecraftServer.kcauldronConfig.updatecheckerQuite.getValue()) {
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Retrieving latest KBootstrap version...");
}
new KVersionRetriever(this, false, false, "pw.prok", "KBootstrap");
}
@Override
public void upToDate() {
}
@Override
public void newVersion(String kbootstrapVersion) {
boolean quite = MinecraftServer.kcauldronConfig.updatecheckerQuite
.getValue();
try {
MinecraftServer server = MinecraftServer.getServer();
final String filename = KCauldron.getChannel() + "-" + mVersion
+ "-server.jar";
File path = KCauldron.getServerLocation();
File newPath = new File(path.getParentFile(),
getInstallAs(filename));
if (mSender != null) {
if (!quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Current version is located in " + ChatColor.GOLD
+ path.getAbsolutePath());
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Installing new version in " + ChatColor.GOLD
+ newPath.getAbsolutePath());
}
if (newPath.exists()) {
Bukkit.getConsoleSender().sendMessage(
"ERROR: Install location already exists: "
+ newPath.getAbsolutePath());
mSender.sendMessage(ChatColor.RED
+ "ERROR: Install location already exists");
return;
}
if (!quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Downloading new version...");
}
}
HttpUriRequest request = RequestBuilder
.get()
.setUri("https://prok.pw/repo/pw/prok/"
+ KCauldron.getChannel() + "/" + mVersion + "/"
+ filename)
.addParameter("hostname", server.getHostname())
.addParameter("port", "" + server.getPort()).build();
HttpResponse response = HttpClientBuilder.create()
.setUserAgent("KCauldron Updater").build().execute(request);
if (response.getStatusLine().getStatusCode() != 200) {
throw new IllegalStateException(
"Could not download new version");
}
InputStream is = response.getEntity().getContent();
Files.copy(is, newPath.toPath());
if (mSender != null && !quite) {
if (!quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Download completed");
+ "Downloading KBootstrap " + kbootstrapVersion + "...");
}
makeSymlinks(newPath);
if (MinecraftServer.kcauldronConfig.updatecheckerDeleteOld
.getValue()) {
if (mSender != null && !quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Mark old version for deletion");
}
path.deleteOnExit();
if (KCauldron.sNewServerLocation != null) {
KCauldron.sNewServerLocation.deleteOnExit();
}
File kbootstrap = File.createTempFile("kbootstrap",
String.valueOf(System.currentTimeMillis()));
download("https://prok.pw/repo/pw/prok/KBootstrap/"
+ kbootstrapVersion + "/KBootstrap-" + kbootstrapVersion
+ "-app.jar", kbootstrap);
if (!quite) {
mSender.sendMessage(ChatColor.DARK_PURPLE
+ "Installing KCauldron " + mVersion
+ " via KBootstrap " + kbootstrapVersion + "...");
}
if (mSender != null) {
mSender.sendMessage(ChatColor.DARK_PURPLE + "Update completed");
}
KCauldron.sNewServerLocation = newPath;
KCauldron.sNewServerVersion = mVersion;
if (MinecraftServer.kcauldronConfig.updatecheckerAutorestart.getValue()) {
if (mSender != null) {
mSender.sendMessage(ChatColor.DARK_RED + "Initiate server restart");
}
KCauldron.restart();
String javahome = System.getProperty("java.home");
String javapath = javahome + "/bin/java";
List<String> command = new ArrayList<String>();
command.add(javapath);
command.add("-jar");
command.add(kbootstrap.getCanonicalPath());
command.add("--serverDir");
command.add(KCauldron.getServerLocation().getCanonicalPath());
command.add("--installKCauldron");
command.add(mVersion);
command.add("--serverSymlinks");
command.add(MinecraftServer.kcauldronConfig.updatecheckerSymlinks
.getValue());
Bukkit.getConsoleSender().sendMessage(
"Starting command: " + Joiner.on(' ').join(command));
ProcessBuilder builder = new ProcessBuilder(command);
builder.environment().put("JAVA_HOME", javahome);
switch (builder.start().waitFor()) {
case 0:
mSender.sendMessage(ChatColor.GREEN + "KCauldron " + mVersion
+ " installed");
break;
default:
mSender.sendMessage(ChatColor.RED
+ "Failed to install KCauldron " + mVersion);
}
} catch (Exception e) {
if (!quite) {
@ -171,35 +164,29 @@ public class KCauldronUpdater implements Runnable {
}
}
private String getInstallAs(String filename) {
String path = MinecraftServer.kcauldronConfig.updatecheckerInstallAs
.getValue().trim();
if (path.length() > 0) {
return path.replace("%version%", mVersion);
}
return filename;
@Override
public void error(Throwable t) {
KCauldron.sUpdateInProgress = false;
t.printStackTrace();
}
private void makeSymlinks(File newPath) {
try {
for (String symlink : Splitter.on(File.pathSeparatorChar).split(
MinecraftServer.kcauldronConfig.updatecheckerSymlinks
.getValue())) {
symlink = symlink.trim();
if (symlink.length() == 0)
continue;
File symlinkPath = new File(symlink);
if (mSender != null
&& !MinecraftServer.kcauldronConfig.updatecheckerQuite
.getValue()) {
mSender.sendMessage(ChatColor.RED + "Create symlink "
+ ChatColor.GOLD + symlinkPath.getAbsolutePath());
}
Files.deleteIfExists(symlinkPath.toPath());
Files.createSymbolicLink(symlinkPath.toPath(), newPath.toPath());
}
} catch (Exception e) {
private static void download(String url, File destination)
throws IOException {
HttpUriRequest request = RequestBuilder
.get()
.setUri(url)
.addParameter("hostname",
MinecraftServer.getServer().getHostname())
.addParameter("port",
String.valueOf(MinecraftServer.getServer().getPort()))
.build();
HttpResponse response = HttpClientBuilder.create()
.setUserAgent("KCauldron Updater").build().execute(request);
if (response.getStatusLine().getStatusCode() != 200) {
throw new IllegalStateException("Could not download " + url);
}
InputStream is = response.getEntity().getContent();
Files.copy(is, destination.toPath());
is.close();
}
}

View File

@ -18,33 +18,42 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler {
private static final boolean DEBUG;
private static final KLog sLogger;
private static final JSONParser sParser;
private static final String sCurrentVersion;
private static MinecraftServer sServer;
static {
DEBUG = false;
sLogger = KLog.get(KVersionRetriever.class.getSimpleName());
sCurrentVersion = KCauldron.getCurrentVersion();
sParser = new JSONParser();
}
public static void init(MinecraftServer server) {
sServer = server;
if (MinecraftServer.kcauldronConfig.updatecheckerEnable.getValue()) {
new KVersionRetriever(DefaultUpdateCallback.INSTANCE, true);
startServer(DefaultUpdateCallback.INSTANCE, true);
}
}
public static void startServer(IVersionCheckCallback callback, boolean loop) {
new KVersionRetriever(callback, loop, true, "pw.prok",KCauldron.getChannel());
}
private final IVersionCheckCallback mCallback;
private final boolean mLoop;
private final Thread mThread;
private final String mGroup;
private final String mName;
private final boolean mUpToDateSupport;
public KVersionRetriever(IVersionCheckCallback callback, boolean loop) {
public KVersionRetriever(IVersionCheckCallback callback, boolean loop,
boolean upToDateSupport, String group, String name) {
if (DEBUG)
sLogger.info("Created new version retrivier");
mCallback = callback;
mLoop = loop;
mUpToDateSupport = upToDateSupport;
mGroup = group;
mName = name;
mThread = new Thread(this);
mThread.setName("KCauldron version retrievier");
mThread.setPriority(Thread.MIN_PRIORITY);
@ -68,13 +77,9 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler {
}
private void check() {
if (DEBUG)
sLogger.info("Requesting for new version...");
try {
HttpUriRequest request = RequestBuilder
.get()
.setUri("https://prok.pw/version/pw.prok/"
+ KCauldron.getChannel())
HttpUriRequest request = RequestBuilder.get()
.setUri("https://prok.pw/version/" + mGroup + "/" + mName)
.addParameter("hostname", sServer.getHostname())
.addParameter("port", "" + sServer.getPort()).build();
HttpResponse response = HttpClientBuilder.create()
@ -83,14 +88,11 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler {
JSONObject json = (JSONObject) sParser.parse(new InputStreamReader(
response.getEntity().getContent()));
String version = (String) json.get("version");
if (DEBUG) {
sLogger.info("Got the latest version: %s", version);
sLogger.info("Current version is %s", sCurrentVersion);
}
if (!sCurrentVersion.equals(version)) {
mCallback.newVersion(sCurrentVersion, version);
if (!mUpToDateSupport
|| !KCauldron.getCurrentVersion().equals(version)) {
mCallback.newVersion(version);
} else {
mCallback.upToDate(version);
mCallback.upToDate();
}
} catch (Exception e) {
uncaughtException(null, e);
@ -106,9 +108,9 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler {
}
public interface IVersionCheckCallback {
void upToDate(String version);
void upToDate();
void newVersion(String currentVersion, String newVersion);
void newVersion(String newVersion);
void error(Throwable t);
}