mirror of https://github.com/docker/docs.git
[vmwarevsphere] Start using govmomi provided helpers
Also update govmomi to latest revision and call Logout method when needed Signed-off-by: S.Çağlar Onur <conur@vmware.com>
This commit is contained in:
parent
7f708edcec
commit
0aedfd201d
|
@ -234,8 +234,8 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi",
|
||||
"Comment": "prerelease-v0.1.0-73-gfc131d4-65-g482cd82",
|
||||
"Rev": "482cd823716e0fa9bc4e186d262a6ea23d940fbf"
|
||||
"Comment": "v0.3.0-11-g20c009c",
|
||||
"Rev": "20c009ce9c493f0c714a9fffa5bda5fb84df2b6c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/go-units",
|
||||
|
|
|
@ -225,6 +225,7 @@ func (d *Driver) GetIP() (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
vm, err := d.fetchVM(c, ctx, d.MachineName)
|
||||
if err != nil {
|
||||
|
@ -250,6 +251,7 @@ func (d *Driver) GetState() (state.State, error) {
|
|||
if err != nil {
|
||||
return state.None, err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
vm, err := d.fetchVM(c, ctx, d.MachineName)
|
||||
if err != nil {
|
||||
|
@ -284,26 +286,27 @@ func (d *Driver) PreCreateCheck() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
// Create a new finder
|
||||
f := find.NewFinder(c.Client, true)
|
||||
|
||||
dc, err := d.getDatacenter(f, ctx)
|
||||
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.SetDatacenter(dc)
|
||||
|
||||
if _, err := d.getDatastore(f, ctx); err != nil {
|
||||
if _, err := f.DatastoreOrDefault(ctx, d.Datastore); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := d.getNetwork(f, ctx); err != nil {
|
||||
if _, err := f.NetworkOrDefault(ctx, d.Network); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hs, err := d.getHostSystem(f, ctx)
|
||||
hs, err := f.HostSystemOrDefault(ctx, d.HostSystem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -348,27 +351,29 @@ func (d *Driver) Create() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
// Create a new finder
|
||||
f := find.NewFinder(c.Client, true)
|
||||
|
||||
dc, err := d.getDatacenter(f, ctx)
|
||||
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.SetDatacenter(dc)
|
||||
|
||||
dss, err := d.getDatastore(f, ctx)
|
||||
dss, err := f.DatastoreOrDefault(ctx, d.Datastore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
net, err := d.getNetwork(f, ctx)
|
||||
net, err := f.NetworkOrDefault(ctx, d.Network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hs, err := d.getHostSystem(f, ctx)
|
||||
hs, err := f.HostSystemOrDefault(ctx, d.HostSystem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -558,6 +563,7 @@ func (d *Driver) Start() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
vm, err := d.fetchVM(c, ctx, d.MachineName)
|
||||
if err != nil {
|
||||
|
@ -590,6 +596,7 @@ func (d *Driver) Stop() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
vm, err := d.fetchVM(c, ctx, d.MachineName)
|
||||
if err != nil {
|
||||
|
@ -645,6 +652,7 @@ func (d *Driver) Kill() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
vm, err := d.fetchVM(c, ctx, d.MachineName)
|
||||
if err != nil {
|
||||
|
@ -683,18 +691,19 @@ func (d *Driver) Remove() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
|
||||
// Create a new finder
|
||||
f := find.NewFinder(c.Client, true)
|
||||
|
||||
dc, err := d.getDatacenter(f, ctx)
|
||||
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.SetDatacenter(dc)
|
||||
|
||||
dss, err := d.getDatastore(f, ctx)
|
||||
dss, err := f.DatastoreOrDefault(ctx, d.Datastore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -821,7 +830,7 @@ func (d *Driver) fetchVM(c *govmomi.Client, ctx context.Context, vmname string)
|
|||
var vm *object.VirtualMachine
|
||||
var err error
|
||||
|
||||
dc, err := d.getDatacenter(f, ctx)
|
||||
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
|
||||
if err != nil {
|
||||
return vm, err
|
||||
}
|
||||
|
@ -856,83 +865,3 @@ func (f *FileAttrFlag) SetPerms(owner, group, perms int) {
|
|||
func (f *FileAttrFlag) Attr() types.BaseGuestFileAttributes {
|
||||
return &f.GuestPosixFileAttributes
|
||||
}
|
||||
|
||||
func (d *Driver) getDatacenter(f *find.Finder, ctx context.Context) (dc *object.Datacenter, err error) {
|
||||
|
||||
// Datacenter
|
||||
if d.Datacenter != "" {
|
||||
// Find specified Datacenter
|
||||
dc, err = f.Datacenter(ctx, d.Datacenter)
|
||||
if err != nil {
|
||||
return dc, err
|
||||
}
|
||||
} else {
|
||||
// Use default Datacenter
|
||||
dc, err = f.DefaultDatacenter(ctx)
|
||||
if err != nil {
|
||||
return dc, err
|
||||
}
|
||||
}
|
||||
log.Debug("Datacenter found: ", dc)
|
||||
return dc, nil
|
||||
}
|
||||
|
||||
func (d *Driver) getDatastore(f *find.Finder, ctx context.Context) (dss *object.Datastore, err error) {
|
||||
|
||||
// Datastore
|
||||
if d.Datastore != "" {
|
||||
// Find specified Datastore
|
||||
dss, err = f.Datastore(ctx, d.Datastore)
|
||||
if err != nil {
|
||||
return dss, err
|
||||
}
|
||||
} else {
|
||||
// Find default Datastore
|
||||
dss, err = f.DefaultDatastore(ctx)
|
||||
if err != nil {
|
||||
return dss, err
|
||||
}
|
||||
}
|
||||
log.Debug("Datastore found: ", dss)
|
||||
return dss, err
|
||||
}
|
||||
|
||||
func (d *Driver) getNetwork(f *find.Finder, ctx context.Context) (net object.NetworkReference, err error) {
|
||||
|
||||
// Network
|
||||
if d.Network != "" {
|
||||
// Find specified Network
|
||||
net, err = f.Network(ctx, d.Network)
|
||||
if err != nil {
|
||||
return net, err
|
||||
}
|
||||
} else {
|
||||
// Find default Network
|
||||
net, err = f.DefaultNetwork(ctx)
|
||||
if err != nil {
|
||||
return net, err
|
||||
}
|
||||
}
|
||||
log.Debug("Network found: ", net)
|
||||
return net, nil
|
||||
|
||||
}
|
||||
|
||||
func (d *Driver) getHostSystem(f *find.Finder, ctx context.Context) (hs *object.HostSystem, err error) {
|
||||
// HostSystem
|
||||
if d.HostSystem != "" {
|
||||
// Find specified HostSystem
|
||||
hs, err = f.HostSystem(ctx, d.HostSystem)
|
||||
if err != nil {
|
||||
return hs, err
|
||||
}
|
||||
} else {
|
||||
// Find default HostSystem
|
||||
hs, err = f.DefaultHostSystem(ctx)
|
||||
if err != nil {
|
||||
return hs, err
|
||||
}
|
||||
}
|
||||
log.Debug("HostSystem found: ", hs)
|
||||
return hs, nil
|
||||
}
|
||||
|
|
|
@ -1,9 +1,35 @@
|
|||
# changelog
|
||||
|
||||
### (unreleased)
|
||||
### 0.3.0 (2016-01-16)
|
||||
|
||||
* Add object.VirtualNicManager wrapper
|
||||
|
||||
* Add object.HostVsanSystem wrapper
|
||||
|
||||
* Add object.HostSystem methods: EnterMaintenanceMode, ExitMaintenanceMode, Disconnect, Reconnect
|
||||
|
||||
* Add finder.Folder method
|
||||
|
||||
* Add object.Common.Destroy method
|
||||
|
||||
* Add object.ComputeResource.Reconfigure method
|
||||
|
||||
* Add license.AssignmentManager wrapper
|
||||
|
||||
* Add object.HostFirewallSystem wrapper
|
||||
|
||||
* Add object.DiagnosticManager wrapper
|
||||
|
||||
* Add LoginExtensionByCertificate support
|
||||
|
||||
* Add object.ExtensionManager
|
||||
|
||||
...
|
||||
|
||||
### 0.2.0 (2015-09-15)
|
||||
|
||||
* Update to vim25/6.0 API
|
||||
|
||||
* Stop returning children from `ManagedObjectList`
|
||||
|
||||
Change the `ManagedObjectList` function in the `find` package to only
|
||||
|
|
|
@ -4,19 +4,23 @@
|
|||
#
|
||||
|
||||
Alvaro Miranda <kikitux@gmail.com>
|
||||
Amit Bathla <abathla@vmware.com>
|
||||
Bob Killen <killen.bob@gmail.com>
|
||||
Bruce Downs <bdowns@vmware.com>
|
||||
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
|
||||
Danny Lockard <danny.lockard@banno.com>
|
||||
Doug MacEachern <dougm@vmware.com>
|
||||
Eloy Coto <eloy.coto@gmail.com>
|
||||
Eric Yutao <eric.yutao@gmail.com>
|
||||
Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
Gavin Gray <gavin@infinio.com>
|
||||
Gavrie Philipson <gavrie@philipson.co.il> <gavrie.philipson@elastifile.com>
|
||||
Louie Jiang <jiangl@vmware.com>
|
||||
Mevan Samaratunga <mevansam@gmail.com>
|
||||
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
|
||||
runner.mei <runner.mei@gmail.com>
|
||||
S.Çağlar Onur <conur@vmware.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com> <takaaki.furukawa@mail.rakuten.com>
|
||||
Yang Yang <yangy@vmware.com>
|
||||
Yuya Kusakabe <yuya.kusakabe@gmail.com>
|
||||
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
|
||||
|
|
|
@ -8,7 +8,7 @@ For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) director
|
|||
|
||||
## Compatibility
|
||||
|
||||
This library is built for and tested against ESXi and vCenter 5.5.
|
||||
This library is built for and tested against ESXi and vCenter 5.5 and 6.0.
|
||||
|
||||
If you're able to use it against older versions of ESXi and/or vCenter, please
|
||||
leave a note and we'll include it in this compatibility list.
|
||||
|
@ -22,7 +22,7 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr
|
|||
It primarily provides convenience functions for working with the vSphere API.
|
||||
See [godoc.org][godoc] for documentation.
|
||||
|
||||
[apiref]:http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
|
||||
[apiref]:http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
|
||||
[godoc]:http://godoc.org/github.com/vmware/govmomi
|
||||
|
||||
## Status
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -57,6 +57,7 @@ are kept outside the object package.
|
|||
package govmomi
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/url"
|
||||
|
||||
"github.com/vmware/govmomi/property"
|
||||
|
@ -74,7 +75,7 @@ type Client struct {
|
|||
}
|
||||
|
||||
// NewClient creates a new client from a URL. The client authenticates with the
|
||||
// server before returning if the URL contains user information.
|
||||
// server with username/password before returning if the URL contains user information.
|
||||
func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error) {
|
||||
soapClient := soap.NewClient(u, insecure)
|
||||
vimClient, err := vim25.NewClient(ctx, soapClient)
|
||||
|
@ -98,11 +99,41 @@ func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error)
|
|||
return c, nil
|
||||
}
|
||||
|
||||
// NewClientWithCertificate creates a new client from a URL. The client authenticates with the
|
||||
// server with the certificate before returning if the URL contains user information.
|
||||
func NewClientWithCertificate(ctx context.Context, u *url.URL, insecure bool, cert tls.Certificate) (*Client, error) {
|
||||
soapClient := soap.NewClient(u, insecure)
|
||||
soapClient.SetCertificate(cert)
|
||||
vimClient, err := vim25.NewClient(ctx, soapClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Client{
|
||||
Client: vimClient,
|
||||
SessionManager: session.NewManager(vimClient),
|
||||
}
|
||||
|
||||
if u.User != nil {
|
||||
err = c.LoginExtensionByCertificate(ctx, u.User.Username(), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Login dispatches to the SessionManager.
|
||||
func (c *Client) Login(ctx context.Context, u *url.Userinfo) error {
|
||||
return c.SessionManager.Login(ctx, u)
|
||||
}
|
||||
|
||||
// Login dispatches to the SessionManager.
|
||||
func (c *Client) LoginExtensionByCertificate(ctx context.Context, key string, locale string) error {
|
||||
return c.SessionManager.LoginExtensionByCertificate(ctx, key, locale)
|
||||
}
|
||||
|
||||
// Logout dispatches to the SessionManager.
|
||||
func (c *Client) Logout(ctx context.Context) error {
|
||||
// Close any idle connections after logging out.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -43,6 +43,7 @@ func NewManager(c *vim25.Client) *Manager {
|
|||
|
||||
c: c,
|
||||
|
||||
eventCategory: make(map[string]string),
|
||||
eventCategoryMu: new(sync.Mutex),
|
||||
}
|
||||
|
||||
|
@ -125,7 +126,7 @@ func (m Manager) eventCategoryMap(ctx context.Context) (map[string]string, error
|
|||
m.eventCategoryMu.Lock()
|
||||
defer m.eventCategoryMu.Unlock()
|
||||
|
||||
if m.eventCategory != nil {
|
||||
if len(m.eventCategory) != 0 {
|
||||
return m.eventCategory, nil
|
||||
}
|
||||
|
||||
|
@ -137,8 +138,6 @@ func (m Manager) eventCategoryMap(ctx context.Context) (map[string]string, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
m.eventCategory = make(map[string]string, len(o.Description.EventInfo))
|
||||
|
||||
for _, info := range o.Description.EventInfo {
|
||||
m.eventCategory[info.Key] = info.Category
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -243,6 +243,18 @@ func (f *Finder) DefaultDatacenter(ctx context.Context) (*object.Datacenter, err
|
|||
return dc, nil
|
||||
}
|
||||
|
||||
func (f *Finder) DatacenterOrDefault(ctx context.Context, path string) (*object.Datacenter, error) {
|
||||
if path != "" {
|
||||
dc, err := f.Datacenter(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dc, nil
|
||||
}
|
||||
|
||||
return f.DefaultDatacenter(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) DatastoreList(ctx context.Context, path string) ([]*object.Datastore, error) {
|
||||
es, err := f.find(ctx, f.datastoreFolder, false, path)
|
||||
if err != nil {
|
||||
|
@ -289,6 +301,18 @@ func (f *Finder) DefaultDatastore(ctx context.Context) (*object.Datastore, error
|
|||
return ds, nil
|
||||
}
|
||||
|
||||
func (f *Finder) DatastoreOrDefault(ctx context.Context, path string) (*object.Datastore, error) {
|
||||
if path != "" {
|
||||
ds, err := f.Datastore(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
return f.DefaultDatastore(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) ComputeResourceList(ctx context.Context, path string) ([]*object.ComputeResource, error) {
|
||||
es, err := f.find(ctx, f.hostFolder, false, path)
|
||||
if err != nil {
|
||||
|
@ -339,6 +363,18 @@ func (f *Finder) DefaultComputeResource(ctx context.Context) (*object.ComputeRes
|
|||
return cr, nil
|
||||
}
|
||||
|
||||
func (f *Finder) ComputeResourceOrDefault(ctx context.Context, path string) (*object.ComputeResource, error) {
|
||||
if path != "" {
|
||||
cr, err := f.ComputeResource(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cr, nil
|
||||
}
|
||||
|
||||
return f.DefaultComputeResource(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) ClusterComputeResourceList(ctx context.Context, path string) ([]*object.ClusterComputeResource, error) {
|
||||
es, err := f.find(ctx, f.hostFolder, false, path)
|
||||
if err != nil {
|
||||
|
@ -393,19 +429,21 @@ func (f *Finder) HostSystemList(ctx context.Context, path string) ([]*object.Hos
|
|||
switch o := e.Object.(type) {
|
||||
case mo.HostSystem:
|
||||
hs = object.NewHostSystem(f.client, o.Reference())
|
||||
case mo.ComputeResource:
|
||||
|
||||
hs.InventoryPath = e.Path
|
||||
hss = append(hss, hs)
|
||||
case mo.ComputeResource, mo.ClusterComputeResource:
|
||||
cr := object.NewComputeResource(f.client, o.Reference())
|
||||
|
||||
cr.InventoryPath = e.Path
|
||||
|
||||
hosts, err := cr.Hosts(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hs = object.NewHostSystem(f.client, hosts[0])
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
hs.InventoryPath = e.Path
|
||||
hss = append(hss, hs)
|
||||
hss = append(hss, hosts...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(hss) == 0 {
|
||||
|
@ -437,6 +475,18 @@ func (f *Finder) DefaultHostSystem(ctx context.Context) (*object.HostSystem, err
|
|||
return hs, nil
|
||||
}
|
||||
|
||||
func (f *Finder) HostSystemOrDefault(ctx context.Context, path string) (*object.HostSystem, error) {
|
||||
if path != "" {
|
||||
hs, err := f.HostSystem(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hs, nil
|
||||
}
|
||||
|
||||
return f.DefaultHostSystem(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.NetworkReference, error) {
|
||||
es, err := f.find(ctx, f.networkFolder, false, path)
|
||||
if err != nil {
|
||||
|
@ -455,6 +505,10 @@ func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.Network
|
|||
r := object.NewDistributedVirtualPortgroup(f.client, ref)
|
||||
r.InventoryPath = e.Path
|
||||
ns = append(ns, r)
|
||||
case "DistributedVirtualSwitch", "VmwareDistributedVirtualSwitch":
|
||||
r := object.NewDistributedVirtualSwitch(f.client, ref)
|
||||
r.InventoryPath = e.Path
|
||||
ns = append(ns, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,6 +541,18 @@ func (f *Finder) DefaultNetwork(ctx context.Context) (object.NetworkReference, e
|
|||
return network, nil
|
||||
}
|
||||
|
||||
func (f *Finder) NetworkOrDefault(ctx context.Context, path string) (object.NetworkReference, error) {
|
||||
if path != "" {
|
||||
network, err := f.Network(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return network, nil
|
||||
}
|
||||
|
||||
return f.DefaultNetwork(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) ResourcePoolList(ctx context.Context, path string) ([]*object.ResourcePool, error) {
|
||||
es, err := f.find(ctx, f.hostFolder, true, path)
|
||||
if err != nil {
|
||||
|
@ -534,6 +600,18 @@ func (f *Finder) DefaultResourcePool(ctx context.Context) (*object.ResourcePool,
|
|||
return rp, nil
|
||||
}
|
||||
|
||||
func (f *Finder) ResourcePoolOrDefault(ctx context.Context, path string) (*object.ResourcePool, error) {
|
||||
if path != "" {
|
||||
rp, err := f.ResourcePool(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rp, nil
|
||||
}
|
||||
|
||||
return f.DefaultResourcePool(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) VirtualMachineList(ctx context.Context, path string) ([]*object.VirtualMachine, error) {
|
||||
es, err := f.find(ctx, f.vmFolder, false, path)
|
||||
if err != nil {
|
||||
|
@ -605,3 +683,29 @@ func (f *Finder) VirtualApp(ctx context.Context, path string) (*object.VirtualAp
|
|||
|
||||
return apps[0], nil
|
||||
}
|
||||
|
||||
func (f *Finder) Folder(ctx context.Context, path string) (*object.Folder, error) {
|
||||
mo, err := f.ManagedObjectList(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(mo) == 0 {
|
||||
return nil, &NotFoundError{"folder", path}
|
||||
}
|
||||
|
||||
if len(mo) > 1 {
|
||||
return nil, &MultipleFoundError{"folder", path}
|
||||
}
|
||||
|
||||
ref := mo[0].Object.Reference()
|
||||
if ref.Type != "Folder" {
|
||||
return nil, &NotFoundError{"folder", path}
|
||||
}
|
||||
|
||||
folder := object.NewFolder(f.client, ref)
|
||||
|
||||
folder.InventoryPath = mo[0].Path
|
||||
|
||||
return folder, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
mini_portile (0.6.0)
|
||||
nokogiri (1.6.3.1)
|
||||
mini_portile (= 0.6.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
nokogiri
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
# 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.
|
||||
|
@ -738,22 +738,6 @@ class WSDL
|
|||
|
||||
def self.header(name)
|
||||
return <<EOF
|
||||
/*
|
||||
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 #{name}
|
||||
|
||||
EOF
|
||||
|
|
|
@ -2,6 +2,39 @@
|
|||
|
||||
### (unreleased)
|
||||
|
||||
* Add `-p` and `-a` options to govc datastore.ls command
|
||||
|
||||
### 0.3.0 (2016-01-16)
|
||||
|
||||
* Add permissions.{ls,set,remove} commands
|
||||
|
||||
* Add datastore.{create,remove} commands.
|
||||
The new create command supports both creating NAS and VMFS datastores.
|
||||
|
||||
* Add dvs.{create,add} and dvs.portgroup.add commands
|
||||
|
||||
* Add host.vnic.{service,info} commands
|
||||
|
||||
* Add cluster.{create,change,add} commands
|
||||
|
||||
* Add host.{disconnect,reconnect,remove,maintenance.enter,maintenance.exit} commands
|
||||
|
||||
* Add license.decode, license.assigned.list and license.assign commands
|
||||
|
||||
* Add firewall.ruleset.find command
|
||||
|
||||
* Add logs, logs.ls and logs.download commands
|
||||
|
||||
* Add support for LoginExtensionByCertificate with new `-cert` and `-key` flags
|
||||
|
||||
* Add govc extension.{info,register,unregister,setcert} commands
|
||||
|
||||
* Add govc vapp.{info,destroy,power} commands
|
||||
|
||||
### 0.2.0 (2015-09-15)
|
||||
|
||||
* The `vm.power` guest `-s` and `-r` options will fallback to hard `-off` / `-reset` if tools is unavailable and `-force` flag is given
|
||||
|
||||
* Add `PowerOn, InjectOvfEnv, WaitForIP` options to `import.ovf` and `import.ova` option spec file
|
||||
|
||||
* Add `import.spec` to produce an example json document
|
||||
|
@ -10,12 +43,22 @@
|
|||
|
||||
* Add `-folder` to `import.ovf` and `import.ova`
|
||||
|
||||
* Add `fields` command to manage custom fields
|
||||
|
||||
* Add `datastore.info` command
|
||||
|
||||
* Add `events` command
|
||||
|
||||
* Add `-net.address` (Hardware Address) option to `vm.change` and `vm.create`
|
||||
|
||||
* Add `host.add` command to add host to datacenter.
|
||||
|
||||
* Add `GOVC_USERNAME` and `GOVC_PASSWORD` to allow overriding username and/or
|
||||
password (used when they contain special characters that prevent them from
|
||||
being embedded in the URL).
|
||||
|
||||
* Add `-e' (ExtraConfig) option to `vm.change` and `vm.info`
|
||||
|
||||
* Retry twice on temporary network errors.
|
||||
|
||||
* Add `host.autostart` commands to manage VM autostart.
|
||||
|
|
|
@ -22,6 +22,8 @@ import (
|
|||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
)
|
||||
|
@ -34,11 +36,19 @@ func init() {
|
|||
cli.Register("about", &about{})
|
||||
}
|
||||
|
||||
func (cmd *about) Register(f *flag.FlagSet) {}
|
||||
func (cmd *about) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *about) Process() error { return nil }
|
||||
func (cmd *about) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *about) Run(f *flag.FlagSet) error {
|
||||
func (cmd *about) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,22 +1,32 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if ! which gox > /dev/null; then
|
||||
echo "gox is not installed..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git_version=$(git describe)
|
||||
if git_status=$(git status --porcelain 2>/dev/null) && [ -n "${git_status}" ]; then
|
||||
git_version="${git_version}-dirty"
|
||||
fi
|
||||
|
||||
ldflags="-X github.com/vmware/govmomi/govc/version.gitVersion ${git_version}"
|
||||
ldflags="-X github.com/vmware/govmomi/govc/version.gitVersion=${git_version}"
|
||||
|
||||
BUILD_OS=${BUILD_OS:-darwin linux windows freebsd}
|
||||
BUILD_ARCH=${BUILD_ARCH:-386 amd64}
|
||||
|
||||
gox \
|
||||
-parallel=1 \
|
||||
-ldflags="${ldflags}" \
|
||||
-os="${BUILD_OS}" \
|
||||
-arch="${BUILD_ARCH}" \
|
||||
github.com/vmware/govmomi/govc
|
||||
for os in ${BUILD_OS}; do
|
||||
export GOOS="${os}"
|
||||
for arch in ${BUILD_ARCH}; do
|
||||
export GOARCH="${arch}"
|
||||
|
||||
out="govc_${os}_${arch}"
|
||||
if [ "${os}" == "windows" ]; then
|
||||
out="${out}.exe"
|
||||
fi
|
||||
|
||||
set -x
|
||||
go build \
|
||||
-o="${out}" \
|
||||
-pkgdir="./_pkg" \
|
||||
-compiler='gc' \
|
||||
-ldflags="${ldflags}" \
|
||||
github.com/vmware/govmomi/govc
|
||||
set +x
|
||||
done
|
||||
done
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -21,50 +21,24 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"text/tabwriter"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type HasFlags interface {
|
||||
// Register may be called more than once and should be idempotent.
|
||||
Register(f *flag.FlagSet)
|
||||
Register(ctx context.Context, f *flag.FlagSet)
|
||||
|
||||
// Process may be called more than once and should be idempotent.
|
||||
Process() error
|
||||
Process(ctx context.Context) error
|
||||
}
|
||||
|
||||
type Command interface {
|
||||
HasFlags
|
||||
|
||||
Run(f *flag.FlagSet) error
|
||||
}
|
||||
|
||||
var hasFlagsType = reflect.TypeOf((*HasFlags)(nil)).Elem()
|
||||
|
||||
func RegisterCommand(h HasFlags, f *flag.FlagSet) {
|
||||
visited := make(map[interface{}]struct{})
|
||||
Walk(h, hasFlagsType, func(v interface{}) error {
|
||||
if _, ok := visited[v]; ok {
|
||||
return nil
|
||||
}
|
||||
visited[v] = struct{}{}
|
||||
v.(HasFlags).Register(f)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ProcessCommand(h HasFlags) error {
|
||||
visited := make(map[interface{}]struct{})
|
||||
err := Walk(h, hasFlagsType, func(v interface{}) error {
|
||||
if _, ok := visited[v]; ok {
|
||||
return nil
|
||||
}
|
||||
visited[v] = struct{}{}
|
||||
err := v.(HasFlags).Process()
|
||||
return err
|
||||
})
|
||||
return err
|
||||
Run(ctx context.Context, f *flag.FlagSet) error
|
||||
}
|
||||
|
||||
func generalHelp() {
|
||||
|
@ -117,6 +91,8 @@ func commandHelp(name string, cmd Command, f *flag.FlagSet) {
|
|||
}
|
||||
|
||||
func Run(args []string) int {
|
||||
var err error
|
||||
|
||||
if len(args) == 0 {
|
||||
generalHelp()
|
||||
return 1
|
||||
|
@ -134,37 +110,33 @@ func Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
f := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
f.SetOutput(ioutil.Discard)
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.SetOutput(ioutil.Discard)
|
||||
|
||||
RegisterCommand(cmd, f)
|
||||
ctx := context.Background()
|
||||
cmd.Register(ctx, fs)
|
||||
|
||||
if err := f.Parse(args[1:]); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
commandHelp(args[0], cmd, f)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||
}
|
||||
return 1
|
||||
if err = fs.Parse(args[1:]); err != nil {
|
||||
goto error
|
||||
}
|
||||
|
||||
if err := ProcessCommand(cmd); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
commandHelp(args[0], cmd, f)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||
}
|
||||
return 1
|
||||
if err = cmd.Process(ctx); err != nil {
|
||||
goto error
|
||||
}
|
||||
|
||||
if err := cmd.Run(f); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
commandHelp(args[0], cmd, f)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
|
||||
}
|
||||
return 1
|
||||
if err = cmd.Run(ctx, fs); err != nil {
|
||||
goto error
|
||||
}
|
||||
|
||||
return 0
|
||||
|
||||
error:
|
||||
if err == flag.ErrHelp {
|
||||
commandHelp(args[0], cmd, fs)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err)
|
||||
}
|
||||
|
||||
return 1
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
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 cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type WalkFn func(c interface{}) error
|
||||
|
||||
// Walk recursively walks struct types that implement the specified interface.
|
||||
// Fields that implement the specified interface are expected to be pointer
|
||||
// values. This allows the function to cache pointer values on a per-type
|
||||
// basis. If, during a recursive walk, the same type is encountered twice, the
|
||||
// function creates a new value of that type the first time, and reuses that
|
||||
// same value the second time.
|
||||
//
|
||||
// This function is used to make sure that a hierarchy of flags where multiple
|
||||
// structs refer to the `Client` flag will not end up with more than one
|
||||
// instance of the actual client. Rather, every struct referring to the
|
||||
// `Client` flag will have a pointer to the same underlying `Client` struct.
|
||||
//
|
||||
func Walk(c interface{}, ifaceType reflect.Type, fn WalkFn) error {
|
||||
var walker WalkFn
|
||||
|
||||
visited := make(map[reflect.Type]reflect.Value)
|
||||
walker = func(c interface{}) error {
|
||||
v := reflect.ValueOf(c)
|
||||
if v.Kind() == reflect.Interface {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
t := v.Type()
|
||||
|
||||
// Call user specified function.
|
||||
err := fn(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
ff := t.Field(i)
|
||||
ft := ff.Type
|
||||
fv := v.Field(i)
|
||||
|
||||
// Check that a pointer to this field's type doesn't implement the
|
||||
// specified interface. If it does, this field references the type as
|
||||
// value. This is not allowed because it prohibits a value from being
|
||||
// shared among multiple structs that reference it.
|
||||
//
|
||||
// For example: if a struct has two fields of the same type, they must
|
||||
// both point to the same value after this routine has executed. If these
|
||||
// fields are not a pointer type, the value cannot be shared.
|
||||
//
|
||||
if reflect.PtrTo(ft).Implements(ifaceType) {
|
||||
panic(fmt.Sprintf(`field "%s" in struct "%s" must be a pointer`, ff.Name, v.Type()))
|
||||
}
|
||||
|
||||
// Type must implement specified interface.
|
||||
if !ft.Implements(ifaceType) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Type must be a pointer.
|
||||
if ft.Kind() != reflect.Ptr {
|
||||
panic(fmt.Sprintf(`field "%s" in struct "%s" must be a pointer`, ff.Name, v.Type()))
|
||||
}
|
||||
|
||||
// Have not seen this type before, create a value.
|
||||
if _, ok := visited[ft]; !ok {
|
||||
visited[ft] = reflect.New(ft.Elem())
|
||||
}
|
||||
|
||||
// Make sure current field is set.
|
||||
if fv.IsNil() {
|
||||
fv.Set(visited[ft])
|
||||
}
|
||||
|
||||
// Recurse.
|
||||
err := walker(fv.Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return walker(c)
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
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 cluster
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type add struct {
|
||||
*flags.DatacenterFlag
|
||||
*flags.HostConnectFlag
|
||||
|
||||
cluster string
|
||||
connect bool
|
||||
license string
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("cluster.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx)
|
||||
cmd.HostConnectFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.cluster, "cluster", "*", "Path to cluster")
|
||||
|
||||
f.StringVar(&cmd.license, "license", "", "Assign license key")
|
||||
|
||||
f.BoolVar(&cmd.connect, "connect", true, "Immediately connect to host")
|
||||
}
|
||||
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.HostConnectFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if cmd.HostName == "" {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
if cmd.UserName == "" {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
if cmd.Password == "" {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Description() string {
|
||||
return `Add host to cluster.
|
||||
|
||||
The host is added to the cluster specified by the 'cluster' flag.`
|
||||
}
|
||||
|
||||
func (cmd *add) Add(ctx context.Context, cluster *object.ClusterComputeResource) error {
|
||||
spec := cmd.HostConnectSpec
|
||||
|
||||
var license *string
|
||||
if cmd.license != "" {
|
||||
license = &cmd.license
|
||||
}
|
||||
|
||||
task, err := cluster.AddHost(ctx, spec, cmd.connect, license, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s to cluster %s... ", spec.HostName, cluster.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() != 0 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cluster, err := finder.ClusterComputeResource(ctx, cmd.cluster)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = cmd.Add(ctx, cluster)
|
||||
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if we failed due to SSLVerifyFault and -noverify is set
|
||||
if err := cmd.AcceptThumbprint(err); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Accepted unverified thumbprint, try again
|
||||
return cmd.Add(ctx, cluster)
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
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 cluster
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type change struct {
|
||||
*flags.DatacenterFlag
|
||||
|
||||
types.ClusterConfigSpecEx
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("cluster.change", &change{})
|
||||
}
|
||||
|
||||
func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
cmd.DrsConfig = new(types.ClusterDrsConfigInfo)
|
||||
cmd.DasConfig = new(types.ClusterDasConfigInfo)
|
||||
cmd.VsanConfig = new(types.VsanClusterConfigInfo)
|
||||
cmd.VsanConfig.DefaultConfig = new(types.VsanClusterConfigInfoHostDefaultInfo)
|
||||
|
||||
// DRS
|
||||
f.Var(flags.NewOptionalBool(&cmd.DrsConfig.Enabled), "drs-enabled", "Enable DRS")
|
||||
|
||||
drsModes := []string{
|
||||
string(types.DrsBehaviorManual),
|
||||
string(types.DrsBehaviorPartiallyAutomated),
|
||||
string(types.DrsBehaviorFullyAutomated),
|
||||
}
|
||||
f.StringVar((*string)(&cmd.DrsConfig.DefaultVmBehavior), "drs-mode", "",
|
||||
"DRS behavior for virtual machines: "+strings.Join(drsModes, ", "))
|
||||
|
||||
// HA
|
||||
f.Var(flags.NewOptionalBool(&cmd.DasConfig.Enabled), "ha-enabled", "Enable HA")
|
||||
|
||||
// vSAN
|
||||
f.Var(flags.NewOptionalBool(&cmd.VsanConfig.Enabled), "vsan-enabled", "Enable vSAN")
|
||||
f.Var(flags.NewOptionalBool(&cmd.VsanConfig.DefaultConfig.AutoClaimStorage), "vsan-autoclaim", "")
|
||||
}
|
||||
|
||||
func (cmd *change) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *change) Usage() string {
|
||||
return "CLUSTER..."
|
||||
}
|
||||
|
||||
func (cmd *change) Description() string {
|
||||
return `Change configuration of the given clusters.`
|
||||
}
|
||||
|
||||
func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, path := range f.Args() {
|
||||
clusters, err := finder.ClusterComputeResourceList(ctx, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cluster := range clusters {
|
||||
task, err := cluster.Reconfigure(ctx, &cmd.ClusterConfigSpecEx, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = task.WaitForResult(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
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 cluster
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type create struct {
|
||||
*flags.DatacenterFlag
|
||||
|
||||
parent string
|
||||
|
||||
types.ClusterConfigSpecEx
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("cluster.create", &create{})
|
||||
}
|
||||
|
||||
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.parent, "parent", "", "Path to parent folder for the new cluster")
|
||||
}
|
||||
|
||||
func (cmd *create) Usage() string {
|
||||
return "CLUSTER"
|
||||
}
|
||||
|
||||
func (cmd *create) Description() string {
|
||||
return `Create CLUSTER in datacenter.
|
||||
|
||||
The cluster is added to the folder specified by the 'parent' flag. If not given,
|
||||
this defaults to the hosts folder in the specified or default datacenter.`
|
||||
}
|
||||
|
||||
func (cmd *create) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
var parent *object.Folder
|
||||
|
||||
if f.NArg() != 1 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
if cmd.parent == "" {
|
||||
dc, err := cmd.Datacenter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
folders, err := dc.Folders(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parent = folders.HostFolder
|
||||
} else {
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parent, err = finder.Folder(ctx, cmd.parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err := parent.CreateCluster(ctx, f.Arg(0), cmd.ClusterConfigSpecEx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -34,15 +34,23 @@ func init() {
|
|||
cli.Register("datacenter.create", &create{})
|
||||
}
|
||||
|
||||
func (cmd *create) Register(f *flag.FlagSet) {}
|
||||
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *create) Usage() string {
|
||||
return "[DATACENTER NAME]..."
|
||||
}
|
||||
|
||||
func (cmd *create) Process() error { return nil }
|
||||
func (cmd *create) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *create) Run(f *flag.FlagSet) error {
|
||||
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
datacenters := f.Args()
|
||||
if len(datacenters) < 1 {
|
||||
return flag.ErrHelp
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,15 +33,23 @@ func init() {
|
|||
cli.Register("datacenter.destroy", &destroy{})
|
||||
}
|
||||
|
||||
func (cmd *destroy) Register(f *flag.FlagSet) {}
|
||||
func (cmd *destroy) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *destroy) Usage() string {
|
||||
return "[DATACENTER NAME]..."
|
||||
}
|
||||
|
||||
func (cmd *destroy) Process() error { return nil }
|
||||
func (cmd *destroy) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *destroy) Run(f *flag.FlagSet) error {
|
||||
func (cmd *destroy) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if len(f.Args()) < 1 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -37,17 +37,31 @@ func init() {
|
|||
cli.Register("datastore.cp", &cp{})
|
||||
}
|
||||
|
||||
func (cmd *cp) Register(f *flag.FlagSet) {
|
||||
func (cmd *cp) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.force, "f", false, "If true, overwrite any identically named file at the destination")
|
||||
}
|
||||
|
||||
func (cmd *cp) Process() error { return nil }
|
||||
func (cmd *cp) Process(ctx context.Context) error {
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *cp) Usage() string {
|
||||
return "SRC DST"
|
||||
}
|
||||
|
||||
func (cmd *cp) Run(f *flag.FlagSet) error {
|
||||
func (cmd *cp) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
args := f.Args()
|
||||
if len(args) != 2 {
|
||||
return errors.New("SRC and DST arguments are required")
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
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 datastore
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type create struct {
|
||||
*flags.HostSystemFlag
|
||||
|
||||
// Generic options
|
||||
Type typeFlag
|
||||
Name string
|
||||
Force bool
|
||||
|
||||
// Options for NAS
|
||||
RemoteHost string
|
||||
RemotePath string
|
||||
AccessMode string
|
||||
UserName string
|
||||
Password string
|
||||
|
||||
// Options for VMFS
|
||||
DiskCanonicalName string
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("datastore.create", &create{})
|
||||
}
|
||||
|
||||
var nasTypes = []string{
|
||||
string(types.HostFileSystemVolumeFileSystemTypeNFS),
|
||||
string(types.HostFileSystemVolumeFileSystemTypeNFS41),
|
||||
string(types.HostFileSystemVolumeFileSystemTypeCIFS),
|
||||
}
|
||||
|
||||
var vmfsTypes = []string{
|
||||
"VMFS",
|
||||
}
|
||||
|
||||
var allTypes = []string{}
|
||||
|
||||
func init() {
|
||||
allTypes = append(allTypes, nasTypes...)
|
||||
allTypes = append(allTypes, vmfsTypes...)
|
||||
}
|
||||
|
||||
type typeFlag string
|
||||
|
||||
func (t *typeFlag) Set(s string) error {
|
||||
s = strings.ToLower(s)
|
||||
for _, e := range allTypes {
|
||||
if s == strings.ToLower(e) {
|
||||
*t = typeFlag(e)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("unknown type")
|
||||
}
|
||||
|
||||
func (t *typeFlag) String() string {
|
||||
return string(*t)
|
||||
}
|
||||
|
||||
func (t *typeFlag) partOf(m []string) bool {
|
||||
for _, e := range m {
|
||||
if t.String() == e {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *typeFlag) IsNasType() bool {
|
||||
return t.partOf(nasTypes)
|
||||
}
|
||||
|
||||
func (t *typeFlag) IsVmfsType() bool {
|
||||
return t.partOf(vmfsTypes)
|
||||
}
|
||||
|
||||
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
modes := []string{
|
||||
string(types.HostMountModeReadOnly),
|
||||
string(types.HostMountModeReadWrite),
|
||||
}
|
||||
|
||||
f.StringVar(&cmd.Name, "name", "", "Datastore name")
|
||||
f.Var(&cmd.Type, "type", fmt.Sprintf("Datastore type (%s)", strings.Join(allTypes, "|")))
|
||||
f.BoolVar(&cmd.Force, "force", false, "Ignore DuplicateName error if datastore is already mounted on a host")
|
||||
|
||||
// Options for NAS
|
||||
f.StringVar(&cmd.RemoteHost, "remote-host", "", "Remote hostname of the NAS datastore")
|
||||
f.StringVar(&cmd.RemotePath, "remote-path", "", "Remote path of the NFS mount point")
|
||||
f.StringVar(&cmd.AccessMode, "mode", modes[0],
|
||||
fmt.Sprintf("Access mode for the mount point (%s)", strings.Join(modes, "|")))
|
||||
f.StringVar(&cmd.UserName, "username", "", "Username to use when connecting (CIFS only)")
|
||||
f.StringVar(&cmd.Password, "password", "", "Password to use when connecting (CIFS only)")
|
||||
|
||||
// Options for VMFS
|
||||
f.StringVar(&cmd.DiskCanonicalName, "disk", "", "Canonical name of disk (VMFS only)")
|
||||
}
|
||||
|
||||
func (cmd *create) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *create) Usage() string {
|
||||
return "HOST..."
|
||||
}
|
||||
|
||||
func (cmd *create) Description() string {
|
||||
return `Create datastore on HOST.
|
||||
|
||||
Examples:
|
||||
govc datastore.create -type nfs -name nfsDatastore -remote-host 10.143.2.232 -remote-path /share cluster1
|
||||
govc datastore.create -type vmfs -name localDatastore -disk=mpx.vmhba0:C0:T0:L0 cluster1`
|
||||
}
|
||||
|
||||
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case cmd.Type.IsNasType():
|
||||
return cmd.CreateNasDatastore(ctx, hosts)
|
||||
case cmd.Type.IsVmfsType():
|
||||
return cmd.CreateVmfsDatastore(ctx, hosts)
|
||||
default:
|
||||
return fmt.Errorf("unhandled type %#v", cmd.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd *create) GetHostNasVolumeSpec() types.HostNasVolumeSpec {
|
||||
s := types.HostNasVolumeSpec{
|
||||
LocalPath: cmd.Name,
|
||||
Type: cmd.Type.String(),
|
||||
RemoteHost: cmd.RemoteHost,
|
||||
RemotePath: cmd.RemotePath,
|
||||
AccessMode: cmd.AccessMode,
|
||||
UserName: cmd.UserName,
|
||||
Password: cmd.Password,
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (cmd *create) CreateNasDatastore(ctx context.Context, hosts []*object.HostSystem) error {
|
||||
object := types.ManagedObjectReference{
|
||||
Type: "Datastore",
|
||||
Value: fmt.Sprintf("%s:%s", cmd.RemoteHost, cmd.RemotePath),
|
||||
}
|
||||
|
||||
spec := cmd.GetHostNasVolumeSpec()
|
||||
|
||||
for _, host := range hosts {
|
||||
ds, err := host.ConfigManager().DatastoreSystem(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = ds.CreateNasDatastore(ctx, spec)
|
||||
if err != nil {
|
||||
if soap.IsSoapFault(err) {
|
||||
switch fault := soap.ToSoapFault(err).VimFault().(type) {
|
||||
case types.PlatformConfigFault:
|
||||
if len(fault.FaultMessage) != 0 {
|
||||
return errors.New(fault.FaultMessage[0].Message)
|
||||
}
|
||||
case types.DuplicateName:
|
||||
if cmd.Force && fault.Object == object {
|
||||
fmt.Fprintf(os.Stderr, "%s: '%s' already mounted\n",
|
||||
host.InventoryPath, cmd.Name)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s: %s", host.InventoryPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *create) CreateVmfsDatastore(ctx context.Context, hosts []*object.HostSystem) error {
|
||||
for _, host := range hosts {
|
||||
ds, err := host.ConfigManager().DatastoreSystem(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Find the specified disk
|
||||
disks, err := ds.QueryAvailableDisksForVmfs(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var disk *types.HostScsiDisk
|
||||
for _, e := range disks {
|
||||
if e.CanonicalName == cmd.DiskCanonicalName {
|
||||
disk = &e
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if disk == nil {
|
||||
return fmt.Errorf("no eligible disk found for name %#v", cmd.DiskCanonicalName)
|
||||
}
|
||||
|
||||
// Query for creation options and pick the right one
|
||||
options, err := ds.QueryVmfsDatastoreCreateOptions(ctx, disk.DevicePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var option *types.VmfsDatastoreOption
|
||||
for _, e := range options {
|
||||
if _, ok := e.Info.(*types.VmfsDatastoreAllExtentOption); ok {
|
||||
option = &e
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if option == nil {
|
||||
return fmt.Errorf("cannot use entire disk for datastore for name %#v", cmd.DiskCanonicalName)
|
||||
}
|
||||
|
||||
spec := *option.Spec.(*types.VmfsDatastoreCreateSpec)
|
||||
spec.Vmfs.VolumeName = cmd.Name
|
||||
_, err = ds.CreateVmfsDatastore(ctx, spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,6 +20,8 @@ import (
|
|||
"errors"
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
|
@ -33,26 +35,29 @@ func init() {
|
|||
cli.Register("datastore.download", &download{})
|
||||
}
|
||||
|
||||
func (cmd *download) Register(f *flag.FlagSet) {}
|
||||
func (cmd *download) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *download) Process() error { return nil }
|
||||
func (cmd *download) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *download) Usage() string {
|
||||
return "REMOTE LOCAL"
|
||||
}
|
||||
|
||||
func (cmd *download) Run(f *flag.FlagSet) error {
|
||||
func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
args := f.Args()
|
||||
if len(args) != 2 {
|
||||
return errors.New("invalid arguments")
|
||||
}
|
||||
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u, err := cmd.DatastoreURL(args[0])
|
||||
ds, err := cmd.Datastore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -64,5 +69,5 @@ func (cmd *download) Run(f *flag.FlagSet) error {
|
|||
defer logger.Wait()
|
||||
}
|
||||
|
||||
return c.Client.DownloadFile(args[1], u, &p)
|
||||
return ds.DownloadFile(context.TODO(), args[0], args[1], &p)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"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/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
@ -41,22 +42,40 @@ func init() {
|
|||
cli.Register("datastore.info", &info{})
|
||||
}
|
||||
|
||||
func (cmd *info) Register(f *flag.FlagSet) {}
|
||||
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
|
||||
func (cmd *info) Process() error { return nil }
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *info) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *info) Usage() string {
|
||||
return "[PATH]..."
|
||||
}
|
||||
|
||||
func (cmd *info) Run(f *flag.FlagSet) error {
|
||||
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -67,16 +86,6 @@ func (cmd *info) Run(f *flag.FlagSet) error {
|
|||
args = []string{"*"}
|
||||
}
|
||||
|
||||
datastores, err := finder.DatastoreList(ctx, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
refs := make([]types.ManagedObjectReference, 0, len(datastores))
|
||||
for _, ds := range datastores {
|
||||
refs = append(refs, ds.Reference())
|
||||
}
|
||||
|
||||
var res infoResult
|
||||
var props []string
|
||||
|
||||
|
@ -86,10 +95,25 @@ func (cmd *info) Run(f *flag.FlagSet) error {
|
|||
props = []string{"info", "summary"} // Load summary
|
||||
}
|
||||
|
||||
pc := property.DefaultCollector(c)
|
||||
err = pc.Retrieve(ctx, refs, props, &res.Datastores)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, arg := range args {
|
||||
objects, err := finder.DatastoreList(ctx, arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res.objects = append(res.objects, objects...)
|
||||
}
|
||||
|
||||
if len(res.objects) != 0 {
|
||||
refs := make([]types.ManagedObjectReference, 0, len(res.objects))
|
||||
for _, o := range res.objects {
|
||||
refs = append(refs, o.Reference())
|
||||
}
|
||||
|
||||
pc := property.DefaultCollector(c)
|
||||
err = pc.Retrieve(ctx, refs, props, &res.Datastores)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return cmd.WriteResult(&res)
|
||||
|
@ -97,14 +121,23 @@ func (cmd *info) Run(f *flag.FlagSet) error {
|
|||
|
||||
type infoResult struct {
|
||||
Datastores []mo.Datastore
|
||||
objects []*object.Datastore
|
||||
}
|
||||
|
||||
func (r *infoResult) Write(w io.Writer) error {
|
||||
// Maintain order via r.objects as Property collector does not always return results in order.
|
||||
objects := make(map[types.ManagedObjectReference]mo.Datastore, len(r.Datastores))
|
||||
for _, o := range r.Datastores {
|
||||
objects[o.Reference()] = o
|
||||
}
|
||||
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
|
||||
|
||||
for _, ds := range r.Datastores {
|
||||
for _, o := range r.objects {
|
||||
ds := objects[o.Reference()]
|
||||
s := ds.Summary
|
||||
fmt.Fprintf(tw, "Name:\t%s\n", s.Name)
|
||||
fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath)
|
||||
fmt.Fprintf(tw, " Type:\t%s\n", s.Type)
|
||||
fmt.Fprintf(tw, " URL:\t%s\n", s.Url)
|
||||
fmt.Fprintf(tw, " Capacity:\t%.1f GB\n", float64(s.Capacity)/(1<<30))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -36,24 +36,42 @@ type ls struct {
|
|||
*flags.DatastoreFlag
|
||||
*flags.OutputFlag
|
||||
|
||||
long bool
|
||||
long bool
|
||||
slash bool
|
||||
all bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("datastore.ls", &ls{})
|
||||
}
|
||||
|
||||
func (cmd *ls) Register(f *flag.FlagSet) {
|
||||
func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.long, "l", false, "Long listing format")
|
||||
f.BoolVar(&cmd.slash, "p", false, "Write a slash (`/') after each filename if that file is a directory")
|
||||
f.BoolVar(&cmd.all, "a", false, "Include entries whose names begin with a dot (.)")
|
||||
}
|
||||
|
||||
func (cmd *ls) Process() error { return nil }
|
||||
func (cmd *ls) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *ls) Usage() string {
|
||||
return "[FILE]..."
|
||||
}
|
||||
|
||||
func (cmd *ls) Run(f *flag.FlagSet) error {
|
||||
func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
ds, err := cmd.Datastore()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -70,8 +88,8 @@ func (cmd *ls) Run(f *flag.FlagSet) error {
|
|||
}
|
||||
|
||||
result := &listOutput{
|
||||
rs: make([]types.HostDatastoreBrowserSearchResults, 0),
|
||||
long: cmd.long,
|
||||
rs: make([]types.HostDatastoreBrowserSearchResults, 0),
|
||||
cmd: cmd,
|
||||
}
|
||||
|
||||
for _, arg := range args {
|
||||
|
@ -137,12 +155,29 @@ func (cmd *ls) ListPath(b *object.HostDatastoreBrowser, path string, spec types.
|
|||
}
|
||||
|
||||
type listOutput struct {
|
||||
rs []types.HostDatastoreBrowserSearchResults
|
||||
long bool
|
||||
rs []types.HostDatastoreBrowserSearchResults
|
||||
cmd *ls
|
||||
}
|
||||
|
||||
func (o *listOutput) add(r types.HostDatastoreBrowserSearchResults) {
|
||||
o.rs = append(o.rs, r)
|
||||
res := r
|
||||
res.File = nil
|
||||
|
||||
for _, f := range r.File {
|
||||
if f.GetFileInfo().Path[0] == '.' && !o.cmd.all {
|
||||
continue
|
||||
}
|
||||
|
||||
if o.cmd.slash {
|
||||
if d, ok := f.(*types.FolderFileInfo); ok {
|
||||
d.Path += "/"
|
||||
}
|
||||
}
|
||||
|
||||
res.File = append(res.File, f)
|
||||
}
|
||||
|
||||
o.rs = append(o.rs, res)
|
||||
}
|
||||
|
||||
// hasMultiplePaths returns whether or not the slice of search results contains
|
||||
|
@ -185,7 +220,7 @@ func (o *listOutput) Write(w io.Writer) error {
|
|||
}
|
||||
for _, file := range r.File {
|
||||
info := file.GetFileInfo()
|
||||
if o.long {
|
||||
if o.cmd.long {
|
||||
fmt.Fprintf(tw, "%s\t%s\t%s\n", units.ByteSize(info.FileSize), info.Modification.Format("Mon Jan 2 15:04:05 2006"), info.Path)
|
||||
} else {
|
||||
fmt.Fprintf(tw, "%s\n", info.Path)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -38,17 +38,25 @@ func init() {
|
|||
cli.Register("datastore.mkdir", &mkdir{})
|
||||
}
|
||||
|
||||
func (cmd *mkdir) Register(f *flag.FlagSet) {
|
||||
func (cmd *mkdir) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.createParents, "p", false, "Create intermediate directories as needed")
|
||||
}
|
||||
|
||||
func (cmd *mkdir) Process() error { return nil }
|
||||
func (cmd *mkdir) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *mkdir) Usage() string {
|
||||
return "DIRECTORY"
|
||||
}
|
||||
|
||||
func (cmd *mkdir) Run(f *flag.FlagSet) error {
|
||||
func (cmd *mkdir) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
args := f.Args()
|
||||
if len(args) == 0 {
|
||||
return errors.New("missing operand")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -36,17 +36,25 @@ func init() {
|
|||
cli.Register("datastore.mv", &mv{})
|
||||
}
|
||||
|
||||
func (cmd *mv) Register(f *flag.FlagSet) {
|
||||
func (cmd *mv) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.force, "f", false, "If true, overwrite any identically named file at the destination")
|
||||
}
|
||||
|
||||
func (cmd *mv) Process() error { return nil }
|
||||
func (cmd *mv) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *mv) Usage() string {
|
||||
return "SRC DST"
|
||||
}
|
||||
|
||||
func (cmd *mv) Run(f *flag.FlagSet) error {
|
||||
func (cmd *mv) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
args := f.Args()
|
||||
if len(args) != 2 {
|
||||
return errors.New("SRC and DST arguments are required")
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
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 datastore
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
)
|
||||
|
||||
type remove struct {
|
||||
*flags.HostSystemFlag
|
||||
*flags.DatastoreFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("datastore.remove", &remove{})
|
||||
}
|
||||
|
||||
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *remove) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *remove) Usage() string {
|
||||
return "HOST..."
|
||||
}
|
||||
|
||||
func (cmd *remove) Description() string {
|
||||
return `Remove datastore from HOST.
|
||||
Example:
|
||||
govc datastore.remove -ds nfsDatastore cluster1
|
||||
`
|
||||
}
|
||||
|
||||
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
ds, err := cmd.Datastore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
hds, err := host.ConfigManager().DatastoreSystem(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hds.Remove(ctx, ds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -38,17 +38,25 @@ func init() {
|
|||
cli.Alias("datastore.rm", "datastore.delete")
|
||||
}
|
||||
|
||||
func (cmd *rm) Register(f *flag.FlagSet) {
|
||||
func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.force, "f", false, "Force; ignore nonexistent files and arguments")
|
||||
}
|
||||
|
||||
func (cmd *rm) Process() error { return nil }
|
||||
func (cmd *rm) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *rm) Usage() string {
|
||||
return "FILE"
|
||||
}
|
||||
|
||||
func (cmd *rm) Run(f *flag.FlagSet) error {
|
||||
func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
args := f.Args()
|
||||
if len(args) == 0 {
|
||||
return errors.New("missing operand")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,6 +20,8 @@ import (
|
|||
"errors"
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
|
@ -34,26 +36,35 @@ func init() {
|
|||
cli.Register("datastore.upload", &upload{})
|
||||
}
|
||||
|
||||
func (cmd *upload) Register(f *flag.FlagSet) {}
|
||||
func (cmd *upload) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
|
||||
func (cmd *upload) Process() error { return nil }
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *upload) Process(ctx context.Context) error {
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *upload) Usage() string {
|
||||
return "LOCAL REMOTE"
|
||||
}
|
||||
|
||||
func (cmd *upload) Run(f *flag.FlagSet) error {
|
||||
func (cmd *upload) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
args := f.Args()
|
||||
if len(args) != 2 {
|
||||
return errors.New("invalid arguments")
|
||||
}
|
||||
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u, err := cmd.DatastoreURL(args[1])
|
||||
ds, err := cmd.Datastore()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -65,5 +76,5 @@ func (cmd *upload) Run(f *flag.FlagSet) error {
|
|||
defer logger.Wait()
|
||||
}
|
||||
|
||||
return c.Client.UploadFile(args[0], u, &p)
|
||||
return ds.UploadFile(context.TODO(), args[0], args[1], &p)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -37,7 +37,10 @@ func init() {
|
|||
cli.Register("device.boot", &boot{})
|
||||
}
|
||||
|
||||
func (cmd *boot) Register(f *flag.FlagSet) {
|
||||
func (cmd *boot) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.Int64Var(&cmd.BootDelay, "delay", 0, "Delay in ms before starting the boot sequence")
|
||||
f.StringVar(&cmd.order, "order", "", "Boot device order")
|
||||
f.Int64Var(&cmd.BootRetryDelay, "retry-delay", 0, "Delay in ms before a boot retry")
|
||||
|
@ -49,9 +52,14 @@ func (cmd *boot) Register(f *flag.FlagSet) {
|
|||
f.BoolVar(cmd.EnterBIOSSetup, "setup", false, "If true, enter BIOS setup on next boot")
|
||||
}
|
||||
|
||||
func (cmd *boot) Process() error { return nil }
|
||||
func (cmd *boot) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *boot) Run(f *flag.FlagSet) error {
|
||||
func (cmd *boot) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -35,13 +35,21 @@ func init() {
|
|||
cli.Register("device.cdrom.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.controller, "controller", "", "IDE controller name")
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -34,11 +34,19 @@ func init() {
|
|||
cli.Register("device.cdrom.eject", &eject{})
|
||||
}
|
||||
|
||||
func (cmd *eject) Register(f *flag.FlagSet) {
|
||||
func (cmd *eject) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.device, "device", "", "CD-ROM device name")
|
||||
}
|
||||
|
||||
func (cmd *eject) Process() error { return nil }
|
||||
func (cmd *eject) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *eject) Description() string {
|
||||
return `Eject media from CD-ROM device.
|
||||
|
@ -46,7 +54,7 @@ func (cmd *eject) Description() string {
|
|||
If device is not specified, the first CD-ROM device is used.`
|
||||
}
|
||||
|
||||
func (cmd *eject) Run(f *flag.FlagSet) error {
|
||||
func (cmd *eject) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -35,11 +35,24 @@ func init() {
|
|||
cli.Register("device.cdrom.insert", &insert{})
|
||||
}
|
||||
|
||||
func (cmd *insert) Register(f *flag.FlagSet) {
|
||||
func (cmd *insert) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.device, "device", "", "CD-ROM device name")
|
||||
}
|
||||
|
||||
func (cmd *insert) Process() error { return nil }
|
||||
func (cmd *insert) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *insert) Usage() string {
|
||||
return "ISO"
|
||||
|
@ -51,7 +64,7 @@ func (cmd *insert) Description() string {
|
|||
If device is not specified, the first CD-ROM device is used.`
|
||||
}
|
||||
|
||||
func (cmd *insert) Run(f *flag.FlagSet) error {
|
||||
func (cmd *insert) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,15 +33,23 @@ func init() {
|
|||
cli.Register("device.connect", &connect{})
|
||||
}
|
||||
|
||||
func (cmd *connect) Register(f *flag.FlagSet) {}
|
||||
func (cmd *connect) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *connect) Process() error { return nil }
|
||||
func (cmd *connect) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *connect) Usage() string {
|
||||
return "DEVICE..."
|
||||
}
|
||||
|
||||
func (cmd *connect) Run(f *flag.FlagSet) error {
|
||||
func (cmd *connect) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,15 +33,23 @@ func init() {
|
|||
cli.Register("device.disconnect", &disconnect{})
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Register(f *flag.FlagSet) {}
|
||||
func (cmd *disconnect) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Process() error { return nil }
|
||||
func (cmd *disconnect) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Usage() string {
|
||||
return "DEVICE..."
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Run(f *flag.FlagSet) error {
|
||||
func (cmd *disconnect) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,11 +33,19 @@ func init() {
|
|||
cli.Register("device.floppy.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {}
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -34,11 +34,19 @@ func init() {
|
|||
cli.Register("device.floppy.eject", &eject{})
|
||||
}
|
||||
|
||||
func (cmd *eject) Register(f *flag.FlagSet) {
|
||||
func (cmd *eject) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.device, "device", "", "Floppy device name")
|
||||
}
|
||||
|
||||
func (cmd *eject) Process() error { return nil }
|
||||
func (cmd *eject) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *eject) Description() string {
|
||||
return `Eject image from floppy device.
|
||||
|
@ -46,7 +54,7 @@ func (cmd *eject) Description() string {
|
|||
If device is not specified, the first floppy device is used.`
|
||||
}
|
||||
|
||||
func (cmd *eject) Run(f *flag.FlagSet) error {
|
||||
func (cmd *eject) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -35,11 +35,24 @@ func init() {
|
|||
cli.Register("device.floppy.insert", &insert{})
|
||||
}
|
||||
|
||||
func (cmd *insert) Register(f *flag.FlagSet) {
|
||||
func (cmd *insert) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
|
||||
cmd.DatastoreFlag.Register(ctx, f)
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.device, "device", "", "Floppy device name")
|
||||
}
|
||||
|
||||
func (cmd *insert) Process() error { return nil }
|
||||
func (cmd *insert) Process(ctx context.Context) error {
|
||||
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *insert) Usage() string {
|
||||
return "IMG"
|
||||
|
@ -51,7 +64,7 @@ func (cmd *insert) Description() string {
|
|||
If device is not specified, the first floppy device is used.`
|
||||
}
|
||||
|
||||
func (cmd *insert) Run(f *flag.FlagSet) error {
|
||||
func (cmd *insert) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -19,33 +19,50 @@ package device
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type info struct {
|
||||
*flags.VirtualMachineFlag
|
||||
*flags.OutputFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("device.info", &info{})
|
||||
}
|
||||
|
||||
func (cmd *info) Register(f *flag.FlagSet) {}
|
||||
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
func (cmd *info) Process() error { return nil }
|
||||
|
||||
func (cmd *info) Usage() string {
|
||||
return "DEVICE..."
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *info) Run(f *flag.FlagSet) error {
|
||||
func (cmd *info) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *info) Usage() string {
|
||||
return "[DEVICE]..."
|
||||
}
|
||||
|
||||
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -60,19 +77,41 @@ func (cmd *info) Run(f *flag.FlagSet) error {
|
|||
return err
|
||||
}
|
||||
|
||||
res := infoResult{
|
||||
list: devices,
|
||||
}
|
||||
|
||||
if f.NArg() == 0 {
|
||||
res.Devices = devices
|
||||
} else {
|
||||
for _, name := range f.Args() {
|
||||
device := devices.Find(name)
|
||||
if device == nil {
|
||||
return fmt.Errorf("device '%s' not found", name)
|
||||
}
|
||||
|
||||
res.Devices = append(res.Devices, device)
|
||||
}
|
||||
}
|
||||
|
||||
return cmd.WriteResult(&res)
|
||||
}
|
||||
|
||||
type infoResult struct {
|
||||
Devices object.VirtualDeviceList
|
||||
// need the full list of devices to lookup attached devices and controllers
|
||||
list object.VirtualDeviceList
|
||||
}
|
||||
|
||||
func (r *infoResult) Write(w io.Writer) error {
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
|
||||
|
||||
for _, name := range f.Args() {
|
||||
device := devices.Find(name)
|
||||
if device == nil {
|
||||
return fmt.Errorf("device '%s' not found", name)
|
||||
}
|
||||
|
||||
for _, device := range r.Devices {
|
||||
d := device.GetVirtualDevice()
|
||||
info := d.DeviceInfo.GetDescription()
|
||||
|
||||
fmt.Fprintf(tw, "Name:\t%s\n", name)
|
||||
fmt.Fprintf(tw, " Type:\t%s\n", devices.TypeName(device))
|
||||
fmt.Fprintf(tw, "Name:\t%s\n", r.Devices.Name(device))
|
||||
fmt.Fprintf(tw, " Type:\t%s\n", r.Devices.TypeName(device))
|
||||
fmt.Fprintf(tw, " Label:\t%s\n", info.Label)
|
||||
fmt.Fprintf(tw, " Summary:\t%s\n", info.Summary)
|
||||
fmt.Fprintf(tw, " Key:\t%d\n", d.Key)
|
||||
|
@ -80,12 +119,12 @@ func (cmd *info) Run(f *flag.FlagSet) error {
|
|||
if c, ok := device.(types.BaseVirtualController); ok {
|
||||
var attached []string
|
||||
for _, key := range c.GetVirtualController().Device {
|
||||
attached = append(attached, devices.Name(devices.FindByKey(key)))
|
||||
attached = append(attached, r.Devices.Name(r.list.FindByKey(key)))
|
||||
}
|
||||
fmt.Fprintf(tw, " Devices:\t%s\n", strings.Join(attached, ", "))
|
||||
} else {
|
||||
if c := devices.FindByKey(d.ControllerKey); c != nil {
|
||||
fmt.Fprintf(tw, " Controller:\t%s\n", devices.Name(c))
|
||||
if c := r.list.FindByKey(d.ControllerKey); c != nil {
|
||||
fmt.Fprintf(tw, " Controller:\t%s\n", r.Devices.Name(c))
|
||||
fmt.Fprintf(tw, " Unit number:\t%d\n", d.UnitNumber)
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +147,12 @@ func (cmd *info) Run(f *flag.FlagSet) error {
|
|||
if b, ok := md.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok && b.Parent != nil {
|
||||
fmt.Fprintf(tw, " Parent:\t%s\n", b.Parent.GetVirtualDeviceFileBackingInfo().FileName)
|
||||
}
|
||||
case *types.VirtualSerialPort:
|
||||
if b, ok := md.Backing.(*types.VirtualSerialPortURIBackingInfo); ok {
|
||||
fmt.Fprintf(tw, " Direction:\t%s\n", b.Direction)
|
||||
fmt.Fprintf(tw, " Service URI:\t%s\n", b.ServiceURI)
|
||||
fmt.Fprintf(tw, " Proxy URI:\t%s\n", b.ProxyURI)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -37,13 +37,21 @@ func init() {
|
|||
cli.Register("device.ls", &ls{})
|
||||
}
|
||||
|
||||
func (cmd *ls) Register(f *flag.FlagSet) {
|
||||
func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.boot, "boot", false, "List devices configured in the VM's boot options")
|
||||
}
|
||||
|
||||
func (cmd *ls) Process() error { return nil }
|
||||
func (cmd *ls) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *ls) Run(f *flag.FlagSet) error {
|
||||
func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,15 +33,23 @@ func init() {
|
|||
cli.Register("device.remove", &remove{})
|
||||
}
|
||||
|
||||
func (cmd *remove) Register(f *flag.FlagSet) {}
|
||||
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *remove) Process() error { return nil }
|
||||
func (cmd *remove) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *remove) Usage() string {
|
||||
return "DEVICE..."
|
||||
}
|
||||
|
||||
func (cmd *remove) Run(f *flag.FlagSet) error {
|
||||
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -40,7 +40,10 @@ func init() {
|
|||
cli.Register("device.scsi.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
var ctypes []string
|
||||
ct := object.SCSIControllerTypes()
|
||||
for _, t := range ct {
|
||||
|
@ -52,9 +55,14 @@ func (cmd *add) Register(f *flag.FlagSet) {
|
|||
f.BoolVar(&cmd.hotAddRemove, "hot", false, "Enable hot-add/remove")
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,11 +33,19 @@ func init() {
|
|||
cli.Register("device.serial.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {}
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -11,6 +11,8 @@ 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.
|
||||
*/
|
||||
|
||||
|
@ -35,14 +37,22 @@ func init() {
|
|||
cli.Register("device.serial.connect", &connect{})
|
||||
}
|
||||
|
||||
func (cmd *connect) Register(f *flag.FlagSet) {
|
||||
func (cmd *connect) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.device, "device", "", "serial port device name")
|
||||
f.BoolVar(&cmd.client, "client", false, "Use client direction")
|
||||
}
|
||||
|
||||
func (cmd *connect) Process() error { return nil }
|
||||
func (cmd *connect) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *connect) Run(f *flag.FlagSet) error {
|
||||
func (cmd *connect) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -34,13 +34,21 @@ func init() {
|
|||
cli.Register("device.serial.disconnect", &disconnect{})
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Register(f *flag.FlagSet) {
|
||||
func (cmd *disconnect) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
|
||||
cmd.VirtualMachineFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.device, "device", "", "serial port device name")
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Process() error { return nil }
|
||||
func (cmd *disconnect) Process(ctx context.Context) error {
|
||||
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Run(f *flag.FlagSet) error {
|
||||
func (cmd *disconnect) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
vm, err := cmd.VirtualMachine()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
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 dvs
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type add struct {
|
||||
*flags.HostSystemFlag
|
||||
|
||||
path string
|
||||
pnic string
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("dvs.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.path, "dvs", "", "DVS path")
|
||||
f.StringVar(&cmd.pnic, "pnic", "vmnic0", "Name of the host physical NIC")
|
||||
}
|
||||
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Usage() string {
|
||||
return "HOST..."
|
||||
}
|
||||
|
||||
func (cmd *add) Description() string {
|
||||
return `Add hosts to DVS.`
|
||||
}
|
||||
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() == 0 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
net, err := finder.Network(ctx, cmd.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dvs, ok := net.(*object.DistributedVirtualSwitch)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s (%T) is not of type %T", cmd.path, net, dvs)
|
||||
}
|
||||
|
||||
var s mo.VmwareDistributedVirtualSwitch
|
||||
err = dvs.Properties(ctx, dvs.Reference(), []string{"config"}, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
backing := new(types.DistributedVirtualSwitchHostMemberPnicBacking)
|
||||
|
||||
for _, vmnic := range strings.Split(cmd.pnic, ",") {
|
||||
backing.PnicSpec = append(backing.PnicSpec, types.DistributedVirtualSwitchHostMemberPnicSpec{
|
||||
PnicDevice: strings.TrimSpace(vmnic),
|
||||
})
|
||||
}
|
||||
|
||||
config := &types.DVSConfigSpec{
|
||||
ConfigVersion: s.Config.GetDVSConfigInfo().ConfigVersion,
|
||||
}
|
||||
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
existing := make(map[string]bool)
|
||||
// TODO: host.pnic.info command
|
||||
for _, member := range s.Config.GetDVSConfigInfo().Host {
|
||||
existing[member.Config.Host.Value] = true
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
ref := host.Reference()
|
||||
if existing[ref.Value] {
|
||||
fmt.Fprintf(os.Stderr, "%s is already a member of %s\n", host.InventoryPath, dvs.InventoryPath)
|
||||
continue
|
||||
}
|
||||
|
||||
config.Host = append(config.Host, types.DistributedVirtualSwitchHostMemberConfigSpec{
|
||||
Operation: "add",
|
||||
Host: ref,
|
||||
Backing: backing,
|
||||
})
|
||||
}
|
||||
|
||||
if len(config.Host) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
task, err := dvs.Reconfigure(ctx, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("adding %d hosts to dvs %s... ", len(config.Host), dvs.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
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 dvs
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type create struct {
|
||||
*flags.DatacenterFlag
|
||||
|
||||
types.DVSCreateSpec
|
||||
|
||||
configSpec *types.VMwareDVSConfigSpec
|
||||
|
||||
parent string
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("dvs.create", &create{})
|
||||
}
|
||||
|
||||
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
cmd.configSpec = new(types.VMwareDVSConfigSpec)
|
||||
|
||||
cmd.DVSCreateSpec.ConfigSpec = cmd.configSpec
|
||||
|
||||
f.StringVar(&cmd.parent, "parent", "", "Path to parent folder for the new dvs")
|
||||
}
|
||||
|
||||
func (cmd *create) Usage() string {
|
||||
return "DVS"
|
||||
}
|
||||
|
||||
func (cmd *create) Description() string {
|
||||
return `Create DVS (DistributedVirtualSwitch) in datacenter.
|
||||
|
||||
The dvs is added to the folder specified by the 'parent' flag. If not given,
|
||||
this defaults to the network folder in the specified or default datacenter.`
|
||||
}
|
||||
|
||||
func (cmd *create) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
var parent *object.Folder
|
||||
|
||||
if f.NArg() != 1 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
name := f.Arg(0)
|
||||
|
||||
if cmd.parent == "" {
|
||||
dc, err := cmd.Datacenter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
folders, err := dc.Folders(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parent = folders.NetworkFolder
|
||||
} else {
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parent, err = finder.Folder(ctx, cmd.parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cmd.configSpec.Name = name
|
||||
|
||||
task, err := parent.CreateDVS(ctx, cmd.DVSCreateSpec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s to folder %s... ", name, parent.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
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 portgroup
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type add struct {
|
||||
*flags.DatacenterFlag
|
||||
|
||||
types.DVPortgroupConfigSpec
|
||||
|
||||
path string
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("dvs.portgroup.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.path, "dvs", "", "DVS path")
|
||||
|
||||
ptypes := []string{
|
||||
string(types.DistributedVirtualPortgroupPortgroupTypeEarlyBinding),
|
||||
string(types.DistributedVirtualPortgroupPortgroupTypeLateBinding),
|
||||
string(types.DistributedVirtualPortgroupPortgroupTypeEphemeral),
|
||||
}
|
||||
|
||||
f.StringVar(&cmd.DVPortgroupConfigSpec.Type, "type", ptypes[0],
|
||||
fmt.Sprintf("Portgroup type (%s)", strings.Join(ptypes, "|")))
|
||||
|
||||
f.IntVar(&cmd.DVPortgroupConfigSpec.NumPorts, "nports", 128, "Number of ports")
|
||||
}
|
||||
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Usage() string {
|
||||
return "NAME"
|
||||
}
|
||||
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() == 0 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
name := f.Arg(0)
|
||||
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
net, err := finder.Network(ctx, cmd.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dvs, ok := net.(*object.DistributedVirtualSwitch)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s (%T) is not of type %T", cmd.path, net, dvs)
|
||||
}
|
||||
|
||||
cmd.DVPortgroupConfigSpec.Name = name
|
||||
|
||||
task, err := dvs.AddPortgroup(ctx, []types.DVPortgroupConfigSpec{cmd.DVPortgroupConfigSpec})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s portgroup to dvs %s... ", name, dvs.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -21,13 +21,11 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/event"
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/list"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
@ -42,24 +40,25 @@ func init() {
|
|||
cli.Register("events", &events{})
|
||||
}
|
||||
|
||||
func (cmd *events) Register(f *flag.FlagSet) {
|
||||
func (cmd *events) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
f.IntVar(&cmd.Max, "n", 25, "Output the last N events")
|
||||
}
|
||||
|
||||
func (cmd *events) Process() error { return nil }
|
||||
func (cmd *events) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *events) Usage() string {
|
||||
return "[PATH]..."
|
||||
}
|
||||
|
||||
func (cmd *events) Run(f *flag.FlagSet) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *events) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -67,20 +66,9 @@ func (cmd *events) Run(f *flag.FlagSet) error {
|
|||
|
||||
m := event.NewManager(c)
|
||||
|
||||
var objs []list.Element
|
||||
|
||||
args := f.Args()
|
||||
if len(args) == 0 {
|
||||
args = []string{"."}
|
||||
}
|
||||
|
||||
for _, arg := range args {
|
||||
es, err := finder.ManagedObjectList(ctx, arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
objs = append(objs, es...)
|
||||
objs, err := cmd.ManagedObjects(ctx, f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var events []types.BaseEvent
|
||||
|
@ -88,14 +76,14 @@ func (cmd *events) Run(f *flag.FlagSet) error {
|
|||
for _, o := range objs {
|
||||
filter := types.EventFilterSpec{
|
||||
Entity: &types.EventFilterSpecByEntity{
|
||||
Entity: o.Object.Reference(),
|
||||
Entity: o,
|
||||
Recursion: types.EventFilterSpecRecursionOptionAll,
|
||||
},
|
||||
}
|
||||
|
||||
collector, err := m.CreateCollectorForEvents(ctx, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[%s] %s", o.Path, err)
|
||||
return fmt.Errorf("[%#v] %s", o, err)
|
||||
}
|
||||
defer collector.Destroy(ctx)
|
||||
|
||||
|
@ -114,8 +102,6 @@ func (cmd *events) Run(f *flag.FlagSet) error {
|
|||
|
||||
event.Sort(events)
|
||||
|
||||
tw := tabwriter.NewWriter(os.Stdout, 3, 0, 2, ' ', 0)
|
||||
|
||||
for _, e := range events {
|
||||
cat, err := m.EventCategory(ctx, e)
|
||||
if err != nil {
|
||||
|
@ -129,10 +115,10 @@ func (cmd *events) Run(f *flag.FlagSet) error {
|
|||
msg = fmt.Sprintf("%s (target=%s %s)", msg, t.Info.Entity.Type, t.Info.EntityName)
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "[%s]\t[%s]\t%s\n",
|
||||
fmt.Fprintf(os.Stdout, "[%s] [%s] %s\n",
|
||||
event.CreatedTime.Local().Format(time.ANSIC),
|
||||
cat, msg)
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
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 extension
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type info struct {
|
||||
*flags.ClientFlag
|
||||
*flags.OutputFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("extension.info", &info{})
|
||||
}
|
||||
|
||||
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *info) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *info) Usage() string {
|
||||
return "[KEY]..."
|
||||
}
|
||||
|
||||
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m, err := object.GetExtensionManager(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
list, err := m.List(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var res infoResult
|
||||
|
||||
if f.NArg() == 0 {
|
||||
res.Extensions = list
|
||||
} else {
|
||||
exts := make(map[string]types.Extension)
|
||||
for _, e := range list {
|
||||
exts[e.Key] = e
|
||||
}
|
||||
|
||||
for _, key := range f.Args() {
|
||||
if e, ok := exts[key]; ok {
|
||||
res.Extensions = append(res.Extensions, e)
|
||||
} else {
|
||||
return fmt.Errorf("extension %s not found", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd.WriteResult(&res)
|
||||
}
|
||||
|
||||
type infoResult struct {
|
||||
Extensions []types.Extension
|
||||
}
|
||||
|
||||
func (r *infoResult) Write(w io.Writer) error {
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
|
||||
|
||||
for _, e := range r.Extensions {
|
||||
fmt.Fprintf(tw, "Name:\t%s\n", e.Key)
|
||||
fmt.Fprintf(tw, " Version:\t%s\n", e.Version)
|
||||
fmt.Fprintf(tw, " Description:\t%s\n", e.Description.GetDescription().Summary)
|
||||
fmt.Fprintf(tw, " Company:\t%s\n", e.Company)
|
||||
fmt.Fprintf(tw, " Last heartbeat time:\t%s\n", e.LastHeartbeatTime)
|
||||
fmt.Fprintf(tw, " Subject name:\t%s\n", e.SubjectName)
|
||||
fmt.Fprintf(tw, " Type:\t%s\n", e.Type)
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
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 extension
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type register struct {
|
||||
*flags.ClientFlag
|
||||
|
||||
update bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("extension.register", ®ister{})
|
||||
}
|
||||
|
||||
func (cmd *register) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.update, "update", false, "Update extension")
|
||||
}
|
||||
|
||||
func (cmd *register) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *register) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m, err := object.GetExtensionManager(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var e types.Extension
|
||||
e.Description = new(types.Description)
|
||||
|
||||
if err = json.NewDecoder(os.Stdin).Decode(&e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.LastHeartbeatTime = time.Now().UTC()
|
||||
|
||||
if cmd.update {
|
||||
return m.Update(ctx, e)
|
||||
}
|
||||
|
||||
return m.Register(ctx, e)
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
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 extension
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type setcert struct {
|
||||
*flags.ClientFlag
|
||||
|
||||
cert string
|
||||
org string
|
||||
|
||||
encodedCert bytes.Buffer
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("extension.setcert", &setcert{})
|
||||
}
|
||||
|
||||
func (cmd *setcert) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.cert, "cert-pem", "-", "PEM encoded certificate")
|
||||
f.StringVar(&cmd.org, "org", "VMware", "Organization for generated certificate")
|
||||
}
|
||||
|
||||
func (cmd *setcert) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *setcert) Usage() string {
|
||||
return "ID"
|
||||
}
|
||||
|
||||
func (cmd *setcert) Description() string {
|
||||
return `The '-cert-pem' option can be one of the following:
|
||||
'-' : Read the certificate from stdin
|
||||
'+' : Generate a new key pair and save locally to ID.crt and ID.key
|
||||
... : Any other value is passed as-is to ExtensionManager.SetCertificate
|
||||
`
|
||||
}
|
||||
|
||||
func (cmd *setcert) create(id string) error {
|
||||
certFile, err := os.Create(id + ".crt")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer certFile.Close()
|
||||
|
||||
keyFile, err := os.Create(id + ".key")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer keyFile.Close()
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notBefore := time.Now()
|
||||
notAfter := notBefore.Add(5 * 365 * 24 * time.Hour) // 5 years
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{cmd.org},
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = pem.Encode(&cmd.encodedCert, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = certFile.Write(cmd.encodedCert.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = pem.Encode(keyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *setcert) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m, err := object.GetExtensionManager(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.NArg() != 1 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
key := f.Arg(0)
|
||||
|
||||
if cmd.cert == "-" {
|
||||
b, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.cert = string(b)
|
||||
} else if cmd.cert == "+" {
|
||||
if err := cmd.create(key); err != nil {
|
||||
return fmt.Errorf("creating certificate: %s", err)
|
||||
}
|
||||
cmd.cert = cmd.encodedCert.String()
|
||||
}
|
||||
|
||||
return m.SetCertificate(ctx, key, cmd.cert)
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
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 extension
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type unregister struct {
|
||||
*flags.ClientFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("extension.unregister", &unregister{})
|
||||
}
|
||||
|
||||
func (cmd *unregister) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *unregister) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *unregister) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m, err := object.GetExtensionManager(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, key := range f.Args() {
|
||||
if err = m.Unregister(ctx, key); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -34,21 +34,27 @@ func init() {
|
|||
cli.Register("fields.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {}
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Usage() string {
|
||||
return "NAME"
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() != 1 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -36,13 +36,19 @@ func init() {
|
|||
cli.Register("fields.ls", &ls{})
|
||||
}
|
||||
|
||||
func (cmd *ls) Register(f *flag.FlagSet) {}
|
||||
func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *ls) Process() error { return nil }
|
||||
|
||||
func (cmd *ls) Run(f *flag.FlagSet) error {
|
||||
ctx := context.TODO()
|
||||
func (cmd *ls) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,21 +33,27 @@ func init() {
|
|||
cli.Register("fields.rename", &rename{})
|
||||
}
|
||||
|
||||
func (cmd *rename) Register(f *flag.FlagSet) {}
|
||||
func (cmd *rename) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *rename) Process() error { return nil }
|
||||
func (cmd *rename) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *rename) Usage() string {
|
||||
return "KEY NAME"
|
||||
}
|
||||
|
||||
func (cmd *rename) Run(f *flag.FlagSet) error {
|
||||
func (cmd *rename) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() != 2 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -33,17 +33,23 @@ func init() {
|
|||
cli.Register("fields.rm", &rm{})
|
||||
}
|
||||
|
||||
func (cmd *rm) Register(f *flag.FlagSet) {}
|
||||
func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *rm) Process() error { return nil }
|
||||
func (cmd *rm) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *rm) Usage() string {
|
||||
return "KEY..."
|
||||
}
|
||||
|
||||
func (cmd *rm) Run(f *flag.FlagSet) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -21,7 +21,6 @@ import (
|
|||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/list"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
@ -34,26 +33,27 @@ func init() {
|
|||
cli.Register("fields.set", &set{})
|
||||
}
|
||||
|
||||
func (cmd *set) Register(f *flag.FlagSet) {}
|
||||
func (cmd *set) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *set) Process() error { return nil }
|
||||
func (cmd *set) Process(ctx context.Context) error {
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *set) Usage() string {
|
||||
return "KEY VALUE PATH..."
|
||||
}
|
||||
|
||||
func (cmd *set) Run(f *flag.FlagSet) error {
|
||||
func (cmd *set) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() < 3 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
finder, err := cmd.Finder()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -64,8 +64,6 @@ func (cmd *set) Run(f *flag.FlagSet) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var objs []list.Element
|
||||
|
||||
args := f.Args()
|
||||
|
||||
key, err := m.FindKey(ctx, args[0])
|
||||
|
@ -75,17 +73,13 @@ func (cmd *set) Run(f *flag.FlagSet) error {
|
|||
|
||||
val := args[1]
|
||||
|
||||
for _, arg := range args[2:] {
|
||||
es, err := finder.ManagedObjectList(ctx, arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
objs = append(objs, es...)
|
||||
objs, err := cmd.ManagedObjects(ctx, args[2:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ref := range objs {
|
||||
err := m.Set(ctx, ref.Object.Reference(), key, val)
|
||||
err := m.Set(ctx, ref, key, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -18,6 +18,7 @@ package flags
|
|||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
|
@ -25,9 +26,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/session"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
|
@ -39,6 +38,8 @@ const (
|
|||
envURL = "GOVC_URL"
|
||||
envUsername = "GOVC_USERNAME"
|
||||
envPassword = "GOVC_PASSWORD"
|
||||
envCertificate = "GOVC_CERTIFICATE"
|
||||
envPrivateKey = "GOVC_PRIVATE_KEY"
|
||||
envInsecure = "GOVC_INSECURE"
|
||||
envPersist = "GOVC_PERSIST_SESSION"
|
||||
envMinAPIVersion = "GOVC_MIN_API_VERSION"
|
||||
|
@ -47,13 +48,15 @@ const (
|
|||
const cDescr = "ESX or vCenter URL"
|
||||
|
||||
type ClientFlag struct {
|
||||
*DebugFlag
|
||||
common
|
||||
|
||||
register sync.Once
|
||||
*DebugFlag
|
||||
|
||||
url *url.URL
|
||||
username string
|
||||
password string
|
||||
cert string
|
||||
key string
|
||||
insecure bool
|
||||
persist bool
|
||||
minAPIVersion string
|
||||
|
@ -61,6 +64,19 @@ type ClientFlag struct {
|
|||
client *vim25.Client
|
||||
}
|
||||
|
||||
var clientFlagKey = flagKey("client")
|
||||
|
||||
func NewClientFlag(ctx context.Context) (*ClientFlag, context.Context) {
|
||||
if v := ctx.Value(clientFlagKey); v != nil {
|
||||
return v.(*ClientFlag), ctx
|
||||
}
|
||||
|
||||
v := &ClientFlag{}
|
||||
v.DebugFlag, ctx = NewDebugFlag(ctx)
|
||||
ctx = context.WithValue(ctx, clientFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *ClientFlag) URLWithoutPassword() *url.URL {
|
||||
if flag.url == nil {
|
||||
return nil
|
||||
|
@ -80,37 +96,18 @@ func (flag *ClientFlag) String() string {
|
|||
return url.String()
|
||||
}
|
||||
|
||||
var schemeMatch = regexp.MustCompile(`^\w+://`)
|
||||
|
||||
func (flag *ClientFlag) Set(s string) error {
|
||||
var err error
|
||||
|
||||
if s != "" {
|
||||
// Default the scheme to https
|
||||
if !schemeMatch.MatchString(s) {
|
||||
s = "https://" + s
|
||||
}
|
||||
flag.url, err = soap.ParseURL(s)
|
||||
|
||||
flag.url, err = url.Parse(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Default the path to /sdk
|
||||
if flag.url.Path == "" {
|
||||
flag.url.Path = "/sdk"
|
||||
}
|
||||
|
||||
if flag.url.User == nil {
|
||||
flag.url.User = url.UserPassword("", "")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (flag *ClientFlag) Register(f *flag.FlagSet) {
|
||||
flag.register.Do(func() {
|
||||
func (flag *ClientFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.DebugFlag.Register(ctx, f)
|
||||
|
||||
{
|
||||
flag.Set(os.Getenv(envURL))
|
||||
usage := fmt.Sprintf("%s [%s]", cDescr, envURL)
|
||||
|
@ -122,6 +119,18 @@ func (flag *ClientFlag) Register(f *flag.FlagSet) {
|
|||
flag.password = os.Getenv(envPassword)
|
||||
}
|
||||
|
||||
{
|
||||
value := os.Getenv(envCertificate)
|
||||
usage := fmt.Sprintf("Certificate [%s]", envCertificate)
|
||||
f.StringVar(&flag.cert, "cert", value, usage)
|
||||
}
|
||||
|
||||
{
|
||||
value := os.Getenv(envPrivateKey)
|
||||
usage := fmt.Sprintf("Private key [%s]", envPrivateKey)
|
||||
f.StringVar(&flag.key, "key", value, usage)
|
||||
}
|
||||
|
||||
{
|
||||
insecure := false
|
||||
switch env := strings.ToLower(os.Getenv(envInsecure)); env {
|
||||
|
@ -155,39 +164,45 @@ func (flag *ClientFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *ClientFlag) Process() error {
|
||||
if flag.url == nil {
|
||||
return errors.New("specify an " + cDescr)
|
||||
}
|
||||
|
||||
// Override username if set
|
||||
if flag.username != "" {
|
||||
var password string
|
||||
var ok bool
|
||||
|
||||
if flag.url.User != nil {
|
||||
password, ok = flag.url.User.Password()
|
||||
func (flag *ClientFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.DebugFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok {
|
||||
flag.url.User = url.UserPassword(flag.username, password)
|
||||
} else {
|
||||
flag.url.User = url.User(flag.username)
|
||||
}
|
||||
}
|
||||
|
||||
// Override password if set
|
||||
if flag.password != "" {
|
||||
var username string
|
||||
|
||||
if flag.url.User != nil {
|
||||
username = flag.url.User.Username()
|
||||
if flag.url == nil {
|
||||
return errors.New("specify an " + cDescr)
|
||||
}
|
||||
|
||||
flag.url.User = url.UserPassword(username, flag.password)
|
||||
}
|
||||
// Override username if set
|
||||
if flag.username != "" {
|
||||
var password string
|
||||
var ok bool
|
||||
|
||||
return nil
|
||||
if flag.url.User != nil {
|
||||
password, ok = flag.url.User.Password()
|
||||
}
|
||||
|
||||
if ok {
|
||||
flag.url.User = url.UserPassword(flag.username, password)
|
||||
} else {
|
||||
flag.url.User = url.User(flag.username)
|
||||
}
|
||||
}
|
||||
|
||||
// Override password if set
|
||||
if flag.password != "" {
|
||||
var username string
|
||||
|
||||
if flag.url.User != nil {
|
||||
username = flag.url.User.Username()
|
||||
}
|
||||
|
||||
flag.url.User = url.UserPassword(username, flag.password)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Retry twice when a temporary I/O error occurs.
|
||||
|
@ -221,11 +236,9 @@ func (flag *ClientFlag) saveClient(c *vim25.Client) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
enc := json.NewEncoder(f)
|
||||
err = enc.Encode(c)
|
||||
err = json.NewEncoder(f).Encode(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -288,6 +301,17 @@ func (flag *ClientFlag) loadClient() (*vim25.Client, error) {
|
|||
|
||||
func (flag *ClientFlag) newClient() (*vim25.Client, error) {
|
||||
sc := soap.NewClient(flag.url, flag.insecure)
|
||||
isTunnel := false
|
||||
|
||||
if flag.cert != "" {
|
||||
isTunnel = true
|
||||
cert, err := tls.LoadX509KeyPair(flag.cert, flag.key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sc.SetCertificate(cert)
|
||||
}
|
||||
|
||||
// Add retry functionality before making any calls
|
||||
rt := attachRetries(sc)
|
||||
|
@ -300,9 +324,17 @@ func (flag *ClientFlag) newClient() (*vim25.Client, error) {
|
|||
c.Client = sc
|
||||
|
||||
m := session.NewManager(c)
|
||||
err = m.Login(context.TODO(), flag.url.User)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
u := flag.url.User
|
||||
if isTunnel {
|
||||
err = m.LoginExtensionByCertificate(context.TODO(), u.Username(), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err = m.Login(context.TODO(), u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = flag.saveClient(c)
|
||||
|
@ -316,7 +348,18 @@ func (flag *ClientFlag) newClient() (*vim25.Client, error) {
|
|||
// apiVersionValid returns whether or not the API version supported by the
|
||||
// server the client is connected to is not recent enough.
|
||||
func apiVersionValid(c *vim25.Client, minVersionString string) error {
|
||||
realVersion, err := ParseVersion(c.ServiceContent.About.ApiVersion)
|
||||
if minVersionString == "-" {
|
||||
// Disable version check
|
||||
return nil
|
||||
}
|
||||
|
||||
apiVersion := c.ServiceContent.About.ApiVersion
|
||||
if strings.HasSuffix(apiVersion, ".x") {
|
||||
// Skip version check for development builds
|
||||
return nil
|
||||
}
|
||||
|
||||
realVersion, err := ParseVersion(apiVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package flags
|
||||
|
||||
import "sync"
|
||||
|
||||
// Key type for storing flag instances in a context.Context.
|
||||
type flagKey string
|
||||
|
||||
// Type to help flags out with only registering/processing once.
|
||||
type common struct {
|
||||
register sync.Once
|
||||
process sync.Once
|
||||
}
|
||||
|
||||
func (c *common) RegisterOnce(fn func()) {
|
||||
c.register.Do(fn)
|
||||
}
|
||||
|
||||
func (c *common) ProcessOnce(fn func() error) (err error) {
|
||||
c.process.Do(func() {
|
||||
err = fn()
|
||||
})
|
||||
return err
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,26 +20,44 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/find"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type DatacenterFlag struct {
|
||||
common
|
||||
|
||||
*ClientFlag
|
||||
*OutputFlag
|
||||
|
||||
register sync.Once
|
||||
path string
|
||||
dc *object.Datacenter
|
||||
finder *find.Finder
|
||||
err error
|
||||
path string
|
||||
dc *object.Datacenter
|
||||
finder *find.Finder
|
||||
err error
|
||||
}
|
||||
|
||||
func (flag *DatacenterFlag) Register(f *flag.FlagSet) {
|
||||
flag.register.Do(func() {
|
||||
var datacenterFlagKey = flagKey("datacenter")
|
||||
|
||||
func NewDatacenterFlag(ctx context.Context) (*DatacenterFlag, context.Context) {
|
||||
if v := ctx.Value(datacenterFlagKey); v != nil {
|
||||
return v.(*DatacenterFlag), ctx
|
||||
}
|
||||
|
||||
v := &DatacenterFlag{}
|
||||
v.ClientFlag, ctx = NewClientFlag(ctx)
|
||||
v.OutputFlag, ctx = NewOutputFlag(ctx)
|
||||
ctx = context.WithValue(ctx, datacenterFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *DatacenterFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.ClientFlag.Register(ctx, f)
|
||||
flag.OutputFlag.Register(ctx, f)
|
||||
|
||||
env := "GOVC_DATACENTER"
|
||||
value := os.Getenv(env)
|
||||
usage := fmt.Sprintf("Datacenter [%s]", env)
|
||||
|
@ -47,7 +65,17 @@ func (flag *DatacenterFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *DatacenterFlag) Process() error { return nil }
|
||||
func (flag *DatacenterFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *DatacenterFlag) Finder() (*find.Finder, error) {
|
||||
if flag.finder != nil {
|
||||
|
@ -64,12 +92,8 @@ func (flag *DatacenterFlag) Finder() (*find.Finder, error) {
|
|||
// Datacenter is not required (ls command for example).
|
||||
// Set for relative func if dc flag is given or
|
||||
// if there is a single (default) Datacenter
|
||||
if flag.path == "" {
|
||||
flag.dc, flag.err = finder.DefaultDatacenter(context.TODO())
|
||||
} else {
|
||||
if flag.dc, err = finder.Datacenter(context.TODO(), flag.path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if flag.dc, err = finder.DatacenterOrDefault(context.TODO(), flag.path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
finder.SetDatacenter(flag.dc)
|
||||
|
@ -96,3 +120,35 @@ func (flag *DatacenterFlag) Datacenter() (*object.Datacenter, error) {
|
|||
|
||||
return flag.dc, err
|
||||
}
|
||||
|
||||
func (flag *DatacenterFlag) ManagedObjects(ctx context.Context, args []string) ([]types.ManagedObjectReference, error) {
|
||||
var refs []types.ManagedObjectReference
|
||||
|
||||
c, err := flag.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
refs = append(refs, c.ServiceContent.RootFolder)
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
finder, err := flag.Finder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, arg := range args {
|
||||
elements, err := finder.ManagedObjectList(ctx, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, e := range elements {
|
||||
refs = append(refs, e.Object.Reference())
|
||||
}
|
||||
}
|
||||
|
||||
return refs, nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -17,34 +17,41 @@ limitations under the License.
|
|||
package flags
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDatastoreDirNotExist = errors.New("datastore directory does not exist")
|
||||
ErrDatastoreFileNotExist = errors.New("datastore file does not exist")
|
||||
)
|
||||
|
||||
type DatastoreFlag struct {
|
||||
common
|
||||
|
||||
*DatacenterFlag
|
||||
|
||||
register sync.Once
|
||||
name string
|
||||
ds *object.Datastore
|
||||
name string
|
||||
ds *object.Datastore
|
||||
}
|
||||
|
||||
func (flag *DatastoreFlag) Register(f *flag.FlagSet) {
|
||||
flag.register.Do(func() {
|
||||
var datastoreFlagKey = flagKey("datastore")
|
||||
|
||||
func NewDatastoreFlag(ctx context.Context) (*DatastoreFlag, context.Context) {
|
||||
if v := ctx.Value(datastoreFlagKey); v != nil {
|
||||
return v.(*DatastoreFlag), ctx
|
||||
}
|
||||
|
||||
v := &DatastoreFlag{}
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
ctx = context.WithValue(ctx, datastoreFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *DatastoreFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
env := "GOVC_DATASTORE"
|
||||
value := os.Getenv(env)
|
||||
usage := fmt.Sprintf("Datastore [%s]", env)
|
||||
|
@ -52,7 +59,14 @@ func (flag *DatastoreFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *DatastoreFlag) Process() error { return nil }
|
||||
func (flag *DatastoreFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *DatastoreFlag) Datastore() (*object.Datastore, error) {
|
||||
if flag.ds != nil {
|
||||
|
@ -64,13 +78,11 @@ func (flag *DatastoreFlag) Datastore() (*object.Datastore, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if flag.name == "" {
|
||||
flag.ds, err = finder.DefaultDatastore(context.TODO())
|
||||
} else {
|
||||
flag.ds, err = finder.Datastore(context.TODO(), flag.name)
|
||||
if flag.ds, err = finder.DatastoreOrDefault(context.TODO(), flag.name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return flag.ds, err
|
||||
return flag.ds, nil
|
||||
}
|
||||
|
||||
func (flag *DatastoreFlag) DatastorePath(name string) (string, error) {
|
||||
|
@ -100,50 +112,3 @@ func (flag *DatastoreFlag) DatastoreURL(path string) (*url.URL, error) {
|
|||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (flag *DatastoreFlag) Stat(file string) (types.BaseFileInfo, error) {
|
||||
ds, err := flag.Datastore()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err := ds.Browser(context.TODO())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spec := types.HostDatastoreBrowserSearchSpec{
|
||||
Details: &types.FileQueryFlags{
|
||||
FileType: true,
|
||||
FileOwner: types.NewBool(true), // TODO: omitempty is generated, but seems to be required
|
||||
},
|
||||
MatchPattern: []string{path.Base(file)},
|
||||
}
|
||||
|
||||
dsPath := ds.Path(path.Dir(file))
|
||||
task, err := b.SearchDatastore(context.TODO(), dsPath, &spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info, err := task.WaitForResult(context.TODO(), nil)
|
||||
if err != nil {
|
||||
if info != nil && info.Error != nil {
|
||||
_, ok := info.Error.Fault.(*types.FileNotFound)
|
||||
if ok {
|
||||
// FileNotFound means the base path doesn't exist.
|
||||
return nil, ErrDatastoreDirNotExist
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := info.Result.(types.HostDatastoreBrowserSearchResults)
|
||||
if len(res.File) == 0 {
|
||||
// File doesn't exist
|
||||
return nil, ErrDatastoreFileNotExist
|
||||
}
|
||||
|
||||
return res.File[0], nil
|
||||
}
|
||||
|
|
|
@ -24,27 +24,49 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/debug"
|
||||
)
|
||||
|
||||
type DebugFlag struct {
|
||||
common
|
||||
|
||||
enable bool
|
||||
}
|
||||
|
||||
func (flag *DebugFlag) Register(f *flag.FlagSet) {
|
||||
env := "GOVC_DEBUG"
|
||||
enable := false
|
||||
switch env := strings.ToLower(os.Getenv(env)); env {
|
||||
case "1", "true":
|
||||
enable = true
|
||||
var debugFlagKey = flagKey("debug")
|
||||
|
||||
func NewDebugFlag(ctx context.Context) (*DebugFlag, context.Context) {
|
||||
if v := ctx.Value(debugFlagKey); v != nil {
|
||||
return v.(*DebugFlag), ctx
|
||||
}
|
||||
|
||||
usage := fmt.Sprintf("Store debug logs [%s]", env)
|
||||
f.BoolVar(&flag.enable, "debug", enable, usage)
|
||||
v := &DebugFlag{}
|
||||
ctx = context.WithValue(ctx, debugFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *DebugFlag) Process() error {
|
||||
if flag.enable {
|
||||
func (flag *DebugFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
env := "GOVC_DEBUG"
|
||||
enable := false
|
||||
switch env := strings.ToLower(os.Getenv(env)); env {
|
||||
case "1", "true":
|
||||
enable = true
|
||||
}
|
||||
|
||||
usage := fmt.Sprintf("Store debug logs [%s]", env)
|
||||
f.BoolVar(&flag.enable, "debug", enable, usage)
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *DebugFlag) Process(ctx context.Context) error {
|
||||
if !flag.enable {
|
||||
return nil
|
||||
}
|
||||
|
||||
return flag.ProcessOnce(func() error {
|
||||
// Base path for storing debug logs.
|
||||
r := os.Getenv("GOVC_DEBUG_PATH")
|
||||
if r == "" {
|
||||
|
@ -66,7 +88,6 @@ func (flag *DebugFlag) Process() error {
|
|||
}
|
||||
|
||||
debug.SetProvider(&p)
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
@ -16,10 +16,17 @@ limitations under the License.
|
|||
|
||||
package flags
|
||||
|
||||
import "flag"
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type EmptyFlag struct{}
|
||||
|
||||
func (flag *EmptyFlag) Register(f *flag.FlagSet) {}
|
||||
func (flag *EmptyFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
}
|
||||
|
||||
func (flag *EmptyFlag) Process() error { return nil }
|
||||
func (flag *EmptyFlag) Process(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
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 flags
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type HostConnectFlag struct {
|
||||
common
|
||||
|
||||
types.HostConnectSpec
|
||||
|
||||
noverify bool
|
||||
}
|
||||
|
||||
var hostConnectFlagKey = flagKey("hostConnect")
|
||||
|
||||
func NewHostConnectFlag(ctx context.Context) (*HostConnectFlag, context.Context) {
|
||||
if v := ctx.Value(hostConnectFlagKey); v != nil {
|
||||
return v.(*HostConnectFlag), ctx
|
||||
}
|
||||
|
||||
v := &HostConnectFlag{}
|
||||
ctx = context.WithValue(ctx, hostConnectFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *HostConnectFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
f.StringVar(&flag.HostName, "hostname", "", "Hostname or IP address of the host")
|
||||
f.StringVar(&flag.UserName, "username", "", "Username of administration account on the host")
|
||||
f.StringVar(&flag.Password, "password", "", "Password of administration account on the host")
|
||||
f.StringVar(&flag.SslThumbprint, "fingerprint", "", "Fingerprint of the host's SSL certificate")
|
||||
f.BoolVar(&flag.Force, "force", false, "Force when host is managed by another VC")
|
||||
|
||||
f.BoolVar(&flag.noverify, "noverify", false, "When true, ignore host SSL certificate verification error")
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *HostConnectFlag) Process(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AcceptThumbprint returns nil if the given error is an SSLVerifyFault and -noverify is true.
|
||||
// In which case, flag.SslThumbprint is set to fault.Thumbprint and the caller should retry the task.
|
||||
func (flag *HostConnectFlag) AcceptThumbprint(err error) error {
|
||||
if f, ok := err.(types.HasFault); ok {
|
||||
switch fault := f.Fault().(type) {
|
||||
case *types.SSLVerifyFault:
|
||||
if flag.noverify {
|
||||
flag.SslThumbprint = fault.Thumbprint
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("%s Fingerprint is %s", err, fault.Thumbprint)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,27 +20,44 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type HostSystemFlag struct {
|
||||
common
|
||||
|
||||
*ClientFlag
|
||||
*DatacenterFlag
|
||||
*SearchFlag
|
||||
|
||||
register sync.Once
|
||||
name string
|
||||
host *object.HostSystem
|
||||
pool *object.ResourcePool
|
||||
name string
|
||||
host *object.HostSystem
|
||||
pool *object.ResourcePool
|
||||
}
|
||||
|
||||
func (flag *HostSystemFlag) Register(f *flag.FlagSet) {
|
||||
flag.SearchFlag = NewSearchFlag(SearchHosts)
|
||||
var hostSystemFlagKey = flagKey("hostSystem")
|
||||
|
||||
func NewHostSystemFlag(ctx context.Context) (*HostSystemFlag, context.Context) {
|
||||
if v := ctx.Value(hostSystemFlagKey); v != nil {
|
||||
return v.(*HostSystemFlag), ctx
|
||||
}
|
||||
|
||||
v := &HostSystemFlag{}
|
||||
v.ClientFlag, ctx = NewClientFlag(ctx)
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
v.SearchFlag, ctx = NewSearchFlag(ctx, SearchHosts)
|
||||
ctx = context.WithValue(ctx, hostSystemFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *HostSystemFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.ClientFlag.Register(ctx, f)
|
||||
flag.DatacenterFlag.Register(ctx, f)
|
||||
flag.SearchFlag.Register(ctx, f)
|
||||
|
||||
flag.register.Do(func() {
|
||||
env := "GOVC_HOST"
|
||||
value := os.Getenv(env)
|
||||
usage := fmt.Sprintf("Host system [%s]", env)
|
||||
|
@ -48,7 +65,20 @@ func (flag *HostSystemFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *HostSystemFlag) Process() error { return nil }
|
||||
func (flag *HostSystemFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.SearchFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *HostSystemFlag) HostSystemIfSpecified() (*object.HostSystem, error) {
|
||||
if flag.host != nil {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,7 +20,6 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
@ -28,21 +27,33 @@ import (
|
|||
)
|
||||
|
||||
type NetworkFlag struct {
|
||||
common
|
||||
|
||||
*DatacenterFlag
|
||||
|
||||
register sync.Once
|
||||
name string
|
||||
net object.NetworkReference
|
||||
adapter string
|
||||
address string
|
||||
name string
|
||||
net object.NetworkReference
|
||||
adapter string
|
||||
address string
|
||||
}
|
||||
|
||||
func NewNetworkFlag() *NetworkFlag {
|
||||
return &NetworkFlag{}
|
||||
var networkFlagKey = flagKey("network")
|
||||
|
||||
func NewNetworkFlag(ctx context.Context) (*NetworkFlag, context.Context) {
|
||||
if v := ctx.Value(networkFlagKey); v != nil {
|
||||
return v.(*NetworkFlag), ctx
|
||||
}
|
||||
|
||||
v := &NetworkFlag{}
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
ctx = context.WithValue(ctx, networkFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *NetworkFlag) Register(f *flag.FlagSet) {
|
||||
flag.register.Do(func() {
|
||||
func (flag *NetworkFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
env := "GOVC_NETWORK"
|
||||
value := os.Getenv(env)
|
||||
flag.Set(value)
|
||||
|
@ -53,7 +64,14 @@ func (flag *NetworkFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *NetworkFlag) Process() error { return nil }
|
||||
func (flag *NetworkFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *NetworkFlag) String() string {
|
||||
return flag.name
|
||||
|
@ -74,13 +92,11 @@ func (flag *NetworkFlag) Network() (object.NetworkReference, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if flag.name == "" {
|
||||
flag.net, err = finder.DefaultNetwork(context.TODO())
|
||||
} else {
|
||||
flag.net, err = finder.Network(context.TODO(), flag.name)
|
||||
if flag.net, err = finder.NetworkOrDefault(context.TODO(), flag.name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return flag.net, err
|
||||
return flag.net, nil
|
||||
}
|
||||
|
||||
func (flag *NetworkFlag) Device() (types.BaseVirtualDevice, error) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 flags
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type optionalBool struct {
|
||||
val **bool
|
||||
}
|
||||
|
||||
func (b *optionalBool) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
*b.val = &v
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *optionalBool) Get() interface{} {
|
||||
if *b.val == nil {
|
||||
return nil
|
||||
}
|
||||
return **b.val
|
||||
}
|
||||
|
||||
func (b *optionalBool) String() string {
|
||||
if *b.val == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("%v", **b.val)
|
||||
}
|
||||
|
||||
func (b *optionalBool) IsBoolFlag() bool { return true }
|
||||
|
||||
// NewOptionalBool returns a flag.Value implementation where there is no default value.
|
||||
// This avoids sending a default value over the wire as using flag.BoolVar() would.
|
||||
func NewOptionalBool(v **bool) flag.Value {
|
||||
return &optionalBool{v}
|
||||
}
|
|
@ -25,6 +25,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/progress"
|
||||
)
|
||||
|
||||
|
@ -33,21 +35,39 @@ type OutputWriter interface {
|
|||
}
|
||||
|
||||
type OutputFlag struct {
|
||||
common
|
||||
|
||||
JSON bool
|
||||
TTY bool
|
||||
}
|
||||
|
||||
func (flag *OutputFlag) Register(f *flag.FlagSet) {
|
||||
f.BoolVar(&flag.JSON, "json", false, "Enable JSON output")
|
||||
}
|
||||
var outputFlagKey = flagKey("output")
|
||||
|
||||
func (flag *OutputFlag) Process() error {
|
||||
if !flag.JSON {
|
||||
// Assume we have a tty if not outputting JSON
|
||||
flag.TTY = true
|
||||
func NewOutputFlag(ctx context.Context) (*OutputFlag, context.Context) {
|
||||
if v := ctx.Value(outputFlagKey); v != nil {
|
||||
return v.(*OutputFlag), ctx
|
||||
}
|
||||
|
||||
return nil
|
||||
v := &OutputFlag{}
|
||||
ctx = context.WithValue(ctx, outputFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *OutputFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
f.BoolVar(&flag.JSON, "json", false, "Enable JSON output")
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *OutputFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if !flag.JSON {
|
||||
// Assume we have a tty if not outputting JSON
|
||||
flag.TTY = true
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Log outputs the specified string, prefixed with the current time.
|
||||
|
@ -81,8 +101,7 @@ func (flag *OutputFlag) WriteResult(result OutputWriter) error {
|
|||
var out = os.Stdout
|
||||
|
||||
if flag.JSON {
|
||||
enc := json.NewEncoder(out)
|
||||
err = enc.Encode(result)
|
||||
err = json.NewEncoder(out).Encode(result)
|
||||
} else {
|
||||
err = result.Write(out)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,22 +20,37 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type ResourcePoolFlag struct {
|
||||
common
|
||||
|
||||
*DatacenterFlag
|
||||
|
||||
register sync.Once
|
||||
name string
|
||||
pool *object.ResourcePool
|
||||
name string
|
||||
pool *object.ResourcePool
|
||||
}
|
||||
|
||||
func (flag *ResourcePoolFlag) Register(f *flag.FlagSet) {
|
||||
flag.register.Do(func() {
|
||||
var resourcePoolFlagKey = flagKey("resourcePool")
|
||||
|
||||
func NewResourcePoolFlag(ctx context.Context) (*ResourcePoolFlag, context.Context) {
|
||||
if v := ctx.Value(resourcePoolFlagKey); v != nil {
|
||||
return v.(*ResourcePoolFlag), ctx
|
||||
}
|
||||
|
||||
v := &ResourcePoolFlag{}
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
ctx = context.WithValue(ctx, resourcePoolFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *ResourcePoolFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
env := "GOVC_RESOURCE_POOL"
|
||||
value := os.Getenv(env)
|
||||
usage := fmt.Sprintf("Resource pool [%s]", env)
|
||||
|
@ -43,7 +58,14 @@ func (flag *ResourcePoolFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *ResourcePoolFlag) Process() error { return nil }
|
||||
func (flag *ResourcePoolFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *ResourcePoolFlag) ResourcePool() (*object.ResourcePool, error) {
|
||||
if flag.pool != nil {
|
||||
|
@ -55,11 +77,9 @@ func (flag *ResourcePoolFlag) ResourcePool() (*object.ResourcePool, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if flag.name == "" {
|
||||
flag.pool, err = finder.DefaultResourcePool(context.TODO())
|
||||
} else {
|
||||
flag.pool, err = finder.ResourcePool(context.TODO(), flag.name)
|
||||
if flag.pool, err = finder.ResourcePoolOrDefault(context.TODO(), flag.name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return flag.pool, err
|
||||
return flag.pool, nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -22,6 +22,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/find"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"golang.org/x/net/context"
|
||||
|
@ -30,9 +31,12 @@ import (
|
|||
const (
|
||||
SearchVirtualMachines = iota + 1
|
||||
SearchHosts
|
||||
SearchVirtualApps
|
||||
)
|
||||
|
||||
type SearchFlag struct {
|
||||
common
|
||||
|
||||
*ClientFlag
|
||||
*DatacenterFlag
|
||||
|
||||
|
@ -48,65 +52,91 @@ type SearchFlag struct {
|
|||
isset bool
|
||||
}
|
||||
|
||||
func NewSearchFlag(t int) *SearchFlag {
|
||||
s := SearchFlag{
|
||||
var searchFlagKey = flagKey("search")
|
||||
|
||||
func NewSearchFlag(ctx context.Context, t int) (*SearchFlag, context.Context) {
|
||||
if v := ctx.Value(searchFlagKey); v != nil {
|
||||
return v.(*SearchFlag), ctx
|
||||
}
|
||||
|
||||
v := &SearchFlag{
|
||||
t: t,
|
||||
}
|
||||
|
||||
v.ClientFlag, ctx = NewClientFlag(ctx)
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
|
||||
switch t {
|
||||
case SearchVirtualMachines:
|
||||
s.entity = "VM"
|
||||
v.entity = "VM"
|
||||
case SearchHosts:
|
||||
s.entity = "host"
|
||||
v.entity = "host"
|
||||
case SearchVirtualApps:
|
||||
v.entity = "vapp"
|
||||
default:
|
||||
panic("invalid search type")
|
||||
}
|
||||
|
||||
return &s
|
||||
ctx = context.WithValue(ctx, searchFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *SearchFlag) Register(fs *flag.FlagSet) {
|
||||
register := func(v *string, f string, d string) {
|
||||
f = fmt.Sprintf("%s.%s", strings.ToLower(flag.entity), f)
|
||||
d = fmt.Sprintf(d, flag.entity)
|
||||
fs.StringVar(v, f, "", d)
|
||||
}
|
||||
func (flag *SearchFlag) Register(ctx context.Context, fs *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.ClientFlag.Register(ctx, fs)
|
||||
flag.DatacenterFlag.Register(ctx, fs)
|
||||
|
||||
switch flag.t {
|
||||
case SearchVirtualMachines:
|
||||
register(&flag.byDatastorePath, "path", "Find %s by path to .vmx file")
|
||||
}
|
||||
|
||||
switch flag.t {
|
||||
case SearchVirtualMachines, SearchHosts:
|
||||
register(&flag.byDNSName, "dns", "Find %s by FQDN")
|
||||
register(&flag.byIP, "ip", "Find %s by IP address")
|
||||
register(&flag.byUUID, "uuid", "Find %s by instance UUID")
|
||||
}
|
||||
|
||||
register(&flag.byInventoryPath, "ipath", "Find %s by inventory path")
|
||||
}
|
||||
|
||||
func (flag *SearchFlag) Process() error {
|
||||
flags := []string{
|
||||
flag.byDatastorePath,
|
||||
flag.byDNSName,
|
||||
flag.byInventoryPath,
|
||||
flag.byIP,
|
||||
flag.byUUID,
|
||||
}
|
||||
|
||||
flag.isset = false
|
||||
for _, f := range flags {
|
||||
if f != "" {
|
||||
if flag.isset {
|
||||
return errors.New("cannot use more than one search flag")
|
||||
}
|
||||
flag.isset = true
|
||||
register := func(v *string, f string, d string) {
|
||||
f = fmt.Sprintf("%s.%s", strings.ToLower(flag.entity), f)
|
||||
d = fmt.Sprintf(d, flag.entity)
|
||||
fs.StringVar(v, f, "", d)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
switch flag.t {
|
||||
case SearchVirtualMachines:
|
||||
register(&flag.byDatastorePath, "path", "Find %s by path to .vmx file")
|
||||
}
|
||||
|
||||
switch flag.t {
|
||||
case SearchVirtualMachines, SearchHosts:
|
||||
register(&flag.byDNSName, "dns", "Find %s by FQDN")
|
||||
register(&flag.byIP, "ip", "Find %s by IP address")
|
||||
register(&flag.byUUID, "uuid", "Find %s by instance UUID")
|
||||
}
|
||||
|
||||
register(&flag.byInventoryPath, "ipath", "Find %s by inventory path")
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *SearchFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flags := []string{
|
||||
flag.byDatastorePath,
|
||||
flag.byDNSName,
|
||||
flag.byInventoryPath,
|
||||
flag.byIP,
|
||||
flag.byUUID,
|
||||
}
|
||||
|
||||
flag.isset = false
|
||||
for _, f := range flags {
|
||||
if f != "" {
|
||||
if flag.isset {
|
||||
return errors.New("cannot use more than one search flag")
|
||||
}
|
||||
flag.isset = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *SearchFlag) IsSet() bool {
|
||||
|
@ -156,9 +186,9 @@ func (flag *SearchFlag) searchByIP(c *vim25.Client, dc *object.Datacenter) (obje
|
|||
func (flag *SearchFlag) searchByUUID(c *vim25.Client, dc *object.Datacenter) (object.Reference, error) {
|
||||
switch flag.t {
|
||||
case SearchVirtualMachines:
|
||||
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, true)
|
||||
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, true, nil)
|
||||
case SearchHosts:
|
||||
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, false)
|
||||
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, false, nil)
|
||||
default:
|
||||
panic("unsupported type")
|
||||
}
|
||||
|
@ -241,16 +271,73 @@ func (flag *SearchFlag) VirtualMachines(args []string) ([]*object.VirtualMachine
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var nfe error
|
||||
|
||||
// List virtual machines for every argument
|
||||
for _, arg := range args {
|
||||
vms, err := finder.VirtualMachineList(context.TODO(), arg)
|
||||
if err != nil {
|
||||
if _, ok := err.(*find.NotFoundError); ok {
|
||||
// Let caller decide how to handle NotFoundError
|
||||
nfe = err
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, vms...)
|
||||
}
|
||||
|
||||
return out, nfe
|
||||
}
|
||||
|
||||
func (flag *SearchFlag) VirtualApp() (*object.VirtualApp, error) {
|
||||
ref, err := flag.search()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
app, ok := ref.(*object.VirtualApp)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected VirtualApp entity, got %s", ref.Reference().Type)
|
||||
}
|
||||
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func (flag *SearchFlag) VirtualApps(args []string) ([]*object.VirtualApp, error) {
|
||||
var out []*object.VirtualApp
|
||||
|
||||
if flag.IsSet() {
|
||||
app, err := flag.VirtualApp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, app)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// List virtual apps
|
||||
if len(args) == 0 {
|
||||
return nil, errors.New("no argument")
|
||||
}
|
||||
|
||||
finder, err := flag.Finder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// List virtual apps for every argument
|
||||
for _, arg := range args {
|
||||
apps, err := finder.VirtualAppList(context.TODO(), arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, apps...)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
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 flags
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type VirtualAppFlag struct {
|
||||
common
|
||||
|
||||
*DatacenterFlag
|
||||
*SearchFlag
|
||||
|
||||
name string
|
||||
app *object.VirtualApp
|
||||
}
|
||||
|
||||
var virtualAppFlagKey = flagKey("virtualApp")
|
||||
|
||||
func NewVirtualAppFlag(ctx context.Context) (*VirtualAppFlag, context.Context) {
|
||||
if v := ctx.Value(virtualAppFlagKey); v != nil {
|
||||
return v.(*VirtualAppFlag), ctx
|
||||
}
|
||||
|
||||
v := &VirtualAppFlag{}
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
v.SearchFlag, ctx = NewSearchFlag(ctx, SearchVirtualApps)
|
||||
ctx = context.WithValue(ctx, virtualAppFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *VirtualAppFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.DatacenterFlag.Register(ctx, f)
|
||||
flag.SearchFlag.Register(ctx, f)
|
||||
|
||||
env := "GOVC_VAPP"
|
||||
value := os.Getenv(env)
|
||||
usage := fmt.Sprintf("Virtual App [%s]", env)
|
||||
f.StringVar(&flag.name, "vapp", value, usage)
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *VirtualAppFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.SearchFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *VirtualAppFlag) VirtualApp() (*object.VirtualApp, error) {
|
||||
if flag.app != nil {
|
||||
return flag.app, nil
|
||||
}
|
||||
|
||||
// Use search flags if specified.
|
||||
if flag.SearchFlag.IsSet() {
|
||||
app, err := flag.SearchFlag.VirtualApp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
flag.app = app
|
||||
return flag.app, nil
|
||||
}
|
||||
|
||||
// Never look for a default virtual app.
|
||||
if flag.name == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
finder, err := flag.Finder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
flag.app, err = finder.VirtualApp(context.TODO(), flag.name)
|
||||
return flag.app, err
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -20,26 +20,43 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type VirtualMachineFlag struct {
|
||||
common
|
||||
|
||||
*ClientFlag
|
||||
*DatacenterFlag
|
||||
*SearchFlag
|
||||
|
||||
register sync.Once
|
||||
name string
|
||||
vm *object.VirtualMachine
|
||||
name string
|
||||
vm *object.VirtualMachine
|
||||
}
|
||||
|
||||
func (flag *VirtualMachineFlag) Register(f *flag.FlagSet) {
|
||||
flag.SearchFlag = NewSearchFlag(SearchVirtualMachines)
|
||||
var virtualMachineFlagKey = flagKey("virtualMachine")
|
||||
|
||||
func NewVirtualMachineFlag(ctx context.Context) (*VirtualMachineFlag, context.Context) {
|
||||
if v := ctx.Value(virtualMachineFlagKey); v != nil {
|
||||
return v.(*VirtualMachineFlag), ctx
|
||||
}
|
||||
|
||||
v := &VirtualMachineFlag{}
|
||||
v.ClientFlag, ctx = NewClientFlag(ctx)
|
||||
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
|
||||
v.SearchFlag, ctx = NewSearchFlag(ctx, SearchVirtualMachines)
|
||||
ctx = context.WithValue(ctx, virtualMachineFlagKey, v)
|
||||
return v, ctx
|
||||
}
|
||||
|
||||
func (flag *VirtualMachineFlag) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
flag.RegisterOnce(func() {
|
||||
flag.ClientFlag.Register(ctx, f)
|
||||
flag.DatacenterFlag.Register(ctx, f)
|
||||
flag.SearchFlag.Register(ctx, f)
|
||||
|
||||
flag.register.Do(func() {
|
||||
env := "GOVC_VM"
|
||||
value := os.Getenv(env)
|
||||
usage := fmt.Sprintf("Virtual machine [%s]", env)
|
||||
|
@ -47,7 +64,20 @@ func (flag *VirtualMachineFlag) Register(f *flag.FlagSet) {
|
|||
})
|
||||
}
|
||||
|
||||
func (flag *VirtualMachineFlag) Process() error { return nil }
|
||||
func (flag *VirtualMachineFlag) Process(ctx context.Context) error {
|
||||
return flag.ProcessOnce(func() error {
|
||||
if err := flag.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := flag.SearchFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (flag *VirtualMachineFlag) VirtualMachine() (*object.VirtualMachine, error) {
|
||||
if flag.vm != nil {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
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
|
||||
|
@ -17,7 +18,6 @@ limitations under the License.
|
|||
package host
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
|
@ -32,63 +32,88 @@ import (
|
|||
type add struct {
|
||||
*flags.ClientFlag
|
||||
*flags.DatacenterFlag
|
||||
*flags.HostConnectFlag
|
||||
|
||||
parent string
|
||||
|
||||
host string
|
||||
username string
|
||||
password string
|
||||
connect bool
|
||||
fingerprint string
|
||||
parent string
|
||||
connect bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {
|
||||
f.StringVar(&cmd.parent, "parent", "", "Path to folder to add the host to")
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.host, "host", "", "Hostname or IP address of the host")
|
||||
f.StringVar(&cmd.username, "username", "", "Username of administration account on the host")
|
||||
f.StringVar(&cmd.password, "password", "", "Password of administration account on the host")
|
||||
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
cmd.DatacenterFlag.Register(ctx, f)
|
||||
|
||||
cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx)
|
||||
cmd.HostConnectFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.parent, "parent", "", "Path to folder to add the host to")
|
||||
f.BoolVar(&cmd.connect, "connect", true, "Immediately connect to host")
|
||||
f.StringVar(&cmd.fingerprint, "fingerprint", "", "Fingerprint of the host's SSL certificate")
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error {
|
||||
if cmd.host == "" {
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.HostConnectFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if cmd.HostName == "" {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
if cmd.username == "" {
|
||||
if cmd.UserName == "" {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
if cmd.password == "" {
|
||||
if cmd.Password == "" {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Usage() string {
|
||||
return "HOST"
|
||||
}
|
||||
|
||||
func (cmd *add) Description() string {
|
||||
return `Add HOST to datacenter.
|
||||
return `Add host to datacenter.
|
||||
|
||||
The host is added to the folder specified by the 'parent' flag. If not given,
|
||||
this defaults to the hosts folder in the specified or default datacenter.`
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
var ctx = context.Background()
|
||||
var parent *object.Folder
|
||||
func (cmd *add) Add(ctx context.Context, parent *object.Folder) error {
|
||||
spec := cmd.HostConnectSpec
|
||||
|
||||
client, err := cmd.Client()
|
||||
req := types.AddStandaloneHost_Task{
|
||||
This: parent.Reference(),
|
||||
Spec: spec,
|
||||
AddConnected: cmd.connect,
|
||||
}
|
||||
|
||||
res, err := methods.AddStandaloneHost_Task(ctx, parent.Client(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s to folder %s... ", spec.HostName, parent.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
task := object.NewTask(parent.Client(), res.Returnval)
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
var parent *object.Folder
|
||||
|
||||
if f.NArg() != 0 {
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
if cmd.parent == "" {
|
||||
dc, err := cmd.Datacenter()
|
||||
if err != nil {
|
||||
|
@ -107,59 +132,22 @@ func (cmd *add) Run(f *flag.FlagSet) error {
|
|||
return err
|
||||
}
|
||||
|
||||
mo, err := finder.ManagedObjectList(ctx, cmd.parent)
|
||||
parent, err = finder.Folder(ctx, cmd.parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(mo) == 0 {
|
||||
return errors.New("parent does not resolve to object")
|
||||
}
|
||||
|
||||
if len(mo) > 1 {
|
||||
return errors.New("parent resolves to more than one object")
|
||||
}
|
||||
|
||||
ref := mo[0].Object.Reference()
|
||||
if ref.Type != "Folder" {
|
||||
return errors.New("parent does not resolve to folder")
|
||||
}
|
||||
|
||||
parent = object.NewFolder(client, ref)
|
||||
}
|
||||
|
||||
req := types.AddStandaloneHost_Task{
|
||||
This: parent.Reference(),
|
||||
Spec: types.HostConnectSpec{
|
||||
HostName: cmd.host,
|
||||
UserName: cmd.username,
|
||||
Password: cmd.password,
|
||||
SslThumbprint: cmd.fingerprint,
|
||||
},
|
||||
AddConnected: cmd.connect,
|
||||
err := cmd.Add(ctx, parent)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res, err := methods.AddStandaloneHost_Task(ctx, client, &req)
|
||||
if err != nil {
|
||||
// Check if we failed due to SSLVerifyFault and -noverify is set
|
||||
if err := cmd.AcceptThumbprint(err); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
task := object.NewTask(client, res.Returnval)
|
||||
_, err = task.WaitForResult(ctx, nil)
|
||||
if err != nil {
|
||||
f, ok := err.(types.HasFault)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
|
||||
switch fault := f.Fault().(type) {
|
||||
case *types.SSLVerifyFault:
|
||||
// Add fingerprint to error message
|
||||
return fmt.Errorf("%s Fingerprint is %s.", err.Error(), fault.Thumbprint)
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
// Accepted unverified thumbprint, try again
|
||||
return cmd.Add(ctx, parent)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ package autostart
|
|||
import (
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
@ -31,15 +33,23 @@ func init() {
|
|||
cli.Register("host.autostart.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {}
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
|
||||
cmd.AutostartFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.AutostartFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Usage() string {
|
||||
return "VM..."
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
var powerInfo = types.AutoStartPowerInfo{
|
||||
StartAction: "powerOn",
|
||||
StartDelay: -1,
|
||||
|
|
|
@ -34,9 +34,32 @@ type AutostartFlag struct {
|
|||
*flags.HostSystemFlag
|
||||
}
|
||||
|
||||
func (f *AutostartFlag) Register(fs *flag.FlagSet) {}
|
||||
func newAutostartFlag(ctx context.Context) (*AutostartFlag, context.Context) {
|
||||
f := &AutostartFlag{}
|
||||
f.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
f.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
|
||||
f.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
return f, ctx
|
||||
}
|
||||
|
||||
func (f *AutostartFlag) Process() error { return nil }
|
||||
func (f *AutostartFlag) Register(ctx context.Context, fs *flag.FlagSet) {
|
||||
f.ClientFlag.Register(ctx, fs)
|
||||
f.DatacenterFlag.Register(ctx, fs)
|
||||
f.HostSystemFlag.Register(ctx, fs)
|
||||
}
|
||||
|
||||
func (f *AutostartFlag) Process(ctx context.Context) error {
|
||||
if err := f.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.DatacenterFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// VirtualMachines returns list of virtual machine objects based on the
|
||||
// arguments specified on the command line. This helper is defined in
|
||||
|
|
|
@ -19,41 +19,45 @@ package autostart
|
|||
import (
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type configure struct {
|
||||
*AutostartFlag
|
||||
|
||||
defaults types.AutoStartDefaults
|
||||
types.AutoStartDefaults
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.autostart.configure", &configure{})
|
||||
}
|
||||
|
||||
func (cmd *configure) Register(f *flag.FlagSet) {
|
||||
cmd.defaults.Enabled = types.NewBool(false)
|
||||
f.BoolVar(cmd.defaults.Enabled, "enabled", false, "")
|
||||
func (cmd *configure) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
|
||||
cmd.AutostartFlag.Register(ctx, f)
|
||||
|
||||
f.IntVar(&cmd.defaults.StartDelay, "start-delay", 0, "")
|
||||
f.StringVar(&cmd.defaults.StopAction, "stop-action", "", "")
|
||||
f.IntVar(&cmd.defaults.StopDelay, "stop-delay", 0, "")
|
||||
|
||||
cmd.defaults.WaitForHeartbeat = types.NewBool(false)
|
||||
f.BoolVar(cmd.defaults.WaitForHeartbeat, "wait-for-heartbeat", false, "")
|
||||
f.Var(flags.NewOptionalBool(&cmd.Enabled), "enabled", "")
|
||||
f.IntVar(&cmd.StartDelay, "start-delay", 0, "")
|
||||
f.StringVar(&cmd.StopAction, "stop-action", "", "")
|
||||
f.IntVar(&cmd.StopDelay, "stop-delay", 0, "")
|
||||
f.Var(flags.NewOptionalBool(&cmd.WaitForHeartbeat), "wait-for-heartbeat", "")
|
||||
}
|
||||
|
||||
func (cmd *configure) Process() error { return nil }
|
||||
func (cmd *configure) Process(ctx context.Context) error {
|
||||
if err := cmd.AutostartFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *configure) Usage() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (cmd *configure) Run(f *flag.FlagSet) error {
|
||||
// Note: this command cannot DISABLE autostart because the "Enabled" field is
|
||||
// marked "omitempty", which means that it is not included when it is false.
|
||||
// Also see: https://github.com/vmware/govmomi/issues/240
|
||||
return cmd.ReconfigureDefaults(cmd.defaults)
|
||||
func (cmd *configure) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
return cmd.ReconfigureDefaults(cmd.AutoStartDefaults)
|
||||
}
|
||||
|
|
|
@ -32,8 +32,9 @@ import (
|
|||
)
|
||||
|
||||
type info struct {
|
||||
*AutostartFlag
|
||||
cli.Command
|
||||
|
||||
*AutostartFlag
|
||||
*flags.OutputFlag
|
||||
}
|
||||
|
||||
|
@ -41,15 +42,28 @@ func init() {
|
|||
cli.Register("host.autostart.info", &info{})
|
||||
}
|
||||
|
||||
func (cmd *info) Register(f *flag.FlagSet) {}
|
||||
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
|
||||
cmd.AutostartFlag.Register(ctx, f)
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *info) Process() error { return nil }
|
||||
func (cmd *info) Process(ctx context.Context) error {
|
||||
if err := cmd.AutostartFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *info) Usage() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (cmd *info) Run(f *flag.FlagSet) error {
|
||||
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
client, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -19,6 +19,8 @@ package autostart
|
|||
import (
|
||||
"flag"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
@ -31,15 +33,23 @@ func init() {
|
|||
cli.Register("host.autostart.remove", &remove{})
|
||||
}
|
||||
|
||||
func (cmd *remove) Register(f *flag.FlagSet) {}
|
||||
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
|
||||
cmd.AutostartFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *remove) Process() error { return nil }
|
||||
func (cmd *remove) Process(ctx context.Context) error {
|
||||
if err := cmd.AutostartFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *remove) Usage() string {
|
||||
return "VM..."
|
||||
}
|
||||
|
||||
func (cmd *remove) Run(f *flag.FlagSet) error {
|
||||
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
var powerInfo = types.AutoStartPowerInfo{
|
||||
StartAction: "none",
|
||||
StartDelay: -1,
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
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 host
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
)
|
||||
|
||||
type disconnect struct {
|
||||
*flags.HostSystemFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.disconnect", &disconnect{})
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Description() string {
|
||||
return `Disconnect host from vCenter and instruct the host to stop sending heartbeats.`
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Disconnect(ctx context.Context, host *object.HostSystem) error {
|
||||
task, err := host.Disconnect(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("%s disconnecting... ", host.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *disconnect) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
err = cmd.Disconnect(ctx, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -24,6 +24,8 @@ import (
|
|||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
)
|
||||
|
@ -42,13 +44,21 @@ func (cmd *esxcli) Usage() string {
|
|||
return "COMMAND [ARG]..."
|
||||
}
|
||||
|
||||
func (cmd *esxcli) Register(f *flag.FlagSet) {
|
||||
func (cmd *esxcli) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.hints, "hints", true, "Use command info hints when formatting output")
|
||||
}
|
||||
|
||||
func (cmd *esxcli) Process() error { return nil }
|
||||
func (cmd *esxcli) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *esxcli) Run(f *flag.FlagSet) error {
|
||||
func (cmd *esxcli) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return nil
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
|
45
vendor/github.com/vmware/govmomi/govc/host/esxcli/firewall_info.go
generated
vendored
Normal file
45
vendor/github.com/vmware/govmomi/govc/host/esxcli/firewall_info.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
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 esxcli
|
||||
|
||||
import "github.com/vmware/govmomi/object"
|
||||
|
||||
type FirewallInfo struct {
|
||||
Loaded bool
|
||||
Enabled bool
|
||||
DefaultAction string
|
||||
}
|
||||
|
||||
// GetFirewallInfo via 'esxcli network firewall get'
|
||||
// The HostFirewallSystem type does not expose this data.
|
||||
// This helper can be useful in particular to determine if the firewall is enabled or disabled.
|
||||
func GetFirewallInfo(s *object.HostSystem) (*FirewallInfo, error) {
|
||||
x, err := NewExecutor(s.Client(), s)
|
||||
|
||||
res, err := x.Run([]string{"network", "firewall", "get"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := &FirewallInfo{
|
||||
Loaded: res.Values[0]["Loaded"][0] == "true",
|
||||
Enabled: res.Values[0]["Enabled"][0] == "true",
|
||||
DefaultAction: res.Values[0]["DefaultAction"][0],
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
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 esxcli
|
||||
|
||||
import (
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
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 firewall
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/govc/host/esxcli"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type find struct {
|
||||
*flags.ClientFlag
|
||||
*flags.OutputFlag
|
||||
*flags.HostSystemFlag
|
||||
|
||||
enabled bool
|
||||
check bool
|
||||
|
||||
types.HostFirewallRule
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("firewall.ruleset.find", &find{})
|
||||
}
|
||||
|
||||
func (cmd *find) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
f.BoolVar(&cmd.check, "c", true, "Check if esx firewall is enabled")
|
||||
f.BoolVar(&cmd.enabled, "enabled", true, "Find enabled rule sets if true, disabled if false")
|
||||
f.StringVar((*string)(&cmd.Direction), "direction", string(types.HostFirewallRuleDirectionOutbound), "Direction")
|
||||
f.StringVar((*string)(&cmd.PortType), "type", string(types.HostFirewallRulePortTypeDst), "Port type")
|
||||
f.StringVar((*string)(&cmd.Protocol), "proto", string(types.HostFirewallRuleProtocolTcp), "Protocol")
|
||||
f.IntVar(&cmd.Port, "port", 0, "Port")
|
||||
}
|
||||
|
||||
func (cmd *find) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *find) Description() string {
|
||||
return `Find firewall rulesets matching the given rule.
|
||||
|
||||
For a complete list of rulesets: govc host.esxcli network firewall ruleset list
|
||||
For a complete list of rules: govc host.esxcli network firewall ruleset rule list`
|
||||
}
|
||||
|
||||
func (cmd *find) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
host, err := cmd.HostSystem()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fs, err := host.ConfigManager().FirewallSystem(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.check {
|
||||
esxfw, err := esxcli.GetFirewallInfo(host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !esxfw.Enabled {
|
||||
fmt.Fprintln(os.Stderr, "host firewall is disabled")
|
||||
}
|
||||
}
|
||||
|
||||
info, err := fs.Info(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.NArg() != 0 {
|
||||
// TODO: f.Args() -> types.HostFirewallRulesetIpList
|
||||
return flag.ErrHelp
|
||||
}
|
||||
|
||||
rs := object.HostFirewallRulesetList(info.Ruleset)
|
||||
matched, err := rs.EnabledByRule(cmd.HostFirewallRule, cmd.enabled)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, r := range matched {
|
||||
fmt.Println(r.Key)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -23,12 +23,14 @@ import (
|
|||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"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/mo"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type info struct {
|
||||
|
@ -41,73 +43,100 @@ func init() {
|
|||
cli.Register("host.info", &info{})
|
||||
}
|
||||
|
||||
func (c *info) Register(f *flag.FlagSet) {}
|
||||
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
|
||||
cmd.ClientFlag.Register(ctx, f)
|
||||
|
||||
func (c *info) Process() error { return nil }
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
|
||||
func (c *info) Run(f *flag.FlagSet) error {
|
||||
client, err := c.Client()
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *info) Process(ctx context.Context) error {
|
||||
if err := cmd.ClientFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
c, err := cmd.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hosts []*object.HostSystem
|
||||
var res infoResult
|
||||
var props []string
|
||||
|
||||
if cmd.OutputFlag.JSON {
|
||||
props = nil // Load everything
|
||||
} else {
|
||||
props = []string{"summary"} // Load summary
|
||||
}
|
||||
|
||||
// We could do without the -host flag, leaving it for compat
|
||||
host, err := c.HostSystemIfSpecified()
|
||||
host, err := cmd.HostSystemIfSpecified()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Default only if there is a single host
|
||||
if host == nil && f.NArg() == 0 {
|
||||
host, err = c.HostSystem()
|
||||
host, err = cmd.HostSystem()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if host != nil {
|
||||
hosts = append(hosts, host)
|
||||
res.objects = append(res.objects, host)
|
||||
} else {
|
||||
hosts, err = c.HostSystems(f.Args())
|
||||
res.objects, err = cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var res infoResult
|
||||
var props []string
|
||||
if len(res.objects) != 0 {
|
||||
refs := make([]types.ManagedObjectReference, 0, len(res.objects))
|
||||
for _, o := range res.objects {
|
||||
refs = append(refs, o.Reference())
|
||||
}
|
||||
|
||||
if c.OutputFlag.JSON {
|
||||
props = nil // Load everything
|
||||
} else {
|
||||
props = []string{"summary"} // Load summary
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
var h mo.HostSystem
|
||||
|
||||
pc := property.DefaultCollector(client)
|
||||
err = pc.RetrieveOne(context.TODO(), host.Reference(), props, &h)
|
||||
pc := property.DefaultCollector(c)
|
||||
err = pc.Retrieve(ctx, refs, props, &res.HostSystems)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res.HostSystems = append(res.HostSystems, h)
|
||||
}
|
||||
|
||||
return c.WriteResult(&res)
|
||||
return cmd.WriteResult(&res)
|
||||
}
|
||||
|
||||
type infoResult struct {
|
||||
HostSystems []mo.HostSystem
|
||||
objects []*object.HostSystem
|
||||
}
|
||||
|
||||
func (r *infoResult) Write(w io.Writer) error {
|
||||
// Maintain order via r.objects as Property collector does not always return results in order.
|
||||
objects := make(map[types.ManagedObjectReference]mo.HostSystem, len(r.HostSystems))
|
||||
for _, o := range r.HostSystems {
|
||||
objects[o.Reference()] = o
|
||||
}
|
||||
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
|
||||
|
||||
for _, host := range r.HostSystems {
|
||||
for _, o := range r.objects {
|
||||
host := objects[o.Reference()]
|
||||
s := host.Summary
|
||||
h := s.Hardware
|
||||
z := s.QuickStats
|
||||
|
@ -116,6 +145,7 @@ func (r *infoResult) Write(w io.Writer) error {
|
|||
memUsage := 100 * float64(z.OverallMemoryUsage<<20) / float64(h.MemorySize)
|
||||
|
||||
fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name)
|
||||
fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath)
|
||||
fmt.Fprintf(tw, " Manufacturer:\t%s\n", h.Vendor)
|
||||
fmt.Fprintf(tw, " Logical CPUs:\t%d CPUs @ %dMHz\n", ncpu, h.CpuMhz)
|
||||
fmt.Fprintf(tw, " Processor type:\t%s\n", h.CpuModel)
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
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 maintenancec
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
)
|
||||
|
||||
type enter struct {
|
||||
*flags.HostSystemFlag
|
||||
|
||||
timeout int
|
||||
evacuate bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.maintenance.enter", &enter{})
|
||||
}
|
||||
|
||||
func (cmd *enter) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
f.IntVar(&cmd.timeout, "timeout", 0, "Timeout")
|
||||
f.BoolVar(&cmd.evacuate, "evacuate", false, "Evacuate powered off VMs")
|
||||
}
|
||||
|
||||
func (cmd *enter) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *enter) Usage() string {
|
||||
return "HOST..."
|
||||
}
|
||||
|
||||
func (cmd *enter) Description() string {
|
||||
return `Put the hosts in maintenance mode.
|
||||
|
||||
While this task is running and when the host is in maintenance mode,
|
||||
no virtual machines can be powered on and no provisioning operations can be performed on the host.`
|
||||
}
|
||||
|
||||
func (cmd *enter) EnterMaintenanceMode(ctx context.Context, host *object.HostSystem) error {
|
||||
task, err := host.EnterMaintenanceMode(ctx, cmd.timeout, cmd.evacuate, nil) // TODO: spec param
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("%s entering maintenance mode... ", host.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *enter) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
err = cmd.EnterMaintenanceMode(ctx, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -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 maintenancec
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
)
|
||||
|
||||
type exit struct {
|
||||
*flags.HostSystemFlag
|
||||
|
||||
timeout int
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.maintenance.exit", &exit{})
|
||||
}
|
||||
|
||||
func (cmd *exit) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
f.IntVar(&cmd.timeout, "timeout", 0, "Timeout")
|
||||
}
|
||||
|
||||
func (cmd *exit) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *exit) Usage() string {
|
||||
return "HOST..."
|
||||
}
|
||||
|
||||
func (cmd *exit) Description() string {
|
||||
return `Take hosts out of maintenance mode.
|
||||
|
||||
This blocks if any concurrent running maintenance-only host configurations operations are being performed.
|
||||
For example, if VMFS volumes are being upgraded.
|
||||
|
||||
The 'timeout' flag is the number of seconds to wait for the exit maintenance mode to succeed.
|
||||
If the timeout is less than or equal to zero, there is no timeout.`
|
||||
}
|
||||
|
||||
func (cmd *exit) ExitMaintenanceMode(ctx context.Context, host *object.HostSystem) error {
|
||||
task, err := host.ExitMaintenanceMode(ctx, cmd.timeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("%s exiting maintenance mode... ", host.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *exit) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
err = cmd.ExitMaintenanceMode(ctx, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -35,18 +35,26 @@ func init() {
|
|||
cli.Register("host.portgroup.add", &add{})
|
||||
}
|
||||
|
||||
func (cmd *add) Register(f *flag.FlagSet) {
|
||||
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
f.StringVar(&cmd.spec.VswitchName, "vswitch", "", "vSwitch Name")
|
||||
f.IntVar(&cmd.spec.VlanId, "vlan", 0, "VLAN ID")
|
||||
}
|
||||
|
||||
func (cmd *add) Process() error { return nil }
|
||||
func (cmd *add) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *add) Usage() string {
|
||||
return "NAME"
|
||||
}
|
||||
|
||||
func (cmd *add) Run(f *flag.FlagSet) error {
|
||||
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
ns, err := cmd.HostNetworkSystem()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
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.
|
||||
|
@ -32,15 +32,23 @@ func init() {
|
|||
cli.Register("host.portgroup.remove", &remove{})
|
||||
}
|
||||
|
||||
func (cmd *remove) Register(f *flag.FlagSet) {}
|
||||
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *remove) Process() error { return nil }
|
||||
func (cmd *remove) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *remove) Usage() string {
|
||||
return "NAME"
|
||||
}
|
||||
|
||||
func (cmd *remove) Run(f *flag.FlagSet) error {
|
||||
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
ns, err := cmd.HostNetworkSystem()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
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 host
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type reconnect struct {
|
||||
*flags.HostSystemFlag
|
||||
*flags.HostConnectFlag
|
||||
|
||||
types.HostSystemReconnectSpec
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.reconnect", &reconnect{})
|
||||
}
|
||||
|
||||
func (cmd *reconnect) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
|
||||
cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx)
|
||||
cmd.HostConnectFlag.Register(ctx, f)
|
||||
|
||||
cmd.HostSystemReconnectSpec.SyncState = types.NewBool(false)
|
||||
f.BoolVar(cmd.HostSystemReconnectSpec.SyncState, "sync-state", false, "Sync state")
|
||||
}
|
||||
|
||||
func (cmd *reconnect) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.HostConnectFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *reconnect) Description() string {
|
||||
return `Reconnect host to vCenter.
|
||||
|
||||
This command can also be used to change connection properties (hostname, fingerprint, username, password),
|
||||
without disconnecting the host.`
|
||||
}
|
||||
|
||||
func (cmd *reconnect) Reconnect(ctx context.Context, host *object.HostSystem) error {
|
||||
task, err := host.Reconnect(ctx, &cmd.HostConnectSpec, &cmd.HostSystemReconnectSpec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("%s reconnecting... ", host.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *reconnect) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
err = cmd.Reconnect(ctx, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
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 host
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
)
|
||||
|
||||
type remove struct {
|
||||
*flags.HostSystemFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.remove", &remove{})
|
||||
}
|
||||
|
||||
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *remove) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *remove) Usage() string {
|
||||
return "HOST..."
|
||||
}
|
||||
|
||||
func (cmd *remove) Description() string {
|
||||
return `Remove hosts from vCenter.`
|
||||
}
|
||||
|
||||
func (cmd *remove) Remove(ctx context.Context, host *object.HostSystem) error {
|
||||
var h mo.HostSystem
|
||||
err := host.Properties(ctx, host.Reference(), []string{"parent"}, &h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remove := host.Destroy
|
||||
|
||||
if h.Parent.Type == "ComputeResource" {
|
||||
// Standalone host. From the docs:
|
||||
// "Invoking remove on a HostSystem of standalone type throws a NotSupported fault.
|
||||
// A standalone HostSystem can be removeed only by invoking remove on its parent ComputeResource."
|
||||
remove = object.NewComputeResource(host.Client(), *h.Parent).Destroy
|
||||
}
|
||||
|
||||
task, err := remove(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := cmd.ProgressLogger(fmt.Sprintf("%s removing... ", host.InventoryPath))
|
||||
defer logger.Wait()
|
||||
|
||||
_, err = task.WaitForResult(ctx, logger)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
hosts, err := cmd.HostSystems(f.Args())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
err = cmd.Remove(ctx, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
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 storage
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/units"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var infoTypes = []string{"hba", "lun"}
|
||||
|
||||
type infoType string
|
||||
|
||||
func (t *infoType) Set(s string) error {
|
||||
s = strings.ToLower(s)
|
||||
|
||||
for _, e := range infoTypes {
|
||||
if s == e {
|
||||
*t = infoType(s)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid type")
|
||||
}
|
||||
|
||||
func (t *infoType) String() string {
|
||||
return string(*t)
|
||||
}
|
||||
|
||||
func (t *infoType) Result(hss mo.HostStorageSystem) flags.OutputWriter {
|
||||
switch string(*t) {
|
||||
case "hba":
|
||||
return hbaResult(hss)
|
||||
case "lun":
|
||||
return lunResult(hss)
|
||||
default:
|
||||
panic("unsupported")
|
||||
}
|
||||
}
|
||||
|
||||
type info struct {
|
||||
*flags.HostSystemFlag
|
||||
*flags.OutputFlag
|
||||
|
||||
typ infoType
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.storage.info", &info{})
|
||||
}
|
||||
|
||||
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
|
||||
err := cmd.typ.Set("lun")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.Var(&cmd.typ, "t", fmt.Sprintf("Type (%s)", strings.Join(infoTypes, ",")))
|
||||
}
|
||||
|
||||
func (cmd *info) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *info) Usage() string {
|
||||
return "[-t TYPE]"
|
||||
}
|
||||
|
||||
func (cmd *info) Description() string {
|
||||
return `Show information about a host's storage system.`
|
||||
}
|
||||
|
||||
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
host, err := cmd.HostSystem()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ss, err := host.ConfigManager().StorageSystem(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hss mo.HostStorageSystem
|
||||
err = ss.Properties(ctx, ss.Reference(), nil, &hss)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd.WriteResult(cmd.typ.Result(hss))
|
||||
}
|
||||
|
||||
type hbaResult mo.HostStorageSystem
|
||||
|
||||
func (r hbaResult) Write(w io.Writer) error {
|
||||
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
|
||||
|
||||
fmt.Fprintf(tw, "Device\t")
|
||||
fmt.Fprintf(tw, "PCI\t")
|
||||
fmt.Fprintf(tw, "Driver\t")
|
||||
fmt.Fprintf(tw, "Status\t")
|
||||
fmt.Fprintf(tw, "Model\t")
|
||||
fmt.Fprintf(tw, "\n")
|
||||
|
||||
for _, e := range r.StorageDeviceInfo.HostBusAdapter {
|
||||
hba := e.GetHostHostBusAdapter()
|
||||
|
||||
fmt.Fprintf(tw, "%s\t", hba.Device)
|
||||
fmt.Fprintf(tw, "%s\t", hba.Pci)
|
||||
fmt.Fprintf(tw, "%s\t", hba.Driver)
|
||||
fmt.Fprintf(tw, "%s\t", hba.Status)
|
||||
fmt.Fprintf(tw, "%s\t", hba.Model)
|
||||
fmt.Fprintf(tw, "\n")
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
}
|
||||
|
||||
type lunResult mo.HostStorageSystem
|
||||
|
||||
func (r lunResult) Write(w io.Writer) error {
|
||||
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
|
||||
|
||||
fmt.Fprintf(tw, "Name\t")
|
||||
fmt.Fprintf(tw, "Type\t")
|
||||
fmt.Fprintf(tw, "Capacity\t")
|
||||
fmt.Fprintf(tw, "Model\t")
|
||||
fmt.Fprintf(tw, "\n")
|
||||
|
||||
for _, e := range r.StorageDeviceInfo.ScsiLun {
|
||||
var capacity int64
|
||||
|
||||
lun := e.GetScsiLun()
|
||||
if disk, ok := e.(*types.HostScsiDisk); ok {
|
||||
capacity = int64(disk.Capacity.Block) * int64(disk.Capacity.BlockSize)
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "%s\t", lun.DeviceName)
|
||||
fmt.Fprintf(tw, "%s\t", lun.DeviceType)
|
||||
|
||||
if capacity == 0 {
|
||||
fmt.Fprintf(tw, "-\t")
|
||||
} else {
|
||||
fmt.Fprintf(tw, "%s\t", units.ByteSize(capacity))
|
||||
}
|
||||
|
||||
fmt.Fprintf(tw, "%s\t", lun.Model)
|
||||
fmt.Fprintf(tw, "\n")
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
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 storage
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"text/tabwriter"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/vmware/govmomi/govc/cli"
|
||||
"github.com/vmware/govmomi/govc/flags"
|
||||
"github.com/vmware/govmomi/units"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type partition struct {
|
||||
*flags.HostSystemFlag
|
||||
*flags.OutputFlag
|
||||
}
|
||||
|
||||
func init() {
|
||||
cli.Register("host.storage.partition", &partition{})
|
||||
}
|
||||
|
||||
func (cmd *partition) Register(ctx context.Context, f *flag.FlagSet) {
|
||||
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
|
||||
cmd.HostSystemFlag.Register(ctx, f)
|
||||
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
|
||||
cmd.OutputFlag.Register(ctx, f)
|
||||
}
|
||||
|
||||
func (cmd *partition) Process(ctx context.Context) error {
|
||||
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cmd.OutputFlag.Process(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd *partition) Usage() string {
|
||||
return "DEVICE_PATH"
|
||||
}
|
||||
|
||||
func (cmd *partition) Description() string {
|
||||
return `Show partition table for device at DEVICE_PATH.`
|
||||
}
|
||||
|
||||
func (cmd *partition) Run(ctx context.Context, f *flag.FlagSet) error {
|
||||
if f.NArg() != 1 {
|
||||
return fmt.Errorf("specify device path")
|
||||
}
|
||||
|
||||
path := f.Args()[0]
|
||||
|
||||
host, err := cmd.HostSystem()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ss, err := host.ConfigManager().StorageSystem(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hss mo.HostStorageSystem
|
||||
err = ss.Properties(ctx, ss.Reference(), nil, &hss)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
info, err := ss.RetrieveDiskPartitionInfo(ctx, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmd.WriteResult(partitionInfo(*info))
|
||||
}
|
||||
|
||||
type partitionInfo types.HostDiskPartitionInfo
|
||||
|
||||
func (p partitionInfo) Write(w io.Writer) error {
|
||||
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
|
||||
|
||||
fmt.Fprintf(tw, "Table format: %s\n", p.Spec.PartitionFormat)
|
||||
fmt.Fprintf(tw, "Number of sectors: %d\n", p.Spec.TotalSectors)
|
||||
fmt.Fprintf(tw, "\n")
|
||||
|
||||
fmt.Fprintf(tw, "Number\t")
|
||||
fmt.Fprintf(tw, "Start\t")
|
||||
fmt.Fprintf(tw, "End\t")
|
||||
fmt.Fprintf(tw, "Size\t")
|
||||
fmt.Fprintf(tw, "Type\t")
|
||||
fmt.Fprintf(tw, "\n")
|
||||
|
||||
for _, e := range p.Spec.Partition {
|
||||
sectors := e.EndSector - e.StartSector
|
||||
|
||||
fmt.Fprintf(tw, "%d\t", e.Partition)
|
||||
fmt.Fprintf(tw, "%d\t", e.StartSector)
|
||||
fmt.Fprintf(tw, "%d\t", e.EndSector)
|
||||
fmt.Fprintf(tw, "%s\t", units.ByteSize(sectors*512))
|
||||
fmt.Fprintf(tw, "%s\t", e.Type)
|
||||
fmt.Fprintf(tw, "\n")
|
||||
}
|
||||
|
||||
return tw.Flush()
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue