Exemplo n.º 1
0
func (d *Dispatcher) deleteVM(vm *vm.VirtualMachine, force bool) error {
	defer trace.End(trace.Begin(fmt.Sprintf("vm %q, force %t", vm.String(), force)))

	var err error
	power, err := vm.PowerState(d.ctx)
	if err != nil || power != types.VirtualMachinePowerStatePoweredOff {
		if err != nil {
			log.Warnf("Failed to get vm power status %q: %s", vm.Reference(), err)
		}
		if !force {
			if err != nil {
				return err
			}
			name := d.getName(vm)
			if name != "" {
				err = errors.Errorf("VM %q is powered on", name)
			} else {
				err = errors.Errorf("VM %q is powered on", vm.Reference())
			}
			return err
		}
		if _, err = vm.WaitForResult(d.ctx, func(ctx context.Context) (tasks.Task, error) {
			return vm.PowerOff(ctx)
		}); err != nil {
			log.Debugf("Failed to power off existing appliance for %s, try to remove anyway", err)
		}
	}
	// get the actual folder name before we delete it
	folder, err := vm.FolderName(d.ctx)
	if err != nil {
		// failed to get folder name, might not be able to remove files for this VM
		name := d.getName(vm)
		if name == "" {
			log.Errorf("Unable to automatically remove all files in datastore for VM %q", vm.Reference())
		} else {
			// try to use the vm name in place of folder
			log.Infof("Delete will attempt to remove datastore files for VM %q", name)
			folder = name
		}
	}

	_, err = vm.WaitForResult(d.ctx, func(ctx context.Context) (tasks.Task, error) {
		return vm.DeleteExceptDisks(ctx)
	})
	if err != nil {
		err = errors.Errorf("Failed to destroy VM %q: %s", vm.Reference(), err)
		err2 := vm.Unregister(d.ctx)
		if err2 != nil {
			return errors.Errorf("%s then failed to unregister VM: %s", err, err2)
		}
		log.Infof("Unregistered VM to cleanup after failed destroy: %q", vm.Reference())
	}
	if _, err = d.deleteDatastoreFiles(d.session.Datastore, folder, true); err != nil {
		log.Warnf("Failed to remove datastore files for VM path %q: %s", folder, err)
	}

	return nil
}