Я пытаюсь использовать библиотеку govmomi (https://github.com/vmware/govmomi), чтобы внести некоторые автоматические изменения в ВМ, но я не могу обойти исключения из нулевого указателя в строках 134 и 136 за последние несколько часовЯ заставил его работать в какой-то момент, но потом я не уверен, что делаю сейчас неправильно, потому что я пробовал так много комбинаций, но сейчас, похоже, ничего не работает ...
package main
import (
"context"
"flag"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"net/url"
"os"
"strings"
"fmt"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/types"
"log"
)
type change struct {
*flags.VirtualMachineFlag
}
const (
envURL = "GOVC_URL"
envUserName = "GOVC_USERNAME"
envPassword = "GOVC_PASSWORD"
envInsecure = "GOVC_INSECURE"
)
// getEnvString returns string from environment variable.
func getEnvString(v string, def string) string {
r := os.Getenv(v)
if r == "" {
return def
}
return r
}
// getEnvBool returns boolean from environment variable.
func getEnvBool(v string, def bool) bool {
r := os.Getenv(v)
if r == "" {
return def
}
switch strings.ToLower(r[0:1]) {
case "t", "y", "1":
return true
}
return false
}
var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", getEnvString(envURL, "https://username:password@host"+vim25.Path), urlDescription)
var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", getEnvBool(envInsecure, false), insecureDescription)
func processOverride(u *url.URL) {
envUsername := os.Getenv(envUserName)
envPassword := os.Getenv(envPassword)
// Override username if provided
if envUsername != "" {
var password string
var ok bool
if u.User != nil {
password, ok = u.User.Password()
}
if ok {
u.User = url.UserPassword(envUsername, password)
} else {
u.User = url.User(envUsername)
}
}
// Override password if provided
if envPassword != "" {
var username string
if u.User != nil {
username = u.User.Username()
}
u.User = url.UserPassword(username, envPassword)
}
}
func NewClient(ctx context.Context) (*govmomi.Client, error) {
flag.Parse()
// Parse URL from string
u, err := soap.ParseURL(*urlFlag)
if err != nil {
return nil, err
}
// Override username and/or password as required
processOverride(u)
// Connect and log in to ESX or vCenter
return govmomi.NewClient(ctx, u, *insecureFlag)
}
func main() {
ctx := context.Background()
// Connect and login to ESX or vCenter
c, err := NewClient(ctx)
if err != nil {
log.Fatal(err)
}
defer c.Logout(ctx)
var spec *types.VirtualMachineConfigSpec
var cmd *change
var flip bool
flip = false
spec.VPMCEnabled = &flip
vm, err := cmd.VirtualMachine()
task, err := vm.Reconfigure(ctx, *spec)
if err != nil {
println(err)
}
fmt.Println(task.Wait(ctx))
}
2 строки, которые выдают ошибки:
spec.VPMCEnabled = &flip
и
vm, err := cmd.VirtualMachine()
обе выдают одинаковые panic: runtime error: invalid memory address or nil pointer dereference
. ЕслиЯ закомментирую первый, который выдает ошибку, второй затем выдает ее.
Я думаю, что оба не связаны, но я не могу понять, как правильно выполнить разыменование.
---- ОБНОВЛЕНИЕ РЕДАКТИРОВАНИЯ 1 --------------
Я внес некоторые изменения в этот ответ ниже, но все еще не могу обойти ошибку в task, err := vm.Reconfigure(ctx, *spec)
...
package main
import (
"context"
"flag"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"net/url"
"os"
"strings"
"fmt"
"github.com/vmware/govmomi/vim25/types"
"log"
)
const (
envURL = "GOVC_URL"
envUserName = "GOVC_USERNAME"
envPassword = "GOVC_PASSWORD"
envInsecure = "GOVC_INSECURE"
)
// getEnvString returns string from environment variable.
func getEnvString(v string, def string) string {
r := os.Getenv(v)
if r == "" {
return def
}
return r
}
// getEnvBool returns boolean from environment variable.
func getEnvBool(v string, def bool) bool {
r := os.Getenv(v)
if r == "" {
return def
}
switch strings.ToLower(r[0:1]) {
case "t", "y", "1":
return true
}
return false
}
var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", getEnvString(envURL, "https://username:password@host"+vim25.Path), urlDescription)
var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", getEnvBool(envInsecure, false), insecureDescription)
func processOverride(u *url.URL) {
envUsername := os.Getenv(envUserName)
envPassword := os.Getenv(envPassword)
// Override username if provided
if envUsername != "" {
var password string
var ok bool
if u.User != nil {
password, ok = u.User.Password()
}
if ok {
u.User = url.UserPassword(envUsername, password)
} else {
u.User = url.User(envUsername)
}
}
// Override password if provided
if envPassword != "" {
var username string
if u.User != nil {
username = u.User.Username()
}
u.User = url.UserPassword(username, envPassword)
}
}
func NewClient(ctx context.Context) (*govmomi.Client, error) {
flag.Parse()
// Parse URL from string
u, err := soap.ParseURL(*urlFlag)
if err != nil {
return nil, err
}
// Override username and/or password as required
processOverride(u)
// Connect and log in to ESX or vCenter
return govmomi.NewClient(ctx, u, *insecureFlag)
}
func main() {
ctx := context.Background()
// Connect and login to ESX or vCenter
c, err := NewClient(ctx)
if err != nil {
log.Fatal(err)
}
defer c.Logout(ctx)
var spec *types.VirtualMachineConfigSpec
spec = new(types.VirtualMachineConfigSpec)
var flip bool
flip = false
spec.VPMCEnabled = &flip
var vm *object.VirtualMachine
vm = new(object.VirtualMachine)
task, err := vm.Reconfigure(ctx, *spec)
if err != nil {
println(err)
}
fmt.Println(task.Wait(ctx))
}
полная ошибка, которую я получаю, это:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x280 pc=0x14e18f6]
goroutine 1 [running]:
github.com/vmware/govmomi/vim25.(*Client).RoundTrip(0x0, 0x1886f00, 0xc000016088, 0x1884140, 0xc000298720, 0x1884140, 0xc000298740, 0x300, 0x16e8ac0)
/Users/ronakpatel/go/src/github.com/vmware/govmomi/vim25/client.go:89 +0x26
github.com/vmware/govmomi/vim25/methods.ReconfigVM_Task(0x1886f00, 0xc000016088, 0x1884060, 0x0, 0xc0002d0000, 0xc000288000, 0xc000080400, 0x0)
/Users/ronakpatel/go/src/github.com/vmware/govmomi/vim25/methods/methods.go:10879 +0xb8
github.com/vmware/govmomi/object.VirtualMachine.Reconfigure(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1886f00, 0xc000016088, 0x0, ...)
/Users/ronakpatel/go/src/github.com/vmware/govmomi/object/virtual_machine.go:207 +0x19b
main.main()
/Users/ronakpatel/go/src/awesomeProject1/main.go:143 +0x1ec
exit status 2
---- ОБНОВЛЕНИЕ РЕДАКТИРОВАНИЯ 2 ----------
Я изменил что-то вокруг насОтвет, приведенный ниже, но теперь я снова получаю сообщение об ошибке, но в этой части: task, err := vm.Reconfigure(ctx, spec1)
Ошибка:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x153d05a]
goroutine 1 [running]:
main.main()
/Users/ronakpatel/go/src/awesomeProject1/main.go:134 +0x19a
exit status 2
Код:
spec1 := types.VirtualMachineConfigSpec{
VPMCEnabled: &[]bool{false}[0],
}
var vm *object.VirtualMachine
var vmf *flags.VirtualMachineFlag
vmf, ctx = flags.NewVirtualMachineFlag(ctx)
vm, _ = vmf.VirtualMachine()
task, err := vm.Reconfigure(ctx, spec1)
if err != nil {
println(err)
}
fmt.Println(task.Wait(ctx))