2
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
8
http://www.apache.org/licenses/LICENSE-2.0
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
20
"github.com/juju/govmomi/property"
21
"github.com/juju/govmomi/vim25"
22
"github.com/juju/govmomi/vim25/methods"
23
"github.com/juju/govmomi/vim25/mo"
24
"github.com/juju/govmomi/vim25/types"
25
"golang.org/x/net/context"
28
type VirtualMachine struct {
34
func NewVirtualMachine(c *vim25.Client, ref types.ManagedObjectReference) *VirtualMachine {
35
return &VirtualMachine{
36
Common: NewCommon(c, ref),
40
func (v VirtualMachine) PowerOn(ctx context.Context) (*Task, error) {
41
req := types.PowerOnVM_Task{
45
res, err := methods.PowerOnVM_Task(ctx, v.c, &req)
50
return NewTask(v.c, res.Returnval), nil
53
func (v VirtualMachine) PowerOff(ctx context.Context) (*Task, error) {
54
req := types.PowerOffVM_Task{
58
res, err := methods.PowerOffVM_Task(ctx, v.c, &req)
63
return NewTask(v.c, res.Returnval), nil
66
func (v VirtualMachine) Reset(ctx context.Context) (*Task, error) {
67
req := types.ResetVM_Task{
71
res, err := methods.ResetVM_Task(ctx, v.c, &req)
76
return NewTask(v.c, res.Returnval), nil
79
func (v VirtualMachine) Suspend(ctx context.Context) (*Task, error) {
80
req := types.SuspendVM_Task{
84
res, err := methods.SuspendVM_Task(ctx, v.c, &req)
89
return NewTask(v.c, res.Returnval), nil
92
func (v VirtualMachine) ShutdownGuest(ctx context.Context) error {
93
req := types.ShutdownGuest{
97
_, err := methods.ShutdownGuest(ctx, v.c, &req)
101
func (v VirtualMachine) RebootGuest(ctx context.Context) error {
102
req := types.RebootGuest{
106
_, err := methods.RebootGuest(ctx, v.c, &req)
110
func (v VirtualMachine) Destroy(ctx context.Context) (*Task, error) {
111
req := types.Destroy_Task{
115
res, err := methods.Destroy_Task(ctx, v.c, &req)
120
return NewTask(v.c, res.Returnval), nil
123
func (v VirtualMachine) Clone(ctx context.Context, folder *Folder, name string, config types.VirtualMachineCloneSpec) (*Task, error) {
124
req := types.CloneVM_Task{
126
Folder: folder.Reference(),
131
res, err := methods.CloneVM_Task(ctx, v.c, &req)
136
return NewTask(v.c, res.Returnval), nil
139
func (v VirtualMachine) Reconfigure(ctx context.Context, config types.VirtualMachineConfigSpec) (*Task, error) {
140
req := types.ReconfigVM_Task{
145
res, err := methods.ReconfigVM_Task(ctx, v.c, &req)
150
return NewTask(v.c, res.Returnval), nil
153
func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
156
p := property.DefaultCollector(v.c)
157
err := property.Wait(ctx, p, v.Reference(), []string{"guest.ipAddress"}, func(pc []types.PropertyChange) bool {
158
for _, c := range pc {
159
if c.Name != "guest.ipAddress" {
162
if c.Op != types.PropertyChangeOpAssign {
183
// Device returns the VirtualMachine's config.hardware.device property.
184
func (v VirtualMachine) Device(ctx context.Context) (VirtualDeviceList, error) {
185
var o mo.VirtualMachine
187
err := v.Properties(ctx, v.Reference(), []string{"config.hardware.device"}, &o)
192
return VirtualDeviceList(o.Config.Hardware.Device), nil
195
func (v VirtualMachine) configureDevice(ctx context.Context, op types.VirtualDeviceConfigSpecOperation, fop types.VirtualDeviceConfigSpecFileOperation, devices ...types.BaseVirtualDevice) error {
196
spec := types.VirtualMachineConfigSpec{}
198
for _, device := range devices {
199
config := &types.VirtualDeviceConfigSpec{
204
if disk, ok := device.(*types.VirtualDisk); ok {
205
config.FileOperation = fop
207
// Special case to attach an existing disk
208
if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 {
210
if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
211
childDisk = b.Parent != nil
215
config.FileOperation = "" // existing disk
220
spec.DeviceChange = append(spec.DeviceChange, config)
223
task, err := v.Reconfigure(ctx, spec)
228
return task.Wait(ctx)
231
// AddDevice adds the given devices to the VirtualMachine
232
func (v VirtualMachine) AddDevice(ctx context.Context, device ...types.BaseVirtualDevice) error {
233
return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationAdd, types.VirtualDeviceConfigSpecFileOperationCreate, device...)
236
// EditDevice edits the given (existing) devices on the VirtualMachine
237
func (v VirtualMachine) EditDevice(ctx context.Context, device ...types.BaseVirtualDevice) error {
238
return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationEdit, types.VirtualDeviceConfigSpecFileOperationReplace, device...)
241
// RemoveDevice removes the given devices on the VirtualMachine
242
func (v VirtualMachine) RemoveDevice(ctx context.Context, device ...types.BaseVirtualDevice) error {
243
return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationRemove, types.VirtualDeviceConfigSpecFileOperationDestroy, device...)
246
// BootOptions returns the VirtualMachine's config.bootOptions property.
247
func (v VirtualMachine) BootOptions(ctx context.Context) (*types.VirtualMachineBootOptions, error) {
248
var o mo.VirtualMachine
250
err := v.Properties(ctx, v.Reference(), []string{"config.bootOptions"}, &o)
255
return o.Config.BootOptions, nil
258
// SetBootOptions reconfigures the VirtualMachine with the given options.
259
func (v VirtualMachine) SetBootOptions(ctx context.Context, options *types.VirtualMachineBootOptions) error {
260
spec := types.VirtualMachineConfigSpec{}
262
spec.BootOptions = options
264
task, err := v.Reconfigure(ctx, spec)
269
return task.Wait(ctx)
272
// Answer answers a pending question.
273
func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error {
274
req := types.AnswerVM{
277
AnswerChoice: answer,
280
_, err := methods.AnswerVM(ctx, v.c, &req)
288
func (v VirtualMachine) MarkAsTemplate(ctx context.Context) error {
289
req := types.MarkAsTemplate{
293
_, err := methods.MarkAsTemplate(ctx, v.c, &req)
301
func (v VirtualMachine) MarkAsVirtualMachine(ctx context.Context, pool ResourcePool, host *HostSystem) error {
302
req := types.MarkAsVirtualMachine{
304
Pool: pool.Reference(),
308
ref := host.Reference()
312
_, err := methods.MarkAsVirtualMachine(ctx, v.c, &req)