* Plugins:

- Fix classpath setting for webapps
      - Implement uninstall args in clients.config
This commit is contained in:
zzz
2010-02-11 19:18:26 +00:00
parent cada9fae44
commit 62308f26bc
5 changed files with 57 additions and 24 deletions

View File

@ -1,6 +1,7 @@
package net.i2p.router.web;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -69,9 +70,11 @@ public class ConfigClientsHandler extends FormHandler {
} else {
try {
PluginStarter.stopPlugin(_context, app);
} catch (Exception e) {}
PluginStarter.deletePlugin(_context, app);
addFormNotice(_("Deleted plugin {0}", app));
} catch (IOException e) {
addFormError(_("Error deleting plugin {0}", app) + ": " + e);
}
}
return;
}
@ -81,7 +84,7 @@ public class ConfigClientsHandler extends FormHandler {
String app = _action.substring(5);
try {
PluginStarter.stopPlugin(_context, app);
} catch (Exception e) {}
} catch (IOException e) {}
addFormNotice(_("Stopped plugin {0}", app));
return;
}

View File

@ -77,6 +77,7 @@ public class PluginStarter implements Runnable {
log.error("Cannot start nonexistent plugin: " + appName);
return false;
}
//log.error("Starting plugin: " + appName);
// load and start things in clients.config
File clientConfig = new File(pluginDir, "clients.config");
@ -84,7 +85,7 @@ public class PluginStarter implements Runnable {
Properties props = new Properties();
DataHelper.loadProps(props, clientConfig);
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
runClientApps(ctx, pluginDir, clients, true);
runClientApps(ctx, pluginDir, clients, "start");
}
// start console webapps in console/webapps
@ -98,6 +99,7 @@ public class PluginStarter implements Runnable {
for (int i = 0; i < fileNames.length; i++) {
try {
String warName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
//log.error("Found webapp: " + warName);
// check for duplicates in $I2P
// easy way for now...
if (warName.equals("i2psnark") || warName.equals("susidns") || warName.equals("i2ptunnel") ||
@ -107,6 +109,7 @@ public class PluginStarter implements Runnable {
}
String enabled = props.getProperty(PREFIX + warName + ENABLED);
if (! "false".equals(enabled)) {
//log.error("Starting webapp: " + warName);
String path = new File(webappDir, fileNames[i]).getCanonicalPath();
WebAppStarter.startWebApp(ctx, server, warName, path);
}
@ -157,7 +160,7 @@ public class PluginStarter implements Runnable {
}
/** @return true on success */
static boolean stopPlugin(RouterContext ctx, String appName) throws Exception {
static boolean stopPlugin(RouterContext ctx, String appName) throws IOException {
Log log = ctx.logManager().getLog(PluginStarter.class);
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
@ -171,7 +174,7 @@ public class PluginStarter implements Runnable {
Properties props = new Properties();
DataHelper.loadProps(props, clientConfig);
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
runClientApps(ctx, pluginDir, clients, false);
runClientApps(ctx, pluginDir, clients, "stop");
}
// stop console webapps in console/webapps
@ -201,17 +204,26 @@ public class PluginStarter implements Runnable {
if (name != null && name.length() > 0)
NavHelper.unregisterApp(name);
log.error("Stopping plugin: " + appName);
return true;
}
/** @return true on success - call stopPlugin() first */
static boolean deletePlugin(RouterContext ctx, String appName) {
static boolean deletePlugin(RouterContext ctx, String appName) throws IOException {
Log log = ctx.logManager().getLog(PluginStarter.class);
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
log.error("Cannot stop nonexistent plugin: " + appName);
return false;
}
// uninstall things in clients.config
File clientConfig = new File(pluginDir, "clients.config");
if (clientConfig.exists()) {
Properties props = new Properties();
DataHelper.loadProps(props, clientConfig);
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
runClientApps(ctx, pluginDir, clients, "uninstall");
}
FileUtil.rmdir(pluginDir, false);
Properties props = pluginProperties();
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
@ -313,20 +325,28 @@ public class PluginStarter implements Runnable {
return null;
}
/** @param start true=start, false=stop */
private static void runClientApps(RouterContext ctx, File pluginDir, List<ClientAppConfig> apps, boolean start) {
/** @param action "start" or "stop" or "uninstall" */
private static void runClientApps(RouterContext ctx, File pluginDir, List<ClientAppConfig> apps, String action) {
Log log = ctx.logManager().getLog(PluginStarter.class);
for(ClientAppConfig app : apps) {
if (start && app.disabled)
if (action.equals("start") && app.disabled)
continue;
String argVal[];
if (start) {
if (action.equals("start")) {
// start
argVal = LoadClientAppsJob.parseArgs(app.args);
} else {
// stopargs must be present
if (app.stopargs == null || app.stopargs.length() <= 0)
String args;
if (action.equals("stop"))
args = app.stopargs;
else if (action.equals("uninstall"))
args = app.uninstallargs;
else
throw new IllegalArgumentException("bad action");
// args must be present
if (args == null || args.length() <= 0)
continue;
argVal = LoadClientAppsJob.parseArgs(app.stopargs);
argVal = LoadClientAppsJob.parseArgs(args);
}
// do this after parsing so we don't need to worry about quoting
for (int i = 0; i < argVal.length; i++) {
@ -345,7 +365,7 @@ public class PluginStarter implements Runnable {
}
addToClasspath(cp, app.clientName, log);
}
if (app.delay == 0 || !start) {
if (app.delay == 0 || !action.equals("start")) {
// run this guy now
LoadClientAppsJob.runClient(app.className, app.clientName, argVal, log);
} else {

View File

@ -308,7 +308,7 @@ public class PluginUpdateHandler extends UpdateHandler {
if (!PluginStarter.stopPlugin(_context, appName)) {
// failed, ignore
}
} catch (Exception e) {} // ignore
} catch (IOException e) {} // ignore
} else {
if (Boolean.valueOf(props.getProperty("update-only")).booleanValue()) {

View File

@ -53,8 +53,10 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
I2PAppContext i2pContext = I2PAppContext.getGlobalContext();
File libDir = new File(i2pContext.getBaseDir(), "lib");
File pluginLibDir = new File(i2pContext.getAppDir(),
PluginUpdateHandler.PLUGIN_DIR + ctxPath + '/' + "lib");
// FIXME this only works if war is the same name as the plugin
File pluginDir = new File(i2pContext.getAppDir(),
PluginUpdateHandler.PLUGIN_DIR + ctxPath);
File dir = libDir;
String cp;
if (ctxPath.equals("/susidns")) {
@ -63,10 +65,11 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
} else if (ctxPath.equals("/i2psnark")) {
// duplicate classes removed from the .war in 0.7.12
cp = "i2psnark.jar";
} else if (pluginLibDir.exists()) {
Properties props = RouterConsoleRunner.webAppProperties(pluginLibDir.getAbsolutePath());
} else if (pluginDir.exists()) {
File consoleDir = new File(pluginDir, "console");
Properties props = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
dir = pluginLibDir;
dir = pluginDir;
} else {
Properties props = RouterConsoleRunner.webAppProperties();
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
@ -79,6 +82,8 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
String path;
if (elem.startsWith("$I2P"))
path = i2pContext.getBaseDir().getAbsolutePath() + '/' + elem.substring(4);
else if (elem.startsWith("$PLUGIN"))
path = dir.getAbsolutePath() + '/' + elem.substring(7);
else
path = dir.getAbsolutePath() + '/' + elem;
System.err.println("Adding " + path + " to classpath for " + appName);

View File

@ -37,6 +37,8 @@ public class ClientAppConfig {
public String classpath;
/** @since 0.7.12 */
public String stopargs;
/** @since 0.7.12 */
public String uninstallargs;
public ClientAppConfig(String cl, String client, String a, long d, boolean dis) {
className = cl;
@ -47,10 +49,11 @@ public class ClientAppConfig {
}
/** @since 0.7.12 */
public ClientAppConfig(String cl, String client, String a, long d, boolean dis, String cp, String sa) {
public ClientAppConfig(String cl, String client, String a, long d, boolean dis, String cp, String sa, String ua) {
this(cl, client, a, d, dis);
classpath = cp;
stopargs = sa;
uninstallargs = ua;
}
public static File configFile(I2PAppContext ctx) {
@ -118,6 +121,7 @@ public class ClientAppConfig {
String disabled = clientApps.getProperty(PREFIX + i + ".startOnLoad");
String classpath = clientApps.getProperty(PREFIX + i + ".classpath");
String stopargs = clientApps.getProperty(PREFIX + i + ".stopargs");
String uninstallargs = clientApps.getProperty(PREFIX + i + ".uninstallargs");
i++;
boolean dis = disabled != null && "false".equals(disabled);
@ -129,7 +133,8 @@ public class ClientAppConfig {
if (delayStr != null && !onStartup)
try { delay = 1000*Integer.parseInt(delayStr); } catch (NumberFormatException nfe) {}
rv.add(new ClientAppConfig(className, clientName, args, delay, dis, classpath, stopargs));
rv.add(new ClientAppConfig(className, clientName, args, delay, dis,
classpath, stopargs, uninstallargs));
}
return rv;
}