@@ -51,15 +51,49 @@ type createOptions struct {
51
51
type runOptions struct {
52
52
// configPath is path to the config for container
53
53
configPath string
54
+
54
55
// podConfig is path to the config for sandbox
55
56
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
+ },
56
90
}
57
91
58
92
var createContainerCommand = cli.Command {
59
93
Name : "create" ,
60
94
Usage : "Create a new container" ,
61
95
ArgsUsage : "POD container-config.[json|yaml] pod-config.[json|yaml]" ,
62
- Flags : []cli. Flag {} ,
96
+ Flags : pullFlags ,
63
97
64
98
Action : func (context * cli.Context ) error {
65
99
if len (context .Args ()) != 3 {
@@ -69,16 +103,24 @@ var createContainerCommand = cli.Command{
69
103
if err := getRuntimeClient (context ); err != nil {
70
104
return err
71
105
}
106
+ if err := getImageClient (context ); err != nil {
107
+ return err
108
+ }
72
109
73
110
opts := createOptions {
74
111
podID : context .Args ().Get (0 ),
75
112
runOptions : & runOptions {
76
113
configPath : context .Args ().Get (1 ),
77
114
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
+ },
78
120
},
79
121
}
80
122
81
- ctrID , err := CreateContainer (runtimeClient , opts )
123
+ ctrID , err := CreateContainer (imageClient , runtimeClient , opts )
82
124
if err != nil {
83
125
return fmt .Errorf ("Creating container failed: %v" , err )
84
126
}
@@ -359,12 +401,10 @@ var runContainerCommand = cli.Command{
359
401
Name : "run" ,
360
402
Usage : "Run a new container inside a sandbox" ,
361
403
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
+ }),
368
408
369
409
Action : func (context * cli.Context ) error {
370
410
if len (context .Args ()) != 2 {
@@ -374,13 +414,21 @@ var runContainerCommand = cli.Command{
374
414
if err := getRuntimeClient (context ); err != nil {
375
415
return err
376
416
}
417
+ if err := getImageClient (context ); err != nil {
418
+ return err
419
+ }
377
420
378
421
opts := runOptions {
379
422
configPath : context .Args ().Get (0 ),
380
423
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
+ },
381
429
}
382
430
383
- err := RunContainer (runtimeClient , opts , context .String ("runtime" ))
431
+ err := RunContainer (imageClient , runtimeClient , opts , context .String ("runtime" ))
384
432
if err != nil {
385
433
return fmt .Errorf ("Running container failed: %v" , err )
386
434
}
@@ -390,27 +438,30 @@ var runContainerCommand = cli.Command{
390
438
391
439
// RunContainer starts a container in the provided sandbox
392
440
func RunContainer (
393
- client pb.RuntimeServiceClient , opts runOptions , runtime string ,
441
+ iClient pb.ImageServiceClient ,
442
+ rClient pb.RuntimeServiceClient ,
443
+ opts runOptions ,
444
+ runtime string ,
394
445
) error {
395
446
// Create the pod
396
447
podSandboxConfig , err := loadPodSandboxConfig (opts .podConfig )
397
448
if err != nil {
398
449
return fmt .Errorf ("load podSandboxConfig failed: %v" , err )
399
450
}
400
- podID , err := RunPodSandbox (runtimeClient , podSandboxConfig , runtime )
451
+ podID , err := RunPodSandbox (rClient , podSandboxConfig , runtime )
401
452
if err != nil {
402
453
return fmt .Errorf ("run pod sandbox failed: %v" , err )
403
454
}
404
455
405
456
// Create the container
406
457
containerOptions := createOptions {podID , & opts }
407
- ctrID , err := CreateContainer (runtimeClient , containerOptions )
458
+ ctrID , err := CreateContainer (iClient , rClient , containerOptions )
408
459
if err != nil {
409
460
return fmt .Errorf ("creating container failed: %v" , err )
410
461
}
411
462
412
463
// Start the container
413
- err = StartContainer (runtimeClient , ctrID )
464
+ err = StartContainer (rClient , ctrID )
414
465
if err != nil {
415
466
return fmt .Errorf ("starting the container %q failed: %v" , ctrID , err )
416
467
}
@@ -419,7 +470,12 @@ func RunContainer(
419
470
420
471
// CreateContainer sends a CreateContainerRequest to the server, and parses
421
472
// 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
+
423
479
config , err := loadContainerConfig (opts .configPath )
424
480
if err != nil {
425
481
return "" , err
@@ -432,13 +488,26 @@ func CreateContainer(client pb.RuntimeServiceClient, opts createOptions) (string
432
488
}
433
489
}
434
490
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
+
435
504
request := & pb.CreateContainerRequest {
436
505
PodSandboxId : opts .podID ,
437
506
Config : config ,
438
507
SandboxConfig : podConfig ,
439
508
}
440
509
logrus .Debugf ("CreateContainerRequest: %v" , request )
441
- r , err := client .CreateContainer (context .Background (), request )
510
+ r , err := rClient .CreateContainer (context .Background (), request )
442
511
logrus .Debugf ("CreateContainerResponse: %v" , r )
443
512
if err != nil {
444
513
return "" , err
0 commit comments