概要
govmomi の methods で API を呼び出した場合、レスポンスが object.Task でないためいきなり Wait が呼べません
レスポンスから object.Task を作成して Wait する必要があります
環境
- CentOS 7.5.1804
- golang 1.11.2
- govmomi 6712f991d8852a25ae4304a720463301c1ac4c64
サンプルコード
今回はスナップショットの作成 (methods.CreateSnapshot_Task
) を Wait する方法を紹介します
mkdir go/src/github.com/hawksnowlog/h
vim go/src/github.com/hawksnowlog/h/main.go
package main
import (
"context"
"flag"
"fmt"
"net/url"
"os"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
)
var envURL = "https://192.168.100.20/sdk"
var user = "administrator@vsphere.local"
var pass = "xxxxxxxxxx"
var vmname = "vm01"
var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", envURL, urlDescription)
var envInsecure = true
var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", envInsecure, insecureDescription)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
flag.Parse()
u, err := url.Parse(*urlFlag)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
u.User = url.UserPassword(user, pass)
c, err := govmomi.NewClient(ctx, u, *insecureFlag)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
f := find.NewFinder(c.Client, true)
dc, err := f.DefaultDatacenter(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
f.SetDatacenter(dc)
// vm list
vss, err := f.VirtualMachineList(ctx, "*")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
ref := types.ManagedObjectReference{}
for _, vm := range vss {
name := vm.Name()
if name == vmname {
ref = vm.Common.Reference()
break
}
}
// snapshot from vm
fmt.Println(ref.Type)
fmt.Println(ref.Value)
ssreq := new(types.CreateSnapshot_Task)
ssreq.Description = "Snapshot created by govmomi"
ssreq.Name = vmname + "ss"
ssreq.Memory = false
ssreq.This.Type = ref.Type
ssreq.This.Value = ref.Value
res, err := methods.CreateSnapshot_Task(ctx, c.RoundTripper, ssreq)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
task := object.NewTask(c.Client, res.Returnval)
err = task.Wait(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("created snapshot")
}
go build github.com/hawksnowlog/h
go install github.com/hawksnowlog/h
$GOPATH/bin/h
解説
res, err := methods.CreateSnapshot_Task(ctx, c.RoundTripper, ssreq)
で取得できる res は types.CreateSnapshot_TaskResponse
になっています
これだと .Wait(ctx)
関数を呼び出せません
なので res を元に task := object.NewTask(c.Client, res.Returnval)
で object.Task
を作成してから .Wait(ctx)
を呼び出してあげます
ssreq.This.Type = ref.Type
と ssreq.This.Value = ref.Value
はただの文字列になっています
例えばそれぞれ「VirtualMachine」「vm-20」という文字列です
今回のサンプルでは VM を取得してそこから moref を参照していますが決め打ちで決まっている場合は VM を検索するロジックは削除できます
最後に
govmomi で Task を Wait する方法を紹介しました
govmomi は基本は非同期なので、この Wait のやり方を覚えておかないとまだリソースが作成されていない状態で次に行ってしまったりするので注意が必要です
簡単な方法なので覚えておくと良いと思います
0 件のコメント:
コメントを投稿