use of org.platformlayer.ops.process.ProcessExecutionException in project platformlayer by platformlayer.
the class OpsTargetBase method doFind.
protected List<FilesystemInfo> doFind(File path, Integer maxDepth) throws OpsException {
Command command = maybeSudo("find");
String[] fields = new String[] { "T@", "s", "m", "u", "g", "n", "p", "l", "y", "d" };
StringBuilder format = new StringBuilder();
for (int i = 0; i < fields.length; i++) {
if (i != 0) {
format.append("\\t");
}
format.append("%");
format.append(fields[i]);
}
format.append("\\n");
command.addFile(path);
if (maxDepth != null) {
command.addLiteral("-maxdepth");
command.addQuoted(maxDepth.toString());
}
command.addLiteral("-printf");
command.addQuoted(format.toString());
ProcessExecution execution;
try {
execution = executeCommand(command);
} catch (ProcessExecutionException e) {
execution = e.getExecution();
if (execution != null && execution.getExitCode() == 1 && execution.getStdErr().contains("No such file or directory")) {
return null;
}
throw new OpsException("Error executing find command", e);
}
List<FilesystemInfo> filesystemInfos = Lists.newArrayList();
String stdout = execution.getStdOut();
for (String line : stdout.split("\n")) {
String[] fieldValues = line.split("\t");
if (fieldValues.length != fields.length) {
throw new OpsException("Cannot parse line: " + line);
}
FilesystemInfo filesystemInfo = new FilesystemInfo();
for (int i = 0; i < fieldValues.length; i++) {
String field = fields[i];
String fieldValue = fieldValues[i];
if (field.equals("u")) {
filesystemInfo.owner = fieldValue;
} else if (field.equals("g")) {
filesystemInfo.group = fieldValue;
} else if (field.equals("n")) {
filesystemInfo.links = fieldValue;
} else if (field.equals("m")) {
filesystemInfo.mode = fieldValue;
} else if (field.equals("p")) {
filesystemInfo.name = fieldValue;
} else if (field.equals("s")) {
filesystemInfo.size = Long.parseLong(fieldValue);
} else if (field.equals("y")) {
filesystemInfo.type = fieldValue;
} else if (field.equals("l")) {
if (!Strings.isNullOrEmpty(fieldValue)) {
filesystemInfo.symlinkTarget = fieldValue;
}
} else if (field.equals("T@")) {
filesystemInfo.date = fieldValue;
} else if (field.equals("d")) {
filesystemInfo.depth = Integer.parseInt(fieldValue);
} else {
throw new IllegalStateException();
}
}
filesystemInfos.add(filesystemInfo);
}
return filesystemInfos;
}
use of org.platformlayer.ops.process.ProcessExecutionException in project platformlayer by platformlayer.
the class OpsTargetBase method executeCommand.
@Override
public ProcessExecution executeCommand(Command command) throws OpsException {
log.info("Executing command: " + command.toString());
if (command.getEnvironment() != null) {
String s = Joiner.on(",").join(command.getEnvironment().keys());
log.info("Environment keys set: " + s);
}
ProcessExecution execution = executeCommandUnchecked(command);
if (execution.getExitCode() != 0) {
throw new ProcessExecutionException("Unexpected exit code from running command. Command=" + command.toString(), execution);
}
return execution;
}
use of org.platformlayer.ops.process.ProcessExecutionException in project platformlayer by platformlayer.
the class SocatPeerToPeerCopy method copy.
@Override
public void copy(final OpsTarget src, final File srcFile, final OpsTarget dest, final File finalDestFile) throws OpsException {
File tempDir = dest.createTempDir();
try {
final File tempDest = new File(tempDir, finalDestFile.getName());
int maxAttempts = 3;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
final InetAddressPair channel = findChannel(src, dest);
final int listenPort = PORT;
Callable<ProcessExecution> pushFile = new Callable<ProcessExecution>() {
@Override
public ProcessExecution call() throws Exception {
// TODO: This is actually _really_ problematic because pkill kills proceses in guests also...
// // TODO: Check no concurrent socats?? Move to a better system??
// Command killExistingSocats = Command.build("pkill socat || true");
// src.executeCommand(killExistingSocats);
// TODO: Secure this better (using host address is probably sufficient, but then we need a full
// network map to know which IP to use)
// Command sendCommand = Command.build("socat -u OPEN:{0},rdonly TCP4-LISTEN:{1},range={2}",
// srcImageFile, port, targetAddress.getHostAddress() + "/32");
Command pushCommand = Command.build("socat -u OPEN:{0},rdonly {1}", srcFile, toSocatPush(channel.dest, listenPort));
return src.executeCommand(pushCommand.setTimeout(TimeSpan.TEN_MINUTES));
}
};
Callable<ProcessExecution> listenFile = new Callable<ProcessExecution>() {
@Override
public ProcessExecution call() throws Exception {
// TODO: This is actually _really_ problematic because pkill kills proceses in guests also...
// TODO: Check no concurrent socats?? Move to a better system??
Command killExistingSocats = Command.build("pkill socat || true");
dest.executeCommand(killExistingSocats);
try {
Command listenCommand = Command.build("socat -u {0} CREATE:{1}", toSocatListen(channel.src, listenPort), tempDest);
return dest.executeCommand(listenCommand.setTimeout(TimeSpan.TEN_MINUTES));
} catch (ProcessExecutionException e) {
log.warn("Error running listen process for P2P copy: " + channel, e);
throw new OpsException("Error running listen process", e);
}
}
};
Future<ProcessExecution> listenFileFuture = executorService.submit(listenFile);
for (int readAttempts = 1; readAttempts <= 10; readAttempts++) {
TimeSpan.ONE_SECOND.doSafeSleep();
if (!listenFileFuture.isDone()) {
boolean pushedOkay = false;
try {
pushFile.call();
pushedOkay = true;
} catch (Exception e) {
ProcessExecution pushExecution = null;
if (e instanceof ProcessExecutionException) {
pushExecution = ((ProcessExecutionException) e).getExecution();
}
if (pushExecution != null && pushExecution.getExitCode() == 1 && pushExecution.getStdErr().contains("Connection refused")) {
log.info("Got connection refused on push; will retry");
} else {
throw new OpsException("Error pushing file", e);
}
}
if (pushedOkay) {
try {
listenFileFuture.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
log.info("Timeout while waiting for receive to complete");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new OpsException("Interrupted during file receive", e);
} catch (ExecutionException e) {
throw new OpsException("Error during file receive", e);
}
}
}
if (listenFileFuture.isDone()) {
try {
ProcessExecution listenExecution = listenFileFuture.get();
log.warn("File receiving exited: " + listenExecution);
break;
} catch (ExecutionException e) {
throw new OpsException("Error receiving file", e);
} catch (InterruptedException e) {
ExceptionUtils.handleInterrupted(e);
throw new OpsException("Error receiving file", e);
}
}
}
if (!listenFileFuture.isDone()) {
throw new OpsException("Failed to push file (too many retries");
}
Md5Hash targetHash = dest.getFileHash(tempDest);
Md5Hash srcHash = src.getFileHash(srcFile);
if (Objects.equal(srcHash, targetHash)) {
break;
} else {
dest.rm(tempDest);
if (attempt != maxAttempts) {
log.warn("Files did not match after transfer");
} else {
throw new OpsException("Files did not match after transfer");
}
}
// if (serveFuture.isDone()) {
// // This is interesting for debug purposes; otherwise not very useful
// try {
// ProcessExecution serveExecution = serveFuture.get();
// log.warn("Serving process exited: " + serveExecution);
// } catch (ExecutionException e) {
// throw new OpsException("Error sending file to image store", e);
// } catch (InterruptedException e) {
// ExceptionUtils.handleInterrupted(e);
// throw new OpsException("Error sending file to image store", e);
// }
// }
}
dest.mv(tempDest, finalDestFile);
} finally {
dest.rmdir(tempDir);
}
}
use of org.platformlayer.ops.process.ProcessExecutionException in project platformlayer by platformlayer.
the class DiskImageController method waitForTarget.
private String waitForTarget(final OpsTarget target) throws OpsException {
// Maybe the config CD isn't yet mounted? Maybe SSH isn't yet started? Not sure yet..
try {
log.info("Sleeping in the hope of avoiding (not fully understood) SSH issue");
Thread.sleep(15000);
} catch (InterruptedException e) {
ExceptionUtils.handleInterrupted(e);
throw new OpsException("Interrupted", e);
}
try {
return TimeoutPoll.poll(TimeSpan.FIVE_MINUTES, TimeSpan.TEN_SECONDS, new PollFunction<String>() {
@Override
public String call() throws Exception {
try {
ProcessExecution execution = target.executeCommand("uname -srp");
return execution.getStdOut();
} catch (ProcessExecutionException e) {
log.info("Waiting for machine; got process execution error", e);
return null;
}
}
});
} catch (ExecutionException e) {
throw new OpsException("Error while waiting for machine", e);
} catch (TimeoutException e) {
throw new OpsException("Timeout while waiting for machine", e);
}
}
use of org.platformlayer.ops.process.ProcessExecutionException in project platformlayer by platformlayer.
the class NetworkTunDevice method handler.
@Handler
public void handler(OpsTarget target) throws OpsException {
if (OpsContext.isConfigure()) {
Command findCommand = Command.build("/sbin/ifconfig {0}", interfaceName);
boolean found = false;
try {
target.executeCommand(findCommand);
found = true;
} catch (ProcessExecutionException e) {
ProcessExecution execution = e.getExecution();
if (execution.getExitCode() == 1 && execution.getStdErr().contains("Device not found")) {
found = false;
} else {
throw new OpsException("Error checking for interface", e);
}
}
if (!found) {
// This is actually idempotent, but I think it's scary to rely on it being so
Command command = Command.build("/usr/sbin/tunctl -t {0}", interfaceName);
target.executeCommand(command);
}
{
// TODO: Safe to re-run?
Command command = Command.build("ifconfig {0} up", interfaceName);
target.executeCommand(command);
}
if (bridgeName != null) {
// TODO: Safe to re-run?
Command command = Command.build("brctl addif {0} {1}", bridgeName.get(), interfaceName);
try {
target.executeCommand(command);
} catch (ProcessExecutionException e) {
ProcessExecution execution = e.getExecution();
if (execution.getExitCode() == 1 && execution.getStdErr().contains("already a member of a bridge")) {
// OK
// TODO: Check that the bridge is bridgeName
} else {
throw new OpsException("Error attaching interface to bridge", e);
}
}
}
}
if (OpsContext.isDelete()) {
// TODO: Implement
log.warn("NetworkTunDevice delete not implemented");
}
}
Aggregations