Пример #1
0
        public VirtualEthernetSwitchManagementService GetVirtualSwitchManagementService()
        {
            // VirtualSwitchManagementService is a singleton, most anonymous way of lookup is by asking for the set
            // of local instances, which should be size 1.
            var virtSwtichSvcCollection = VirtualEthernetSwitchManagementService.GetInstances();
            foreach (VirtualEthernetSwitchManagementService item in virtSwtichSvcCollection)
            {
                return item;
            }

            var errMsg = string.Format("No Hyper-V subsystem on server");
            var ex = new WmiException(errMsg);
            logger.Error(errMsg, ex);
            throw ex;
        }
Пример #2
0
        /// <summary>
        /// Always produces a VHDX.
        /// </summary>
        /// <param name="MaxInternalSize"></param>
        /// <param name="Path"></param>
        public void CreateDynamicVirtualHardDisk(ulong MaxInternalSize, string Path)
        {
            // Produce description of the virtual disk in the format of a Msvm_VirtualHardDiskSettings object

            // Example at http://www.getcodesamples.com/src/FC025DDC/76689747, but
            // Is there a template we can use to fill in the settings?
            var newVirtHDSettings = VirtualHardDiskSettingData.CreateInstance();
            newVirtHDSettings.LateBoundObject["Type"] = 3; // Dynamic
            newVirtHDSettings.LateBoundObject["Format"] = 3; // VHDX
            newVirtHDSettings.LateBoundObject["Path"] = Path;
            newVirtHDSettings.LateBoundObject["MaxInternalSize"] = MaxInternalSize;
            newVirtHDSettings.LateBoundObject["BlockSize"] = 0; // Use defaults
            newVirtHDSettings.LateBoundObject["LogicalSectorSize"] = 0; // Use defaults
            newVirtHDSettings.LateBoundObject["PhysicalSectorSize"] = 0; // Use defaults

            // Optional: newVirtHDSettings.CommitObject();

            // Add the new vhd object as a virtual hard disk to the vm.
            string newVirtHDSettingsString = newVirtHDSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);

            // Resource settings are changed through the management service
            System.Management.ManagementPath jobPath;
            var imgMgr = GetImageManagementService();
            var ret_val = imgMgr.CreateVirtualHardDisk(newVirtHDSettingsString, out jobPath);

            // If the Job is done asynchronously
            if (ret_val == ReturnCode.Started)
            {
                StorageJobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed to CreateVirtualHardDisk size {0}, path {1} due to {2}",
                    MaxInternalSize,
                    Path,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #3
0
        public void DeleteHostKvpItem(ComputerSystem vm, string key)
        {
            // Obtain controller for Hyper-V virtualisation subsystem
            VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();

            // Create object to hold the data.
            KvpExchangeDataItem kvpItem = KvpExchangeDataItem.CreateInstance();
            kvpItem.LateBoundObject["Name"] = WmiCallsV2.CloudStackUserDataKey;
            kvpItem.LateBoundObject["Data"] = "dummy";
            kvpItem.LateBoundObject["Source"] = 0;
            logger.Debug("VM " + vm.Name + " will have KVP key " + key + " removed.");

            String kvpStr = kvpItem.LateBoundObject.GetText(TextFormat.CimDtd20);

            // Update the resource settings for the VM.
            ManagementPath jobPath;

            uint ret_val = vmMgmtSvc.RemoveKvpItems(new String[] { kvpStr }, vm.Path, 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;
            }
        }
Пример #4
0
        private void SetBandWidthLimit(ulong limit, EthernetPortAllocationSettingData portPath)
        {
            logger.DebugFormat("Setting network rate limit to {0}", limit);

            var vmVirtMgmtSvc = GetVirtualisationSystemManagementService();
            var bandwidthSettings = EthernetSwitchPortBandwidthSettingData.GetInstances(vmVirtMgmtSvc.Scope, "InstanceID LIKE \"%Default\"");

            // Assert
            if (bandwidthSettings.Count != 1)
            {
                var errMsg = string.Format("Internal error, could not find default EthernetSwitchPortBandwidthSettingData instance");
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            var defaultBandwidthSettings = bandwidthSettings.OfType<EthernetSwitchPortBandwidthSettingData>().First();

            var newBandwidthSettings = new EthernetSwitchPortBandwidthSettingData((ManagementBaseObject)defaultBandwidthSettings.LateBoundObject.Clone());
            newBandwidthSettings.Limit = limit * 1000000;

            // Insert bandwidth settings to nic
            string[] newResources = new string[] { newBandwidthSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
            ManagementPath[] newResourcePaths = AddFeatureSettings(newResources, portPath.Path);

            // assert
            if (newResourcePaths.Length != 1)
            {
                var errMsg = string.Format(
                    "Failed to properly apply network rate limit {0} for NIC on port {1}",
                    limit,
                    portPath.Path);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #5
0
        /// <summary>
        /// External VSwitch has an external NIC, and we assume there is only one external NIC and one external vswitch.
        /// </summary>
        /// <param name="vmSettings"></param>
        /// <returns></returns>
        /// <throw>Throws if there is no vswitch</throw>
        /// <remarks>
        /// With V1 API, external ethernet port was attached to the land endpoint, which was attached to the switch.
        /// e.g. Msvm_ExternalEthernetPort -> SwitchLANEndpoint -> SwitchPort -> VirtualSwitch
        /// 
        /// With V2 API, there are two kinds of lan endpoint:  one on the computer system and one on the switch
        /// e.g. Msvm_ExternalEthernetPort -> LANEndpoint -> LANEdnpoint -> EthernetSwitchPort -> VirtualEthernetSwitch
        /// </remarks>
        public static VirtualEthernetSwitch GetExternalVirtSwitch(String vSwitchName)
        {
            // Work back from the first *bound* external NIC we find.
            var externNICs = ExternalEthernetPort.GetInstances("IsBound = TRUE");
            VirtualEthernetSwitch vSwitch = null;
            // Assert
            if (externNICs.Count == 0 )
            {
                var errMsg = "No ExternalEthernetPort available to Hyper-V";
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            foreach(ExternalEthernetPort externNIC in externNICs.OfType<ExternalEthernetPort>()) {
            // A sequence of ASSOCIATOR objects need to be traversed to get from external NIC the vswitch.
            // We use ManagementObjectSearcher objects to execute this sequence of questions
            // NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain
            // the virtualisation objects.
            var endpointQuery = new RelatedObjectQuery(externNIC.Path.Path, LANEndpoint.CreatedClassName);
            var endpointSearch = new ManagementObjectSearcher(externNIC.Scope, endpointQuery);
            var endpointCollection = new LANEndpoint.LANEndpointCollection(endpointSearch.Get());

            // assert
            if (endpointCollection.Count < 1 )
            {
                var errMsg = string.Format("No adapter-based LANEndpoint for external NIC {0} on Hyper-V server", externNIC.Name);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            LANEndpoint adapterEndPoint = endpointCollection.OfType<LANEndpoint>().First();
            var switchEndpointQuery = new RelatedObjectQuery(adapterEndPoint.Path.Path, LANEndpoint.CreatedClassName);
            var switchEndpointSearch = new ManagementObjectSearcher(externNIC.Scope, switchEndpointQuery);
            var switchEndpointCollection = new LANEndpoint.LANEndpointCollection(switchEndpointSearch.Get());

            // assert
            if (endpointCollection.Count < 1)
            {
                var errMsg = string.Format("No Switch-based LANEndpoint for external NIC {0} on Hyper-V server", externNIC.Name);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            LANEndpoint switchEndPoint = switchEndpointCollection.OfType<LANEndpoint>().First();
            var switchPortQuery = new RelatedObjectQuery(switchEndPoint.Path.Path, EthernetSwitchPort.CreatedClassName);
            var switchPortSearch = new ManagementObjectSearcher(switchEndPoint.Scope, switchPortQuery);
            var switchPortCollection = new EthernetSwitchPort.EthernetSwitchPortCollection(switchPortSearch.Get());

            // assert
            if (switchPortCollection.Count < 1 )
            {
                var errMsg = string.Format("No SwitchPort for external NIC {0} on Hyper-V server", externNIC.Name);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            EthernetSwitchPort switchPort = switchPortCollection.OfType<EthernetSwitchPort>().First();
            var vSwitchQuery = new RelatedObjectQuery(switchPort.Path.Path, VirtualEthernetSwitch.CreatedClassName);
            var vSwitchSearch = new ManagementObjectSearcher(externNIC.Scope, vSwitchQuery);
            var vSwitchCollection = new VirtualEthernetSwitch.VirtualEthernetSwitchCollection(vSwitchSearch.Get());

            // assert
            if (vSwitchCollection.Count < 1)
            {
                var errMsg = string.Format("No virtual switch for external NIC {0} on Hyper-V server", externNIC.Name);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            vSwitch = vSwitchCollection.OfType<VirtualEthernetSwitch>().First();
            if (vSwitch.ElementName.Equals(vSwitchName) == true)
            {
                return vSwitch;
            }
            }
            return vSwitch;
        }
Пример #6
0
        private void InsertDiskImage(ComputerSystem vm, string diskImagePath, 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 = CloneStorageAllocationSetting(defaultDiskQuery);

            // Set file containing the disk image
            newDiskSettings.LateBoundObject["Parent"] = drivePath.Path;

            // V2 API uses HostResource to specify image, see http://msdn.microsoft.com/en-us/library/hh859775(v=vs.85).aspx
            newDiskSettings.LateBoundObject["HostResource"] = new string[] { diskImagePath };
            newDiskSettings.CommitObject();

            // Add the new Msvm_StorageAllocationSettingData object as a virtual hard disk to the vm.
            string[] newDiskResource = new string[] { newDiskSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
            ManagementPath[] newDiskPaths = AddStorageResource(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,
                    diskImagePath);
        }
Пример #7
0
        /// <summary>
        /// Removes a disk image from a drive, but does not remove the drive itself.
        /// </summary>
        /// <param name="vm"></param>
        /// <param name="diskFileName"></param>
        private void RemoveStorageImage(ComputerSystem vm, string diskFileName)
        {
            // Obtain StorageAllocationSettingData for disk
            StorageAllocationSettingData.StorageAllocationSettingDataCollection storageSettingsObjs = StorageAllocationSettingData.GetInstances();

            StorageAllocationSettingData imageToRemove = null;
            foreach (StorageAllocationSettingData item in storageSettingsObjs)
            {
                if (item.HostResource == null || item.HostResource.Length != 1)
                {
                    continue;
                }

                string hostResource = item.HostResource[0];
                if (Path.Equals(hostResource, diskFileName))
                {
                    imageToRemove = item;
                    break;
                }
            }

            // assert
            if (imageToRemove  == null)
            {
                var errMsg = string.Format(
                    "Failed to remove disk image {0} from VM {1} (GUID {2}): the disk image is not attached.",
                    diskFileName,
                    vm.ElementName,
                    vm.Name);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            RemoveStorageResource(imageToRemove.Path, vm);

            logger.InfoFormat("Removed disk image {0} from VM {1} (GUID {2}): the disk image is not attached.",
                    diskFileName,
                    vm.ElementName,
                    vm.Name);
        }
Пример #8
0
        public 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;
            // DateTime is unused
            var ret_val = vm.RequestStateChange(requiredState, new DateTime(), out jobPath);

            // If the Job is done asynchronously
            if (ret_val == ReturnCode.Started)
            {
                JobCompleted(jobPath);
            }
            else if (ret_val == 32775)
            {   // TODO: check
                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);
        }
Пример #9
0
        /// <summary>
        /// Create new storage media resources, e.g. hard disk images and ISO disk images
        /// see http://msdn.microsoft.com/en-us/library/hh859775(v=vs.85).aspx
        /// </summary>
        /// <param name="wmiQuery"></param>
        /// <returns></returns>
        private static StorageAllocationSettingData CloneStorageAllocationSetting(string wmiQuery)
        {
            var defaultDiskImageSettingsObjs = StorageAllocationSettingData.GetInstances(wmiQuery);

            // assert
            if (defaultDiskImageSettingsObjs.Count != 1)
            {
                var errMsg = string.Format("Failed to find Msvm_StorageAllocationSettingData for the query {0}", wmiQuery);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            StorageAllocationSettingData defaultDiskDriveSettings = defaultDiskImageSettingsObjs.OfType<StorageAllocationSettingData>().First();
            return new StorageAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone());
        }
Пример #10
0
        /// <summary>
        /// Migrates the volume of a vm to a given destination storage
        /// </summary>
        /// <param name="displayName"></param>
        /// <param name="destination host"></param>
        /// <param name="volumeToPool"> volume to me migrated to which pool</param>
        public void MigrateVmWithVolume(string vmName, string destination, Dictionary<string, string> volumeToPool)
        {
            ComputerSystem vm = GetComputerSystem(vmName);
            VirtualSystemSettingData vmSettings = GetVmSettings(vm);
            VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance();
            VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService();
            StorageAllocationSettingData[] sasd = GetStorageSettings(vm);

            string[] rasds = null;
            if (sasd != null)
            {
                rasds = new string[sasd.Length];
                uint index = 0;
                foreach (StorageAllocationSettingData item in sasd)
                {
                    string vhdFileName = Path.GetFileNameWithoutExtension(item.HostResource[0]);
                    if (!String.IsNullOrEmpty(vhdFileName) && volumeToPool.ContainsKey(vhdFileName))
                    {
                        string newVhdPath = Path.Combine(volumeToPool[vhdFileName], Path.GetFileName(item.HostResource[0]));
                        item.LateBoundObject["HostResource"] = new string[] { newVhdPath };
                        item.LateBoundObject["PoolId"] = "";
                    }

                    rasds[index++] = item.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
                }
            }

            IPAddress addr = IPAddress.Parse(destination);
            IPHostEntry entry = Dns.GetHostEntry(addr);
            string[] destinationHost = new string[] { destination };

            migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.VirtualSystemAndStorage;
            migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP;
            migrationSettingData.LateBoundObject["DestinationIPAddressList"] = destinationHost;
            string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);

            ManagementPath jobPath;
            var ret_val = service.MigrateVirtualSystemToHost(vm.Path, entry.HostName, migrationSettings, rasds, null, out jobPath);
            if (ret_val == ReturnCode.Started)
            {
                MigrationJobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed migrating VM {0} and its volumes to destination {1} (GUID {2}) due to {3}",
                    vm.ElementName,
                    destination,
                    vm.Name,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #11
0
        /// <summary>
        /// Migrates the volume of a vm to a given destination storage
        /// </summary>
        /// <param name="displayName"></param>
        /// <param name="volume"></param>
        /// <param name="destination storage pool"></param>
        public void MigrateVolume(string vmName, string volume, string destination)
        {
            ComputerSystem vm = GetComputerSystem(vmName);
            VirtualSystemSettingData vmSettings = GetVmSettings(vm);
            VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance();
            VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService();
            StorageAllocationSettingData[] sasd = GetStorageSettings(vm);

            string[] rasds = null;
            if (sasd != null)
            {
                rasds = new string[1];
                foreach (StorageAllocationSettingData item in sasd)
                {
                    string vhdFileName = Path.GetFileNameWithoutExtension(item.HostResource[0]);
                    if (!String.IsNullOrEmpty(vhdFileName) && vhdFileName.Equals(volume))
                    {
                        string newVhdPath = Path.Combine(destination, Path.GetFileName(item.HostResource[0]));
                        item.LateBoundObject["HostResource"] = new string[] { newVhdPath };
                        item.LateBoundObject["PoolId"] = "";
                        rasds[0] = item.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);
                        break;
                    }
                }
            }

            migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.Storage;
            migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP;
            string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);

            ManagementPath jobPath;
            var ret_val = service.MigrateVirtualSystemToHost(vm.Path, null, migrationSettings, rasds, null, out jobPath);
            if (ret_val == ReturnCode.Started)
            {
                MigrationJobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed migrating volume {0} of VM {1} (GUID {2}) due to {3}",
                    volume,
                    vm.ElementName,
                    vm.Name,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #12
0
        /// <summary>
        /// Migrates a vm to the given destination host
        /// </summary>
        /// <param name="desplayName"></param>
        /// <param name="destination host"></param>
        public void MigrateVm(string vmName, string destination)
        {
            ComputerSystem vm = GetComputerSystem(vmName);
            VirtualSystemMigrationSettingData migrationSettingData = VirtualSystemMigrationSettingData.CreateInstance();
            VirtualSystemMigrationService service = GetVirtualisationSystemMigrationService();

            IPAddress addr = IPAddress.Parse(destination);
            IPHostEntry entry = Dns.GetHostEntry(addr);
            string[] destinationHost = new string[] { destination };

            migrationSettingData.LateBoundObject["MigrationType"] = MigrationType.VirtualSystem;
            migrationSettingData.LateBoundObject["TransportType"] = TransportType.TCP;
            migrationSettingData.LateBoundObject["DestinationIPAddressList"] = destinationHost;
            string migrationSettings = migrationSettingData.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20);

            ManagementPath jobPath;
            var ret_val = service.MigrateVirtualSystemToHost(vm.Path, entry.HostName, migrationSettings, null, null, out jobPath);
            if (ret_val == ReturnCode.Started)
            {
                MigrationJobCompleted(jobPath);
            }
            else if (ret_val != ReturnCode.Completed)
            {
                var errMsg = string.Format(
                    "Failed migrating 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;
            }
        }
Пример #13
0
        public 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.VirtualSystemType == "Microsoft:Hyper-V:System:Realized" ||
                    wmiObj.VirtualSystemType == "Microsoft:Hyper-V:System:Planned")
                {
                    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;
        }
Пример #14
0
        public EthernetSwitchPortVlanSettingData GetVlanSettings(EthernetPortAllocationSettingData ethernetConnection)
        {
            // An ASSOCIATOR object provides the cross reference from the VirtualSystemSettingData and the
            // EthernetPortAllocationSettingData, 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}", vmSettings.path, resultclassName);
            //
            var wmiObjQuery = new RelatedObjectQuery(ethernetConnection.Path.Path, EthernetSwitchPortVlanSettingData.CreatedClassName);

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

            if (wmiObjCollection.Count == 0)
            {
                return null;
            }

            // Assert
            if (wmiObjCollection.Count > 1)
            {
                var errMsg = string.Format("Internal error, morn one VLAN settings for a single ethernetConnection");
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return wmiObjCollection.OfType<EthernetSwitchPortVlanSettingData>().First();
        }
Пример #15
0
        private ManagementPath AttachNewDrive(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["AddressOnParent"] = "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.AddressOnParent);
            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];
        }
Пример #16
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.
            UInt16 startupAction = 2; // Do nothing.
            UInt16 stopAction = 4; // Shutdown.
            VirtualSystemSettingData vs_gs_data = VirtualSystemSettingData.CreateInstance();
            vs_gs_data.LateBoundObject["ElementName"] = name;
            vs_gs_data.LateBoundObject["AutomaticStartupAction"] = startupAction.ToString();
            vs_gs_data.LateBoundObject["AutomaticShutdownAction"] = stopAction.ToString();
            vs_gs_data.LateBoundObject["Notes"] = new string[] { "CloudStack creating VM, do not edit. \n" };

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

            // 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;
        }
Пример #17
0
        private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName)
        {
            // Get the virtual switch
            VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
            //check the the recevied vSwitch is the same as vSwitchName.
            if (!vSwitchName.Equals("")  && !vSwitch.ElementName.Equals(vSwitchName))
            {
               var errMsg = string.Format("Internal error, coudl not find Virtual Switch with the name : " +vSwitchName);
               var ex = new WmiException(errMsg);
               logger.Error(errMsg, ex);
               throw ex;
            }

            // Create port for adapter
            var defaultEthernetPortSettings = EthernetPortAllocationSettingData.GetInstances(vSwitch.Scope, "InstanceID LIKE \"%Default\"");

            // assert
            if (defaultEthernetPortSettings.Count != 1)
            {
                var errMsg = string.Format("Internal error, coudl not find default EthernetPortAllocationSettingData instance");
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            var defaultEthernetPortSettingsObj = defaultEthernetPortSettings.OfType<EthernetPortAllocationSettingData>().First();
            var newEthernetPortSettings = new EthernetPortAllocationSettingData((ManagementBaseObject)defaultEthernetPortSettingsObj.LateBoundObject.Clone());
            newEthernetPortSettings.LateBoundObject["Parent"] = newAdapter.Path.Path;
            newEthernetPortSettings.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };

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

            // 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}",
                    newVm.ElementName,
                    newVm.Name,
                    newResourcePaths.Length);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return new EthernetPortAllocationSettingData(newResourcePaths[0]);
        }
Пример #18
0
        private static void ModifySystemSetting(VirtualSystemManagementService vmMgmtSvc, string systemSettings)
        {
            // Resource settings are changed through the management service
            System.Management.ManagementPath jobPath;

            var ret_val = vmMgmtSvc.ModifySystemSettings(
                systemSettings,
                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 system setting {0}",
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #19
0
        /// < summary>
        /// Removes a storage resource from a computer system.
        /// </summary>
        /// <param name="storageSettings">Path that uniquely identifies the resource.</param>
        /// <param name="vm">VM to which the disk image will be attached.</param>
        // Add new
        private void RemoveNetworkResource(ManagementPath resourcePath)
        {
            var virtSwitchMgmtSvc = GetVirtualSwitchManagementService();
            ManagementPath jobPath;
            var ret_val = virtSwitchMgmtSvc.RemoveResourceSettings(
                new ManagementPath[] { resourcePath },
                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 remove network resources {0} from switch due to {1}",
                    resourcePath.Path,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #20
0
        private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings)
        {
            // Resource settings are changed through the management service
            System.Management.ManagementPath jobPath;
            System.Management.ManagementPath[] results;

            var ret_val = vmMgmtSvc.ModifyResourceSettings(
                resourceSettings,
                out jobPath,
                out results);

            // 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;
            }
        }
Пример #21
0
        /// < summary>
        /// Removes a storage resource from a computer system.
        /// </summary>
        /// <param name="storageSettings">Path that uniquely identifies the resource.</param>
        /// <param name="vm">VM to which the disk image will be attached.</param>
        private void RemoveStorageResource(ManagementPath resourcePath, ComputerSystem vm)
        {
            var virtSysMgmtSvc = GetVirtualisationSystemManagementService();

            ManagementPath jobPath;
            var ret_val = virtSysMgmtSvc.RemoveResourceSettings(
                new ManagementPath[] { resourcePath },
                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 remove resource {0} from VM {1} (GUID {2}) due to {3}",
                    resourcePath.Path,
                    vm.ElementName,
                    vm.Name,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #22
0
        private static void StorageJobCompleted(ManagementPath jobPath)
        {
            StorageJob jobObj = null;
            for (; ; )
            {
                jobObj = new StorageJob(jobPath);
                if (jobObj.JobState != JobState.Starting && jobObj.JobState != JobState.Running)
                {
                    break;
                }
                logger.InfoFormat("In progress... {0}% completed.", jobObj.PercentComplete);
                System.Threading.Thread.Sleep(1000);
            }

            if (jobObj.JobState != JobState.Completed)
            {
                var errMsg = string.Format(
                    "Hyper-V Job failed, Error Code:{0}, Description: {1}",
                    jobObj.ErrorCode,
                    jobObj.ErrorDescription);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
        }
Пример #23
0
        private ManagementPath SetPortVlan(string vlan, EthernetPortAllocationSettingData portPath)
        {
            logger.DebugFormat("Setting VLAN to {0}", vlan);

            var vmVirtMgmtSvc = GetVirtualisationSystemManagementService();
            EthernetSwitchPortVlanSettingData.GetInstances();

            // Create NIC resource by cloning the default NIC
            var vlanSettings = EthernetSwitchPortVlanSettingData.GetInstances(vmVirtMgmtSvc.Scope, "InstanceID LIKE \"%Default\"");

            // Assert
            if (vlanSettings.Count != 1)
            {
                var errMsg = string.Format("Internal error, could not find default EthernetSwitchPortVlanSettingData instance");
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }
            var defaultVlanSettings = vlanSettings.OfType<EthernetSwitchPortVlanSettingData>().First();

            var newVlanSettings = new EthernetSwitchPortVlanSettingData((ManagementBaseObject)defaultVlanSettings.LateBoundObject.Clone());

            //  Assign configuration to new NIC
            newVlanSettings.LateBoundObject["AccessVlanId"] = vlan;
            newVlanSettings.LateBoundObject["OperationMode"] = 1; // Access=1, trunk=2, private=3 ;
            newVlanSettings.CommitObject();

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

            // assert
            if (newResourcePaths.Length != 1)
            {
                var errMsg = string.Format(
                    "Failed to properly set VLAN to {0} for NIC on port {1}",
                    vlan,
                    portPath.Path);
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return newResourcePaths[0];
        }
Пример #24
0
        private ManagementPath[] AddFeatureSettings(string[] featureSettings, ManagementPath affectedConfiguration)
        {
            var virtSysMgmtSvc = GetVirtualisationSystemManagementService();

            ManagementPath jobPath;
            ManagementPath[] resultSettings;
            var ret_val = virtSysMgmtSvc.AddFeatureSettings(
                affectedConfiguration,
                featureSettings,
                out jobPath,
                out resultSettings);

            // 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 features settings {0} to resource {1} due to {2}",
                    featureSettings,
                    affectedConfiguration,
                    ReturnCode.ToString(ret_val));
                var ex = new WmiException(errMsg);
                logger.Error(errMsg, ex);
                throw ex;
            }

            return resultSettings;
        }
Пример #25
0
        /// </summary>
        /// <param name="vm"></param>
        /// <param name="cntrllerAddr"></param>
        /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param>
        public ManagementPath AddDiskDriveToIdeController(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 HARDDISK_DRIVE:
                    diskResourceSubType = HARDDISK_DISK;
                    break;
                case ISO_DRIVE:
                    diskResourceSubType = 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 = AttachNewDrive(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;
        }
Пример #26
0
        private ManagementPath AddScsiController(ComputerSystem vm)
        {
            // A description of the controller is created by modifying a clone of the default ResourceAllocationSettingData for scsi controller
            string scsiQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", SCSI_CONTROLLER);
            var scsiSettings = CloneResourceAllocationSetting(scsiQuery);

            scsiSettings.LateBoundObject["ElementName"] = "SCSI Controller";
            scsiSettings.CommitObject();

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

            // assert
            if (newResourcePaths.Length != 1)
            {
                var errMsg = string.Format(
                    "Failed to add scsi controller to 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;
            }

            logger.DebugFormat("New controller type {0} WMI path is {1}s",
                scsiSettings.ResourceSubType,
                newResourcePaths[0].Path);
            return newResourcePaths[0];
        }
Пример #27
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 SyntheticEthernetPortSettingData CreateNICforVm(ComputerSystem vm, string mac)
        {
            logger.DebugFormat("Creating nic for VM {0} (GUID {1})", vm.ElementName, vm.Name);

            // Obtain controller for Hyper-V networking subsystem
            var 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());

            //  Assign configuration to new NIC
            string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' })));
            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]);
        }
Пример #28
0
        private ManagementPath[] AddVirtualResource(string[] resourceSettings, ComputerSystem vm )
        {
            var virtSysMgmtSvc = GetVirtualisationSystemManagementService();

            ManagementPath jobPath;
            ManagementPath[] resourcePaths;
            var ret_val = virtSysMgmtSvc.AddResourceSettings(
                vm.Path,
                resourceSettings,
                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;
        }
Пример #29
0
        /// <summary>
        /// Create new VM.  By default we start it. 
        /// </summary>
        public ComputerSystem DeployVirtualMachine(dynamic jsonObj, string systemVmIso)
        {
            var vmInfo = jsonObj.vm;
            string vmName = vmInfo.name;
            var nicInfo = vmInfo.nics;
            int vcpus = vmInfo.cpus;
            int memSize = vmInfo.maxRam / 1048576;
            string errMsg = vmName;
            var diskDrives = vmInfo.disks;
            var bootArgs = vmInfo.bootArgs;
            string defaultvlan = "4094";

            // assert
            errMsg = vmName + ": missing disk information, array empty or missing, agent expects *at least* one disk for a VM";
            if (diskDrives == null)
            {
                logger.Error(errMsg);
                throw new ArgumentException(errMsg);
            }
            // assert
            errMsg = vmName + ": missing NIC information, array empty or missing, agent expects at least an empty array.";
            if (nicInfo == null )
            {
                logger.Error(errMsg);
                throw new ArgumentException(errMsg);
            }

            // For existing VMs, return when we spot one of this name not stopped.  In the meantime, remove any existing VMs of same name.
            ComputerSystem vmWmiObj = null;
            while ((vmWmiObj = GetComputerSystem(vmName)) != null)
            {
                logger.WarnFormat("Create request for existing vm, name {0}", vmName);
                if (vmWmiObj.EnabledState == EnabledState.Disabled)
                {
                    logger.InfoFormat("Deleting existing VM with name {0}, before we go on to create a VM with the same name", vmName);
                    DestroyVm(vmName);
                }
                else if (vmWmiObj.EnabledState == EnabledState.Enabled)
                {
                    string infoMsg = string.Format("Create VM discovered there exists a VM with name {0}, state {1}",
                        vmName,
                        EnabledState.ToString(vmWmiObj.EnabledState));
                    logger.Info(infoMsg);
                    return vmWmiObj;
                }
                else
                {
                    errMsg = string.Format("Create VM failing, because there exists a VM with name {0}, state {1}",
                        vmName,
                        EnabledState.ToString(vmWmiObj.EnabledState));
                    var ex = new WmiException(errMsg);
                    logger.Error(errMsg, ex);
                    throw ex;
                }
            }

            // Create vm carcase
            logger.DebugFormat("Going ahead with create VM {0}, {1} vcpus, {2}MB RAM", vmName, vcpus, memSize);
            var newVm = CreateVM(vmName, memSize, vcpus);

            // Add a SCSI controller for attaching/detaching data volumes.
            AddScsiController(newVm);

            foreach (var diskDrive in diskDrives)
            {
                string vhdFile = null;
                string diskName = null;
                string isoPath = null;
                VolumeObjectTO volInfo = VolumeObjectTO.ParseJson(diskDrive.data);
                TemplateObjectTO templateInfo = TemplateObjectTO.ParseJson(diskDrive.data);

                if (volInfo != null)
                {
                    // assert
                    errMsg = vmName + ": volume missing primaryDataStore for disk " + diskDrive.ToString();
                    if (volInfo.primaryDataStore == null)
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }
                    diskName = volInfo.name;

                    // assert
                    errMsg = vmName + ": can't deal with DataStore type for disk " + diskDrive.ToString();
                    if (volInfo.primaryDataStore == null)
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }
                    errMsg = vmName + ": Malformed PrimaryDataStore for disk " + diskDrive.ToString();
                    if (String.IsNullOrEmpty(volInfo.primaryDataStore.Path))
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }
                    errMsg = vmName + ": Missing folder PrimaryDataStore for disk " + diskDrive.ToString() + ", missing path: " +  volInfo.primaryDataStore.Path;
                    if (!Directory.Exists(volInfo.primaryDataStore.Path))
                    {
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }

                    vhdFile = volInfo.FullFileName;
                    if (!System.IO.File.Exists(vhdFile))
                    {
                        errMsg = vmName + ": non-existent volume, missing " + vhdFile + " for drive " + diskDrive.ToString();
                        logger.Error(errMsg);
                        throw new ArgumentException(errMsg);
                    }
                    logger.Debug("Going to create " + vmName + " with attached voluem " + diskName + " at " + vhdFile);
                }
                else if (templateInfo != null && templateInfo.nfsDataStoreTO != null)
                {
                    NFSTO share = templateInfo.nfsDataStoreTO;
                    Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
                    // The share is mapped, now attach the iso
                    isoPath = Utils.NormalizePath(Path.Combine(share.UncPath, templateInfo.path));
                }

                string driveType = diskDrive.type;
                string ideCtrllr = "0";
                string driveResourceType = null;
                switch (driveType) {
                    case "ROOT":
                        ideCtrllr = "0";
                        driveResourceType = HARDDISK_DRIVE;
                        break;
                    case "ISO":
                        ideCtrllr = "1";
                        driveResourceType = ISO_DRIVE;
                        break;
                    case "DATADISK":
                        break;
                    default:
                        // TODO: double check exception type
                        errMsg = string.Format("Unknown disk type {0} for disk {1}, vm named {2}",
                                string.IsNullOrEmpty(driveType) ? "NULL" : driveType,
                                string.IsNullOrEmpty(diskName) ? "NULL" : diskName, vmName);
                        var ex = new WmiException(errMsg);
                        logger.Error(errMsg, ex);
                        throw ex;
                }

                logger.DebugFormat("Create disk type {1} (Named: {0}), on vm {2} {3}", diskName, driveResourceType, vmName,
                        string.IsNullOrEmpty(vhdFile) ? " no disk to insert" : ", inserting disk" + vhdFile);
                if (driveType.Equals("DATADISK"))
                {
                    AttachDisk(vmName, vhdFile, (string)diskDrive.diskSeq);
                }
                else
                {
                    AddDiskDriveToIdeController(newVm, vhdFile, ideCtrllr, driveResourceType);
                    if (isoPath != null)
                    {
                        AttachIso(vmName, isoPath);
                    }
                }
            }

            String publicIpAddress = "";
            int nicCount = 0;
            // Add the Nics to the VM in the deviceId order.
            foreach (var nc in nicInfo)
            {
                foreach (var nic in nicInfo)
                {

                    int nicid = nic.deviceId;
                    Int32 networkRateMbps = nic.networkRateMbps;
                    string mac = nic.mac;
                    string vlan = null;
                    string isolationUri = nic.isolationUri;
                    string broadcastUri = nic.broadcastUri;
                    string nicIp = nic.ip;
                    string nicNetmask = nic.netmask;
                    if ( (broadcastUri != null ) || (isolationUri != null && isolationUri.StartsWith("vlan://")))
                    {
                        if (broadcastUri != null && broadcastUri.StartsWith("storage"))
                        {
                            vlan = broadcastUri.Substring("storage://".Length);
                        }
                        else
                        {
                            vlan = isolationUri.Substring("vlan://".Length);
                        }
                        int tmp;
                        if (vlan.Equals("untagged", StringComparison.CurrentCultureIgnoreCase) ) {
                            // recevied vlan is untagged, don't parse for the vlan in the isolation uri
                            vlan = null;
                        }
                        else if (!int.TryParse(vlan, out tmp))
                        {
                            // TODO: double check exception type
                            errMsg = string.Format("Invalid VLAN value {0} for on vm {1} for nic uuid {2}", isolationUri, vmName, nic.uuid);
                            var ex = new WmiException(errMsg);
                            logger.Error(errMsg, ex);
                            throw ex;
                        }
                    }
                    if(nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255") ) {
                        // this is the extra nic added to VR.
                        vlan = defaultvlan;
                    }

                    if (nicCount == 2)
                    {
                         publicIpAddress = nic.ip;
                    }

                    if (nicid == nicCount)
                    {
                        // Create network adapter
                        var newAdapter = CreateNICforVm(newVm, mac);
                        String switchName ="";
                        if (nic.name != null)
                        {
                            switchName =  nic.name;
                        }

                        // connection to vswitch
                        var portSettings = AttachNicToPort(newVm, newAdapter, switchName);

                        // set vlan
                        if (vlan != null)
                        {
                            SetPortVlan(vlan, portSettings);
                        }

                        if (networkRateMbps > 0)
                        {
                            SetBandWidthLimit((ulong)networkRateMbps, portSettings);
                        }

                        logger.DebugFormat("Created adapter {0} on port {1}, {2}",
                            newAdapter.Path, portSettings.Path, (vlan == null ? "No VLAN" : "VLAN " + vlan));
                    }
                }
                nicCount++;
            }

            // pass the boot args for the VM using KVP component.
            // We need to pass the boot args to system vm's to get them configured with cloudstack configuration.
            // Add new user data
            var vm = GetComputerSystem(vmName);
            if (bootArgs != null && !String.IsNullOrEmpty((string)bootArgs))
            {

                String bootargs = bootArgs;
                AddUserData(vm, bootargs);

                // Verify key added to subsystem
                //kvpInfo = GetKvpSettings(vmSettings);

                // HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object.
                //kvpProps = kvpInfo.HostExchangeItems;

            }
            // call patch systemvm iso only for systemvms
            if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-"))
            {
                if (systemVmIso != null && systemVmIso.Length != 0)
                {
                    patchSystemVmIso(vmName, systemVmIso);
                }
            }

            logger.DebugFormat("Starting VM {0}", vmName);
            SetState(newVm, RequiredState.Enabled);
            // Mark the VM as created by cloudstack tag
            TagVm(newVm);

            // we need to reboot to get the hv kvp daemon get started vr gets configured.
            if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-"))
            {
                System.Threading.Thread.Sleep(90000);
                // wait for the second boot and then return with sucesss
                //if publicIPAddress is empty or null don't ping the ip
              /*if (publicIpAddress.Equals("") == true)
                {
                    System.Threading.Thread.Sleep(90000);
                }
                else
                {
                    pingResource(publicIpAddress);
                }*/
            }
            logger.InfoFormat("Started VM {0}", vmName);
            return newVm;
        }
Пример #30
0
        public VirtualSystemMigrationService GetVirtualisationSystemMigrationService()
        {
            var virtSysMigSvcCollection = VirtualSystemMigrationService.GetInstances();
            foreach (VirtualSystemMigrationService item in virtSysMigSvcCollection)
            {
                return item;
            }

            var errMsg = string.Format("No Hyper-V migration service subsystem on server");
            var ex = new WmiException(errMsg);
            logger.Error(errMsg, ex);
            throw ex;
        }