Esempio n. 1
0
        public Container(
            string id,
            string handle,
            IContainerUser user,
            IContainerDirectory directory,
            IContainerPropertyService propertyService,
            ILocalTcpPortManager tcpPortManager,
            JobObject jobObject,
            DiskQuotaControl diskQuotaControl,
            IProcessRunner processRunner,
            IProcessRunner constrainedProcessRunner,
            ProcessHelper processHelper,
            Dictionary<string, string> defaultEnvironment,
            ContainerHostDependencyHelper dependencyHelper
            )
        {
            this.id = id;
            this.handle = handle;
            this.user = user;
            this.directory = directory;
            this.propertyService = propertyService;
            this.tcpPortManager = tcpPortManager;
            this.jobObject = jobObject;
            this.diskQuotaControl = diskQuotaControl;
            this.processRunner = processRunner;
            this.constrainedProcessRunner = constrainedProcessRunner;
            this.processHelper = processHelper;
            this.dependencyHelper = dependencyHelper;
            this.defaultEnvironment = defaultEnvironment ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            this.currentState = ContainerState.Active;
        }
 public ProcessTracker(IMessageTransport transport, JobObject jobObject, IProcess hostProcess, ProcessHelper processHelper)
 {
     this.transport = transport;
     this.jobObject = jobObject;
     this.hostProcess = hostProcess;
     this.processHelper = processHelper;
 }
        public void GuardDoesNotRetainReferenceToParentJobObject()
        {
            var st = new Stopwatch();
            st.Start();
            while (st.ElapsedMilliseconds < 5 * 1000)
            {
                try
                {
                    using (var gJobObject = new JobObject("Global\\" + username + "-guard", true))
                    {
                        break;
                    }
                }
                catch
                {
                    // retry
                }
            }

            Assert.False(guardProcess.HasExited);

            // Act
            this.jobObject.Dispose();

            // Assert
            guardProcess.WaitForExit(1000);
            Assert.True(guardProcess.HasExited);
        }
Esempio n. 4
0
 public static Process ExecuteInJob(JobObject jobObject, string command, params object[] args)
 {
     var process = ExecuteWithWait(command, args);
     jobObject.AssignProcessToJob(process);
     ContinueAndWait(process);
     return process;
 }
Esempio n. 5
0
        public void TerminateThrowsIfJobObjectIsDisposed()
        {
            JobObject jobObject = new JobObject();

            jobObject.Dispose();

            Assert.Throws <ObjectDisposedException>(() => jobObject.TerminateProcesses());
        }
        public IContainerHostClient StartContainerHost(string containerId, IContainerDirectory directory, JobObject jobObject, NetworkCredential credentials)
        {
            CopyHostToContainer(directory);

            var hostRunSpec = new ProcessRunSpec
            {
                ExecutablePath = directory.MapBinPath(dependencyHelper.ContainerHostExe),
                Arguments = new[] { containerId },
                BufferedInputOutput = true,
                WorkingDirectory = directory.UserPath,
                Credentials = credentials,
            };

            // Order here is important.
            // - Start the process
            // - Add the process to the job object
            // - Verify that the process is healthy
            // - Start the RPC message pump
            //
            // We need to ensure that the host process cannot create any new processes before
            // it's added to the job object.

            var hostProcess = processRunner.Run(hostRunSpec);
            jobObject.AssignProcessToJob(hostProcess.Handle);
            WaitForProcessToStart(hostProcess, HostProcessStartTimeout);

            var messageTransport = MessageTransport.Create(hostProcess.StandardOutput, hostProcess.StandardInput);
            var messagingClient = MessagingClient.Create(async message =>
            {
                await messageTransport.PublishRequestAsync(message);
            });

            messageTransport.SubscribeResponse(message =>
            {
                messagingClient.PublishResponse(message);
                return Task.FromResult(0);
            });

            messageTransport.SubscribeEvent(@event =>
            {
                try
                {
                    messagingClient.PublishEvent(@event);
                }
                catch (Exception e)
                {
                    log.Log(LogLevel.Error, e.ToString(), e);
                }
                return Task.FromResult(0);
            });

            var containerHostClient = new ContainerHostClient(hostProcess, messageTransport, messagingClient, jobObject);

            messageTransport.Start();

            return containerHostClient;
        }
Esempio n. 7
0
        public void DisposingJobObjectCleansUpHandle()
        {
            JobObject jobObject = null;

            jobObject = new JobObject();

            jobObject.Dispose();

            Assert.Null(jobObject.Handle);
        }
        public GuardAcceptanceTests()
        {
            this.userManager = new LocalPrincipalManager();
               userManager.CreateUser(username);

               this.jobObject = new JobObject(username);
               var guardExePath = Path.Combine(Directory.GetCurrentDirectory(), "Guard.exe");

               this.guardProcess = Process.Start(new ProcessStartInfo()
               {
               FileName = guardExePath,
               Arguments = String.Format("{0} {1}", username, username),
               });
        }
Esempio n. 9
0
            public void GetQueuedCompletionStatus_ForkBomb_DoesHaveLimitViolation()
            {
                using (var jobObject = new JobObject())
                {
                    jobObject.SetActiveProcessLimit(2);

                    var process = IFTestHelper.ExecuteWithWait("fork-bomb");
                    jobObject.AssignProcessToJob(process);
                    IFTestHelper.Continue(process);
                    process.WaitForExit(1000);

                    var msgs = jobObject.GetQueuedCompletionStatus();
                    Assert.Contains(msgs, x => x == JobObject.CompletionMsg.ActiveProcessLimit);
                }
            }
Esempio n. 10
0
            public void GetQueuedCompletionStatus_CanLimitMemory()
            {
                using (var jobObject = new JobObject())
                {
                    const ulong limitInBytes  = 1024 * 1024 * 25; // 25MB
                    const ulong allocateBytes = limitInBytes * 2;

                    jobObject.SetJobMemoryLimit(limitInBytes);

                    var process = IFTestHelper.ExecuteInJob(jobObject, "allocate-memory", "--bytes", allocateBytes);
                    process.WaitForExit(1000);

                    var msgs = jobObject.GetQueuedCompletionStatus();
                    Assert.Contains(msgs, x => x == JobObject.CompletionMsg.JobMemoryLimit);
                }
            }
Esempio n. 11
0
        public void CreatingJobObjectBySameNameGivesEquivalentJobObject()
        {
            using (var jobObject = new JobObject("TestJobObjectName"))
                using (var otherJobObject = new JobObject("TestJobObjectName"))
                    using (Process p = Process.Start("cmd.exe"))
                    {
                        jobObject.AssignProcessToJob(p);

                        // Since there is no way to compare two JobObjects directly, we
                        // assume equivalency by their content.
                        var processIds      = jobObject.GetProcessIds();
                        var otherProcessids = otherJobObject.GetProcessIds();

                        p.Kill();

                        Assert.Equal(processIds, otherProcessids);
                    }
        }
Esempio n. 12
0
        public void CanAssignProcessToJobObject()
        {
            JobObject jobObject = new JobObject();

            Process p = null;
            try
            {
                p = Process.Start("cmd.exe");

                jobObject.AssignProcessToJob(p);

                bool isInJob;
                NativeMethods.IsProcessInJob(p.Handle, jobObject.Handle, out isInJob);
                Assert.True(isInJob);
            }
            finally
            {
                p.Kill();
            }
        }
Esempio n. 13
0
        public void CanAssignProcessToJobObject()
        {
            JobObject jobObject = new JobObject();

            Process p = null;

            try
            {
                p = Process.Start("cmd.exe");

                jobObject.AssignProcessToJob(p);

                bool isInJob;
                NativeMethods.IsProcessInJob(p.Handle, jobObject.Handle, out isInJob);
                Assert.True(isInJob);
            }
            finally
            {
                p.Kill();
            }
        }
Esempio n. 14
0
        public void CanTerminateAndWaitForObjectsUnderJobObject()
        {
            JobObject jobObject = new JobObject();

            Process p = null;
            try
            {
                p = IFTestHelper.ExecuteWithWait("nop");
                jobObject.AssignProcessToJob(p);

                jobObject.TerminateProcessesAndWait(1000);

                IFTestHelper.ContinueAndWait(p, timeout: 1000);
                Assert.True(p.HasExited);
            }
            finally
            {
                if (!p.HasExited)
                    p.Kill();
            }
        }
Esempio n. 15
0
        public void SetActiveProcessLimit_StopsForkBomb()
        {
            using (var jobObject = new JobObject())
            {
                jobObject.SetActiveProcessLimit(2);

                var process = IFTestHelper.ExecuteWithWait("fork-bomb");
                jobObject.AssignProcessToJob(process);
                IFTestHelper.Continue(process);
                process.WaitForExit(1000);
                var hasExited = process.HasExited;
                if (!hasExited)
                {
                    process.Kill();
                }
                if (!hasExited)
                {
                    Console.WriteLine(process.StandardOutput.ReadToEnd());
                    Console.Error.WriteLine(process.StandardError.ReadToEnd());
                }
                Assert.True(hasExited, "Active process limit was not enforced");
            }
        }
Esempio n. 16
0
        public void CanTerminateAndWaitForObjectsUnderJobObject()
        {
            JobObject jobObject = new JobObject();

            Process p = null;

            try
            {
                p = IFTestHelper.ExecuteWithWait("nop");
                jobObject.AssignProcessToJob(p);

                jobObject.TerminateProcessesAndWait(1000);

                IFTestHelper.ContinueAndWait(p, timeout: 1000);
                Assert.True(p.HasExited);
            }
            finally
            {
                if (!p.HasExited)
                {
                    p.Kill();
                }
            }
        }
Esempio n. 17
0
        public void ClosingLastHandleKillsProcess()
        {
            JobObject jobObject = new JobObject();

            Process p = null;

            try
            {
                p = Process.Start("cmd.exe");
                jobObject.AssignProcessToJob(p);

                jobObject.Dispose();

                p.WaitForExit(2000);
                Assert.True(p.HasExited);
            }
            finally
            {
                if (!p.HasExited)
                {
                    p.Kill();
                }
            }
        }
Esempio n. 18
0
 public CpuStatistics()
 {
     jobObject = new JobObject();
 }
Esempio n. 19
0
 public JobCpuLimits()
 {
     jobObject  = new JobObject();
     jobObject2 = new JobObject();
 }
Esempio n. 20
0
 public JobMemoryLimits()
 {
     jobObject = new JobObject();
 }
Esempio n. 21
0
 public JobCpuLimits()
 {
     jobObject = new JobObject();
     jobObject2 = new JobObject();
 }
Esempio n. 22
0
        public JobObjectLimitsTests()
        {
            jobObject = Substitute.For <JobObject>();

            jobObjectLimits = new JobObjectLimits(jobObject, TimeSpan.FromMilliseconds(10));
        }
Esempio n. 23
0
        public void CreatingJobObjectBySameNameGivesEquivalentJobObject()
        {
            using (var jobObject = new JobObject("TestJobObjectName"))
            using (var otherJobObject = new JobObject("TestJobObjectName"))
            using (Process p = Process.Start("cmd.exe"))
            {
                jobObject.AssignProcessToJob(p);

                // Since there is no way to compare two JobObjects directly, we
                // assume equivalency by their content.
                var processIds = jobObject.GetProcessIds();
                var otherProcessids = otherJobObject.GetProcessIds();

                p.Kill();

                Assert.Equal(processIds, otherProcessids);
            }
        }
Esempio n. 24
0
 public void CreatingJobObjectGetsValidHandle()
 {
     var jobObject = new JobObject();
     Assert.False(jobObject.Handle.IsInvalid);
 }
Esempio n. 25
0
 public ClipboardTests()
 {
     jobObject = new JobObject();
 }
Esempio n. 26
0
        public void CreatingJobObjectGetsValidHandle()
        {
            var jobObject = new JobObject();

            Assert.False(jobObject.Handle.IsInvalid);
        }
Esempio n. 27
0
        static void Main(string[] args)
        {
            //Debugger.Launch();

            if (args.Length == 0)
                ExitWithError("Must specify container-id as the first argument.", -1);

            containerId = args[0];

            hostJobObject = new JobObject(null);

            hostProcess = ProcessHelper.WrapProcess(Process.GetCurrentProcess());

            var input = Console.In;
            var output = Console.Out;

            using (var transport = MessageTransport.Create(input, output))
            {
                processTracker = new ProcessTracker(transport, hostJobObject, hostProcess, new ProcessHelper());

                var createProcessHandler = new CreateProcessHandler(new ProcessRunner(), processTracker);
                var pingHandler = new PingHandler();
                var findProcessByIdHandler = new FindProcessByIdHandler(processTracker);
                var stopProcessHandler = new StopProcessHandler(processTracker);
                var stopAllProcessesHandler = new StopAllProcessesHandler(processTracker);
                var waitForProcessExitHandler = new WaitForProcessExitHandler(processTracker);

                var dispatcher = new MessageDispatcher();
                dispatcher.RegisterMethod<CreateProcessRequest>(
                    CreateProcessRequest.MethodName,
                    async (request) =>
                    {
                        var result = await createProcessHandler.ExecuteAsync(request.@params);
                        return new CreateProcessResponse(request.id, result);
                    });
                dispatcher.RegisterMethod<PingRequest>(
                    PingRequest.MethodName,
                    async (request) =>
                    {
                        await pingHandler.ExecuteAsync();
                        return new PingResponse(request.id);
                    });
                dispatcher.RegisterMethod<FindProcessByIdRequest>(
                    FindProcessByIdRequest.MethodName,
                    async (request) =>
                    {
                        var result = await findProcessByIdHandler.ExecuteAsync(request.@params);
                        return new FindProcessByIdResponse(request.id, result);
                    });
                dispatcher.RegisterMethod<StopProcessRequest>(
                    StopProcessRequest.MethodName,
                    async (request) =>
                    {
                        await stopProcessHandler.ExecuteAsync(request.@params);
                        return new StopProcessResponse(request.id);
                    });
                dispatcher.RegisterMethod<StopAllProcessesRequest>(
                    StopAllProcessesRequest.MethodName,
                    async (request) =>
                    {
                        await stopAllProcessesHandler.ExecuteAsync(request.@params);
                        return new StopAllProcessesResponse(request.id);
                    });
                dispatcher.RegisterMethod<WaitForProcessExitRequest>(
                    WaitForProcessExitRequest.MethodName,
                    async (request) =>
                    {
                        var result = await waitForProcessExitHandler.ExecuteAsync(request.@params);
                        return new WaitForProcessExitResponse(request.id, result);
                    });

                transport.SubscribeRequest(
                    async (request) =>
                    {
                        var response = await dispatcher.DispatchAsync(request);
                        await transport.PublishResponseAsync(response);
                    });

                transport.Start();

                ReportOk();
                exitEvent.WaitOne();
            }
        }
Esempio n. 28
0
 public JobObjectLimits(JobObject jobObject, TimeSpan? pollPeriod = null)
 {
     this.jobObject = jobObject;
     this.pollPeriod = pollPeriod ?? DefaultPollPeriod;
 }
Esempio n. 29
0
 public CpuStatistics()
 {
     jobObject = new JobObject();
 }
Esempio n. 30
0
        public void ClosingLastHandleKillsProcess()
        {
            JobObject jobObject = new JobObject();

            Process p = null;
            try
            {
                p = Process.Start("cmd.exe");
                jobObject.AssignProcessToJob(p);

                jobObject.Dispose();

                p.WaitForExit(2000);
                Assert.True(p.HasExited);
            }
            finally
            {
                if (!p.HasExited)
                    p.Kill();
            }
        }
Esempio n. 31
0
 public ProcessIds()
 {
     jobObject = new JobObject();
 }
Esempio n. 32
0
        public void OpeningNonExistingJobObjectThrows()
        {
            var ex = Record.Exception(() => { var otherJobObject = new JobObject("TestJobObjectName", true); });

            Assert.NotNull(ex);
        }
Esempio n. 33
0
 public ProcessIds()
 {
     jobObject = new JobObject();
 }
Esempio n. 34
0
        public void TerminateThrowsIfJobObjectIsDisposed()
        {
            JobObject jobObject = new JobObject();
            jobObject.Dispose();

            Assert.Throws<ObjectDisposedException>(() => jobObject.TerminateProcesses());
        }
Esempio n. 35
0
 public ClipboardTests()
 {
     jobObject = new JobObject();
 }
Esempio n. 36
0
        public void SetActiveProcessLimit_StopsForkBomb()
        {
            using (var jobObject = new JobObject())
            {
                jobObject.SetActiveProcessLimit(2);

                var process = IFTestHelper.ExecuteWithWait("fork-bomb");
                jobObject.AssignProcessToJob(process);
                IFTestHelper.Continue(process);
                process.WaitForExit(1000);
                var hasExited = process.HasExited;
                if(!hasExited) process.Kill();
                if (!hasExited)
                {
                    Console.WriteLine(process.StandardOutput.ReadToEnd());
                    Console.Error.WriteLine(process.StandardError.ReadToEnd());
                }
                Assert.True(hasExited, "Active process limit was not enforced");
            }
        }
Esempio n. 37
0
 public void OpeningNonExistingJobObjectThrows()
 {
     var ex = Record.Exception(() => { var otherJobObject = new JobObject("TestJobObjectName", true); });
     Assert.NotNull(ex);
 }
Esempio n. 38
0
        public void DisposingJobObjectCleansUpHandle()
        {
            JobObject jobObject = null;
            jobObject = new JobObject();

            jobObject.Dispose();

            Assert.Null(jobObject.Handle);
        }
            public void PutsEscapedUserProcessesBackIntoJobObject()
            {
                Container1.StartGuard();

                // ping.exe is a Console app. Windows will start a conhost for ping.exe which
                // is by default outside job objects. We want to assert that all processes
                // including conhost is added back to the JobObject.
                var username = ContainerUsername(Container1);

                var userPids = UserPids(username);
                var pidsInJob = new List<int>();
                var sw = Stopwatch.StartNew();
                while (userPids.Count != pidsInJob.Count && sw.ElapsedMilliseconds < 1000)
                {
                    pidsInJob = new JobObject(Container1.Id).GetProcessIds().ToList();
                }
                pidsInJob.Sort();

                Assert.Equal(userPids, pidsInJob);
            }
Esempio n. 40
0
 public JobMemoryLimits()
 {
     jobObject = new JobObject();
 }
        public IContainer CreateContainer(ContainerSpec containerSpec)
        {
            Guard.NotNull(containerSpec, "containerSpec");

            UndoStack undoStack = new UndoStack();
            IContainer container;

            try
            {
                var handle = containerSpec.Handle;
                if (String.IsNullOrEmpty(handle))
                    handle = handleHelper.GenerateHandle();

                var id = handleHelper.GenerateId(handle);

                var user = ContainerUser.Create(userManager, id);
                undoStack.Push(() => user.Delete());

                var directory = directoryFactory.Create(fileSystem, containerBasePath, id);
                directory.CreateSubdirectories(user);
                undoStack.Push(directory.Destroy);

                directory.CreateBindMounts(containerSpec.BindMounts, user);

                var jobObject = new JobObject(id);
                undoStack.Push(() => jobObject.Dispose());

                var containerHostClient = containerHostService.StartContainerHost(id, directory, jobObject, user.GetCredential());
                undoStack.Push(() => containerHostClient.Shutdown());

                var constrainedProcessRunner = new ConstrainedProcessRunner(containerHostClient);
                undoStack.Push(() => constrainedProcessRunner.Dispose());

                var processHelper = new ProcessHelper();
                var dependencyHelper = new ContainerHostDependencyHelper();

                var diskQuotaControl = diskQuotaManager.CreateDiskQuotaControl(directory);

                container = new Container(
                    id,
                    handle,
                    user,
                    directory,
                    containerPropertiesService,
                    tcpPortManager,
                    jobObject,
                    diskQuotaControl,
                    processRunner,
                    constrainedProcessRunner,
                    processHelper,
                    containerSpec.Environment,
                    dependencyHelper);

                containerPropertiesService.SetProperties(container, containerSpec.Properties);
                lock (containers)
                {
                    containers.Add(container);
                }
            }
            catch (Exception e)
            {
                try
                {
                    undoStack.UndoAll();
                    throw;
                }
                catch (AggregateException undoException)
                {
                    throw new AggregateException(new[] { e, undoException });
                }
            }

            return container;
        }
        IContainer RestoreContainerFromPath(string containerPath)
        {
            var id = Path.GetFileName(containerPath);

            var user = ContainerUser.Restore(userManager, id);
            var directory = ContainerDirectory.Restore(fileSystem, containerPath);

            var jobObjectName = id;
            var jobObject = new JobObject(jobObjectName);

            var environment = new Dictionary<string, string>();
            var processHelper = new ProcessHelper();

            var diskQuotaControl = new DiskQuotaControl();
            diskQuotaControl.UserNameResolution = UserNameResolutionConstants.dqResolveNone;
            diskQuotaControl.Initialize(directory.Volume, true);

            var dependencyHelper = new ContainerHostDependencyHelper();

            var container = new Container(
                id,
                id, // TODO: Recover the handle from container metadata
                user,
                directory,
                containerPropertiesService,
                tcpPortManager,
                jobObject,
                diskQuotaControl,
                processRunner,
                processRunner,
                processHelper,
                environment,
                dependencyHelper);

            return container;
        }
Esempio n. 43
0
 public JobObjectLimits(JobObject jobObject, TimeSpan?pollPeriod = null)
 {
     this.jobObject  = jobObject;
     this.pollPeriod = pollPeriod ?? DefaultPollPeriod;
 }
        public JobObjectLimitsTests()
        {
            jobObject = Substitute.For<JobObject>();

            jobObjectLimits = new JobObjectLimits(jobObject, TimeSpan.FromMilliseconds(10));
        }