Skip to content

Commit ea02006

Browse files
committed
history: make sure build record is finalized before exporting
Signed-off-by: CrazyMax <[email protected]>
1 parent a9ab809 commit ea02006

File tree

4 files changed

+63
-20
lines changed

4 files changed

+63
-20
lines changed

commands/history/export.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ import (
2020
)
2121

2222
type exportOptions struct {
23-
builder string
24-
refs []string
25-
output string
26-
all bool
23+
builder string
24+
refs []string
25+
output string
26+
all bool
27+
finalize bool
2728
}
2829

2930
func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) error {
@@ -62,6 +63,22 @@ func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) e
6263
return errors.Errorf("no record found for ref %q", ref)
6364
}
6465

66+
if opts.finalize {
67+
for _, rec := range recs {
68+
if rec.Trace == nil {
69+
if err := finalizeRecord(ctx, rec.Ref, nodes); err != nil {
70+
return err
71+
}
72+
}
73+
}
74+
recs, err = queryRecords(ctx, ref, nodes, &queryOptions{
75+
CompletedOnly: true,
76+
})
77+
if err != nil {
78+
return err
79+
}
80+
}
81+
6582
if ref == "" {
6683
slices.SortFunc(recs, func(a, b historyRecord) int {
6784
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
@@ -154,7 +171,8 @@ func exportCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
154171

155172
flags := cmd.Flags()
156173
flags.StringVarP(&options.output, "output", "o", "", "Output file path")
157-
flags.BoolVar(&options.all, "all", false, "Export all records for the builder")
174+
flags.BoolVar(&options.all, "all", false, "Export all build records for the builder")
175+
flags.BoolVar(&options.finalize, "finalize", false, "Ensure build records are finalized before exporting")
158176

159177
return cmd
160178
}

commands/history/trace.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"github.com/docker/buildx/util/otelutil"
1818
"github.com/docker/buildx/util/otelutil/jaeger"
1919
"github.com/docker/cli/cli/command"
20-
controlapi "github.com/moby/buildkit/api/services/control"
2120
"github.com/opencontainers/go-digest"
2221
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
2322
"github.com/pkg/browser"
@@ -57,14 +56,7 @@ func loadTrace(ctx context.Context, ref string, nodes []builder.Node) (string, [
5756
// build is complete but no trace yet. try to finalize the trace
5857
time.Sleep(1 * time.Second) // give some extra time for last parts of trace to be written
5958

60-
c, err := rec.node.Driver.Client(ctx)
61-
if err != nil {
62-
return "", nil, err
63-
}
64-
_, err = c.ControlClient().UpdateBuildHistory(ctx, &controlapi.UpdateBuildHistoryRequest{
65-
Ref: rec.Ref,
66-
Finalize: true,
67-
})
59+
err := finalizeRecord(ctx, rec.Ref, []builder.Node{*rec.node})
6860
if err != nil {
6961
return "", nil, err
7062
}

commands/history/utils.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,28 @@ func queryRecords(ctx context.Context, ref string, nodes []builder.Node, opts *q
248248
return out, nil
249249
}
250250

251+
func finalizeRecord(ctx context.Context, ref string, nodes []builder.Node) error {
252+
eg, ctx := errgroup.WithContext(ctx)
253+
for _, node := range nodes {
254+
node := node
255+
eg.Go(func() error {
256+
if node.Driver == nil {
257+
return nil
258+
}
259+
c, err := node.Driver.Client(ctx)
260+
if err != nil {
261+
return err
262+
}
263+
_, err = c.ControlClient().UpdateBuildHistory(ctx, &controlapi.UpdateBuildHistoryRequest{
264+
Ref: ref,
265+
Finalize: true,
266+
})
267+
return err
268+
})
269+
}
270+
return eg.Wait()
271+
}
272+
251273
func formatDuration(d time.Duration) string {
252274
if d < time.Minute {
253275
return fmt.Sprintf("%.1fs", d.Seconds())

docs/reference/buildx_history_export.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ Export build records into Docker Desktop bundle
55

66
### Options
77

8-
| Name | Type | Default | Description |
9-
|:---------------------------------------|:---------|:--------|:-----------------------------------------|
10-
| [`--all`](#all) | `bool` | | Export all records for the builder |
11-
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
12-
| [`-D`](#debug), [`--debug`](#debug) | `bool` | | Enable debug logging |
13-
| [`-o`](#output), [`--output`](#output) | `string` | | Output file path |
8+
| Name | Type | Default | Description |
9+
|:---------------------------------------|:---------|:--------|:----------------------------------------------------|
10+
| [`--all`](#all) | `bool` | | Export all build records for the builder |
11+
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
12+
| [`-D`](#debug), [`--debug`](#debug) | `bool` | | Enable debug logging |
13+
| [`--finalize`](#finalize) | `bool` | | Ensure build records are finalized before exporting |
14+
| [`-o`](#output), [`--output`](#output) | `string` | | Output file path |
1415

1516

1617
<!---MARKER_GEN_END-->
@@ -49,6 +50,16 @@ docker buildx history export --builder builder0 ^1 -o builder0-build.dockerbuild
4950
docker buildx history export --debug qu2gsuo8ejqrwdfii23xkkckt -o debug-build.dockerbuild
5051
```
5152

53+
### <a name="finalize"></a> Ensure build records are finalized before exporting (--finalize)
54+
55+
Clients can report their own traces concurrently and not all traces may be
56+
finalized when a build is completed. Use the `--finalize` flag to ensure all
57+
traces are finalized before exporting.
58+
59+
```console
60+
docker buildx history export --finalize qu2gsuo8ejqrwdfii23xkkckt -o finalized-build.dockerbuild
61+
```
62+
5263
### <a name="output"></a> Export a single build to a custom file (--output)
5364

5465
```console

0 commit comments

Comments
 (0)