package esx import ( "context" "errors" "fmt" "path" "regexp" "strings" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" ) type PowerState string const ( PowerStateOff = PowerState("off") PowerStateOn = PowerState("on") PowerStateSuspended = PowerState("suspended") PowerStateUndefined = PowerState("") ) type VirtualMachine struct { ClientRef //c *vim25.Client mo *mo.VirtualMachine ref types.ManagedObjectReference } func (v *VirtualMachine) refresh() error { pc := property.DefaultCollector(v.VIM()) refs := []types.ManagedObjectReference{v.ref} var vms []mo.VirtualMachine err := pc.Retrieve(context.Background(), refs, nil, &vms) if err != nil { return err } if len(vms) != 1 || vms[0].Name != v.mo.Name { return errors.New("internal error (vms don't) match") } v.mo = &vms[0] return nil } func (v *VirtualMachine) Update() error { return v.refresh() } func (v *VirtualMachine) Name() string { return v.mo.Name } func (v *VirtualMachine) UUID() string { return v.mo.Config.Uuid } func (v *VirtualMachine) Id() string { return v.mo.Summary.Vm.Value } func (v *VirtualMachine) InternalPath() (string, string, error) { layout, err := v.GetFiles() if err != nil { panic(err) } for _, l := range layout.File { if strings.HasSuffix(l.Name, ".vmx") { re := regexp.MustCompile(`\[(.*?)\] (.*)`) matches := re.FindStringSubmatch(l.Name) if len(matches) == 3 { return matches[1], path.Dir(matches[2]), nil } } } return "", "", fmt.Errorf("not found") } func (v *VirtualMachine) GetNetworkAddressV4() []string { addresses := make([]string, 0) for _, x := range v.mo.Config.ExtraConfig { kv := x.GetOptionValue() // fmt.Printf("%v:%v\n", kv.Key, kv.Value) switch kv.Key { case "guestinfo.local-ipv4": addresses = append(addresses, kv.Value.(string)) } } return addresses } func (v *VirtualMachine) GetFiles() (*types.VirtualMachineFileLayoutEx, error) { if err := v.refresh(); err != nil { return nil, err } return v.mo.LayoutEx, nil } func (v *VirtualMachine) State() PowerState { switch v.mo.Runtime.PowerState { case types.VirtualMachinePowerStatePoweredOff: return PowerStateOff case types.VirtualMachinePowerStatePoweredOn: return PowerStateOn case types.VirtualMachinePowerStateSuspended: return PowerStateSuspended default: return PowerStateUndefined } } func (v *VirtualMachine) PowerOn(ctx context.Context) error { cmd := fmt.Sprintf("vim-cmd vmsvc/power.on %s", v.Id()) return v.hostExec(ctx, cmd) } func (v *VirtualMachine) PowerOff(ctx context.Context) error { cmd := fmt.Sprintf("vim-cmd vmsvc/power.off %s", v.Id()) return v.hostExec(ctx, cmd) } func (v *VirtualMachine) Suspend(ctx context.Context) error { cmd := fmt.Sprintf("vim-cmd vmsvc/power.suspend %s", v.Id()) return v.hostExec(ctx, cmd) } func (v *VirtualMachine) Resume(ctx context.Context) error { cmd := fmt.Sprintf("vim-cmd vmsvc/power.on %s", v.Id()) return v.hostExec(ctx, cmd) }