Моя команда разрабатывает приложение, которое должно клонировать существующие шаблоны в нашей среде vSphere. Для этого мы используем VMware.Vim в приложении C#. Мы заменяем уже существующую реализацию, которая использует PowerShell.
Ниже приведен код, который выдает ошибку. В конечном итоге мы собираемся балансировать нагрузку на основе использования памяти, но в настоящее время мы выбираем хост случайным образом. Вот почему есть некоторый дополнительный код со сбором всех хостов и последующим их выбором.
Когда он попадает в CloneVM_Task, возникает исключение с сообщением «Операция не разрешена в текущем состоянии». брошен Исключение не дает мне много работы, и я не могу найти никаких полезных журналов в vSphere. vSphere просто говорит «Ошибка не позволила клонировать виртуальную машину» в журнале событий. Мы используем версию 6.7. Я новичок в VMWare, поэтому любая помощь приветствуется. Их документация отсутствует, если не сказать больше.
public async void CreateVirtualMachineAsync(NewVMRequest newVMRequest)
{
var appliance = await _applianceService.GetAppliance(newVMRequest.Appliance);
var vimClient = new VimClientImpl
{
IgnoreServerCertificateErrors = true, ServiceUrl = appliance.ServiceUrl
};
vimClient.Login(appliance.User, appliance.Password);
var datacenter = GetDatacenter(vimClient);
var hostCollection = GetListOfHosts(vimClient, datacenter);
var randomHost = PickRandomHost(hostCollection);
var sourceVm = GetSelectedVm(vimClient, newVMRequest);
if (sourceVm == null)
{
_logger.LogDebug($"Could not find virtual machine {newVMRequest.Source} to use for template");
_logger.LogError($"Could not find virtual machine {newVMRequest.Source} to use for template", null);
return;
}
var selectedStore = ConnectToDataStore(vimClient);
var cluster = GetCluster(vimClient);
var mySpec = CreateCloneSpec(selectedStore, randomHost, cluster, sourceVm);
vimClient.WaitForTask(sourceVm.CloneVM_Task(sourceVm.Parent, newVMRequest.Name, mySpec));
vimClient.Disconnect();
}
private VirtualMachineCloneSpec CreateCloneSpec(Datastore selectedStore, ManagedObjectReference randomHost, ClusterComputeResource cluster, VirtualMachine sourceVm)
{
var mySpec = new VirtualMachineCloneSpec
{
Location = new VirtualMachineRelocateSpec
{
Datastore = selectedStore.MoRef,
Transform = VirtualMachineRelocateTransformation.sparse,
Host = randomHost,
Pool = cluster.ResourcePool
},
Config = new VirtualMachineConfigSpec()
};
var networkDevice = new VirtualDevice();
foreach (var vDevice in sourceVm.Config.Hardware.Device)
{
if (vDevice.DeviceInfo.Label.Contains("Network"))
{
networkDevice = vDevice;
}
}
var devSpec = new VirtualDeviceConfigSpec
{
Device = networkDevice, FileOperation = VirtualDeviceConfigSpecFileOperation.create
};
mySpec.Config.DeviceChange = new[] { devSpec };
return mySpec;
}
private Datacenter GetDatacenter(VimClient vimClient)
{
var entities = vimClient.FindEntityViews(typeof(Datacenter), null, null, null);
return (Datacenter)entities.First();
}
private List<ManagedObjectReference> GetListOfHosts(VimClient vimClient, Datacenter datacenter)
{
var hostCollection = new List<ManagedObjectReference>();
var hostFolderMoRef = datacenter.HostFolder;
var hostFolder = (Folder)vimClient.GetView(hostFolderMoRef, null);
var childEntityMoRefs = hostFolder.ChildEntity;
foreach (var childEntityMoRef in childEntityMoRefs)
{
var thisCluster = (ClusterComputeResource)vimClient.GetView(childEntityMoRef, null);
var clusterHostMoRefs = thisCluster.Host;
foreach (var clusterHostMoRef in clusterHostMoRefs)
{
var hostSystem = (HostSystem)vimClient.GetView(clusterHostMoRef, null);
hostCollection.Add(hostSystem.MoRef);
}
}
return hostCollection;
}
private ManagedObjectReference PickRandomHost(List<ManagedObjectReference> hostCollection)
{
var rand = new Random();
return hostCollection[rand.Next(0, hostCollection.Count)];
}
private VirtualMachine GetSelectedVm(VimClient vimClient, NewVMRequest newVMRequest)
{
var filter = new NameValueCollection
{
{"name", newVMRequest.Source},
{"Config.Template", newVMRequest.UseTemplate.ToString().ToLower()}
};
var entityViews = vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, null);
if (entityViews.Count == 0)
{
return null;
}
return (VirtualMachine)vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, null).First();
}
private Datastore ConnectToDataStore(VimClient vimClient)
{
var myDs = vimClient.FindEntityView(typeof(Datastore), null, null /*dsFilter*/, null);
return (Datastore)myDs;
}
private ClusterComputeResource GetCluster(VimClient vimClient)
{
var appClusters = vimClient.FindEntityViews(typeof(ClusterComputeResource), null, null, null);
return (ClusterComputeResource)appClusters?.FirstOrDefault();
}