Skip to content

Commit

Permalink
govc: add datastore.download -json support
Browse files Browse the repository at this point in the history
Only applies to ".ovf" and ".vmdk" files currently.

Signed-off-by: Doug MacEachern <dougm@broadcom.com>
  • Loading branch information
dougm committed Jan 2, 2025
1 parent 615a520 commit ca2e6ff
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 80 deletions.
58 changes: 39 additions & 19 deletions cli/datastore/download.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
/*
Copyright (c) 2014-2015 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// © Broadcom. All Rights Reserved.
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
// SPDX-License-Identifier: Apache-2.0

package datastore

Expand All @@ -23,10 +11,14 @@ import (
"fmt"
"io"
"os"
"path"

"github.com/vmware/govmomi/cli"
"github.com/vmware/govmomi/cli/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vmdk"
)

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

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

src := args[0]
dst := args[1]

var dp object.DatastorePath
if dp.FromString(src) {
// e.g. `govc library.info -l -L ...`
cmd.DatastoreFlag.Name = dp.Datastore
src = dp.Path
}

ds, err := cmd.Datastore()
if err != nil {
return err
Expand All @@ -95,14 +100,29 @@ func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error {

p := soap.DefaultDownload

src := args[0]
dst := args[1]

if dst == "-" {
f, _, err := ds.Download(ctx, src, &p)
if err != nil {
return err
}

if cmd.DatastoreFlag.All() {
switch path.Ext(src) {
case ".vmdk":
data, err := vmdk.ParseDescriptor(f)
if err != nil {
return err
}
return cmd.DatastoreFlag.WriteResult(data)
case ".ovf":
data, err := ovf.Unmarshal(f)
if err != nil {
return err
}
return cmd.DatastoreFlag.WriteResult(data)
}
}

_, err = io.Copy(os.Stdout, f)
return err
}
Expand Down
3 changes: 3 additions & 0 deletions govc/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,9 @@ If DEST name is "-", source is written to stdout.
Examples:
govc datastore.download vm-name/vmware.log ./local.log
govc datastore.download vm-name/vmware.log - | grep -i error
govc datastore.download -json vm-name/vm-name.vmdk - | jq .ddb
ovf=$(govc library.info -l -L vmservice/photon-5.0/*.ovf)
govc datastore.download -json "$ovf" - | jq -r .diskSection.disk[].capacity
Options:
-ds= Datastore [GOVC_DATASTORE]
Expand Down
24 changes: 24 additions & 0 deletions govc/test/library.bats
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ load test_helper

@test "library.import" {
vcsim_env
unset GOVC_HOST # else datastore.download tries via ESX

run govc library.create my-content
assert_success
Expand Down Expand Up @@ -134,6 +135,29 @@ load test_helper
assert_matches "$TTYLINUX_NAME.ovf"
assert_matches "$TTYLINUX_NAME-disk1.vmdk"

run govc library.info -l -L "/my-content/$TTYLINUX_NAME/*.ovf"
assert_success
ovf="$output"

# validate ovf.Envelope as json
run govc datastore.download -json "$ovf" -
assert_success

run jq -r .virtualSystem.operatingSystemSection.osType <<<"$output"
assert_success "otherLinuxGuest"

run govc library.info -L "/my-content/$TTYLINUX_NAME/*.vmdk"
assert_success
vmdk="$output"

# validate vmdk.Descriptor as json
run govc datastore.download -json "$vmdk" -
assert_success

base=$(basename "$vmdk")
run jq -r .extent[].info <<<"$output"
assert_success "${base/.vmdk/-flat.vmdk}"

run govc library.import /my-content "$GOVC_IMAGES/$TTYLINUX_NAME.iso"
assert_failure # already_exists

Expand Down
23 changes: 8 additions & 15 deletions ovf/ovf.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
/*
Copyright (c) 2015 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// © Broadcom. All Rights Reserved.
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
// SPDX-License-Identifier: Apache-2.0

package ovf

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

return &e, nil
}

// Write satisfies the flags.OutputWriter interface.
func (e *Envelope) Write(w io.Writer) error {
return xml.NewEncoder(w).Encode(e)
}
46 changes: 17 additions & 29 deletions vmdk/descriptor.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
/*
Copyright (c) 2024-2024 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// © Broadcom. All Rights Reserved.
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
// SPDX-License-Identifier: Apache-2.0

package vmdk

Expand All @@ -27,13 +15,13 @@ import (
)

type Descriptor struct {
Encoding string
Version int
CID DiskContentID
ParentCID DiskContentID
Type string
Extent []Extent
DDB map[string]string
Encoding string `json:"encoding"`
Version int `json:"version"`
CID DiskContentID `json:"cid"`
ParentCID DiskContentID `json:"parentCID"`
Type string `json:"type"`
Extent []Extent `json:"extent"`
DDB map[string]string `json:"ddb"`
}

type DiskContentID uint32
Expand All @@ -43,10 +31,10 @@ func (cid DiskContentID) String() string {
}

type Extent struct {
Type string
Permission string
Size uint64
Info string
Type string `json:"type"`
Permission string `json:"permission"`
Size uint64 `json:"size"`
Info string `json:"info"`
}

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

key, val := strings.TrimSpace(s[0]), strings.TrimSpace(s[1])
val = strings.Trim(val, `"`)
if strings.HasPrefix(key, "ddb") {
d.DDB[key] = val
if k := strings.TrimPrefix(key, "ddb."); k != key {
d.DDB[k] = val
continue
}

Expand Down Expand Up @@ -161,7 +149,7 @@ createType="{{ .Type }}"
# The Disk Data Base
#DDB{{ range $key, $val := .DDB }}
{{ $key }} = "{{ $val }}"{{end}}
ddb.{{ $key }} = "{{ $val }}"{{end}}
`

func (d *Descriptor) Write(w io.Writer) error {
Expand Down
22 changes: 5 additions & 17 deletions vmdk/descriptor_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
/*
Copyright (c) 2024-2024 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// © Broadcom. All Rights Reserved.
// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
// SPDX-License-Identifier: Apache-2.0

package vmdk_test

Expand All @@ -37,8 +25,8 @@ func TestDescriptor(t *testing.T) {
Info: "test-flat.vmdk",
}},
DDB: map[string]string{
"ddb.adapterType": "lsilogic",
"ddb.virtualHWVersion": "14",
"adapterType": "lsilogic",
"virtualHWVersion": "14",
},
}

Expand Down

0 comments on commit ca2e6ff

Please sign in to comment.