history: finalize export records on their owning node

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2026-03-17 11:08:18 +01:00
committed by CrazyMax
parent 9fef35c40b
commit b1a2f3006b
3 changed files with 46 additions and 38 deletions
+33 -19
View File
@@ -4,7 +4,6 @@ import (
"context"
"io"
"os"
"slices"
"github.com/containerd/console"
"github.com/containerd/platforms"
@@ -53,37 +52,52 @@ func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) e
return errors.Errorf("no record found for ref %q", ref)
}
if opts.finalize {
var finalized bool
toExport := recs
if !opts.all && ref == "" {
latestRef := recs[0].Ref
recCount := 0
for _, rec := range recs {
if rec.Trace == nil {
finalized = true
if err := finalizeRecord(ctx, rec.Ref, nodes); err != nil {
return err
}
if rec.Ref != latestRef {
break
}
recCount++
}
toExport = recs[:recCount]
}
if opts.finalize {
seen := make(map[string]struct{}, len(toExport))
var finalized bool
for _, rec := range toExport {
if rec.node == nil || rec.Trace != nil {
continue
}
key := rec.node.Builder + "\x00" + rec.node.Name + "\x00" + rec.Ref
if _, ok := seen[key]; ok {
continue
}
seen[key] = struct{}{}
finalized = true
if err := finalizeRecord(ctx, rec.Ref, *rec.node); err != nil {
return err
}
}
if finalized {
recs, err = queryRecords(ctx, ref, nodes, &queryOptions{
queryRef := ref
if !opts.all {
queryRef = toExport[0].Ref
}
recs, err = queryRecords(ctx, queryRef, nodes, &queryOptions{
CompletedOnly: true,
})
if err != nil {
return err
}
toExport = recs
}
}
if ref == "" {
slices.SortFunc(recs, func(a, b historyRecord) int {
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
})
}
res = append(res, toExport...)
if opts.all {
res = append(res, recs...)
break
} else {
res = append(res, recs[0])
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ func loadTrace(ctx context.Context, ref string, nodes []builder.Node) (string, [
// build is complete but no trace yet. try to finalize the trace
time.Sleep(1 * time.Second) // give some extra time for last parts of trace to be written
err := finalizeRecord(ctx, rec.Ref, []builder.Node{*rec.node})
err := finalizeRecord(ctx, rec.Ref, *rec.node)
if err != nil {
return "", nil, err
}
+12 -18
View File
@@ -257,25 +257,19 @@ func queryRecords(ctx context.Context, ref string, nodes []builder.Node, opts *q
return out, nil
}
func finalizeRecord(ctx context.Context, ref string, nodes []builder.Node) error {
eg, ctx := errgroup.WithContext(ctx)
for _, node := range nodes {
eg.Go(func() error {
if node.Driver == nil {
return nil
}
c, err := node.Driver.Client(ctx)
if err != nil {
return err
}
_, err = c.ControlClient().UpdateBuildHistory(ctx, &controlapi.UpdateBuildHistoryRequest{
Ref: ref,
Finalize: true,
})
return err
})
func finalizeRecord(ctx context.Context, ref string, node builder.Node) error {
if node.Driver == nil {
return nil
}
return eg.Wait()
c, err := node.Driver.Client(ctx)
if err != nil {
return err
}
_, err = c.ControlClient().UpdateBuildHistory(ctx, &controlapi.UpdateBuildHistoryRequest{
Ref: ref,
Finalize: true,
})
return err
}
func formatDuration(d time.Duration) string {