Adds (WIP) outline for VanillaWindowsProcess
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/2b07bed4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/2b07bed4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/2b07bed4 Branch: refs/heads/master Commit: 2b07bed4f2ed5e00b0422161455c2baa91ddea60 Parents: ce2a7c2 Author: Martin Harris <[email protected]> Authored: Mon Apr 13 10:48:58 2015 +0100 Committer: Richard Downer <[email protected]> Committed: Thu May 28 17:27:34 2015 +0100 ---------------------------------------------------------------------- .../location/basic/WinRmMachineLocation.java | 8 + .../basic/AbstractSoftwareProcessDriver.java | 243 +++++++++++++++++-- .../basic/AbstractSoftwareProcessSshDriver.java | 197 +-------------- .../AbstractSoftwareProcessWinRmDriver.java | 94 ++++++- .../basic/AbstractVanillaSoftwareProcess.java | 32 +++ .../AbstractVanillaSoftwareProcessDriver.java | 22 ++ .../entity/basic/VanillaSoftwareProcess.java | 12 +- .../basic/VanillaSoftwareProcessDriver.java | 3 +- .../entity/basic/VanillaWindowsProcess.java | 27 +++ .../basic/VanillaWindowsProcessDriver.java | 23 ++ .../entity/basic/VanillaWindowsProcessImpl.java | 38 +++ .../basic/VanillaWindowsProcessWinRmDriver.java | 54 +++++ 12 files changed, 527 insertions(+), 226 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java b/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java index 54e3829..186fc4f 100644 --- a/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java +++ b/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java @@ -91,12 +91,20 @@ public class WinRmMachineLocation extends AbstractLocation implements MachineLoc return null; } + public int executeScript(String script) { + return executeScript(ImmutableList.of(script)); + } + public int executeScript(List<String> script) { WinRmTool winRmTool = WinRmTool.connect(getHostname(), getUsername(), getPassword()); WinRmToolResponse response = winRmTool.executeScript(script); return response.getStatusCode(); } + public int executePsScript(String psScript) { + return executePsScript(ImmutableList.of(psScript)); + } + public int executePsScript(List<String> psScript) { WinRmTool winRmTool = WinRmTool.connect(getHostname(), getUsername(), getPassword()); WinRmToolResponse response = winRmTool.executePs(psScript); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java index 67af47f..9762c4f 100644 --- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java +++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java @@ -18,18 +18,26 @@ */ package brooklyn.entity.basic; +import static brooklyn.util.JavaGroovyEquivalents.elvis; import static com.google.common.base.Preconditions.checkNotNull; import java.io.File; import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import brooklyn.config.ConfigKey; +import brooklyn.entity.software.SshEffectorTasks; import brooklyn.location.Location; import brooklyn.util.ResourceUtils; +import brooklyn.util.collections.MutableMap; +import brooklyn.util.exceptions.Exceptions; +import brooklyn.util.os.Os; +import brooklyn.util.stream.ReaderInputStream; import brooklyn.util.task.DynamicTasks; import brooklyn.util.task.Tasks; import brooklyn.util.text.Strings; @@ -131,7 +139,7 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr DynamicTasks.queue("post-install-command", new Runnable() { public void run() { runPostInstallCommand(entity.getConfig(BrooklynConfigKeys.POST_INSTALL_COMMAND)); }}); - }; + } DynamicTasks.queue("customize", new Runnable() { public void run() { waitForConfigKey(BrooklynConfigKeys.CUSTOMIZE_LATCH); @@ -176,10 +184,8 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr public abstract void runPreInstallCommand(String command); public abstract void setup(); - public abstract void copyInstallResources(); public abstract void install(); public abstract void runPostInstallCommand(String command); - public abstract void copyRuntimeResources(); public abstract void customize(); public abstract void runPreLaunchCommand(String command); public abstract void launch(); @@ -197,25 +203,27 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr @Override public void restart() { - DynamicTasks.queue("stop (best effort)", new Runnable() { public void run() { - DynamicTasks.markInessential(); - boolean previouslyRunning = isRunning(); - try { - ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STOPPING); - stop(); - } catch (Exception e) { - // queue a failed task so that there is visual indication that this task had a failure, - // without interrupting the parent - if (previouslyRunning) { - log.warn(getEntity() + " restart: stop failed, when was previously running (ignoring)", e); - DynamicTasks.queue(Tasks.fail("Primary job failure (when previously running)", e)); - } else { - log.debug(getEntity() + " restart: stop failed (but was not previously running, so not a surprise)", e); - DynamicTasks.queue(Tasks.fail("Primary job failure (when not previously running)", e)); + DynamicTasks.queue("stop (best effort)", new Runnable() { + public void run() { + DynamicTasks.markInessential(); + boolean previouslyRunning = isRunning(); + try { + ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STOPPING); + stop(); + } catch (Exception e) { + // queue a failed task so that there is visual indication that this task had a failure, + // without interrupting the parent + if (previouslyRunning) { + log.warn(getEntity() + " restart: stop failed, when was previously running (ignoring)", e); + DynamicTasks.queue(Tasks.fail("Primary job failure (when previously running)", e)); + } else { + log.debug(getEntity() + " restart: stop failed (but was not previously running, so not a surprise)", e); + DynamicTasks.queue(Tasks.fail("Primary job failure (when not previously running)", e)); + } + // the above queued tasks will cause this task to be indicated as failed, with an indication of severity } - // the above queued tasks will cause this task to be indicated as failed, with an indication of severity } - }}); + }); if (doFullStartOnRestart()) { DynamicTasks.waitForLast(); @@ -251,6 +259,172 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr return resource.getResourceFromUrl(url); } + /** + * Files and templates to be copied to the server <em>before</em> installation. This allows the {@link #install()} + * process to have access to all required resources. + * <p> + * Will be prefixed with the entity's {@link #getInstallDir() install directory} if relative. + * + * @see SoftwareProcess#INSTALL_FILES + * @see SoftwareProcess#INSTALL_TEMPLATES + * @see #copyRuntimeResources() + */ + public void copyInstallResources() { + + // Ensure environment variables are not looked up here, otherwise sub-classes might + // lookup port numbers and fail with ugly error if port is not set; better to wait + // until in Entity's code (e.g. customize) where such checks are done explicitly. + createDirectory(getInstallDir(), "create install directory"); + + // TODO see comment in copyResource, that should be queued as a task like the above + // (better reporting in activities console) + + Map<String, String> installFiles = entity.getConfig(SoftwareProcess.INSTALL_FILES); + if (installFiles != null && installFiles.size() > 0) { + for (String source : installFiles.keySet()) { + String target = installFiles.get(source); + String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getInstallDir(), target); + copyResource(source, destination, true); + } + } + + Map<String, String> installTemplates = entity.getConfig(SoftwareProcess.INSTALL_TEMPLATES); + if (installTemplates != null && installTemplates.size() > 0) { + for (String source : installTemplates.keySet()) { + String target = installTemplates.get(source); + String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getInstallDir(), target); + copyTemplate(source, destination, true, MutableMap.<String, Object>of()); + } + } + + } + + protected abstract void createDirectory(String directoryName, String summaryForLogging); + + /** + * Files and templates to be copied to the server <em>after</em> customisation. This allows overwriting of + * existing files such as entity configuration which may be copied from the installation directory + * during the {@link #customize()} process. + * <p> + * Will be prefixed with the entity's {@link #getRunDir() run directory} if relative. + * + * @see SoftwareProcess#RUNTIME_FILES + * @see SoftwareProcess#RUNTIME_TEMPLATES + * @see #copyInstallResources() + */ + public void copyRuntimeResources() { + try { + // Ensure environment variables are not looked up here, otherwise sub-classes might + // lookup port numbers and fail with ugly error if port is not set. It could also + // cause us to block for attribute ready earlier than we need. + DynamicTasks.queue(SshEffectorTasks.ssh("mkdir -p " + getRunDir()).summary("create run directory") + .requiringExitCodeZero()).get(); + + Map<String, String> runtimeFiles = entity.getConfig(SoftwareProcess.RUNTIME_FILES); + if (runtimeFiles != null && runtimeFiles.size() > 0) { + for (String source : runtimeFiles.keySet()) { + String target = runtimeFiles.get(source); + String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getRunDir(), target); + copyResource(source, destination, true); + } + } + + Map<String, String> runtimeTemplates = entity.getConfig(SoftwareProcess.RUNTIME_TEMPLATES); + if (runtimeTemplates != null && runtimeTemplates.size() > 0) { + for (String source : runtimeTemplates.keySet()) { + String target = runtimeTemplates.get(source); + String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getRunDir(), target); + copyTemplate(source, destination, true, MutableMap.<String, Object>of()); + } + } + } catch (Exception e) { + log.warn("Error copying runtime resources", e); + throw Exceptions.propagate(e); + } + } + + /** + * @param template File to template and copy. + * @param target Destination on server. + * @return The exit code the SSH command run. + */ + public int copyTemplate(File template, String target) { + return copyTemplate(template.toURI().toASCIIString(), target); + } + + /** + * @param template URI of file to template and copy, e.g. file://.., http://.., classpath://.. + * @param target Destination on server. + * @return The exit code of the SSH command run. + */ + public int copyTemplate(String template, String target) { + return copyTemplate(template, target, false, ImmutableMap.<String, String>of()); + } + + /** + * @param template URI of file to template and copy, e.g. file://.., http://.., classpath://.. + * @param target Destination on server. + * @param extraSubstitutions Extra substitutions for the templater to use, for example + * "foo" -> "bar", and in a template ${foo}. + * @return The exit code of the SSH command run. + */ + public int copyTemplate(String template, String target, boolean createParent, Map<String, ?> extraSubstitutions) { + String data = processTemplate(template, extraSubstitutions); + return copyResource(MutableMap.<Object,Object>of(), new StringReader(data), target, createParent); + } + + public abstract int copyResource(Map<Object,Object> sshFlags, String source, String target, boolean createParentDir); + + public abstract int copyResource(Map<Object,Object> sshFlags, InputStream source, String target, boolean createParentDir); + + /** + * @param file File to copy. + * @param target Destination on server. + * @return The exit code the SSH command run. + */ + public int copyResource(File file, String target) { + return copyResource(file.toURI().toASCIIString(), target); + } + + /** + * @param resource URI of file to copy, e.g. file://.., http://.., classpath://.. + * @param target Destination on server. + * @return The exit code of the SSH command run + */ + public int copyResource(String resource, String target) { + return copyResource(MutableMap.of(), resource, target); + } + + public int copyResource(String resource, String target, boolean createParentDir) { + return copyResource(MutableMap.of(), resource, target, createParentDir); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public int copyResource(Map sshFlags, String source, String target) { + return copyResource(sshFlags, source, target, false); + } + + /** + * @see #copyResource(Map, InputStream, String, boolean) + */ + public int copyResource(Reader source, String target) { + return copyResource(MutableMap.of(), source, target, false); + } + + /** + * @see #copyResource(Map, InputStream, String, boolean) + */ + public int copyResource(Map<Object,Object> sshFlags, Reader source, String target, boolean createParent) { + return copyResource(sshFlags, new ReaderInputStream(source), target, createParent); + } + + /** + * @see #copyResource(Map, InputStream, String, boolean) + */ + public int copyResource(InputStream source, String target) { + return copyResource(MutableMap.of(), source, target, false); + } + public String getResourceAsString(String url) { return resource.getResourceAsString(url); } @@ -289,4 +463,33 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr Object val = entity.getConfig(configKey); if (val != null) log.debug("{} finished waiting for {} (value {}); continuing...", new Object[] {this, configKey, val}); } + + /** + * @deprecated since 0.5.0; instead rely on {@link brooklyn.entity.drivers.downloads.DownloadResolverManager} to include local-repo, such as: + * + * <pre> + * {@code + * DownloadResolver resolver = Entities.newDownloader(this); + * List<String> urls = resolver.getTargets(); + * } + * </pre> + */ + protected String getEntityVersionLabel() { + return getEntityVersionLabel("_"); + } + + /** + * @deprecated since 0.5.0; instead rely on {@link brooklyn.entity.drivers.downloads.DownloadResolverManager} to include local-repo + */ + protected String getEntityVersionLabel(String separator) { + return elvis(entity.getEntityType().getSimpleName(), + entity.getClass().getName())+(getVersion() != null ? separator+getVersion() : ""); + } + + public String getVersion() { + return getEntity().getConfig(SoftwareProcess.SUGGESTED_VERSION); + } + + public abstract String getRunDir(); + public abstract String getInstallDir(); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java index d731dc5..597a967 100644 --- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java +++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java @@ -22,10 +22,7 @@ import static brooklyn.util.JavaGroovyEquivalents.elvis; import static brooklyn.util.JavaGroovyEquivalents.groovyTruth; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; import java.util.List; import java.util.Map; import java.util.Set; @@ -42,7 +39,6 @@ import brooklyn.entity.effector.EffectorTasks; import brooklyn.entity.software.SshEffectorTasks; import brooklyn.event.feed.ConfigToAttributes; import brooklyn.location.basic.SshMachineLocation; -import brooklyn.util.collections.MutableMap; import brooklyn.util.exceptions.Exceptions; import brooklyn.util.guava.Maybe; import brooklyn.util.internal.ssh.SshTool; @@ -50,7 +46,6 @@ import brooklyn.util.internal.ssh.sshj.SshjTool; import brooklyn.util.os.Os; import brooklyn.util.ssh.BashCommands; import brooklyn.util.stream.KnownSizeInputStream; -import brooklyn.util.stream.ReaderInputStream; import brooklyn.util.stream.Streams; import brooklyn.util.task.DynamicTasks; import brooklyn.util.task.Tasks; @@ -61,7 +56,6 @@ import brooklyn.util.time.Duration; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; @@ -112,10 +106,6 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP return (SshMachineLocation) super.getLocation(); } - public String getVersion() { - return getEntity().getConfig(SoftwareProcess.SUGGESTED_VERSION); - } - /** * Name to be used in the local repo, when looking for the download file. */ @@ -131,28 +121,6 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP return "tar.gz"; } - /** - * @deprecated since 0.5.0; instead rely on {@link DownloadResolverManager} to include local-repo, such as: - * - * <pre> - * {@code - * DownloadResolver resolver = Entities.newDownloader(this); - * List<String> urls = resolver.getTargets(); - * } - * </pre> - */ - protected String getEntityVersionLabel() { - return getEntityVersionLabel("_"); - } - - /** - * @deprecated since 0.5.0; instead rely on {@link DownloadResolverManager} to include local-repo - */ - protected String getEntityVersionLabel(String separator) { - return elvis(entity.getEntityType().getSimpleName(), - entity.getClass().getName())+(getVersion() != null ? separator+getVersion() : ""); - } - protected void setInstallDir(String installDir) { this.installDir = installDir; entity.setAttribute(SoftwareProcess.INSTALL_DIR, installDir); @@ -324,94 +292,16 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP return getMachine().execScript(flags, summaryForLogging, script, environment); } - /** - * Files and templates to be copied to the server <em>before</em> installation. This allows the {@link #install()} - * process to have access to all required resources. - * <p> - * Will be prefixed with the entity's {@link #getInstallDir() install directory} if relative. - * - * @see SoftwareProcess#INSTALL_FILES - * @see SoftwareProcess#INSTALL_TEMPLATES - * @see #copyRuntimeResources() - */ @Override public void copyInstallResources() { - getLocation().acquireMutex("installing "+elvis(entity,this), "installation lock at host for files and templates"); + getLocation().acquireMutex("installing " + elvis(entity, this), "installation lock at host for files and templates"); try { - // Ensure environment variables are not looked up here, otherwise sub-classes might - // lookup port numbers and fail with ugly error if port is not set; better to wait - // until in Entity's code (e.g. customize) where such checks are done explicitly. - DynamicTasks.queue(SshEffectorTasks.ssh("mkdir -p " + getInstallDir()).summary("create install directory") - .requiringExitCodeZero()).get(); - - // TODO see comment in copyResource, that should be queued as a task like the above - // (better reporting in activities console) - - Map<String, String> installFiles = entity.getConfig(SoftwareProcess.INSTALL_FILES); - if (installFiles != null && installFiles.size() > 0) { - for (String source : installFiles.keySet()) { - String target = installFiles.get(source); - String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getInstallDir(), target); - copyResource(source, destination, true); - } - } - - Map<String, String> installTemplates = entity.getConfig(SoftwareProcess.INSTALL_TEMPLATES); - if (installTemplates != null && installTemplates.size() > 0) { - for (String source : installTemplates.keySet()) { - String target = installTemplates.get(source); - String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getInstallDir(), target); - copyTemplate(source, destination, true, MutableMap.<String, Object>of()); - } - } + super.copyInstallResources(); } catch (Exception e) { log.warn("Error copying install resources", e); throw Exceptions.propagate(e); } finally { - getLocation().releaseMutex("installing "+elvis(entity,this)); - } - } - - /** - * Files and templates to be copied to the server <em>after</em> customisation. This allows overwriting of - * existing files such as entity configuration which may be copied from the installation directory - * during the {@link #customize()} process. - * <p> - * Will be prefixed with the entity's {@link #getRunDir() run directory} if relative. - * - * @see SoftwareProcess#RUNTIME_FILES - * @see SoftwareProcess#RUNTIME_TEMPLATES - * @see #copyInstallResources() - */ - @Override - public void copyRuntimeResources() { - try { - // Ensure environment variables are not looked up here, otherwise sub-classes might - // lookup port numbers and fail with ugly error if port is not set. It could also - // cause us to block for attribute ready earlier than we need. - DynamicTasks.queue(SshEffectorTasks.ssh("mkdir -p " + getRunDir()).summary("create run directory") - .requiringExitCodeZero()).get(); - - Map<String, String> runtimeFiles = entity.getConfig(SoftwareProcess.RUNTIME_FILES); - if (runtimeFiles != null && runtimeFiles.size() > 0) { - for (String source : runtimeFiles.keySet()) { - String target = runtimeFiles.get(source); - String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getRunDir(), target); - copyResource(source, destination, true); - } - } - - Map<String, String> runtimeTemplates = entity.getConfig(SoftwareProcess.RUNTIME_TEMPLATES); - if (runtimeTemplates != null && runtimeTemplates.size() > 0) { - for (String source : runtimeTemplates.keySet()) { - String target = runtimeTemplates.get(source); - String destination = Os.isAbsolutish(target) ? target : Os.mergePathsUnix(getRunDir(), target); - copyTemplate(source, destination, true, MutableMap.<String, Object>of()); - } - } - } catch (Exception e) { - log.warn("Error copying runtime resources", e); - throw Exceptions.propagate(e); + getLocation().releaseMutex("installing " + elvis(entity, this)); } } @@ -443,62 +333,7 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP return Strings.toStringMap(entity.getConfig(SoftwareProcess.SHELL_ENVIRONMENT)); } - /** - * @param template File to template and copy. - * @param target Destination on server. - * @return The exit code the SSH command run. - */ - public int copyTemplate(File template, String target) { - return copyTemplate(template.toURI().toASCIIString(), target); - } - - /** - * @param template URI of file to template and copy, e.g. file://.., http://.., classpath://.. - * @param target Destination on server. - * @return The exit code of the SSH command run. - */ - public int copyTemplate(String template, String target) { - return copyTemplate(template, target, false, ImmutableMap.<String, String>of()); - } - - /** - * @param template URI of file to template and copy, e.g. file://.., http://.., classpath://.. - * @param target Destination on server. - * @param extraSubstitutions Extra substitutions for the templater to use, for example - * "foo" -> "bar", and in a template ${foo}. - * @return The exit code of the SSH command run. - */ - public int copyTemplate(String template, String target, boolean createParent, Map<String, ?> extraSubstitutions) { - String data = processTemplate(template, extraSubstitutions); - return copyResource(MutableMap.<Object,Object>of(), new StringReader(data), target, createParent); - } - - /** - * @param file File to copy. - * @param target Destination on server. - * @return The exit code the SSH command run. - */ - public int copyResource(File file, String target) { - return copyResource(file.toURI().toASCIIString(), target); - } - - /** - * @param resource URI of file to copy, e.g. file://.., http://.., classpath://.. - * @param target Destination on server. - * @return The exit code of the SSH command run - */ - public int copyResource(String resource, String target) { - return copyResource(MutableMap.of(), resource, target); - } - public int copyResource(String resource, String target, boolean createParentDir) { - return copyResource(MutableMap.of(), resource, target, createParentDir); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public int copyResource(Map sshFlags, String source, String target) { - return copyResource(sshFlags, source, target, false); - } /** * @param sshFlags Extra flags to be used when making an SSH connection to the entity's machine. @@ -539,26 +374,6 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP return result; } - /** - * @see #copyResource(Map, InputStream, String) - */ - public int copyResource(Reader source, String target) { - return copyResource(MutableMap.of(), source, target, false); - } - - /** - * @see #copyResource(Map, InputStream, String) - */ - public int copyResource(Map<Object,Object> sshFlags, Reader source, String target, boolean createParent) { - return copyResource(sshFlags, new ReaderInputStream(source), target, createParent); - } - - /** - * @see #copyResource(Map, InputStream, String) - */ - public int copyResource(InputStream source, String target) { - return copyResource(MutableMap.of(), source, target, false); - } /** * Input stream will be closed automatically. @@ -837,6 +652,12 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP return s; } + @Override + protected void createDirectory(String directoryName, String summaryForLogging) { + DynamicTasks.queue(SshEffectorTasks.ssh("mkdir -p " + directoryName).summary(summaryForLogging) + .requiringExitCodeZero()).get(); + } + public Set<Integer> getPortsUsed() { Set<Integer> result = Sets.newLinkedHashSet(); result.add(22); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java index b53685b..ed92e15 100644 --- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java +++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java @@ -21,33 +21,115 @@ package brooklyn.entity.basic; import java.io.File; import java.io.InputStream; import java.util.List; +import java.util.Map; +import brooklyn.config.ConfigKey; import brooklyn.location.basic.WinRmMachineLocation; +import com.google.api.client.util.Strings; +import com.google.common.collect.ImmutableList; + public abstract class AbstractSoftwareProcessWinRmDriver extends AbstractSoftwareProcessDriver { public AbstractSoftwareProcessWinRmDriver(EntityLocal entity, WinRmMachineLocation location) { super(entity, location); } - public WinRmMachineLocation getMachine() { - return (WinRmMachineLocation) getLocation(); + @Override + public void runPreInstallCommand(String command) { + execute(ImmutableList.of(command)); + } + + @Override + public void setup() { + // Default to no-op + } + + @Override + public void runPostInstallCommand(String command) { + execute(ImmutableList.of(command)); + } + + @Override + public void runPreLaunchCommand(String command) { + execute(ImmutableList.of(command)); + } + + @Override + public void runPostLaunchCommand(String command) { + execute(ImmutableList.of(command)); + } + + @Override + public WinRmMachineLocation getLocation() { + return (WinRmMachineLocation)super.getLocation(); + } + + @Override + public String getRunDir() { + // TODO: This needs to be tidied, and read from the appropriate flags (if set) + return "$HOME\\brooklyn-managed-processes\\apps\\" + entity.getApplicationId() + "\\entities\\" + getEntityVersionLabel()+"_"+entity.getId(); + } + + @Override + public String getInstallDir() { + // TODO: This needs to be tidied, and read from the appropriate flags (if set) + return "$HOME\\brooklyn-managed-processes\\installs\\" + entity.getApplicationId() + "\\" + getEntityVersionLabel()+"_"+entity.getId(); + } + + @Override + public int copyResource(Map<Object, Object> sshFlags, String source, String target, boolean createParentDir) { + if (createParentDir) { + createDirectory(getDirectory(target), "Creating resource directory"); + } + return copyTo(new File(source), new File(target)); + } + + @Override + public int copyResource(Map<Object, Object> sshFlags, InputStream source, String target, boolean createParentDir) { + if (createParentDir) { + createDirectory(getDirectory(target), "Creating resource directory"); + } + return copyTo(source, new File(target)); + } + + @Override + protected void createDirectory(String directoryName, String summaryForLogging) { + getLocation().executePsScript("New-Item -path \"" + directoryName + "\" -type directory -ErrorAction SilentlyContinue"); + } + + protected boolean executeCommand(ConfigKey<String> regularCommandKey, ConfigKey<String> powershellCommandKey) { + String regularCommand = getEntity().getConfig(regularCommandKey); + String powershellCommand = getEntity().getConfig(powershellCommandKey); + if ((Strings.isNullOrEmpty(regularCommand) && Strings.isNullOrEmpty(powershellCommand)) || ( + !Strings.isNullOrEmpty(regularCommand) && !Strings.isNullOrEmpty(powershellCommand))) { + throw new IllegalStateException(String.format("Exactly one of %s or %s must be set", regularCommandKey.getName(), powershellCommandKey.getName())); + } + if (Strings.isNullOrEmpty(regularCommand)) { + return getLocation().executePsScript(ImmutableList.of(powershellCommand)) == 0; + } else { + return getLocation().executeScript(ImmutableList.of(regularCommand)) == 0; + } } public int execute(List<String> script) { - return getMachine().executeScript(script); + return getLocation().executeScript(script); } public int executePowerShell(List<String> psScript) { - return getMachine().executePsScript(psScript); + return getLocation().executePsScript(psScript); } public int copyTo(File source, File destination) { - return getMachine().copyTo(source, destination); + return getLocation().copyTo(source, destination); } public int copyTo(InputStream source, File destination) { - return getMachine().copyTo(source, destination); + return getLocation().copyTo(source, destination); + } + + private String getDirectory(String fileName) { + return fileName.substring(0, fileName.lastIndexOf("\\")); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcess.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcess.java new file mode 100644 index 0000000..18fda37 --- /dev/null +++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcess.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 brooklyn.entity.basic; + +import brooklyn.config.ConfigKey; +import brooklyn.event.basic.AttributeSensorAndConfigKey; + +public interface AbstractVanillaSoftwareProcess extends SoftwareProcess { + AttributeSensorAndConfigKey<String, String> DOWNLOAD_URL = SoftwareProcess.DOWNLOAD_URL; + + ConfigKey<String> SUGGESTED_VERSION = ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "0.0.0"); + + ConfigKey<String> LAUNCH_COMMAND = ConfigKeys.newStringConfigKey("launch.command", "command to run to launch the process", "./start.sh"); + ConfigKey<String> CHECK_RUNNING_COMMAND = ConfigKeys.newStringConfigKey("checkRunning.command", "command to determine whether the process is running"); + ConfigKey<String> STOP_COMMAND = ConfigKeys.newStringConfigKey("stop.command", "command to run to stop the process"); +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcessDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcessDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcessDriver.java new file mode 100644 index 0000000..ca80f63 --- /dev/null +++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractVanillaSoftwareProcessDriver.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 brooklyn.entity.basic; + +public interface AbstractVanillaSoftwareProcessDriver extends SoftwareProcessDriver { +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java index f6d6ec1..a1cca3f 100644 --- a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java @@ -19,9 +19,7 @@ package brooklyn.entity.basic; import brooklyn.catalog.Catalog; -import brooklyn.config.ConfigKey; import brooklyn.entity.proxying.ImplementedBy; -import brooklyn.event.basic.AttributeSensorAndConfigKey; /** * A {@link SoftwareProcess} entity that runs commands from an archive. @@ -54,14 +52,6 @@ import brooklyn.event.basic.AttributeSensorAndConfigKey; */ @Catalog(name="Vanilla Software Process", description="A software process configured with scripts, e.g. for launch, check-running and stop") @ImplementedBy(VanillaSoftwareProcessImpl.class) -public interface VanillaSoftwareProcess extends SoftwareProcess { - - AttributeSensorAndConfigKey<String, String> DOWNLOAD_URL = SoftwareProcess.DOWNLOAD_URL; - - ConfigKey<String> SUGGESTED_VERSION = ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "0.0.0"); - - ConfigKey<String> LAUNCH_COMMAND = ConfigKeys.newStringConfigKey("launch.command", "command to run to launch the process", "./start.sh"); - ConfigKey<String> CHECK_RUNNING_COMMAND = ConfigKeys.newStringConfigKey("checkRunning.command", "command to determine whether the process is running"); - ConfigKey<String> STOP_COMMAND = ConfigKeys.newStringConfigKey("stop.command", "command to run to stop the process"); +public interface VanillaSoftwareProcess extends AbstractVanillaSoftwareProcess { } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java index f03796b..31ecdde 100644 --- a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessDriver.java @@ -18,5 +18,6 @@ */ package brooklyn.entity.basic; -public interface VanillaSoftwareProcessDriver extends SoftwareProcessDriver { +public interface VanillaSoftwareProcessDriver extends AbstractVanillaSoftwareProcessDriver { + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java new file mode 100644 index 0000000..133ea45 --- /dev/null +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 brooklyn.entity.basic; + +import brooklyn.config.ConfigKey; + +public interface VanillaWindowsProcess extends AbstractVanillaSoftwareProcess { + ConfigKey<String> LAUNCH_POWERSHELL_COMMAND = ConfigKeys.newStringConfigKey("launch.powershell.command", "command to run to launch the process", "./start.sh"); + ConfigKey<String> CHECK_RUNNING_POWERSHELL_COMMAND = ConfigKeys.newStringConfigKey("checkRunning.powershell.command", "command to determine whether the process is running"); + ConfigKey<String> STOP_POWERSHELL_COMMAND = ConfigKeys.newStringConfigKey("stop.powershell.command", "command to run to stop the process"); +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java new file mode 100644 index 0000000..228c443 --- /dev/null +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessDriver.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 brooklyn.entity.basic; + +public interface VanillaWindowsProcessDriver extends AbstractVanillaSoftwareProcessDriver { + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java new file mode 100644 index 0000000..f09bb87 --- /dev/null +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessImpl.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 brooklyn.entity.basic; + +public class VanillaWindowsProcessImpl extends SoftwareProcessImpl implements VanillaWindowsProcess { + @Override + public Class getDriverInterface() { + return VanillaWindowsProcessDriver.class; + } + + @Override + protected void connectSensors() { + super.connectSensors(); + connectServiceUpIsRunning(); + } + + @Override + protected void disconnectSensors() { + disconnectServiceUpIsRunning(); + super.disconnectSensors(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2b07bed4/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java new file mode 100644 index 0000000..c966685 --- /dev/null +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 brooklyn.entity.basic; + +import brooklyn.location.basic.WinRmMachineLocation; + +public class VanillaWindowsProcessWinRmDriver extends AbstractSoftwareProcessWinRmDriver implements VanillaWindowsProcessDriver { + + public VanillaWindowsProcessWinRmDriver(EntityLocal entity, WinRmMachineLocation location) { + super(entity, location); + } + + @Override + public void install() { + + } + + @Override + public void customize() { + + } + + @Override + public void launch() { + + } + + @Override + public boolean isRunning() { + return executeCommand(VanillaWindowsProcess.CHECK_RUNNING_COMMAND, VanillaWindowsProcess.CHECK_RUNNING_POWERSHELL_COMMAND); + } + + @Override + public void stop() { + + } + +}
