Execute location obtain commands as tasks
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/48a26707 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/48a26707 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/48a26707 Branch: refs/heads/master Commit: 48a267079b4ab04ed68ce21f0b31941222c18488 Parents: bd165c1 Author: Svetoslav Neykov <[email protected]> Authored: Tue May 31 14:58:19 2016 +0300 Committer: Svetoslav Neykov <[email protected]> Committed: Fri Jun 3 17:19:40 2016 +0300 ---------------------------------------------------------------------- .../brooklyn/util/core/task/ssh/SshTasks.java | 18 +++++-- .../location/jclouds/JcloudsLocation.java | 50 ++++++++++++++++---- 2 files changed, 54 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/48a26707/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java index c9fd66b..1ecc461 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java @@ -18,6 +18,8 @@ */ package org.apache.brooklyn.util.core.task.ssh; +import java.util.Arrays; +import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -71,12 +73,20 @@ import com.google.common.collect.Maps; public class SshTasks { private static final Logger log = LoggerFactory.getLogger(SshTasks.class); - + public static ProcessTaskFactory<Integer> newSshExecTaskFactory(SshMachineLocation machine, String ...commands) { - return newSshExecTaskFactory(machine, true, commands); + return newSshExecTaskFactory(machine, Arrays.asList(commands)); } - + public static ProcessTaskFactory<Integer> newSshExecTaskFactory(SshMachineLocation machine, final boolean useMachineConfig, String ...commands) { + return newSshExecTaskFactory(machine, useMachineConfig, Arrays.asList(commands)); + } + + public static ProcessTaskFactory<Integer> newSshExecTaskFactory(SshMachineLocation machine, List<String> commands) { + return newSshExecTaskFactory(machine, true, commands); + } + + public static ProcessTaskFactory<Integer> newSshExecTaskFactory(SshMachineLocation machine, final boolean useMachineConfig, List<String> commands) { return new PlainSshExecTaskFactory<Integer>(machine, commands) { { if (useMachineConfig) @@ -167,7 +177,7 @@ public class SshTasks { BashCommands.dontRequireTtyForSudo(), // strange quotes are to ensure we don't match against echoed stdin BashCommands.sudo("echo \"sudo\"-is-working-"+id)) - .summary("setting up sudo") + .summary("patch /etc/sudoers to disable requiretty") .configure(SshTool.PROP_ALLOCATE_PTY, true) .allowingNonZeroExitCode() .returning(new Function<ProcessTaskWrapper<?>,Boolean>() { public Boolean apply(ProcessTaskWrapper<?> task) { http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/48a26707/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java index 8247043..8c1ae46 100644 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java @@ -58,6 +58,7 @@ import org.apache.brooklyn.api.location.NoMachinesAvailableException; import org.apache.brooklyn.api.location.PortRange; import org.apache.brooklyn.api.mgmt.AccessController; import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.mgmt.TaskAdaptable; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.config.ConfigKey.HasConfigKey; import org.apache.brooklyn.core.BrooklynVersion; @@ -99,8 +100,13 @@ 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.task.DynamicTasks; +import org.apache.brooklyn.util.core.task.DynamicTasks.TaskQueueingResult; import org.apache.brooklyn.util.core.task.TaskBuilder; +import org.apache.brooklyn.util.core.task.TaskInternal; import org.apache.brooklyn.util.core.task.Tasks; +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; import org.apache.brooklyn.util.core.text.TemplateProcessor; import org.apache.brooklyn.util.exceptions.CompoundRuntimeException; import org.apache.brooklyn.util.exceptions.Exceptions; @@ -882,17 +888,14 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im Boolean dontRequireTtyForSudo = setup.get(JcloudsLocationConfig.DONT_REQUIRE_TTY_FOR_SUDO); if (Boolean.TRUE.equals(dontRequireTtyForSudo) || - dontRequireTtyForSudo == null && setup.get(DONT_CREATE_USER)) { + (dontRequireTtyForSudo == null && setup.get(DONT_CREATE_USER))) { if (windows) { LOG.warn("Ignoring flag DONT_REQUIRE_TTY_FOR_SUDO on Windows location {}", machineLocation); } else { customisationForLogging.add("patch /etc/sudoers to disable requiretty"); - executeCommandThrowingOnError( - ImmutableMap.<String, Object>of(SshTool.PROP_ALLOCATE_PTY.getName(), true), - (SshMachineLocation)machineLocation, - "patch /etc/sudoers to disable requiretty", - ImmutableList.of(BashCommands.dontRequireTtyForSudo())); + queueLocationTask("patch /etc/sudoers to disable requiretty", + SshTasks.dontRequireTtyForSudo((SshMachineLocation)machineLocation, true).newTask().asTask()); } } @@ -1105,14 +1108,41 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } private void executeCommandThrowingOnError(Map<String, Object> flags, SshMachineLocation loc, String name, List<String> commands) { - int ret = loc.execCommands(flags, name, commands); - if (ret != 0) { - throw new IllegalStateException("Command '" + name + "' failed with exit code " + ret + " for location " + loc); + Task<Integer> task = SshTasks.newSshExecTaskFactory(loc, commands) + .summary(name) + .requiringExitCodeZero() + .configure(flags) + .newTask() + .asTask(); + queueLocationTask("waiting for '" + name + "' on machine " + loc, task); + } + + protected <T> T queueLocationTask(String msg, Task<T> task) { + TaskQueueingResult<T> queueResult = DynamicTasks.queueIfPossible(task); + final String origDetails = Tasks.setBlockingDetails(msg); + try { + if(queueResult.isQueuedOrSubmitted()){ + return task.getUnchecked(); + } else { + // TODO Should we add an `orExecuteInSameThread()` in `TaskQueueingResult`? + try { + return ((TaskInternal<T>)task).getJob().call(); + } catch (Exception e) { + throw Exceptions.propagate(e); + } + } + } finally { + Tasks.setBlockingDetails(origDetails); } } private void executeCommandWarningOnError(SshMachineLocation loc, String name, List<String> commands) { - int ret = loc.execCommands(name, commands); + Task<Integer> task = SshTasks.newSshExecTaskFactory(loc, commands) + .summary(name) + .allowingNonZeroExitCode() + .newTask() + .asTask(); + int ret = queueLocationTask("waiting for '" + name + "' on machine " + loc, task); if (ret != 0) { LOG.warn("Command '{}' failed with exit code {} for location {}", new Object[] {name, ret, this}); }
