/// <inheritdoc/> public override bool Provision(bool force) { // Perform the provisioning operations. controller = new SetupController <NodeDefinition>($"Provisioning [{cluster.Definition.Name}] cluster", cluster.Nodes) { ShowStatus = this.ShowStatus, MaxParallel = this.MaxParallel }; controller.AddStep("node labels", (node, stepDelay) => SetLabels(node)); if (!controller.Run()) { Console.Error.WriteLine("*** ERROR: One or more configuration steps failed."); return(false); } return(true); }
/// <inheritdoc/> public override bool Provision(bool force) { if (IsProvisionNOP) { // There's nothing to do here. return(true); } // Update the node labels with the actual capabilities of the // virtual machines being provisioned. foreach (var node in cluster.Definition.Nodes) { if (string.IsNullOrEmpty(node.Labels.PhysicalMachine)) { node.Labels.PhysicalMachine = Environment.MachineName; } if (node.Labels.ComputeCores == 0) { node.Labels.ComputeCores = cluster.Definition.Hosting.VmProcessors; } if (node.Labels.ComputeRam == 0) { node.Labels.ComputeRam = (int)(ClusterDefinition.ValidateSize(cluster.Definition.Hosting.VmMemory, typeof(HostingOptions), nameof(HostingOptions.VmMemory)) / ByteUnits.MebiBytes); } if (string.IsNullOrEmpty(node.Labels.StorageSize)) { node.Labels.StorageSize = ByteUnits.ToGiString(node.GetVmMemory(cluster.Definition)); } } // If a public address isn't explicitly specified, we'll assume that we're // running inside the network and we can access the private address. foreach (var node in cluster.Definition.Nodes) { if (string.IsNullOrEmpty(node.PublicAddress)) { node.PublicAddress = node.PrivateAddress; } } // Perform the provisioning operations. controller = new SetupController <NodeDefinition>($"Provisioning [{cluster.Definition.Name}] cluster", cluster.Nodes) { ShowStatus = this.ShowStatus, MaxParallel = 1 // We're only going to provision one VM at a time on a local Hyper-V instance. }; controller.AddGlobalStep("prepare hyper-v", () => PrepareHyperV()); controller.AddStep("virtual machines", (node, stepDelay) => ProvisionVM(node)); controller.AddGlobalStep(string.Empty, () => Finish(), quiet: true); if (!controller.Run()) { Console.Error.WriteLine("*** ERROR: One or more configuration steps failed."); return(false); } return(true); }
/// <inheritdoc/> public override bool Provision(bool force) { // $todo(jeff.lill): // // I'm not implementing [force] here. I'm not entirely sure // that this makes sense for production clusters. // // Perhaps it would make more sense to replace this with a // [neon cluster remove] command. // // https://github.com/nforgeio/neonKUBE/issues/156 if (IsProvisionNOP) { // There's nothing to do here. return(true); } // Update the node labels with the actual capabilities of the // virtual machines being provisioned. foreach (var node in cluster.Definition.Nodes) { if (string.IsNullOrEmpty(node.Labels.PhysicalMachine)) { node.Labels.PhysicalMachine = node.VmHost; } if (node.Labels.ComputeCores == 0) { node.Labels.ComputeCores = node.GetVmProcessors(cluster.Definition); } if (node.Labels.ComputeRam == 0) { node.Labels.ComputeRam = (int)(node.GetVmMemory(cluster.Definition) / ByteUnits.MebiBytes); } if (string.IsNullOrEmpty(node.Labels.StorageSize)) { node.Labels.StorageSize = ByteUnits.ToGiString(node.GetVmDisk(cluster.Definition)); } } // Build a list of [SshProxy] instances that map to the specified XenServer // hosts. We'll use the [XenClient] instances as proxy metadata. var sshProxies = new List <SshProxy <XenClient> >(); xenHosts = new List <XenClient>(); foreach (var host in cluster.Definition.Hosting.VmHosts) { var hostAddress = host.Address; var hostname = host.Name; var hostUsername = host.Username ?? cluster.Definition.Hosting.VmHostUsername; var hostPassword = host.Password ?? cluster.Definition.Hosting.VmHostPassword; if (string.IsNullOrEmpty(hostname)) { hostname = host.Address; } var xenHost = new XenClient(hostAddress, hostUsername, hostPassword, name: host.Name, logFolder: logFolder); xenHosts.Add(xenHost); sshProxies.Add(xenHost.SshProxy); } // We're going to provision the XenServer hosts in parallel to // speed up cluster setup. This works because each XenServer // is essentially independent from the others. controller = new SetupController <XenClient>($"Provisioning [{cluster.Definition.Name}] cluster", sshProxies) { ShowStatus = this.ShowStatus, MaxParallel = this.MaxParallel }; controller.AddWaitUntilOnlineStep(); controller.AddStep("host folders", (node, stepDelay) => node.CreateHostFolders()); controller.AddStep("verify readiness", (node, stepDelay) => VerifyReady(node)); controller.AddStep("virtual machine template", (node, stepDelay) => CheckVmTemplate(node)); controller.AddStep("virtual machines", (node, stepDelay) => ProvisionVirtualMachines(node)); controller.AddGlobalStep(string.Empty, () => Finish(), quiet: true); if (!controller.Run()) { Console.Error.WriteLine("*** ERROR: One or more configuration steps failed."); return(false); } return(true); }