Add SCP From
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 27 Jul 2009 13:19:29 +0000 (13:19 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 27 Jul 2009 13:19:29 +0000 (13:19 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2778 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/AbstractJschTask.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpFrom.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxMachine.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java

index 8f1e12ae50a9c6b89dc959e4014a510b2513d724..cc1ce57da5e1c2e7aa1ecfcdda758588111d9c7d 100644 (file)
@@ -38,16 +38,16 @@ public abstract class AbstractJschTask implements Runnable {
 
        abstract void run(Session session);
 
-       protected void checkAck(InputStream in) throws IOException {
+       protected int checkAck(InputStream in) throws IOException {
                int b = in.read();
                // b may be 0 for success,
                // 1 for error,
                // 2 for fatal error,
                // -1
                if (b == 0)
-                       return;
+                       return b;
                else if (b == -1)
-                       throw new SlcException("SSH ack returned -1");
+                       return b;//throw new SlcException("SSH ack returned -1");
                else if (b == 1 || b == 2) {
                        StringBuffer sb = new StringBuffer();
                        int c;
@@ -62,6 +62,7 @@ public abstract class AbstractJschTask implements Runnable {
                                throw new SlcException("SSH fatal error: " + sb.toString());
                        }
                }
+               return b;
        }
 
        public SshTarget getSshTarget() {
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpFrom.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpFrom.java
new file mode 100644 (file)
index 0000000..d88fda1
--- /dev/null
@@ -0,0 +1,157 @@
+package org.argeo.slc.jsch;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.core.io.Resource;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.Session;
+
+public class ScpFrom extends AbstractJschTask {
+       private final static Log log = LogFactory.getLog(ScpFrom.class);
+
+       private Resource localResource;
+       private String remotePath;
+       private Boolean mkdir = false;
+
+       public void run(Session session) {
+               if (localResource != null) {
+                       File lFile;
+                       try {
+                               lFile = localResource.getFile();
+                       } catch (IOException e) {
+                               throw new SlcException("Cannot interpret resource "
+                                               + localResource + " as file.", e);
+                       }
+                       downloadFile(session, lFile, remotePath);
+               }
+       }
+
+       protected void downloadFile(Session session, File localFile,
+                       String remoteFile) {
+               OutputStream out = null;
+               OutputStream channelOut;
+               InputStream channelIn;
+               try {
+                       // exec 'scp -f rfile' remotely
+                       String command = "scp -f " + remoteFile;
+                       Channel channel = session.openChannel("exec");
+                       ((ChannelExec) channel).setCommand(command);
+
+                       // get I/O streams for remote scp
+                       channelOut = channel.getOutputStream();
+                       channelIn = channel.getInputStream();
+
+                       channel.connect();
+
+                       byte[] buf = new byte[1024];
+
+                       // send '\0'
+                       buf[0] = 0;
+                       channelOut.write(buf, 0, 1);
+                       channelOut.flush();
+
+                       while (true) {
+                               int c = checkAck(channelIn);
+                               if (c != 'C') {
+                                       break;
+                               }
+
+                               // read '0644 '
+                               channelIn.read(buf, 0, 5);
+
+                               long filesize = 0L;
+                               while (true) {
+                                       if (channelIn.read(buf, 0, 1) < 0) {
+                                               // error
+                                               break;
+                                       }
+                                       if (buf[0] == ' ')
+                                               break;
+                                       filesize = filesize * 10L + (long) (buf[0] - '0');
+                               }
+
+                               String remoteFileName = null;
+                               for (int i = 0;; i++) {
+                                       channelIn.read(buf, i, 1);
+                                       if (buf[i] == (byte) 0x0a) {
+                                               remoteFileName = new String(buf, 0, i);
+                                               break;
+                                       }
+                               }
+
+                               // System.out.println("filesize="+filesize+", file="+file);
+
+                               // send '\0'
+                               buf[0] = 0;
+                               channelOut.write(buf, 0, 1);
+                               channelOut.flush();
+
+                               // Create a s adirectory if it doesn't exists
+                               if (!localFile.exists() && mkdir)
+                                       localFile.mkdirs();
+
+                               // read a content of lfile
+                               String localPath = localFile.isDirectory() ? localFile
+                                               .getPath()
+                                               + File.separator + remoteFileName : localFile.getPath();
+                               if (log.isDebugEnabled())
+                                       log.debug("Download " + remoteFile + " to " + localPath);
+
+                               out = new FileOutputStream(localPath);
+                               int foo;
+                               while (true) {
+                                       if (buf.length < filesize)
+                                               foo = buf.length;
+                                       else
+                                               foo = (int) filesize;
+                                       foo = channelIn.read(buf, 0, foo);
+                                       if (foo < 0) {
+                                               // error
+                                               break;
+                                       }
+                                       out.write(buf, 0, foo);
+                                       filesize -= foo;
+                                       if (filesize == 0L)
+                                               break;
+                               }
+
+                               checkAck(channelIn);
+
+                               // send '\0'
+                               buf[0] = 0;
+                               channelOut.write(buf, 0, 1);
+                               channelOut.flush();
+                       }
+
+                       channel.disconnect();
+                       // session.disconnect();
+               } catch (Exception e) {
+                       throw new SlcException("Cannot download " + remoteFile + " to "
+                                       + localFile, e);
+               } finally {
+                       IOUtils.closeQuietly(out);
+               }
+       }
+
+       public void setLocalResource(Resource localFile) {
+               this.localResource = localFile;
+       }
+
+       public void setRemotePath(String remoteFile) {
+               this.remotePath = remoteFile;
+       }
+
+       public void setMkdir(Boolean mkdir) {
+               this.mkdir = mkdir;
+       }
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxMachine.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxMachine.java
new file mode 100644 (file)
index 0000000..effa3da
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.slc.lib.vbox;
+
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.deploy.DeployedSystem;
+import org.argeo.slc.deploy.DeploymentData;
+import org.argeo.slc.deploy.TargetData;
+import org.springframework.beans.factory.BeanNameAware;
+
+public class VBoxMachine implements DeployedSystem, BeanNameAware {
+       private String deployedSystemId = null;
+       private String name;
+
+       public String getDeployedSystemId() {
+               return deployedSystemId;
+       }
+
+       public DeploymentData getDeploymentData() {
+               throw new UnsupportedException();
+       }
+
+       public Distribution getDistribution() {
+               throw new UnsupportedException();
+       }
+
+       public TargetData getTargetData() {
+               throw new UnsupportedException();
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public void setDeployedSystemId(String deployedSystemId) {
+               this.deployedSystemId = deployedSystemId;
+       }
+
+       public void setBeanName(String name) {
+               this.name = name;
+       }
+
+}
index d25576e335b07c8b46754111068f92d7da9f9dc2..ecc1e649b7bc77dd946bdfaf99465a87b372001d 100644 (file)
@@ -1,20 +1,54 @@
 package org.argeo.slc.lib.vbox;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
 import org.argeo.slc.core.execution.tasks.SystemCall;
+import org.springframework.core.io.Resource;
 
 public class VBoxManager {
        private final static Log log = LogFactory.getLog(VBoxManager.class);
 
-       private String machineName;
+       private VBoxMachine vm;
        private String executable = "VBoxManage";
 
        private List<VBoxNat> nats = new ArrayList<VBoxNat>();
 
+       public void importOvf(Resource ovfDefinition) {
+               try {
+                       List<Object> cmd = new ArrayList<Object>();
+                       cmd.add(executable);
+                       cmd.add("import");
+                       cmd.add(ovfDefinition.getFile().getCanonicalPath());
+                       cmd.add("--vsys 0 --vmname <name>");
+                       cmd.add("0");
+                       cmd.add("--vmname");
+                       cmd.add(vm.getName());
+                       new SystemCall(cmd).run();
+               } catch (IOException e) {
+                       throw new SlcException("Cannot import OVF appliance "
+                                       + ovfDefinition, e);
+               }
+       }
+
+       public void startVm() {
+               startVm("gui");
+       }
+
+       public void startVm(String type) {
+               List<Object> cmd = new ArrayList<Object>();
+               cmd.add(executable);
+               cmd.add("startvm");
+               cmd.add(vm.getName());
+               cmd.add("--type");
+               cmd.add(type);
+               new SystemCall(cmd).run();
+       }
+
        public void applyNats() {
                StringBuffer script = new StringBuffer("");
                for (VBoxNat vBoxNat : nats) {
@@ -43,7 +77,7 @@ public class VBoxManager {
                List<Object> cmd = new ArrayList<Object>();
                cmd.add(executable);
                cmd.add("setextradata");
-               cmd.add(machineName);
+               cmd.add(vm.getName());
                cmd.add("VBoxInternal/Devices/" + device + "/0/LUN#0/Config/" + id
                                + "/" + cfgKey);
                cmd.add(value);
@@ -55,14 +89,6 @@ public class VBoxManager {
                return cmd;
        }
 
-       public String getMachineName() {
-               return machineName;
-       }
-
-       public void setMachineName(String machineName) {
-               this.machineName = machineName;
-       }
-
        public String getExecutable() {
                return executable;
        }
@@ -79,4 +105,8 @@ public class VBoxManager {
                nats = boxNats;
        }
 
+       public void setVm(VBoxMachine vm) {
+               this.vm = vm;
+       }
+
 }