When attempting to update the current vSphere Lifecycle Manager (VLCM) image for a cluster using PowerCLI, it fails with a error similar to the one below:
PS C:\GSlabs\Scripts> Get-Cluster -Name ### | Import-LcmClusterDesiredState -LocalSpecLocation '<path\to\json-file>' -Confirm:$false
Import-LcmClusterDesiredState : <timestamp> Import-LcmClusterDesiredState 500: Internal server error calling EsxSettingsClustersSoftwareDraftsImportSoftwareSpec: {"messages":[{"args":["import_software_spec","com.vmware.vapi.std.errors.already_exists"],"default_message":"Unexpected error for method: import_software_spec -> com.vmware.vapi.std.errors.already_exists","id":"vapi.bindings.method.impl.unexpected"},{"args":[],"default_message":"Record already exists.","id":"com.vmware.vcIntegrity.lifecycle.drafts.AlreadyExists"}]}
At line:2 char:30
+ ... <clustername> | Import-LcmClusterDesiredState -LocalSpecLocation '### ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Import-LcmClusterDesiredState], CisException
+ FullyQualifiedErrorId : ViCore.Impl.V1.Service.LcmService.ImportDesireState.Error,VMware.VimAutomation.ViCore.Cmdlets.Commands.Lcm.ImportLcmClusterDesiredState
Using vSphere Client, the image configuration can be successfully changed however.
VMware vCenter Server 8.0.x
This can happen if the cluster has a draft software configuration attached that was not properly finalized.
When this happens the cluster will be stuck in draft status and does not allow any further software configuration updates via API/SDK (including PowerCLI) call until the draft has been either committed or was removed.
To solve the issue, you need to remove any existing draft from the cluster.
# /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres -c "select id, name from vpx_entity where type_id = 3 and name like '%<cluster_name>%';"
Example:
root@vcsa [ /opt/vmware/vpostgres ]# /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres -c "select id, name from vpx_entity where type_id = 3 and name like '%<clustername>%';" id | name----+------------ 8 | <clustername>(1 row)
The "id" value above is only part of the actual cluster ID. The actual one will be "domain-c<id>" - for the example it is "domain-c8".
# curl -k -X POST "https://<vcsa_fqdn>/api/session" -u '[email protected]:<password>'
The output for this command will be a new session ID, for example:
root@vcsa [ ~ ]# curl -k -X POST "https://vcsa.example.domain/api/session" -u '[email protected]:###' "cdb21b2430598d612ba569d160eb7a54"
# curl -k -X POST 'https://<vcsa_fqdn>/api/esx/settings/clusters/<cluster_id>/software/drafts' -H 'vmware-api-session-id: <session_id>'
For example:
# curl -k -X POST 'https://vcsa.example.domain/api/esx/settings/clusters/domain-c8/software/drafts' -H 'vmware-api-session-id: cdb21b2430598d612ba569d160eb7a54'"24"
# curl -k -X DELETE 'https://<vcsa_fqdn>/api/esx/settings/clusters/<cluster_id>/software/drafts/<draft_id>' -H 'vmware-api-session-id: <session_id>'
Going with the example above:
# curl -k -X DELETE 'https://vcsa.example.domain/api/esx/settings/clusters/domain-c8/software/drafts/24' -H 'vmware-api-session-id: cdb21b2430598d612ba569d160eb7a54'
# curl -k -X POST 'https://<vcsa_fqdn>/api/esx/settings/clusters/<cluster_id>/software/drafts' -H 'vmware-api-session-id: <session_id>'
Once this has been confirmed, run the Import-LcmClusterDesiredState cmdlet again in order to update the desired software configuration of the cluster.