Skip to content

Commit 554d64c

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 ea15dbf commit 554d64c

File tree

7 files changed

+130
-88
lines changed

7 files changed

+130
-88
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,8 +47,11 @@ type runcJailer struct {
4647
runcBinaryPath string
4748
uid uint32
4849
gid uint32
50+
once sync.Once
4951
}
5052

53+
var configSpec *specs.Spec
54+
5155
func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, runcBinPath string, uid, gid uint32) (*runcJailer, error) {
5256
l := logger.WithField("ociBundlePath", ociBundlePath).
5357
WithField("runcBinaryPath", runcBinPath)
@@ -75,17 +79,17 @@ func newRuncJailer(ctx context.Context, logger *logrus.Entry, ociBundlePath, run
7579

7680
// JailPath returns the base directory from where the jail binary will be ran
7781
// from
78-
func (j runcJailer) OCIBundlePath() string {
82+
func (j *runcJailer) OCIBundlePath() string {
7983
return j.ociBundlePath
8084
}
8185

8286
// RootPath returns the root fs of the jailed system.
83-
func (j runcJailer) RootPath() string {
87+
func (j *runcJailer) RootPath() string {
8488
return filepath.Join(j.OCIBundlePath(), rootfsFolder)
8589
}
8690

8791
// JailPath will return the OCI bundle rootfs path
88-
func (j runcJailer) JailPath() vm.Dir {
92+
func (j *runcJailer) JailPath() vm.Dir {
8993
return vm.Dir(j.RootPath())
9094
}
9195

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

105+
if machineConfig.NetNS == "" {
106+
if netns := getNetNS(configSpec); netns != "" {
107+
machineConfig.NetNS = netns
108+
}
109+
}
110+
101111
opts := []firecracker.Opt{
102112
firecracker.WithProcessRunner(j.jailerCommand(vmID, cfg.Debug)),
103113
firecracker.WithClient(client),
@@ -213,7 +223,7 @@ func (j *runcJailer) BuildJailedRootHandler(cfg *Config, socketPath *string, vmI
213223

214224
// BuildLinkFifoHandler will return a new firecracker.Handler with the function
215225
// that will allow linking of the fifos making them visible to Firecracker.
216-
func (j runcJailer) BuildLinkFifoHandler() firecracker.Handler {
226+
func (j *runcJailer) BuildLinkFifoHandler() firecracker.Handler {
217227
return firecracker.Handler{
218228
Name: jailerFifoHandlerName,
219229
Fn: func(ctx context.Context, m *firecracker.Machine) error {
@@ -239,7 +249,7 @@ func (j runcJailer) BuildLinkFifoHandler() firecracker.Handler {
239249

240250
// StubDrivesOptions will return a set of options used to create a new stub
241251
// drive handler.
242-
func (j runcJailer) StubDrivesOptions() []stubDrivesOpt {
252+
func (j *runcJailer) StubDrivesOptions() []stubDrivesOpt {
243253
return []stubDrivesOpt{
244254
func(drives []models.Drive) error {
245255
for _, drive := range drives {
@@ -258,7 +268,7 @@ func (j runcJailer) StubDrivesOptions() []stubDrivesOpt {
258268
// the jail. For block devices we will use mknod to create the device and then
259269
// set the correct permissions to ensure visibility in the jail. Regular files
260270
// will be copied into the jail.
261-
func (j runcJailer) ExposeFileToJail(srcPath string) error {
271+
func (j *runcJailer) ExposeFileToJail(srcPath string) error {
262272
uid := j.uid
263273
gid := j.gid
264274

@@ -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)