private ISoftwareManagementTask createThriftTask(
      ChunkContext chunkContext, String targetName, StatusUpdater statusUpdater) {
    ISoftwareManagementTask task;
    // get command work directory
    File workDir = CommandUtil.createWorkDir(getJobExecutionId(chunkContext));

    // update work directory in job context
    putIntoJobExecutionContext(
        chunkContext, JobConstants.CURRENT_COMMAND_WORK_DIR, workDir.getAbsolutePath());

    boolean needAllocIp = true;
    if (ManagementOperation.DESTROY.equals(managementOperation)
        || ManagementOperation.PRE_DESTROY.equals(managementOperation)) {
      needAllocIp = false;
    }
    String specFilePath = null;

    if (!(ManagementOperation.DESTROY.equals(managementOperation)
        || ManagementOperation.PRE_DESTROY.equals(managementOperation))) {
      // write cluster spec file
      File specFile = clusterManager.writeClusterSpecFile(targetName, workDir, needAllocIp);
      specFilePath = specFile.getAbsolutePath();
    }

    task =
        SoftwareManagementTaskFactory.createThriftTask(
            targetName, specFilePath, statusUpdater, managementOperation, lockClusterEntityMgr);
    return task;
  }
 @RequestMapping(
     value = "/cluster/{clusterName}",
     method = RequestMethod.GET,
     produces = "application/json")
 @ResponseBody
 public ClusterRead getCluster(@PathVariable("clusterName") final String clusterName) {
   return clusterMgr.getClusterByName(clusterName);
 }
 @RequestMapping(value = "/cluster/{clusterName}", method = RequestMethod.DELETE)
 @ResponseStatus(HttpStatus.ACCEPTED)
 public void deleteCluster(
     @PathVariable("clusterName") String clusterName,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception {
   // TODO: make sure cluster name is valid
   Long taskId = clusterMgr.deleteClusterByName(clusterName);
   redirectRequest(taskId, request, response);
 }
  // cluster API
  @RequestMapping(value = "/clusters", method = RequestMethod.POST, consumes = "application/json")
  @ResponseStatus(HttpStatus.ACCEPTED)
  public void createCluster(
      @RequestBody ClusterCreate createSpec,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    // TODO: make sure cluster name is valid
    Long taskId = clusterMgr.createCluster(createSpec);
    redirectRequest(taskId, request, response);
  }
 @RequestMapping(value = "/cluster/{clusterName}", method = RequestMethod.PUT)
 @ResponseStatus(HttpStatus.ACCEPTED)
 public void startStopResumeCluster(
     @PathVariable("clusterName") String clusterName,
     @RequestParam(value = "state", required = false) String state,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception {
   Long taskId;
   if (state.equals("stop")) {
     taskId = clusterMgr.stopCluster(clusterName);
     redirectRequest(taskId, request, response);
   } else if (state.equals("start")) {
     taskId = clusterMgr.startCluster(clusterName);
     redirectRequest(taskId, request, response);
   } else if (state.equals("resume")) {
     taskId = clusterMgr.resumeClusterCreation(clusterName);
     redirectRequest(taskId, request, response);
   } else {
     throw BddException.INVALID_PARAMETER("cluster state", state);
   }
 }
 @RequestMapping(
     value = "/cluster/{clusterName}/nodegroup/{groupName}",
     method = RequestMethod.PUT)
 @ResponseStatus(HttpStatus.ACCEPTED)
 public void resizeCluster(
     @PathVariable("clusterName") String clusterName,
     @PathVariable("groupName") String groupName,
     @RequestBody int instanceNum,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception {
   if (instanceNum <= 0) {
     throw BddException.INVALID_PARAMETER(
         "node group instance number", String.valueOf(instanceNum));
   }
   Long taskId = clusterMgr.resizeCluster(clusterName, groupName, instanceNum);
   redirectRequest(taskId, request, response);
 }
  @Override
  public RepeatStatus executeStep(
      ChunkContext chunkContext, JobExecutionStatusHolder jobExecutionStatusHolder)
      throws Exception {

    // This step is only for app manager like ClouderaMgr and Ambari
    String clusterName =
        getJobParameters(chunkContext).getString(JobConstants.CLUSTER_NAME_JOB_PARAM);

    SoftwareManager softwareMgr = softwareMgrs.getSoftwareManagerByClusterName(clusterName);

    String appMgrName = softwareMgr.getName();
    if (Constants.IRONFAN.equals(appMgrName)) {
      // we do not config any local repo for Ironfan
      return RepeatStatus.FINISHED;
    }

    ClusterCreate clusterConfig =
        clusterManager.getClusterConfigMgr().getClusterConfig(clusterName);
    String localRepoURL = clusterConfig.getLocalRepoURL();
    logger.info("Use the following URL as the local yum server:" + localRepoURL);

    if (!CommonUtil.isBlank(localRepoURL)) {
      // Setup local repo file on each node for ClouderaMgr/Ambari.
      logger.info(
          "ConfigLocalRepoStep: start to setup local repo on each node for ClouderaMgr/Ambari.");

      List<NodeEntity> nodes = getNodesToBeSetLocalRepo(chunkContext, clusterName);
      String appMgrRepoID =
          Configuration.getString(
              Constants.SERENGETI_NODE_YUM_CLOUDERA_MANAGER_REPO_ID,
              Constants.NODE_APPMANAGER_YUM_CLOUDERA_MANAGER_REPO_ID);
      if (appMgrName.equals(Constants.AMBARI_PLUGIN_TYPE)) {
        appMgrRepoID =
            Configuration.getString(
                Constants.SERENGETI_NODE_YUM_AMBARI_REPO_ID,
                Constants.NODE_APPMANAGER_YUM_AMBARI_REPO_ID);
      }

      setLocalRepoService.setLocalRepoForNodes(clusterName, nodes, appMgrRepoID, localRepoURL);
    }

    return RepeatStatus.FINISHED;
  }
 @RequestMapping(value = "/clusters", method = RequestMethod.GET, produces = "application/json")
 @ResponseBody
 public List<ClusterRead> getClusters() {
   return clusterMgr.getClusters();
 }
  @Override
  public RepeatStatus executeStep(
      ChunkContext chunkContext, JobExecutionStatusHolder jobExecutionStatusHolder)
      throws Exception {

    String targetName =
        getJobParameters(chunkContext).getString(JobConstants.TARGET_NAME_JOB_PARAM);
    String clusterName =
        getJobParameters(chunkContext).getString(JobConstants.CLUSTER_NAME_JOB_PARAM);
    if (targetName == null) {
      targetName = clusterName;
    }
    String jobName = chunkContext.getStepContext().getJobName();
    logger.info(
        "target : " + targetName + ", operation: " + managementOperation + ", jobname: " + jobName);

    serviceSyncup.syncUp(clusterName);
    logger.debug("Try to sync up service status for cluster " + clusterName);

    boolean vmPowerOn = false;
    String vmPowerOnStr = getJobParameters(chunkContext).getString(JobConstants.IS_VM_POWER_ON);
    if (vmPowerOnStr != null) {
      logger.info("vm original status is power on? " + vmPowerOnStr);
      vmPowerOn = Boolean.parseBoolean(vmPowerOnStr);
    }

    if (checkVMStatus && targetName.split("-").length == 3 && !vmPowerOn) {
      return RepeatStatus.FINISHED;
    }

    // Only check host time for cluster config, disk fix, scale up (management
    // operation configure), start (management operation start) and create
    // (resume only)
    SoftwareManager softwareMgr = null;
    try {
      softwareMgr = softwareMgrs.getSoftwareManagerByClusterName(clusterName);
    } catch (SoftwareManagerCollectorException e) {
      if (ManagementOperation.PRE_DESTROY.equals(managementOperation)
          || ManagementOperation.DESTROY.equals(managementOperation)) {
        return RepeatStatus.FINISHED;
      }
      throw e;
    }
    if (ManagementOperation.CONFIGURE.equals(managementOperation)
        || ManagementOperation.START.equals(managementOperation)
        || JobConstants.RESUME_CLUSTER_JOB_NAME.equals(jobName)) {
      logger.info("Start to check host time.");
      List<NodeEntity> nodes = lockClusterEntityMgr.getClusterEntityMgr().findAllNodes(clusterName);
      Set<String> hostnames = new HashSet<String>();
      for (NodeEntity node : nodes) {
        // for software operation, we can only handle VMs who are already VM_READY
        // Add this filter to tolerate some vm failures in cluster start
        boolean force = JobUtils.getJobParameterForceClusterOperation(chunkContext);
        if (force && (node.getStatus() != NodeStatus.VM_READY)) {
          continue;
        }
        hostnames.add(node.getHostName());
      }
      ClusterCreate clusterSpec = clusterManager.getClusterSpec(clusterName);
      SyncHostsUtils.SyncHosts(clusterSpec, hostnames, softwareMgr);
    }

    StatusUpdater statusUpdater =
        new DefaultStatusUpdater(jobExecutionStatusHolder, getJobExecutionId(chunkContext));

    ISoftwareManagementTask task = null;
    String appMgrName = softwareMgr.getName();
    validateUserExistense();
    if (!Constants.IRONFAN.equals(appMgrName)) {
      task = createExternalTask(chunkContext, targetName, clusterName, statusUpdater);
    } else {
      task = createThriftTask(chunkContext, targetName, statusUpdater);
    }

    if (task != null) {
      Map<String, Object> ret = task.call();

      if (!(Boolean) ret.get("succeed")) {
        String errorMessage = (String) ret.get("errorMessage");
        putIntoJobExecutionContext(chunkContext, JobConstants.CURRENT_ERROR_MESSAGE, errorMessage);
        putIntoJobExecutionContext(chunkContext, JobConstants.SOFTWARE_MANAGEMENT_STEP_FAILE, true);
        throw TaskException.EXECUTION_FAILED(errorMessage);
      }
    }

    return RepeatStatus.FINISHED;
  }