CloudMigrations: Query GMS for a presigned upload url at upload time (#90505)

query GMS for an upload url at upload time
This commit is contained in:
Michael Mandrus
2024-07-17 11:53:21 -04:00
committed by GitHub
parent 970cafa20f
commit 9b7e9d992b
11 changed files with 75 additions and 12 deletions
@@ -487,7 +487,6 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
SessionUID: sessionUid,
Status: cloudmigration.SnapshotStatusCreating,
EncryptionKey: initResp.EncryptionKey,
UploadURL: initResp.UploadURL,
GMSSnapshotUID: initResp.SnapshotID,
LocalDir: filepath.Join(s.cfg.CloudMigration.SnapshotFolder, "grafana", "snapshots", initResp.SnapshotID),
}
@@ -601,11 +600,16 @@ func (s *Service) UploadSnapshot(ctx context.Context, sessionUid string, snapsho
return fmt.Errorf("fetching snapshot with uid %s: %w", snapshotUid, err)
}
s.log.Info("Uploading snapshot in local directory", "gmsSnapshotUID", snapshot.GMSSnapshotUID, "localDir", snapshot.LocalDir, "uploadURL", snapshot.UploadURL)
uploadUrl, err := s.gmsClient.CreatePresignedUploadUrl(ctx, *session, *snapshot)
if err != nil {
return fmt.Errorf("creating presigned upload url for snapshot %s: %w", snapshotUid, err)
}
s.log.Info("Uploading snapshot in local directory", "gmsSnapshotUID", snapshot.GMSSnapshotUID, "localDir", snapshot.LocalDir, "uploadURL", uploadUrl)
// start uploading the snapshot asynchronously while we return a success response to the client
go func() {
if err := s.uploadSnapshot(context.Background(), session, snapshot); err != nil {
if err := s.uploadSnapshot(context.Background(), session, snapshot, uploadUrl); err != nil {
s.log.Error("uploading snapshot", "err", err)
}
}()
@@ -449,9 +449,10 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi
}
type gmsClientMock struct {
validateKeyCalled int
startSnapshotCalled int
getStatusCalled int
validateKeyCalled int
startSnapshotCalled int
getStatusCalled int
createUploadUrlCalled int
getSnapshotResponse *cloudmigration.GetSnapshotStatusResponse
}
@@ -474,3 +475,8 @@ func (m *gmsClientMock) GetSnapshotStatus(_ context.Context, _ cloudmigration.Cl
m.getStatusCalled++
return m.getSnapshotResponse, nil
}
func (m *gmsClientMock) CreatePresignedUploadUrl(ctx context.Context, session cloudmigration.CloudMigrationSession, snapshot cloudmigration.CloudMigrationSnapshot) (string, error) {
m.createUploadUrlCalled++
return "http://localhost:3000", nil
}
@@ -249,7 +249,7 @@ func (s *Service) buildSnapshot(ctx context.Context, signedInUser *user.SignedIn
}
// asynchronous process for and updating the snapshot status
func (s *Service) uploadSnapshot(ctx context.Context, session *cloudmigration.CloudMigrationSession, snapshotMeta *cloudmigration.CloudMigrationSnapshot) (err error) {
func (s *Service) uploadSnapshot(ctx context.Context, session *cloudmigration.CloudMigrationSession, snapshotMeta *cloudmigration.CloudMigrationSnapshot, uploadUrl string) (err error) {
// TODO -- make sure we can only upload one snapshot at a time
s.buildSnapshotMutex.Lock()
defer s.buildSnapshotMutex.Unlock()
@@ -288,7 +288,7 @@ func (s *Service) uploadSnapshot(ctx context.Context, session *cloudmigration.Cl
for _, fileName := range fileNames {
filePath := filepath.Join(snapshotMeta.LocalDir, fileName)
key := fmt.Sprintf("%d/snapshots/%s/%s", session.StackID, snapshotMeta.GMSSnapshotUID, fileName)
if err := s.uploadUsingPresignedURL(ctx, snapshotMeta.UploadURL, key, filePath); err != nil {
if err := s.uploadUsingPresignedURL(ctx, uploadUrl, key, filePath); err != nil {
return fmt.Errorf("uploading snapshot file using presigned url: %w", err)
}
}
@@ -300,7 +300,7 @@ func (s *Service) uploadSnapshot(ctx context.Context, session *cloudmigration.Cl
return fmt.Errorf("seeking to beginning of index file: %w", err)
}
if err := s.objectStorage.PresignedURLUpload(ctx, snapshotMeta.UploadURL, key, indexFile); err != nil {
if err := s.objectStorage.PresignedURLUpload(ctx, uploadUrl, key, indexFile); err != nil {
return fmt.Errorf("uploading file using presigned url: %w", err)
}