/// <summary> /// Creates instance /// </summary> public SandboxedProcessInfo( PathTable pathTable, ISandboxedProcessFileStorage fileStorage, string fileName, FileAccessManifest fileAccessManifest, bool disableConHostSharing, ContainerConfiguration containerConfiguration, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, IKextConnection sandboxedKextConnection = null) { Contract.Requires(pathTable != null); Contract.Requires(fileStorage != null); Contract.Requires(fileName != null); PathTable = pathTable; FileAccessManifest = fileAccessManifest; FileStorage = fileStorage; FileName = fileName; DisableConHostSharing = disableConHostSharing; // This should be set for testing purposes only. TestRetries = testRetries; NestedProcessTerminationTimeout = DefaultNestedProcessTerminationTimeout; LoggingContext = loggingContext; DetoursEventListener = detoursEventListener; SandboxedKextConnection = sandboxedKextConnection; ContainerConfiguration = containerConfiguration; }
/// <summary> /// Creates instance for test /// </summary> public SandboxedProcessInfo( PathTable pathTable, ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, IKextConnection sandboxedKextConnection = null, ContainerConfiguration containerConfiguration = null, FileAccessManifest fileAccessManifest = null) : this( pathTable, fileStorage, fileName, fileAccessManifest ?? new FileAccessManifest(pathTable), disableConHostSharing, containerConfiguration ?? ContainerConfiguration.DisabledIsolation, testRetries, loggingContext, detoursEventListener, sandboxedKextConnection) { Contract.Requires(pathTable != null); Contract.Requires(fileStorage != null); Contract.Requires(fileName != null); }
/// <summary> /// Creates an instances of this class. /// </summary> public SandboxedProcessOutput( long length, string value, string fileName, Encoding encoding, ISandboxedProcessFileStorage fileStorage, SandboxedProcessFile file, BuildXLException exception) { Contract.Requires((fileName == null && length >= 0) || (fileName != null && length >= NoLength) || exception != null); Contract.Requires(exception != null ^ (value != null ^ fileName != null)); Contract.Requires(value == null || length == value.Length); Contract.Requires(exception != null || encoding != null); Contract.Requires(exception != null || fileName != null || fileStorage != null); Contract.Requires(encoding != null); m_length = length; m_value = value; m_fileName = fileName; m_encoding = encoding; m_fileStorage = fileStorage; m_file = file; m_saveTask = m_fileName != null ? Unit.VoidTask : null; m_exception = exception; }
/// <summary> /// Creates an instances of this class. /// </summary> public SandboxedProcessOutput( long length, string value, string fileName, Encoding encoding, ISandboxedProcessFileStorage fileStorage, SandboxedProcessFile file, BuildXLException exception) { requires((fileName == null && length >= 0) || (fileName != null && length >= NoLength) || exception != null); requires(exception != null ^ (value != null ^ fileName != null)); requires(value == null || length == value.Length); requires(exception != null || encoding != null); requires(exception != null || fileName != null || fileStorage != null); requires(encoding != null); m_length = length; m_value = value; m_fileName = fileName; m_encoding = encoding; m_fileStorage = fileStorage; m_file = file; m_saveTask = m_fileName != null ? Unit.VoidTask : null; m_exception = exception; void requires(bool condition) { if (!condition) { throw Contract.AssertFailure($"length: {length}; value: '{value}'; filename: {fileName}; encoding: {encoding}; exception: {exception?.ToString()}"); } } }
/// <summary> /// Deserializes an instance of <see cref="SandboxedProcessOutput"/>. /// </summary> public static SandboxedProcessOutput Deserialize(BuildXLReader reader) { long length = reader.ReadInt64(); string value = reader.ReadNullableString(); string fileName = reader.ReadNullableString(); Encoding encoding = reader.ReadEncoding(); SandboxedProcessStandardFiles standardFiles = reader.ReadNullable(r => SandboxedProcessStandardFiles.Deserialize(r)); ISandboxedProcessFileStorage fileStorage = null; if (standardFiles != null) { fileStorage = new StandardFileStorage(standardFiles); } SandboxedProcessFile file = (SandboxedProcessFile)reader.ReadUInt32Compact(); BuildXLException exception = reader.ReadNullable(r => new BuildXLException(r.ReadNullableString(), (ExceptionRootCause)r.ReadUInt32Compact())); return(new SandboxedProcessOutput( length, value, fileName, encoding, fileStorage, file, exception)); }
/// <summary> /// Creates instance for test /// </summary> public SandboxedProcessInfo( PathTable pathTable, [CanBeNull] ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, LoggingContext loggingContext, bool testRetries = false, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, ContainerConfiguration containerConfiguration = null, FileAccessManifest fileAccessManifest = null, bool createJobObjectForCurrentProcess = true) : this( pathTable, fileStorage, fileName, fileAccessManifest ?? new FileAccessManifest(pathTable), disableConHostSharing, containerConfiguration ?? ContainerConfiguration.DisabledIsolation, loggingContext, testRetries, detoursEventListener, sandboxConnection, createJobObjectForCurrentProcess : createJobObjectForCurrentProcess) { Contract.Requires(pathTable != null); Contract.Requires(fileName != null); }
/// <summary> /// Creates instance /// </summary> public SandboxedProcessInfo( PathTable pathTable, [CanBeNull] ISandboxedProcessFileStorage fileStorage, string fileName, FileAccessManifest fileAccessManifest, bool disableConHostSharing, ContainerConfiguration containerConfiguration, LoggingContext loggingContext, bool testRetries = false, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, SidebandWriter sidebandWriter = null, bool createJobObjectForCurrentProcess = true) { Contract.Requires(pathTable != null); Contract.Requires(fileName != null); PathTable = pathTable; FileAccessManifest = fileAccessManifest; FileStorage = fileStorage; FileName = fileName; DisableConHostSharing = disableConHostSharing; // This should be set for testing purposes only. TestRetries = testRetries; NestedProcessTerminationTimeout = DefaultNestedProcessTerminationTimeout; LoggingContext = loggingContext; DetoursEventListener = detoursEventListener; SandboxConnection = sandboxConnection; ContainerConfiguration = containerConfiguration; SidebandWriter = sidebandWriter; CreateJobObjectForCurrentProcess = createJobObjectForCurrentProcess; }
/// <summary> /// Runs a sequence of RemoteApi commands in a <see cref="SandboxedProcess" />. /// </summary> public static async Task <SandboxedProcessResult> RunInSandboxAsync( LoggingContext loggingContext, PathTable pathTable, string workingDirectory, ISandboxedProcessFileStorage sandboxStorage, Action <FileAccessManifest> populateManifest, params Command[] commands) { Contract.Requires(!string.IsNullOrEmpty(workingDirectory)); Contract.Requires(populateManifest != null); if (!File.Exists(ExecutablePath)) { throw new BuildXLException("Expected to find RemoteApi.exe at " + ExecutablePath); } var info = new SandboxedProcessInfo(pathTable, sandboxStorage, ExecutablePath, disableConHostSharing: false, loggingContext: loggingContext) { PipSemiStableHash = 0, PipDescription = "RemoteApi Test", Arguments = string.Empty, WorkingDirectory = workingDirectory, }; info.FileAccessManifest.ReportFileAccesses = false; info.FileAccessManifest.ReportUnexpectedFileAccesses = true; info.FileAccessManifest.FailUnexpectedFileAccesses = false; info.FileAccessManifest.AddScope(AbsolutePath.Invalid, FileAccessPolicy.MaskNothing, FileAccessPolicy.ReportDirectoryEnumerationAccess); populateManifest(info.FileAccessManifest); // Allow access to the RemoteApi executable. AbsolutePath exeDirectory = AbsolutePath.Create(pathTable, Path.GetDirectoryName(ExecutablePath)); info.FileAccessManifest.AddScope(exeDirectory, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowReadAlways); using (TextReader commandReader = GetCommandReader(commands)) { info.StandardInputReader = commandReader; info.StandardInputEncoding = Encoding.ASCII; // TODO: Maybe watch stdout and validate the command results. using (SandboxedProcess process = await SandboxedProcess.StartAsync(info)) { SandboxedProcessResult result = await process.GetResultAsync(); if (result.ExitCode != 0) { var stdErr = await result.StandardError.ReadValueAsync(); XAssert.AreEqual(0, result.ExitCode, "RemoteApi.exe failed: " + stdErr); } return(result); } } }
/// <summary> /// Creates instance /// </summary> public SandboxedProcessInfo( ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detourseEventListener = null, IKextConnection sandboxedKextConnection = null) : this(new PathTable(), fileStorage, fileName, disableConHostSharing, testRetries, loggingContext, detourseEventListener, sandboxedKextConnection) { }
public SandboxedProcessOutputBuilder( Encoding encoding, int maxMemoryLength, ISandboxedProcessFileStorage fileStorage, SandboxedProcessFile file, Action <string> observer) { Contract.Requires(encoding != null); Contract.Requires(maxMemoryLength >= 0); Contract.Requires(fileStorage != null); m_stringBuilderWrapper = Pools.GetStringBuilder(); m_stringBuilder = m_stringBuilderWrapper.Instance; Encoding = encoding; m_maxMemoryLength = maxMemoryLength; m_fileStorage = fileStorage; m_file = file; m_observer = observer; }
/// <remarks> /// This constructor is never used in this project, but there exist external projects that /// compile against this assembly and already depend on this constructor. /// </remarks> public SandboxedProcessInfo( [CanBeNull] ISandboxedProcessFileStorage fileStorage, string fileName, bool disableConHostSharing, bool testRetries = false, LoggingContext loggingContext = null, IDetoursEventListener detoursEventListener = null, ISandboxConnection sandboxConnection = null, bool createJobObjectForCurrentProcess = true) : this( new PathTable(), fileStorage, fileName, disableConHostSharing, loggingContext ?? new LoggingContext("ExternalComponent"), testRetries, detoursEventListener, sandboxConnection, createJobObjectForCurrentProcess : createJobObjectForCurrentProcess) { }
/// <summary> /// Creates an instance of <see cref="SandboxedProcessStandardFiles"/> from <see cref="ISandboxedProcessFileStorage"/>. /// </summary> public static SandboxedProcessStandardFiles From(ISandboxedProcessFileStorage fileStorage) => new SandboxedProcessStandardFiles( fileStorage.GetFileName(SandboxedProcessFile.StandardOutput), fileStorage.GetFileName(SandboxedProcessFile.StandardError));