mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
Merge pull request #381 in YUNIONIO/onecloud from ~WANYAOQI/onecloud:bugfix/wyq/snopshot-bugfix to release/2.2.0
* commit '724169ef44aa4aced5b93b985402bcdfb1bd682d': snapshot fixs
This commit is contained in:
@@ -3959,7 +3959,7 @@ func (self *SGuest) PerformDiskSnapshot(ctx context.Context, userCred mcclient.T
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError(err.Error())
|
||||
}
|
||||
err = ValidateSnapshotName(self.Hypervisor, name)
|
||||
err = ValidateSnapshotName(self.Hypervisor, name, userCred.GetProjectId())
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError(err.Error())
|
||||
}
|
||||
@@ -3967,16 +3967,12 @@ func (self *SGuest) PerformDiskSnapshot(ctx context.Context, userCred mcclient.T
|
||||
return nil, httperrors.NewNotFoundError("Guest disk %s not found", diskId)
|
||||
}
|
||||
if self.GetHypervisor() == HYPERVISOR_KVM {
|
||||
snapshots := SnapshotManager.GetDiskSnapshotsByCreate(diskId, MANUAL)
|
||||
if snapshots != nil {
|
||||
if len(snapshots) >= options.Options.DefaultMaxManualSnapshotCount {
|
||||
return nil, httperrors.NewBadRequestError("Disk %s snapshot full, cannot take any more", diskId)
|
||||
}
|
||||
for _, snapshot := range snapshots {
|
||||
if snapshot.Name == name {
|
||||
return nil, httperrors.NewBadRequestError("Name Conflict")
|
||||
}
|
||||
}
|
||||
q := SnapshotManager.Query()
|
||||
cnt := q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), diskId),
|
||||
sqlchemy.Equals(q.Field("created_by"), MANUAL),
|
||||
sqlchemy.Equals(q.Field("fake_deleted"), false))).Count()
|
||||
if cnt >= options.Options.DefaultMaxManualSnapshotCount {
|
||||
return nil, httperrors.NewBadRequestError("Disk %s snapshot full, cannot take any more", diskId)
|
||||
}
|
||||
pendingUsage := &SQuota{Snapshot: 1}
|
||||
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, self.ProjectId, pendingUsage)
|
||||
|
||||
@@ -58,7 +58,13 @@ func init() {
|
||||
SnapshotManager = &SSnapshotManager{SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(SSnapshot{}, "snapshots_tbl", "snapshot", "snapshots")}
|
||||
}
|
||||
|
||||
func ValidateSnapshotName(hypervisor, name string) error {
|
||||
func ValidateSnapshotName(hypervisor, name, owner string) error {
|
||||
q := SnapshotManager.Query()
|
||||
q = SnapshotManager.FilterByName(q, name)
|
||||
q = SnapshotManager.FilterByOwner(q, owner)
|
||||
if q.Count() != 0 {
|
||||
return fmt.Errorf("Name conflict?")
|
||||
}
|
||||
if !('A' <= name[0] && name[0] <= 'Z' || 'a' <= name[0] && name[0] <= 'z') {
|
||||
return fmt.Errorf("Name must start with letter")
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type DiskResetTask struct {
|
||||
@@ -21,18 +22,28 @@ func init() {
|
||||
taskman.RegisterTask(DiskCleanUpSnapshotsTask{})
|
||||
}
|
||||
|
||||
func (self *DiskResetTask) TaskFailed(ctx context.Context, disk *models.SDisk, reason string) {
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESET_DISK, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
}
|
||||
|
||||
func (self *DiskResetTask) TaskCompleted(ctx context.Context, disk *models.SDisk, data *jsonutils.JSONDict) {
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESET_DISK, data, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, data)
|
||||
}
|
||||
|
||||
func (self *DiskResetTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
disk := obj.(*models.SDisk)
|
||||
storage := disk.GetStorage()
|
||||
if storage == nil {
|
||||
disk.SetStatus(self.UserCred, models.DISK_READY, "")
|
||||
self.SetStageFailed(ctx, "Disk storage not found")
|
||||
self.TaskFailed(ctx, disk, "Disk storage not found")
|
||||
return
|
||||
}
|
||||
host := storage.GetMasterHost()
|
||||
if host == nil {
|
||||
disk.SetStatus(self.UserCred, models.DISK_READY, "")
|
||||
self.SetStageFailed(ctx, "Storage master host not found")
|
||||
self.TaskFailed(ctx, disk, "Storage master host not found")
|
||||
return
|
||||
}
|
||||
self.RequestResetDisk(ctx, disk, host)
|
||||
@@ -42,7 +53,7 @@ func (self *DiskResetTask) RequestResetDisk(ctx context.Context, disk *models.SD
|
||||
snapshotId, err := self.Params.GetString("snapshot_id")
|
||||
if err != nil {
|
||||
disk.SetStatus(self.UserCred, models.DISK_READY, "")
|
||||
self.SetStageFailed(ctx, fmt.Sprintf("Get snapshotId error %s", err.Error()))
|
||||
self.TaskFailed(ctx, disk, fmt.Sprintf("Get snapshotId error %s", err.Error()))
|
||||
return
|
||||
}
|
||||
iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId)
|
||||
@@ -62,7 +73,7 @@ func (self *DiskResetTask) RequestResetDisk(ctx context.Context, disk *models.SD
|
||||
err = host.GetHostDriver().RequestResetDisk(ctx, host, disk, params, self)
|
||||
if err != nil {
|
||||
disk.SetStatus(self.UserCred, models.DISK_READY, "")
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
self.TaskFailed(ctx, disk, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +94,7 @@ func (self *DiskResetTask) OnRequestResetDisk(ctx context.Context, disk *models.
|
||||
err := disk.CleanUpDiskSnapshots(ctx, self.UserCred, snapshot)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
self.SetStageFailed(ctx, fmt.Sprintf("OnRequestResetDisk %s", err.Error()))
|
||||
self.TaskFailed(ctx, disk, fmt.Sprintf("OnRequestResetDisk %s", err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -93,13 +104,13 @@ func (self *DiskResetTask) OnRequestResetDisk(ctx context.Context, disk *models.
|
||||
guest.StartGueststartTask(ctx, self.UserCred, nil, self.GetTaskId())
|
||||
} else {
|
||||
disk.SetStatus(self.UserCred, models.DISK_READY, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
self.TaskCompleted(ctx, disk, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *DiskResetTask) OnStartGuest(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
|
||||
disk.SetStatus(self.UserCred, models.DISK_READY, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
self.TaskCompleted(ctx, disk, nil)
|
||||
}
|
||||
|
||||
type DiskCleanUpSnapshotsTask struct {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type DiskResizeTask struct {
|
||||
@@ -30,11 +31,12 @@ func (self *DiskResizeTask) OnInit(ctx context.Context, obj db.IStandaloneModel,
|
||||
host = guest.GetHost()
|
||||
}
|
||||
}
|
||||
resion := "Cannot find host for disk"
|
||||
reason := "Cannot find host for disk"
|
||||
if host == nil || host.HostStatus != models.HOST_ONLINE {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), resion)
|
||||
self.SetStageFailed(ctx, resion)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE_FAIL, resion, self.GetUserCred())
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), reason)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE_FAIL, reason, self.GetUserCred())
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESIZE, reason, self.UserCred, false)
|
||||
} else {
|
||||
disk.SetStatus(self.GetUserCred(), models.DISK_START_RESIZE, "")
|
||||
for _, guest := range disk.GetGuests() {
|
||||
@@ -64,10 +66,11 @@ func (self *DiskResizeTask) OnStartResizeDiskSucc(ctx context.Context, disk *mod
|
||||
disk.SetStatus(self.GetUserCred(), models.DISK_RESIZING, "")
|
||||
}
|
||||
|
||||
func (self *DiskResizeTask) OnStartResizeDiskFailed(ctx context.Context, disk *models.SDisk, resion error) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), resion.Error())
|
||||
self.SetStageFailed(ctx, resion.Error())
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE_FAIL, resion.Error(), self.GetUserCred())
|
||||
func (self *DiskResizeTask) OnStartResizeDiskFailed(ctx context.Context, disk *models.SDisk, reason error) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), reason.Error())
|
||||
self.SetStageFailed(ctx, reason.Error())
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE_FAIL, reason.Error(), self.GetUserCred())
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESIZE, reason.Error(), self.UserCred, false)
|
||||
}
|
||||
|
||||
func (self *DiskResizeTask) OnDiskResizeComplete(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
|
||||
@@ -99,11 +102,13 @@ func (self *DiskResizeTask) OnDiskResizeComplete(ctx context.Context, disk *mode
|
||||
db.OpsLog.LogEvent(disk, db.ACT_UPDATE_STATUS, notes, self.UserCred)
|
||||
self.CleanHostSchedCache(disk)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE, disk.GetShortDesc(), self.UserCred)
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESIZE, nil, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, disk.GetShortDesc())
|
||||
self.finalReleasePendingUsage(ctx)
|
||||
}
|
||||
|
||||
func (self *DiskResizeTask) OnDiskResizeCompleteFailed(ctx context.Context, disk *models.SDisk, resion error) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), resion.Error())
|
||||
func (self *DiskResizeTask) OnDiskResizeCompleteFailed(ctx context.Context, disk *models.SDisk, reason error) {
|
||||
disk.SetDiskReady(ctx, self.GetUserCred(), reason.Error())
|
||||
db.OpsLog.LogEvent(disk, db.ACT_RESIZE_FAIL, disk.GetShortDesc(), self.UserCred)
|
||||
logclient.AddActionLog(disk, logclient.ACT_RESIZE, reason.Error(), self.UserCred, false)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type GuestDiskSnapshotTask struct {
|
||||
@@ -103,6 +104,10 @@ func (self *GuestDiskSnapshotTask) TaskComplete(ctx context.Context, guest *mode
|
||||
}
|
||||
|
||||
func (self *GuestDiskSnapshotTask) OnSyncStatus(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
snapshotId, _ := self.Params.GetString("snapshot_id")
|
||||
iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId)
|
||||
db.OpsLog.LogEvent(iSnapshot, db.ACT_SNAPSHOT_DONE, nil, self.UserCred)
|
||||
logclient.AddActionLog(iSnapshot, logclient.ACT_CREATE, nil, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -116,6 +121,8 @@ func (self *GuestDiskSnapshotTask) TaskFailed(ctx context.Context, guest *models
|
||||
})
|
||||
self.SetStageFailed(ctx, reason)
|
||||
guest.SetStatus(self.UserCred, models.VM_SNAPSHOT_FAILED, reason)
|
||||
db.OpsLog.LogEvent(iSnapshot, db.ACT_SNAPSHOT_FAIL, reason, self.UserCred)
|
||||
logclient.AddActionLog(iSnapshot, logclient.ACT_CREATE, reason, self.UserCred, false)
|
||||
}
|
||||
|
||||
/***************************** Snapshot Delete Task *****************************/
|
||||
@@ -289,6 +296,8 @@ func (self *SnapshotDeleteTask) OnReloadDiskSnapshot(ctx context.Context, snapsh
|
||||
}
|
||||
|
||||
func (self *SnapshotDeleteTask) TaskComplete(ctx context.Context, snapshot *models.SSnapshot, data jsonutils.JSONObject) {
|
||||
db.OpsLog.LogEvent(snapshot, db.ACT_SNAPSHOT_DELETE, nil, self.UserCred)
|
||||
logclient.AddActionLog(snapshot, logclient.ACT_DELETE, nil, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ const (
|
||||
SnapshotStatusAccomplished SnapshotStatusType = "accomplished"
|
||||
SnapshotStatusProgress SnapshotStatusType = "progressing"
|
||||
SnapshotStatusFailed SnapshotStatusType = "failed"
|
||||
|
||||
SnapshotTypeSystem string = "System"
|
||||
SnapshotTypeData string = "Data"
|
||||
)
|
||||
|
||||
type SSnapshot struct {
|
||||
@@ -65,7 +68,13 @@ func (self *SSnapshot) GetDiskId() string {
|
||||
}
|
||||
|
||||
func (self *SSnapshot) GetDiskType() string {
|
||||
return self.SourceDiskType
|
||||
if self.SourceDiskType == SnapshotTypeSystem {
|
||||
return models.DISK_TYPE_SYS
|
||||
} else if self.SourceDiskType == SnapshotTypeData {
|
||||
return models.DISK_TYPE_DATA
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SSnapshot) Refresh() error {
|
||||
|
||||
@@ -56,6 +56,7 @@ const (
|
||||
ACT_VM_SYNC_STATUS = "同步状态"
|
||||
ACT_VM_UNBIND_KEYPAIR = "解绑密钥"
|
||||
ACT_VM_ASSIGNSECGROUP = "关联安全组"
|
||||
ACT_RESET_DISK = "回滚磁盘"
|
||||
)
|
||||
|
||||
// golang 不支持 const 的string array, http://t.cn/EzAvbw8
|
||||
|
||||
Reference in New Issue
Block a user