CloudMigrations: Fix traceability & HTTP Client initialisation (#94141)
* Add traceability to Migration Assistant feature * Fix some compilation errors * Fix lint issues * Use async context * Add trace for LibraryElements
This commit is contained in:
@@ -23,9 +23,14 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/util/retryer"
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
|
||||
func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.SignedInUser) (*cloudmigration.MigrateDataRequest, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getMigrationDataJSON")
|
||||
defer span.End()
|
||||
|
||||
// Data sources
|
||||
dataSources, err := s.getDataSourceCommands(ctx)
|
||||
if err != nil {
|
||||
@@ -103,6 +108,9 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S
|
||||
}
|
||||
|
||||
func (s *Service) getDataSourceCommands(ctx context.Context) ([]datasources.AddDataSourceCommand, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDataSourceCommands")
|
||||
defer span.End()
|
||||
|
||||
dataSources, err := s.dsService.GetAllDataSources(ctx, &datasources.GetAllDataSourcesQuery{})
|
||||
if err != nil {
|
||||
s.log.Error("Failed to get all datasources", "err", err)
|
||||
@@ -141,6 +149,9 @@ func (s *Service) getDataSourceCommands(ctx context.Context) ([]datasources.AddD
|
||||
|
||||
// getDashboardAndFolderCommands returns the json payloads required by the dashboard and folder creation APIs
|
||||
func (s *Service) getDashboardAndFolderCommands(ctx context.Context, signedInUser *user.SignedInUser) ([]dashboards.Dashboard, []folder.CreateFolderCommand, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDashboardAndFolderCommands")
|
||||
defer span.End()
|
||||
|
||||
dashs, err := s.dashboardService.GetAllDashboards(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -196,6 +207,9 @@ type libraryElement struct {
|
||||
|
||||
// getLibraryElementsCommands returns the json payloads required by the library elements creation API
|
||||
func (s *Service) getLibraryElementsCommands(ctx context.Context, signedInUser *user.SignedInUser) ([]libraryElement, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getLibraryElementsCommands")
|
||||
defer span.End()
|
||||
|
||||
const perPage = 100
|
||||
|
||||
cmds := make([]libraryElement, 0)
|
||||
@@ -242,6 +256,9 @@ func (s *Service) getLibraryElementsCommands(ctx context.Context, signedInUser *
|
||||
|
||||
// asynchronous process for writing the snapshot to the filesystem and updating the snapshot status
|
||||
func (s *Service) buildSnapshot(ctx context.Context, signedInUser *user.SignedInUser, maxItemsPerPartition uint32, metadata []byte, snapshotMeta cloudmigration.CloudMigrationSnapshot) error {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.buildSnapshot")
|
||||
defer span.End()
|
||||
|
||||
// TODO -- make sure we can only build one snapshot at a time
|
||||
s.buildSnapshotMutex.Lock()
|
||||
defer s.buildSnapshotMutex.Unlock()
|
||||
@@ -339,6 +356,9 @@ 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, uploadUrl string) (err error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.uploadSnapshot")
|
||||
defer span.End()
|
||||
|
||||
// TODO -- make sure we can only upload one snapshot at a time
|
||||
s.buildSnapshotMutex.Lock()
|
||||
defer s.buildSnapshotMutex.Unlock()
|
||||
@@ -361,37 +381,61 @@ func (s *Service) uploadSnapshot(ctx context.Context, session *cloudmigration.Cl
|
||||
}
|
||||
}()
|
||||
|
||||
_, readIndexSpan := s.tracer.Start(ctx, "CloudMigrationService.uploadSnapshot.readIndex")
|
||||
index, err := snapshot.ReadIndex(indexFile)
|
||||
if err != nil {
|
||||
readIndexSpan.SetStatus(codes.Error, "reading index from file")
|
||||
readIndexSpan.RecordError(err)
|
||||
readIndexSpan.End()
|
||||
|
||||
return fmt.Errorf("reading index from file: %w", err)
|
||||
}
|
||||
readIndexSpan.End()
|
||||
|
||||
s.log.Debug(fmt.Sprintf("uploadSnapshot: read index file in %d ms", time.Since(start).Milliseconds()))
|
||||
|
||||
uploadCtx, uploadSpan := s.tracer.Start(ctx, "CloudMigrationService.uploadSnapshot.uploadDataFiles")
|
||||
// Upload the data files.
|
||||
for _, fileNames := range index.Items {
|
||||
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, uploadUrl, key, filePath); err != nil {
|
||||
if err := s.uploadUsingPresignedURL(uploadCtx, uploadUrl, key, filePath); err != nil {
|
||||
uploadSpan.SetStatus(codes.Error, "uploading snapshot data file using presigned url")
|
||||
uploadSpan.RecordError(err)
|
||||
uploadSpan.End()
|
||||
|
||||
return fmt.Errorf("uploading snapshot file using presigned url: %w", err)
|
||||
}
|
||||
s.log.Debug(fmt.Sprintf("uploadSnapshot: uploaded %s in %d ms", fileName, time.Since(start).Milliseconds()))
|
||||
}
|
||||
}
|
||||
uploadSpan.End()
|
||||
|
||||
s.log.Debug(fmt.Sprintf("uploadSnapshot: uploaded all data files in %d ms", time.Since(start).Milliseconds()))
|
||||
|
||||
uploadCtx, uploadSpan = s.tracer.Start(ctx, "CloudMigrationService.uploadSnapshot.uploadIndex")
|
||||
|
||||
// Upload the index file. Must be done after uploading the data files.
|
||||
key := fmt.Sprintf("%d/snapshots/%s/%s", session.StackID, snapshotMeta.GMSSnapshotUID, "index.json")
|
||||
if _, err := indexFile.Seek(0, 0); err != nil {
|
||||
uploadSpan.SetStatus(codes.Error, "seeking to beginning of index file")
|
||||
uploadSpan.RecordError(err)
|
||||
uploadSpan.End()
|
||||
|
||||
return fmt.Errorf("seeking to beginning of index file: %w", err)
|
||||
}
|
||||
|
||||
if err := s.objectStorage.PresignedURLUpload(ctx, uploadUrl, key, indexFile); err != nil {
|
||||
if err := s.objectStorage.PresignedURLUpload(uploadCtx, uploadUrl, key, indexFile); err != nil {
|
||||
uploadSpan.SetStatus(codes.Error, "uploading index file using presigned url")
|
||||
uploadSpan.RecordError(err)
|
||||
uploadSpan.End()
|
||||
|
||||
return fmt.Errorf("uploading file using presigned url: %w", err)
|
||||
}
|
||||
|
||||
uploadSpan.End()
|
||||
|
||||
s.log.Debug(fmt.Sprintf("uploadSnapshot: uploaded index file in %d ms", time.Since(start).Milliseconds()))
|
||||
s.log.Info("successfully uploaded snapshot", "snapshotUid", snapshotMeta.UID, "cloud_snapshotUid", snapshotMeta.GMSSnapshotUID)
|
||||
|
||||
@@ -408,6 +452,9 @@ func (s *Service) uploadSnapshot(ctx context.Context, session *cloudmigration.Cl
|
||||
}
|
||||
|
||||
func (s *Service) uploadUsingPresignedURL(ctx context.Context, uploadURL, key string, filePath string) (err error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.uploadUsingPresignedURL")
|
||||
defer span.End()
|
||||
|
||||
// The directory that contains the file can set in the configuration, therefore the directory can be any directory.
|
||||
// nolint:gosec
|
||||
file, err := os.Open(filePath)
|
||||
|
||||
Reference in New Issue
Block a user