@@ -36,6 +36,10 @@ import (
36
36
"github.com/firecracker-microvm/firecracker-containerd/internal/vm"
37
37
)
38
38
39
+ const (
40
+ networkNamespaceRuncName = "network"
41
+ )
42
+
39
43
// runcJailer uses runc to set up a jailed environment for the Firecracker VM.
40
44
type runcJailer struct {
41
45
ctx context.Context
@@ -99,7 +103,7 @@ func (j *runcJailer) JailPath() vm.Dir {
99
103
// instance. In addition, some configuration values will be overwritten to the
100
104
// jailed values, like SocketPath in the machineConfig.
101
105
func (j * runcJailer ) BuildJailedMachine (cfg * Config , machineConfig * firecracker.Config , vmID string ) ([]firecracker.Opt , error ) {
102
- handler := j .BuildJailedRootHandler (cfg , & machineConfig . SocketPath , vmID )
106
+ handler := j .BuildJailedRootHandler (cfg , machineConfig , vmID )
103
107
fifoHandler := j .BuildLinkFifoHandler ()
104
108
// Build a new client since BuildJailedRootHandler modifies the socket path value.
105
109
client := firecracker .NewClient (machineConfig .SocketPath , j .logger , machineConfig .Debug )
@@ -130,10 +134,10 @@ func (j *runcJailer) BuildJailedMachine(cfg *Config, machineConfig *firecracker.
130
134
131
135
// BuildJailedRootHandler will populate the jail with the necessary files, which may be
132
136
// device nodes, hard links, and/or bind-mount targets
133
- func (j * runcJailer ) BuildJailedRootHandler (cfg * Config , socketPath * string , vmID string ) firecracker.Handler {
137
+ func (j * runcJailer ) BuildJailedRootHandler (cfg * Config , machineConfig * firecracker. Config , vmID string ) firecracker.Handler {
134
138
ociBundlePath := j .OCIBundlePath ()
135
139
rootPath := j .RootPath ()
136
- * socketPath = filepath .Join (rootPath , "api.socket" )
140
+ machineConfig . SocketPath = filepath .Join (rootPath , "api.socket" )
137
141
138
142
return firecracker.Handler {
139
143
Name : jailerHandlerName ,
@@ -146,7 +150,7 @@ func (j *runcJailer) BuildJailedRootHandler(cfg *Config, socketPath *string, vmI
146
150
}
147
151
148
152
j .logger .Debug ("Overwritting process args of config" )
149
- if err := j .overwriteConfig (cfg , filepath .Base (m .Cfg .SocketPath ), rootPathToConfig ); err != nil {
153
+ if err := j .overwriteConfig (cfg , machineConfig , filepath .Base (m .Cfg .SocketPath ), rootPathToConfig ); err != nil {
150
154
return errors .Wrap (err , "failed to overwrite config.json" )
151
155
}
152
156
@@ -302,7 +306,7 @@ func (j *runcJailer) ExposeFileToJail(srcPath string) error {
302
306
}
303
307
304
308
// copyFileToJail will copy a file from src to dst, and chown the new file to the jail user.
305
- func (j runcJailer ) copyFileToJail (src , dst string , mode os.FileMode ) error {
309
+ func (j * runcJailer ) copyFileToJail (src , dst string , mode os.FileMode ) error {
306
310
if err := copyFile (src , dst , mode ); err != nil {
307
311
return err
308
312
}
@@ -363,37 +367,41 @@ func (j *runcJailer) jailerCommand(containerName string, isDebug bool) *exec.Cmd
363
367
}
364
368
365
369
// overwriteConfig will set the proper default values if a field had not been set.
366
- func (j * runcJailer ) overwriteConfig (cfg * Config , socketPath , configPath string ) error {
370
+ func (j * runcJailer ) overwriteConfig (cfg * Config , machineConfig * firecracker. Config , socketPath , configPath string ) error {
367
371
var err error
368
372
j .once .Do (func () {
369
- if configSpec == nil {
370
- spec := specs.Spec {}
371
- var configBytes []byte
372
- configBytes , err = ioutil .ReadFile (configPath )
373
- if err != nil {
374
- return
375
- }
373
+ // here we attempt to cache the runc config. If the config has already been
374
+ // cached, we will return immediately
375
+ if configSpec != nil {
376
+ return
377
+ }
376
378
377
- if err = json .Unmarshal (configBytes , & spec ); err != nil {
378
- return
379
- }
379
+ spec := specs.Spec {}
380
+ var configBytes []byte
381
+ configBytes , err = ioutil .ReadFile (configPath )
382
+ if err != nil {
383
+ return
384
+ }
380
385
381
- configSpec = & spec
386
+ if err = json .Unmarshal (configBytes , & spec ); err != nil {
387
+ return
388
+ }
382
389
383
- if spec .Process .User .UID != 0 ||
384
- spec .Process .User .GID != 0 {
385
- err = fmt .Errorf (
386
- "using UID %d and GID %d, these values must not be set" ,
387
- spec .Process .User .UID ,
388
- spec .Process .User .GID ,
389
- )
390
- return
391
- }
390
+ configSpec = & spec
392
391
393
- spec = j .setDefaultConfigValues (cfg , socketPath , spec )
394
- spec .Root .Path = rootfsFolder
395
- spec .Root .Readonly = false
392
+ if spec .Process .User .UID != 0 ||
393
+ spec .Process .User .GID != 0 {
394
+ err = fmt .Errorf (
395
+ "using UID %d and GID %d, these values must not be set" ,
396
+ spec .Process .User .UID ,
397
+ spec .Process .User .GID ,
398
+ )
399
+ return
396
400
}
401
+
402
+ spec = j .setDefaultConfigValues (cfg , socketPath , spec )
403
+ spec .Root .Path = rootfsFolder
404
+ spec .Root .Readonly = false
397
405
})
398
406
399
407
if err != nil {
@@ -404,6 +412,16 @@ func (j *runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string)
404
412
spec .Process .User .UID = j .uid
405
413
spec .Process .User .GID = j .gid
406
414
415
+ if machineConfig .NetNS != "" {
416
+ for i , ns := range spec .Linux .Namespaces {
417
+ if ns .Type == networkNamespaceRuncName {
418
+ ns .Path = machineConfig .NetNS
419
+ spec .Linux .Namespaces [i ] = ns
420
+ break
421
+ }
422
+ }
423
+ }
424
+
407
425
configBytes , err := json .Marshal (& spec )
408
426
if err != nil {
409
427
return err
@@ -477,7 +495,7 @@ func getNetNS(spec *specs.Spec) string {
477
495
}
478
496
479
497
for _ , ns := range spec .Linux .Namespaces {
480
- if ns .Type == "network" {
498
+ if ns .Type == networkNamespaceRuncName {
481
499
return ns .Path
482
500
}
483
501
}
0 commit comments