diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index b8639df768..20b7aff041 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -48,6 +48,7 @@ import ( "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/billing" + "yunion.io/x/onecloud/pkg/util/rand" "yunion.io/x/onecloud/pkg/util/rbacutils" ) @@ -1915,6 +1916,14 @@ func (manager *SDiskManager) getAutoSnapshotDisksId() ([]SSnapshotPolicyDisk, er return spds, nil } +func generateAutoSnapshotName() string { + name := "Auto-" + rand.String(8) + for SnapshotManager.Query().Equals("name", name).Count() > 0 { + name = "Auto-" + rand.String(8) + } + return name +} + func (manager *SDiskManager) AutoDiskSnapshot(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) { spds, err := manager.getAutoSnapshotDisksId() if err != nil { @@ -1934,7 +1943,7 @@ func (manager *SDiskManager) AutoDiskSnapshot(ctx context.Context, userCred mccl snapCount int cleanOverdueSnapshots bool guests = disk.GetGuests() - snapshotName = "Auto-" + disk.Name + time.Now().Format("2006-01-02#15:04:05") + snapshotName = generateAutoSnapshotName() ) if utils.IsInStringArray(disk.GetStorage().StorageType, []string{api.STORAGE_LOCAL, api.STORAGE_GPFS, api.STORAGE_NFS}) && @@ -1942,18 +1951,25 @@ func (manager *SDiskManager) AutoDiskSnapshot(ctx context.Context, userCred mccl err = fmt.Errorf("Guest(%s) in status(%s) cannot do snapshot action", guests[0].Id, guests[0].Status) goto onFail } + if err := disk.CreateSnpashotAuto(ctx, userCred, snapshotName); err != nil { err = fmt.Errorf("Create snapshot auto failed %s", err) goto onFail } + // if auto snapshot count gt max auto snapshot count, do clean overdued snapshots - snapCount, err = SnapshotManager.Query().Equals("fake_deleted", false).Equals("disk_id", disk.Id). - Equals("created_by", api.SNAPSHOT_AUTO).CountWithError() + snapCount, err = SnapshotManager.Query(). + Equals("fake_deleted", false). + Equals("disk_id", disk.Id). + Equals("created_by", api.SNAPSHOT_AUTO). + CountWithError() if err != nil { err = fmt.Errorf("GetSnapshotCount fail %s", err) goto onFail } - cleanOverdueSnapshots = snapCount > (options.Options.DefaultMaxSnapshotCount - options.Options.DefaultMaxManualSnapshotCount) + + cleanOverdueSnapshots = snapCount > + (options.Options.DefaultMaxSnapshotCount - options.Options.DefaultMaxManualSnapshotCount) // else if snapshot is overdued, do clean overdued snapshots if snapshotPolicy.RetentionDays > 0 && !cleanOverdueSnapshots { @@ -1982,14 +1998,7 @@ func (manager *SDiskManager) AutoDiskSnapshot(ctx context.Context, userCred mccl } func (self *SDisk) CreateSnpashotAuto(ctx context.Context, userCred mcclient.TokenCredential, snapshotName string) error { - // TODO: snapshot quota is not enough, default is 10, or is need check - quotaPlatform := self.GetQuotaPlatformID() - pendingUsage := &SQuota{Snapshot: 1} - _, err := QuotaManager.CheckQuota(ctx, userCred, rbacutils.ScopeProject, self.GetOwnerId(), quotaPlatform, pendingUsage) - if err != nil { - return httperrors.NewOutOfQuotaError("Check set pending quota error %s", err) - } - snap, err := SnapshotManager.CreateSnapshot(ctx, userCred, api.SNAPSHOT_AUTO, self.Id, "", "", snapshotName) + snap, err := SnapshotManager.CreateSnapshot(ctx, self.GetOwnerId(), api.SNAPSHOT_AUTO, self.Id, "", "", snapshotName) if err != nil { return err } diff --git a/pkg/compute/models/snapshots.go b/pkg/compute/models/snapshots.go index f530485955..2492156885 100644 --- a/pkg/compute/models/snapshots.go +++ b/pkg/compute/models/snapshots.go @@ -410,7 +410,7 @@ func (self *SSnapshotManager) GetDiskSnapshotCount(diskId string) (int, error) { sqlchemy.Equals(q.Field("fake_deleted"), false))).CountWithError() } -func (self *SSnapshotManager) CreateSnapshot(ctx context.Context, userCred mcclient.TokenCredential, createdBy, diskId, guestId, location, name string) (*SSnapshot, error) { +func (self *SSnapshotManager) CreateSnapshot(ctx context.Context, owner mcclient.IIdentityProvider, createdBy, diskId, guestId, location, name string) (*SSnapshot, error) { iDisk, err := DiskManager.FetchById(diskId) if err != nil { return nil, err @@ -419,8 +419,8 @@ func (self *SSnapshotManager) CreateSnapshot(ctx context.Context, userCred mccli storage := disk.GetStorage() snapshot := &SSnapshot{} snapshot.SetModelManager(self, snapshot) - snapshot.ProjectId = userCred.GetProjectId() - snapshot.DomainId = userCred.GetProjectDomainId() + snapshot.ProjectId = owner.GetProjectId() + snapshot.DomainId = owner.GetProjectDomainId() snapshot.DiskId = disk.Id if len(disk.ExternalId) == 0 { snapshot.StorageId = disk.StorageId @@ -622,7 +622,7 @@ func TotalSnapshotCount(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityPr } q = CloudProviderFilter(q, q.Field("manager_id"), providers, brands, cloudEnv) - + q = q.Equals("created_by", api.SNAPSHOT_MANUAL) q = q.Equals("fake_deleted", false) return q.CountWithError() } diff --git a/pkg/compute/service/service.go b/pkg/compute/service/service.go index a8a3e67e5a..de3036ebba 100644 --- a/pkg/compute/service/service.go +++ b/pkg/compute/service/service.go @@ -84,7 +84,7 @@ func StartService() { cron.AddJobAtIntervalsWithStartRun("AutoSyncCloudaccountTask", time.Duration(opts.CloudAutoSyncIntervalSeconds)*time.Second, models.CloudaccountManager.AutoSyncCloudaccountTask, true) - cron.AddJobEveryFewDays("AutoDiskSnapshot", opts.AutoSnapshotDay, opts.AutoSnapshotHour, 0, 0, models.DiskManager.AutoDiskSnapshot, false) + cron.AddJobEveryFewHour("AutoDiskSnapshot", 1, 5, 0, models.DiskManager.AutoDiskSnapshot, false) cron.AddJobEveryFewDays("SyncSkus", opts.SyncSkusDay, opts.SyncSkusHour, 0, 0, models.SyncSkus, true) cron.AddJobEveryFewDays("StorageSnapshotsRecycle", 1, 2, 0, 0, models.StorageManager.StorageSnapshotsRecycle, false)