in ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java [260:509]
public void addExecutionCommandsToStage(final ActionExecutionContext actionContext, Stage stage,
Map<String, String> requestParams, boolean checkHostIsMemberOfCluster)
throws AmbariException {
String actionName = actionContext.getActionName();
String clusterName = actionContext.getClusterName();
final Cluster cluster;
if (null != clusterName) {
cluster = clusters.getCluster(clusterName);
} else {
cluster = null;
}
ComponentInfo componentInfo = null;
List<RequestResourceFilter> resourceFilters = actionContext.getResourceFilters();
final RequestResourceFilter resourceFilter;
if (resourceFilters != null && !resourceFilters.isEmpty()) {
resourceFilter = resourceFilters.get(0);
} else {
resourceFilter = new RequestResourceFilter();
}
// List of host to select from
Set<String> candidateHosts = new HashSet<>();
final String serviceName = actionContext.getExpectedServiceName();
final String componentName = actionContext.getExpectedComponentName();
LOG.debug("Called addExecutionCommandsToStage() for serviceName: {}, componentName: {}.", serviceName, componentName);
if (resourceFilter.getHostNames().isEmpty()) {
LOG.debug("Resource filter has no hostnames.");
} else {
LOG.debug("Resource filter has hosts: {}", StringUtils.join(resourceFilter.getHostNames(), ", "));
}
if (null != cluster) {
// StackId stackId = cluster.getCurrentStackVersion();
if (serviceName != null && !serviceName.isEmpty()) {
if (componentName != null && !componentName.isEmpty()) {
Service service = cluster.getService(serviceName);
ServiceComponent component = service.getServiceComponent(componentName);
StackId stackId = component.getDesiredStackId();
Map<String, ServiceComponentHost> componentHosts = component.getServiceComponentHosts();
candidateHosts.addAll(componentHosts.keySet());
try {
componentInfo = ambariMetaInfo.getComponent(stackId.getStackName(),
stackId.getStackVersion(), serviceName, componentName);
} catch (ObjectNotFoundException e) {
// do nothing, componentId is checked for null later
LOG.error("Did not find service {} and component {} in stack {}.", serviceName, componentName, stackId.getStackName());
}
} else {
for (String component : cluster.getService(serviceName).getServiceComponents().keySet()) {
Map<String, ServiceComponentHost> componentHosts = cluster.getService(serviceName)
.getServiceComponent(component).getServiceComponentHosts();
candidateHosts.addAll(componentHosts.keySet());
}
}
} else {
// All hosts are valid target host
candidateHosts.addAll(clusters.getHostsForCluster(cluster.getClusterName()).keySet());
}
LOG.debug("Request for service {} and component {} is set to run on candidate hosts: {}.", serviceName, componentName, StringUtils.join(candidateHosts, ", "));
// Filter hosts that are in MS
Set<String> ignoredHosts = maintenanceStateHelper.filterHostsInMaintenanceState(
candidateHosts, new MaintenanceStateHelper.HostPredicate() {
@Override
public boolean shouldHostBeRemoved(final String hostname)
throws AmbariException {
return ! maintenanceStateHelper.isOperationAllowed(
cluster, actionContext.getOperationLevel(),
resourceFilter, serviceName, componentName, hostname);
}
}
);
if (! ignoredHosts.isEmpty()) {
LOG.debug("Hosts to ignore: {}.", ignoredHosts);
LOG.debug("Ignoring action for hosts due to maintenance state.Ignored hosts ={}, component={}, service={}, cluster={}, actionName={}",
ignoredHosts, componentName, serviceName, cluster.getClusterName(), actionContext.getActionName());
}
}
// If request did not specify hosts and there exists no host
if (resourceFilter.getHostNames().isEmpty() && candidateHosts.isEmpty()) {
throw new AmbariException("Suitable hosts not found, component="
+ componentName + ", service=" + serviceName
+ ((null == cluster) ? "" : ", cluster=" + cluster.getClusterName() + ", ")
+ "actionName=" + actionContext.getActionName());
}
if (checkHostIsMemberOfCluster) {
// Compare specified hosts to available hosts
if (!resourceFilter.getHostNames().isEmpty() && !candidateHosts.isEmpty()) {
for (String hostname : resourceFilter.getHostNames()) {
if (!candidateHosts.contains(hostname)) {
throw new AmbariException("Request specifies host " + hostname +
" but it is not a valid host based on the " +
"target service=" + serviceName + " and component=" + componentName);
}
}
}
}
List<String> targetHosts = resourceFilter.getHostNames();
//Find target hosts to execute
if (targetHosts.isEmpty()) {
TargetHostType hostType = actionContext.getTargetType();
switch (hostType) {
case ALL:
targetHosts.addAll(candidateHosts);
break;
case ANY:
targetHosts.add(managementController.getHealthyHost(candidateHosts));
break;
case MAJORITY:
for (int i = 0; i < (candidateHosts.size() / 2) + 1; i++) {
String hostname = managementController.getHealthyHost(candidateHosts);
targetHosts.add(hostname);
candidateHosts.remove(hostname);
}
break;
default:
throw new AmbariException("Unsupported target type = " + hostType);
}
}
setAdditionalParametersForStageAccordingToAction(stage, actionContext);
// create tasks for each host
for (String hostName : targetHosts) {
// ensure that any tags that need to be refreshed are extracted from the
// context and put onto the execution command
Map<String, String> actionParameters = actionContext.getParameters();
stage.addHostRoleExecutionCommand(hostName, Role.valueOf(actionContext.getActionName()),
RoleCommand.ACTIONEXECUTE,
new ServiceComponentHostOpInProgressEvent(actionContext.getActionName(), hostName,
System.currentTimeMillis()),
clusterName, serviceName, actionContext.isRetryAllowed(),
actionContext.isFailureAutoSkipped());
Map<String, String> commandParams = new TreeMap<>();
int taskTimeout = Integer.parseInt(configs.getDefaultAgentTaskTimeout(false));
// use the biggest of all these:
// if the action context timeout is bigger than the default, use the context
// if the action context timeout is smaller than the default, use the default
// if the action context timeout is undefined, use the default
if (null != actionContext.getTimeout() && actionContext.getTimeout() > taskTimeout) {
commandParams.put(COMMAND_TIMEOUT, actionContext.getTimeout().toString());
} else {
commandParams.put(COMMAND_TIMEOUT, Integer.toString(taskTimeout));
}
if (requestParams != null && requestParams.containsKey(KeyNames.LOG_OUTPUT)) {
LOG.info("Should command log output?: " + requestParams.get(KeyNames.LOG_OUTPUT));
commandParams.put(KeyNames.LOG_OUTPUT, requestParams.get(KeyNames.LOG_OUTPUT));
}
commandParams.put(SCRIPT, actionName + "." + ACTION_FILE_EXTENSION);
commandParams.put(SCRIPT_TYPE, TYPE_PYTHON);
StageUtils.useAmbariJdkInCommandParams(commandParams, configs);
ExecutionCommand execCmd = stage.getExecutionCommandWrapper(hostName,
actionContext.getActionName()).getExecutionCommand();
// !!! ensure that these are empty so that commands have the correct tags
// applied when the execution is about to be scheduled to run
execCmd.setConfigurations(new TreeMap<>());
// if the command should fetch brand new configuration tags before
// execution, then we don't need to fetch them now
if (null != actionParameters && !actionParameters.isEmpty()) {
if (actionParameters.containsKey(KeyNames.OVERRIDE_CONFIGS)) {
execCmd.setOverrideConfigs(true);
}
if (actionParameters.containsKey(KeyNames.OVERRIDE_STACK_NAME)) {
Map<String, String> clusterLevelParams = execCmd.getClusterLevelParams();
if (clusterLevelParams == null) {
clusterLevelParams = new HashMap<>();
}
clusterLevelParams.put(STACK_NAME, actionContext.getStackId().getStackName());
execCmd.setClusterLevelParams(clusterLevelParams);
}
}
execCmd.setServiceName(serviceName == null || serviceName.isEmpty() ?
resourceFilter.getServiceName() : serviceName);
execCmd.setComponentName(componentName == null || componentName.isEmpty() ?
resourceFilter.getComponentName() : componentName);
Map<String, String> hostLevelParams = execCmd.getHostLevelParams();
hostLevelParams.put(GPL_LICENSE_ACCEPTED, configs.getGplLicenseAccepted().toString());
hostLevelParams.put(AGENT_STACK_RETRY_ON_UNAVAILABILITY, configs.isAgentStackRetryOnInstallEnabled());
hostLevelParams.put(AGENT_STACK_RETRY_COUNT, configs.getAgentStackRetryOnInstallCount());
for (Map.Entry<String, String> dbConnectorName : configs.getDatabaseConnectorNames().entrySet()) {
hostLevelParams.put(dbConnectorName.getKey(), dbConnectorName.getValue());
}
for (Map.Entry<String, String> previousDBConnectorName : configs.getPreviousDatabaseConnectorNames().entrySet()) {
hostLevelParams.put(previousDBConnectorName.getKey(), previousDBConnectorName.getValue());
}
if (StringUtils.isNotBlank(serviceName)) {
Service service = cluster.getService(serviceName);
repoVersionHelper.addRepoInfoToHostLevelParams(cluster, actionContext, service.getDesiredRepositoryVersion(),
hostLevelParams, hostName);
} else {
repoVersionHelper.addRepoInfoToHostLevelParams(cluster, actionContext, null, hostLevelParams, hostName);
}
Map<String, String> roleParams = execCmd.getRoleParams();
if (roleParams == null) {
roleParams = new TreeMap<>();
}
roleParams.putAll(actionParameters);
SecretReference.replaceReferencesWithPasswords(roleParams, cluster);
if (componentInfo != null) {
roleParams.put(COMPONENT_CATEGORY, componentInfo.getCategory());
}
// if there is a stack upgrade which is currently suspended then pass that
// information down with the command as some components may need to know
if (null != cluster && cluster.isUpgradeSuspended()) {
cluster.addSuspendedUpgradeParameters(commandParams, roleParams);
}
execCmd.setCommandParams(commandParams);
execCmd.setRoleParams(roleParams);
if (null != cluster) {
// Generate localComponents
for (ServiceComponentHost sch : cluster.getServiceComponentHosts(hostName)) {
execCmd.getLocalComponents().add(sch.getServiceComponentName());
}
}
actionContext.visitAll(execCmd);
}
}