Skip to content

Commit f372b9f

Browse files
authored
Merge pull request #3759 from dougm/govc-nfc-lease
govc: Add -lease option to import/export commands
2 parents ea5fd98 + 96ad8ab commit f372b9f

File tree

8 files changed

+138
-72
lines changed

8 files changed

+138
-72
lines changed

cli/export/ovf.go

+14-9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type ovfx struct {
3838
images bool
3939
prefix bool
4040
sha int
41+
lease bool
4142

4243
mf bytes.Buffer
4344
}
@@ -62,6 +63,7 @@ func (cmd *ovfx) Register(ctx context.Context, f *flag.FlagSet) {
6263
f.BoolVar(&cmd.images, "i", false, "Include image files (*.{iso,img})")
6364
f.BoolVar(&cmd.prefix, "prefix", true, "Prepend target name to image filenames if missing")
6465
f.IntVar(&cmd.sha, "sha", 0, "Generate manifest using SHA 1, 256, 512 or 0 to skip")
66+
f.BoolVar(&cmd.lease, "lease", false, "Output NFC Lease only")
6567
}
6668

6769
func (cmd *ovfx) Usage() string {
@@ -72,18 +74,12 @@ func (cmd *ovfx) Description() string {
7274
return `Export VM.
7375
7476
Examples:
75-
govc export.ovf -vm $vm DIR`
76-
}
77-
78-
func (cmd *ovfx) Process(ctx context.Context) error {
79-
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
80-
return err
81-
}
82-
return nil
77+
govc export.ovf -vm $vm DIR
78+
govc export.ovf -vm $vm -lease`
8379
}
8480

8581
func (cmd *ovfx) Run(ctx context.Context, f *flag.FlagSet) error {
86-
if f.NArg() != 1 {
82+
if f.NArg() != 1 && !cmd.lease {
8783
// TODO: output summary similar to ovftool's
8884
return flag.ErrHelp
8985
}
@@ -131,6 +127,15 @@ func (cmd *ovfx) Run(ctx context.Context, f *flag.FlagSet) error {
131127
return err
132128
}
133129

130+
if cmd.lease {
131+
o, err := lease.Properties(ctx)
132+
if err != nil {
133+
return err
134+
}
135+
136+
return cmd.WriteResult(o)
137+
}
138+
134139
u := lease.StartUpdater(ctx, info)
135140
defer u.Done()
136141

cli/importx/ova.go

+2-14
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ import (
99
"flag"
1010

1111
"github.com/vmware/govmomi/cli"
12-
"github.com/vmware/govmomi/object"
1312
"github.com/vmware/govmomi/ovf/importer"
14-
"github.com/vmware/govmomi/vim25/types"
1513
)
1614

1715
type ova struct {
@@ -36,17 +34,7 @@ func (cmd *ova) Run(ctx context.Context, f *flag.FlagSet) error {
3634
archive.Client = cmd.Importer.Client
3735

3836
cmd.Importer.Archive = archive
37+
fpath = "*.ovf"
3938

40-
moref, err := cmd.Import(fpath)
41-
if err != nil {
42-
return err
43-
}
44-
45-
vm := object.NewVirtualMachine(cmd.Importer.Client, *moref)
46-
return cmd.Deploy(vm, cmd.OutputFlag)
47-
}
48-
49-
func (cmd *ova) Import(fpath string) (*types.ManagedObjectReference, error) {
50-
ovf := "*.ovf"
51-
return cmd.Importer.Import(context.TODO(), ovf, cmd.Options)
39+
return cmd.Import(ctx, fpath)
5240
}

cli/importx/ovf.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type ovfx struct {
2525
*OptionsFlag
2626

2727
Importer importer.Importer
28+
29+
lease bool
2830
}
2931

3032
func init() {
@@ -49,6 +51,7 @@ func (cmd *ovfx) Register(ctx context.Context, f *flag.FlagSet) {
4951
f.StringVar(&cmd.Importer.Name, "name", "", "Name to use for new entity")
5052
f.BoolVar(&cmd.Importer.VerifyManifest, "m", false, "Verify checksum of uploaded files against manifest (.mf)")
5153
f.BoolVar(&cmd.Importer.Hidden, "hidden", false, "Enable hidden properties")
54+
f.BoolVar(&cmd.lease, "lease", false, "Output NFC Lease only")
5255
}
5356

5457
func (cmd *ovfx) Process(ctx context.Context) error {
@@ -88,7 +91,25 @@ func (cmd *ovfx) Run(ctx context.Context, f *flag.FlagSet) error {
8891

8992
cmd.Importer.Archive = archive
9093

91-
moref, err := cmd.Importer.Import(context.TODO(), fpath, cmd.Options)
94+
return cmd.Import(ctx, fpath)
95+
}
96+
97+
func (cmd *ovfx) Import(ctx context.Context, fpath string) error {
98+
if cmd.lease {
99+
_, lease, err := cmd.Importer.ImportVApp(ctx, fpath, cmd.Options)
100+
if err != nil {
101+
return err
102+
}
103+
104+
o, err := lease.Properties(ctx)
105+
if err != nil {
106+
return err
107+
}
108+
109+
return cmd.WriteResult(o)
110+
}
111+
112+
moref, err := cmd.Importer.Import(ctx, fpath, cmd.Options)
92113
if err != nil {
93114
return err
94115
}

cli/task/set.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func (cmd *set) Description() string {
4343
4444
Examples:
4545
id=$(govc task.create com.vmware.govmomi.simulator.test)
46-
govc task.set $id -s error`
46+
govc task.set $id -s error
47+
govc task.set $id -p 100 -s success`
4748
}
4849

4950
func (cmd *set) Usage() string {
@@ -67,6 +68,13 @@ func (cmd *set) Run(ctx context.Context, f *flag.FlagSet) error {
6768

6869
task := object.NewTask(c, ref)
6970

71+
if cmd.progress != 0 {
72+
err := task.UpdateProgress(ctx, cmd.progress)
73+
if err != nil {
74+
return err
75+
}
76+
}
77+
7078
var fault *types.LocalizedMethodFault
7179

7280
if cmd.err != "" {
@@ -84,13 +92,6 @@ func (cmd *set) Run(ctx context.Context, f *flag.FlagSet) error {
8492
}
8593
}
8694

87-
if cmd.progress != 0 {
88-
err := task.UpdateProgress(ctx, cmd.progress)
89-
if err != nil {
90-
return err
91-
}
92-
}
93-
9495
if cmd.desc.Key != "" {
9596
err := task.SetDescription(ctx, cmd.desc)
9697
if err != nil {

cli/vm/snapshot/export.go

+48-12
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,20 @@ package snapshot
77
import (
88
"context"
99
"flag"
10+
"fmt"
11+
"path/filepath"
1012

1113
"github.com/vmware/govmomi/cli"
1214
"github.com/vmware/govmomi/cli/flags"
15+
"github.com/vmware/govmomi/nfc"
16+
"github.com/vmware/govmomi/vim25/soap"
1317
)
1418

1519
type export struct {
1620
*flags.VirtualMachineFlag
21+
22+
lease bool
23+
dest string
1724
}
1825

1926
func init() {
@@ -23,6 +30,9 @@ func init() {
2330
func (cmd *export) Register(ctx context.Context, f *flag.FlagSet) {
2431
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
2532
cmd.VirtualMachineFlag.Register(ctx, f)
33+
34+
f.BoolVar(&cmd.lease, "lease", false, "Output NFC Lease only")
35+
f.StringVar(&cmd.dest, "d", ".", "Destination directory")
2636
}
2737

2838
func (cmd *export) Usage() string {
@@ -35,18 +45,12 @@ func (cmd *export) Description() string {
3545
NAME can be the snapshot name, tree path, or managed object ID.
3646
3747
Examples:
38-
govc snapshot.export -vm my-vm my-snapshot`
39-
}
40-
41-
func (cmd *export) Process(ctx context.Context) error {
42-
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
43-
return err
44-
}
45-
return nil
48+
govc snapshot.export -vm my-vm my-snapshot
49+
govc snapshot.export -vm my-vm -lease my-snapshot`
4650
}
4751

4852
func (cmd *export) Run(ctx context.Context, f *flag.FlagSet) error {
49-
if f.NArg() != 1 {
53+
if f.NArg() != 1 && !cmd.lease {
5054
return flag.ErrHelp
5155
}
5256

@@ -64,15 +68,47 @@ func (cmd *export) Run(ctx context.Context, f *flag.FlagSet) error {
6468
return err
6569
}
6670

67-
l, err := vm.ExportSnapshot(ctx, s)
71+
lease, err := vm.ExportSnapshot(ctx, s)
6872
if err != nil {
6973
return err
7074
}
7175

72-
o, err := l.Properties(ctx)
76+
info, err := lease.Wait(ctx, nil)
7377
if err != nil {
7478
return err
7579
}
7680

77-
return cmd.WriteResult(o)
81+
if cmd.lease {
82+
o, err := lease.Properties(ctx)
83+
if err != nil {
84+
return err
85+
}
86+
87+
return cmd.WriteResult(o)
88+
}
89+
90+
u := lease.StartUpdater(ctx, info)
91+
defer u.Done()
92+
93+
for _, i := range info.Items {
94+
err := cmd.Download(ctx, lease, i)
95+
if err != nil {
96+
return err
97+
}
98+
}
99+
100+
return lease.Complete(ctx)
101+
}
102+
103+
func (cmd *export) Download(ctx context.Context, lease *nfc.Lease, item nfc.FileItem) error {
104+
path := filepath.Join(cmd.dest, item.Path)
105+
106+
logger := cmd.ProgressLogger(fmt.Sprintf("Downloading %s... ", item.Path))
107+
defer logger.Wait()
108+
109+
opts := soap.Download{
110+
Progress: logger,
111+
}
112+
113+
return lease.DownloadFile(ctx, path, item, opts)
78114
}

govc/USAGE.md

+7
Original file line numberDiff line numberDiff line change
@@ -2513,10 +2513,12 @@ Export VM.
25132513
25142514
Examples:
25152515
govc export.ovf -vm $vm DIR
2516+
govc export.ovf -vm $vm -lease
25162517
25172518
Options:
25182519
-f=false Overwrite existing
25192520
-i=false Include image files (*.{iso,img})
2521+
-lease=false Output NFC Lease only
25202522
-name= Specifies target name (defaults to source name)
25212523
-prefix=true Prepend target name to image filenames if missing
25222524
-sha=0 Generate manifest using SHA 1, 256, 512 or 0 to skip
@@ -3767,6 +3769,7 @@ Options:
37673769
-folder= Inventory folder [GOVC_FOLDER]
37683770
-hidden=false Enable hidden properties
37693771
-host= Host system [GOVC_HOST]
3772+
-lease=false Output NFC Lease only
37703773
-m=false Verify checksum of uploaded files against manifest (.mf)
37713774
-name= Name to use for new entity
37723775
-options= Options spec file path for VM deployment
@@ -3783,6 +3786,7 @@ Options:
37833786
-folder= Inventory folder [GOVC_FOLDER]
37843787
-hidden=false Enable hidden properties
37853788
-host= Host system [GOVC_HOST]
3789+
-lease=false Output NFC Lease only
37863790
-m=false Verify checksum of uploaded files against manifest (.mf)
37873791
-name= Name to use for new entity
37883792
-options= Options spec file path for VM deployment
@@ -5677,8 +5681,11 @@ NAME can be the snapshot name, tree path, or managed object ID.
56775681
56785682
Examples:
56795683
govc snapshot.export -vm my-vm my-snapshot
5684+
govc snapshot.export -vm my-vm -lease my-snapshot
56805685
56815686
Options:
5687+
-d=. Destination directory
5688+
-lease=false Output NFC Lease only
56825689
-vm= Virtual machine [GOVC_VM]
56835690
```
56845691

govc/test/snapshot.bats

+19-19
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22

33
load test_helper
44

5-
test_vm_snapshot() {
6-
vm=$1
5+
@test "vm.snapshot vcsim" {
6+
vcsim_env
7+
8+
vm=$(new_empty_vm)
9+
10+
run govc vm.disk.create -vm "$vm" -name "$vm/disk.vmdk" -size 1M
11+
assert_success
12+
713
id=$(new_id)
814

915
# No snapshots == no output
@@ -22,8 +28,18 @@ test_vm_snapshot() {
2228
run govc snapshot.create -vm "$vm" "$id"
2329
assert_success
2430

25-
run govc snapshot.export -vm "$vm" "$id"
31+
run govc snapshot.export -lease -vm "$vm" "$id"
32+
assert_success
33+
34+
dir=$(govc datastore.info -json | jq -r .datastores[].info.url)
35+
mkdir "$dir/$id"
36+
37+
run govc snapshot.export -d "$dir/$id" -vm "$vm" "$id"
38+
assert_success
39+
40+
run ls "$dir/$id"/*.vmdk
2641
assert_success
42+
assert_output_lines 1
2743

2844
run govc snapshot.revert -vm "$vm" enoent
2945
assert_failure
@@ -122,19 +138,3 @@ test_vm_snapshot() {
122138
result=$(govc snapshot.tree -vm "$vm" -f | grep '\.' | wc -l)
123139
[ "$result" -eq 1 ]
124140
}
125-
126-
@test "vm.snapshot vcsim" {
127-
vcsim_env
128-
129-
vm=$(new_empty_vm)
130-
131-
test_vm_snapshot $vm
132-
}
133-
134-
@test "vm.snapshot" {
135-
esx_env
136-
137-
vm=$(new_ttylinux_vm)
138-
139-
test_vm_snapshot $vm
140-
}

0 commit comments

Comments
 (0)