Skip to content

Commit ca2e6ff

Browse files
committedJan 2, 2025·
govc: add datastore.download -json support
Only applies to ".ovf" and ".vmdk" files currently. Signed-off-by: Doug MacEachern <dougm@broadcom.com>
1 parent 615a520 commit ca2e6ff

File tree

6 files changed

+96
-80
lines changed

6 files changed

+96
-80
lines changed
 

‎cli/datastore/download.go

+39-19
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
/*
2-
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
15-
*/
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
164

175
package datastore
186

@@ -23,10 +11,14 @@ import (
2311
"fmt"
2412
"io"
2513
"os"
14+
"path"
2615

2716
"github.com/vmware/govmomi/cli"
2817
"github.com/vmware/govmomi/cli/flags"
18+
"github.com/vmware/govmomi/object"
19+
"github.com/vmware/govmomi/ovf"
2920
"github.com/vmware/govmomi/vim25/soap"
21+
"github.com/vmware/govmomi/vmdk"
3022
)
3123

3224
type download struct {
@@ -67,7 +59,10 @@ If DEST name is "-", source is written to stdout.
6759
6860
Examples:
6961
govc datastore.download vm-name/vmware.log ./local.log
70-
govc datastore.download vm-name/vmware.log - | grep -i error`
62+
govc datastore.download vm-name/vmware.log - | grep -i error
63+
govc datastore.download -json vm-name/vm-name.vmdk - | jq .ddb
64+
ovf=$(govc library.info -l -L vmservice/photon-5.0/*.ovf)
65+
govc datastore.download -json "$ovf" - | jq -r .diskSection.disk[].capacity`
7166
}
7267

7368
func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error {
@@ -76,6 +71,16 @@ func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error {
7671
return errors.New("invalid arguments")
7772
}
7873

74+
src := args[0]
75+
dst := args[1]
76+
77+
var dp object.DatastorePath
78+
if dp.FromString(src) {
79+
// e.g. `govc library.info -l -L ...`
80+
cmd.DatastoreFlag.Name = dp.Datastore
81+
src = dp.Path
82+
}
83+
7984
ds, err := cmd.Datastore()
8085
if err != nil {
8186
return err
@@ -95,14 +100,29 @@ func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error {
95100

96101
p := soap.DefaultDownload
97102

98-
src := args[0]
99-
dst := args[1]
100-
101103
if dst == "-" {
102104
f, _, err := ds.Download(ctx, src, &p)
103105
if err != nil {
104106
return err
105107
}
108+
109+
if cmd.DatastoreFlag.All() {
110+
switch path.Ext(src) {
111+
case ".vmdk":
112+
data, err := vmdk.ParseDescriptor(f)
113+
if err != nil {
114+
return err
115+
}
116+
return cmd.DatastoreFlag.WriteResult(data)
117+
case ".ovf":
118+
data, err := ovf.Unmarshal(f)
119+
if err != nil {
120+
return err
121+
}
122+
return cmd.DatastoreFlag.WriteResult(data)
123+
}
124+
}
125+
106126
_, err = io.Copy(os.Stdout, f)
107127
return err
108128
}

‎govc/USAGE.md

+3
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,9 @@ If DEST name is "-", source is written to stdout.
14271427
Examples:
14281428
govc datastore.download vm-name/vmware.log ./local.log
14291429
govc datastore.download vm-name/vmware.log - | grep -i error
1430+
govc datastore.download -json vm-name/vm-name.vmdk - | jq .ddb
1431+
ovf=$(govc library.info -l -L vmservice/photon-5.0/*.ovf)
1432+
govc datastore.download -json "$ovf" - | jq -r .diskSection.disk[].capacity
14301433
14311434
Options:
14321435
-ds= Datastore [GOVC_DATASTORE]

‎govc/test/library.bats

+24
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ load test_helper
6363

6464
@test "library.import" {
6565
vcsim_env
66+
unset GOVC_HOST # else datastore.download tries via ESX
6667

6768
run govc library.create my-content
6869
assert_success
@@ -134,6 +135,29 @@ load test_helper
134135
assert_matches "$TTYLINUX_NAME.ovf"
135136
assert_matches "$TTYLINUX_NAME-disk1.vmdk"
136137

138+
run govc library.info -l -L "/my-content/$TTYLINUX_NAME/*.ovf"
139+
assert_success
140+
ovf="$output"
141+
142+
# validate ovf.Envelope as json
143+
run govc datastore.download -json "$ovf" -
144+
assert_success
145+
146+
run jq -r .virtualSystem.operatingSystemSection.osType <<<"$output"
147+
assert_success "otherLinuxGuest"
148+
149+
run govc library.info -L "/my-content/$TTYLINUX_NAME/*.vmdk"
150+
assert_success
151+
vmdk="$output"
152+
153+
# validate vmdk.Descriptor as json
154+
run govc datastore.download -json "$vmdk" -
155+
assert_success
156+
157+
base=$(basename "$vmdk")
158+
run jq -r .extent[].info <<<"$output"
159+
assert_success "${base/.vmdk/-flat.vmdk}"
160+
137161
run govc library.import /my-content "$GOVC_IMAGES/$TTYLINUX_NAME.iso"
138162
assert_failure # already_exists
139163

‎ovf/ovf.go

+8-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
/*
2-
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
15-
*/
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
164

175
package ovf
186

@@ -33,3 +21,8 @@ func Unmarshal(r io.Reader) (*Envelope, error) {
3321

3422
return &e, nil
3523
}
24+
25+
// Write satisfies the flags.OutputWriter interface.
26+
func (e *Envelope) Write(w io.Writer) error {
27+
return xml.NewEncoder(w).Encode(e)
28+
}

‎vmdk/descriptor.go

+17-29
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
/*
2-
Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
15-
*/
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
164

175
package vmdk
186

@@ -27,13 +15,13 @@ import (
2715
)
2816

2917
type Descriptor struct {
30-
Encoding string
31-
Version int
32-
CID DiskContentID
33-
ParentCID DiskContentID
34-
Type string
35-
Extent []Extent
36-
DDB map[string]string
18+
Encoding string `json:"encoding"`
19+
Version int `json:"version"`
20+
CID DiskContentID `json:"cid"`
21+
ParentCID DiskContentID `json:"parentCID"`
22+
Type string `json:"type"`
23+
Extent []Extent `json:"extent"`
24+
DDB map[string]string `json:"ddb"`
3725
}
3826

3927
type DiskContentID uint32
@@ -43,10 +31,10 @@ func (cid DiskContentID) String() string {
4331
}
4432

4533
type Extent struct {
46-
Type string
47-
Permission string
48-
Size uint64
49-
Info string
34+
Type string `json:"type"`
35+
Permission string `json:"permission"`
36+
Size uint64 `json:"size"`
37+
Info string `json:"info"`
5038
}
5139

5240
func NewDescriptor(extent ...Extent) *Descriptor {
@@ -91,8 +79,8 @@ func ParseDescriptor(r io.Reader) (*Descriptor, error) {
9179

9280
key, val := strings.TrimSpace(s[0]), strings.TrimSpace(s[1])
9381
val = strings.Trim(val, `"`)
94-
if strings.HasPrefix(key, "ddb") {
95-
d.DDB[key] = val
82+
if k := strings.TrimPrefix(key, "ddb."); k != key {
83+
d.DDB[k] = val
9684
continue
9785
}
9886

@@ -161,7 +149,7 @@ createType="{{ .Type }}"
161149
162150
# The Disk Data Base
163151
#DDB{{ range $key, $val := .DDB }}
164-
{{ $key }} = "{{ $val }}"{{end}}
152+
ddb.{{ $key }} = "{{ $val }}"{{end}}
165153
`
166154

167155
func (d *Descriptor) Write(w io.Writer) error {

‎vmdk/descriptor_test.go

+5-17
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
/*
2-
Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
15-
*/
1+
// © Broadcom. All Rights Reserved.
2+
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
3+
// SPDX-License-Identifier: Apache-2.0
164

175
package vmdk_test
186

@@ -37,8 +25,8 @@ func TestDescriptor(t *testing.T) {
3725
Info: "test-flat.vmdk",
3826
}},
3927
DDB: map[string]string{
40-
"ddb.adapterType": "lsilogic",
41-
"ddb.virtualHWVersion": "14",
28+
"adapterType": "lsilogic",
29+
"virtualHWVersion": "14",
4230
},
4331
}
4432

0 commit comments

Comments
 (0)
Please sign in to comment.