add snapshot reference count, fix code

This commit is contained in:
wanyaoqi
2018-12-11 20:31:36 +08:00
parent 6a6806e65b
commit 86b3b38f41
9 changed files with 49 additions and 9 deletions
+1 -2
View File
@@ -2,9 +2,8 @@ package appsrv
import (
"context"
"net/http"
"fmt"
"net/http"
"yunion.io/x/onecloud/pkg/httperrors"
)
+6 -3
View File
@@ -100,6 +100,9 @@ type SDisk struct {
// # backing template id and type
TemplateId string `width:"256" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=True)
// backing snapshot id
SnapshotId string `width:"256" charset:"ascii" nullable:"true" list:"user"`
// # file system
FsFormat string `width:"32" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True)
// # disk type, OS, SWAP, DAT
@@ -446,6 +449,8 @@ func (self *SDisk) StartAllocate(ctx context.Context, host *SHost, storage *SSto
content.Add(jsonutils.NewInt(int64(self.DiskSize)), "size")
if len(snapshot) > 0 {
content.Add(jsonutils.NewString(snapshot), "snapshot")
SnapshotManager.AddRefCount(self.SnapshotId, 1)
self.SetMetadata(ctx, "merge_snapshot", jsonutils.JSONTrue, userCred)
} else if len(templateId) > 0 {
content.Add(jsonutils.NewString(templateId), "image_id")
}
@@ -1078,7 +1083,6 @@ func parseDiskInfo(ctx context.Context, userCred mcclient.TokenCredential, info
} else if strings.HasPrefix(p, "snapshot-") {
// HACK: use snapshot creat disk format snapshot-id
// example: snapshot-3140cecb-ccc4-4865-abae-3a5ba8c69d9b
log.Errorln("The snapshot XXXXXXX Create disk", p[len("snapshot-"):])
if err := fillDiskConfigBySnapshot(userCred, &diskConfig, p[len("snapshot-"):]); err != nil {
return nil, err
}
@@ -1167,8 +1171,7 @@ func (self *SDisk) fetchDiskInfo(diskConfig *SDiskConfig) {
self.TemplateId = diskConfig.ImageId
self.DiskType = DISK_TYPE_SYS
} else if len(diskConfig.SnapshotId) > 0 {
// XXX: HACK reuse template id as snapshot id
// self.TemplateId = "snapshot-" + diskConfig.SnapshotId
self.SnapshotId = diskConfig.SnapshotId
self.DiskType = diskConfig.DiskType
}
if len(diskConfig.Fs) > 0 {
+16 -1
View File
@@ -8,6 +8,7 @@ import (
"net/http"
"strconv"
"strings"
"time"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
@@ -22,7 +23,6 @@ import (
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/seclib2"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/util/billing"
@@ -2112,3 +2112,18 @@ func (self *SGuest) doSaveRenewInfo(userCred mcclient.TokenCredential, bc *billi
db.OpsLog.LogEvent(self, db.ACT_RENEW, self.GetShortDesc(), userCred)
return nil
}
func (self *SGuest) AllowPerformStreamDisksComplete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "stream-disks-complete")
}
func (self *SGuest) PerformStreamDisksComplete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
for _, disk := range self.GetDisks() {
d := disk.GetDisk()
if len(d.SnapshotId) > 0 {
SnapshotManager.AddRefCount(d.SnapshotId, -1)
d.SetMetadata(ctx, "merge_snapshot", jsonutils.JSONFalse, userCred)
}
}
return nil, nil
}
+6
View File
@@ -166,6 +166,12 @@ func (self *SGuestdisk) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
if len(tid) > 0 {
desc.Add(jsonutils.NewString(tid), "template_id")
}
if len(disk.SnapshotId) > 0 {
needMerge := disk.GetMetadata("merge_snapshot", nil)
if needMerge == "true" {
desc.Set("merge_snapshot", jsonutils.JSONTrue)
}
}
fs := disk.GetFsFormat()
if len(fs) > 0 {
desc.Add(jsonutils.NewString(fs), "fs")
-1
View File
@@ -2350,7 +2350,6 @@ func (self *SGuest) CreateDisksOnHost(ctx context.Context, userCred mcclient.Tok
return err
}
data.Add(jsonutils.NewString(disk.Id), fmt.Sprintf("disk.%d.id", idx))
log.Errorln("CreateDisksOnHost XXXXXXXXXX", diskConfig.SnapshotId)
if len(diskConfig.SnapshotId) > 0 {
data.Add(jsonutils.NewString(diskConfig.SnapshotId), fmt.Sprintf("disk.%d.snapshot", idx))
}
+17
View File
@@ -49,6 +49,9 @@ type SSnapshot struct {
FakeDeleted bool `nullable:"false" default:"false" index:"true"`
DiskType string `width:"32" charset:"ascii" nullable:"true" list:"user"`
// create disk from snapshot, snapshot as disk backing file
RefCount int `nullable:"false" default:"0" list:"user"`
CloudregionId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
}
@@ -246,6 +249,17 @@ func (self *SSnapshot) GetHost() *SHost {
return storage.GetMasterHost()
}
func (self *SSnapshotManager) AddRefCount(snapshotId string, count int) {
iSnapshot, _ := self.FetchById(snapshotId)
snapshot := iSnapshot.(*SSnapshot)
if snapshot != nil {
self.TableSpec().Update(snapshot, func() error {
snapshot.RefCount += count
return nil
})
}
}
func (self *SSnapshotManager) GetDiskSnapshotsByCreate(diskId, createdBy string) []SSnapshot {
dest := make([]SSnapshot, 0)
q := self.Query().SubQuery()
@@ -343,6 +357,9 @@ func (self *SSnapshot) StartSnapshotDeleteTask(ctx context.Context, userCred mcc
}
func (self *SSnapshot) ValidateDeleteCondition(ctx context.Context) error {
if self.RefCount > 0 {
return fmt.Errorf("Snapshot reference(by disk) count > 0, can not delete")
}
return nil
}
+3
View File
@@ -93,6 +93,9 @@ func (self *DiskDeleteTask) OnGuestDiskDeleteComplete(ctx context.Context, obj d
disk := obj.(*models.SDisk)
self.CleanHostSchedCache(disk)
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE, disk.GetShortDesc(), self.UserCred)
if len(disk.SnapshotId) > 0 && disk.GetMetadata("merge_snapshot", nil) == "true" {
models.SnapshotManager.AddRefCount(disk.SnapshotId, -1)
}
disk.RealDelete(ctx, self.UserCred)
self.SetStageComplete(ctx, nil)
}
@@ -67,7 +67,6 @@ func (self *KVMGuestCreateDiskTask) OnKvmDiskPrepared(ctx context.Context, obj d
disk := iDisk.(*models.SDisk)
if disk.Status == models.DISK_INIT {
snapshotId, _ := self.Params.GetString(fmt.Sprintf("disk.%d.snapshot", diskIndex))
log.Errorln("XXXXXXXXXXXXXX", snapshotId)
err = disk.StartDiskCreateTask(ctx, self.UserCred, false, snapshotId, self.GetTaskId())
if err != nil {
self.SetStageFailed(ctx, err.Error())
-1
View File
@@ -73,7 +73,6 @@ func inputCheck(ctx context.Context) (string, error) {
var userCred = auth.FetchUserCredential(ctx, nil)
if !userCred.HasSystemAdminPrivelege() {
return "", httperrors.NewForbiddenError("System admin only")
}
var params = appctx.AppContextParams(ctx)