Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incusd/recover: Handle instances last #678

Merged
merged 1 commit into from
Mar 27, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 34 additions & 19 deletions cmd/incusd/api_internal_recover.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ func internalRecoverScan(ctx context.Context, s *state.State, userPools []api.St

// If in import mode and no dependency errors, then re-create missing DB records.

// Create the pools themselves.
for _, pool := range pools {
// Create missing storage pool DB record if neeed.
if pool.ID() == storagePools.PoolIDTemporary {
Expand Down Expand Up @@ -369,10 +370,11 @@ func internalRecoverScan(ctx context.Context, s *state.State, userPools []api.St

// Record this newly created pool so that defer doesn't unmount on return.
pools[pool.Name()] = newPool
pool = newPool // Replace temporary pool handle with proper one from DB.
}
}

// Create any missing instance, storage volume, and storage bucket records.
// Recover the storage volumes and buckets.
for _, pool := range pools {
for projectName, poolVols := range poolsProjectVols[pool.Name()] {
projectInfo := projects[projectName]

Expand All @@ -381,7 +383,6 @@ func internalRecoverScan(ctx context.Context, s *state.State, userPools []api.St
return response.SmartError(fmt.Errorf("Project %q not found", projectName))
}

profileProjectName := project.ProfileProjectFromRecord(projectInfo)
customStorageProjectName := project.StorageVolumeProjectFromRecord(projectInfo, db.StoragePoolVolumeTypeCustom)

// Recover unknown custom volumes (do this first before recovering instances so that any
Expand All @@ -402,6 +403,36 @@ func internalRecoverScan(ctx context.Context, s *state.State, userPools []api.St
revert.Add(cleanup)
}

// Recover unknown buckets.
for _, poolVol := range poolVols {
// Skip non bucket volumes.
if poolVol.Bucket == nil {
continue
}

// Import bucket.
cleanup, err := pool.ImportBucket(projectName, poolVol, nil)
if err != nil {
return response.SmartError(fmt.Errorf("Failed importing bucket %q in project %q: %w", poolVol.Bucket.Name, projectName, err))
}

revert.Add(cleanup)
}
}
}

// Finally restore the instances.
for _, pool := range pools {
for projectName, poolVols := range poolsProjectVols[pool.Name()] {
projectInfo := projects[projectName]

if projectInfo == nil {
// Shouldn't happen as we validated this above, but be sure for safety.
return response.SmartError(fmt.Errorf("Project %q not found", projectName))
}

profileProjectName := project.ProfileProjectFromRecord(projectInfo)

// Recover unknown instance volumes.
for _, poolVol := range poolVols {
if poolVol.Container == nil && (poolVol.Volume != nil || poolVol.Bucket != nil) {
Expand Down Expand Up @@ -462,22 +493,6 @@ func internalRecoverScan(ctx context.Context, s *state.State, userPools []api.St
}
}
}

// Recover unknown buckets.
for _, poolVol := range poolVols {
// Skip non bucket volumes.
if poolVol.Bucket == nil {
continue
}

// Import bucket.
cleanup, err := pool.ImportBucket(projectName, poolVol, nil)
if err != nil {
return response.SmartError(fmt.Errorf("Failed importing bucket %q in project %q: %w", poolVol.Bucket.Name, projectName, err))
}

revert.Add(cleanup)
}
}
}

Expand Down
Loading