@Override public String execCommandTimeout(String command, Duration timeout) { ProcessTaskWrapper<String> task = SshEffectorTasks.ssh(command) .environmentVariables( ((AbstractSoftwareProcessSshDriver) getDriver()).getShellEnvironment()) .configure(SshTool.PROP_ALLOCATE_PTY, true) // TODO configure globally .requiringZeroAndReturningStdout() .machine(getMachine()) .summary(command) .newTask(); try { String result = DynamicTasks.queueIfPossible(task) .executionContext(this) .orSubmitAsync() .asTask() .get(timeout); return result; } catch (TimeoutException te) { throw new IllegalStateException("Timed out running command: " + command); } catch (Exception e) { Integer exitCode = task.getExitCode(); LOG.warn( "Command failed, return code {}: {}", exitCode == null ? -1 : exitCode, task.getStderr()); throw Exceptions.propagate(e); } }
protected String execHostnameMinusI(SshMachineLocation machine) { if (log.isDebugEnabled()) log.debug("Retrieve `hostname -I` via ssh for {}", machine); ProcessTaskWrapper<Integer> cmd = exec(machine, false, "echo localip=`hostname -I`"); for (String line : cmd.getStdout().split("\n")) { if (line.contains("localip=") && !line.contains("`hostname -I`")) { return line.substring(line.indexOf("localip=") + "localip=".length()).trim(); } } log.info( "No local ip found for {} (got {}; {})", new Object[] {machine, cmd.getStdout(), cmd.getStderr()}); return null; }
public static ChefModes detectChefMode(Entity entity) { ChefModes mode = entity.getConfig(ChefConfig.CHEF_MODE); if (mode == ChefModes.AUTODETECT) { // TODO server via API ProcessTaskWrapper<Boolean> installCheck = DynamicTasks.queue(ChefServerTasks.isKnifeInstalled()); mode = installCheck.get() ? ChefModes.KNIFE : ChefModes.SOLO; log.debug( "Using Chef in " + mode + " mode due to autodetect exit code " + installCheck.getExitCode()); } Preconditions.checkNotNull( mode, "Non-null " + ChefConfig.CHEF_MODE + " required for " + entity); return mode; }
protected String execHostname(SshMachineLocation machine) { if (log.isDebugEnabled()) log.debug("Retrieve `hostname` via ssh for {}", machine); ProcessTaskWrapper<Integer> cmd = exec(machine, false, "echo hostname=`hostname`"); // ProcessTaskWrapper<Integer> cmd = DynamicTasks.queue(SshEffectorTasks.ssh(machine, // "echo hostname=`hostname`") // .summary("getHostname")) // .block(); for (String line : cmd.getStdout().split("\n")) { if (line.contains("hostname=") && !line.contains("`hostname`")) { return line.substring(line.indexOf("hostname=") + "hostname=".length()).trim(); } } log.info( "No hostname found for {} (got {}; {})", new Object[] {machine, cmd.getStdout(), cmd.getStderr()}); return null; }
/** * attempts to resolve hostnameTarget from origin * * @return null if it definitively can't be resolved, best-effort IP address if possible, or blank * if we could not run ssh or make sense of the output */ public static String getResolvedAddress( Entity entity, SshMachineLocation origin, String hostnameTarget) { ProcessTaskWrapper<Integer> task = SshTasks.newSshExecTaskFactory(origin, "ping -c 1 -t 1 " + hostnameTarget) .summary("checking resolution of " + hostnameTarget) .allowingNonZeroExitCode() .newTask(); DynamicTasks.queueIfPossible(task).orSubmitAndBlock(entity).asTask().blockUntilEnded(); if (task.asTask().isError()) { log.warn( "ping could not be run, at " + entity + " / " + origin + ": " + Tasks.getError(task.asTask())); return ""; } if (task.getExitCode() == null || task.getExitCode() != 0) { if (task.getExitCode() != null && task.getExitCode() < 10) { // small number means ping failed to resolve or ping the hostname log.debug( "not able to resolve " + hostnameTarget + " from " + origin + " for " + entity + " because exit code was " + task.getExitCode()); return null; } // large number means ping probably did not run log.warn( "ping not run as expected, at " + entity + " / " + origin + " (code " + task.getExitCode() + "):\n" + task.getStdout().trim() + " --- " + task.getStderr().trim()); return ""; } String out = task.getStdout(); try { String line1 = Strings.getFirstLine(out); String ip = Strings.getFragmentBetween(line1, "(", ")"); if (Strings.isNonBlank(ip)) return ip; } catch (Exception e) { Exceptions.propagateIfFatal(e); /* ignore non-parseable output */ } if (out.contains("127.0.0.1")) return "127.0.0.1"; return ""; }
/** * Resolves the on-box dir. * * <p>Initialize and pre-create the right onbox working dir, if an ssh machine location. Logs a * warning if not. */ @SuppressWarnings("deprecation") public static String resolveOnBoxDir(EntityInternal entity, MachineLocation machine) { String base = entity.getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR); if (base == null) base = machine.getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR); if (base != null && Boolean.TRUE.equals(entity.getConfig(ON_BOX_BASE_DIR_RESOLVED))) return base; if (base == null) base = entity.getManagementContext().getConfig().getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR); if (base == null) base = entity.getConfig(BrooklynConfigKeys.BROOKLYN_DATA_DIR); if (base == null) base = machine.getConfig(BrooklynConfigKeys.BROOKLYN_DATA_DIR); if (base == null) base = entity.getManagementContext().getConfig().getConfig(BrooklynConfigKeys.BROOKLYN_DATA_DIR); if (base == null) base = "~/brooklyn-managed-processes"; if (base.equals("~")) base = "."; if (base.startsWith("~/")) base = "." + base.substring(1); String resolvedBase = null; if (entity.getConfig(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION) || machine.getConfig(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION)) { if (log.isDebugEnabled()) log.debug("Skipping on-box base dir resolution for " + entity + " at " + machine); if (!Os.isAbsolutish(base)) base = "~/" + base; resolvedBase = Os.tidyPath(base); } else if (machine instanceof SshMachineLocation) { SshMachineLocation ms = (SshMachineLocation) machine; ProcessTaskWrapper<Integer> baseTask = SshEffectorTasks.ssh( BashCommands.alternatives( "mkdir -p \"${BASE_DIR}\"", BashCommands.chain( BashCommands.sudo("mkdir -p \"${BASE_DIR}\""), BashCommands.sudo("chown " + ms.getUser() + " \"${BASE_DIR}\""))), "cd ~", "cd ${BASE_DIR}", "echo BASE_DIR_RESULT':'`pwd`:BASE_DIR_RESULT") .environmentVariable("BASE_DIR", base) .requiringExitCodeZero() .summary("initializing on-box base dir " + base) .newTask(); DynamicTasks.queueIfPossible(baseTask).orSubmitAsync(entity); resolvedBase = Strings.getFragmentBetween( baseTask.block().getStdout(), "BASE_DIR_RESULT:", ":BASE_DIR_RESULT"); } if (resolvedBase == null) { if (!Os.isAbsolutish(base)) base = "~/" + base; resolvedBase = Os.tidyPath(base); log.warn( "Could not resolve on-box directory for " + entity + " at " + machine + "; using " + resolvedBase + ", though this may not be accurate at the target (and may fail shortly)"); } entity.config().set(BrooklynConfigKeys.ONBOX_BASE_DIR, resolvedBase); entity.config().set(ON_BOX_BASE_DIR_RESOLVED, true); return resolvedBase; }