private List<NodeEntity> getNodesToBeSetLocalRepo(ChunkContext chunkContext, String clusterName)
      throws TaskException {
    List<NodeEntity> toBeSetLocalRepo = null;
    if ((managementOperation == ManagementOperation.CREATE)
        || (managementOperation == ManagementOperation.RESUME)) {
      toBeSetLocalRepo = getClusterEntityMgr().findAllNodes(clusterName);
      return toBeSetLocalRepo;
    } else if (managementOperation == ManagementOperation.RESIZE) {
      String groupName =
          getJobParameters(chunkContext).getString(JobConstants.GROUP_NAME_JOB_PARAM);
      List<NodeEntity> nodesInGroup = clusterEntityMgr.findAllNodes(clusterName, groupName);
      long oldInstanceNum =
          getJobParameters(chunkContext).getLong(JobConstants.GROUP_INSTANCE_OLD_NUMBER_JOB_PARAM);

      for (NodeEntity node : nodesInGroup) {
        long index = CommonUtil.getVmIndex(node.getVmName());
        if (index < oldInstanceNum) {
          // do not verify existing nodes from last successful deployment
          continue;
        }
        if (node.getStatus().ordinal() >= NodeStatus.VM_READY.ordinal()) {
          if (toBeSetLocalRepo == null) {
            toBeSetLocalRepo = new ArrayList<NodeEntity>();
          }
          toBeSetLocalRepo.add(node);
        }
      }
      return toBeSetLocalRepo;
    } else {
      throw TaskException.EXECUTION_FAILED("Unknown operation type.");
    }
  }
  @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;
  }