fix(auth): serialize restore checkpoint lifecycle

This commit is contained in:
2026-08-18 02:43:42 +02:00
parent 39a0fdbd00
commit 6ec5b76c54
4 changed files with 391 additions and 40 deletions
+12 -2
View File
@@ -97,8 +97,12 @@ type dependencies struct {
// Create creates an archive with the real Docker command boundary. It performs no shell
// interpolation and never supplies secret contents in process arguments.
func Create(ctx context.Context, installation config.Installation, request CreateRequest) (Result, error) {
return createWithDependencies(ctx, installation, request, productionCreateDependencies(installation))
}
func productionCreateDependencies(installation config.Installation) dependencies {
runner := hostRunner{runner: compose.NewRunner(""), binary: "docker", profile: installation.Profile}
return createWithDependencies(ctx, installation, request, dependencies{
return dependencies{
runner: runner,
now: time.Now,
homeDir: os.UserHomeDir,
@@ -113,7 +117,7 @@ func Create(ctx context.Context, installation config.Installation, request Creat
sleep: time.Sleep,
reserveOutput: reserveArchiveOutput,
publishReserved: publishReservedArchive,
})
}
}
func createWithDependencies(ctx context.Context, installation config.Installation, request CreateRequest, dependencies dependencies) (result Result, resultErr error) {
@@ -133,7 +137,13 @@ func createWithDependencies(ctx context.Context, installation config.Installatio
resultErr = errors.Join(resultErr, fmt.Errorf("release backup lifecycle lock: %w", releaseErr))
}
}()
return createWithDependenciesLockHeld(ctx, installation, request, dependencies)
}
// createWithDependenciesLockHeld performs backup creation while the caller owns the installation
// lifecycle lock. It must never acquire a lifecycle lock itself: Restore uses this primitive to
// create its recovery checkpoint inside its already-locked transaction.
func createWithDependenciesLockHeld(ctx context.Context, installation config.Installation, request CreateRequest, dependencies dependencies) (result Result, resultErr error) {
if err := rejectInlineSecretValues(installation.EnvFile); err != nil {
return Result{}, err
}