/// <summary> /// Appends the steps required to start a neonHIVE related Docker service and upload /// a script to the hive managers to make it easy to restart the service manually or /// for hive updates. /// </summary> /// <param name="hive">The target hive.</param> /// <param name="steps">The target step list.</param> /// <param name="serviceName">Identifies the service.</param> /// <param name="image">The Docker image to be used by the service.</param> /// <param name="command">The <c>docker service create ...</c> command.</param> /// <param name="runOptions">Optional run options (defaults to <see cref="RunOptions.FaultOnError"/>).</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 service. /// </item> /// <item> /// Uploads the generated script to each hive manager to [<see cref="HiveHostFolders.Scripts"/>/<paramref name="serviceName"/>.sh]. /// </item> /// </list> /// </remarks> public static void AddServiceStartSteps(HiveProxy hive, ConfigStepList steps, string serviceName, string image, IBashCommandFormatter command, RunOptions runOptions = RunOptions.FaultOnError) { Covenant.Requires <ArgumentNullException>(hive != null); Covenant.Requires <ArgumentNullException>(steps != null); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(serviceName)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(image)); Covenant.Requires <ArgumentNullException>(command != null); // Generate the service start script. var script = CreateStartScript(serviceName, image, false, command); // Add steps to upload the script to the managers and then call the script // to create the service on the first manager. var scriptPath = LinuxPath.Combine(HiveHostFolders.Scripts, $"{serviceName}.sh"); steps.Add(hive.GetFileUploadSteps(hive.Managers, scriptPath, script, permissions: "740")); steps.Add(CommandStep.CreateIdempotentDocker(hive.FirstManager.Name, $"setup/{serviceName}", scriptPath)); }
/// <summary> /// Appends the steps required to start a neonHIVE related Docker container and upload /// a script to the hive managers to make it easy to restart the service manually or /// for hive updates. /// </summary> /// <param name="hive">The target hive.</param> /// <param name="steps">The target step list.</param> /// <param name="node">The target hive node.</param> /// <param name="containerName">Identifies the service.</param> /// <param name="image">The Docker image to be used by the container.</param> /// <param name="command">The <c>docker service create ...</c> command.</param> /// <param name="runOptions">Optional run options (defaults to <see cref="RunOptions.FaultOnError"/>).</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). We also add /// a Docker command that pulls the image. /// </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 service. /// </item> /// <item> /// Uploads the generated script to each hive manager to [<see cref="HiveHostFolders.Scripts"/>/<paramref name="containerName"/>.sh]. /// </item> /// </list> /// </remarks> public static void AddContainerStartSteps(HiveProxy hive, ConfigStepList steps, SshProxy <NodeDefinition> node, string containerName, string image, IBashCommandFormatter command, RunOptions runOptions = RunOptions.FaultOnError) { Covenant.Requires <ArgumentNullException>(hive != null); Covenant.Requires <ArgumentNullException>(steps != null); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(containerName)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(image)); Covenant.Requires <ArgumentNullException>(command != null); // Generate the container start script. var script = CreateStartScript(containerName, image, true, command); // Add steps to upload the script to the managers and then call the script // to create the container on the target node. var scriptPath = LinuxPath.Combine(HiveHostFolders.Scripts, $"{containerName}.sh"); steps.Add(hive.GetFileUploadSteps(node, scriptPath, script, permissions: "740")); steps.Add(CommandStep.CreateIdempotentDocker(node.Name, $"setup/{containerName}", scriptPath)); }
/// <summary> /// Starts a neonHIVE related Docker service and also uploads a script to the /// hive managers to make it easy to restart the service manually or for hive /// updates. /// </summary> /// <param name="hive">The target hive.</param> /// <param name="serviceName">Identifies the service.</param> /// <param name="image">The Docker image to be used by the service.</param> /// <param name="command">The <c>docker service create ...</c> command.</param> /// <param name="runOptions">Optional run options (defaults to <see cref="RunOptions.FaultOnError"/>).</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 service. /// </item> /// <item> /// Uploads the generated script to each hive manager to [<see cref="HiveHostFolders.Scripts"/>/<paramref name="serviceName"/>.sh]. /// </item> /// </list> /// </remarks> public static void StartService(HiveProxy hive, string serviceName, string image, IBashCommandFormatter command, RunOptions runOptions = RunOptions.FaultOnError) { Covenant.Requires <ArgumentNullException>(hive != null); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(serviceName)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrWhiteSpace(image)); Covenant.Requires <ArgumentNullException>(command != null); var firstManager = hive.FirstManager; firstManager.Status = $"start: {serviceName}"; // Generate the service start script. var script = CreateStartScript(serviceName, image, false, command); // Upload the script to each of the manager nodes and set permissions. var scriptPath = LinuxPath.Combine(HiveHostFolders.Scripts, $"{serviceName}.sh"); foreach (var manager in hive.Managers) { manager.UploadText(scriptPath, script); manager.SudoCommand($"chmod 740 {scriptPath}"); } // Run the script without a parameter on the first manager to start the service. firstManager.IdempotentDockerCommand($"setup/{serviceName}", response => { if (response.ExitCode != 0) { firstManager.Fault(response.ErrorSummary); } }, runOptions, scriptPath); firstManager.Status = string.Empty; }