temp commit

This commit is contained in:
wanyaoqi
2019-01-22 16:56:47 +08:00
committed by Zexi Li
parent 0308eda220
commit 0af9edab26
17 changed files with 343 additions and 69 deletions
-1
View File
@@ -102,7 +102,6 @@ func (f *SLocalGuestFS) Cleandir(dir string, keepdir, caseInsensitive bool) erro
return fmt.Errorf("No such file %s", sPath)
}
// TODO
func (f *SLocalGuestFS) Zerofiles(dir string, caseInsensitive bool) error {
sPath := f.getLocalPath(dir, caseInsensitive)
if len(sPath) > 0 {
+30 -16
View File
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"io/ioutil"
"net/url"
"os"
"os/exec"
"path"
@@ -20,6 +19,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/sshkeys"
"yunion.io/x/onecloud/pkg/hostman/guestfs"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient/modules"
@@ -32,6 +32,7 @@ import (
const VNC_PORT_BASE = 5900
type SGuestManager struct {
host hostutils.IHost
ServersPath string
Servers map[string]*SKVMGuestInstance
CandidateServers map[string]*SKVMGuestInstance
@@ -40,8 +41,9 @@ type SGuestManager struct {
isLoaded bool
}
func NewGuestManager(serversPath string) *SGuestManager {
func NewGuestManager(host hostutils.IHost, serversPath string) *SGuestManager {
manager := &SGuestManager{}
manager.host = host
manager.ServersPath = serversPath
manager.Servers = make(map[string]*SKVMGuestInstance, 0)
manager.CandidateServers = make(map[string]*SKVMGuestInstance, 0)
@@ -66,14 +68,13 @@ func (m *SGuestManager) Bootstrap() {
}
func (m *SGuestManager) VerifyExistingGuests(pendingDelete bool) {
params := url.Values{
"limit": {"0"},
"admin": {"True"},
"system": {"True"},
"pending_delete": {fmt.Sprintf("%s", pendingDelete)},
}
// TODO get host id
params.Set("filter.0", fmt.Sprintf("host_id.equals(%s)", "get host id "))
params := jsonutils.NewDict()
params.Set("limit", jsonutils.NewInt(0))
params.Set("admin", jsonutils.JSONTrue)
params.Set("system", jsonutils.JSONTrue)
params.Set("pending_delete", jsonutils.NewBool(pendingDelete))
params.Set("filter.0", jsonutils.NewString(
fmt.Sprintf("host_id.equals(%s)", m.host.GetHostId())))
if len(m.CandidateServers) > 0 {
keys := make([]string, len(m.CandidateServers))
var index = 0
@@ -81,9 +82,9 @@ func (m *SGuestManager) VerifyExistingGuests(pendingDelete bool) {
keys[index] = k
index++
}
params.Set("filter.1", strings.Join(keys, ","))
params.Set("filter.1", jsonutils.NewString(strings.Join(keys, ",")))
}
res, err := modules.Servers.List(hostutils.GetComputeSession(context.Background()), id, params)
res, err := modules.Servers.List(hostutils.GetComputeSession(context.Background()), params)
if err != nil {
m.OnVerifyExistingGuestsFail(err, pendingDelete)
} else {
@@ -130,7 +131,19 @@ func (m *SGuestManager) RemoveCandidateServer(server *SKVMGuestInstance) {
}
func (m *SGuestManager) OnLoadExistingGuestsComplete() {
log.Infof("Load existing guests complete...")
err := m.host.PutHostOnline()
if err != nil {
log.Errorln(err)
}
// TODO
// hostmetrics.Init()
if !options.HostOptions.EnableCpuBinding {
// TODO
// m.cleanupCpuset()
}
}
func (m *SGuestManager) StartCpusetBalancer() {
@@ -316,7 +329,7 @@ func (m *SGuestManager) GuestStart(ctx context.Context, sid string, body jsonuti
if err := guest.StartGuest(ctx, params); err != nil {
return nil, httperrors.NewBadRequestError("Failed to start server")
} else {
return jsonutils.NewDict(jsonutils.JSONPair{"vnc_port", jsonutils.NewInt(0)}), nil
return jsonutils.NewDict(jsonutils.NewPair("vnc_port", jsonutils.NewInt(0))), nil
}
} else {
vncPort := guest.GetVncPort()
@@ -555,7 +568,8 @@ func (m *SGuestManager) DeleteSnapshot(ctx context.Context, params interface{})
return guest.ExecDeleteSnapshotTask(ctx, delParams.Disk, delParams.DeleteSnapshot,
delParams.ConvertSnapshot, delParams.PendingDelete)
} else {
return nil, delParams.Disk.DeleteSnapshot(delParams.DeleteSnapshot)
return jsonutils.NewDict(jsonutils.NewPair("deleted", jsonutils.JSONTrue)),
delParams.Disk.DeleteSnapshot(delParams.DeleteSnapshot)
}
}
@@ -577,9 +591,9 @@ func Stop() {
guestManger.ExitGuestCleanup()
}
func Init(serversPath string) {
func Init(host hostutils.IHost, serversPath string) {
if guestManger == nil {
guestManger = NewGuestManager(serversPath)
guestManger = NewGuestManager(host, serversPath)
}
}
+4 -9
View File
@@ -716,9 +716,7 @@ func (s *SGuestReloadDiskTask) onResumeSucc(results string) {
func (s *SGuestReloadDiskTask) taskFailed(reason string) {
log.Errorf("SGuestReloadDiskTask error: %s", reason)
if _, err := hostutils.TaskFailed(s.ctx, reason); err != nil {
log.Errorln(err)
}
hostutils.TaskFailed(s.ctx, reason)
}
/**
@@ -764,10 +762,7 @@ func (s *SGuestDiskSnapshotTask) onSnapshotBlkdevFail(string) {
if err != nil {
log.Errorln(err)
}
_, err = hostutils.TaskFailed(s.ctx, "Reload blkdev error")
if err != nil {
log.Errorln(err)
}
hostutils.TaskFailed(s.ctx, "Reload blkdev error")
}
func (s *SGuestDiskSnapshotTask) onResumeSucc(res string) {
@@ -775,7 +770,7 @@ func (s *SGuestDiskSnapshotTask) onResumeSucc(res string) {
snapshotDir := s.disk.GetSnapshotDir()
snapshotLocation := path.Join(snapshotDir, s.snapshotId)
_, err := hostutils.TaskComplete(s.ctx, jsonutils.NewDict(
jsonutils.JSONPair{"localtion", jsonutils.NewString(snapshotLocation)}))
jsonutils.NewPair("localtion", jsonutils.NewString(snapshotLocation))))
if err != nil {
log.Errorln(err)
}
@@ -882,7 +877,7 @@ func (s *SGuestSnapshotDeleteTask) onResumeSucc(res string) {
exec.Command("rm", "-f", path.Join(snapshotDir, s.deleteSnapshot))
}
_, err := hostutils.TaskComplete(s.ctx,
jsonutils.NewDict(jsonutils.JSONPair{"localtion", jsonutils.JSONTrue}))
jsonutils.NewDict(jsonutils.NewPair("deleted", jsonutils.JSONTrue)))
if err != nil {
log.Errorln(err)
}
+17 -4
View File
@@ -311,6 +311,10 @@ func (s *SKVMGuestInstance) StartMonitor(ctx context.Context) {
}
func (s *SKVMGuestInstance) delayStartMonitor(ctx context.Context) {
if s.GetQmpMonitorPort(-1) > 0 {
// TODO enable hmp?
}
if options.HostOptions.EnableQmpMonitor && s.GetQmpMonitorPort(-1) > 0 {
s.Monitor = monitor.NewQmpMonitor(
s.onMonitorDisConnect,
@@ -333,8 +337,7 @@ func (s *SKVMGuestInstance) onGetQemuVersion(ctx context.Context, version string
log.Infof("Guest(%s) qemu version %s", s.Id, s.QemuVersion)
if s.Desc.Contains("live_migrate_dest_port") && ctx != nil {
migratePort, _ := s.Desc.Get("live_migrate_dest_port")
body := jsonutils.NewDict(
jsonutils.JSONPair{"live_migrate_dest_port", migratePort})
body := jsonutils.NewDict(jsonutils.NewPair("live_migrate_dest_port", migratePort))
hostutils.TaskComplete(ctx, body)
} else if jsonutils.QueryBoolean(s.Desc, "is_slave", false) {
// TODO
@@ -375,6 +378,17 @@ func (s *SKVMGuestInstance) onMonitorTimeout(ctx context.Context, err error) {
func() { s.asyncScriptStart(ctx, jsonutils.NewDict()) })
}
func (s *SKVMGuestInstance) GetHmpMonitorPort(vncPort int) int {
if vncPort <= 0 {
vncPort = s.GetVncPort()
}
if vncPort > 0 {
return vncPort + MONITOR_PORT_BASE
} else {
return -1
}
}
func (s *SKVMGuestInstance) GetQmpMonitorPort(vncPort int) int {
if vncPort <= 0 {
vncPort = s.GetVncPort()
@@ -518,7 +532,6 @@ func (s *SKVMGuestInstance) delTmpDisks(ctx context.Context, migrated bool) {
for _, disk := range disks {
if disk.Contains("path") {
diskPath, _ := disk.GetString("path")
// TODO GetDisksByPath, storagetypes, deleteallsnapshot, delete
d := storageman.GetManager().GetDiskByPath(diskPath)
if d != nil && d.GetType == storagetypes.STORAGE_LOCAL && migrated {
if err := d.DeleteAllSnapshot(); err != nil {
@@ -1008,5 +1021,5 @@ func (s *SKVMGuestInstance) deleteStaticSnapshotFile(
log.Errorln(err)
return nil, err
}
return jsonutils.NewDict(jsonutils.JSONPair{"localtion", jsonutils.JSONTrue}), nil
return jsonutils.NewDict(jsonutils.JSONPair{"deleted", jsonutils.JSONTrue}), nil
}
+1 -1
View File
@@ -346,7 +346,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
cmd += fmt.Sprintf(" -cpu %s", cpu_type)
// TODO hmp - -
// cmd += s.getMonitorDesc("hmqmon", s.GetQmpMonitorPort(int(vncPort)), MODE_READLINE)
cmd += s.getMonitorDesc("hmqmon", s.GetQmpMonitorPort(int(vncPort)), MODE_READLINE)
if options.HostOptions.EnableQmpMonitor {
cmd += s.getMonitorDesc("qmqmon", s.GetQmpMonitorPort(int(vncPort)), MODE_CONTROL)
}
+16 -3
View File
@@ -41,8 +41,9 @@ var (
)
type SHostInfo struct {
isRegistered bool
IsRegistered chan struct{}
isRegistered bool
IsRegistered chan struct{}
registerCallback func()
kvmModuleSupport string
nestStatus string
@@ -644,7 +645,8 @@ func (h *SHostInfo) GetMatchNic(bridge, iface, mac string) *SNIC {
return nil
}
func (h *SHostInfo) StartRegister(delay int) {
func (h *SHostInfo) StartRegister(delay int, callback func()) {
h.registerCallback = callback
timeutils2.AddTimeout(delay*time.Second, h.register)
}
@@ -853,6 +855,13 @@ func (h *SHostInfo) putHostOffline() {
}
}
func (h *SHostInfo) PutHostOnline() error {
_, err := modules.Hosts.PerformAction(
hostutils.GetComputeSession(context.Background()),
h.HostId, "online", nil)
return err
}
func (h *SHostInfo) getNetworkInfo() {
params := jsonutils.NewDict()
params.Set("details", jsonutils.JSONTrue)
@@ -1103,6 +1112,10 @@ func (h *SHostInfo) onSucc() {
// TODO
h.StartPinger()
if h.registerCallback != nil {
h.registerCallback()
}
// To notify caller, host register is success
close(h.IsRegistered)
}
+8
View File
@@ -18,6 +18,14 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
type IHost interface {
GetZone() string
GetHostId() string
GetMediumType() string
PutHostOnline() error
}
func GetComputeSession(ctx context.Context) *mcclient.ClientSession {
return auth.GetAdminSession(ctx, options.HostOptions.Region, "v2")
}
+2
View File
@@ -71,6 +71,8 @@ type SHostOptions struct {
DefaultWriteBpsPerCpu int `default:"54525952" help:"Default write bps per cpu for hard IO limit"`
DefaultWriteIopsPerCpu int `default:"416" help:"Default write iops per cpu for hard IO limit"`
SetVncPassword bool `default:"true" help:"Auto set vnc password after monitor connected"`
EnableCpuBinding bool `default:"true" help:"Enable cpu binding and rebalance"`
}
var HostOptions SHostOptions
+3 -7
View File
@@ -32,23 +32,19 @@ func (host *SHostService) StartService() {
log.Fatalf(err)
}
if err := storageman.Init(hostInstance.HostId, hostInstance.Zone); err != nil {
if err := storageman.Init(hostInstance); err != nil {
log.Fatalf(err)
}
// wait host registerd
// Firewall.Init()
guestman.Init(hostInstance, options.HostOptions.ServersPath)
var c = make(chan struct{})
cloudcommon.InitAuth(&options.HostOptions.Options, func() {
log.Infof("Auth complete!!")
hostinfo.Instance().StartRegister()
hostInstance.StartRegister(5, guestman.GetGuestManager().Bootstrap)
<-hostinfo.Instance().IsRegistered
guestman.Init(options.HostOptions.ServersPath)
guestman.GetGuestManager().Bootstrap()
close(c)
})
+4 -10
View File
@@ -7,20 +7,14 @@ import (
"strings"
"yunion.io/x/onecloud/pkg/cloudcommon/storagetypes"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/hostman/options"
)
const MINIMAL_FREE_SPACE = 128
type IHost interface {
GetZone() string
GetHostId() string
GetMediumType() string
}
type SStorageManager struct {
host IHost
host hostutils.IHost
Storages []IStorage
AgentStorage IStorage
@@ -32,7 +26,7 @@ type SStorageManager struct {
NfsStorageImagecacheManagers map[string]IImageCacheManger
}
func NewStorageManager(host IHost) (*SStorageManager, error) {
func NewStorageManager(host hostutils.IHost) (*SStorageManager, error) {
var (
ret = &SStorageManager{
host: host,
@@ -276,7 +270,7 @@ func Manager() *SStorageManager {
return storageManager
}
func Init(host IHost) error {
func Init(host hostutils.IHost) error {
var (
err error
zone = host.GetZone()
+11 -12
View File
@@ -14,32 +14,31 @@ import (
type IDisk interface {
GetId() string
Probe() error
GetPath() string
GetSnapshotDir() string
GetDiskDesc() jsonutils.JSONObject
GetDiskSetupScripts(idx int) string
// TODO
// DeleteAllSnapshot() error
// TODO DeleteAllSnapshot() error
Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
GetPath() string
GetSnapshotDir() string
PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
CreateFromUrl(context.Context, string) error
// CreateFromSnapshot
// TODO CreateFromSnapshot
CreateFromTemplate(context.Context, string, string, int64) (jsonutils.JSONObject, error)
CreateFromImageFuse(context.Context, string) error
CreateRaw(ctx context.Context, sizeMb int, diskFromat string, fsFormat string,
encryption bool, diskId string, back string) (jsonutils.JSONObject, error)
PostCreateFromImageFuse()
CreateSnapshot(snapshotId string) error
DeleteSnapshot(snapshotId string) error
DeleteSnapshot(snapshotId, convertSnapshot string, pendingDelete bool) error
// @params: diskPath, guestDesc, deployInfo
DeployGuestFs(string, *jsonutils.JSONDict, *guestfs.SDeployInfo) (jsonutils.JSONObject, error)
PostCreateFromImageFuse()
DeployGuestFs(diskPath string, guestDesc *jsonutils.JSONDict,
deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error)
}
type SBaseDisk struct {
+53 -5
View File
@@ -18,9 +18,13 @@ import (
var (
keyWords = []string{"disks"}
actionFuncs = map[string]actionFunc{
"create": diskCreate,
"delete": diskDelete,
"resize": diskResize,
"create": diskCreate,
"delete": diskDelete,
"resize": diskResize,
"save-prepare": diskSavePrepare,
"reset": diskReset,
// "snapshot": diskSnapshot,
"cleanup-snapshots": diskCleanupSnapshots,
}
)
@@ -151,7 +155,7 @@ func perfomrDiskActions(ctx context.Context, w http.ResponseWriter, r *http.Requ
func diskCreate(ctx context.Context, storage IStorage, diskId string, disk IDisk, body jsonutils.JSONObject) (interface{}, error) {
diskInfo, err := body.Get("disk")
if err != nil {
return nil, httperrors.NewInputParameterError("Missing disk")
return nil, httperrors.NewMissingParameterError("disk")
}
hostutils.DelayTask(ctx, storage.CreateDiskByDiskinfo,
&SDiskCreateByDiskinfo{diskId, disk, diskInfo, storage})
@@ -166,8 +170,52 @@ func diskDelete(ctx context.Context, storage IStorage, diskId string, disk IDisk
func diskResize(ctx context.Context, storage IStorage, diskId string, disk IDisk, body jsonutils.JSONObject) (interface{}, error) {
diskInfo, err := body.Get("disk")
if err != nil {
return nil, httperrors.NewInputParameterError("Missing disk")
return nil, httperrors.NewMissingParameterError("disk")
}
hostutils.DelayTask(ctx, disk.Resize, diskInfo)
return nil, nil
}
func diskSavePrepare(ctx context.Context, storage IStorage, diskId string, disk IDisk, body jsonutils.JSONObject) (interface{}, error) {
diskInfo, err := body.Get("disk")
if err != nil {
return nil, httperrors.NewMissingParameterError("disk")
}
hostutils.DelayTask(ctx, disk.PrepareSaveToGlance, diskInfo)
return nil, nil
}
func diskReset(ctx context.Context, storage IStorage, diskId string, disk IDisk, body jsonutils.JSONObject) (interface{}, error) {
snapshotId, err := body.GetString("snapshot_id")
if err != nil {
return nil, httperrors.NewMissingParameterError("snapshot_id")
}
outOfChain, err := body.Bool("out_of_chain")
if err != nil {
return nil, httperrors.NewMissingParameterError("out_of_chain")
}
hostutils.DelayTask(ctx, disk.ResetFromSnapshot, &SDiskReset{snapshotId, outOfChain})
return nil, nil
}
// func diskSnapshot(ctx context.Context, storage IStorage, diskId string, disk IDisk, body jsonutils.JSONObject) (interface{}, error) {
// snapshotId, err := body.GetString("snapshot_id")
// if err != nil {
// return nil, httperrors.NewMissingParameterError("snapshot_id")
// }
// hostutils.DelayTask(ctx, disk.CreateSnapshot(snapshotId), snapshotId)
// return nil, nil
// }
func diskCleanupSnapshots(ctx context.Context, storage IStorage, diskId string, disk IDisk, body jsonutils.JSONObject) (interface{}, error) {
convertSnapshots, err := body.GetArray("convert_snapshots")
if err != nil {
return nil, httperrors.NewMissingParameterError("convert_snapshots")
}
deleteSnapshots, err := body.GetArray("delete_snapshots")
if err != nil {
return nil, httperrors.NewMissingParameterError("delete_snapshots")
}
hostutils.DelayTask(ctx, disk.CleanupSnapshots, &SDiskCleanupSnapshots{convertSnapshots, deleteSnapshots})
return nil, nil
}
+174
View File
@@ -9,6 +9,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman/remotefile"
@@ -302,3 +303,176 @@ func (d *SLocalDisk) PostCreateFromImageFuse() {
log.Errorln(err)
}
}
func (d *SLocalDisk) CreateSnapshot(snapshotId string) error {
snapshotDir := d.GetSnapshotDir()
if !fileutils2.Exists(snapshotDir) {
err := exec.Command("mkdir", "-p", snapshotDir).Run()
if err != nil {
log.Errorln(err)
return err
}
}
snapshotPath := path.Join(snapshotDir, snapshotId)
err := exec.Command("mv", "-f", d.getPath(), snapshotPath).Run()
if err != nil {
log.Errorln(err)
return err
}
img, err := qemuimg.NewQemuImage(d.getPath())
if err != nil {
log.Errorln(err)
exec.Command("mv", "-f", snapshotPath, d.getPath()).Run()
return err
}
if err := img.CreateQcow2(0, false, snapshotPath); err != nil {
log.Errorf("Snapshot create image error %s", err)
exec.Command("mv", "-f", snapshotPath, d.getPath()).Run()
return err
}
return nil
}
func (d *SLocalDisk) DeleteSnapshot(snapshotId, convertSnapshot string, pendingDelete bool) error {
snapshotDir := d.GetSnapshotDir()
if len(convertSnapshot) > 0 {
if !fileutils2.Exists(snapshotDir) {
err := exec.Command("mkdir", "-p", snapshotDir).Run()
if err != nil {
log.Errorln(err)
return err
}
}
convertSnapshotPath := path.Join(snapshotDir, convertSnapshot)
output := convertSnapshotPath + ".tmp"
if fileutils2.Exists(output) {
exec.Command("rm", "-f", output).Run()
}
img, err := qemuimg.NewQemuImage(convertSnapshotPath)
if err != nil {
log.Errorln(err)
return err
}
if err = img.Convert2Qcow2To(output, true); err != nil {
log.Errorln(err)
exec.Command("rm", "-f", output).Run()
return err
}
if err = exec.Command("rm", "-f", convertSnapshotPath).Run(); err != nil {
log.Errorln(err)
return err
}
if err = exec.Command("mv", "-f", output, convertSnapshotPath).Run(); err != nil {
log.Errorln(err)
return err
}
if !pendingDelete {
err = exec.Command("rm", "-f", path.Join(snapshotDir, snapshotId)).Run()
if err != nil {
log.Errorln(err)
return err
}
}
return nil
} else {
err := exec.Command("rm", "-f", path.Join(snapshotDir, snapshotId)).Run()
if err != nil {
log.Errorln(err)
return err
}
return nil
}
}
func (d *SLocalDisk) PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
diskInfo, ok := params.(*jsonutils.JSONDict)
if !ok {
return nil, hostutils.ParamsError
}
if err := d.Probe(); err != nil {
return nil, err
}
destDir := d.Storage.GetImgsaveBackupPath()
if err := exec.Command("mkdir", "-p", destDir).Run(); err != nil {
log.Errorln(err)
return nil, err
}
backupPath := path.Join(destDir, fmt.Sprintf("%s.%s", d.Id, appctx.AppContextTaskId(ctx)))
if err := exec.Command("cp", "--sparse=always", "-f", d.GetPath(), backupPath).Run(); err != nil {
log.Errorln(err)
exec.Command("rm", "-f", backupPath).Run()
return nil, err
}
return jsonutils.NewDict(jsonutils.NewPair("backup", jsonutils.NewString(backupPath))), nil
}
func (d *SLocalDisk) ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
resetParams, ok := params.(*SDiskReset)
if !ok {
return nil, hostutils.ParamsError
}
snapshotDir := d.GetSnapshotDir()
snapshotPath := path.Join(snapshotDir, resetParams.SnapshotId)
diskTmpPath := d.GetPath() + "_reset.tmp"
if err := exec.Command("mv", "-f", d.GetPath(), diskTmpPath).Run(); err != nil {
log.Errorln(err)
return nil, err
}
if !resetParams.OutOfChain {
img, err := qemuimg.NewQemuImage(d.GetPath())
if err != nil {
log.Errorln(err)
exec.Command("mv", "-f", diskTmpPath, d.GetPath()).Run()
return nil, err
}
if err := img.CreateQcow2(0, false, snapshotPath); err != nil {
log.Errorln(err)
exec.Command("mv", "-f", diskTmpPath, d.GetPath()).Run()
return nil, err
}
} else {
if err := exec.Command("cp", "-f", snapshotPath, d.GetPath()).Run(); err != nil {
log.Errorln(err)
exec.Command("mv", "-f", diskTmpPath, d.GetPath()).Run()
return nil, err
}
}
return nil, exec.Command("rm", "-f", diskTmpPath).Run()
}
func (d *SLocalDisk) CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
cleanupParams, ok := params.(*SDiskCleanupSnapshots)
if !ok {
return nil, hostutils.ParamsError
}
snapshotDir := d.GetSnapshotDir()
for _, snapshotId := range cleanupParams.ConvertSnapshots {
snapId, _ := snapshotId.GetString()
snapshotPath := path.Join(snapshotDir, snapId)
output := snapshotPath + "_convert.tmp"
img, err := qemuimg.NewQemuImage(snapshotPath)
if err != nil {
log.Errorln(err)
return nil, err
}
if err = img.Convert2Qcow2To(output, true); err != nil {
log.Errorln(err)
return nil, err
}
if exec.Command("mv", "-f", output, snapshotPath).Run(); err != nil {
exec.Command("rm", "-f", output).Run()
log.Errorln(err)
return nil, err
}
}
for _, snapshotId := range cleanupParams.DeleteSnapshots {
snapId, _ := snapshotId.GetString()
if err := exec.Command("rm", "-f", path.Join(snapshotDir, snapId)).Run(); err != nil {
log.Errorln(err)
return nil, err
}
}
return nil, nil
}
+5
View File
@@ -47,6 +47,7 @@ type IStorage interface {
DeleteDiskfile(diskPath string) error
GetFuseTmpPath() string
GetFuseMountPath() string
GetImgsaveBackupPath() string
}
type SBaseStorage struct {
@@ -219,3 +220,7 @@ func (s *SBaseStorage) CreateDiskFromSnpashot(ctx context.Context, disk IDisk, c
}
return disk.GetDiskDesc(), nil
}
func (s *SLocalStorage) GetImgsaveBackupPath() string {
return s.getSubdirPath(_IMGSAVE_BACKUPS_)
}
+1 -1
View File
@@ -106,7 +106,7 @@ func storageUpdate(ctx context.Context, body jsonutils.JSONObject) (interface{},
storage := storageManager.GetStorage(storageId)
ret, err := modules.Hoststorages.Get(hostutils.GetComputeSession(context.Background()),
storageManager.GetHostId(), storageId,
jsonutils.NewDict(jsonutils.JSONPair{"details", jsonutils.JSONTrue}))
jsonutils.NewDict(jsonutils.NewPair("details", jsonutils.JSONTrue)))
if err != nil {
log.Errorln(err)
return nil, err
+10
View File
@@ -9,3 +9,13 @@ type SDiskCreateByDiskinfo struct {
Storage IStorage
}
type SDiskReset struct {
SnapshotId string
OutOfChain bool
}
type SDiskCleanupSnapshots struct {
ConvertSnapshots []jsonutils.JSONObject
DeleteSnapshots []jsonutils.JSONObject
}
+4
View File
@@ -14,6 +14,10 @@ type JSONPair struct {
val JSONObject
}
func NewPair(key string, val JSONObject) JSONPair {
return JSONPair{key, val}
}
func NewDict(objs ...JSONPair) *JSONDict {
dict := JSONDict{data: make(map[string]JSONObject)}
for _, o := range objs {