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 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; }
Stream OpenOrCreateFile(IContainerDirectory directory, FileAccess fileAccess, FileShare fileShare) { const int MaxAttempt = 10; const int SleepPerAttempt = 250; var path = directory.MapPrivatePath(fileName); int attempt = 1; while (true) { try { return(fileSystem.OpenFile(path, FileMode.OpenOrCreate, fileAccess, (fileShare | FileShare.Delete))); } catch (UnauthorizedAccessException) { if (attempt >= MaxAttempt) { throw; } } attempt++; clock.Sleep(SleepPerAttempt); } }
public IContainer CreateContainer(string id, string handle, IContainerUser user, IContainerDirectory directory, IContainerPropertyService propertyService, ILocalTcpPortManager tcpPortManager, JobObject jobObject, IContainerDiskQuota containerDiskQuota, IProcessRunner processRunner, IProcessRunner constrainedProcessRunner, ProcessHelper processHelper, Dictionary <string, string> defaultEnvironment, ContainerHostDependencyHelper dependencyHelper, BindMount[] bindMounts) { return(new Container( id, handle, user, directory, propertyService, tcpPortManager, jobObject, containerDiskQuota, processRunner, constrainedProcessRunner, processHelper, defaultEnvironment, dependencyHelper, bindMounts )); }
public IContainerDiskQuota CreateDiskQuotaControl(IContainerDirectory dir, string sid) { var diskQuotaControl = new DiskQuotaControl(); diskQuotaControl.UserNameResolution = UserNameResolutionConstants.dqResolveNone; diskQuotaControl.Initialize(dir.Volume, true); return(new ContainerDiskQuota(diskQuotaControl, sid)); }
public DiskQuotaControl CreateDiskQuotaControl(IContainerDirectory dir) { var diskQuotaControl = new DiskQuotaControl(); diskQuotaControl.UserNameResolution = UserNameResolutionConstants.dqResolveNone; diskQuotaControl.Initialize(dir.Volume, true); return(diskQuotaControl); }
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 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 ContainerServiceTests() { ContainerBasePath = @"C:\Containers"; ContainerUserGroup = "ContainerUsers"; ContainerPropertiesService = Substitute.For <IContainerPropertyService>(); FileSystem = Substitute.For <IFileSystemManager>(); Id = "DEADBEEF"; HandleHelper = Substitute.For <ContainerHandleHelper>(); HandleHelper.GenerateId(null).ReturnsForAnyArgs(Id); ProcessRunner = Substitute.For <IProcessRunner>(); TcpPortManager = Substitute.For <ILocalTcpPortManager>(); UserManager = Substitute.For <IUserManager>(); ContainerHostClient = Substitute.For <IContainerHostClient>(); ContainerHostService = Substitute.For <IContainerHostService>(); ContainerHostService.StartContainerHost(null, null, null, null) .ReturnsForAnyArgs(ContainerHostClient); UserManager.CreateUser(null).ReturnsForAnyArgs(new NetworkCredential("username", "password")); sid = "S-1234"; UserManager.GetSID(null).ReturnsForAnyArgs(sid); diskQuotaManager = Substitute.For <IDiskQuotaManager>(); containerDiskQuota = Substitute.For <IContainerDiskQuota>(); diskQuotaManager.CreateDiskQuotaControl(null, "").ReturnsForAnyArgs(containerDiskQuota); var directoryFactory = Substitute.For <IContainerDirectoryFactory>(); containerDirectory = Substitute.For <IContainerDirectory>(); directoryFactory.Create(FileSystem, ContainerBasePath, Id).Returns(containerDirectory); var containerFactory = new TestContainerFactory(); Service = new ContainerService( HandleHelper, UserManager, FileSystem, ContainerPropertiesService, TcpPortManager, ProcessRunner, ContainerHostService, diskQuotaManager, directoryFactory, containerFactory, ContainerBasePath ); }
void UpdatePropertiesAtomically(IContainerDirectory directory, Action <Dictionary <string, string> > updateAction) { using (var fs = OpenOrCreateFile(directory, FileAccess.ReadWrite, FileShare.None)) { fs.Position = 0; var properties = Deserialize(fs); updateAction(properties); fs.Position = 0; Serialize(properties, fs); fs.SetLength(fs.Position); } }
public ContainerServiceTests() { ContainerBasePath = @"C:\Containers"; ContainerUserGroup = "ContainerUsers"; ContainerPropertiesService = Substitute.For<IContainerPropertyService>(); FileSystem = Substitute.For<IFileSystemManager>(); Id = "DEADBEEF"; HandleHelper = Substitute.For<ContainerHandleHelper>(); HandleHelper.GenerateId(null).ReturnsForAnyArgs(Id); ProcessRunner = Substitute.For<IProcessRunner>(); TcpPortManager = Substitute.For<ILocalTcpPortManager>(); UserManager = Substitute.For<IUserManager>(); ContainerHostClient = Substitute.For<IContainerHostClient>(); ContainerHostService = Substitute.For<IContainerHostService>(); ContainerHostService.StartContainerHost(null, null, null, null) .ReturnsForAnyArgs(ContainerHostClient); UserManager.CreateUser(null).ReturnsForAnyArgs(new NetworkCredential("username", "password")); UserManager.GetSID(null).ReturnsForAnyArgs("S-1234"); diskQuotaManager = Substitute.For<IDiskQuotaManager>(); diskQuotaControl = Substitute.For<DiskQuotaControl>(); diskQuotaManager.CreateDiskQuotaControl(null).ReturnsForAnyArgs(diskQuotaControl); var directoryFactory = Substitute.For<IContainerDirectoryFactory>(); containerDirectory = Substitute.For<IContainerDirectory>(); directoryFactory.Create(FileSystem, ContainerBasePath, Id).Returns(containerDirectory); Service = new ContainerService( HandleHelper, UserManager, FileSystem, ContainerPropertiesService, TcpPortManager, ProcessRunner, ContainerHostService, diskQuotaManager, directoryFactory, ContainerBasePath ); }
public ProcessCommandTests() { // Create a temporary directory to use as the container root tempDir = CreateTempDir(); handle = new ContainerHandle("TestContainerHandle"); user = Substitute.For <IContainerUser>(); user.UserName.Returns("TestUser"); user.GetCredential().ReturnsForAnyArgs(new System.Net.NetworkCredential("TestUser", "TestUserPassword")); directory = Substitute.For <IContainerDirectory>(); process = Substitute.For <IProcess>(); container = Substitute.For <IContainer>(); container.ContainerDirectoryPath.Returns(tempDir); }
public IContainer CreateContainer(string id, string handle, IContainerUser user, IContainerDirectory directory, IContainerPropertyService propertyService, ILocalTcpPortManager tcpPortManager, JobObject jobObject, IContainerDiskQuota containerDiskQuota, IProcessRunner processRunner, IProcessRunner constrainedProcessRunner, ProcessHelper processHelper, Dictionary <string, string> defaultEnvironment, ContainerHostDependencyHelper dependencyHelper, BindMount[] bindMounts) { if (handle == "KnownBadHandle") { var badContainer = Substitute.For <IContainer>(); badContainer.Handle.Returns("KnownBadHandle"); badContainer.When(x => x.Destroy()).Do(x => { if (destroyCount++ == 0) { throw new Exception(); } }); return(badContainer); } else { return(new Container( id, handle, user, directory, propertyService, tcpPortManager, jobObject, containerDiskQuota, processRunner, constrainedProcessRunner, processHelper, defaultEnvironment, dependencyHelper, bindMounts )); } }
private void CopyHostToContainer(IContainerDirectory directory) { fileSystem.CopyFile( dependencyHelper.ContainerHostExePath, directory.MapBinPath(dependencyHelper.ContainerHostExe)); // This check is here for the acceptance tests. // They get ContainerHost.exe by referencing the project. However, msbuild does // not copy .config files of referenced assemblies. Thus when running the acceptance // tests, the ContainerHost.exe used does not have an app.config. if (fileSystem.FileExists(dependencyHelper.ContainerHostExeConfigPath)) { fileSystem.CopyFile( dependencyHelper.ContainerHostExeConfigPath, directory.MapBinPath(dependencyHelper.ContainerHostExeConfig)); } foreach (var dependencyFilePath in dependencyHelper.GetContainerHostDependencies()) { var targetFilePath = directory.MapBinPath(Path.GetFileName(dependencyFilePath)); fileSystem.CopyFile(dependencyFilePath, targetFilePath); } }
void UpdatePropertiesAtomically(IContainerDirectory directory, Action<Dictionary<string, string>> updateAction) { using (var fs = OpenOrCreateFile(directory, FileAccess.ReadWrite, FileShare.None)) { fs.Position = 0; var properties = Deserialize(fs); updateAction(properties); fs.Position = 0; Serialize(properties, fs); fs.SetLength(fs.Position); } }
Stream OpenOrCreateFile(IContainerDirectory directory, FileAccess fileAccess, FileShare fileShare) { const int MaxAttempt = 10; const int SleepPerAttempt = 250; var path = directory.MapPrivatePath(fileName); int attempt = 1; while (true) { try { return fileSystem.OpenFile(path, FileMode.OpenOrCreate, fileAccess, (fileShare | FileShare.Delete)); } catch (UnauthorizedAccessException) { if (attempt >= MaxAttempt) throw; } attempt++; clock.Sleep(SleepPerAttempt); } }
private void CopyHostToContainer(IContainerDirectory directory) { fileSystem.CopyFile( dependencyHelper.ContainerHostExePath, directory.MapBinPath(dependencyHelper.ContainerHostExe)); // This check is here for the acceptance tests. // They get ContainerHost.exe by referencing the project. However, msbuild does // not copy .config files of referenced assemblies. Thus when running the acceptance // tests, the ContainerHost.exe used does not have an app.config. if (fileSystem.FileExists(dependencyHelper.ContainerHostExeConfigPath)) { fileSystem.CopyFile( dependencyHelper.ContainerHostExeConfigPath, directory.MapBinPath(dependencyHelper.ContainerHostExeConfig)); } foreach (var dependencyFilePath in dependencyHelper.GetContainerHostDependencies()) { var targetFilePath = directory.MapBinPath(Path.GetFileName(dependencyFilePath)); fileSystem.CopyFile(dependencyFilePath, targetFilePath); } }