mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
feat: support snapshot of esxi
This commit is contained in:
@@ -130,7 +130,7 @@ func init() {
|
||||
Cpu: args.CpuNum,
|
||||
Mem: args.MemSize,
|
||||
}
|
||||
vm, err := host.CloneVM(context.Background(), temVm, idss[0].(*esxi.SDatastore), createParams)
|
||||
vm, err := host.CloneVM(context.Background(), temVm, nil, idss[0].(*esxi.SDatastore), createParams)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SHost.CloneVMFromTemplate")
|
||||
}
|
||||
@@ -198,6 +198,68 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&VirtualMachineShowOptions{}, "vm-snapshots", "Show vm snapshots details", func(cli *esxi.SESXiClient, args *VirtualMachineShowOptions) error {
|
||||
vm, err := getVM(cli, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vmsps, err := vm.GetInstanceSnapshots()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(vmsps, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
type VirtualMachineSnapshotCreateOptions struct {
|
||||
VirtualMachineShowOptions
|
||||
NAME string `help:"Name of snapshot"`
|
||||
Desc string `help:"Description of snapshot"`
|
||||
}
|
||||
shellutils.R(&VirtualMachineSnapshotCreateOptions{}, "vm-snapshot-create", "Create vm snapshot", func(cli *esxi.SESXiClient, args *VirtualMachineSnapshotCreateOptions) error {
|
||||
vm, err := getVM(cli, &args.VirtualMachineShowOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sp, err := vm.CreateInstanceSnapshot(context.Background(), args.NAME, args.Desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(sp)
|
||||
return nil
|
||||
})
|
||||
|
||||
type VirtualMachineSnapshotOptions struct {
|
||||
VirtualMachineShowOptions
|
||||
ID string `help:"ID of snapshot"`
|
||||
}
|
||||
shellutils.R(&VirtualMachineSnapshotOptions{}, "vm-snapshot-delete", "Delete vm snapshot", func(cli *esxi.SESXiClient, args *VirtualMachineSnapshotOptions) error {
|
||||
vm, err := getVM(cli, &args.VirtualMachineShowOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sp, err := vm.GetInstanceSnapshot(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sp.Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
shellutils.R(&VirtualMachineSnapshotOptions{}, "vm-snapshot-reset", "Reset vm to snapshot", func(cli *esxi.SESXiClient, args *VirtualMachineSnapshotOptions) error {
|
||||
vm, err := getVM(cli, &args.VirtualMachineShowOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = vm.ResetToInstanceSnapshot(context.Background(), args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&VirtualMachineShowOptions{}, "vm-disks", "Show vm disks details", func(cli *esxi.SESXiClient, args *VirtualMachineShowOptions) error {
|
||||
vm, err := getVM(cli, args)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package esxi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type SVirtualMachineSnapshot struct {
|
||||
snapshotTree types.VirtualMachineSnapshotTree
|
||||
vm *SVirtualMachine
|
||||
}
|
||||
|
||||
func NewSnapshot(st types.VirtualMachineSnapshotTree) *SVirtualMachineSnapshot {
|
||||
return &SVirtualMachineSnapshot{
|
||||
snapshotTree: st,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetId() string {
|
||||
return moRefId(s.snapshotTree.Snapshot)
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetName() string {
|
||||
return s.snapshotTree.Name
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetDescription() string {
|
||||
return s.snapshotTree.Description
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%d", s.vm.GetGlobalId(), s.snapshotTree.Id)
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetStatus() string {
|
||||
return api.INSTANCE_SNAPSHOT_READY
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) GetProjectId() string {
|
||||
return s.vm.GetProjectId()
|
||||
}
|
||||
|
||||
func (s *SVirtualMachineSnapshot) Delete() error {
|
||||
cTrue := true
|
||||
req := types.RemoveSnapshot_Task{
|
||||
This: s.snapshotTree.Snapshot.Reference(),
|
||||
RemoveChildren: false,
|
||||
Consolidate: &cTrue,
|
||||
}
|
||||
res, err := methods.RemoveSnapshot_Task(s.vm.manager.context, s.vm.manager.client.Client, &req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "RemoveSnapshot_Task")
|
||||
}
|
||||
return object.NewTask(s.vm.manager.client.Client, res.Returnval).Wait(s.vm.manager.context)
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/vmware/govmomi/nfc"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
@@ -48,18 +49,19 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/version"
|
||||
)
|
||||
|
||||
var VIRTUAL_MACHINE_PROPS = []string{"name", "parent", "runtime", "summary", "config", "guest", "resourcePool", "layoutEx"}
|
||||
var VIRTUAL_MACHINE_PROPS = []string{"name", "parent", "runtime", "summary", "config", "guest", "resourcePool", "layoutEx", "snapshot"}
|
||||
|
||||
type SVirtualMachine struct {
|
||||
multicloud.SInstanceBase
|
||||
SManagedObject
|
||||
|
||||
vnics []SVirtualNIC
|
||||
vdisks []SVirtualDisk
|
||||
vga SVirtualVGA
|
||||
cdroms []SVirtualCdrom
|
||||
devs map[int32]SVirtualDevice
|
||||
ihost cloudprovider.ICloudHost
|
||||
vnics []SVirtualNIC
|
||||
vdisks []SVirtualDisk
|
||||
vga SVirtualVGA
|
||||
cdroms []SVirtualCdrom
|
||||
devs map[int32]SVirtualDevice
|
||||
ihost cloudprovider.ICloudHost
|
||||
snapshots []SVirtualMachineSnapshot
|
||||
|
||||
guestIps map[string]string
|
||||
}
|
||||
@@ -253,7 +255,7 @@ func (self *SVirtualMachine) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
|
||||
func (self *SVirtualMachine) GetIDiskById(idStr string) (cloudprovider.ICloudDisk, error) {
|
||||
for i := 0; i < len(self.vdisks); i += 1 {
|
||||
if self.vdisks[i].GetGlobalId() == idStr {
|
||||
if self.vdisks[i].MatchId(idStr) {
|
||||
return &self.vdisks[i], nil
|
||||
}
|
||||
}
|
||||
@@ -1357,3 +1359,89 @@ func (self *SVirtualMachine) IsTemplate() bool {
|
||||
}
|
||||
return movm.Config != nil && movm.Config.Template
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) fetchSnapshots() {
|
||||
movm := self.getVirtualMachine()
|
||||
if movm.Snapshot == nil {
|
||||
return
|
||||
}
|
||||
self.snapshots = self.extractSnapshots(movm.Snapshot.RootSnapshotList, make([]SVirtualMachineSnapshot, 0, len(movm.Snapshot.RootSnapshotList)))
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) extractSnapshots(tree []types.VirtualMachineSnapshotTree, snapshots []SVirtualMachineSnapshot) []SVirtualMachineSnapshot {
|
||||
for i := range tree {
|
||||
snapshots = append(snapshots, SVirtualMachineSnapshot{
|
||||
snapshotTree: tree[i],
|
||||
vm: self,
|
||||
})
|
||||
snapshots = self.extractSnapshots(tree[i].ChildSnapshotList, snapshots)
|
||||
}
|
||||
return snapshots
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetInstanceSnapshots() ([]cloudprovider.ICloudInstanceSnapshot, error) {
|
||||
if self.snapshots == nil {
|
||||
self.fetchSnapshots()
|
||||
}
|
||||
ret := make([]cloudprovider.ICloudInstanceSnapshot, 0, len(self.snapshots))
|
||||
for i := range self.snapshots {
|
||||
ret = append(ret, &self.snapshots[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetInstanceSnapshot(idStr string) (cloudprovider.ICloudInstanceSnapshot, error) {
|
||||
if self.snapshots == nil {
|
||||
self.fetchSnapshots()
|
||||
}
|
||||
for i := range self.snapshots {
|
||||
if self.snapshots[i].GetGlobalId() == idStr {
|
||||
// copyone
|
||||
sp := self.snapshots[i]
|
||||
return &sp, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) CreateInstanceSnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudInstanceSnapshot, error) {
|
||||
ovm := self.getVmObj()
|
||||
task, err := ovm.CreateSnapshot(ctx, name, desc, false, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CreateSnapshot")
|
||||
}
|
||||
info, err := task.WaitForResult(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "task.Wait")
|
||||
}
|
||||
sp := info.Result.(types.ManagedObjectReference)
|
||||
err = self.Refresh()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "create successfully")
|
||||
}
|
||||
self.fetchSnapshots()
|
||||
for i := range self.snapshots {
|
||||
if self.snapshots[i].snapshotTree.Snapshot == sp {
|
||||
// copyone
|
||||
sp := self.snapshots[i]
|
||||
return &sp, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrap(errors.ErrNotFound, "create successfully")
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) ResetToInstanceSnapshot(ctx context.Context, idStr string) error {
|
||||
cloudIsp, err := self.GetInstanceSnapshot(idStr)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetInstanceSnapshot")
|
||||
}
|
||||
isp := cloudIsp.(*SVirtualMachineSnapshot)
|
||||
req := types.RevertToSnapshot_Task{
|
||||
This: isp.snapshotTree.Snapshot.Reference(),
|
||||
}
|
||||
res, err := methods.RevertToSnapshot_Task(ctx, self.manager.client.Client, &req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "RevertToSnapshot_Task")
|
||||
}
|
||||
return object.NewTask(self.manager.client.Client, res.Returnval).Wait(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user