private RequestStageContainer createInstallPackagesRequest(String hostName, final String desiredRepoVersion,
                                                             String stackName, String stackVersion, String clName,
                                                             final boolean forceInstallOnNonMemberHost,
                                                             Set<Map<String, String>> componentNames)
    throws NoSuchParentResourceException, SystemException {

    Host host;
    try {
      host = getManagementController().getClusters().getHost(hostName);
    } catch (AmbariException e) {
      throw new NoSuchParentResourceException(
              String.format("Can not find host %s", hostName), e);
    }
    AmbariManagementController managementController = getManagementController();
    AmbariMetaInfo ami = managementController.getAmbariMetaInfo();

    final StackId stackId = new StackId(stackName, stackVersion);
    if (!ami.isSupportedStack(stackName, stackVersion)) {
      throw new NoSuchParentResourceException(String.format("Stack %s is not supported",
              stackId));
    }

    Set<Cluster> clusterSet;
    if (clName == null) {
      try {
        clusterSet = getManagementController().getClusters().getClustersForHost(hostName);
      } catch (AmbariException e) {
        throw new NoSuchParentResourceException(String.format((
                "Host %s does not belong to any cluster"
        ), hostName), e);
      }
    } else {
      Cluster cluster;
      try {
        cluster = getManagementController().getClusters().getCluster(clName);
      } catch (AmbariException e) {
        throw new NoSuchParentResourceException(String.format((
                "Cluster %s does not exist"
        ), clName), e);
      }
      clusterSet = Collections.singleton(cluster);
    }

    Cluster cluster;
    if (clusterSet.isEmpty()) {
      throw new UnsupportedOperationException(String.format("Host %s belongs " +
        "to 0 clusters with stack id %s. Performing %s action failed.",
        hostName, stackId, INSTALL_PACKAGES_FULL_NAME));
    } else if (clusterSet.size() > 1) {
      throw new UnsupportedOperationException(String.format("Host %s belongs " +
        "to %d clusters with stack id %s. Performing %s action on multiple " +
        "clusters is not supported", hostName, clusterSet.size(), stackId,
        INSTALL_PACKAGES_FULL_NAME));
    } else {
      cluster = clusterSet.iterator().next();
    }

    RepositoryVersionEntity repoVersionEnt = repositoryVersionDAO.findByStackAndVersion(stackId, desiredRepoVersion);
    if (repoVersionEnt==null) {
      throw new IllegalArgumentException(String.format(
              "Repo version %s is not available for stack %s",
              desiredRepoVersion, stackId));
    }

    HostVersionEntity hostVersEntity = hostVersionDAO.findByClusterStackVersionAndHost(clName, stackId,
            desiredRepoVersion, hostName);
    if (!forceInstallOnNonMemberHost) {
      if (hostVersEntity == null) {
        throw new IllegalArgumentException(String.format(
          "Repo version %s for stack %s is not available for host %s",
          desiredRepoVersion, stackId, hostName));
      }
      if (hostVersEntity.getState() != RepositoryVersionState.INSTALLED &&
        hostVersEntity.getState() != RepositoryVersionState.INSTALL_FAILED &&
        hostVersEntity.getState() != RepositoryVersionState.OUT_OF_SYNC) {
        throw new UnsupportedOperationException(String.format("Repo version %s for stack %s " +
            "for host %s is in %s state. Can not transition to INSTALLING state",
          desiredRepoVersion, stackId, hostName, hostVersEntity.getState().toString()));
      }
    }

    // Determine repositories for host
    String osFamily = host.getOsFamily();
    RepoOsEntity osEntity = null;
    for (RepoOsEntity operatingSystem : repoVersionEnt.getRepoOsEntities()) {
      if (osFamily.equals(operatingSystem.getFamily())) {
        osEntity = operatingSystem;
        break;
      }
    }

    if (null == osEntity) {
      throw new SystemException(String.format("Operating System matching %s could not be found",
          osFamily));
    }

    if (CollectionUtils.isEmpty(osEntity.getRepoDefinitionEntities())) {
      throw new SystemException(String.format("Repositories for os type %s are " +
                      "not defined. Repo version=%s, stackId=%s",
        osFamily, desiredRepoVersion, stackId));
    }

    Set<String> servicesOnHost = new HashSet<>();

    if (forceInstallOnNonMemberHost) {
      for (Map<String, String> componentProperties : componentNames) {

        String componentName = componentProperties.get(COMPONENT_NAME_PROPERTY_ID);
        if (StringUtils.isEmpty(componentName)) {
          throw new IllegalArgumentException("Components list contains a component with no 'name' property");
        }

        String serviceName = null;
        try {
          serviceName = ami.getComponentToService(stackName, stackVersion, componentName.trim().toUpperCase());
          if (serviceName == null) {
            throw new IllegalArgumentException("Service not found for component : " + componentName);
          }
          servicesOnHost.add(serviceName);
        } catch (AmbariException e) {
          LOG.error("Service not found for component {}!", componentName, e);
          throw new IllegalArgumentException("Service not found for component : " + componentName);
        }
      }

    } else {
      List<ServiceComponentHost> components = cluster.getServiceComponentHosts(host.getHostName());
      for (ServiceComponentHost component : components) {
        servicesOnHost.add(component.getServiceName());
      }
    }

    Map<String, String> roleParams = repoVersionHelper.buildRoleParams(managementController, repoVersionEnt,
        osFamily, servicesOnHost);

    // Create custom action
    RequestResourceFilter filter = new RequestResourceFilter(null, null,
            Collections.singletonList(hostName));

    roleParams.put(OVERRIDE_CONFIGS, null);
    roleParams.put(OVERRIDE_STACK_NAME, null);
    ActionExecutionContext actionContext = new ActionExecutionContext(
            null, INSTALL_PACKAGES_ACTION,
            Collections.singletonList(filter),
            roleParams);
    actionContext.setTimeout(Integer.valueOf(configuration.getDefaultAgentTaskTimeout(true)));
    actionContext.setStackId(repoVersionEnt.getStackId());

    repoVersionHelper.addCommandRepositoryToContext(actionContext, repoVersionEnt, osEntity);

    String caption = String.format(INSTALL_PACKAGES_FULL_NAME + " on host %s", hostName);
    RequestStageContainer req = createRequest(caption);

    Map<String, String> hostLevelParams = new HashMap<>();
    hostLevelParams.put(JDK_LOCATION, getManagementController().getJdkResourceUrl());

    // Generate cluster host info
    String clusterHostInfoJson;
    try {
      clusterHostInfoJson = StageUtils.getGson().toJson(
        StageUtils.getClusterHostInfo(cluster));
    } catch (AmbariException e) {
      throw new SystemException("Could not build cluster topology", e);
    }

    Stage stage = stageFactory.createNew(req.getId(),
            "/tmp/ambari",
            cluster.getClusterName(),
            cluster.getClusterId(),
            caption,
            "{}",
            StageUtils.getGson().toJson(hostLevelParams));

    long stageId = req.getLastStageId() + 1;
    if (0L == stageId) {
      stageId = 1L;
    }
    stage.setStageId(stageId);
    req.addStages(Collections.singletonList(stage));

    try {
      actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, null, !forceInstallOnNonMemberHost);
    } catch (AmbariException e) {
      throw new SystemException("Can not modify stage", e);
    }

    if (forceInstallOnNonMemberHost) {
      addSelectStackStage(desiredRepoVersion, forceInstallOnNonMemberHost, cluster, filter, caption, req,
        hostLevelParams, clusterHostInfoJson);
    }

    try {
      if (!forceInstallOnNonMemberHost) {
        hostVersEntity.setState(RepositoryVersionState.INSTALLING);
        hostVersionDAO.merge(hostVersEntity);
      }
      req.persist();
    } catch (AmbariException e) {
      throw new SystemException("Can not persist request", e);
    }
    return req;
  }
Adds requested entities to resources
@param resources a list of resources to add to
@param requestedEntities requested entities
@param requestedIds
@param clusterName name of cluster or null if no any
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java