Example #1
0
        /// <inheritdoc/>
        public override bool Provision(bool force)
        {
            // Perform the provisioning operations.

            controller = new SetupController <NodeDefinition>($"Provisioning [{hive.Definition.Name}] hive", hive.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);
        }
Example #2
0
 /// <inheritdoc/>
 public abstract void AddPostVpnSteps(SetupController <NodeDefinition> controller);
Example #3
0
 /// <inheritdoc/>
 public override void AddPostVpnSteps(SetupController <NodeDefinition> controller)
 {
 }
Example #4
0
        /// <inheritdoc/>
        public override bool Provision(bool force)
        {
            // $todo(jeff.lill):
            //
            // I'm not entirely sure that the [force] option makes sense for
            // production hives and especially when there are pet nodes.
            //
            // Perhaps it would make more sense to replace this with a
            // [neon hive remove] command.
            //
            //      https://github.com/jefflill/NeonForge/issues/156

            this.forceVmOverwrite = 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 hive.Definition.Nodes)
            {
                if (string.IsNullOrEmpty(node.Labels.PhysicalMachine))
                {
                    node.Labels.PhysicalMachine = Environment.MachineName;
                }

                if (node.Labels.ComputeCores == 0)
                {
                    node.Labels.ComputeCores = hive.Definition.Hosting.VmProcessors;
                }

                if (node.Labels.ComputeRamMB == 0)
                {
                    node.Labels.ComputeRamMB = (int)(HiveDefinition.ValidateSize(hive.Definition.Hosting.VmMemory, typeof(HostingOptions), nameof(HostingOptions.VmMemory)) / NeonHelper.Mega);
                }

                if (node.Labels.StorageCapacityGB == 0)
                {
                    node.Labels.StorageCapacityGB = (int)(node.GetVmMemory(hive.Definition) / NeonHelper.Giga);
                }
            }

            // If a public address isn't explicitly specified, we'll assume that the
            // tool is running inside the network and we can access the private address.

            foreach (var node in hive.Definition.Nodes)
            {
                if (string.IsNullOrEmpty(node.PublicAddress))
                {
                    node.PublicAddress = node.PrivateAddress;
                }
            }

            // Perform the provisioning operations.

            controller = new SetupController <NodeDefinition>($"Provisioning [{hive.Definition.Name}] hive", hive.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("create 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);
        }
Example #5
0
        /// <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 hives and especially
            // when there are pet nodes.
            //
            // Perhaps it would make more sense to replace this with a
            // [neon hive remove] command.
            //
            //      https://github.com/jefflill/NeonForge/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 hive.Definition.Nodes)
            {
                if (string.IsNullOrEmpty(node.Labels.PhysicalMachine))
                {
                    node.Labels.PhysicalMachine = node.VmHost;
                }

                if (node.Labels.ComputeCores == 0)
                {
                    node.Labels.ComputeCores = node.GetVmProcessors(hive.Definition);
                }

                if (node.Labels.ComputeRamMB == 0)
                {
                    node.Labels.ComputeRamMB = (int)(node.GetVmMemory(hive.Definition) / NeonHelper.Mega);
                }

                if (node.Labels.StorageCapacityGB == 0)
                {
                    node.Labels.StorageCapacityGB = (int)(node.GetVmDisk(hive.Definition) / NeonHelper.Giga);
                }
            }

            // 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 hive.Definition.Hosting.VmHosts)
            {
                var hostAddress  = host.Address;
                var hostname     = host.Name;
                var hostUsername = host.Username ?? hive.Definition.Hosting.VmHostUsername;
                var hostPassword = host.Password ?? hive.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 hive setup.  This works because each XenServer
            // is essentially independent from the others.

            controller = new SetupController <XenClient>($"Provisioning [{hive.Definition.Name}] hive", sshProxies)
            {
                ShowStatus  = this.ShowStatus,
                MaxParallel = this.MaxParallel
            };

            controller.AddWaitUntilOnlineStep();

            controller.AddStep("sudo config",
                               (node, stepDelay) =>
            {
                using (var sshClient = node.CloneSshClient())
                {
                    // We're going to rewrite [/etc/sudoers.d/nopasswd] so that client
                    // connections won't require a TTY and also that SUDO password
                    // prompting will be disabled for all users.
                    //
                    // The file will end up looking like:
                    //
                    //      Defaults !requiretty
                    //      %sudo    ALL=NOPASSWD: ALL

                    var response = sshClient.RunCommand("echo \"Defaults !requiretty\" >> /etc/sudoers.d/nopasswd");

                    if (response.ExitStatus != 0)
                    {
                        node.Fault($"Cannot update [/etc/sudoers.d/nopasswd]: {response.Result}");
                        return;
                    }

                    response = sshClient.RunCommand("echo \"%sudo    ALL=NOPASSWD: ALL\" >> /etc/sudoers.d/nopasswd");

                    if (response.ExitStatus != 0)
                    {
                        node.Fault($"Cannot update [/etc/sudoers.d/nopasswd]: {response.Result}");
                        return;
                    }
                }
            });

            controller.AddStep("hive folders", (node, stepDelay) => node.CreateHiveHostFolders());
            controller.AddStep("verify readiness", (node, stepDelay) => VerifyReady(node));
            controller.AddStep("virtual machine template", (node, stepDelay) => CheckVmTemplate(node));
            controller.AddStep("provision 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);
        }