esxlib/esx/vm.go

144 lines
3.1 KiB
Go
Raw Permalink Normal View History

2023-06-24 19:57:08 +00:00
package esx
2023-06-22 05:16:40 +00:00
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 {
2023-06-24 19:57:08 +00:00
ClientRef
mo *mo.VirtualMachine
ref types.ManagedObjectReference
2023-06-22 05:16:40 +00:00
}
func (v *VirtualMachine) refresh() error {
2023-06-24 19:57:08 +00:00
pc := property.DefaultCollector(v.VIM())
2023-06-22 05:16:40 +00:00
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)
2023-09-02 17:53:56 +00:00
if v.mo.Summary.Guest != nil {
if v.mo.Summary.Guest.IpAddress != "" {
addresses = append(addresses, v.mo.Summary.Guest.IpAddress)
return addresses
}
}
2023-06-22 05:16:40 +00:00
for _, x := range v.mo.Config.ExtraConfig {
kv := x.GetOptionValue()
2023-09-02 17:53:56 +00:00
//fmt.Printf("%v:%v\n", kv.Key, kv.Value)
2023-06-22 05:16:40 +00:00
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 {
2023-06-24 19:57:08 +00:00
cmd := fmt.Sprintf("vim-cmd vmsvc/power.on %s", v.Id())
return v.hostExec(ctx, cmd)
2023-06-22 05:16:40 +00:00
}
func (v *VirtualMachine) PowerOff(ctx context.Context) error {
2023-06-24 19:57:08 +00:00
cmd := fmt.Sprintf("vim-cmd vmsvc/power.off %s", v.Id())
return v.hostExec(ctx, cmd)
2023-06-22 05:16:40 +00:00
}
func (v *VirtualMachine) Suspend(ctx context.Context) error {
2023-06-24 19:57:08 +00:00
cmd := fmt.Sprintf("vim-cmd vmsvc/power.suspend %s", v.Id())
return v.hostExec(ctx, cmd)
2023-06-22 05:16:40 +00:00
}
func (v *VirtualMachine) Resume(ctx context.Context) error {
2023-06-24 19:57:08 +00:00
cmd := fmt.Sprintf("vim-cmd vmsvc/power.on %s", v.Id())
return v.hostExec(ctx, cmd)
2023-06-22 05:16:40 +00:00
}