Adding support for Docker container
diff --git a/slider-agent/src/main/python/agent/ActionQueue.py b/slider-agent/src/main/python/agent/ActionQueue.py
index 4cb5de7..e82339e 100644
--- a/slider-agent/src/main/python/agent/ActionQueue.py
+++ b/slider-agent/src/main/python/agent/ActionQueue.py
@@ -31,7 +31,9 @@
from CommandStatusDict import CommandStatusDict
from CustomServiceOrchestrator import CustomServiceOrchestrator
import Constants
-
+import subprocess
+import getpass
+from DockerManager import DockerManager
logger = logging.getLogger()
installScriptHash = -1
@@ -51,6 +53,8 @@
STORE_APPLIED_CONFIG = 'record_config'
AUTO_RESTART = 'auto_restart'
+
+ docker_mode = False
def __init__(self, config, controller, agentToggleLogger):
super(ActionQueue, self).__init__()
@@ -66,7 +70,8 @@
self.customServiceOrchestrator = CustomServiceOrchestrator(config,
controller,
self.queueOutAgentToggleLogger)
-
+ self.dockerManager = DockerManager(self.tmpdir, config.getWorkRootPath(), self.customServiceOrchestrator)
+
def stop(self):
self._stop.set()
@@ -157,7 +162,14 @@
logger.info("Component has indicated auto-restart. Saving details from START command.")
# running command
- commandresult = self.customServiceOrchestrator.runCommand(command,
+ commandresult = None
+ logger.info("command fromhost: " + str(command))
+
+ if 'configurations' in command and 'docker' in command['configurations']:
+ self.docker_mode = True
+ commandresult = self.dockerManager.execute_command(command, store_config or store_command)
+ else:
+ commandresult = self.customServiceOrchestrator.runCommand(command,
in_progress_status[
'tmpout'],
in_progress_status[
@@ -214,7 +226,11 @@
service = command['serviceName']
component = command['componentName']
reportResult = CommandStatusDict.shouldReportResult(command)
- component_status = self.customServiceOrchestrator.requestComponentStatus(command)
+ component_status = None
+ if self.docker_mode:
+ component_status = self.dockerManager.query_status(command)
+ else:
+ component_status = self.customServiceOrchestrator.requestComponentStatus(command)
result = {"componentName": component,
"msg": "",
diff --git a/slider-agent/src/main/python/agent/DockerManager.py b/slider-agent/src/main/python/agent/DockerManager.py
new file mode 100644
index 0000000..23c8c49
--- /dev/null
+++ b/slider-agent/src/main/python/agent/DockerManager.py
@@ -0,0 +1,178 @@
+import logging
+import os
+import subprocess
+from AgentConfig import AgentConfig
+import Constants
+
+logger = logging.getLogger()
+
+class DockerManager():
+ stored_status_command = ''
+ stored_command = ''
+
+ def __init__(self, tmpdir, workroot, customServiceOrchestrator):
+ self.tmpdir = tmpdir
+ self.workroot = workroot
+ self.customServiceOrchestrator = customServiceOrchestrator
+
+ def execute_command(self, command, store_command=False):
+ returncode = ''
+ out = ''
+ err = ''
+
+ if store_command:
+ logger.info("Storing applied config: " + str(command['configurations']))
+ self.stored_command = command
+
+ if command['roleCommand'] == 'INSTALL':
+ returncode, out, err = self.pull_image(command)
+ if command['roleCommand'] == 'START':
+ returncode, out, err = self.start_container(command)
+ # need check
+ return {Constants.EXIT_CODE:returncode, 'stdout':out, 'stderr':err}
+
+ def pull_image(self, command):
+ logger.info(str( command['configurations']))
+ command_path = self.extract_config_from_command(command, 'docker.command_path')
+ imageName = self.extract_config_from_command(command, 'docker.image_name')
+
+ docker_command = [command_path, 'pull', imageName]
+ logger.info("docker pull command: " + str(docker_command))
+ return self.execute_command_on_linux(docker_command)
+
+
+ def extract_config_from_command(self, command, field):
+ value = ''
+ if 'configurations' in command:
+ if 'docker' in command['configurations']:
+ if field in command['configurations']['docker']:
+ logger.info(field + ': ' + str( command['configurations']['docker'][field]))
+ value = command['configurations']['docker'][field]
+ return value
+
+
+ # will evolve into a class hierarch, linux and windows
+ def execute_command_on_linux(self, docker_command):
+ proc = subprocess.Popen(docker_command, stdout = subprocess.PIPE)
+ out, err = proc.communicate()
+ logger.info("docker command output: " + str(out) + " err: " + str(err))
+ return proc.returncode, out, err
+
+
+ def start_container(self, command):
+ #extracting param needed by docker run from the command passed from AM
+ command_path = self.extract_config_from_command(command, 'docker.command_path')
+ imageName = self.extract_config_from_command(command, 'docker.image_name')
+ options = self.extract_config_from_command(command, 'docker.options')
+ containerPort = self.extract_config_from_command(command, 'docker.container_port')
+ mounting_directory = self.extract_config_from_command(command, 'docker.mounting_directory')
+ memory_usage = self.extract_config_from_command(command, "docker.memory_usage")
+ additional_param = self.extract_config_from_command(command, 'docker.additional_param')
+ input_file_local_path = self.extract_config_from_command(command, 'docker.input_file.local_path')
+ input_file_mount_path = self.extract_config_from_command(command, 'docker.input_file.mount_path')
+
+ docker_command = [command_path, "run"]
+ if options:
+ docker_command = self.add_docker_run_options_to_command(docker_command, options)
+ if containerPort:
+ self.add_port_binding_to_command(docker_command, command, containerPort)
+ if mounting_directory:
+ self.add_mnted_dir_to_command(docker_command, "/docker_use", mounting_directory)
+ if input_file_local_path:
+ self.add_mnted_dir_to_command(docker_command, "/inputDir", input_file_mount_path)
+ if memory_usage:
+ self.add_resource_restriction(docker_command, memory_usage)
+ self.add_container_name_to_command(docker_command, command)
+ docker_command.append(imageName)
+ if additional_param:
+ docker_command = self.add_additional_param_to_command(docker_command, additional_param)
+ logger.info("docker run command: " + str(docker_command))
+ return self.execute_command_on_linux(docker_command)
+
+ def add_docker_run_options_to_command(self, docker_command, options):
+ return docker_command + options.split(" ")
+
+ def add_port_binding_to_command(self, docker_command, command, containerPort):
+ docker_command.append("-p")
+ hostPort = self.extract_config_from_command(command, 'docker.host_port')
+ if not hostPort:
+ #this is the list of allowed port range specified in appConfig
+ allowedPorts = self.customServiceOrchestrator.get_allowed_ports(command)
+ #if the user specify hostPort in appConfig, then we use it, otherwise allocate it
+ allocated_for_this_component_format = "${{{0}.ALLOCATED_PORT}}"
+ component = command['componentName']
+ port_allocation_req = allocated_for_this_component_format.format(component)
+ hostPort = self.customServiceOrchestrator.allocate_ports(port_allocation_req, port_allocation_req, allowedPorts)
+ docker_command.append(hostPort+":"+containerPort)
+
+ def add_mnted_dir_to_command(self, docker_command, host_dir, container_dir):
+ docker_command.append("-v")
+ tmp_mount_dir = self.workroot + host_dir
+ docker_command.append(tmp_mount_dir+":"+container_dir)
+
+ def add_container_name_to_command(self, docker_command, command):
+ docker_command.append("-name")
+ docker_command.append(self.get_container_id(command))
+
+ def add_additional_param_to_command(self, docker_command, additional_param):
+ return docker_command + additional_param.split(" ")
+
+ def get_container_id(self, command):
+ # will make this more resilient to changes
+ return self.tmpdir[-30:-2]
+
+ def add_resource_restriction(self, docker_command, memory_usage):
+ docker_command.append("-m")
+ docker_command.append(memory_usage)
+
+ def query_status(self, command):
+ if command['roleCommand'] == "GET_CONFIG":
+ return self.getConfig(command)
+ else:
+ returncode = ''
+ out = ''
+ err = ''
+ status_command_str = self.extract_config_from_command(command, 'docker.status_command')
+ if status_command_str:
+ self.stored_status_command = status_command_str.split(" ")
+ logger.info("status command" + str(self.stored_status_command))
+ if self.stored_status_command:
+ returncode, out, err = self.execute_command_on_linux(self.stored_status_command)
+ logger.info("status of the app in docker container: " + str(returncode) + str(out) + str(err))
+ return {Constants.EXIT_CODE:returncode, 'stdout':out, 'stderr':err}
+
+ def getConfig(self, command):
+ logger.info("get config command: " + str(command))
+ if 'configurations' in self.stored_command:
+ if 'commandParams' in command and 'config_type' in command['commandParams']:
+ config_type = command['commandParams']['config_type']
+ logger.info("Requesting applied config for type {0}".format(config_type))
+ if config_type in self.stored_command['configurations']:
+ logger.info("get config result: " + self.stored_command['configurations'][config_type])
+ return {
+ 'configurations': {config_type: self.stored_command['configurations'][config_type]}
+ }
+ else:
+ return {
+ 'configurations': {}
+ }
+ pass
+ else:
+ logger.info("Requesting all applied config." + str(self.stored_command['configurations']))
+ return {
+ 'configurations': self.stored_command['configurations']
+ }
+ pass
+ else:
+ return {
+ 'configurations': {}
+ }
+ pass
+
+ def stop_container(self):
+ docker_command = ["/usr/bin/docker", "stop"]
+ docker_command.append(self.get_container_id(docker_command))
+ logger.info("docker stop: " + str(docker_command))
+ code, out, err = self.execute_command_on_linux(docker_command)
+ logger.info("output: " + str(out))
+
\ No newline at end of file
diff --git a/slider-agent/src/main/python/agent/main.py b/slider-agent/src/main/python/agent/main.py
index 3a75cb1..3aeaea2 100644
--- a/slider-agent/src/main/python/agent/main.py
+++ b/slider-agent/src/main/python/agent/main.py
@@ -41,6 +41,7 @@
IS_WINDOWS = platform.system() == "Windows"
formatstr = "%(levelname)s %(asctime)s %(filename)s:%(lineno)d - %(message)s"
agentPid = os.getpid()
+con = None
configFileRelPath = "infra/conf/agent.ini"
logFileName = "slider-agent.log"
@@ -54,6 +55,9 @@
if os.getpid() != agentPid:
os._exit(0)
logger.info('signal received, exiting.')
+
+ tmpdir = con.actionQueue.dockerManager.stop_container()
+
ProcessHelper.stopAgent()
@@ -287,6 +291,8 @@
# Launch Controller communication
controller = Controller(agentConfig)
controller.start()
+ global con
+ con = controller
try:
while controller.is_alive():
controller.join(timeout=1.0)
diff --git a/slider-core/pom.xml b/slider-core/pom.xml
index d5b3093..6cba0d7 100644
--- a/slider-core/pom.xml
+++ b/slider-core/pom.xml
@@ -205,7 +205,11 @@
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>3.3.1</version>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
diff --git a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
index b624221..f4d3275 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java
@@ -30,7 +30,6 @@
import org.apache.hadoop.registry.client.types.Endpoint;
import org.apache.hadoop.registry.client.types.ProtocolTypes;
import org.apache.hadoop.registry.client.types.ServiceRecord;
-import org.apache.hadoop.security.alias.CredentialProviderFactory;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.ApplicationConstants;
import org.apache.hadoop.yarn.api.records.Container;
@@ -38,7 +37,6 @@
import org.apache.hadoop.yarn.api.records.LocalResource;
import org.apache.hadoop.yarn.api.records.LocalResourceType;
import org.apache.slider.api.ClusterDescription;
-import org.apache.slider.api.ClusterDescriptionKeys;
import org.apache.slider.api.ClusterNode;
import org.apache.slider.api.InternalKeys;
import org.apache.slider.api.OptionKeys;
@@ -73,6 +71,7 @@
import org.apache.slider.providers.agent.application.metadata.ComponentExport;
import org.apache.slider.providers.agent.application.metadata.ConfigFile;
import org.apache.slider.providers.agent.application.metadata.DefaultConfig;
+import org.apache.slider.providers.agent.application.metadata.DockerContainer;
import org.apache.slider.providers.agent.application.metadata.Export;
import org.apache.slider.providers.agent.application.metadata.ExportGroup;
import org.apache.slider.providers.agent.application.metadata.Metainfo;
@@ -718,11 +717,13 @@
CommandScript cmdScript = getScriptPathFromMetainfo(roleName);
List<ComponentCommand> commands = getMetaInfo().getApplicationComponent(roleName).getCommands();
+ /*
if ((cmdScript == null || cmdScript.getScript() == null) && commands.size() == 0) {
log.error("role.script is unavailable for {}. Commands will not be sent.",
roleName);
return response;
}
+ */
String scriptPath = null;
long timeout = 600L;
@@ -794,7 +795,11 @@
installCmd = compCmd;
}
}
- addInstallCommand2(roleName, containerId, response, installCmd, timeout);
+ if(isDockerContainer(roleName)){
+ addInstallDockerCommand2(roleName, containerId, response, installCmd, timeout);
+ } else {
+ addInstallCommand2(roleName, containerId, response, installCmd, timeout);
+ }
componentStatus.commandIssued(command);
}
} else if (command == Command.START) {
@@ -819,7 +824,11 @@
startCmd = compCmd;
}
}
- addStartCommand2(roleName, containerId, response, startCmd, timeout, false);
+ if(isDockerContainer(roleName)){
+ addStartDockerCommand2(roleName, containerId, response, startCmd, timeout, false);
+ } else {
+ addStartCommand2(roleName, containerId, response, startCmd, timeout, false);
+ }
componentStatus.commandIssued(command);
} else {
log.info("Start of {} on {} delayed as dependencies have not started.", roleName, containerId);
@@ -833,7 +842,11 @@
&& command == Command.NOP) {
if (!componentStatus.getConfigReported()) {
log.info("Requesting applied config for {} on {}.", roleName, containerId);
- addGetConfigCommand(roleName, containerId, response);
+ if(isDockerContainer(roleName)){
+ addGetConfigDockerCommand(roleName, containerId, response);
+ } else {
+ addGetConfigCommand(roleName, containerId, response);
+ }
}
}
@@ -860,6 +873,14 @@
return response;
}
+ private boolean isDockerContainer(String roleName){
+ String type = getMetaInfo().getApplicationComponent(roleName).getType();
+ if(SliderUtils.isSet(type)) {
+ return type.toLowerCase().equals("docker");
+ }
+ return false;
+ }
+
protected void processAllocatedPorts(String fqdn,
String roleName,
String containerId,
@@ -1740,6 +1761,60 @@
response.addExecutionCommand(cmd);
}
+ @VisibleForTesting
+ protected void addInstallDockerCommand2(String componentName,
+ String containerId,
+ HeartBeatResponse response,
+ ComponentCommand compCmd,
+ long timeout)
+ throws SliderException {
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+
+ ExecutionCommand cmd = new ExecutionCommand(AgentCommandType.EXECUTION_COMMAND);
+ prepareExecutionCommand(cmd);
+ String clusterName = getClusterName();
+ cmd.setClusterName(clusterName);
+ cmd.setRoleCommand(Command.INSTALL.toString());
+ cmd.setServiceName(clusterName);
+ cmd.setComponentName(componentName);
+ cmd.setRole(componentName);
+ Map<String, String> hostLevelParams = new TreeMap<String, String>();
+ hostLevelParams.put(PACKAGE_LIST, getPackageList());
+ hostLevelParams.put(CONTAINER_ID, containerId);
+ cmd.setHostLevelParams(hostLevelParams);
+
+ Map<String, Map<String, String>> configurations = buildCommandConfigurations(appConf, containerId, componentName);
+ cmd.setConfigurations(configurations);
+
+ ComponentCommand effectiveCommand = compCmd;
+ if(compCmd == null) {
+ effectiveCommand = new ComponentCommand();
+ effectiveCommand.setName("INSTALL");
+ effectiveCommand.setExec("DEFAULT");
+ }
+ cmd.setCommandParams(setCommandParameters(effectiveCommand, timeout, false));
+ configurations.get("global").put("exec_cmd", effectiveCommand.getExec());
+
+ cmd.setHostname(getClusterInfoPropertyValue(StatusKeys.INFO_AM_HOSTNAME));
+ cmd.addContainerDetails(componentName, getMetaInfo());
+
+ log.info("bbb: " + getMetaInfo().toString());
+ log.info("bbb: " + getMetaInfo().getApplicationComponent(componentName).toString());
+ log.info("bbb: " + getMetaInfo().getApplicationComponent(componentName).getDockerContainers().get(0).getImage());
+
+ Map<String, String> dockerConfig = new HashMap<String, String>();
+ dockerConfig.put("docker.command_path",
+ appConf.getGlobalOptions().get("site.docker.docker.command_path"));
+ dockerConfig.put("docker.image_name",
+ getConfigFromMetaInfo(componentName, "image"));
+ configurations.put("docker", dockerConfig);
+
+ log.info("bbb configuration" + cmd.toString());
+
+ response.addExecutionCommand(cmd);
+ }
+
protected static String getPackageListFromApplication(Application application) {
String pkgFormatString = "{\"type\":\"%s\",\"name\":\"%s\"}";
String pkgListFormatString = "[%s]";
@@ -1811,6 +1886,12 @@
String scriptPath,
long timeout)
throws SliderException {
+
+ if(isDockerContainer(componentName)){
+ addStatusDockerCommand(componentName, containerId, response, scriptPath, timeout);
+ return;
+ }
+
assert getAmState().isApplicationLive();
ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
@@ -1838,6 +1919,43 @@
}
@VisibleForTesting
+ protected void addStatusDockerCommand(String componentName,
+ String containerId,
+ HeartBeatResponse response,
+ String scriptPath,
+ long timeout)
+ throws SliderException {
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+
+ StatusCommand cmd = new StatusCommand();
+ String clusterName = getClusterName();
+
+ cmd.setCommandType(AgentCommandType.STATUS_COMMAND);
+ cmd.setComponentName(componentName);
+ cmd.setServiceName(clusterName);
+ cmd.setClusterName(clusterName);
+ cmd.setRoleCommand(StatusCommand.STATUS_COMMAND);
+
+ Map<String, String> hostLevelParams = new TreeMap<String, String>();
+ hostLevelParams.put(JAVA_HOME, appConf.getGlobalOptions().getMandatoryOption(JAVA_HOME));
+ hostLevelParams.put(CONTAINER_ID, containerId);
+ cmd.setHostLevelParams(hostLevelParams);
+
+ cmd.setCommandParams(setCommandParameters(scriptPath, timeout, false));
+
+ Map<String, Map<String, String>> configurations = buildCommandConfigurations(
+ appConf, containerId, componentName);
+ Map<String, String> dockerConfig = new HashMap<String, String>();
+ dockerConfig.put("docker.status_command",
+ getConfigFromMetaInfo(componentName, "status_command"));
+ configurations.put("docker", dockerConfig);
+ cmd.setConfigurations(configurations);
+ log.info("bbb status" + cmd);
+ response.addStatusCommand(cmd);
+ }
+
+ @VisibleForTesting
protected void addGetConfigCommand(String componentName, String containerId, HeartBeatResponse response)
throws SliderException {
assert getAmState().isApplicationLive();
@@ -1860,6 +1978,84 @@
}
@VisibleForTesting
+ protected void addGetConfigDockerCommand(String componentName, String containerId, HeartBeatResponse response)
+ throws SliderException {
+ assert getAmState().isApplicationLive();
+
+ StatusCommand cmd = new StatusCommand();
+ String clusterName = getClusterName();
+
+ cmd.setCommandType(AgentCommandType.STATUS_COMMAND);
+ cmd.setComponentName(componentName);
+ cmd.setServiceName(clusterName);
+ cmd.setClusterName(clusterName);
+ cmd.setRoleCommand(StatusCommand.GET_CONFIG_COMMAND);
+ Map<String, String> hostLevelParams = new TreeMap<String, String>();
+ hostLevelParams.put(CONTAINER_ID, containerId);
+ cmd.setHostLevelParams(hostLevelParams);
+
+ hostLevelParams.put(CONTAINER_ID, containerId);
+
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+ Map<String, Map<String, String>> configurations = buildCommandConfigurations(
+ appConf, containerId, componentName);
+ Map<String, String> dockerConfig = new HashMap<String, String>();
+ dockerConfig.put("docker.status_command",
+ getConfigFromMetaInfo(componentName, "status_command"));
+ configurations.put("docker", dockerConfig);
+
+ cmd.setConfigurations(configurations);
+ log.info("bbb getconfig command " + cmd);
+
+ response.addStatusCommand(cmd);
+ }
+
+ private String getConfigFromMetaInfo(String componentName,
+ String configName) {
+ String result = null;
+ DockerContainer container = getMetaInfo()
+ .getApplicationComponent(componentName).getDockerContainers().get(0);//to support multi container per component later
+ switch (configName){
+ case "image":
+ result = container.getImage();
+ break;
+ case "status_command":
+ result = container.getStatusCommand();
+ break;
+ case "docker_command_path":
+ result = container.getCommandPath();
+ break;
+ case "docker_run_option":
+ result = container.getOptions();
+ break;
+ case "container_port":
+ result = container.getPorts().get(0).getContainerPort();//to support multi port later
+ break;
+ case "host_port":
+ result = container.getPorts().get(0).getHostPort();//to support multi port later
+ break;
+ case "containerMount":
+ result = container.getMounts().get(0).getContainerMount();//to support multi port later
+ break;
+ case "hostMount":
+ result = container.getMounts().get(0).getHostMount();//to support multi port later
+ break;
+ case "additional_param":
+ result = container.getAdditionalParam();//to support multi port later
+ break;
+ case "input_file_container_mount":
+ result = container.getInputFiles().get(0).getContainerMount();//to support multi port later
+ break;
+ case "input_file_local_path":
+ result = container.getInputFiles().get(0).getFileLocalPath();//to support multi port later
+ break;
+ default:
+ break;
+ }
+ return result;
+ }
+
+ @VisibleForTesting
protected void addStartCommand(String componentName, String containerId, HeartBeatResponse response,
String scriptPath, long timeout, boolean isMarkedAutoRestart)
throws
@@ -1963,6 +2159,77 @@
response.addExecutionCommand(cmd);
}
+ @VisibleForTesting
+ protected void addStartDockerCommand2(String componentName, String containerId, HeartBeatResponse response,
+ ComponentCommand startCommand, long timeout, boolean isMarkedAutoRestart)
+ throws
+ SliderException {
+ assert getAmState().isApplicationLive();
+ ConfTreeOperations appConf = getAmState().getAppConfSnapshot();
+ ConfTreeOperations internalsConf = getAmState().getInternalsSnapshot();
+
+ ExecutionCommand cmd = new ExecutionCommand(AgentCommandType.EXECUTION_COMMAND);
+ prepareExecutionCommand(cmd);
+ String clusterName = internalsConf.get(OptionKeys.APPLICATION_NAME);
+ String hostName = getClusterInfoPropertyValue(StatusKeys.INFO_AM_HOSTNAME);
+ cmd.setHostname(hostName);
+ cmd.setClusterName(clusterName);
+ cmd.setRoleCommand(Command.START.toString());
+ cmd.setServiceName(clusterName);
+ cmd.setComponentName(componentName);
+ cmd.setRole(componentName);
+ Map<String, String> hostLevelParams = new TreeMap<>();
+ hostLevelParams.put(CONTAINER_ID, containerId);
+ cmd.setHostLevelParams(hostLevelParams);
+
+ Map<String, String> roleParams = new TreeMap<>();
+ cmd.setRoleParams(roleParams);
+ cmd.getRoleParams().put("auto_restart", Boolean.toString(isMarkedAutoRestart));
+
+ cmd.setCommandParams(setCommandParameters(startCommand, timeout, true));
+
+ Map<String, Map<String, String>> configurations = buildCommandConfigurations(
+ appConf, containerId, componentName);
+
+ log.info("bbb: " + getMetaInfo().toString());
+ log.info("bbb: " + getMetaInfo().getApplicationComponent(componentName).toString());
+
+ Map<String, String> dockerConfig = new HashMap<String, String>();
+ String docker_command_path = getConfigFromMetaInfo(componentName, "docker_command_path");
+ if(docker_command_path == null){
+ docker_command_path = appConf.getGlobalOptions().get("site.docker.docker.command_path");
+ }
+ dockerConfig.put("docker.command_path",docker_command_path);
+ dockerConfig.put("docker.image_name",
+ getConfigFromMetaInfo(componentName, "image"));
+ String docker_run_options = getConfigFromMetaInfo(componentName, "docker_run_option");
+ if(docker_run_options == null){
+ docker_run_options = appConf.getGlobalOptions().get("site.docker.options");
+ }
+ dockerConfig.put("docker.options",docker_run_options);
+ dockerConfig.put("docker.container_port",
+ getConfigFromMetaInfo(componentName, "docker.container_port"));
+ dockerConfig.put("docker.host_port",
+ getConfigFromMetaInfo(componentName, "docker.host_port"));
+
+ // dockerConfig
+ // .put("docker.mounting_directory", getConfigFromMetaInfo(componentName, "containerMount"));
+ // dockerConfig
+ // .put("docker.host_mounting_directory", getConfigFromMetaInfo(componentName, "hostMount"));
+
+ dockerConfig.put("docker.additional_param",
+ getConfigFromMetaInfo(componentName, "additional_param"));
+
+ // dockerConfig.put("docker.input_file.mount_path", getConfigFromMetaInfo(
+ // componentName, "intpu_file_container_mount"));
+ configurations.put("docker", dockerConfig);
+
+ cmd.setConfigurations(configurations);
+ configurations.get("global").put("exec_cmd", startCommand.getExec());
+ cmd.addContainerDetails(componentName, getMetaInfo());
+ response.addExecutionCommand(cmd);
+ }
+
protected Map<String, String> getAllocatedPorts() {
return getAllocatedPorts(SHARED_PORT_TAG);
}
diff --git a/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainer.java b/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainer.java
index 3117f3b..f111656 100644
--- a/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainer.java
+++ b/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainer.java
@@ -39,21 +39,28 @@
private String options;
private List<DockerContainerMount> mounts = new ArrayList<>();
private List<DockerContainerPort> ports = new ArrayList<>();
+ private String statusCommand;
+ private String commandPath;
+ private String additionalParam;
+ private List<DockerContainerInputFile> inputFiles = new ArrayList<>();
public DockerContainer() {
}
@JsonProperty("mounts")
- public List<DockerContainerMount> getMounts() {
- return this.mounts;
- }
+ public List<DockerContainerMount> getMounts() { return this.mounts; }
@JsonProperty("ports")
public List<DockerContainerPort> getPorts() {
return this.ports;
}
+ @JsonProperty("inputFiles")
+ public List<DockerContainerInputFile> getInputFiles() {
+ return this.inputFiles;
+ }
+
public String getName() {
return name;
}
@@ -88,4 +95,28 @@
dcp.validate(version);
}
}
+
+ public String getStatusCommand() {
+ return statusCommand;
+ }
+
+ public void setStatusCommand(String statusCommand) {
+ this.statusCommand = statusCommand;
+ }
+
+ public String getCommandPath() {
+ return commandPath;
+ }
+
+ public void setCommandPath(String commandPath) {
+ this.commandPath = commandPath;
+ }
+
+ public String getAdditionalParam() {
+ return additionalParam;
+ }
+
+ public void setAdditionalParam(String additionalParam) {
+ this.additionalParam = additionalParam;
+ }
}
diff --git a/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainerInputFile.java b/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainerInputFile.java
new file mode 100644
index 0000000..1466678
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/providers/agent/application/metadata/DockerContainerInputFile.java
@@ -0,0 +1,32 @@
+package org.apache.slider.providers.agent.application.metadata;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DockerContainerInputFile {
+ protected static final Logger log = LoggerFactory
+ .getLogger(DockerContainerInputFile.class);
+
+ private String containerMount;
+ private String fileLocalPath;
+
+ public DockerContainerInputFile() {
+ }
+
+ public String getContainerMount() {
+ return containerMount;
+ }
+
+ public void setContainerMount(String containerMount) {
+ this.containerMount = containerMount;
+ }
+
+ public String getFileLocalPath() {
+ return fileLocalPath;
+ }
+
+ public void setFileLocalPath(String fileLocalPath) {
+ this.fileLocalPath = fileLocalPath;
+ }
+
+}
diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
index 9208707..addeee0 100644
--- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
+++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
@@ -20,6 +20,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.slider.providers.agent.application.metadata.Component;
import org.apache.slider.providers.agent.application.metadata.DockerContainer;
+import org.apache.slider.providers.agent.application.metadata.DockerContainerInputFile;
import org.apache.slider.providers.agent.application.metadata.DockerContainerMount;
import org.apache.slider.providers.agent.application.metadata.DockerContainerPort;
import org.apache.slider.providers.agent.application.metadata.Metainfo;
@@ -232,6 +233,9 @@
container.setImage(metaContainer.getImage());
container.setName(metaContainer.getName());
container.setOptions(metaContainer.getOptions());
+ container.setAdditionalParam(metaContainer.getAdditionalParam());
+ container.setCommandPath(metaContainer.getAdditionalParam());
+ container.setStatusCommand(metaContainer.getStatusCommand());
if(metaContainer.getMounts().size() > 0) {
for(DockerContainerMount metaContMount : metaContainer.getMounts()) {
DockerContainerMount contMnt = new DockerContainerMount();
@@ -248,6 +252,14 @@
container.getPorts().add(cntPort);
}
}
+ if(metaContainer.getInputFiles().size() > 0) {
+ for(DockerContainerInputFile metaInpFile : metaContainer.getInputFiles()) {
+ DockerContainerInputFile inpFile = new DockerContainerInputFile();
+ inpFile.setContainerMount(metaInpFile.getContainerMount());
+ inpFile.setFileLocalPath(metaInpFile.getFileLocalPath());
+ container.getInputFiles().add(inpFile);
+ }
+ }
this.getContainers().add(container);
}
}