mirror of https://github.com/apache/jclouds.git
Issue 357:Init script should check for errors + herefile fixes + script events
This commit is contained in:
parent
ccc86123ca
commit
636c3bb6e5
|
@ -47,7 +47,7 @@ import org.apache.tools.ant.types.Environment;
|
||||||
import org.apache.tools.ant.types.FileSet;
|
import org.apache.tools.ant.types.FileSet;
|
||||||
import org.apache.tools.ant.types.Path;
|
import org.apache.tools.ant.types.Path;
|
||||||
import org.apache.tools.ant.types.Environment.Variable;
|
import org.apache.tools.ant.types.Environment.Variable;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
@ -237,13 +237,13 @@ public class SSHJava extends Java {
|
||||||
private int sshexecRedirectStreams(Statement statement) throws IOException {
|
private int sshexecRedirectStreams(Statement statement) throws IOException {
|
||||||
exec.setStreamHandler(redirector.createHandler());
|
exec.setStreamHandler(redirector.createHandler());
|
||||||
log("starting java as:\n" + statement.render(osFamily), Project.MSG_VERBOSE);
|
log("starting java as:\n" + statement.render(osFamily), Project.MSG_VERBOSE);
|
||||||
int rc;
|
int exitStatus;
|
||||||
try {
|
try {
|
||||||
rc = sshexec(statement.render(osFamily));
|
exitStatus = sshexec(statement.render(osFamily));
|
||||||
} finally {
|
} finally {
|
||||||
redirector.complete();
|
redirector.complete();
|
||||||
}
|
}
|
||||||
return rc;
|
return exitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
||||||
|
@ -373,8 +373,8 @@ public class SSHJava extends Java {
|
||||||
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
||||||
}
|
}
|
||||||
|
|
||||||
InitBuilder testInitBuilder = new InitBuilder(id, basedir, basedir, envVariables,
|
InitScript testInitBuilder = InitScript.builder().name(id).home(basedir).exportVariables(envVariables)
|
||||||
ImmutableList.<Statement> of(Statements.interpret( commandBuilder.toString())));
|
.run(Statements.interpret( commandBuilder.toString())).build();
|
||||||
return testInitBuilder.render(osFamily);
|
return testInitBuilder.render(osFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.ec2.domain.Attachment;
|
import org.jclouds.ec2.domain.Attachment;
|
||||||
import org.jclouds.ec2.domain.BlockDevice;
|
import org.jclouds.ec2.domain.BlockDevice;
|
||||||
import org.jclouds.ec2.domain.Image;
|
import org.jclouds.ec2.domain.Image;
|
||||||
|
import org.jclouds.ec2.domain.Image.Architecture;
|
||||||
|
import org.jclouds.ec2.domain.Image.ImageType;
|
||||||
import org.jclouds.ec2.domain.InstanceState;
|
import org.jclouds.ec2.domain.InstanceState;
|
||||||
import org.jclouds.ec2.domain.InstanceType;
|
import org.jclouds.ec2.domain.InstanceType;
|
||||||
import org.jclouds.ec2.domain.IpProtocol;
|
import org.jclouds.ec2.domain.IpProtocol;
|
||||||
|
@ -49,8 +51,6 @@ import org.jclouds.ec2.domain.RootDeviceType;
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.ec2.domain.Snapshot;
|
import org.jclouds.ec2.domain.Snapshot;
|
||||||
import org.jclouds.ec2.domain.Volume;
|
import org.jclouds.ec2.domain.Volume;
|
||||||
import org.jclouds.ec2.domain.Image.Architecture;
|
|
||||||
import org.jclouds.ec2.domain.Image.ImageType;
|
|
||||||
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
|
||||||
import org.jclouds.ec2.predicates.InstanceStateRunning;
|
import org.jclouds.ec2.predicates.InstanceStateRunning;
|
||||||
import org.jclouds.ec2.predicates.InstanceStateStopped;
|
import org.jclouds.ec2.predicates.InstanceStateStopped;
|
||||||
|
@ -65,9 +65,8 @@ import org.jclouds.net.IPSocket;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.predicates.SocketOpen;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.ssh.SshException;
|
import org.jclouds.ssh.SshException;
|
||||||
|
@ -77,7 +76,6 @@ import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -256,12 +254,12 @@ public class EBSBootEC2ClientLiveTest extends BaseVersionedServiceLiveTest {
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
void makeScript() {
|
void makeScript() {
|
||||||
|
|
||||||
mkEbsBoot = new InitBuilder(
|
mkEbsBoot = InitScript.builder()
|
||||||
"mkebsboot",// name of the script
|
.name("mkebsboot")
|
||||||
"/tmp",// working directory
|
.home("/tmp")
|
||||||
"/tmp/logs",// location of stdout.log and stderr.log
|
.logDir("/tmp/logs")
|
||||||
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"),
|
.exportVariables(ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"))
|
||||||
ImmutableList.<Statement> of(Statements
|
.run(Statements
|
||||||
.interpret(
|
.interpret(
|
||||||
"echo creating a filesystem and mounting the ebs volume",
|
"echo creating a filesystem and mounting the ebs volume",
|
||||||
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||||
|
@ -275,7 +273,7 @@ public class EBSBootEC2ClientLiveTest extends BaseVersionedServiceLiveTest {
|
||||||
"echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}",
|
"echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}",
|
||||||
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
|
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
|
||||||
"du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source", "du -sk {varl}IMAGE_DIR{varr}",
|
"du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source", "du -sk {varl}IMAGE_DIR{varr}",
|
||||||
"rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)))
|
"rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)).build()
|
||||||
.render(OsFamily.UNIX);
|
.render(OsFamily.UNIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||||
import org.jclouds.scriptbuilder.statements.java.InstallJDK;
|
import org.jclouds.scriptbuilder.statements.java.InstallJDK;
|
||||||
|
@ -71,15 +71,13 @@ public class RunScriptData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE do not name this the same as your login user, or the init process may kill you!
|
// NOTE do not name this the same as your login user, or the init process may kill you!
|
||||||
public static InitBuilder startJBoss(String configuration) {
|
public static InitScript startJBoss(String configuration) {
|
||||||
return new InitBuilder(
|
return InitScript.builder()
|
||||||
"jboss",
|
.name("jboss")
|
||||||
JBOSS_HOME,
|
.home(JBOSS_HOME)
|
||||||
JBOSS_HOME,
|
.exportVariables(ImmutableMap.of("jbossHome", JBOSS_HOME))
|
||||||
ImmutableMap.of("jbossHome", JBOSS_HOME),
|
.init(appendFile(JBOSS_HOME + "/standalone/configuration/standalone-custom.xml", Splitter.on('\n').split(configuration)))
|
||||||
ImmutableList.<Statement>of(appendFile(JBOSS_HOME + "/standalone/configuration/standalone-custom.xml", Splitter.on('\n').split(configuration))),
|
.run(interpret(new StringBuilder().append("java ").append(' ')
|
||||||
ImmutableList
|
|
||||||
.<Statement> of(interpret(new StringBuilder().append("java ").append(' ')
|
|
||||||
.append("-server -Xms128m -Xmx128m -XX:MaxPermSize=128m -Djava.net.preferIPv4Stack=true -XX:+UseFastAccessorMethods -XX:+TieredCompilation -Xverify:none -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000").append(' ')
|
.append("-server -Xms128m -Xmx128m -XX:MaxPermSize=128m -Djava.net.preferIPv4Stack=true -XX:+UseFastAccessorMethods -XX:+TieredCompilation -Xverify:none -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000").append(' ')
|
||||||
.append("-Djboss.modules.system.pkgs=org.jboss.byteman").append(' ')
|
.append("-Djboss.modules.system.pkgs=org.jboss.byteman").append(' ')
|
||||||
.append("-Dorg.jboss.boot.log.file=$JBOSS_HOME/standalone/log/boot.log").append(' ')
|
.append("-Dorg.jboss.boot.log.file=$JBOSS_HOME/standalone/log/boot.log").append(' ')
|
||||||
|
@ -91,7 +89,7 @@ public class RunScriptData {
|
||||||
.append("org.jboss.as.standalone").append(' ')
|
.append("org.jboss.as.standalone").append(' ')
|
||||||
.append("-Djboss.home.dir=$JBOSS_HOME").append(' ')
|
.append("-Djboss.home.dir=$JBOSS_HOME").append(' ')
|
||||||
.append("--server-config=standalone-custom.xml")
|
.append("--server-config=standalone-custom.xml")
|
||||||
.toString())));
|
.toString())).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make this a cli option
|
// TODO make this a cli option
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.compute.callables;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -30,22 +31,28 @@ import javax.annotation.Resource;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeCompletion;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeFailure;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
|
import com.google.common.primitives.Ints;
|
||||||
import com.google.common.util.concurrent.AbstractFuture;
|
import com.google.common.util.concurrent.AbstractFuture;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A future that works in tandem with a task that was invoked by {@link InitBuilder}
|
* A future that works in tandem with a task that was invoked by
|
||||||
|
* {@link InitScript}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -60,23 +67,31 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final ExecutorService userThreads;
|
private final ExecutorService userThreads;
|
||||||
|
private final EventBus eventBus;
|
||||||
private final SudoAwareInitManager commandRunner;
|
private final SudoAwareInitManager commandRunner;
|
||||||
private final RetryablePredicate<String> notRunningAnymore;
|
|
||||||
|
|
||||||
private boolean shouldCancel;
|
public SudoAwareInitManager getCommandRunner() {
|
||||||
|
return commandRunner;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final RetryablePredicate<String> notRunningAnymore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BlockUntilInitScriptStatusIsZeroThenReturnOutput(
|
public BlockUntilInitScriptStatusIsZeroThenReturnOutput(
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, EventBus eventBus,
|
||||||
ComputeServiceConstants.InitStatusProperties properties,
|
ComputeServiceConstants.InitStatusProperties properties, final ScriptStatusReturnsZero stateRunning,
|
||||||
final ScriptStatusReturnsZero stateRunning, @Assisted final SudoAwareInitManager commandRunner) {
|
@Assisted final SudoAwareInitManager commandRunner) {
|
||||||
|
|
||||||
long retryMaxWait = TimeUnit.DAYS.toMillis(365); // arbitrarily high value, but Long.MAX_VALUE doesn't work!
|
long retryMaxWait = TimeUnit.DAYS.toMillis(365); // arbitrarily high
|
||||||
|
// value, but
|
||||||
|
// Long.MAX_VALUE doesn't
|
||||||
|
// work!
|
||||||
long retryInitialPeriod = properties.initStatusInitialPeriod;
|
long retryInitialPeriod = properties.initStatusInitialPeriod;
|
||||||
long retryMaxPeriod = properties.initStatusMaxPeriod;
|
long retryMaxPeriod = properties.initStatusMaxPeriod;
|
||||||
|
|
||||||
this.commandRunner = checkNotNull(commandRunner, "commandRunner");
|
this.commandRunner = checkNotNull(commandRunner, "commandRunner");
|
||||||
this.userThreads = checkNotNull(userThreads, "userThreads");
|
this.userThreads = checkNotNull(userThreads, "userThreads");
|
||||||
|
this.eventBus = checkNotNull(eventBus, "eventBus");
|
||||||
this.notRunningAnymore = new RetryablePredicate<String>(new Predicate<String>() {
|
this.notRunningAnymore = new RetryablePredicate<String>(new Predicate<String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -85,13 +100,13 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
||||||
}
|
}
|
||||||
}, retryMaxWait, retryInitialPeriod, retryMaxPeriod, TimeUnit.MILLISECONDS) {
|
}, retryMaxWait, retryInitialPeriod, retryMaxPeriod, TimeUnit.MILLISECONDS) {
|
||||||
/**
|
/**
|
||||||
* make sure we stop the retry loop if someone cancelled the future, this keeps threads
|
* make sure we stop the retry loop if someone cancelled the future,
|
||||||
* from being consumed on dead tasks
|
* this keeps threads from being consumed on dead tasks
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean atOrAfter(Date end) {
|
protected boolean atOrAfter(Date end) {
|
||||||
if (shouldCancel)
|
if (isCancelled())
|
||||||
Throwables.propagate(new TimeoutException("cancelled"));
|
Throwables.propagate(new CancellationException("cancelled"));
|
||||||
return super.atOrAfter(end);
|
return super.atOrAfter(end);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -105,20 +120,28 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submits a thread that will either set the result of the future or the exception that took
|
* Submits a thread that will either set the result of the future or the
|
||||||
* place
|
* exception that took place
|
||||||
*/
|
*/
|
||||||
public BlockUntilInitScriptStatusIsZeroThenReturnOutput init() {
|
public BlockUntilInitScriptStatusIsZeroThenReturnOutput init() {
|
||||||
userThreads.submit(new Runnable() {
|
userThreads.submit(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
boolean complete = notRunningAnymore.apply("status");
|
notRunningAnymore.apply("status");
|
||||||
String stdout = commandRunner.runAction("tail").getOutput();
|
String stdout = commandRunner.runAction("stdout").getOutput();
|
||||||
String stderr = commandRunner.runAction("tailerr").getOutput();
|
String stderr = commandRunner.runAction("stderr").getOutput();
|
||||||
// TODO make ScriptBuilder save exit status on nuhup
|
Integer exitStatus = Ints.tryParse(commandRunner.runAction("exitstatus").getOutput().trim());
|
||||||
logger.debug("<< complete(%s) status(%s)", commandRunner.getStatement().getInstanceName(), complete);
|
ExecResponse exec = new ExecResponse(stdout, stderr, exitStatus == null ? -1 : exitStatus);
|
||||||
set(new ExecResponse(stdout, stderr, complete && !shouldCancel ? 0 : -1));
|
if (exitStatus == null) {
|
||||||
|
Integer pid = Ints.tryParse(commandRunner.runAction("status").getOutput().trim());
|
||||||
|
throw new ScriptStillRunningException(String.format("%s still running: pid(%s), last status: %s",
|
||||||
|
BlockUntilInitScriptStatusIsZeroThenReturnOutput.this, pid, exec),
|
||||||
|
BlockUntilInitScriptStatusIsZeroThenReturnOutput.this);
|
||||||
|
}
|
||||||
|
logger.debug("<< complete(%s) status(%s)", commandRunner.getStatement().getInstanceName(), exitStatus);
|
||||||
|
set(exec);
|
||||||
|
} catch (CancellationException e) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
setException(e);
|
setException(e);
|
||||||
}
|
}
|
||||||
|
@ -127,63 +150,43 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean set(ExecResponse value) {
|
||||||
|
eventBus.post(new StatementOnNodeCompletion(getCommandRunner().getStatement(), getCommandRunner().getNode(),
|
||||||
|
value));
|
||||||
|
return super.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void interruptTask() {
|
protected void interruptTask() {
|
||||||
logger.debug("<< cancelled(%s)", commandRunner.getStatement().getInstanceName());
|
logger.debug("<< cancelled(%s)", commandRunner.getStatement().getInstanceName());
|
||||||
commandRunner.refreshAndRunAction("stop");
|
ExecResponse returnVal = commandRunner.refreshAndRunAction("stop");
|
||||||
shouldCancel = true;
|
CancellationException e = new CancellationException(String.format(
|
||||||
|
"cancelled %s on node: %s; stop command had exit status: %s", getCommandRunner().getStatement()
|
||||||
|
.getInstanceName(), getCommandRunner().getNode().getId(), returnVal));
|
||||||
|
eventBus.post(new StatementOnNodeFailure(getCommandRunner().getStatement(), getCommandRunner().getNode(), e));
|
||||||
super.interruptTask();
|
super.interruptTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("running task[%s]", commandRunner);
|
return Objects.toStringHelper(this).add("commandRunner", commandRunner).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
return Objects.hashCode(commandRunner);
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((commandRunner == null) ? 0 : commandRunner.hashCode());
|
|
||||||
result = prime * result + ((logger == null) ? 0 : logger.hashCode());
|
|
||||||
result = prime * result + ((notRunningAnymore == null) ? 0 : notRunningAnymore.hashCode());
|
|
||||||
result = prime * result + (shouldCancel ? 1231 : 1237);
|
|
||||||
result = prime * result + ((userThreads == null) ? 0 : userThreads.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object o) {
|
||||||
if (this == obj)
|
if (o == null)
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (!o.getClass().equals(getClass()))
|
||||||
return false;
|
return false;
|
||||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput other = (BlockUntilInitScriptStatusIsZeroThenReturnOutput) obj;
|
BlockUntilInitScriptStatusIsZeroThenReturnOutput that = BlockUntilInitScriptStatusIsZeroThenReturnOutput.class
|
||||||
if (commandRunner == null) {
|
.cast(o);
|
||||||
if (other.commandRunner != null)
|
return Objects.equal(this.commandRunner, that.commandRunner);
|
||||||
return false;
|
|
||||||
} else if (!commandRunner.equals(other.commandRunner))
|
|
||||||
return false;
|
|
||||||
if (logger == null) {
|
|
||||||
if (other.logger != null)
|
|
||||||
return false;
|
|
||||||
} else if (!logger.equals(other.logger))
|
|
||||||
return false;
|
|
||||||
if (notRunningAnymore == null) {
|
|
||||||
if (other.notRunningAnymore != null)
|
|
||||||
return false;
|
|
||||||
} else if (!notRunningAnymore.equals(other.notRunningAnymore))
|
|
||||||
return false;
|
|
||||||
if (shouldCancel != other.shouldCancel)
|
|
||||||
return false;
|
|
||||||
if (userThreads == null) {
|
|
||||||
if (other.userThreads != null)
|
|
||||||
return false;
|
|
||||||
} else if (!userThreads.equals(other.userThreads))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -192,7 +195,9 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
||||||
try {
|
try {
|
||||||
return super.get(timeout, unit);
|
return super.get(timeout, unit);
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
throw new ScriptStillRunningException(timeout, unit, this);
|
ScriptStillRunningException exception = new ScriptStillRunningException(timeout, unit, this);
|
||||||
|
exception.initCause(e);
|
||||||
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
@ -104,8 +104,8 @@ public class InitScriptConfigurationForTasks {
|
||||||
*
|
*
|
||||||
* @return the naming convention of init scripts. ex. {@code /tmp/init-%s}, noting logs are under
|
* @return the naming convention of init scripts. ex. {@code /tmp/init-%s}, noting logs are under
|
||||||
* the basedir/%s where %s is the taskName
|
* the basedir/%s where %s is the taskName
|
||||||
* @see InitBuilder#getHomeDir
|
* @see InitScript#getHomeDir
|
||||||
* @see InitBuilder#getLogDir
|
* @see InitScript#getLogDir
|
||||||
*/
|
*/
|
||||||
public String getInitScriptPattern() {
|
public String getInitScriptPattern() {
|
||||||
return initScriptPattern;
|
return initScriptPattern;
|
||||||
|
|
|
@ -21,19 +21,15 @@ package org.jclouds.compute.callables;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
|
import org.jclouds.compute.events.InitScriptOnNodeSubmission;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeCompletion;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeFailure;
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
|
||||||
import org.jclouds.scriptbuilder.domain.AdminAccessVisitor;
|
import org.jclouds.scriptbuilder.domain.AdminAccessVisitor;
|
||||||
import org.jclouds.scriptbuilder.domain.AppendFile;
|
import org.jclouds.scriptbuilder.domain.AppendFile;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
@ -45,6 +41,8 @@ import org.jclouds.ssh.SshException;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.assistedinject.AssistedInject;
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
|
||||||
|
@ -53,28 +51,18 @@ import com.google.inject.assistedinject.AssistedInject;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager implements RunScriptOnNode {
|
public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager implements RunScriptOnNode {
|
||||||
@Resource
|
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
protected final String initFile;
|
protected final EventBus eventBus;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the absolute path to the file on disk relating to this task.
|
|
||||||
*/
|
|
||||||
public String getInitFile() {
|
|
||||||
return initFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AssistedInject
|
@AssistedInject
|
||||||
public RunScriptOnNodeAsInitScriptUsingSsh(Function<NodeMetadata, SshClient> sshFactory,
|
public RunScriptOnNodeAsInitScriptUsingSsh(Function<NodeMetadata, SshClient> sshFactory, EventBus eventBus,
|
||||||
InitScriptConfigurationForTasks initScriptConfiguration, @Assisted NodeMetadata node,
|
InitScriptConfigurationForTasks initScriptConfiguration, @Assisted NodeMetadata node,
|
||||||
@Assisted Statement script, @Assisted RunScriptOptions options) {
|
@Assisted Statement script, @Assisted RunScriptOptions options) {
|
||||||
super(sshFactory, options.shouldRunAsRoot(), checkNotNull(node, "node"),
|
super(sshFactory, options.shouldRunAsRoot(), checkNotNull(node, "node"),
|
||||||
checkNotNull(script, "script") instanceof InitBuilder ? InitBuilder.class.cast(script)
|
initScriptConfiguration, checkNotNull(script, "script") instanceof InitScript ? InitScript.class.cast(script)
|
||||||
: createInitScript(checkNotNull(initScriptConfiguration, "initScriptConfiguration"), options
|
: createInitScript(checkNotNull(initScriptConfiguration, "initScriptConfiguration"), options
|
||||||
.getTaskName(), script));
|
.getTaskName(), script));
|
||||||
this.initFile = String.format(initScriptConfiguration.getInitScriptPattern(), init.getInstanceName());
|
this.eventBus = checkNotNull(eventBus, "eventBus");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,19 +76,20 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
||||||
checkState(ssh != null, "please call init() before invoking call");
|
checkState(ssh != null, "please call init() before invoking call");
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
return doCall();
|
ExecResponse returnVal = doCall();
|
||||||
|
eventBus.post(new StatementOnNodeCompletion(init, node, returnVal));
|
||||||
|
return returnVal;
|
||||||
} finally {
|
} finally {
|
||||||
if (ssh != null)
|
if (ssh != null)
|
||||||
ssh.disconnect();
|
ssh.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InitBuilder createInitScript(InitScriptConfigurationForTasks config, String name, Statement script) {
|
public static InitScript createInitScript(InitScriptConfigurationForTasks config, String name, Statement script) {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = "jclouds-script-" + config.getAnonymousTaskSuffixSupplier().get();
|
name = "jclouds-script-" + config.getAnonymousTaskSuffixSupplier().get();
|
||||||
}
|
}
|
||||||
return new InitBuilder(name, config.getBasedir() + "/" + name, config.getBasedir() + "/" + name, Collections
|
return InitScript.builder().name(name).home(config.getBasedir() + "/" + name).run(script).build();
|
||||||
.<String, String> emptyMap(), Collections.singleton(script));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void refreshSshIfNewAdminCredentialsConfigured(AdminAccess input) {
|
protected void refreshSshIfNewAdminCredentialsConfigured(AdminAccess input) {
|
||||||
|
@ -115,10 +104,13 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExecResponse doCall() {
|
protected ExecResponse doCall() {
|
||||||
|
eventBus.post(new InitScriptOnNodeSubmission(init, node));
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
ssh.put(initFile, init.render(OsFamily.UNIX));
|
ssh.put(initFile, init.render(OsFamily.UNIX));
|
||||||
} catch (SshException e) {
|
} catch (SshException e) {
|
||||||
// If there's a problem with the sftp configuration, we can try via ssh exec
|
// If there's a problem with the sftp configuration, we can try via
|
||||||
|
// ssh exec
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
logger.warn(e, "<< (%s) problem using sftp [%s], attempting via sshexec", ssh.toString(), e.getMessage());
|
logger.warn(e, "<< (%s) problem using sftp [%s], attempting via sshexec", ssh.toString(), e.getMessage());
|
||||||
else
|
else
|
||||||
|
@ -127,7 +119,7 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ssh.exec("rm " + initFile);
|
ssh.exec("rm " + initFile);
|
||||||
ssh.exec(Statements.appendFile(initFile, Splitter.on('\n').split(init.render(OsFamily.UNIX)),
|
ssh.exec(Statements.appendFile(initFile, Splitter.on('\n').split(init.render(OsFamily.UNIX)),
|
||||||
AppendFile.MARKER + "_" + init.getInstanceName()).render(OsFamily.UNIX));
|
AppendFile.DELIMETER + "_" + init.getInstanceName()).render(OsFamily.UNIX));
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh.exec("chmod 755 " + initFile);
|
ssh.exec("chmod 755 " + initFile);
|
||||||
|
@ -143,6 +135,10 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
||||||
|
|
||||||
});
|
});
|
||||||
return runAction("start");
|
return runAction("start");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
eventBus.post(new StatementOnNodeFailure(init, node, e));
|
||||||
|
throw Throwables.propagate(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupLinkToInitFile() {
|
protected void setupLinkToInitFile() {
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package org.jclouds.compute.callables;
|
package org.jclouds.compute.callables;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -27,6 +26,7 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeFailure;
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
@ -34,6 +34,7 @@ import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,9 +48,10 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete extends Ru
|
||||||
@Inject
|
@Inject
|
||||||
public RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
public RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory, Timeouts timeouts,
|
BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory, Timeouts timeouts,
|
||||||
Function<NodeMetadata, SshClient> sshFactory, InitScriptConfigurationForTasks initScriptConfiguration,
|
Function<NodeMetadata, SshClient> sshFactory, EventBus eventBus,
|
||||||
@Assisted NodeMetadata node, @Assisted Statement script, @Assisted RunScriptOptions options) {
|
InitScriptConfigurationForTasks initScriptConfiguration, @Assisted NodeMetadata node,
|
||||||
super(sshFactory, initScriptConfiguration, node, script, options);
|
@Assisted Statement script, @Assisted RunScriptOptions options) {
|
||||||
|
super(sshFactory, eventBus, initScriptConfiguration, node, script, options);
|
||||||
this.statusFactory = checkNotNull(statusFactory, "statusFactory");
|
this.statusFactory = checkNotNull(statusFactory, "statusFactory");
|
||||||
this.timeouts = checkNotNull(timeouts, "timeouts");
|
this.timeouts = checkNotNull(timeouts, "timeouts");
|
||||||
}
|
}
|
||||||
|
@ -58,16 +60,21 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete extends Ru
|
||||||
public ExecResponse doCall() {
|
public ExecResponse doCall() {
|
||||||
try {
|
try {
|
||||||
return future().get(timeouts.scriptComplete, TimeUnit.MILLISECONDS);
|
return future().get(timeouts.scriptComplete, TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Throwable e) {
|
||||||
Throwables.propagate(e);
|
eventBus.post(new StatementOnNodeFailure(init, node, e));
|
||||||
return null;
|
throw Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockUntilInitScriptStatusIsZeroThenReturnOutput future() {
|
public BlockUntilInitScriptStatusIsZeroThenReturnOutput future() {
|
||||||
ExecResponse returnVal = super.doCall();
|
ExecResponse returnVal = super.doCall();
|
||||||
checkState(returnVal.getExitCode() == 0, String.format("task: %s had non-zero exit status: %s", init
|
if (returnVal.getExitStatus() != 0) {
|
||||||
.getInstanceName(), returnVal));
|
IllegalStateException e = new IllegalStateException(String.format(
|
||||||
|
"instance: %s on node: %s had non-zero exit status: %s", init.getInstanceName(), getNode().getId(),
|
||||||
|
returnVal));
|
||||||
|
eventBus.post(new StatementOnNodeFailure(init, node, e));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
return statusFactory.create(this).init();
|
return statusFactory.create(this).init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@ import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeFailure;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeCompletion;
|
||||||
|
import org.jclouds.compute.events.StatementOnNodeSubmission;
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
@ -36,6 +39,8 @@ import org.jclouds.ssh.SshClient;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.google.inject.assistedinject.AssistedInject;
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
|
||||||
|
@ -51,6 +56,7 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
protected final Function<NodeMetadata, SshClient> sshFactory;
|
protected final Function<NodeMetadata, SshClient> sshFactory;
|
||||||
|
protected final EventBus eventBus;
|
||||||
protected final NodeMetadata node;
|
protected final NodeMetadata node;
|
||||||
protected final Statement statement;
|
protected final Statement statement;
|
||||||
protected final boolean runAsRoot;
|
protected final boolean runAsRoot;
|
||||||
|
@ -58,9 +64,10 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
|
||||||
protected SshClient ssh;
|
protected SshClient ssh;
|
||||||
|
|
||||||
@AssistedInject
|
@AssistedInject
|
||||||
public RunScriptOnNodeUsingSsh(Function<NodeMetadata, SshClient> sshFactory, @Assisted NodeMetadata node,
|
public RunScriptOnNodeUsingSsh(Function<NodeMetadata, SshClient> sshFactory, EventBus eventBus,
|
||||||
@Assisted Statement statement, @Assisted RunScriptOptions options) {
|
@Assisted NodeMetadata node, @Assisted Statement statement, @Assisted RunScriptOptions options) {
|
||||||
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
||||||
|
this.eventBus = checkNotNull(eventBus, "eventBus");
|
||||||
this.node = checkNotNull(node, "node");
|
this.node = checkNotNull(node, "node");
|
||||||
this.statement = checkNotNull(statement, "statement");
|
this.statement = checkNotNull(statement, "statement");
|
||||||
this.runAsRoot = options.shouldRunAsRoot();
|
this.runAsRoot = options.shouldRunAsRoot();
|
||||||
|
@ -72,13 +79,20 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ExecResponse returnVal;
|
ExecResponse returnVal;
|
||||||
|
eventBus.post(new StatementOnNodeSubmission(statement, node));
|
||||||
String command = (runAsRoot) ? execAsRoot(statement.render(OsFamily.UNIX)) : execScriptAsDefaultUser(statement
|
String command = (runAsRoot) ? execAsRoot(statement.render(OsFamily.UNIX)) : execScriptAsDefaultUser(statement
|
||||||
.render(OsFamily.UNIX));
|
.render(OsFamily.UNIX));
|
||||||
|
try {
|
||||||
returnVal = runCommand(command);
|
returnVal = runCommand(command);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
eventBus.post(new StatementOnNodeFailure(statement, node, e));
|
||||||
|
throw Throwables.propagate(e);
|
||||||
|
}
|
||||||
|
eventBus.post(new StatementOnNodeCompletion(statement, node, returnVal));
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
logger.trace("<< %s[%s]", statement, returnVal);
|
logger.trace("<< %s[%s]", statement, returnVal);
|
||||||
else
|
else
|
||||||
logger.debug("<< %s(%d)", statement, returnVal.getExitCode());
|
logger.debug("<< %s(%d)", statement, returnVal.getExitStatus());
|
||||||
return returnVal;
|
return returnVal;
|
||||||
} finally {
|
} finally {
|
||||||
if (ssh != null)
|
if (ssh != null)
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -47,16 +47,25 @@ public class SudoAwareInitManager {
|
||||||
protected Logger computeLogger = Logger.NULL;
|
protected Logger computeLogger = Logger.NULL;
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
protected NodeMetadata node;
|
protected NodeMetadata node;
|
||||||
protected final InitBuilder init;
|
protected final String initFile;
|
||||||
|
protected final InitScript init;
|
||||||
protected final boolean runAsRoot;
|
protected final boolean runAsRoot;
|
||||||
protected final Function<NodeMetadata, SshClient> sshFactory;
|
protected final Function<NodeMetadata, SshClient> sshFactory;
|
||||||
protected SshClient ssh;
|
protected SshClient ssh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the absolute path to the file on disk relating to this task.
|
||||||
|
*/
|
||||||
|
public String getInitFile() {
|
||||||
|
return initFile;
|
||||||
|
}
|
||||||
|
|
||||||
public SudoAwareInitManager(Function<NodeMetadata, SshClient> sshFactory, boolean runAsRoot, NodeMetadata node,
|
public SudoAwareInitManager(Function<NodeMetadata, SshClient> sshFactory, boolean runAsRoot, NodeMetadata node,
|
||||||
InitBuilder init) {
|
InitScriptConfigurationForTasks initScriptConfiguration, InitScript init) {
|
||||||
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
||||||
this.runAsRoot = runAsRoot;
|
this.runAsRoot = runAsRoot;
|
||||||
this.node = checkNotNull(node, "node");
|
this.node = checkNotNull(node, "node");
|
||||||
|
this.initFile = String.format(initScriptConfiguration.getInitScriptPattern(), init.getInstanceName());
|
||||||
this.init = checkNotNull(init, "init");
|
this.init = checkNotNull(init, "init");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,41 +91,44 @@ public class SudoAwareInitManager {
|
||||||
: execScriptAsDefaultUser(action);
|
: execScriptAsDefaultUser(action);
|
||||||
returnVal = runCommand(command);
|
returnVal = runCommand(command);
|
||||||
if ("status".equals(action))
|
if ("status".equals(action))
|
||||||
logger.trace("<< %s(%d)", action, returnVal.getExitCode());
|
logger.trace("<< %s(%d)", action, returnVal.getExitStatus());
|
||||||
else if (computeLogger.isTraceEnabled())
|
else if (computeLogger.isTraceEnabled())
|
||||||
computeLogger.trace("<< %s[%s]", action, returnVal);
|
computeLogger.trace("<< %s[%s]", action, returnVal);
|
||||||
else
|
else
|
||||||
computeLogger.debug("<< %s(%d)", action, returnVal.getExitCode());
|
computeLogger.debug("<< %s(%d)", action, returnVal.getExitStatus());
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecResponse runCommand(String command) {
|
ExecResponse runCommand(String command) {
|
||||||
String statement = String.format(">> running [%s] as %s@%s", command.replace(
|
String statement = String.format("[%s] as %s@%s", command.replace(
|
||||||
node.getCredentials().getPassword() != null ? node.getCredentials().getPassword() : "XXXXX", "XXXXX"), ssh
|
node.getCredentials().getPassword() != null ? node.getCredentials().getPassword() : "XXXXX", "XXXXX"), ssh
|
||||||
.getUsername(), ssh.getHostAddress());
|
.getUsername(), ssh.getHostAddress());
|
||||||
if (command.endsWith("status"))
|
if (command.endsWith("status"))
|
||||||
logger.trace(statement);
|
logger.trace(">> running " + statement);
|
||||||
else
|
else
|
||||||
computeLogger.debug(statement);
|
computeLogger.debug(">> running " + statement);
|
||||||
return ssh.exec(command);
|
ExecResponse returnVal = ssh.exec(command);
|
||||||
|
if (!command.endsWith("status"))
|
||||||
|
checkState(returnVal.getExitStatus() == 0, "error running %s; returnVal !=0: %s", statement, returnVal);
|
||||||
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
String execScriptAsRoot(String action) {
|
String execScriptAsRoot(String action) {
|
||||||
String command;
|
String command;
|
||||||
if (node.getCredentials().identity.equals("root")) {
|
if (node.getCredentials().identity.equals("root")) {
|
||||||
command = "./" + init.getInstanceName() + " " + action;
|
command = initFile + " " + action;
|
||||||
} else if (node.getCredentials().shouldAuthenticateSudo()) {
|
} else if (node.getCredentials().shouldAuthenticateSudo()) {
|
||||||
command = String.format("echo '%s'|sudo -S ./%s %s", node.getCredentials().getPassword(),
|
command = String.format("echo '%s'|sudo -S %s %s", node.getCredentials().getPassword(),
|
||||||
init.getInstanceName(), action);
|
initFile, action);
|
||||||
} else {
|
} else {
|
||||||
command = "sudo ./" + init.getInstanceName() + " " + action;
|
command = "sudo " + initFile + " " + action;
|
||||||
}
|
}
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String execScriptAsDefaultUser(String action) {
|
protected String execScriptAsDefaultUser(String action) {
|
||||||
return "./" + init.getInstanceName() + " " + action;
|
return initFile + " " + action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeMetadata getNode() {
|
public NodeMetadata getNode() {
|
||||||
|
@ -125,11 +137,11 @@ public class SudoAwareInitManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Objects.toStringHelper(this).add("node", node).add("name", init.getInstanceName())
|
return Objects.toStringHelper(this).add("node", node.getId()).add("name", init.getInstanceName())
|
||||||
.add("runAsRoot", runAsRoot).toString();
|
.add("runAsRoot", runAsRoot).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InitBuilder getStatement() {
|
public InitScript getStatement() {
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,19 +20,21 @@ package org.jclouds.compute.domain;
|
||||||
|
|
||||||
import org.jclouds.compute.config.CustomizationResponse;
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ExecResponse implements CustomizationResponse {
|
public class ExecResponse implements CustomizationResponse {
|
||||||
|
|
||||||
private final String error;
|
|
||||||
private final String output;
|
private final String output;
|
||||||
private final int exitCode;
|
private final String error;
|
||||||
|
private final int exitStatus;
|
||||||
|
|
||||||
public ExecResponse(String output, String error, int exitCode) {
|
public ExecResponse(String output, String error, int exitStatus) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
this.error = error;
|
this.error = error;
|
||||||
this.exitCode = exitCode;
|
this.exitStatus = exitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getError() {
|
public String getError() {
|
||||||
|
@ -43,47 +45,38 @@ public class ExecResponse implements CustomizationResponse {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String toString() {
|
* @see #getExitStatus
|
||||||
return "[output=" + output + ", error=" + error + ", exitCode=" + exitCode + "]";
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public int getExitCode() {
|
||||||
|
return exitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExitStatus() {
|
||||||
|
return exitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
return Objects.hashCode(output, error, exitStatus);
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((error == null) ? 0 : error.hashCode());
|
|
||||||
result = prime * result + exitCode;
|
|
||||||
result = prime * result + ((output == null) ? 0 : output.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object o) {
|
||||||
if (this == obj)
|
if (o == null)
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (!o.getClass().equals(getClass()))
|
||||||
return false;
|
return false;
|
||||||
ExecResponse other = (ExecResponse) obj;
|
ExecResponse that = ExecResponse.class.cast(o);
|
||||||
if (error == null) {
|
return Objects.equal(this.output, that.output) && Objects.equal(this.error, that.error)
|
||||||
if (other.error != null)
|
&& Objects.equal(this.exitStatus, that.exitStatus);
|
||||||
return false;
|
|
||||||
} else if (!error.equals(other.error))
|
|
||||||
return false;
|
|
||||||
if (exitCode != other.exitCode)
|
|
||||||
return false;
|
|
||||||
if (output == null) {
|
|
||||||
if (other.output != null)
|
|
||||||
return false;
|
|
||||||
} else if (!output.equals(other.output))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExitCode() {
|
@Override
|
||||||
return exitCode;
|
public String toString() {
|
||||||
|
return Objects.toStringHelper("").add("output", output).add("error", error).add("exitStatus", exitStatus)
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -220,7 +220,6 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
||||||
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
|
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
|
||||||
result = prime * result + ((hardware == null) ? 0 : hardware.hashCode());
|
result = prime * result + ((hardware == null) ? 0 : hardware.hashCode());
|
||||||
result = prime * result + ((os == null) ? 0 : os.hashCode());
|
result = prime * result + ((os == null) ? 0 : os.hashCode());
|
||||||
result = prime * result + ((credentials == null) ? 0 : credentials.hashCode());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,11 +269,6 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
||||||
return false;
|
return false;
|
||||||
} else if (!os.equals(other.os))
|
} else if (!os.equals(other.os))
|
||||||
return false;
|
return false;
|
||||||
if (credentials == null) {
|
|
||||||
if (other.credentials != null)
|
|
||||||
return false;
|
|
||||||
} else if (!credentials.equals(other.credentials))
|
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.compute.events;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An init script was submitted to a node for exectuion.
|
||||||
|
* <p/>
|
||||||
|
* Note this does not guarantee that there was success, nor that the init script started.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class InitScriptOnNodeSubmission extends StatementOnNodeSubmission {
|
||||||
|
|
||||||
|
public InitScriptOnNodeSubmission(InitScript statement, NodeMetadata node) {
|
||||||
|
super(statement, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitScript getStatement() {
|
||||||
|
return InitScript.class.cast(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.compute.events;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class StatementOnNode {
|
||||||
|
protected final Statement statement;
|
||||||
|
protected final NodeMetadata node;
|
||||||
|
|
||||||
|
public StatementOnNode(Statement statement, NodeMetadata node) {
|
||||||
|
this.statement = checkNotNull(statement, "statement");
|
||||||
|
this.node = checkNotNull(node, "node");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement getStatement() {
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeMetadata getNode() {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(statement, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null)
|
||||||
|
return false;
|
||||||
|
if (!o.getClass().equals(getClass()))
|
||||||
|
return false;
|
||||||
|
StatementOnNode that = StatementOnNode.class.cast(o);
|
||||||
|
return Objects.equal(this.statement, that.statement) && Objects.equal(this.node, that.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return string().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ToStringHelper string() {
|
||||||
|
return Objects.toStringHelper(this).add("statement", statement).add("node", node.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.compute.events;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A statement that completed execution on a node.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class StatementOnNodeCompletion extends StatementOnNode {
|
||||||
|
|
||||||
|
private final ExecResponse response;
|
||||||
|
|
||||||
|
public StatementOnNodeCompletion(Statement statement, NodeMetadata node, ExecResponse response) {
|
||||||
|
super(statement, node);
|
||||||
|
this.response = checkNotNull(response, "response");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecResponse getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ToStringHelper string() {
|
||||||
|
return super.string().add("response", response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.compute.events;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A statement that failed execution on a node.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class StatementOnNodeFailure extends StatementOnNode {
|
||||||
|
|
||||||
|
private final Throwable cause;
|
||||||
|
|
||||||
|
public StatementOnNodeFailure(Statement statement, NodeMetadata node, Throwable cause) {
|
||||||
|
super(statement, node);
|
||||||
|
this.cause = checkNotNull(cause, "cause");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getCause() {
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ToStringHelper string() {
|
||||||
|
return super.string().add("cause", cause.getMessage());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.compute.events;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A statement was submitted to a node for exectuion.
|
||||||
|
* <p/>
|
||||||
|
* Note this does not guarantee that there was success, nor that the node
|
||||||
|
* received the statement.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class StatementOnNodeSubmission extends StatementOnNode {
|
||||||
|
|
||||||
|
public StatementOnNodeSubmission(Statement statement, NodeMetadata node) {
|
||||||
|
super(statement, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||||
import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
|
import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
|
||||||
|
@ -51,7 +51,7 @@ public class TemplateOptionsToStatement implements Function<TemplateOptions, Sta
|
||||||
if (options.getPrivateKey() != null)
|
if (options.getPrivateKey() != null)
|
||||||
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
||||||
if (bootstrap.size() >= 1) {
|
if (bootstrap.size() >= 1) {
|
||||||
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitBuilder))
|
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitScript))
|
||||||
options.nameTask("bootstrap");
|
options.nameTask("bootstrap");
|
||||||
return bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap);
|
return bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,11 @@ public class ScriptStatusReturnsZero implements Predicate<ScriptStatusReturnsZer
|
||||||
logger.trace("looking for [%s] state on %s@%s", commandUsingClient.command, commandUsingClient.client
|
logger.trace("looking for [%s] state on %s@%s", commandUsingClient.command, commandUsingClient.client
|
||||||
.getUsername(), commandUsingClient.client.getHostAddress());
|
.getUsername(), commandUsingClient.client.getHostAddress());
|
||||||
ExecResponse response = refresh(commandUsingClient);
|
ExecResponse response = refresh(commandUsingClient);
|
||||||
while (response.getExitCode() == -1)
|
while (response.getExitStatus() == -1)
|
||||||
response = refresh(commandUsingClient);
|
response = refresh(commandUsingClient);
|
||||||
logger.trace("%s@%s: looking for exit code 0: currently: %s", commandUsingClient.client.getUsername(),
|
logger.trace("%s@%s: looking for exit code 0: currently: %s", commandUsingClient.client.getUsername(),
|
||||||
commandUsingClient.client.getHostAddress(), response.getExitCode());
|
commandUsingClient.client.getHostAddress(), response.getExitStatus());
|
||||||
return 0 == response.getExitCode();
|
return 0 == response.getExitStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecResponse refresh(CommandUsingClient commandUsingClient) {
|
private ExecResponse refresh(CommandUsingClient commandUsingClient) {
|
||||||
|
|
|
@ -67,8 +67,8 @@ public class RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements C
|
||||||
tainted = true;
|
tainted = true;
|
||||||
try {
|
try {
|
||||||
ExecResponse exec = runScriptOnNode.call();
|
ExecResponse exec = runScriptOnNode.call();
|
||||||
logger.trace("<< script output for node(%s): %s", runScriptOnNode.getNode().getId(), exec);
|
|
||||||
logger.debug("<< options applied node(%s)", runScriptOnNode.getNode().getId());
|
logger.debug("<< options applied node(%s)", runScriptOnNode.getNode().getId());
|
||||||
|
logger.trace("<< script output for node(%s): %s", runScriptOnNode.getNode().getId(), exec);
|
||||||
goodNodes.put(runScriptOnNode.getNode(), exec);
|
goodNodes.put(runScriptOnNode.getNode(), exec);
|
||||||
return exec;
|
return exec;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
(merge
|
(merge
|
||||||
{:exit 0 :err "stderr" :out "stdout"}
|
{:exit 0 :err "stderr" :out "stdout"}
|
||||||
(condp = cmd
|
(condp = cmd
|
||||||
"./bootstrap status" {:exit 1 :out "[]"}
|
"/tmp/init-bootstrap status" {:exit 1 :out "[]"}
|
||||||
{})))
|
{})))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
||||||
|
|
||||||
response = future.get(3, TimeUnit.MINUTES);
|
response = future.get(3, TimeUnit.MINUTES);
|
||||||
|
|
||||||
assert response.getExitCode() == 0 : node.getId() + ": " + response;
|
assert response.getExitStatus() == 0 : node.getId() + ": " + response;
|
||||||
|
|
||||||
node = client.getNodeMetadata(node.getId());
|
node = client.getNodeMetadata(node.getId());
|
||||||
// test that the node updated to the correct admin user!
|
// test that the node updated to the correct admin user!
|
||||||
|
@ -265,7 +265,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
||||||
|
|
||||||
weCanCancelTasks(node);
|
weCanCancelTasks(node);
|
||||||
|
|
||||||
assert response.getExitCode() == 0 : node.getId() + ": " + response;
|
assert response.getExitStatus() == 0 : node.getId() + ": " + response;
|
||||||
|
|
||||||
response = client.runScriptOnNode(node.getId(), "echo $USER", wrapInInitScript(false).runAsRoot(false));
|
response = client.runScriptOnNode(node.getId(), "echo $USER", wrapInInitScript(false).runAsRoot(false));
|
||||||
|
|
||||||
|
@ -304,11 +304,11 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
||||||
assert false : node.getId() + ": " + response;
|
assert false : node.getId() + ": " + response;
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
assert !future.isDone();
|
assert !future.isDone();
|
||||||
response = client.runScriptOnNode(node.getId(), Statements.exec("./sleeper status"), wrapInInitScript(false)
|
response = client.runScriptOnNode(node.getId(), Statements.exec("/tmp/init-sleeper status"), wrapInInitScript(false)
|
||||||
.runAsRoot(false));
|
.runAsRoot(false));
|
||||||
assert !response.getOutput().trim().equals("") : node.getId() + ": " + response;
|
assert !response.getOutput().trim().equals("") : node.getId() + ": " + response;
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
response = client.runScriptOnNode(node.getId(), Statements.exec("./sleeper status"), wrapInInitScript(false)
|
response = client.runScriptOnNode(node.getId(), Statements.exec("/tmp/init-sleeper status"), wrapInInitScript(false)
|
||||||
.runAsRoot(false));
|
.runAsRoot(false));
|
||||||
assert response.getOutput().trim().equals("") : node.getId() + ": " + response;
|
assert response.getOutput().trim().equals("") : node.getId() + ": " + response;
|
||||||
try {
|
try {
|
||||||
|
@ -592,10 +592,10 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
||||||
|
|
||||||
IPSocket socket = new IPSocket(Iterables.get(node.getPublicAddresses(), 0), 8080);
|
IPSocket socket = new IPSocket(Iterables.get(node.getPublicAddresses(), 0), 8080);
|
||||||
assert preciseSocketTester.apply(socket) : String.format("failed to open socket %s on node %s:%n%s%s", socket,
|
assert preciseSocketTester.apply(socket) : String.format("failed to open socket %s on node %s:%n%s%s", socket,
|
||||||
node, init(node, processName, "tail"), init(node, processName, "tailerr"));
|
node, init(node, processName, "stdout"), init(node, processName, "stderr"));
|
||||||
stats.socketOpenMilliseconds = watch.elapsedTime(TimeUnit.MILLISECONDS);
|
stats.socketOpenMilliseconds = watch.elapsedTime(TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
exec = init(node, processName, "tail");
|
exec = init(node, processName, "stdout");
|
||||||
|
|
||||||
Matcher matcher = parseReported.matcher(exec.getOutput());
|
Matcher matcher = parseReported.matcher(exec.getOutput());
|
||||||
if (matcher.find())
|
if (matcher.find())
|
||||||
|
@ -606,7 +606,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecResponse init(NodeMetadata node, String processName, String command) {
|
public ExecResponse init(NodeMetadata node, String processName, String command) {
|
||||||
return client.runScriptOnNode(node.getId(), "./" + processName + " "+command, runAsRoot(false)
|
return client.runScriptOnNode(node.getId(), "/tmp/init-" + processName + " "+command, runAsRoot(false)
|
||||||
.wrapInInitScript(false));
|
.wrapInInitScript(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,13 +716,13 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
||||||
|
|
||||||
}), "jboss", node, JBOSS_PATTERN);
|
}), "jboss", node, JBOSS_PATTERN);
|
||||||
|
|
||||||
client.runScriptOnNode(nodeId, "./jboss stop", runAsRoot(false).wrapInInitScript(false));
|
client.runScriptOnNode(nodeId, "/tmp/init-jboss stop", runAsRoot(false).wrapInInitScript(false));
|
||||||
|
|
||||||
trackAvailabilityOfProcessOnNode(context.utils().userExecutor().submit(new Callable<ExecResponse>() {
|
trackAvailabilityOfProcessOnNode(context.utils().userExecutor().submit(new Callable<ExecResponse>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecResponse call() {
|
public ExecResponse call() {
|
||||||
return client.runScriptOnNode(nodeId, "./jboss start", runAsRoot(false).wrapInInitScript(false));
|
return client.runScriptOnNode(nodeId, "/tmp/init-jboss start", runAsRoot(false).wrapInInitScript(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
|
|
||||||
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
||||||
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
||||||
|
private static final ExecResponse EXEC_RC_GOOD = new ExecResponse("0", "", 0);
|
||||||
|
|
||||||
public StubComputeServiceIntegrationTest() {
|
public StubComputeServiceIntegrationTest() {
|
||||||
provider = "stub";
|
provider = "stub";
|
||||||
|
@ -268,13 +269,15 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
expect(client.exec("ln -fs /tmp/init-" + scriptName + " " + scriptName)).andReturn(EXEC_GOOD);
|
expect(client.exec("ln -fs /tmp/init-" + scriptName + " " + scriptName)).andReturn(EXEC_GOOD);
|
||||||
expect(client.getUsername()).andReturn("root").atLeastOnce();
|
expect(client.getUsername()).andReturn("root").atLeastOnce();
|
||||||
expect(client.getHostAddress()).andReturn("localhost").atLeastOnce();
|
expect(client.getHostAddress()).andReturn("localhost").atLeastOnce();
|
||||||
expect(client.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||||
// next status says the script is done, since not found.
|
// next status says the script is done, since not found.
|
||||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_BAD);
|
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||||
expect(client.exec("./" + scriptName + " tail")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " stdout")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " stderr")).andReturn(EXEC_GOOD);
|
||||||
|
expect(client.exec("/tmp/init-" + scriptName + " exitstatus")).andReturn(EXEC_RC_GOOD);
|
||||||
|
|
||||||
// note we have to reconnect here, as we updated the login user.
|
// note we have to reconnect here, as we updated the login user.
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
|
|
||||||
|
@ -307,23 +310,23 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
expect(clientNew.exec("ln -fs /tmp/init-" + scriptName + " " + scriptName)).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("ln -fs /tmp/init-" + scriptName + " " + scriptName)).andReturn(EXEC_GOOD);
|
||||||
expect(clientNew.getUsername()).andReturn("web").atLeastOnce();
|
expect(clientNew.getUsername()).andReturn("web").atLeastOnce();
|
||||||
expect(clientNew.getHostAddress()).andReturn("localhost").atLeastOnce();
|
expect(clientNew.getHostAddress()).andReturn("localhost").atLeastOnce();
|
||||||
expect(clientNew.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("/tmp/init-" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||||
expect(clientNew.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("/tmp/init-" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||||
clientNew.disconnect();
|
clientNew.disconnect();
|
||||||
clientNew.connect();
|
clientNew.connect();
|
||||||
expect(clientNew.exec("./" + scriptName + " tail\n")).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("/tmp/init-" + scriptName + " stdout\n")).andReturn(EXEC_GOOD);
|
||||||
clientNew.disconnect();
|
clientNew.disconnect();
|
||||||
|
|
||||||
clientNew.connect();
|
clientNew.connect();
|
||||||
expect(clientNew.exec("./" + scriptName + " stop\n")).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("/tmp/init-" + scriptName + " stop\n")).andReturn(EXEC_GOOD);
|
||||||
clientNew.disconnect();
|
clientNew.disconnect();
|
||||||
|
|
||||||
clientNew.connect();
|
clientNew.connect();
|
||||||
expect(clientNew.exec("./" + scriptName + " start\n")).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("/tmp/init-" + scriptName + " start\n")).andReturn(EXEC_GOOD);
|
||||||
clientNew.disconnect();
|
clientNew.disconnect();
|
||||||
|
|
||||||
clientNew.connect();
|
clientNew.connect();
|
||||||
expect(clientNew.exec("./" + scriptName + " tail\n")).andReturn(EXEC_GOOD);
|
expect(clientNew.exec("/tmp/init-" + scriptName + " stdout\n")).andReturn(EXEC_GOOD);
|
||||||
clientNew.disconnect();
|
clientNew.disconnect();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
@ -352,13 +355,14 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
expect(client.exec("ln -fs /tmp/init-" + scriptName + " " + scriptName)).andReturn(EXEC_GOOD);
|
expect(client.exec("ln -fs /tmp/init-" + scriptName + " " + scriptName)).andReturn(EXEC_GOOD);
|
||||||
expect(client.getUsername()).andReturn("root").atLeastOnce();
|
expect(client.getUsername()).andReturn("root").atLeastOnce();
|
||||||
expect(client.getHostAddress()).andReturn(nodeId + "").atLeastOnce();
|
expect(client.getHostAddress()).andReturn(nodeId + "").atLeastOnce();
|
||||||
expect(client.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||||
// next status says the script is done, since not found.
|
// next status says the script is done, since not found.
|
||||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_BAD);
|
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||||
expect(client.exec("./" + scriptName + " tail")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " stdout")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(EXEC_GOOD);
|
expect(client.exec("/tmp/init-" + scriptName + " stderr")).andReturn(EXEC_GOOD);
|
||||||
|
expect(client.exec("/tmp/init-" + scriptName + " exitstatus")).andReturn(EXEC_RC_GOOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void helloAndJava(SshClient client) {
|
private void helloAndJava(SshClient client) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ import org.jclouds.concurrent.MoreExecutors;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.predicates.RetryablePredicateTest;
|
import org.jclouds.predicates.RetryablePredicateTest;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
@ -50,7 +50,7 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.base.Functions;
|
import com.google.common.base.Functions;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
@ -62,6 +62,8 @@ import com.google.inject.name.Names;
|
||||||
@Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest")
|
@Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest")
|
||||||
public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
|
|
||||||
|
EventBus eventBus = new EventBus();
|
||||||
|
|
||||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory = Guice.createInjector(
|
BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory = Guice.createInjector(
|
||||||
new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()),
|
new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()),
|
||||||
new AbstractModule() {
|
new AbstractModule() {
|
||||||
|
@ -98,7 +100,7 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||||
new RunScriptOptions());
|
new RunScriptOptions());
|
||||||
|
|
||||||
testMe.call();
|
testMe.call();
|
||||||
|
@ -137,13 +139,13 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
*/
|
*/
|
||||||
private void runDefaults(IAnswer<ExecResponse> answerForScriptStatus, int timesForScriptStatus) {
|
private void runDefaults(IAnswer<ExecResponse> answerForScriptStatus, int timesForScriptStatus) {
|
||||||
Statement command = exec("doFoo");
|
Statement command = exec("doFoo");
|
||||||
NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
|
NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING)
|
||||||
new LoginCredentials("tester", "testpassword!", null, false)).build();
|
.credentials(LoginCredentials.builder().user("tester").password("testpassword!").build()).build();
|
||||||
|
|
||||||
SshClient sshClient = createMock(SshClient.class);
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
.build();
|
||||||
|
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
@ -154,27 +156,28 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
||||||
new ExecResponse("", "", 0));
|
new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// start script as root via sudo, note that since there's no adminPassword we do a straight
|
// start script as root via sudo, note that since there's no adminPassword we do a straight
|
||||||
// sudo
|
// sudo
|
||||||
expect(sshClient.exec("sudo ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("sudo /tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// signal the command completed
|
// signal the command completed
|
||||||
if (answerForScriptStatus == null) {
|
if (answerForScriptStatus == null) {
|
||||||
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1)).times(1);
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1)).times(1);
|
||||||
} else {
|
} else {
|
||||||
expect(sshClient.exec("./jclouds-script-0 status")).andAnswer(answerForScriptStatus).times(timesForScriptStatus);
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 status")).andAnswer(answerForScriptStatus).times(timesForScriptStatus);
|
||||||
}
|
}
|
||||||
expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stdout")).andReturn(new ExecResponse("out", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stderr")).andReturn(new ExecResponse("err", "", 0));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 exitstatus")).andReturn(new ExecResponse("0", "", 0));
|
||||||
|
|
||||||
sshClient.disconnect();
|
sshClient.disconnect();
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||||
new RunScriptOptions());
|
new RunScriptOptions());
|
||||||
|
|
||||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
@ -195,8 +198,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
|
|
||||||
SshClient sshClient = createMock(SshClient.class);
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
.build();
|
||||||
|
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
@ -207,22 +210,23 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
||||||
new ExecResponse("", "", 0));
|
new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// since there's an adminPassword we must pass this in
|
// since there's an adminPassword we must pass this in
|
||||||
expect(sshClient.exec("echo 'testpassword!'|sudo -S ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("echo 'testpassword!'|sudo -S /tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// signal the command completed
|
// signal the command completed
|
||||||
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
||||||
expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stdout")).andReturn(new ExecResponse("out", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stderr")).andReturn(new ExecResponse("err", "", 0));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 exitstatus")).andReturn(new ExecResponse("0", "", 0));
|
||||||
|
|
||||||
sshClient.disconnect();
|
sshClient.disconnect();
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||||
new RunScriptOptions());
|
new RunScriptOptions());
|
||||||
|
|
||||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
@ -243,8 +247,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
|
|
||||||
SshClient sshClient = createMock(SshClient.class);
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
.build();
|
||||||
|
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
@ -255,22 +259,23 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
||||||
new ExecResponse("", "", 0));
|
new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// kick off as current user
|
// kick off as current user
|
||||||
expect(sshClient.exec("./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// signal the command completed
|
// signal the command completed
|
||||||
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
||||||
expect(sshClient.exec("./jclouds-script-0 tail")).andReturn(new ExecResponse("out", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stdout")).andReturn(new ExecResponse("out", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stderr")).andReturn(new ExecResponse("err", "", 0));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 exitstatus")).andReturn(new ExecResponse("0", "", 0));
|
||||||
|
|
||||||
sshClient.disconnect();
|
sshClient.disconnect();
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||||
new RunScriptOptions().runAsRoot(false));
|
new RunScriptOptions().runAsRoot(false));
|
||||||
|
|
||||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
@ -284,4 +289,53 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||||
verify(sshClient);
|
verify(sshClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testBadReturnCode() {
|
||||||
|
Statement command = exec("doFoo");
|
||||||
|
NodeMetadata node = new NodeMetadataBuilder().ids("badreturncode").state(NodeState.RUNNING).credentials(
|
||||||
|
new LoginCredentials("tester", "testpassword!", null, true)).build();
|
||||||
|
|
||||||
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sshClient.connect();
|
||||||
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
expect(sshClient.getUsername()).andReturn("tester").atLeastOnce();
|
||||||
|
expect(sshClient.getHostAddress()).andReturn("somewhere.example.com").atLeastOnce();
|
||||||
|
|
||||||
|
// setup script as default user
|
||||||
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(
|
||||||
|
new ExecResponse("", "", 0));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
|
// kick off as current user
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
|
// signal the command completed
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stdout")).andReturn(new ExecResponse("out", "", 0));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 stderr")).andReturn(new ExecResponse("err", "", 0));
|
||||||
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 exitstatus")).andReturn(new ExecResponse("1", "", 0));
|
||||||
|
|
||||||
|
sshClient.disconnect();
|
||||||
|
replay(sshClient);
|
||||||
|
|
||||||
|
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||||
|
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||||
|
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||||
|
new RunScriptOptions().runAsRoot(false));
|
||||||
|
|
||||||
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
assertEquals(testMe.getNode(), node);
|
||||||
|
assertEquals(testMe.getStatement(), init);
|
||||||
|
|
||||||
|
testMe.init();
|
||||||
|
|
||||||
|
assertEquals(testMe.call(), new ExecResponse("out", "err", 1));
|
||||||
|
|
||||||
|
verify(sshClient);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
@ -39,13 +39,14 @@ import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Functions;
|
import com.google.common.base.Functions;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshTest")
|
@Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshTest")
|
||||||
public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
|
EventBus eventBus = new EventBus();
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalStateException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testWithoutInitThrowsIllegalStateException() {
|
public void testWithoutInitThrowsIllegalStateException() {
|
||||||
|
@ -58,7 +59,7 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
||||||
.forMap(ImmutableMap.of(node, sshClient)), InitScriptConfigurationForTasks.create()
|
.forMap(ImmutableMap.of(node, sshClient)), eventBus, InitScriptConfigurationForTasks.create()
|
||||||
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions());
|
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions());
|
||||||
|
|
||||||
testMe.call();
|
testMe.call();
|
||||||
|
@ -71,8 +72,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
|
|
||||||
SshClient sshClient = createMock(SshClient.class);
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
.build();
|
||||||
|
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
@ -82,17 +83,17 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
// setup script as default user
|
// setup script as default user
|
||||||
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// start script as root via sudo, note that since there's no adminPassword we do a straight sudo
|
// start script as root via sudo, note that since there's no adminPassword we do a straight sudo
|
||||||
expect(sshClient.exec("sudo ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("sudo /tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
|
|
||||||
sshClient.disconnect();
|
sshClient.disconnect();
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
||||||
.forMap(ImmutableMap.of(node, sshClient)), InitScriptConfigurationForTasks.create()
|
.forMap(ImmutableMap.of(node, sshClient)), eventBus, InitScriptConfigurationForTasks.create()
|
||||||
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions());
|
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions());
|
||||||
|
|
||||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
@ -112,8 +113,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
|
|
||||||
SshClient sshClient = createMock(SshClient.class);
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
.build();
|
||||||
|
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
@ -123,17 +124,17 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
// setup script as default user
|
// setup script as default user
|
||||||
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// since there's an adminPassword we must pass this in
|
// since there's an adminPassword we must pass this in
|
||||||
expect(sshClient.exec("echo 'notalot'|sudo -S ./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("echo 'notalot'|sudo -S /tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
|
|
||||||
sshClient.disconnect();
|
sshClient.disconnect();
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
||||||
.forMap(ImmutableMap.of(node, sshClient)), InitScriptConfigurationForTasks.create()
|
.forMap(ImmutableMap.of(node, sshClient)), eventBus, InitScriptConfigurationForTasks.create()
|
||||||
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions());
|
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions());
|
||||||
|
|
||||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
@ -154,8 +155,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
|
|
||||||
SshClient sshClient = createMock(SshClient.class);
|
SshClient sshClient = createMock(SshClient.class);
|
||||||
|
|
||||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
InitScript init = InitScript.builder().name("jclouds-script-0").home("/tmp/jclouds-script-0").run(command)
|
||||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
.build();
|
||||||
|
|
||||||
sshClient.connect();
|
sshClient.connect();
|
||||||
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
sshClient.put("/tmp/init-jclouds-script-0", init.render(OsFamily.UNIX));
|
||||||
|
@ -165,16 +166,16 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||||
// setup script as default user
|
// setup script as default user
|
||||||
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("chmod 755 /tmp/init-jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("ln -fs /tmp/init-jclouds-script-0 jclouds-script-0")).andReturn(new ExecResponse("", "", 0));
|
||||||
expect(sshClient.exec("./jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 init")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
// kick off as current user
|
// kick off as current user
|
||||||
expect(sshClient.exec("./jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
expect(sshClient.exec("/tmp/init-jclouds-script-0 start")).andReturn(new ExecResponse("", "", 0));
|
||||||
|
|
||||||
sshClient.disconnect();
|
sshClient.disconnect();
|
||||||
replay(sshClient);
|
replay(sshClient);
|
||||||
|
|
||||||
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
RunScriptOnNodeAsInitScriptUsingSsh testMe = new RunScriptOnNodeAsInitScriptUsingSsh(Functions
|
||||||
.forMap(ImmutableMap.of(node, sshClient)), InitScriptConfigurationForTasks.create()
|
.forMap(ImmutableMap.of(node, sshClient)), eventBus, InitScriptConfigurationForTasks.create()
|
||||||
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions().runAsRoot(false));
|
.appendIncrementingNumberToAnonymousTaskNames(), node, command, new RunScriptOptions().runAsRoot(false));
|
||||||
|
|
||||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||||
|
|
|
@ -34,12 +34,15 @@ import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@Test(groups = { "unit" }, singleThreaded = true)
|
@Test(groups = { "unit" }, singleThreaded = true)
|
||||||
public class RunScriptOnNodeUsingSshTest {
|
public class RunScriptOnNodeUsingSshTest {
|
||||||
|
EventBus eventBus = new EventBus();
|
||||||
|
|
||||||
private SshClient sshClient;
|
private SshClient sshClient;
|
||||||
private NodeMetadata node;
|
private NodeMetadata node;
|
||||||
private Function<NodeMetadata, SshClient> sshFactory;
|
private Function<NodeMetadata, SshClient> sshFactory;
|
||||||
|
@ -59,7 +62,7 @@ public class RunScriptOnNodeUsingSshTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void simpleTest() {
|
public void simpleTest() {
|
||||||
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, exec("echo $USER\necho $USER"),
|
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, eventBus, node, exec("echo $USER\necho $USER"),
|
||||||
wrapInInitScript(false).runAsRoot(false));
|
wrapInInitScript(false).runAsRoot(false));
|
||||||
|
|
||||||
testMe.init();
|
testMe.init();
|
||||||
|
@ -75,7 +78,7 @@ public class RunScriptOnNodeUsingSshTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void simpleRootTest() {
|
public void simpleRootTest() {
|
||||||
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, exec("echo $USER\necho $USER"),
|
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, eventBus, node, exec("echo $USER\necho $USER"),
|
||||||
wrapInInitScript(false).runAsRoot(true));
|
wrapInInitScript(false).runAsRoot(true));
|
||||||
|
|
||||||
testMe.init();
|
testMe.init();
|
||||||
|
@ -97,7 +100,7 @@ public class RunScriptOnNodeUsingSshTest {
|
||||||
expect(node.getCredentials()).andReturn(new LoginCredentials("tester", "testpassword!", null, true))
|
expect(node.getCredentials()).andReturn(new LoginCredentials("tester", "testpassword!", null, true))
|
||||||
.atLeastOnce();
|
.atLeastOnce();
|
||||||
replay(node);
|
replay(node);
|
||||||
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, exec("echo $USER\necho $USER"),
|
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, eventBus, node, exec("echo $USER\necho $USER"),
|
||||||
wrapInInitScript(false).runAsRoot(true));
|
wrapInInitScript(false).runAsRoot(true));
|
||||||
testMe.init();
|
testMe.init();
|
||||||
|
|
||||||
|
@ -114,7 +117,7 @@ public class RunScriptOnNodeUsingSshTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUserAddAsRoot() {
|
public void testUserAddAsRoot() {
|
||||||
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, UserAdd.builder()
|
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, eventBus, node, UserAdd.builder()
|
||||||
.login("testuser").build(), wrapInInitScript(false).runAsRoot(true).overrideLoginPassword("test"));
|
.login("testuser").build(), wrapInInitScript(false).runAsRoot(true).overrideLoginPassword("test"));
|
||||||
|
|
||||||
testMe.init();
|
testMe.init();
|
||||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="bootstrap"
|
export INSTANCE_NAME="bootstrap"
|
||||||
export INSTANCE_HOME="/tmp/bootstrap"
|
export INSTANCE_HOME="/tmp/bootstrap"
|
||||||
export LOG_DIR="/tmp/bootstrap"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function bootstrap {
|
function bootstrap {
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -62,35 +62,41 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/bootstrap.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;bootstrap\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;bootstrap\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='bootstrap'
|
export INSTANCE_NAME='bootstrap'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/bootstrap.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
function abort {
|
function abort {
|
||||||
echo "aborting: \$@" 1>&2
|
echo "aborting: $@" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
||||||
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_apt(){
|
function ensure_cmd_or_install_package_apt(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
|
|
||||||
hash \$cmd 2>/dev/null || apt-get-install \$pkg || ( apt-get-upgrade && apt-get-install \$pkg )
|
hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-upgrade && apt-get-install $pkg )
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_yum(){
|
function ensure_cmd_or_install_package_yum(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_netutils_apt() {
|
function ensure_netutils_apt() {
|
||||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
||||||
# most network services require that the hostname is in
|
# most network services require that the hostname is in
|
||||||
# the /etc/hosts file, or they won't operate
|
# the /etc/hosts file, or they won't operate
|
||||||
function ensure_hostname_in_hosts() {
|
function ensure_hostname_in_hosts() {
|
||||||
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print \$1" "hostname }' /proc/net/arp >> /etc/hosts
|
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print $1" "hostname }' /proc/net/arp >> /etc/hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
# download locations for many services are at public dns
|
# download locations for many services are at public dns
|
||||||
|
@ -127,60 +133,63 @@ function setupPublicCurl() {
|
||||||
ensure_can_resolve_public_dns
|
ensure_can_resolve_public_dns
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
rm /etc/sudoers
|
rm -f $INSTANCE_HOME/rc
|
||||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
|
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||||
root ALL = (ALL) ALL
|
root ALL = (ALL) ALL
|
||||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 0440 /etc/sudoers
|
chmod 0440 /etc/sudoers
|
||||||
mkdir -p /home/users
|
mkdir -p /home/users
|
||||||
groupadd -f wheel
|
groupadd -f wheel
|
||||||
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(randompassword)' defaultAdminUsername
|
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(randompassword)' defaultAdminUsername
|
||||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||||
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<'END_OF_FILE'
|
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||||
publicKey
|
publicKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
||||||
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
||||||
/etc/init.d/sshd reload||/etc/init.d/ssh reload
|
hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload
|
||||||
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(randompassword)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(randompassword)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
||||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||||
setupPublicCurl || return 1
|
setupPublicCurl || return 1
|
||||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
||||||
mv /usr/local/jdk* /usr/local/jdk/
|
mv /usr/local/jdk* /usr/local/jdk/
|
||||||
test -n "$SUDO_USER" &&
|
test -n "$SUDO_USER" &&
|
||||||
cat >> /home/$SUDO_USER/.bashrc <<'END_OF_FILE'
|
cat >> /home/$SUDO_USER/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/bootstrap.sh
|
chmod u+x $INSTANCE_HOME/bootstrap.sh
|
||||||
;;
|
;;
|
||||||
|
@ -201,6 +210,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -214,4 +234,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="configure-jboss"
|
export INSTANCE_NAME="configure-jboss"
|
||||||
export INSTANCE_HOME="/tmp/configure-jboss"
|
export INSTANCE_HOME="/tmp/configure-jboss"
|
||||||
export LOG_DIR="/tmp/configure-jboss"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function configure-jboss {
|
function configure-jboss {
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -62,35 +62,41 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/configure-jboss.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;configure-jboss\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;configure-jboss\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='configure-jboss'
|
export INSTANCE_NAME='configure-jboss'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/configure-jboss.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
function abort {
|
function abort {
|
||||||
echo "aborting: \$@" 1>&2
|
echo "aborting: $@" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
||||||
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_apt(){
|
function ensure_cmd_or_install_package_apt(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
|
|
||||||
hash \$cmd 2>/dev/null || apt-get-install \$pkg || ( apt-get-upgrade && apt-get-install \$pkg )
|
hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-upgrade && apt-get-install $pkg )
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_yum(){
|
function ensure_cmd_or_install_package_yum(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_netutils_apt() {
|
function ensure_netutils_apt() {
|
||||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
||||||
# most network services require that the hostname is in
|
# most network services require that the hostname is in
|
||||||
# the /etc/hosts file, or they won't operate
|
# the /etc/hosts file, or they won't operate
|
||||||
function ensure_hostname_in_hosts() {
|
function ensure_hostname_in_hosts() {
|
||||||
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print \$1" "hostname }' /proc/net/arp >> /etc/hosts
|
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print $1" "hostname }' /proc/net/arp >> /etc/hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
# download locations for many services are at public dns
|
# download locations for many services are at public dns
|
||||||
|
@ -127,52 +133,54 @@ function setupPublicCurl() {
|
||||||
ensure_can_resolve_public_dns
|
ensure_can_resolve_public_dns
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/configure-jboss.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
rm /etc/sudoers
|
rm -f $INSTANCE_HOME/rc
|
||||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
|
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||||
root ALL = (ALL) ALL
|
root ALL = (ALL) ALL
|
||||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 0440 /etc/sudoers
|
chmod 0440 /etc/sudoers
|
||||||
mkdir -p /home/users
|
mkdir -p /home/users
|
||||||
groupadd -f wheel
|
groupadd -f wheel
|
||||||
useradd -s /bin/bash -g wheel -m -d /home/users/web -p 'crypt(randompassword)' web
|
useradd -s /bin/bash -g wheel -m -d /home/users/web -p 'crypt(randompassword)' web
|
||||||
mkdir -p /home/users/web/.ssh
|
mkdir -p /home/users/web/.ssh
|
||||||
cat >> /home/users/web/.ssh/authorized_keys <<'END_OF_FILE'
|
cat >> /home/users/web/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||||
publicKey
|
publicKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/web/.ssh/authorized_keys
|
chmod 600 /home/users/web/.ssh/authorized_keys
|
||||||
chown -R web /home/users/web
|
chown -R web /home/users/web
|
||||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
||||||
/etc/init.d/sshd reload||/etc/init.d/ssh reload
|
hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload
|
||||||
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(randompassword)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(randompassword)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
||||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||||
setupPublicCurl || return 1
|
setupPublicCurl || return 1
|
||||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
||||||
mv /usr/local/jdk* /usr/local/jdk/
|
mv /usr/local/jdk* /usr/local/jdk/
|
||||||
test -n "$SUDO_USER" &&
|
test -n "$SUDO_USER" &&
|
||||||
cat >> /home/$SUDO_USER/.bashrc <<'END_OF_FILE'
|
cat >> /home/$SUDO_USER/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||||
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
|
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
|
||||||
iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT
|
iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT
|
||||||
|
@ -184,12 +192,13 @@ mv /usr/local/jboss-*/* /usr/local/jboss
|
||||||
chmod -R oug+r+w /usr/local/jboss
|
chmod -R oug+r+w /usr/local/jboss
|
||||||
chown -R web /usr/local/jboss
|
chown -R web /usr/local/jboss
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/configure-jboss.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/configure-jboss.sh
|
chmod u+x $INSTANCE_HOME/configure-jboss.sh
|
||||||
;;
|
;;
|
||||||
|
@ -210,6 +219,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -223,4 +243,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="runScriptWithCreds"
|
export INSTANCE_NAME="runScriptWithCreds"
|
||||||
export INSTANCE_HOME="/tmp/runScriptWithCreds"
|
export INSTANCE_HOME="/tmp/runScriptWithCreds"
|
||||||
export LOG_DIR="/tmp/runScriptWithCreds"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function runScriptWithCreds {
|
function runScriptWithCreds {
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -62,35 +62,41 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/runScriptWithCreds.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;runScriptWithCreds\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;runScriptWithCreds\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='runScriptWithCreds'
|
export INSTANCE_NAME='runScriptWithCreds'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
function abort {
|
function abort {
|
||||||
echo "aborting: \$@" 1>&2
|
echo "aborting: $@" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
||||||
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_apt(){
|
function ensure_cmd_or_install_package_apt(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
|
|
||||||
hash \$cmd 2>/dev/null || apt-get-install \$pkg || ( apt-get-upgrade && apt-get-install \$pkg )
|
hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-upgrade && apt-get-install $pkg )
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_yum(){
|
function ensure_cmd_or_install_package_yum(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_netutils_apt() {
|
function ensure_netutils_apt() {
|
||||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
||||||
# most network services require that the hostname is in
|
# most network services require that the hostname is in
|
||||||
# the /etc/hosts file, or they won't operate
|
# the /etc/hosts file, or they won't operate
|
||||||
function ensure_hostname_in_hosts() {
|
function ensure_hostname_in_hosts() {
|
||||||
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print \$1" "hostname }' /proc/net/arp >> /etc/hosts
|
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print $1" "hostname }' /proc/net/arp >> /etc/hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
# download locations for many services are at public dns
|
# download locations for many services are at public dns
|
||||||
|
@ -127,39 +133,43 @@ function setupPublicCurl() {
|
||||||
ensure_can_resolve_public_dns
|
ensure_can_resolve_public_dns
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
|
rm -f $INSTANCE_HOME/rc
|
||||||
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
setupPublicCurl || exit 1
|
setupPublicCurl || exit 1
|
||||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
||||||
mv /usr/local/jdk* /usr/local/jdk/
|
mv /usr/local/jdk* /usr/local/jdk/
|
||||||
test -n "$SUDO_USER" &&
|
test -n "$SUDO_USER" &&
|
||||||
cat >> /home/$SUDO_USER/.bashrc <<'END_OF_FILE'
|
cat >> /home/$SUDO_USER/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/runScriptWithCreds.sh
|
chmod u+x $INSTANCE_HOME/runScriptWithCreds.sh
|
||||||
;;
|
;;
|
||||||
|
@ -180,6 +190,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -193,4 +214,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="adminUpdate"
|
export INSTANCE_NAME="adminUpdate"
|
||||||
export INSTANCE_HOME="/tmp/adminUpdate"
|
export INSTANCE_HOME="/tmp/adminUpdate"
|
||||||
export LOG_DIR="/tmp/adminUpdate"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function adminUpdate {
|
function adminUpdate {
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -62,50 +62,56 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/adminUpdate.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/adminUpdate.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;adminUpdate\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;adminUpdate\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='adminUpdate'
|
export INSTANCE_NAME='adminUpdate'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/adminUpdate.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/adminUpdate.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/adminUpdate.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
rm /etc/sudoers
|
rm -f $INSTANCE_HOME/rc
|
||||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
|
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||||
root ALL = (ALL) ALL
|
root ALL = (ALL) ALL
|
||||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 0440 /etc/sudoers
|
chmod 0440 /etc/sudoers
|
||||||
mkdir -p /home/users
|
mkdir -p /home/users
|
||||||
groupadd -f wheel
|
groupadd -f wheel
|
||||||
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(randompassword)' foo
|
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(randompassword)' foo
|
||||||
mkdir -p /home/users/foo/.ssh
|
mkdir -p /home/users/foo/.ssh
|
||||||
cat >> /home/users/foo/.ssh/authorized_keys <<'END_OF_FILE'
|
cat >> /home/users/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||||
publicKey
|
publicKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/foo/.ssh/authorized_keys
|
chmod 600 /home/users/foo/.ssh/authorized_keys
|
||||||
chown -R foo /home/users/foo
|
chown -R foo /home/users/foo
|
||||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
||||||
/etc/init.d/sshd reload||/etc/init.d/ssh reload
|
hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload
|
||||||
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(randompassword)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(randompassword)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
||||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/adminUpdate.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/adminUpdate.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/adminUpdate.sh
|
chmod u+x $INSTANCE_HOME/adminUpdate.sh
|
||||||
;;
|
;;
|
||||||
|
@ -126,6 +132,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -139,4 +156,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -10,12 +10,12 @@ function abort {
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="jboss"
|
export INSTANCE_NAME="jboss"
|
||||||
export INSTANCE_HOME="/usr/local/jboss"
|
export INSTANCE_HOME="/usr/local/jboss"
|
||||||
export LOG_DIR="/usr/local/jboss"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function jboss {
|
function jboss {
|
||||||
export JBOSS_HOME="/usr/local/jboss"
|
export JBOSS_HOME="/usr/local/jboss"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -60,7 +60,7 @@ case $1 in
|
||||||
init)
|
init)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
jboss || exit 1
|
jboss || exit 1
|
||||||
cat >> /usr/local/jboss/standalone/configuration/standalone-custom.xml <<'END_OF_FILE'
|
cat >> /usr/local/jboss/standalone/configuration/standalone-custom.xml <<-'END_OF_JCLOUDS_FILE'
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
|
||||||
<server name="basic" xmlns="urn:jboss:domain:1.0">
|
<server name="basic" xmlns="urn:jboss:domain:1.0">
|
||||||
|
@ -165,34 +165,41 @@ init)
|
||||||
</socket-binding-group>
|
</socket-binding-group>
|
||||||
</server>
|
</server>
|
||||||
|
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/jboss.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;jboss\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;jboss\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='jboss'
|
export INSTANCE_NAME='jboss'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/jboss.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export JBOSS_HOME='$JBOSS_HOME'
|
export JBOSS_HOME='$JBOSS_HOME'
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/jboss.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
|
rm -f $INSTANCE_HOME/rc
|
||||||
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
java -server -Xms128m -Xmx128m -XX:MaxPermSize=128m -Djava.net.preferIPv4Stack=true -XX:+UseFastAccessorMethods -XX:+TieredCompilation -Xverify:none -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Dorg.jboss.boot.log.file=$JBOSS_HOME/standalone/log/boot.log -Dlogging.configuration=file:$JBOSS_HOME/standalone/configuration/logging.properties -jar $JBOSS_HOME/jboss-modules.jar -mp $JBOSS_HOME/modules -logmodule org.jboss.logmanager -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone -Djboss.home.dir=$JBOSS_HOME --server-config=standalone-custom.xml
|
java -server -Xms128m -Xmx128m -XX:MaxPermSize=128m -Djava.net.preferIPv4Stack=true -XX:+UseFastAccessorMethods -XX:+TieredCompilation -Xverify:none -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Dorg.jboss.boot.log.file=$JBOSS_HOME/standalone/log/boot.log -Dlogging.configuration=file:$JBOSS_HOME/standalone/configuration/logging.properties -jar $JBOSS_HOME/jboss-modules.jar -mp $JBOSS_HOME/modules -logmodule org.jboss.logmanager -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone -Djboss.home.dir=$JBOSS_HOME --server-config=standalone-custom.xml
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/jboss.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/jboss.sh
|
chmod u+x $INSTANCE_HOME/jboss.sh
|
||||||
;;
|
;;
|
||||||
|
@ -213,6 +220,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -226,4 +244,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -45,6 +45,8 @@ import org.jclouds.lifecycle.Closer;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.eventbus.AsyncEventBus;
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
@ -321,6 +323,12 @@ public class ExecutorServiceModule extends AbstractModule {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
EventBus provideEventBus(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads){
|
||||||
|
return new AsyncEventBus(userThreads);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named(Constants.PROPERTY_USER_THREADS)
|
@Named(Constants.PROPERTY_USER_THREADS)
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.predicates;
|
||||||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
@ -88,6 +89,9 @@ public class RetryablePredicate<T> implements Predicate<T> {
|
||||||
} else if (getFirstThrowableOfType(e, IllegalStateException.class) != null) {
|
} else if (getFirstThrowableOfType(e, IllegalStateException.class) != null) {
|
||||||
logger.warn(e, "predicate %s on %s illegal state [%s], returning false", input, predicate, e.getMessage());
|
logger.warn(e, "predicate %s on %s illegal state [%s], returning false", input, predicate, e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
|
} else if (getFirstThrowableOfType(e, CancellationException.class) != null) {
|
||||||
|
logger.warn(e, "predicate %s on %s cancelled [%s], returning false", input, predicate, e.getMessage());
|
||||||
|
return false;
|
||||||
} else if (getFirstThrowableOfType(e, TimeoutException.class) != null) {
|
} else if (getFirstThrowableOfType(e, TimeoutException.class) != null) {
|
||||||
logger.warn(e, "predicate %s on %s timed out [%s], returning false", input, predicate, e.getMessage());
|
logger.warn(e, "predicate %s on %s timed out [%s], returning false", input, predicate, e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class GuestAdditionsInstaller implements Predicate<String> {
|
||||||
ListenableFuture<ExecResponse> execFuture = context.getComputeService().submitScriptOnNode(vmName,
|
ListenableFuture<ExecResponse> execFuture = context.getComputeService().submitScriptOnNode(vmName,
|
||||||
new InstallGuestAdditions(vboxVersion), RunScriptOptions.NONE);
|
new InstallGuestAdditions(vboxVersion), RunScriptOptions.NONE);
|
||||||
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||||
return execResponse == null ? false : execResponse.getExitCode() == 0;
|
return execResponse == null ? false : execResponse.getExitStatus() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -53,7 +53,7 @@ public class SshAvailable implements Predicate<String> {
|
||||||
try {
|
try {
|
||||||
if (context.getComputeService()
|
if (context.getComputeService()
|
||||||
.runScriptOnNode(nodeId, "id", wrapInInitScript(false).runAsRoot(false))
|
.runScriptOnNode(nodeId, "id", wrapInInitScript(false).runAsRoot(false))
|
||||||
.getExitCode() == 0) {
|
.getExitStatus() == 0) {
|
||||||
logger.debug("Got response from ssh daemon running on %s", nodeId);
|
logger.debug("Got response from ssh daemon running on %s", nodeId);
|
||||||
sshDaemonIsRunning = true;
|
sshDaemonIsRunning = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class SshResponds implements Predicate<SshClient> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.connect();
|
client.connect();
|
||||||
if (client.exec("id").getExitCode() == 0) {
|
if (client.exec("id").getExitStatus() == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (SshException e) {
|
} catch (SshException e) {
|
||||||
|
|
|
@ -51,8 +51,7 @@ public class InstallGuestAdditions extends StatementList {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String render(OsFamily family) {
|
public String render(OsFamily family) {
|
||||||
checkNotNull(family, "family");
|
if (checkNotNull(family, "family") == OsFamily.WINDOWS)
|
||||||
if (family == OsFamily.WINDOWS)
|
|
||||||
throw new UnsupportedOperationException("windows not yet implemented");
|
throw new UnsupportedOperationException("windows not yet implemented");
|
||||||
return super.render(family);
|
return super.render(family);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
@ -30,7 +30,6 @@ import org.jclouds.virtualbox.statements.InstallGuestAdditions;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
|
@ -47,8 +46,8 @@ public class InstallGuestAdditionsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnixInInitScript() throws IOException {
|
public void testUnixInInitScript() throws IOException {
|
||||||
Statement statement = new InitBuilder("install_guest_additions", ImmutableSet.<Statement> of(),
|
Statement statement = InitScript.builder().name("install_guest_additions")
|
||||||
ImmutableSet.<Statement> of(new InstallGuestAdditions("4.1.6")));
|
.run(new InstallGuestAdditions("4.1.6")).build();
|
||||||
|
|
||||||
assertEquals(statement.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(
|
assertEquals(statement.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(
|
||||||
Resources.getResource("test_guest_additions_installer_init." + ShellToken.SH.to(OsFamily.UNIX)),
|
Resources.getResource("test_guest_additions_installer_init." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||||
|
|
|
@ -26,4 +26,4 @@ function exportIpAddressFromVmNamed {
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
exportIpAddressFromVmNamed $@ || exit 1
|
exportIpAddressFromVmNamed $@ || exit 1
|
||||||
echo $FOUND_IP_ADDRESS
|
echo $FOUND_IP_ADDRESS
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -9,12 +9,12 @@ function abort {
|
||||||
}
|
}
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="install_guest_additions"
|
export INSTANCE_NAME="install_guest_additions"
|
||||||
export INSTANCE_HOME="$HOME/instances/install_guest_additions"
|
export INSTANCE_HOME="/tmp/$INSTANCE_NAME"
|
||||||
export LOG_DIR="$HOME/instances/install_guest_additions"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function install_guest_additions {
|
function install_guest_additions {
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -62,35 +62,41 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/install_guest_additions.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/install_guest_additions.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;install_guest_additions\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;install_guest_additions\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='install_guest_additions'
|
export INSTANCE_NAME='install_guest_additions'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/install_guest_additions.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/install_guest_additions.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
function abort {
|
function abort {
|
||||||
echo "aborting: \$@" 1>&2
|
echo "aborting: $@" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
||||||
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_apt(){
|
function ensure_cmd_or_install_package_apt(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
|
|
||||||
hash \$cmd 2>/dev/null || apt-get-install \$pkg || ( apt-get-upgrade && apt-get-install \$pkg )
|
hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-upgrade && apt-get-install $pkg )
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_yum(){
|
function ensure_cmd_or_install_package_yum(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_netutils_apt() {
|
function ensure_netutils_apt() {
|
||||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
||||||
# most network services require that the hostname is in
|
# most network services require that the hostname is in
|
||||||
# the /etc/hosts file, or they won't operate
|
# the /etc/hosts file, or they won't operate
|
||||||
function ensure_hostname_in_hosts() {
|
function ensure_hostname_in_hosts() {
|
||||||
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print \$1" "hostname }' /proc/net/arp >> /etc/hosts
|
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print $1" "hostname }' /proc/net/arp >> /etc/hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
# download locations for many services are at public dns
|
# download locations for many services are at public dns
|
||||||
|
@ -130,31 +136,40 @@ function setupPublicCurl() {
|
||||||
function installModuleAssistantIfNeeded {
|
function installModuleAssistantIfNeeded {
|
||||||
unset OSNAME;
|
unset OSNAME;
|
||||||
local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
||||||
if [ \$OSNAME = 'Ubuntu' ]
|
if [ $OSNAME = 'Ubuntu' ]
|
||||||
then
|
then
|
||||||
echo "OS is Ubuntu"
|
echo "OS is Ubuntu"
|
||||||
apt-get -f -y -qq --force-yes install build-essential module-assistant;
|
apt-get -f -y -qq --force-yes install build-essential module-assistant;
|
||||||
m-a prepare -i
|
m-a prepare -i
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/install_guest_additions.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/install_guest_additions.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
|
rm -f $INSTANCE_HOME/rc
|
||||||
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
setupPublicCurl || exit 1
|
setupPublicCurl || exit 1
|
||||||
|
|
||||||
(mkdir -p /tmp/ && cd /tmp/ && [ ! -f VBoxGuestAdditions_4.1.6.iso ] && curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -C - -X GET http://download.virtualbox.org/virtualbox/4.1.6/VBoxGuestAdditions_4.1.6.iso >VBoxGuestAdditions_4.1.6.iso)
|
(mkdir -p /tmp/ && cd /tmp/ && [ ! -f VBoxGuestAdditions_4.1.6.iso ] && curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -C - -X GET http://download.virtualbox.org/virtualbox/4.1.6/VBoxGuestAdditions_4.1.6.iso >VBoxGuestAdditions_4.1.6.iso)
|
||||||
|
|
||||||
mount -o loop /tmp/VBoxGuestAdditions_4.1.6.iso /mnt
|
mount -o loop /tmp/VBoxGuestAdditions_4.1.6.iso /mnt
|
||||||
|
|
||||||
installModuleAssistantIfNeeded || exit 1
|
installModuleAssistantIfNeeded || exit 1
|
||||||
|
|
||||||
/mnt/VBoxLinuxAdditions.run
|
/mnt/VBoxLinuxAdditions.run
|
||||||
|
|
||||||
umount /mnt
|
umount /mnt
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/install_guest_additions.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/install_guest_additions.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/install_guest_additions.sh
|
chmod u+x $INSTANCE_HOME/install_guest_additions.sh
|
||||||
;;
|
;;
|
||||||
|
@ -175,6 +190,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -188,4 +214,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -38,8 +38,10 @@ import com.google.common.collect.Iterables;
|
||||||
/**
|
/**
|
||||||
* Creates an init script file
|
* Creates an init script file
|
||||||
*
|
*
|
||||||
|
* @see InitScript
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class InitBuilder extends ScriptBuilder {
|
public class InitBuilder extends ScriptBuilder {
|
||||||
|
|
||||||
private final String instanceName;
|
private final String instanceName;
|
||||||
|
@ -53,8 +55,8 @@ public class InitBuilder extends ScriptBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public InitBuilder(String instanceName, Iterable<Statement> initStatements, Iterable<Statement> statements) {
|
public InitBuilder(String instanceName, Iterable<Statement> initStatements, Iterable<Statement> statements) {
|
||||||
this(instanceName, String.format("{varl}HOME{varr}{fs}instances{fs}%s", instanceName), String.format(
|
this(instanceName, String.format("{tmp}{fs}{varl}INSTANCE_NAME{varr}", instanceName), String.format(
|
||||||
"{varl}HOME{varr}{fs}instances{fs}%s", instanceName), ImmutableMap.<String, String> of(), initStatements,
|
"{tmp}{fs}{varl}INSTANCE_NAME{varr}", instanceName), ImmutableMap.<String, String> of(), initStatements,
|
||||||
statements);
|
statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.scriptbuilder;
|
||||||
|
|
||||||
|
import static com.google.common.base.Objects.equal;
|
||||||
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.concat;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static org.jclouds.scriptbuilder.ScriptBuilder.call;
|
||||||
|
import static org.jclouds.scriptbuilder.ScriptBuilder.findPid;
|
||||||
|
import static org.jclouds.scriptbuilder.ScriptBuilder.forget;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.createRunScript;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.kill;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.switchArg;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.scriptbuilder.domain.AcceptsStatementVisitor;
|
||||||
|
import org.jclouds.scriptbuilder.domain.CreateRunScript;
|
||||||
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||||
|
import org.jclouds.scriptbuilder.domain.StatementVisitor;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ForwardingObject;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an init script file
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class InitScript extends ForwardingObject implements Statement, AcceptsStatementVisitor {
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected String instanceName;
|
||||||
|
protected String instanceHome = "{tmp}{fs}{varl}INSTANCE_NAME{varr}";
|
||||||
|
protected String logDir = "{varl}INSTANCE_HOME{varr}";
|
||||||
|
protected Map<String, String> exports = ImmutableMap.of();
|
||||||
|
protected StatementList init = new StatementList();
|
||||||
|
protected StatementList run = new StatementList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getInstanceName()
|
||||||
|
*/
|
||||||
|
public Builder name(String instanceName) {
|
||||||
|
this.instanceName = checkNotNull(instanceName, "instanceName");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getInstanceHome()
|
||||||
|
*/
|
||||||
|
public Builder home(String instanceHome) {
|
||||||
|
this.instanceHome = checkNotNull(instanceHome, "instanceHome");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getLogDir()
|
||||||
|
*/
|
||||||
|
public Builder logDir(String logDir) {
|
||||||
|
this.logDir = checkNotNull(logDir, "logDir");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getExportedVariables()
|
||||||
|
*/
|
||||||
|
public Builder exportVariables(Map<String, String> exports) {
|
||||||
|
this.exports = ImmutableMap.copyOf(checkNotNull(exports, "exports"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getRun()
|
||||||
|
*/
|
||||||
|
public Builder run(Statement run) {
|
||||||
|
this.run = new StatementList(checkNotNull(run, "run"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getRun()
|
||||||
|
*/
|
||||||
|
public Builder run(Statement... run) {
|
||||||
|
this.run = new StatementList(checkNotNull(run, "run"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getRun()
|
||||||
|
*/
|
||||||
|
public Builder run(Iterable<Statement> run) {
|
||||||
|
this.run = new StatementList(checkNotNull(run, "run"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getRun()
|
||||||
|
*/
|
||||||
|
public Builder run(StatementList run) {
|
||||||
|
this.run = checkNotNull(run, "run");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getInit()
|
||||||
|
*/
|
||||||
|
public Builder init(Statement init) {
|
||||||
|
this.init = new StatementList(checkNotNull(init, "init"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getInit()
|
||||||
|
*/
|
||||||
|
public Builder init(Statement... init) {
|
||||||
|
this.init = new StatementList(checkNotNull(init, "init"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getInit()
|
||||||
|
*/
|
||||||
|
public Builder init(Iterable<Statement> init) {
|
||||||
|
this.init = new StatementList(checkNotNull(init, "init"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InitScript#getInit()
|
||||||
|
*/
|
||||||
|
public Builder init(StatementList init) {
|
||||||
|
this.init = checkNotNull(init, "init");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitScript build() {
|
||||||
|
return new InitScript(instanceName, instanceHome, logDir, exports, init, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final String instanceName;
|
||||||
|
protected final String instanceHome;
|
||||||
|
protected final String logDir;
|
||||||
|
protected final Map<String, String> exports;
|
||||||
|
protected final StatementList init;
|
||||||
|
protected final StatementList run;
|
||||||
|
protected final ScriptBuilder delegate;
|
||||||
|
|
||||||
|
protected InitScript(String instanceName, String instanceHome, String logDir, Map<String, String> exports,
|
||||||
|
StatementList init, StatementList run) {
|
||||||
|
this.instanceName = checkNotNull(instanceName, "instanceName");
|
||||||
|
this.instanceHome = checkNotNull(instanceHome, "instanceHome");
|
||||||
|
this.logDir = checkNotNull(logDir, "logDir");
|
||||||
|
this.exports = ImmutableMap.<String, String> copyOf(checkNotNull(exports, "exports"));
|
||||||
|
this.init = checkNotNull(init, "init");
|
||||||
|
this.run = checkNotNull(run, "run");
|
||||||
|
checkArgument(run.delegate().size() > 0, "you must specify at least one statement to run");
|
||||||
|
this.delegate = makeInitScriptStatement(instanceName, instanceHome, logDir, exports, init, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScriptBuilder makeInitScriptStatement(String instanceName, String instanceHome, String logDir,
|
||||||
|
Map<String, String> exports, StatementList init, StatementList run) {
|
||||||
|
Map<String, String> defaultExports = ImmutableMap.of("instanceName", instanceName, "instanceHome", instanceHome,
|
||||||
|
"logDir", logDir);
|
||||||
|
String exitStatusFile = format("%s/rc", logDir);
|
||||||
|
run = new StatementList(ImmutableList.<Statement> builder().add(interpret("rm -f " + exitStatusFile))
|
||||||
|
.add(interpret(format("trap 'echo $?>%s' 0 1 2 3 15", exitStatusFile))).addAll(run.delegate()).build());
|
||||||
|
|
||||||
|
CreateRunScript createRunScript = createRunScript(instanceName,
|
||||||
|
concat(exports.keySet(), defaultExports.keySet()), "{varl}INSTANCE_HOME{varr}", run);
|
||||||
|
|
||||||
|
return new ScriptBuilder()
|
||||||
|
.addEnvironmentVariableScope("default", defaultExports)
|
||||||
|
.addEnvironmentVariableScope(instanceName, exports)
|
||||||
|
.addStatement(
|
||||||
|
switchArg(
|
||||||
|
1,
|
||||||
|
new ImmutableMap.Builder<String, Statement>()
|
||||||
|
.put("init", newStatementList(call("default"), call(instanceName), init, createRunScript))
|
||||||
|
.put("status",
|
||||||
|
newStatementList(call("default"), findPid("{varl}INSTANCE_NAME{varr}"),
|
||||||
|
interpret("echo [{varl}FOUND_PID{varr}]{lf}")))
|
||||||
|
.put("stop",
|
||||||
|
newStatementList(call("default"), findPid("{varl}INSTANCE_NAME{varr}"), kill()))
|
||||||
|
.put("start",
|
||||||
|
newStatementList(
|
||||||
|
call("default"),
|
||||||
|
forget("{varl}INSTANCE_NAME{varr}",
|
||||||
|
"{varl}INSTANCE_HOME{varr}{fs}{varl}INSTANCE_NAME{varr}.{sh}",
|
||||||
|
"{varl}LOG_DIR{varr}")))
|
||||||
|
.put("stdout",
|
||||||
|
newStatementList(call("default"),
|
||||||
|
interpret("cat {varl}LOG_DIR{varr}{fs}stdout.log{lf}")))
|
||||||
|
.put("stderr",
|
||||||
|
newStatementList(call("default"),
|
||||||
|
interpret("cat {varl}LOG_DIR{varr}{fs}stderr.log{lf}")))
|
||||||
|
.put("exitstatus",
|
||||||
|
newStatementList(call("default"),
|
||||||
|
interpret("[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc")))
|
||||||
|
.put("tail",
|
||||||
|
newStatementList(call("default"),
|
||||||
|
interpret("tail {varl}LOG_DIR{varr}{fs}stdout.log{lf}")))
|
||||||
|
.put("tailerr",
|
||||||
|
newStatementList(call("default"),
|
||||||
|
interpret("tail {varl}LOG_DIR{varr}{fs}stderr.log{lf}")))
|
||||||
|
.put("run",
|
||||||
|
newStatementList(call("default"),
|
||||||
|
interpret("{varl}INSTANCE_HOME{varr}{fs}{varl}INSTANCE_NAME{varr}.{sh}{lf}")))
|
||||||
|
.build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return what will be bound to the INSTANCE_NAME variable, and uniquely
|
||||||
|
* identifies the process
|
||||||
|
*/
|
||||||
|
public String getInstanceName() {
|
||||||
|
return instanceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default {@code /tmp/$INSTANCE_NAME}
|
||||||
|
* <br/>
|
||||||
|
* <h3>note</h3> The parent directory
|
||||||
|
* should be set with unix sticky-bit or otherwise made available to all
|
||||||
|
* users. Otherwise, new instances by other users may fail due to not being
|
||||||
|
* able to create a directory. This is why the default is set to {@code /tmp}
|
||||||
|
*
|
||||||
|
* @return what will be bound to the INSTANCE_HOME variable, and represents
|
||||||
|
* the working directory of the instance
|
||||||
|
*/
|
||||||
|
public String getInstanceHome() {
|
||||||
|
return instanceHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default {@code $INSTANCE_HOME}
|
||||||
|
*
|
||||||
|
* @return what will be bound to the LOG_DIR variable, and represents where
|
||||||
|
* stdout and stderr.logs are written.
|
||||||
|
*/
|
||||||
|
public String getLogDir() {
|
||||||
|
return logDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return statements that will be executed upon the init command
|
||||||
|
*/
|
||||||
|
public StatementList getInitStatement() {
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return statements that will be executed upon the run or start commands
|
||||||
|
*/
|
||||||
|
public StatementList getRunStatement() {
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(instanceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object that) {
|
||||||
|
if (that == null)
|
||||||
|
return false;
|
||||||
|
return equal(this.toString(), that.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper(this).add("instanceName", instanceName).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(StatementVisitor visitor) {
|
||||||
|
delegate().accept(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
|
return delegate().functionDependencies(family);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String render(OsFamily family) {
|
||||||
|
return delegate().render(family);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ScriptBuilder delegate() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,13 +23,12 @@ import static com.google.common.base.Preconditions.checkState;
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,21 +37,66 @@ import com.google.common.collect.Maps;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class AppendFile implements Statement {
|
public class AppendFile implements Statement {
|
||||||
public static final String MARKER = "END_OF_FILE";
|
public static final String DELIMETER = "END_OF_JCLOUDS_FILE";
|
||||||
|
|
||||||
final String path;
|
public static Builder builder() {
|
||||||
final Iterable<String> lines;
|
return new Builder();
|
||||||
final String marker;
|
|
||||||
|
|
||||||
public AppendFile(String path, Iterable<String> lines) {
|
|
||||||
this(path, lines, MARKER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppendFile(String path, Iterable<String> lines, String marker) {
|
public static class Builder {
|
||||||
|
protected String path;
|
||||||
|
protected Iterable<String> lines = ImmutableSet.of();
|
||||||
|
protected String delimeter = DELIMETER;
|
||||||
|
protected boolean expandVariables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AppendFile#getPath()
|
||||||
|
*/
|
||||||
|
public Builder path(String path) {
|
||||||
|
this.path = path;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AppendFile#getLines()
|
||||||
|
*/
|
||||||
|
public Builder lines(Iterable<String> lines) {
|
||||||
|
this.lines = ImmutableList.copyOf(lines);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AppendFile#getDelimeter()
|
||||||
|
*/
|
||||||
|
public Builder delimeter(String delimeter) {
|
||||||
|
this.delimeter = delimeter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AppendFile#shouldExpandVariables()
|
||||||
|
*/
|
||||||
|
public Builder expandVariables(boolean expandVariables) {
|
||||||
|
this.expandVariables = expandVariables;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppendFile build() {
|
||||||
|
return new AppendFile(path, lines, delimeter, expandVariables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final String path;
|
||||||
|
protected final Iterable<String> lines;
|
||||||
|
protected final String delimeter;
|
||||||
|
protected final boolean expandVariables;
|
||||||
|
|
||||||
|
protected AppendFile(String path, Iterable<String> lines, String delimeter, boolean expandVariables) {
|
||||||
this.path = checkNotNull(path, "path");
|
this.path = checkNotNull(path, "path");
|
||||||
this.lines = checkNotNull(lines, "lines");
|
this.lines = checkNotNull(lines, "lines");
|
||||||
this.marker = checkNotNull(marker, "marker");
|
this.delimeter = checkNotNull(delimeter, "delimeter");
|
||||||
checkState(Iterables.size(lines) > 0, "you must pass something to execute");
|
checkState(Iterables.size(lines) > 0, "you must pass something to execute");
|
||||||
|
this.expandVariables = expandVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String escapeVarTokens(String toEscape, OsFamily family) {
|
public static String escapeVarTokens(String toEscape, OsFamily family) {
|
||||||
|
@ -76,35 +120,45 @@ public class AppendFile implements Statement {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String render(OsFamily family) {
|
public String render(OsFamily family) {
|
||||||
List<Statement> statements = Lists.newArrayList();
|
|
||||||
if (family == OsFamily.UNIX) {
|
if (family == OsFamily.UNIX) {
|
||||||
StringBuilder builder = new StringBuilder();
|
return interpret(hereFile()).render(family);
|
||||||
hereFile(path, builder);
|
|
||||||
statements.add(interpret(builder.toString()));
|
|
||||||
} else {
|
} else {
|
||||||
for (String line : lines) {
|
return interpret(appendToWindowsFile()).render(family);
|
||||||
statements.add(appendToFile(line, path, family));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new StatementList(statements).render(family);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void hereFile(String path, StringBuilder builder) {
|
protected String appendToWindowsFile() {
|
||||||
builder.append("cat >> ").append(path).append(" <<'").append(marker).append("'\n");
|
StringBuilder builder = new StringBuilder();
|
||||||
for (String line : lines) {
|
for (String line : lines) {
|
||||||
builder.append(line).append("\n");
|
builder.append(appendLineToWindowsFile(line, path));
|
||||||
}
|
}
|
||||||
builder.append(marker).append("\n");
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Statement appendToFile(String line, String path, OsFamily family) {
|
protected String hereFile() {
|
||||||
|
StringBuilder hereFile = startHereFile();
|
||||||
|
for (String line : lines) {
|
||||||
|
hereFile.append('\t').append(line).append("\n");
|
||||||
|
}
|
||||||
|
hereFile.append(delimeter).append("\n");
|
||||||
|
return hereFile.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder startHereFile() {
|
||||||
|
StringBuilder hereFile = new StringBuilder().append("cat >> ").append(path);
|
||||||
|
if (expandVariables)
|
||||||
|
return hereFile.append(" <<-").append(delimeter).append("\n");
|
||||||
|
return hereFile.append(" <<-'").append(delimeter).append("'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String appendLineToWindowsFile(String line, String path) {
|
||||||
String quote = "";
|
String quote = "";
|
||||||
if (!ShellToken.VQ.to(family).equals("")) {
|
if (!ShellToken.VQ.to(OsFamily.WINDOWS).equals("")) {
|
||||||
quote = "'";
|
quote = "'";
|
||||||
} else {
|
} else {
|
||||||
line = escapeVarTokens(line, family);
|
line = escapeVarTokens(line, OsFamily.WINDOWS);
|
||||||
}
|
}
|
||||||
return interpret(String.format("echo %s%s%s >>%s{lf}", quote, line, quote, path));
|
return String.format("echo %s%s%s >>%s{lf}", quote, line, quote, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,118 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.jclouds.scriptbuilder.domain;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a run script
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public class CreateFile implements Statement {
|
|
||||||
public static final String MARKER = "END_OF_FILE";
|
|
||||||
|
|
||||||
final String path;
|
|
||||||
final Iterable<String> lines;
|
|
||||||
final String marker;
|
|
||||||
|
|
||||||
public CreateFile(String path, Iterable<String> lines) {
|
|
||||||
this(path, lines, MARKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CreateFile(String path, Iterable<String> lines, String marker) {
|
|
||||||
this.path = checkNotNull(path, "path");
|
|
||||||
this.lines = checkNotNull(lines, "lines");
|
|
||||||
this.marker = checkNotNull(marker, "marker");
|
|
||||||
checkState(Iterables.size(lines) > 0, "you must pass something to execute");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String escapeVarTokens(String toEscape, OsFamily family) {
|
|
||||||
Map<String, String> inputToEscape = Maps.newHashMap();
|
|
||||||
for (ShellToken token : ImmutableList.of(ShellToken.VARL, ShellToken.VARR)) {
|
|
||||||
if (!token.to(family).equals("")) {
|
|
||||||
String tokenS = "{" + token.toString().toLowerCase() + "}";
|
|
||||||
inputToEscape.put(tokenS, "{escvar}" + tokenS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Entry<String, String> entry : inputToEscape.entrySet()) {
|
|
||||||
toEscape = toEscape.replace(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
return toEscape;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> functionDependencies(OsFamily family) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String render(OsFamily family) {
|
|
||||||
List<Statement> statements = Lists.newArrayList();
|
|
||||||
if (family == OsFamily.UNIX) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
hereFile(path, builder);
|
|
||||||
statements.add(interpret(builder.toString()));
|
|
||||||
} else {
|
|
||||||
for (String line : lines) {
|
|
||||||
statements.add(appendToFile(line, path, family));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new StatementList(statements).render(family);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hereFile(String path, StringBuilder builder) {
|
|
||||||
builder.append("cat > ").append(path).append(" <<'").append(marker).append("'\n");
|
|
||||||
for (String line : lines) {
|
|
||||||
builder.append(line).append("\n");
|
|
||||||
}
|
|
||||||
builder.append(marker).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private Statement appendToFile(String line, String path, OsFamily family) {
|
|
||||||
String quote = "";
|
|
||||||
if (!ShellToken.VQ.to(family).equals("")) {
|
|
||||||
quote = "'";
|
|
||||||
} else {
|
|
||||||
line = escapeVarTokens(line, family);
|
|
||||||
}
|
|
||||||
return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format("echo %s%s%s>>%s{lf}", quote, line,
|
|
||||||
quote, path)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Pattern REDIRECT_FD_PATTERN = Pattern.compile(".*[0-2]>>.*");
|
|
||||||
|
|
||||||
static String addSpaceToEnsureWeDontAccidentallyRedirectFd(String line) {
|
|
||||||
return REDIRECT_FD_PATTERN.matcher(line).matches() ? line.replace(">>", " >>") : line;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -18,11 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.scriptbuilder.domain;
|
package org.jclouds.scriptbuilder.domain;
|
||||||
|
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a run script
|
* Creates a run script
|
||||||
|
@ -30,38 +25,54 @@ import com.google.common.collect.Lists;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class CreateOrOverwriteFile extends AppendFile {
|
public class CreateOrOverwriteFile extends AppendFile {
|
||||||
|
public static Builder builder() {
|
||||||
public CreateOrOverwriteFile(String path, Iterable<String> lines) {
|
return new Builder();
|
||||||
super(path, lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateOrOverwriteFile(String path, Iterable<String> lines, String marker) {
|
public static class Builder extends AppendFile.Builder {
|
||||||
super(path, lines, marker);
|
|
||||||
|
@Override
|
||||||
|
public Builder path(String path) {
|
||||||
|
return Builder.class.cast(super.path(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String render(OsFamily family) {
|
public Builder lines(Iterable<String> lines) {
|
||||||
List<Statement> statements = Lists.newArrayList();
|
return Builder.class.cast(super.lines(lines));
|
||||||
if (family == OsFamily.UNIX) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
hereFile(path, builder);
|
|
||||||
statements.add(interpret(builder.toString()));
|
|
||||||
} else {
|
|
||||||
// Windows:
|
|
||||||
statements.add(interpret(String.format("copy /y CON %s{lf}", path))); // This clears the file
|
|
||||||
for (String line : lines) {
|
|
||||||
statements.add(appendToFile(line, path, family));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new StatementList(statements).render(family);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void hereFile(String path, StringBuilder builder) {
|
@Override
|
||||||
builder.append("cat > ").append(path).append(" <<'").append(marker).append("'\n");
|
public Builder delimeter(String delimeter) {
|
||||||
for (String line : lines) {
|
return Builder.class.cast(super.delimeter(delimeter));
|
||||||
builder.append(line).append("\n");
|
|
||||||
}
|
}
|
||||||
builder.append(marker).append("\n");
|
|
||||||
|
@Override
|
||||||
|
public Builder expandVariables(boolean expandVariables) {
|
||||||
|
return Builder.class.cast(super.expandVariables(expandVariables));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CreateOrOverwriteFile build() {
|
||||||
|
return new CreateOrOverwriteFile(path, lines, delimeter, expandVariables);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CreateOrOverwriteFile(String path, Iterable<String> lines, String delimeter, boolean expandVariables) {
|
||||||
|
super(path, lines, delimeter, expandVariables);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String appendToWindowsFile() {
|
||||||
|
return String.format("copy /y CON %s{lf}", path) + super.appendToWindowsFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuilder startHereFile() {
|
||||||
|
StringBuilder hereFile = new StringBuilder().append("cat > ").append(path);
|
||||||
|
if (expandVariables)
|
||||||
|
return hereFile.append(" <<-").append(delimeter).append("\n");
|
||||||
|
return hereFile.append(" <<-'").append(delimeter).append("'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,23 +22,27 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Predicates.instanceOf;
|
import static com.google.common.base.Predicates.instanceOf;
|
||||||
import static com.google.common.collect.Iterables.any;
|
import static com.google.common.collect.Iterables.any;
|
||||||
import static com.google.common.collect.Lists.newArrayList;
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
import static com.google.common.collect.Maps.newHashMap;
|
import static java.lang.String.format;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.createOrOverwriteFile;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.jclouds.scriptbuilder.ExitInsteadOfReturn;
|
import org.jclouds.scriptbuilder.ExitInsteadOfReturn;
|
||||||
import org.jclouds.scriptbuilder.ScriptBuilder;
|
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||||
import org.jclouds.scriptbuilder.util.Utils;
|
import org.jclouds.scriptbuilder.util.Utils;
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
import com.google.common.base.CaseFormat;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableList.Builder;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a run script
|
* Creates a run script
|
||||||
|
@ -46,7 +50,7 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class CreateRunScript extends StatementList {
|
public class CreateRunScript extends StatementList {
|
||||||
public final static String MARKER = "END_OF_SCRIPT";
|
public final static String DELIMETER = "END_OF_JCLOUDS_SCRIPT";
|
||||||
final String instanceName;
|
final String instanceName;
|
||||||
final Iterable<String> exports;
|
final Iterable<String> exports;
|
||||||
final String pwd;
|
final String pwd;
|
||||||
|
@ -58,44 +62,17 @@ public class CreateRunScript extends StatementList {
|
||||||
this.pwd = checkNotNull(pwd, "pwd").replaceAll("[/\\\\]", "{fs}");
|
this.pwd = checkNotNull(pwd, "pwd").replaceAll("[/\\\\]", "{fs}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AddTitleToFile implements Statement {
|
public static class AddExport implements Statement {
|
||||||
final String title;
|
|
||||||
final String file;
|
|
||||||
|
|
||||||
public AddTitleToFile(String title, String file) {
|
|
||||||
this.title = checkNotNull(title, "title");
|
|
||||||
this.file = checkNotNull(file, "file");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Map<OsFamily, String> OS_TO_TITLE_PATTERN = ImmutableMap.of(OsFamily.UNIX,
|
|
||||||
"echo \"PROMPT_COMMAND='echo -ne \\\"\\033]0;{title}\\007\\\"'\">>{file}\n", OsFamily.WINDOWS,
|
|
||||||
"echo title {title}>>{file}\r\n");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> functionDependencies(OsFamily family) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String render(OsFamily family) {
|
|
||||||
return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens(OS_TO_TITLE_PATTERN.get(family),
|
|
||||||
ImmutableMap.of("title", title, "file", file)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AddExportToFile implements Statement {
|
|
||||||
final String export;
|
final String export;
|
||||||
final String value;
|
final String value;
|
||||||
final String file;
|
|
||||||
|
|
||||||
public AddExportToFile(String export, String value, String file) {
|
public AddExport(String export, String value) {
|
||||||
this.export = checkNotNull(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export), "export");
|
this.export = checkNotNull(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export), "export");
|
||||||
this.value = checkNotNull(value, "value");
|
this.value = checkNotNull(value, "value");
|
||||||
this.file = checkNotNull(file, "file");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<OsFamily, String> OS_TO_EXPORT_PATTERN = ImmutableMap.of(OsFamily.UNIX,
|
public static final Map<OsFamily, String> OS_TO_EXPORT_PATTERN = ImmutableMap.of(OsFamily.UNIX,
|
||||||
"echo \"export {export}='{value}'\">>{file}\n", OsFamily.WINDOWS, "echo set {export}={value}>>{file}\r\n");
|
"export {export}='{value}'\n", OsFamily.WINDOWS, "set {export}={value}\r\n");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependencies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
|
@ -104,137 +81,91 @@ public class CreateRunScript extends StatementList {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String render(OsFamily family) {
|
public String render(OsFamily family) {
|
||||||
return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens(OS_TO_EXPORT_PATTERN.get(family),
|
return Utils
|
||||||
ImmutableMap.of("export", export, "value", value, "file", file)));
|
.replaceTokens(OS_TO_EXPORT_PATTERN.get(family), ImmutableMap.of("export", export, "value", value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String escapeVarTokens(String toEscape, OsFamily family) {
|
|
||||||
Map<String, String> inputToEscape = newHashMap();
|
|
||||||
for (ShellToken token : ImmutableList.of(ShellToken.VARL, ShellToken.VARR)) {
|
|
||||||
if (!token.to(family).equals("")) {
|
|
||||||
String tokenS = "{" + token.toString().toLowerCase() + "}";
|
|
||||||
inputToEscape.put(tokenS, "{escvar}" + tokenS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Entry<String, String> entry : inputToEscape.entrySet()) {
|
|
||||||
toEscape = toEscape.replace(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
return toEscape;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependencies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<OsFamily, String> OS_TO_CHMOD_PATTERN = ImmutableMap.of(OsFamily.UNIX, "chmod u+x {file}\n",
|
|
||||||
OsFamily.WINDOWS, "");
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String render(OsFamily family) {
|
public String render(OsFamily family) {
|
||||||
|
if (checkNotNull(family, "family") == OsFamily.WINDOWS)
|
||||||
|
throw new UnsupportedOperationException("windows not yet implemented");
|
||||||
List<Statement> statements = newArrayList();
|
List<Statement> statements = newArrayList();
|
||||||
Map<String, String> tokenMap = ShellToken.tokenValueMap(family);
|
final Map<String, String> tokenMap = ShellToken.tokenValueMap(family);
|
||||||
String runScript = Utils.replaceTokens(pwd + "{fs}" + instanceName + ".{sh}", tokenMap);
|
String runScript = Utils.replaceTokens(pwd + "{fs}" + instanceName + ".{sh}", tokenMap);
|
||||||
statements.add(interpret(String.format("{md} %s{lf}", pwd)));
|
statements.add(interpret(String.format("{md} %s{lf}", pwd)));
|
||||||
if (family == OsFamily.UNIX) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("\n");
|
builder.append("\n");
|
||||||
addUnixRunScriptHeader(family, runScript, builder);
|
addUnixRunScriptHeader(runScript, builder);
|
||||||
builder.append("\n");
|
builder.append("\n");
|
||||||
addUnixRunScript(runScript, builder);
|
addUnixRunScript(runScript, builder);
|
||||||
builder.append("\n");
|
builder.append("\n");
|
||||||
addUnixRunScriptFooter(family, runScript, builder);
|
addUnixRunScriptFooter(runScript, builder);
|
||||||
builder.append("\n");
|
builder.append("\n");
|
||||||
statements.add(interpret(builder.toString()));
|
statements.add(interpret(builder.toString()));
|
||||||
} else {
|
statements.add(exec("chmod u+x " + runScript));
|
||||||
statements.add(interpret(String.format("{rm} %s 2{closeFd}{lf}", runScript)));
|
|
||||||
for (String line : Splitter.on(ShellToken.LF.to(family)).split(ShellToken.BEGIN_SCRIPT.to(family))) {
|
|
||||||
if (!line.equals(""))
|
|
||||||
statements.add(appendToFile(line, runScript, family));
|
|
||||||
}
|
|
||||||
statements.add(new AddTitleToFile(instanceName, runScript));
|
|
||||||
statements.add(appendToFile(Utils.writeZeroPath(family).replace(ShellToken.LF.to(family), ""), runScript,
|
|
||||||
family));
|
|
||||||
statements.add(new AddExportToFile("instanceName", instanceName, runScript));
|
|
||||||
for (String export : exports) {
|
|
||||||
statements.add(new AddExportToFile(export, Utils.replaceTokens(
|
|
||||||
"{varl}" + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export) + "{varr}", tokenMap),
|
|
||||||
runScript));
|
|
||||||
}
|
|
||||||
statements.add(appendToFile("{cd} " + pwd, runScript, family));
|
|
||||||
statements.addAll(statements);
|
|
||||||
for (String line : Splitter.on(ShellToken.LF.to(family)).split(ShellToken.END_SCRIPT.to(family))) {
|
|
||||||
if (!line.equals(""))
|
|
||||||
statements.add(appendToFile(line, runScript, family));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statements
|
|
||||||
.add(interpret(Utils.replaceTokens(OS_TO_CHMOD_PATTERN.get(family), ImmutableMap.of("file", runScript))));
|
|
||||||
return new StatementList(statements).render(family);
|
return new StatementList(statements).render(family);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addUnixRunScriptFooter(OsFamily family, String runScript, StringBuilder builder) {
|
private void addUnixRunScriptFooter(String runScript, StringBuilder builder) {
|
||||||
builder.append("# add runscript footer\n");
|
builder.append("# add runscript footer\n");
|
||||||
builder.append("cat >> ").append(runScript).append(" <<'").append(MARKER).append("'\n");
|
Iterable<String> endScript = Splitter.on(ShellToken.LF.to(OsFamily.UNIX)).split(
|
||||||
builder.append(ShellToken.END_SCRIPT.to(family));
|
ShellToken.END_SCRIPT.to(OsFamily.UNIX));
|
||||||
builder.append(MARKER).append("\n");
|
builder.append(appendFile(runScript, endScript, DELIMETER).render(OsFamily.UNIX));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addUnixRunScript(String runScript, StringBuilder builder) {
|
private void addUnixRunScript(String runScript, StringBuilder builder) {
|
||||||
builder.append("# add desired commands from the user\n");
|
builder.append("# add desired commands from the user\n");
|
||||||
builder.append("cat >> ").append(runScript).append(" <<'").append(MARKER).append("'\n");
|
Builder<String> userCommands = ImmutableList.<String>builder();
|
||||||
builder.append("cd ").append(pwd).append("\n");
|
userCommands.add("cd " + pwd);
|
||||||
for (Statement statement : statements) {
|
for (Statement statement : statements) {
|
||||||
if (statement instanceof Call
|
if (statement instanceof Call
|
||||||
|| (statement instanceof StatementList && any(StatementList.class.cast(statement).delegate(),
|
|| (statement instanceof StatementList && any(StatementList.class.cast(statement).delegate(),
|
||||||
instanceOf(Call.class)))) {
|
instanceOf(Call.class)))) {
|
||||||
statement = new ExitInsteadOfReturn(statement);
|
statement = new ExitInsteadOfReturn(statement);
|
||||||
}
|
}
|
||||||
builder.append(statement.render(OsFamily.UNIX)).append("\n");
|
userCommands.addAll(Splitter.on('\n').split(statement.render(OsFamily.UNIX)));
|
||||||
}
|
}
|
||||||
builder.append(MARKER).append("\n");
|
builder.append(appendFile(runScript, userCommands.build(), DELIMETER).render(OsFamily.UNIX));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addUnixRunScriptHeader(OsFamily family, String runScript, StringBuilder builder) {
|
private void addUnixRunScriptHeader(String runScript, StringBuilder builder) {
|
||||||
builder.append("# create runscript header\n");
|
builder.append("# create runscript header\n");
|
||||||
builder.append("cat > ").append(runScript).append(" <<").append(MARKER).append("\n");
|
|
||||||
builder.append(ShellToken.BEGIN_SCRIPT.to(family));
|
Builder<String> beginningOfFile = ImmutableList.<String> builder();
|
||||||
builder.append("PROMPT_COMMAND='echo -ne \"\\033]0;").append(instanceName).append("\\007\"'\n");
|
beginningOfFile.addAll(Splitter.on(ShellToken.LF.to(OsFamily.UNIX)).split(
|
||||||
builder.append(Utils.writeZeroPath(family));
|
ShellToken.BEGIN_SCRIPT.to(OsFamily.UNIX)));
|
||||||
builder.append("export INSTANCE_NAME='").append(instanceName).append("'\n");
|
beginningOfFile.add(format("PROMPT_COMMAND='echo -ne \\\"\\033]0;%s\\007\\\"'", instanceName));
|
||||||
for (String export : exports) {
|
beginningOfFile.add(Utils.writeZeroPath(OsFamily.UNIX));
|
||||||
|
beginningOfFile.add(format("export INSTANCE_NAME='%s'", instanceName));
|
||||||
|
builder.append(createOrOverwriteFile(runScript, beginningOfFile.build(), DELIMETER).render(OsFamily.UNIX));
|
||||||
|
|
||||||
|
// expanding variables here.
|
||||||
|
builder.append(AppendFile.builder().path(runScript).delimeter(DELIMETER).expandVariables(true)
|
||||||
|
.lines(Iterables.transform(exports, new Function<String, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(String export) {
|
||||||
String variableNameInUpper = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export);
|
String variableNameInUpper = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, export);
|
||||||
builder.append("export ").append(variableNameInUpper).append("='$").append(variableNameInUpper).append("'\n");
|
return new StringBuilder().append("export ").append(variableNameInUpper).append("='$")
|
||||||
|
.append(variableNameInUpper).append("'").toString();
|
||||||
}
|
}
|
||||||
|
})).build().render(OsFamily.UNIX));
|
||||||
|
|
||||||
Map<String, String> functionsToWrite = ScriptBuilder.resolveFunctionDependenciesForStatements(
|
Map<String, String> functionsToWrite = ScriptBuilder.resolveFunctionDependenciesForStatements(
|
||||||
ImmutableMap.<String, String> of("abort", Utils.writeFunctionFromResource("abort", family)), statements,
|
ImmutableMap.<String, String> of("abort", Utils.writeFunctionFromResource("abort", OsFamily.UNIX)),
|
||||||
family);
|
statements, OsFamily.UNIX);
|
||||||
|
|
||||||
// if there are more functions than simply abort
|
// if there are more functions than simply abort
|
||||||
if (functionsToWrite.size() > 1) {
|
if (functionsToWrite.size() > 1) {
|
||||||
StringBuilder inNeedOfEscaping = new StringBuilder();
|
StringBuilder functions = new StringBuilder();
|
||||||
ScriptBuilder.writeFunctions(functionsToWrite, family, inNeedOfEscaping);
|
ScriptBuilder.writeFunctions(functionsToWrite, OsFamily.UNIX, functions);
|
||||||
builder.append(inNeedOfEscaping.toString().replace("$", "\\$"));
|
builder.append(appendFile(runScript, functions.toString(), DELIMETER).render(OsFamily.UNIX));
|
||||||
}
|
}
|
||||||
builder.append(MARKER).append("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement appendToFile(String line, String runScript, OsFamily family) {
|
|
||||||
String quote = "";
|
|
||||||
if (!ShellToken.VQ.to(family).equals("")) {
|
|
||||||
quote = "'";
|
|
||||||
} else {
|
|
||||||
line = escapeVarTokens(line, family);
|
|
||||||
}
|
|
||||||
return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format("echo %s%s%s>>%s{lf}", quote, line,
|
|
||||||
quote, runScript)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Pattern REDIRECT_FD_PATTERN = Pattern.compile(".*[0-2]>>.*");
|
|
||||||
|
|
||||||
static String addSpaceToEnsureWeDontAccidentallyRedirectFd(String line) {
|
|
||||||
return REDIRECT_FD_PATTERN.matcher(line).matches() ? line.replace(">>", " >>") : line;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -103,7 +103,7 @@ public enum ShellToken {
|
||||||
case WINDOWS:
|
case WINDOWS:
|
||||||
return " exit /b 0\r\n";
|
return " exit /b 0\r\n";
|
||||||
case UNIX:
|
case UNIX:
|
||||||
return " return 0\n}\n";
|
return " return $?\n}\n";
|
||||||
}
|
}
|
||||||
case ESCVAR:
|
case ESCVAR:
|
||||||
switch (family) {
|
switch (family) {
|
||||||
|
@ -173,7 +173,7 @@ public enum ShellToken {
|
||||||
case WINDOWS:
|
case WINDOWS:
|
||||||
return "exit /b 0\r\n";
|
return "exit /b 0\r\n";
|
||||||
case UNIX:
|
case UNIX:
|
||||||
return "exit 0\n";
|
return "exit $?\n";
|
||||||
}
|
}
|
||||||
case EXPORT:
|
case EXPORT:
|
||||||
switch (family) {
|
switch (family) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,20 +65,24 @@ public class Statements {
|
||||||
return new Call(function, args);
|
return new Call(function, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Statement appendFile(String path, Iterable<String> lines) {
|
public static Statement appendFile(String path, String line, String delimeter) {
|
||||||
return new AppendFile(path, lines);
|
return AppendFile.builder().path(path).lines(ImmutableSet.of(line)).delimeter(delimeter).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Statement appendFile(String path, Iterable<String> lines, String marker) {
|
public static Statement appendFile(String path, Iterable<String> lines) {
|
||||||
return new AppendFile(path, lines, marker);
|
return AppendFile.builder().path(path).lines(lines).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Statement appendFile(String path, Iterable<String> lines, String delimeter) {
|
||||||
|
return AppendFile.builder().path(path).lines(lines).delimeter(delimeter).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Statement createOrOverwriteFile(String path, Iterable<String> lines) {
|
public static Statement createOrOverwriteFile(String path, Iterable<String> lines) {
|
||||||
return new CreateOrOverwriteFile(path, lines);
|
return CreateOrOverwriteFile.builder().path(path).lines(lines).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Statement createOrOverwriteFile(String path, Iterable<String> lines, String marker) {
|
public static Statement createOrOverwriteFile(String path, Iterable<String> lines, String delimeter) {
|
||||||
return new CreateOrOverwriteFile(path, lines, marker);
|
return CreateOrOverwriteFile.builder().path(path).lines(lines).delimeter(delimeter).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CreateRunScript createRunScript(String instanceName, Iterable<String> exports, String pwd,
|
public static CreateRunScript createRunScript(String instanceName, Iterable<String> exports, String pwd,
|
||||||
|
@ -101,7 +106,8 @@ public class Statements {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Runs the script in a way that it can be matched later with {@link #findPid}
|
* Runs the script in a way that it can be matched later with
|
||||||
|
* {@link #findPid}
|
||||||
*
|
*
|
||||||
* @param instanceName
|
* @param instanceName
|
||||||
* - what to match the process on
|
* - what to match the process on
|
||||||
|
@ -119,7 +125,8 @@ public class Statements {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kills the pid and subprocesses related to the variable {@code FOUND_PID} if set.
|
* Kills the pid and subprocesses related to the variable {@code FOUND_PID}
|
||||||
|
* if set.
|
||||||
*
|
*
|
||||||
* @see #findPid
|
* @see #findPid
|
||||||
*/
|
*/
|
||||||
|
@ -128,7 +135,8 @@ public class Statements {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* statement can have multiple newlines, note you should use {@code lf} to be portable
|
* statement can have multiple newlines, note you should use {@code lf} to be
|
||||||
|
* portable
|
||||||
*
|
*
|
||||||
* @see ShellToken
|
* @see ShellToken
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -94,11 +94,11 @@ public class SwitchArg implements Statement, AcceptsStatementVisitor {
|
||||||
if (shouldIndent)
|
if (shouldIndent)
|
||||||
actionBuilder.append(INDENT);
|
actionBuilder.append(INDENT);
|
||||||
actionBuilder.append(line).append(ShellToken.LF.to(family));
|
actionBuilder.append(line).append(ShellToken.LF.to(family));
|
||||||
if (line.indexOf(CreateRunScript.MARKER) != -1) {
|
if (line.indexOf(CreateRunScript.DELIMETER) != -1) {
|
||||||
inRunScript = inRunScript ? false : true;
|
inRunScript = inRunScript ? false : true;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (line.indexOf(AppendFile.MARKER) != -1) {
|
if (line.indexOf(AppendFile.DELIMETER) != -1) {
|
||||||
inCreateFile = inCreateFile ? false : true;
|
inCreateFile = inCreateFile ? false : true;
|
||||||
}
|
}
|
||||||
shouldIndent = !inCreateFile && !inRunScript;
|
shouldIndent = !inCreateFile && !inRunScript;
|
||||||
|
|
|
@ -19,27 +19,30 @@
|
||||||
package org.jclouds.scriptbuilder.statements.login;
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
import static com.google.common.base.Charsets.UTF_8;
|
import static com.google.common.base.Charsets.UTF_8;
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.jclouds.crypto.Sha512Crypt;
|
import org.jclouds.crypto.Sha512Crypt;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||||
import org.jclouds.scriptbuilder.statements.ssh.SshStatements;
|
import org.jclouds.scriptbuilder.statements.ssh.SshStatements;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.inject.ImplementedBy;
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
@ -288,7 +291,8 @@ public class AdminAccess implements Statement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Config config;
|
@VisibleForTesting
|
||||||
|
Config config;
|
||||||
|
|
||||||
protected AdminAccess(Config in) {
|
protected AdminAccess(Config in) {
|
||||||
this.config = checkNotNull(in, "in");
|
this.config = checkNotNull(in, "in");
|
||||||
|
@ -344,9 +348,14 @@ public class AdminAccess implements Statement {
|
||||||
checkNotNull(family, "family");
|
checkNotNull(family, "family");
|
||||||
if (family == OsFamily.WINDOWS)
|
if (family == OsFamily.WINDOWS)
|
||||||
throw new UnsupportedOperationException("windows not yet implemented");
|
throw new UnsupportedOperationException("windows not yet implemented");
|
||||||
checkNotNull(config.getAdminUsername(), "adminUsername");
|
checkArgument(!"root".equals(config.getAdminUsername()), "cannot create admin user 'root'; " +
|
||||||
Preconditions.checkArgument(!"root".equals(config.getAdminUsername()), "cannot create admin user 'root'; " +
|
|
||||||
"ensure jclouds is not running as root, or specify an explicit non-root username in AdminAccess");
|
"ensure jclouds is not running as root, or specify an explicit non-root username in AdminAccess");
|
||||||
|
if (Iterables.any(
|
||||||
|
Lists.newArrayList(config.getAdminUsername(), config.getAdminPassword(), config.getAdminPublicKey(),
|
||||||
|
config.getAdminPrivateKey(), config.getLoginPassword()), Predicates.isNull()))
|
||||||
|
init(new DefaultConfiguration());
|
||||||
|
|
||||||
|
checkNotNull(config.getAdminUsername(), "adminUsername");
|
||||||
checkNotNull(config.getAdminPassword(), "adminPassword");
|
checkNotNull(config.getAdminPassword(), "adminPassword");
|
||||||
checkNotNull(config.getAdminPublicKey(), "adminPublicKey");
|
checkNotNull(config.getAdminPublicKey(), "adminPublicKey");
|
||||||
checkNotNull(config.getAdminPrivateKey(), "adminPrivateKey");
|
checkNotNull(config.getAdminPrivateKey(), "adminPrivateKey");
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package org.jclouds.scriptbuilder.statements.login;
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
|
import static org.jclouds.scriptbuilder.domain.Statements.createOrOverwriteFile;
|
||||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||||
|
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
@ -45,8 +45,7 @@ public class Sudoers implements Statement {
|
||||||
if (family == OsFamily.WINDOWS)
|
if (family == OsFamily.WINDOWS)
|
||||||
throw new UnsupportedOperationException("windows not yet implemented");
|
throw new UnsupportedOperationException("windows not yet implemented");
|
||||||
Builder<Statement> statements = ImmutableList.<Statement> builder();
|
Builder<Statement> statements = ImmutableList.<Statement> builder();
|
||||||
statements.add(exec("{rm} " + sudoers));
|
statements.add(createOrOverwriteFile(sudoers, ImmutableSet.of("root ALL = (ALL) ALL", "%wheel ALL = (ALL) NOPASSWD:ALL")));
|
||||||
statements.add(appendFile(sudoers, ImmutableSet.of("root ALL = (ALL) ALL", "%wheel ALL = (ALL) NOPASSWD:ALL")));
|
|
||||||
statements.add(exec("chmod 0440 " + sudoers));
|
statements.add(exec("chmod 0440 " + sudoers));
|
||||||
return new StatementList(statements.build()).render(family);
|
return new StatementList(statements.build()).render(family);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class SshdConfig implements Statement {
|
||||||
Statement prependSshdConfig = exec(String.format(
|
Statement prependSshdConfig = exec(String.format(
|
||||||
"exec 3<> %1$s && awk -v TEXT=\"%2$s\n\" 'BEGIN {print TEXT}{print}' %1$s >&3", sshdConfig,
|
"exec 3<> %1$s && awk -v TEXT=\"%2$s\n\" 'BEGIN {print TEXT}{print}' %1$s >&3", sshdConfig,
|
||||||
linesToPrepend));
|
linesToPrepend));
|
||||||
Statement reloadSshdConfig = exec("/etc/init.d/sshd reload||/etc/init.d/ssh reload");
|
Statement reloadSshdConfig = exec("hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload");
|
||||||
return newStatementList(prependSshdConfig, reloadSshdConfig).render(family);
|
return newStatementList(prependSshdConfig, reloadSshdConfig).render(family);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,9 @@ public class InitBuilderTest {
|
||||||
appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList.<String> of("hello world")),
|
appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList.<String> of("hello world")),
|
||||||
exec("find /")));
|
exec("find /")));
|
||||||
|
|
||||||
@Test
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
public void testBuildSimpleWindows() throws MalformedURLException, IOException {
|
public void testBuildSimpleWindows() throws MalformedURLException, IOException {
|
||||||
assertEquals(
|
testInitBuilder.render(OsFamily.WINDOWS);
|
||||||
testInitBuilder.render(OsFamily.WINDOWS),
|
|
||||||
CharStreams.toString(Resources.newReaderSupplier(
|
|
||||||
Resources.getResource("test_init." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.scriptbuilder;
|
||||||
|
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.call;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.io.CharStreams;
|
||||||
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests possible uses of InitScript
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class InitScriptTest {
|
||||||
|
InitScript testInitScript = InitScript
|
||||||
|
.builder()
|
||||||
|
.name("mkebsboot")
|
||||||
|
.home("/mnt/tmp")
|
||||||
|
.exportVariables(ImmutableMap.of("tmpDir", "/mnt/tmp"))
|
||||||
|
.run(appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList.<String> of("hello world")),
|
||||||
|
exec("find /")).build();
|
||||||
|
|
||||||
|
public void testBuildSimpleWindows() throws MalformedURLException, IOException {
|
||||||
|
assertEquals(
|
||||||
|
testInitScript.render(OsFamily.WINDOWS),
|
||||||
|
CharStreams.toString(Resources.newReaderSupplier(
|
||||||
|
Resources.getResource("test_init." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBuildSimpleUNIX() throws MalformedURLException, IOException {
|
||||||
|
assertEquals(
|
||||||
|
testInitScript.render(OsFamily.UNIX),
|
||||||
|
CharStreams.toString(Resources.newReaderSupplier(
|
||||||
|
Resources.getResource("test_init." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBuildEBS() throws MalformedURLException, IOException {
|
||||||
|
assertEquals(InitScript
|
||||||
|
.builder()
|
||||||
|
.name("mkebsboot")
|
||||||
|
.home("tmp")
|
||||||
|
.logDir("/tmp/logs")
|
||||||
|
.exportVariables(ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"))
|
||||||
|
.run(interpret(
|
||||||
|
"echo creating a filesystem and mounting the ebs volume",
|
||||||
|
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||||
|
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||||
|
"yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
|
||||||
|
"mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||||
|
"echo making a local working copy of the boot disk",
|
||||||
|
"rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}",
|
||||||
|
"echo preparing the local working copy",
|
||||||
|
"touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
|
||||||
|
"echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}",
|
||||||
|
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
|
||||||
|
"du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source",
|
||||||
|
"du -sk {varl}IMAGE_DIR{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||||
|
"umount {varl}EBS_MOUNT_POINT{varr}", "echo ----COMPLETE----")).build().render(OsFamily.UNIX),
|
||||||
|
CharStreams.toString(Resources.newReaderSupplier(
|
||||||
|
Resources.getResource("test_ebs." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
InitScript testCallInRun = InitScript.builder().name("testcall").init(exec("echo hello"))
|
||||||
|
.run(call("sourceEnvFile", "foo"), exec("find /")).build();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCallInRunUNIX() throws MalformedURLException, IOException {
|
||||||
|
assertEquals(
|
||||||
|
testCallInRun.render(OsFamily.UNIX),
|
||||||
|
CharStreams.toString(Resources.newReaderSupplier(
|
||||||
|
Resources.getResource("test_init_script." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -53,16 +53,9 @@ public class CreateRunScriptTest {
|
||||||
.getResource("test_runrun." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)));
|
.getResource("test_runrun." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWINDOWS() throws IOException {
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
assertEquals(statement.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources
|
public void testWINDOWSUnimplemented() throws IOException {
|
||||||
.getResource("test_runrun." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8)));
|
statement.render(OsFamily.WINDOWS);
|
||||||
}
|
|
||||||
|
|
||||||
public void testRedirectGuard() {
|
|
||||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo>>"), "foo>>");
|
|
||||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), "foo0 >>");
|
|
||||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), "foo1 >>");
|
|
||||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), "foo2 >>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ public class ShellTokenTest {
|
||||||
"args", "$@").put("varl", "$").put("return", "return").put("exit", "exit").put(
|
"args", "$@").put("varl", "$").put("return", "return").put("exit", "exit").put(
|
||||||
"varr", "").put("libraryPathVariable", "LD_LIBRARY_PATH").put("beginScript",
|
"varr", "").put("libraryPathVariable", "LD_LIBRARY_PATH").put("beginScript",
|
||||||
"#!/bin/bash\nset +u\nshopt -s xpg_echo\nshopt -s expand_aliases\n").put(
|
"#!/bin/bash\nset +u\nshopt -s xpg_echo\nshopt -s expand_aliases\n").put(
|
||||||
"endScript", "exit 0\n").put("vq", "\"").put("beginFunctions", "").put(
|
"endScript", "exit $?\n").put("vq", "\"").put("beginFunctions", "").put(
|
||||||
"endFunctions", "").put("fncl", "function ").put("fncr", " {\n").put("fnce",
|
"endFunctions", "").put("fncl", "function ").put("fncr", " {\n").put("fnce",
|
||||||
" return 0\n}\n").put("export", "export").put("rm", "rm").put("cd", "cd").put(
|
" return $?\n}\n").put("export", "export").put("rm", "rm").put("cd", "cd").put(
|
||||||
"tmp", "/tmp").put("uid", "$USER").put("root", "/").put("closeFd", ">&-").put("md",
|
"tmp", "/tmp").put("uid", "$USER").put("root", "/").put("closeFd", ">&-").put("md",
|
||||||
"mkdir -p").put("escvar", "\\").build();
|
"mkdir -p").put("escvar", "\\").build();
|
||||||
assertEquals(ShellToken.tokenValueMap(OsFamily.UNIX), expected);
|
assertEquals(ShellToken.tokenValueMap(OsFamily.UNIX), expected);
|
||||||
|
|
|
@ -39,7 +39,17 @@ public class SwitchArgTest {
|
||||||
assertEquals(new SwitchArg(1, ImmutableMap.of("0", newStatementList(appendFile(
|
assertEquals(new SwitchArg(1, ImmutableMap.of("0", newStatementList(appendFile(
|
||||||
"{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", Collections.singleton("hello world")),
|
"{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", Collections.singleton("hello world")),
|
||||||
interpret("echo hello zero{lf}")), "1", interpret("echo hello one{lf}"))).render(OsFamily.UNIX),
|
interpret("echo hello zero{lf}")), "1", interpret("echo hello one{lf}"))).render(OsFamily.UNIX),
|
||||||
"case $1 in\n0)\n cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'\nhello world\nEND_OF_FILE\n echo hello zero\n ;;\n1)\n echo hello one\n ;;\nesac\n");
|
"case $1 in\n"+
|
||||||
|
"0)\n"+
|
||||||
|
" cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\thello world\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
" echo hello zero\n"+
|
||||||
|
" ;;\n"+
|
||||||
|
"1)\n"+
|
||||||
|
" echo hello one\n"+
|
||||||
|
" ;;\n"+
|
||||||
|
"esac\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSwitchArgWindows() {
|
public void testSwitchArgWindows() {
|
||||||
|
|
|
@ -18,20 +18,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.scriptbuilder.functions;
|
package org.jclouds.scriptbuilder.functions;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.createMock;
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
import static org.easymock.EasyMock.verify;
|
||||||
import static org.easymock.classextension.EasyMock.verify;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,8 +96,8 @@ public class CredentialsFromAdminAccessTest {
|
||||||
replay(statement);
|
replay(statement);
|
||||||
replay(creds);
|
replay(creds);
|
||||||
|
|
||||||
InitBuilder testInitBuilder = new InitBuilder("mkebsboot", "/mnt/tmp", "/mnt/tmp", ImmutableMap.of("tmpDir",
|
InitScript testInitBuilder = InitScript.builder().name("mkebsboot").home("/mnt/tmp")
|
||||||
"/mnt/tmp"), ImmutableList.<Statement> of(statement));
|
.exportVariables(ImmutableMap.of("tmpDir", "/mnt/tmp")).run(statement).build();
|
||||||
|
|
||||||
assertEquals(CredentialsFromAdminAccess.INSTANCE.apply(testInitBuilder), creds);
|
assertEquals(CredentialsFromAdminAccess.INSTANCE.apply(testInitBuilder), creds);
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,16 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.scriptbuilder.functions;
|
package org.jclouds.scriptbuilder.functions;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.createMock;
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
import static org.easymock.EasyMock.verify;
|
||||||
import static org.easymock.classextension.EasyMock.verify;
|
|
||||||
|
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,8 +99,8 @@ public class InitAdminAccessTest {
|
||||||
replay(statement);
|
replay(statement);
|
||||||
replay(newStatement);
|
replay(newStatement);
|
||||||
|
|
||||||
InitBuilder testInitBuilder = new InitBuilder("mkebsboot", "/mnt/tmp", "/mnt/tmp", ImmutableMap.of("tmpDir",
|
InitScript testInitBuilder = InitScript.builder().name("mkebsboot").home("/mnt/tmp")
|
||||||
"/mnt/tmp"), ImmutableList.<Statement> of(statement));
|
.exportVariables(ImmutableMap.of("tmpDir", "/mnt/tmp")).run(statement).build();
|
||||||
|
|
||||||
InitAdminAccess initAdminAccess = new InitAdminAccess(configuration);
|
InitAdminAccess initAdminAccess = new InitAdminAccess(configuration);
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,13 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitScript;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
|
@ -48,11 +47,10 @@ public class InstallJDKTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInstallJDKUNIXInScriptBuilderSourcesSetupPublicCurl() throws IOException {
|
public void testInstallJDKUNIXInScriptBuilderSourcesSetupPublicCurl() throws IOException {
|
||||||
assertEquals(
|
assertEquals(InitScript.builder().name("install_jdk").run(InstallJDK.fromURL()).build().render(OsFamily.UNIX),
|
||||||
new InitBuilder("install_jdk", ImmutableSet.<Statement> of(), ImmutableSet.<Statement> of(InstallJDK
|
|
||||||
.fromURL())).render(OsFamily.UNIX),
|
|
||||||
CharStreams.toString(Resources.newReaderSupplier(
|
CharStreams.toString(Resources.newReaderSupplier(
|
||||||
Resources.getResource("test_install_jdk_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)));
|
Resources.getResource("test_install_jdk_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||||
|
Charsets.UTF_8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInstallJDKUNIXWithURL() throws IOException {
|
public void testInstallJDKUNIXWithURL() throws IOException {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.scriptbuilder.statements.login;
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -88,4 +89,34 @@ public class AdminAccessTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
|
public void testFamilyRequiredAllowed() throws IOException {
|
||||||
|
AdminAccess.standard().render(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWhenUninitializedLazyInitWithDefaultConfiguration() throws IOException {
|
||||||
|
AdminAccess access = AdminAccess.standard();
|
||||||
|
// before rendered, holder is empty
|
||||||
|
assertEquals(access.config.getAdminUsername(), null);
|
||||||
|
assertEquals(access.config.getAdminPassword(), null);
|
||||||
|
assertEquals(access.config.getAdminPublicKey(), null);
|
||||||
|
assertEquals(access.config.getAdminPrivateKey(), null);
|
||||||
|
assertEquals(access.config.getLoginPassword(), null);
|
||||||
|
access.render(OsFamily.UNIX);
|
||||||
|
// DefaultConfiguration
|
||||||
|
try {
|
||||||
|
assertEquals(access.config.getAdminUsername(), System.getProperty("user.name"));
|
||||||
|
assertNotNull(access.config.getAdminPassword());
|
||||||
|
assertNotNull(access.config.getAdminPublicKey());
|
||||||
|
assertNotNull(access.config.getAdminPrivateKey());
|
||||||
|
assertNotNull(access.config.getLoginPassword());
|
||||||
|
} catch (AssertionError e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// we are catching throwables here, in case the test runner doesn't
|
||||||
|
// have ssh keys setup
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,11 @@ public class SudoStatementsTest {
|
||||||
public void testCreateWheelUNIX() {
|
public void testCreateWheelUNIX() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
SudoStatements.createWheel().render(OsFamily.UNIX),
|
SudoStatements.createWheel().render(OsFamily.UNIX),
|
||||||
"rm /etc/sudoers\ncat >> /etc/sudoers <<'END_OF_FILE'\nroot ALL = (ALL) ALL\n%wheel ALL = (ALL) NOPASSWD:ALL\nEND_OF_FILE\nchmod 0440 /etc/sudoers\n");
|
"cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\troot ALL = (ALL) ALL\n"+
|
||||||
|
"\t%wheel ALL = (ALL) NOPASSWD:ALL\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 0440 /etc/sudoers\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
|
|
|
@ -61,13 +61,13 @@ public class UserAddTest {
|
||||||
public void testWithSshAuthorizedKeyUNIX() {
|
public void testWithSshAuthorizedKeyUNIX() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
UserAdd.builder().login("me").authorizeRSAPublicKey("rsapublickey").build().render(OsFamily.UNIX),
|
UserAdd.builder().login("me").authorizeRSAPublicKey("rsapublickey").build().render(OsFamily.UNIX),
|
||||||
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\ncat >> /home/users/me/.ssh/authorized_keys <<'END_OF_FILE'\nrsapublickey\nEND_OF_FILE\nchmod 600 /home/users/me/.ssh/authorized_keys\nchown -R me /home/users/me\n");
|
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\ncat >> /home/users/me/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n\trsapublickey\nEND_OF_JCLOUDS_FILE\nchmod 600 /home/users/me/.ssh/authorized_keys\nchown -R me /home/users/me\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWithSshInstalledKeyUNIX() {
|
public void testWithSshInstalledKeyUNIX() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
UserAdd.builder().login("me").installRSAPrivateKey("rsaprivate").build().render(OsFamily.UNIX),
|
UserAdd.builder().login("me").installRSAPrivateKey("rsaprivate").build().render(OsFamily.UNIX),
|
||||||
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\nrm /home/users/me/.ssh/id_rsa\ncat >> /home/users/me/.ssh/id_rsa <<'END_OF_FILE'\nrsaprivate\nEND_OF_FILE\nchmod 600 /home/users/me/.ssh/id_rsa\nchown -R me /home/users/me\n");
|
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\nrm /home/users/me/.ssh/id_rsa\ncat >> /home/users/me/.ssh/id_rsa <<-'END_OF_JCLOUDS_FILE'\n\trsaprivate\nEND_OF_JCLOUDS_FILE\nchmod 600 /home/users/me/.ssh/id_rsa\nchown -R me /home/users/me\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
|
|
|
@ -34,26 +34,46 @@ public class AuthorizeRSAPublicKeyTest {
|
||||||
public void testAuthorizeRSAPublicKeyUNIXCurrentUser() {
|
public void testAuthorizeRSAPublicKeyUNIXCurrentUser() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new AuthorizeRSAPublicKeys(ImmutableSet.of("ssh-dss AAAAB")).render(OsFamily.UNIX),
|
new AuthorizeRSAPublicKeys(ImmutableSet.of("ssh-dss AAAAB")).render(OsFamily.UNIX),
|
||||||
"mkdir -p ~/.ssh\ncat >> ~/.ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\nEND_OF_FILE\nchmod 600 ~/.ssh/authorized_keys\n");
|
"mkdir -p ~/.ssh\n"+
|
||||||
|
"cat >> ~/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\tssh-dss AAAAB\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 600 ~/.ssh/authorized_keys\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAuthorizeRSAPublicKeyUNIXCurrentUserWith2Keys() {
|
public void testAuthorizeRSAPublicKeyUNIXCurrentUserWith2Keys() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new AuthorizeRSAPublicKeys(ImmutableSet.of("ssh-dss AAAAB", "ssh-dss CCCCD")).render(OsFamily.UNIX),
|
new AuthorizeRSAPublicKeys(ImmutableSet.of("ssh-dss AAAAB", "ssh-dss CCCCD")).render(OsFamily.UNIX),
|
||||||
"mkdir -p ~/.ssh\ncat >> ~/.ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\n\nssh-dss CCCCD\nEND_OF_FILE\nchmod 600 ~/.ssh/authorized_keys\n");
|
"mkdir -p ~/.ssh\n"+
|
||||||
|
"cat >> ~/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\tssh-dss AAAAB\n"+
|
||||||
|
"\t\n"+
|
||||||
|
"\tssh-dss CCCCD\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 600 ~/.ssh/authorized_keys\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAuthorizeRSAPublicKeyUNIXSpecifiedDir() {
|
public void testAuthorizeRSAPublicKeyUNIXSpecifiedDir() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new AuthorizeRSAPublicKeys("/home/me/.ssh", ImmutableSet.of("ssh-dss AAAAB")).render(OsFamily.UNIX),
|
new AuthorizeRSAPublicKeys("/home/me/.ssh", ImmutableSet.of("ssh-dss AAAAB")).render(OsFamily.UNIX),
|
||||||
"mkdir -p /home/me/.ssh\ncat >> /home/me/.ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\nEND_OF_FILE\nchmod 600 /home/me/.ssh/authorized_keys\n");
|
"mkdir -p /home/me/.ssh\n"+
|
||||||
|
"cat >> /home/me/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\tssh-dss AAAAB\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 600 /home/me/.ssh/authorized_keys\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAuthorizeRSAPublicKeyUNIXSpecifiedDirWith2Keys() {
|
public void testAuthorizeRSAPublicKeyUNIXSpecifiedDirWith2Keys() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new AuthorizeRSAPublicKeys("/home/me/.ssh", ImmutableSet.of("ssh-dss AAAAB", "ssh-dss CCCCD"))
|
new AuthorizeRSAPublicKeys("/home/me/.ssh", ImmutableSet.of("ssh-dss AAAAB", "ssh-dss CCCCD"))
|
||||||
.render(OsFamily.UNIX),
|
.render(OsFamily.UNIX),
|
||||||
"mkdir -p /home/me/.ssh\ncat >> /home/me/.ssh/authorized_keys <<'END_OF_FILE'\nssh-dss AAAAB\n\nssh-dss CCCCD\nEND_OF_FILE\nchmod 600 /home/me/.ssh/authorized_keys\n");
|
"mkdir -p /home/me/.ssh\n"+
|
||||||
|
"cat >> /home/me/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\tssh-dss AAAAB\n"+
|
||||||
|
"\t\n"+
|
||||||
|
"\tssh-dss CCCCD\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 600 /home/me/.ssh/authorized_keys\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
|
|
|
@ -33,15 +33,28 @@ public class InstallRSAPrivateKeyTest {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new InstallRSAPrivateKey("-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n")
|
new InstallRSAPrivateKey("-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n")
|
||||||
.render(OsFamily.UNIX),
|
.render(OsFamily.UNIX),
|
||||||
"mkdir -p ~/.ssh\nrm ~/.ssh/id_rsa\ncat >> ~/.ssh/id_rsa <<'END_OF_FILE'\n-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n\nEND_OF_FILE\nchmod 600 ~/.ssh/id_rsa\n");
|
"mkdir -p ~/.ssh\n"+
|
||||||
|
"rm ~/.ssh/id_rsa\n"+
|
||||||
|
"cat >> ~/.ssh/id_rsa <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\t-----BEGIN RSA PRIVATE KEY-----\n"+
|
||||||
|
"\t-----END RSA PRIVATE KEY-----\n"+
|
||||||
|
"\t\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 600 ~/.ssh/id_rsa\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInstallRSAPrivateKeyUNIXSpecifiedHome() {
|
public void testInstallRSAPrivateKeyUNIXSpecifiedHome() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new InstallRSAPrivateKey("/home/me/.ssh", "-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n")
|
new InstallRSAPrivateKey("/home/me/.ssh", "-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n")
|
||||||
.render(OsFamily.UNIX),
|
.render(OsFamily.UNIX),
|
||||||
"mkdir -p /home/me/.ssh\nrm /home/me/.ssh/id_rsa\ncat >> /home/me/.ssh/id_rsa <<'END_OF_FILE'\n-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n\nEND_OF_FILE\nchmod 600 /home/me/.ssh/id_rsa\n");
|
"mkdir -p /home/me/.ssh\n"+
|
||||||
}
|
"rm /home/me/.ssh/id_rsa\n"+
|
||||||
|
"cat >> /home/me/.ssh/id_rsa <<-'END_OF_JCLOUDS_FILE'\n"+
|
||||||
|
"\t-----BEGIN RSA PRIVATE KEY-----\n"+
|
||||||
|
"\t-----END RSA PRIVATE KEY-----\n"+
|
||||||
|
"\t\n"+
|
||||||
|
"END_OF_JCLOUDS_FILE\n"+
|
||||||
|
"chmod 600 /home/me/.ssh/id_rsa\n"); }
|
||||||
|
|
||||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
public void testInstallRSAPrivateKeyWINDOWS() {
|
public void testInstallRSAPrivateKeyWINDOWS() {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class SshStatementsTest {
|
||||||
.append("PasswordAuthentication no").append("\n")//
|
.append("PasswordAuthentication no").append("\n")//
|
||||||
.append("PermitRootLogin no").append("\n")//
|
.append("PermitRootLogin no").append("\n")//
|
||||||
.append("\" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3").append("\n")//
|
.append("\" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3").append("\n")//
|
||||||
.append("/etc/init.d/sshd reload||/etc/init.d/ssh reload").append("\n").toString());
|
.append("hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload").append("\n").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSshdConfigUNIX() {
|
public void testSshdConfigUNIX() {
|
||||||
|
@ -46,7 +46,7 @@ public class SshStatementsTest {
|
||||||
new StringBuilder().append("exec 3<> /etc/ssh/sshd_config && awk -v TEXT=\"")//
|
new StringBuilder().append("exec 3<> /etc/ssh/sshd_config && awk -v TEXT=\"")//
|
||||||
.append("AddressFamily inet6").append("\n")//
|
.append("AddressFamily inet6").append("\n")//
|
||||||
.append("\" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3").append("\n")//
|
.append("\" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3").append("\n")//
|
||||||
.append("/etc/init.d/sshd reload||/etc/init.d/ssh reload").append("\n").toString());
|
.append("hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload").append("\n").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
cat >> /etc/chef/client.rb <<'END_OF_FILE'
|
cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
|
||||||
log_level :info
|
log_level :info
|
||||||
log_location STDOUT
|
log_location STDOUT
|
||||||
chef_server_url "http://localhost:4000"
|
chef_server_url "http://localhost:4000"
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
cat > /etc/chef/client.rb <<'END_OF_FILE'
|
cat > /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
|
||||||
log_level :info
|
log_level :info
|
||||||
log_location STDOUT
|
log_location STDOUT
|
||||||
chef_server_url "http://localhost:4000"
|
chef_server_url "http://localhost:4000"
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
|
|
|
@ -16,6 +16,6 @@ chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
||||||
/etc/init.d/sshd reload||/etc/init.d/ssh reload
|
hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload
|
||||||
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(1)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(1)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
||||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
rm /etc/sudoers
|
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
|
||||||
root ALL = (ALL) ALL
|
root ALL = (ALL) ALL
|
||||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 0440 /etc/sudoers
|
chmod 0440 /etc/sudoers
|
||||||
mkdir -p /home/users
|
mkdir -p /home/users
|
||||||
groupadd -f wheel
|
groupadd -f wheel
|
||||||
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(bar)' foo
|
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(bar)' foo
|
||||||
mkdir -p /home/users/foo/.ssh
|
mkdir -p /home/users/foo/.ssh
|
||||||
cat >> /home/users/foo/.ssh/authorized_keys <<'END_OF_FILE'
|
cat >> /home/users/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||||
fooPublicKey
|
fooPublicKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/foo/.ssh/authorized_keys
|
chmod 600 /home/users/foo/.ssh/authorized_keys
|
||||||
chown -R foo /home/users/foo
|
chown -R foo /home/users/foo
|
||||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
||||||
/etc/init.d/sshd reload||/etc/init.d/ssh reload
|
hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload
|
||||||
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(0)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(0)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
||||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
mkdir -p /home/users
|
mkdir -p /home/users
|
||||||
useradd -s /bin/bash -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
useradd -s /bin/bash -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
||||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||||
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<'END_OF_FILE'
|
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||||
publicKey
|
publicKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
||||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||||
rm /home/users/defaultAdminUsername/.ssh/id_rsa
|
rm /home/users/defaultAdminUsername/.ssh/id_rsa
|
||||||
cat >> /home/users/defaultAdminUsername/.ssh/id_rsa <<'END_OF_FILE'
|
cat >> /home/users/defaultAdminUsername/.ssh/id_rsa <<-'END_OF_JCLOUDS_FILE'
|
||||||
privateKey
|
privateKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/defaultAdminUsername/.ssh/id_rsa
|
chmod 600 /home/users/defaultAdminUsername/.ssh/id_rsa
|
||||||
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
rm /etc/sudoers
|
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
|
||||||
root ALL = (ALL) ALL
|
root ALL = (ALL) ALL
|
||||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 0440 /etc/sudoers
|
chmod 0440 /etc/sudoers
|
||||||
mkdir -p /home/users
|
mkdir -p /home/users
|
||||||
groupadd -f wheel
|
groupadd -f wheel
|
||||||
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
||||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||||
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<'END_OF_FILE'
|
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||||
publicKey
|
publicKey
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
||||||
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
|
||||||
/etc/init.d/sshd reload||/etc/init.d/ssh reload
|
hash service 2>/dev/null && service ssh reload || /etc/init.d/ssh* reload
|
||||||
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(1)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(1)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
|
||||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||||
|
|
|
@ -11,13 +11,13 @@ function default {
|
||||||
export INSTANCE_NAME="mkebsboot"
|
export INSTANCE_NAME="mkebsboot"
|
||||||
export INSTANCE_HOME="/tmp"
|
export INSTANCE_HOME="/tmp"
|
||||||
export LOG_DIR="/tmp/logs"
|
export LOG_DIR="/tmp/logs"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function mkebsboot {
|
function mkebsboot {
|
||||||
export IMAGE_DIR="/mnt/tmp"
|
export IMAGE_DIR="/mnt/tmp"
|
||||||
export EBS_DEVICE="/dev/sdh"
|
export EBS_DEVICE="/dev/sdh"
|
||||||
export EBS_MOUNT_POINT="/mnt/ebs"
|
export EBS_MOUNT_POINT="/mnt/ebs"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -65,24 +65,28 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/mkebsboot.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;mkebsboot\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;mkebsboot\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='mkebsboot'
|
export INSTANCE_NAME='mkebsboot'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/mkebsboot.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export IMAGE_DIR='$IMAGE_DIR'
|
export IMAGE_DIR='$IMAGE_DIR'
|
||||||
export EBS_DEVICE='$EBS_DEVICE'
|
export EBS_DEVICE='$EBS_DEVICE'
|
||||||
export EBS_MOUNT_POINT='$EBS_MOUNT_POINT'
|
export EBS_MOUNT_POINT='$EBS_MOUNT_POINT'
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
echo creating a filesystem and mounting the ebs volume
|
echo creating a filesystem and mounting the ebs volume
|
||||||
mkdir -p $IMAGE_DIR $EBS_MOUNT_POINT
|
mkdir -p $IMAGE_DIR $EBS_MOUNT_POINT
|
||||||
|
@ -103,12 +107,13 @@ du -sk $IMAGE_DIR
|
||||||
rm -rf $IMAGE_DIR/*
|
rm -rf $IMAGE_DIR/*
|
||||||
umount $EBS_MOUNT_POINT
|
umount $EBS_MOUNT_POINT
|
||||||
echo ----COMPLETE----
|
echo ----COMPLETE----
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/mkebsboot.sh
|
chmod u+x $INSTANCE_HOME/mkebsboot.sh
|
||||||
;;
|
;;
|
||||||
|
@ -142,4 +147,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -25,4 +25,4 @@ function findPid {
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
findPid $@ || exit 1
|
findPid $@ || exit 1
|
||||||
echo $FOUND_PID
|
echo $FOUND_PID
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -1,134 +0,0 @@
|
||||||
@echo off
|
|
||||||
set PATH=
|
|
||||||
set JAVA_HOME=
|
|
||||||
set PATH=
|
|
||||||
GOTO FUNCTION_END
|
|
||||||
:abort
|
|
||||||
echo aborting: %EXCEPTION%
|
|
||||||
exit /b 1
|
|
||||||
:default
|
|
||||||
set INSTANCE_NAME=mkebsboot
|
|
||||||
set INSTANCE_HOME=/mnt/tmp
|
|
||||||
set LOG_DIR=/mnt/tmp
|
|
||||||
exit /b 0
|
|
||||||
:mkebsboot
|
|
||||||
set TMP_DIR=/mnt/tmp
|
|
||||||
exit /b 0
|
|
||||||
:findPid
|
|
||||||
set FOUND_PID=
|
|
||||||
set _expression=%1
|
|
||||||
shift
|
|
||||||
set FIND_PROCESS=TASKLIST /FI "WINDOWTITLE eq %_expression%" /NH
|
|
||||||
FOR /F "usebackq tokens=2 delims= " %%A IN (`cmd /c "%FIND_PROCESS% 2>NUL"`) DO (
|
|
||||||
SET FOUND_PID=%%A
|
|
||||||
)
|
|
||||||
if defined FOUND_PID (
|
|
||||||
exit /b 0
|
|
||||||
) else (
|
|
||||||
set EXCEPTION=%_expression% not found
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
:forget
|
|
||||||
SETLOCAL
|
|
||||||
set FOUND_PID=
|
|
||||||
set NEXT_MINUTE=
|
|
||||||
set INSTANCE_NAME=%1
|
|
||||||
shift
|
|
||||||
set SCRIPT=%1
|
|
||||||
shift
|
|
||||||
set LOG_DIR=%1
|
|
||||||
shift
|
|
||||||
CALL :findProcess %INSTANCE_NAME%
|
|
||||||
if defined FOUND_PID (
|
|
||||||
echo %INSTANCE_NAME% already running pid [%FOUND_PID%]
|
|
||||||
) else (
|
|
||||||
CALL :nextMinute
|
|
||||||
set _DATE=%DATE:~4%
|
|
||||||
set CMD=schtasks /create /sd %_DATE% /tn %INSTANCE_NAME% /ru System /tr "cmd /c title %INSTANCE_NAME%&%SCRIPT% >%LOG_DIR%\stdout.log 2>%LOG_DIR%\stderr.log" /sc:once /st %NEXT_MINUTE%
|
|
||||||
echo %INSTANCE_NAME% will start at %NEXT_MINUTE%
|
|
||||||
set SECONDS=%TIME:~6,2%
|
|
||||||
set /a SECOND=60-SECONDS
|
|
||||||
%CMD% >NUL
|
|
||||||
ping -n %SECONDS% 127.0.0.1 > NUL 2>&1
|
|
||||||
CALL :findProcess %INSTANCE_NAME%
|
|
||||||
if not defined FOUND_PID (
|
|
||||||
set EXCEPTION=%INSTANCE_NAME% did not start
|
|
||||||
abort
|
|
||||||
)
|
|
||||||
)
|
|
||||||
exit /b 0
|
|
||||||
:FUNCTION_END
|
|
||||||
set PATH=c:\windows\;C:\windows\system32;c:\windows\system32\wbem
|
|
||||||
if not "%1" == "init" if not "%1" == "status" if not "%1" == "stop" if not "%1" == "start" if not "%1" == "tail" if not "%1" == "tailerr" if not "%1" == "run" (
|
|
||||||
set EXCEPTION=bad argument: %1 not in init status stop start tail tailerr run
|
|
||||||
goto abort
|
|
||||||
)
|
|
||||||
goto CASE_%1
|
|
||||||
:CASE_init
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
call :mkebsboot
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
md %INSTANCE_HOME%
|
|
||||||
del %INSTANCE_HOME%\mkebsboot.cmd 2>NUL
|
|
||||||
echo @echo off>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo title mkebsboot>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set PATH=c:\windows\;C:\windows\system32;c:\windows\system32\wbem>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set INSTANCE_NAME=mkebsboot>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set TMP_DIR=%TMP_DIR%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set INSTANCE_NAME=%INSTANCE_NAME%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set INSTANCE_HOME=%INSTANCE_HOME%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set LOG_DIR=%LOG_DIR%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo cd /d %%INSTANCE_HOME%%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
md %INSTANCE_HOME%
|
|
||||||
del %INSTANCE_HOME%\mkebsboot.cmd 2>NUL
|
|
||||||
echo @echo off>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo title mkebsboot>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set PATH=c:\windows\;C:\windows\system32;c:\windows\system32\wbem>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set INSTANCE_NAME=mkebsboot>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set TMP_DIR=%TMP_DIR%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set INSTANCE_NAME=%INSTANCE_NAME%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set INSTANCE_HOME=%INSTANCE_HOME%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo set LOG_DIR=%LOG_DIR%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo cd /d %%INSTANCE_HOME%%>>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
echo exit /b 0 >>%INSTANCE_HOME%\mkebsboot.cmd
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:CASE_status
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
call :findPid %INSTANCE_NAME%
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
echo [%FOUND_PID%]
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:CASE_stop
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
call :findPid %INSTANCE_NAME%
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
if defined FOUND_PID (
|
|
||||||
TASKKILL /F /T /PID %FOUND_PID% >NUL
|
|
||||||
)
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:CASE_start
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
call :forget %INSTANCE_NAME% %INSTANCE_HOME%\%INSTANCE_NAME%.cmd %LOG_DIR%
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:CASE_tail
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
tail %LOG_DIR%\stdout.log
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:CASE_tailerr
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
tail %LOG_DIR%\stderr.log
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:CASE_run
|
|
||||||
call :default
|
|
||||||
if errorlevel 1 goto abort
|
|
||||||
%INSTANCE_HOME%\%INSTANCE_NAME%.cmd
|
|
||||||
GOTO END_SWITCH
|
|
||||||
:END_SWITCH
|
|
||||||
exit /b 0
|
|
|
@ -11,11 +11,11 @@ function default {
|
||||||
export INSTANCE_NAME="mkebsboot"
|
export INSTANCE_NAME="mkebsboot"
|
||||||
export INSTANCE_HOME="/mnt/tmp"
|
export INSTANCE_HOME="/mnt/tmp"
|
||||||
export LOG_DIR="/mnt/tmp"
|
export LOG_DIR="/mnt/tmp"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function mkebsboot {
|
function mkebsboot {
|
||||||
export TMP_DIR="/mnt/tmp"
|
export TMP_DIR="/mnt/tmp"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -63,35 +63,40 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/mkebsboot.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;mkebsboot\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;mkebsboot\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='mkebsboot'
|
export INSTANCE_NAME='mkebsboot'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/mkebsboot.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export TMP_DIR='$TMP_DIR'
|
export TMP_DIR='$TMP_DIR'
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'
|
cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'
|
||||||
hello world
|
hello world
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
|
|
||||||
find /
|
find /
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/mkebsboot.sh
|
chmod u+x $INSTANCE_HOME/mkebsboot.sh
|
||||||
;;
|
;;
|
||||||
|
@ -125,4 +130,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set +u
|
||||||
|
shopt -s xpg_echo
|
||||||
|
shopt -s expand_aliases
|
||||||
|
unset PATH JAVA_HOME LD_LIBRARY_PATH
|
||||||
|
function abort {
|
||||||
|
echo "aborting: $@" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
function default {
|
||||||
|
export INSTANCE_NAME="testcall"
|
||||||
|
export INSTANCE_HOME="/tmp/$INSTANCE_NAME"
|
||||||
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
function testcall {
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
function findPid {
|
||||||
|
unset FOUND_PID;
|
||||||
|
[ $# -eq 1 ] || {
|
||||||
|
abort "findPid requires a parameter of pattern to match"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
local PATTERN="$1"; shift
|
||||||
|
local _FOUND=`ps auxwww|grep "$PATTERN"|grep -v " $0"|grep -v grep|grep -v $$|awk '{print $2}'`
|
||||||
|
[ -n "$_FOUND" ] && {
|
||||||
|
export FOUND_PID=$_FOUND
|
||||||
|
return 0
|
||||||
|
} || {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function forget {
|
||||||
|
unset FOUND_PID;
|
||||||
|
[ $# -eq 3 ] || {
|
||||||
|
abort "forget requires parameters INSTANCE_NAME SCRIPT LOG_DIR"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
local INSTANCE_NAME="$1"; shift
|
||||||
|
local SCRIPT="$1"; shift
|
||||||
|
local LOG_DIR="$1"; shift
|
||||||
|
mkdir -p $LOG_DIR
|
||||||
|
findPid $INSTANCE_NAME
|
||||||
|
[ -n "$FOUND_PID" -a -f $LOG_DIR/stdout.log ] && {
|
||||||
|
echo $INSTANCE_NAME already running pid [$FOUND_PID]
|
||||||
|
return 1;
|
||||||
|
} || {
|
||||||
|
nohup $SCRIPT >$LOG_DIR/stdout.log 2>$LOG_DIR/stderr.log &
|
||||||
|
RETURN=$?
|
||||||
|
# this is generally followed by findPid, so we shouldn't exit
|
||||||
|
# immediately as the proc may not have registered in ps, yet
|
||||||
|
test $RETURN && sleep 1
|
||||||
|
return $RETURN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
case $1 in
|
||||||
|
init)
|
||||||
|
default || exit 1
|
||||||
|
testcall || exit 1
|
||||||
|
echo hello
|
||||||
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
|
# create runscript header
|
||||||
|
cat > $INSTANCE_HOME/testcall.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
|
#!/bin/bash
|
||||||
|
set +u
|
||||||
|
shopt -s xpg_echo
|
||||||
|
shopt -s expand_aliases
|
||||||
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;testcall\007\"'
|
||||||
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
|
export INSTANCE_NAME='testcall'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/testcall.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
|
export LOG_DIR='$LOG_DIR'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/testcall.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
|
function abort {
|
||||||
|
echo "aborting: $@" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
function sourceEnvFile {
|
||||||
|
[ $# -eq 1 ] || {
|
||||||
|
abort "sourceEnvFile requires a parameter of the file to source"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
local ENV_FILE="$1"; shift
|
||||||
|
. "$ENV_FILE" || {
|
||||||
|
abort "Please append 'return 0' to the end of '$ENV_FILE'"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
|
# add desired commands from the user
|
||||||
|
cat >> $INSTANCE_HOME/testcall.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
|
cd $INSTANCE_HOME
|
||||||
|
rm -f $INSTANCE_HOME/rc
|
||||||
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
|
sourceEnvFile foo || exit 1
|
||||||
|
|
||||||
|
find /
|
||||||
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
|
# add runscript footer
|
||||||
|
cat >> $INSTANCE_HOME/testcall.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
|
exit $?
|
||||||
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
|
chmod u+x $INSTANCE_HOME/testcall.sh
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
default || exit 1
|
||||||
|
findPid $INSTANCE_NAME || exit 1
|
||||||
|
echo [$FOUND_PID]
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
default || exit 1
|
||||||
|
findPid $INSTANCE_NAME || exit 1
|
||||||
|
[ -n "$FOUND_PID" ] && {
|
||||||
|
echo stopping $FOUND_PID
|
||||||
|
kill -9 $FOUND_PID
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
start)
|
||||||
|
default || exit 1
|
||||||
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
|
tail)
|
||||||
|
default || exit 1
|
||||||
|
tail $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
tailerr)
|
||||||
|
default || exit 1
|
||||||
|
tail $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
run)
|
||||||
|
default || exit 1
|
||||||
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit $?
|
|
@ -2,20 +2,20 @@ setupPublicCurl || return 1
|
||||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
||||||
mv /usr/local/jdk* /usr/local/jdk/
|
mv /usr/local/jdk* /usr/local/jdk/
|
||||||
test -n "$SUDO_USER" &&
|
test -n "$SUDO_USER" &&
|
||||||
cat >> /home/$SUDO_USER/.bashrc <<'END_OF_FILE'
|
cat >> /home/$SUDO_USER/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||||
|
|
|
@ -9,12 +9,12 @@ function abort {
|
||||||
}
|
}
|
||||||
function default {
|
function default {
|
||||||
export INSTANCE_NAME="install_jdk"
|
export INSTANCE_NAME="install_jdk"
|
||||||
export INSTANCE_HOME="$HOME/instances/install_jdk"
|
export INSTANCE_HOME="/tmp/$INSTANCE_NAME"
|
||||||
export LOG_DIR="$HOME/instances/install_jdk"
|
export LOG_DIR="$INSTANCE_HOME"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function install_jdk {
|
function install_jdk {
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
function findPid {
|
function findPid {
|
||||||
unset FOUND_PID;
|
unset FOUND_PID;
|
||||||
|
@ -62,35 +62,41 @@ init)
|
||||||
mkdir -p $INSTANCE_HOME
|
mkdir -p $INSTANCE_HOME
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > $INSTANCE_HOME/install_jdk.sh <<END_OF_SCRIPT
|
cat > $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;install_jdk\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;install_jdk\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='install_jdk'
|
export INSTANCE_NAME='install_jdk'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/install_jdk.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||||
export LOG_DIR='$LOG_DIR'
|
export LOG_DIR='$LOG_DIR'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
function abort {
|
function abort {
|
||||||
echo "aborting: \$@" 1>&2
|
echo "aborting: $@" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
||||||
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
alias apt-get-upgrade="(apt-get update -qq&&apt-get upgrade -y -qq)"
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_apt(){
|
function ensure_cmd_or_install_package_apt(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
|
|
||||||
hash \$cmd 2>/dev/null || apt-get-install \$pkg || ( apt-get-upgrade && apt-get-install \$pkg )
|
hash $cmd 2>/dev/null || apt-get-install $pkg || ( apt-get-upgrade && apt-get-install $pkg )
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_cmd_or_install_package_yum(){
|
function ensure_cmd_or_install_package_yum(){
|
||||||
local cmd=\$1
|
local cmd=$1
|
||||||
local pkg=\$2
|
local pkg=$2
|
||||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensure_netutils_apt() {
|
function ensure_netutils_apt() {
|
||||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
||||||
# most network services require that the hostname is in
|
# most network services require that the hostname is in
|
||||||
# the /etc/hosts file, or they won't operate
|
# the /etc/hosts file, or they won't operate
|
||||||
function ensure_hostname_in_hosts() {
|
function ensure_hostname_in_hosts() {
|
||||||
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print \$1" "hostname }' /proc/net/arp >> /etc/hosts
|
egrep -q `hostname` /etc/hosts || awk -v hostname=`hostname` 'END { print $1" "hostname }' /proc/net/arp >> /etc/hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
# download locations for many services are at public dns
|
# download locations for many services are at public dns
|
||||||
|
@ -127,39 +133,43 @@ function setupPublicCurl() {
|
||||||
ensure_can_resolve_public_dns
|
ensure_can_resolve_public_dns
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> $INSTANCE_HOME/install_jdk.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd $INSTANCE_HOME
|
cd $INSTANCE_HOME
|
||||||
|
rm -f $INSTANCE_HOME/rc
|
||||||
|
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||||
setupPublicCurl || exit 1
|
setupPublicCurl || exit 1
|
||||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
|
||||||
mv /usr/local/jdk* /usr/local/jdk/
|
mv /usr/local/jdk* /usr/local/jdk/
|
||||||
test -n "$SUDO_USER" &&
|
test -n "$SUDO_USER" &&
|
||||||
cat >> /home/$SUDO_USER/.bashrc <<'END_OF_FILE'
|
cat >> /home/$SUDO_USER/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||||
export JAVA_HOME=/usr/local/jdk
|
export JAVA_HOME=/usr/local/jdk
|
||||||
export PATH=$JAVA_HOME/bin:$PATH
|
export PATH=$JAVA_HOME/bin:$PATH
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> $INSTANCE_HOME/install_jdk.sh <<'END_OF_SCRIPT'
|
cat >> $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x $INSTANCE_HOME/install_jdk.sh
|
chmod u+x $INSTANCE_HOME/install_jdk.sh
|
||||||
;;
|
;;
|
||||||
|
@ -180,6 +190,17 @@ start)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||||
;;
|
;;
|
||||||
|
stdout)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stdout.log
|
||||||
|
;;
|
||||||
|
stderr)
|
||||||
|
default || exit 1
|
||||||
|
cat $LOG_DIR/stderr.log
|
||||||
|
;;
|
||||||
|
exitstatus)
|
||||||
|
default || exit 1
|
||||||
|
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||||
tail)
|
tail)
|
||||||
default || exit 1
|
default || exit 1
|
||||||
tail $LOG_DIR/stdout.log
|
tail $LOG_DIR/stdout.log
|
||||||
|
@ -193,4 +214,4 @@ run)
|
||||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
md %TEMP%\%USERNAME%\scripttest
|
|
||||||
del %TEMP%\%USERNAME%\scripttest\yahooprod.cmd 2>NUL
|
|
||||||
echo @echo off>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo title yahooprod>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo set PATH=c:\windows\;C:\windows\system32;c:\windows\system32\wbem>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo set INSTANCE_NAME=yahooprod>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo set JAVA_HOME=%JAVA_HOME%>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo cd /d %TEMP%\%USERNAME%\scripttest>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
md %TEMP%\%USERNAME%\scripttest
|
|
||||||
del %TEMP%\%USERNAME%\scripttest\yahooprod.cmd 2>NUL
|
|
||||||
echo @echo off>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo title yahooprod>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo set PATH=c:\windows\;C:\windows\system32;c:\windows\system32\wbem>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo set INSTANCE_NAME=yahooprod>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo set JAVA_HOME=%JAVA_HOME%>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo cd /d %TEMP%\%USERNAME%\scripttest>>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
||||||
echo exit /b 0 >>%TEMP%\%USERNAME%\scripttest\yahooprod.cmd
|
|
|
@ -1,33 +1,38 @@
|
||||||
mkdir -p /tmp/$USER/scripttest
|
mkdir -p /tmp/$USER/scripttest
|
||||||
|
|
||||||
# create runscript header
|
# create runscript header
|
||||||
cat > /tmp/$USER/scripttest/yahooprod.sh <<END_OF_SCRIPT
|
cat > /tmp/$USER/scripttest/yahooprod.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set +u
|
set +u
|
||||||
shopt -s xpg_echo
|
shopt -s xpg_echo
|
||||||
shopt -s expand_aliases
|
shopt -s expand_aliases
|
||||||
PROMPT_COMMAND='echo -ne "\033]0;yahooprod\007"'
|
|
||||||
|
PROMPT_COMMAND='echo -ne \"\033]0;yahooprod\007\"'
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
|
|
||||||
export INSTANCE_NAME='yahooprod'
|
export INSTANCE_NAME='yahooprod'
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
cat >> /tmp/$USER/scripttest/yahooprod.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||||
export JAVA_HOME='$JAVA_HOME'
|
export JAVA_HOME='$JAVA_HOME'
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add desired commands from the user
|
# add desired commands from the user
|
||||||
cat >> /tmp/$USER/scripttest/yahooprod.sh <<'END_OF_SCRIPT'
|
cat >> /tmp/$USER/scripttest/yahooprod.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
cd /tmp/$USER/scripttest
|
cd /tmp/$USER/scripttest
|
||||||
echo hello
|
echo hello
|
||||||
|
|
||||||
cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'
|
cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'
|
||||||
hello world
|
hello world
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
|
|
||||||
echo $JAVA_HOME/bin/java -DinstanceName=$INSTANCE_NAME myServer.Main
|
echo $JAVA_HOME/bin/java -DinstanceName=$INSTANCE_NAME myServer.Main
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
cat >> /tmp/$USER/scripttest/yahooprod.sh <<'END_OF_SCRIPT'
|
cat >> /tmp/$USER/scripttest/yahooprod.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||||
exit 0
|
exit $?
|
||||||
END_OF_SCRIPT
|
|
||||||
|
END_OF_JCLOUDS_SCRIPT
|
||||||
|
|
||||||
chmod u+x /tmp/$USER/scripttest/yahooprod.sh
|
chmod u+x /tmp/$USER/scripttest/yahooprod.sh
|
||||||
|
|
|
@ -9,7 +9,7 @@ function abort {
|
||||||
}
|
}
|
||||||
function default {
|
function default {
|
||||||
export RUNTIME="Moo"
|
export RUNTIME="Moo"
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||||
case $1 in
|
case $1 in
|
||||||
|
@ -22,10 +22,10 @@ stop)
|
||||||
echo stop $RUNTIME
|
echo stop $RUNTIME
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'
|
cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'
|
||||||
hello world
|
hello world
|
||||||
END_OF_FILE
|
END_OF_JCLOUDS_FILE
|
||||||
echo "the following should be []: [$RUNTIME]"
|
echo "the following should be []: [$RUNTIME]"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit $?
|
||||||
|
|
|
@ -28,4 +28,4 @@ findPid $@ || exit 1
|
||||||
echo stopping $FOUND_PID
|
echo stopping $FOUND_PID
|
||||||
kill -9 $FOUND_PID
|
kill -9 $FOUND_PID
|
||||||
}
|
}
|
||||||
exit 0
|
exit $?
|
||||||
|
|
Loading…
Reference in New Issue