/// <summary> /// You need to put this activity in a different agent that write the diagnostics log that you want to change. /// </summary> /// <param name="context"></param> protected override void Execute(CodeActivityContext context) { Thread.Sleep(30000); var findAndReplace = context.GetValue(FindAndReplaceStrings); _teamProjectUri = context.GetValue(TeamProjectUri); _buildUri = context.GetValue(BuildUri); var vssCredential = new VssCredentials(true); _fcClient = new FileContainerHttpClient(_teamProjectUri, vssCredential); var containers = _fcClient.QueryContainersAsync(new List<Uri>() { _buildUri }).Result; if (!containers.Any()) return; var agentLogs = GetAgentLogs(containers); if (agentLogs == null) return; using (var handler = new HttpClientHandler() { UseDefaultCredentials = true }) { var reader = DownloadAgentLog(agentLogs, handler); using (var ms = new MemoryStream()) { ReplaceStrings(findAndReplace, reader, ms); var response = UploadDocument(containers, agentLogs, ms); } } }
public static VssConnection CreateConnection(Uri serverUri, VssCredentials credentials) { VssClientHttpRequestSettings settings = VssClientHttpRequestSettings.Default.Clone(); settings.MaxRetryRequest = 5; // Remove Invariant from the list of accepted languages. // // The constructor of VssHttpRequestSettings (base class of VssClientHttpRequestSettings) adds the current // UI culture to the list of accepted languages. The UI culture will be Invariant on OSX/Linux when the // LANG environment variable is not set when the program starts. If Invariant is in the list of accepted // languages, then "System.ArgumentException: The value cannot be null or empty." will be thrown when the // settings are applied to an HttpRequestMessage. settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture); var headerValues = new List<ProductInfoHeaderValue>(); headerValues.Add(new ProductInfoHeaderValue($"VstsAgentCore-{BuildConstants.AgentPackage.PackageName}", Constants.Agent.Version)); headerValues.Add(new ProductInfoHeaderValue($"({RuntimeInformation.OSDescription.Trim()})")); if (settings.UserAgent != null && settings.UserAgent.Count > 0) { headerValues.AddRange(settings.UserAgent); } settings.UserAgent = headerValues; VssConnection connection = new VssConnection(serverUri, credentials, settings); return connection; }
public ReleaseServer(Uri projectCollection, VssCredentials credentials, Guid projectId) { ArgUtil.NotNull(projectCollection, nameof(projectCollection)); ArgUtil.NotNull(credentials, nameof(credentials)); _projectCollectionUrl = projectCollection; _credential = credentials; _projectId = projectId; _releaseHttpClient = new ReleaseHttpClient(projectCollection, credentials, new VssHttpRetryMessageHandler(3)); }
public override VssCredentials GetVssCredentials(IHostContext context) { ArgUtil.NotNull(context, nameof(context)); Tracing trace = context.GetTrace(nameof(IntegratedCredential)); trace.Info(nameof(GetVssCredentials)); // Create instance of VssConnection using default Windows credentials (NTLM) VssCredentials creds = new VssCredentials(true); trace.Verbose("cred created"); return creds; }
public BuildServer( Uri projectCollection, VssCredentials credentials, Guid projectId) { ArgUtil.NotNull(projectCollection, nameof(projectCollection)); ArgUtil.NotNull(credentials, nameof(credentials)); ArgUtil.NotEmpty(projectId, nameof(projectId)); _projectCollectionUrl = projectCollection; _credential = credentials; _projectId = projectId; BuildHttpClient = new Build2.BuildHttpClient(projectCollection, credentials, new VssHttpRetryMessageHandler(3)); }
public FileContainerServer( Uri projectCollectionUrl, VssCredentials credential, Guid projectId, long containerId, string containerPath) { _projectCollectionUrl = projectCollectionUrl; _credential = credential; _projectId = projectId; _containerId = containerId; _containerPath = containerPath; // default file upload request timeout to 300 seconds // TODO: Load from .ini file. VssHttpRequestSettings fileUploadRequestSettings = new VssHttpRequestSettings(); fileUploadRequestSettings.SendTimeout = TimeSpan.FromSeconds(300); FileContainerHttpClient = new FileContainerHttpClient( _projectCollectionUrl, _credential, fileUploadRequestSettings, new VssHttpRetryMessageHandler(3)); }
public TaskAgentHttpClientBase(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings) : base(baseUrl, credentials, settings) { }
public async Task <Boolean> CreateSessionAsync(CancellationToken token) { Trace.Entering(); // Settings var configManager = HostContext.GetService <IConfigurationManager>(); _settings = configManager.LoadSettings(); var serverUrl = _settings.ServerUrl; Trace.Info(_settings); // Capabilities. _term.WriteLine(StringUtil.Loc("ScanToolCapabilities")); Dictionary <string, string> systemCapabilities = await HostContext.GetService <ICapabilitiesManager>().GetCapabilitiesAsync(_settings, token); // Create connection. Trace.Info("Loading Credentials"); var credMgr = HostContext.GetService <ICredentialManager>(); VssCredentials creds = credMgr.LoadCredentials(); var agent = new TaskAgentReference { Id = _settings.AgentId, Name = _settings.AgentName, Version = Constants.Agent.Version, OSDescription = RuntimeInformation.OSDescription, }; string sessionName = $"{Environment.MachineName ?? "AGENT"}"; var taskAgentSession = new TaskAgentSession(sessionName, agent, systemCapabilities); string errorMessage = string.Empty; bool encounteringError = false; _term.WriteLine(StringUtil.Loc("ConnectToServer")); while (true) { token.ThrowIfCancellationRequested(); Trace.Info($"Attempt to create session."); try { Trace.Info("Connecting to the Agent Server..."); await _agentServer.ConnectAsync(new Uri(serverUrl), creds); Trace.Info("VssConnection created"); _session = await _agentServer.CreateAgentSessionAsync( _settings.PoolId, taskAgentSession, token); Trace.Info($"Session created."); if (encounteringError) { _term.WriteLine(StringUtil.Loc("QueueConnected", DateTime.UtcNow)); _sessionCreationExceptionTracker.Clear(); encounteringError = false; } return(true); } catch (OperationCanceledException) when(token.IsCancellationRequested) { Trace.Info("Session creation has been cancelled."); throw; } catch (TaskAgentAccessTokenExpiredException) { Trace.Info("Agent OAuth token has been revoked. Session creation failed."); throw; } catch (Exception ex) { Trace.Error("Catch exception during create session."); Trace.Error(ex); if (!IsSessionCreationExceptionRetriable(ex)) { _term.WriteError(StringUtil.Loc("SessionCreateFailed", ex.Message)); return(false); } if (!encounteringError) //print the message only on the first error { _term.WriteError(StringUtil.Loc("QueueConError", DateTime.UtcNow, ex.Message, _sessionCreationRetryInterval.TotalSeconds)); encounteringError = true; } Trace.Info("Sleeping for {0} seconds before retrying.", _sessionCreationRetryInterval.TotalSeconds); await HostContext.Delay(_sessionCreationRetryInterval, token); } } }
private async Task AddBuildTagAsync( IAsyncCommandContext context, Uri projectCollection, VssCredentials credentials, Guid projectId, int buildId, string buildTag, CancellationToken cancellationToken) { BuildServer buildServer = new BuildServer(projectCollection, credentials, projectId); var tags = await buildServer.AddBuildTag(buildId, buildTag, cancellationToken); if (tags == null || !tags.Contains(buildTag)) { throw new Exception(StringUtil.Loc("BuildTagAddFailed", buildTag)); } else { context.Output(StringUtil.Loc("BuildTagsForBuild", buildId, String.Join(", ", tags))); } }
public async Task <TaskResult> RunAsync(Pipelines.AgentJobRequestMessage message, CancellationToken jobRequestCancellationToken) { // Validate parameters. Trace.Entering(); ArgUtil.NotNull(message, nameof(message)); ArgUtil.NotNull(message.Resources, nameof(message.Resources)); ArgUtil.NotNull(message.Variables, nameof(message.Variables)); ArgUtil.NotNull(message.Steps, nameof(message.Steps)); Trace.Info("Job ID {0}", message.JobId); DateTime jobStartTimeUtc = DateTime.UtcNow; // Agent.RunMode RunMode runMode; if (message.Variables.ContainsKey(Constants.Variables.Agent.RunMode) && Enum.TryParse(message.Variables[Constants.Variables.Agent.RunMode].Value, ignoreCase: true, result: out runMode) && runMode == RunMode.Local) { HostContext.RunMode = runMode; } ServiceEndpoint systemConnection = message.Resources.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); // System.AccessToken if (message.Variables.ContainsKey(Constants.Variables.System.EnableAccessToken) && StringUtil.ConvertToBoolean(message.Variables[Constants.Variables.System.EnableAccessToken].Value)) { message.Variables[Constants.Variables.System.AccessToken] = new VariableValue(systemConnection.Authorization.Parameters["AccessToken"], false); } // Make sure SystemConnection Url and Endpoint Url match Config Url base ReplaceConfigUriBaseInJobRequestMessage(message); // Setup the job server and job server queue. var jobServer = HostContext.GetService <IJobServer>(); VssCredentials jobServerCredential = ApiUtil.GetVssCredential(systemConnection); Uri jobServerUrl = systemConnection.Url; Trace.Info($"Creating job server with URL: {jobServerUrl}"); // jobServerQueue is the throttling reporter. _jobServerQueue = HostContext.GetService <IJobServerQueue>(); VssConnection jobConnection = ApiUtil.CreateConnection(jobServerUrl, jobServerCredential, new DelegatingHandler[] { new ThrottlingReportHandler(_jobServerQueue) }); await jobServer.ConnectAsync(jobConnection); _jobServerQueue.Start(message); IExecutionContext jobContext = null; CancellationTokenRegistration?agentShutdownRegistration = null; try { // Create the job execution context. jobContext = HostContext.CreateService <IExecutionContext>(); jobContext.InitializeJob(message, jobRequestCancellationToken); Trace.Info("Starting the job execution context."); jobContext.Start(); jobContext.Section(StringUtil.Loc("StepStarting", message.JobDisplayName)); agentShutdownRegistration = HostContext.AgentShutdownToken.Register(() => { // log an issue, then agent get shutdown by Ctrl-C or Ctrl-Break. // the server will use Ctrl-Break to tells the agent that operating system is shutting down. string errorMessage; switch (HostContext.AgentShutdownReason) { case ShutdownReason.UserCancelled: errorMessage = StringUtil.Loc("UserShutdownAgent"); break; case ShutdownReason.OperatingSystemShutdown: errorMessage = StringUtil.Loc("OperatingSystemShutdown", Environment.MachineName); break; default: throw new ArgumentException(HostContext.AgentShutdownReason.ToString(), nameof(HostContext.AgentShutdownReason)); } jobContext.AddIssue(new Issue() { Type = IssueType.Error, Message = errorMessage }); }); // Set agent version variable. jobContext.Variables.Set(Constants.Variables.Agent.Version, Constants.Agent.Version); jobContext.Output(StringUtil.Loc("AgentVersion", Constants.Agent.Version)); // Print proxy setting information for better diagnostic experience var agentWebProxy = HostContext.GetService <IVstsAgentWebProxy>(); if (!string.IsNullOrEmpty(agentWebProxy.ProxyAddress)) { jobContext.Output(StringUtil.Loc("AgentRunningBehindProxy", agentWebProxy.ProxyAddress)); } // Validate directory permissions. string workDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); Trace.Info($"Validating directory permissions for: '{workDirectory}'"); try { Directory.CreateDirectory(workDirectory); IOUtil.ValidateExecutePermission(workDirectory); } catch (Exception ex) { Trace.Error(ex); jobContext.Error(ex); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } // Set agent variables. AgentSettings settings = HostContext.GetService <IConfigurationStore>().GetSettings(); jobContext.Variables.Set(Constants.Variables.Agent.Id, settings.AgentId.ToString(CultureInfo.InvariantCulture)); jobContext.Variables.Set(Constants.Variables.Agent.HomeDirectory, HostContext.GetDirectory(WellKnownDirectory.Root)); jobContext.Variables.Set(Constants.Variables.Agent.JobName, message.JobDisplayName); jobContext.Variables.Set(Constants.Variables.Agent.MachineName, Environment.MachineName); jobContext.Variables.Set(Constants.Variables.Agent.Name, settings.AgentName); jobContext.Variables.Set(Constants.Variables.Agent.OS, VarUtil.OS); jobContext.Variables.Set(Constants.Variables.Agent.RootDirectory, IOUtil.GetWorkPath(HostContext)); #if OS_WINDOWS jobContext.Variables.Set(Constants.Variables.Agent.ServerOMDirectory, Path.Combine(IOUtil.GetExternalsPath(), Constants.Path.ServerOMDirectory)); #endif jobContext.Variables.Set(Constants.Variables.Agent.WorkFolder, IOUtil.GetWorkPath(HostContext)); jobContext.Variables.Set(Constants.Variables.System.WorkFolder, IOUtil.GetWorkPath(HostContext)); string toolsDirectory = Environment.GetEnvironmentVariable("AGENT_TOOLSDIRECTORY") ?? Environment.GetEnvironmentVariable(Constants.Variables.Agent.ToolsDirectory); if (string.IsNullOrEmpty(toolsDirectory)) { toolsDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), Constants.Path.ToolDirectory); Directory.CreateDirectory(toolsDirectory); } else { Trace.Info($"Set tool cache directory base on environment: '{toolsDirectory}'"); Directory.CreateDirectory(toolsDirectory); } jobContext.Variables.Set(Constants.Variables.Agent.ToolsDirectory, toolsDirectory); // Setup TEMP directories _tempDirectoryManager = HostContext.GetService <ITempDirectoryManager>(); _tempDirectoryManager.InitializeTempDirectory(jobContext); // todo: task server can throw. try/catch and fail job gracefully. // prefer task definitions url, then TFS collection url, then TFS account url var taskServer = HostContext.GetService <ITaskServer>(); Uri taskServerUri = null; if (!string.IsNullOrEmpty(jobContext.Variables.System_TaskDefinitionsUri)) { taskServerUri = new Uri(jobContext.Variables.System_TaskDefinitionsUri); } else if (!string.IsNullOrEmpty(jobContext.Variables.System_TFCollectionUrl)) { taskServerUri = new Uri(jobContext.Variables.System_TFCollectionUrl); } var taskServerCredential = ApiUtil.GetVssCredential(systemConnection); if (taskServerUri != null) { Trace.Info($"Creating task server with {taskServerUri}"); await taskServer.ConnectAsync(ApiUtil.CreateConnection(taskServerUri, taskServerCredential)); } if (taskServerUri == null || !await taskServer.TaskDefinitionEndpointExist()) { Trace.Info($"Can't determine task download url from JobMessage or the endpoint doesn't exist."); var configStore = HostContext.GetService <IConfigurationStore>(); taskServerUri = new Uri(configStore.GetSettings().ServerUrl); Trace.Info($"Recreate task server with configuration server url: {taskServerUri}"); await taskServer.ConnectAsync(ApiUtil.CreateConnection(taskServerUri, taskServerCredential)); } // Expand the endpoint data values. foreach (ServiceEndpoint endpoint in jobContext.Endpoints) { jobContext.Variables.ExpandValues(target: endpoint.Data); VarUtil.ExpandEnvironmentVariables(HostContext, target: endpoint.Data); } // Get the job extension. Trace.Info("Getting job extension."); var hostType = jobContext.Variables.System_HostType; var extensionManager = HostContext.GetService <IExtensionManager>(); // We should always have one job extension IJobExtension jobExtension = (extensionManager.GetExtensions <IJobExtension>() ?? new List <IJobExtension>()) .Where(x => x.HostType.HasFlag(hostType)) .FirstOrDefault(); ArgUtil.NotNull(jobExtension, nameof(jobExtension)); List <IStep> jobSteps = new List <IStep>(); try { Trace.Info("Initialize job. Getting all job steps."); var initializeResult = await jobExtension.InitializeJob(jobContext, message); jobSteps.AddRange(initializeResult.PreJobSteps); jobSteps.AddRange(initializeResult.JobSteps); jobSteps.AddRange(initializeResult.PostJobStep); } catch (OperationCanceledException ex) when(jobContext.CancellationToken.IsCancellationRequested) { // set the job to canceled // don't log error issue to job ExecutionContext, since server owns the job level issue Trace.Error($"Job is canceled during initialize."); Trace.Error($"Caught exception: {ex}"); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Canceled)); } catch (Exception ex) { // set the job to failed. // don't log error issue to job ExecutionContext, since server owns the job level issue Trace.Error($"Job initialize failed."); Trace.Error($"Caught exception from {nameof(jobExtension.InitializeJob)}: {ex}"); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } // trace out all steps Trace.Info($"Total job steps: {jobSteps.Count}."); Trace.Verbose($"Job steps: '{string.Join(", ", jobSteps.Select(x => x.DisplayName))}'"); bool processCleanup = jobContext.Variables.GetBoolean("process.clean") ?? true; HashSet <string> existingProcesses = new HashSet <string>(StringComparer.OrdinalIgnoreCase); string processLookupId = null; if (processCleanup) { processLookupId = $"vsts_{Guid.NewGuid()}"; // Set the VSTS_PROCESS_LOOKUP_ID env variable. jobContext.SetVariable(Constants.ProcessLookupId, processLookupId, false, false); // Take a snapshot of current running processes Dictionary <int, Process> processes = SnapshotProcesses(); foreach (var proc in processes) { // Pid_ProcessName existingProcesses.Add($"{proc.Key}_{proc.Value.ProcessName}"); } } // Run all job steps Trace.Info("Run all job steps."); var stepsRunner = HostContext.GetService <IStepsRunner>(); try { await stepsRunner.RunAsync(jobContext, jobSteps); } catch (Exception ex) { // StepRunner should never throw exception out. // End up here mean there is a bug in StepRunner // Log the error and fail the job. Trace.Error($"Caught exception from job steps {nameof(StepsRunner)}: {ex}"); jobContext.Error(ex); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } finally { if (processCleanup) { // Only check environment variable for any process that doesn't run before we invoke our process. Dictionary <int, Process> currentProcesses = SnapshotProcesses(); foreach (var proc in currentProcesses) { if (existingProcesses.Contains($"{proc.Key}_{proc.Value.ProcessName}")) { Trace.Verbose($"Skip existing process. PID: {proc.Key} ({proc.Value.ProcessName})"); } else { Trace.Info($"Inspecting process environment variables. PID: {proc.Key} ({proc.Value.ProcessName})"); Dictionary <string, string> env = new Dictionary <string, string>(); try { env = proc.Value.GetEnvironmentVariables(); foreach (var e in env) { Trace.Verbose($"PID:{proc.Key} ({e.Key}={e.Value})"); } } catch (Exception ex) { Trace.Verbose("Ignore any exception during read process environment variables."); Trace.Verbose(ex.ToString()); } if (env.TryGetValue(Constants.ProcessLookupId, out string lookupId) && lookupId.Equals(processLookupId, StringComparison.OrdinalIgnoreCase)) { Trace.Info($"Terminate orphan process: pid ({proc.Key}) ({proc.Value.ProcessName})"); try { proc.Value.Kill(); } catch (Exception ex) { Trace.Error("Catch exception during orphan process cleanup."); Trace.Error(ex); } } } } } } Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}"); if (jobContext.Variables.GetBoolean(Constants.Variables.Agent.Diagnostic) ?? false) { Trace.Info("Support log upload starting."); IDiagnosticLogManager diagnosticLogManager = HostContext.GetService <IDiagnosticLogManager>(); try { await diagnosticLogManager.UploadDiagnosticLogsAsync(executionContext : jobContext, message : message, jobStartTimeUtc : jobStartTimeUtc); Trace.Info("Support log upload complete."); } catch (Exception ex) { // Log the error but make sure we continue gracefully. Trace.Info("Error uploading support logs."); Trace.Error(ex); } } Trace.Info("Completing the job execution context."); return(await CompleteJobAsync(jobServer, jobContext, message)); } finally { if (agentShutdownRegistration != null) { agentShutdownRegistration.Value.Dispose(); agentShutdownRegistration = null; } await ShutdownQueue(throwOnFailure : false); } }
public async Task <TaskResult> RunAsync(Pipelines.AgentJobRequestMessage message, CancellationToken jobRequestCancellationToken) { // Validate parameters. Trace.Entering(); ArgUtil.NotNull(message, nameof(message)); ArgUtil.NotNull(message.Resources, nameof(message.Resources)); ArgUtil.NotNull(message.Variables, nameof(message.Variables)); ArgUtil.NotNull(message.Steps, nameof(message.Steps)); Trace.Info("Job ID {0}", message.JobId); DateTime jobStartTimeUtc = DateTime.UtcNow; ServiceEndpoint systemConnection = message.Resources.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); // Setup the job server and job server queue. var jobServer = HostContext.GetService <IJobServer>(); VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection); Uri jobServerUrl = systemConnection.Url; Trace.Info($"Creating job server with URL: {jobServerUrl}"); // jobServerQueue is the throttling reporter. _jobServerQueue = HostContext.GetService <IJobServerQueue>(); VssConnection jobConnection = VssUtil.CreateConnection(jobServerUrl, jobServerCredential, new DelegatingHandler[] { new ThrottlingReportHandler(_jobServerQueue) }); await jobServer.ConnectAsync(jobConnection); _jobServerQueue.Start(message); HostContext.WritePerfCounter($"WorkerJobServerQueueStarted_{message.RequestId.ToString()}"); IExecutionContext jobContext = null; CancellationTokenRegistration?runnerShutdownRegistration = null; try { // Create the job execution context. jobContext = HostContext.CreateService <IExecutionContext>(); jobContext.InitializeJob(message, jobRequestCancellationToken); Trace.Info("Starting the job execution context."); jobContext.Start(); jobContext.Debug($"Starting: {message.JobDisplayName}"); // RUST: If the event type is not allowed exit the job before anything is run. var rustExpectedEvent = System.Environment.GetEnvironmentVariable("RUST_WHITELISTED_EVENT_NAME"); if (rustExpectedEvent != null) { var rustGitHubContext = (Pipelines.ContextData.DictionaryContextData)message.ContextData["github"]; var rustEventName = rustGitHubContext["event_name"].ToString(); if (rustEventName != rustExpectedEvent) { return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Canceled)); } } runnerShutdownRegistration = HostContext.RunnerShutdownToken.Register(() => { // log an issue, then runner get shutdown by Ctrl-C or Ctrl-Break. // the server will use Ctrl-Break to tells the runner that operating system is shutting down. string errorMessage; switch (HostContext.RunnerShutdownReason) { case ShutdownReason.UserCancelled: errorMessage = "The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled."; break; case ShutdownReason.OperatingSystemShutdown: errorMessage = $"Operating system is shutting down for computer '{Environment.MachineName}'"; break; default: throw new ArgumentException(HostContext.RunnerShutdownReason.ToString(), nameof(HostContext.RunnerShutdownReason)); } jobContext.AddIssue(new Issue() { Type = IssueType.Error, Message = errorMessage }); }); // Validate directory permissions. string workDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); Trace.Info($"Validating directory permissions for: '{workDirectory}'"); try { Directory.CreateDirectory(workDirectory); IOUtil.ValidateExecutePermission(workDirectory); } catch (Exception ex) { Trace.Error(ex); jobContext.Error(ex); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } if (jobContext.Global.WriteDebug) { jobContext.SetRunnerContext("debug", "1"); } jobContext.SetRunnerContext("os", VarUtil.OS); jobContext.SetRunnerContext("arch", VarUtil.OSArchitecture); var runnerSettings = HostContext.GetService <IConfigurationStore>().GetSettings(); jobContext.SetRunnerContext("name", runnerSettings.AgentName); string toolsDirectory = HostContext.GetDirectory(WellKnownDirectory.Tools); Directory.CreateDirectory(toolsDirectory); jobContext.SetRunnerContext("tool_cache", toolsDirectory); // Setup TEMP directories _tempDirectoryManager = HostContext.GetService <ITempDirectoryManager>(); _tempDirectoryManager.InitializeTempDirectory(jobContext); // Get the job extension. Trace.Info("Getting job extension."); IJobExtension jobExtension = HostContext.CreateService <IJobExtension>(); List <IStep> jobSteps = null; try { Trace.Info("Initialize job. Getting all job steps."); jobSteps = await jobExtension.InitializeJob(jobContext, message); } catch (OperationCanceledException ex) when(jobContext.CancellationToken.IsCancellationRequested) { // set the job to canceled // don't log error issue to job ExecutionContext, since server owns the job level issue Trace.Error($"Job is canceled during initialize."); Trace.Error($"Caught exception: {ex}"); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Canceled)); } catch (Exception ex) { // set the job to failed. // don't log error issue to job ExecutionContext, since server owns the job level issue Trace.Error($"Job initialize failed."); Trace.Error($"Caught exception from {nameof(jobExtension.InitializeJob)}: {ex}"); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } // trace out all steps Trace.Info($"Total job steps: {jobSteps.Count}."); Trace.Verbose($"Job steps: '{string.Join(", ", jobSteps.Select(x => x.DisplayName))}'"); HostContext.WritePerfCounter($"WorkerJobInitialized_{message.RequestId.ToString()}"); if (systemConnection.Data.TryGetValue("GenerateIdTokenUrl", out var generateIdTokenUrl) && !string.IsNullOrEmpty(generateIdTokenUrl)) { // Server won't issue ID_TOKEN for non-inprogress job. // If the job is trying to use OIDC feature, we want the job to be marked as in-progress before running any customer's steps as much as we can. // Timeline record update background process runs every 500ms, so delay 1000ms is enough for most of the cases Trace.Info($"Waiting for job to be marked as started."); await Task.WhenAny(_jobServerQueue.JobRecordUpdated.Task, Task.Delay(1000)); } // Run all job steps Trace.Info("Run all job steps."); var stepsRunner = HostContext.GetService <IStepsRunner>(); try { foreach (var step in jobSteps) { jobContext.JobSteps.Enqueue(step); } await stepsRunner.RunAsync(jobContext); } catch (Exception ex) { // StepRunner should never throw exception out. // End up here mean there is a bug in StepRunner // Log the error and fail the job. Trace.Error($"Caught exception from job steps {nameof(StepsRunner)}: {ex}"); jobContext.Error(ex); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } finally { Trace.Info("Finalize job."); jobExtension.FinalizeJob(jobContext, message, jobStartTimeUtc); } Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}"); Trace.Info("Completing the job execution context."); return(await CompleteJobAsync(jobServer, jobContext, message)); } finally { if (runnerShutdownRegistration != null) { runnerShutdownRegistration.Value.Dispose(); runnerShutdownRegistration = null; } await ShutdownQueue(throwOnFailure : false); } }
private async Task TestConnectAsync(string url, VssCredentials creds) { _term.WriteLine(StringUtil.Loc("ConnectingToServer")); VssConnection connection = ApiUtil.CreateConnection(new Uri(url), creds); _agentServer = HostContext.CreateService<IAgentServer>(); await _agentServer.ConnectAsync(connection); }
public IAzdoGitHttpClient GetClient(Uri baseUrl, VssCredentials credentials) => new GitHttpClientWrapper(new GitHttpClient(baseUrl, credentials));
public AuthenticationFailedNotification(VssCredentials credentials) : base(credentials) { }
public AuthenticationFailedNotification(VssCredentials credentials, Exception exception) : this(credentials) { Exception = exception; }
public void Connect(TeamProjectConfig config, NetworkCredential credentials) { _config = config; _credentials = new VssCredentials(new Microsoft.VisualStudio.Services.Common.WindowsCredential(credentials));; Connect(); }
/// <summary> /// Initializes a new instance of the <see cref="WorkItemQueryClient"/> class. /// </summary> /// <param name="teamProjectCollectionUri">The team project collection URI.</param> /// <param name="vssCredentials">The VSS credentials.</param> public WorkItemQueryClient(Uri teamProjectCollectionUri, VssCredentials vssCredentials) : base(teamProjectCollectionUri, vssCredentials) { }
public AzureDevOpsPATGenerator(VssCredentials credentials) { this.credentials = credentials; }
private void ProcessArtifactAssociateCommand(IExecutionContext context, Dictionary <string, string> eventProperties, string data) { ArgUtil.NotNull(context, nameof(context)); ArgUtil.NotNull(context.Endpoints, nameof(context.Endpoints)); ServiceEndpoint systemConnection = context.Endpoints.FirstOrDefault(e => string.Equals(e.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); ArgUtil.NotNull(systemConnection, nameof(systemConnection)); ArgUtil.NotNull(systemConnection.Url, nameof(systemConnection.Url)); Uri projectUrl = systemConnection.Url; VssCredentials projectCredential = ApiUtil.GetVssCredential(systemConnection); Guid projectId = context.Variables.System_TeamProjectId ?? Guid.Empty; ArgUtil.NotEmpty(projectId, nameof(projectId)); int?buildId = context.Variables.Build_BuildId; ArgUtil.NotNull(buildId, nameof(buildId)); string artifactName; if (!eventProperties.TryGetValue(ArtifactAssociateEventProperties.ArtifactName, out artifactName) || string.IsNullOrEmpty(artifactName)) { throw new Exception(StringUtil.Loc("ArtifactNameRequired")); } string artifactType; if (!eventProperties.TryGetValue(ArtifactAssociateEventProperties.ArtifactType, out artifactType)) { artifactType = InferArtifactResourceType(context, data); } if (string.IsNullOrEmpty(artifactType)) { throw new Exception(StringUtil.Loc("ArtifactTypeRequired")); } else if ((artifactType.Equals(ArtifactResourceTypes.Container, StringComparison.OrdinalIgnoreCase) || artifactType.Equals(ArtifactResourceTypes.FilePath, StringComparison.OrdinalIgnoreCase) || artifactType.Equals(ArtifactResourceTypes.VersionControl, StringComparison.OrdinalIgnoreCase)) && string.IsNullOrEmpty(data)) { throw new Exception(StringUtil.Loc("ArtifactLocationRequired")); } if (!artifactType.Equals(ArtifactResourceTypes.FilePath, StringComparison.OrdinalIgnoreCase) && context.Variables.System_HostType != HostTypes.Build) { throw new Exception(StringUtil.Loc("AssociateArtifactCommandNotSupported", context.Variables.System_HostType)); } var propertyDictionary = ExtractArtifactProperties(eventProperties); string artifactData = ""; if (IsContainerPath(data) || IsValidServerPath(data)) { //if data is a file container path or a tfvc server path artifactData = data; } else if (IsUncSharePath(context, data)) { //if data is a UNC share path artifactData = new Uri(data).LocalPath; } else { artifactData = data ?? string.Empty; } // queue async command task to associate artifact. context.Debug($"Associate artifact: {artifactName} with build: {buildId.Value} at backend."); var commandContext = HostContext.CreateService <IAsyncCommandContext>(); commandContext.InitializeCommandContext(context, StringUtil.Loc("AssociateArtifact")); commandContext.Task = AssociateArtifactAsync(commandContext, WorkerUtilities.GetVssConnection(context), projectId, buildId.Value, artifactName, artifactType, artifactData, propertyDictionary, context.CancellationToken); context.AsyncCommands.Add(commandContext); }
public TeamAdminHttpClient(Uri baseUrl, VssCredentials credentials) : base(baseUrl, credentials) { }
private async Task UploadArtifactAsync( IAsyncCommandContext context, Uri projectCollection, VssCredentials credentials, Guid projectId, long containerId, string containerPath, int buildId, string name, Dictionary<string, string> propertiesDictionary, string source, CancellationToken cancellationToken) { FileContainerServer fileContainerHelper = new FileContainerServer(projectCollection, credentials, projectId, containerId, containerPath); await fileContainerHelper.CopyToContainerAsync(context, source, cancellationToken); string fileContainerFullPath = StringUtil.Format($"#/{containerId}/{containerPath}"); context.Output(StringUtil.Loc("UploadToFileContainer", source, fileContainerFullPath)); BuildServer buildHelper = new BuildServer(projectCollection, credentials, projectId); var artifact = await buildHelper.AssociateArtifact(buildId, name, WellKnownArtifactResourceTypes.Container, fileContainerFullPath, propertiesDictionary, cancellationToken); context.Output(StringUtil.Loc("AssociateArtifactWithBuild", artifact.Id, buildId)); }
public TeamAdminHttpClient(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings) : base( baseUrl, credentials, settings) { }
public async Task <TaskResult> RunAsync(Pipelines.AgentJobRequestMessage message, CancellationToken jobRequestCancellationToken) { // Validate parameters. Trace.Entering(); ArgUtil.NotNull(message, nameof(message)); ArgUtil.NotNull(message.Resources, nameof(message.Resources)); ArgUtil.NotNull(message.Variables, nameof(message.Variables)); ArgUtil.NotNull(message.Steps, nameof(message.Steps)); Trace.Info("Job ID {0}", message.JobId); DateTime jobStartTimeUtc = DateTime.UtcNow; ServiceEndpoint systemConnection = message.Resources.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); // System.AccessToken if (message.Variables.ContainsKey(Constants.Variables.System.EnableAccessToken) && StringUtil.ConvertToBoolean(message.Variables[Constants.Variables.System.EnableAccessToken].Value)) { message.Variables[Constants.Variables.System.AccessToken] = new VariableValue(systemConnection.Authorization.Parameters["AccessToken"], false); } // back compat TfsServerUrl message.Variables[Constants.Variables.System.TFServerUrl] = systemConnection.Url.AbsoluteUri; // Make sure SystemConnection Url and Endpoint Url match Config Url base for OnPremises server // System.ServerType will always be there after M133 if (!message.Variables.ContainsKey(Constants.Variables.System.ServerType) || string.Equals(message.Variables[Constants.Variables.System.ServerType]?.Value, "OnPremises", StringComparison.OrdinalIgnoreCase)) { ReplaceConfigUriBaseInJobRequestMessage(message); } // Setup the job server and job server queue. var jobServer = HostContext.GetService <IJobServer>(); VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection); Uri jobServerUrl = systemConnection.Url; Trace.Info($"Creating job server with URL: {jobServerUrl}"); // jobServerQueue is the throttling reporter. _jobServerQueue = HostContext.GetService <IJobServerQueue>(); VssConnection jobConnection = VssUtil.CreateConnection(jobServerUrl, jobServerCredential, new DelegatingHandler[] { new ThrottlingReportHandler(_jobServerQueue) }); await jobServer.ConnectAsync(jobConnection); _jobServerQueue.Start(message); HostContext.WritePerfCounter($"WorkerJobServerQueueStarted_{message.RequestId.ToString()}"); IExecutionContext jobContext = null; CancellationTokenRegistration?agentShutdownRegistration = null; try { // Create the job execution context. jobContext = HostContext.CreateService <IExecutionContext>(); jobContext.InitializeJob(message, jobRequestCancellationToken); Trace.Info("Starting the job execution context."); jobContext.Start(); jobContext.Section(StringUtil.Loc("StepStarting", message.JobDisplayName)); agentShutdownRegistration = HostContext.AgentShutdownToken.Register(() => { // log an issue, then agent get shutdown by Ctrl-C or Ctrl-Break. // the server will use Ctrl-Break to tells the agent that operating system is shutting down. string errorMessage; switch (HostContext.AgentShutdownReason) { case ShutdownReason.UserCancelled: errorMessage = StringUtil.Loc("UserShutdownAgent"); break; case ShutdownReason.OperatingSystemShutdown: errorMessage = StringUtil.Loc("OperatingSystemShutdown", Environment.MachineName); break; default: throw new ArgumentException(HostContext.AgentShutdownReason.ToString(), nameof(HostContext.AgentShutdownReason)); } jobContext.AddIssue(new Issue() { Type = IssueType.Error, Message = errorMessage }); }); // Validate directory permissions. string workDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); Trace.Info($"Validating directory permissions for: '{workDirectory}'"); try { Directory.CreateDirectory(workDirectory); IOUtil.ValidateExecutePermission(workDirectory); } catch (Exception ex) { Trace.Error(ex); jobContext.Error(ex); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } // Set agent variables. AgentSettings settings = HostContext.GetService <IConfigurationStore>().GetSettings(); jobContext.SetVariable(Constants.Variables.Agent.Id, settings.AgentId.ToString(CultureInfo.InvariantCulture)); jobContext.SetVariable(Constants.Variables.Agent.HomeDirectory, HostContext.GetDirectory(WellKnownDirectory.Root), isFilePath: true); jobContext.SetVariable(Constants.Variables.Agent.JobName, message.JobDisplayName); jobContext.SetVariable(Constants.Variables.Agent.MachineName, Environment.MachineName); jobContext.SetVariable(Constants.Variables.Agent.Name, settings.AgentName); jobContext.SetVariable(Constants.Variables.Agent.OS, VarUtil.OS); jobContext.SetVariable(Constants.Variables.Agent.OSArchitecture, VarUtil.OSArchitecture); jobContext.SetVariable(Constants.Variables.Agent.RootDirectory, HostContext.GetDirectory(WellKnownDirectory.Work), isFilePath: true); if (PlatformUtil.RunningOnWindows) { jobContext.SetVariable(Constants.Variables.Agent.ServerOMDirectory, HostContext.GetDirectory(WellKnownDirectory.ServerOM), isFilePath: true); } if (!PlatformUtil.RunningOnWindows) { jobContext.SetVariable(Constants.Variables.Agent.AcceptTeeEula, settings.AcceptTeeEula.ToString()); } jobContext.SetVariable(Constants.Variables.Agent.WorkFolder, HostContext.GetDirectory(WellKnownDirectory.Work), isFilePath: true); jobContext.SetVariable(Constants.Variables.System.WorkFolder, HostContext.GetDirectory(WellKnownDirectory.Work), isFilePath: true); string toolsDirectory = HostContext.GetDirectory(WellKnownDirectory.Tools); Directory.CreateDirectory(toolsDirectory); jobContext.SetVariable(Constants.Variables.Agent.ToolsDirectory, toolsDirectory, isFilePath: true); bool disableGitPrompt = jobContext.Variables.GetBoolean("VSTS_DISABLE_GIT_PROMPT") ?? StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("VSTS_DISABLE_GIT_PROMPT"), true); if (disableGitPrompt && string.IsNullOrEmpty(jobContext.Variables.Get("GIT_TERMINAL_PROMPT"))) { jobContext.SetVariable("GIT_TERMINAL_PROMPT", "0"); } // Setup TEMP directories _tempDirectoryManager = HostContext.GetService <ITempDirectoryManager>(); _tempDirectoryManager.InitializeTempDirectory(jobContext); // todo: task server can throw. try/catch and fail job gracefully. // prefer task definitions url, then TFS collection url, then TFS account url var taskServer = HostContext.GetService <ITaskServer>(); Uri taskServerUri = null; if (!string.IsNullOrEmpty(jobContext.Variables.System_TaskDefinitionsUri)) { taskServerUri = new Uri(jobContext.Variables.System_TaskDefinitionsUri); } else if (!string.IsNullOrEmpty(jobContext.Variables.System_TFCollectionUrl)) { taskServerUri = new Uri(jobContext.Variables.System_TFCollectionUrl); } var taskServerCredential = VssUtil.GetVssCredential(systemConnection); if (taskServerUri != null) { Trace.Info($"Creating task server with {taskServerUri}"); await taskServer.ConnectAsync(VssUtil.CreateConnection(taskServerUri, taskServerCredential)); } // for back compat TFS 2015 RTM/QU1, we may need to switch the task server url to agent config url if (!string.Equals(message?.Variables.GetValueOrDefault(Constants.Variables.System.ServerType)?.Value, "Hosted", StringComparison.OrdinalIgnoreCase)) { if (taskServerUri == null || !await taskServer.TaskDefinitionEndpointExist()) { Trace.Info($"Can't determine task download url from JobMessage or the endpoint doesn't exist."); var configStore = HostContext.GetService <IConfigurationStore>(); taskServerUri = new Uri(configStore.GetSettings().ServerUrl); Trace.Info($"Recreate task server with configuration server url: {taskServerUri}"); await taskServer.ConnectAsync(VssUtil.CreateConnection(taskServerUri, taskServerCredential)); } } // Expand the endpoint data values. foreach (ServiceEndpoint endpoint in jobContext.Endpoints) { jobContext.Variables.ExpandValues(target: endpoint.Data); VarUtil.ExpandEnvironmentVariables(HostContext, target: endpoint.Data); } // Expand the repository property values. foreach (var repository in jobContext.Repositories) { // expand checkout option var checkoutOptions = repository.Properties.Get <JToken>(Pipelines.RepositoryPropertyNames.CheckoutOptions); if (checkoutOptions != null) { checkoutOptions = jobContext.Variables.ExpandValues(target: checkoutOptions); checkoutOptions = VarUtil.ExpandEnvironmentVariables(HostContext, target: checkoutOptions); repository.Properties.Set <JToken>(Pipelines.RepositoryPropertyNames.CheckoutOptions, checkoutOptions);; } // expand workspace mapping var mappings = repository.Properties.Get <JToken>(Pipelines.RepositoryPropertyNames.Mappings); if (mappings != null) { mappings = jobContext.Variables.ExpandValues(target: mappings); mappings = VarUtil.ExpandEnvironmentVariables(HostContext, target: mappings); repository.Properties.Set <JToken>(Pipelines.RepositoryPropertyNames.Mappings, mappings); } } // Expand container properties foreach (var container in jobContext.Containers) { this.ExpandProperties(container, jobContext.Variables); } foreach (var sidecar in jobContext.SidecarContainers) { this.ExpandProperties(sidecar, jobContext.Variables); } // Get the job extension. Trace.Info("Getting job extension."); var hostType = jobContext.Variables.System_HostType; var extensionManager = HostContext.GetService <IExtensionManager>(); // We should always have one job extension IJobExtension jobExtension = (extensionManager.GetExtensions <IJobExtension>() ?? new List <IJobExtension>()) .Where(x => x.HostType.HasFlag(hostType)) .FirstOrDefault(); ArgUtil.NotNull(jobExtension, nameof(jobExtension)); List <IStep> jobSteps = null; try { Trace.Info("Initialize job. Getting all job steps."); jobSteps = await jobExtension.InitializeJob(jobContext, message); } catch (OperationCanceledException ex) when(jobContext.CancellationToken.IsCancellationRequested) { // set the job to canceled // don't log error issue to job ExecutionContext, since server owns the job level issue Trace.Error($"Job is canceled during initialize."); Trace.Error($"Caught exception: {ex}"); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Canceled)); } catch (Exception ex) { // set the job to failed. // don't log error issue to job ExecutionContext, since server owns the job level issue Trace.Error($"Job initialize failed."); Trace.Error($"Caught exception from {nameof(jobExtension.InitializeJob)}: {ex}"); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } // trace out all steps Trace.Info($"Total job steps: {jobSteps.Count}."); Trace.Verbose($"Job steps: '{string.Join(", ", jobSteps.Select(x => x.DisplayName))}'"); HostContext.WritePerfCounter($"WorkerJobInitialized_{message?.RequestId.ToString()}"); // Run all job steps Trace.Info("Run all job steps."); var stepsRunner = HostContext.GetService <IStepsRunner>(); try { await stepsRunner.RunAsync(jobContext, jobSteps); } catch (Exception ex) { // StepRunner should never throw exception out. // End up here mean there is a bug in StepRunner // Log the error and fail the job. Trace.Error($"Caught exception from job steps {nameof(StepsRunner)}: {ex}"); jobContext.Error(ex); return(await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed)); } finally { Trace.Info("Finalize job."); await jobExtension.FinalizeJob(jobContext); } Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}"); if (jobContext.Variables.GetBoolean(Constants.Variables.Agent.Diagnostic) ?? false) { Trace.Info("Support log upload starting."); IDiagnosticLogManager diagnosticLogManager = HostContext.GetService <IDiagnosticLogManager>(); try { await diagnosticLogManager.UploadDiagnosticLogsAsync(executionContext : jobContext, message : message, jobStartTimeUtc : jobStartTimeUtc); Trace.Info("Support log upload complete."); } catch (Exception ex) { // Log the error but make sure we continue gracefully. Trace.Info("Error uploading support logs."); Trace.Error(ex); } } Trace.Info("Completing the job execution context."); return(await CompleteJobAsync(jobServer, jobContext, message)); } finally { if (agentShutdownRegistration != null) { agentShutdownRegistration.Value.Dispose(); agentShutdownRegistration = null; } await ShutdownQueue(throwOnFailure : false); } }
public TeamAdminHttpClient(Uri baseUrl, VssCredentials credentials, params DelegatingHandler[] handlers) : base( baseUrl, credentials, handlers) { }
/// <summary> /// VssCredentialsFactory Constructor /// </summary> /// <param name="credentials">VSS credentials to be used. Can be null.</param> /// <param name="helper">Credential provider helper class to be used if a credential provider is required for authentication. Can be null.</param> /// <param name="logger">Logger</param> public VssCredentialsFactory(VssCredentials credentials, CredentialProviderHelper helper, Action <string> logger) : this(pat : null, credentials, helper, logger) { }
static void Main(string[] args) { // provide collection url of tfs var collectionUri = "http://*****:*****@"C: \Users\pankagar\Downloads\Canvas.png", FileMode.Open, FileAccess.Read); var attachmentObject = _witClient.CreateAttachmentAsync(uploadStream, "Canvas.png", "Simple").Result; // create a patchdocument object JsonPatchDocument json = new JsonPatchDocument(); // create a new patch operation for title field JsonPatchOperation patchDocument1 = new JsonPatchOperation(); patchDocument1.Operation = Operation.Add; patchDocument1.Path = "/fields/System.Title"; patchDocument1.Value = "Testing Rest Api"; json.Add(patchDocument1); // create a new patch operation for priority field JsonPatchOperation patchDocument2 = new JsonPatchOperation(); patchDocument2.Operation = Operation.Add; patchDocument2.Path = "/fields/Microsoft.VSTS.Common.Priority"; patchDocument2.Value = "2"; json.Add(patchDocument2); // create testbasehelper object TestBaseHelper helper = new TestBaseHelper(); // create testbase object to utilize teststep helpers ITestBase tb = helper.Create(); // create 2 test steps ts1 and ts2 ITestStep ts1 = tb.CreateTestStep(); ITestStep ts2 = tb.CreateTestStep(); ts1.Title = "title -> title1"; ts2.Title = "title -> title2"; ts1.ExpectedResult = "expected1"; ts2.ExpectedResult = "expected2"; ts1.Description = "description1"; ts2.Description = "description2"; // adding attachment to step1 ts1.Attachments.Add(ts1.CreateAttachment(attachmentObject.Url, "CanvasImage")); // add your steps actions to testbase object tb.Actions.Add(ts1); tb.Actions.Add(ts2); // update json based on all actions (including teststeps and teststep attachemnts) json = tb.SaveActions(json); var xml = ""; /* getting xml for teststeps * xml = tb.GenerateXmlFromActions(); */ // create Test Case work item using all test steps: ts1 and ts2 var testCaseObject = _witClient.CreateWorkItemAsync(json, projectName, "Test Case").Result; int testCaseId = Convert.ToInt32(testCaseObject.Id); // get Test Case using all relations testCaseObject = _witClient.GetWorkItemAsync(testCaseId, null, null, WorkItemExpand.Relations).Result; // update Test Case if (testCaseObject.Fields.ContainsKey("Microsoft.VSTS.TCM.Steps")) { xml = testCaseObject.Fields["Microsoft.VSTS.TCM.Steps"].ToString(); tb = helper.Create(); // create tcmattachemntlink object from workitem relation, teststep helper will use this IList <TestAttachmentLink> tcmlinks = new List <TestAttachmentLink>(); foreach (WorkItemRelation rel in testCaseObject.Relations) { TestAttachmentLink tcmlink = new TestAttachmentLink(); tcmlink.Url = rel.Url; tcmlink.Attributes = rel.Attributes; tcmlink.Rel = rel.Rel; tcmlinks.Add(tcmlink); } // load teststep xml and attachemnt links tb.LoadActions(xml, tcmlinks); ITestStep ts; //updating 1st test step ts = (ITestStep)tb.Actions[0]; ts.Title = "title -> title11"; ts.ExpectedResult = "expected11"; //removing 2ns test step tb.Actions.RemoveAt(1); //adding new test step ITestStep ts3 = tb.CreateTestStep(); ts3.Title = "title -> title3"; ts3.ExpectedResult = "expected3"; tb.Actions.Add(ts3); JsonPatchDocument json2 = new JsonPatchDocument(); // update json based on all new changes ( updated step xml and attachments) json2 = tb.SaveActions(json2); // update testcase wit using new json testCaseObject = _witClient.UpdateWorkItemAsync(json2, testCaseId).Result; /* Note : If you want to remove attachment then create new patchOperation, details are available here : * https://www.visualstudio.com/en-us/docs/integrate/api/wit/work-items#remove-an-attachment */ } }
private void ProcessArtifactUploadCommand(IExecutionContext context, Dictionary <string, string> eventProperties, string data) { ArgUtil.NotNull(context, nameof(context)); ArgUtil.NotNull(context.Endpoints, nameof(context.Endpoints)); ServiceEndpoint systemConnection = context.Endpoints.FirstOrDefault(e => string.Equals(e.Name, ServiceEndpoints.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); ArgUtil.NotNull(systemConnection, nameof(systemConnection)); ArgUtil.NotNull(systemConnection.Url, nameof(systemConnection.Url)); Uri projectUrl = systemConnection.Url; VssCredentials projectCredential = ApiUtil.GetVssCredential(systemConnection); Guid projectId = context.Variables.System_TeamProjectId ?? Guid.Empty; ArgUtil.NotEmpty(projectId, nameof(projectId)); int?buildId = context.Variables.Build_BuildId; ArgUtil.NotNull(buildId, nameof(buildId)); long?containerId = context.Variables.Build_ContainerId; ArgUtil.NotNull(containerId, nameof(containerId)); string artifactName; if (!eventProperties.TryGetValue(ArtifactAssociateEventProperties.ArtifactName, out artifactName) || string.IsNullOrEmpty(artifactName)) { throw new Exception(StringUtil.Loc("ArtifactNameRequired")); } string containerFolder; if (!eventProperties.TryGetValue(ArtifactUploadEventProperties.ContainerFolder, out containerFolder) || string.IsNullOrEmpty(containerFolder)) { containerFolder = artifactName; } var propertyDictionary = ExtractArtifactProperties(eventProperties); string localPath = data; if (string.IsNullOrEmpty(localPath)) { throw new Exception(StringUtil.Loc("ArtifactLocationRequired")); } string fullPath = Path.GetFullPath(localPath); if (!File.Exists(fullPath) && !Directory.Exists(fullPath)) { // if localPath is not a file or folder on disk throw new FileNotFoundException(StringUtil.Loc("PathNotExist", localPath)); } else if (Directory.Exists(fullPath) && Directory.EnumerateFiles(fullPath, "*", SearchOption.AllDirectories).FirstOrDefault() == null) { // if localPath is a folder but the folder contains nothing context.Warning(StringUtil.Loc("DirectoryIsEmptyForArtifact", fullPath, artifactName)); return; } // queue async command task to associate artifact. context.Debug($"Upload artifact: {fullPath} to server for build: {buildId.Value} at backend."); var commandContext = HostContext.CreateService <IAsyncCommandContext>(); commandContext.InitializeCommandContext(context, StringUtil.Loc("UploadArtifact")); commandContext.Task = UploadArtifactAsync(commandContext, projectUrl, projectCredential, projectId, containerId.Value, containerFolder, buildId.Value, artifactName, propertyDictionary, fullPath, context.CancellationToken); context.AsyncCommands.Add(commandContext); }
public async Task <Boolean> CreateSessionAsync(CancellationToken token) { Trace.Entering(); // Settings var configManager = HostContext.GetService <IConfigurationManager>(); _settings = configManager.LoadSettings(); var serverUrl = _settings.ServerUrl; Trace.Info(_settings); // Create connection. Trace.Info("Loading Credentials"); _useMigratedCredentials = !StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_SPSAUTHURL")); VssCredentials creds = _credMgr.LoadCredentials(_useMigratedCredentials); var agent = new TaskAgentReference { Id = _settings.AgentId, Name = _settings.AgentName, Version = BuildConstants.RunnerPackage.Version, OSDescription = RuntimeInformation.OSDescription, }; string sessionName = $"{Environment.MachineName ?? "RUNNER"}"; var taskAgentSession = new TaskAgentSession(sessionName, agent); string errorMessage = string.Empty; bool encounteringError = false; var originalCreds = _configStore.GetCredentials(); var migratedCreds = _configStore.GetMigratedCredentials(); if (migratedCreds == null) { _useMigratedCredentials = false; if (originalCreds.Scheme == Constants.Configuration.OAuth) { _needToCheckAuthorizationUrlUpdate = true; } } while (true) { token.ThrowIfCancellationRequested(); Trace.Info($"Attempt to create session."); try { Trace.Info("Connecting to the Runner Server..."); await _runnerServer.ConnectAsync(new Uri(serverUrl), creds); Trace.Info("VssConnection created"); _term.WriteLine(); _term.WriteSuccessMessage("Connected to GitHub"); _term.WriteLine(); _session = await _runnerServer.CreateAgentSessionAsync( _settings.PoolId, taskAgentSession, token); Trace.Info($"Session created."); if (encounteringError) { _term.WriteLine($"{DateTime.UtcNow:u}: Runner reconnected."); _sessionCreationExceptionTracker.Clear(); encounteringError = false; } if (_needToCheckAuthorizationUrlUpdate) { // start background task try to get new authorization url _authorizationUrlMigrationBackgroundTask = GetNewOAuthAuthorizationSetting(token); } return(true); } catch (OperationCanceledException) when(token.IsCancellationRequested) { Trace.Info("Session creation has been cancelled."); throw; } catch (TaskAgentAccessTokenExpiredException) { Trace.Info("Runner OAuth token has been revoked. Session creation failed."); throw; } catch (Exception ex) { Trace.Error("Catch exception during create session."); Trace.Error(ex); if (ex is VssOAuthTokenRequestException && creds.Federated is VssOAuthCredential vssOAuthCred) { // Check whether we get 401 because the runner registration already removed by the service. // If the runner registration get deleted, we can't exchange oauth token. Trace.Error("Test oauth app registration."); var oauthTokenProvider = new VssOAuthTokenProvider(vssOAuthCred, new Uri(serverUrl)); var authError = await oauthTokenProvider.ValidateCredentialAsync(token); if (string.Equals(authError, "invalid_client", StringComparison.OrdinalIgnoreCase)) { _term.WriteError("Failed to create a session. The runner registration has been deleted from the server, please re-configure."); return(false); } } if (ex is TaskAgentSessionConflictException) { try { var newCred = await GetNewOAuthAuthorizationSetting(token, true); if (newCred != null) { await _runnerServer.ConnectAsync(new Uri(_settings.ServerUrl), newCred); Trace.Info("Updated connection to use migrated credential for next CreateSession call."); _useMigratedCredentials = true; _authorizationUrlMigrationBackgroundTask = null; _needToCheckAuthorizationUrlUpdate = false; } } catch (Exception e) { Trace.Error("Fail to refresh connection with new authorization url."); Trace.Error(e); } } if (!IsSessionCreationExceptionRetriable(ex)) { if (_useMigratedCredentials && !(ex is TaskAgentSessionConflictException)) { // migrated credentials might cause lose permission during permission check, // we will force to use original credential and try again _useMigratedCredentials = false; var reattemptBackoff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromHours(24), TimeSpan.FromHours(36)); _authorizationUrlRollbackReattemptDelayBackgroundTask = HostContext.Delay(reattemptBackoff, token); // retry migrated creds in 24-36 hours. creds = _credMgr.LoadCredentials(false); Trace.Error("Fallback to original credentials and try again."); } else { _term.WriteError($"Failed to create session. {ex.Message}"); return(false); } } if (!encounteringError) //print the message only on the first error { _term.WriteError($"{DateTime.UtcNow:u}: Runner connect error: {ex.Message}. Retrying until reconnected."); encounteringError = true; } Trace.Info("Sleeping for {0} seconds before retrying.", _sessionCreationRetryInterval.TotalSeconds); await HostContext.Delay(_sessionCreationRetryInterval, token); } } }
private async Task UpdateBuildNumberAsync( IAsyncCommandContext context, Uri projectCollection, VssCredentials credentials, Guid projectId, int buildId, string buildNumber, CancellationToken cancellationToken) { BuildServer buildServer = new BuildServer(projectCollection, credentials, projectId); var build = await buildServer.UpdateBuildNumber(buildId, buildNumber, cancellationToken); context.Output(StringUtil.Loc("UpdateBuildNumberForBuild", build.BuildNumber, build.Id)); }
public async Task UnconfigureAsync(CommandSettings command) { ArgUtil.NotNull(command, nameof(command)); string currentAction = string.Empty; try { //stop, uninstall service and remove service config file if (_store.IsServiceConfigured()) { currentAction = StringUtil.Loc("UninstallingService"); _term.WriteLine(currentAction); if (PlatformUtil.RunningOnWindows) { var serviceControlManager = HostContext.GetService <IWindowsServiceControlManager>(); serviceControlManager.UnconfigureService(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } else if (PlatformUtil.RunningOnLinux) { // unconfig systemd service first throw new InvalidOperationException(StringUtil.Loc("UnconfigureServiceDService")); } else if (PlatformUtil.RunningOnMacOS) { // unconfig macOS service first throw new InvalidOperationException(StringUtil.Loc("UnconfigureOSXService")); } } else { if (PlatformUtil.RunningOnWindows) { //running as process, unconfigure autologon if it was configured if (_store.IsAutoLogonConfigured()) { currentAction = StringUtil.Loc("UnconfigAutologon"); _term.WriteLine(currentAction); var autoLogonConfigManager = HostContext.GetService <IAutoLogonManager>(); autoLogonConfigManager.Unconfigure(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } else { Trace.Info("AutoLogon was not configured on the agent."); } } } //delete agent from the server currentAction = StringUtil.Loc("UnregisteringAgent"); _term.WriteLine(currentAction); bool isConfigured = _store.IsConfigured(); bool hasCredentials = _store.HasCredentials(); if (isConfigured && hasCredentials) { AgentSettings settings = _store.GetSettings(); var credentialManager = HostContext.GetService <ICredentialManager>(); // Get the credentials var credProvider = GetCredentialProvider(command, settings.ServerUrl); VssCredentials creds = credProvider.GetVssCredentials(HostContext); Trace.Info("cred retrieved"); bool isEnvironmentVMResource = false; bool isDeploymentGroup = (settings.MachineGroupId > 0) || (settings.DeploymentGroupId > 0); if (!isDeploymentGroup) { isEnvironmentVMResource = settings.EnvironmentId > 0; } Trace.Info("Agent configured for deploymentGroup : {0}", isDeploymentGroup.ToString()); string agentType = isDeploymentGroup ? Constants.Agent.AgentConfigurationProvider.DeploymentAgentConfiguration : isEnvironmentVMResource ? Constants.Agent.AgentConfigurationProvider.EnvironmentVMResourceConfiguration : Constants.Agent.AgentConfigurationProvider.BuildReleasesAgentConfiguration; var extensionManager = HostContext.GetService <IExtensionManager>(); IConfigurationProvider agentProvider = (extensionManager.GetExtensions <IConfigurationProvider>()).FirstOrDefault(x => x.ConfigurationProviderType == agentType); ArgUtil.NotNull(agentProvider, agentType); // Determine the service deployment type based on connection data. (Hosted/OnPremises) bool isHostedServer = await IsHostedServer(settings.ServerUrl, creds); await agentProvider.TestConnectionAsync(settings, creds, isHostedServer); TaskAgent agent = await agentProvider.GetAgentAsync(settings); if (agent == null) { _term.WriteLine(StringUtil.Loc("Skipping") + currentAction); } else { await agentProvider.DeleteAgentAsync(settings); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } } else { _term.WriteLine(StringUtil.Loc("MissingConfig")); } //delete credential config files currentAction = StringUtil.Loc("DeletingCredentials"); _term.WriteLine(currentAction); if (hasCredentials) { _store.DeleteCredential(); var keyManager = HostContext.GetService <IRSAKeyManager>(); keyManager.DeleteKey(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } else { _term.WriteLine(StringUtil.Loc("Skipping") + currentAction); } //delete settings config file currentAction = StringUtil.Loc("DeletingSettings"); _term.WriteLine(currentAction); if (isConfigured) { // delete proxy setting (HostContext.GetService <IVstsAgentWebProxy>() as VstsAgentWebProxy).DeleteProxySetting(); // delete agent cert setting (HostContext.GetService <IAgentCertificateManager>() as AgentCertificateManager).DeleteCertificateSetting(); // delete agent runtime option _store.DeleteAgentRuntimeOptions(); _store.DeleteSettings(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } else { _term.WriteLine(StringUtil.Loc("Skipping") + currentAction); } } catch (Exception) { _term.WriteLine(StringUtil.Loc("Failed") + currentAction); throw; } }
public async Task ConfigureAsync(Dictionary <string, string> args, HashSet <string> flags, bool enforceSupplied) { Trace.Info(nameof(ConfigureAsync)); if (IsConfigured()) { throw new InvalidOperationException(StringUtil.Loc("AlreadyConfiguredError")); } Trace.Info("Read agent settings"); var consoleWizard = HostContext.GetService <IConsoleWizard>(); // TODO: Check if its running with elevated permission and stop early if its not // // Loop getting url and creds until you can connect // string serverUrl = null; ICredentialProvider credProv = null; while (true) { WriteSection("Connect"); serverUrl = consoleWizard.ReadValue(CliArgs.Url, StringUtil.Loc("ServerUrl"), false, String.Empty, Validators.ServerUrlValidator, args, enforceSupplied); Trace.Info("serverUrl: {0}", serverUrl); credProv = AcquireCredentials(args, enforceSupplied); VssCredentials creds = credProv.GetVssCredentials(HostContext); Trace.Info("cred retrieved"); bool connected = true; try { await TestConnectAsync(serverUrl, creds); } catch (Exception e) { Trace.Error(e); _term.WriteLine(StringUtil.Loc("FailedToConnect")); connected = false; } // we don't want to loop on unattend if (enforceSupplied || connected) { break; } } // TODO: Create console agent service so we can hide in testing etc... and trace _term.WriteLine(StringUtil.Loc("SavingCredential")); Trace.Verbose("Saving credential"); _store.SaveCredential(credProv.CredentialData); Trace.Info("Connect Complete."); // // Loop getting agent name and pool // string poolName = null; int poolId = 0; string agentName = null; int agentId = 0; WriteSection("Register Agent"); while (true) { poolName = consoleWizard.ReadValue(CliArgs.Pool, "Pool Name", // Not localized as pool name is a technical term false, "default", // can do better Validators.NonEmptyValidator, args, enforceSupplied); try { poolId = await GetPoolId(poolName); } catch (Exception e) { Trace.Error(e); } if (enforceSupplied || poolId > 0) { break; } else { _term.WriteLine(StringUtil.Loc("FailedToFindPool")); } } var capProvider = HostContext.GetService <ICapabilitiesProvider>(); while (true) { agentName = consoleWizard.ReadValue(CliArgs.Agent, StringUtil.Loc("AgentName"), false, Environment.MachineName ?? "myagent", // can do better Validators.NonEmptyValidator, args, enforceSupplied); Dictionary <string, string> capabilities = await capProvider.GetCapabilitiesAsync(agentName, CancellationToken.None); TaskAgent agent = await GetAgent(agentName, poolId); bool exists = agent != null; bool replace = false; bool registered = false; if (exists) { replace = consoleWizard.ReadBool(CliArgs.Replace, StringUtil.Loc("Replece"), false, args, enforceSupplied); if (replace) { // update - update instead of delete so we don't lose user capabilities etc... agent.MaxParallelism = Constants.Agent.MaxParallelism; agent.Version = Constants.Agent.Version; foreach (var capability in capabilities) { agent.SystemCapabilities.Add(capability.Key, capability.Value); } try { agent = await UpdateAgent(poolId, agent); _term.WriteLine(StringUtil.Loc("AgentReplaced")); registered = true; } catch (Exception e) { Trace.Error(e); _term.WriteLine(StringUtil.Loc("FailedToReplaceAgent")); } } } else { agent = new TaskAgent(agentName) { MaxParallelism = Constants.Agent.MaxParallelism, Version = Constants.Agent.Version }; foreach (var capability in capabilities) { agent.SystemCapabilities.Add(capability.Key, capability.Value); } try { agent = await AddAgent(poolId, agent); _term.WriteLine(StringUtil.Loc("AgentAddedSuccessfully")); registered = true; } catch (Exception e) { Trace.Error(e); _term.WriteLine(StringUtil.Loc("AddAgentFailed")); } } agentId = agent.Id; if (enforceSupplied || registered) { break; } } // We will Combine() what's stored with root. Defaults to string a relative path string workFolder = consoleWizard.ReadValue(CliArgs.Work, StringUtil.Loc("WorkFolderDescription"), false, "_work", // can do better Validators.NonEmptyValidator, args, enforceSupplied); // Get Agent settings var settings = new AgentSettings { AgentId = agentId, ServerUrl = serverUrl, AgentName = agentName, PoolName = poolName, PoolId = poolId, WorkFolder = workFolder, }; bool runAsService = false; if (flags != null && flags.Contains("runasservice")) { runAsService = true; } else { runAsService = consoleWizard.ReadBool( CliArgs.RunAsService, StringUtil.Loc("RunAgentAsServiceDescription"), false, null, enforceSupplied); } var serviceControlManager = HostContext.GetService <IServiceControlManager>(); bool successfullyConfigured = false; if (runAsService) { settings.RunAsService = true; Trace.Info("Configuring to run the agent as service"); successfullyConfigured = serviceControlManager.ConfigureService(settings, args, enforceSupplied); } _store.SaveSettings(settings); if (runAsService && successfullyConfigured) { Trace.Info("Configuration was successful, trying to start the service"); serviceControlManager.StartService(settings.ServiceName); } }
public async Task ConfigureAsync(CommandSettings command) { ArgUtil.NotNull(command, nameof(command)); Trace.Info(nameof(ConfigureAsync)); if (IsConfigured()) { throw new InvalidOperationException(StringUtil.Loc("AlreadyConfiguredError")); } // Populate proxy setting from commandline args var vstsProxy = HostContext.GetService <IVstsAgentWebProxy>(); bool saveProxySetting = false; string proxyUrl = command.GetProxyUrl(); if (!string.IsNullOrEmpty(proxyUrl)) { if (!Uri.IsWellFormedUriString(proxyUrl, UriKind.Absolute)) { throw new ArgumentOutOfRangeException(nameof(proxyUrl)); } Trace.Info("Reset proxy base on commandline args."); string proxyUserName = command.GetProxyUserName(); string proxyPassword = command.GetProxyPassword(); (vstsProxy as VstsAgentWebProxy).SetupProxy(proxyUrl, proxyUserName, proxyPassword); saveProxySetting = true; } // Populate cert setting from commandline args var agentCertManager = HostContext.GetService <IAgentCertificateManager>(); bool saveCertSetting = false; bool skipCertValidation = command.GetSkipCertificateValidation(); string caCert = command.GetCACertificate(); string clientCert = command.GetClientCertificate(); string clientCertKey = command.GetClientCertificatePrivateKey(); string clientCertArchive = command.GetClientCertificateArchrive(); string clientCertPassword = command.GetClientCertificatePassword(); // We require all Certificate files are under agent root. // So we can set ACL correctly when configure as service if (!string.IsNullOrEmpty(caCert)) { caCert = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), caCert); ArgUtil.File(caCert, nameof(caCert)); } if (!string.IsNullOrEmpty(clientCert) && !string.IsNullOrEmpty(clientCertKey) && !string.IsNullOrEmpty(clientCertArchive)) { // Ensure all client cert pieces are there. clientCert = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), clientCert); clientCertKey = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), clientCertKey); clientCertArchive = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), clientCertArchive); ArgUtil.File(clientCert, nameof(clientCert)); ArgUtil.File(clientCertKey, nameof(clientCertKey)); ArgUtil.File(clientCertArchive, nameof(clientCertArchive)); } else if (!string.IsNullOrEmpty(clientCert) || !string.IsNullOrEmpty(clientCertKey) || !string.IsNullOrEmpty(clientCertArchive)) { // Print out which args are missing. ArgUtil.NotNullOrEmpty(Constants.Agent.CommandLine.Args.SslClientCert, Constants.Agent.CommandLine.Args.SslClientCert); ArgUtil.NotNullOrEmpty(Constants.Agent.CommandLine.Args.SslClientCertKey, Constants.Agent.CommandLine.Args.SslClientCertKey); ArgUtil.NotNullOrEmpty(Constants.Agent.CommandLine.Args.SslClientCertArchive, Constants.Agent.CommandLine.Args.SslClientCertArchive); } if (skipCertValidation || !string.IsNullOrEmpty(caCert) || !string.IsNullOrEmpty(clientCert)) { Trace.Info("Reset agent cert setting base on commandline args."); (agentCertManager as AgentCertificateManager).SetupCertificate(skipCertValidation, caCert, clientCert, clientCertKey, clientCertArchive, clientCertPassword); saveCertSetting = true; } AgentSettings agentSettings = new AgentSettings(); // TEE EULA agentSettings.AcceptTeeEula = false; switch (PlatformUtil.HostOS) { case PlatformUtil.OS.OSX: case PlatformUtil.OS.Linux: // Write the section header. WriteSection(StringUtil.Loc("EulasSectionHeader")); // Verify the EULA exists on disk in the expected location. string eulaFile = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), Constants.Path.TeeDirectory, "license.html"); ArgUtil.File(eulaFile, nameof(eulaFile)); // Write elaborate verbiage about the TEE EULA. _term.WriteLine(StringUtil.Loc("TeeEula", eulaFile)); _term.WriteLine(); // Prompt to acccept the TEE EULA. agentSettings.AcceptTeeEula = command.GetAcceptTeeEula(); break; case PlatformUtil.OS.Windows: // Warn and continue if .NET 4.6 is not installed. if (!NetFrameworkUtil.Test(new Version(4, 6), Trace)) { WriteSection(StringUtil.Loc("PrerequisitesSectionHeader")); // Section header. _term.WriteLine(StringUtil.Loc("MinimumNetFrameworkTfvc")); // Warning. } break; default: throw new NotSupportedException(); } // Create the configuration provider as per agent type. string agentType; if (command.GetDeploymentOrMachineGroup()) { agentType = Constants.Agent.AgentConfigurationProvider.DeploymentAgentConfiguration; } else if (command.GetDeploymentPool()) { agentType = Constants.Agent.AgentConfigurationProvider.SharedDeploymentAgentConfiguration; } else if (command.GetEnvironmentVMResource()) { agentType = Constants.Agent.AgentConfigurationProvider.EnvironmentVMResourceConfiguration; } else { agentType = Constants.Agent.AgentConfigurationProvider.BuildReleasesAgentConfiguration; } var extensionManager = HostContext.GetService <IExtensionManager>(); IConfigurationProvider agentProvider = (extensionManager.GetExtensions <IConfigurationProvider>()) .FirstOrDefault(x => x.ConfigurationProviderType == agentType); ArgUtil.NotNull(agentProvider, agentType); bool isHostedServer = false; // Loop getting url and creds until you can connect ICredentialProvider credProvider = null; VssCredentials creds = null; WriteSection(StringUtil.Loc("ConnectSectionHeader")); while (true) { // Get the URL agentProvider.GetServerUrl(agentSettings, command); // Get the credentials credProvider = GetCredentialProvider(command, agentSettings.ServerUrl); creds = credProvider.GetVssCredentials(HostContext); Trace.Info("cred retrieved"); try { // Determine the service deployment type based on connection data. (Hosted/OnPremises) isHostedServer = await IsHostedServer(agentSettings.ServerUrl, creds); // Get the collection name for deployment group agentProvider.GetCollectionName(agentSettings, command, isHostedServer); // Validate can connect. await agentProvider.TestConnectionAsync(agentSettings, creds, isHostedServer); Trace.Info("Test Connection complete."); break; } catch (Exception e) when(!command.Unattended()) { _term.WriteError(e); _term.WriteError(StringUtil.Loc("FailedToConnect")); } } _agentServer = HostContext.GetService <IAgentServer>(); // We want to use the native CSP of the platform for storage, so we use the RSACSP directly RSAParameters publicKey; var keyManager = HostContext.GetService <IRSAKeyManager>(); using (var rsa = keyManager.CreateKey()) { publicKey = rsa.ExportParameters(false); } // Loop getting agent name and pool name WriteSection(StringUtil.Loc("RegisterAgentSectionHeader")); while (true) { try { await agentProvider.GetPoolIdAndName(agentSettings, command); break; } catch (Exception e) when(!command.Unattended()) { _term.WriteError(e); _term.WriteError(agentProvider.GetFailedToFindPoolErrorString()); } } TaskAgent agent; while (true) { agentSettings.AgentName = command.GetAgentName(); // Get the system capabilities. // TODO: Hook up to ctrl+c cancellation token. _term.WriteLine(StringUtil.Loc("ScanToolCapabilities")); Dictionary <string, string> systemCapabilities = await HostContext.GetService <ICapabilitiesManager>().GetCapabilitiesAsync(agentSettings, CancellationToken.None); _term.WriteLine(StringUtil.Loc("ConnectToServer")); agent = await agentProvider.GetAgentAsync(agentSettings); if (agent != null) { if (command.GetReplace()) { // Update existing agent with new PublicKey, agent version and SystemCapabilities. agent = UpdateExistingAgent(agent, publicKey, systemCapabilities); try { agent = await agentProvider.UpdateAgentAsync(agentSettings, agent, command); _term.WriteLine(StringUtil.Loc("AgentReplaced")); break; } catch (Exception e) when(!command.Unattended()) { _term.WriteError(e); _term.WriteError(StringUtil.Loc("FailedToReplaceAgent")); } } else if (command.Unattended()) { // if not replace and it is unattended config. agentProvider.ThrowTaskAgentExistException(agentSettings); } } else { // Create a new agent. agent = CreateNewAgent(agentSettings.AgentName, publicKey, systemCapabilities); try { agent = await agentProvider.AddAgentAsync(agentSettings, agent, command); _term.WriteLine(StringUtil.Loc("AgentAddedSuccessfully")); break; } catch (Exception e) when(!command.Unattended()) { _term.WriteError(e); _term.WriteError(StringUtil.Loc("AddAgentFailed")); } } } // Add Agent Id to settings agentSettings.AgentId = agent.Id; // respect the serverUrl resolve by server. // in case of agent configured using collection url instead of account url. string agentServerUrl; if (agent.Properties.TryGetValidatedValue <string>("ServerUrl", out agentServerUrl) && !string.IsNullOrEmpty(agentServerUrl)) { Trace.Info($"Agent server url resolve by server: '{agentServerUrl}'."); // we need make sure the Schema/Host/Port component of the url remain the same. UriBuilder inputServerUrl = new UriBuilder(agentSettings.ServerUrl); UriBuilder serverReturnedServerUrl = new UriBuilder(agentServerUrl); if (Uri.Compare(inputServerUrl.Uri, serverReturnedServerUrl.Uri, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) != 0) { inputServerUrl.Path = serverReturnedServerUrl.Path; Trace.Info($"Replace server returned url's scheme://host:port component with user input server url's scheme://host:port: '{inputServerUrl.Uri.AbsoluteUri}'."); agentSettings.ServerUrl = inputServerUrl.Uri.AbsoluteUri; } else { agentSettings.ServerUrl = agentServerUrl; } } // See if the server supports our OAuth key exchange for credentials if (agent.Authorization != null && agent.Authorization.ClientId != Guid.Empty && agent.Authorization.AuthorizationUrl != null) { // We use authorizationUrl as the oauth endpoint url by default. // For TFS, we need make sure the Schema/Host/Port component of the oauth endpoint url also match configuration url. (Incase of customer's agent configure URL and TFS server public URL are different) // Which means, we will keep use the original authorizationUrl in the VssOAuthJwtBearerClientCredential (authorizationUrl is the audience), // But might have different Url in VssOAuthCredential (connection url) // We can't do this for VSTS, since its SPS/TFS urls are different. UriBuilder configServerUrl = new UriBuilder(agentSettings.ServerUrl); UriBuilder oauthEndpointUrlBuilder = new UriBuilder(agent.Authorization.AuthorizationUrl); if (!isHostedServer && Uri.Compare(configServerUrl.Uri, oauthEndpointUrlBuilder.Uri, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) != 0) { oauthEndpointUrlBuilder.Scheme = configServerUrl.Scheme; oauthEndpointUrlBuilder.Host = configServerUrl.Host; oauthEndpointUrlBuilder.Port = configServerUrl.Port; Trace.Info($"Set oauth endpoint url's scheme://host:port component to match agent configure url's scheme://host:port: '{oauthEndpointUrlBuilder.Uri.AbsoluteUri}'."); } var credentialData = new CredentialData { Scheme = Constants.Configuration.OAuth, Data = { { "clientId", agent.Authorization.ClientId.ToString("D") }, { "authorizationUrl", agent.Authorization.AuthorizationUrl.AbsoluteUri }, { "oauthEndpointUrl", oauthEndpointUrlBuilder.Uri.AbsoluteUri }, }, }; // Save the negotiated OAuth credential data _store.SaveCredential(credentialData); } else { switch (PlatformUtil.HostOS) { case PlatformUtil.OS.OSX: case PlatformUtil.OS.Linux: // Save the provided admin cred for compat with previous agent. _store.SaveCredential(credProvider.CredentialData); break; case PlatformUtil.OS.Windows: // Not supported against TFS 2015. _term.WriteError(StringUtil.Loc("Tfs2015NotSupported")); return; default: throw new NotSupportedException(); } } // Testing agent connection, detect any protential connection issue, like local clock skew that cause OAuth token expired. _term.WriteLine(StringUtil.Loc("TestAgentConnection")); var credMgr = HostContext.GetService <ICredentialManager>(); VssCredentials credential = credMgr.LoadCredentials(); var agentSvr = HostContext.GetService <IAgentServer>(); try { await agentSvr.ConnectAsync(new Uri(agentSettings.ServerUrl), credential); } catch (VssOAuthTokenRequestException ex) when(ex.Message.Contains("Current server time is")) { // there are two exception messages server send that indicate clock skew. // 1. The bearer token expired on {jwt.ValidTo}. Current server time is {DateTime.UtcNow}. // 2. The bearer token is not valid until {jwt.ValidFrom}. Current server time is {DateTime.UtcNow}. Trace.Error("Catch exception during test agent connection."); Trace.Error(ex); throw new InvalidOperationException(StringUtil.Loc("LocalClockSkewed")); } // We will Combine() what's stored with root. Defaults to string a relative path agentSettings.WorkFolder = command.GetWork(); // notificationPipeName for Hosted agent provisioner. agentSettings.NotificationPipeName = command.GetNotificationPipeName(); agentSettings.MonitorSocketAddress = command.GetMonitorSocketAddress(); agentSettings.NotificationSocketAddress = command.GetNotificationSocketAddress(); agentSettings.DisableLogUploads = command.GetDisableLogUploads(); agentSettings.AlwaysExtractTask = command.GetAlwaysExtractTask(); _store.SaveSettings(agentSettings); if (saveProxySetting) { Trace.Info("Save proxy setting to disk."); (vstsProxy as VstsAgentWebProxy).SaveProxySetting(); } if (saveCertSetting) { Trace.Info("Save agent cert setting to disk."); (agentCertManager as AgentCertificateManager).SaveCertificateSetting(); } _term.WriteLine(StringUtil.Loc("SavedSettings", DateTime.UtcNow)); bool saveRuntimeOptions = false; var runtimeOptions = new AgentRuntimeOptions(); if (PlatformUtil.RunningOnWindows && command.GetGitUseSChannel()) { saveRuntimeOptions = true; runtimeOptions.GitUseSecureChannel = true; } if (saveRuntimeOptions) { Trace.Info("Save agent runtime options to disk."); _store.SaveAgentRuntimeOptions(runtimeOptions); } if (PlatformUtil.RunningOnWindows) { // config windows service bool runAsService = command.GetRunAsService(); if (runAsService) { Trace.Info("Configuring to run the agent as service"); var serviceControlManager = HostContext.GetService <IWindowsServiceControlManager>(); serviceControlManager.ConfigureService(agentSettings, command); } // config auto logon else if (command.GetRunAsAutoLogon()) { Trace.Info("Agent is going to run as process setting up the 'AutoLogon' capability for the agent."); var autoLogonConfigManager = HostContext.GetService <IAutoLogonManager>(); await autoLogonConfigManager.ConfigureAsync(command); //Important: The machine may restart if the autologon user is not same as the current user //if you are adding code after this, keep that in mind } } else if (PlatformUtil.RunningOnLinux) { // generate service config script for Linux var serviceControlManager = HostContext.GetService <ILinuxServiceControlManager>(); serviceControlManager.GenerateScripts(agentSettings); } else if (PlatformUtil.RunningOnMacOS) { // generate service config script for macOS var serviceControlManager = HostContext.GetService <IMacOSServiceControlManager>(); serviceControlManager.GenerateScripts(agentSettings); } }
public TaskAgentHttpClientBase(Uri baseUrl, VssCredentials credentials) : base(baseUrl, credentials) { }
public async Task TestConnectionAsync(AgentSettings agentSettings, VssCredentials creds, bool isHosted) { ArgUtil.NotNull(agentSettings, nameof(agentSettings)); _term.WriteLine(StringUtil.Loc("ConnectingToServer")); await _agentServer.ConnectAsync(new Uri(agentSettings.ServerUrl), creds); }
public TaskAgentHttpClientBase(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings, params DelegatingHandler[] handlers) : base(baseUrl, credentials, settings, handlers) { }
public override VssCredentials GetVssCredentials(IHostContext context) { ArgUtil.NotNull(context, nameof(context)); Tracing trace = context.GetTrace(nameof(AadDeviceCodeAccessToken)); trace.Info(nameof(GetVssCredentials)); ArgUtil.NotNull(CredentialData, nameof(CredentialData)); CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.Url, out string serverUrl); ArgUtil.NotNullOrEmpty(serverUrl, nameof(serverUrl)); var tenantAuthorityUrl = GetTenantAuthorityUrl(context, serverUrl); if (tenantAuthorityUrl == null) { throw new NotSupportedException($"This Azure DevOps organization '{serverUrl}' is not backed by Azure Active Directory."); } LoggerCallbackHandler.LogCallback = ((LogLevel level, string message, bool containsPii) => { switch (level) { case LogLevel.Information: trace.Info(message); break; case LogLevel.Error: trace.Error(message); break; case LogLevel.Warning: trace.Warning(message); break; default: trace.Verbose(message); break; } }); LoggerCallbackHandler.UseDefaultLogging = false; AuthenticationContext ctx = new AuthenticationContext(tenantAuthorityUrl.AbsoluteUri); var queryParameters = $"redirect_uri={Uri.EscapeDataString(new Uri(serverUrl).GetLeftPart(UriPartial.Authority))}"; DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync("https://management.core.windows.net/", _azureDevOpsClientId, queryParameters).GetAwaiter().GetResult(); var term = context.GetService <ITerminal>(); term.WriteLine($"Please finish AAD device code flow in browser ({codeResult.VerificationUrl}), user code: {codeResult.UserCode}"); if (string.Equals(CredentialData.Data[Constants.Agent.CommandLine.Flags.LaunchBrowser], bool.TrueString, StringComparison.OrdinalIgnoreCase)) { try { if (PlatformUtil.RunningOnWindows) { Process.Start(new ProcessStartInfo() { FileName = codeResult.VerificationUrl, UseShellExecute = true }); } else if (PlatformUtil.RunningOnLinux) { Process.Start(new ProcessStartInfo() { FileName = "xdg-open", Arguments = codeResult.VerificationUrl }); } else if (PlatformUtil.RunningOnMacOS) { Process.Start(new ProcessStartInfo() { FileName = "open", Arguments = codeResult.VerificationUrl }); } else { throw new NotImplementedException("Unexpected platform"); } } catch (Exception ex) { // not able to open browser, ex: xdg-open/open is not installed. trace.Error(ex); term.WriteLine($"Fail to open browser. {codeResult.Message}"); } } AuthenticationResult authResult = ctx.AcquireTokenByDeviceCodeAsync(codeResult).GetAwaiter().GetResult(); ArgUtil.NotNull(authResult, nameof(authResult)); trace.Info($"receive AAD auth result with {authResult.AccessTokenType} token"); var aadCred = new VssAadCredential(new VssAadToken(authResult)); VssCredentials creds = new VssCredentials(null, aadCred, CredentialPromptType.DoNotPrompt); trace.Info("cred created"); return(creds); }
private async Task AssociateArtifactAsync( IAsyncCommandContext context, Uri projectCollection, VssCredentials credentials, Guid projectId, int buildId, string name, string type, string data, Dictionary<string, string> propertiesDictionary, CancellationToken cancellationToken) { BuildServer buildHelper = new BuildServer(projectCollection, credentials, projectId); var artifact = await buildHelper.AssociateArtifact(buildId, name, type, data, propertiesDictionary, cancellationToken); context.Output(StringUtil.Loc("AssociateArtifactWithBuild", artifact.Id, buildId)); }
public async Task ConfigureAsync(CommandSettings command) { Trace.Info(nameof(ConfigureAsync)); if (IsConfigured()) { throw new InvalidOperationException(StringUtil.Loc("AlreadyConfiguredError")); } // TEE EULA bool acceptTeeEula = false; switch (Constants.Agent.Platform) { case Constants.OSPlatform.OSX: case Constants.OSPlatform.Linux: // Write the section header. WriteSection(StringUtil.Loc("EulasSectionHeader")); // Verify the EULA exists on disk in the expected location. string eulaFile = Path.Combine(IOUtil.GetExternalsPath(), Constants.Path.TeeDirectory, "license.html"); ArgUtil.File(eulaFile, nameof(eulaFile)); // Write elaborate verbiage about the TEE EULA. _term.WriteLine(StringUtil.Loc("TeeEula", eulaFile)); _term.WriteLine(); // Prompt to acccept the TEE EULA. acceptTeeEula = command.GetAcceptTeeEula(); break; case Constants.OSPlatform.Windows: // Warn and continue if .NET 4.6 is not installed. var netFrameworkUtil = HostContext.GetService <INetFrameworkUtil>(); if (!netFrameworkUtil.Test(new Version(4, 6))) { WriteSection(StringUtil.Loc("PrerequisitesSectionHeader")); // Section header. _term.WriteLine(StringUtil.Loc("MinimumNetFrameworkTfvc")); // Warning. } break; default: throw new NotSupportedException(); } // Create the configuration provider as per agent type. string agentType = command.DeploymentGroup ? Constants.Agent.AgentConfigurationProvider.DeploymentAgentConfiguration : Constants.Agent.AgentConfigurationProvider.BuildReleasesAgentConfiguration; var extensionManager = HostContext.GetService <IExtensionManager>(); IConfigurationProvider agentProvider = (extensionManager.GetExtensions <IConfigurationProvider>()) .FirstOrDefault(x => x.ConfigurationProviderType == agentType); ArgUtil.NotNull(agentProvider, agentType); // TODO: Check if its running with elevated permission and stop early if its not // Loop getting url and creds until you can connect string serverUrl = null; ICredentialProvider credProvider = null; VssCredentials creds = null; WriteSection(StringUtil.Loc("ConnectSectionHeader")); while (true) { // Get the URL serverUrl = agentProvider.GetServerUrl(command); // Get the credentials credProvider = GetCredentialProvider(command, serverUrl); creds = credProvider.GetVssCredentials(HostContext); Trace.Info("cred retrieved"); try { // Validate can connect. await agentProvider.TestConnectionAsync(serverUrl, creds); Trace.Info("Test Connection complete."); break; } catch (Exception e) when(!command.Unattended) { _term.WriteError(e); _term.WriteError(StringUtil.Loc("FailedToConnect")); } } _agentServer = HostContext.GetService <IAgentServer>(); // We want to use the native CSP of the platform for storage, so we use the RSACSP directly RSAParameters publicKey; var keyManager = HostContext.GetService <IRSAKeyManager>(); using (var rsa = keyManager.CreateKey()) { publicKey = rsa.ExportParameters(false); } // Loop getting agent name and pool name string poolName = null; int poolId = 0; string agentName = null; WriteSection(StringUtil.Loc("RegisterAgentSectionHeader")); while (true) { try { poolId = await agentProvider.GetPoolId(command); break; } catch (Exception e) when(!command.Unattended) { _term.WriteError(e); _term.WriteError(agentProvider.GetFailedToFindPoolErrorString()); } } TaskAgent agent; while (true) { agentName = command.GetAgentName(); // Get the system capabilities. // TODO: Hook up to ctrl+c cancellation token. _term.WriteLine(StringUtil.Loc("ScanToolCapabilities")); Dictionary <string, string> systemCapabilities = await HostContext.GetService <ICapabilitiesManager>().GetCapabilitiesAsync( new AgentSettings { AgentName = agentName }, CancellationToken.None); _term.WriteLine(StringUtil.Loc("ConnectToServer")); agent = await GetAgent(agentName, poolId); if (agent != null) { if (command.GetReplace()) { // Update existing agent with new PublicKey, agent version and SystemCapabilities. agent = UpdateExistingAgent(agent, publicKey, systemCapabilities); try { agent = await agentProvider.UpdateAgentAsync(poolId, agent, command); _term.WriteLine(StringUtil.Loc("AgentReplaced")); break; } catch (Exception e) when(!command.Unattended) { _term.WriteError(e); _term.WriteError(StringUtil.Loc("FailedToReplaceAgent")); } } else if (command.Unattended) { // if not replace and it is unattended config. throw new TaskAgentExistsException(StringUtil.Loc("AgentWithSameNameAlreadyExistInPool", poolId, agentName)); } } else { // Create a new agent. agent = CreateNewAgent(agentName, publicKey, systemCapabilities); try { agent = await agentProvider.AddAgentAsync(poolId, agent, command); _term.WriteLine(StringUtil.Loc("AgentAddedSuccessfully")); break; } catch (Exception e) when(!command.Unattended) { _term.WriteError(e); _term.WriteError(StringUtil.Loc("AddAgentFailed")); } } } // respect the serverUrl resolve by server. // in case of agent configured using collection url instead of account url. string agentServerUrl; if (agent.Properties.TryGetValidatedValue <string>("ServerUrl", out agentServerUrl) && !string.IsNullOrEmpty(agentServerUrl)) { Trace.Info($"Agent server url resolve by server: '{agentServerUrl}'."); // we need make sure the Host component of the url remain the same. UriBuilder inputServerUrl = new UriBuilder(serverUrl); UriBuilder serverReturnedServerUrl = new UriBuilder(agentServerUrl); if (Uri.Compare(inputServerUrl.Uri, serverReturnedServerUrl.Uri, UriComponents.Host, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) != 0) { inputServerUrl.Path = serverReturnedServerUrl.Path; Trace.Info($"Replace server returned url's host component with user input server url's host: '{inputServerUrl.Uri.AbsoluteUri}'."); serverUrl = inputServerUrl.Uri.AbsoluteUri; } else { serverUrl = agentServerUrl; } } // See if the server supports our OAuth key exchange for credentials if (agent.Authorization != null && agent.Authorization.ClientId != Guid.Empty && agent.Authorization.AuthorizationUrl != null) { var credentialData = new CredentialData { Scheme = Constants.Configuration.OAuth, Data = { { "clientId", agent.Authorization.ClientId.ToString("D") }, { "authorizationUrl", agent.Authorization.AuthorizationUrl.AbsoluteUri }, }, }; // Save the negotiated OAuth credential data _store.SaveCredential(credentialData); } else { switch (Constants.Agent.Platform) { case Constants.OSPlatform.OSX: case Constants.OSPlatform.Linux: // Save the provided admin cred for compat with previous agent. _store.SaveCredential(credProvider.CredentialData); break; case Constants.OSPlatform.Windows: // Not supported against TFS 2015. _term.WriteError(StringUtil.Loc("Tfs2015NotSupported")); return; default: throw new NotSupportedException(); } } // Testing agent connection, detect any protential connection issue, like local clock skew that cause OAuth token expired. _term.WriteLine(StringUtil.Loc("TestAgentConnection")); var credMgr = HostContext.GetService <ICredentialManager>(); VssCredentials credential = credMgr.LoadCredentials(); VssConnection conn = ApiUtil.CreateConnection(new Uri(serverUrl), credential); var agentSvr = HostContext.GetService <IAgentServer>(); try { await agentSvr.ConnectAsync(conn); } catch (VssOAuthTokenRequestException ex) when(ex.Message.Contains("Current server time is")) { // there are two exception messages server send that indicate clock skew. // 1. The bearer token expired on {jwt.ValidTo}. Current server time is {DateTime.UtcNow}. // 2. The bearer token is not valid until {jwt.ValidFrom}. Current server time is {DateTime.UtcNow}. Trace.Error("Catch exception during test agent connection."); Trace.Error(ex); throw new Exception(StringUtil.Loc("LocalClockSkewed")); } // We will Combine() what's stored with root. Defaults to string a relative path string workFolder = command.GetWork(); // notificationPipeName for Hosted agent provisioner. string notificationPipeName = command.GetNotificationPipeName(); string notificationSocketAddress = command.GetNotificationSocketAddress(); // Get Agent settings var settings = new AgentSettings { AcceptTeeEula = acceptTeeEula, AgentId = agent.Id, AgentName = agentName, NotificationPipeName = notificationPipeName, NotificationSocketAddress = notificationSocketAddress, PoolId = poolId, PoolName = poolName, ServerUrl = serverUrl, WorkFolder = workFolder }; // This is required in case agent is configured as DeploymentAgent. It will make entry for projectName and DeploymentGroup agentProvider.UpdateAgentSetting(settings); _store.SaveSettings(settings); _term.WriteLine(StringUtil.Loc("SavedSettings", DateTime.UtcNow)); #if OS_WINDOWS // config windows service as part of configuration bool runAsService = command.GetRunAsService(); if (runAsService) { if (!new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)) { Trace.Error("Needs Administrator privileges for configure agent as windows service."); throw new SecurityException(StringUtil.Loc("NeedAdminForConfigAgentWinService")); } Trace.Info("Configuring to run the agent as service"); var serviceControlManager = HostContext.GetService <IWindowsServiceControlManager>(); serviceControlManager.ConfigureService(settings, command); } #elif OS_LINUX || OS_OSX // generate service config script for OSX and Linux, GenerateScripts() will no-opt on windows. var serviceControlManager = HostContext.GetService <ILinuxServiceControlManager>(); serviceControlManager.GenerateScripts(settings); #endif }
public override VssCredentials GetVssCredentials(IHostContext context) { ArgUtil.NotNull(context, nameof(context)); Tracing trace = context.GetTrace(nameof(PersonalAccessToken)); trace.Info(nameof(GetVssCredentials)); ArgUtil.NotNull(CredentialData, nameof(CredentialData)); string token; if (!CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.Token, out token)) { token = null; } string username; if (!CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.UserName, out username)) { username = null; } ArgUtil.NotNullOrEmpty(token, nameof(token)); ArgUtil.NotNullOrEmpty(username, nameof(username)); trace.Info("token retrieved: {0} chars", token.Length); // ServiceIdentity uses a service identity credential VssServiceIdentityToken identityToken = new VssServiceIdentityToken(token); VssServiceIdentityCredential serviceIdentityCred = new VssServiceIdentityCredential(username, "", identityToken); VssCredentials creds = new VssCredentials(serviceIdentityCred); trace.Verbose("cred created"); return creds; }
public static void RunClientSampleMethods(Uri connectionUrl, VssCredentials credentials, string area = null, string resource = null, DirectoryInfo outputPath = null) { if (area == "*") { area = null; } if (resource == "*") { resource = null; } Dictionary <ClientSample, IEnumerable <RunnableClientSampleMethod> > runnableMethodsBySample = GetRunnableClientSampleMethods(area, resource); if (runnableMethodsBySample.Any()) { ClientSampleContext context = new ClientSampleContext(connectionUrl, credentials); Console.WriteLine("Start running client samples..."); Console.WriteLine(""); Console.WriteLine(" URL : {0}", connectionUrl); Console.WriteLine(" Area : {0}", (area == null ? "(all)" : area)); Console.WriteLine(" Resource: {0}", (resource == null ? "(all)" : resource)); Console.WriteLine(" Output : {0}", (outputPath == null ? "(disabled)" : outputPath.FullName)); Console.WriteLine(""); // Make sure we can connect before running the samples context.Connection.ConnectAsync().SyncResult(); context.SetValue <DirectoryInfo>(ClientSampleHttpLogger.PropertyOutputFilePath, outputPath); foreach (var item in runnableMethodsBySample) { ClientSample clientSample = item.Key; clientSample.Context = context; foreach (var runnableMethod in item.Value) { try { context.Log("+------------------------------------------------------------------------------+"); context.Log("| {0} |", String.Format("{0}/{1}", runnableMethod.MethodBase.Name, runnableMethod.MethodBase.DeclaringType.Name).PadRight(76)); context.Log("| |"); context.Log("| API: {0} |", String.Format("{0}/{1}", runnableMethod.Area, runnableMethod.Resource).PadRight(71)); context.Log("+------------------------------------------------------------------------------+"); context.Log(""); // Set these so the HTTP logger has access to them when it needs to write the output ClientSampleContext.CurrentRunnableMethod = runnableMethod; ClientSampleContext.CurrentContext = context; // Reset suppression (in case the last runnable method forget to re-enable it) ClientSampleHttpLogger.SetSuppressOutput(context, false); runnableMethod.MethodBase.Invoke(clientSample, null); } catch (Exception ex) { Console.WriteLine("FAILED! With exception: " + ex.Message); } finally { context.Log(""); } } } } }
public async Task UnconfigureAsync(CommandSettings command) { string currentAction = StringUtil.Loc("UninstallingService"); try { //stop, uninstall service and remove service config file _term.WriteLine(currentAction); if (_store.IsServiceConfigured()) { #if OS_WINDOWS if (!new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)) { Trace.Error("Needs Administrator privileges for unconfigure windows service agent."); throw new SecurityException(StringUtil.Loc("NeedAdminForUnconfigWinServiceAgent")); } var serviceControlManager = HostContext.GetService <IWindowsServiceControlManager>(); serviceControlManager.UnconfigureService(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); #elif OS_LINUX // unconfig system D service first throw new Exception(StringUtil.Loc("UnconfigureServiceDService")); #elif OS_OSX // unconfig osx service first throw new Exception(StringUtil.Loc("UnconfigureOSXService")); #endif } //delete agent from the server currentAction = StringUtil.Loc("UnregisteringAgent"); _term.WriteLine(currentAction); bool isConfigured = _store.IsConfigured(); bool hasCredentials = _store.HasCredentials(); if (isConfigured && hasCredentials) { AgentSettings settings = _store.GetSettings(); var credentialManager = HostContext.GetService <ICredentialManager>(); // Get the credentials var credProvider = GetCredentialProvider(command, settings.ServerUrl); VssCredentials creds = credProvider.GetVssCredentials(HostContext); Trace.Info("cred retrieved"); Uri uri = new Uri(settings.ServerUrl); VssConnection conn = ApiUtil.CreateConnection(uri, creds); var agentSvr = HostContext.GetService <IAgentServer>(); await agentSvr.ConnectAsync(conn); Trace.Info("Connect complete."); bool isDeploymentGroup = (settings.MachineGroupId > 0) || (settings.DeploymentGroupId > 0); Trace.Info("Agent configured for deploymentGroup : {0}", isDeploymentGroup.ToString()); string agentType = isDeploymentGroup ? Constants.Agent.AgentConfigurationProvider.DeploymentAgentConfiguration : Constants.Agent.AgentConfigurationProvider.BuildReleasesAgentConfiguration; var extensionManager = HostContext.GetService <IExtensionManager>(); IConfigurationProvider agentProvider = (extensionManager.GetExtensions <IConfigurationProvider>()).FirstOrDefault(x => x.ConfigurationProviderType == agentType); ArgUtil.NotNull(agentProvider, agentType); List <TaskAgent> agents = await agentSvr.GetAgentsAsync(settings.PoolId, settings.AgentName); if (agents.Count == 0) { _term.WriteLine(StringUtil.Loc("Skipping") + currentAction); } else { await agentProvider.DeleteAgentAsync(settings.PoolId, settings.AgentId); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } } else { _term.WriteLine(StringUtil.Loc("MissingConfig")); } //delete credential config files currentAction = StringUtil.Loc("DeletingCredentials"); _term.WriteLine(currentAction); if (hasCredentials) { _store.DeleteCredential(); var keyManager = HostContext.GetService <IRSAKeyManager>(); keyManager.DeleteKey(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } else { _term.WriteLine(StringUtil.Loc("Skipping") + currentAction); } //delete settings config file currentAction = StringUtil.Loc("DeletingSettings"); _term.WriteLine(currentAction); if (isConfigured) { _store.DeleteSettings(); _term.WriteLine(StringUtil.Loc("Success") + currentAction); } else { _term.WriteLine(StringUtil.Loc("Skipping") + currentAction); } } catch (Exception) { _term.WriteLine(StringUtil.Loc("Failed") + currentAction); throw; } }
/// <inheritdoc /> protected override ITeamProjectCollection ConnectToTfsCollection(Uri endpoint, VssCredentials credentials) { var tfsServer = new Microsoft.TeamFoundation.Client.TfsTeamProjectCollection(endpoint, credentials); tfsServer.EnsureAuthenticated(); return(tfsServer.AsProxy()); }