mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
add snapshot reference count, fix code
This commit is contained in:
@@ -2,9 +2,8 @@ package appsrv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user