You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by du...@apache.org on 2020/11/10 08:33:46 UTC
[brooklyn-server] 01/03: First draft taskfactory
This is an automated email from the ASF dual-hosted git repository.
duncangrant pushed a commit to branch winrmtaskfactory
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 9fc84763665e7f343be6bf9d854ef9d7716217a9
Author: Duncan Grant <du...@cloudsoft.io>
AuthorDate: Thu Nov 5 10:15:50 2020 +0000
First draft taskfactory
---
.../brooklyn/api/location/MachineLocation.java | 19 +++++
.../core/effector/ssh/SshEffectorTasks.java | 3 +-
.../brooklyn/location/ssh/SshMachineLocation.java | 17 +++-
.../ssh/internal/AbstractSshExecTaskFactory.java | 3 +-
.../util/core/task/system/ProcessTaskFactory.java | 3 +-
.../util/core/task/system/ProcessTaskStub.java | 5 +-
.../internal/AbstractProcessTaskFactory.java | 3 +-
.../system/internal/SystemProcessTaskFactory.java | 3 +-
.../brooklyn/core/location/SimulatedLocation.java | 48 ++++++++++-
pom.xml | 2 +-
.../location/winrm/PlainWinRMExecTaskFactory.java | 72 ++++++++++++++++
.../apache/brooklyn/location/winrm/WinRMTasks.java | 52 ++++++++++++
.../location/winrm/WinRmMachineLocation.java | 99 +++++++++++++++++++---
.../util/core/internal/winrm/WinRmTool.java | 2 +-
.../core/internal/winrm/winrm4j/Winrm4jTool.java | 14 ++-
15 files changed, 317 insertions(+), 28 deletions(-)
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java b/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java
index aa8ef9c..508c5d4 100644
--- a/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java
+++ b/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java
@@ -19,6 +19,8 @@
package org.apache.brooklyn.api.location;
import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
import org.apache.brooklyn.util.net.HasNetworkAddresses;
@@ -44,4 +46,21 @@ public interface MachineLocation extends AddressableLocation, HasNetworkAddresse
*/
MachineDetails getMachineDetails();
+ String getUser();
+
+ int execCommands(String summaryForLogging, List<String> commands);
+
+ int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands);
+
+ int execCommands(String summaryForLogging, List<String> commands, Map<String, ?> env);
+
+ int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env);
+
+ int execScript(String summaryForLogging, List<String> commands);
+
+ int execScript(Map<String, ?> props, String summaryForLogging, List<String> commands);
+
+ int execScript(String summaryForLogging, List<String> commands, Map<String, ?> env);
+
+ int execScript(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env);
}
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
index e285817..706ea3d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
@@ -27,6 +27,7 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.StringConfigMap;
@@ -105,7 +106,7 @@ public class SshEffectorTasks {
public SshEffectorTaskFactory(String ...commands) {
super(commands);
}
- public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
+ public SshEffectorTaskFactory(MachineLocation machine, String ...commands) {
super(machine, commands);
}
@Override
diff --git a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
index ada35d0..14df87d 100644
--- a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
@@ -514,6 +514,7 @@ public class SshMachineLocation extends AbstractMachineLocation implements Machi
return HostAndPort.fromParts(host, port);
}
+ @Override
public String getUser() {
if (!groovyTruth(user)) {
if (config().getLocalRaw(SshTool.PROP_USER).isPresent()) {
@@ -698,16 +699,20 @@ public class SshMachineLocation extends AbstractMachineLocation implements Machi
* and/or {@code commandPrepend} and {@code commandAppend} similar to
* (currently supported in SshjTool) {@code separator}.)
*/
+ @Override
public int execCommands(String summaryForLogging, List<String> commands) {
return execCommands(MutableMap.<String,Object>of(), summaryForLogging, commands, MutableMap.<String,Object>of());
}
- public int execCommands(Map<String,?> props, String summaryForLogging, List<String> commands) {
+ @Override
+ public int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands) {
return execCommands(props, summaryForLogging, commands, MutableMap.<String,Object>of());
}
- public int execCommands(String summaryForLogging, List<String> commands, Map<String,?> env) {
+ @Override
+ public int execCommands(String summaryForLogging, List<String> commands, Map<String, ?> env) {
return execCommands(MutableMap.<String,Object>of(), summaryForLogging, commands, env);
}
- public int execCommands(Map<String,?> props, String summaryForLogging, List<String> commands, Map<String,?> env) {
+ @Override
+ public int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env) {
return newExecWithLoggingHelpers().execCommands(augmentPropertiesWithSshConfigGivenToProps(props), summaryForLogging, commands, env);
}
@@ -718,15 +723,19 @@ public class SshMachineLocation extends AbstractMachineLocation implements Machi
* flags 'noStdoutLogging' and 'noStderrLogging' are set. To set a logging prefix, use
* the flag 'logPrefix'.
*/
+ @Override
public int execScript(String summaryForLogging, List<String> commands) {
return execScript(MutableMap.<String,Object>of(), summaryForLogging, commands, MutableMap.<String,Object>of());
}
+ @Override
public int execScript(Map<String,?> props, String summaryForLogging, List<String> commands) {
return execScript(props, summaryForLogging, commands, MutableMap.<String,Object>of());
}
+ @Override
public int execScript(String summaryForLogging, List<String> commands, Map<String,?> env) {
return execScript(MutableMap.<String,Object>of(), summaryForLogging, commands, env);
}
+ @Override
public int execScript(Map<String,?> props, String summaryForLogging, List<String> commands, Map<String,?> env) {
return newExecWithLoggingHelpers().execScript(augmentPropertiesWithSshConfigGivenToProps(props), summaryForLogging, commands, env);
}
@@ -869,7 +878,7 @@ public class SshMachineLocation extends AbstractMachineLocation implements Machi
PipedInputStream insO = new PipedInputStream(); OutputStream outO = new PipedOutputStream(insO);
PipedInputStream insE = new PipedInputStream(); OutputStream outE = new PipedOutputStream(insE);
StreamGobbler sgsO = new StreamGobbler(insO, null, LOG); sgsO.setLogPrefix("[curl @ "+address+":stdout] ").start();
- StreamGobbler sgsE = new StreamGobbler(insE, null, LOG); sgsE.setLogPrefix("[curl @ "+address+":stdout] ").start();
+ StreamGobbler sgsE = new StreamGobbler(insE, null, LOG); sgsE.setLogPrefix("[curl @ "+address+":stderr] ").start();
Map<String, ?> sshProps = MutableMap.<String, Object>builder().putAll(props).put("out", outO).put("err", outE).build();
int result = execScript(sshProps, "copying remote resource "+url+" to server", ImmutableList.of(
BashCommands.INSTALL_CURL, // TODO should hold the 'installing' mutex
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
index 04272e8..354a2bb 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/internal/AbstractSshExecTaskFactory.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.util.core.task.ssh.internal;
import com.google.common.base.Preconditions;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
@@ -35,7 +36,7 @@ public abstract class AbstractSshExecTaskFactory<T extends AbstractProcessTaskFa
}
/** convenience constructor to supply machine immediately */
- public AbstractSshExecTaskFactory(SshMachineLocation machine, String ...commands) {
+ public AbstractSshExecTaskFactory(MachineLocation machine, String ...commands) {
this(commands);
machine(machine);
}
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
index 8042cc2..b0878c3 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskFactory.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.util.core.task.system;
import java.util.Map;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.mgmt.TaskFactory;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -30,7 +31,7 @@ import com.google.common.annotations.Beta;
import com.google.common.base.Function;
public interface ProcessTaskFactory<T> extends TaskFactory<ProcessTaskWrapper<T>> {
- public ProcessTaskFactory<T> machine(SshMachineLocation machine);
+ public ProcessTaskFactory<T> machine(MachineLocation machine);
public ProcessTaskFactory<T> add(String ...commandsToAdd);
public ProcessTaskFactory<T> add(Iterable<String> commandsToAdd);
public ProcessTaskFactory<T> requiringExitCodeZero();
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
index 5514ccf..549ba91 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/ProcessTaskStub.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
@@ -35,7 +36,7 @@ public class ProcessTaskStub {
protected final List<String> commands = new ArrayList<String>();
/** null for localhost */
- protected SshMachineLocation machine;
+ protected MachineLocation machine;
// config data
protected String summary;
@@ -75,7 +76,7 @@ public class ProcessTaskStub {
}
/** null for localhost */
- public SshMachineLocation getMachine() {
+ public MachineLocation getMachine() {
return machine;
}
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
index 6f9f0e0..e0a225a 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/AbstractProcessTaskFactory.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.util.core.task.system.internal;
import java.util.Arrays;
import java.util.Map;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.config.ConfigKey;
@@ -68,7 +69,7 @@ public abstract class AbstractProcessTaskFactory<T extends AbstractProcessTaskFa
}
@Override
- public T machine(SshMachineLocation machine) {
+ public T machine(MachineLocation machine) {
markDirty();
this.machine = machine;
return self();
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
index 20e6180..afe5d33 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/SystemProcessTaskFactory.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.util.core.task.system.internal;
import java.io.File;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.core.config.Sanitizer;
@@ -57,7 +58,7 @@ public class SystemProcessTaskFactory<T extends SystemProcessTaskFactory<T,RET>,
}
@Override
- public T machine(SshMachineLocation machine) {
+ public T machine(MachineLocation machine) {
log.warn("Not permitted to set machines on "+this+" (ignoring - "+machine+")");
if (log.isDebugEnabled())
log.debug("Source of attempt to set machines on "+this+" ("+machine+")",
diff --git a/core/src/test/java/org/apache/brooklyn/core/location/SimulatedLocation.java b/core/src/test/java/org/apache/brooklyn/core/location/SimulatedLocation.java
index c5c2c85..41be3f5 100644
--- a/core/src/test/java/org/apache/brooklyn/core/location/SimulatedLocation.java
+++ b/core/src/test/java/org/apache/brooklyn/core/location/SimulatedLocation.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.core.location;
import java.net.InetAddress;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -162,7 +163,52 @@ public class SimulatedLocation extends AbstractLocation implements MachineProvis
OsDetails osDetails = BasicOsDetails.Factory.ANONYMOUS_LINUX;
return new BasicMachineDetails(hardwareDetails, osDetails);
}
-
+
+ @Override
+ public String getUser() {
+ return null;
+ }
+
+ @Override
+ public int execCommands(String summaryForLogging, List<String> commands) {
+ return 0;
+ }
+
+ @Override
+ public int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands) {
+ return 0;
+ }
+
+ @Override
+ public int execCommands(String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ return 0;
+ }
+
+ @Override
+ public int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ return 0;
+ }
+
+ @Override
+ public int execScript(String summaryForLogging, List<String> commands) {
+ return 0;
+ }
+
+ @Override
+ public int execScript(Map<String, ?> props, String summaryForLogging, List<String> commands) {
+ return 0;
+ }
+
+ @Override
+ public int execScript(String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ return 0;
+ }
+
+ @Override
+ public int execScript(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ return 0;
+ }
+
private RuntimeException newException(String msg) {
try {
Exception result = getConfig(EXCEPTION_CLAZZ).getConstructor(String.class).newInstance(msg);
diff --git a/pom.xml b/pom.xml
index 0e96278..1c56a1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,7 +164,7 @@
<jax-rs-api.version>2.1.1</jax-rs-api.version> <!-- differs from jclouds 2.1.2, which depends on v2.0.1 -->
<maxmind.version>2.8.0-rc1</maxmind.version>
<maxmind-db.version>1.2.1</maxmind-db.version>
- <winrm4j.version>0.9.0</winrm4j.version> <!-- FIXME NO CHECK IN -->
+ <winrm4j.version>0.9.0-SNAPSHOT</winrm4j.version> <!-- FIXME NO CHECK IN -->
<felix-osgi-compendium.version>1.4.0</felix-osgi-compendium.version>
<kubernetes-client.version>4.9.0</kubernetes-client.version>
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/PlainWinRMExecTaskFactory.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/PlainWinRMExecTaskFactory.java
new file mode 100644
index 0000000..0fa344e
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/PlainWinRMExecTaskFactory.java
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.brooklyn.location.winrm;
+
+import com.google.common.base.Function;
+import org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+
+import java.util.List;
+
+public class PlainWinRMExecTaskFactory<RET> extends AbstractSshExecTaskFactory<PlainSshExecTaskFactory<RET>,RET> {
+
+ /** constructor where machine will be added later */
+ public PlainWinRMExecTaskFactory(String ...commands) {
+ super(commands);
+ }
+
+ /** convenience constructor to supply machine immediately */
+ public PlainWinRMExecTaskFactory(WinRmMachineLocation machine, String ...commands) {
+ this(commands);
+ machine(machine);
+ }
+
+ /** Constructor where machine will be added later */
+ public PlainWinRMExecTaskFactory(List<String> commands) {
+ this(commands.toArray(new String[commands.size()]));
+ }
+
+ /** Convenience constructor to supply machine immediately */
+ public PlainWinRMExecTaskFactory(WinRmMachineLocation machine, List<String> commands) {
+ this(machine, commands.toArray(new String[commands.size()]));
+ }
+
+ @Override
+ public <T2> PlainWinRMExecTaskFactory<T2> returning(ScriptReturnType type) {
+ return (PlainWinRMExecTaskFactory<T2>) super.<T2>returning(type);
+ }
+
+ @Override
+ public <RET2> PlainWinRMExecTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
+ return (PlainWinRMExecTaskFactory<RET2>) super.returning(resultTransformation);
+ }
+
+ @Override
+ public PlainWinRMExecTaskFactory<Boolean> returningIsExitCodeZero() {
+ return (PlainWinRMExecTaskFactory<Boolean>) super.returningIsExitCodeZero();
+ }
+
+ @Override
+ public PlainWinRMExecTaskFactory<String> requiringZeroAndReturningStdout() {
+ return (PlainWinRMExecTaskFactory<String>) super.requiringZeroAndReturningStdout();
+ }
+}
+
+
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRMTasks.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRMTasks.java
new file mode 100644
index 0000000..fb89ad5
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRMTasks.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.brooklyn.location.winrm;
+
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.location.winrm.PlainWinRMExecTaskFactory;
+import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
+import org.apache.brooklyn.util.net.Urls;
+
+import java.util.Map;
+
+public class WinRMTasks {
+ public static ProcessTaskFactory<Integer> newWinrmExecTaskFactory(org.apache.brooklyn.location.winrm.WinRmMachineLocation winRmMachineLocation, String ...commands) {
+ return new PlainWinRMExecTaskFactory<>(winRmMachineLocation, commands);
+ }
+
+ public static TaskFactory<?> installFromUrl(final ResourceUtils utils, final Map<String, ?> props, final WinRmMachineLocation location, final String url, final String destPath) {
+ return new TaskFactory<TaskAdaptable<?>>() {
+ @Override
+ public TaskAdaptable<?> newTask() {
+ return Tasks.<Void>builder().displayName("installing "+ Urls.getBasename(url)).description("installing "+url+" to "+destPath).body(new Runnable() {
+ @Override
+ public void run() {
+ int result = location.installTo(utils, props, url, destPath);
+ if (result!=0)
+ throw new IllegalStateException("Failed to install '"+url+"' to '"+destPath+"' at "+location+": exit code "+result);
+ }
+ }).build();
+ }
+ };
+ }
+}
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
index 0fd93b7..88d29a0 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -21,10 +21,7 @@ package org.apache.brooklyn.location.winrm;
import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKeyWithPrefix;
import static org.apache.brooklyn.core.config.ConfigKeys.newStringConfigKey;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
+import java.io.*;
import java.net.InetAddress;
import java.util.List;
import java.util.Map;
@@ -32,6 +29,7 @@ import java.util.Set;
import javax.annotation.Nullable;
+import com.google.common.base.*;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.MachineDetails;
import org.apache.brooklyn.api.location.MachineLocation;
@@ -41,24 +39,25 @@ import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.ConfigUtils;
import org.apache.brooklyn.core.config.Sanitizer;
-import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.location.AbstractMachineLocation;
import org.apache.brooklyn.core.location.access.PortForwardManager;
import org.apache.brooklyn.core.location.access.PortForwardManagerLocationResolver;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.location.ssh.CanResolveOnBoxDir;
+import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ClassLoaderUtils;
+import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.core.internal.winrm.WinRmTool;
import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
import org.apache.brooklyn.util.core.internal.winrm.winrm4j.Winrm4jTool;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.ssh.BashCommands;
+import org.apache.brooklyn.util.stream.StreamGobbler;
import org.apache.brooklyn.util.stream.Streams;
import org.apache.brooklyn.util.text.Strings;
import org.apache.commons.codec.binary.Base64;
@@ -66,10 +65,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -204,11 +199,54 @@ public class WinRmMachineLocation extends AbstractMachineLocation implements Mac
return UNKNOWN_MACHINE_DETAILS;
}
+ @Override
public String getUser() {
return config().get(USER);
}
@Override
+ public int execCommands(String summaryForLogging, List<String> commands) {
+ return executeCommand(commands).getStatusCode();
+ }
+
+ @Override
+ public int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands) {
+ return executeCommand(props, commands).getStatusCode();
+ }
+
+ @Override
+ public int execCommands(String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ return executeCommand(ImmutableMap.of(Winrm4jTool.ENVIRONMENT, env),commands).getStatusCode();
+ }
+
+ @Override
+ public int execCommands(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ ImmutableMap<Object, Object> properties = ImmutableMap.builder().putAll(props).put(Winrm4jTool.ENVIRONMENT, env).build();
+ return executeCommand(properties, commands).getStatusCode();
+ }
+
+ @Override
+ public int execScript(String summaryForLogging, List<String> commands) {
+ return executePsScript(commands).getStatusCode();
+ }
+
+ @Override
+ public int execScript(Map<String, ?> props, String summaryForLogging, List<String> commands) {
+ return executePsScript(props, commands).getStatusCode();
+ }
+
+ @Override
+ public int execScript(String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ return executePsScript(ImmutableMap.of(Winrm4jTool.ENVIRONMENT,env), commands).getStatusCode();
+ }
+
+ @Override
+ public int execScript(Map<String, ?> props, String summaryForLogging, List<String> commands, Map<String, ?> env) {
+ ImmutableMap<Object, Object> properties = ImmutableMap.builder().putAll(props).put(Winrm4jTool.ENVIRONMENT, env).build();
+ return executePsScript(properties, commands).getStatusCode();
+ }
+
+ @Override
public InetAddress getAddress() {
return getConfig(ADDRESS);
}
@@ -507,4 +545,41 @@ public class WinRmMachineLocation extends AbstractMachineLocation implements Mac
return unresolvedPath.replaceAll("/", "\\");
}
+ public int installTo(ResourceUtils utils, Map<String, ?> props, String url, String destPath) {
+ LOG.debug("installing {} to {} on {}, attempting remote curl", new Object[] { url, destPath, this });
+
+ try(PipedInputStream insO = new PipedInputStream(); OutputStream outO = new PipedOutputStream(insO);
+ PipedInputStream insE = new PipedInputStream(); OutputStream outE = new PipedOutputStream(insE);
+ StreamGobbler sgsO = new StreamGobbler(insO, null, LOG);
+ StreamGobbler sgsE = new StreamGobbler(insE, null, LOG)
+ ){
+ sgsO.setLogPrefix("[curl @ "+getAddress()+":stdout] ").start();
+ sgsE.setLogPrefix("[curl @ "+getAddress()+":stderr] ").start();
+ Map<String, ?> winrmProps = MutableMap.<String, Object>builder().putAll(props).put("out", outO).put("err", outE).build();
+ int result = execScript(winrmProps,"",ImmutableList.of(
+ "$WebClient = New-Object System.Net.WebClient",
+ "$WebClient.DownloadFile(" + url + "," + destPath + ")"
+ ));
+
+ if (result != 0) {
+ LOG.debug("installing {} to {} on {}, curl failed, attempting local fetch and copy", new Object[] { url, destPath, this });
+ try {
+ Tasks.setBlockingDetails("retrieving resource "+url+" for copying across");
+ InputStream stream = utils.getResourceFromUrl(url);
+ Tasks.setBlockingDetails("copying resource "+url+" to server");
+ result = copyTo(props, stream, destPath);
+ } finally {
+ Tasks.setBlockingDetails(null);
+ }
+ }
+ if (result == 0) {
+ LOG.debug("installing {} complete; {} on {}", new Object[] { url, destPath, this });
+ } else {
+ LOG.warn("installing {} failed; {} on {}: {}", new Object[] { url, destPath, this, result });
+ }
+ return result;
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
}
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
index 1d9d2b9..b566224 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
@@ -105,6 +105,6 @@ public interface WinRmTool {
WinRmToolResponse executeCommand(List<String> commands);
WinRmToolResponse executePs(List<String> commands);
-
+
WinRmToolResponse copyToServer(InputStream source, String destination);
}
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
index b7ff665..332b008 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.util.core.internal.winrm.winrm4j;
import static com.google.common.base.Preconditions.checkNotNull;
-import java.io.InputStream;
+import java.io.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
import org.apache.brooklyn.util.core.internal.winrm.WinRmException;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.javalang.Threads;
@@ -116,7 +117,16 @@ public class Winrm4jTool implements org.apache.brooklyn.util.core.internal.winrm
public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executeCommand(final List<String> commands) {
return exec(new Function<io.cloudsoft.winrm4j.winrm.WinRmTool, io.cloudsoft.winrm4j.winrm.WinRmToolResponse>() {
@Override public WinRmToolResponse apply(io.cloudsoft.winrm4j.winrm.WinRmTool tool) {
- return tool.executeCommand(commands);
+ OutputStream outputStream = bag.get(ShellTool.PROP_OUT_STREAM);
+ OutputStream errorStream = bag.get(ShellTool.PROP_ERR_STREAM);
+ try(Writer out = outputStream != null ? new OutputStreamWriter(outputStream): new StringWriter();
+ Writer err = errorStream != null ? new OutputStreamWriter(errorStream): new StringWriter()) {
+ return tool.executeCommand(commands, out, err);
+ } catch (IOException e) {
+ // TODO Duncan
+ e.printStackTrace();
+ return null;
+ }
}
});
}