/// <summary> /// Determines whether a Docker config exists. /// </summary> /// <param name="configName">The config name.</param> /// <returns><c>true</c> if the config exists.</returns> /// <exception cref="HiveException">Thrown if the operation failed.</exception> public bool Exists(string configName) { var manager = hive.GetReachableManager(); var response = manager.DockerCommand(RunOptions.None, "docker config inspect", configName); if (response.ExitCode == 0) { return(true); } else { // $todo(jeff.lill): // // I'm trying to distinguish between a a failure because the config doesn't // exist and other potential failures (e.g. Docker is not running). // // This is a bit fragile. if (response.ErrorText.StartsWith("Status: Error: no such config:", StringComparison.InvariantCultureIgnoreCase)) { return(false); } else { throw new HiveException(response.ErrorSummary); } } }
/// <summary> /// Lists the Docker services running on the hive. /// </summary> /// <returns>The service names.</returns> /// <exception cref="HiveException">Thrown if the operation failed.</exception> public IEnumerable <string> ListServices() { var manager = hive.GetReachableManager(); var response = manager.SudoCommand("docker service ls --format {{.Name}}"); if (response.ExitCode != 0) { throw new HiveException(response.ErrorSummary); } using (var reader = new StringReader(response.OutputText)) { return(reader.Lines().ToArray()); } }
/// <summary> /// Deploys the local Docker registry to the hive. /// </summary> /// <param name="hostname">The registry hostname.</param> /// <param name="username">The registry username.</param> /// <param name="password">The registry password.</param> /// <param name="secret">The registry secret.</param> /// <param name="certificate">The certificate used to secure the registry.</param> /// <param name="image">Optionally specifies the Docker image to be deployed (defaults to <b>nhive/neon-registry</b>).</param> /// <param name="progress">Optional action that will be called with a progress message.</param> /// <exception cref="HiveException">Thrown if a registry is already deployed or deployment failed.</exception> /// <exception cref="NotSupportedException">Thrown if the hive does not support local registries.</exception> public void CreateLocalRegistry( string hostname, string username, string password, string secret, TlsCertificate certificate, string image = HiveConst.NeonProdRegistry + "/neon-registry", Action <string> progress = null) { Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(hostname)); Covenant.Requires <ArgumentException>(HiveDefinition.DnsHostRegex.IsMatch(hostname)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(username)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(password)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(secret)); Covenant.Requires <ArgumentNullException>(certificate != null); if (!hive.Definition.HiveFS.Enabled) { throw new NotSupportedException("Cannot deploy a local Docker registry to the hive because the hive's Cepf file system is not enabled."); } if (HasLocalRegistry) { throw new HiveException("The [neon-registry] service is already deployed."); } progress?.Invoke($"Setting certificate."); hive.Certificate.Set("neon-registry", certificate); progress?.Invoke($"Updating Consul settings."); hive.Registry.SetLocalHostname(hostname); hive.Registry.SetLocalSecret(secret); progress?.Invoke($"Adding hive DNS host entry for [{hostname}] (60 seconds)."); hive.Dns.Set(GetRegistryDnsEntry(hostname), waitUntilPropagated: true); progress?.Invoke($"Writing traffic manager rule."); hive.PublicTraffic.SetRule(GetRegistryTrafficManagerRule(hostname)); progress?.Invoke($"Creating [neon-registry] service."); var manager = hive.GetReachableManager(); var createResponse = manager.DockerCommand(RunOptions.None, "docker service create", "--name", "neon-registry", "--mode", "global", "--constraint", "node.role==manager", "--env", $"USERNAME={username}", "--env", $"PASSWORD={password}", "--env", $"SECRET={secret}", "--env", $"LOG_LEVEL=info", "--env", $"READ_ONLY=false", "--mount", "type=volume,src=neon-registry,volume-driver=neon,dst=/var/lib/neon-registry", "--network", "neon-public", "--restart-delay", "10s", image); if (createResponse.ExitCode != 0) { throw new HiveException($"[neon-registry] service create failed: {createResponse.ErrorText}"); } progress?.Invoke($"Service created."); progress?.Invoke($"Logging the hive into the [{hostname}] registry."); hive.Registry.Login(hostname, username, password); }
/// <summary> /// Executes a command on a healthy hive manager node using the root Vault token. /// </summary> /// <param name="command">The command (including the <b>vault</b>).</param> /// <param name="args">The optional arguments.</param> /// <returns>The command response.</returns> /// <remarks> /// <note> /// This method faults and throws an exception if the command returns /// a non-zero exit code. /// </note> /// </remarks> public CommandResponse Command(string command, params object[] args) { Covenant.Requires <ArgumentNullException>(command != null); return(Command(hive.GetReachableManager(), command, args)); }