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.Path;
|
||||
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.ShellToken;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
@ -237,13 +237,13 @@ public class SSHJava extends Java {
|
|||
private int sshexecRedirectStreams(Statement statement) throws IOException {
|
||||
exec.setStreamHandler(redirector.createHandler());
|
||||
log("starting java as:\n" + statement.render(osFamily), Project.MSG_VERBOSE);
|
||||
int rc;
|
||||
int exitStatus;
|
||||
try {
|
||||
rc = sshexec(statement.render(osFamily));
|
||||
exitStatus = sshexec(statement.render(osFamily));
|
||||
} finally {
|
||||
redirector.complete();
|
||||
}
|
||||
return rc;
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
private void mkdirAndCopyTo(String destination, Iterable<FileSet> sets) {
|
||||
|
@ -373,8 +373,8 @@ public class SSHJava extends Java {
|
|||
Joiner.on(' ').join(commandLine.getJavaCommand().getArguments()));
|
||||
}
|
||||
|
||||
InitBuilder testInitBuilder = new InitBuilder(id, basedir, basedir, envVariables,
|
||||
ImmutableList.<Statement> of(Statements.interpret( commandBuilder.toString())));
|
||||
InitScript testInitBuilder = InitScript.builder().name(id).home(basedir).exportVariables(envVariables)
|
||||
.run(Statements.interpret( commandBuilder.toString())).build();
|
||||
return testInitBuilder.render(osFamily);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ import org.jclouds.domain.LoginCredentials;
|
|||
import org.jclouds.ec2.domain.Attachment;
|
||||
import org.jclouds.ec2.domain.BlockDevice;
|
||||
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.InstanceType;
|
||||
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.Snapshot;
|
||||
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.predicates.InstanceStateRunning;
|
||||
import org.jclouds.ec2.predicates.InstanceStateStopped;
|
||||
|
@ -65,9 +65,8 @@ import org.jclouds.net.IPSocket;
|
|||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
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.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
|
@ -77,7 +76,6 @@ import org.testng.annotations.BeforeTest;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -256,12 +254,12 @@ public class EBSBootEC2ClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||
@BeforeTest
|
||||
void makeScript() {
|
||||
|
||||
mkEbsBoot = new InitBuilder(
|
||||
"mkebsboot",// name of the script
|
||||
"/tmp",// working directory
|
||||
"/tmp/logs",// location of stdout.log and stderr.log
|
||||
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"),
|
||||
ImmutableList.<Statement> of(Statements
|
||||
mkEbsBoot = InitScript.builder()
|
||||
.name("mkebsboot")
|
||||
.home("/tmp")
|
||||
.logDir("/tmp/logs")
|
||||
.exportVariables(ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"))
|
||||
.run(Statements
|
||||
.interpret(
|
||||
"echo creating a filesystem and mounting the ebs volume",
|
||||
"{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}",
|
||||
"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 " + SCRIPT_END)))
|
||||
"rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)).build()
|
||||
.render(OsFamily.UNIX);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
|
||||
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.StatementList;
|
||||
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!
|
||||
public static InitBuilder startJBoss(String configuration) {
|
||||
return new InitBuilder(
|
||||
"jboss",
|
||||
JBOSS_HOME,
|
||||
JBOSS_HOME,
|
||||
ImmutableMap.of("jbossHome", JBOSS_HOME),
|
||||
ImmutableList.<Statement>of(appendFile(JBOSS_HOME + "/standalone/configuration/standalone-custom.xml", Splitter.on('\n').split(configuration))),
|
||||
ImmutableList
|
||||
.<Statement> of(interpret(new StringBuilder().append("java ").append(' ')
|
||||
public static InitScript startJBoss(String configuration) {
|
||||
return InitScript.builder()
|
||||
.name("jboss")
|
||||
.home(JBOSS_HOME)
|
||||
.exportVariables(ImmutableMap.of("jbossHome", JBOSS_HOME))
|
||||
.init(appendFile(JBOSS_HOME + "/standalone/configuration/standalone-custom.xml", Splitter.on('\n').split(configuration)))
|
||||
.run(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("-Djboss.modules.system.pkgs=org.jboss.byteman").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("-Djboss.home.dir=$JBOSS_HOME").append(' ')
|
||||
.append("--server-config=standalone-custom.xml")
|
||||
.toString())));
|
||||
.toString())).build();
|
||||
}
|
||||
|
||||
// TODO make this a cli option
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.compute.callables;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -30,22 +31,28 @@ import javax.annotation.Resource;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
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.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Predicate;
|
||||
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.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
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
|
||||
*/
|
||||
|
@ -60,23 +67,31 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final ExecutorService userThreads;
|
||||
private final EventBus eventBus;
|
||||
private final SudoAwareInitManager commandRunner;
|
||||
private final RetryablePredicate<String> notRunningAnymore;
|
||||
|
||||
private boolean shouldCancel;
|
||||
public SudoAwareInitManager getCommandRunner() {
|
||||
return commandRunner;
|
||||
}
|
||||
|
||||
private final RetryablePredicate<String> notRunningAnymore;
|
||||
|
||||
@Inject
|
||||
public BlockUntilInitScriptStatusIsZeroThenReturnOutput(
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
|
||||
ComputeServiceConstants.InitStatusProperties properties,
|
||||
final ScriptStatusReturnsZero stateRunning, @Assisted final SudoAwareInitManager commandRunner) {
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, EventBus eventBus,
|
||||
ComputeServiceConstants.InitStatusProperties properties, final ScriptStatusReturnsZero stateRunning,
|
||||
@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 retryMaxPeriod = properties.initStatusMaxPeriod;
|
||||
|
||||
this.commandRunner = checkNotNull(commandRunner, "commandRunner");
|
||||
this.userThreads = checkNotNull(userThreads, "userThreads");
|
||||
this.eventBus = checkNotNull(eventBus, "eventBus");
|
||||
this.notRunningAnymore = new RetryablePredicate<String>(new Predicate<String>() {
|
||||
|
||||
@Override
|
||||
|
@ -85,13 +100,13 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
|||
}
|
||||
}, retryMaxWait, retryInitialPeriod, retryMaxPeriod, TimeUnit.MILLISECONDS) {
|
||||
/**
|
||||
* make sure we stop the retry loop if someone cancelled the future, this keeps threads
|
||||
* from being consumed on dead tasks
|
||||
* make sure we stop the retry loop if someone cancelled the future,
|
||||
* this keeps threads from being consumed on dead tasks
|
||||
*/
|
||||
@Override
|
||||
protected boolean atOrAfter(Date end) {
|
||||
if (shouldCancel)
|
||||
Throwables.propagate(new TimeoutException("cancelled"));
|
||||
if (isCancelled())
|
||||
Throwables.propagate(new CancellationException("cancelled"));
|
||||
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
|
||||
* place
|
||||
* Submits a thread that will either set the result of the future or the
|
||||
* exception that took place
|
||||
*/
|
||||
public BlockUntilInitScriptStatusIsZeroThenReturnOutput init() {
|
||||
userThreads.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
boolean complete = notRunningAnymore.apply("status");
|
||||
String stdout = commandRunner.runAction("tail").getOutput();
|
||||
String stderr = commandRunner.runAction("tailerr").getOutput();
|
||||
// TODO make ScriptBuilder save exit status on nuhup
|
||||
logger.debug("<< complete(%s) status(%s)", commandRunner.getStatement().getInstanceName(), complete);
|
||||
set(new ExecResponse(stdout, stderr, complete && !shouldCancel ? 0 : -1));
|
||||
notRunningAnymore.apply("status");
|
||||
String stdout = commandRunner.runAction("stdout").getOutput();
|
||||
String stderr = commandRunner.runAction("stderr").getOutput();
|
||||
Integer exitStatus = Ints.tryParse(commandRunner.runAction("exitstatus").getOutput().trim());
|
||||
ExecResponse exec = new ExecResponse(stdout, stderr, exitStatus == null ? -1 : exitStatus);
|
||||
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) {
|
||||
setException(e);
|
||||
}
|
||||
|
@ -127,63 +150,43 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean set(ExecResponse value) {
|
||||
eventBus.post(new StatementOnNodeCompletion(getCommandRunner().getStatement(), getCommandRunner().getNode(),
|
||||
value));
|
||||
return super.set(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void interruptTask() {
|
||||
logger.debug("<< cancelled(%s)", commandRunner.getStatement().getInstanceName());
|
||||
commandRunner.refreshAndRunAction("stop");
|
||||
shouldCancel = true;
|
||||
ExecResponse returnVal = commandRunner.refreshAndRunAction("stop");
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("running task[%s]", commandRunner);
|
||||
return Objects.toStringHelper(this).add("commandRunner", commandRunner).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
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;
|
||||
return Objects.hashCode(commandRunner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
if (!o.getClass().equals(getClass()))
|
||||
return false;
|
||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput other = (BlockUntilInitScriptStatusIsZeroThenReturnOutput) obj;
|
||||
if (commandRunner == null) {
|
||||
if (other.commandRunner != null)
|
||||
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;
|
||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput that = BlockUntilInitScriptStatusIsZeroThenReturnOutput.class
|
||||
.cast(o);
|
||||
return Objects.equal(this.commandRunner, that.commandRunner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -192,7 +195,9 @@ public class BlockUntilInitScriptStatusIsZeroThenReturnOutput extends AbstractFu
|
|||
try {
|
||||
return super.get(timeout, unit);
|
||||
} 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.Singleton;
|
||||
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
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
|
||||
* the basedir/%s where %s is the taskName
|
||||
* @see InitBuilder#getHomeDir
|
||||
* @see InitBuilder#getLogDir
|
||||
* @see InitScript#getHomeDir
|
||||
* @see InitScript#getLogDir
|
||||
*/
|
||||
public String getInitScriptPattern() {
|
||||
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.checkState;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
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.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
import org.jclouds.scriptbuilder.domain.AdminAccessVisitor;
|
||||
import org.jclouds.scriptbuilder.domain.AppendFile;
|
||||
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.Splitter;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
|
||||
|
@ -53,28 +51,18 @@ import com.google.inject.assistedinject.AssistedInject;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager implements RunScriptOnNode {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final String initFile;
|
||||
|
||||
/**
|
||||
* @return the absolute path to the file on disk relating to this task.
|
||||
*/
|
||||
public String getInitFile() {
|
||||
return initFile;
|
||||
}
|
||||
protected final EventBus eventBus;
|
||||
|
||||
@AssistedInject
|
||||
public RunScriptOnNodeAsInitScriptUsingSsh(Function<NodeMetadata, SshClient> sshFactory,
|
||||
public RunScriptOnNodeAsInitScriptUsingSsh(Function<NodeMetadata, SshClient> sshFactory, EventBus eventBus,
|
||||
InitScriptConfigurationForTasks initScriptConfiguration, @Assisted NodeMetadata node,
|
||||
@Assisted Statement script, @Assisted RunScriptOptions options) {
|
||||
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
|
||||
.getTaskName(), script));
|
||||
this.initFile = String.format(initScriptConfiguration.getInitScriptPattern(), init.getInstanceName());
|
||||
this.eventBus = checkNotNull(eventBus, "eventBus");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,19 +76,20 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
|||
checkState(ssh != null, "please call init() before invoking call");
|
||||
try {
|
||||
ssh.connect();
|
||||
return doCall();
|
||||
ExecResponse returnVal = doCall();
|
||||
eventBus.post(new StatementOnNodeCompletion(init, node, returnVal));
|
||||
return returnVal;
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
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) {
|
||||
name = "jclouds-script-" + config.getAnonymousTaskSuffixSupplier().get();
|
||||
}
|
||||
return new InitBuilder(name, config.getBasedir() + "/" + name, config.getBasedir() + "/" + name, Collections
|
||||
.<String, String> emptyMap(), Collections.singleton(script));
|
||||
return InitScript.builder().name(name).home(config.getBasedir() + "/" + name).run(script).build();
|
||||
}
|
||||
|
||||
protected void refreshSshIfNewAdminCredentialsConfigured(AdminAccess input) {
|
||||
|
@ -115,10 +104,13 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
|||
}
|
||||
|
||||
protected ExecResponse doCall() {
|
||||
eventBus.post(new InitScriptOnNodeSubmission(init, node));
|
||||
try {
|
||||
try {
|
||||
ssh.put(initFile, init.render(OsFamily.UNIX));
|
||||
} 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())
|
||||
logger.warn(e, "<< (%s) problem using sftp [%s], attempting via sshexec", ssh.toString(), e.getMessage());
|
||||
else
|
||||
|
@ -127,7 +119,7 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
|||
ssh.connect();
|
||||
ssh.exec("rm " + initFile);
|
||||
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);
|
||||
|
@ -143,6 +135,10 @@ public class RunScriptOnNodeAsInitScriptUsingSsh extends SudoAwareInitManager im
|
|||
|
||||
});
|
||||
return runAction("start");
|
||||
} catch (Throwable e) {
|
||||
eventBus.post(new StatementOnNodeFailure(init, node, e));
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setupLinkToInitFile() {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.jclouds.compute.callables;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -27,6 +26,7 @@ import javax.inject.Inject;
|
|||
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.events.StatementOnNodeFailure;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
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.Throwables;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
|
@ -47,9 +48,10 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete extends Ru
|
|||
@Inject
|
||||
public RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory, Timeouts timeouts,
|
||||
Function<NodeMetadata, SshClient> sshFactory, InitScriptConfigurationForTasks initScriptConfiguration,
|
||||
@Assisted NodeMetadata node, @Assisted Statement script, @Assisted RunScriptOptions options) {
|
||||
super(sshFactory, initScriptConfiguration, node, script, options);
|
||||
Function<NodeMetadata, SshClient> sshFactory, EventBus eventBus,
|
||||
InitScriptConfigurationForTasks initScriptConfiguration, @Assisted NodeMetadata node,
|
||||
@Assisted Statement script, @Assisted RunScriptOptions options) {
|
||||
super(sshFactory, eventBus, initScriptConfiguration, node, script, options);
|
||||
this.statusFactory = checkNotNull(statusFactory, "statusFactory");
|
||||
this.timeouts = checkNotNull(timeouts, "timeouts");
|
||||
}
|
||||
|
@ -58,16 +60,21 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete extends Ru
|
|||
public ExecResponse doCall() {
|
||||
try {
|
||||
return future().get(timeouts.scriptComplete, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
return null;
|
||||
} catch (Throwable e) {
|
||||
eventBus.post(new StatementOnNodeFailure(init, node, e));
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockUntilInitScriptStatusIsZeroThenReturnOutput future() {
|
||||
ExecResponse returnVal = super.doCall();
|
||||
checkState(returnVal.getExitCode() == 0, String.format("task: %s had non-zero exit status: %s", init
|
||||
.getInstanceName(), returnVal));
|
||||
if (returnVal.getExitStatus() != 0) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ import javax.inject.Named;
|
|||
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
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.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -36,6 +39,8 @@ import org.jclouds.ssh.SshClient;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
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.AssistedInject;
|
||||
|
||||
|
@ -51,6 +56,7 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final Function<NodeMetadata, SshClient> sshFactory;
|
||||
protected final EventBus eventBus;
|
||||
protected final NodeMetadata node;
|
||||
protected final Statement statement;
|
||||
protected final boolean runAsRoot;
|
||||
|
@ -58,9 +64,10 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
|
|||
protected SshClient ssh;
|
||||
|
||||
@AssistedInject
|
||||
public RunScriptOnNodeUsingSsh(Function<NodeMetadata, SshClient> sshFactory, @Assisted NodeMetadata node,
|
||||
@Assisted Statement statement, @Assisted RunScriptOptions options) {
|
||||
public RunScriptOnNodeUsingSsh(Function<NodeMetadata, SshClient> sshFactory, EventBus eventBus,
|
||||
@Assisted NodeMetadata node, @Assisted Statement statement, @Assisted RunScriptOptions options) {
|
||||
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
||||
this.eventBus = checkNotNull(eventBus, "eventBus");
|
||||
this.node = checkNotNull(node, "node");
|
||||
this.statement = checkNotNull(statement, "statement");
|
||||
this.runAsRoot = options.shouldRunAsRoot();
|
||||
|
@ -72,13 +79,20 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
|
|||
try {
|
||||
ssh.connect();
|
||||
ExecResponse returnVal;
|
||||
eventBus.post(new StatementOnNodeSubmission(statement, node));
|
||||
String command = (runAsRoot) ? execAsRoot(statement.render(OsFamily.UNIX)) : execScriptAsDefaultUser(statement
|
||||
.render(OsFamily.UNIX));
|
||||
try {
|
||||
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())
|
||||
logger.trace("<< %s[%s]", statement, returnVal);
|
||||
else
|
||||
logger.debug("<< %s(%d)", statement, returnVal.getExitCode());
|
||||
logger.debug("<< %s(%d)", statement, returnVal.getExitStatus());
|
||||
return returnVal;
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.jclouds.compute.domain.ExecResponse;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -47,16 +47,25 @@ public class SudoAwareInitManager {
|
|||
protected Logger computeLogger = Logger.NULL;
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected NodeMetadata node;
|
||||
protected final InitBuilder init;
|
||||
protected final String initFile;
|
||||
protected final InitScript init;
|
||||
protected final boolean runAsRoot;
|
||||
protected final Function<NodeMetadata, SshClient> sshFactory;
|
||||
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,
|
||||
InitBuilder init) {
|
||||
InitScriptConfigurationForTasks initScriptConfiguration, InitScript init) {
|
||||
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
||||
this.runAsRoot = runAsRoot;
|
||||
this.node = checkNotNull(node, "node");
|
||||
this.initFile = String.format(initScriptConfiguration.getInitScriptPattern(), init.getInstanceName());
|
||||
this.init = checkNotNull(init, "init");
|
||||
}
|
||||
|
||||
|
@ -82,41 +91,44 @@ public class SudoAwareInitManager {
|
|||
: execScriptAsDefaultUser(action);
|
||||
returnVal = runCommand(command);
|
||||
if ("status".equals(action))
|
||||
logger.trace("<< %s(%d)", action, returnVal.getExitCode());
|
||||
logger.trace("<< %s(%d)", action, returnVal.getExitStatus());
|
||||
else if (computeLogger.isTraceEnabled())
|
||||
computeLogger.trace("<< %s[%s]", action, returnVal);
|
||||
else
|
||||
computeLogger.debug("<< %s(%d)", action, returnVal.getExitCode());
|
||||
computeLogger.debug("<< %s(%d)", action, returnVal.getExitStatus());
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
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
|
||||
.getUsername(), ssh.getHostAddress());
|
||||
if (command.endsWith("status"))
|
||||
logger.trace(statement);
|
||||
logger.trace(">> running " + statement);
|
||||
else
|
||||
computeLogger.debug(statement);
|
||||
return ssh.exec(command);
|
||||
computeLogger.debug(">> running " + statement);
|
||||
ExecResponse returnVal = ssh.exec(command);
|
||||
if (!command.endsWith("status"))
|
||||
checkState(returnVal.getExitStatus() == 0, "error running %s; returnVal !=0: %s", statement, returnVal);
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String execScriptAsRoot(String action) {
|
||||
String command;
|
||||
if (node.getCredentials().identity.equals("root")) {
|
||||
command = "./" + init.getInstanceName() + " " + action;
|
||||
command = initFile + " " + action;
|
||||
} else if (node.getCredentials().shouldAuthenticateSudo()) {
|
||||
command = String.format("echo '%s'|sudo -S ./%s %s", node.getCredentials().getPassword(),
|
||||
init.getInstanceName(), action);
|
||||
command = String.format("echo '%s'|sudo -S %s %s", node.getCredentials().getPassword(),
|
||||
initFile, action);
|
||||
} else {
|
||||
command = "sudo ./" + init.getInstanceName() + " " + action;
|
||||
command = "sudo " + initFile + " " + action;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
protected String execScriptAsDefaultUser(String action) {
|
||||
return "./" + init.getInstanceName() + " " + action;
|
||||
return initFile + " " + action;
|
||||
}
|
||||
|
||||
public NodeMetadata getNode() {
|
||||
|
@ -125,11 +137,11 @@ public class SudoAwareInitManager {
|
|||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
|
||||
public InitBuilder getStatement() {
|
||||
public InitScript getStatement() {
|
||||
return init;
|
||||
}
|
||||
}
|
|
@ -20,19 +20,21 @@ package org.jclouds.compute.domain;
|
|||
|
||||
import org.jclouds.compute.config.CustomizationResponse;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ExecResponse implements CustomizationResponse {
|
||||
|
||||
private final String error;
|
||||
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.error = error;
|
||||
this.exitCode = exitCode;
|
||||
this.exitStatus = exitStatus;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
|
@ -43,47 +45,38 @@ public class ExecResponse implements CustomizationResponse {
|
|||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[output=" + output + ", error=" + error + ", exitCode=" + exitCode + "]";
|
||||
/**
|
||||
* @see #getExitStatus
|
||||
*/
|
||||
@Deprecated
|
||||
public int getExitCode() {
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
public int getExitStatus() {
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
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;
|
||||
return Objects.hashCode(output, error, exitStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
if (!o.getClass().equals(getClass()))
|
||||
return false;
|
||||
ExecResponse other = (ExecResponse) obj;
|
||||
if (error == null) {
|
||||
if (other.error != null)
|
||||
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;
|
||||
ExecResponse that = ExecResponse.class.cast(o);
|
||||
return Objects.equal(this.output, that.output) && Objects.equal(this.error, that.error)
|
||||
&& Objects.equal(this.exitStatus, that.exitStatus);
|
||||
}
|
||||
|
||||
public int getExitCode() {
|
||||
return exitCode;
|
||||
@Override
|
||||
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 + ((hardware == null) ? 0 : hardware.hashCode());
|
||||
result = prime * result + ((os == null) ? 0 : os.hashCode());
|
||||
result = prime * result + ((credentials == null) ? 0 : credentials.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -270,11 +269,6 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
return false;
|
||||
} else if (!os.equals(other.os))
|
||||
return false;
|
||||
if (credentials == null) {
|
||||
if (other.credentials != null)
|
||||
return false;
|
||||
} else if (!credentials.equals(other.credentials))
|
||||
return false;
|
||||
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 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.StatementList;
|
||||
import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
|
||||
|
@ -51,7 +51,7 @@ public class TemplateOptionsToStatement implements Function<TemplateOptions, Sta
|
|||
if (options.getPrivateKey() != null)
|
||||
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
||||
if (bootstrap.size() >= 1) {
|
||||
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitBuilder))
|
||||
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitScript))
|
||||
options.nameTask("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
|
||||
.getUsername(), commandUsingClient.client.getHostAddress());
|
||||
ExecResponse response = refresh(commandUsingClient);
|
||||
while (response.getExitCode() == -1)
|
||||
while (response.getExitStatus() == -1)
|
||||
response = refresh(commandUsingClient);
|
||||
logger.trace("%s@%s: looking for exit code 0: currently: %s", commandUsingClient.client.getUsername(),
|
||||
commandUsingClient.client.getHostAddress(), response.getExitCode());
|
||||
return 0 == response.getExitCode();
|
||||
commandUsingClient.client.getHostAddress(), response.getExitStatus());
|
||||
return 0 == response.getExitStatus();
|
||||
}
|
||||
|
||||
private ExecResponse refresh(CommandUsingClient commandUsingClient) {
|
||||
|
|
|
@ -67,8 +67,8 @@ public class RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements C
|
|||
tainted = true;
|
||||
try {
|
||||
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.trace("<< script output for node(%s): %s", runScriptOnNode.getNode().getId(), exec);
|
||||
goodNodes.put(runScriptOnNode.getNode(), exec);
|
||||
return exec;
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
(merge
|
||||
{:exit 0 :err "stderr" :out "stdout"}
|
||||
(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);
|
||||
|
||||
assert response.getExitCode() == 0 : node.getId() + ": " + response;
|
||||
assert response.getExitStatus() == 0 : node.getId() + ": " + response;
|
||||
|
||||
node = client.getNodeMetadata(node.getId());
|
||||
// test that the node updated to the correct admin user!
|
||||
|
@ -265,7 +265,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
|||
|
||||
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));
|
||||
|
||||
|
@ -304,11 +304,11 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
|||
assert false : node.getId() + ": " + response;
|
||||
} catch (TimeoutException e) {
|
||||
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));
|
||||
assert !response.getOutput().trim().equals("") : node.getId() + ": " + response;
|
||||
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));
|
||||
assert response.getOutput().trim().equals("") : node.getId() + ": " + response;
|
||||
try {
|
||||
|
@ -592,10 +592,10 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
|||
|
||||
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,
|
||||
node, init(node, processName, "tail"), init(node, processName, "tailerr"));
|
||||
node, init(node, processName, "stdout"), init(node, processName, "stderr"));
|
||||
stats.socketOpenMilliseconds = watch.elapsedTime(TimeUnit.MILLISECONDS);
|
||||
|
||||
exec = init(node, processName, "tail");
|
||||
exec = init(node, processName, "stdout");
|
||||
|
||||
Matcher matcher = parseReported.matcher(exec.getOutput());
|
||||
if (matcher.find())
|
||||
|
@ -606,7 +606,7 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
|||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -716,13 +716,13 @@ public abstract class BaseComputeServiceLiveTest extends BaseVersionedServiceLiv
|
|||
|
||||
}), "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>() {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -70,6 +70,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
|
||||
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
||||
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
||||
private static final ExecResponse EXEC_RC_GOOD = new ExecResponse("0", "", 0);
|
||||
|
||||
public StubComputeServiceIntegrationTest() {
|
||||
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.getUsername()).andReturn("root").atLeastOnce();
|
||||
expect(client.getHostAddress()).andReturn("localhost").atLeastOnce();
|
||||
expect(client.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||
// next status says the script is done, since not found.
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||
expect(client.exec("./" + scriptName + " tail")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " stdout")).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.
|
||||
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.getUsername()).andReturn("web").atLeastOnce();
|
||||
expect(clientNew.getHostAddress()).andReturn("localhost").atLeastOnce();
|
||||
expect(clientNew.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(clientNew.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
expect(clientNew.exec("/tmp/init-" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(clientNew.exec("/tmp/init-" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
clientNew.disconnect();
|
||||
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.connect();
|
||||
expect(clientNew.exec("./" + scriptName + " stop\n")).andReturn(EXEC_GOOD);
|
||||
expect(clientNew.exec("/tmp/init-" + scriptName + " stop\n")).andReturn(EXEC_GOOD);
|
||||
clientNew.disconnect();
|
||||
|
||||
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.connect();
|
||||
expect(clientNew.exec("./" + scriptName + " tail\n")).andReturn(EXEC_GOOD);
|
||||
expect(clientNew.exec("/tmp/init-" + scriptName + " stdout\n")).andReturn(EXEC_GOOD);
|
||||
clientNew.disconnect();
|
||||
} catch (IOException 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.getUsername()).andReturn("root").atLeastOnce();
|
||||
expect(client.getHostAddress()).andReturn(nodeId + "").atLeastOnce();
|
||||
expect(client.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||
// next status says the script is done, since not found.
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||
expect(client.exec("./" + scriptName + " tail")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||
expect(client.exec("/tmp/init-" + scriptName + " stdout")).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) {
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.jclouds.concurrent.MoreExecutors;
|
|||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
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.Statement;
|
||||
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.Stopwatch;
|
||||
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.Guice;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
|
@ -62,6 +62,8 @@ import com.google.inject.name.Names;
|
|||
@Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest")
|
||||
public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
||||
|
||||
EventBus eventBus = new EventBus();
|
||||
|
||||
BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory statusFactory = Guice.createInjector(
|
||||
new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()),
|
||||
new AbstractModule() {
|
||||
|
@ -98,7 +100,7 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
|
||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
new RunScriptOptions());
|
||||
|
||||
testMe.call();
|
||||
|
@ -137,13 +139,13 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
*/
|
||||
private void runDefaults(IAnswer<ExecResponse> answerForScriptStatus, int timesForScriptStatus) {
|
||||
Statement command = exec("doFoo");
|
||||
NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING).credentials(
|
||||
new LoginCredentials("tester", "testpassword!", null, false)).build();
|
||||
NodeMetadata node = new NodeMetadataBuilder().ids("id").state(NodeState.RUNNING)
|
||||
.credentials(LoginCredentials.builder().user("tester").password("testpassword!").build()).build();
|
||||
|
||||
SshClient sshClient = createMock(SshClient.class);
|
||||
|
||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
||||
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));
|
||||
|
@ -154,27 +156,28 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
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("./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
|
||||
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
|
||||
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 {
|
||||
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("./jclouds-script-0 tailerr")).andReturn(new ExecResponse("err", "", 0));
|
||||
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("0", "", 0));
|
||||
|
||||
sshClient.disconnect();
|
||||
replay(sshClient);
|
||||
|
||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
new RunScriptOptions());
|
||||
|
||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||
|
@ -195,8 +198,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
|
||||
SshClient sshClient = createMock(SshClient.class);
|
||||
|
||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
||||
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));
|
||||
|
@ -207,22 +210,23 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
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("./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
|
||||
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
|
||||
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
||||
expect(sshClient.exec("./jclouds-script-0 tail")).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 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("0", "", 0));
|
||||
|
||||
sshClient.disconnect();
|
||||
replay(sshClient);
|
||||
|
||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
new RunScriptOptions());
|
||||
|
||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||
|
@ -243,8 +247,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
|
||||
SshClient sshClient = createMock(SshClient.class);
|
||||
|
||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
||||
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));
|
||||
|
@ -255,22 +259,23 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
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("./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
|
||||
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
|
||||
expect(sshClient.exec("./jclouds-script-0 status")).andReturn(new ExecResponse("", "", 1));
|
||||
expect(sshClient.exec("./jclouds-script-0 tail")).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 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("0", "", 0));
|
||||
|
||||
sshClient.disconnect();
|
||||
replay(sshClient);
|
||||
|
||||
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete testMe = new RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete(
|
||||
statusFactory, timeouts, Functions.forMap(ImmutableMap.of(node, sshClient)),
|
||||
InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
eventBus, InitScriptConfigurationForTasks.create().appendIncrementingNumberToAnonymousTaskNames(), node, command,
|
||||
new RunScriptOptions().runAsRoot(false));
|
||||
|
||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||
|
@ -284,4 +289,53 @@ public class RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilCompleteTest {
|
|||
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.options.RunScriptOptions;
|
||||
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.Statement;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
@ -39,13 +39,14 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", singleThreaded = true, testName = "RunScriptOnNodeAsInitScriptUsingSshTest")
|
||||
public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
||||
EventBus eventBus = new EventBus();
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testWithoutInitThrowsIllegalStateException() {
|
||||
|
@ -58,7 +59,7 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
replay(sshClient);
|
||||
|
||||
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());
|
||||
|
||||
testMe.call();
|
||||
|
@ -71,8 +72,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
|
||||
SshClient sshClient = createMock(SshClient.class);
|
||||
|
||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
||||
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));
|
||||
|
@ -82,17 +83,17 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
// 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("./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
|
||||
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();
|
||||
replay(sshClient);
|
||||
|
||||
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());
|
||||
|
||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||
|
@ -112,8 +113,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
|
||||
SshClient sshClient = createMock(SshClient.class);
|
||||
|
||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
||||
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));
|
||||
|
@ -123,17 +124,17 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
// 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("./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
|
||||
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();
|
||||
replay(sshClient);
|
||||
|
||||
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());
|
||||
|
||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||
|
@ -154,8 +155,8 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
|
||||
SshClient sshClient = createMock(SshClient.class);
|
||||
|
||||
InitBuilder init = new InitBuilder("jclouds-script-0", "/tmp/jclouds-script-0", "/tmp/jclouds-script-0",
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(command));
|
||||
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));
|
||||
|
@ -165,16 +166,16 @@ public class RunScriptOnNodeAsInitScriptUsingSshTest {
|
|||
// 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("./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
|
||||
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();
|
||||
replay(sshClient);
|
||||
|
||||
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));
|
||||
|
||||
assertEquals(testMe.getInitFile(), "/tmp/init-jclouds-script-0");
|
||||
|
|
|
@ -34,12 +34,15 @@ import org.testng.annotations.BeforeMethod;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
@Test(groups = { "unit" }, singleThreaded = true)
|
||||
public class RunScriptOnNodeUsingSshTest {
|
||||
EventBus eventBus = new EventBus();
|
||||
|
||||
private SshClient sshClient;
|
||||
private NodeMetadata node;
|
||||
private Function<NodeMetadata, SshClient> sshFactory;
|
||||
|
@ -59,7 +62,7 @@ public class RunScriptOnNodeUsingSshTest {
|
|||
}
|
||||
|
||||
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));
|
||||
|
||||
testMe.init();
|
||||
|
@ -75,7 +78,7 @@ public class RunScriptOnNodeUsingSshTest {
|
|||
}
|
||||
|
||||
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));
|
||||
|
||||
testMe.init();
|
||||
|
@ -97,7 +100,7 @@ public class RunScriptOnNodeUsingSshTest {
|
|||
expect(node.getCredentials()).andReturn(new LoginCredentials("tester", "testpassword!", null, true))
|
||||
.atLeastOnce();
|
||||
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));
|
||||
testMe.init();
|
||||
|
||||
|
@ -114,7 +117,7 @@ public class RunScriptOnNodeUsingSshTest {
|
|||
}
|
||||
|
||||
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"));
|
||||
|
||||
testMe.init();
|
||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
|||
function default {
|
||||
export INSTANCE_NAME="bootstrap"
|
||||
export INSTANCE_HOME="/tmp/bootstrap"
|
||||
export LOG_DIR="/tmp/bootstrap"
|
||||
return 0
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function bootstrap {
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -62,35 +62,41 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/bootstrap.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='bootstrap'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/bootstrap.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/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
function abort {
|
||||
echo "aborting: \$@" 1>&2
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
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)"
|
||||
|
||||
function ensure_cmd_or_install_package_apt(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
local cmd=$1
|
||||
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(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
||||
local cmd=$1
|
||||
local pkg=$2
|
||||
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||
}
|
||||
|
||||
function ensure_netutils_apt() {
|
||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
|||
# most network services require that the hostname is in
|
||||
# the /etc/hosts file, or they won't operate
|
||||
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
|
||||
|
@ -127,60 +133,63 @@ function setupPublicCurl() {
|
|||
ensure_can_resolve_public_dns
|
||||
return 0
|
||||
}
|
||||
END_OF_SCRIPT
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
rm /etc/sudoers
|
||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||
root ALL = (ALL) ALL
|
||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(randompassword)' defaultAdminUsername
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
||||
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
" '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}}
|
||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||
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 -)
|
||||
mv /usr/local/jdk* /usr/local/jdk/
|
||||
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 PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/bootstrap.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/bootstrap.sh
|
||||
;;
|
||||
|
@ -201,6 +210,17 @@ 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
|
||||
|
@ -214,4 +234,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
|||
function default {
|
||||
export INSTANCE_NAME="configure-jboss"
|
||||
export INSTANCE_HOME="/tmp/configure-jboss"
|
||||
export LOG_DIR="/tmp/configure-jboss"
|
||||
return 0
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function configure-jboss {
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -62,35 +62,41 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/configure-jboss.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 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_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
function abort {
|
||||
echo "aborting: \$@" 1>&2
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
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)"
|
||||
|
||||
function ensure_cmd_or_install_package_apt(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
local cmd=$1
|
||||
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(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
||||
local cmd=$1
|
||||
local pkg=$2
|
||||
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||
}
|
||||
|
||||
function ensure_netutils_apt() {
|
||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
|||
# most network services require that the hostname is in
|
||||
# the /etc/hosts file, or they won't operate
|
||||
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
|
||||
|
@ -127,52 +133,54 @@ function setupPublicCurl() {
|
|||
ensure_can_resolve_public_dns
|
||||
return 0
|
||||
}
|
||||
END_OF_SCRIPT
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
rm /etc/sudoers
|
||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||
root ALL = (ALL) ALL
|
||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/web -p 'crypt(randompassword)' web
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/web/.ssh/authorized_keys
|
||||
chown -R web /home/users/web
|
||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
" '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}}
|
||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||
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 -)
|
||||
mv /usr/local/jdk* /usr/local/jdk/
|
||||
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 PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
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 8080 -j ACCEPT
|
||||
|
@ -184,12 +192,13 @@ mv /usr/local/jboss-*/* /usr/local/jboss
|
|||
chmod -R oug+r+w /usr/local/jboss
|
||||
chown -R web /usr/local/jboss
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/configure-jboss.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/configure-jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/configure-jboss.sh
|
||||
;;
|
||||
|
@ -210,6 +219,17 @@ 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
|
||||
|
@ -223,4 +243,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
|||
function default {
|
||||
export INSTANCE_NAME="runScriptWithCreds"
|
||||
export INSTANCE_HOME="/tmp/runScriptWithCreds"
|
||||
export LOG_DIR="/tmp/runScriptWithCreds"
|
||||
return 0
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function runScriptWithCreds {
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -62,35 +62,41 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/runScriptWithCreds.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='runScriptWithCreds'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/runScriptWithCreds.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/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
function abort {
|
||||
echo "aborting: \$@" 1>&2
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
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)"
|
||||
|
||||
function ensure_cmd_or_install_package_apt(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
local cmd=$1
|
||||
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(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
||||
local cmd=$1
|
||||
local pkg=$2
|
||||
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||
}
|
||||
|
||||
function ensure_netutils_apt() {
|
||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
|||
# most network services require that the hostname is in
|
||||
# the /etc/hosts file, or they won't operate
|
||||
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
|
||||
|
@ -127,39 +133,43 @@ function setupPublicCurl() {
|
|||
ensure_can_resolve_public_dns
|
||||
return 0
|
||||
}
|
||||
END_OF_SCRIPT
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
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 -)
|
||||
mv /usr/local/jdk* /usr/local/jdk/
|
||||
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 PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/runScriptWithCreds.sh
|
||||
;;
|
||||
|
@ -180,6 +190,17 @@ 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
|
||||
|
@ -193,4 +214,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -10,11 +10,11 @@ function abort {
|
|||
function default {
|
||||
export INSTANCE_NAME="adminUpdate"
|
||||
export INSTANCE_HOME="/tmp/adminUpdate"
|
||||
export LOG_DIR="/tmp/adminUpdate"
|
||||
return 0
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function adminUpdate {
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -62,50 +62,56 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/adminUpdate.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/adminUpdate.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='adminUpdate'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/adminUpdate.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
rm /etc/sudoers
|
||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||
root ALL = (ALL) ALL
|
||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(randompassword)' foo
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/foo/.ssh/authorized_keys
|
||||
chown -R foo /home/users/foo
|
||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
" '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}}
|
||||
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
|
||||
cat >> $INSTANCE_HOME/adminUpdate.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/adminUpdate.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/adminUpdate.sh
|
||||
;;
|
||||
|
@ -126,6 +132,17 @@ 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
|
||||
|
@ -139,4 +156,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -10,12 +10,12 @@ function abort {
|
|||
function default {
|
||||
export INSTANCE_NAME="jboss"
|
||||
export INSTANCE_HOME="/usr/local/jboss"
|
||||
export LOG_DIR="/usr/local/jboss"
|
||||
return 0
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function jboss {
|
||||
export JBOSS_HOME="/usr/local/jboss"
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -60,7 +60,7 @@ case $1 in
|
|||
init)
|
||||
default || 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'?>
|
||||
|
||||
<server name="basic" xmlns="urn:jboss:domain:1.0">
|
||||
|
@ -165,34 +165,41 @@ init)
|
|||
</socket-binding-group>
|
||||
</server>
|
||||
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/jboss.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='jboss'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/jboss.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||
export JBOSS_HOME='$JBOSS_HOME'
|
||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
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
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/jboss.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/jboss.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/jboss.sh
|
||||
;;
|
||||
|
@ -213,6 +220,17 @@ 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
|
||||
|
@ -226,4 +244,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -45,6 +45,8 @@ import org.jclouds.lifecycle.Closer;
|
|||
import org.jclouds.logging.Logger;
|
||||
|
||||
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.inject.AbstractModule;
|
||||
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
|
||||
@Singleton
|
||||
@Named(Constants.PROPERTY_USER_THREADS)
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.predicates;
|
|||
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
@ -88,6 +89,9 @@ public class RetryablePredicate<T> implements Predicate<T> {
|
|||
} else if (getFirstThrowableOfType(e, IllegalStateException.class) != null) {
|
||||
logger.warn(e, "predicate %s on %s illegal state [%s], returning false", input, predicate, e.getMessage());
|
||||
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) {
|
||||
logger.warn(e, "predicate %s on %s timed out [%s], returning false", input, predicate, e.getMessage());
|
||||
return false;
|
||||
|
|
|
@ -39,7 +39,7 @@ public class GuestAdditionsInstaller implements Predicate<String> {
|
|||
ListenableFuture<ExecResponse> execFuture = context.getComputeService().submitScriptOnNode(vmName,
|
||||
new InstallGuestAdditions(vboxVersion), RunScriptOptions.NONE);
|
||||
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 {
|
||||
if (context.getComputeService()
|
||||
.runScriptOnNode(nodeId, "id", wrapInInitScript(false).runAsRoot(false))
|
||||
.getExitCode() == 0) {
|
||||
.getExitStatus() == 0) {
|
||||
logger.debug("Got response from ssh daemon running on %s", nodeId);
|
||||
sshDaemonIsRunning = true;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class SshResponds implements Predicate<SshClient> {
|
|||
|
||||
try {
|
||||
client.connect();
|
||||
if (client.exec("id").getExitCode() == 0) {
|
||||
if (client.exec("id").getExitStatus() == 0) {
|
||||
return true;
|
||||
}
|
||||
} catch (SshException e) {
|
||||
|
|
|
@ -51,8 +51,7 @@ public class InstallGuestAdditions extends StatementList {
|
|||
|
||||
@Override
|
||||
public String render(OsFamily family) {
|
||||
checkNotNull(family, "family");
|
||||
if (family == OsFamily.WINDOWS)
|
||||
if (checkNotNull(family, "family") == OsFamily.WINDOWS)
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
return super.render(family);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
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.ShellToken;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
@ -30,7 +30,6 @@ import org.jclouds.virtualbox.statements.InstallGuestAdditions;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
|
@ -47,8 +46,8 @@ public class InstallGuestAdditionsTest {
|
|||
|
||||
@Test
|
||||
public void testUnixInInitScript() throws IOException {
|
||||
Statement statement = new InitBuilder("install_guest_additions", ImmutableSet.<Statement> of(),
|
||||
ImmutableSet.<Statement> of(new InstallGuestAdditions("4.1.6")));
|
||||
Statement statement = InitScript.builder().name("install_guest_additions")
|
||||
.run(new InstallGuestAdditions("4.1.6")).build();
|
||||
|
||||
assertEquals(statement.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(
|
||||
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
|
||||
exportIpAddressFromVmNamed $@ || exit 1
|
||||
echo $FOUND_IP_ADDRESS
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -9,12 +9,12 @@ function abort {
|
|||
}
|
||||
function default {
|
||||
export INSTANCE_NAME="install_guest_additions"
|
||||
export INSTANCE_HOME="$HOME/instances/install_guest_additions"
|
||||
export LOG_DIR="$HOME/instances/install_guest_additions"
|
||||
return 0
|
||||
export INSTANCE_HOME="/tmp/$INSTANCE_NAME"
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function install_guest_additions {
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -62,35 +62,41 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# 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
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 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_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/install_guest_additions.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
function abort {
|
||||
echo "aborting: \$@" 1>&2
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
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)"
|
||||
|
||||
function ensure_cmd_or_install_package_apt(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
local cmd=$1
|
||||
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(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
||||
local cmd=$1
|
||||
local pkg=$2
|
||||
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||
}
|
||||
|
||||
function ensure_netutils_apt() {
|
||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
|||
# most network services require that the hostname is in
|
||||
# the /etc/hosts file, or they won't operate
|
||||
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
|
||||
|
@ -130,31 +136,40 @@ function setupPublicCurl() {
|
|||
function installModuleAssistantIfNeeded {
|
||||
unset OSNAME;
|
||||
local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
||||
if [ \$OSNAME = 'Ubuntu' ]
|
||||
if [ $OSNAME = 'Ubuntu' ]
|
||||
then
|
||||
echo "OS is Ubuntu"
|
||||
apt-get -f -y -qq --force-yes install build-essential module-assistant;
|
||||
m-a prepare -i
|
||||
fi
|
||||
}
|
||||
END_OF_SCRIPT
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
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)
|
||||
|
||||
mount -o loop /tmp/VBoxGuestAdditions_4.1.6.iso /mnt
|
||||
|
||||
installModuleAssistantIfNeeded || exit 1
|
||||
|
||||
/mnt/VBoxLinuxAdditions.run
|
||||
|
||||
umount /mnt
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/install_guest_additions.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/install_guest_additions.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/install_guest_additions.sh
|
||||
;;
|
||||
|
@ -175,6 +190,17 @@ 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
|
||||
|
@ -188,4 +214,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -38,8 +38,10 @@ import com.google.common.collect.Iterables;
|
|||
/**
|
||||
* Creates an init script file
|
||||
*
|
||||
* @see InitScript
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Deprecated
|
||||
public class InitBuilder extends ScriptBuilder {
|
||||
|
||||
private final String instanceName;
|
||||
|
@ -53,8 +55,8 @@ public class InitBuilder extends ScriptBuilder {
|
|||
}
|
||||
|
||||
public InitBuilder(String instanceName, Iterable<Statement> initStatements, Iterable<Statement> statements) {
|
||||
this(instanceName, String.format("{varl}HOME{varr}{fs}instances{fs}%s", instanceName), String.format(
|
||||
"{varl}HOME{varr}{fs}instances{fs}%s", instanceName), ImmutableMap.<String, String> of(), initStatements,
|
||||
this(instanceName, String.format("{tmp}{fs}{varl}INSTANCE_NAME{varr}", instanceName), String.format(
|
||||
"{tmp}{fs}{varl}INSTANCE_NAME{varr}", instanceName), ImmutableMap.<String, String> of(), initStatements,
|
||||
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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
|
@ -38,21 +37,66 @@ import com.google.common.collect.Maps;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
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;
|
||||
final Iterable<String> lines;
|
||||
final String marker;
|
||||
|
||||
public AppendFile(String path, Iterable<String> lines) {
|
||||
this(path, lines, MARKER);
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
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.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");
|
||||
this.expandVariables = expandVariables;
|
||||
}
|
||||
|
||||
public static String escapeVarTokens(String toEscape, OsFamily family) {
|
||||
|
@ -76,35 +120,45 @@ public class AppendFile implements Statement {
|
|||
|
||||
@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()));
|
||||
return interpret(hereFile()).render(family);
|
||||
} else {
|
||||
for (String line : lines) {
|
||||
statements.add(appendToFile(line, path, family));
|
||||
return interpret(appendToWindowsFile()).render(family);
|
||||
}
|
||||
}
|
||||
return new StatementList(statements).render(family);
|
||||
}
|
||||
|
||||
protected void hereFile(String path, StringBuilder builder) {
|
||||
builder.append("cat >> ").append(path).append(" <<'").append(marker).append("'\n");
|
||||
protected String appendToWindowsFile() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
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 = "";
|
||||
if (!ShellToken.VQ.to(family).equals("")) {
|
||||
if (!ShellToken.VQ.to(OsFamily.WINDOWS).equals("")) {
|
||||
quote = "'";
|
||||
} 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;
|
||||
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Creates a run script
|
||||
|
@ -30,38 +25,54 @@ import com.google.common.collect.Lists;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class CreateOrOverwriteFile extends AppendFile {
|
||||
|
||||
public CreateOrOverwriteFile(String path, Iterable<String> lines) {
|
||||
super(path, lines);
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public CreateOrOverwriteFile(String path, Iterable<String> lines, String marker) {
|
||||
super(path, lines, marker);
|
||||
public static class Builder extends AppendFile.Builder {
|
||||
|
||||
@Override
|
||||
public Builder path(String path) {
|
||||
return Builder.class.cast(super.path(path));
|
||||
}
|
||||
|
||||
@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 {
|
||||
// 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);
|
||||
public Builder lines(Iterable<String> lines) {
|
||||
return Builder.class.cast(super.lines(lines));
|
||||
}
|
||||
|
||||
protected 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");
|
||||
@Override
|
||||
public Builder delimeter(String delimeter) {
|
||||
return Builder.class.cast(super.delimeter(delimeter));
|
||||
}
|
||||
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.collect.Iterables.any;
|
||||
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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jclouds.scriptbuilder.ExitInsteadOfReturn;
|
||||
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||
import org.jclouds.scriptbuilder.util.Utils;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Creates a run script
|
||||
|
@ -46,7 +50,7 @@ import com.google.common.collect.ImmutableMap;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
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 Iterable<String> exports;
|
||||
final String pwd;
|
||||
|
@ -58,44 +62,17 @@ public class CreateRunScript extends StatementList {
|
|||
this.pwd = checkNotNull(pwd, "pwd").replaceAll("[/\\\\]", "{fs}");
|
||||
}
|
||||
|
||||
public static class AddTitleToFile 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 {
|
||||
public static class AddExport implements Statement {
|
||||
final String export;
|
||||
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.value = checkNotNull(value, "value");
|
||||
this.file = checkNotNull(file, "file");
|
||||
}
|
||||
|
||||
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
|
||||
public Iterable<String> functionDependencies(OsFamily family) {
|
||||
|
@ -104,137 +81,91 @@ public class CreateRunScript extends StatementList {
|
|||
|
||||
@Override
|
||||
public String render(OsFamily family) {
|
||||
return addSpaceToEnsureWeDontAccidentallyRedirectFd(Utils.replaceTokens(OS_TO_EXPORT_PATTERN.get(family),
|
||||
ImmutableMap.of("export", export, "value", value, "file", file)));
|
||||
return Utils
|
||||
.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
|
||||
public Iterable<String> functionDependencies(OsFamily family) {
|
||||
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
|
||||
public String render(OsFamily family) {
|
||||
if (checkNotNull(family, "family") == OsFamily.WINDOWS)
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
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);
|
||||
statements.add(interpret(String.format("{md} %s{lf}", pwd)));
|
||||
if (family == OsFamily.UNIX) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("\n");
|
||||
addUnixRunScriptHeader(family, runScript, builder);
|
||||
addUnixRunScriptHeader(runScript, builder);
|
||||
builder.append("\n");
|
||||
addUnixRunScript(runScript, builder);
|
||||
builder.append("\n");
|
||||
addUnixRunScriptFooter(family, runScript, builder);
|
||||
addUnixRunScriptFooter(runScript, builder);
|
||||
builder.append("\n");
|
||||
statements.add(interpret(builder.toString()));
|
||||
} else {
|
||||
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))));
|
||||
statements.add(exec("chmod u+x " + runScript));
|
||||
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("cat >> ").append(runScript).append(" <<'").append(MARKER).append("'\n");
|
||||
builder.append(ShellToken.END_SCRIPT.to(family));
|
||||
builder.append(MARKER).append("\n");
|
||||
Iterable<String> endScript = Splitter.on(ShellToken.LF.to(OsFamily.UNIX)).split(
|
||||
ShellToken.END_SCRIPT.to(OsFamily.UNIX));
|
||||
builder.append(appendFile(runScript, endScript, DELIMETER).render(OsFamily.UNIX));
|
||||
}
|
||||
|
||||
private void addUnixRunScript(String runScript, StringBuilder builder) {
|
||||
builder.append("# add desired commands from the user\n");
|
||||
builder.append("cat >> ").append(runScript).append(" <<'").append(MARKER).append("'\n");
|
||||
builder.append("cd ").append(pwd).append("\n");
|
||||
Builder<String> userCommands = ImmutableList.<String>builder();
|
||||
userCommands.add("cd " + pwd);
|
||||
for (Statement statement : statements) {
|
||||
if (statement instanceof Call
|
||||
|| (statement instanceof StatementList && any(StatementList.class.cast(statement).delegate(),
|
||||
instanceOf(Call.class)))) {
|
||||
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("cat > ").append(runScript).append(" <<").append(MARKER).append("\n");
|
||||
builder.append(ShellToken.BEGIN_SCRIPT.to(family));
|
||||
builder.append("PROMPT_COMMAND='echo -ne \"\\033]0;").append(instanceName).append("\\007\"'\n");
|
||||
builder.append(Utils.writeZeroPath(family));
|
||||
builder.append("export INSTANCE_NAME='").append(instanceName).append("'\n");
|
||||
for (String export : exports) {
|
||||
|
||||
Builder<String> beginningOfFile = ImmutableList.<String> builder();
|
||||
beginningOfFile.addAll(Splitter.on(ShellToken.LF.to(OsFamily.UNIX)).split(
|
||||
ShellToken.BEGIN_SCRIPT.to(OsFamily.UNIX)));
|
||||
beginningOfFile.add(format("PROMPT_COMMAND='echo -ne \\\"\\033]0;%s\\007\\\"'", instanceName));
|
||||
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);
|
||||
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(
|
||||
ImmutableMap.<String, String> of("abort", Utils.writeFunctionFromResource("abort", family)), statements,
|
||||
family);
|
||||
ImmutableMap.<String, String> of("abort", Utils.writeFunctionFromResource("abort", OsFamily.UNIX)),
|
||||
statements, OsFamily.UNIX);
|
||||
|
||||
// if there are more functions than simply abort
|
||||
if (functionsToWrite.size() > 1) {
|
||||
StringBuilder inNeedOfEscaping = new StringBuilder();
|
||||
ScriptBuilder.writeFunctions(functionsToWrite, family, inNeedOfEscaping);
|
||||
builder.append(inNeedOfEscaping.toString().replace("$", "\\$"));
|
||||
StringBuilder functions = new StringBuilder();
|
||||
ScriptBuilder.writeFunctions(functionsToWrite, OsFamily.UNIX, functions);
|
||||
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:
|
||||
return " exit /b 0\r\n";
|
||||
case UNIX:
|
||||
return " return 0\n}\n";
|
||||
return " return $?\n}\n";
|
||||
}
|
||||
case ESCVAR:
|
||||
switch (family) {
|
||||
|
@ -173,7 +173,7 @@ public enum ShellToken {
|
|||
case WINDOWS:
|
||||
return "exit /b 0\r\n";
|
||||
case UNIX:
|
||||
return "exit 0\n";
|
||||
return "exit $?\n";
|
||||
}
|
||||
case EXPORT:
|
||||
switch (family) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
|
@ -64,20 +65,24 @@ public class Statements {
|
|||
return new Call(function, args);
|
||||
}
|
||||
|
||||
public static Statement appendFile(String path, Iterable<String> lines) {
|
||||
return new AppendFile(path, lines);
|
||||
public static Statement appendFile(String path, String line, String delimeter) {
|
||||
return AppendFile.builder().path(path).lines(ImmutableSet.of(line)).delimeter(delimeter).build();
|
||||
}
|
||||
|
||||
public static Statement appendFile(String path, Iterable<String> lines, String marker) {
|
||||
return new AppendFile(path, lines, marker);
|
||||
public static Statement appendFile(String path, Iterable<String> lines) {
|
||||
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) {
|
||||
return new CreateOrOverwriteFile(path, lines);
|
||||
return CreateOrOverwriteFile.builder().path(path).lines(lines).build();
|
||||
}
|
||||
|
||||
public static Statement createOrOverwriteFile(String path, Iterable<String> lines, String marker) {
|
||||
return new CreateOrOverwriteFile(path, lines, marker);
|
||||
public static Statement createOrOverwriteFile(String path, Iterable<String> lines, String delimeter) {
|
||||
return CreateOrOverwriteFile.builder().path(path).lines(lines).delimeter(delimeter).build();
|
||||
}
|
||||
|
||||
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
|
||||
* - 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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -94,11 +94,11 @@ public class SwitchArg implements Statement, AcceptsStatementVisitor {
|
|||
if (shouldIndent)
|
||||
actionBuilder.append(INDENT);
|
||||
actionBuilder.append(line).append(ShellToken.LF.to(family));
|
||||
if (line.indexOf(CreateRunScript.MARKER) != -1) {
|
||||
if (line.indexOf(CreateRunScript.DELIMETER) != -1) {
|
||||
inRunScript = inRunScript ? false : true;
|
||||
|
||||
}
|
||||
if (line.indexOf(AppendFile.MARKER) != -1) {
|
||||
if (line.indexOf(AppendFile.DELIMETER) != -1) {
|
||||
inCreateFile = inCreateFile ? false : true;
|
||||
}
|
||||
shouldIndent = !inCreateFile && !inRunScript;
|
||||
|
|
|
@ -19,27 +19,30 @@
|
|||
package org.jclouds.scriptbuilder.statements.login;
|
||||
|
||||
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 java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.crypto.Sha512Crypt;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||
import org.jclouds.scriptbuilder.statements.ssh.SshStatements;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
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.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
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.inject.ImplementedBy;
|
||||
|
||||
|
@ -288,7 +291,8 @@ public class AdminAccess implements Statement {
|
|||
}
|
||||
}
|
||||
|
||||
private Config config;
|
||||
@VisibleForTesting
|
||||
Config config;
|
||||
|
||||
protected AdminAccess(Config in) {
|
||||
this.config = checkNotNull(in, "in");
|
||||
|
@ -344,9 +348,14 @@ public class AdminAccess implements Statement {
|
|||
checkNotNull(family, "family");
|
||||
if (family == OsFamily.WINDOWS)
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
checkNotNull(config.getAdminUsername(), "adminUsername");
|
||||
Preconditions.checkArgument(!"root".equals(config.getAdminUsername()), "cannot create admin user 'root'; " +
|
||||
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");
|
||||
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.getAdminPublicKey(), "adminPublicKey");
|
||||
checkNotNull(config.getAdminPrivateKey(), "adminPrivateKey");
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package org.jclouds.scriptbuilder.statements.login;
|
||||
|
||||
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 org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
|
@ -45,8 +45,7 @@ public class Sudoers implements Statement {
|
|||
if (family == OsFamily.WINDOWS)
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
Builder<Statement> statements = ImmutableList.<Statement> builder();
|
||||
statements.add(exec("{rm} " + sudoers));
|
||||
statements.add(appendFile(sudoers, ImmutableSet.of("root ALL = (ALL) ALL", "%wheel ALL = (ALL) NOPASSWD:ALL")));
|
||||
statements.add(createOrOverwriteFile(sudoers, ImmutableSet.of("root ALL = (ALL) ALL", "%wheel ALL = (ALL) NOPASSWD:ALL")));
|
||||
statements.add(exec("chmod 0440 " + sudoers));
|
||||
return new StatementList(statements.build()).render(family);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class SshdConfig implements Statement {
|
|||
Statement prependSshdConfig = exec(String.format(
|
||||
"exec 3<> %1$s && awk -v TEXT=\"%2$s\n\" 'BEGIN {print TEXT}{print}' %1$s >&3", sshdConfig,
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,12 +49,9 @@ public class InitBuilderTest {
|
|||
appendFile("{tmp}{fs}{uid}{fs}scripttest{fs}temp.txt", ImmutableList.<String> of("hello world")),
|
||||
exec("find /")));
|
||||
|
||||
@Test
|
||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||
public void testBuildSimpleWindows() throws MalformedURLException, IOException {
|
||||
assertEquals(
|
||||
testInitBuilder.render(OsFamily.WINDOWS),
|
||||
CharStreams.toString(Resources.newReaderSupplier(
|
||||
Resources.getResource("test_init." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8)));
|
||||
testInitBuilder.render(OsFamily.WINDOWS);
|
||||
}
|
||||
|
||||
@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)));
|
||||
}
|
||||
|
||||
public void testWINDOWS() throws IOException {
|
||||
assertEquals(statement.render(OsFamily.WINDOWS), CharStreams.toString(Resources.newReaderSupplier(Resources
|
||||
.getResource("test_runrun." + ShellToken.SH.to(OsFamily.WINDOWS)), Charsets.UTF_8)));
|
||||
}
|
||||
|
||||
public void testRedirectGuard() {
|
||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo>>"), "foo>>");
|
||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo0>>"), "foo0 >>");
|
||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo1>>"), "foo1 >>");
|
||||
assertEquals(CreateRunScript.addSpaceToEnsureWeDontAccidentallyRedirectFd("foo2>>"), "foo2 >>");
|
||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||
public void testWINDOWSUnimplemented() throws IOException {
|
||||
statement.render(OsFamily.WINDOWS);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ public class ShellTokenTest {
|
|||
"args", "$@").put("varl", "$").put("return", "return").put("exit", "exit").put(
|
||||
"varr", "").put("libraryPathVariable", "LD_LIBRARY_PATH").put("beginScript",
|
||||
"#!/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",
|
||||
" 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",
|
||||
"mkdir -p").put("escvar", "\\").build();
|
||||
assertEquals(ShellToken.tokenValueMap(OsFamily.UNIX), expected);
|
||||
|
|
|
@ -39,7 +39,17 @@ public class SwitchArgTest {
|
|||
assertEquals(new SwitchArg(1, ImmutableMap.of("0", newStatementList(appendFile(
|
||||
"{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),
|
||||
"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() {
|
||||
|
|
|
@ -18,20 +18,19 @@
|
|||
*/
|
||||
package org.jclouds.scriptbuilder.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
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.Statements;
|
||||
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
|
@ -97,8 +96,8 @@ public class CredentialsFromAdminAccessTest {
|
|||
replay(statement);
|
||||
replay(creds);
|
||||
|
||||
InitBuilder testInitBuilder = new InitBuilder("mkebsboot", "/mnt/tmp", "/mnt/tmp", ImmutableMap.of("tmpDir",
|
||||
"/mnt/tmp"), ImmutableList.<Statement> of(statement));
|
||||
InitScript testInitBuilder = InitScript.builder().name("mkebsboot").home("/mnt/tmp")
|
||||
.exportVariables(ImmutableMap.of("tmpDir", "/mnt/tmp")).run(statement).build();
|
||||
|
||||
assertEquals(CredentialsFromAdminAccess.INSTANCE.apply(testInitBuilder), creds);
|
||||
|
||||
|
|
|
@ -18,18 +18,16 @@
|
|||
*/
|
||||
package org.jclouds.scriptbuilder.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
|
@ -101,8 +99,8 @@ public class InitAdminAccessTest {
|
|||
replay(statement);
|
||||
replay(newStatement);
|
||||
|
||||
InitBuilder testInitBuilder = new InitBuilder("mkebsboot", "/mnt/tmp", "/mnt/tmp", ImmutableMap.of("tmpDir",
|
||||
"/mnt/tmp"), ImmutableList.<Statement> of(statement));
|
||||
InitScript testInitBuilder = InitScript.builder().name("mkebsboot").home("/mnt/tmp")
|
||||
.exportVariables(ImmutableMap.of("tmpDir", "/mnt/tmp")).run(statement).build();
|
||||
|
||||
InitAdminAccess initAdminAccess = new InitAdminAccess(configuration);
|
||||
|
||||
|
|
|
@ -23,14 +23,13 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.IOException;
|
||||
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.ShellToken;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
|
@ -48,11 +47,10 @@ public class InstallJDKTest {
|
|||
}
|
||||
|
||||
public void testInstallJDKUNIXInScriptBuilderSourcesSetupPublicCurl() throws IOException {
|
||||
assertEquals(
|
||||
new InitBuilder("install_jdk", ImmutableSet.<Statement> of(), ImmutableSet.<Statement> of(InstallJDK
|
||||
.fromURL())).render(OsFamily.UNIX),
|
||||
assertEquals(InitScript.builder().name("install_jdk").run(InstallJDK.fromURL()).build().render(OsFamily.UNIX),
|
||||
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 {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.scriptbuilder.statements.login;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
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() {
|
||||
assertEquals(
|
||||
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)
|
||||
|
|
|
@ -61,13 +61,13 @@ public class UserAddTest {
|
|||
public void testWithSshAuthorizedKeyUNIX() {
|
||||
assertEquals(
|
||||
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() {
|
||||
assertEquals(
|
||||
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)
|
||||
|
|
|
@ -34,26 +34,46 @@ public class AuthorizeRSAPublicKeyTest {
|
|||
public void testAuthorizeRSAPublicKeyUNIXCurrentUser() {
|
||||
assertEquals(
|
||||
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() {
|
||||
assertEquals(
|
||||
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() {
|
||||
assertEquals(
|
||||
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() {
|
||||
assertEquals(
|
||||
new AuthorizeRSAPublicKeys("/home/me/.ssh", ImmutableSet.of("ssh-dss AAAAB", "ssh-dss CCCCD"))
|
||||
.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)
|
||||
|
|
|
@ -33,15 +33,28 @@ public class InstallRSAPrivateKeyTest {
|
|||
assertEquals(
|
||||
new InstallRSAPrivateKey("-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n")
|
||||
.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() {
|
||||
assertEquals(
|
||||
new InstallRSAPrivateKey("/home/me/.ssh", "-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----\n")
|
||||
.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)
|
||||
public void testInstallRSAPrivateKeyWINDOWS() {
|
||||
|
|
|
@ -38,7 +38,7 @@ public class SshStatementsTest {
|
|||
.append("PasswordAuthentication no").append("\n")//
|
||||
.append("PermitRootLogin no").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() {
|
||||
|
@ -46,7 +46,7 @@ public class SshStatementsTest {
|
|||
new StringBuilder().append("exec 3<> /etc/ssh/sshd_config && awk -v TEXT=\"")//
|
||||
.append("AddressFamily inet6").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_location STDOUT
|
||||
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_location STDOUT
|
||||
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
|
||||
PermitRootLogin no
|
||||
" '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}}
|
||||
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_FILE'
|
||||
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||
root ALL = (ALL) ALL
|
||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(bar)' foo
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/foo/.ssh/authorized_keys
|
||||
chown -R foo /home/users/foo
|
||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
" '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}}
|
||||
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
mkdir -p /home/users
|
||||
useradd -s /bin/bash -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/defaultAdminUsername/.ssh/id_rsa
|
||||
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
rm /etc/sudoers
|
||||
cat >> /etc/sudoers <<'END_OF_FILE'
|
||||
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
||||
root ALL = (ALL) ALL
|
||||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
||||
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
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/defaultAdminUsername/.ssh/authorized_keys
|
||||
chown -R defaultAdminUsername /home/users/defaultAdminUsername
|
||||
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
|
||||
PermitRootLogin no
|
||||
" '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}}
|
||||
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_HOME="/tmp"
|
||||
export LOG_DIR="/tmp/logs"
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function mkebsboot {
|
||||
export IMAGE_DIR="/mnt/tmp"
|
||||
export EBS_DEVICE="/dev/sdh"
|
||||
export EBS_MOUNT_POINT="/mnt/ebs"
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -65,24 +65,28 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/mkebsboot.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='mkebsboot'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||
export IMAGE_DIR='$IMAGE_DIR'
|
||||
export EBS_DEVICE='$EBS_DEVICE'
|
||||
export EBS_MOUNT_POINT='$EBS_MOUNT_POINT'
|
||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
echo creating a filesystem and mounting the ebs volume
|
||||
mkdir -p $IMAGE_DIR $EBS_MOUNT_POINT
|
||||
|
@ -103,12 +107,13 @@ du -sk $IMAGE_DIR
|
|||
rm -rf $IMAGE_DIR/*
|
||||
umount $EBS_MOUNT_POINT
|
||||
echo ----COMPLETE----
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/mkebsboot.sh
|
||||
;;
|
||||
|
@ -142,4 +147,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -25,4 +25,4 @@ function findPid {
|
|||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
findPid $@ || exit 1
|
||||
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_HOME="/mnt/tmp"
|
||||
export LOG_DIR="/mnt/tmp"
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function mkebsboot {
|
||||
export TMP_DIR="/mnt/tmp"
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -63,35 +63,40 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/mkebsboot.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='mkebsboot'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||
export TMP_DIR='$TMP_DIR'
|
||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'
|
||||
cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'
|
||||
hello world
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
|
||||
find /
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/mkebsboot.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/mkebsboot.sh
|
||||
;;
|
||||
|
@ -125,4 +130,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
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 -)
|
||||
mv /usr/local/jdk* /usr/local/jdk/
|
||||
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 PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||
|
|
|
@ -9,12 +9,12 @@ function abort {
|
|||
}
|
||||
function default {
|
||||
export INSTANCE_NAME="install_jdk"
|
||||
export INSTANCE_HOME="$HOME/instances/install_jdk"
|
||||
export LOG_DIR="$HOME/instances/install_jdk"
|
||||
return 0
|
||||
export INSTANCE_HOME="/tmp/$INSTANCE_NAME"
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function install_jdk {
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
|
@ -62,35 +62,41 @@ init)
|
|||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/install_jdk.sh <<END_OF_SCRIPT
|
||||
cat > $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 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_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
function abort {
|
||||
echo "aborting: \$@" 1>&2
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
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)"
|
||||
|
||||
function ensure_cmd_or_install_package_apt(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
local cmd=$1
|
||||
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(){
|
||||
local cmd=\$1
|
||||
local pkg=\$2
|
||||
hash \$cmd 2>/dev/null || yum --nogpgcheck -y ensure \$pkg
|
||||
local cmd=$1
|
||||
local pkg=$2
|
||||
hash $cmd 2>/dev/null || yum --nogpgcheck -y ensure $pkg
|
||||
}
|
||||
|
||||
function ensure_netutils_apt() {
|
||||
|
@ -106,7 +112,7 @@ function ensure_netutils_yum() {
|
|||
# most network services require that the hostname is in
|
||||
# the /etc/hosts file, or they won't operate
|
||||
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
|
||||
|
@ -127,39 +133,43 @@ function setupPublicCurl() {
|
|||
ensure_can_resolve_public_dns
|
||||
return 0
|
||||
}
|
||||
END_OF_SCRIPT
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
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 -)
|
||||
mv /usr/local/jdk* /usr/local/jdk/
|
||||
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 PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> $HOME/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> $HOME/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
cat >> /etc/skel/.bashrc <<'END_OF_FILE'
|
||||
END_OF_JCLOUDS_FILE
|
||||
cat >> /etc/skel/.bashrc <<-'END_OF_JCLOUDS_FILE'
|
||||
export JAVA_HOME=/usr/local/jdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
ln -fs /usr/local/jdk/bin/java /usr/bin/java
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/install_jdk.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> $INSTANCE_HOME/install_jdk.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/install_jdk.sh
|
||||
;;
|
||||
|
@ -180,6 +190,17 @@ 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
|
||||
|
@ -193,4 +214,4 @@ run)
|
|||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
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
|
||||
|
||||
# create runscript header
|
||||
cat > /tmp/$USER/scripttest/yahooprod.sh <<END_OF_SCRIPT
|
||||
cat > /tmp/$USER/scripttest/yahooprod.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
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 INSTANCE_NAME='yahooprod'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> /tmp/$USER/scripttest/yahooprod.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||
export JAVA_HOME='$JAVA_HOME'
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# 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
|
||||
echo hello
|
||||
|
||||
cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'
|
||||
cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'
|
||||
hello world
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
|
||||
echo $JAVA_HOME/bin/java -DinstanceName=$INSTANCE_NAME myServer.Main
|
||||
|
||||
END_OF_SCRIPT
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> /tmp/$USER/scripttest/yahooprod.sh <<'END_OF_SCRIPT'
|
||||
exit 0
|
||||
END_OF_SCRIPT
|
||||
cat >> /tmp/$USER/scripttest/yahooprod.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x /tmp/$USER/scripttest/yahooprod.sh
|
||||
|
|
|
@ -9,7 +9,7 @@ function abort {
|
|||
}
|
||||
function default {
|
||||
export RUNTIME="Moo"
|
||||
return 0
|
||||
return $?
|
||||
}
|
||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
case $1 in
|
||||
|
@ -22,10 +22,10 @@ stop)
|
|||
echo stop $RUNTIME
|
||||
;;
|
||||
status)
|
||||
cat >> /tmp/$USER/scripttest/temp.txt <<'END_OF_FILE'
|
||||
cat >> /tmp/$USER/scripttest/temp.txt <<-'END_OF_JCLOUDS_FILE'
|
||||
hello world
|
||||
END_OF_FILE
|
||||
END_OF_JCLOUDS_FILE
|
||||
echo "the following should be []: [$RUNTIME]"
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -28,4 +28,4 @@ findPid $@ || exit 1
|
|||
echo stopping $FOUND_PID
|
||||
kill -9 $FOUND_PID
|
||||
}
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
Loading…
Reference in New Issue