_appMasterConfig.setApplicationSpecFactory(_applicationSpecFactory.getClass()
.getCanonicalName());
appContext.setApplicationName(appName);
// Set up the container launch context for the application master
ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);
LOG.info("Copy Application archive file from local filesystem and add to local environment");
// Copy the application master jar to the filesystem
// Create a local resource to point to the destination jar path
FileSystem fs = FileSystem.get(_conf);
// get packages for each component packages
Map<String, URI> packages = new HashMap<String, URI>();
packages
.put(AppMasterConfig.AppEnvironment.APP_MASTER_PKG.toString(), appMasterArchive.toURI());
packages.put(AppMasterConfig.AppEnvironment.APP_SPEC_FILE.toString(), _yamlConfigFile.toURI());
for (String serviceName : _applicationSpec.getServices()) {
packages.put(serviceName, _applicationSpec.getServicePackage(serviceName));
}
Map<String, Path> hdfsDest = new HashMap<String, Path>();
Map<String, String> classpathMap = new HashMap<String, String>();
for (String name : packages.keySet()) {
URI uri = packages.get(name);
Path dst = copyToHDFS(fs, name, uri);
hdfsDest.put(name, dst);
String classpath = generateClasspathAfterExtraction(name, new File(uri));
classpathMap.put(name, classpath);
_appMasterConfig.setClasspath(name, classpath);
String serviceMainClass = _applicationSpec.getServiceMainClass(name);
if (serviceMainClass != null) {
_appMasterConfig.setMainClass(name, serviceMainClass);
}
}
// Get YAML files describing all workflows to immediately start
Map<String, URI> workflowFiles = new HashMap<String, URI>();
List<TaskConfig> taskConfigs = _applicationSpec.getTaskConfigs();
if (taskConfigs != null) {
for (TaskConfig taskConfig : taskConfigs) {
URI configUri = taskConfig.getYamlURI();
if (taskConfig.name != null && configUri != null) {
workflowFiles.put(taskConfig.name, taskConfig.getYamlURI());
}
}
}
// set local resources for the application master
// local files or archives as needed
// In this scenario, the jar file for the application master is part of the local resources
Map<String, LocalResource> localResources = new HashMap<String, LocalResource>();
LocalResource appMasterPkg =
setupLocalResource(fs,
hdfsDest.get(AppMasterConfig.AppEnvironment.APP_MASTER_PKG.toString()));
LocalResource appSpecFile =
setupLocalResource(fs,
hdfsDest.get(AppMasterConfig.AppEnvironment.APP_SPEC_FILE.toString()));
localResources.put(AppMasterConfig.AppEnvironment.APP_MASTER_PKG.toString(), appMasterPkg);
localResources.put(AppMasterConfig.AppEnvironment.APP_SPEC_FILE.toString(), appSpecFile);
for (String name : workflowFiles.keySet()) {
URI uri = workflowFiles.get(name);
Path dst = copyToHDFS(fs, name, uri);
LocalResource taskLocalResource = setupLocalResource(fs, dst);
localResources.put(AppMasterConfig.AppEnvironment.TASK_CONFIG_FILE.toString() + "_" + name,
taskLocalResource);
}
// Set local resource info into app master container launch context
amContainer.setLocalResources(localResources);
// Set the necessary security tokens as needed
// amContainer.setContainerTokens(containerToken);
// Add AppMaster.jar location to classpath
// At some point we should not be required to add
// the hadoop specific classpaths to the env.
// It should be provided out of the box.
// For now setting all required classpaths including
// the classpath to "." for the application jar
StringBuilder classPathEnv =
new StringBuilder(Environment.CLASSPATH.$()).append(File.pathSeparatorChar).append("./*")
.append(File.pathSeparatorChar);
classPathEnv.append(classpathMap.get(AppMasterConfig.AppEnvironment.APP_MASTER_PKG.toString()));
for (String c : _conf.getStrings(YarnConfiguration.YARN_APPLICATION_CLASSPATH,
YarnConfiguration.DEFAULT_YARN_APPLICATION_CLASSPATH)) {
classPathEnv.append(File.pathSeparatorChar);
classPathEnv.append(c.trim());
}
classPathEnv.append(File.pathSeparatorChar).append("./log4j.properties");
// add the runtime classpath needed for tests to work
if (_conf.getBoolean(YarnConfiguration.IS_MINI_YARN_CLUSTER, false)) {
classPathEnv.append(':');
classPathEnv.append(System.getProperty("java.class.path"));
}
LOG.info("\n\n Setting the classpath to launch AppMaster:\n\n");
// Set the env variables to be setup in the env where the application master will be run
Map<String, String> env = new HashMap<String, String>(_appMasterConfig.getEnv());
env.put("CLASSPATH", classPathEnv.toString());
amContainer.setEnvironment(env);
// Set the necessary command to execute the application master
Vector<CharSequence> vargs = new Vector<CharSequence>(30);
// Set java executable command
LOG.info("Setting up app master launch command");
vargs.add(Environment.JAVA_HOME.$() + "/bin/java");
int amMemory = 4096;
// Set Xmx based on am memory size
vargs.add("-Xmx" + amMemory + "m");
// Set class name
vargs.add(AppMasterLauncher.class.getCanonicalName());
// Set params for Application Master
// vargs.add("--num_containers " + String.valueOf(numContainers));
vargs.add("1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/AppMaster.stdout");
vargs.add("2>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/AppMaster.stderr");
// Get final commmand
StringBuilder command = new StringBuilder();
for (CharSequence str : vargs) {
command.append(str).append(" ");
}
LOG.info("Completed setting up app master command " + command.toString());
List<String> commands = new ArrayList<String>();
commands.add(command.toString());
amContainer.setCommands(commands);
// Set up resource type requirements
// For now, only memory is supported so we set memory requirements
Resource capability = Records.newRecord(Resource.class);
capability.setMemory(amMemory);
appContext.setResource(capability);
// Service data is a binary blob that can be passed to the application
// Not needed in this scenario
// amContainer.setServiceData(serviceData);
// Setup security tokens
if (UserGroupInformation.isSecurityEnabled()) {
Credentials credentials = new Credentials();
String tokenRenewer = _conf.get(YarnConfiguration.RM_PRINCIPAL);
if (tokenRenewer == null || tokenRenewer.length() == 0) {
throw new IOException("Can't get Master Kerberos principal for the RM to use as renewer");
}
// For now, only getting tokens for the default file-system.
final Token<?> tokens[] = fs.addDelegationTokens(tokenRenewer, credentials);
if (tokens != null) {
for (Token<?> token : tokens) {
LOG.info("Got dt for " + fs.getUri() + "; " + token);
}
}
DataOutputBuffer dob = new DataOutputBuffer();
credentials.writeTokenStorageToStream(dob);
ByteBuffer fsTokens = ByteBuffer.wrap(dob.getData(), 0, dob.getLength());
amContainer.setTokens(fsTokens);
}
appContext.setAMContainerSpec(amContainer);
// Set the priority for the application master