bool LaunchProcesses(List <ProcessStartData> processes, string name)
        {
            if (processManager == null)
            {
                processManager = new ProcessManager();
                processManager.OnProcessExit += (processName, exitCode) =>
                                                StopWithException(new ProcessExecutionException(
                                                                      $"{processName} exited with exit code {exitCode}",
                                                                      exitCode));
            }

            foreach (var item in processes)
            {
                try
                {
                    LaunchYetiProcess(item);
                }
                catch (ProcessException e)
                {
                    Trace.WriteLine($"Failed to start {item.Name}: {e.Message}");
                    dialogUtil.ShowError(ErrorStrings.FailedToStartRequiredProcess(e.Message),
                                         e.ToString());
                    return(false);
                }
            }

            Trace.WriteLine($"Manager successfully started all {name} processes");
            return(true);
        }
Exemple #2
0
        async Task CustomCommandAsync(IAsyncProject project, Gamelet gamelet, DataRecorder record,
                                      string command)
        {
            var startInfo = new ProcessStartInfo
            {
                FileName         = Path.Combine(Environment.SystemDirectory, YetiConstants.Command),
                Arguments        = $"/C \"{command}\"",
                WorkingDirectory = await project.GetAbsoluteRootPathAsync(),
            };

            startInfo.EnvironmentVariables[GgpInstanceIdName] = gamelet.Id;
            Stopwatch stopwatch = Stopwatch.StartNew();

            using (IProcess process = _managedProcessFactory.CreateVisible(startInfo, int.MaxValue))
            {
                try
                {
                    await process.RunToExitWithSuccessAsync();

                    record.CustomDeploy(stopwatch.ElapsedMilliseconds, DataRecorder.NoError);
                }
                catch (ProcessException e)
                {
                    Trace.WriteLine("Error running custom deploy command: " + e);
                    record.CustomDeploy(stopwatch.ElapsedMilliseconds, e);
                    throw new DeployException(
                              ErrorStrings.ErrorRunningCustomDeployCommand(e.Message), e);
                }
            }
        }
        void OpenLogs(object sender, RoutedEventArgs e)
        {
            var path = "<Invalid>";

            try
            {
                path = YetiLog.CurrentLogFile;
                if (!File.Exists(path))
                {
                    path = Path.GetDirectoryName(path);
                }

                Process.Start(path);
            }
            catch (InvalidOperationException ex)
            {
                Trace.WriteLine(ex);
                LogsLink.Text = ErrorStrings.FailedToOpenLogsBecauseLoggingNotInitialized;
            }
            catch (Exception ex) when(ex is Win32Exception || ex is FileNotFoundException)
            {
                Trace.WriteLine(ex);
                LogsLink.Text = ErrorStrings.FailedToOpenLogsBecauseLogFileMayNotExist(path);
            }
        }
Exemple #4
0
        List <string> ReadMountsContentOrDefault(Gamelet gamelet, ActionRecorder actionRecorder)
        {
            List <string>   content       = new List <string>();
            ICancelableTask getMountsTask =
                _cancelableTaskFactory.Create(TaskMessages.CheckingMountInfo, async _ => {
                content = await _remoteCommand.RunWithSuccessCapturingOutputAsync(
                    new SshTarget(gamelet), ReadMountsCmd) ?? new List <string>();
            });

            try
            {
                getMountsTask.RunAndRecord(actionRecorder, ActionType.GameletReadMounts);
                return(content);
            }
            catch (ProcessException e)
            {
                Trace.WriteLine($"Error reading /proc/mounts file: {e.Message}");
                _dialogUtil.ShowError(ErrorStrings.FailedToStartRequiredProcess(e.Message),
                                      e.ToString());
                return(content);
            }
            finally
            {
                string joinedContent = string.Join("\n\t", content);
                Trace.WriteLine($"Gamelet /proc/mounts:{Environment.NewLine}{joinedContent}");
            }
        }
Exemple #5
0
        async Task DeployToTargetAsync(DataRecorder record, ICancelable task, SshTarget target,
                                       string localPath, string remotePath, bool force = false)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                BinarySignatureCheck.Types.Result signatureCheck = force
                    ? BinarySignatureCheck.Types.Result.AlwaysCopy
                    : BinarySignatureCheck.Types.Result.YesCopy;

                record.SetCopyAttempted(true);
                record.BinarySize(FileUtil.GetFileSize(localPath, _fileSystem));
                record.SignatureCheckResult(signatureCheck);
                record.DeploymentMode();

                await _remoteFile.SyncAsync(target, localPath, remotePath, task, force);

                record.CopyBinary(stopwatch.ElapsedMilliseconds, DataRecorder.NoError);
            }
            catch (ProcessException exception)
            {
                record.CopyBinary(stopwatch.ElapsedMilliseconds, exception);
                throw new DeployException(
                          ErrorStrings.FailedToDeployExecutable(exception.Message),
                          exception);
            }
        }
Exemple #6
0
        async Task SetRemoteExecutableBitAsync(SshTarget target, string remoteTargetPath,
                                               DataRecorder record)
        {
            try
            {
                await _remoteCommand.RunWithSuccessAsync(target, "chmod a+x " + remoteTargetPath);

                record.Chmod(DataRecorder.NoError);
            }
            catch (ProcessException e)
            {
                Trace.WriteLine("Error setting executable permissions: " + e.ToString());
                record.Chmod(e);
                throw new DeployException(ErrorStrings.FailedToSetExecutablePermissions(e.Message),
                                          e);
            }
        }
        /// <summary>
        /// Load the application given a string representing the app id or name.
        /// </summary>
        /// <exception cref="InvalidStateException">Thrown if the application doesn't exist
        /// </exception>
        /// <exception cref="ConfigurationException">Thrown if applicationNameOrId is null
        /// or empty</exception>
        async Task <Application> LoadApplicationAsync(ICloudRunner runner,
                                                      string applicationNameOrId)
        {
            if (string.IsNullOrEmpty(applicationNameOrId))
            {
                throw new ConfigurationException(ErrorStrings.NoApplicationConfigured);
            }

            var application = await _applicationClientFactory.Create(runner)
                              .LoadByNameOrIdAsync(applicationNameOrId);

            if (application == null)
            {
                throw new InvalidStateException(
                          ErrorStrings.FailedToRetrieveApplication(applicationNameOrId));
            }

            return(application);
        }
        public DetailsDialog(string title, string message, string details, bool dontShowAgainButton,
                             string[] dontShowAgainSettingPath = null)
        {
            InitializeComponent();
            Title        = title;
            Message.Text = message;
            if (!string.IsNullOrEmpty(details))
            {
                Details.Text = details;
            }
            else
            {
                DetailsExpander.Visibility = Visibility.Collapsed;
            }

            DontShowAgain.Visibility = dontShowAgainButton ? Visibility.Visible : Visibility.Hidden;
            if (dontShowAgainSettingPath != null)
            {
                DontShowAgain.ToolTip =
                    ErrorStrings.DontShowAgainSettingHint(dontShowAgainSettingPath);
            }
        }
        /// <summary>
        /// Load a test account given the organization id, project id and test account
        /// (Stadia Name). Returns null if the test account is empty or null.
        /// </summary>
        /// <exception cref="ConfigurationException">Thrown if the given test account doesn't exist
        /// or if there is more than one test account with the given name.
        /// </exception>
        async Task <TestAccount> LoadTestAccountAsync(ICloudRunner runner, string organizationId,
                                                      string projectId, string testAccount)
        {
            if (string.IsNullOrEmpty(testAccount))
            {
                return(null);
            }

            var testAccounts = await _testAccountClientFactory.Create(runner)
                               .LoadByIdOrGamerTagAsync(organizationId, projectId, testAccount);

            if (testAccounts.Count == 0)
            {
                throw new ConfigurationException(ErrorStrings.InvalidTestAccount(testAccount));
            }

            if (testAccounts.Count > 1)
            {
                throw new ConfigurationException(
                          ErrorStrings.MoreThanOneTestAccount(testAccounts[0].GamerTagName));
            }

            return(testAccounts[0]);
        }
        public async Task <IReadOnlyList <IDebugLaunchSettings> > QueryDebugTargetsAsync(
            IAsyncProject project, DebugLaunchOptions launchOptions)
        {
            try
            {
                // Make sure we can find the target executable.
                var targetPath = await project.GetTargetPathAsync();

                if (!_fileSystem.File.Exists(targetPath))
                {
                    Trace.WriteLine($"Unable to find target executable: {targetPath}");
                    _dialogUtil.ShowError(ErrorStrings.UnableToFindTargetExecutable(targetPath));
                    return(new IDebugLaunchSettings[] { });
                }

                _metrics.UseNewDebugSessionId();
                var actionRecorder = new ActionRecorder(_metrics);

                var targetFileName = await project.GetTargetFileNameAsync();

                var gameletCommand = (targetFileName + " " +
                                      await project.GetGameletLaunchArgumentsAsync()).Trim();

                var launchParams = new LaunchParams()
                {
                    Cmd       = gameletCommand,
                    RenderDoc = await project.GetLaunchRenderDocAsync(),
                    Rgp       = await project.GetLaunchRgpAsync(),
                    SurfaceEnforcementMode = await project.GetSurfaceEnforcementAsync(),
                    VulkanDriverVariant    = await project.GetVulkanDriverVariantAsync(),
                    QueryParams            = await project.GetQueryParamsAsync(),
                    Endpoint = await project.GetEndpointAsync()
                };

                if (_sdkVersion != null && !string.IsNullOrEmpty(_sdkVersion.ToString()))
                {
                    launchParams.SdkVersion = _sdkVersion.ToString();
                }

                if (!TrySetupQueries(project, actionRecorder,
                                     out SetupQueriesResult setupQueriesResult))
                {
                    return(new IDebugLaunchSettings[] { });
                }

                launchParams.ApplicationName = setupQueriesResult.Application.Name;
                launchParams.ApplicationId   = setupQueriesResult.Application.Id;
                if (setupQueriesResult.TestAccount != null)
                {
                    launchParams.TestAccount          = setupQueriesResult.TestAccount.Name;
                    launchParams.TestAccountGamerName =
                        setupQueriesResult.TestAccount.GamerStadiaName;
                }

                DeployOnLaunchSetting deployOnLaunchAsync = await project.GetDeployOnLaunchAsync();

                launchParams.Account = _credentialManager.LoadAccount();

                // TODO: Enable PlayerEndpoint Launches for non-internal usage in VS.
                if (launchParams.Endpoint == StadiaEndpoint.PlayerEndpoint &&
                    launchParams.Account != null &&
                    !launchParams.Account.EndsWith("@sparklingsunset.com") &&
                    !launchParams.Account.EndsWith("@subtlesunset.com"))
                {
                    throw new NotImplementedException(
                              "Player Endpoints are not yet supported, please select " +
                              "Test Client in the Project Properties instead.");
                }

                // TODO: Enable launch on any endpoint for external accounts.
                if (launchParams.Endpoint == StadiaEndpoint.AnyEndpoint &&
                    launchParams.Account != null &&
                    !launchParams.Account.EndsWith("@sparklingsunset.com") &&
                    !launchParams.Account.EndsWith("@subtlesunset.com"))
                {
                    throw new NotImplementedException(
                              "Launch on any player endpoint is not supported yet, please select " +
                              "another endpoint in the Project Properties instead.");
                }

                bool launchGameApiEnabled =
                    _yetiVsiService.Options.LaunchGameApiFlow == LaunchGameApiFlow.ENABLED;
                IGameletSelector gameletSelector =
                    _gameletSelectorFactory.Create(launchGameApiEnabled, actionRecorder);
                if (!gameletSelector.TrySelectAndPrepareGamelet(
                        targetPath, deployOnLaunchAsync, setupQueriesResult.Gamelets,
                        setupQueriesResult.TestAccount, launchParams.Account, out Gamelet gamelet))
                {
                    return(new IDebugLaunchSettings[] { });
                }

                launchParams.GameletName            = gamelet.Name;
                launchParams.PoolId                 = gamelet.PoolId;
                launchParams.GameletSdkVersion      = gamelet.GameletVersions.DevToolingVersion;
                launchParams.GameletEnvironmentVars =
                    await project.GetGameletEnvironmentVariablesAsync();

                // Prepare for debug launch using these settings.
                var debugLaunchSettings = new DebugLaunchSettings(launchOptions);
                debugLaunchSettings.Environment["PATH"] = await project.GetExecutablePathAsync();

                debugLaunchSettings.LaunchOperation  = DebugLaunchOperation.CreateProcess;
                debugLaunchSettings.CurrentDirectory = await project.GetAbsoluteRootPathAsync();

                if (!launchOptions.HasFlag(DebugLaunchOptions.NoDebug))
                {
                    var parameters = _paramsFactory.Create();
                    parameters.TargetIp         = new SshTarget(gamelet).GetString();
                    parameters.DebugSessionId   = _metrics.DebugSessionId;
                    debugLaunchSettings.Options = _paramsFactory.Serialize(parameters);
                }

                IAction action     = actionRecorder.CreateToolAction(ActionType.RemoteDeploy);
                bool    isDeployed = _cancelableTaskFactory.Create(
                    TaskMessages.DeployingExecutable, async task =>
                {
                    await _remoteDeploy.DeployGameExecutableAsync(
                        project, new SshTarget(gamelet), task, action);
                    task.Progress.Report(TaskMessages.CustomDeployCommand);
                    await _remoteDeploy.ExecuteCustomCommandAsync(project, gamelet, action);
                }).RunAndRecord(action);

                if (!isDeployed)
                {
                    return(new IDebugLaunchSettings[] { });
                }

                if (launchOptions.HasFlag(DebugLaunchOptions.NoDebug))
                {
                    if (_gameLauncher.LaunchGameApiEnabled ||
                        launchParams.Endpoint == StadiaEndpoint.PlayerEndpoint ||
                        launchParams.Endpoint == StadiaEndpoint.AnyEndpoint)
                    {
                        IVsiGameLaunch launch = _gameLauncher.CreateLaunch(launchParams);
                        if (launch != null)
                        {
                            debugLaunchSettings.Arguments =
                                _launchCommandFormatter.CreateWithLaunchName(
                                    launchParams, launch.LaunchName);
                        }
                        else
                        {
                            Trace.WriteLine("Unable to retrieve launch name from the launch api.");
                            return(new IDebugLaunchSettings[] { });
                        }
                    }
                    else
                    {
                        debugLaunchSettings.Arguments =
                            _launchCommandFormatter.CreateFromParams(launchParams);
                    }

                    debugLaunchSettings.Executable =
                        Path.Combine(Environment.SystemDirectory, YetiConstants.Command);

                    debugLaunchSettings.LaunchOptions = DebugLaunchOptions.NoDebug |
                                                        DebugLaunchOptions.MergeEnvironment;
                }
                else
                {
                    if (_yetiVsiService.DebuggerOptions[DebuggerOption.SKIP_WAIT_LAUNCH] ==
                        DebuggerOptionState.DISABLED)
                    {
                        launchParams.Debug = true;
                    }

                    // TODO: This should really be the game_client executable, since
                    // the args we pass are for game_client as well.  We just need to find another
                    // way to pass the game executable.
                    debugLaunchSettings.Executable            = targetPath;
                    debugLaunchSettings.LaunchDebugEngineGuid = YetiConstants.DebugEngineGuid;
                    debugLaunchSettings.Arguments             =
                        _launchCommandFormatter.EncodeLaunchParams(launchParams);
                    debugLaunchSettings.LaunchOptions = DebugLaunchOptions.MergeEnvironment;
                }

                return(new IDebugLaunchSettings[] { debugLaunchSettings });
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                _dialogUtil.ShowError(e.Message, e.ToString());
                return(new IDebugLaunchSettings[] { });
            }
        }