* Updates:

- Notify manager about all available update methods at once, so the priority
     system works and it doesn't only update via HTTP
   - Start router update download at startup if available
   - Only check plugins when core version increases, not decreases, so we
     don't update plugins when downgrading
   - Limit length of URL shown on summary bar
This commit is contained in:
zzz
2013-04-19 11:49:22 +00:00
parent ca1e8d09cc
commit 1e5ffe636f
7 changed files with 149 additions and 44 deletions

View File

@@ -101,6 +101,7 @@ public class ConsoleUpdateManager implements UpdateManager {
notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context))); notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context)));
notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION); notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION);
// hack to init from the current news file... do this before we register Updaters // hack to init from the current news file... do this before we register Updaters
// This will not kick off any Updaters as none are yet registered
(new NewsFetcher(_context, this, Collections.EMPTY_LIST)).checkForUpdates(); (new NewsFetcher(_context, this, Collections.EMPTY_LIST)).checkForUpdates();
for (String plugin : PluginStarter.getPlugins()) { for (String plugin : PluginStarter.getPlugins()) {
Properties props = PluginStarter.pluginProperties(_context, plugin); Properties props = PluginStarter.pluginProperties(_context, plugin);
@@ -608,6 +609,7 @@ public class ConsoleUpdateManager implements UpdateManager {
/** /**
* Called by the Updater, either after check() was called, or it found out on its own. * Called by the Updater, either after check() was called, or it found out on its own.
* Use this if there is only one UpdateMethod; otherwise use the Map method below.
* *
* @param newsSource who told us * @param newsSource who told us
* @param id plugin name for plugins, ignored otherwise * @param id plugin name for plugins, ignored otherwise
@@ -620,50 +622,95 @@ public class ConsoleUpdateManager implements UpdateManager {
UpdateType type, String id, UpdateType type, String id,
UpdateMethod method, List<URI> updateSources, UpdateMethod method, List<URI> updateSources,
String newVersion, String minVersion) { String newVersion, String minVersion) {
return notifyVersionAvailable(task, newsSource, type, id,
Collections.singletonMap(method, updateSources),
newVersion, minVersion);
}
/**
* Called by the Checker, either after check() was called, or it found out on its own.
* Checkers must use this method if there are multiple UpdateMethods discoverd simultaneously.
*
* @param newsSource who told us
* @param id plugin name for plugins, ignored otherwise
* @param sourceMap Mapping of methods to sources
* @param newVersion The new version available
* @param minVersion The minimum installed version to be able to update to newVersion
* @return true if we didn't know already
* @since 0.9.6
*/
public boolean notifyVersionAvailable(UpdateTask task, URI newsSource,
UpdateType type, String id,
Map<UpdateMethod, List<URI>> sourceMap,
String newVersion, String minVersion) {
if (type == NEWS) { if (type == NEWS) {
// shortcut // shortcut
notifyInstalled(NEWS, "", newVersion); notifyInstalled(NEWS, "", newVersion);
return true; return true;
} }
UpdateItem ui = new UpdateItem(type, id); UpdateItem ui = new UpdateItem(type, id);
VersionAvailable newVA = new VersionAvailable(newVersion, minVersion, method, updateSources); boolean shouldUpdate = false;
Version old = _installed.get(ui); for (Map.Entry<UpdateMethod, List<URI>> e : sourceMap.entrySet()) {
if (_log.shouldLog(Log.INFO)) UpdateMethod method = e.getKey();
_log.info("notifyVersionAvailable " + ui + ' ' + newVA + " old: " + old); List<URI> updateSources = e.getValue();
if (old != null && old.compareTo(newVA) >= 0) {
if (_log.shouldLog(Log.WARN)) VersionAvailable newVA = new VersionAvailable(newVersion, minVersion, method, updateSources);
_log.warn(ui.toString() + ' ' + old + " already installed"); Version old = _installed.get(ui);
return false; if (_log.shouldLog(Log.INFO))
} _log.info("notifyVersionAvailable " + ui + ' ' + newVA + " old: " + old);
old = _downloaded.get(ui); if (old != null && old.compareTo(newVA) >= 0) {
if (old != null && old.compareTo(newVA) >= 0) {
if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + old + " already downloaded");
return false;
}
VersionAvailable oldVA = _available.get(ui);
if (oldVA != null) {
int comp = oldVA.compareTo(newVA);
if (comp > 0) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + oldVA + " already available"); _log.warn(ui.toString() + ' ' + old + " already installed");
// don't bother updating sources
return false; return false;
} }
if (comp == 0) { old = _downloaded.get(ui);
if (oldVA.sourceMap.putIfAbsent(method, updateSources) == null) { if (old != null && old.compareTo(newVA) >= 0) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + oldVA + " updated with new source method"); _log.warn(ui.toString() + ' ' + old + " already downloaded");
} else { // don't bother updating sources
return false;
}
VersionAvailable oldVA = _available.get(ui);
if (oldVA != null) {
int comp = oldVA.compareTo(newVA);
if (comp > 0) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + oldVA + " already available"); _log.warn(ui.toString() + ' ' + oldVA + " already available");
} continue;
return false; } else if (comp == 0) {
List<URI> oldSources = oldVA.sourceMap.putIfAbsent(method, updateSources);
if (oldSources == null) {
// merge with existing VersionAvailable
// new method
if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + oldVA + " updated with new source method");
} else if (!oldSources.containsAll(updateSources)) {
// merge with existing VersionAvailable
// new sources to existing method
for (URI uri : updateSources) {
if (!oldSources.contains(uri)) {
if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + oldVA + " adding " + uri + " to method " + method);
oldSources.add(uri);
}
}
} else {
if (_log.shouldLog(Log.WARN))
_log.warn(ui.toString() + ' ' + oldVA + " already available");
}
continue;
} // else new version is newer
} }
}
if (_log.shouldLog(Log.INFO)) // Use the new VersionAvailable
_log.info(ui.toString() + ' ' + newVA + " now available"); if (_log.shouldLog(Log.INFO))
_available.put(ui, newVA); _log.info(ui.toString() + ' ' + newVA + " now available");
_available.put(ui, newVA);
shouldUpdate = true;
}
if (!shouldUpdate)
return false;
String msg = null; String msg = null;
switch (type) { switch (type) {
@@ -679,7 +726,12 @@ public class ConsoleUpdateManager implements UpdateManager {
if (shouldInstall() && if (shouldInstall() &&
!(isUpdateInProgress(ROUTER_SIGNED) || !(isUpdateInProgress(ROUTER_SIGNED) ||
isUpdateInProgress(ROUTER_UNSIGNED))) { isUpdateInProgress(ROUTER_UNSIGNED))) {
if (_log.shouldLog(Log.INFO))
_log.info("Updating " + ui + " after notify");
update_fromCheck(type, id, DEFAULT_MAX_TIME); update_fromCheck(type, id, DEFAULT_MAX_TIME);
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Not updating " + ui + ", update disabled or in progress");
} }
// ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display // ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display
break; break;
@@ -890,7 +942,7 @@ public class ConsoleUpdateManager implements UpdateManager {
} }
/** from NewsFetcher */ /** from NewsFetcher */
private boolean shouldInstall() { boolean shouldInstall() {
String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY); String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY);
if ("notify".equals(policy) || NewsHelper.dontInstall(_context)) if ("notify".equals(policy) || NewsHelper.dontInstall(_context))
return false; return false;
@@ -1049,7 +1101,9 @@ public class ConsoleUpdateManager implements UpdateManager {
} }
static String linkify(String url) { static String linkify(String url) {
return "<a target=\"_blank\" href=\"" + url + "\"/>" + url + "</a>"; String durl = url.length() <= 28 ? url :
url.substring(0, 25) + "&hellip;";
return "<a target=\"_blank\" href=\"" + url + "\"/>" + durl + "</a>";
} }
/** translate a string */ /** translate a string */

View File

@@ -148,21 +148,21 @@ class NewsFetcher extends UpdateRunner {
// TODO if minversion > our version, continue // TODO if minversion > our version, continue
// and look for a second entry with clearnet URLs // and look for a second entry with clearnet URLs
// TODO clearnet URLs, notify with HTTP_CLEARNET and/or HTTPS_CLEARNET // TODO clearnet URLs, notify with HTTP_CLEARNET and/or HTTPS_CLEARNET
_mgr.notifyVersionAvailable(this, _currentURI, Map<UpdateMethod, List<URI>> sourceMap = new HashMap(4);
ROUTER_SIGNED, "", HTTP, sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP));
_mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP),
ver, "");
String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY; String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY;
String murl = args.get(key); String murl = args.get(key);
if (murl != null) { if (murl != null) {
List<URI> uris = tokenize(murl); List<URI> uris = tokenize(murl);
if (!uris.isEmpty()) { if (!uris.isEmpty()) {
Collections.shuffle(uris, _context.random()); Collections.shuffle(uris, _context.random());
_mgr.notifyVersionAvailable(this, _currentURI, sourceMap.put(TORRENT, uris);
ROUTER_SIGNED, "", TORRENT,
uris, ver, "");
} }
} }
// notify about all sources at once
_mgr.notifyVersionAvailable(this, _currentURI,
ROUTER_SIGNED, "", sourceMap,
ver, "");
} else { } else {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Our version is current"); _log.debug("Our version is current");

View File

@@ -39,6 +39,7 @@ class NewsTimerTask implements SimpleTimer.TimedEvent {
private final RouterContext _context; private final RouterContext _context;
private final Log _log; private final Log _log;
private final ConsoleUpdateManager _mgr; private final ConsoleUpdateManager _mgr;
private boolean _firstRun = true;
private static final long INITIAL_DELAY = 5*60*1000; private static final long INITIAL_DELAY = 5*60*1000;
private static final long RUN_DELAY = 10*60*1000; private static final long RUN_DELAY = 10*60*1000;
@@ -64,7 +65,20 @@ class NewsTimerTask implements SimpleTimer.TimedEvent {
// nonblocking // nonblocking
fetchUnsignedHead(); fetchUnsignedHead();
} }
} else if (_firstRun) {
// This covers the case where we got a new news but then shut down before it
// was successfully downloaded, and then restarted within the 36 hour delay
// before fetching news again.
// If we already know about a new version (from ConsoleUpdateManager calling
// NewsFetcher.checkForUpdates() before any Updaters were registered),
// this will fire off an update.
// If disabled this does nothing.
// TODO unsigned too?
if (_mgr.shouldInstall() &&
!_mgr.isCheckInProgress() && !_mgr.isUpdateInProgress())
_mgr.update(ROUTER_SIGNED);
} }
_firstRun = false;
} }
private boolean shouldFetchNews() { private boolean shouldFetchNews() {

View File

@@ -69,9 +69,13 @@ public class PluginStarter implements Runnable {
public void run() { public void run() {
if (_context.getBooleanPropertyDefaultTrue("plugins.autoUpdate") && if (_context.getBooleanPropertyDefaultTrue("plugins.autoUpdate") &&
(!NewsHelper.isUpdateInProgress()) && !NewsHelper.isUpdateInProgress()) {
(!RouterVersion.VERSION.equals(_context.getProperty("router.previousVersion")))) String prev = _context.getProperty("router.previousVersion");
updateAll(_context, true); if (prev != null &&
(new VersionComparator()).compare(RouterVersion.VERSION, prev) > 0) {
updateAll(_context, true);
}
}
startPlugins(_context); startPlugins(_context);
} }

View File

@@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* The central resource coordinating updates. * The central resource coordinating updates.
@@ -34,6 +35,7 @@ public interface UpdateManager {
/** /**
* Called by the Checker, either after check() was called, or it found out on its own. * Called by the Checker, either after check() was called, or it found out on its own.
* Use this if there is only one UpdateMethod; otherwise use the Map method below.
* *
* @param newsSource who told us * @param newsSource who told us
* @param id plugin name for plugins, ignored otherwise * @param id plugin name for plugins, ignored otherwise
@@ -48,6 +50,23 @@ public interface UpdateManager {
UpdateMethod method, List<URI> updateSources, UpdateMethod method, List<URI> updateSources,
String newVersion, String minVersion); String newVersion, String minVersion);
/**
* Called by the Checker, either after check() was called, or it found out on its own.
* Checkers must use this method if there are multiple UpdateMethods discoverd simultaneously.
*
* @param newsSource who told us
* @param id plugin name for plugins, ignored otherwise
* @param sourceMap Mapping of methods to sources
* @param newVersion The new version available
* @param minVersion The minimum installed version to be able to update to newVersion
* @return true if we didn't know already
* @since 0.9.6
*/
public boolean notifyVersionAvailable(UpdateTask task, URI newsSource,
UpdateType type, String id,
Map<UpdateMethod, List<URI>> sourceMap,
String newVersion, String minVersion);
/** /**
* Called by the Checker after check() was called and all notifyVersionAvailable() callbacks are finished * Called by the Checker after check() was called and all notifyVersionAvailable() callbacks are finished
* @param newer notifyVersionAvailable was called * @param newer notifyVersionAvailable was called

View File

@@ -1,3 +1,17 @@
2013-04-19 zzz
* AppManager: Register jetty, console, and SAM with manager
* i2psnark: Disable spellcheck in more form fields
* LogManager: Add support for saving properties added in recent releases
* Updates:
- Notify manager about all available update methods at once, so the priority
system works and it doesn't only update via HTTP
- Start router update download at startup if available
- Only check plugins when core version increases, not decreases, so we
don't update plugins when downgrading
- Limit length of URL shown on summary bar
* WorkingDir: Correctly strip DOS line endings while migrating,
to fix eepsite location on 0.9.5 Windows installs (ticket #919)
2013-04-18 zzz 2013-04-18 zzz
* i2psnark: Fix params after P-R-G * i2psnark: Fix params after P-R-G
* i2ptunnel: Set target=_top in all external links to break out of console iframe * i2ptunnel: Set target=_top in all external links to break out of console iframe

View File

@@ -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 = 10; public final static long BUILD = 11;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";