Skip to content

Commit

Permalink
Add storage support to vm.migrate (#641)
Browse files Browse the repository at this point in the history
Fixes #639
  • Loading branch information
dougm committed Dec 9, 2016
1 parent 1a7dc61 commit b5c807e
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 12 deletions.
2 changes: 2 additions & 0 deletions govc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### unreleased

* Add storage support to vm.migrate

* Add support for file backed serialport devices

### 0.12.0 (2016-12-01)
Expand Down
5 changes: 3 additions & 2 deletions govc/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2277,16 +2277,17 @@ Options:
```
Usage: govc vm.migrate [OPTIONS] VM...
Migrates VM execution to a specific resource pool or host.
Migrates VM to a specific resource pool, host or datastore.
Examples:
govc vm.migrate -host another-host vm-1 vm-2 vm-3
govc vm.migrate -ds another-ds vm-1 vm-2 vm-3
Options:
-ds= Datastore [GOVC_DATASTORE]
-host= Host system [GOVC_HOST]
-pool= Resource pool [GOVC_RESOURCE_POOL]
-priority=defaultPriority The task priority
-state= If specified, the VM migrates only if its state matches
```

## vm.network.add
Expand Down
7 changes: 7 additions & 0 deletions govc/flags/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ func (f *DatastoreFlag) Datastore() (*object.Datastore, error) {
return f.ds, nil
}

func (flag *DatastoreFlag) DatastoreIfSpecified() (*object.Datastore, error) {
if flag.Name == "" {
return nil, nil
}
return flag.Datastore()
}

func (f *DatastoreFlag) DatastorePath(name string) (string, error) {
ds, err := f.Datastore()
if err != nil {
Expand Down
61 changes: 51 additions & 10 deletions govc/vm/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ package vm
import (
"context"
"flag"
"fmt"

"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)

type migrate struct {
*flags.ResourcePoolFlag
*flags.HostSystemFlag
*flags.DatastoreFlag
*flags.SearchFlag

priority types.VirtualMachineMovePriority
state types.VirtualMachinePowerState
spec types.VirtualMachineRelocateSpec
}

func init() {
Expand All @@ -48,8 +51,10 @@ func (cmd *migrate) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)

cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)

f.StringVar((*string)(&cmd.priority), "priority", string(types.VirtualMachineMovePriorityDefaultPriority), "The task priority")
f.StringVar((*string)(&cmd.state), "state", "", "If specified, the VM migrates only if its state matches")
}

func (cmd *migrate) Process(ctx context.Context) error {
Expand All @@ -59,6 +64,9 @@ func (cmd *migrate) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}

return nil
}
Expand All @@ -68,10 +76,28 @@ func (cmd *migrate) Usage() string {
}

func (cmd *migrate) Description() string {
return `Migrates VM execution to a specific resource pool or host.
return `Migrates VM to a specific resource pool, host or datastore.
Examples:
govc vm.migrate -host another-host vm-1 vm-2 vm-3`
govc vm.migrate -host another-host vm-1 vm-2 vm-3
govc vm.migrate -ds another-ds vm-1 vm-2 vm-3`
}

func (cmd *migrate) relocate(ctx context.Context, vm *object.VirtualMachine) error {
task, err := vm.Relocate(ctx, cmd.spec, cmd.priority)
if err != nil {
return err
}

logger := cmd.DatastoreFlag.ProgressLogger(fmt.Sprintf("migrating %s... ", vm.Reference()))
_, err = task.WaitForResult(ctx, logger)
if err != nil {
return err
}

logger.Wait()

return nil
}

func (cmd *migrate) Run(ctx context.Context, f *flag.FlagSet) error {
Expand All @@ -85,18 +111,33 @@ func (cmd *migrate) Run(ctx context.Context, f *flag.FlagSet) error {
return err
}

if host != nil {
ref := host.Reference()
cmd.spec.Host = &ref
}

pool, err := cmd.ResourcePoolFlag.ResourcePoolIfSpecified()
if err != nil {
return err
}

for _, vm := range vms {
task, err := vm.Migrate(ctx, pool, host, cmd.priority, cmd.state)
if err != nil {
return err
}
if pool != nil {
ref := pool.Reference()
cmd.spec.Pool = &ref
}

err = task.Wait(ctx)
ds, err := cmd.DatastoreFlag.DatastoreIfSpecified()
if err != nil {
return err
}

if ds != nil {
ref := ds.Reference()
cmd.spec.Datastore = &ref
}

for _, vm := range vms {
err = cmd.relocate(ctx, vm)
if err != nil {
return err
}
Expand Down

0 comments on commit b5c807e

Please sign in to comment.