Cloud migrations: store snapshots in the database (#108551)

* Cloud migrations: store snapshots in the database

* update github.com/grafana/grafana-cloud-migration-snapshot to v1.9.0

* make update-workspace

* use new field name in test

* return error after call to fmt.Errorf

* create methods for readability / fix session deletiong not deleting snapshots

* remove debugging changes

* update sample.ini

* update tests to include OrgID in ListSnapshotsQuery

* lint

* lint

* Update pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go

Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

* remove TODO

* Update pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go

Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>

* remove one of the debug logs

---------

Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>
This commit is contained in:
Bruno
2025-07-25 11:41:21 -03:00
committed by GitHub
parent 47cf7ea8b6
commit b1592b5e36
17 changed files with 470 additions and 107 deletions
@@ -496,23 +496,24 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
// save snapshot to the db
snapshot := cloudmigration.CloudMigrationSnapshot{
UID: util.GenerateShortUID(),
SessionUID: cmd.SessionUID,
Status: cloudmigration.SnapshotStatusCreating,
EncryptionKey: initResp.EncryptionKey,
GMSSnapshotUID: initResp.SnapshotID,
LocalDir: filepath.Join(s.cfg.CloudMigration.SnapshotFolder, "grafana", "snapshots", initResp.SnapshotID),
UID: util.GenerateShortUID(),
SessionUID: cmd.SessionUID,
Status: cloudmigration.SnapshotStatusCreating,
GMSPublicKey: initResp.GMSPublicKey,
GMSSnapshotUID: initResp.SnapshotID,
Metadata: initResp.Metadata,
EncryptionAlgo: initResp.Algo,
LocalDir: filepath.Join(s.cfg.CloudMigration.SnapshotFolder, "grafana", "snapshots", initResp.SnapshotID),
ResourceStorageType: s.cfg.CloudMigration.ResourceStorageType,
}
uid, err := s.store.CreateSnapshot(ctx, snapshot)
if err != nil {
if err := s.store.CreateSnapshot(ctx, snapshot); err != nil {
return nil, fmt.Errorf("saving snapshot: %w", err)
}
snapshot.UID = uid
// Update status to "creating" to ensure the frontend polls from now on
if err := s.updateSnapshotWithRetries(ctx, cloudmigration.UpdateSnapshotCmd{
UID: uid,
UID: snapshot.UID,
SessionID: cmd.SessionUID,
Status: cloudmigration.SnapshotStatusCreating,
}); err != nil {
@@ -538,6 +539,7 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
s.report(asyncCtx, session, gmsclient.EventStartBuildingSnapshot, 0, nil, signedInUser.UserUID)
start := time.Now()
err := s.buildSnapshot(asyncCtx, signedInUser, initResp.MaxItemsPerPartition, initResp.Metadata, snapshot, cmd.ResourceTypes)
if err != nil {
asyncSpan.SetStatus(codes.Error, "error building snapshot")
@@ -896,10 +898,12 @@ func (s *Service) deleteLocalFiles(snapshots []cloudmigration.CloudMigrationSnap
var err error
for _, snapshot := range snapshots {
err = os.RemoveAll(snapshot.LocalDir)
if err != nil {
// in this case we only log the error, don't return it to continue with the process
s.log.Error("deleting migration snapshot files", "err", err)
if snapshot.LocalDir != "" {
err = os.RemoveAll(snapshot.LocalDir)
if err != nil {
// in this case we only log the error, don't return it to continue with the process
s.log.Error("deleting migration snapshot files", "err", err)
}
}
}
return err