Skip to content

Commit 8041544

Browse files
committed
revisit: add timeout parameter to cli and driver
Signed-off-by: Viacheslav Vasilyev <avoidik@gmail.com>
1 parent ef0a7b3 commit 8041544

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+231
-151
lines changed

builder/builder.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ type CreateOpts struct {
345345
Use bool
346346
Endpoint string
347347
Append bool
348+
Timeout time.Duration
348349
}
349350

350351
func Create(ctx context.Context, txn *store.Txn, dockerCli command.Cli, opts CreateOpts) (*Builder, error) {
@@ -525,7 +526,7 @@ func Create(ctx context.Context, txn *store.Txn, dockerCli command.Cli, opts Cre
525526
}
526527

527528
cancelCtx, cancel := context.WithCancelCause(ctx)
528-
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
529+
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, opts.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
529530
defer func() { cancel(errors.WithStack(context.Canceled)) }()
530531

531532
nodes, err := b.LoadNodes(timeoutCtx, WithData())

builder/node.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"sort"
77
"strings"
8+
"time"
89

910
"github.com/containerd/platforms"
1011
"github.com/docker/buildx/driver"
@@ -39,6 +40,8 @@ type Node struct {
3940
CDIDevices []client.CDIDevice
4041
}
4142

43+
const defaultDriverTimeout = 120 * time.Second
44+
4245
// Nodes returns nodes for this builder.
4346
func (b *Builder) Nodes() []Node {
4447
return b.nodes
@@ -131,6 +134,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N
131134
Platforms: n.Platforms,
132135
ContextPathHash: b.opts.contextPathHash,
133136
DialMeta: lno.dialMeta,
137+
Timeout: defaultDriverTimeout,
134138
})
135139
if err != nil {
136140
node.Err = err

commands/create.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7+
"time"
78

89
"github.com/docker/buildx/builder"
910
"github.com/docker/buildx/driver"
@@ -27,6 +28,7 @@ type createOptions struct {
2728
buildkitdFlags string
2829
buildkitdConfigFile string
2930
bootstrap bool
31+
timeout time.Duration
3032
// upgrade bool // perform upgrade of the driver
3133
}
3234

@@ -61,6 +63,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
6163
Use: in.use,
6264
Endpoint: ep,
6365
Append: in.actionAppend,
66+
Timeout: in.timeout,
6467
})
6568
if err != nil {
6669
return err
@@ -80,7 +83,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
8083
return nil
8184
}
8285

83-
func createCmd(dockerCli command.Cli) *cobra.Command {
86+
func createCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
8487
var options createOptions
8588

8689
var drivers bytes.Buffer
@@ -96,6 +99,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
9699
Short: "Create a new builder instance",
97100
Args: cli.RequiresMaxArgs(1),
98101
RunE: func(cmd *cobra.Command, args []string) error {
102+
options.timeout = rootOpts.timeout
99103
return runCreate(cmd.Context(), dockerCli, options, args)
100104
},
101105
ValidArgsFunction: completion.Disable,

commands/diskusage.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ type duOptions struct {
6565
filter opts.FilterOpt
6666
verbose bool
6767
format string
68+
timeout time.Duration
6869
}
6970

7071
func runDiskUsage(ctx context.Context, dockerCli command.Cli, opts duOptions) error {
@@ -92,7 +93,11 @@ func runDiskUsage(ctx context.Context, dockerCli command.Cli, opts duOptions) er
9293
return err
9394
}
9495

95-
nodes, err := b.LoadNodes(ctx)
96+
timeoutCtx, cancel := context.WithCancelCause(ctx)
97+
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, opts.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
98+
defer func() { cancel(errors.WithStack(context.Canceled)) }()
99+
100+
nodes, err := b.LoadNodes(timeoutCtx)
96101
if err != nil {
97102
return err
98103
}
@@ -187,6 +192,7 @@ func duCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
187192
Args: cli.NoArgs,
188193
RunE: func(cmd *cobra.Command, args []string) error {
189194
options.builder = rootOpts.builder
195+
options.timeout = rootOpts.timeout
190196
return runDiskUsage(cmd.Context(), dockerCli, options)
191197
},
192198
ValidArgsFunction: completion.Disable,

commands/inspect.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
type inspectOptions struct {
2525
bootstrap bool
2626
builder string
27+
timeout time.Duration
2728
}
2829

2930
func runInspect(ctx context.Context, dockerCli command.Cli, in inspectOptions) error {
@@ -36,7 +37,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, in inspectOptions) e
3637
}
3738

3839
timeoutCtx, cancel := context.WithCancelCause(ctx)
39-
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
40+
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
4041
defer func() { cancel(errors.WithStack(context.Canceled)) }()
4142

4243
nodes, err := b.LoadNodes(timeoutCtx, builder.WithData())
@@ -180,6 +181,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
180181
if len(args) > 0 {
181182
options.builder = args[0]
182183
}
184+
options.timeout = rootOpts.timeout
183185
return runInspect(cmd.Context(), dockerCli, options)
184186
},
185187
ValidArgsFunction: completion.BuilderNames(dockerCli),

commands/ls.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const (
4040
type lsOptions struct {
4141
format string
4242
noTrunc bool
43+
timeout time.Duration
4344
}
4445

4546
func runLs(ctx context.Context, dockerCli command.Cli, in lsOptions) error {
@@ -60,7 +61,7 @@ func runLs(ctx context.Context, dockerCli command.Cli, in lsOptions) error {
6061
}
6162

6263
timeoutCtx, cancel := context.WithCancelCause(ctx)
63-
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
64+
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
6465
defer func() { cancel(errors.WithStack(context.Canceled)) }()
6566

6667
eg, _ := errgroup.WithContext(timeoutCtx)
@@ -97,14 +98,15 @@ func runLs(ctx context.Context, dockerCli command.Cli, in lsOptions) error {
9798
return nil
9899
}
99100

100-
func lsCmd(dockerCli command.Cli) *cobra.Command {
101+
func lsCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
101102
var options lsOptions
102103

103104
cmd := &cobra.Command{
104105
Use: "ls",
105106
Short: "List builder instances",
106107
Args: cli.ExactArgs(0),
107108
RunE: func(cmd *cobra.Command, args []string) error {
109+
options.timeout = rootOpts.timeout
108110
return runLs(cmd.Context(), dockerCli, options)
109111
},
110112
ValidArgsFunction: completion.Disable,

commands/prune.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type pruneOptions struct {
3636
minFreeSpace opts.MemBytes
3737
force bool
3838
verbose bool
39+
timeout time.Duration
3940
}
4041

4142
const (
@@ -68,7 +69,11 @@ func runPrune(ctx context.Context, dockerCli command.Cli, opts pruneOptions) err
6869
return err
6970
}
7071

71-
nodes, err := b.LoadNodes(ctx)
72+
timeoutCtx, cancel := context.WithCancelCause(ctx)
73+
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, opts.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
74+
defer func() { cancel(errors.WithStack(context.Canceled)) }()
75+
76+
nodes, err := b.LoadNodes(timeoutCtx)
7277
if err != nil {
7378
return err
7479
}
@@ -168,6 +173,7 @@ func pruneCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
168173
Args: cli.NoArgs,
169174
RunE: func(cmd *cobra.Command, args []string) error {
170175
options.builder = rootOpts.builder
176+
options.timeout = rootOpts.timeout
171177
return runPrune(cmd.Context(), dockerCli, options)
172178
},
173179
ValidArgsFunction: completion.Disable,

commands/rm.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type rmOptions struct {
2121
keepDaemon bool
2222
allInactive bool
2323
force bool
24+
timeout time.Duration
2425
}
2526

2627
const (
@@ -109,6 +110,7 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
109110
}
110111
options.builders = args
111112
}
113+
options.timeout = rootOpts.timeout
112114
return runRm(cmd.Context(), dockerCli, options)
113115
},
114116
ValidArgsFunction: completion.BuilderNames(dockerCli),
@@ -152,7 +154,7 @@ func rmAllInactive(ctx context.Context, txn *store.Txn, dockerCli command.Cli, i
152154
}
153155

154156
timeoutCtx, cancel := context.WithCancelCause(ctx)
155-
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
157+
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
156158
defer func() { cancel(errors.WithStack(context.Canceled)) }()
157159

158160
eg, _ := errgroup.WithContext(timeoutCtx)

commands/root.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"fmt"
55
"os"
6+
"time"
67

78
historycmd "github.com/docker/buildx/commands/history"
89
imagetoolscmd "github.com/docker/buildx/commands/imagetools"
@@ -23,6 +24,8 @@ import (
2324

2425
const experimentalCommandHint = `Experimental commands and flags are hidden. Set BUILDX_EXPERIMENTAL=1 to show them.`
2526

27+
const defaultTimeoutCli = 20 * time.Second
28+
2629
func NewRootCmd(name string, isPlugin bool, dockerCli *command.DockerCli) *cobra.Command {
2730
var opt rootOptions
2831
cmd := &cobra.Command{
@@ -102,6 +105,7 @@ func NewRootCmd(name string, isPlugin bool, dockerCli *command.DockerCli) *cobra
102105
type rootOptions struct {
103106
builder string
104107
debug bool
108+
timeout time.Duration
105109
}
106110

107111
func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) {
@@ -110,10 +114,10 @@ func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) {
110114
cmd.AddCommand(
111115
buildCmd(dockerCli, opts, nil),
112116
bakeCmd(dockerCli, opts),
113-
createCmd(dockerCli),
117+
createCmd(dockerCli, opts),
114118
dialStdioCmd(dockerCli, opts),
115119
rmCmd(dockerCli, opts),
116-
lsCmd(dockerCli),
120+
lsCmd(dockerCli, opts),
117121
useCmd(dockerCli, opts),
118122
inspectCmd(dockerCli, opts),
119123
stopCmd(dockerCli, opts),
@@ -139,4 +143,14 @@ func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) {
139143
func rootFlags(options *rootOptions, flags *pflag.FlagSet) {
140144
flags.StringVar(&options.builder, "builder", os.Getenv("BUILDX_BUILDER"), "Override the configured builder instance")
141145
flags.BoolVarP(&options.debug, "debug", "D", debug.IsEnabled(), "Enable debug logging")
146+
147+
var timeoutDuration = defaultTimeoutCli
148+
if value, ok := os.LookupEnv("BUILDX_TIMEOUT"); ok {
149+
var err error
150+
timeoutDuration, err = time.ParseDuration(value)
151+
if err != nil {
152+
timeoutDuration = defaultTimeoutCli
153+
}
154+
}
155+
flags.DurationVar(&options.timeout, "timeout", timeoutDuration, "Override the default global timeout (as duration, for example 1m20s)")
142156
}

commands/stop.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ package commands
22

33
import (
44
"context"
5+
"time"
56

67
"github.com/docker/buildx/builder"
78
"github.com/docker/buildx/util/cobrautil/completion"
89
"github.com/docker/cli/cli"
910
"github.com/docker/cli/cli/command"
11+
"github.com/pkg/errors"
1012
"github.com/spf13/cobra"
1113
)
1214

1315
type stopOptions struct {
1416
builder string
17+
timeout time.Duration
1518
}
1619

1720
func runStop(ctx context.Context, dockerCli command.Cli, in stopOptions) error {
@@ -22,7 +25,12 @@ func runStop(ctx context.Context, dockerCli command.Cli, in stopOptions) error {
2225
if err != nil {
2326
return err
2427
}
25-
nodes, err := b.LoadNodes(ctx)
28+
29+
timeoutCtx, cancel := context.WithCancelCause(ctx)
30+
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet // no need to manually cancel this context as we already rely on parent
31+
defer func() { cancel(errors.WithStack(context.Canceled)) }()
32+
33+
nodes, err := b.LoadNodes(timeoutCtx)
2634
if err != nil {
2735
return err
2836
}
@@ -42,6 +50,7 @@ func stopCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
4250
if len(args) > 0 {
4351
options.builder = args[0]
4452
}
53+
options.timeout = rootOpts.timeout
4554
return runStop(cmd.Context(), dockerCli, options)
4655
},
4756
ValidArgsFunction: completion.BuilderNames(dockerCli),

0 commit comments

Comments
 (0)