Skip to content

Commit 56ed692

Browse files
committed
Adding netns to jailer
This adds netns specification per create vm request. In the event that no netns was found in the runc config, we will then make sure of what was passed into the create vm request Signed-off-by: xibz <[email protected]>
1 parent 173b9d5 commit 56ed692

File tree

5 files changed

+44
-33
lines changed

5 files changed

+44
-33
lines changed

runtime/firecracker-runc-config.json.example

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@
9696
{
9797
"type": "pid"
9898
},
99-
{
100-
"type": "network"
101-
},
10299
{
103100
"type": "ipc"
104101
},

runtime/jailer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,5 @@ func newJailer(
7373
}
7474

7575
l := logger.WithField("jailer", "runc")
76-
return newRuncJailer(ctx, l, ociBundlePath, service.config.JailerConfig.RuncBinaryPath, jailerUID, jailerGID)
76+
return newRuncJailer(ctx, l, ociBundlePath, service.config.JailerConfig.RuncBinaryPath, request)
7777
}

runtime/runc_jailer.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333

3434
"github.com/firecracker-microvm/firecracker-containerd/internal"
3535
"github.com/firecracker-microvm/firecracker-containerd/internal/vm"
36+
"github.com/firecracker-microvm/firecracker-containerd/proto"
3637
)
3738

3839
// runcJailer uses runc to set up a jailed environment for the Firecracker VM.
@@ -46,19 +47,24 @@ type runcJailer struct {
4647
runcBinaryPath string
4748
uid uint32
4849
gid uint32
50+
netns string
4951
}
5052

51-
func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, runcBinPath string, uid, gid uint32) (*runcJailer, error) {
53+
func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, runcBinPath string, req *proto.CreateVMRequest) (*runcJailer, error) {
5254
l := logger.WithField("ociBundlePath", ociBundlePath).
5355
WithField("runcBinaryPath", runcBinPath)
56+
if req.JailerConfig == nil {
57+
return nil, fmt.Errorf("no jailer configuration specified")
58+
}
5459

5560
j := &runcJailer{
5661
ctx: ctx,
5762
logger: l,
5863
ociBundlePath: ociBundlePath,
5964
runcBinaryPath: runcBinPath,
60-
uid: uid,
61-
gid: gid,
65+
uid: jailerUID,
66+
gid: jailerGID,
67+
netns: req.JailerConfig.NetworkNamespace,
6268
}
6369

6470
rootPath := j.RootPath()
@@ -347,8 +353,6 @@ func (j runcJailer) jailerCommand(containerName string) *exec.Cmd {
347353
}
348354

349355
// overwriteConfig will set the proper default values if a field had not been set.
350-
//
351-
// TODO: Add netns
352356
func (j runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string) error {
353357
spec := specs.Spec{}
354358
configBytes, err := ioutil.ReadFile(configPath)
@@ -376,6 +380,13 @@ func (j runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string)
376380
spec.Process.User.UID = j.uid
377381
spec.Process.User.GID = j.gid
378382

383+
if len(j.netns) > 0 && !hasNetworkNamespace(spec.Linux.Namespaces) {
384+
spec.Linux.Namespaces = append(spec.Linux.Namespaces, specs.LinuxNamespace{
385+
Type: "network",
386+
Path: j.netns,
387+
})
388+
}
389+
379390
configBytes, err = json.Marshal(&spec)
380391
if err != nil {
381392
return err
@@ -442,3 +453,13 @@ func mkdirAllWithPermissions(path string, mode os.FileMode, uid, gid uint32) err
442453

443454
return nil
444455
}
456+
457+
func hasNetworkNamespace(namespaces []specs.LinuxNamespace) bool {
458+
for _, namespace := range namespaces {
459+
if namespace.Type == specs.LinuxNamespaceType("network") {
460+
return true
461+
}
462+
}
463+
464+
return false
465+
}

runtime/runc_jailer_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/stretchr/testify/require"
2929

3030
"github.com/firecracker-microvm/firecracker-containerd/internal"
31+
"github.com/firecracker-microvm/firecracker-containerd/proto"
3132
)
3233

3334
func TestBuildJailedRootHandler_Isolated(t *testing.T) {
@@ -53,7 +54,9 @@ func TestBuildJailedRootHandler_Isolated(t *testing.T) {
5354
defer firecrackerFd.Close()
5455

5556
l := logrus.NewEntry(logrus.New())
56-
jailer, err := newRuncJailer(context.Background(), l, dir, "bin-path", 123, 456)
57+
jailer, err := newRuncJailer(context.Background(), l, dir, "bin-path", &proto.CreateVMRequest{
58+
JailerConfig: &proto.JailerConfig{},
59+
})
5760
require.NoError(t, err, "failed to create runc jailer")
5861

5962
cfg := Config{

runtime/service_integ_test.go

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/containerd/containerd/pkg/ttrpcutil"
3838
"github.com/containerd/containerd/runtime"
3939
"github.com/containerd/typeurl"
40+
"github.com/containernetworking/plugins/pkg/ns"
4041
"github.com/opencontainers/runtime-spec/specs-go"
4142
"github.com/pkg/errors"
4243
"github.com/shirou/gopsutil/process"
@@ -225,6 +226,8 @@ func TestMultipleVMs_Isolated(t *testing.T) {
225226
cfg.JailerConfig.RuncBinaryPath = "/usr/local/bin/runc"
226227
})
227228

229+
netns, err := ns.GetCurrentNS()
230+
228231
cases := []struct {
229232
MaxContainers int32
230233
JailerConfig *proto.JailerConfig
@@ -240,11 +243,15 @@ func TestMultipleVMs_Isolated(t *testing.T) {
240243
},
241244
{
242245
MaxContainers: 3,
243-
JailerConfig: &proto.JailerConfig{},
246+
JailerConfig: &proto.JailerConfig{
247+
NetworkNamespace: netns.Path(),
248+
},
244249
},
245250
{
246251
MaxContainers: 3,
247-
JailerConfig: &proto.JailerConfig{},
252+
JailerConfig: &proto.JailerConfig{
253+
NetworkNamespace: netns.Path(),
254+
},
248255
},
249256
}
250257

@@ -273,6 +280,7 @@ func TestMultipleVMs_Isolated(t *testing.T) {
273280

274281
tapName := fmt.Sprintf("tap%d", vmID)
275282
err = createTapDevice(ctx, tapName)
283+
276284
require.NoError(t, err, "failed to create tap device for vm %d", vmID)
277285

278286
rootfsPath := defaultVMRootfsPath
@@ -299,10 +307,6 @@ func TestMultipleVMs_Isolated(t *testing.T) {
299307
JailerConfig: jailerConfig,
300308
}
301309

302-
if jailerConfig != nil {
303-
req.NetworkInterfaces = nil
304-
}
305-
306310
_, err = fcClient.CreateVM(ctx, req)
307311
require.NoError(t, err, "failed to create vm")
308312

@@ -319,13 +323,6 @@ func TestMultipleVMs_Isolated(t *testing.T) {
319323
fmt.Sprintf("/bin/sleep %d", testTimeout/time.Second),
320324
}, " && "))
321325

322-
if jailerConfig != nil {
323-
// TODO: this if statement block can go away once we add netns
324-
processArgs = oci.WithProcessArgs("/bin/sh", "-c", strings.Join([]string{
325-
fmt.Sprintf("/bin/sleep %d", testTimeout/time.Second),
326-
}, " && "))
327-
}
328-
329326
// spawn a container that just prints the VM's eth0 mac address (which we have set uniquely per VM)
330327
newContainer, err := client.NewContainer(ctx,
331328
containerName,
@@ -454,20 +451,13 @@ func TestMultipleVMs_Isolated(t *testing.T) {
454451

455452
stdoutLines := strings.Split(strings.TrimSpace(taskStdout.String()), "\n")
456453
lines := 2
457-
if jailerConfig != nil {
458-
lines = 1
459-
}
460454
require.Len(t, stdoutLines, lines)
461455

462456
printedVMID := strings.TrimSpace(stdoutLines[0])
463-
// TODO: Remove this if statement once we can add a netns which
464-
// will allow firecracker to have visibility of the tap devices.
465-
if jailerConfig == nil {
466-
require.Equal(t, vmIDtoMacAddr(uint(vmID)), printedVMID, "unexpected VMID output from container %q", containerName)
457+
require.Equal(t, vmIDtoMacAddr(uint(vmID)), printedVMID, "unexpected VMID output from container %q", containerName)
467458

468-
taskMntNS := strings.TrimSpace(stdoutLines[1])
469-
require.Equal(t, execMntNS, taskMntNS, "unexpected mnt NS output from container %q", containerName)
470-
}
459+
taskMntNS := strings.TrimSpace(stdoutLines[1])
460+
require.Equal(t, execMntNS, taskMntNS, "unexpected mnt NS output from container %q", containerName)
471461

472462
case <-ctx.Done():
473463
require.Fail(t, "context cancelled",

0 commit comments

Comments
 (0)