Skip to content

Commit

Permalink
Merge pull request #1036 from dougm/datastore-disk-cp
Browse files Browse the repository at this point in the history
Use VirtualDiskManager in datastore cp and mv commands
  • Loading branch information
dougm authored Feb 16, 2018
2 parents 5eba1d9 + d622f14 commit 3c1bff8
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 181 deletions.
103 changes: 74 additions & 29 deletions govc/datastore/cp.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2018 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -18,42 +18,89 @@ package datastore

import (
"context"
"errors"
"flag"
"fmt"

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

type cp struct {
*flags.OutputFlag
*flags.DatastoreFlag

force bool
target
}

func init() {
cli.Register("datastore.cp", &cp{})
}

func (cmd *cp) Register(ctx context.Context, f *flag.FlagSet) {
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
type target struct {
*flags.DatastoreFlag // The source Datastore and the default target Datastore

dc *flags.DatacenterFlag // Optionally target a different Datacenter
ds *flags.DatastoreFlag // Optionally target a different Datastore

kind bool
force bool
}

func (cmd *target) FileManager() (*object.DatastoreFileManager, error) {
dc, err := cmd.Datacenter()
if err != nil {
return nil, err
}

ds, err := cmd.Datastore()
if err != nil {
return nil, err
}

m := ds.NewFileManager(dc, cmd.force)

dc, err = cmd.dc.Datacenter()
if err != nil {
return nil, err
}
m.DatacenterTarget = dc

return m, nil
}

func (cmd *target) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)

cmd.dc = &flags.DatacenterFlag{
OutputFlag: cmd.OutputFlag,
ClientFlag: cmd.ClientFlag,
}
f.StringVar(&cmd.dc.Name, "dc-target", "", "Datacenter destination (defaults to -dc)")

cmd.ds = &flags.DatastoreFlag{
DatacenterFlag: cmd.dc,
}
f.StringVar(&cmd.ds.Name, "ds-target", "", "Datastore destination (defaults to -ds)")

f.BoolVar(&cmd.kind, "t", true, "Use file type to choose disk or file manager")
f.BoolVar(&cmd.force, "f", false, "If true, overwrite any identically named file at the destination")
}

func (cmd *cp) Process(ctx context.Context) error {
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
func (cmd *target) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}

if cmd.dc.Name == "" {
// Use source DC as target DC
cmd.dc = cmd.DatacenterFlag
cmd.ds.DatacenterFlag = cmd.dc
}

if cmd.ds.Name == "" {
// Use source DS as target DS
cmd.ds.Name = cmd.DatastoreFlag.Name
}

return nil
}

Expand All @@ -66,42 +113,40 @@ func (cmd *cp) Description() string {
Examples:
govc datastore.cp foo/foo.vmx foo/foo.vmx.old
govc datastore.cp -f my.vmx foo/foo.vmx`
govc datastore.cp -f my.vmx foo/foo.vmx
govc datastore.cp disks/disk1.vmdk disks/disk2.vmdk
govc datastore.cp disks/disk1.vmdk -dc-target DC2 disks/disk2.vmdk
govc datastore.cp disks/disk1.vmdk -ds-target NFS-2 disks/disk2.vmdk`
}

func (cmd *cp) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("SRC and DST arguments are required")
return flag.ErrHelp
}

c, err := cmd.Client()
m, err := cmd.FileManager()
if err != nil {
return err
}

dc, err := cmd.Datacenter()
if err != nil {
return err
}

// TODO: support cross-datacenter copy

src, err := cmd.DatastorePath(args[0])
if err != nil {
return err
}

dst, err := cmd.DatastorePath(args[1])
dst, err := cmd.target.ds.DatastorePath(args[1])
if err != nil {
return err
}

m := object.NewFileManager(c)
task, err := m.CopyDatastoreFile(ctx, src, dc, dst, dc, cmd.force)
if err != nil {
return err
cp := m.CopyFile
if cmd.kind {
cp = m.Copy
}

return task.Wait(ctx)
logger := cmd.ProgressLogger(fmt.Sprintf("Copying %s to %s...", src, dst))
defer logger.Wait()

return cp(m.WithProgress(ctx, logger), src, dst)
}
86 changes: 0 additions & 86 deletions govc/datastore/disk/cp.go

This file was deleted.

49 changes: 13 additions & 36 deletions govc/datastore/mv.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2018 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -18,38 +18,20 @@ package datastore

import (
"context"
"errors"
"flag"
"fmt"

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

type mv struct {
*flags.DatastoreFlag

force bool
target
}

func init() {
cli.Register("datastore.mv", &mv{})
}

func (cmd *mv) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)

f.BoolVar(&cmd.force, "f", false, "If true, overwrite any identically named file at the destination")
}

func (cmd *mv) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}

func (cmd *mv) Usage() string {
return "SRC DST"
}
Expand All @@ -65,36 +47,31 @@ Examples:
func (cmd *mv) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("SRC and DST arguments are required")
return flag.ErrHelp
}

c, err := cmd.Client()
m, err := cmd.FileManager()
if err != nil {
return err
}

dc, err := cmd.Datacenter()
if err != nil {
return err
}

// TODO: support cross-datacenter move

src, err := cmd.DatastorePath(args[0])
if err != nil {
return err
}

dst, err := cmd.DatastorePath(args[1])
dst, err := cmd.target.ds.DatastorePath(args[1])
if err != nil {
return err
}

m := object.NewFileManager(c)
task, err := m.MoveDatastoreFile(ctx, src, dc, dst, dc, cmd.force)
if err != nil {
return err
mv := m.MoveFile
if cmd.kind {
mv = m.Move
}

return task.Wait(ctx)
logger := cmd.ProgressLogger(fmt.Sprintf("Moving %s to %s...", src, dst))
defer logger.Wait()

return mv(m.WithProgress(ctx, logger), src, dst)
}
10 changes: 5 additions & 5 deletions govc/flags/datacenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type DatacenterFlag struct {
*ClientFlag
*OutputFlag

path string
Name string
dc *object.Datacenter
finder *find.Finder
err error
Expand Down Expand Up @@ -61,7 +61,7 @@ func (flag *DatacenterFlag) Register(ctx context.Context, f *flag.FlagSet) {
env := "GOVC_DATACENTER"
value := os.Getenv(env)
usage := fmt.Sprintf("Datacenter [%s]", env)
f.StringVar(&flag.path, "dc", value, usage)
f.StringVar(&flag.Name, "dc", value, usage)
})
}

Expand Down Expand Up @@ -93,10 +93,10 @@ func (flag *DatacenterFlag) Finder() (*find.Finder, error) {
// Set for relative func if dc flag is given or
// if there is a single (default) Datacenter
ctx := context.TODO()
if flag.path == "" {
if flag.Name == "" {
flag.dc, flag.err = finder.DefaultDatacenter(ctx)
} else {
if flag.dc, err = finder.Datacenter(ctx, flag.path); err != nil {
if flag.dc, err = finder.Datacenter(ctx, flag.Name); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -127,7 +127,7 @@ func (flag *DatacenterFlag) Datacenter() (*object.Datacenter, error) {
}

func (flag *DatacenterFlag) DatacenterIfSpecified() (*object.Datacenter, error) {
if flag.path == "" {
if flag.Name == "" {
return nil, nil
}
return flag.Datacenter()
Expand Down
Loading

0 comments on commit 3c1bff8

Please sign in to comment.