add timeout parameter to cli and driver

Signed-off-by: avoidik <avoidik@gmail.com>
Signed-off-by: Viacheslav Vasilyev <avoidik@gmail.com>
This commit is contained in:
avoidik 2024-07-10 15:25:03 +01:00 committed by Camden Narzt
parent 6df3a09284
commit b1c75354e9
No known key found for this signature in database
GPG Key ID: E349304DE45D816B
13 changed files with 54 additions and 18 deletions

View File

@ -344,6 +344,7 @@ type CreateOpts struct {
Use bool
Endpoint string
Append bool
Timeout time.Duration
}
func Create(ctx context.Context, txn *store.Txn, dockerCli command.Cli, opts CreateOpts) (*Builder, error) {
@ -524,7 +525,7 @@ func Create(ctx context.Context, txn *store.Txn, dockerCli command.Cli, opts Cre
}
cancelCtx, cancel := context.WithCancelCause(ctx)
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
timeoutCtx, _ := context.WithTimeoutCause(cancelCtx, opts.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
nodes, err := b.LoadNodes(timeoutCtx, WithData())

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"time"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/driver"
@ -27,6 +28,7 @@ type createOptions struct {
buildkitdFlags string
buildkitdConfigFile string
bootstrap bool
timeout time.Duration
// upgrade bool // perform upgrade of the driver
}
@ -61,6 +63,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
Use: in.use,
Endpoint: ep,
Append: in.actionAppend,
Timeout: in.timeout,
})
if err != nil {
return err
@ -80,7 +83,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
return nil
}
func createCmd(dockerCli command.Cli) *cobra.Command {
func createCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options createOptions
var drivers bytes.Buffer
@ -96,6 +99,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
Short: "Create a new builder instance",
Args: cli.RequiresMaxArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
options.timeout = rootOpts.timeout
return runCreate(cmd.Context(), dockerCli, options, args)
},
ValidArgsFunction: completion.Disable,

View File

@ -24,6 +24,7 @@ import (
type inspectOptions struct {
bootstrap bool
builder string
timeout time.Duration
}
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
}
timeoutCtx, cancel := context.WithCancelCause(ctx)
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
nodes, err := b.LoadNodes(timeoutCtx, builder.WithData())
@ -180,6 +181,7 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
if len(args) > 0 {
options.builder = args[0]
}
options.timeout = rootOpts.timeout
return runInspect(cmd.Context(), dockerCli, options)
},
ValidArgsFunction: completion.BuilderNames(dockerCli),

View File

@ -40,6 +40,7 @@ const (
type lsOptions struct {
format string
noTrunc bool
timeout time.Duration
}
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 {
}
timeoutCtx, cancel := context.WithCancelCause(ctx)
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
eg, _ := errgroup.WithContext(timeoutCtx)
@ -97,7 +98,7 @@ func runLs(ctx context.Context, dockerCli command.Cli, in lsOptions) error {
return nil
}
func lsCmd(dockerCli command.Cli) *cobra.Command {
func lsCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options lsOptions
cmd := &cobra.Command{
@ -105,6 +106,7 @@ func lsCmd(dockerCli command.Cli) *cobra.Command {
Short: "List builder instances",
Args: cli.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
options.timeout = rootOpts.timeout
return runLs(cmd.Context(), dockerCli, options)
},
ValidArgsFunction: completion.Disable,

View File

@ -21,6 +21,7 @@ type rmOptions struct {
keepDaemon bool
allInactive bool
force bool
timeout time.Duration
}
const (
@ -109,6 +110,7 @@ func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
}
options.builders = args
}
options.timeout = rootOpts.timeout
return runRm(cmd.Context(), dockerCli, options)
},
ValidArgsFunction: completion.BuilderNames(dockerCli),
@ -151,7 +153,7 @@ func rmAllInactive(ctx context.Context, txn *store.Txn, dockerCli command.Cli, i
}
timeoutCtx, cancel := context.WithCancelCause(ctx)
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
timeoutCtx, _ = context.WithTimeoutCause(timeoutCtx, in.timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
eg, _ := errgroup.WithContext(timeoutCtx)

View File

@ -3,6 +3,7 @@ package commands
import (
"fmt"
"os"
"time"
debugcmd "github.com/docker/buildx/commands/debug"
historycmd "github.com/docker/buildx/commands/history"
@ -22,6 +23,8 @@ import (
"github.com/spf13/pflag"
)
const defaultTimeoutCli = 20 * time.Second
func NewRootCmd(name string, isPlugin bool, dockerCli *command.DockerCli) *cobra.Command {
var opt rootOptions
cmd := &cobra.Command{
@ -96,6 +99,7 @@ func NewRootCmd(name string, isPlugin bool, dockerCli *command.DockerCli) *cobra
type rootOptions struct {
builder string
debug bool
timeout time.Duration
}
func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) {
@ -104,10 +108,10 @@ func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) {
cmd.AddCommand(
buildCmd(dockerCli, opts, nil),
bakeCmd(dockerCli, opts),
createCmd(dockerCli),
createCmd(dockerCli, opts),
dialStdioCmd(dockerCli, opts),
rmCmd(dockerCli, opts),
lsCmd(dockerCli),
lsCmd(dockerCli, opts),
useCmd(dockerCli, opts),
inspectCmd(dockerCli, opts),
stopCmd(dockerCli, opts),
@ -134,4 +138,14 @@ func addCommands(cmd *cobra.Command, opts *rootOptions, dockerCli command.Cli) {
func rootFlags(options *rootOptions, flags *pflag.FlagSet) {
flags.StringVar(&options.builder, "builder", os.Getenv("BUILDX_BUILDER"), "Override the configured builder instance")
flags.BoolVarP(&options.debug, "debug", "D", debug.IsEnabled(), "Enable debug logging")
var timeoutDuration = defaultTimeoutCli
if value, ok := os.LookupEnv("BUILDX_TIMEOUT"); ok {
var err error
timeoutDuration, err = time.ParseDuration(value)
if err != nil {
timeoutDuration = defaultTimeoutCli
}
}
flags.DurationVar(&options.timeout, "timeout", timeoutDuration, "Override the default global timeout (20 seconds)")
}

View File

@ -3,6 +3,7 @@ package control
import (
"context"
"io"
"time"
"github.com/docker/buildx/build"
cbuild "github.com/docker/buildx/controller/build"
@ -24,3 +25,7 @@ type BuildxController interface {
DisconnectProcess(ctx context.Context, pid string) error
Inspect(ctx context.Context) *cbuild.Options
}
type ControlOptions struct {
Timeout time.Duration
}

View File

@ -217,7 +217,7 @@ func (d *Driver) wait(ctx context.Context, l progress.SubLogger) error {
select {
case <-ctx.Done():
return context.Cause(ctx)
case <-time.After(time.Duration(try*120) * time.Millisecond):
case <-time.After(d.Timeout / time.Microsecond):
try++
continue
}

View File

@ -52,7 +52,6 @@ type Driver struct {
configMapClient clientcorev1.ConfigMapInterface
podChooser podchooser.PodChooser
defaultLoad bool
timeout time.Duration
}
func (d *Driver) IsMobyDriver() bool {
@ -91,7 +90,7 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
}
}
return sub.Wrap(
fmt.Sprintf("waiting for %d pods to be ready, timeout: %s", d.minReplicas, units.HumanDuration(d.timeout)),
fmt.Sprintf("waiting for %d pods to be ready, timeout: %s", d.minReplicas, units.HumanDuration(d.Timeout)),
func() error {
return d.wait(ctx)
})
@ -105,8 +104,8 @@ func (d *Driver) wait(ctx context.Context) error {
depl *appsv1.Deployment
)
timeoutChan := time.After(d.timeout)
ticker := time.NewTicker(100 * time.Millisecond)
timeoutChan := time.After(d.Timeout)
ticker := time.NewTicker(d.Timeout / time.Microsecond)
defer ticker.Stop()
for {

View File

@ -23,7 +23,6 @@ import (
const (
prioritySupported = 40
priorityUnsupported = 80
defaultTimeout = 120 * time.Second
)
type ClientConfig interface {
@ -134,7 +133,7 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
}
d.defaultLoad = defaultLoad
d.timeout = timeout
d.Timeout = timeout
d.deployment, d.configMaps, err = manifest.NewDeployment(deploymentOpt)
if err != nil {
@ -175,7 +174,7 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
}
defaultLoad := false
timeout := defaultTimeout
timeout := cfg.Timeout
deploymentOpt.Qemu.Image = bkimage.QemuImage

View File

@ -4,6 +4,7 @@ import (
"context"
"sort"
"sync"
"time"
"github.com/docker/cli/cli/context/store"
dockerclient "github.com/docker/docker/client"
@ -38,6 +39,7 @@ type InitConfig struct {
Platforms []specs.Platform
ContextPathHash string
DialMeta map[string][]string
Timeout time.Duration
}
var drivers map[string]Factory

View File

@ -8,7 +8,6 @@ import (
"os"
"strings"
"sync"
"time"
"github.com/docker/buildx/driver"
util "github.com/docker/buildx/driver/remote/util"
@ -48,7 +47,7 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
}
return progress.Wrap("[internal] waiting for connection", l, func(_ progress.SubLogger) error {
cancelCtx, cancel := context.WithCancelCause(ctx)
ctx, _ := context.WithTimeoutCause(cancelCtx, 20*time.Second, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
ctx, _ := context.WithTimeoutCause(cancelCtx, d.Timeout, errors.WithStack(context.DeadlineExceeded)) //nolint:govet,lostcancel // no need to manually cancel this context as we already rely on parent
defer func() { cancel(errors.WithStack(context.Canceled)) }()
return c.Wait(ctx)
})

View File

@ -6,6 +6,7 @@ import (
"path/filepath"
"strconv"
"strings"
"time"
"github.com/docker/buildx/driver"
util "github.com/docker/buildx/driver/remote/util"
@ -87,6 +88,12 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
return nil, err
}
d.defaultLoad = parsed
case "timeout":
parsed, err := time.ParseDuration(v)
if err != nil {
return nil, err
}
d.Timeout = parsed
default:
return nil, errors.Errorf("invalid driver option %s for remote driver", k)
}