Пример #1
0
        public void Strings()
        {
            Assert.Equal("500m", ByteUnits.ToMilliByteString(0.5m));
            Assert.Equal("1000000m", ByteUnits.ToMilliByteString(1000));

            Assert.Equal("500", ByteUnits.ToByteString(500));
            Assert.Equal("1000000", ByteUnits.ToByteString(1000000));

            Assert.Equal("1K", ByteUnits.ToKString(1000));
            Assert.Equal("2K", ByteUnits.ToKString(2000));
            Assert.Equal("0.5K", ByteUnits.ToKString(500));

            Assert.Equal("1Ki", ByteUnits.ToKiString(1024));
            Assert.Equal("2Ki", ByteUnits.ToKiString(2048));
            Assert.Equal("0.5Ki", ByteUnits.ToKiString(512));

            Assert.Equal("1M", ByteUnits.ToMString(1000000));
            Assert.Equal("2M", ByteUnits.ToMString(2000000));
            Assert.Equal("0.5M", ByteUnits.ToMString(500000));

            Assert.Equal("1Mi", ByteUnits.ToMiString(1 * ByteUnits.MebiBytes));
            Assert.Equal("2Mi", ByteUnits.ToMiString(2 * ByteUnits.MebiBytes));
            Assert.Equal("0.5Mi", ByteUnits.ToMiString(ByteUnits.MebiBytes / 2));

            Assert.Equal("1G", ByteUnits.ToGString(1000000000));
            Assert.Equal("2G", ByteUnits.ToGString(2000000000));
            Assert.Equal("0.5G", ByteUnits.ToGString(500000000));

            Assert.Equal("1Gi", ByteUnits.ToGiString(1 * ByteUnits.GibiBytes));
            Assert.Equal("2Gi", ByteUnits.ToGiString(2 * ByteUnits.GibiBytes));
            Assert.Equal("0.5Gi", ByteUnits.ToGiString(ByteUnits.GibiBytes / 2));

            Assert.Equal("1T", ByteUnits.ToTString(1000000000000));
            Assert.Equal("2T", ByteUnits.ToTString(2000000000000));
            Assert.Equal("0.5T", ByteUnits.ToTString(500000000000));

            Assert.Equal("1Ti", ByteUnits.ToTiString(1 * ByteUnits.TebiBytes));
            Assert.Equal("2Ti", ByteUnits.ToTiString(2 * ByteUnits.TebiBytes));
            Assert.Equal("0.5Ti", ByteUnits.ToTiString(ByteUnits.TebiBytes / 2));

            Assert.Equal("1P", ByteUnits.ToPString(1000000000000000));
            Assert.Equal("2P", ByteUnits.ToPString(2000000000000000));
            Assert.Equal("0.5P", ByteUnits.ToPString(500000000000000));

            Assert.Equal("1Pi", ByteUnits.ToPiString(1 * ByteUnits.PebiBytes));
            Assert.Equal("2Pi", ByteUnits.ToPiString(2 * ByteUnits.PebiBytes));
            Assert.Equal("0.5Pi", ByteUnits.ToPiString(ByteUnits.PebiBytes / 2));

            Assert.Equal("1E", ByteUnits.ToEString(1000000000000000000));
            Assert.Equal("2E", ByteUnits.ToEString(2000000000000000000));
            Assert.Equal("0.5E", ByteUnits.ToEString(500000000000000000));

            Assert.Equal("1Ei", ByteUnits.ToEiString(1 * ByteUnits.ExbiBytes));
            Assert.Equal("2Ei", ByteUnits.ToEiString(2 * ByteUnits.ExbiBytes));
            Assert.Equal("0.5Ei", ByteUnits.ToEiString(ByteUnits.ExbiBytes / 2));
        }
Пример #2
0
        /// <summary>
        /// Inspects the node to determine physical machine capabilities like
        /// processor count, RAM, and primary disk capacity and then sets the
        /// corresponding node labels.
        /// </summary>
        /// <param name="node">The target node.</param>
        private void SetLabels(SshProxy <NodeDefinition> node)
        {
            CommandResponse result;

            // Download [/proc/meminfo] and extract the [MemTotal] value (in kB).

            result = node.SudoCommand("cat /proc/meminfo");

            if (result.ExitCode == 0)
            {
                var memInfo       = result.OutputText;
                var memTotalRegex = new Regex(@"^MemTotal:\s*(?<size>\d+)\s*kB", RegexOptions.Multiline);
                var memMatch      = memTotalRegex.Match(memInfo);

                if (memMatch.Success && long.TryParse(memMatch.Groups["size"].Value, out var memSizeKiB))
                {
                    // Note that the RAM reported by Linux is somewhat less than the
                    // physical RAM installed.

                    node.Metadata.Labels.ComputeRam = (int)(memSizeKiB / 1024);  // Convert KiB --> MiB
                }
            }

            // Download [/proc/cpuinfo] and count the number of processors.

            result = node.SudoCommand("cat /proc/cpuinfo");

            if (result.ExitCode == 0)
            {
                var cpuInfo          = result.OutputText;
                var processorRegex   = new Regex(@"^processor\s*:\s*\d+", RegexOptions.Multiline);
                var processorMatches = processorRegex.Matches(cpuInfo);

                node.Metadata.Labels.ComputeCores = processorMatches.Count;
            }

            // Determine the primary disk size.

            // $hack(jeff.lill):
            //
            // I'm not entirely sure how to determine which block device is hosting
            // the primary file system for all systems.  For now, I'm just going to
            // assume that this can be one of:
            //
            //      /dev/sda1
            //      /dev/sda
            //      /dev/xvda1
            //      /dev/xvda
            //
            // I'll try each of these in order and setting the label for the
            // first reasonable result we get back.

            var blockDevices = new string[]
            {
                "/dev/sda1",
                "/dev/sda",
                "/dev/xvda1",
                "/dev/xvda"
            };

            foreach (var blockDevice in blockDevices)
            {
                result = node.SudoCommand($"lsblk -b --output SIZE -n -d {blockDevice}", RunOptions.LogOutput);

                if (result.ExitCode == 0)
                {
                    if (long.TryParse(result.OutputText.Trim(), out var deviceSize) && deviceSize > 0)
                    {
                        node.Metadata.Labels.StorageSize = ByteUnits.ToGiString(deviceSize);
                        break;
                    }
                }
            }
        }
Пример #3
0
        /// <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);
        }
Пример #4
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 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);
        }