概要
govmomi で指定の VM を 1 台削除する方法を紹介します
環境
- Ubuntu 16.04
- golang 1.8
- govmomi 0.14.0
ソースコード
- vim destroy_vm.go
package main
import (
"context"
"flag"
"fmt"
"net/url"
"os"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
)
type VCenterAPI struct {
URL string
User string
Pass string
Insecure bool
URLFlag *string
InsecureFlag *bool
Network string
GovmomiClient *govmomi.Client
Finder *find.Finder
DC *object.Datacenter
}
func NewVCenterAPI() (api *VCenterAPI) {
api = new(VCenterAPI)
api.URL = "https://192.168.100.101/sdk"
api.User = "vcenter-username"
api.Pass = "vcenter-password"
api.Insecure = true
api.URLFlag = flag.String("url", api.URL, "")
api.InsecureFlag = flag.Bool("insecure", api.Insecure, "")
api.Network = "VM Network"
flag.Parse()
return api
}
func (api *VCenterAPI) Init() (err error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
u, err := url.Parse(*api.URLFlag)
if err != nil {
return err
}
u.User = url.UserPassword(api.User, api.Pass)
c, err := govmomi.NewClient(ctx, u, *api.InsecureFlag)
if err != nil {
return err
}
f := find.NewFinder(c.Client, true)
dc, err := f.DefaultDatacenter(ctx)
if err != nil {
return err
}
f.SetDatacenter(dc)
api.GovmomiClient = c
api.Finder = f
api.DC = dc
return nil
}
func (api *VCenterAPI) DestroyVM(path string) (err error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
vm, err := api.Finder.VirtualMachine(ctx, path)
if err != nil {
return err
}
t, err := vm.Destroy(ctx)
if err != nil {
return err
}
err = t.Wait(ctx)
if err != nil {
return err
}
return nil
}
func (api *VCenterAPI) PowerOffVM(path string) (err error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
vm, err := api.Finder.VirtualMachine(ctx, path)
if err != nil {
return err
}
t, err := vm.PowerOff(ctx)
if err != nil {
return err
}
err = t.Wait(ctx)
if err != nil {
return err
}
return nil
}
func main() {
api := NewVCenterAPI()
err := api.Init()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
path := "/dc/vm/folder/vm1"
err = api.PowerOffVM(path)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = api.DestroyVM(path)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
- go fmt destroy_vm.go
- go run destroy_vm.go
解説
削除する前に VM が停止していなければいけません
なので、PowerOffVM という関数を用意しています
DestroyVM も PowerOffVM もロジックはだいたい同じです
ポイントは find.VirtualMachine
を使って単一の VM だけ取得している点です
find.Finder.VirtualMachineList
を使って VM のインベントリパスを指定しても問題ないのですが、例えばアスタリスクなどを使って複数の VM を指定した場合複数の VM が取得できてしまいます
自分で VM の名前などでフィルタを掛けてもいいですが、そんなことをしないでも良いように準備されている find.VirtualMachine
を使っています
あとはそこで取得できた object.VirtualMachine の構造体が用意している Destroy(context)
を呼び出すだけで OK です
関数の戻り値にタスクが戻ってくるので Wait することでパワーオフと削除を待つことができます
実行する際に VM へのインベントリパスを指定しています
パスが存在しない場合にはエラーになります
主な発生するエラーは以下の通りです
- find.VirtualMachine で複数指定すると以下のエラーになる
path '/dc/vm/folder/*'
resolves to multiple vms
- Destroy 対象の VM がパワー ON だと以下のエラーになる
- The attempted operation cannot be performed in the current state (Powered on).
- 指定した VM のインベントリパスがない場合
- vm ‘/dc/vm/folder/non-vm’ not found
最後に
govmomi で VM を削除する方法を紹介しました
サンプルコードが見つからなかったのでリファレンスとソースコードを見ながら実装しましたが、慣れれば簡単にできるようになると思います
0 件のコメント:
コメントを投稿