/// <exception cref="System.IO.IOException"/> public override int LaunchContainer(Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container container, Path nmPrivateContainerScriptPath, Path nmPrivateTokensPath, string userName, string appId, Path containerWorkDir, IList <string> localDirs, IList <string > logDirs) { string containerImageName = container.GetLaunchContext().GetEnvironment()[YarnConfiguration .NmDockerContainerExecutorImageName]; if (Log.IsDebugEnabled()) { Log.Debug("containerImageName from launchContext: " + containerImageName); } Preconditions.CheckArgument(!Strings.IsNullOrEmpty(containerImageName), "Container image must not be null" ); containerImageName = containerImageName.ReplaceAll("['\"]", string.Empty); Preconditions.CheckArgument(SaneDockerImage(containerImageName), "Image: " + containerImageName + " is not a proper docker image"); string dockerExecutor = GetConf().Get(YarnConfiguration.NmDockerContainerExecutorExecName , YarnConfiguration.NmDefaultDockerContainerExecutorExecName); FsPermission dirPerm = new FsPermission(AppdirPerm); ContainerId containerId = container.GetContainerId(); // create container dirs on all disks string containerIdStr = ConverterUtils.ToString(containerId); string appIdStr = ConverterUtils.ToString(containerId.GetApplicationAttemptId().GetApplicationId ()); foreach (string sLocalDir in localDirs) { Path usersdir = new Path(sLocalDir, ContainerLocalizer.Usercache); Path userdir = new Path(usersdir, userName); Path appCacheDir = new Path(userdir, ContainerLocalizer.Appcache); Path appDir = new Path(appCacheDir, appIdStr); Path containerDir = new Path(appDir, containerIdStr); CreateDir(containerDir, dirPerm, true, userName); } // Create the container log-dirs on all disks CreateContainerLogDirs(appIdStr, containerIdStr, logDirs, userName); Path tmpDir = new Path(containerWorkDir, YarnConfiguration.DefaultContainerTempDir ); CreateDir(tmpDir, dirPerm, false, userName); // copy launch script to work dir Path launchDst = new Path(containerWorkDir, ContainerLaunch.ContainerScript); lfs.Util().Copy(nmPrivateContainerScriptPath, launchDst); // copy container tokens to work dir Path tokenDst = new Path(containerWorkDir, ContainerLaunch.FinalContainerTokensFile ); lfs.Util().Copy(nmPrivateTokensPath, tokenDst); string localDirMount = ToMount(localDirs); string logDirMount = ToMount(logDirs); string containerWorkDirMount = ToMount(Sharpen.Collections.SingletonList(containerWorkDir .ToUri().GetPath())); StringBuilder commands = new StringBuilder(); string commandStr = commands.Append(dockerExecutor).Append(" ").Append("run").Append (" ").Append("--rm --net=host").Append(" ").Append(" --name " + containerIdStr). Append(localDirMount).Append(logDirMount).Append(containerWorkDirMount).Append(" " ).Append(containerImageName).ToString(); string dockerPidScript = "`" + dockerExecutor + " inspect --format {{.State.Pid}} " + containerIdStr + "`"; // Create new local launch wrapper script DockerContainerExecutor.LocalWrapperScriptBuilder sb = new DockerContainerExecutor.UnixLocalWrapperScriptBuilder (this, containerWorkDir, commandStr, dockerPidScript); Path pidFile = GetPidFilePath(containerId); if (pidFile != null) { sb.WriteLocalWrapperScript(launchDst, pidFile); } else { Log.Info("Container " + containerIdStr + " was marked as inactive. Returning terminated error" ); return(ContainerExecutor.ExitCode.Terminated.GetExitCode()); } Shell.ShellCommandExecutor shExec = null; try { lfs.SetPermission(launchDst, ContainerExecutor.TaskLaunchScriptPermission); lfs.SetPermission(sb.GetWrapperScriptPath(), ContainerExecutor.TaskLaunchScriptPermission ); // Setup command to run string[] command = GetRunCommand(sb.GetWrapperScriptPath().ToString(), containerIdStr , userName, pidFile, this.GetConf()); if (Log.IsDebugEnabled()) { Log.Debug("launchContainer: " + commandStr + " " + Joiner.On(" ").Join(command)); } shExec = new Shell.ShellCommandExecutor(command, new FilePath(containerWorkDir.ToUri ().GetPath()), container.GetLaunchContext().GetEnvironment()); // sanitized env if (IsContainerActive(containerId)) { shExec.Execute(); } else { Log.Info("Container " + containerIdStr + " was marked as inactive. Returning terminated error" ); return(ContainerExecutor.ExitCode.Terminated.GetExitCode()); } } catch (IOException e) { if (null == shExec) { return(-1); } int exitCode = shExec.GetExitCode(); Log.Warn("Exit code from container " + containerId + " is : " + exitCode); // 143 (SIGTERM) and 137 (SIGKILL) exit codes means the container was // terminated/killed forcefully. In all other cases, log the // container-executor's output if (exitCode != ContainerExecutor.ExitCode.ForceKilled.GetExitCode() && exitCode != ContainerExecutor.ExitCode.Terminated.GetExitCode()) { Log.Warn("Exception from container-launch with container ID: " + containerId + " and exit code: " + exitCode, e); LogOutput(shExec.GetOutput()); string diagnostics = "Exception from container-launch: \n" + StringUtils.StringifyException (e) + "\n" + shExec.GetOutput(); container.Handle(new ContainerDiagnosticsUpdateEvent(containerId, diagnostics)); } else { container.Handle(new ContainerDiagnosticsUpdateEvent(containerId, "Container killed on request. Exit code is " + exitCode)); } return(exitCode); } finally { if (shExec != null) { shExec.Close(); } } return(0); }