1
0
mirror of https://github.com/Oxalide/vsphere-influxdb-go.git synced 2023-10-10 11:36:51 +00:00

add vendoring with go dep

This commit is contained in:
Adrian Todorov
2017-10-25 20:52:40 +00:00
parent 704f4d20d1
commit a59409f16b
1627 changed files with 489673 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
/*
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.
*/
package importx
import (
"archive/tar"
"context"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"github.com/vmware/govmomi/ovf"
)
// ArchiveFlag doesn't register any flags;
// only encapsulates some common archive related functionality.
type ArchiveFlag struct {
Archive
}
func newArchiveFlag(ctx context.Context) (*ArchiveFlag, context.Context) {
return &ArchiveFlag{}, ctx
}
func (f *ArchiveFlag) Register(ctx context.Context, fs *flag.FlagSet) {
}
func (f *ArchiveFlag) Process(ctx context.Context) error {
return nil
}
func (f *ArchiveFlag) ReadOvf(fpath string) ([]byte, error) {
r, _, err := f.Archive.Open(fpath)
if err != nil {
return nil, err
}
defer r.Close()
return ioutil.ReadAll(r)
}
func (f *ArchiveFlag) ReadEnvelope(fpath string) (*ovf.Envelope, error) {
if fpath == "" {
return &ovf.Envelope{}, nil
}
r, _, err := f.Open(fpath)
if err != nil {
return nil, err
}
defer r.Close()
e, err := ovf.Unmarshal(r)
if err != nil {
return nil, fmt.Errorf("failed to parse ovf: %s", err.Error())
}
return e, nil
}
type Archive interface {
Open(string) (io.ReadCloser, int64, error)
}
type TapeArchive struct {
path string
}
type TapeArchiveEntry struct {
io.Reader
f *os.File
}
func (t *TapeArchiveEntry) Close() error {
return t.f.Close()
}
func (t *TapeArchive) Open(name string) (io.ReadCloser, int64, error) {
f, err := os.Open(t.path)
if err != nil {
return nil, 0, err
}
r := tar.NewReader(f)
for {
h, err := r.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, 0, err
}
matched, err := path.Match(name, path.Base(h.Name))
if err != nil {
return nil, 0, err
}
if matched {
return &TapeArchiveEntry{r, f}, h.Size, nil
}
}
_ = f.Close()
return nil, 0, os.ErrNotExist
}
type FileArchive struct {
path string
}
func (t *FileArchive) Open(name string) (io.ReadCloser, int64, error) {
fpath := name
if name != t.path {
fpath = filepath.Join(filepath.Dir(t.path), name)
}
s, err := os.Stat(fpath)
if err != nil {
return nil, 0, err
}
f, err := os.Open(fpath)
if err != nil {
return nil, 0, err
}
return f, s.Size(), nil
}

View File

@@ -0,0 +1,91 @@
/*
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.
*/
package importx
import (
"context"
"errors"
"flag"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
)
type FolderFlag struct {
*flags.DatacenterFlag
folder string
}
func newFolderFlag(ctx context.Context) (*FolderFlag, context.Context) {
f := &FolderFlag{}
f.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
return f, ctx
}
func (flag *FolderFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.DatacenterFlag.Register(ctx, f)
f.StringVar(&flag.folder, "folder", "", "Path to folder to add the VM to")
}
func (flag *FolderFlag) Process(ctx context.Context) error {
return flag.DatacenterFlag.Process(ctx)
}
func (flag *FolderFlag) Folder() (*object.Folder, error) {
ctx := context.TODO()
if len(flag.folder) == 0 {
dc, err := flag.Datacenter()
if err != nil {
return nil, err
}
folders, err := dc.Folders(ctx)
if err != nil {
return nil, err
}
return folders.VmFolder, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
mo, err := finder.ManagedObjectList(ctx, flag.folder)
if err != nil {
return nil, err
}
if len(mo) == 0 {
return nil, errors.New("folder argument does not resolve to object")
}
if len(mo) > 1 {
return nil, errors.New("folder argument resolves to more than one object")
}
ref := mo[0].Object.Reference()
if ref.Type != "Folder" {
return nil, errors.New("folder argument does not resolve to folder")
}
c, err := flag.Client()
if err != nil {
return nil, err
}
return object.NewFolder(c, ref), nil
}

View File

@@ -0,0 +1,59 @@
/*
Copyright (c) 2014 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.
*/
package importx
import (
"fmt"
"path"
)
type importable struct {
localPath string
remotePath string
}
func (i importable) Ext() string {
return path.Ext(i.localPath)
}
func (i importable) Base() string {
return path.Base(i.localPath)
}
func (i importable) BaseClean() string {
b := i.Base()
e := i.Ext()
return b[:len(b)-len(e)]
}
func (i importable) RemoteSrcVMDK() string {
file := fmt.Sprintf("%s-src.vmdk", i.BaseClean())
return i.toRemotePath(file)
}
func (i importable) RemoteDstVMDK() string {
file := fmt.Sprintf("%s.vmdk", i.BaseClean())
return i.toRemotePath(file)
}
func (i importable) toRemotePath(p string) string {
if i.remotePath == "" {
return p
}
return path.Join(i.remotePath, p)
}

View File

@@ -0,0 +1,131 @@
/*
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.
*/
package importx
import (
"context"
"fmt"
"net/url"
"sync"
"sync/atomic"
"time"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
)
type ovfFileItem struct {
url *url.URL
item types.OvfFileItem
ch chan progress.Report
}
func (o ovfFileItem) Sink() chan<- progress.Report {
return o.ch
}
type leaseUpdater struct {
client *vim25.Client
lease *object.HttpNfcLease
pos int64 // Number of bytes
total int64 // Total number of bytes
done chan struct{} // When lease updater should stop
wg sync.WaitGroup // Track when update loop is done
}
func newLeaseUpdater(client *vim25.Client, lease *object.HttpNfcLease, items []ovfFileItem) *leaseUpdater {
l := leaseUpdater{
client: client,
lease: lease,
done: make(chan struct{}),
}
for _, item := range items {
l.total += item.item.Size
go l.waitForProgress(item)
}
// Kickstart update loop
l.wg.Add(1)
go l.run()
return &l
}
func (l *leaseUpdater) waitForProgress(item ovfFileItem) {
var pos, total int64
total = item.item.Size
for {
select {
case <-l.done:
return
case p, ok := <-item.ch:
// Return in case of error
if ok && p.Error() != nil {
return
}
if !ok {
// Last element on the channel, add to total
atomic.AddInt64(&l.pos, total-pos)
return
}
// Approximate progress in number of bytes
x := int64(float32(total) * (p.Percentage() / 100.0))
atomic.AddInt64(&l.pos, x-pos)
pos = x
}
}
}
func (l *leaseUpdater) run() {
defer l.wg.Done()
tick := time.NewTicker(2 * time.Second)
defer tick.Stop()
for {
select {
case <-l.done:
return
case <-tick.C:
// From the vim api HttpNfcLeaseProgress(percent) doc, percent ==
// "Completion status represented as an integer in the 0-100 range."
// Always report the current value of percent, as it will renew the
// lease even if the value hasn't changed or is 0.
percent := int32(float32(100*atomic.LoadInt64(&l.pos)) / float32(l.total))
err := l.lease.HttpNfcLeaseProgress(context.TODO(), percent)
if err != nil {
fmt.Printf("from lease updater: %s\n", err)
}
}
}
}
func (l *leaseUpdater) Done() {
close(l.done)
l.wg.Wait()
}

View File

@@ -0,0 +1,95 @@
/*
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.
*/
package importx
import (
"context"
"encoding/json"
"flag"
"os"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/vim25/types"
)
type Property struct {
types.KeyValue
Spec *ovf.Property `json:",omitempty"`
}
type Network struct {
Name string
Network string
}
type Options struct {
AllDeploymentOptions []string `json:",omitempty"`
Deployment string
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"`
PowerOn bool
InjectOvfEnv bool
WaitForIP bool
Name *string
}
type OptionsFlag struct {
Options Options
path string
}
func newOptionsFlag(ctx context.Context) (*OptionsFlag, context.Context) {
return &OptionsFlag{}, ctx
}
func (flag *OptionsFlag) Register(ctx context.Context, f *flag.FlagSet) {
f.StringVar(&flag.path, "options", "", "Options spec file path for VM deployment")
}
func (flag *OptionsFlag) Process(ctx context.Context) error {
if len(flag.path) == 0 {
return nil
}
var err error
in := os.Stdin
if flag.path != "-" {
in, err = os.Open(flag.path)
if err != nil {
return err
}
defer in.Close()
}
return json.NewDecoder(in).Decode(&flag.Options)
}

60
vendor/github.com/vmware/govmomi/govc/importx/ova.go generated vendored Normal file
View File

@@ -0,0 +1,60 @@
/*
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.
*/
package importx
import (
"context"
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type ova struct {
*ovfx
}
func init() {
cli.Register("import.ova", &ova{&ovfx{}})
}
func (cmd *ova) Usage() string {
return "PATH_TO_OVA"
}
func (cmd *ova) Run(ctx context.Context, f *flag.FlagSet) error {
fpath, err := cmd.Prepare(f)
if err != nil {
return err
}
cmd.Archive = &TapeArchive{fpath}
moref, err := cmd.Import(fpath)
if err != nil {
return err
}
vm := object.NewVirtualMachine(cmd.Client, *moref)
return cmd.Deploy(vm)
}
func (cmd *ova) Import(fpath string) (*types.ManagedObjectReference, error) {
ovf := "*.ovf"
return cmd.ovfx.Import(ovf)
}

452
vendor/github.com/vmware/govmomi/govc/importx/ovf.go generated vendored Normal file
View File

@@ -0,0 +1,452 @@
/*
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.
*/
package importx
import (
"context"
"errors"
"flag"
"fmt"
"path"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type ovfx struct {
*flags.DatastoreFlag
*flags.HostSystemFlag
*flags.OutputFlag
*flags.ResourcePoolFlag
*ArchiveFlag
*OptionsFlag
*FolderFlag
Name string
Client *vim25.Client
Datacenter *object.Datacenter
Datastore *object.Datastore
ResourcePool *object.ResourcePool
}
func init() {
cli.Register("import.ovf", &ovfx{})
}
func (cmd *ovfx) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
cmd.ResourcePoolFlag.Register(ctx, f)
cmd.ArchiveFlag, ctx = newArchiveFlag(ctx)
cmd.ArchiveFlag.Register(ctx, f)
cmd.OptionsFlag, ctx = newOptionsFlag(ctx)
cmd.OptionsFlag.Register(ctx, f)
cmd.FolderFlag, ctx = newFolderFlag(ctx)
cmd.FolderFlag.Register(ctx, f)
f.StringVar(&cmd.Name, "name", "", "Name to use for new entity")
}
func (cmd *ovfx) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
if err := cmd.ResourcePoolFlag.Process(ctx); err != nil {
return err
}
if err := cmd.ArchiveFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OptionsFlag.Process(ctx); err != nil {
return err
}
if err := cmd.FolderFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *ovfx) Usage() string {
return "PATH_TO_OVF"
}
func (cmd *ovfx) Run(ctx context.Context, f *flag.FlagSet) error {
fpath, err := cmd.Prepare(f)
if err != nil {
return err
}
cmd.Archive = &FileArchive{fpath}
moref, err := cmd.Import(fpath)
if err != nil {
return err
}
vm := object.NewVirtualMachine(cmd.Client, *moref)
return cmd.Deploy(vm)
}
func (cmd *ovfx) Prepare(f *flag.FlagSet) (string, error) {
var err error
args := f.Args()
if len(args) != 1 {
return "", errors.New("no file specified")
}
cmd.Client, err = cmd.DatastoreFlag.Client()
if err != nil {
return "", err
}
cmd.Datacenter, err = cmd.DatastoreFlag.Datacenter()
if err != nil {
return "", err
}
cmd.Datastore, err = cmd.DatastoreFlag.Datastore()
if err != nil {
return "", err
}
cmd.ResourcePool, err = cmd.ResourcePoolFlag.ResourcePool()
if err != nil {
return "", err
}
return f.Arg(0), nil
}
func (cmd *ovfx) Deploy(vm *object.VirtualMachine) error {
if err := cmd.InjectOvfEnv(vm); err != nil {
return err
}
if err := cmd.PowerOn(vm); err != nil {
return err
}
if err := cmd.WaitForIP(vm); err != nil {
return err
}
return nil
}
func (cmd *ovfx) Map(op []Property) (p []types.KeyValue) {
for _, v := range op {
p = append(p, v.KeyValue)
}
return
}
func (cmd *ovfx) NetworkMap(e *ovf.Envelope) (p []types.OvfNetworkMapping) {
ctx := context.TODO()
finder, err := cmd.DatastoreFlag.Finder()
if err != nil {
return
}
networks := map[string]string{}
if e.Network != nil {
for _, net := range e.Network.Networks {
networks[net.Name] = net.Name
}
}
for _, net := range cmd.Options.NetworkMapping {
networks[net.Name] = net.Network
}
for src, dst := range networks {
if net, err := finder.Network(ctx, dst); err == nil {
p = append(p, types.OvfNetworkMapping{
Name: src,
Network: net.Reference(),
})
}
}
return
}
func (cmd *ovfx) Import(fpath string) (*types.ManagedObjectReference, error) {
ctx := context.TODO()
o, err := cmd.ReadOvf(fpath)
if err != nil {
return nil, err
}
e, err := cmd.ReadEnvelope(fpath)
if err != nil {
return nil, fmt.Errorf("failed to parse ovf: %s", err.Error())
}
name := "Govc Virtual Appliance"
if e.VirtualSystem != nil {
name = e.VirtualSystem.ID
if e.VirtualSystem.Name != nil {
name = *e.VirtualSystem.Name
}
}
// Override name from options if specified
if cmd.Options.Name != nil {
name = *cmd.Options.Name
}
// Override name from arguments if specified
if cmd.Name != "" {
name = cmd.Name
}
cisp := types.OvfCreateImportSpecParams{
DiskProvisioning: cmd.Options.DiskProvisioning,
EntityName: name,
IpAllocationPolicy: cmd.Options.IPAllocationPolicy,
IpProtocol: cmd.Options.IPProtocol,
OvfManagerCommonParams: types.OvfManagerCommonParams{
DeploymentOption: cmd.Options.Deployment,
Locale: "US"},
PropertyMapping: cmd.Map(cmd.Options.PropertyMapping),
NetworkMapping: cmd.NetworkMap(e),
}
m := object.NewOvfManager(cmd.Client)
spec, err := m.CreateImportSpec(ctx, string(o), cmd.ResourcePool, cmd.Datastore, cisp)
if err != nil {
return nil, err
}
if spec.Error != nil {
return nil, errors.New(spec.Error[0].LocalizedMessage)
}
if spec.Warning != nil {
for _, w := range spec.Warning {
_, _ = cmd.Log(fmt.Sprintf("Warning: %s\n", w.LocalizedMessage))
}
}
if cmd.Options.Annotation != "" {
switch s := spec.ImportSpec.(type) {
case *types.VirtualMachineImportSpec:
s.ConfigSpec.Annotation = cmd.Options.Annotation
case *types.VirtualAppImportSpec:
s.VAppConfigSpec.Annotation = cmd.Options.Annotation
}
}
var host *object.HostSystem
if cmd.SearchFlag.IsSet() {
if host, err = cmd.HostSystem(); err != nil {
return nil, err
}
}
folder, err := cmd.Folder()
if err != nil {
return nil, err
}
lease, err := cmd.ResourcePool.ImportVApp(ctx, spec.ImportSpec, folder, host)
if err != nil {
return nil, err
}
info, err := lease.Wait(ctx)
if err != nil {
return nil, err
}
// Build slice of items and URLs first, so that the lease updater can know
// about every item that needs to be uploaded, and thereby infer progress.
var items []ovfFileItem
for _, device := range info.DeviceUrl {
for _, item := range spec.FileItem {
if device.ImportKey != item.DeviceId {
continue
}
u, err := cmd.Client.ParseURL(device.Url)
if err != nil {
return nil, err
}
i := ovfFileItem{
url: u,
item: item,
ch: make(chan progress.Report),
}
items = append(items, i)
}
}
u := newLeaseUpdater(cmd.Client, lease, items)
defer u.Done()
for _, i := range items {
err = cmd.Upload(lease, i)
if err != nil {
return nil, err
}
}
return &info.Entity, lease.HttpNfcLeaseComplete(ctx)
}
func (cmd *ovfx) Upload(lease *object.HttpNfcLease, ofi ovfFileItem) error {
item := ofi.item
file := item.Path
f, size, err := cmd.Open(file)
if err != nil {
return err
}
defer f.Close()
logger := cmd.ProgressLogger(fmt.Sprintf("Uploading %s... ", path.Base(file)))
defer logger.Wait()
opts := soap.Upload{
ContentLength: size,
Progress: progress.Tee(ofi, logger),
}
// Non-disk files (such as .iso) use the PUT method.
// Overwrite: t header is also required in this case (ovftool does the same)
if item.Create {
opts.Method = "PUT"
opts.Headers = map[string]string{
"Overwrite": "t",
}
} else {
opts.Method = "POST"
opts.Type = "application/x-vnd.vmware-streamVmdk"
}
return cmd.Client.Client.Upload(f, ofi.url, &opts)
}
func (cmd *ovfx) PowerOn(vm *object.VirtualMachine) error {
ctx := context.TODO()
if !cmd.Options.PowerOn {
return nil
}
cmd.Log("Powering on VM...\n")
task, err := vm.PowerOn(ctx)
if err != nil {
return err
}
if _, err = task.WaitForResult(ctx, nil); err != nil {
return err
}
return nil
}
func (cmd *ovfx) InjectOvfEnv(vm *object.VirtualMachine) error {
if !cmd.Options.InjectOvfEnv {
return nil
}
cmd.Log("Injecting OVF environment...\n")
var opts []types.BaseOptionValue
a := cmd.Client.ServiceContent.About
// build up Environment in order to marshal to xml
var props []ovf.EnvProperty
for _, p := range cmd.Options.PropertyMapping {
props = append(props, ovf.EnvProperty{
Key: p.Key,
Value: p.Value,
})
}
env := ovf.Env{
EsxID: vm.Reference().Value,
Platform: &ovf.PlatformSection{
Kind: a.Name,
Version: a.Version,
Vendor: a.Vendor,
Locale: "US",
},
Property: &ovf.PropertySection{
Properties: props,
},
}
opts = append(opts, &types.OptionValue{
Key: "guestinfo.ovfEnv",
Value: env.MarshalManual(),
})
ctx := context.Background()
task, err := vm.Reconfigure(ctx, types.VirtualMachineConfigSpec{
ExtraConfig: opts,
})
if err != nil {
return err
}
return task.Wait(ctx)
}
func (cmd *ovfx) WaitForIP(vm *object.VirtualMachine) error {
ctx := context.TODO()
if !cmd.Options.PowerOn || !cmd.Options.WaitForIP {
return nil
}
cmd.Log("Waiting for IP address...\n")
ip, err := vm.WaitForIP(ctx)
if err != nil {
return err
}
cmd.Log(fmt.Sprintf("Received IP address: %s\n", ip))
return nil
}

184
vendor/github.com/vmware/govmomi/govc/importx/spec.go generated vendored Normal file
View File

@@ -0,0 +1,184 @@
/*
Copyright (c) 2015-2016 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.
*/
package importx
import (
"context"
"encoding/json"
"flag"
"fmt"
"path"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/vim25/types"
)
var (
// all possible ovf property values
// the first element being the default value
allDeploymentOptions = []string{"small", "medium", "large"}
allDiskProvisioningOptions = []string{"thin", "monolithicSparse", "monolithicFlat", "twoGbMaxExtentSparse", "twoGbMaxExtentFlat", "seSparse", "eagerZeroedThick", "thick", "sparse", "flat"}
allIPAllocationPolicyOptions = []string{"dhcpPolicy", "transientPolicy", "fixedPolicy", "fixedAllocatedPolicy"}
allIPProtocolOptions = []string{"IPv4", "IPv6"}
)
type spec struct {
*ArchiveFlag
verbose bool
}
func init() {
cli.Register("import.spec", &spec{})
}
func (cmd *spec) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ArchiveFlag, ctx = newArchiveFlag(ctx)
cmd.ArchiveFlag.Register(ctx, f)
f.BoolVar(&cmd.verbose, "verbose", false, "Verbose spec output")
}
func (cmd *spec) Process(ctx context.Context) error {
if err := cmd.ArchiveFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *spec) Usage() string {
return "PATH_TO_OVF_OR_OVA"
}
func (cmd *spec) Run(ctx context.Context, f *flag.FlagSet) error {
fpath := ""
args := f.Args()
if len(args) == 1 {
fpath = f.Arg(0)
}
if len(fpath) > 0 {
switch path.Ext(fpath) {
case ".ovf":
cmd.Archive = &FileArchive{fpath}
case "", ".ova":
cmd.Archive = &TapeArchive{fpath}
fpath = "*.ovf"
default:
return fmt.Errorf("invalid file extension %s", path.Ext(fpath))
}
}
return cmd.Spec(fpath)
}
func (cmd *spec) Map(e *ovf.Envelope) (res []Property) {
if e == nil || e.VirtualSystem == nil {
return nil
}
for _, p := range e.VirtualSystem.Product {
for i, v := range p.Property {
d := ""
if v.Default != nil {
d = *v.Default
}
// From OVF spec, section 9.5.1:
// key-value-env = [class-value "."] key-value-prod ["." instance-value]
k := v.Key
if p.Class != nil {
k = fmt.Sprintf("%s.%s", *p.Class, k)
}
if p.Instance != nil {
k = fmt.Sprintf("%s.%s", k, *p.Instance)
}
np := Property{KeyValue: types.KeyValue{Key: k, Value: d}}
if cmd.verbose {
np.Spec = &p.Property[i]
}
res = append(res, np)
}
}
return
}
func (cmd *spec) Spec(fpath string) error {
e, err := cmd.ReadEnvelope(fpath)
if err != nil {
return err
}
var deploymentOptions = allDeploymentOptions
if e.DeploymentOption != nil && e.DeploymentOption.Configuration != nil {
deploymentOptions = nil
// add default first
for _, c := range e.DeploymentOption.Configuration {
if c.Default != nil && *c.Default {
deploymentOptions = append(deploymentOptions, c.ID)
}
}
for _, c := range e.DeploymentOption.Configuration {
if c.Default == nil || !*c.Default {
deploymentOptions = append(deploymentOptions, c.ID)
}
}
}
o := Options{
Deployment: deploymentOptions[0],
DiskProvisioning: allDiskProvisioningOptions[0],
IPAllocationPolicy: allIPAllocationPolicyOptions[0],
IPProtocol: allIPProtocolOptions[0],
PowerOn: false,
WaitForIP: false,
InjectOvfEnv: false,
PropertyMapping: cmd.Map(e)}
if e.VirtualSystem != nil && e.VirtualSystem.Annotation != nil {
for _, a := range e.VirtualSystem.Annotation {
o.Annotation += a.Annotation
}
}
if e.Network != nil {
for _, net := range e.Network.Networks {
o.NetworkMapping = append(o.NetworkMapping, Network{net.Name, ""})
}
}
if cmd.verbose {
o.AllDeploymentOptions = deploymentOptions
o.AllDiskProvisioningOptions = allDiskProvisioningOptions
o.AllIPAllocationPolicyOptions = allIPAllocationPolicyOptions
o.AllIPProtocolOptions = allIPProtocolOptions
}
j, err := json.Marshal(&o)
if err != nil {
return err
}
fmt.Println(string(j))
return nil
}

504
vendor/github.com/vmware/govmomi/govc/importx/vmdk.go generated vendored Normal file
View File

@@ -0,0 +1,504 @@
/*
Copyright (c) 2014-2016 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.
*/
package importx
import (
"context"
"errors"
"flag"
"fmt"
"path"
"reflect"
"regexp"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type vmdk struct {
*flags.DatastoreFlag
*flags.ResourcePoolFlag
*flags.OutputFlag
upload bool
force bool
keep bool
Client *vim25.Client
Datacenter *object.Datacenter
Datastore *object.Datastore
ResourcePool *object.ResourcePool
}
func init() {
cli.Register("import.vmdk", &vmdk{})
cli.Alias("import.vmdk", "datastore.import")
}
func (cmd *vmdk) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
cmd.ResourcePoolFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
f.BoolVar(&cmd.upload, "upload", true, "Upload specified disk")
f.BoolVar(&cmd.force, "force", false, "Overwrite existing disk")
f.BoolVar(&cmd.keep, "keep", false, "Keep uploaded disk after import")
}
func (cmd *vmdk) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
if err := cmd.ResourcePoolFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *vmdk) Usage() string {
return "PATH_TO_VMDK [REMOTE_DIRECTORY]"
}
func (cmd *vmdk) Run(ctx context.Context, f *flag.FlagSet) error {
var err error
args := f.Args()
if len(args) < 1 {
return errors.New("no file to import")
}
file := importable{
localPath: f.Arg(0),
}
// Include remote path if specified
if len(args) >= 2 {
file.remotePath = f.Arg(1)
}
cmd.Client, err = cmd.DatastoreFlag.Client()
if err != nil {
return err
}
cmd.Datacenter, err = cmd.DatastoreFlag.Datacenter()
if err != nil {
return err
}
cmd.Datastore, err = cmd.DatastoreFlag.Datastore()
if err != nil {
return err
}
cmd.ResourcePool, err = cmd.ResourcePoolFlag.ResourcePool()
if err != nil {
return err
}
err = cmd.PrepareDestination(file)
if err != nil {
return err
}
if cmd.upload {
err = cmd.Upload(file)
if err != nil {
return err
}
}
return cmd.Import(file)
}
// PrepareDestination makes sure that the destination VMDK does not yet exist.
// If the force flag is passed, it removes the existing VMDK. This functions
// exists to give a meaningful error if the remote VMDK already exists.
//
// CopyVirtualDisk can return a "<src> file does not exist" error while in fact
// the source file *does* exist and the *destination* file also exist.
//
func (cmd *vmdk) PrepareDestination(i importable) error {
ctx := context.TODO()
vmdkPath := i.RemoteDstVMDK()
res, err := cmd.Datastore.Stat(ctx, vmdkPath)
if err != nil {
switch err.(type) {
case object.DatastoreNoSuchDirectoryError:
// The base path doesn't exist. Create it.
dsPath := cmd.Datastore.Path(path.Dir(vmdkPath))
m := object.NewFileManager(cmd.Client)
return m.MakeDirectory(ctx, dsPath, cmd.Datacenter, true)
case object.DatastoreNoSuchFileError:
// Destination path doesn't exist; all good to continue with import.
return nil
}
return err
}
// Check that the returned entry has the right type.
switch res.(type) {
case *types.VmDiskFileInfo:
default:
expected := "VmDiskFileInfo"
actual := reflect.TypeOf(res)
panic(fmt.Sprintf("Expected: %s, actual: %s", expected, actual))
}
if !cmd.force {
dsPath := cmd.Datastore.Path(vmdkPath)
err = fmt.Errorf("File %s already exists", dsPath)
return err
}
// Delete existing disk.
err = cmd.DeleteDisk(vmdkPath)
if err != nil {
return err
}
return nil
}
func (cmd *vmdk) Upload(i importable) error {
ctx := context.TODO()
p := soap.DefaultUpload
if cmd.OutputFlag.TTY {
logger := cmd.ProgressLogger("Uploading... ")
p.Progress = logger
defer logger.Wait()
}
return cmd.Datastore.UploadFile(ctx, i.localPath, i.RemoteSrcVMDK(), &p)
}
func (cmd *vmdk) Import(i importable) error {
err := cmd.Copy(i)
if err != nil {
return err
}
if !cmd.keep {
err = cmd.DeleteDisk(i.RemoteSrcVMDK())
if err != nil {
return err
}
}
return nil
}
func (cmd *vmdk) Copy(i importable) error {
var err error
logger := cmd.ProgressLogger("Importing... ")
defer logger.Wait()
agg := progress.NewAggregator(logger)
defer agg.Done()
switch p := cmd.Client.ServiceContent.About.ApiType; p {
case "HostAgent":
err = cmd.CopyHostAgent(i, agg)
case "VirtualCenter":
err = cmd.CopyVirtualCenter(i, agg)
default:
return fmt.Errorf("unsupported ApiType: %s", p)
}
return err
}
func (cmd *vmdk) CopyHostAgent(i importable, s progress.Sinker) error {
ctx := context.TODO()
spec := &types.VirtualDiskSpec{
AdapterType: "lsiLogic",
DiskType: "thin",
}
dc := cmd.Datacenter
src := cmd.Datastore.Path(i.RemoteSrcVMDK())
dst := cmd.Datastore.Path(i.RemoteDstVMDK())
vdm := object.NewVirtualDiskManager(cmd.Client)
task, err := vdm.CopyVirtualDisk(ctx, src, dc, dst, dc, spec, false)
if err != nil {
return err
}
ps := progress.Prefix(s, "copying disk")
_, err = task.WaitForResult(ctx, ps)
if err != nil {
return err
}
return nil
}
func (cmd *vmdk) CopyVirtualCenter(i importable, s progress.Sinker) error {
var err error
srcName := i.BaseClean() + "-srcvm"
dstName := i.BaseClean() + "-dstvm"
spec := &configSpec{
Name: srcName,
GuestId: "otherGuest",
Files: &types.VirtualMachineFileInfo{
VmPathName: fmt.Sprintf("[%s]", cmd.Datastore.Name()),
},
}
spec.AddDisk(cmd.Datastore, i.RemoteSrcVMDK())
src, err := cmd.CreateVM(spec)
if err != nil {
return err
}
dst, err := cmd.CloneVM(src, dstName)
if err != nil {
return err
}
err = cmd.DestroyVM(src)
if err != nil {
return err
}
vmdk, err := cmd.DetachDisk(dst)
if err != nil {
return err
}
err = cmd.MoveDisk(vmdk, i.RemoteDstVMDK())
if err != nil {
return err
}
err = cmd.DestroyVM(dst)
if err != nil {
return err
}
return nil
}
func (cmd *vmdk) MoveDisk(src, dst string) error {
ctx := context.TODO()
dsSrc := cmd.Datastore.Path(src)
dsDst := cmd.Datastore.Path(dst)
vdm := object.NewVirtualDiskManager(cmd.Client)
task, err := vdm.MoveVirtualDisk(ctx, dsSrc, cmd.Datacenter, dsDst, cmd.Datacenter, true)
if err != nil {
return err
}
return task.Wait(ctx)
}
func (cmd *vmdk) DeleteDisk(path string) error {
ctx := context.TODO()
vdm := object.NewVirtualDiskManager(cmd.Client)
task, err := vdm.DeleteVirtualDisk(ctx, cmd.Datastore.Path(path), cmd.Datacenter)
if err != nil {
return err
}
return task.Wait(ctx)
}
func (cmd *vmdk) DetachDisk(vm *object.VirtualMachine) (string, error) {
ctx := context.TODO()
var mvm mo.VirtualMachine
pc := property.DefaultCollector(cmd.Client)
err := pc.RetrieveOne(ctx, vm.Reference(), []string{"config.hardware"}, &mvm)
if err != nil {
return "", err
}
spec := new(configSpec)
dsFile := spec.RemoveDisk(&mvm)
task, err := vm.Reconfigure(ctx, spec.ToSpec())
if err != nil {
return "", err
}
err = task.Wait(ctx)
if err != nil {
return "", err
}
return dsFile, nil
}
func (cmd *vmdk) CreateVM(spec *configSpec) (*object.VirtualMachine, error) {
ctx := context.TODO()
folders, err := cmd.Datacenter.Folders(ctx)
if err != nil {
return nil, err
}
task, err := folders.VmFolder.CreateVM(ctx, spec.ToSpec(), cmd.ResourcePool, nil)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(ctx, nil)
if err != nil {
return nil, err
}
return object.NewVirtualMachine(cmd.Client, info.Result.(types.ManagedObjectReference)), nil
}
func (cmd *vmdk) CloneVM(vm *object.VirtualMachine, name string) (*object.VirtualMachine, error) {
ctx := context.TODO()
folders, err := cmd.Datacenter.Folders(ctx)
if err != nil {
return nil, err
}
spec := types.VirtualMachineCloneSpec{
Config: &types.VirtualMachineConfigSpec{},
Location: types.VirtualMachineRelocateSpec{},
}
task, err := vm.Clone(ctx, folders.VmFolder, name, spec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(ctx, nil)
if err != nil {
return nil, err
}
return object.NewVirtualMachine(cmd.Client, info.Result.(types.ManagedObjectReference)), nil
}
func (cmd *vmdk) DestroyVM(vm *object.VirtualMachine) error {
ctx := context.TODO()
_, err := cmd.DetachDisk(vm)
if err != nil {
return err
}
task, err := vm.Destroy(ctx)
if err != nil {
return err
}
err = task.Wait(ctx)
if err != nil {
return err
}
return nil
}
type configSpec types.VirtualMachineConfigSpec
func (c *configSpec) ToSpec() types.VirtualMachineConfigSpec {
return types.VirtualMachineConfigSpec(*c)
}
func (c *configSpec) AddChange(d types.BaseVirtualDeviceConfigSpec) {
c.DeviceChange = append(c.DeviceChange, d)
}
func (c *configSpec) AddDisk(ds *object.Datastore, path string) {
var devices object.VirtualDeviceList
controller, err := devices.CreateSCSIController("")
if err != nil {
panic(err)
}
devices = append(devices, controller)
disk := devices.CreateDisk(controller.(types.BaseVirtualController), ds.Reference(), ds.Path(path))
devices = append(devices, disk)
spec, err := devices.ConfigSpec(types.VirtualDeviceConfigSpecOperationAdd)
if err != nil {
panic(err)
}
c.DeviceChange = append(c.DeviceChange, spec...)
}
var dsPathRegexp = regexp.MustCompile(`^\[.*\] (.*)$`)
func (c *configSpec) RemoveDisk(vm *mo.VirtualMachine) string {
var file string
for _, d := range vm.Config.Hardware.Device {
switch device := d.(type) {
case *types.VirtualDisk:
if file != "" {
panic("expected VM to have only one disk")
}
switch backing := device.Backing.(type) {
case *types.VirtualDiskFlatVer1BackingInfo:
file = backing.FileName
case *types.VirtualDiskFlatVer2BackingInfo:
file = backing.FileName
case *types.VirtualDiskSeSparseBackingInfo:
file = backing.FileName
case *types.VirtualDiskSparseVer1BackingInfo:
file = backing.FileName
case *types.VirtualDiskSparseVer2BackingInfo:
file = backing.FileName
default:
name := reflect.TypeOf(device.Backing).String()
panic(fmt.Sprintf("unexpected backing type: %s", name))
}
// Remove [datastore] prefix
m := dsPathRegexp.FindStringSubmatch(file)
if len(m) != 2 {
panic(fmt.Sprintf("expected regexp match for %#v", file))
}
file = m[1]
removeOp := &types.VirtualDeviceConfigSpec{
Operation: types.VirtualDeviceConfigSpecOperationRemove,
Device: device,
}
c.AddChange(removeOp)
}
}
return file
}