Bind restore to committed remote snapshots

This commit is contained in:
2026-08-10 20:42:43 +00:00
parent eac7e155a5
commit 4158394dcf
17 changed files with 686 additions and 75 deletions

View File

@@ -36,6 +36,9 @@ type Record struct {
LocalRelativePath string
LocalPath string
RemoteKey string
SHA256 string
Size int64
Generation string
S3Bucket string
}
@@ -119,13 +122,23 @@ func BuildPlan(
if err != nil {
return nil, err
}
result.Records = append(result.Records, Record{
manifestRecord := Record{
Kind: InputKindManifest,
LocalRelativePath: manifestRel,
LocalPath: paths.PreviousManifestPath,
RemoteKey: currentManifestKey,
S3Bucket: bucket,
})
}
if current.Commit != nil {
committedManifest, ok := current.Commit.Artifact(artifacts.RemoteArtifactTypeSessionManifest)
if !ok || committedManifest.DestinationKey != currentManifestKey {
return nil, fmt.Errorf("previous-session remote commit does not declare its session manifest")
}
manifestRecord.SHA256 = committedManifest.SHA256
manifestRecord.Size = committedManifest.Size
manifestRecord.Generation = committedManifest.Generation
}
result.Records = append(result.Records, manifestRecord)
for _, requirement := range orderedRequirements {
candidates := artifactRelativePathCandidates(requirement.Name, previousManifest, cfg)
@@ -142,18 +155,28 @@ func BuildPlan(
selectedRel := ""
selectedKey := ""
var selectedArtifact *artifacts.RemoteArtifact
for _, candidate := range candidates {
if current.Commit != nil {
artifact, ok := committedPublishedArtifact(current.Commit, previousSessionPrefix, candidate)
if !ok {
continue
}
selectedRel = candidate
selectedKey = artifact.DestinationKey
selectedArtifact = &artifact
break
}
remoteKey := artifacts.S3PublishedOutputKey(previousSessionPrefix, candidate)
exists, err := store.Exists(ctx, remoteKey)
if err != nil {
return nil, fmt.Errorf("check previous-session artifact object %q: %w", remoteKey, err)
}
if !exists {
continue
if exists {
selectedRel = candidate
selectedKey = remoteKey
break
}
selectedRel = candidate
selectedKey = remoteKey
break
}
if selectedRel == "" {
if requirement.Required {
@@ -174,7 +197,7 @@ func BuildPlan(
if err != nil {
return nil, err
}
result.Records = append(result.Records, Record{
record := Record{
Kind: InputKindArtifact,
RequirementName: requirement.Name,
Required: requirement.Required,
@@ -182,7 +205,13 @@ func BuildPlan(
LocalPath: localPath,
RemoteKey: selectedKey,
S3Bucket: bucket,
})
}
if selectedArtifact != nil {
record.SHA256 = selectedArtifact.SHA256
record.Size = selectedArtifact.Size
record.Generation = selectedArtifact.Generation
}
result.Records = append(result.Records, record)
}
sort.Strings(result.SkippedMissing)
@@ -195,6 +224,19 @@ func BuildPlan(
return result, nil
}
func committedPublishedArtifact(commit *artifacts.RemoteCommitManifest, sessionPrefix, relativePath string) (artifacts.RemoteArtifact, bool) {
if commit == nil {
return artifacts.RemoteArtifact{}, false
}
want := artifacts.S3RunRelativeDestinationKey(artifacts.S3RunPrefix(sessionPrefix, commit.RunID), relativePath)
for _, artifact := range commit.Artifacts {
if artifact.Type == artifacts.RemoteArtifactTypePublishedOutput && artifact.DestinationKey == want {
return artifact, true
}
}
return artifacts.RemoteArtifact{}, false
}
func requiredPreviousArtifactNames(requirements []artifacts.PreviousArtifactRequirement) []string {
names := make([]string, 0, len(requirements))
for _, requirement := range requirements {