brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [54/62] [abbrv] incubator-brooklyn git commit: Moves SshEffectorTasks from software-base to core
Date Wed, 19 Aug 2015 21:21:28 GMT
Moves SshEffectorTasks from software-base to core

- Was previously in org.apache.brooklyn.sensor.ssh
- Now in org.apache.brooklyn.util.core.task.ssh, next to the other
  ssh-related task classes.


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

Branch: refs/heads/master
Commit: 44a5f3063b5dfb96d5c3fe846b9d8b512e19644e
Parents: 2203330
Author: Aled Sage <aled.sage@gmail.com>
Authored: Wed Aug 19 16:51:42 2015 +0100
Committer: Aled Sage <aled.sage@gmail.com>
Committed: Wed Aug 19 17:43:24 2015 +0100

----------------------------------------------------------------------
 .../util/core/task/ssh/SshEffectorTasks.java    | 329 ++++++++++++++++++
 .../core/task/ssh/SshEffectorTasksTest.java     | 264 +++++++++++++++
 .../brooklyn/demo/CumulusRDFApplication.java    |   2 +-
 .../postgresql/PostgreSqlNodeSaltImpl.java      |   2 +-
 .../entity/salt/SaltLifecycleEffectorTasks.java |   2 +-
 .../apache/brooklyn/entity/salt/SaltTasks.java  |   2 +-
 .../postgresql/PostgreSqlSaltLiveTest.java      |   2 +-
 .../brooklynnode/BrooklynNodeSshDriver.java     |   2 +-
 .../BrooklynNodeUpgradeEffectorBody.java        |   2 +-
 .../entity/chef/ChefLifecycleEffectorTasks.java |   2 +-
 .../brooklyn/entity/chef/ChefSoloTasks.java     |   2 +-
 .../apache/brooklyn/entity/chef/ChefTasks.java  |   2 +-
 .../java/JavaSoftwareProcessSshDriver.java      |   2 +-
 .../entity/machine/MachineEntityImpl.java       |   2 +-
 .../base/AbstractSoftwareProcessSshDriver.java  |   2 +-
 .../MachineLifecycleEffectorTasks.java          |   2 +-
 .../brooklyn/sensor/ssh/SshCommandEffector.java |   3 +-
 .../brooklyn/sensor/ssh/SshEffectorTasks.java   | 334 -------------------
 .../ChefSoloDriverMySqlEntityLiveTest.java      |   2 +-
 .../mysql/ChefSoloDriverToyMySqlEntity.java     |   2 +-
 .../software/base/SoftwareEffectorTest.java     |   4 +-
 .../test/mysql/AbstractToyMySqlEntityTest.java  |   2 +-
 .../mysql/DynamicToyMySqlEntityBuilder.java     |   2 +-
 .../sensor/ssh/SshEffectorTasksTest.java        | 264 ---------------
 .../database/mariadb/MariaDbSshDriver.java      |   2 +-
 .../entity/database/mysql/MySqlSshDriver.java   |   2 +-
 .../PostgreSqlNodeChefImplFromScratch.java      |   2 +-
 .../postgresql/PostgreSqlSshDriver.java         |   2 +-
 .../database/postgresql/PostgreSqlChefTest.java |   2 +-
 .../nosql/cassandra/CassandraNodeSshDriver.java |   2 +-
 .../nosql/couchbase/CouchbaseNodeSshDriver.java |   2 +-
 .../entity/nosql/riak/RiakNodeSshDriver.java    |   2 +-
 .../entity/osgi/karaf/KarafContainerTest.java   |   2 +-
 .../qa/load/SimulatedMySqlNodeImpl.java         |   2 +-
 34 files changed, 625 insertions(+), 629 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
new file mode 100644
index 0000000..849cd25
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
@@ -0,0 +1,329 @@
+/*
+ * 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.util.core.task.ssh;
+
+import java.util.List;
+import java.util.Map;
+
+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.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.StringConfigMap;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigUtils;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.core.task.Tasks;
+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.ProcessTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.ssh.BashCommands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+/**
+ * Conveniences for generating {@link Task} instances to perform SSH activities.
+ * <p>
+ * If the {@link SshMachineLocation machine} is not specified directly it
+ * will be inferred from the {@link Entity} context of either the {@link Effector}
+ * or the current {@link Task}.
+ * 
+ * @see SshTasks
+ * @since 0.6.0
+ */
+@Beta
+public class SshEffectorTasks {
+
+    private static final Logger log = LoggerFactory.getLogger(SshEffectorTasks.class);
+    
+    public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
+        "Whether to ignore any ssh flags (behaviour constraints) set on the entity or location " +
+        "where this is running, using only flags explicitly specified", false);
+    
+    /**
+     * Like {@link EffectorBody} but providing conveniences when in an entity with a single machine location.
+     */
+    public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
+        
+        /** convenience for accessing the machine */
+        public SshMachineLocation machine() {
+            return EffectorTasks.getSshMachine(entity());
+        }
+
+        /** convenience for generating an {@link PlainSshExecTaskFactory} which can be further customised if desired, and then (it must be explicitly) queued */
+        public ProcessTaskFactory<Integer> ssh(String ...commands) {
+            return new SshEffectorTaskFactory<Integer>(commands).machine(machine());
+        }
+    }
+
+    /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link EffectorTaskFactory} signature so can be used directly as an impl for an effector,
+     * also injects the machine automatically; can also be used outwith effector contexts, and machine is still injected if it is
+     * run from inside a task at an entity with a single SshMachineLocation */
+    public static class SshEffectorTaskFactory<RET> extends AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements EffectorTaskFactory<RET> {
+
+        public SshEffectorTaskFactory(String ...commands) {
+            super(commands);
+        }
+        public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
+            super(machine, commands);
+        }
+        @Override
+        public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> effector, ConfigBag parameters) {
+            markDirty();
+            if (summary==null) summary(effector.getName()+" (ssh)");
+            machine(EffectorTasks.getSshMachine(entity));
+            return newTask();
+        }
+        @Override
+        public synchronized ProcessTaskWrapper<RET> newTask() {
+            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (machine==null) {
+                if (log.isDebugEnabled())
+                    log.debug("Using an ssh task not in an effector without any machine; will attempt to infer the machine: "+this);
+                if (entity!=null)
+                    machine(EffectorTasks.getSshMachine(entity));
+            }
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+        
+        @Override
+        public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType type) {
+            return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
+        }
+
+        @Override
+        public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
+            return (SshEffectorTaskFactory<Boolean>) super.returningIsExitCodeZero();
+        }
+
+        public SshEffectorTaskFactory<String> requiringZeroAndReturningStdout() {
+            return (SshEffectorTaskFactory<String>) super.requiringZeroAndReturningStdout();
+        }
+        
+        public <RET2> SshEffectorTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
+            return (SshEffectorTaskFactory<RET2>) super.returning(resultTransformation);
+        }
+    }
+    
+    public static class SshPutEffectorTaskFactory extends SshPutTaskFactory implements EffectorTaskFactory<Void> {
+        public SshPutEffectorTaskFactory(String remoteFile) {
+            super(remoteFile);
+        }
+        public SshPutEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
+            super(machine, remoteFile);
+        }
+        @Override
+        public SshPutTaskWrapper newTask(Entity entity, Effector<Void> effector, ConfigBag parameters) {
+            machine(EffectorTasks.getSshMachine(entity));
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+        @Override
+        public SshPutTaskWrapper newTask() {
+            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (machine==null) {
+                if (log.isDebugEnabled())
+                    log.debug("Using an ssh put task not in an effector without any machine; will attempt to infer the machine: "+this);
+                if (entity!=null) {
+                    machine(EffectorTasks.getSshMachine(entity));
+                }
+
+            }
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+    }
+
+    public static class SshFetchEffectorTaskFactory extends SshFetchTaskFactory implements EffectorTaskFactory<String> {
+        public SshFetchEffectorTaskFactory(String remoteFile) {
+            super(remoteFile);
+        }
+        public SshFetchEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
+            super(machine, remoteFile);
+        }
+        @Override
+        public SshFetchTaskWrapper newTask(Entity entity, Effector<String> effector, ConfigBag parameters) {
+            machine(EffectorTasks.getSshMachine(entity));
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+        @Override
+        public SshFetchTaskWrapper newTask() {
+            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (machine==null) {
+                if (log.isDebugEnabled())
+                    log.debug("Using an ssh fetch task not in an effector without any machine; will attempt to infer the machine: "+this);
+                if (entity!=null)
+                    machine(EffectorTasks.getSshMachine(entity));
+            }
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+    }
+
+    public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
+        return new SshEffectorTaskFactory<Integer>(commands);
+    }
+
+    public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
+        return ssh(commands.toArray(new String[commands.size()]));
+    }
+
+    public static SshPutTaskFactory put(String remoteFile) {
+        return new SshPutEffectorTaskFactory(remoteFile);
+    }
+
+    public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
+        return new SshFetchEffectorTaskFactory(remoteFile);
+    }
+
+    /** task which returns 0 if pid is running */
+    public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
+        return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit code)").allowingNonZeroExitCode();
+    }
+    
+    /** task which fails if the given PID is not running */
+    public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
+        return codePidRunning(pid).summary("PID "+pid+" is-running check (required)").requiringExitCodeZero("Process with PID "+pid+" is required to be running");
+    }
+
+    /** as {@link #codePidRunning(Integer)} but returning boolean */
+    public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
+        return codePidRunning(pid).summary("PID "+pid+" is-running check (boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+            public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return Integer.valueOf(0).equals(input.getExitCode()); }
+        });
+    }
+
+
+    /** task which returns 0 if pid in the given file is running;
+     * method accepts wildcards so long as they match a single file on the remote end
+     * <p>
+     * returns 1 if no matching file, 
+     * 1 if matching file but no matching process,
+     * and 2 if 2+ matching files */
+    public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final String pidFile) {
+        return ssh(BashCommands.chain(
+                // this fails, but isn't an error
+                BashCommands.requireTest("-f "+pidFile, "The PID file "+pidFile+" does not exist."),
+                // this fails and logs an error picked up later
+                BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", "ERROR: there are multiple matching PID files"),
+                // this fails and logs an error picked up later
+                BashCommands.require("cat "+pidFile, "ERROR: the PID file "+pidFile+" cannot be read (permissions?)."),
+                // finally check the process
+                "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" is-running check (exit code)")
+                .allowingNonZeroExitCode()
+                .addCompletionListener(new Function<ProcessTaskWrapper<?>,Void>() {
+                    public Void apply(ProcessTaskWrapper<?> input) {
+                        if (input.getStderr().contains("ERROR:"))
+                            throw new IllegalStateException("Invalid or inaccessible PID filespec: "+pidFile);
+                        return null;
+                    }
+                });
+    }
+    
+    /** task which fails if the pid in the given file is not running (or if there is no such PID file);
+     * method accepts wildcards so long as they match a single file on the remote end (fails if 0 or 2+ matching files) */
+    public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String pidFile) {
+        return codePidFromFileRunning(pidFile)
+                .summary("PID file "+pidFile+" is-running check (required)")
+                .requiringExitCodeZero("Process with PID from file "+pidFile+" is required to be running");
+    }
+
+    /** as {@link #codePidFromFileRunning(String)} but returning boolean */
+    public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String pidFile) {
+        return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" is-running check (boolean)").
+                returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+                    public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return ((Integer)0).equals(input.getExitCode()); }
+                });
+    }
+
+    /** extracts the values for the main brooklyn.ssh.config.* config keys (i.e. those declared in ConfigKeys) 
+     * as declared on the entity, and inserts them in a map using the unprefixed state, for ssh.
+     * <p>
+     * currently this is computed for each call, which may be wasteful, but it is reliable in the face of config changes.
+     * we could cache the Map.  note that we do _not_ cache (or even own) the SshTool; 
+     * the SshTool is created or re-used by the SshMachineLocation making use of these properties */
+    @Beta
+    public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
+        ConfigBag allConfig = ConfigBag.newInstance();
+        
+        StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
+        allConfig.putAll(globalConfig.getAllConfig());
+        
+        if (optionalLocation!=null)
+            allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
+        
+        allConfig.putAll(((EntityInternal)entity).getAllConfig());
+        
+        Map<String, Object> result = Maps.newLinkedHashMap();
+        for (String keyS : allConfig.getAllConfig().keySet()) {
+            if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
+                ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
+                
+                Object val = allConfig.getStringKey(keyS);
+                
+                /*
+                 * NOV 2013 changing this to rely on config above being inserted in the right order,
+                 * so entity config will be preferred over location, and location over global.
+                 * If that is consistent then remove the lines below.
+                 * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
+                 */
+                
+//                // have to use raw config to test whether the config is set
+//                Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
+//                if (val!=null) {
+//                    val = entity.getConfig(key);
+//                } else {
+//                    val = globalConfig.getRawConfig(key);
+//                    if (val!=null) val = globalConfig.getConfig(key);
+//                }
+//                if (val!=null) {
+                    result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
+//                }
+            }
+        }
+        return result;
+    }
+
+    private static void applySshFlags(ConfigBag config, Entity entity, Location machine) {
+        if (entity!=null) {
+            if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
+                config.putIfAbsent(getSshFlags(entity, machine));
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
new file mode 100644
index 0000000..92f45d7
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.util.core.task.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.io.Files;
+
+public class SshEffectorTasksTest {
+
+    private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
+    
+    TestApplication app;
+    ManagementContext mgmt;
+    SshMachineLocation host;
+    File tempDir;
+    
+    boolean failureExpected;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() throws Exception {
+        app = TestApplication.Factory.newManagedInstanceForTests();
+        mgmt = app.getManagementContext();
+        
+        LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+        host = lhc.obtain();
+        app.start(Arrays.asList(host));
+        clearExpectedFailure();
+        tempDir = Files.createTempDir();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        mgmt = null;
+        FileUtils.deleteDirectory(tempDir);
+        checkExpectedFailure();
+    }
+
+    protected void checkExpectedFailure() {
+        if (failureExpected) {
+            clearExpectedFailure();
+            Assert.fail("Test should have thrown an exception but it did not.");
+        }
+    }
+    
+    protected void clearExpectedFailure() {
+        failureExpected = false;
+    }
+
+    protected void setExpectingFailure() {
+        failureExpected = true;
+    }
+    
+    public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
+        return Entities.submit(app, taskFactory);
+    }
+    
+    // ------------------- basic ssh
+    
+    @Test(groups="Integration")
+    public void testSshEchoHello() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
+        Assert.assertFalse(t.isDone());
+        Assert.assertEquals(t.get(), (Integer)0);
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        Assert.assertEquals(t.getStdout().trim(), "hello world");
+    }
+
+    @Test(groups="Integration")
+    public void testSshPut() throws IOException {
+        String fn = Urls.mergePaths(tempDir.getPath(), "f1");
+        SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
+        t.block();
+        Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
+        // and make sure this doesn't throw
+        Assert.assertTrue(t.isDone());
+        Assert.assertTrue(t.isSuccessful());
+        Assert.assertEquals(t.get(), null);
+        Assert.assertEquals(t.getExitCode(), (Integer)0);
+    }
+
+    @Test(groups="Integration")
+    public void testSshFetch() throws IOException {
+        String fn = Urls.mergePaths(tempDir.getPath(), "f2");
+        FileUtils.write(new File(fn), "hello fetched world");
+        
+        SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
+        t.block();
+        
+        Assert.assertTrue(t.isDone());
+        Assert.assertEquals(t.get(), "hello fetched world");
+    }
+
+    // ----------------- pid stuff
+    
+    @Test(groups="Integration")
+    public void testNonRunningPid() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
+        Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
+        Assert.assertNotEquals(t.getExitCode(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
+        Assert.assertFalse(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testNonRunningPidRequired() {
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+        }
+        checkExpectedFailure();
+    }
+
+    public static Integer getMyPid() {
+        try {
+            java.lang.management.RuntimeMXBean runtime = 
+                    java.lang.management.ManagementFactory.getRuntimeMXBean();
+            java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
+            jvm.setAccessible(true);
+//            sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+            Object mgmt = jvm.get(runtime);
+            java.lang.reflect.Method pid_method =  
+                    mgmt.getClass().getDeclaredMethod("getProcessId");
+            pid_method.setAccessible(true);
+
+            return (Integer) pid_method.invoke(mgmt);
+        } catch (Exception e) {
+            throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
+        }
+    }
+
+    @Test(groups="Integration")
+    public void testRunningPid() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
+        Assert.assertTrue(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testRunningPidFromFile() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
+        Assert.assertTrue(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailure() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( "99999".getBytes(), f );
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)1);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)1);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)2);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnSuccess() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+        
+        t.getTask().getUnchecked();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
+        
+        t.getTask().getUnchecked();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index 02d4f89..ef925c6 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -58,13 +58,13 @@ import org.apache.brooklyn.policy.ha.ServiceFailureDetector;
 import org.apache.brooklyn.policy.ha.ServiceReplacer;
 import org.apache.brooklyn.policy.ha.ServiceRestarter;
 import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.CommandLineUtil;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index 9fd0eee..70747b5 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -22,6 +22,7 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.salt.SaltConfig;
 import org.apache.brooklyn.entity.salt.SaltConfigs;
 import org.apache.brooklyn.entity.salt.SaltLifecycleEffectorTasks;
@@ -39,7 +40,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
 import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.sensor.core.DependentConfiguration;
 import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
index 09409dc..4fa3d96 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
@@ -24,9 +24,9 @@ import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
 import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
index 510f9a2..87096a6 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
@@ -32,10 +32,10 @@ import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
 
 import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
index a2a44dd..1a42cbb 100644
--- a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
+++ b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
@@ -24,6 +24,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNodeSaltImpl;
 import org.apache.brooklyn.entity.salt.SaltConfig;
@@ -39,7 +40,6 @@ import org.apache.brooklyn.entity.database.VogellaExampleAccess;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
 import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.time.Duration;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
index de6f550..f27a6dc 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
@@ -34,12 +34,12 @@ import org.apache.brooklyn.core.entity.drivers.downloads.DownloadSubstituters;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
 import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.file.ArchiveBuilder;
 import org.apache.brooklyn.util.core.file.ArchiveUtils;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.net.Networking;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
index 17ae472..0b1c089 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
@@ -40,10 +40,10 @@ import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeDriver;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwareParameters;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwareParameters.StopMode;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index 4b5ddc8..45c639c 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -30,7 +30,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.Jsonya;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.Jsonya.Navigator;
@@ -38,6 +37,7 @@ import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.TaskTags;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
index 64a27a4..c543779 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.chef;
 import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.ssh.BashCommands;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
index 0f359d5..a7b79a3 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
 import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.file.ArchiveTasks;
 import org.apache.brooklyn.util.core.file.ArchiveUtils.ArchiveType;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.ssh.BashCommands;
 import org.apache.brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
index 156db74..6e4b7c7 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
@@ -48,13 +48,13 @@ import com.google.common.collect.Maps;
 import com.google.gson.internal.Primitives;
 
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.ssh.SshTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
index 6ebca42..144894b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
@@ -31,8 +31,8 @@ import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
index 93516fe..2be96b6 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
@@ -49,11 +49,11 @@ import com.google.common.collect.Sets;
 
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
index 5af6294..c2e4cc8 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
@@ -76,11 +76,11 @@ import com.google.common.collect.Iterables;
 import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
index 671348b..f91be61 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
@@ -29,9 +29,10 @@ import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
 import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks.SshEffectorTaskFactory;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks.SshEffectorTaskFactory;
 import org.apache.brooklyn.util.text.Strings;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java
deleted file mode 100644
index f4ae082..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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.sensor.ssh;
-
-import java.util.List;
-import java.util.Map;
-
-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.mgmt.Task;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.config.ConfigUtils;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.location.internal.LocationInternal;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshTasks;
-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.ProcessTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.ssh.BashCommands;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-
-/**
- * Conveniences for generating {@link Task} instances to perform SSH activities.
- * <p>
- * If the {@link SshMachineLocation machine} is not specified directly it
- * will be inferred from the {@link Entity} context of either the {@link Effector}
- * or the current {@link Task}.
- * 
- * @see SshTasks
- * @since 0.6.0
- */
-@Beta
-public class SshEffectorTasks {
-
-    private static final Logger log = LoggerFactory.getLogger(SshEffectorTasks.class);
-    
-    public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
-        "Whether to ignore any ssh flags (behaviour constraints) set on the entity or location " +
-        "where this is running, using only flags explicitly specified", false);
-    
-    /** like {@link EffectorBody} but providing conveniences when in a {@link SoftwareProcess}
-     * (or other entity with a single machine location) */
-    public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
-        
-        /** convenience for accessing the machine */
-        public SshMachineLocation machine() {
-            return EffectorTasks.getSshMachine(entity());
-        }
-
-        /** convenience for generating an {@link PlainSshExecTaskFactory} which can be further customised if desired, and then (it must be explicitly) queued */
-        public ProcessTaskFactory<Integer> ssh(String ...commands) {
-            return new SshEffectorTaskFactory<Integer>(commands).machine(machine());
-        }
-    }
-
-    /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link EffectorTaskFactory} signature so can be used directly as an impl for an effector,
-     * also injects the machine automatically; can also be used outwith effector contexts, and machine is still injected if it is
-     * run from inside a task at an entity with a single SshMachineLocation */
-    public static class SshEffectorTaskFactory<RET> extends AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements EffectorTaskFactory<RET> {
-
-        public SshEffectorTaskFactory(String ...commands) {
-            super(commands);
-        }
-        public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
-            super(machine, commands);
-        }
-        @Override
-        public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> effector, ConfigBag parameters) {
-            markDirty();
-            if (summary==null) summary(effector.getName()+" (ssh)");
-            machine(EffectorTasks.getSshMachine(entity));
-            return newTask();
-        }
-        @Override
-        public synchronized ProcessTaskWrapper<RET> newTask() {
-            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (machine==null) {
-                if (log.isDebugEnabled())
-                    log.debug("Using an ssh task not in an effector without any machine; will attempt to infer the machine: "+this);
-                if (entity!=null)
-                    machine(EffectorTasks.getSshMachine(entity));
-            }
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-        
-        @Override
-        public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType type) {
-            return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
-        }
-
-        @Override
-        public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
-            return (SshEffectorTaskFactory<Boolean>) super.returningIsExitCodeZero();
-        }
-
-        public SshEffectorTaskFactory<String> requiringZeroAndReturningStdout() {
-            return (SshEffectorTaskFactory<String>) super.requiringZeroAndReturningStdout();
-        }
-        
-        public <RET2> SshEffectorTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
-            return (SshEffectorTaskFactory<RET2>) super.returning(resultTransformation);
-        }
-    }
-    
-    public static class SshPutEffectorTaskFactory extends SshPutTaskFactory implements EffectorTaskFactory<Void> {
-        public SshPutEffectorTaskFactory(String remoteFile) {
-            super(remoteFile);
-        }
-        public SshPutEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
-            super(machine, remoteFile);
-        }
-        @Override
-        public SshPutTaskWrapper newTask(Entity entity, Effector<Void> effector, ConfigBag parameters) {
-            machine(EffectorTasks.getSshMachine(entity));
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-        @Override
-        public SshPutTaskWrapper newTask() {
-            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (machine==null) {
-                if (log.isDebugEnabled())
-                    log.debug("Using an ssh put task not in an effector without any machine; will attempt to infer the machine: "+this);
-                if (entity!=null) {
-                    machine(EffectorTasks.getSshMachine(entity));
-                }
-
-            }
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-    }
-
-    public static class SshFetchEffectorTaskFactory extends SshFetchTaskFactory implements EffectorTaskFactory<String> {
-        public SshFetchEffectorTaskFactory(String remoteFile) {
-            super(remoteFile);
-        }
-        public SshFetchEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
-            super(machine, remoteFile);
-        }
-        @Override
-        public SshFetchTaskWrapper newTask(Entity entity, Effector<String> effector, ConfigBag parameters) {
-            machine(EffectorTasks.getSshMachine(entity));
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-        @Override
-        public SshFetchTaskWrapper newTask() {
-            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (machine==null) {
-                if (log.isDebugEnabled())
-                    log.debug("Using an ssh fetch task not in an effector without any machine; will attempt to infer the machine: "+this);
-                if (entity!=null)
-                    machine(EffectorTasks.getSshMachine(entity));
-            }
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-    }
-
-    public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
-        return new SshEffectorTaskFactory<Integer>(commands);
-    }
-
-    public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
-        return ssh(commands.toArray(new String[commands.size()]));
-    }
-
-    public static SshPutTaskFactory put(String remoteFile) {
-        return new SshPutEffectorTaskFactory(remoteFile);
-    }
-
-    public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
-        return new SshFetchEffectorTaskFactory(remoteFile);
-    }
-
-    /** task which returns 0 if pid is running */
-    public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
-        return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit code)").allowingNonZeroExitCode();
-    }
-    
-    /** task which fails if the given PID is not running */
-    public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
-        return codePidRunning(pid).summary("PID "+pid+" is-running check (required)").requiringExitCodeZero("Process with PID "+pid+" is required to be running");
-    }
-
-    /** as {@link #codePidRunning(Integer)} but returning boolean */
-    public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
-        return codePidRunning(pid).summary("PID "+pid+" is-running check (boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
-            public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return Integer.valueOf(0).equals(input.getExitCode()); }
-        });
-    }
-
-
-    /** task which returns 0 if pid in the given file is running;
-     * method accepts wildcards so long as they match a single file on the remote end
-     * <p>
-     * returns 1 if no matching file, 
-     * 1 if matching file but no matching process,
-     * and 2 if 2+ matching files */
-    public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final String pidFile) {
-        return ssh(BashCommands.chain(
-                // this fails, but isn't an error
-                BashCommands.requireTest("-f "+pidFile, "The PID file "+pidFile+" does not exist."),
-                // this fails and logs an error picked up later
-                BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", "ERROR: there are multiple matching PID files"),
-                // this fails and logs an error picked up later
-                BashCommands.require("cat "+pidFile, "ERROR: the PID file "+pidFile+" cannot be read (permissions?)."),
-                // finally check the process
-                "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" is-running check (exit code)")
-                .allowingNonZeroExitCode()
-                .addCompletionListener(new Function<ProcessTaskWrapper<?>,Void>() {
-                    public Void apply(ProcessTaskWrapper<?> input) {
-                        if (input.getStderr().contains("ERROR:"))
-                            throw new IllegalStateException("Invalid or inaccessible PID filespec: "+pidFile);
-                        return null;
-                    }
-                });
-    }
-    
-    /** task which fails if the pid in the given file is not running (or if there is no such PID file);
-     * method accepts wildcards so long as they match a single file on the remote end (fails if 0 or 2+ matching files) */
-    public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String pidFile) {
-        return codePidFromFileRunning(pidFile)
-                .summary("PID file "+pidFile+" is-running check (required)")
-                .requiringExitCodeZero("Process with PID from file "+pidFile+" is required to be running");
-    }
-
-    /** as {@link #codePidFromFileRunning(String)} but returning boolean */
-    public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String pidFile) {
-        return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" is-running check (boolean)").
-                returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
-                    public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return ((Integer)0).equals(input.getExitCode()); }
-                });
-    }
-
-    /** extracts the values for the main brooklyn.ssh.config.* config keys (i.e. those declared in ConfigKeys) 
-     * as declared on the entity, and inserts them in a map using the unprefixed state, for ssh.
-     * <p>
-     * currently this is computed for each call, which may be wasteful, but it is reliable in the face of config changes.
-     * we could cache the Map.  note that we do _not_ cache (or even own) the SshTool; 
-     * the SshTool is created or re-used by the SshMachineLocation making use of these properties */
-    @Beta
-    public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
-        ConfigBag allConfig = ConfigBag.newInstance();
-        
-        StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
-        allConfig.putAll(globalConfig.getAllConfig());
-        
-        if (optionalLocation!=null)
-            allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
-        
-        allConfig.putAll(((EntityInternal)entity).getAllConfig());
-        
-        Map<String, Object> result = Maps.newLinkedHashMap();
-        for (String keyS : allConfig.getAllConfig().keySet()) {
-            if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
-                ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
-                
-                Object val = allConfig.getStringKey(keyS);
-                
-                /*
-                 * NOV 2013 changing this to rely on config above being inserted in the right order,
-                 * so entity config will be preferred over location, and location over global.
-                 * If that is consistent then remove the lines below.
-                 * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
-                 */
-                
-//                // have to use raw config to test whether the config is set
-//                Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
-//                if (val!=null) {
-//                    val = entity.getConfig(key);
-//                } else {
-//                    val = globalConfig.getRawConfig(key);
-//                    if (val!=null) val = globalConfig.getConfig(key);
-//                }
-//                if (val!=null) {
-                    result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
-//                }
-            }
-        }
-        return result;
-    }
-
-    private static void applySshFlags(ConfigBag config, Entity entity, Location machine) {
-        if (entity!=null) {
-            if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
-                config.putIfAbsent(getSshFlags(entity, machine));
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
index f3ab58c..0166d94 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
index c36dc21..468b95e 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.entity.chef.ChefSoloDriver;
 import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
 import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.time.Duration;
 
 @Deprecated /** @deprecated since 0.7.0 use see examples {Dynamic,Typed}ToyMySqlEntityChef */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
index 91f9af5..1057ef9 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks.SshEffectorBody;
 import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks.SshEffectorBody;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
index 76f3cb0..f2ab43c 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
@@ -25,10 +25,10 @@ import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
index 7410c8a..2e304e6 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
@@ -35,9 +35,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation.LocalhostMachine;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.ssh.SshTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java
deleted file mode 100644
index 9f823eb..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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.sensor.ssh;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
-import org.apache.brooklyn.util.net.Urls;
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-import com.google.common.io.Files;
-
-public class SshEffectorTasksTest {
-
-    private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
-    
-    TestApplication app;
-    ManagementContext mgmt;
-    SshMachineLocation host;
-    File tempDir;
-    
-    boolean failureExpected;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() throws Exception {
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        mgmt = app.getManagementContext();
-        
-        LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
-        host = lhc.obtain();
-        app.start(Arrays.asList(host));
-        clearExpectedFailure();
-        tempDir = Files.createTempDir();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-        mgmt = null;
-        FileUtils.deleteDirectory(tempDir);
-        checkExpectedFailure();
-    }
-
-    protected void checkExpectedFailure() {
-        if (failureExpected) {
-            clearExpectedFailure();
-            Assert.fail("Test should have thrown an exception but it did not.");
-        }
-    }
-    
-    protected void clearExpectedFailure() {
-        failureExpected = false;
-    }
-
-    protected void setExpectingFailure() {
-        failureExpected = true;
-    }
-    
-    public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
-        return Entities.submit(app, taskFactory);
-    }
-    
-    // ------------------- basic ssh
-    
-    @Test(groups="Integration")
-    public void testSshEchoHello() {
-        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
-        Assert.assertFalse(t.isDone());
-        Assert.assertEquals(t.get(), (Integer)0);
-        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
-        Assert.assertEquals(t.getStdout().trim(), "hello world");
-    }
-
-    @Test(groups="Integration")
-    public void testSshPut() throws IOException {
-        String fn = Urls.mergePaths(tempDir.getPath(), "f1");
-        SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
-        t.block();
-        Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
-        // and make sure this doesn't throw
-        Assert.assertTrue(t.isDone());
-        Assert.assertTrue(t.isSuccessful());
-        Assert.assertEquals(t.get(), null);
-        Assert.assertEquals(t.getExitCode(), (Integer)0);
-    }
-
-    @Test(groups="Integration")
-    public void testSshFetch() throws IOException {
-        String fn = Urls.mergePaths(tempDir.getPath(), "f2");
-        FileUtils.write(new File(fn), "hello fetched world");
-        
-        SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
-        t.block();
-        
-        Assert.assertTrue(t.isDone());
-        Assert.assertEquals(t.get(), "hello fetched world");
-    }
-
-    // ----------------- pid stuff
-    
-    @Test(groups="Integration")
-    public void testNonRunningPid() {
-        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
-        Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
-        Assert.assertNotEquals(t.getExitCode(), (Integer)0);
-        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
-        Assert.assertFalse(t2.getTask().getUnchecked());
-    }
-
-    @Test(groups="Integration")
-    public void testNonRunningPidRequired() {
-        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
-        }
-        checkExpectedFailure();
-    }
-
-    public static Integer getMyPid() {
-        try {
-            java.lang.management.RuntimeMXBean runtime = 
-                    java.lang.management.ManagementFactory.getRuntimeMXBean();
-            java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
-            jvm.setAccessible(true);
-//            sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
-            Object mgmt = jvm.get(runtime);
-            java.lang.reflect.Method pid_method =  
-                    mgmt.getClass().getDeclaredMethod("getProcessId");
-            pid_method.setAccessible(true);
-
-            return (Integer) pid_method.invoke(mgmt);
-        } catch (Exception e) {
-            throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
-        }
-    }
-
-    @Test(groups="Integration")
-    public void testRunningPid() {
-        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
-        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
-        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
-        Assert.assertTrue(t2.getTask().getUnchecked());
-    }
-
-    @Test(groups="Integration")
-    public void testRunningPidFromFile() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( (""+getMyPid()).getBytes(), f );
-        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
-        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
-        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
-        Assert.assertTrue(t2.getTask().getUnchecked());
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnFailure() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( "99999".getBytes(), f );
-        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-        
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
-            Assert.assertEquals(t.getExitCode(), (Integer)1);
-        }
-        checkExpectedFailure();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
-        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
-        
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
-            Assert.assertEquals(t.getExitCode(), (Integer)1);
-        }
-        checkExpectedFailure();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
-        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
-        
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
-            Assert.assertEquals(t.getExitCode(), (Integer)2);
-        }
-        checkExpectedFailure();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnSuccess() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( (""+getMyPid()).getBytes(), f );
-        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-        
-        t.getTask().getUnchecked();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( (""+getMyPid()).getBytes(), f );
-        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
-        
-        t.getTask().getUnchecked();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44a5f306/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
index af1c240..226ba20 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
@@ -39,9 +39,9 @@ import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.os.Os;



Mime
View raw message