Example #1
0
        public static SyntheticEthernetPortSettingData[] GetEthernetPorts(ComputerSystem vm)
        {
            // An ASSOCIATOR object provides the cross reference from the ComputerSettings and the
            // SyntheticEthernetPortSettingData, via the VirtualSystemSettingData.
            // However, generated wrappers do not expose a ASSOCIATOR OF query as a method.
            // Instead, we use the System.Management to code the equivalant of
            //
            // string query = string.Format( "ASSOCIATORS OF {{{0}}} WHERE ResultClass = {1}", vm.path, resultclassName);
            //
            VirtualSystemSettingData vmSettings = GetVmSettings(vm);

            var wmiObjQuery = new RelatedObjectQuery(vmSettings.Path.Path, SyntheticEthernetPortSettingData.CreatedClassName);

            // NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain
            // the virtualisation objects.
            var wmiObjectSearch = new ManagementObjectSearcher(vm.Scope, wmiObjQuery);
            var wmiObjCollection = new SyntheticEthernetPortSettingData.SyntheticEthernetPortSettingDataCollection(wmiObjectSearch.Get());

            List<SyntheticEthernetPortSettingData> results = new List<SyntheticEthernetPortSettingData>(wmiObjCollection.Count);
            foreach (SyntheticEthernetPortSettingData item in wmiObjCollection)
            {
                results.Add(item);
            }

            return results.ToArray();
        }
Example #2
0
        /// <summary>
        /// Create a disk and attach it to the vm
        /// </summary>
        /// <param name="vm"></param>
        /// <param name="cntrllerAddr"></param>
        /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param>
        public static ManagementPath AddDiskDriveToVm(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType)
        {
            logger.DebugFormat("Creating DISK for VM {0} (GUID {1}) by attaching {2}",
                        vm.ElementName,
                        vm.Name,
                        vhdfile);

            // Determine disk type for drive and assert drive type valid
            string diskResourceSubType = null;
            switch(driveResourceType) {
                case IDE_HARDDISK_DRIVE:
                    diskResourceSubType = IDE_HARDDISK_DISK;
                    break;
                case IDE_ISO_DRIVE:
                    diskResourceSubType = IDE_ISO_DISK;
                    break;
                default:
                    var errMsg = string.Format(
                        "Unrecognised disk drive type {0} for VM {1} (GUID {2})",
                        string.IsNullOrEmpty(driveResourceType) ? "NULL": driveResourceType,
                        vm.ElementName,
                        vm.Name);
                    var ex = new WmiException(errMsg);
                    logger.Error(errMsg, ex);
                    throw ex;
            }

            ManagementPath newDrivePath = AttachNewDriveToVm(vm, cntrllerAddr, driveResourceType);

            // If there's not disk to insert, we are done.
            if (String.IsNullOrEmpty(vhdfile))
            {
                logger.DebugFormat("No disk to be added to drive, disk drive {0} is complete", newDrivePath.Path);
            }
            else
            {
                InsertDiskImage(vm, vhdfile, diskResourceSubType, newDrivePath);
            }
            return newDrivePath;
        }
Example #3
0
        /// <summary>
        /// Create a (synthetic) nic, and attach it to the vm
        /// </summary>
        /// <param name="vm"></param>
        /// <param name="mac"></param>
        /// <param name="vlan"></param>
        /// <returns></returns>
        public static SyntheticEthernetPortSettingData CreateNICforVm(ComputerSystem vm, string mac, string vlan)
        {
            logger.DebugFormat("Creating nic for VM {0} (GUID {1})", vm.ElementName, vm.Name);

            // Obtain controller for Hyper-V networking subsystem
            VirtualSwitchManagementService vmNetMgmtSvc = GetVirtualSwitchManagementService();

            // Create NIC resource by cloning the default NIC
            var synthNICsSettings = SyntheticEthernetPortSettingData.GetInstances(vmNetMgmtSvc.Scope, "InstanceID LIKE \"%Default\"");

            // Assert
            if (synthNICsSettings.Count != 1)
            {
                var errMsg = string.Format("Internal error, coudl not find default SyntheticEthernetPort instance");
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            var defaultSynthNICSettings = synthNICsSettings.OfType<SyntheticEthernetPortSettingData>().First();

            var newSynthNICSettings = new SyntheticEthernetPortSettingData((ManagementBaseObject)defaultSynthNICSettings.LateBoundObject.Clone());

            // Get the virtual switch
            VirtualSwitch vSwitch = GetExternalVirtSwitch();

            // Crate switch port for new VM
            ManagementPath newSwitchPath = CreateSwitchPortForVm(vm, vmNetMgmtSvc, vSwitch);

            // Add required VLAND support
            if (vlan != null)
            {
                SetPortVlan(vlan, vmNetMgmtSvc, newSwitchPath);
            }

            logger.DebugFormat("Created switch port {0} on switch {1}", newSwitchPath.Path, vSwitch.Path.Path);

            //  Assign configuration to new NIC
            string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' })));
            newSynthNICSettings.LateBoundObject["Connection"] = new string[] { newSwitchPath.Path };
            newSynthNICSettings.LateBoundObject["ElementName"] = vm.ElementName;
            newSynthNICSettings.LateBoundObject["Address"] = normalisedMAC;
            newSynthNICSettings.LateBoundObject["StaticMacAddress"] = "TRUE";
            newSynthNICSettings.LateBoundObject["VirtualSystemIdentifiers"] = new string[] { "{" + Guid.NewGuid().ToString() + "}" };
            newSynthNICSettings.CommitObject();

            // Insert NIC into vm
            string[] newResources = new string[] { newSynthNICSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20)};
            ManagementPath[] newResourcePaths = AddVirtualResource(newResources, vm );

            // assert
            if (newResourcePaths.Length != 1)
            {
                var errMsg = string.Format(
                    "Failed to properly insert a single NIC on VM {0} (GUID {1}): number of resource created {2}",
                    vm.ElementName,
                    vm.Name,
                    newResourcePaths.Length);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return new SyntheticEthernetPortSettingData(newResourcePaths[0]);
        }
Example #4
0
        private static void InsertDiskImage(ComputerSystem vm, string vhdfile, string diskResourceSubType, ManagementPath drivePath)
        {
            // A description of the disk is created by modifying a clone of the default ResourceAllocationSettingData for that disk type
            string defaultDiskQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", diskResourceSubType);
            var newDiskSettings = CloneResourceAllocationSetting(defaultDiskQuery);

            // Set disk drive and VHD file on disk for new disk
            newDiskSettings.LateBoundObject["Parent"] = drivePath.Path;
            newDiskSettings.LateBoundObject["Connection"] = new string[] { vhdfile };
            newDiskSettings.CommitObject();

            // Add the new vhd object as a virtual hard disk to the vm.
            string[] newDiskResource = new string[] { newDiskSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
            ManagementPath[] newDiskPaths = AddVirtualResource(newDiskResource, vm);
            // assert
            if (newDiskPaths.Length != 1)
            {
                var errMsg = string.Format(
                    "Failed to add disk image type {3} to VM {0} (GUID {1}): number of resource created {2}",
                    vm.ElementName,
                    vm.Name,
                    newDiskPaths.Length,
                    diskResourceSubType);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            logger.InfoFormat("Created disk {2} for VM {0} (GUID {1}), image {3} ",
                    vm.ElementName,
                    vm.Name,
                    newDiskPaths[0].Path,
                    vhdfile);
        }
Example #5
0
        private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings)
        {
            // Resource settings are changed through the management service
            System.Management.ManagementPath jobPath;

            var ret_val = vmMgmtSvc.ModifyVirtualSystemResources(vm.Path,
                resourceSettings,
                out jobPath);
            // If the Job is done asynchronously
            if (ret_val == ReturnCode.Started)
            {
                JobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted",
                    vm.ElementName,
                    vm.Name,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Example #6
0
        private static ComputerSystem CreateDefaultVm(VirtualSystemManagementService vmMgmtSvc, string name)
        {
            // Tweak default settings by basing new VM on default global setting object
            // with designed display name.

            VirtualSystemGlobalSettingData vs_gs_data = VirtualSystemGlobalSettingData.CreateInstance();
            vs_gs_data.LateBoundObject["ElementName"] = name;

            System.Management.ManagementPath jobPath;
            System.Management.ManagementPath defined_sys;
            var ret_val = vmMgmtSvc.DefineVirtualSystem(
                new string[0],
                null,
                vs_gs_data.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20),
                out defined_sys,
                out jobPath);

            // If the Job is done asynchronously
            if (ret_val == ReturnCode.Started)
            {
                JobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed to create VM {0} due to {1} (DefineVirtualSystem call)",
                    name, ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            logger.DebugFormat(CultureInfo.InvariantCulture, "Created VM {0}", name);

            // Is the defined_system real?
            var vm = new ComputerSystem(defined_sys);

            // Assertion
            if (vm.ElementName.CompareTo(name) != 0)
            {
                var errMsg = string.Format(
                    "New VM created with wrong name (is {0}, should be {1}, GUID {2})",
                    vm.ElementName,
                    name,
                    vm.Name);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return vm;
        }
Example #7
0
 private static ManagementPath CreateSwitchPortForVm(ComputerSystem vm, VirtualSwitchManagementService vmNetMgmtSvc, VirtualSwitch vSwitch)
 {
     ManagementPath newSwitchPath = null;
     var ret_val = vmNetMgmtSvc.CreateSwitchPort(
         vm.ElementName,
         Guid.NewGuid().ToString(),
         "",
         vSwitch.Path,
         out newSwitchPath);
     // Job is always done synchronously
     if (ret_val != ReturnCode.Completed)
     {
         var errMsg = string.Format(
             "Failed to create switch for NIC on VM {0} (GUID {1}), error code {2}",
             vm.ElementName,
             vm.Name,
             ret_val);
         var ex = new WmiException(errMsg);
         logger.Error(errMsg, ex);
         throw ex;
     }
     return newSwitchPath;
 }
Example #8
0
        private static ManagementPath AttachNewDriveToVm(ComputerSystem vm, string cntrllerAddr, string driveType)
        {
            // Disk drives are attached to a 'Parent' IDE controller.  We IDE Controller's settings for the 'Path', which our new Disk drive will use to reference it.
            VirtualSystemSettingData vmSettings = GetVmSettings(vm);
            var ctrller = GetIDEControllerSettings(vmSettings, cntrllerAddr);

            // A description of the drive is created by modifying a clone of the default ResourceAllocationSettingData for that drive type
            string defaultDriveQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", driveType);
            var newDiskDriveSettings = CloneResourceAllocationSetting(defaultDriveQuery);

            // Set IDE controller and address on the controller for the new drive
            newDiskDriveSettings.LateBoundObject["Parent"] = ctrller.Path.ToString();
            newDiskDriveSettings.LateBoundObject["Address"] = "0";
            newDiskDriveSettings.CommitObject();

            // Add this new disk drive to the VM
            logger.DebugFormat("Creating disk drive type {0}, parent IDE controller is {1} and address on controller is {2}",
                newDiskDriveSettings.ResourceSubType,
                newDiskDriveSettings.Parent,
                newDiskDriveSettings.Address);
            string[] newDriveResource = new string[] { newDiskDriveSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
            ManagementPath[] newDrivePaths = AddVirtualResource(newDriveResource, vm);

            // assert
            if (newDrivePaths.Length != 1)
            {
                var errMsg = string.Format(
                    "Failed to add disk drive type {3} to VM {0} (GUID {1}): number of resource created {2}",
                    vm.ElementName,
                    vm.Name,
                    newDrivePaths.Length,
                    driveType);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            logger.DebugFormat("New disk drive type {0} WMI path is {1}s",
                newDiskDriveSettings.ResourceSubType,
                newDrivePaths[0].Path);
            return newDrivePaths[0];
        }
Example #9
0
        // Add new
        private static ManagementPath[] AddVirtualResource(string[] resourceSettings, ComputerSystem vm )
        {
            var virtSysMgmtSvc = GetVirtualisationSystemManagementService();

            ManagementPath jobPath;
            ManagementPath[] resourcePaths;
            var ret_val = virtSysMgmtSvc.AddVirtualSystemResources(
                resourceSettings,
                vm.Path,
                out jobPath,
                out resourcePaths);

            // If the Job is done asynchronously
            if (ret_val == ReturnCode.Started)
            {
                JobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed to add resources to VM {0} (GUID {1}) due to {2}",
                    vm.ElementName,
                    vm.Name,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return resourcePaths;
        }
Example #10
0
        public static void SetState(ComputerSystem vm, ushort requiredState)
        {
            logger.InfoFormat(
                "Changing state of {0} (GUID {1}) to {2}",
                vm.ElementName,
                vm.Name,
                RequiredState.ToString(requiredState));

            ManagementPath jobPath;
            // TimeSpan is a value type; default ctor is equivalent to 0.
            var ret_val = vm.RequestStateChange(requiredState, new TimeSpan(), out jobPath);

            // If the Job is done asynchronously
            if (ret_val == ReturnCode.Started)
            {
                JobCompleted(jobPath);
            }
            else if (ret_val == 32775)
            {
                logger.InfoFormat("RequestStateChange returned 32775, which means vm in wrong state for requested state change.  Treating as if requested state was reached");
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed to change state of VM {0} (GUID {1}) to {2} due to {3}",
                    vm.ElementName,
                    vm.Name,
                    RequiredState.ToString(requiredState),
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            logger.InfoFormat(
                "Successfully changed vm state of {0} (GUID {1} to requested state {2}",
                vm.ElementName,
                vm.Name,
                requiredState);
        }
Example #11
0
        public static VirtualSystemSettingData GetVmSettings(ComputerSystem vm)
        {
            // An ASSOCIATOR object provides the cross reference from the ComputerSettings and the
            // VirtualSystemSettingData, but generated wrappers do not expose a ASSOCIATOR OF query as a method.
            // Instead, we use the System.Management to code the equivalant of
            //  string query = string.Format( "ASSOCIATORS OF {{{0}}} WHERE ResultClass = {1}", vm.path, resultclassName);
            //
            var wmiObjQuery = new RelatedObjectQuery(vm.Path.Path, VirtualSystemSettingData.CreatedClassName);

            // NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain
            // the virtualisation objects.
            var wmiObjectSearch = new ManagementObjectSearcher(vm.Scope, wmiObjQuery);
            var wmiObjCollection = new VirtualSystemSettingData.VirtualSystemSettingDataCollection(wmiObjectSearch.Get());

            // When snapshots are taken into account, there can be multiple settings objects
            // take the first one that isn't a snapshot
            foreach (VirtualSystemSettingData wmiObj in wmiObjCollection)
            {
                if (wmiObj.SettingType == 3)
                {
                    return wmiObj;
                }
            }

            var errMsg = string.Format("No VirtualSystemSettingData for VM {0}, path {1}", vm.ElementName, vm.Path.Path);
            var ex = new WmiException(errMsg);
            logger.Error(errMsg, ex);
            throw ex;
        }
Example #12
0
        public static SwitchPort[] GetSwitchPorts(ComputerSystem vm)
        {
            var virtSwitchMgmtSvc = GetVirtualSwitchManagementService();
            // Get NIC path
            var condition = string.Format("ElementName=\"{0}\"", vm.ElementName);
            var switchPortCollection = SwitchPort.GetInstances(virtSwitchMgmtSvc.Scope, condition);

            List<SwitchPort> result = new List<SwitchPort>(switchPortCollection.Count);
            foreach (SwitchPort item in switchPortCollection)
            {
                result.Add(item);
            }
            return result.ToArray();
        }