runc: add support for rootless containers

This enables the support for the rootless container mode. There are many
restrictions on what rootless containers can do, so many different runC
commands have been disabled:

* runc checkpoint
* runc events
* runc pause
* runc ps
* runc restore
* runc resume
* runc update

The following commands work:

* runc create
* runc delete
* runc exec
* runc kill
* runc list
* runc run
* runc spec
* runc state

In addition, any specification options that imply joining cgroups have
also been disabled. This is due to support for unprivileged subtree
management not being available from Linux upstream.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
Aleksa Sarai
2016-04-23 23:39:42 +10:00
parent 6bd4bd9030
commit d2f49696b0
21 changed files with 742 additions and 193 deletions
+78 -2
View File
@@ -3,8 +3,10 @@
package specconv
import (
"os"
"testing"
"github.com/opencontainers/runc/libcontainer/configs/validate"
"github.com/opencontainers/runtime-spec/specs-go"
)
@@ -16,7 +18,13 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) {
CgroupsPath: cgroupsPath,
}
cgroup, err := createCgroupConfig("ContainerID", false, spec)
opts := &CreateOpts{
CgroupName: "ContainerID",
UseSystemdCgroup: false,
Spec: spec,
}
cgroup, err := createCgroupConfig(opts)
if err != nil {
t.Errorf("Couldn't create Cgroup config: %v", err)
}
@@ -28,8 +36,13 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) {
func TestLinuxCgroupsPathNotSpecified(t *testing.T) {
spec := &specs.Spec{}
opts := &CreateOpts{
CgroupName: "ContainerID",
UseSystemdCgroup: false,
Spec: spec,
}
cgroup, err := createCgroupConfig("ContainerID", false, spec)
cgroup, err := createCgroupConfig(opts)
if err != nil {
t.Errorf("Couldn't create Cgroup config: %v", err)
}
@@ -39,6 +52,26 @@ func TestLinuxCgroupsPathNotSpecified(t *testing.T) {
}
}
func TestSpecconvExampleValidate(t *testing.T) {
spec := ExampleSpec()
spec.Root.Path = "/"
opts := &CreateOpts{
CgroupName: "ContainerID",
UseSystemdCgroup: false,
Spec: spec,
}
config, err := CreateLibcontainerConfig(opts)
if err != nil {
t.Errorf("Couldn't create libcontainer config: %v", err)
}
validator := validate.New()
if err := validator.Validate(config); err != nil {
t.Errorf("Expected specconv to produce valid container config: %v", err)
}
}
func TestDupNamespaces(t *testing.T) {
spec := &specs.Spec{
Linux: &specs.Linux{
@@ -62,3 +95,46 @@ func TestDupNamespaces(t *testing.T) {
t.Errorf("Duplicated namespaces should be forbidden")
}
}
func TestRootlessSpecconvValidate(t *testing.T) {
spec := &specs.Spec{
Linux: specs.Linux{
Namespaces: []specs.Namespace{
{
Type: specs.UserNamespace,
},
},
UIDMappings: []specs.IDMapping{
{
HostID: uint32(os.Geteuid()),
ContainerID: 0,
Size: 1,
},
},
GIDMappings: []specs.IDMapping{
{
HostID: uint32(os.Getegid()),
ContainerID: 0,
Size: 1,
},
},
},
}
opts := &CreateOpts{
CgroupName: "ContainerID",
UseSystemdCgroup: false,
Spec: spec,
Rootless: true,
}
config, err := CreateLibcontainerConfig(opts)
if err != nil {
t.Errorf("Couldn't create libcontainer config: %v", err)
}
validator := validate.New()
if err := validator.Validate(config); err != nil {
t.Errorf("Expected specconv to produce valid rootless container config: %v", err)
}
}