Skip to content

Commit b825062

Browse files
committed
fixup! Add support for netns
Signed-off-by: xibz <[email protected]>
1 parent e66c08f commit b825062

File tree

5 files changed

+56
-150
lines changed

5 files changed

+56
-150
lines changed

runtime/cni_integ_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ import (
3939
)
4040

4141
func TestCNISupport_Isolated(t *testing.T) {
42-
prepareIntegTest(t)
43-
42+
prepareIntegTest(t, withJailer())
4443
testTimeout := 120 * time.Second
4544
ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), defaultNamespace), testTimeout)
4645
defer cancel()

runtime/runc_jailer.go

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ import (
3636
"github.com/firecracker-microvm/firecracker-containerd/internal/vm"
3737
)
3838

39+
const (
40+
networkNamespaceRuncName = "network"
41+
)
42+
3943
// runcJailer uses runc to set up a jailed environment for the Firecracker VM.
4044
type runcJailer struct {
4145
ctx context.Context
@@ -99,7 +103,7 @@ func (j *runcJailer) JailPath() vm.Dir {
99103
// instance. In addition, some configuration values will be overwritten to the
100104
// jailed values, like SocketPath in the machineConfig.
101105
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)
103107
fifoHandler := j.BuildLinkFifoHandler()
104108
// Build a new client since BuildJailedRootHandler modifies the socket path value.
105109
client := firecracker.NewClient(machineConfig.SocketPath, j.logger, machineConfig.Debug)
@@ -130,10 +134,10 @@ func (j *runcJailer) BuildJailedMachine(cfg *Config, machineConfig *firecracker.
130134

131135
// BuildJailedRootHandler will populate the jail with the necessary files, which may be
132136
// 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 {
134138
ociBundlePath := j.OCIBundlePath()
135139
rootPath := j.RootPath()
136-
*socketPath = filepath.Join(rootPath, "api.socket")
140+
machineConfig.SocketPath = filepath.Join(rootPath, "api.socket")
137141

138142
return firecracker.Handler{
139143
Name: jailerHandlerName,
@@ -146,7 +150,7 @@ func (j *runcJailer) BuildJailedRootHandler(cfg *Config, socketPath *string, vmI
146150
}
147151

148152
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 {
150154
return errors.Wrap(err, "failed to overwrite config.json")
151155
}
152156

@@ -302,7 +306,7 @@ func (j *runcJailer) ExposeFileToJail(srcPath string) error {
302306
}
303307

304308
// 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 {
306310
if err := copyFile(src, dst, mode); err != nil {
307311
return err
308312
}
@@ -363,7 +367,7 @@ func (j *runcJailer) jailerCommand(containerName string, isDebug bool) *exec.Cmd
363367
}
364368

365369
// 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 {
367371
var err error
368372
j.once.Do(func() {
369373
if configSpec == nil {
@@ -404,6 +408,26 @@ func (j *runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string)
404408
spec.Process.User.UID = j.uid
405409
spec.Process.User.GID = j.gid
406410

411+
// remove the network namespace if there exists a CNI
412+
if hasCNI(machineConfig.NetworkInterfaces) {
413+
namespaces := []specs.LinuxNamespace{}
414+
for _, ns := range spec.Linux.Namespaces {
415+
if ns.Type != networkNamespaceRuncName {
416+
namespaces = append(namespaces, ns)
417+
}
418+
}
419+
420+
spec.Linux.Namespaces = namespaces
421+
} else if machineConfig.NetNS != "" {
422+
for i, ns := range spec.Linux.Namespaces {
423+
if ns.Type == networkNamespaceRuncName {
424+
ns.Path = machineConfig.NetNS
425+
spec.Linux.Namespaces[i] = ns
426+
break
427+
}
428+
}
429+
}
430+
407431
configBytes, err := json.Marshal(&spec)
408432
if err != nil {
409433
return err
@@ -477,10 +501,20 @@ func getNetNS(spec *specs.Spec) string {
477501
}
478502

479503
for _, ns := range spec.Linux.Namespaces {
480-
if ns.Type == "network" {
504+
if ns.Type == networkNamespaceRuncName {
481505
return ns.Path
482506
}
483507
}
484508

485509
return ""
486510
}
511+
512+
func hasCNI(interfaces firecracker.NetworkInterfaces) bool {
513+
for _, iface := range interfaces {
514+
if iface.CNIConfiguration != nil {
515+
return true
516+
}
517+
}
518+
519+
return false
520+
}

runtime/runc_jailer_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,22 @@ func TestBuildJailedRootHandler_Isolated(t *testing.T) {
6161
KernelImagePath: kernelImagePath,
6262
RootDrive: rootDrivePath,
6363
}
64-
socketPath := "/path/to/api.socket"
64+
machineConfig := firecracker.Config{
65+
SocketPath: "/path/to/api.socket",
66+
KernelImagePath: kernelImagePath,
67+
Drives: []models.Drive{
68+
{
69+
PathOnHost: firecracker.String(rootDrivePath),
70+
IsRootDevice: firecracker.Bool(true),
71+
IsReadOnly: firecracker.Bool(true),
72+
},
73+
},
74+
}
6575
vmID := "foo"
66-
handler := jailer.BuildJailedRootHandler(&cfg, &socketPath, vmID)
76+
handler := jailer.BuildJailedRootHandler(&cfg, &machineConfig, vmID)
6777

6878
machine := firecracker.Machine{
69-
Cfg: firecracker.Config{
70-
SocketPath: socketPath,
71-
KernelImagePath: kernelImagePath,
72-
Drives: []models.Drive{
73-
{
74-
PathOnHost: firecracker.String(rootDrivePath),
75-
IsRootDevice: firecracker.Bool(true),
76-
IsReadOnly: firecracker.Bool(true),
77-
},
78-
},
79-
},
79+
Cfg: machineConfig,
8080
}
8181
err = handler.Fn(context.Background(), &machine)
8282
assert.NoError(t, err, "jailed handler failed to run")

tools/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ COPY _submodules/firecracker/target/$FIRECRACKER_TARGET/release/firecracker /usr
152152
COPY _submodules/firecracker/target/$FIRECRACKER_TARGET/release/jailer /usr/local/bin/
153153
COPY _submodules/runc/runc /usr/local/bin
154154
COPY tools/image-builder/rootfs.img /var/lib/firecracker-containerd/runtime/default-rootfs.img
155-
COPY tools/docker//firecracker-runc-config.json /etc/containerd/firecracker-runc-config.json
155+
COPY runtime/firecracker-runc-config.json.example /etc/containerd/firecracker-runc-config.json
156156

157157
# pull the images the tests need into the content store so we don't need internet
158158
# access during the tests themselves

tools/docker/firecracker-runc-config.json

Lines changed: 0 additions & 127 deletions
This file was deleted.

0 commit comments

Comments
 (0)