Skip to content

Commit 7ae8d91

Browse files
committed
Pull image on container creation
Signed-off-by: Sascha Grunert <[email protected]>
1 parent 40d135c commit 7ae8d91

File tree

1 file changed

+84
-15
lines changed

1 file changed

+84
-15
lines changed

cmd/crictl/container.go

+84-15
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,49 @@ type createOptions struct {
5151
type runOptions struct {
5252
// configPath is path to the config for container
5353
configPath string
54+
5455
// podConfig is path to the config for sandbox
5556
podConfig string
57+
58+
// the image pull options
59+
*pullOptions
60+
}
61+
62+
type pullOptions struct {
63+
// do not pull the image on container creation
64+
dontPull bool
65+
66+
// creds is string in the format `USERNAME[:PASSWORD]` for accessing the
67+
// registry during image pull
68+
creds string
69+
70+
// auth is a base64 encoded 'USERNAME[:PASSWORD]' string used for
71+
// authentication with a registry when pulling an image
72+
auth string
73+
}
74+
75+
var pullFlags = []cli.Flag{
76+
cli.BoolFlag{
77+
Name: "no-pull",
78+
Usage: "Do not pull the image on container creation",
79+
},
80+
cli.StringFlag{
81+
Name: "creds",
82+
Value: "",
83+
Usage: "Use `USERNAME[:PASSWORD]` for accessing the registry",
84+
},
85+
cli.StringFlag{
86+
Name: "auth",
87+
Value: "",
88+
Usage: "Use `AUTH_STRING` for accessing the registry. AUTH_STRING is a base64 encoded 'USERNAME[:PASSWORD]'",
89+
},
5690
}
5791

5892
var createContainerCommand = cli.Command{
5993
Name: "create",
6094
Usage: "Create a new container",
6195
ArgsUsage: "POD container-config.[json|yaml] pod-config.[json|yaml]",
62-
Flags: []cli.Flag{},
96+
Flags: pullFlags,
6397

6498
Action: func(context *cli.Context) error {
6599
if len(context.Args()) != 3 {
@@ -69,16 +103,24 @@ var createContainerCommand = cli.Command{
69103
if err := getRuntimeClient(context); err != nil {
70104
return err
71105
}
106+
if err := getImageClient(context); err != nil {
107+
return err
108+
}
72109

73110
opts := createOptions{
74111
podID: context.Args().Get(0),
75112
runOptions: &runOptions{
76113
configPath: context.Args().Get(1),
77114
podConfig: context.Args().Get(2),
115+
pullOptions: &pullOptions{
116+
dontPull: context.Bool("no-pull"),
117+
creds: context.String("creds"),
118+
auth: context.String("auth"),
119+
},
78120
},
79121
}
80122

81-
ctrID, err := CreateContainer(runtimeClient, opts)
123+
ctrID, err := CreateContainer(imageClient, runtimeClient, opts)
82124
if err != nil {
83125
return fmt.Errorf("Creating container failed: %v", err)
84126
}
@@ -359,12 +401,10 @@ var runContainerCommand = cli.Command{
359401
Name: "run",
360402
Usage: "Run a new container inside a sandbox",
361403
ArgsUsage: "container-config.[json|yaml] pod-config.[json|yaml]",
362-
Flags: []cli.Flag{
363-
cli.StringFlag{
364-
Name: "runtime, r",
365-
Usage: "Runtime handler to use. Available options are defined by the container runtime.",
366-
},
367-
},
404+
Flags: append(pullFlags, cli.StringFlag{
405+
Name: "runtime, r",
406+
Usage: "Runtime handler to use. Available options are defined by the container runtime.",
407+
}),
368408

369409
Action: func(context *cli.Context) error {
370410
if len(context.Args()) != 2 {
@@ -374,13 +414,21 @@ var runContainerCommand = cli.Command{
374414
if err := getRuntimeClient(context); err != nil {
375415
return err
376416
}
417+
if err := getImageClient(context); err != nil {
418+
return err
419+
}
377420

378421
opts := runOptions{
379422
configPath: context.Args().Get(0),
380423
podConfig: context.Args().Get(1),
424+
pullOptions: &pullOptions{
425+
dontPull: context.Bool("no-pull"),
426+
creds: context.String("creds"),
427+
auth: context.String("auth"),
428+
},
381429
}
382430

383-
err := RunContainer(runtimeClient, opts, context.String("runtime"))
431+
err := RunContainer(imageClient, runtimeClient, opts, context.String("runtime"))
384432
if err != nil {
385433
return fmt.Errorf("Running container failed: %v", err)
386434
}
@@ -390,27 +438,30 @@ var runContainerCommand = cli.Command{
390438

391439
// RunContainer starts a container in the provided sandbox
392440
func RunContainer(
393-
client pb.RuntimeServiceClient, opts runOptions, runtime string,
441+
iClient pb.ImageServiceClient,
442+
rClient pb.RuntimeServiceClient,
443+
opts runOptions,
444+
runtime string,
394445
) error {
395446
// Create the pod
396447
podSandboxConfig, err := loadPodSandboxConfig(opts.podConfig)
397448
if err != nil {
398449
return fmt.Errorf("load podSandboxConfig failed: %v", err)
399450
}
400-
podID, err := RunPodSandbox(runtimeClient, podSandboxConfig, runtime)
451+
podID, err := RunPodSandbox(rClient, podSandboxConfig, runtime)
401452
if err != nil {
402453
return fmt.Errorf("run pod sandbox failed: %v", err)
403454
}
404455

405456
// Create the container
406457
containerOptions := createOptions{podID, &opts}
407-
ctrID, err := CreateContainer(runtimeClient, containerOptions)
458+
ctrID, err := CreateContainer(iClient, rClient, containerOptions)
408459
if err != nil {
409460
return fmt.Errorf("creating container failed: %v", err)
410461
}
411462

412463
// Start the container
413-
err = StartContainer(runtimeClient, ctrID)
464+
err = StartContainer(rClient, ctrID)
414465
if err != nil {
415466
return fmt.Errorf("starting the container %q failed: %v", ctrID, err)
416467
}
@@ -419,7 +470,12 @@ func RunContainer(
419470

420471
// CreateContainer sends a CreateContainerRequest to the server, and parses
421472
// the returned CreateContainerResponse.
422-
func CreateContainer(client pb.RuntimeServiceClient, opts createOptions) (string, error) {
473+
func CreateContainer(
474+
iClient pb.ImageServiceClient,
475+
rClient pb.RuntimeServiceClient,
476+
opts createOptions,
477+
) (string, error) {
478+
423479
config, err := loadContainerConfig(opts.configPath)
424480
if err != nil {
425481
return "", err
@@ -432,13 +488,26 @@ func CreateContainer(client pb.RuntimeServiceClient, opts createOptions) (string
432488
}
433489
}
434490

491+
if !opts.dontPull {
492+
auth, err := getAuth(opts.creds, opts.auth)
493+
if err != nil {
494+
return "", err
495+
}
496+
497+
// Try to pull the image before container creation
498+
image := config.GetImage().GetImage()
499+
if _, err := PullImage(iClient, image, auth); err != nil {
500+
return "", err
501+
}
502+
}
503+
435504
request := &pb.CreateContainerRequest{
436505
PodSandboxId: opts.podID,
437506
Config: config,
438507
SandboxConfig: podConfig,
439508
}
440509
logrus.Debugf("CreateContainerRequest: %v", request)
441-
r, err := client.CreateContainer(context.Background(), request)
510+
r, err := rClient.CreateContainer(context.Background(), request)
442511
logrus.Debugf("CreateContainerResponse: %v", r)
443512
if err != nil {
444513
return "", err

0 commit comments

Comments
 (0)