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); }
public static Process ExecuteInJob(JobObject jobObject, string command, params object[] args) { var process = ExecuteWithWait(command, args); jobObject.AssignProcessToJob(process); ContinueAndWait(process); return process; }
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; }
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), }); }
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); } }
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); } }
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); } }
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(); } }
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(); } }
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(); } }
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"); } }
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(); } } }
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(); } } }
public CpuStatistics() { jobObject = new JobObject(); }
public JobCpuLimits() { jobObject = new JobObject(); jobObject2 = new JobObject(); }
public JobMemoryLimits() { jobObject = new JobObject(); }
public JobCpuLimits() { jobObject = new JobObject(); jobObject2 = new JobObject(); }
public JobObjectLimitsTests() { jobObject = Substitute.For <JobObject>(); jobObjectLimits = new JobObjectLimits(jobObject, TimeSpan.FromMilliseconds(10)); }
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); } }
public void CreatingJobObjectGetsValidHandle() { var jobObject = new JobObject(); Assert.False(jobObject.Handle.IsInvalid); }
public ClipboardTests() { jobObject = new JobObject(); }
public void CreatingJobObjectGetsValidHandle() { var jobObject = new JobObject(); Assert.False(jobObject.Handle.IsInvalid); }
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(); } }
public JobObjectLimits(JobObject jobObject, TimeSpan? pollPeriod = null) { this.jobObject = jobObject; this.pollPeriod = pollPeriod ?? DefaultPollPeriod; }
public CpuStatistics() { jobObject = new JobObject(); }
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(); } }
public ProcessIds() { jobObject = new JobObject(); }
public void OpeningNonExistingJobObjectThrows() { var ex = Record.Exception(() => { var otherJobObject = new JobObject("TestJobObjectName", true); }); Assert.NotNull(ex); }
public ProcessIds() { jobObject = new JobObject(); }
public void TerminateThrowsIfJobObjectIsDisposed() { JobObject jobObject = new JobObject(); jobObject.Dispose(); Assert.Throws<ObjectDisposedException>(() => jobObject.TerminateProcesses()); }
public ClipboardTests() { jobObject = new JobObject(); }
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"); } }
public void OpeningNonExistingJobObjectThrows() { var ex = Record.Exception(() => { var otherJobObject = new JobObject("TestJobObjectName", true); }); Assert.NotNull(ex); }
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); }
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; }
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)); }