/// <summary> /// Starts a neonHIVE related Docker container on a node and also uploads a script /// to make it easy to restart the container manually or for hive updates. /// </summary> /// <param name="node">The target hive node.</param> /// <param name="containerName">Identifies the container.</param> /// <param name="image">The Docker image to be used by the container.</param> /// <param name="runOptions">Optional run options (defaults to <see cref="RunOptions.FaultOnError"/>).</param> /// <param name="commands">The commands required to start the container.</param> /// <remarks> /// <para> /// This method performs the following steps: /// </para> /// <list type="number"> /// <item> /// Passes <paramref name="image"/> to <see cref="Program.ResolveDockerImage(string)"/> to /// obtain the actual image to be started. /// </item> /// <item> /// Generates the first few lines of the script file that sets the /// default image as the <c>TARGET_IMAGE</c> macro and then overrides /// this with the script parameter (if there is one). /// </item> /// <item> /// Appends the commands to the script, replacing any text that matches /// <see cref="ImagePlaceholderArg"/> with <c>${TARGET_IMAGE}</c> to make it easy /// for services to be upgraded later. /// </item> /// <item> /// Starts the container. /// </item> /// <item> /// Uploads the generated script to the node to [<see cref="HiveHostFolders.Scripts"/>/<paramref name="containerName"/>.sh]. /// </item> /// </list> /// </remarks> public static void StartContainer(SshProxy <NodeDefinition> node, string containerName, string image, RunOptions runOptions = RunOptions.FaultOnError, params IBashCommandFormatter[] commands) { Covenant.Requires <ArgumentNullException>(node != null); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(containerName)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(image)); Covenant.Requires <ArgumentNullException>(commands != null); Covenant.Requires <ArgumentNullException>(commands.Length > 0); node.Status = $"start: {containerName}"; // Generate the container start script. var script = CreateStartScript(containerName, image, true, commands); // Upload the script to the target node and set permissions. var scriptPath = LinuxPath.Combine(HiveHostFolders.Scripts, $"{containerName}.sh"); node.UploadText(scriptPath, script); node.SudoCommand($"chmod 740 {scriptPath}"); // Run the script without a parameter to start the container. node.IdempotentDockerCommand($"setup/{containerName}", null, runOptions, scriptPath); node.Status = string.Empty; }