Move ServiceMix Kernel trunk into Felix
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@768912 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/gshell/gshell-admin/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/admin/etc/org.apache.servicemix.features.cfg b/karaf/gshell/gshell-admin/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/admin/etc/org.apache.servicemix.features.cfg
new file mode 100644
index 0000000..2e22aec
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/admin/etc/org.apache.servicemix.features.cfg
@@ -0,0 +1,28 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+#
+# Comma separated list of features repositories to register by default
+#
+featuresRepositories=mvn:org.apache.servicemix.kernel/apache-servicemix-kernel/${version}/xml/features
+
+#
+# Comma separated list of features to install at startup
+#
+featuresBoot=
diff --git a/karaf/gshell/gshell-admin/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/admin/etc/startup.properties b/karaf/gshell/gshell-admin/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/admin/etc/startup.properties
new file mode 100644
index 0000000..f9689b1
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/admin/etc/startup.properties
@@ -0,0 +1,76 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# This file allows you to control the start level of each bundle.
+#
+
+#
+# Startup core services like logging
+#
+org/ops4j/pax/url/pax-url-mvn/${pax.url.version}/pax-url-mvn-${pax.url.version}.jar=5
+org/ops4j/pax/url/pax-url-wrap/${pax.url.version}/pax-url-wrap-${pax.url.version}.jar=5
+org/apache/geronimo/specs/geronimo-servlet_2.5_spec/${geronimo.servlet.version}/geronimo-servlet_2.5_spec-${geronimo.servlet.version}.jar=10
+org/apache/servicemix/specs/org.apache.servicemix.specs.jaxp-api-1.4/${servicemix.specs.version}/org.apache.servicemix.specs.jaxp-api-1.4-${servicemix.specs.version}.jar=10
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.jaxp-ri/${jaxp.ri.version}/org.apache.servicemix.bundles.jaxp-ri-${jaxp.ri.version}.jar=10
+org/apache/felix/org.osgi.compendium/${felix.compendium.version}/org.osgi.compendium-${felix.compendium.version}.jar=10
+org/apache/felix/org.apache.felix.configadmin/${felix.configadmin.version}/org.apache.felix.configadmin-${felix.configadmin.version}.jar=10
+org/apache/geronimo/specs/geronimo-annotation_1.0_spec/${geronimo.annotation.version}/geronimo-annotation_1.0_spec-${geronimo.annotation.version}.jar=10
+org/apache/felix/org.apache.felix.prefs/${felix.prefs.version}/org.apache.felix.prefs-${felix.prefs.version}.jar=10
+org/apache/servicemix/kernel/org.apache.servicemix.kernel.filemonitor/${pom.version}/org.apache.servicemix.kernel.filemonitor-${pom.version}.jar=15
+org/ops4j/pax/logging/pax-logging-api/${pax.logging.version}/pax-logging-api-${pax.logging.version}.jar=20
+org/ops4j/pax/logging/pax-logging-service/${pax.logging.version}/pax-logging-service-${pax.logging.version}.jar=20
+
+#
+# The rest of the services..
+#
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.jline/${jline.version}/org.apache.servicemix.bundles.jline-${jline.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.aopalliance/${aopalliance.version}/org.apache.servicemix.bundles.aopalliance-${aopalliance.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.cglib/${cglib.version}/org.apache.servicemix.bundles.cglib-${cglib.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.mina/${mina.version}/org.apache.servicemix.bundles.mina-${mina.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.oro/${oro.version}/org.apache.servicemix.bundles.oro-${oro.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-codec/${commons.codec.version}/org.apache.servicemix.bundles.commons-codec-${commons.codec.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-httpclient/${commons.httpclient.version}/org.apache.servicemix.bundles.commons-httpclient-${commons.httpclient.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-jexl/${commons.jexl.version}/org.apache.servicemix.bundles.commons-jexl-${commons.jexl.version}.jar=30
+org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-vfs/${commons.vfs.version}/org.apache.servicemix.bundles.commons-vfs-${commons.vfs.version}.jar=30
+org/springframework/spring-aop/${spring.version}/spring-aop-${spring.version}.jar=30
+org/springframework/spring-beans/${spring.version}/spring-beans-${spring.version}.jar=30
+org/springframework/spring-context/${spring.version}/spring-context-${spring.version}.jar=30
+org/springframework/spring-core/${spring.version}/spring-core-${spring.version}.jar=30
+org/springframework/osgi/spring-osgi-core/${spring.osgi.version}/spring-osgi-core-${spring.osgi.version}.jar=30
+org/springframework/osgi/spring-osgi-extender/${spring.osgi.version}/spring-osgi-extender-${spring.osgi.version}.jar=30
+org/springframework/osgi/spring-osgi-io/${spring.osgi.version}/spring-osgi-io-${spring.osgi.version}.jar=30
+org/apache/servicemix/kernel/org.apache.servicemix.kernel.spring/${pom.version}/org.apache.servicemix.kernel.spring-${pom.version}.jar=30
+org/apache/servicemix/kernel/org.apache.servicemix.kernel.management/${pom.version}/org.apache.servicemix.kernel.management-${pom.version}.jar=30
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.admin/${pom.version}/org.apache.servicemix.kernel.gshell.admin-${pom.version}.jar=30
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.osgi/${pom.version}/org.apache.servicemix.kernel.gshell.osgi-${pom.version}.jar=30
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.features/${pom.version}/org.apache.servicemix.kernel.gshell.features-${pom.version}.jar=30
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.log/${pom.version}/org.apache.servicemix.kernel.gshell.log-${pom.version}.jar=30
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.config/${pom.version}/org.apache.servicemix.kernel.gshell.config-${pom.version}.jar=30
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.packages/${pom.version}/org.apache.servicemix.kernel.gshell.packages-${pom.version}.jar=30
+org/apache/servicemix/kernel/jaas/org.apache.servicemix.kernel.jaas.config/${pom.version}/org.apache.servicemix.kernel.jaas.config-${pom.version}.jar=30
+org/apache/servicemix/kernel/jaas/org.apache.servicemix.kernel.jaas.modules/${pom.version}/org.apache.servicemix.kernel.jaas.modules-${pom.version}.jar=30
+com/google/code/sshd/sshd/${sshd.version}/sshd-${sshd.version}.jar=30
+org/osgi/jmx/${osgi.jmx.version}/jmx-${osgi.jmx.version}.jar=30
+com/oracle/osgi/jmx-impl/${osgi.jmx.version}/jmx-impl-${osgi.jmx.version}.jar=30
+
+#
+# Start console last
+#
+org/apache/servicemix/kernel/gshell/org.apache.servicemix.kernel.gshell.core/${pom.version}/org.apache.servicemix.kernel.gshell.core-${pom.version}.jar=40
+
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/Process.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/Process.java
new file mode 100644
index 0000000..eedb31d
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/Process.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * Interface representing a process
+ */
+public interface Process extends Serializable {
+
+ /**
+ * Retrieves the PID of the process
+ * @return the pid
+ */
+ int getPid();
+
+ /**
+ * Check if this process is still running
+ * @return <code>true</code> if the process is running
+ * @throws IOException if an error occurs
+ */
+ boolean isRunning() throws IOException;
+
+ /**
+ * Destroy the process.
+ *
+ * @throws IOException
+ */
+ void destroy() throws IOException;
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/ProcessBuilder.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/ProcessBuilder.java
new file mode 100644
index 0000000..6862222
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/ProcessBuilder.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Interface used to create new processes.
+ */
+public interface ProcessBuilder {
+
+ /**
+ * Specified the current directory to run the command from
+ *
+ * @param dir the directory to run the command from
+ * @return the ProcessBuilder instance
+ */
+ ProcessBuilder directory(File dir);
+
+ /**
+ * Set the command to execute
+ *
+ * @param command the command to execute
+ * @return the ProcessBuilder instance
+ */
+ ProcessBuilder command(String command);
+
+ /**
+ * Create and start the process
+ *
+ * @return the process that has been started
+ * @throws IOException if the process can not be created
+ */
+ Process start() throws IOException;
+
+ /**
+ * Attach to an existing process
+ *
+ * @return the process that has been attached
+ * @throws IOException if the process can not be attached to
+ */
+ Process attach(int pid) throws IOException;
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/ProcessBuilderFactory.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/ProcessBuilderFactory.java
new file mode 100644
index 0000000..433b615
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/ProcessBuilderFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm;
+
+/**
+ * Factory for process builders.
+ */
+public abstract class ProcessBuilderFactory {
+
+ public static ProcessBuilderFactory newInstance() {
+ return new org.apache.servicemix.jpm.impl.ProcessBuilderFactoryImpl();
+ }
+
+ public abstract ProcessBuilder newBuilder();
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessBuilderFactoryImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessBuilderFactoryImpl.java
new file mode 100644
index 0000000..4db4657
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessBuilderFactoryImpl.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm.impl;
+
+import org.apache.servicemix.jpm.ProcessBuilder;
+import org.apache.servicemix.jpm.ProcessBuilderFactory;
+
+public class ProcessBuilderFactoryImpl extends ProcessBuilderFactory {
+
+ public ProcessBuilder newBuilder() {
+ return new ProcessBuilderImpl();
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessBuilderImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessBuilderImpl.java
new file mode 100644
index 0000000..649da6b
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessBuilderImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm.impl;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.servicemix.jpm.Process;
+import org.apache.servicemix.jpm.ProcessBuilder;
+
+
+public class ProcessBuilderImpl implements ProcessBuilder {
+
+ private File dir;
+ private String command;
+
+ public ProcessBuilder directory(File dir) {
+ this.dir = dir;
+ return this;
+ }
+
+ public ProcessBuilder command(String command) {
+ this.command = command;
+ return this;
+ }
+
+ public Process start() throws IOException {
+ return ProcessImpl.create(dir, command);
+ }
+
+ public Process attach(int pid) throws IOException {
+ return ProcessImpl.attach(pid);
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessImpl.java
new file mode 100644
index 0000000..71146fa
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ProcessImpl.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm.impl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.InterruptedIOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicemix.jpm.Process;
+
+public class ProcessImpl implements Process {
+
+ private int pid;
+ //private File input;
+ //private File output;
+ //private File error;
+
+ public ProcessImpl(int pid/*, File input, File output, File error*/) {
+ this.pid = pid;
+ //this.input = input;
+ //this.output = output;
+ //this.error = error;
+ }
+
+ public int getPid() {
+ return pid;
+ }
+
+ public boolean isRunning() throws IOException {
+ if (ScriptUtils.isWindows()) {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("${pid}", Integer.toString(pid));
+ int ret = ScriptUtils.execute("running", props);
+ return ret == 0;
+ } else {
+ try {
+ java.lang.Process process = new java.lang.ProcessBuilder("ps", "-p", Integer.toString(pid)).start();
+ BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ r.readLine(); // skip headers
+ String s = r.readLine();
+ boolean running = s != null && s.length() > 0;
+ int ret = process.waitFor();
+ return running;
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
+ }
+ }
+
+ public void destroy() throws IOException {
+ int ret;
+ if (ScriptUtils.isWindows()) {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("${pid}", Integer.toString(pid));
+ ret = ScriptUtils.execute("destroy", props);
+ } else {
+ ret = ScriptUtils.executeProcess(new java.lang.ProcessBuilder("kill", "-9", Integer.toString(pid)));
+ }
+ if (ret != 0) {
+ throw new IOException("Unable to destroy proces, it may be already terminated");
+ }
+ }
+
+ /*
+ public OutputStream getInputStream() throws FileNotFoundException {
+ return new FileOutputStream(input);
+ }
+
+ public InputStream getOutputStream() throws FileNotFoundException {
+ return new FileInputStream(output);
+ }
+
+ public InputStream getErrorStream() throws FileNotFoundException {
+ return new FileInputStream(error);
+ }
+ */
+
+ public int waitFor() throws InterruptedException {
+ return 0;
+ }
+
+ public int exitValue() {
+ return 0;
+ }
+
+ public static Process create(File dir, String command) throws IOException {
+ //File input = File.createTempFile("jpm.", ".input");
+ //File output = File.createTempFile("jpm.", ".output");
+ //File error = File.createTempFile("jpm.", ".error");
+ File pidFile = File.createTempFile("jpm.", ".pid");
+ try {
+ Map<String, String> props = new HashMap<String, String>();
+ //props.put("${in.file}", input.getCanonicalPath());
+ //props.put("${out.file}", output.getCanonicalPath());
+ //props.put("${err.file}", error.getCanonicalPath());
+ props.put("${pid.file}", pidFile.getCanonicalPath());
+ props.put("${dir}", dir != null ? dir.getCanonicalPath() : "");
+ if (ScriptUtils.isWindows()) {
+ command = command.replaceAll("\"", "\"\"");
+ }
+ props.put("${command}", command);
+ int ret = ScriptUtils.execute("start", props);
+ if (ret != 0) {
+ throw new IOException("Unable to create process (error code: " + ret + ")");
+ }
+ int pid = readPid(pidFile);
+ return new ProcessImpl(pid/*, input, output, error*/);
+ } finally {
+ pidFile.delete();
+ }
+ }
+
+ public static Process attach(int pid) throws IOException {
+ return new ProcessImpl(pid);
+ }
+
+ private static int readPid(File pidFile) throws IOException {
+ InputStream is = new FileInputStream(pidFile);
+ try {
+ BufferedReader r = new BufferedReader(new InputStreamReader(is));
+ String pidString = r.readLine();
+ return Integer.valueOf(pidString);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {}
+ }
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ScriptUtils.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ScriptUtils.java
new file mode 100644
index 0000000..869c958
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/jpm/impl/ScriptUtils.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.jpm.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.Scanner;
+
+public class ScriptUtils {
+
+ public static int execute(String name, Map<String, String> props) throws IOException {
+ File script = File.createTempFile("jpm.", ".script");
+ try {
+ if (isWindows()) {
+ String res = "windows/" + name + ".vbs";
+ ScriptUtils.copyFilteredResource(res, script, props);
+ return executeProcess(new java.lang.ProcessBuilder("cscript",
+ "/NOLOGO",
+ "//E:vbs",
+ script.getCanonicalPath()));
+ } else {
+ String res = "unix/" + name + ".sh";
+ ScriptUtils.copyFilteredResource(res, script, props);
+ return executeProcess(new java.lang.ProcessBuilder("/bin/sh",
+ script.getCanonicalPath()));
+ }
+ } finally {
+ script.delete();
+ }
+ }
+
+ public static int executeProcess(java.lang.ProcessBuilder builder) throws IOException {
+ try {
+ java.lang.Process process = builder.start();
+ return process.waitFor();
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
+ }
+
+ public static void copyFilteredResource(String resource, File outFile, Map<String, String> props) throws IOException {
+ InputStream is = null;
+ try {
+ is = ScriptUtils.class.getResourceAsStream(resource);
+ // Read it line at a time so that we can use the platform line ending when we write it out.
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine() ) {
+ String line = scanner.nextLine();
+ line = filter(line, props);
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } finally {
+ safeClose(is);
+ }
+ }
+
+ private static void safeClose(InputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private static void safeClose(OutputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private static String filter(String line, Map<String, String> props) {
+ for (Map.Entry<String, String> i : props.entrySet()) {
+ int p1 = line.indexOf(i.getKey());
+ if( p1 >= 0 ) {
+ String l1 = line.substring(0, p1);
+ String l2 = line.substring(p1+i.getKey().length());
+ line = l1+i.getValue()+l2;
+ }
+ }
+ return line;
+ }
+
+ private static final boolean windows;
+
+ static {
+ windows = System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
+ }
+
+ public static boolean isWindows() {
+ return windows;
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/AdminService.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/AdminService.java
new file mode 100644
index 0000000..cbf7181
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/AdminService.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin;
+
+public interface AdminService {
+
+ Instance createInstance(String name, int port, String location) throws Exception;
+
+ Instance[] getInstances();
+
+ Instance getInstance(String name);
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/AdminServiceMBean.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/AdminServiceMBean.java
new file mode 100644
index 0000000..8a68d2d
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/AdminServiceMBean.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin;
+
+public interface AdminServiceMBean {
+
+ void createInstance(String name, int port, String location) throws Exception;
+
+ String[] getInstances();
+
+ int getPort(String name) throws Exception;
+
+ void changePort(String name, int port) throws Exception;
+
+ String getState(String name) throws Exception;
+
+ void start(String name, String javaOpts) throws Exception;
+
+ void stop(String name) throws Exception;
+
+ void destroy(String name) throws Exception;
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/Instance.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/Instance.java
new file mode 100644
index 0000000..07612aa
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/Instance.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin;
+
+public interface Instance {
+
+ String STOPPED = "Stopped";
+ String STARTING = "Starting";
+ String STARTED = "Started";
+
+ String getName();
+
+ String getLocation();
+
+ int getPid();
+
+ int getPort() throws Exception;
+
+ void changePort(int port) throws Exception;
+
+ void start(String javaOpts) throws Exception;
+
+ void stop() throws Exception;
+
+ void destroy() throws Exception;
+
+ String getState() throws Exception;
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/AdminServiceImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/AdminServiceImpl.java
new file mode 100644
index 0000000..54283a8
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/AdminServiceImpl.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.ServerSocket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gshell.shell.ShellContext;
+import org.apache.geronimo.gshell.shell.ShellContextHolder;
+import org.apache.servicemix.kernel.gshell.admin.AdminService;
+import org.apache.servicemix.kernel.gshell.admin.Instance;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+import org.osgi.service.prefs.PreferencesService;
+import org.springframework.beans.factory.InitializingBean;
+
+public class AdminServiceImpl implements AdminService, InitializingBean {
+
+ private static final Log LOGGER = LogFactory.getLog(AdminServiceImpl.class);
+
+ private PreferencesService preferences;
+
+ private Map<String, Instance> instances = new HashMap<String, Instance>();
+
+ private int defaultPortStart = 8101;
+
+ public PreferencesService getPreferences() {
+ return preferences;
+ }
+
+ public void setPreferences(PreferencesService preferences) {
+ this.preferences = preferences;
+ }
+
+ public synchronized void afterPropertiesSet() throws Exception {
+ try {
+ Preferences prefs = preferences.getUserPreferences("AdminServiceState");
+ Preferences child = prefs.node("Instances");
+ int count = child.getInt("count", 0);
+ Map<String, Instance> newInstances = new HashMap<String, Instance>();
+ for (int i = 0; i < count; i++) {
+ String name = child.get("item." + i + ".name", null);
+ String loc = child.get("item." + i + ".loc", null);
+ int pid = child.getInt("item." + i + ".pid", 0);
+ if (name != null) {
+ InstanceImpl instance = new InstanceImpl(this, name, loc);
+ if (pid > 0) {
+ try {
+ instance.attach(pid);
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ newInstances.put(name, instance);
+ }
+ }
+ instances = newInstances;
+ } catch (Exception e) {
+ LOGGER.warn("Unable to reload ServiceMix instance list", e);
+ }
+ }
+
+ public synchronized Instance createInstance(String name, int port, String location) throws Exception {
+ if (instances.get(name) != null) {
+ throw new IllegalArgumentException("Instance '" + name + "' already exists");
+ }
+ File serviceMixBase = new File(location != null ? location : ("instances/" + name)).getCanonicalFile();
+ int sshPort = port;
+ if (sshPort <= 0) {
+ try {
+ Preferences prefs = preferences.getUserPreferences("AdminServiceState");
+ sshPort = prefs.getInt("port", defaultPortStart + 1);
+ prefs.putInt("port", sshPort + 1);
+ prefs.flush();
+ prefs.sync();
+ } catch (Exception e) {
+ try {
+ ServerSocket ss = new ServerSocket(0);
+ sshPort = ss.getLocalPort();
+ ss.close();
+ } catch (Exception t) {
+ }
+ }
+ if (sshPort <= 0) {
+ sshPort = defaultPortStart;
+ }
+ }
+ println("Creating new instance on port " + sshPort + " at: @|bold " + serviceMixBase + "|");
+
+ mkdir(serviceMixBase, "bin");
+ mkdir(serviceMixBase, "etc");
+ mkdir(serviceMixBase, "system");
+ mkdir(serviceMixBase, "deploy");
+ mkdir(serviceMixBase, "data");
+
+ copyResourceToDir(serviceMixBase, "etc/config.properties", true);
+ copyResourceToDir(serviceMixBase, "etc/org.apache.servicemix.features.cfg", true);
+ copyResourceToDir(serviceMixBase, "etc/users.properties", true);
+ copyResourceToDir(serviceMixBase, "etc/org.ops4j.pax.logging.cfg", true);
+ copyResourceToDir(serviceMixBase, "etc/org.ops4j.pax.url.mvn.cfg", true);
+ copyResourceToDir(serviceMixBase, "etc/startup.properties", true);
+
+ HashMap<String, String> props = new HashMap<String, String>();
+ props.put("${servicemix.name}", name);
+ props.put("${servicemix.home}", System.getProperty("servicemix.home"));
+ props.put("${servicemix.base}", serviceMixBase.getPath());
+ props.put("${servicemix.sshPort}", Integer.toString(sshPort));
+ copyFilteredResourceToDir(serviceMixBase, "etc/system.properties", props);
+ copyFilteredResourceToDir(serviceMixBase, "etc/org.apache.servicemix.shell.cfg", props);
+ if( System.getProperty("os.name").startsWith("Win") ) {
+ copyFilteredResourceToDir(serviceMixBase, "bin/servicemix.bat", props);
+ } else {
+ copyFilteredResourceToDir(serviceMixBase, "bin/servicemix", props);
+ chmod(new File(serviceMixBase, "bin/servicemix"), "a+x");
+ }
+ Instance instance = new InstanceImpl(this, name, serviceMixBase.toString());
+ instances.put(name, instance);
+ saveState();
+ return instance;
+ }
+
+ public synchronized Instance[] getInstances() {
+ return instances.values().toArray(new Instance[0]);
+ }
+
+ public synchronized Instance getInstance(String name) {
+ return instances.get(name);
+ }
+
+ synchronized void forget(String name) {
+ instances.remove(name);
+ }
+
+ synchronized void saveState() throws IOException, BackingStoreException {
+ Preferences prefs = preferences.getUserPreferences("AdminServiceState");
+ Preferences child = prefs.node("Instances");
+ child.clear();
+ Instance[] data = getInstances();
+ child.putInt("count", data.length);
+ for (int i = 0; i < data.length; i++) {
+ child.put("item." + i + ".name", data[i].getName());
+ child.put("item." + i + ".loc", data[i].getLocation());
+ child.putInt("item." + i + ".pid", data[i].getPid());
+ }
+ prefs.flush();
+ prefs.sync();
+ }
+
+ private void copyResourceToDir(File target, String resource, boolean text) throws Exception {
+ File outFile = new File(target, resource);
+ if( !outFile.exists() ) {
+ println("Creating file: @|bold " + outFile.getPath() + "|");
+ InputStream is = getClass().getClassLoader().getResourceAsStream("/org/apache/servicemix/kernel/gshell/admin/" + resource);
+ try {
+ if( text ) {
+ // Read it line at a time so that we can use the platform line ending when we write it out.
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine() ) {
+ String line = scanner.nextLine();
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } else {
+ // Binary so just write it out the way it came in.
+ FileOutputStream out = new FileOutputStream(new File(target, resource));
+ try {
+ int c=0;
+ while((c=is.read())>=0) {
+ out.write(c);
+ }
+ } finally {
+ safeClose(out);
+ }
+ }
+ } finally {
+ safeClose(is);
+ }
+ }
+ }
+
+ private void println(String st) {
+ ShellContext ctx = ShellContextHolder.get(true);
+ if (ctx != null) {
+ ctx.getIo().out.println(st);
+ } else {
+ System.out.println(st);
+ }
+ }
+
+ private void copyFilteredResourceToDir(File target, String resource, HashMap<String, String> props) throws Exception {
+ File outFile = new File(target, resource);
+ if( !outFile.exists() ) {
+ println("Creating file: @|bold "+outFile.getPath()+"|");
+ InputStream is = getClass().getClassLoader().getResourceAsStream("/org/apache/servicemix/kernel/gshell/admin/" + resource);
+ try {
+ // Read it line at a time so that we can use the platform line ending when we write it out.
+ PrintStream out = new PrintStream(new FileOutputStream(outFile));
+ try {
+ Scanner scanner = new Scanner(is);
+ while (scanner.hasNextLine() ) {
+ String line = scanner.nextLine();
+ line = filter(line, props);
+ out.println(line);
+ }
+ } finally {
+ safeClose(out);
+ }
+ } finally {
+ safeClose(is);
+ }
+ }
+ }
+
+ private void safeClose(InputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private void safeClose(OutputStream is) throws IOException {
+ if (is == null) {
+ return;
+ }
+ try {
+ is.close();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ private String filter(String line, HashMap<String, String> props) {
+ for (Map.Entry<String, String> i : props.entrySet()) {
+ int p1 = line.indexOf(i.getKey());
+ if( p1 >= 0 ) {
+ String l1 = line.substring(0, p1);
+ String l2 = line.substring(p1+i.getKey().length());
+ line = l1+i.getValue()+l2;
+ }
+ }
+ return line;
+ }
+
+ private void mkdir(File serviceMixBase, String path) {
+ File file = new File(serviceMixBase, path);
+ if( !file.exists() ) {
+ println("Creating dir: @|bold "+file.getPath()+"|");
+ file.mkdirs();
+ }
+ }
+
+ private int chmod(File serviceFile, String mode) throws Exception {
+ ProcessBuilder builder = new ProcessBuilder();
+ builder.command("chmod", mode, serviceFile.getCanonicalPath());
+ Process p = builder.start();
+
+ // gnodet: Fix SMX4KNL-46: cpu goes to 100% after running the 'admin create' command
+ // Not sure exactly what happens, but commenting the process io redirection seems
+ // to work around the problem.
+ //
+ //PumpStreamHandler handler = new PumpStreamHandler(io.inputStream, io.outputStream, io.errorStream);
+ //handler.attach(p);
+ //handler.start();
+ int status = p.waitFor();
+ //handler.stop();
+ return status;
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/AdminServiceMBeanImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/AdminServiceMBeanImpl.java
new file mode 100644
index 0000000..a53b663
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/AdminServiceMBeanImpl.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal;
+
+import org.apache.servicemix.kernel.gshell.admin.AdminService;
+import org.apache.servicemix.kernel.gshell.admin.AdminServiceMBean;
+import org.apache.servicemix.kernel.gshell.admin.Instance;
+
+public class AdminServiceMBeanImpl implements AdminServiceMBean {
+
+ private AdminService adminService;
+
+ public AdminService getAdminService() {
+ return adminService;
+ }
+
+ public void setAdminService(AdminService adminService) {
+ this.adminService = adminService;
+ }
+
+ public void createInstance(String name, int port, String location) throws Exception {
+ adminService.createInstance(name, port, location);
+ }
+
+ public String[] getInstances() {
+ Instance[] instances = adminService.getInstances();
+ String[] names = new String[instances.length];
+ for (int i = 0; i < instances.length; i++) {
+ names[i] = instances[i].getName();
+ }
+ return names;
+ }
+
+ public int getPort(String name) throws Exception {
+ return getExistingInstance(name).getPort();
+ }
+
+ public void changePort(String name, int port) throws Exception {
+ getExistingInstance(name).changePort(port);
+ }
+
+ public String getState(String name) throws Exception {
+ return getExistingInstance(name).getState();
+ }
+
+ public void start(String name, String javaOpts) throws Exception {
+ getExistingInstance(name).start(javaOpts);
+ }
+
+ public void stop(String name) throws Exception {
+ getExistingInstance(name).stop();
+ }
+
+ public void destroy(String name) throws Exception {
+ getExistingInstance(name).destroy();
+ }
+
+
+ private Instance getExistingInstance(String name) {
+ Instance i = adminService.getInstance(name);
+ if (i == null) {
+ throw new IllegalArgumentException("Instance '" + name + "' does not exist");
+ }
+ return i;
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/InstanceImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/InstanceImpl.java
new file mode 100644
index 0000000..3815ca5
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/InstanceImpl.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.jpm.Process;
+import org.apache.servicemix.jpm.ProcessBuilderFactory;
+import org.apache.servicemix.jpm.impl.ScriptUtils;
+import org.apache.servicemix.kernel.gshell.admin.Instance;
+
+public class InstanceImpl implements Instance {
+
+ private static final Log LOG = LogFactory.getLog(InstanceImpl.class);
+
+ private AdminServiceImpl service;
+ private String name;
+ private String location;
+ private Process process;
+
+ public InstanceImpl(AdminServiceImpl service, String name, String location) {
+ this.service = service;
+ this.name = name;
+ this.location = location;
+ }
+
+ public void attach(int pid) throws IOException {
+ checkProcess();
+ if (this.process != null) {
+ throw new IllegalStateException("Instance already started");
+ }
+ this.process = ProcessBuilderFactory.newInstance().newBuilder().attach(pid);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public int getPid() {
+ checkProcess();
+ return this.process != null ? this.process.getPid() : 0;
+ }
+
+ public int getPort() throws Exception {
+ InputStream is = null;
+ try {
+ File f = new File(location, "etc/org.apache.servicemix.shell.cfg");
+ is = new FileInputStream(f);
+ Properties props = new Properties();
+ props.load(is);
+ String loc = props.getProperty("sshPort");
+ return Integer.parseInt(loc);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ public void changePort(int port) throws Exception {
+ checkProcess();
+ if (this.process != null) {
+ throw new IllegalStateException("Instance not stopped");
+ }
+ Properties props = new Properties();
+ File f = new File(location, "etc/org.apache.servicemix.shell.cfg");
+ InputStream is = new FileInputStream(f);
+ try {
+ props.load(is);
+ } finally {
+ is.close();
+ }
+ props.setProperty("sshPort", Integer.toString(port));
+ OutputStream os = new FileOutputStream(f);
+ try {
+ props.store(os, null);
+ } finally {
+ os.close();
+ }
+ }
+
+ public synchronized void start(String javaOpts) throws Exception {
+ checkProcess();
+ if (this.process != null) {
+ throw new IllegalStateException("Instance already started");
+ }
+ if (javaOpts == null) {
+ javaOpts = "-server -Xmx512M -Dcom.sun.management.jmxremote";
+ }
+ File libDir = new File(System.getProperty("servicemix.home"), "lib");
+ File[] jars = libDir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+ StringBuilder classpath = new StringBuilder();
+ for (File jar : jars) {
+ if (classpath.length() > 0) {
+ classpath.append(System.getProperty("path.separator"));
+ }
+ classpath.append(jar.getCanonicalPath());
+ }
+ String command = new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath()
+ + " " + javaOpts
+ + " -Dservicemix.home=\"" + System.getProperty("servicemix.home") + "\""
+ + " -Dservicemix.base=\"" + new File(location).getCanonicalPath() + "\""
+ + " -Dservicemix.startLocalConsole=false"
+ + " -Dservicemix.startRemoteShell=true"
+ + " -classpath " + classpath.toString()
+ + " org.apache.servicemix.kernel.main.Main";
+ LOG.debug("Starting instance with command: " + command);
+ this.process = ProcessBuilderFactory.newInstance().newBuilder()
+ .directory(new File(location))
+ .command(command)
+ .start();
+ this.service.saveState();
+ }
+
+ public synchronized void stop() throws Exception {
+ checkProcess();
+ if (this.process == null) {
+ throw new IllegalStateException("Instance not started");
+ }
+ this.process.destroy();
+ }
+
+ public synchronized void destroy() throws Exception {
+ checkProcess();
+ if (this.process != null) {
+ throw new IllegalStateException("Instance not stopped");
+ }
+ deleteFile(new File(location));
+ this.service.forget(name);
+ this.service.saveState();
+ }
+
+
+ public synchronized String getState() {
+ checkProcess();
+ if (this.process == null) {
+ return STOPPED;
+ } else {
+ try {
+ int port = getPort();
+ Socket s = new Socket("localhost", port);
+ s.close();
+ return STARTED;
+ } catch (Exception e) {
+ // ignore
+ }
+ return STARTING;
+ }
+ }
+
+ protected void checkProcess() {
+ if (this.process != null) {
+ try {
+ if (!this.process.isRunning()) {
+ this.process = null;
+ }
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ protected static boolean deleteFile(File fileToDelete) {
+ if (fileToDelete == null || !fileToDelete.exists()) {
+ return true;
+ }
+ boolean result = true;
+ if (fileToDelete.isDirectory()) {
+ File[] files = fileToDelete.listFiles();
+ if (files == null) {
+ result = false;
+ } else {
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ if (file.getName().equals(".") || file.getName().equals("..")) {
+ continue;
+ }
+ if (file.isDirectory()) {
+ result &= deleteFile(file);
+ } else {
+ result &= file.delete();
+ }
+ }
+ }
+ }
+ result &= fileToDelete.delete();
+ return result;
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/AdminCommandSupport.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/AdminCommandSupport.java
new file mode 100644
index 0000000..9da97b4
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/AdminCommandSupport.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.servicemix.kernel.gshell.admin.AdminService;
+import org.apache.servicemix.kernel.gshell.admin.Instance;
+import org.apache.servicemix.kernel.gshell.core.OsgiCommandSupport;
+
+public abstract class AdminCommandSupport extends OsgiCommandSupport {
+
+ private AdminService adminService;
+
+ public AdminService getAdminService() {
+ return adminService;
+ }
+
+ public void setAdminService(AdminService adminService) {
+ this.adminService = adminService;
+ }
+
+ protected Instance getExistingInstance(String name) {
+ Instance i = adminService.getInstance(name);
+ if (i == null) {
+ throw new IllegalArgumentException("Instance '" + name + "' does not exist");
+ }
+ return i;
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ChangePortCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ChangePortCommand.java
new file mode 100644
index 0000000..adbf2f6
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ChangePortCommand.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Argument;
+
+public class ChangePortCommand extends AdminCommandSupport {
+
+ @Argument(index=0, required=true, description="The instance name")
+ private String instance = null;
+
+ @Argument(index=1, required=true, description="The new port")
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changePort(port);
+ return Result.SUCCESS;
+ }
+}
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ConnectCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ConnectCommand.java
new file mode 100644
index 0000000..244b9f8
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ConnectCommand.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.geronimo.gshell.shell.ShellContextHolder;
+
+public class ConnectCommand extends AdminCommandSupport {
+
+ @Argument(index=0, required=true, description="The instance name")
+ private String instance = null;
+
+ @Option(name="-u", aliases={"--username"}, token="USERNAME", description="Remote user name")
+ private String username = "smx";
+
+ @Option(name="-p", aliases={"--password"}, token="PASSWORD", description="Remote user password")
+ private String password = "smx";
+
+ protected Object doExecute() throws Exception {
+ int port = getExistingInstance(instance).getPort();
+ ShellContextHolder.get().getShell().execute("ssh -l " + username + " -P " + password + " -p " + port + " localhost");
+ return Result.SUCCESS;
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/CreateCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/CreateCommand.java
new file mode 100644
index 0000000..d13c381
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/CreateCommand.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.clp.Option;
+
+/**
+ * Creates a new servicemix instance
+ *
+ * @version $Rev: 679826 $ $Date: 2008-07-25 17:00:12 +0200 (Fri, 25 Jul 2008) $
+ */
+public class CreateCommand extends AdminCommandSupport
+{
+ @Option(name = "-p", aliases = { "--port"}, description = "Port number for remote shell connection")
+ private int port = 0;
+
+ @Option(name = "-l", aliases = { "--location"}, description = "Location of the new instance on the file system")
+ private String location;
+
+ @Argument(index=0, required=true, description="Name of the new ServiceMix instance")
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getAdminService().createInstance(instance, port, location);
+ return Result.SUCCESS;
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/DestroyCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/DestroyCommand.java
new file mode 100644
index 0000000..6084caa
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/DestroyCommand.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Argument;
+
+/**
+ * Creates a new servicemix instance
+ *
+ * @version $Rev: 679826 $ $Date: 2008-07-25 17:00:12 +0200 (Fri, 25 Jul 2008) $
+ */
+public class DestroyCommand extends AdminCommandSupport
+{
+ @Argument(index=0, required=true, description="The name of the ServiceMix instance to destroy")
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).destroy();
+ return Result.SUCCESS;
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ListCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ListCommand.java
new file mode 100644
index 0000000..61f3afb
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/ListCommand.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.servicemix.kernel.gshell.admin.Instance;
+
+/**
+ * List available instances
+ */
+public class ListCommand extends AdminCommandSupport {
+
+ @Option(name = "-l", aliases = { "--location" }, description = "Display instances location")
+ boolean location;
+
+ protected Object doExecute() throws Exception {
+ Instance[] instances = getAdminService().getInstances();
+ if (location) {
+ io.out.println(" Port State Pid Location");
+ } else {
+ io.out.println(" Port State Pid Name");
+ }
+ for (Instance instance : instances) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+ String s = Integer.toString(instance.getPort());
+ for (int i = s.length(); i < 5; i++) {
+ sb.append(' ');
+ }
+ sb.append(s);
+ sb.append("] [");
+ String state = instance.getState();
+ while (state.length() < "starting".length()) {
+ state += " ";
+ }
+ sb.append(state);
+ sb.append("] [");
+ s = Integer.toString(instance.getPid());
+ for (int i = s.length(); i < 5; i++) {
+ sb.append(' ');
+ }
+ sb.append(s);
+ sb.append("] ");
+ if (location) {
+ sb.append(instance.getLocation());
+ } else {
+ sb.append(instance.getName());
+ }
+ io.out.println(sb.toString());
+ }
+ return Result.SUCCESS;
+ }
+
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/StartCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/StartCommand.java
new file mode 100644
index 0000000..77afa91
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/StartCommand.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.clp.Option;
+
+public class StartCommand extends AdminCommandSupport {
+
+ @Option(name = "-o", aliases = { "--java-opts"}, description = "Java options when launching the instance")
+ private String javaOpts;
+
+ @Argument(index=0, required=true, description="The instance name")
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).start(javaOpts);
+ return Result.SUCCESS;
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/StopCommand.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/StopCommand.java
new file mode 100644
index 0000000..c449387
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/commands/StopCommand.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.commands;
+
+import org.apache.geronimo.gshell.clp.Argument;
+
+public class StopCommand extends AdminCommandSupport {
+
+ @Argument(index=0, required=true, description="The instance name")
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).stop();
+ return Result.SUCCESS;
+ }
+}
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/completers/InstanceCompleter.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/completers/InstanceCompleter.java
new file mode 100644
index 0000000..cfcb95a
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/servicemix/kernel/gshell/admin/internal/completers/InstanceCompleter.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.admin.internal.completers;
+
+import java.util.List;
+
+import org.apache.servicemix.kernel.gshell.admin.AdminService;
+import org.apache.servicemix.kernel.gshell.admin.Instance;
+import org.apache.geronimo.gshell.console.completer.StringsCompleter;
+import jline.Completor;
+
+/**
+ * {@link jline.Completor} for server instance names.
+ *
+ * Displays a list of configured server instances for the Admin commands.
+ *
+ */
+public class InstanceCompleter implements Completor {
+ private AdminService adminService;
+
+ public void setAdminService(AdminService adminService) {
+ this.adminService = adminService;
+ }
+
+ public int complete(String buffer, int cursor, List candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ for (Instance instance : adminService.getInstances()) {
+ delegate.getStrings().add(instance.getName());
+ }
+ return delegate.complete(buffer, cursor, candidates);
+ }
+}
diff --git a/karaf/gshell/gshell-admin/src/main/resources/META-INF/spring/gshell-admin.xml b/karaf/gshell/gshell-admin/src/main/resources/META-INF/spring/gshell-admin.xml
new file mode 100644
index 0000000..5f05513
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/META-INF/spring/gshell-admin.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:osgi="http://www.springframework.org/schema/osgi"
+ xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:gshell="http://servicemix.apache.org/schema/servicemix-gshell"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/osgi
+ http://www.springframework.org/schema/osgi/spring-osgi.xsd
+ http://www.springframework.org/schema/osgi-compendium
+ http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd
+ http://servicemix.apache.org/schema/servicemix-gshell
+ http://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd">
+
+ <import resource="classpath:org/apache/servicemix/kernel/gshell/core/commands.xml" />
+
+ <bean id="adminCommandBundleSupport" scope="prototype">
+ <property name="adminService" ref="adminService" />
+ </bean>
+
+ <gshell:command-bundle>
+ <gshell:command name="admin/create">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.CreateCommand"
+ parent="adminCommandBundleSupport" />
+ </gshell:command>
+ <gshell:command name="admin/connect">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.ConnectCommand"
+ parent="adminCommandBundleSupport" />
+ <gshell:completers>
+ <ref bean="instanceCompleter" />
+ <null/>
+ </gshell:completers>
+ </gshell:command>
+ <gshell:command name="admin/list">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.ListCommand"
+ parent="adminCommandBundleSupport" />
+ </gshell:command>
+ <gshell:command name="admin/start">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.StartCommand"
+ parent="adminCommandBundleSupport" />
+ <gshell:completers>
+ <ref bean="instanceCompleter" />
+ <null/>
+ </gshell:completers>
+ </gshell:command>
+ <gshell:command name="admin/stop">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.StopCommand"
+ parent="adminCommandBundleSupport" />
+ <gshell:completers>
+ <ref bean="instanceCompleter" />
+ <null/>
+ </gshell:completers>
+ </gshell:command>
+ <gshell:command name="admin/destroy">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.DestroyCommand"
+ parent="adminCommandBundleSupport" />
+ <gshell:completers>
+ <ref bean="instanceCompleter" />
+ <null/>
+ </gshell:completers>
+ </gshell:command>
+ <gshell:command name="admin/change-port">
+ <gshell:action class="org.apache.servicemix.kernel.gshell.admin.internal.commands.ChangePortCommand"
+ parent="adminCommandBundleSupport" />
+ <gshell:completers>
+ <ref bean="instanceCompleter" />
+ <null/>
+ </gshell:completers>
+ </gshell:command>
+ </gshell:command-bundle>
+
+ <osgi:reference id="preferences" interface="org.osgi.service.prefs.PreferencesService" cardinality="0..1" />
+
+ <bean id="adminService" class="org.apache.servicemix.kernel.gshell.admin.internal.AdminServiceImpl">
+ <property name="preferences" ref="preferences" />
+ </bean>
+
+ <bean id="instanceCompleter" class="org.apache.servicemix.kernel.gshell.admin.internal.completers.InstanceCompleter">
+ <property name="adminService" ref="adminService" />
+ </bean>
+
+
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/unix/start.sh b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/unix/start.sh
new file mode 100644
index 0000000..1d1d720
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/unix/start.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+#exec 1>${out.file}
+#exec 2>${err.file}
+exec 1>/dev/null
+exec 2>/dev/null
+if [ "x${dir}" != "x" ]; then
+ cd ${dir}
+fi
+nohup ${command} &
+echo $! > ${pid.file}
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/destroy.vbs b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/destroy.vbs
new file mode 100644
index 0000000..abd60eb
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/destroy.vbs
@@ -0,0 +1,27 @@
+'===============================================================================
+'
+' Licensed to the Apache Software Foundation (ASF) under one or more
+' contributor license agreements. See the NOTICE file distributed with
+' this work for additional information regarding copyright ownership.
+' The ASF licenses this file to You under the Apache License, Version 2.0
+' (the "License"); you may not use this file except in compliance with
+' the License. You may obtain a copy of the License at
+'
+' http://www.apache.org/licenses/LICENSE-2.0
+'
+' Unless required by applicable law or agreed to in writing, software
+' distributed under the License is distributed on an "AS IS" BASIS,
+' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+' See the License for the specific language governing permissions and
+' limitations under the License.
+'
+'===============================================================================
+
+Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
+Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = ${pid}")
+intRetVal = 1
+For Each objProcess in colProcessList
+ objProcess.Terminate()
+ intRetVal = 0
+Next
+WScript.Quit(intRetVal)
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/running.vbs b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/running.vbs
new file mode 100644
index 0000000..32c65c5
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/running.vbs
@@ -0,0 +1,26 @@
+'===============================================================================
+'
+' Licensed to the Apache Software Foundation (ASF) under one or more
+' contributor license agreements. See the NOTICE file distributed with
+' this work for additional information regarding copyright ownership.
+' The ASF licenses this file to You under the Apache License, Version 2.0
+' (the "License"); you may not use this file except in compliance with
+' the License. You may obtain a copy of the License at
+'
+' http://www.apache.org/licenses/LICENSE-2.0
+'
+' Unless required by applicable law or agreed to in writing, software
+' distributed under the License is distributed on an "AS IS" BASIS,
+' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+' See the License for the specific language governing permissions and
+' limitations under the License.
+'
+'===============================================================================
+
+Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
+Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = ${pid}")
+intRetVal = 1
+For Each objProcess in colProcessList
+ intRetVal = 0
+Next
+WScript.Quit(intRetVal)
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/start.vbs b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/start.vbs
new file mode 100644
index 0000000..6004c86
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/jpm/impl/windows/start.vbs
@@ -0,0 +1,34 @@
+'===============================================================================
+'
+' Licensed to the Apache Software Foundation (ASF) under one or more
+' contributor license agreements. See the NOTICE file distributed with
+' this work for additional information regarding copyright ownership.
+' The ASF licenses this file to You under the Apache License, Version 2.0
+' (the "License"); you may not use this file except in compliance with
+' the License. You may obtain a copy of the License at
+'
+' http://www.apache.org/licenses/LICENSE-2.0
+'
+' Unless required by applicable law or agreed to in writing, software
+' distributed under the License is distributed on an "AS IS" BASIS,
+' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+' See the License for the specific language governing permissions and
+' limitations under the License.
+'
+'===============================================================================
+
+Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
+Set objConfig = objWMIService.Get("Win32_ProcessStartup").SpawnInstance_
+objConfig.ShowWindow = SW_HIDE
+objConfig.CreateFlags = 8
+If Len("${dir}") > 0 Then
+ intReturn = objWMIService.Get("Win32_Process").Create("${command}", "${dir}", objConfig, intProcessID)
+Else
+ intReturn = objWMIService.Get("Win32_Process").Create("${command}", Null, objConfig, intProcessID)
+End If
+If intReturn = 0 Then
+ Set objOutputFile = CreateObject("Scripting.fileSystemObject").CreateTextFile("${pid.file}", TRUE)
+ objOutputFile.WriteLine(intProcessID)
+ objOutputFile.Close
+End If
+WScript.Quit(intReturn)
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/bin/servicemix b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/bin/servicemix
new file mode 100644
index 0000000..20a33e6
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/bin/servicemix
@@ -0,0 +1,25 @@
+#!/bin/sh
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+SERVICEMIX_HOME=${servicemix.home}
+SERVICEMIX_BASE=${servicemix.base}
+
+export SERVICEMIX_BASE
+${SERVICEMIX_HOME}/bin/servicemix "$*"
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/bin/servicemix.bat b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/bin/servicemix.bat
new file mode 100644
index 0000000..13c155a
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/bin/servicemix.bat
@@ -0,0 +1,25 @@
+@ECHO OFF
+REM =========================================================================
+REM
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM
+REM =========================================================================
+
+SET SERVICEMIX_BASE=${servicemix.base}
+SETLOCAL
+SET SERVICEMIX_HOME=${servicemix.home}
+
+%SERVICEMIX_HOME%\bin\servicemix.bat %*
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.apache.servicemix.shell.cfg b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.apache.servicemix.shell.cfg
new file mode 100644
index 0000000..e6a8fd2
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.apache.servicemix.shell.cfg
@@ -0,0 +1,23 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+#
+startLocalConsole=${servicemix.startLocalConsole}
+startRemoteShell=${servicemix.startRemoteShell}
+sshPort=${servicemix.sshPort}
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.ops4j.pax.logging.cfg b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.ops4j.pax.logging.cfg
new file mode 100644
index 0000000..24ddea5
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.ops4j.pax.logging.cfg
@@ -0,0 +1,36 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# Root logger
+log4j.rootLogger=INFO, out, osgi:VmLogAppender
+
+# Logger infos
+log4j.logger.org.apache.geronimo.gshell.remote=WARN
+
+# CONSOLE appender not used by default
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n
+
+# File appender
+log4j.appender.out=org.apache.log4j.FileAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n
+log4j.appender.out.file=${servicemix.base}/data/log/servicemix.log
+log4j.appender.out.append=true
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.ops4j.pax.url.mvn.cfg b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.ops4j.pax.url.mvn.cfg
new file mode 100644
index 0000000..d0317cd
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/org.ops4j.pax.url.mvn.cfg
@@ -0,0 +1,73 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+#
+# If set to true, the following property will not allow any certificate to be used
+# when accessing maven repositories through SSL
+#
+#org.ops4j.pax.url.mvn.certificateCheck=
+
+#
+# Path to the local maven settings file.
+# The repositories defined in this file will be automatically added to the list
+# of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property
+# below is not set.
+# The following locations are checked for the existence of the settings.xml file
+# * 1. looks for the specified url
+# * 2. if not found looks for ${user.home}/.m2/settings.xml
+# * 3. if not found looks for ${maven.home}/conf/settings.xml
+# * 4. if not found looks for ${M2_HOME}/conf/settings.xml
+#
+#org.ops4j.pax.url.mvn.settings=
+
+#
+# Path to the local maven repository which is used to avoid downloading
+# artifacts when they already exist locally.
+# The value of this property will be extracted from the settings.xml file
+# above, or defaulted to:
+# System.getProperty( "user.home" ) + "/.m2/repository"
+#
+#org.ops4j.pax.url.mvn.localRepository=
+
+#
+# Comma separated list of repositories scanned when resolving an artifact.
+# Those repositories will be checked before iterating through the
+ below list of repositories and even before the local repository
+# A repository url can be appended with zero or more of the following flags:
+# @snapshots : the repository contains snaphots
+# @noreleases : the repository does not contain any released artifacts
+#
+# The following property value will add the system folder as a repo.
+#
+org.ops4j.pax.url.mvn.defaultRepositories=file:${servicemix.home}/system@snapshots,file:${servicemix.base}/system@snapshots
+
+#
+# Comma separated list of repositories scanned when resolving an artifact.
+# The default list includes the following repositories:
+# http://repo1.maven.org/maven2
+# http://repository.ops4j.org/maven2
+# To add repositories to the default ones, prepend '+' to the list of repositories
+# to add.
+# A repository url can be appended with zero or more of the following flags:
+# @snapshots : the repository contains snaphots
+# @noreleases : the repository does not contain any released artifacts
+#
+# The following property value will add the system folders as a repo.
+#
+org.ops4j.pax.url.mvn.repositories=file:${servicemix.base}/system@snapshots,file:${user.home}/.m2/repository@snapshots,http://repo1.maven.org/maven2,http://people.apache.org/repo/m2-snapshot-repository@snapshots@noreleases,http://svn.apache.org/repos/asf/servicemix/m2-repo
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/system.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/system.properties
new file mode 100644
index 0000000..255295e
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/system.properties
@@ -0,0 +1,21 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+org.ops4j.pax.logging.DefaultServiceLog.level=ERROR
+servicemix.name=${servicemix.name}
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/users.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/users.properties
new file mode 100644
index 0000000..0348fae
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/etc/users.properties
@@ -0,0 +1,21 @@
+################################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+#
+smx=smx,admin
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ChangePortCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ChangePortCommand.properties
new file mode 100644
index 0000000..6a7edbf
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ChangePortCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Change the port of an existing instance.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ConnectCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ConnectCommand.properties
new file mode 100644
index 0000000..1c78a34
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ConnectCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Connect to an existing instance.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/CreateCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/CreateCommand.properties
new file mode 100644
index 0000000..532ada2
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/CreateCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Create a new instance.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/DestroyCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/DestroyCommand.properties
new file mode 100644
index 0000000..cb0581c
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/DestroyCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Destroy an existing instance.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ListCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ListCommand.properties
new file mode 100644
index 0000000..c473471
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/ListCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=List existing instances.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/StartCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/StartCommand.properties
new file mode 100644
index 0000000..dfb4046
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/StartCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Start an existing instance.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/StopCommand.properties b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/StopCommand.properties
new file mode 100644
index 0000000..0cd3acd
--- /dev/null
+++ b/karaf/gshell/gshell-admin/src/main/resources/org/apache/servicemix/kernel/gshell/admin/internal/commands/StopCommand.properties
@@ -0,0 +1,27 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Stop an existing instance.
+
+command.manual=\
+ TODO: date manual
\ No newline at end of file