예제 #1
0
  @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;
  }