// Copyright Epic Games, Inc. All Rights Reserved. using EpicGames.Core; using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Xml; namespace AutomationTool.Tasks { /// /// Parameters for a Docker task /// public class DockerTaskParameters { /// /// Docker command line arguments /// [TaskParameter(Optional = true)] public string Arguments; /// /// Base directory for running the command /// [TaskParameter(Optional = true)] public string BaseDir; /// /// The minimum exit code, which is treated as an error. /// [TaskParameter(Optional = true)] public int ErrorLevel = 1; /// /// Whether or not to show the console output from the Docker command. /// [TaskParameter(Optional = true)] public bool Verbose = true; /// /// Path to a file containing the credentials needed to run the Docker command /// [TaskParameter(Optional = true)] public string CredentialsFile; } /// /// Spawns Docker and waits for it to complete. /// [TaskElement("Docker", typeof(DockerTaskParameters))] public class DockerTask : CustomTask { /// /// Parameters for this task /// DockerTaskParameters Parameters; /// /// Construct a Docker task /// /// Parameters for the task public DockerTask(DockerTaskParameters InParameters) { Parameters = InParameters; } /// /// Execute the task. /// /// Information about the current job /// Set of build products produced by this node. /// Mapping from tag names to the set of files they include public override void Execute(JobContext Job, HashSet BuildProducts, Dictionary> TagNameToFileSet) { FileReference ToolFile = CommandUtils.FindToolInPath("docker"); if(ToolFile == null) { throw new AutomationException("Unable to find path to Docker. Check you have it installed, and it is on your PATH."); } string DockerArgs = Parameters.Arguments; string CmdString = $"{ToolFile.FullName} {DockerArgs}"; string DockerInput = null; if (!string.IsNullOrWhiteSpace(Parameters.CredentialsFile)) { if (!File.Exists(Parameters.CredentialsFile)) { throw new AutomationException("Credentials file {0} could not be found.", Parameters.CredentialsFile); } string[] CredentialTokens = File.ReadAllText(Parameters.CredentialsFile).Split(':'); if (CredentialTokens.Length == 2) { DockerArgs += $" --username {CredentialTokens[0]} --password-stdin"; DockerInput = CredentialTokens[1]; } else if (CredentialTokens.Length == 1) { DockerArgs += $" --password-stdin"; DockerInput = CredentialTokens[0]; } else { throw new AutomationException("Expected password or username:password in credentials file ({0})", Parameters.CredentialsFile); } } CommandUtils.ERunOptions Options = CommandUtils.ERunOptions.AppMustExist; if (Parameters.Verbose) { Options |= CommandUtils.ERunOptions.AllowSpew; } IProcessResult Result = CommandUtils.Run(ToolFile.FullName, DockerArgs, DockerInput, WorkingDir: Parameters.BaseDir, Options: Options); if (Result.ExitCode < 0 || Result.ExitCode >= Parameters.ErrorLevel) { throw new AutomationException("Docker terminated with an exit code indicating an error ({0})", Result.ExitCode); } } /// /// Output this task out to an XML writer. /// public override void Write(XmlWriter Writer) { Write(Writer, Parameters); } /// /// Find all the tags which are used as inputs to this task /// /// The tag names which are read by this task public override IEnumerable FindConsumedTagNames() { yield break; } /// /// Find all the tags which are modified by this task /// /// The tag names which are modified by this task public override IEnumerable FindProducedTagNames() { yield break; } } }