forked from I2P_Developers/i2p.i2p
* Plugins:
- Fix classpath setting for webapps - Implement uninstall args in clients.config
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
package net.i2p.router.web;
|
package net.i2p.router.web;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -69,9 +70,11 @@ public class ConfigClientsHandler extends FormHandler {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
PluginStarter.stopPlugin(_context, app);
|
PluginStarter.stopPlugin(_context, app);
|
||||||
} catch (Exception e) {}
|
PluginStarter.deletePlugin(_context, app);
|
||||||
PluginStarter.deletePlugin(_context, app);
|
addFormNotice(_("Deleted plugin {0}", app));
|
||||||
addFormNotice(_("Deleted plugin {0}", app));
|
} catch (IOException e) {
|
||||||
|
addFormError(_("Error deleting plugin {0}", app) + ": " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -81,7 +84,7 @@ public class ConfigClientsHandler extends FormHandler {
|
|||||||
String app = _action.substring(5);
|
String app = _action.substring(5);
|
||||||
try {
|
try {
|
||||||
PluginStarter.stopPlugin(_context, app);
|
PluginStarter.stopPlugin(_context, app);
|
||||||
} catch (Exception e) {}
|
} catch (IOException e) {}
|
||||||
addFormNotice(_("Stopped plugin {0}", app));
|
addFormNotice(_("Stopped plugin {0}", app));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ public class PluginStarter implements Runnable {
|
|||||||
log.error("Cannot start nonexistent plugin: " + appName);
|
log.error("Cannot start nonexistent plugin: " + appName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
//log.error("Starting plugin: " + appName);
|
||||||
|
|
||||||
// load and start things in clients.config
|
// load and start things in clients.config
|
||||||
File clientConfig = new File(pluginDir, "clients.config");
|
File clientConfig = new File(pluginDir, "clients.config");
|
||||||
@ -84,7 +85,7 @@ public class PluginStarter implements Runnable {
|
|||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
DataHelper.loadProps(props, clientConfig);
|
DataHelper.loadProps(props, clientConfig);
|
||||||
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
|
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
|
||||||
runClientApps(ctx, pluginDir, clients, true);
|
runClientApps(ctx, pluginDir, clients, "start");
|
||||||
}
|
}
|
||||||
|
|
||||||
// start console webapps in console/webapps
|
// start console webapps in console/webapps
|
||||||
@ -98,6 +99,7 @@ public class PluginStarter implements Runnable {
|
|||||||
for (int i = 0; i < fileNames.length; i++) {
|
for (int i = 0; i < fileNames.length; i++) {
|
||||||
try {
|
try {
|
||||||
String warName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
|
String warName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
|
||||||
|
//log.error("Found webapp: " + warName);
|
||||||
// check for duplicates in $I2P
|
// check for duplicates in $I2P
|
||||||
// easy way for now...
|
// easy way for now...
|
||||||
if (warName.equals("i2psnark") || warName.equals("susidns") || warName.equals("i2ptunnel") ||
|
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);
|
String enabled = props.getProperty(PREFIX + warName + ENABLED);
|
||||||
if (! "false".equals(enabled)) {
|
if (! "false".equals(enabled)) {
|
||||||
|
//log.error("Starting webapp: " + warName);
|
||||||
String path = new File(webappDir, fileNames[i]).getCanonicalPath();
|
String path = new File(webappDir, fileNames[i]).getCanonicalPath();
|
||||||
WebAppStarter.startWebApp(ctx, server, warName, path);
|
WebAppStarter.startWebApp(ctx, server, warName, path);
|
||||||
}
|
}
|
||||||
@ -157,7 +160,7 @@ public class PluginStarter implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return true on success */
|
/** @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);
|
Log log = ctx.logManager().getLog(PluginStarter.class);
|
||||||
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
|
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
|
||||||
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
|
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
|
||||||
@ -171,7 +174,7 @@ public class PluginStarter implements Runnable {
|
|||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
DataHelper.loadProps(props, clientConfig);
|
DataHelper.loadProps(props, clientConfig);
|
||||||
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
|
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
|
||||||
runClientApps(ctx, pluginDir, clients, false);
|
runClientApps(ctx, pluginDir, clients, "stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop console webapps in console/webapps
|
// stop console webapps in console/webapps
|
||||||
@ -201,17 +204,26 @@ public class PluginStarter implements Runnable {
|
|||||||
if (name != null && name.length() > 0)
|
if (name != null && name.length() > 0)
|
||||||
NavHelper.unregisterApp(name);
|
NavHelper.unregisterApp(name);
|
||||||
|
|
||||||
|
log.error("Stopping plugin: " + appName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true on success - call stopPlugin() first */
|
/** @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);
|
Log log = ctx.logManager().getLog(PluginStarter.class);
|
||||||
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
|
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
|
||||||
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
|
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
|
||||||
log.error("Cannot stop nonexistent plugin: " + appName);
|
log.error("Cannot stop nonexistent plugin: " + appName);
|
||||||
return false;
|
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);
|
FileUtil.rmdir(pluginDir, false);
|
||||||
Properties props = pluginProperties();
|
Properties props = pluginProperties();
|
||||||
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
|
||||||
@ -313,20 +325,28 @@ public class PluginStarter implements Runnable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param start true=start, false=stop */
|
/** @param action "start" or "stop" or "uninstall" */
|
||||||
private static void runClientApps(RouterContext ctx, File pluginDir, List<ClientAppConfig> apps, boolean start) {
|
private static void runClientApps(RouterContext ctx, File pluginDir, List<ClientAppConfig> apps, String action) {
|
||||||
Log log = ctx.logManager().getLog(PluginStarter.class);
|
Log log = ctx.logManager().getLog(PluginStarter.class);
|
||||||
for(ClientAppConfig app : apps) {
|
for(ClientAppConfig app : apps) {
|
||||||
if (start && app.disabled)
|
if (action.equals("start") && app.disabled)
|
||||||
continue;
|
continue;
|
||||||
String argVal[];
|
String argVal[];
|
||||||
if (start) {
|
if (action.equals("start")) {
|
||||||
|
// start
|
||||||
argVal = LoadClientAppsJob.parseArgs(app.args);
|
argVal = LoadClientAppsJob.parseArgs(app.args);
|
||||||
} else {
|
} else {
|
||||||
// stopargs must be present
|
String args;
|
||||||
if (app.stopargs == null || app.stopargs.length() <= 0)
|
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;
|
continue;
|
||||||
argVal = LoadClientAppsJob.parseArgs(app.stopargs);
|
argVal = LoadClientAppsJob.parseArgs(args);
|
||||||
}
|
}
|
||||||
// do this after parsing so we don't need to worry about quoting
|
// do this after parsing so we don't need to worry about quoting
|
||||||
for (int i = 0; i < argVal.length; i++) {
|
for (int i = 0; i < argVal.length; i++) {
|
||||||
@ -345,7 +365,7 @@ public class PluginStarter implements Runnable {
|
|||||||
}
|
}
|
||||||
addToClasspath(cp, app.clientName, log);
|
addToClasspath(cp, app.clientName, log);
|
||||||
}
|
}
|
||||||
if (app.delay == 0 || !start) {
|
if (app.delay == 0 || !action.equals("start")) {
|
||||||
// run this guy now
|
// run this guy now
|
||||||
LoadClientAppsJob.runClient(app.className, app.clientName, argVal, log);
|
LoadClientAppsJob.runClient(app.className, app.clientName, argVal, log);
|
||||||
} else {
|
} else {
|
||||||
|
@ -308,7 +308,7 @@ public class PluginUpdateHandler extends UpdateHandler {
|
|||||||
if (!PluginStarter.stopPlugin(_context, appName)) {
|
if (!PluginStarter.stopPlugin(_context, appName)) {
|
||||||
// failed, ignore
|
// failed, ignore
|
||||||
}
|
}
|
||||||
} catch (Exception e) {} // ignore
|
} catch (IOException e) {} // ignore
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (Boolean.valueOf(props.getProperty("update-only")).booleanValue()) {
|
if (Boolean.valueOf(props.getProperty("update-only")).booleanValue()) {
|
||||||
|
@ -53,8 +53,10 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
|
|||||||
|
|
||||||
I2PAppContext i2pContext = I2PAppContext.getGlobalContext();
|
I2PAppContext i2pContext = I2PAppContext.getGlobalContext();
|
||||||
File libDir = new File(i2pContext.getBaseDir(), "lib");
|
File libDir = new File(i2pContext.getBaseDir(), "lib");
|
||||||
File pluginLibDir = new File(i2pContext.getAppDir(),
|
// FIXME this only works if war is the same name as the plugin
|
||||||
PluginUpdateHandler.PLUGIN_DIR + ctxPath + '/' + "lib");
|
File pluginDir = new File(i2pContext.getAppDir(),
|
||||||
|
PluginUpdateHandler.PLUGIN_DIR + ctxPath);
|
||||||
|
|
||||||
File dir = libDir;
|
File dir = libDir;
|
||||||
String cp;
|
String cp;
|
||||||
if (ctxPath.equals("/susidns")) {
|
if (ctxPath.equals("/susidns")) {
|
||||||
@ -63,10 +65,11 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
|
|||||||
} else if (ctxPath.equals("/i2psnark")) {
|
} else if (ctxPath.equals("/i2psnark")) {
|
||||||
// duplicate classes removed from the .war in 0.7.12
|
// duplicate classes removed from the .war in 0.7.12
|
||||||
cp = "i2psnark.jar";
|
cp = "i2psnark.jar";
|
||||||
} else if (pluginLibDir.exists()) {
|
} else if (pluginDir.exists()) {
|
||||||
Properties props = RouterConsoleRunner.webAppProperties(pluginLibDir.getAbsolutePath());
|
File consoleDir = new File(pluginDir, "console");
|
||||||
|
Properties props = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
|
||||||
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
|
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
|
||||||
dir = pluginLibDir;
|
dir = pluginDir;
|
||||||
} else {
|
} else {
|
||||||
Properties props = RouterConsoleRunner.webAppProperties();
|
Properties props = RouterConsoleRunner.webAppProperties();
|
||||||
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
|
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
|
||||||
@ -79,6 +82,8 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
|
|||||||
String path;
|
String path;
|
||||||
if (elem.startsWith("$I2P"))
|
if (elem.startsWith("$I2P"))
|
||||||
path = i2pContext.getBaseDir().getAbsolutePath() + '/' + elem.substring(4);
|
path = i2pContext.getBaseDir().getAbsolutePath() + '/' + elem.substring(4);
|
||||||
|
else if (elem.startsWith("$PLUGIN"))
|
||||||
|
path = dir.getAbsolutePath() + '/' + elem.substring(7);
|
||||||
else
|
else
|
||||||
path = dir.getAbsolutePath() + '/' + elem;
|
path = dir.getAbsolutePath() + '/' + elem;
|
||||||
System.err.println("Adding " + path + " to classpath for " + appName);
|
System.err.println("Adding " + path + " to classpath for " + appName);
|
||||||
|
@ -37,6 +37,8 @@ public class ClientAppConfig {
|
|||||||
public String classpath;
|
public String classpath;
|
||||||
/** @since 0.7.12 */
|
/** @since 0.7.12 */
|
||||||
public String stopargs;
|
public String stopargs;
|
||||||
|
/** @since 0.7.12 */
|
||||||
|
public String uninstallargs;
|
||||||
|
|
||||||
public ClientAppConfig(String cl, String client, String a, long d, boolean dis) {
|
public ClientAppConfig(String cl, String client, String a, long d, boolean dis) {
|
||||||
className = cl;
|
className = cl;
|
||||||
@ -47,10 +49,11 @@ public class ClientAppConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @since 0.7.12 */
|
/** @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);
|
this(cl, client, a, d, dis);
|
||||||
classpath = cp;
|
classpath = cp;
|
||||||
stopargs = sa;
|
stopargs = sa;
|
||||||
|
uninstallargs = ua;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File configFile(I2PAppContext ctx) {
|
public static File configFile(I2PAppContext ctx) {
|
||||||
@ -118,6 +121,7 @@ public class ClientAppConfig {
|
|||||||
String disabled = clientApps.getProperty(PREFIX + i + ".startOnLoad");
|
String disabled = clientApps.getProperty(PREFIX + i + ".startOnLoad");
|
||||||
String classpath = clientApps.getProperty(PREFIX + i + ".classpath");
|
String classpath = clientApps.getProperty(PREFIX + i + ".classpath");
|
||||||
String stopargs = clientApps.getProperty(PREFIX + i + ".stopargs");
|
String stopargs = clientApps.getProperty(PREFIX + i + ".stopargs");
|
||||||
|
String uninstallargs = clientApps.getProperty(PREFIX + i + ".uninstallargs");
|
||||||
i++;
|
i++;
|
||||||
boolean dis = disabled != null && "false".equals(disabled);
|
boolean dis = disabled != null && "false".equals(disabled);
|
||||||
|
|
||||||
@ -129,7 +133,8 @@ public class ClientAppConfig {
|
|||||||
if (delayStr != null && !onStartup)
|
if (delayStr != null && !onStartup)
|
||||||
try { delay = 1000*Integer.parseInt(delayStr); } catch (NumberFormatException nfe) {}
|
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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user