public IProcess StartHost(Interpreter interpreter, string profilePath, string userName, ClaimsPrincipal principal, string commandLine) { var exeLocator = BrokerExecutableLocator.Create(_fs); var hostBinPath = exeLocator.GetHostExecutablePath(); if (!_fs.FileExists(hostBinPath) && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { hostBinPath = PathConstants.RunHostBinPath; } var process = Utility.RunAsCurrentUser(_sessionLogger, _ps, hostBinPath, commandLine, GetRHomePath(interpreter), GetLoadLibraryPath(interpreter)); process.WaitForExit(250); if (process.HasExited && process.ExitCode != 0) { var message = _ps.MessageFromExitCode(process.ExitCode); if (!string.IsNullOrEmpty(message)) { throw new Win32Exception(message); } throw new Win32Exception(process.ExitCode); } return(process); }
public void Empty() { var locator = new BrokerExecutableLocator(_fs, OSPlatform.Windows); locator.GetBrokerExecutablePath().Should().BeNull(); locator.GetHostExecutablePath().Should().BeNull(); }
public IProcess StartHost(string interpreterPath, string interpreterArchitecture, string commandLine) { var exeLocator = new BrokerExecutableLocator(_fs); var hostBinPath = exeLocator.GetHostExecutablePath(interpreterArchitecture); if (hostBinPath == null) { throw new Win32Exception($"Microsoft.R.Host is missing. Interpreter: {interpreterPath}. Architecture: {interpreterArchitecture}"); } var psi = new ProcessStartInfo { FileName = hostBinPath, Arguments = commandLine, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, WorkingDirectory = Environment.GetEnvironmentVariable("PWD") }; psi.Environment.Add("R_HOME", interpreterPath); psi.Environment.Add("LD_LIBRARY_PATH", Path.Combine(interpreterPath, "lib")); var process = _ps.Start(psi); process.WaitForExit(250); if (process.HasExited && process.ExitCode != 0) { throw new Win32Exception(process.ExitCode); } return(process); }
public void Duplicate() { var locator = new BrokerExecutableLocator(_fs, OSPlatform.Windows); var brokerPath1 = Path.Combine(locator.BaseDirectory, BrokerExecutableLocator.WindowsBrokerName); var brokerPath2 = Path.Combine(locator.BaseDirectory, @"Broker\Windows\" + BrokerExecutableLocator.WindowsBrokerName); _fs.FileExists(brokerPath1).Returns(true); _fs.FileExists(brokerPath2).Returns(true); locator.GetBrokerExecutablePath().Should().Be(brokerPath2); }
private async Task ConnectToBrokerWorkerAsync(CancellationToken cancellationToken) { Trace.Assert(_brokerProcess == null); var fs = _services.FileSystem(); var locator = new BrokerExecutableLocator(fs); var rhostBrokerExe = locator.GetBrokerExecutablePath(); // _services.UI().LogMessage($"R Host broker: {rhostBrokerExe}"); if (!fs.FileExists(rhostBrokerExe)) { throw new RHostBrokerBinaryMissingException(); } IProcess process = null; try { var pipeName = Guid.NewGuid().ToString(); var cts = new CancellationTokenSource(Debugger.IsAttached ? 500000 : 100000); using (var processConnectCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cts.Token)) using (var serverUriPipe = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { var psi = GetProcessStartInfo(rhostBrokerExe, pipeName); // _services.UI().LogMessage($"Starting R Host broker: {rhostBrokerExe}"); process = StartBroker(psi); process.Exited += delegate { cts.Cancel(); _brokerProcess = null; _connectLock.EnqueueReset(); }; var uri = await GetBrokerUri(serverUriPipe, processConnectCts.Token, cts.Token); CreateHttpClient(uri); } if (DisposableBag.TryAdd(DisposeBrokerProcess)) { _brokerProcess = process; } } catch (Exception ex) { _services.UI().LogMessage($"Unable to start R Host broker process. Exception {ex.Message}"); throw; } finally { if (_brokerProcess == null) { try { process?.Kill(); } catch (Exception) { } finally { process?.Dispose(); } } } }
public async Task RHostPipeFuzzTest(int iteration) { var input = GenerateInput(); var locator = BrokerExecutableLocator.Create(new WindowsFileSystem()); var rhostExePath = locator.GetHostExecutablePath(); var arguments = Invariant($"--rhost-name \"FuzzTest\" --rhost-r-dir \"{_interpreter.BinPath}\""); var psi = new ProcessStartInfo(rhostExePath) { UseShellExecute = false, CreateNoWindow = false, Arguments = arguments, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, LoadUserProfile = true }; var shortHome = new StringBuilder(1024); GetShortPathName(_interpreter.Path, shortHome, shortHome.Capacity); psi.EnvironmentVariables["R_HOME"] = shortHome.ToString(); psi.EnvironmentVariables["PATH"] = _interpreter.BinPath + ";" + Environment.GetEnvironmentVariable("PATH"); psi.WorkingDirectory = Path.GetDirectoryName(rhostExePath); var process = new Process { StartInfo = psi, EnableRaisingEvents = true, }; process.Start(); process.WaitForExit(250); // Process should not exit before fully starting up process.HasExited.Should().BeFalse(); try { var killRhostTask = Task.Delay(3000).ContinueWith(t => TryKill(process)); var cts = new CancellationTokenSource(3000); await ReadStartupOutputFromRHostAsync(process.StandardOutput.BaseStream, cts.Token); await SendFuzzedInputToRHostAsync(process.StandardInput.BaseStream, input, cts.Token); var readOutputTask = ReadAnyOutputFromRHostAsync(process.StandardOutput.BaseStream, cts.Token); // Fuzzed input should not kill the host. process.HasExited.Should().BeFalse(); await Task.WhenAll(killRhostTask, readOutputTask); } finally { // In case anything fails above kill host. TryKill(process); } }
private void TestPlatform(string brokerSubPath, string hostSubPath, OSPlatform platform) { var locator = new BrokerExecutableLocator(_fs, platform); var brokerPath = Path.Combine(locator.BaseDirectory, brokerSubPath); var hostPath = Path.Combine(locator.BaseDirectory, hostSubPath); _fs.FileExists(brokerPath).Returns(true); locator.GetBrokerExecutablePath().Should().Be(brokerPath); locator.GetHostExecutablePath().Should().BeNull(); _fs.FileExists(hostPath).Returns(true); locator.GetBrokerExecutablePath().Should().Be(brokerPath); locator.GetHostExecutablePath().Should().Be(hostPath); }
public IProcess StartHost(Interpreter interpreter, string commandLine) { var exeLocator = BrokerExecutableLocator.Create(_fs); var hostBinPath = exeLocator.GetHostExecutablePath(); if (!_fs.FileExists(hostBinPath) && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { hostBinPath = PathConstants.RunHostBinPath; } var process = Utility.RunAsCurrentUser(_ps, hostBinPath, commandLine, GetRHomePath(interpreter), GetLoadLibraryPath(interpreter)); process.WaitForExit(250); if (process.HasExited && process.ExitCode != 0) { throw new Win32Exception(process.ExitCode); } return(process); }
private async Task <string> GetRemoteRtvsPackagePath(IRExpressionEvaluator eval) { var isWindows = await eval.IsRSessionPlatformWindowsAsync(); if (!isWindows) { // Remote Linux return("/usr/share/rtvs"); } // Check if there is 'rtvs' folder on remote var rtvsExists = await eval.FileExistsAsync("./rtvs/NAMESPACE"); if (rtvsExists) { return("."); } // Most probably tests are running remote broker locally var locator = BrokerExecutableLocator.Create(_fileSystem); var hostDirectory = Path.GetDirectoryName(locator.GetHostExecutablePath()); rtvsExists = _fileSystem.FileExists(Path.Combine(hostDirectory, @"rtvs\NAMESPACE")); return(rtvsExists ? hostDirectory : Path.GetFullPath(Path.Combine(hostDirectory, @"..\.."))); }
protected override string GetRHostBinaryPath() { var locator = BrokerExecutableLocator.Create(_fs); return(locator.GetHostExecutablePath()); }
public IProcess StartHost(Interpreter interpreter, string profilePath, string userName, ClaimsPrincipal principal, string commandLine) { var locator = BrokerExecutableLocator.Create(new WindowsFileSystem()); var rhostExePath = locator.GetHostExecutablePath(); commandLine = FormattableString.Invariant($"\"{rhostExePath}\" {commandLine}"); var usernameBldr = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH + 1); var domainBldr = new StringBuilder(NativeMethods.CREDUI_MAX_DOMAIN_LENGTH + 1); // Get R_HOME value var shortHome = new StringBuilder(NativeMethods.MAX_PATH); NativeMethods.GetShortPathName(interpreter.InstallPath, shortHome, shortHome.Capacity); var useridentity = principal.Identity as WindowsIdentity; var loggedOnUser = useridentity != null && WindowsIdentity.GetCurrent().User != useridentity.User; // build user environment block Win32EnvironmentBlock eb; if (loggedOnUser) { var error = NativeMethods.CredUIParseUserName(userName, usernameBldr, usernameBldr.Capacity, domainBldr, domainBldr.Capacity); if (error != 0) { _sessionLogger.LogError(Resources.Error_UserNameParse, userName, error); throw new ArgumentException(Resources.Error_UserNameParse.FormatInvariant(userName, error)); } var username = usernameBldr.ToString(); var domain = domainBldr.ToString(); eb = CreateEnvironmentBlockForUser(useridentity, username, profilePath); // add globally set environment variables AddGlobalREnvironmentVariables(eb); } else { eb = Win32EnvironmentBlock.Create((useridentity ?? WindowsIdentity.GetCurrent()).Token); } // add additional variables to the environment block eb["R_HOME"] = shortHome.ToString(); _sessionLogger.LogTrace(Resources.Trace_EnvironmentVariable, "R_HOME", eb["R_HOME"]); eb["PATH"] = FormattableString.Invariant($"{interpreter.BinPath};{Environment.GetEnvironmentVariable("PATH")}"); _sessionLogger.LogTrace(Resources.Trace_EnvironmentVariable, "PATH", eb["PATH"]); Win32Process win32Process; using (var nativeEnv = eb.GetNativeEnvironmentBlock()) { if (loggedOnUser) { win32Process = Win32Process.StartProcessAsUser(useridentity, rhostExePath, commandLine, Path.GetDirectoryName(rhostExePath), nativeEnv); } else { win32Process = Win32Process.StartProcessAsUser(null, rhostExePath, commandLine, Path.GetDirectoryName(rhostExePath), nativeEnv); } } win32Process.Exited += (s, e) => { }; win32Process.WaitForExit(250); if (win32Process.HasExited && win32Process.ExitCode < 0) { var message = ErrorCodeConverter.MessageFromErrorCode(win32Process.ExitCode); if (!string.IsNullOrEmpty(message)) { throw new Win32Exception(message); } throw new Win32Exception(win32Process.ExitCode); } return(win32Process); }