/// <exception cref="System.IO.IOException"/> public override int LaunchContainer(Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container container, Path nmPrivateCotainerScriptPath, Path nmPrivateTokensPath, string user , string appId, Path containerWorkDir, IList <string> localDirs, IList <string> logDirs ) { VerifyUsernamePattern(user); string runAsUser = GetRunAsUser(user); ContainerId containerId = container.GetContainerId(); string containerIdStr = ConverterUtils.ToString(containerId); resourcesHandler.PreExecute(containerId, container.GetResource()); string resourcesOptions = resourcesHandler.GetResourcesOption(containerId); Shell.ShellCommandExecutor shExec = null; try { Path pidFilePath = GetPidFilePath(containerId); if (pidFilePath != null) { IList <string> command = new AList <string>(); AddSchedPriorityCommand(command); Sharpen.Collections.AddAll(command, Arrays.AsList(containerExecutorExe, runAsUser , user, Sharpen.Extensions.ToString(LinuxContainerExecutor.Commands.LaunchContainer .GetValue()), appId, containerIdStr, containerWorkDir.ToString(), nmPrivateCotainerScriptPath .ToUri().GetPath().ToString(), nmPrivateTokensPath.ToUri().GetPath().ToString(), pidFilePath.ToString(), StringUtils.Join(",", localDirs), StringUtils.Join(",", logDirs), resourcesOptions)); string[] commandArray = Sharpen.Collections.ToArray(command, new string[command.Count ]); shExec = new Shell.ShellCommandExecutor(commandArray, null, container.GetLaunchContext ().GetEnvironment()); // NM's cwd // sanitized env if (Log.IsDebugEnabled()) { Log.Debug("launchContainer: " + Arrays.ToString(commandArray)); } shExec.Execute(); if (Log.IsDebugEnabled()) { LogOutput(shExec.GetOutput()); } } else { Log.Info("Container was marked as inactive. Returning terminated error"); return(ContainerExecutor.ExitCode.Terminated.GetExitCode()); } } catch (Shell.ExitCodeException e) { 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); StringBuilder builder = new StringBuilder(); builder.Append("Exception from container-launch.\n"); builder.Append("Container id: " + containerId + "\n"); builder.Append("Exit code: " + exitCode + "\n"); if (!Optional.FromNullable(e.Message).Or(string.Empty).IsEmpty()) { builder.Append("Exception message: " + e.Message + "\n"); } builder.Append("Stack trace: " + StringUtils.StringifyException(e) + "\n"); if (!shExec.GetOutput().IsEmpty()) { builder.Append("Shell output: " + shExec.GetOutput() + "\n"); } string diagnostics = builder.ToString(); LogOutput(diagnostics); container.Handle(new ContainerDiagnosticsUpdateEvent(containerId, diagnostics)); } else { container.Handle(new ContainerDiagnosticsUpdateEvent(containerId, "Container killed on request. Exit code is " + exitCode)); } return(exitCode); } finally { resourcesHandler.PostExecute(containerId); } if (Log.IsDebugEnabled()) { Log.Debug("Output from LinuxContainerExecutor's launchContainer follows:"); LogOutput(shExec.GetOutput()); } return(0); }
/// <exception cref="System.IO.IOException"/> public override int LaunchContainer(Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container container, Path nmPrivateContainerScriptPath, Path nmPrivateTokensPath, string user, string appId, Path containerWorkDir, IList <string> localDirs, IList <string > logDirs) { 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, user); Path appCacheDir = new Path(userdir, ContainerLocalizer.Appcache); Path appDir = new Path(appCacheDir, appIdStr); Path containerDir = new Path(appDir, containerIdStr); CreateDir(containerDir, dirPerm, true, user); } // Create the container log-dirs on all disks CreateContainerLogDirs(appIdStr, containerIdStr, logDirs, user); Path tmpDir = new Path(containerWorkDir, YarnConfiguration.DefaultContainerTempDir ); CreateDir(tmpDir, dirPerm, false, user); // copy container tokens to work dir Path tokenDst = new Path(containerWorkDir, ContainerLaunch.FinalContainerTokensFile ); CopyFile(nmPrivateTokensPath, tokenDst, user); // copy launch script to work dir Path launchDst = new Path(containerWorkDir, ContainerLaunch.ContainerScript); CopyFile(nmPrivateContainerScriptPath, launchDst, user); // Create new local launch wrapper script DefaultContainerExecutor.LocalWrapperScriptBuilder sb = GetLocalWrapperScriptBuilder (containerIdStr, containerWorkDir); // Fail fast if attempting to launch the wrapper script would fail due to // Windows path length limitation. if (Shell.Windows && sb.GetWrapperScriptPath().ToString().Length > WinMaxPath) { throw new IOException(string.Format("Cannot launch container using script at path %s, because it exceeds " + "the maximum supported path length of %d characters. Consider " + "configuring shorter directories in %s." , sb.GetWrapperScriptPath(), WinMaxPath, YarnConfiguration.NmLocalDirs)); } 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()); } // create log dir under app // fork script Shell.CommandExecutor shExec = null; try { SetScriptExecutable(launchDst, user); SetScriptExecutable(sb.GetWrapperScriptPath(), user); shExec = BuildCommandExecutor(sb.GetWrapperScriptPath().ToString(), containerIdStr , user, pidFile, container.GetResource(), new FilePath(containerWorkDir.ToUri(). GetPath()), container.GetLaunchContext().GetEnvironment()); 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); StringBuilder builder = new StringBuilder(); builder.Append("Exception from container-launch.\n"); builder.Append("Container id: " + containerId + "\n"); builder.Append("Exit code: " + exitCode + "\n"); if (!Optional.FromNullable(e.Message).Or(string.Empty).IsEmpty()) { builder.Append("Exception message: " + e.Message + "\n"); } builder.Append("Stack trace: " + StringUtils.StringifyException(e) + "\n"); if (!shExec.GetOutput().IsEmpty()) { builder.Append("Shell output: " + shExec.GetOutput() + "\n"); } string diagnostics = builder.ToString(); LogOutput(diagnostics); 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); }