snapshot fixs

This commit is contained in:
wanyaoqi
2018-10-29 19:41:43 +08:00
parent cf095f2d9d
commit 724169ef44
7 changed files with 67 additions and 30 deletions
+7 -11
View File
@@ -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)
+7 -1
View File
@@ -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")
}
+18 -7
View File
@@ -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 {
+15 -10
View File
@@ -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)
}
+10 -1
View File
@@ -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 {
+1
View File
@@ -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