@Override
  public String startPoolManagementProcess(String businessKey, Pool pool) {
    Map<String, Object> arguments = Maps.newHashMap();

    arguments.put(CoreProcessVariables.POOL, pool);
    arguments.put(CoreProcessVariables.PROVIDER, getId());
    arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
    arguments.put(
        CoreProcessVariables.BOOTSTRAP_TIMEOUT,
        convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));

    /* needed because the Activiti EL doesn't work as expected and properties can't be read from the pool. */
    arguments.put(
        ProcessVariables.SPOT_BID, pool.getProvider().getOption(ProviderOptions.SPOT_BID));

    /* Authenticate as kermit to make the process visible in the Explorer UI */
    processEngine
        .getIdentityService()
        .setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);

    ProcessInstance instance =
        processEngine
            .getRuntimeService()
            .startProcessInstanceByKey(MANAGEMENT_PROCESS_KEY, businessKey, arguments);

    return instance.getProcessInstanceId();
  }
  @Override
  public void execute(DelegateExecution execution) throws Exception {
    Pool pool = (Pool) execution.getVariable(CoreProcessVariables.POOL);
    checkNotNull(
        pool,
        "Please add the pool description as a process " + "variable with the name '%s'.",
        CoreProcessVariables.POOL);

    Machine machine = (Machine) execution.getVariable("machine");
    LOG.info(">> Connecting to machine {} to install packages", machine);

    SSHClient client = Ssh.newClient(machine, pool.getAdminAccess());
    try {
      String puppetScript =
          Mustache.toString(
              InstallPackages.class,
              "/com/axemblr/provisionr/core/puppet/packages.pp.mustache",
              ImmutableMap.of("packages", packagesAsListOfMaps(pool.getSoftware())));

      Ssh.createFile(client, puppetScript, 0600, "/tmp/packages.pp");
      Session session = client.startSession();
      try {
        session.allocateDefaultPTY();
        Session.Command command = session.exec("sudo puppet apply --verbose /tmp/packages.pp");

        Ssh.logCommandOutput(LOG, machine.getExternalId(), command);
        command.join();

        if (command.getExitStatus() != 0) {
          throw new RuntimeException(
              String.format(
                  "Failed to execute puppet. Exit code: %d. Exit message: %s",
                  command.getExitStatus(), command.getExitErrorMessage()));

        } else {
          LOG.info("<< Command completed successfully with exit code 0");
        }

      } finally {
        session.close();
      }
    } finally {
      client.close();
    }
  }
  @Override
  public String startPoolManagementProcess(String businessKey, Pool pool) {
    Map<String, Object> arguments = Maps.newHashMap();

    arguments.put(CoreProcessVariables.POOL, pool);
    arguments.put(CoreProcessVariables.PROVIDER, getId());
    arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
    arguments.put(
        CoreProcessVariables.BOOTSTRAP_TIMEOUT,
        convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));

    /* Authenticate as kermit to make the process visible in the Explorer UI */
    processEngine
        .getIdentityService()
        .setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);

    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance instance =
        runtimeService.startProcessInstanceByKey(PROCESS_KEY, businessKey, arguments);

    return instance.getProcessInstanceId();
  }