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:
zzz
2015-05-07 13:04:43 +00:00
parent b12f988390
commit 2f5e64e532
18 changed files with 509 additions and 51 deletions

View File

@ -27,6 +27,8 @@ public class ConfigUpdateHandler extends FormHandler {
private String _trustedKeys;
private boolean _updateUnsigned;
private String _zipURL;
private boolean _updateDevSU3;
private String _devSU3URL;
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";
@ -61,6 +63,17 @@ public class ConfigUpdateHandler extends FormHandler {
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
* Some JVMs (IcedTea) don't have pack200
@ -163,11 +176,14 @@ public class ConfigUpdateHandler extends FormHandler {
return;
}
boolean a1 = mgr.checkAvailable(NEWS, 30*1000) != null;
boolean a1 = mgr.checkAvailable(NEWS, 40*1000) != null;
boolean a2 = false;
if ((!a1) && _updateUnsigned && _zipURL != null && _zipURL.length() > 0)
a2 = mgr.checkAvailable(ROUTER_UNSIGNED, 30*1000) != null;
if (a1 || a2) {
boolean a3 = false;
if ((!a1) && _updateDevSU3 && _devSU3URL != null && _devSU3URL.length() > 0)
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")) )
addFormNotice(_("Update available, attempting to download now"));
else
@ -220,8 +236,10 @@ public class ConfigUpdateHandler extends FormHandler {
changes.put(PROP_SHOULD_PROXY, Boolean.toString(_updateThroughProxy));
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_DEV_SU3, Boolean.toString(_updateDevSU3));
}
String oldFreqStr = _context.getProperty(PROP_REFRESH_FREQUENCY, DEFAULT_REFRESH_FREQUENCY);
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);
}
@ -293,4 +323,8 @@ public class ConfigUpdateHandler extends FormHandler {
public void setZipURL(String url) { _zipURL = url; }
/** @since 0.9.9 */
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; }
}

View File

@ -95,6 +95,14 @@ public class ConfigUpdateHelper extends HelperBase {
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,
36*60*60*1000l, 48*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, "");
}
/** @since 0.9.20 */
public String getDevSU3URL() {
return _context.getProperty(ConfigUpdateHandler.PROP_DEV_SU3_URL, "");
}
public String getNewsStatus() {
return NewsHelper.status(_context);
}

View File

@ -51,11 +51,13 @@ public class NewsHelper extends ContentHelper {
return mgr.isUpdateInProgress(ROUTER_SIGNED) ||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) ||
mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
mgr.isUpdateInProgress(ROUTER_DEV_SU3) ||
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
*/
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
* @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
* @return null if none
* @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
* @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
*/
public static boolean isUnsignedUpdateAvailable() {
public static boolean isUnsignedUpdateAvailable(RouterContext ctx) {
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
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));
}
/**
* 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
* '07-Jul 21:09 UTC' with month name in the system locale

View File

@ -657,22 +657,33 @@ public class SummaryHelper extends HelperBase {
}
********/
private boolean updateAvailable() {
private static boolean updateAvailable() {
return NewsHelper.isUpdateAvailable();
}
private boolean unsignedUpdateAvailable() {
return NewsHelper.isUnsignedUpdateAvailable();
return NewsHelper.isUnsignedUpdateAvailable(_context);
}
private String getUpdateVersion() {
return NewsHelper.updateVersion();
/** @since 0.9.20 */
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();
}
/** @since 0.9.20 */
private static String getDevSU3UpdateVersion() {
return DataHelper.escapeHTML(NewsHelper.devSU3UpdateVersion());
}
/**
* The update status and buttons
* @since 0.8.13 moved from SummaryBarRenderer
@ -687,8 +698,11 @@ public class SummaryHelper extends HelperBase {
needSpace = true;
}
String dver = NewsHelper.updateVersionDownloaded();
if (dver == null)
dver = NewsHelper.unsignedVersionDownloaded();
if (dver == null) {
dver = NewsHelper.devSU3VersionDownloaded();
if (dver == null)
dver = NewsHelper.unsignedVersionDownloaded();
}
if (dver != null &&
!NewsHelper.isUpdateInProgress() &&
!_context.router().gracefulShutdownInProgress()) {
@ -701,11 +715,12 @@ public class SummaryHelper extends HelperBase {
buf.append(_("Click Restart to install"));
else
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>");
}
boolean avail = updateAvailable();
boolean unsignedAvail = unsignedUpdateAvailable();
boolean devSU3Avail = devSU3UpdateAvailable();
String constraint = avail ? NewsHelper.updateConstraint() : null;
if (avail && constraint != null &&
!NewsHelper.isUpdateInProgress() &&
@ -719,7 +734,7 @@ public class SummaryHelper extends HelperBase {
buf.append(constraint).append("</b></h4>");
avail = false;
}
if ((avail || unsignedAvail) &&
if ((avail || unsignedAvail || devSU3Avail) &&
!NewsHelper.isUpdateInProgress() &&
!_context.router().gracefulShutdownInProgress() &&
_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("</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) {
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"

View File

@ -79,6 +79,8 @@ public class UpdateHandler {
_nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) {
if (_action.contains("Unsigned")) {
update(ROUTER_UNSIGNED);
} else if (_action.contains("DevSU3")) {
update(ROUTER_DEV_SU3);
} else if (ConfigUpdateHandler.USE_SU3_UPDATE) {
update(ROUTER_SIGNED_SU3);
} else {
@ -92,7 +94,7 @@ public class UpdateHandler {
if (mgr == null)
return;
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");
return;
}