Skip to content
This repository was archived by the owner on Nov 12, 2025. It is now read-only.

Commit 40b5a90

Browse files
author
Valentin Aitken
committed
WinRM Script tests
1 parent 4378f58 commit 40b5a90

File tree

8 files changed

+390
-39
lines changed

8 files changed

+390
-39
lines changed

core/src/main/java/org/apache/brooklyn/util/core/internal/winrm/NativeWindowsScriptRunner.java renamed to core/src/main/java/org/apache/brooklyn/util/core/internal/winrm/NaiveWindowsScriptRunner.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
*/
1919
package org.apache.brooklyn.util.core.internal.winrm;
2020

21+
import java.io.InputStream;
2122
import java.util.Map;
2223

23-
public interface NativeWindowsScriptRunner {
24+
public interface NaiveWindowsScriptRunner {
2425

2526
/** Runs a command and returns the result code */
2627
Integer executeNativeOrPsCommand(Map flags, String regularCommand, String powershellCommand, String summaryForLogging, Boolean allowNoOp);
28+
29+
int copyTo(InputStream source, String destination);
2730
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.brooklyn.util.core.internal.winrm;
20+
21+
import com.google.common.base.Joiner;
22+
import com.google.common.collect.ImmutableMap;
23+
import org.apache.brooklyn.config.ConfigKey;
24+
import org.apache.brooklyn.util.collections.MutableMap;
25+
import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
26+
import org.apache.brooklyn.util.os.Os;
27+
import org.apache.brooklyn.util.text.Identifiers;
28+
import org.apache.brooklyn.util.text.Strings;
29+
import org.apache.brooklyn.util.time.Time;
30+
31+
import java.io.ByteArrayInputStream;
32+
import java.util.List;
33+
import java.util.Map;
34+
35+
import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKeyWithDefault;
36+
import static org.apache.brooklyn.util.core.internal.ssh.ShellAbstractTool.getOptionalVal;
37+
38+
/**
39+
* Implemented like SshCliTool
40+
*/
41+
// TODO Use a general interface for SshTool and WinRmScriptTool with
42+
public class WinRmScriptTool {
43+
public static final ConfigKey<String> PROP_SCRIPT_DIR = newConfigKeyWithDefault(ShellTool.PROP_SCRIPT_DIR, "The directory where the script should be uploaded. It is an env variable.", "temp");
44+
public static final ConfigKey<String> PROP_SUMMARY = ShellTool.PROP_SUMMARY;
45+
46+
private static final String SCRIPT_TEMP_DIR_VARIABLE = "BROOKLYN_TEMP_SCRIPT_DIR";
47+
48+
private String scriptNameWithoutExtension;
49+
private String scriptDir;
50+
private String summary;
51+
private NaiveWindowsScriptRunner scriptRunner;
52+
53+
public WinRmScriptTool(Map<String, ?> props, NaiveWindowsScriptRunner scriptRunner) {
54+
this.scriptDir = getOptionalVal(props, PROP_SCRIPT_DIR);
55+
56+
String summary = getOptionalVal(props, PROP_SUMMARY);
57+
if (summary != null) {
58+
summary = Strings.makeValidFilename(summary);
59+
if (summary.length() > 30)
60+
summary = summary.substring(0, 30);
61+
}
62+
63+
this.summary = summary;
64+
this.scriptNameWithoutExtension = "brooklyn-" +
65+
Time.makeDateStampString() + "-" + Identifiers.makeRandomId(4) +
66+
(Strings.isBlank(summary) ? "" : "-" + summary);
67+
68+
this.scriptRunner = scriptRunner;
69+
}
70+
71+
public static String psStringExpressionToBatchVariable(String psString, String batchVariable) {
72+
return "for /f \"delims=\" %%i in ('powershell -noprofile \\'Write-Host \""+ psString +"\"\\') do @set "+batchVariable+ "=%i";
73+
}
74+
75+
private String psExtension(String filename) {
76+
return filename + ".ps1";
77+
}
78+
79+
private String batchExtension(String filename) {
80+
return filename + ".bat";
81+
}
82+
83+
public int execPsScript(List<String> psCommands) {
84+
return execPsScript(ImmutableMap.<String, Object>of(), psCommands);
85+
}
86+
87+
public int execPsScript(Map<String, Object> flags, List<String> commands) {
88+
byte[] scriptBytes = toScript(commands).getBytes();
89+
String scriptFilename = psExtension(scriptNameWithoutExtension);
90+
if (flags.containsKey("scriptFilename"))
91+
flags.put("scriptFilename", scriptFilename);
92+
String scriptPath = Os.mergePathsWin("$env:"+scriptDir, scriptFilename);
93+
scriptRunner.copyTo(new ByteArrayInputStream(scriptBytes), scriptPath);
94+
return scriptRunner.executeNativeOrPsCommand(MutableMap.of(), null, "& " + scriptPath, summary, false);
95+
}
96+
97+
public int execNativeScript(List<String> commands) {
98+
return execNativeScript(ImmutableMap.<String, Object>of(), commands);
99+
}
100+
101+
public int execNativeScript(Map<String, Object> flags, List<String> commands) {
102+
byte[] scriptBytes = toScript(commands).getBytes();
103+
String scriptFilename = batchExtension(scriptNameWithoutExtension);
104+
if (flags.containsKey("scriptFilename"))
105+
flags.put("scriptFilename", scriptFilename);
106+
scriptRunner.copyTo(new ByteArrayInputStream(scriptBytes), Os.mergePathsWin("$env:"+scriptDir, scriptFilename));
107+
String scriptPath = Os.mergePathsWin("%"+scriptDir+"%", scriptFilename);
108+
return scriptRunner.executeNativeOrPsCommand(MutableMap.of(), scriptPath, null, summary, false);
109+
}
110+
111+
private String toScript(List<String> commands) {
112+
return Joiner.on("\r\n").join(commands);
113+
}
114+
}

software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
import org.apache.brooklyn.core.sensor.Sensors;
2828
import org.apache.brooklyn.entity.software.base.lifecycle.WinRmExecuteHelper;
2929
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
30-
import org.apache.brooklyn.util.core.internal.winrm.NativeWindowsScriptRunner;
30+
import org.apache.brooklyn.util.core.ResourceUtils;
31+
import org.apache.brooklyn.util.core.internal.winrm.NaiveWindowsScriptRunner;
3132
import org.apache.brooklyn.util.core.task.Tasks;
3233
import org.apache.brooklyn.util.exceptions.Exceptions;
3334
import org.apache.brooklyn.util.exceptions.ReferenceWithError;
@@ -47,7 +48,7 @@
4748

4849
import static org.apache.brooklyn.util.JavaGroovyEquivalents.elvis;
4950

50-
public abstract class AbstractSoftwareProcessWinRmDriver extends AbstractSoftwareProcessDriver implements NativeWindowsScriptRunner {
51+
public abstract class AbstractSoftwareProcessWinRmDriver extends AbstractSoftwareProcessDriver implements NaiveWindowsScriptRunner {
5152
private static final Logger LOG = LoggerFactory.getLogger(AbstractSoftwareProcessWinRmDriver.class);
5253

5354
AttributeSensor<String> WINDOWS_USERNAME = Sensors.newStringSensor("windows.username",
@@ -153,36 +154,18 @@ public String getInstallDir() {
153154
}
154155

155156
@Override
156-
public int copyResource(Map<Object, Object> sshFlags, String source, String target, boolean createParentDir) {
157-
if (createParentDir) {
158-
createDirectory(getDirectory(target), "Creating resource directory");
159-
}
160-
161-
InputStream stream = null;
162-
try {
163-
Tasks.setBlockingDetails("retrieving resource "+source+" for copying across");
164-
stream = resource.getResourceFromUrl(source);
165-
Tasks.setBlockingDetails("copying resource "+source+" to server");
166-
return copyTo(stream, target);
167-
} catch (Exception e) {
168-
throw Exceptions.propagate(e);
169-
} finally {
170-
Tasks.setBlockingDetails(null);
171-
if (stream != null) Streams.closeQuietly(stream);
172-
}
157+
public int copyResource(Map<Object, Object> flags, String source, String target, boolean createParentDir) {
158+
return getLocation().copyResource(flags, source, target, createParentDir, resource);
173159
}
174160

175161
@Override
176-
public int copyResource(Map<Object, Object> sshFlags, InputStream source, String target, boolean createParentDir) {
177-
if (createParentDir) {
178-
createDirectory(getDirectory(target), "Creating resource directory");
179-
}
180-
return copyTo(source, target);
162+
public int copyResource(Map<Object, Object> flags, InputStream source, String target, boolean createParentDir) {
163+
return getLocation().copyResource(flags, source, target, createParentDir);
181164
}
182165

183166
@Override
184167
protected void createDirectory(String directoryName, String summaryForLogging) {
185-
getLocation().executePsCommand("New-Item -path \"" + directoryName + "\" -type directory -ErrorAction SilentlyContinue");
168+
getLocation().createDirectory(directoryName, summaryForLogging);
186169
}
187170

188171
@Override
@@ -234,10 +217,6 @@ public void rebootAndWait() {
234217
waitForWinRmStatus(true, entity.getConfig(VanillaWindowsProcess.REBOOT_COMPLETED_TIMEOUT)).getWithError();
235218
}
236219

237-
private String getDirectory(String fileName) {
238-
return fileName.substring(0, fileName.lastIndexOf("\\"));
239-
}
240-
241220
private ReferenceWithError<Boolean> waitForWinRmStatus(final boolean requiredStatus, Duration timeout) {
242221
// TODO: Reduce / remove duplication between this and JcloudsLocation.waitForWinRmAvailable
243222
Callable<Boolean> checker = new Callable<Boolean>() {

software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/WinRmExecuteHelper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import org.apache.brooklyn.api.mgmt.Task;
3333
import org.apache.brooklyn.api.mgmt.TaskQueueingContext;
3434
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
35-
import org.apache.brooklyn.util.core.internal.winrm.NativeWindowsScriptRunner;
35+
import org.apache.brooklyn.util.core.internal.winrm.NaiveWindowsScriptRunner;
3636
import org.apache.brooklyn.util.core.task.DynamicTasks;
3737
import org.apache.brooklyn.util.core.task.TaskBuilder;
3838
import org.apache.brooklyn.util.core.task.Tasks;
@@ -52,7 +52,7 @@ public class WinRmExecuteHelper {
5252

5353
private Task<Integer> task;
5454

55-
protected final NativeWindowsScriptRunner runner;
55+
protected final NaiveWindowsScriptRunner runner;
5656
public final String summary;
5757

5858
private String command;
@@ -63,7 +63,7 @@ public class WinRmExecuteHelper {
6363
protected Predicate<? super Integer> resultCodeCheck = Predicates.alwaysTrue();
6464
protected ByteArrayOutputStream stdout, stderr, stdin;
6565

66-
public WinRmExecuteHelper(NativeWindowsScriptRunner runner, String summary) {
66+
public WinRmExecuteHelper(NaiveWindowsScriptRunner runner, String summary) {
6767
this.runner = runner;
6868
this.summary = summary;
6969
}

0 commit comments

Comments
 (0)