FELIX-1024: Fix the karaf client/server to allow direct execution of commands
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@782734 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/client/src/main/java/org/apache/felix/karaf/client/Main.java b/karaf/client/src/main/java/org/apache/felix/karaf/client/Main.java
index 910ef57..8784337 100644
--- a/karaf/client/src/main/java/org/apache/felix/karaf/client/Main.java
+++ b/karaf/client/src/main/java/org/apache/felix/karaf/client/Main.java
@@ -16,6 +16,8 @@
*/
package org.apache.felix.karaf.client;
+import java.io.ByteArrayInputStream;
+
import org.apache.sshd.ClientChannel;
import org.apache.sshd.ClientSession;
import org.apache.sshd.SshClient;
@@ -31,8 +33,8 @@
public static void main(String[] args) throws Exception {
String host = "localhost";
int port = 8101;
- String user = "smx";
- String password = "smx";
+ String user = "karaf";
+ String password = "karaf";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < args.length; i++) {
@@ -76,8 +78,14 @@
future.await();
ClientSession session = future.getSession();
session.authPassword(user, password);
- ClientChannel channel = session.createChannel("shell");
- channel.setIn(new ConsoleReader().getInput());
+ ClientChannel channel;
+ if (sb.length() > 0) {
+ channel = session.createChannel("exec");
+ channel.setIn(new ByteArrayInputStream(sb.append("\n").toString().getBytes()));
+ } else {
+ channel = session.createChannel("shell");
+ channel.setIn(new ConsoleReader().getInput());
+ }
channel.setOut(System.out);
channel.setErr(System.err);
channel.open();
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/felix/karaf/gshell/core/sshd/ShellCommandFactory.java b/karaf/gshell/gshell-core/src/main/java/org/apache/felix/karaf/gshell/core/sshd/ShellCommandFactory.java
new file mode 100644
index 0000000..428da2c
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/felix/karaf/gshell/core/sshd/ShellCommandFactory.java
@@ -0,0 +1,146 @@
+/*
+ * 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.felix.karaf.gshell.core.sshd;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+import org.apache.sshd.server.CommandFactory;
+import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
+import org.apache.geronimo.gshell.shell.ShellContext;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.io.Closer;
+import org.apache.geronimo.gshell.command.Variables;
+
+public class ShellCommandFactory implements CommandFactory {
+
+ private CommandLineExecutor executor;
+
+ public CommandLineExecutor getExecutor() {
+ return executor;
+ }
+
+ public void setExecutor(CommandLineExecutor executor) {
+ this.executor = executor;
+ }
+
+ public Command createCommand(String command) {
+ return new ShellCommand(command);
+ }
+
+ public class ShellCommand implements Command, ShellContext, Shell {
+
+ private String command;
+ private InputStream in;
+ private OutputStream out;
+ private OutputStream err;
+ private ExitCallback callback;
+ private Variables var;
+ private IO io;
+ private boolean closed;
+
+ public ShellCommand(String command) {
+ this.command = command;
+ }
+
+ public Shell getShell() {
+ return this;
+ }
+
+ public IO getIo() {
+ if (io == null) {
+ io = new IO(in, out, err, true);
+ }
+ return io;
+ }
+
+ public Variables getVariables() {
+ if (var == null) {
+ var = new Variables();
+ }
+ return var;
+ }
+
+ public void setInputStream(InputStream in) {
+ this.in = in;
+ }
+
+ public void setOutputStream(OutputStream out) {
+ this.out = out;
+ }
+
+ public void setErrorStream(OutputStream err) {
+ this.err = err;
+ }
+
+ public void setExitCallback(ExitCallback callback) {
+ this.callback = callback;
+ }
+
+ public void start() throws IOException {
+ try {
+ try {
+ executor.execute(this, command);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } finally {
+ callback.onExit(0);
+ }
+ }
+
+ public Object execute(final String line) throws Exception {
+
+ return executor.execute(getContext(), line);
+ }
+
+ public Object execute(final String command, final Object[] args) throws Exception {
+ return executor.execute(getContext(), args);
+ }
+
+ public Object execute(final Object... args) throws Exception {
+ return executor.execute(getContext(), args);
+ }
+
+ public boolean isOpened() {
+ return !closed;
+ }
+
+ public void close() {
+ closed = true;
+ Closer.close(in, out, err);
+ callback.onExit(0);
+ }
+
+ public boolean isInteractive() {
+ return false;
+ }
+
+ public ShellContext getContext() {
+ return this;
+ }
+
+ public void run(Object... args) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java
index 9795f01..62c9bbc 100644
--- a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java
@@ -150,20 +150,20 @@
this.callback = callback;
}
- public void start(final Map<String,String> env) throws IOException {
+ public void start(final Environment env) throws IOException {
this.io = new IO(in, out, err, false);
// Create variables, inheriting the application ones
this.variables = new Variables(application.getVariables());
// Set up additional env
if (env != null) {
- for (Map.Entry<String,String> entry : env.entrySet()) {
+ for (Map.Entry<String,String> entry : env.getEnv().entrySet()) {
this.variables.set(entry.getKey(), entry.getValue());
}
}
this.variables.set("gshell.prompt", application.getModel().getBranding().getPrompt());
this.variables.set(CommandResolver.GROUP, "/");
- this.variables.set("gshell.username", env.get("USER"));
+ this.variables.set("gshell.username", env.getEnv().get("USER"));
this.variables.set("gshell.hostname", application.getLocalHost());
// HACK: Add history for the 'history' command, since its not part of the Shell intf it can't really access it
this.variables.set("gshell.internal.history", getHistory(), true);
diff --git a/karaf/gshell/gshell-run/src/main/resources/META-INF/spring/gshell-remote.xml b/karaf/gshell/gshell-run/src/main/resources/META-INF/spring/gshell-remote.xml
index 81b5990..e41e3fa 100644
--- a/karaf/gshell/gshell-run/src/main/resources/META-INF/spring/gshell-remote.xml
+++ b/karaf/gshell/gshell-run/src/main/resources/META-INF/spring/gshell-remote.xml
@@ -66,6 +66,11 @@
</property>
</bean>
</property>
+ <property name="commandFactory">
+ <bean class="org.apache.felix.karaf.gshell.core.sshd.ShellCommandFactory">
+ <property name="executor" ref="commandLineExecutor" />
+ </bean>
+ </property>
<property name="keyPairProvider" ref="keyPairProvider" />
<property name="passwordAuthenticator" ref="passwordAuthenticator" />
</bean>
diff --git a/karaf/pom.xml b/karaf/pom.xml
index fe886f7..c5d5af8 100644
--- a/karaf/pom.xml
+++ b/karaf/pom.xml
@@ -94,7 +94,7 @@
<junit.version>3.8.2_1</junit.version>
<jline.version>0.9.94_1</jline.version>
<log4j.version>1.2.14</log4j.version>
- <mina.version>2.0.0-M5</mina.version>
+ <mina.version>2.0.0-M6</mina.version>
<oro.version>2.0.8_1</oro.version>
<pax.exam.version>0.5.0</pax.exam.version>
<pax.logging.version>1.3.0</pax.logging.version>