public override async Task ExecuteAsync(IOperationExecutionContext context) { await this.LoginAsync(context, this.ContainerSource); try { var procExec = await context.Agent.GetServiceAsync <IRemoteProcessExecuter>(); var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>(); await fileOps.CreateDirectoryAsync(context.WorkingDirectory); var sourcePath = context.ResolvePath(this.SourceDirectory); await fileOps.CreateDirectoryAsync(sourcePath); var dockerfilePath = fileOps.CombinePath(sourcePath, "Dockerfile"); if (!string.IsNullOrWhiteSpace(this.DockerfileTemplate)) { var item = SDK.GetRaftItem(RaftItemType.TextTemplate, this.DockerfileTemplate, context); if (item == null) { this.LogError($"Text template \"{this.DockerfileTemplate}\" not found."); return; } var dockerfileText = await context.ApplyTextTemplateAsync(item.Content, this.TemplateArguments != null?new Dictionary <string, RuntimeValue>(this.TemplateArguments) : null); await fileOps.WriteAllTextAsync(dockerfilePath, dockerfileText, InedoLib.UTF8Encoding); } var containerSource = (ContainerSource)SecureResource.Create(this.ContainerSource, (IResourceResolutionContext)context); var containerId = new ContainerId(this.ContainerSource, containerSource?.RegistryPrefix, this.RepositoryName, this.Tag); var escapeArg = GetEscapeArg(context); var args = $"build --force-rm --progress=plain --tag={escapeArg(containerId.FullName)} {this.AdditionalArguments} {escapeArg(sourcePath)}"; this.LogDebug("Executing docker " + args); var startInfo = new RemoteProcessStartInfo { FileName = this.DockerExePath, Arguments = args, WorkingDirectory = sourcePath }; using (var process = procExec.CreateProcess(startInfo)) { process.OutputDataReceived += (s, e) => this.LogInformation(e.Data); process.ErrorDataReceived += (s, e) => this.LogBuildError(context, e.Data); process.Start(); await process.WaitAsync(context.CancellationToken); if (process.ExitCode != 0) { this.LogError($"exit code: {process.ExitCode ?? -1}"); return; } } var digest = await this.ExecuteGetDigest(context, containerId.FullName); containerId = containerId.WithDigest(digest); if (!string.IsNullOrEmpty(this.ContainerSource)) { await this.PushAsync(context, containerId); if (this.RemoveAfterPush) { this.LogDebug("Removing local image after successful push..."); await this.RemoveAsync(context, containerId); } } if (this.AttachToBuild) { await this.AttachToBuildAsync(context, containerId); } } finally { await this.LogoutAsync(context, this.ContainerSource); } }
public override async Task ExecuteAsync(IOperationExecutionContext context) { var template = await getTemplateAsync().ConfigureAwait(false); this.LogDebug("Detecting newlines in source template..."); var sourceNewLines = template.Contains("\r\n") ? TemplateNewLineMode.Windows : template.Contains("\n") ? TemplateNewLineMode.Linux : TemplateNewLineMode.Auto; this.LogDebug("Applying template..."); var result = await context.ApplyTextTemplateAsync(template, this.AdditionalVariables).ConfigureAwait(false); this.LogInformation("Template applied."); if (this.NewLineMode == TemplateNewLineMode.Windows) { result = result.Replace("\n", "\r\n"); } if (!string.IsNullOrWhiteSpace(this.OutputFile)) { var path = context.ResolvePath(this.OutputFile); this.LogDebug($"Writing output to {path}..."); var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>().ConfigureAwait(false); if (this.NewLineMode == TemplateNewLineMode.Auto) { result = result.Replace("\n", fileOps.NewLine); } await fileOps.CreateDirectoryAsync(PathEx.GetDirectoryName(path)); await fileOps.WriteAllTextAsync(path, result).ConfigureAwait(false); } this.LogDebug("Setting output variable..."); this.OutputVariable = result; async Task <string> getTemplateAsync() { if (!string.IsNullOrEmpty(this.Literal)) { this.LogDebug("Applying literal template: " + this.Literal); return(this.Literal); } if (!string.IsNullOrEmpty(this.InputFile)) { var path = context.ResolvePath(this.InputFile); this.LogDebug($"Using file {path} as template..."); var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>().ConfigureAwait(false); if (!await fileOps.FileExistsAsync(path).ConfigureAwait(false)) { throw new ExecutionFailureException("Template file not found."); } return(await fileOps.ReadAllTextAsync(path).ConfigureAwait(false)); } if (!string.IsNullOrEmpty(this.Asset)) { string templateName; string raftName; var templateNameParts = this.Asset.Split(new[] { "::" }, 2, StringSplitOptions.None); if (templateNameParts.Length == 2) { raftName = templateNameParts[0]; templateName = templateNameParts[1]; } else { if (SDK.ProductName == "BuildMaster") { raftName = context.TryGetFunctionValue("$ApplicationName")?.AsString() ?? ""; } else { raftName = RaftRepository.DefaultName; } templateName = templateNameParts[0]; } using (var raft = RaftRepository.OpenRaft(raftName)) { if (raft == null) { throw new ExecutionFailureException("Raft not found."); } using (var stream = await raft.OpenRaftItemAsync(RaftItemType.TextTemplate, templateName, FileMode.Open, FileAccess.Read)) { if (stream == null) { throw new ExecutionFailureException($"Template \"{templateName}\" not found in raft."); } this.LogDebug("Loading template from raft..."); using (var reader = new StreamReader(stream, InedoLib.UTF8Encoding)) { return(await reader.ReadToEndAsync().ConfigureAwait(false)); } } } } this.LogWarning("No template specified. Setting output to empty string."); return(string.Empty); } }