From 1c23cd8f757b8930cc88f5aa368b7a17ca082b85 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Mon, 27 Jul 2009 13:19:29 +0000 Subject: [PATCH] Add SCP From git-svn-id: https://svn.argeo.org/slc/trunk@2778 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../org/argeo/slc/jsch/AbstractJschTask.java | 7 +- .../main/java/org/argeo/slc/jsch/ScpFrom.java | 157 ++++++++++++++++++ .../org/argeo/slc/lib/vbox/VBoxMachine.java | 46 +++++ .../org/argeo/slc/lib/vbox/VBoxManager.java | 50 ++++-- 4 files changed, 247 insertions(+), 13 deletions(-) create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpFrom.java create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxMachine.java diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/AbstractJschTask.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/AbstractJschTask.java index 8f1e12ae5..cc1ce57da 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/AbstractJschTask.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/AbstractJschTask.java @@ -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 index 000000000..d88fda172 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpFrom.java @@ -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 index 000000000..effa3da86 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxMachine.java @@ -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; + } + +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java index d25576e33..ecc1e649b 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java @@ -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 nats = new ArrayList(); + public void importOvf(Resource ovfDefinition) { + try { + List cmd = new ArrayList(); + cmd.add(executable); + cmd.add("import"); + cmd.add(ovfDefinition.getFile().getCanonicalPath()); + cmd.add("--vsys 0 --vmname "); + 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 cmd = new ArrayList(); + 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 cmd = new ArrayList(); 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; + } + } -- 2.39.2