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());
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
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);
        }
Beispiel #8
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);
            }
        }