Adds latches for pre-install files and pre-install/install/customize reboots


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/2c162165
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/2c162165
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/2c162165

Branch: refs/heads/master
Commit: 2c16216558ed7c0745cf386b983623151f35de27
Parents: fbb4ce9
Author: Martin Harris <[email protected]>
Authored: Thu May 14 13:06:25 2015 +0100
Committer: Richard Downer <[email protected]>
Committed: Thu May 28 17:27:35 2015 +0100

----------------------------------------------------------------------
 .../entity/basic/BrooklynConfigKeys.java        |  1 +
 .../location/basic/WinRmMachineLocation.java    | 59 +++++++++++++++-----
 .../basic/AbstractSoftwareProcessDriver.java    | 38 ++++++++++---
 .../AbstractSoftwareProcessWinRmDriver.java     | 41 ++++++++++++++
 .../brooklyn/entity/basic/SoftwareProcess.java  | 25 +++++++++
 .../entity/basic/VanillaWindowsProcess.java     | 14 +++++
 .../basic/VanillaWindowsProcessWinRmDriver.java | 17 +++++-
 7 files changed, 171 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java 
b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
index 6038d0c..25972c6 100644
--- a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
+++ b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
@@ -145,6 +145,7 @@ public class BrooklynConfigKeys {
 
     public static final ConfigKey<Boolean> START_LATCH = 
newBooleanConfigKey("start.latch", "Latch for blocking start until ready");
     public static final ConfigKey<Boolean> SETUP_LATCH = 
newBooleanConfigKey("setup.latch", "Latch for blocking setup until ready");
+    public static final ConfigKey<Boolean> PRE_INSTALL_RESOURCES_LATCH = 
newBooleanConfigKey("resources.preInstall.latch", "Latch for blocking 
pre-install resources until ready");
     public static final ConfigKey<Boolean> INSTALL_RESOURCES_LATCH = 
newBooleanConfigKey("resources.install.latch", "Latch for blocking install 
resources until ready");
     public static final ConfigKey<Boolean> INSTALL_LATCH = 
newBooleanConfigKey("install.latch", "Latch for blocking install until ready");
     public static final ConfigKey<Boolean> RUNTIME_RESOURCES_LATCH = 
newBooleanConfigKey("resources.runtime.latch", "Latch for blocking runtime 
resources until ready");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/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 d535d34..1f651e1 100644
--- a/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
@@ -48,6 +48,7 @@ import io.cloudsoft.winrm4j.winrm.WinRmTool;
 import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
@@ -117,7 +118,7 @@ public class WinRmMachineLocation extends AbstractLocation 
implements MachineLoc
                 exceptions.add(e);
             }
         }
-        throw Exceptions.propagate("failed to execute powershell script", 
exceptions);
+        throw Exceptions.propagate("failed to execute shell script", 
exceptions);
     }
 
     public WinRmToolResponse executePsScript(String psScript) {
@@ -128,9 +129,7 @@ public class WinRmMachineLocation extends AbstractLocation 
implements MachineLoc
         Collection<Throwable> exceptions = Lists.newArrayList();
         for (int i = 0; i < 10; i++) {
             try {
-                WinRmTool winRmTool = WinRmTool.connect(getHostname(), 
getUsername(), getPassword());
-                WinRmToolResponse response = winRmTool.executePs(psScript);
-                return response;
+                return executePsScriptNoRetry(psScript);
             } catch (Exception e) {
                 LOG.warn("ignoring winrm exception and retrying after 5 
seconds:", e);
                 Time.sleep(Duration.FIVE_SECONDS);
@@ -140,6 +139,12 @@ public class WinRmMachineLocation extends AbstractLocation 
implements MachineLoc
         throw Exceptions.propagate("failed to execute powershell script", 
exceptions);
     }
 
+    public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostname(), getUsername(), 
getPassword());
+        WinRmToolResponse response = winRmTool.executePs(psScript);
+        return response;
+    }
+
     public int copyTo(File source, File destination) {
         try {
             return copyTo(new FileInputStream(source), destination);
@@ -184,16 +189,42 @@ public class WinRmMachineLocation extends 
AbstractLocation implements MachineLoc
 
     public static String getDefaultUserMetadataString() {
         // Using an encoded command obviates the need to escape
-        String unencodePowershell =
-                "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting 
-ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices 
-Authentication PacketPrivacy\r\n" +
-                "$RDP.SetAllowTSConnections(1,1)\r\n" +
-                "Set-ExecutionPolicy Unrestricted -Force\r\n" +
-                "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 
100\r\n" +
-                "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0\r\n" 
+
-                "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 
0\r\n" +
-                "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0\r\n" +
-                "New-ItemProperty 
\"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name 
\"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"";
-//                "New-ItemProperty 
\"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name 
\"LmCompatibilityLevel\" -Value 3 -PropertyType \"DWord\" \r\n";
+        String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
+                // Allow TS connections
+                "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting 
-ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices 
-Authentication PacketPrivacy",
+                "$RDP.SetAllowTSConnections(1,1)",
+                "Set-ExecutionPolicy Unrestricted -Force",
+                // Set unlimited values for remote execution limits
+                "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 100",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 0",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0",
+                "New-ItemProperty 
\"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name 
\"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"",
+                // The following allows scripts to re-authenticate with local 
credential - this is required
+                // as certain operations cannot be performed with remote 
credentials
+                "$allowed = @('WSMAN/*')",
+                "$key = 
'hklm:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CredentialsDelegation'",
+                "if (!(Test-Path $key)) {",
+                "    md $key",
+                "}",
+                "New-ItemProperty -Path $key -Name AllowFreshCredentials 
-Value 1 -PropertyType Dword -Force",
+                "New-ItemProperty -Path $key -Name 
AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force",
+                "$credKey = Join-Path $key 'AllowFreshCredentials'",
+                "if (!(Test-Path $credKey)) {",
+                "    md $credkey",
+                "}",
+                "$ntlmKey = Join-Path $key 
'AllowFreshCredentialsWhenNTLMOnly'",
+                "if (!(Test-Path $ntlmKey)) {",
+                "    md $ntlmKey",
+                "}",
+                "$i = 1",
+                "$allowed |% {",
+                "    # Script does not take into account existing entries in 
this key",
+                "    New-ItemProperty -Path $credKey -Name $i -Value $_ 
-PropertyType String -Force",
+                "    New-ItemProperty -Path $ntlmKey -Name $i -Value $_ 
-PropertyType String -Force",
+                "    $i++",
+                "}"
+        ));
 
         String encoded = new 
String(Base64.encodeBase64(unencodePowershell.getBytes(Charsets.UTF_16LE)));
         return "winrm quickconfig -q & " +

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/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 061cd12..a5a4cde 100644
--- 
a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
+++ 
b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
@@ -105,6 +105,11 @@ public abstract class AbstractSoftwareProcessDriver 
implements SoftwareProcessDr
             skipStart = entityStarted.or(false);
         }
         if (!skipStart) {
+            DynamicTasks.queue("copy-pre-install-resources", new Runnable() { 
public void run() {
+                
waitForConfigKey(BrooklynConfigKeys.PRE_INSTALL_RESOURCES_LATCH);
+                copyPreInstallResources();
+            }});
+
             DynamicTasks.queue("pre-install", new Runnable() { public void 
run() {
                 preInstall();
             }});
@@ -178,7 +183,7 @@ public abstract class AbstractSoftwareProcessDriver 
implements SoftwareProcessDr
     public abstract void stop();
 
     /**
-     * Implement this method in child classes to add some post-launch behavior
+     * Implement this method in child classes to add some pre-install behavior
      */
     public void preInstall() {}
 
@@ -260,6 +265,20 @@ public abstract class AbstractSoftwareProcessDriver 
implements SoftwareProcessDr
     }
 
     /**
+     * Files and templates to be copied to the server <em>before</em> 
pre-install. This allows the {@link #preInstall()}
+     * process to have access to all required resources.
+     * <p>
+     * Will be prefixed with the entity's {@link #getInstallDir() install 
directory} if relative.
+     *
+     * @see SoftwareProcess#PRE_INSTALL_FILES
+     * @see SoftwareProcess#PRE_INSTALL_TEMPLATES
+     * @see #copyRuntimeResources()
+     */
+    public void copyPreInstallResources() {
+        copyResources(entity.getConfig(SoftwareProcess.PRE_INSTALL_FILES), 
entity.getConfig(SoftwareProcess.PRE_INSTALL_TEMPLATES));
+    }
+
+    /**
      * 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>
@@ -270,7 +289,10 @@ public abstract class AbstractSoftwareProcessDriver 
implements SoftwareProcessDr
      * @see #copyRuntimeResources()
      */
     public void copyInstallResources() {
+        copyResources(entity.getConfig(SoftwareProcess.INSTALL_FILES), 
entity.getConfig(SoftwareProcess.INSTALL_TEMPLATES));
+    }
 
+    private void copyResources(Map<String, String> files, Map<String, String> 
templates) {
         // 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.
@@ -279,19 +301,17 @@ public abstract class AbstractSoftwareProcessDriver 
implements SoftwareProcessDr
         // 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);
+        if (files != null && files.size() > 0) {
+            for (String source : files.keySet()) {
+                String target = files.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);
+        if (templates != null && templates.size() > 0) {
+            for (String source : templates.keySet()) {
+                String target = templates.get(source);
                 String destination = Os.isAbsolutish(target) ? target : 
Os.mergePathsUnix(getInstallDir(), target);
                 copyTemplate(source, destination, true, MutableMap.<String, 
Object>of());
             }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/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 af6a80c..92f4fa6 100644
--- 
a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
+++ 
b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
@@ -22,11 +22,18 @@ import java.io.File;
 import java.io.InputStream;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.python.core.PyException;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.Sensors;
 import brooklyn.location.basic.WinRmMachineLocation;
+import brooklyn.util.exceptions.ReferenceWithError;
+import brooklyn.util.repeat.Repeater;
+import brooklyn.util.time.Duration;
 import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
 
 import com.google.api.client.util.Strings;
@@ -132,6 +139,10 @@ public abstract class AbstractSoftwareProcessWinRmDriver 
extends AbstractSoftwar
         return getLocation().executeScript(script).getStatusCode();
     }
 
+    public int executePowerShellNoRetry(List<String> psScript) {
+        return getLocation().executePsScriptNoRetry(psScript).getStatusCode();
+    }
+
     public int executePowerShell(List<String> psScript) {
         return getLocation().executePsScript(psScript).getStatusCode();
     }
@@ -144,8 +155,38 @@ public abstract class AbstractSoftwareProcessWinRmDriver 
extends AbstractSoftwar
         return getLocation().copyTo(source, destination);
     }
 
+    public void rebootAndWait() {
+        try {
+            executePowerShellNoRetry(ImmutableList.of("Restart-Computer 
-Force"));
+        } catch (PyException e) {
+            // Restarting the computer will cause the command to fail; ignore 
the exception and continue
+        }
+        waitForWinRmStatus(false, 
entity.getConfig(VanillaWindowsProcess.REBOOT_UNAVAILABLE_TIMEOUT));
+        waitForWinRmStatus(true, 
entity.getConfig(VanillaWindowsProcess.REBOOT_AVAILABLE_TIMEOUT)).getWithError();
+    }
+
     private String getDirectory(String fileName) {
         return fileName.substring(0, fileName.lastIndexOf("\\"));
     }
 
+    private ReferenceWithError<Boolean> waitForWinRmStatus(final boolean 
requiredStatus, Duration timeout) {
+        // TODO: Reduce / remove duplication between this and 
JcloudsLocation.waitForWinRmAvailable
+        Callable<Boolean> checker = new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                try {
+                    return (execute(ImmutableList.of("hostname")) == 0) == 
requiredStatus;
+                } catch (Exception e) {
+                    return !requiredStatus;
+                }
+            }
+        };
+
+        return new Repeater()
+                .every(1, TimeUnit.SECONDS)
+                .until(checker)
+                .limitTimeTo(timeout)
+                .runKeepingError();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java 
b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
index d91a719..fe6d052 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -114,6 +114,31 @@ public interface SoftwareProcess extends Entity, Startable 
{
     ConfigKey<String> SUGGESTED_RUN_DIR = BrooklynConfigKeys.SUGGESTED_RUN_DIR;
 
     /**
+     * Files to be copied to the server before pre-install.
+     * <p>
+     * Map of {@code classpath://foo/file.txt} (or other url) source to 
destination path,
+     * as {@code subdir/file} relative to installation directory or {@code 
/absolute/path/to/file}.
+     *
+     * @see #PRE_INSTALL_TEMPLATES
+     */
+    @Beta
+    @SuppressWarnings("serial")
+    @SetFromFlag("preInstallFiles")
+    ConfigKey<Map<String, String>> PRE_INSTALL_FILES = 
ConfigKeys.newConfigKey(new TypeToken<Map<String, String>>() { },
+            "files.preinstall", "Mapping of files, to be copied before 
install, to destination name relative to installDir");
+
+    /**
+     * Templates to be filled in and then copied to the server before install.
+     *
+     * @see #PRE_INSTALL_FILES
+     */
+    @Beta
+    @SuppressWarnings("serial")
+    @SetFromFlag("preInstallTemplates")
+    ConfigKey<Map<String, String>> PRE_INSTALL_TEMPLATES = 
ConfigKeys.newConfigKey(new TypeToken<Map<String, String>>() { },
+            "templates.preinstall", "Mapping of templates, to be filled in and 
copied before pre-install, to destination name relative to installDir");
+
+    /**
      * Files to be copied to the server before install.
      * <p>
      * Map of {@code classpath://foo/file.txt} (or other url) source to 
destination path,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/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
index 532821d..4740bf6 100644
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java
+++ 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcess.java
@@ -20,9 +20,18 @@ package brooklyn.entity.basic;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.util.time.Duration;
 
 @ImplementedBy(VanillaWindowsProcessImpl.class)
 public interface VanillaWindowsProcess extends AbstractVanillaProcess {
+    ConfigKey<String> PRE_INSTALL_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("pre.install.powershell.command",
+            "powershell command to run during the pre-install phase");
+    ConfigKey<Boolean> PRE_INSTALL_REBOOT_REQUIRED = 
ConfigKeys.newBooleanConfigKey("pre.install.reboot.required",
+            "indicates that a reboot should be performed after the pre-install 
command is run", false);
+    ConfigKey<Boolean> INSTALL_REBOOT_REQUIRED = 
ConfigKeys.newBooleanConfigKey("install.reboot.required",
+            "indicates that a reboot should be performed after the install 
command is run", false);
+    ConfigKey<Boolean> CUSTOMIZE_REBOOT_REQUIRED = 
ConfigKeys.newBooleanConfigKey("customize.reboot.required",
+            "indicates that a reboot should be performed after the customize 
command is run", false);
     ConfigKey<String> LAUNCH_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("launch.powershell.command",
             "command to run to launch the process");
     ConfigKey<String> CHECK_RUNNING_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("checkRunning.powershell.command",
@@ -37,4 +46,9 @@ public interface VanillaWindowsProcess extends 
AbstractVanillaProcess {
             "command to run during the install phase");
     ConfigKey<String> INSTALL_POWERSHELL_COMMAND = 
ConfigKeys.newStringConfigKey("install.powershell.command",
             "powershell command to run during the install phase");
+    ConfigKey<Duration> REBOOT_UNAVAILABLE_TIMEOUT = 
ConfigKeys.newDurationConfigKey("reboot.unavailable.timeout",
+            "duration to wait whilst waiting for a machine to become 
unavailable after a reboot", Duration.TWO_MINUTES);
+    // If automatic updates are enabled and there are updates waiting to be 
installed, thirty minutes may not be sufficient...
+    ConfigKey<Duration> REBOOT_AVAILABLE_TIMEOUT = 
ConfigKeys.newDurationConfigKey("reboot.unavailable.timeout",
+            "duration to wait whilst waiting for a machine to become 
unavailable after a reboot", Duration.minutes(30));
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2c162165/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
index 4e66180..db2f546 100644
--- 
a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
+++ 
b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
@@ -27,15 +27,30 @@ public class VanillaWindowsProcessWinRmDriver extends 
AbstractSoftwareProcessWin
     }
 
     @Override
+    public void preInstall() {
+        super.preInstall();
+        executeCommand(VanillaWindowsProcess.PRE_INSTALL_COMMAND, 
VanillaWindowsProcess.PRE_INSTALL_POWERSHELL_COMMAND, true);
+        if 
(entity.getConfig(VanillaWindowsProcess.PRE_INSTALL_REBOOT_REQUIRED)) {
+            rebootAndWait();
+        }
+    }
+
+    @Override
     public void install() {
         // TODO: Follow install path of VanillaSoftwareProcessSshDriver
         executeCommand(VanillaWindowsProcess.INSTALL_COMMAND, 
VanillaWindowsProcess.INSTALL_POWERSHELL_COMMAND, true);
+        if (entity.getConfig(VanillaWindowsProcess.INSTALL_REBOOT_REQUIRED)) {
+            rebootAndWait();
+        }
     }
 
     @Override
     public void customize() {
         // TODO: Follow customize path of VanillaSoftwareProcessSshDriver
         executeCommand(VanillaWindowsProcess.CUSTOMIZE_COMMAND, 
VanillaWindowsProcess.CUSTOMIZE_POWERSHELL_COMMAND, true);
+        if (entity.getConfig(VanillaWindowsProcess.CUSTOMIZE_REBOOT_REQUIRED)) 
{
+            rebootAndWait();
+        }
     }
 
     @Override
@@ -51,7 +66,7 @@ public class VanillaWindowsProcessWinRmDriver extends 
AbstractSoftwareProcessWin
 
     @Override
     public void stop() {
-        executeCommand(VanillaWindowsProcess.STOP_POWERSHELL_COMMAND, 
VanillaWindowsProcess.STOP_COMMAND, true);
+        executeCommand(VanillaWindowsProcess.STOP_COMMAND, 
VanillaWindowsProcess.STOP_POWERSHELL_COMMAND, true);
     }
 
 }

Reply via email to