forked from I2P_Developers/i2p.i2p
Update: Add support for su3-signed development builds (ticket #1381)
Full version is used as the su3 version. Uses same su3 certs as release updates. Users may add additional certs to ~/.i2p/certificates/router/ as necessary. Copy echelon's reseed key for use as a router signer. Unsigned update remains a separate option for now. Various update subsystem cleanups.
This commit is contained in:
@ -82,6 +82,7 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
private static final long STATUS_CLEAN_TIME = 20*60*1000;
|
private static final long STATUS_CLEAN_TIME = 20*60*1000;
|
||||||
private static final long TASK_CLEANER_TIME = 15*60*1000;
|
private static final long TASK_CLEANER_TIME = 15*60*1000;
|
||||||
private static final String PROP_UNSIGNED_AVAILABLE = "router.updateUnsignedAvailable";
|
private static final String PROP_UNSIGNED_AVAILABLE = "router.updateUnsignedAvailable";
|
||||||
|
private static final String PROP_DEV_SU3_AVAILABLE = "router.updateDevSU3Available";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param args ignored
|
* @param args ignored
|
||||||
@ -174,6 +175,7 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
// TODO see NewsFetcher
|
// TODO see NewsFetcher
|
||||||
//register(u, ROUTER_SIGNED, HTTPS_CLEARNET, -5);
|
//register(u, ROUTER_SIGNED, HTTPS_CLEARNET, -5);
|
||||||
//register(u, ROUTER_SIGNED, HTTP_CLEARNET, -10);
|
//register(u, ROUTER_SIGNED, HTTP_CLEARNET, -10);
|
||||||
|
|
||||||
UnsignedUpdateHandler uuh = new UnsignedUpdateHandler(_context, this);
|
UnsignedUpdateHandler uuh = new UnsignedUpdateHandler(_context, this);
|
||||||
register((Checker)uuh, ROUTER_UNSIGNED, HTTP, 0);
|
register((Checker)uuh, ROUTER_UNSIGNED, HTTP, 0);
|
||||||
register((Updater)uuh, ROUTER_UNSIGNED, HTTP, 0);
|
register((Updater)uuh, ROUTER_UNSIGNED, HTTP, 0);
|
||||||
@ -185,6 +187,19 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
_available.put(new UpdateItem(ROUTER_UNSIGNED, ""), newVA);
|
_available.put(new UpdateItem(ROUTER_UNSIGNED, ""), newVA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DevSU3UpdateHandler dsuh = new DevSU3UpdateHandler(_context, this);
|
||||||
|
register((Checker)dsuh, ROUTER_DEV_SU3, HTTP, 0);
|
||||||
|
register((Updater)dsuh, ROUTER_DEV_SU3, HTTP, 0);
|
||||||
|
newVersion = _context.getProperty(PROP_DEV_SU3_AVAILABLE);
|
||||||
|
if (newVersion != null) {
|
||||||
|
List<URI> updateSources = dsuh.getUpdateSources();
|
||||||
|
if (dsuh != null) {
|
||||||
|
VersionAvailable newVA = new VersionAvailable(newVersion, "", HTTP, updateSources);
|
||||||
|
_available.put(new UpdateItem(ROUTER_DEV_SU3, ""), newVA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PluginUpdateHandler puh = new PluginUpdateHandler(_context, this);
|
PluginUpdateHandler puh = new PluginUpdateHandler(_context, this);
|
||||||
register((Checker)puh, PLUGIN, HTTP, 0);
|
register((Checker)puh, PLUGIN, HTTP, 0);
|
||||||
register((Updater)puh, PLUGIN, HTTP, 0);
|
register((Updater)puh, PLUGIN, HTTP, 0);
|
||||||
@ -652,7 +667,8 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
* Call once for each type/method pair.
|
* Call once for each type/method pair.
|
||||||
*/
|
*/
|
||||||
public void register(Updater updater, UpdateType type, UpdateMethod method, int priority) {
|
public void register(Updater updater, UpdateType type, UpdateMethod method, int priority) {
|
||||||
if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED || type == ROUTER_SIGNED_SU3) &&
|
if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED ||
|
||||||
|
type == ROUTER_SIGNED_SU3 || type == ROUTER_DEV_SU3) &&
|
||||||
NewsHelper.dontInstall(_context)) {
|
NewsHelper.dontInstall(_context)) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("Ignoring registration for " + type + ", router updates disabled");
|
_log.warn("Ignoring registration for " + type + ", router updates disabled");
|
||||||
@ -813,8 +829,11 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ROUTER_UNSIGNED:
|
case ROUTER_UNSIGNED:
|
||||||
|
case ROUTER_DEV_SU3:
|
||||||
// save across restarts
|
// save across restarts
|
||||||
_context.router().saveConfig(PROP_UNSIGNED_AVAILABLE, newVersion);
|
String prop = type == ROUTER_UNSIGNED ? PROP_UNSIGNED_AVAILABLE
|
||||||
|
: PROP_DEV_SU3_AVAILABLE;
|
||||||
|
_context.router().saveConfig(prop, newVersion);
|
||||||
// fall through
|
// fall through
|
||||||
|
|
||||||
case ROUTER_SIGNED:
|
case ROUTER_SIGNED:
|
||||||
@ -822,6 +841,7 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
if (shouldInstall() &&
|
if (shouldInstall() &&
|
||||||
!(isUpdateInProgress(ROUTER_SIGNED) ||
|
!(isUpdateInProgress(ROUTER_SIGNED) ||
|
||||||
isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
||||||
|
isUpdateInProgress(ROUTER_DEV_SU3) ||
|
||||||
isUpdateInProgress(ROUTER_UNSIGNED))) {
|
isUpdateInProgress(ROUTER_UNSIGNED))) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Updating " + ui + " after notify");
|
_log.info("Updating " + ui + " after notify");
|
||||||
@ -908,6 +928,7 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
case ROUTER_SIGNED:
|
case ROUTER_SIGNED:
|
||||||
case ROUTER_SIGNED_SU3:
|
case ROUTER_SIGNED_SU3:
|
||||||
case ROUTER_UNSIGNED:
|
case ROUTER_UNSIGNED:
|
||||||
|
case ROUTER_DEV_SU3:
|
||||||
// ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display
|
// ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1061,6 +1082,14 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ROUTER_DEV_SU3:
|
||||||
|
rv = handleSu3File(task.getURI(), actualVersion, file);
|
||||||
|
if (rv) {
|
||||||
|
_context.router().saveConfig(PROP_DEV_SU3_AVAILABLE, null);
|
||||||
|
notifyDownloaded(task.getType(), task.getID(), actualVersion);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case PLUGIN: // file handled in PluginUpdateRunner
|
case PLUGIN: // file handled in PluginUpdateRunner
|
||||||
default: // assume Updater installed it
|
default: // assume Updater installed it
|
||||||
rv = true;
|
rv = true;
|
||||||
@ -1111,6 +1140,7 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
if (type == ROUTER_SIGNED) {
|
if (type == ROUTER_SIGNED) {
|
||||||
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||||
|
_downloaded.remove(new UpdateItem(ROUTER_DEV_SU3, ""));
|
||||||
// remove available from other type
|
// remove available from other type
|
||||||
UpdateItem altui = new UpdateItem(ROUTER_SIGNED_SU3, id);
|
UpdateItem altui = new UpdateItem(ROUTER_SIGNED_SU3, id);
|
||||||
Version old = _available.get(altui);
|
Version old = _available.get(altui);
|
||||||
@ -1121,6 +1151,7 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
} else if (type == ROUTER_SIGNED_SU3) {
|
} else if (type == ROUTER_SIGNED_SU3) {
|
||||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||||
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||||
|
_downloaded.remove(new UpdateItem(ROUTER_DEV_SU3, ""));
|
||||||
// remove available from other type
|
// remove available from other type
|
||||||
UpdateItem altui = new UpdateItem(ROUTER_SIGNED, id);
|
UpdateItem altui = new UpdateItem(ROUTER_SIGNED, id);
|
||||||
Version old = _available.get(altui);
|
Version old = _available.get(altui);
|
||||||
@ -1131,6 +1162,11 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
} else if (type == ROUTER_UNSIGNED) {
|
} else if (type == ROUTER_UNSIGNED) {
|
||||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||||
|
_downloaded.remove(new UpdateItem(ROUTER_DEV_SU3, ""));
|
||||||
|
} else if (type == ROUTER_DEV_SU3) {
|
||||||
|
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||||
|
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||||
|
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||||
}
|
}
|
||||||
Version old = _available.get(ui);
|
Version old = _available.get(ui);
|
||||||
if (old != null && old.compareTo(ver) <= 0)
|
if (old != null && old.compareTo(ver) <= 0)
|
||||||
@ -1202,6 +1238,15 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ROUTER_DEV_SU3:
|
||||||
|
String url3 = _context.getProperty(ConfigUpdateHandler.PROP_DEV_SU3_URL);
|
||||||
|
if (url3 != null) {
|
||||||
|
try {
|
||||||
|
return Collections.singletonList(new URI(url3));
|
||||||
|
} catch (URISyntaxException use) {}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case PLUGIN:
|
case PLUGIN:
|
||||||
Properties props = PluginStarter.pluginProperties(_context, id);
|
Properties props = PluginStarter.pluginProperties(_context, id);
|
||||||
String xpi2pURL = props.getProperty("updateURL");
|
String xpi2pURL = props.getProperty("updateURL");
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
package net.i2p.router.update;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.i2p.crypto.TrustedUpdate;
|
||||||
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.router.RouterVersion;
|
||||||
|
import net.i2p.router.web.ConfigUpdateHandler;
|
||||||
|
import net.i2p.update.*;
|
||||||
|
import net.i2p.util.PartialEepGet;
|
||||||
|
import net.i2p.util.PortMapper;
|
||||||
|
import net.i2p.util.VersionComparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for an updated su3 version.
|
||||||
|
*
|
||||||
|
* Take the update URL
|
||||||
|
* then fetch the first 56 bytes of the URL, extract the version,
|
||||||
|
* and compare to current full router version.
|
||||||
|
*
|
||||||
|
* @since 0.9.20 from PluginUpdateChecker
|
||||||
|
*/
|
||||||
|
class DevSU3UpdateChecker extends UpdateRunner {
|
||||||
|
|
||||||
|
public DevSU3UpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
||||||
|
List<URI> uris) {
|
||||||
|
super(ctx, mgr, UpdateType.ROUTER_DEV_SU3, uris, RouterVersion.FULL_VERSION);
|
||||||
|
if (!uris.isEmpty())
|
||||||
|
_currentURI = uris.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void update() {
|
||||||
|
// must be set for super
|
||||||
|
_isPartial = true;
|
||||||
|
// use the same settings as for updater
|
||||||
|
// always proxy, or else FIXME
|
||||||
|
//boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||||
|
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||||
|
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||||
|
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
|
||||||
|
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
|
||||||
|
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
|
||||||
|
String msg = _("HTTP client proxy tunnel must be running");
|
||||||
|
if (_log.shouldWarn())
|
||||||
|
_log.warn(msg);
|
||||||
|
updateStatus("<b>" + msg + "</b>");
|
||||||
|
_mgr.notifyCheckComplete(this, false, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//updateStatus("<b>" + _("Checking for development build update") + "</b>");
|
||||||
|
_baos.reset();
|
||||||
|
try {
|
||||||
|
_get = new PartialEepGet(_context, proxyHost, proxyPort, _baos, _currentURI.toString(), TrustedUpdate.HEADER_BYTES);
|
||||||
|
_get.addStatusListener(this);
|
||||||
|
_get.fetch(CONNECT_TIMEOUT);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
_log.error("Error fetching the update", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred,
|
||||||
|
long bytesRemaining, String url) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining,
|
||||||
|
String url, String outputFile, boolean notModified) {
|
||||||
|
String newVersion = TrustedUpdate.getVersionString(new ByteArrayInputStream(_baos.toByteArray()));
|
||||||
|
boolean newer = VersionComparator.comp(newVersion, RouterVersion.FULL_VERSION) > 0;
|
||||||
|
if (newer) {
|
||||||
|
_mgr.notifyVersionAvailable(this, _currentURI, UpdateType.ROUTER_DEV_SU3, "", UpdateMethod.HTTP,
|
||||||
|
_urls, newVersion, RouterVersion.FULL_VERSION);
|
||||||
|
} else {
|
||||||
|
updateStatus("<b>" + _("No new version found at {0}", linkify(url)) + "</b>");
|
||||||
|
if (_log.shouldWarn())
|
||||||
|
_log.warn("Found old version \"" + newVersion + "\" at " + url);
|
||||||
|
}
|
||||||
|
_mgr.notifyCheckComplete(this, newer, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
|
||||||
|
File f = new File(_updateFile);
|
||||||
|
f.delete();
|
||||||
|
_mgr.notifyCheckComplete(this, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,94 @@
|
|||||||
|
package net.i2p.router.update;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.router.web.ConfigUpdateHandler;
|
||||||
|
import net.i2p.router.web.NewsHelper;
|
||||||
|
import net.i2p.update.*;
|
||||||
|
import static net.i2p.update.UpdateType.*;
|
||||||
|
import static net.i2p.update.UpdateMethod.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Handles the request to update the router by firing off an
|
||||||
|
* {@link net.i2p.util.EepGet} call to download the latest su3 file
|
||||||
|
* and display the status.
|
||||||
|
* </p>
|
||||||
|
* <p>After the download completes the su3 is verified, and the zip is extracted
|
||||||
|
* and copied to the router directory,
|
||||||
|
* and if configured the router is restarted to complete
|
||||||
|
* the update process.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
class DevSU3UpdateHandler implements Checker, Updater {
|
||||||
|
private final RouterContext _context;
|
||||||
|
private final ConsoleUpdateManager _mgr;
|
||||||
|
|
||||||
|
public DevSU3UpdateHandler(RouterContext ctx, ConsoleUpdateManager mgr) {
|
||||||
|
_context = ctx;
|
||||||
|
_mgr = mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null if none
|
||||||
|
*/
|
||||||
|
public List<URI> getUpdateSources() {
|
||||||
|
String url = _context.getProperty(ConfigUpdateHandler.PROP_DEV_SU3_URL);
|
||||||
|
if (url == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Collections.singletonList(new URI(url));
|
||||||
|
} catch (URISyntaxException use) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param currentVersion ignored, we use current router version
|
||||||
|
* @return active task or null if unable to check
|
||||||
|
*/
|
||||||
|
public UpdateTask check(UpdateType type, UpdateMethod method,
|
||||||
|
String id, String currentVersion, long maxTime) {
|
||||||
|
if (type != UpdateType.ROUTER_DEV_SU3 || method != UpdateMethod.HTTP)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
List<URI> updateSources = getUpdateSources();
|
||||||
|
if (updateSources == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
long ms = _context.getProperty(NewsHelper.PROP_LAST_UPDATE_TIME, 0L);
|
||||||
|
if (ms <= 0) {
|
||||||
|
// we don't know what version you have, so stamp it with the current time,
|
||||||
|
// and we'll look for something newer next time around.
|
||||||
|
_context.router().saveConfig(NewsHelper.PROP_LAST_UPDATE_TIME,
|
||||||
|
Long.toString(_context.clock().now()));
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateRunner update = new DevSU3UpdateChecker(_context, _mgr, updateSources);
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a download and return a handle to the download task.
|
||||||
|
* Should not block.
|
||||||
|
*
|
||||||
|
* @param id plugin name or ignored
|
||||||
|
* @param maxTime how long you have
|
||||||
|
* @return active task or null if unable to download
|
||||||
|
*/
|
||||||
|
public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources,
|
||||||
|
String id, String newVersion, long maxTime) {
|
||||||
|
if (type != ROUTER_DEV_SU3 || method != HTTP || updateSources.isEmpty())
|
||||||
|
return null;
|
||||||
|
UpdateRunner update = new DevSU3UpdateRunner(_context, _mgr, updateSources);
|
||||||
|
// set status before thread to ensure UI feedback
|
||||||
|
_mgr.notifyProgress(update, "<b>" + _mgr._("Updating") + "</b>");
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package net.i2p.router.update;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.i2p.crypto.TrustedUpdate;
|
||||||
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.router.web.ConfigUpdateHandler;
|
||||||
|
import static net.i2p.update.UpdateType.*;
|
||||||
|
import net.i2p.util.EepGet;
|
||||||
|
import net.i2p.util.Log;
|
||||||
|
import net.i2p.util.PortMapper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eepget the .su3 file to the temp dir, then notify.
|
||||||
|
* ConsoleUpdateManager will do the rest.
|
||||||
|
*
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
class DevSU3UpdateRunner extends UpdateRunner {
|
||||||
|
|
||||||
|
public DevSU3UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||||
|
super(ctx, mgr, ROUTER_DEV_SU3, uris);
|
||||||
|
if (!uris.isEmpty())
|
||||||
|
_currentURI = uris.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the file */
|
||||||
|
@Override
|
||||||
|
protected void update() {
|
||||||
|
// always proxy for now
|
||||||
|
//boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||||
|
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||||
|
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||||
|
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
|
||||||
|
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
|
||||||
|
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
|
||||||
|
String msg = _("HTTP client proxy tunnel must be running");
|
||||||
|
if (_log.shouldWarn())
|
||||||
|
_log.warn(msg);
|
||||||
|
updateStatus("<b>" + msg + "</b>");
|
||||||
|
_mgr.notifyTaskFailed(this, msg, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String zipURL = _currentURI.toString();
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Starting signed dev update URL: " + zipURL);
|
||||||
|
try {
|
||||||
|
// 40 retries!!
|
||||||
|
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, zipURL, false);
|
||||||
|
_get.addStatusListener(DevSU3UpdateRunner.this);
|
||||||
|
_get.fetch(CONNECT_TIMEOUT, -1, INACTIVITY_TIMEOUT);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
_log.error("Error updating", t);
|
||||||
|
}
|
||||||
|
if (!this.done)
|
||||||
|
_mgr.notifyTaskFailed(this, "", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** eepget listener callback Overrides */
|
||||||
|
@Override
|
||||||
|
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining,
|
||||||
|
String url, String outputFile, boolean notModified) {
|
||||||
|
File tmp = new File(_updateFile);
|
||||||
|
// We use TrustedUpdate here to get the version without any su3 checks,
|
||||||
|
// which will be done later.
|
||||||
|
// Only gets 16 bytes max since we aren't using the SU3 version extraction.
|
||||||
|
String version = TrustedUpdate.getVersionString(tmp);
|
||||||
|
if (version.equals(""))
|
||||||
|
version = "unknown";
|
||||||
|
if (_mgr.notifyComplete(this, version, tmp))
|
||||||
|
this.done = true;
|
||||||
|
else
|
||||||
|
tmp.delete(); // corrupt
|
||||||
|
}
|
||||||
|
}
|
@ -73,6 +73,8 @@ class NewsFetcher extends UpdateRunner {
|
|||||||
_isRunning = true;
|
_isRunning = true;
|
||||||
try {
|
try {
|
||||||
fetchNews();
|
fetchNews();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
_mgr.notifyTaskFailed(this, "", t);
|
||||||
} finally {
|
} finally {
|
||||||
_mgr.notifyCheckComplete(this, _isNewer, _success);
|
_mgr.notifyCheckComplete(this, _isNewer, _success);
|
||||||
_isRunning = false;
|
_isRunning = false;
|
||||||
|
@ -101,15 +101,13 @@ class NewsTimerTask implements SimpleTimer.TimedEvent {
|
|||||||
_context.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED) &&
|
_context.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED) &&
|
||||||
!NewsHelper.dontInstall(_context);
|
!NewsHelper.dontInstall(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @since 0.9.20 */
|
||||||
* HEAD the update url, and if the last-mod time is newer than the last update we
|
private boolean shouldFetchDevSU3() {
|
||||||
* downloaded, as stored in the properties, then we download it using eepget.
|
String url = _context.getProperty(ConfigUpdateHandler.PROP_DEV_SU3_URL);
|
||||||
*
|
return url != null && url.length() > 0 &&
|
||||||
* Non-blocking
|
_context.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_DEV_SU3) &&
|
||||||
*/
|
!NewsHelper.dontInstall(_context);
|
||||||
private void fetchUnsignedHead() {
|
|
||||||
_mgr.check(ROUTER_UNSIGNED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,12 +124,19 @@ class NewsTimerTask implements SimpleTimer.TimedEvent {
|
|||||||
public void run() {
|
public void run() {
|
||||||
// blocking
|
// blocking
|
||||||
fetchNews();
|
fetchNews();
|
||||||
|
if (shouldFetchDevSU3()) {
|
||||||
|
// give it a sec for the download to kick in, if it's going to
|
||||||
|
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
||||||
|
if (!_mgr.isCheckInProgress() && !_mgr.isUpdateInProgress())
|
||||||
|
// nonblocking
|
||||||
|
_mgr.check(ROUTER_DEV_SU3);
|
||||||
|
}
|
||||||
if (shouldFetchUnsigned()) {
|
if (shouldFetchUnsigned()) {
|
||||||
// give it a sec for the download to kick in, if it's going to
|
// give it a sec for the download to kick in, if it's going to
|
||||||
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
||||||
if (!_mgr.isCheckInProgress() && !_mgr.isUpdateInProgress())
|
if (!_mgr.isCheckInProgress() && !_mgr.isUpdateInProgress())
|
||||||
// nonblocking
|
// nonblocking
|
||||||
fetchUnsignedHead();
|
_mgr.check(ROUTER_UNSIGNED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,16 +40,6 @@ class PluginUpdateChecker extends UpdateRunner {
|
|||||||
@Override
|
@Override
|
||||||
public String getID() { return _appName; }
|
public String getID() { return _appName; }
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
_isRunning = true;
|
|
||||||
try {
|
|
||||||
update();
|
|
||||||
} finally {
|
|
||||||
_isRunning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void update() {
|
protected void update() {
|
||||||
// must be set for super
|
// must be set for super
|
||||||
|
@ -22,8 +22,6 @@ class UnsignedUpdateChecker extends UpdateRunner {
|
|||||||
private final long _ms;
|
private final long _ms;
|
||||||
private boolean _unsignedUpdateAvailable;
|
private boolean _unsignedUpdateAvailable;
|
||||||
|
|
||||||
protected static final String SIGNED_UPDATE_FILE = "i2pupdate.sud";
|
|
||||||
|
|
||||||
public UnsignedUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
public UnsignedUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
||||||
List<URI> uris, long lastUpdateTime) {
|
List<URI> uris, long lastUpdateTime) {
|
||||||
super(ctx, mgr, UpdateType.ROUTER_UNSIGNED, uris);
|
super(ctx, mgr, UpdateType.ROUTER_UNSIGNED, uris);
|
||||||
@ -36,6 +34,8 @@ class UnsignedUpdateChecker extends UpdateRunner {
|
|||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
success = fetchUnsignedHead();
|
success = fetchUnsignedHead();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
_mgr.notifyTaskFailed(this, "", t);
|
||||||
} finally {
|
} finally {
|
||||||
_mgr.notifyCheckComplete(this, _unsignedUpdateAvailable, success);
|
_mgr.notifyCheckComplete(this, _unsignedUpdateAvailable, success);
|
||||||
_isRunning = false;
|
_isRunning = false;
|
||||||
@ -59,11 +59,14 @@ class UnsignedUpdateChecker extends UpdateRunner {
|
|||||||
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
|
if (proxyPort == ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT &&
|
||||||
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
|
proxyHost.equals(ConfigUpdateHandler.DEFAULT_PROXY_HOST) &&
|
||||||
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
|
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) < 0) {
|
||||||
|
String msg = _("HTTP client proxy tunnel must be running");
|
||||||
if (_log.shouldWarn())
|
if (_log.shouldWarn())
|
||||||
_log.warn("Cannot check for unsigned update - HTTP client tunnel not running");
|
_log.warn(msg);
|
||||||
|
updateStatus("<b>" + msg + "</b>");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//updateStatus("<b>" + _("Checking for development build update") + "</b>");
|
||||||
try {
|
try {
|
||||||
EepHead get = new EepHead(_context, proxyHost, proxyPort, 0, url);
|
EepHead get = new EepHead(_context, proxyHost, proxyPort, 0, url);
|
||||||
if (get.fetch()) {
|
if (get.fetch()) {
|
||||||
@ -81,7 +84,7 @@ class UnsignedUpdateChecker extends UpdateRunner {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
_log.error("Error fetching the unsigned update", t);
|
_log.error("Error fetching the update", t);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,6 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
|||||||
protected URI _currentURI;
|
protected URI _currentURI;
|
||||||
private final String _currentVersion;
|
private final String _currentVersion;
|
||||||
|
|
||||||
private static final String SIGNED_UPDATE_FILE = "i2pupdate.sud";
|
|
||||||
|
|
||||||
protected static final long CONNECT_TIMEOUT = 55*1000;
|
protected static final long CONNECT_TIMEOUT = 55*1000;
|
||||||
protected static final long INACTIVITY_TIMEOUT = 5*60*1000;
|
protected static final long INACTIVITY_TIMEOUT = 5*60*1000;
|
||||||
protected static final long NOPROXY_INACTIVITY_TIMEOUT = 60*1000;
|
protected static final long NOPROXY_INACTIVITY_TIMEOUT = 60*1000;
|
||||||
|
@ -27,6 +27,8 @@ public class ConfigUpdateHandler extends FormHandler {
|
|||||||
private String _trustedKeys;
|
private String _trustedKeys;
|
||||||
private boolean _updateUnsigned;
|
private boolean _updateUnsigned;
|
||||||
private String _zipURL;
|
private String _zipURL;
|
||||||
|
private boolean _updateDevSU3;
|
||||||
|
private String _devSU3URL;
|
||||||
|
|
||||||
public static final String PROP_NEWS_URL = "router.newsURL";
|
public static final String PROP_NEWS_URL = "router.newsURL";
|
||||||
// public static final String DEFAULT_NEWS_URL = "http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/news.xml?rev=HEAD";
|
// public static final String DEFAULT_NEWS_URL = "http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/news.xml?rev=HEAD";
|
||||||
@ -61,6 +63,17 @@ public class ConfigUpdateHandler extends FormHandler {
|
|||||||
|
|
||||||
public static final String PROP_UPDATE_URL = "router.updateURL";
|
public static final String PROP_UPDATE_URL = "router.updateURL";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default false
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
public static final String PROP_UPDATE_DEV_SU3 = "router.updateDevSU3";
|
||||||
|
/**
|
||||||
|
* no default
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
public static final String PROP_DEV_SU3_URL = "router.updateDevSU3URL";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changed as of release 0.8 to support both .sud and .su2
|
* Changed as of release 0.8 to support both .sud and .su2
|
||||||
* Some JVMs (IcedTea) don't have pack200
|
* Some JVMs (IcedTea) don't have pack200
|
||||||
@ -163,11 +176,14 @@ public class ConfigUpdateHandler extends FormHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean a1 = mgr.checkAvailable(NEWS, 30*1000) != null;
|
boolean a1 = mgr.checkAvailable(NEWS, 40*1000) != null;
|
||||||
boolean a2 = false;
|
boolean a2 = false;
|
||||||
if ((!a1) && _updateUnsigned && _zipURL != null && _zipURL.length() > 0)
|
boolean a3 = false;
|
||||||
a2 = mgr.checkAvailable(ROUTER_UNSIGNED, 30*1000) != null;
|
if ((!a1) && _updateDevSU3 && _devSU3URL != null && _devSU3URL.length() > 0)
|
||||||
if (a1 || a2) {
|
a2 = mgr.checkAvailable(ROUTER_DEV_SU3, 40*1000) != null;
|
||||||
|
if ((!a2) && _updateUnsigned && _zipURL != null && _zipURL.length() > 0)
|
||||||
|
a3 = mgr.checkAvailable(ROUTER_UNSIGNED, 40*1000) != null;
|
||||||
|
if (a1 || a2 || a3) {
|
||||||
if ( (_updatePolicy == null) || (!_updatePolicy.equals("notify")) )
|
if ( (_updatePolicy == null) || (!_updatePolicy.equals("notify")) )
|
||||||
addFormNotice(_("Update available, attempting to download now"));
|
addFormNotice(_("Update available, attempting to download now"));
|
||||||
else
|
else
|
||||||
@ -220,8 +236,10 @@ public class ConfigUpdateHandler extends FormHandler {
|
|||||||
|
|
||||||
changes.put(PROP_SHOULD_PROXY, Boolean.toString(_updateThroughProxy));
|
changes.put(PROP_SHOULD_PROXY, Boolean.toString(_updateThroughProxy));
|
||||||
changes.put(PROP_SHOULD_PROXY_NEWS, Boolean.toString(_newsThroughProxy));
|
changes.put(PROP_SHOULD_PROXY_NEWS, Boolean.toString(_newsThroughProxy));
|
||||||
if (isAdvanced())
|
if (isAdvanced()) {
|
||||||
changes.put(PROP_UPDATE_UNSIGNED, Boolean.toString(_updateUnsigned));
|
changes.put(PROP_UPDATE_UNSIGNED, Boolean.toString(_updateUnsigned));
|
||||||
|
changes.put(PROP_UPDATE_DEV_SU3, Boolean.toString(_updateDevSU3));
|
||||||
|
}
|
||||||
|
|
||||||
String oldFreqStr = _context.getProperty(PROP_REFRESH_FREQUENCY, DEFAULT_REFRESH_FREQUENCY);
|
String oldFreqStr = _context.getProperty(PROP_REFRESH_FREQUENCY, DEFAULT_REFRESH_FREQUENCY);
|
||||||
long oldFreq = DEFAULT_REFRESH_FREQ;
|
long oldFreq = DEFAULT_REFRESH_FREQ;
|
||||||
@ -276,6 +294,18 @@ public class ConfigUpdateHandler extends FormHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( (_devSU3URL != null) && (_devSU3URL.length() > 0) ) {
|
||||||
|
String oldURL = _context.router().getConfigSetting(PROP_DEV_SU3_URL);
|
||||||
|
if ( (oldURL == null) || (!_devSU3URL.equals(oldURL)) ) {
|
||||||
|
if (isAdvanced()) {
|
||||||
|
changes.put(PROP_DEV_SU3_URL, _devSU3URL);
|
||||||
|
addFormNotice(_("Updating signed development build URL to {0}", _devSU3URL));
|
||||||
|
} else {
|
||||||
|
addFormError("Changing signed update URL disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_context.router().saveConfig(changes, null);
|
_context.router().saveConfig(changes, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,4 +323,8 @@ public class ConfigUpdateHandler extends FormHandler {
|
|||||||
public void setZipURL(String url) { _zipURL = url; }
|
public void setZipURL(String url) { _zipURL = url; }
|
||||||
/** @since 0.9.9 */
|
/** @since 0.9.9 */
|
||||||
public void setNewsThroughProxy(String foo) { _newsThroughProxy = true; }
|
public void setNewsThroughProxy(String foo) { _newsThroughProxy = true; }
|
||||||
|
/** @since 0.9.20 */
|
||||||
|
public void setUpdateDevSU3(String foo) { _updateDevSU3 = true; }
|
||||||
|
/** @since 0.9.20 */
|
||||||
|
public void setDevSU3URL(String url) { _devSU3URL = url; }
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,14 @@ public class ConfigUpdateHelper extends HelperBase {
|
|||||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateUnsigned\" >";
|
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateUnsigned\" >";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.20 */
|
||||||
|
public String getUpdateDevSU3() {
|
||||||
|
if (_context.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_DEV_SU3))
|
||||||
|
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateDevSU3\" checked=\"checked\" >";
|
||||||
|
else
|
||||||
|
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateDevSU3\" >";
|
||||||
|
}
|
||||||
|
|
||||||
private static final long PERIODS[] = new long[] { 12*60*60*1000l, 24*60*60*1000l,
|
private static final long PERIODS[] = new long[] { 12*60*60*1000l, 24*60*60*1000l,
|
||||||
36*60*60*1000l, 48*60*60*1000l,
|
36*60*60*1000l, 48*60*60*1000l,
|
||||||
3*24*60*60*1000l, 7*24*60*60*1000l,
|
3*24*60*60*1000l, 7*24*60*60*1000l,
|
||||||
@ -168,6 +176,11 @@ public class ConfigUpdateHelper extends HelperBase {
|
|||||||
return _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL, "");
|
return _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.20 */
|
||||||
|
public String getDevSU3URL() {
|
||||||
|
return _context.getProperty(ConfigUpdateHandler.PROP_DEV_SU3_URL, "");
|
||||||
|
}
|
||||||
|
|
||||||
public String getNewsStatus() {
|
public String getNewsStatus() {
|
||||||
return NewsHelper.status(_context);
|
return NewsHelper.status(_context);
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,13 @@ public class NewsHelper extends ContentHelper {
|
|||||||
return mgr.isUpdateInProgress(ROUTER_SIGNED) ||
|
return mgr.isUpdateInProgress(ROUTER_SIGNED) ||
|
||||||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
||||||
mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
||||||
|
mgr.isUpdateInProgress(ROUTER_DEV_SU3) ||
|
||||||
mgr.isUpdateInProgress(TYPE_DUMMY);
|
mgr.isUpdateInProgress(TYPE_DUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will be false if already downloaded
|
* Release update only.
|
||||||
|
* Will be false if already downloaded.
|
||||||
* @since 0.9.4 moved from NewsFetcher
|
* @since 0.9.4 moved from NewsFetcher
|
||||||
*/
|
*/
|
||||||
public static boolean isUpdateAvailable() {
|
public static boolean isUpdateAvailable() {
|
||||||
@ -66,7 +68,8 @@ public class NewsHelper extends ContentHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available version, will be null if already downloaded
|
* Release update only.
|
||||||
|
* Available version, will be null if already downloaded.
|
||||||
* @return null if none
|
* @return null if none
|
||||||
* @since 0.9.4 moved from NewsFetcher
|
* @since 0.9.4 moved from NewsFetcher
|
||||||
*/
|
*/
|
||||||
@ -80,6 +83,7 @@ public class NewsHelper extends ContentHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Release update only.
|
||||||
* Translated message about new version available but constrained
|
* Translated message about new version available but constrained
|
||||||
* @return null if none
|
* @return null if none
|
||||||
* @since 0.9.9
|
* @since 0.9.9
|
||||||
@ -91,7 +95,8 @@ public class NewsHelper extends ContentHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Already downloaded but not installed version
|
* Release update only.
|
||||||
|
* Already downloaded but not installed version.
|
||||||
* @return null if none
|
* @return null if none
|
||||||
* @since 0.9.4
|
* @since 0.9.4
|
||||||
*/
|
*/
|
||||||
@ -105,13 +110,14 @@ public class NewsHelper extends ContentHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will be false if already downloaded
|
* Will be false if already downloaded or if dev update disabled.
|
||||||
* @since 0.9.4 moved from NewsFetcher
|
* @since 0.9.4 moved from NewsFetcher
|
||||||
*/
|
*/
|
||||||
public static boolean isUnsignedUpdateAvailable() {
|
public static boolean isUnsignedUpdateAvailable(RouterContext ctx) {
|
||||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||||
if (mgr == null) return false;
|
if (mgr == null) return false;
|
||||||
return mgr.getUpdateAvailable(ROUTER_UNSIGNED) != null;
|
return mgr.getUpdateAvailable(ROUTER_UNSIGNED) != null &&
|
||||||
|
ctx.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,6 +141,38 @@ public class NewsHelper extends ContentHelper {
|
|||||||
return formatUnsignedVersion(mgr.getUpdateDownloaded(ROUTER_UNSIGNED));
|
return formatUnsignedVersion(mgr.getUpdateDownloaded(ROUTER_UNSIGNED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will be false if already downloaded or if dev update disabled.
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
public static boolean isDevSU3UpdateAvailable(RouterContext ctx) {
|
||||||
|
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||||
|
if (mgr == null) return false;
|
||||||
|
return mgr.getUpdateAvailable(ROUTER_DEV_SU3) != null &&
|
||||||
|
ctx.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_DEV_SU3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null if none
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
public static String devSU3UpdateVersion() {
|
||||||
|
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||||
|
if (mgr == null) return null;
|
||||||
|
return mgr.getUpdateAvailable(ROUTER_DEV_SU3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Already downloaded but not installed version
|
||||||
|
* @return null if none
|
||||||
|
* @since 0.9.20
|
||||||
|
*/
|
||||||
|
public static String devSU3VersionDownloaded() {
|
||||||
|
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||||
|
if (mgr == null) return null;
|
||||||
|
return mgr.getUpdateDownloaded(ROUTER_DEV_SU3);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert long date stamp to
|
* Convert long date stamp to
|
||||||
* '07-Jul 21:09 UTC' with month name in the system locale
|
* '07-Jul 21:09 UTC' with month name in the system locale
|
||||||
|
@ -657,22 +657,33 @@ public class SummaryHelper extends HelperBase {
|
|||||||
}
|
}
|
||||||
********/
|
********/
|
||||||
|
|
||||||
private boolean updateAvailable() {
|
private static boolean updateAvailable() {
|
||||||
return NewsHelper.isUpdateAvailable();
|
return NewsHelper.isUpdateAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean unsignedUpdateAvailable() {
|
private boolean unsignedUpdateAvailable() {
|
||||||
return NewsHelper.isUnsignedUpdateAvailable();
|
return NewsHelper.isUnsignedUpdateAvailable(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUpdateVersion() {
|
/** @since 0.9.20 */
|
||||||
return NewsHelper.updateVersion();
|
private boolean devSU3UpdateAvailable() {
|
||||||
|
return NewsHelper.isDevSU3UpdateAvailable(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUnsignedUpdateVersion() {
|
private static String getUpdateVersion() {
|
||||||
|
return DataHelper.escapeHTML(NewsHelper.updateVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getUnsignedUpdateVersion() {
|
||||||
|
// value is a formatted date, does not need escaping
|
||||||
return NewsHelper.unsignedUpdateVersion();
|
return NewsHelper.unsignedUpdateVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.20 */
|
||||||
|
private static String getDevSU3UpdateVersion() {
|
||||||
|
return DataHelper.escapeHTML(NewsHelper.devSU3UpdateVersion());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The update status and buttons
|
* The update status and buttons
|
||||||
* @since 0.8.13 moved from SummaryBarRenderer
|
* @since 0.8.13 moved from SummaryBarRenderer
|
||||||
@ -687,8 +698,11 @@ public class SummaryHelper extends HelperBase {
|
|||||||
needSpace = true;
|
needSpace = true;
|
||||||
}
|
}
|
||||||
String dver = NewsHelper.updateVersionDownloaded();
|
String dver = NewsHelper.updateVersionDownloaded();
|
||||||
if (dver == null)
|
if (dver == null) {
|
||||||
dver = NewsHelper.unsignedVersionDownloaded();
|
dver = NewsHelper.devSU3VersionDownloaded();
|
||||||
|
if (dver == null)
|
||||||
|
dver = NewsHelper.unsignedVersionDownloaded();
|
||||||
|
}
|
||||||
if (dver != null &&
|
if (dver != null &&
|
||||||
!NewsHelper.isUpdateInProgress() &&
|
!NewsHelper.isUpdateInProgress() &&
|
||||||
!_context.router().gracefulShutdownInProgress()) {
|
!_context.router().gracefulShutdownInProgress()) {
|
||||||
@ -701,11 +715,12 @@ public class SummaryHelper extends HelperBase {
|
|||||||
buf.append(_("Click Restart to install"));
|
buf.append(_("Click Restart to install"));
|
||||||
else
|
else
|
||||||
buf.append(_("Click Shutdown and restart to install"));
|
buf.append(_("Click Shutdown and restart to install"));
|
||||||
buf.append(' ').append(_("Version {0}", dver));
|
buf.append(' ').append(_("Version {0}", DataHelper.escapeHTML(dver)));
|
||||||
buf.append("</b></h4>");
|
buf.append("</b></h4>");
|
||||||
}
|
}
|
||||||
boolean avail = updateAvailable();
|
boolean avail = updateAvailable();
|
||||||
boolean unsignedAvail = unsignedUpdateAvailable();
|
boolean unsignedAvail = unsignedUpdateAvailable();
|
||||||
|
boolean devSU3Avail = devSU3UpdateAvailable();
|
||||||
String constraint = avail ? NewsHelper.updateConstraint() : null;
|
String constraint = avail ? NewsHelper.updateConstraint() : null;
|
||||||
if (avail && constraint != null &&
|
if (avail && constraint != null &&
|
||||||
!NewsHelper.isUpdateInProgress() &&
|
!NewsHelper.isUpdateInProgress() &&
|
||||||
@ -719,7 +734,7 @@ public class SummaryHelper extends HelperBase {
|
|||||||
buf.append(constraint).append("</b></h4>");
|
buf.append(constraint).append("</b></h4>");
|
||||||
avail = false;
|
avail = false;
|
||||||
}
|
}
|
||||||
if ((avail || unsignedAvail) &&
|
if ((avail || unsignedAvail || devSU3Avail) &&
|
||||||
!NewsHelper.isUpdateInProgress() &&
|
!NewsHelper.isUpdateInProgress() &&
|
||||||
!_context.router().gracefulShutdownInProgress() &&
|
!_context.router().gracefulShutdownInProgress() &&
|
||||||
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) > 0 && // assume using proxy for now
|
_context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY) > 0 && // assume using proxy for now
|
||||||
@ -741,6 +756,14 @@ public class SummaryHelper extends HelperBase {
|
|||||||
.append(_("Download {0} Update", getUpdateVersion()))
|
.append(_("Download {0} Update", getUpdateVersion()))
|
||||||
.append("</button><br>\n");
|
.append("</button><br>\n");
|
||||||
}
|
}
|
||||||
|
if (devSU3Avail) {
|
||||||
|
buf.append("<button type=\"submit\" class=\"download\" name=\"updateAction\" value=\"DevSU3\" >")
|
||||||
|
// Note to translators: parameter is a router version, e.g. "0.9.19-16"
|
||||||
|
// <br> is optional, to help the browser make the lines even in the button
|
||||||
|
// If the translation is shorter than the English, you should probably not include <br>
|
||||||
|
.append(_("Download Signed<br>Development Update<br>{0}", getDevSU3UpdateVersion()))
|
||||||
|
.append("</button><br>\n");
|
||||||
|
}
|
||||||
if (unsignedAvail) {
|
if (unsignedAvail) {
|
||||||
buf.append("<button type=\"submit\" class=\"download\" name=\"updateAction\" value=\"Unsigned\" >")
|
buf.append("<button type=\"submit\" class=\"download\" name=\"updateAction\" value=\"Unsigned\" >")
|
||||||
// Note to translators: parameter is a date and time, e.g. "02-Mar 20:34 UTC"
|
// Note to translators: parameter is a date and time, e.g. "02-Mar 20:34 UTC"
|
||||||
|
@ -79,6 +79,8 @@ public class UpdateHandler {
|
|||||||
_nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) {
|
_nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) {
|
||||||
if (_action.contains("Unsigned")) {
|
if (_action.contains("Unsigned")) {
|
||||||
update(ROUTER_UNSIGNED);
|
update(ROUTER_UNSIGNED);
|
||||||
|
} else if (_action.contains("DevSU3")) {
|
||||||
|
update(ROUTER_DEV_SU3);
|
||||||
} else if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
} else if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||||
update(ROUTER_SIGNED_SU3);
|
update(ROUTER_SIGNED_SU3);
|
||||||
} else {
|
} else {
|
||||||
@ -92,7 +94,7 @@ public class UpdateHandler {
|
|||||||
if (mgr == null)
|
if (mgr == null)
|
||||||
return;
|
return;
|
||||||
if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
||||||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3)) {
|
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) || mgr.isUpdateInProgress(ROUTER_DEV_SU3)) {
|
||||||
_log.error("Update already running");
|
_log.error("Update already running");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,10 @@
|
|||||||
<td><textarea cols="60" rows="6" name="updateURL" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="updateURL" /></textarea></td>
|
<td><textarea cols="60" rows="6" name="updateURL" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="updateURL" /></textarea></td>
|
||||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Trusted keys")%>:</b></td>
|
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Trusted keys")%>:</b></td>
|
||||||
<td><textarea cols="60" rows="6" name="trustedKeys" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></td></tr>
|
<td><textarea cols="60" rows="6" name="trustedKeys" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></td></tr>
|
||||||
|
<tr><td id="devSU3build" class="mediumtags" align="right"><b><%=intl._("Update with signed development builds?")%></b></td>
|
||||||
|
<td><jsp:getProperty name="updatehelper" property="updateDevSU3" /></td>
|
||||||
|
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Signed Build URL")%>:</b></td>
|
||||||
|
<td><input type="text" size="60" name="devSU3URL" value="<jsp:getProperty name="updatehelper" property="devSU3URL" />"></td></tr>
|
||||||
<tr><td id="unsignedbuild" class="mediumtags" align="right"><b><%=intl._("Update with unsigned development builds?")%></b></td>
|
<tr><td id="unsignedbuild" class="mediumtags" align="right"><b><%=intl._("Update with unsigned development builds?")%></b></td>
|
||||||
<td><jsp:getProperty name="updatehelper" property="updateUnsigned" /></td>
|
<td><jsp:getProperty name="updatehelper" property="updateUnsigned" /></td>
|
||||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Unsigned Build URL")%>:</b></td>
|
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Unsigned Build URL")%>:</b></td>
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
2015-05-07 zzz
|
||||||
|
* Update: Add support for su3-signed development builds (ticket #1381)
|
||||||
|
|
||||||
2015-05-06 zzz
|
2015-05-06 zzz
|
||||||
|
* Datagram: Convert IOE to DFE and throw on error (ticket #1562)
|
||||||
* Naming services: Export address books with Windows
|
* Naming services: Export address books with Windows
|
||||||
line endings on Windows (ticket #1557)
|
line endings on Windows (ticket #1557)
|
||||||
* Transport: Add config to force IPv4 (only) to firewalled (ticket #1541)
|
* Transport: Add config to force IPv4 (only) to firewalled (ticket #1541)
|
||||||
@ -122,7 +126,7 @@ Prop from i2p.i2p.zzz.test2:
|
|||||||
* Transport: Fix active peer count for NTCP
|
* Transport: Fix active peer count for NTCP
|
||||||
|
|
||||||
2015-04-15 tuna
|
2015-04-15 tuna
|
||||||
* SimpleScheduler: Deprecated, functionaltiy moved to SimpleTimer2 (ticket #1069)
|
* SimpleScheduler: Deprecated, functionality moved to SimpleTimer2 (ticket #1069)
|
||||||
|
|
||||||
2015-04-13 zzz
|
2015-04-13 zzz
|
||||||
* Router: Fix NPE on bad share bandwidth config (ticket #1524)
|
* Router: Fix NPE on bad share bandwidth config (ticket #1524)
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
JNJOWTH/Vas1W6XlwGcOOAARTQ==
|
||||||
|
-----END CERTIFICATE-----
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 16;
|
public final static long BUILD = 17;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user