Skip to content

Commit e66c08f

Browse files
committed
Add support for netns
This change allows for users to pass in a custom network namespace in the create vm request. This will then pass that netns to the SDK which will run the VM in that netns. Signed-off-by: xibz <[email protected]>
1 parent 5f3e0c7 commit e66c08f

File tree

9 files changed

+258
-89
lines changed

9 files changed

+258
-89
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ require (
1818
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad // indirect
1919
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect
2020
github.com/docker/go-units v0.3.3
21-
github.com/firecracker-microvm/firecracker-go-sdk v0.17.1-0.20191029213755-dbf9a1e05f09
21+
github.com/firecracker-microvm/firecracker-go-sdk v0.19.1-0.20191108195453-43d336c3dcbf
2222
github.com/go-ole/go-ole v1.2.4 // indirect
2323
github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384 // indirect
2424
github.com/gofrs/uuid v3.2.0+incompatible

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk
6161
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
6262
github.com/firecracker-microvm/firecracker-go-sdk v0.17.1-0.20191029213755-dbf9a1e05f09 h1:JDfRpK+V2J1Es+Xm6aMJjCqvA4xv1kuWnJfeSopyDwo=
6363
github.com/firecracker-microvm/firecracker-go-sdk v0.17.1-0.20191029213755-dbf9a1e05f09/go.mod h1:tVXziw7GjioCKVjI5/agymYxUaqJM6q7cp9e6kwjo8Q=
64+
github.com/firecracker-microvm/firecracker-go-sdk v0.19.1-0.20191108195453-43d336c3dcbf h1:HlqW7e7IwSIHBHJg4gBN6Kz9afSnEmB3+9e4/iTbBTw=
65+
github.com/firecracker-microvm/firecracker-go-sdk v0.19.1-0.20191108195453-43d336c3dcbf/go.mod h1:kW0gxvPpPvMukUxxTO9DrpSlScrtrTDGY3VgjAj/Qwc=
6466
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb h1:D4uzjWwKYQ5XnAvUbuvHW93esHg7F8N/OYeBBcJoTr0=
6567
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
6668
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=

proto/firecracker.pb.go

Lines changed: 42 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/firecracker.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,6 @@ message GetVMMetadataResponse {
7272
}
7373

7474
message JailerConfig {
75+
string NetNS = 1;
7576
}
7677

runtime/runc_jailer.go

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"os/exec"
2424
"path/filepath"
2525
"strings"
26+
"sync"
2627
"syscall"
2728

2829
"github.com/firecracker-microvm/firecracker-go-sdk"
@@ -46,10 +47,13 @@ type runcJailer struct {
4647
runcBinaryPath string
4748
uid uint32
4849
gid uint32
50+
once sync.Once
4951
}
5052

5153
const firecrackerFileName = "firecracker"
5254

55+
var configSpec *specs.Spec
56+
5357
func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, runcBinPath string, uid, gid uint32) (*runcJailer, error) {
5458
l := logger.WithField("ociBundlePath", ociBundlePath).
5559
WithField("runcBinaryPath", runcBinPath)
@@ -77,17 +81,17 @@ func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, run
7781

7882
// JailPath returns the base directory from where the jail binary will be ran
7983
// from
80-
func (j runcJailer) OCIBundlePath() string {
84+
func (j *runcJailer) OCIBundlePath() string {
8185
return j.ociBundlePath
8286
}
8387

8488
// RootPath returns the root fs of the jailed system.
85-
func (j runcJailer) RootPath() string {
89+
func (j *runcJailer) RootPath() string {
8690
return filepath.Join(j.OCIBundlePath(), rootfsFolder)
8791
}
8892

8993
// JailPath will return the OCI bundle rootfs path
90-
func (j runcJailer) JailPath() vm.Dir {
94+
func (j *runcJailer) JailPath() vm.Dir {
9195
return vm.Dir(j.RootPath())
9296
}
9397

@@ -100,6 +104,12 @@ func (j *runcJailer) BuildJailedMachine(cfg *Config, machineConfig *firecracker.
100104
// Build a new client since BuildJailedRootHandler modifies the socket path value.
101105
client := firecracker.NewClient(machineConfig.SocketPath, j.logger, machineConfig.Debug)
102106

107+
if machineConfig.NetNS == "" {
108+
if netns := getNetNS(configSpec); netns != "" {
109+
machineConfig.NetNS = netns
110+
}
111+
}
112+
103113
opts := []firecracker.Opt{
104114
firecracker.WithProcessRunner(j.jailerCommand(vmID, cfg.Debug)),
105115
firecracker.WithClient(client),
@@ -206,7 +216,7 @@ func (j *runcJailer) BuildJailedRootHandler(cfg *Config, socketPath *string, vmI
206216

207217
// BuildLinkFifoHandler will return a new firecracker.Handler with the function
208218
// that will allow linking of the fifos making them visible to Firecracker.
209-
func (j runcJailer) BuildLinkFifoHandler() firecracker.Handler {
219+
func (j *runcJailer) BuildLinkFifoHandler() firecracker.Handler {
210220
return firecracker.Handler{
211221
Name: jailerFifoHandlerName,
212222
Fn: func(ctx context.Context, m *firecracker.Machine) error {
@@ -232,7 +242,7 @@ func (j runcJailer) BuildLinkFifoHandler() firecracker.Handler {
232242

233243
// StubDrivesOptions will return a set of options used to create a new stub
234244
// drive handler.
235-
func (j runcJailer) StubDrivesOptions() []stubDrivesOpt {
245+
func (j *runcJailer) StubDrivesOptions() []stubDrivesOpt {
236246
return []stubDrivesOpt{
237247
func(drives []models.Drive) error {
238248
for _, drive := range drives {
@@ -251,7 +261,7 @@ func (j runcJailer) StubDrivesOptions() []stubDrivesOpt {
251261
// the jail. For block devices we will use mknod to create the device and then
252262
// set the correct permissions to ensure visibility in the jail. Regular files
253263
// will be copied into the jail.
254-
func (j runcJailer) ExposeFileToJail(srcPath string) error {
264+
func (j *runcJailer) ExposeFileToJail(srcPath string) error {
255265
uid := j.uid
256266
gid := j.gid
257267

@@ -340,7 +350,7 @@ func copyFile(src, dst string, mode os.FileMode) error {
340350
return nil
341351
}
342352

343-
func (j runcJailer) jailerCommand(containerName string, isDebug bool) *exec.Cmd {
353+
func (j *runcJailer) jailerCommand(containerName string, isDebug bool) *exec.Cmd {
344354
cmd := exec.CommandContext(j.ctx, j.runcBinaryPath, "run", containerName)
345355
cmd.Dir = j.OCIBundlePath()
346356

@@ -353,36 +363,48 @@ func (j runcJailer) jailerCommand(containerName string, isDebug bool) *exec.Cmd
353363
}
354364

355365
// overwriteConfig will set the proper default values if a field had not been set.
356-
//
357-
// TODO: Add netns
358-
func (j runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string) error {
359-
spec := specs.Spec{}
360-
configBytes, err := ioutil.ReadFile(configPath)
361-
if err != nil {
362-
return err
363-
}
366+
func (j *runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string) error {
367+
var err error
368+
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+
}
364376

365-
if err := json.Unmarshal(configBytes, &spec); err != nil {
366-
return err
367-
}
377+
if err = json.Unmarshal(configBytes, &spec); err != nil {
378+
return
379+
}
368380

369-
if spec.Process.User.UID != 0 ||
370-
spec.Process.User.GID != 0 {
371-
return fmt.Errorf(
372-
"using UID %d and GID %d, these values must not be set",
373-
spec.Process.User.UID,
374-
spec.Process.User.GID,
375-
)
376-
}
381+
configSpec = &spec
377382

378-
spec = j.setDefaultConfigValues(cfg, socketPath, spec)
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+
}
379392

380-
spec.Root.Path = rootfsFolder
381-
spec.Root.Readonly = false
393+
spec = j.setDefaultConfigValues(cfg, socketPath, spec)
394+
spec.Root.Path = rootfsFolder
395+
spec.Root.Readonly = false
396+
}
397+
})
398+
399+
if err != nil {
400+
return err
401+
}
402+
403+
spec := *configSpec
382404
spec.Process.User.UID = j.uid
383405
spec.Process.User.GID = j.gid
384406

385-
configBytes, err = json.Marshal(&spec)
407+
configBytes, err := json.Marshal(&spec)
386408
if err != nil {
387409
return err
388410
}
@@ -396,7 +418,7 @@ func (j runcJailer) overwriteConfig(cfg *Config, socketPath, configPath string)
396418

397419
// setDefaultConfigValues will process the spec file provided and allow any
398420
// empty/zero values to be replaced with default values.
399-
func (j runcJailer) setDefaultConfigValues(cfg *Config, socketPath string, spec specs.Spec) specs.Spec {
421+
func (j *runcJailer) setDefaultConfigValues(cfg *Config, socketPath string, spec specs.Spec) specs.Spec {
400422
if spec.Process == nil {
401423
spec.Process = &specs.Process{}
402424
}
@@ -448,3 +470,17 @@ func mkdirAllWithPermissions(path string, mode os.FileMode, uid, gid uint32) err
448470

449471
return nil
450472
}
473+
474+
func getNetNS(spec *specs.Spec) string {
475+
if spec == nil {
476+
return ""
477+
}
478+
479+
for _, ns := range spec.Linux.Namespaces {
480+
if ns.Type == "network" {
481+
return ns.Path
482+
}
483+
}
484+
485+
return ""
486+
}

runtime/service.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,10 @@ func (s *service) buildVMConfiguration(req *proto.CreateVMRequest) (*firecracker
712712
VMID: s.vmID,
713713
}
714714

715+
if req.JailerConfig != nil {
716+
cfg.NetNS = req.JailerConfig.NetNS
717+
}
718+
715719
s.logger.Debugf("using socket path: %s", cfg.SocketPath)
716720

717721
// Kernel configuration

0 commit comments

Comments
 (0)