Skip to content

Commit ca88e0f

Browse files
authored
Merge pull request #418 from xibz/cgroup
Adding Cgroup customization via CreateVM
2 parents 4d1bab3 + 821ee1d commit ca88e0f

File tree

6 files changed

+123
-44
lines changed

6 files changed

+123
-44
lines changed

proto/firecracker.pb.go

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

proto/firecracker.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,11 @@ message JailerConfig {
102102
string Mems = 3;
103103
uint32 UID = 4;
104104
uint32 GID = 5;
105+
// CgroupPath is used to dictate where the cgroup should be located
106+
// relative to the cgroup directory which is
107+
// /sys/fs/cgroup/cpu/<CgroupPath>/<vmID>
108+
// if no value was provided, then /firecracker-containerd will be used as
109+
// the default value
110+
string CgroupPath = 6;
105111
}
106112

runtime/jailer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func newJailer(
102102
GID: request.JailerConfig.GID,
103103
CPUs: request.JailerConfig.CPUs,
104104
Mems: request.JailerConfig.Mems,
105+
CgroupPath: request.JailerConfig.CgroupPath,
105106
}
106107
return newRuncJailer(ctx, l, service.vmID, config)
107108
}

runtime/jailer_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"context"
1818
"io/ioutil"
1919
"os"
20+
"os/exec"
2021
"path/filepath"
2122
"syscall"
2223
"testing"
@@ -25,6 +26,8 @@ import (
2526
"github.com/stretchr/testify/assert"
2627
"github.com/stretchr/testify/require"
2728

29+
"github.com/firecracker-microvm/firecracker-containerd/config"
30+
"github.com/firecracker-microvm/firecracker-containerd/internal/vm"
2831
"github.com/firecracker-microvm/firecracker-containerd/proto"
2932
)
3033

@@ -57,6 +60,7 @@ func createSparseFile(path string, size int) error {
5760

5861
return nil
5962
}
63+
6064
func TestCopyFile_sparse(t *testing.T) {
6165
dir, err := ioutil.TempDir("", t.Name())
6266
require.NoError(t, err)
@@ -96,3 +100,43 @@ func TestJailer_invalidUIDGID(t *testing.T) {
96100
_, err := newJailer(context.Background(), logrus.NewEntry(logrus.New()), "/foo", &service{}, &req)
97101
assert.Error(t, err, "expected invalid uid and gid error, but received none")
98102
}
103+
104+
func TestNewJailer_Isolated(t *testing.T) {
105+
prepareIntegTest(t)
106+
107+
ociBundlePath, err := ioutil.TempDir("", t.Name())
108+
require.NoError(t, err)
109+
defer os.RemoveAll(ociBundlePath)
110+
b, err := exec.Command(
111+
"cp",
112+
"firecracker-runc-config.json.example",
113+
filepath.Join(ociBundlePath, "config.json"),
114+
).CombinedOutput()
115+
require.NoErrorf(t, err, "copy runc config failed with: %s", string(b))
116+
117+
ctx := context.Background()
118+
logger := logrus.NewEntry(logrus.New())
119+
s := &service{
120+
vmID: "id",
121+
shimDir: vm.Dir("/path/to/shim"),
122+
config: &config.Config{
123+
JailerConfig: config.JailerConfig{
124+
RuncBinaryPath: "/path/to/runc_bin_path",
125+
RuncConfigPath: filepath.Join(ociBundlePath, "config.json"),
126+
},
127+
},
128+
}
129+
req := &proto.CreateVMRequest{
130+
JailerConfig: &proto.JailerConfig{
131+
UID: 123,
132+
GID: 456,
133+
CgroupPath: "/my/cgroup_path",
134+
},
135+
}
136+
137+
j, err := newJailer(ctx, logger, ociBundlePath, s, req)
138+
require.NoError(t, err)
139+
runc, ok := j.(*runcJailer)
140+
require.True(t, ok)
141+
assert.Equal(t, filepath.Join(req.JailerConfig.CgroupPath, s.vmID), runc.CgroupPath())
142+
}

runtime/runc_jailer.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ type runcJailerConfig struct {
6060
GID uint32
6161
CPUs string
6262
Mems string
63+
CgroupPath string
6364
}
6465

6566
func newRuncJailer(ctx context.Context, logger *logrus.Entry, vmID string, cfg runcJailerConfig) (*runcJailer, error) {
@@ -429,7 +430,12 @@ func (j *runcJailer) overwriteConfig(cfg *config.Config, machineConfig *firecrac
429430
}
430431

431432
func (j runcJailer) CgroupPath() string {
432-
return filepath.Join("/firecracker-containerd", j.vmID)
433+
basePath := "/firecracker-containerd"
434+
if j.Config.CgroupPath != "" {
435+
basePath = j.Config.CgroupPath
436+
}
437+
438+
return filepath.Join(basePath, j.vmID)
433439
}
434440

435441
// setDefaultConfigValues will process the spec file provided and allow any

runtime/service_integ_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ func TestMultipleVMs_Isolated(t *testing.T) {
273273
NetNS: netns.Path(),
274274
},
275275
},
276+
{
277+
MaxContainers: 3,
278+
JailerConfig: &proto.JailerConfig{
279+
UID: 300000,
280+
GID: 300000,
281+
NetNS: netns.Path(),
282+
CgroupPath: "/mycgroup",
283+
},
284+
},
276285
}
277286

278287
testTimeout := 600 * time.Second
@@ -471,7 +480,7 @@ func testMultipleExecs(
471480
require.NoError(t, err, "failed to stat root path of jailer")
472481
_, err = os.Stat(filepath.Join("/sys/fs/cgroup/cpu", cgroupPath))
473482
require.NoError(t, err, "failed to stat cgroup path of jailer")
474-
assert.Equal(t, filepath.Join("/firecracker-containerd", vmIDStr), cgroupPath)
483+
assert.Regexp(t, fmt.Sprintf(".+/%s", vmIDStr), cgroupPath)
475484
}
476485

477486
// Verify each exec had the same stdout and use that value as the mount namespace that will be compared

0 commit comments

Comments
 (0)