Skip to content

Commit b57b2b0

Browse files
committed
Add --pull-timeout flag to crictl create, run and pull commands
This allows to set a pull context timeout for the supported commands. Runtimes may or may not use the timeout from the RPC for image pulls, but `crictl` should generally support that feature. Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
1 parent 6c92933 commit b57b2b0

File tree

2 files changed

+59
-18
lines changed

2 files changed

+59
-18
lines changed

cmd/crictl/container.go

+34-15
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ type pullOptions struct {
8585
// Username to use for accessing the registry
8686
// password will be requested on the command line
8787
username string
88+
89+
// timeout is the maximum time used for the image pull
90+
timeout time.Duration
8891
}
8992

9093
var createPullFlags = []cli.Flag{
@@ -111,6 +114,17 @@ var createPullFlags = []cli.Flag{
111114
Value: "",
112115
Usage: "Use `USERNAME` for accessing the registry. The password will be requested on the command line",
113116
},
117+
&cli.DurationFlag{
118+
Name: "cancel-timeout",
119+
Aliases: []string{"T"},
120+
Usage: "Seconds to wait for a container create request to complete before cancelling the request",
121+
},
122+
&cli.DurationFlag{
123+
Name: "pull-timeout",
124+
Aliases: []string{"pt"},
125+
Usage: "Maximum time to be used for pulling the image, disabled if set to 0s",
126+
EnvVars: []string{"CRICTL_PULL_TIMEOUT"},
127+
},
114128
}
115129

116130
var runPullFlags = []cli.Flag{
@@ -137,17 +151,28 @@ var runPullFlags = []cli.Flag{
137151
Value: "",
138152
Usage: "Use `USERNAME` for accessing the registry. password will be requested",
139153
},
154+
&cli.StringFlag{
155+
Name: "runtime",
156+
Aliases: []string{"r"},
157+
Usage: "Runtime handler to use. Available options are defined by the container runtime.",
158+
}, &cli.DurationFlag{
159+
Name: "timeout",
160+
Aliases: []string{"t"},
161+
Usage: "Seconds to wait for a container create request before cancelling the request",
162+
},
163+
&cli.DurationFlag{
164+
Name: "pull-timeout",
165+
Aliases: []string{"pt"},
166+
Usage: "Maximum time to be used for pulling the image, disabled if set to 0s",
167+
EnvVars: []string{"CRICTL_PULL_TIMEOUT"},
168+
},
140169
}
141170

142171
var createContainerCommand = &cli.Command{
143172
Name: "create",
144173
Usage: "Create a new container",
145174
ArgsUsage: "POD container-config.[json|yaml] pod-config.[json|yaml]",
146-
Flags: append(createPullFlags, &cli.DurationFlag{
147-
Name: "cancel-timeout",
148-
Aliases: []string{"T"},
149-
Usage: "Seconds to wait for a container create request to complete before cancelling the request",
150-
}),
175+
Flags: createPullFlags,
151176

152177
Action: func(c *cli.Context) (err error) {
153178
if c.Args().Len() != 3 {
@@ -177,6 +202,7 @@ var createContainerCommand = &cli.Command{
177202
creds: c.String("creds"),
178203
auth: c.String("auth"),
179204
username: c.String("username"),
205+
timeout: c.Duration("pull-timeout"),
180206
},
181207
timeout: c.Duration("cancel-timeout"),
182208
},
@@ -581,15 +607,7 @@ var runContainerCommand = &cli.Command{
581607
Name: "run",
582608
Usage: "Run a new container inside a sandbox",
583609
ArgsUsage: "container-config.[json|yaml] pod-config.[json|yaml]",
584-
Flags: append(runPullFlags, &cli.StringFlag{
585-
Name: "runtime",
586-
Aliases: []string{"r"},
587-
Usage: "Runtime handler to use. Available options are defined by the container runtime.",
588-
}, &cli.DurationFlag{
589-
Name: "timeout",
590-
Aliases: []string{"t"},
591-
Usage: "Seconds to wait for a container create request before cancelling the request",
592-
}),
610+
Flags: runPullFlags,
593611

594612
Action: func(c *cli.Context) (err error) {
595613
if c.Args().Len() != 2 {
@@ -617,6 +635,7 @@ var runContainerCommand = &cli.Command{
617635
creds: c.String("creds"),
618636
auth: c.String("auth"),
619637
username: c.String("username"),
638+
timeout: c.Duration("pull-timeout"),
620639
},
621640
timeout: c.Duration("timeout"),
622641
}
@@ -747,7 +766,7 @@ func CreateContainer(
747766

748767
// Try to pull the image before container creation
749768
ann := config.GetImage().GetAnnotations()
750-
if _, err := PullImageWithSandbox(iClient, image, auth, podConfig, ann); err != nil {
769+
if _, err := PullImageWithSandbox(iClient, image, auth, podConfig, ann, opts.pullOptions.timeout); err != nil {
751770
return "", err
752771
}
753772
}

cmd/crictl/image.go

+25-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"strconv"
2727
"strings"
2828
"syscall"
29+
"time"
2930

3031
"github.com/docker/go-units"
3132
"github.com/sirupsen/logrus"
@@ -83,6 +84,12 @@ var pullImageCommand = &cli.Command{
8384
Aliases: []string{"a"},
8485
Usage: "Annotation to be set on the pulled image",
8586
},
87+
&cli.DurationFlag{
88+
Name: "pull-timeout",
89+
Aliases: []string{"pt"},
90+
Usage: "Maximum time to be used for pulling the image, disabled if set to 0s",
91+
EnvVars: []string{"CRICTL_PULL_TIMEOUT"},
92+
},
8693
},
8794
ArgsUsage: "NAME[:TAG|@DIGEST]",
8895
Action: func(c *cli.Context) error {
@@ -119,7 +126,8 @@ var pullImageCommand = &cli.Command{
119126
return err
120127
}
121128
}
122-
r, err := PullImageWithSandbox(imageClient, imageName, auth, sandbox, ann)
129+
timeout := c.Duration("timeout")
130+
r, err := PullImageWithSandbox(imageClient, imageName, auth, sandbox, ann, timeout)
123131
if err != nil {
124132
return fmt.Errorf("pulling image: %w", err)
125133
}
@@ -633,7 +641,7 @@ func normalizeRepoDigest(repoDigests []string) (string, string) {
633641

634642
// PullImageWithSandbox sends a PullImageRequest to the server, and parses
635643
// the returned PullImageResponse.
636-
func PullImageWithSandbox(client internalapi.ImageManagerService, image string, auth *pb.AuthConfig, sandbox *pb.PodSandboxConfig, ann map[string]string) (*pb.PullImageResponse, error) {
644+
func PullImageWithSandbox(client internalapi.ImageManagerService, image string, auth *pb.AuthConfig, sandbox *pb.PodSandboxConfig, ann map[string]string, timeout time.Duration) (*pb.PullImageResponse, error) {
637645
request := &pb.PullImageRequest{
638646
Image: &pb.ImageSpec{
639647
Image: image,
@@ -647,7 +655,21 @@ func PullImageWithSandbox(client internalapi.ImageManagerService, image string,
647655
request.SandboxConfig = sandbox
648656
}
649657
logrus.Debugf("PullImageRequest: %v", request)
650-
res, err := client.PullImage(context.TODO(), request.Image, request.Auth, request.SandboxConfig)
658+
659+
if timeout < 0 {
660+
return nil, errors.New("timeout should be bigger than 0")
661+
}
662+
663+
ctx, cancel := context.WithCancel(context.Background())
664+
defer cancel()
665+
666+
if timeout > 0 {
667+
logrus.Debugf("Using context with timeout of %s", timeout)
668+
ctx, cancel = context.WithTimeout(ctx, timeout)
669+
defer cancel()
670+
}
671+
672+
res, err := client.PullImage(ctx, request.Image, request.Auth, request.SandboxConfig)
651673
if err != nil {
652674
return nil, err
653675
}

0 commit comments

Comments
 (0)