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;
        }
Esempio n. 2
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;
        }
        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);
            }
        }
Esempio n. 4
0
 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
                ));
 }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
        public DiskQuotaControl CreateDiskQuotaControl(IContainerDirectory dir)
        {
            var diskQuotaControl = new DiskQuotaControl();

            diskQuotaControl.UserNameResolution = UserNameResolutionConstants.dqResolveNone;
            diskQuotaControl.Initialize(dir.Volume, true);
            return(diskQuotaControl);
        }
Esempio n. 7
0
        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
            );
        }
Esempio n. 12
0
        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
                               ));
                }
            }
Esempio n. 14
0
        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);
            }
        }