Beispiel #1
0
 public override void Run()
 {
     try
     {
         Sharpen.Thread.Sleep(delay);
         containerExecutor.SignalContainer(user, pid, signal);
     }
     catch (Exception)
     {
         return;
     }
     catch (IOException e)
     {
         string message = "Exception when user " + user + " killing task " + pid + " in DelayedProcessKiller: "
                          + StringUtils.StringifyException(e);
         Log.Warn(message);
         container.Handle(new ContainerDiagnosticsUpdateEvent(container.GetContainerId(),
                                                              message));
     }
 }
Beispiel #2
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);
        }