func resourceVSphereVirtualMachineUpdateLocation(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] %s: Checking for pending migration operations", resourceVSphereVirtualMachineIDString(d))
	client := meta.(*VSphereClient).vimClient

	// A little bit of duplication of VM object data is done here to keep the
	// method signature lean.
	id := d.Id()
	vm, err := virtualmachine.FromUUID(client, id)
	if err != nil {
		return fmt.Errorf("cannot locate virtual machine with UUID %q: %s", id, err)
	}

	// Determine if we are performing any storage vMotion tasks. This will generate the relocators if there are any.
	vprops, err := virtualmachine.Properties(vm)
	if err != nil {
		return fmt.Errorf("error fetching VM properties: %s", err)
	}
	devices := object.VirtualDeviceList(vprops.Config.Hardware.Device)
	relocators, diskRelocateOK, err := virtualdevice.DiskMigrateRelocateOperation(d, client, devices)
	if err != nil {
		return err
	}
	// If we don't have any changes, stop here.
	if !d.HasChange("resource_pool_id") && !d.HasChange("host_system_id") && !d.HasChange("datastore_id") && !diskRelocateOK {
		log.Printf("[DEBUG] %s: No migration operations found", resourceVSphereVirtualMachineIDString(d))
		return nil
	}
	log.Printf("[DEBUG] %s: Migration operations found, proceeding with migration", resourceVSphereVirtualMachineIDString(d))

	// Fetch and validate pool and host
	poolID := d.Get("resource_pool_id").(string)
	pool, err := resourcepool.FromID(client, poolID)
	if err != nil {
		return fmt.Errorf("could not find resource pool ID %q: %s", poolID, err)
	}
	var hs *object.HostSystem
	if v, ok := d.GetOk("host_system_id"); ok {
		hsID := v.(string)
		var err error
		if hs, err = hostsystem.FromID(client, hsID); err != nil {
			return fmt.Errorf("error locating host system at ID %q: %s", hsID, err)
		}
	}
	if err := resourcepool.ValidateHost(client, pool, hs); err != nil {
		return err
	}

	// Start building the spec
	spec := types.VirtualMachineRelocateSpec{
		Pool: types.NewReference(pool.Reference()),
	}

	// Fetch the datastore
	if dsID, ok := d.GetOk("datastore_id"); ok {
		ds, err := datastore.FromID(client, dsID.(string))
		if err != nil {
			return fmt.Errorf("error locating datastore for VM: %s", err)
		}
		spec.Datastore = types.NewReference(ds.Reference())
	}

	if hs != nil {
		hsRef := hs.Reference()
		spec.Host = &hsRef
	}

	spec.Disk = relocators

	// Ready to perform migration
	timeout := d.Get("migrate_wait_timeout").(int)
	if _, ok := d.GetOk("datastore_cluster_id"); ok {
		err = resourceVSphereVirtualMachineUpdateLocationRelocateWithSDRS(d, meta, vm, spec, timeout)
	} else {
		err = virtualmachine.Relocate(vm, spec, timeout)
	}
	return err
}
func resourceVSphereVirtualMachineUpdateLocation(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[DEBUG] %s: Checking for pending migration operations", resourceVSphereVirtualMachineIDString(d))
	client := meta.(*VSphereClient).vimClient

	
	
	id := d.Id()
	vm, err := virtualmachine.FromUUID(client, id)
	if err != nil {
		return fmt.Errorf("cannot locate virtual machine with UUID %q: %s", id, err)
	}

	
	vprops, err := virtualmachine.Properties(vm)
	if err != nil {
		return fmt.Errorf("error fetching VM properties: %s", err)
	}
	devices := object.VirtualDeviceList(vprops.Config.Hardware.Device)
	relocators, diskRelocateOK, err := virtualdevice.DiskMigrateRelocateOperation(d, client, devices)
	if err != nil {
		return err
	}
	
	if !d.HasChange("resource_pool_id") && !d.HasChange("host_system_id") && !d.HasChange("datastore_id") && !diskRelocateOK {
		log.Printf("[DEBUG] %s: No migration operations found", resourceVSphereVirtualMachineIDString(d))
		return nil
	}
	log.Printf("[DEBUG] %s: Migration operations found, proceeding with migration", resourceVSphereVirtualMachineIDString(d))

	
	poolID := d.Get("resource_pool_id").(string)
	pool, err := resourcepool.FromID(client, poolID)
	if err != nil {
		return fmt.Errorf("could not find resource pool ID %q: %s", poolID, err)
	}
	var hs *object.HostSystem
	if v, ok := d.GetOk("host_system_id"); ok {
		hsID := v.(string)
		var err error
		if hs, err = hostsystem.FromID(client, hsID); err != nil {
			return fmt.Errorf("error locating host system at ID %q: %s", hsID, err)
		}
	}
	if err := resourcepool.ValidateHost(client, pool, hs); err != nil {
		return err
	}

	
	spec := types.VirtualMachineRelocateSpec{
		Pool: types.NewReference(pool.Reference()),
	}

	
	if dsID, ok := d.GetOk("datastore_id"); ok {
		ds, err := datastore.FromID(client, dsID.(string))
		if err != nil {
			return fmt.Errorf("error locating datastore for VM: %s", err)
		}
		spec.Datastore = types.NewReference(ds.Reference())
	}

	if hs != nil {
		hsRef := hs.Reference()
		spec.Host = &hsRef
	}

	spec.Disk = relocators

	
	timeout := d.Get("migrate_wait_timeout").(int)
	if _, ok := d.GetOk("datastore_cluster_id"); ok {
		err = resourceVSphereVirtualMachineUpdateLocationRelocateWithSDRS(d, meta, vm, spec, timeout)
	} else {
		err = virtualmachine.Relocate(vm, spec, timeout)
	}
	return err
}
func resourceVSphereVirtualMachineUpdateLocation ( d * schema . ResourceData , meta interface { } ) error { log . Printf ( " " , resourceVSphereVirtualMachineIDString ( d ) ) client := meta . ( * VSphereClient ) . vimClient // A little bit of duplication of VM object data is done here to keep the // method signature lean. id := d . Id ( ) vm , err := virtualmachine . FromUUID ( client , id ) if err != nil { return fmt . Errorf ( " " , id , err ) } // Determine if we are performing any storage vMotion tasks. This will generate the relocators if there are any. vprops , err := virtualmachine . Properties ( vm ) if err != nil { return fmt . Errorf ( " " , err ) } devices := object . VirtualDeviceList ( vprops . Config . Hardware . Device ) relocators , diskRelocateOK , err := virtualdevice . DiskMigrateRelocateOperation ( d , client , devices ) if err != nil { return err } // If we don't have any changes, stop here. if ! d . HasChange ( " " ) && ! d . HasChange ( " " ) && ! d . HasChange ( " " ) && ! diskRelocateOK { log . Printf ( " " , resourceVSphereVirtualMachineIDString ( d ) ) return nil } log . Printf ( " " , resourceVSphereVirtualMachineIDString ( d ) ) // Fetch and validate pool and host poolID := d . Get ( " " ) . ( string ) pool , err := resourcepool . FromID ( client , poolID ) if err != nil { return fmt . Errorf ( " " , poolID , err ) } var hs * object . HostSystem if v , ok := d . GetOk ( " " ) ; ok { hsID := v . ( string ) var err error if hs , err = hostsystem . FromID ( client , hsID ) ; err != nil { return fmt . Errorf ( " " , hsID , err ) } } if err := resourcepool . ValidateHost ( client , pool , hs ) ; err != nil { return err } // Start building the spec spec := types . VirtualMachineRelocateSpec { Pool : types . NewReference ( pool . Reference ( ) ) , } // Fetch the datastore if dsID , ok := d . GetOk ( " " ) ; ok { ds , err := datastore . FromID ( client , dsID . ( string ) ) if err != nil { return fmt . Errorf ( " " , err ) } spec . Datastore = types . NewReference ( ds . Reference ( ) ) } if hs != nil { hsRef := hs . Reference ( ) spec . Host = & hsRef } spec . Disk = relocators // Ready to perform migration timeout := d . Get ( " " ) . ( int ) if _ , ok := d . GetOk ( " " ) ; ok { err = resourceVSphereVirtualMachineUpdateLocationRelocateWithSDRS ( d , meta , vm , spec , timeout ) } else { err = virtualmachine . Relocate ( vm , spec , timeout ) } return err }
// resourceVSphereVirtualMachineUpdateLocation manages vMotion. This includes
// the migration of a VM from one host to another, or from one datastore to
// another (storage vMotion).
//
// This function is responsible for building the top-level relocate spec. For
// disks, we call out to relocate functionality in the disk sub-resource.
resourceVSphereVirtualMachineUpdateLocation manages vMotion . This includes the migration of a VM from one host to another or from one datastore to another ( storage vMotion ) . This function is responsible for building the top - level relocate spec . For disks we call out to relocate functionality in the disk sub - resource .