Skip to content

Commit

Permalink
refactor: make importing templates available as a lib
Browse files Browse the repository at this point in the history
Signed-off-by: Luis Davim <dluis@vmware.com>
  • Loading branch information
luisdavim committed Jul 11, 2024
1 parent fb9679e commit 12467b0
Show file tree
Hide file tree
Showing 16 changed files with 776 additions and 678 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/stretchr/testify v1.9.0
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728
github.com/xlab/treeprint v1.2.0
golang.org/x/text v0.16.0
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728 h1:sH9mEk+fly
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
118 changes: 9 additions & 109 deletions govc/flags/output.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright (c) 2014-2016 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-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
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,
Expand All @@ -26,7 +26,6 @@ import (
"os"
"reflect"
"strings"
"sync"
"time"

"github.com/dougm/pretty"
Expand Down Expand Up @@ -204,7 +203,7 @@ type errorOutput struct {
}

func (e errorOutput) Write(w io.Writer) error {
reason := e.error.Error()
reason := e.Error()
var messages []string
var faults []types.LocalizableMessage

Expand Down Expand Up @@ -261,124 +260,25 @@ func (e errorOutput) canEncode() bool {
return soap.IsSoapFault(e.error) || soap.IsVimFault(e.error)
}

// cannotEncode causes cli.Run to output err.Error() as it would without an error format specified
var cannotEncode = errors.New("cannot encode error")
// errCannotEncode causes cli.Run to output err.Error() as it would without an error format specified
var errCannotEncode = errors.New("cannot encode error")

func (e errorOutput) MarshalJSON() ([]byte, error) {
_, ok := e.error.(json.Marshaler)
if ok || e.canEncode() {
return json.Marshal(e.error)
}
return nil, cannotEncode
return nil, errCannotEncode
}

func (e errorOutput) MarshalXML(encoder *xml.Encoder, start xml.StartElement) error {
_, ok := e.error.(xml.Marshaler)
if ok || e.canEncode() {
return encoder.Encode(e.error)
}
return cannotEncode
return errCannotEncode
}

type progressLogger struct {
flag *OutputFlag
prefix string

wg sync.WaitGroup

sink chan chan progress.Report
done chan struct{}
}

func newProgressLogger(flag *OutputFlag, prefix string) *progressLogger {
p := &progressLogger{
flag: flag,
prefix: prefix,

sink: make(chan chan progress.Report),
done: make(chan struct{}),
}

p.wg.Add(1)

go p.loopA()

return p
}

// loopA runs before Sink() has been called.
func (p *progressLogger) loopA() {
var err error

defer p.wg.Done()

tick := time.NewTicker(100 * time.Millisecond)
defer tick.Stop()

called := false

for stop := false; !stop; {
select {
case ch := <-p.sink:
err = p.loopB(tick, ch)
stop = true
called = true
case <-p.done:
stop = true
case <-tick.C:
line := fmt.Sprintf("\r%s", p.prefix)
p.flag.Log(line)
}
}

if err != nil && err != io.EOF {
p.flag.Log(fmt.Sprintf("\r%sError: %s\n", p.prefix, err))
} else if called {
p.flag.Log(fmt.Sprintf("\r%sOK\n", p.prefix))
}
}

// loopA runs after Sink() has been called.
func (p *progressLogger) loopB(tick *time.Ticker, ch <-chan progress.Report) error {
var r progress.Report
var ok bool
var err error

for ok = true; ok; {
select {
case r, ok = <-ch:
if !ok {
break
}
err = r.Error()
case <-tick.C:
line := fmt.Sprintf("\r%s", p.prefix)
if r != nil {
line += fmt.Sprintf("(%.0f%%", r.Percentage())
detail := r.Detail()
if detail != "" {
line += fmt.Sprintf(", %s", detail)
}
line += ")"
}
p.flag.Log(line)
}
}

return err
}

func (p *progressLogger) Sink() chan<- progress.Report {
ch := make(chan progress.Report)
p.sink <- ch
return ch
}

func (p *progressLogger) Wait() {
close(p.done)
p.wg.Wait()
}

func (flag *OutputFlag) ProgressLogger(prefix string) *progressLogger {
return newProgressLogger(flag, prefix)
func (flag *OutputFlag) ProgressLogger(prefix string) *progress.ProgressLogger {
return progress.NewProgressLogger(flag.Log, prefix)
}
74 changes: 4 additions & 70 deletions govc/importx/options.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright (c) 2015-2023 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-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
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,
Expand All @@ -26,78 +26,12 @@ import (
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/ovf/importer"
"github.com/vmware/govmomi/vim25/types"
)

type KeyValue struct {
Key string
Value string
}

// case insensitive for Key + Value
func (kv *KeyValue) UnmarshalJSON(b []byte) error {
e := struct {
types.KeyValue
Key *string
Value *string
}{
types.KeyValue{}, &kv.Key, &kv.Value,
}

err := json.Unmarshal(b, &e)
if err != nil {
return err
}

if kv.Key == "" {
kv.Key = e.KeyValue.Key // "key"
}

if kv.Value == "" {
kv.Value = e.KeyValue.Value // "value"
}

return nil
}

type Property struct {
KeyValue
Spec *ovf.Property `json:",omitempty"`
}

type Network struct {
Name string
Network string
}

type Options struct {
AllDeploymentOptions []string `json:",omitempty"`
Deployment string `json:",omitempty"`

AllDiskProvisioningOptions []string `json:",omitempty"`
DiskProvisioning string

AllIPAllocationPolicyOptions []string `json:",omitempty"`
IPAllocationPolicy string

AllIPProtocolOptions []string `json:",omitempty"`
IPProtocol string

PropertyMapping []Property `json:",omitempty"`

NetworkMapping []Network `json:",omitempty"`

Annotation string `json:",omitempty"`

MarkAsTemplate bool
PowerOn bool
InjectOvfEnv bool
WaitForIP bool
Name *string
}

type OptionsFlag struct {
Options Options
Options importer.Options

path string
}
Expand Down
15 changes: 8 additions & 7 deletions govc/importx/ova.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-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
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,
Expand All @@ -22,6 +22,7 @@ import (

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

Expand All @@ -43,21 +44,21 @@ func (cmd *ova) Run(ctx context.Context, f *flag.FlagSet) error {
return err
}

archive := &TapeArchive{Path: fpath}
archive.Client = cmd.Client
archive := &importer.TapeArchive{Path: fpath}
archive.Client = cmd.Importer.Client

cmd.Archive = archive
cmd.Importer.Archive = archive

moref, err := cmd.Import(fpath)
if err != nil {
return err
}

vm := object.NewVirtualMachine(cmd.Client, *moref)
vm := object.NewVirtualMachine(cmd.Importer.Client, *moref)
return cmd.Deploy(vm, cmd.OutputFlag)
}

func (cmd *ova) Import(fpath string) (*types.ManagedObjectReference, error) {
ovf := "*.ovf"
return cmd.ovfx.Import(ovf)
return cmd.Importer.Import(context.TODO(), ovf, cmd.Options)
}
Loading

0 comments on commit 12467b0

Please sign in to comment.