public virtual void TestContainerLaunch() { string appSubmitter = "nobody"; string cmd = LinuxContainerExecutor.Commands.LaunchContainer.GetValue().ToString( ); string appId = "APP_ID"; string containerId = "CONTAINER_ID"; Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container container = Org.Mockito.Mockito.Mock <Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container >(); ContainerId cId = Org.Mockito.Mockito.Mock <ContainerId>(); ContainerLaunchContext context = Org.Mockito.Mockito.Mock <ContainerLaunchContext> (); Dictionary <string, string> env = new Dictionary <string, string>(); Org.Mockito.Mockito.When(container.GetContainerId()).ThenReturn(cId); Org.Mockito.Mockito.When(container.GetLaunchContext()).ThenReturn(context); Org.Mockito.Mockito.When(cId.ToString()).ThenReturn(containerId); Org.Mockito.Mockito.When(context.GetEnvironment()).ThenReturn(env); Path scriptPath = new Path("file:///bin/echo"); Path tokensPath = new Path("file:///dev/null"); Path workDir = new Path("/tmp"); Path pidFile = new Path(workDir, "pid.txt"); mockExec.ActivateContainer(cId, pidFile); int ret = mockExec.LaunchContainer(container, scriptPath, tokensPath, appSubmitter , appId, workDir, dirsHandler.GetLocalDirs(), dirsHandler.GetLogDirs()); NUnit.Framework.Assert.AreEqual(0, ret); NUnit.Framework.Assert.AreEqual(Arrays.AsList(YarnConfiguration.DefaultNmNonsecureModeLocalUser , appSubmitter, cmd, appId, containerId, workDir.ToString(), "/bin/echo", "/dev/null" , pidFile.ToString(), StringUtils.Join(",", dirsHandler.GetLocalDirs()), StringUtils .Join(",", dirsHandler.GetLogDirs()), "cgroups=none"), ReadMockParams()); }
public virtual void TestContainerLaunchError() { // reinitialize executer FilePath f = new FilePath("./src/test/resources/mock-container-executer-with-error" ); if (!FileUtil.CanExecute(f)) { FileUtil.SetExecutable(f, true); } string executorPath = f.GetAbsolutePath(); Configuration conf = new Configuration(); conf.Set(YarnConfiguration.NmLinuxContainerExecutorPath, executorPath); conf.Set(YarnConfiguration.NmLocalDirs, "file:///bin/echo"); conf.Set(YarnConfiguration.NmLogDirs, "file:///dev/null"); mockExec = Org.Mockito.Mockito.Spy(new LinuxContainerExecutor()); Org.Mockito.Mockito.DoAnswer(new _Answer_226()).When(mockExec).LogOutput(Matchers.Any <string>()); dirsHandler = new LocalDirsHandlerService(); dirsHandler.Init(conf); mockExec.SetConf(conf); string appSubmitter = "nobody"; string cmd = LinuxContainerExecutor.Commands.LaunchContainer.GetValue().ToString( ); string appId = "APP_ID"; string containerId = "CONTAINER_ID"; Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container container = Org.Mockito.Mockito.Mock <Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container >(); ContainerId cId = Org.Mockito.Mockito.Mock <ContainerId>(); ContainerLaunchContext context = Org.Mockito.Mockito.Mock <ContainerLaunchContext> (); Dictionary <string, string> env = new Dictionary <string, string>(); Org.Mockito.Mockito.When(container.GetContainerId()).ThenReturn(cId); Org.Mockito.Mockito.When(container.GetLaunchContext()).ThenReturn(context); Org.Mockito.Mockito.DoAnswer(new _Answer_254()).When(container).Handle(Matchers.Any <ContainerDiagnosticsUpdateEvent>()); Org.Mockito.Mockito.When(cId.ToString()).ThenReturn(containerId); Org.Mockito.Mockito.When(context.GetEnvironment()).ThenReturn(env); Path scriptPath = new Path("file:///bin/echo"); Path tokensPath = new Path("file:///dev/null"); Path workDir = new Path("/tmp"); Path pidFile = new Path(workDir, "pid.txt"); mockExec.ActivateContainer(cId, pidFile); int ret = mockExec.LaunchContainer(container, scriptPath, tokensPath, appSubmitter , appId, workDir, dirsHandler.GetLocalDirs(), dirsHandler.GetLogDirs()); NUnit.Framework.Assert.AreNotSame(0, ret); NUnit.Framework.Assert.AreEqual(Arrays.AsList(YarnConfiguration.DefaultNmNonsecureModeLocalUser , appSubmitter, cmd, appId, containerId, workDir.ToString(), "/bin/echo", "/dev/null" , pidFile.ToString(), StringUtils.Join(",", dirsHandler.GetLocalDirs()), StringUtils .Join(",", dirsHandler.GetLogDirs()), "cgroups=none"), ReadMockParams()); }
CreateMockedContainer(ApplicationId appId, int containerId) { ApplicationAttemptId appAttemptId = BuilderUtils.NewApplicationAttemptId(appId, 1 ); ContainerId cId = BuilderUtils.NewContainerId(appAttemptId, containerId); Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container c = Org.Mockito.Mockito.Mock <Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container >(); Org.Mockito.Mockito.When(c.GetContainerId()).ThenReturn(cId); ContainerLaunchContext launchContext = Org.Mockito.Mockito.Mock <ContainerLaunchContext >(); Org.Mockito.Mockito.When(c.GetLaunchContext()).ThenReturn(launchContext); Org.Mockito.Mockito.When(launchContext.GetApplicationACLs()).ThenReturn(new Dictionary <ApplicationAccessType, string>()); return(c); }
public virtual int Call() { // dispatcher not typed ContainerLaunchContext launchContext = container.GetLaunchContext(); IDictionary <Path, IList <string> > localResources = null; ContainerId containerID = container.GetContainerId(); string containerIdStr = ConverterUtils.ToString(containerID); IList <string> command = launchContext.GetCommands(); int ret = -1; // CONTAINER_KILLED_ON_REQUEST should not be missed if the container // is already at KILLING if (container.GetContainerState() == ContainerState.Killing) { dispatcher.GetEventHandler().Handle(new ContainerExitEvent(containerID, ContainerEventType .ContainerKilledOnRequest, Shell.Windows ? ContainerExecutor.ExitCode.ForceKilled .GetExitCode() : ContainerExecutor.ExitCode.Terminated.GetExitCode(), "Container terminated before launch." )); return(0); } try { localResources = container.GetLocalizedResources(); if (localResources == null) { throw RPCUtil.GetRemoteException("Unable to get local resources when Container " + containerID + " is at " + container.GetContainerState()); } string user = container.GetUser(); // /////////////////////////// Variable expansion // Before the container script gets written out. IList <string> newCmds = new AList <string>(command.Count); string appIdStr = app.GetAppId().ToString(); string relativeContainerLogDir = Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Launcher.ContainerLaunch .GetRelativeContainerLogDir(appIdStr, containerIdStr); Path containerLogDir = dirsHandler.GetLogPathForWrite(relativeContainerLogDir, false ); foreach (string str in command) { // TODO: Should we instead work via symlinks without this grammar? newCmds.AddItem(ExpandEnvironment(str, containerLogDir)); } launchContext.SetCommands(newCmds); IDictionary <string, string> environment = launchContext.GetEnvironment(); // Make a copy of env to iterate & do variable expansion foreach (KeyValuePair <string, string> entry in environment) { string value = entry.Value; value = ExpandEnvironment(value, containerLogDir); entry.SetValue(value); } // /////////////////////////// End of variable expansion FileContext lfs = FileContext.GetLocalFSFileContext(); Path nmPrivateContainerScriptPath = dirsHandler.GetLocalPathForWrite(GetContainerPrivateDir (appIdStr, containerIdStr) + Path.Separator + ContainerScript); Path nmPrivateTokensPath = dirsHandler.GetLocalPathForWrite(GetContainerPrivateDir (appIdStr, containerIdStr) + Path.Separator + string.Format(ContainerLocalizer.TokenFileNameFmt , containerIdStr)); Path nmPrivateClasspathJarDir = dirsHandler.GetLocalPathForWrite(GetContainerPrivateDir (appIdStr, containerIdStr)); DataOutputStream containerScriptOutStream = null; DataOutputStream tokensOutStream = null; // Select the working directory for the container Path containerWorkDir = dirsHandler.GetLocalPathForWrite(ContainerLocalizer.Usercache + Path.Separator + user + Path.Separator + ContainerLocalizer.Appcache + Path.Separator + appIdStr + Path.Separator + containerIdStr, LocalDirAllocator.SizeUnknown, false ); string pidFileSubpath = GetPidFileSubpath(appIdStr, containerIdStr); // pid file should be in nm private dir so that it is not // accessible by users pidFilePath = dirsHandler.GetLocalPathForWrite(pidFileSubpath); IList <string> localDirs = dirsHandler.GetLocalDirs(); IList <string> logDirs = dirsHandler.GetLogDirs(); IList <string> containerLogDirs = new AList <string>(); foreach (string logDir in logDirs) { containerLogDirs.AddItem(logDir + Path.Separator + relativeContainerLogDir); } if (!dirsHandler.AreDisksHealthy()) { ret = ContainerExitStatus.DisksFailed; throw new IOException("Most of the disks failed. " + dirsHandler.GetDisksHealthReport (false)); } try { // /////////// Write out the container-script in the nmPrivate space. IList <Path> appDirs = new AList <Path>(localDirs.Count); foreach (string localDir in localDirs) { Path usersdir = new Path(localDir, ContainerLocalizer.Usercache); Path userdir = new Path(usersdir, user); Path appsdir = new Path(userdir, ContainerLocalizer.Appcache); appDirs.AddItem(new Path(appsdir, appIdStr)); } containerScriptOutStream = lfs.Create(nmPrivateContainerScriptPath, EnumSet.Of(CreateFlag .Create, CreateFlag.Overwrite)); // Set the token location too. environment[ApplicationConstants.ContainerTokenFileEnvName] = new Path(containerWorkDir , FinalContainerTokensFile).ToUri().GetPath(); // Sanitize the container's environment SanitizeEnv(environment, containerWorkDir, appDirs, containerLogDirs, localResources , nmPrivateClasspathJarDir); // Write out the environment exec.WriteLaunchEnv(containerScriptOutStream, environment, localResources, launchContext .GetCommands()); // /////////// End of writing out container-script // /////////// Write out the container-tokens in the nmPrivate space. tokensOutStream = lfs.Create(nmPrivateTokensPath, EnumSet.Of(CreateFlag.Create, CreateFlag .Overwrite)); Credentials creds = container.GetCredentials(); creds.WriteTokenStorageToStream(tokensOutStream); } finally { // /////////// End of writing out container-tokens IOUtils.Cleanup(Log, containerScriptOutStream, tokensOutStream); } // LaunchContainer is a blocking call. We are here almost means the // container is launched, so send out the event. dispatcher.GetEventHandler().Handle(new ContainerEvent(containerID, ContainerEventType .ContainerLaunched)); context.GetNMStateStore().StoreContainerLaunched(containerID); // Check if the container is signalled to be killed. if (!shouldLaunchContainer.CompareAndSet(false, true)) { Log.Info("Container " + containerIdStr + " not launched as " + "cleanup already called" ); ret = ContainerExecutor.ExitCode.Terminated.GetExitCode(); } else { exec.ActivateContainer(containerID, pidFilePath); ret = exec.LaunchContainer(container, nmPrivateContainerScriptPath, nmPrivateTokensPath , user, appIdStr, containerWorkDir, localDirs, logDirs); } } catch (Exception e) { Log.Warn("Failed to launch container.", e); dispatcher.GetEventHandler().Handle(new ContainerExitEvent(containerID, ContainerEventType .ContainerExitedWithFailure, ret, e.Message)); return(ret); } finally { completed.Set(true); exec.DeactivateContainer(containerID); try { context.GetNMStateStore().StoreContainerCompleted(containerID, ret); } catch (IOException) { Log.Error("Unable to set exit code for container " + containerID); } } if (Log.IsDebugEnabled()) { Log.Debug("Container " + containerIdStr + " completed with exit code " + ret); } if (ret == ContainerExecutor.ExitCode.ForceKilled.GetExitCode() || ret == ContainerExecutor.ExitCode .Terminated.GetExitCode()) { // If the process was killed, Send container_cleanedup_after_kill and // just break out of this method. dispatcher.GetEventHandler().Handle(new ContainerExitEvent(containerID, ContainerEventType .ContainerKilledOnRequest, ret, "Container exited with a non-zero exit code " + ret)); return(ret); } if (ret != 0) { Log.Warn("Container exited with a non-zero exit code " + ret); this.dispatcher.GetEventHandler().Handle(new ContainerExitEvent(containerID, ContainerEventType .ContainerExitedWithFailure, ret, "Container exited with a non-zero exit code " + ret)); return(ret); } Log.Info("Container " + containerIdStr + " succeeded "); dispatcher.GetEventHandler().Handle(new ContainerEvent(containerID, ContainerEventType .ContainerExitedWithSuccess)); return(0); }
/// <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 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); }
/// <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); }
public virtual void TestContainerLaunchError() { if (Shell.Windows) { BaseTmpPath = new Path(new FilePath("target").GetAbsolutePath(), typeof(TestDefaultContainerExecutor ).Name); } Path localDir = new Path(BaseTmpPath, "localDir"); IList <string> localDirs = new AList <string>(); localDirs.AddItem(localDir.ToString()); IList <string> logDirs = new AList <string>(); Path logDir = new Path(BaseTmpPath, "logDir"); logDirs.AddItem(logDir.ToString()); Configuration conf = new Configuration(); conf.Set(CommonConfigurationKeys.FsPermissionsUmaskKey, "077"); conf.Set(YarnConfiguration.NmLocalDirs, localDir.ToString()); conf.Set(YarnConfiguration.NmLogDirs, logDir.ToString()); FileContext lfs = FileContext.GetLocalFSFileContext(conf); DefaultContainerExecutor mockExec = Org.Mockito.Mockito.Spy(new DefaultContainerExecutor (lfs)); mockExec.SetConf(conf); Org.Mockito.Mockito.DoAnswer(new _Answer_245()).When(mockExec).LogOutput(Matchers.Any <string>()); string appSubmitter = "nobody"; string appId = "APP_ID"; string containerId = "CONTAINER_ID"; Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container container = Org.Mockito.Mockito.Mock <Org.Apache.Hadoop.Yarn.Server.Nodemanager.Containermanager.Container.Container >(); ContainerId cId = Org.Mockito.Mockito.Mock <ContainerId>(); ContainerLaunchContext context = Org.Mockito.Mockito.Mock <ContainerLaunchContext> (); Dictionary <string, string> env = new Dictionary <string, string>(); Org.Mockito.Mockito.When(container.GetContainerId()).ThenReturn(cId); Org.Mockito.Mockito.When(container.GetLaunchContext()).ThenReturn(context); try { Org.Mockito.Mockito.DoAnswer(new _Answer_268()).When(container).Handle(Matchers.Any <ContainerDiagnosticsUpdateEvent>()); Org.Mockito.Mockito.When(cId.ToString()).ThenReturn(containerId); Org.Mockito.Mockito.When(cId.GetApplicationAttemptId()).ThenReturn(ApplicationAttemptId .NewInstance(ApplicationId.NewInstance(0, 1), 0)); Org.Mockito.Mockito.When(context.GetEnvironment()).ThenReturn(env); mockExec.CreateUserLocalDirs(localDirs, appSubmitter); mockExec.CreateUserCacheDirs(localDirs, appSubmitter); mockExec.CreateAppDirs(localDirs, appSubmitter, appId); mockExec.CreateAppLogDirs(appId, logDirs, appSubmitter); Path scriptPath = new Path("file:///bin/echo"); Path tokensPath = new Path("file:///dev/null"); if (Shell.Windows) { FilePath tmp = new FilePath(BaseTmpPath.ToString(), "test_echo.cmd"); BufferedWriter output = new BufferedWriter(new FileWriter(tmp)); output.Write("Exit 1"); output.Write("Echo No such file or directory 1>&2"); output.Close(); scriptPath = new Path(tmp.GetAbsolutePath()); tmp = new FilePath(BaseTmpPath.ToString(), "tokens"); tmp.CreateNewFile(); tokensPath = new Path(tmp.GetAbsolutePath()); } Path workDir = localDir; Path pidFile = new Path(workDir, "pid.txt"); mockExec.Init(); mockExec.ActivateContainer(cId, pidFile); int ret = mockExec.LaunchContainer(container, scriptPath, tokensPath, appSubmitter , appId, workDir, localDirs, localDirs); NUnit.Framework.Assert.AreNotSame(0, ret); } finally { mockExec.DeleteAsUser(appSubmitter, localDir); mockExec.DeleteAsUser(appSubmitter, logDir); } }