C# vSphere VMware.Vim克隆虚拟机&x27;当前状态下不允许该操作;

C# vSphere VMware.Vim克隆虚拟机&x27;当前状态下不允许该操作;,c#,vmware,vsphere,C#,Vmware,Vsphere,我的团队正在开发一个需要在vSphere环境中克隆现有模板的应用程序。我们在C#应用程序中使用VMware.Vim来实现这一点。我们正在替换使用PowerShell的现有实现 下面是引发错误的代码。我们最终将根据内存使用情况进行负载平衡,但目前我们正在随机选择主机。这就是为什么收集所有主机然后选择一个主机时会有一些额外的代码 当它到达CloneVM_任务时,抛出一个异常,消息为“当前状态下不允许该操作”。这个异常没有给我太多的工作空间,我在vSphere中找不到任何有用的日志。vSphere只是

我的团队正在开发一个需要在vSphere环境中克隆现有模板的应用程序。我们在C#应用程序中使用VMware.Vim来实现这一点。我们正在替换使用PowerShell的现有实现

下面是引发错误的代码。我们最终将根据内存使用情况进行负载平衡,但目前我们正在随机选择主机。这就是为什么收集所有主机然后选择一个主机时会有一些额外的代码

当它到达CloneVM_任务时,抛出一个异常,消息为“当前状态下不允许该操作”。这个异常没有给我太多的工作空间,我在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();
}
public async void createVirtualMachine同步(NewVMRequest NewVMRequest)
{
var appliance=await_applianceService.GetAppliance(newVMRequest.appliance);
var vimClient=新的VimClientImpl
{
IgnoreServerCertificateErrors=true,ServiceUrl=appliance.ServiceUrl
};
vimClient.Login(appliance.User、appliance.Password);
var datacenter=GetDatacenter(vimClient);
var hostCollection=GetListOfHosts(vimClient,数据中心);
var randomHost=PickRandomHost(主机集合);
var sourceVm=GetSelectedVm(vimClient,newVMRequest);
if(sourceVm==null)
{
_logger.LogDebug($“找不到用于模板的虚拟机{newVMRequest.Source}”);
_logger.LogError($“找不到用于模板的虚拟机{newVMRequest.Source}”,null);
返回;
}
var selectedStore=ConnectToDataStore(vimClient);
var cluster=GetCluster(vimClient);
var mySpec=CreateCloneSpec(selectedStore、randomHost、cluster、sourceVm);
WaitForTask(sourceVm.CloneVM_任务(sourceVm.Parent,newVMRequest.Name,mySpec));
vimClient.Disconnect();
}
私有VirtualMachineCloneSpec CreateCloneSpec(数据存储选择存储、ManagedObjectReference随机主机、群集计算机资源群集、VirtualMachine sourceVm)
{
var mySpec=新的VirtualMachineConeSpec
{
位置=新的VirtualMachinerLocateSpec
{
数据存储=selectedStore.MoRef,
Transform=VirtualMachinerLocateTransformation.sparse,
主机=随机主机,
Pool=cluster.ResourcePool
},
Config=new VirtualMachineConfigSpec()
};
var networkDevice=new VirtualDevice();
foreach(sourceVm.Config.Hardware.Device中的var vDevice)
{
if(vDevice.DeviceInfo.Label.Contains(“网络”))
{
网络设备=虚拟设备;
}
}
var devSpec=新的虚拟设备配置规范
{
设备=网络设备,文件操作=VirtualDeviceConfigSpecFileOperation.create
};
mySpec.Config.DeviceChange=new[]{devSpec};
返回mySpec;
}
专用数据中心GetDatacenter(VimClient VimClient)
{
var entities=vimClient.FindEntityViews(typeof(数据中心),null,null,null);
返回(数据中心)实体。First();
}
私有列表GetListOfHosts(VimClient VimClient、数据中心数据中心)
{
var hostCollection=新列表();
var hostFolderMoRef=datacenter.HostFolder;
var hostFolder=(Folder)vimClient.GetView(hostFolderMoRef,null);
var childEntityMoRefs=hostFolder.ChildEntity;
foreach(childEntityMoRefs中的var childEntityMoRef)
{
var thisCluster=(clusterComputerSource)vimClient.GetView(childEntityMoRef,null);
var clusterHostMoRefs=thisCluster.Host;
foreach(clusterHostMoRefs中的变量clusterHostMoRef)
{
var hostSystem=(hostSystem)vimClient.GetView(clusterHostMoRef,null);
添加(hostSystem.MoRef);
}
}
归还寄存物;
}
私有ManagedObjectReference PickRandomHost(列出主机集合)
{
var rand=new Random();
返回hostCollection[rand.Next(0,hostCollection.Count)];
}
私有虚拟机GetSelectedVm(VimClient VimClient,NewVMRequest NewVMRequest)
{
var filter=newnamevalueCollection
{
{“name”,newVMRequest.Source},
{“Config.Template”,newVMRequest.UseTemplate.ToString().ToLower()}
};
var entityViews=vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine),null,filter,null);
如果(entityViews.Count==0)
{
返回null;
}
return(VirtualMachine)vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine),null,filter,null.First();
}
专用数据存储ConnectToDataStore(VimClient VimClient)
{  
var myDs=vimClient.FindEntityView(typeof(Datastore),null,null/*dsFilter*/,null);
返回(数据存储)myDs;
}
专用群集计算机源GetCluster(VimClient VimClient)
{
var appClusters=vimClient.FindEntityViews(typeof(ClusterComputeResource),null,null,null);
返回(ClusterComputerResource)appClusters?.FirstOrDefault();
}

在大多数情况下,您的代码看起来不错。我建议更改spec文件,并使用尽可能少的信息从现有模板创建克隆。一旦你成功了,你可以添加更多的细节,看看是否会出错

从这个开始,看看这是否能让你成功

private VirtualMachineCloneSpec CreateCloneSpec(Datastore selectedStore, ManagedObjectReference randomHost, ClusterComputeResource cluster, VirtualMachine sourceVm)
{
    var mySpec =  new VirtualMachineCloneSpec
    {
        Location = new VirtualMachineRelocateSpec
        {
            Datastore = selectedStore.MoRef,
            Host = randomHost,
            Pool = cluster.ResourcePool
        },
        PowerOn = false,
        Template = false
    };

    return mySpec;
}

如果完成了上述操作,则添加VirtualMachine LocateTransformation,以根据需要将厚VM转换为瘦VM和网络连接。

从UI按原样克隆VM时会发生什么?你也会犯同样的错误吗?这是一个上电的VM还是一个模板?我尝试使用代码克隆这两个模板和上电的VM,但我得到了相同的错误。我可以通过Web UI进行克隆。是的,当我使用基本规范时,这是有效的。现在我只需要整理一下o部分