Update runc usage for new specs changes
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
9047912c35
commit
47eaa08f5a
2
exec.go
2
exec.go
|
@ -10,7 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var execCommand = cli.Command{
|
var execCommand = cli.Command{
|
||||||
|
|
4
main.go
4
main.go
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -59,7 +59,7 @@ func main() {
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "root",
|
Name: "root",
|
||||||
Value: specs.LinuxStateDirectory,
|
Value: "/run/runc",
|
||||||
Usage: "root directory for storage of container state (this should be located in tmpfs)",
|
Usage: "root directory for storage of container state (this should be located in tmpfs)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var restoreCommand = cli.Command{
|
var restoreCommand = cli.Command{
|
||||||
|
@ -100,7 +100,7 @@ using the runc checkpoint command.`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreContainer(context *cli.Context, spec *specs.LinuxSpec, config *configs.Config, imagePath string) (code int, err error) {
|
func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Config, imagePath string) (code int, err error) {
|
||||||
var (
|
var (
|
||||||
rootuid = 0
|
rootuid = 0
|
||||||
id = context.Args().First()
|
id = context.Args().First()
|
||||||
|
|
178
spec.go
178
spec.go
|
@ -18,7 +18,7 @@ import (
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
"github.com/opencontainers/runc/libcontainer/seccomp"
|
"github.com/opencontainers/runc/libcontainer/seccomp"
|
||||||
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
|
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var specCommand = cli.Command{
|
var specCommand = cli.Command{
|
||||||
|
@ -34,79 +34,84 @@ var specCommand = cli.Command{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) {
|
Action: func(context *cli.Context) {
|
||||||
spec := specs.LinuxSpec{
|
spec := specs.Spec{
|
||||||
Spec: specs.Spec{
|
Version: specs.Version,
|
||||||
Version: specs.Version,
|
Platform: specs.Platform{
|
||||||
Platform: specs.Platform{
|
OS: runtime.GOOS,
|
||||||
OS: runtime.GOOS,
|
Arch: runtime.GOARCH,
|
||||||
Arch: runtime.GOARCH,
|
},
|
||||||
|
Root: specs.Root{
|
||||||
|
Path: "rootfs",
|
||||||
|
Readonly: true,
|
||||||
|
},
|
||||||
|
Process: specs.Process{
|
||||||
|
Terminal: true,
|
||||||
|
User: specs.User{},
|
||||||
|
Args: []string{
|
||||||
|
"sh",
|
||||||
},
|
},
|
||||||
Root: specs.Root{
|
Env: []string{
|
||||||
Path: "rootfs",
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
Readonly: true,
|
"TERM=xterm",
|
||||||
},
|
},
|
||||||
Process: specs.Process{
|
Cwd: "/",
|
||||||
Terminal: true,
|
NoNewPrivileges: true,
|
||||||
User: specs.User{},
|
Capabilities: []string{
|
||||||
Args: []string{
|
"CAP_AUDIT_WRITE",
|
||||||
"sh",
|
"CAP_KILL",
|
||||||
},
|
"CAP_NET_BIND_SERVICE",
|
||||||
Env: []string{
|
},
|
||||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
Rlimits: []specs.Rlimit{
|
||||||
"TERM=xterm",
|
{
|
||||||
},
|
Type: "RLIMIT_NOFILE",
|
||||||
Cwd: "/",
|
Hard: uint64(1024),
|
||||||
NoNewPrivileges: true,
|
Soft: uint64(1024),
|
||||||
Capabilities: []string{
|
|
||||||
"CAP_AUDIT_WRITE",
|
|
||||||
"CAP_KILL",
|
|
||||||
"CAP_NET_BIND_SERVICE",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Hostname: "shell",
|
},
|
||||||
Mounts: []specs.Mount{
|
Hostname: "runc",
|
||||||
{
|
Mounts: []specs.Mount{
|
||||||
Destination: "/proc",
|
{
|
||||||
Type: "proc",
|
Destination: "/proc",
|
||||||
Source: "proc",
|
Type: "proc",
|
||||||
Options: nil,
|
Source: "proc",
|
||||||
},
|
Options: nil,
|
||||||
{
|
},
|
||||||
Destination: "/dev",
|
{
|
||||||
Type: "tmpfs",
|
Destination: "/dev",
|
||||||
Source: "tmpfs",
|
Type: "tmpfs",
|
||||||
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
|
Source: "tmpfs",
|
||||||
},
|
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
|
||||||
{
|
},
|
||||||
Destination: "/dev/pts",
|
{
|
||||||
Type: "devpts",
|
Destination: "/dev/pts",
|
||||||
Source: "devpts",
|
Type: "devpts",
|
||||||
Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
|
Source: "devpts",
|
||||||
},
|
Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
|
||||||
{
|
},
|
||||||
Destination: "/dev/shm",
|
{
|
||||||
Type: "tmpfs",
|
Destination: "/dev/shm",
|
||||||
Source: "shm",
|
Type: "tmpfs",
|
||||||
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
|
Source: "shm",
|
||||||
},
|
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
|
||||||
{
|
},
|
||||||
Destination: "/dev/mqueue",
|
{
|
||||||
Type: "mqueue",
|
Destination: "/dev/mqueue",
|
||||||
Source: "mqueue",
|
Type: "mqueue",
|
||||||
Options: []string{"nosuid", "noexec", "nodev"},
|
Source: "mqueue",
|
||||||
},
|
Options: []string{"nosuid", "noexec", "nodev"},
|
||||||
{
|
},
|
||||||
Destination: "/sys",
|
{
|
||||||
Type: "sysfs",
|
Destination: "/sys",
|
||||||
Source: "sysfs",
|
Type: "sysfs",
|
||||||
Options: []string{"nosuid", "noexec", "nodev", "ro"},
|
Source: "sysfs",
|
||||||
},
|
Options: []string{"nosuid", "noexec", "nodev", "ro"},
|
||||||
{
|
},
|
||||||
Destination: "/sys/fs/cgroup",
|
{
|
||||||
Type: "cgroup",
|
Destination: "/sys/fs/cgroup",
|
||||||
Source: "cgroup",
|
Type: "cgroup",
|
||||||
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
|
Source: "cgroup",
|
||||||
},
|
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Linux: specs.Linux{
|
Linux: specs.Linux{
|
||||||
|
@ -135,13 +140,6 @@ var specCommand = cli.Command{
|
||||||
Type: "mount",
|
Type: "mount",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Rlimits: []specs.Rlimit{
|
|
||||||
{
|
|
||||||
Type: "RLIMIT_NOFILE",
|
|
||||||
Hard: uint64(1024),
|
|
||||||
Soft: uint64(1024),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +199,7 @@ var mountPropagationMapping = map[string]int{
|
||||||
|
|
||||||
// validateSpec validates the fields in the spec
|
// validateSpec validates the fields in the spec
|
||||||
// TODO: Add validation for other fields where applicable
|
// TODO: Add validation for other fields where applicable
|
||||||
func validateSpec(spec *specs.LinuxSpec) error {
|
func validateSpec(spec *specs.Spec) error {
|
||||||
if spec.Process.Cwd == "" {
|
if spec.Process.Cwd == "" {
|
||||||
return fmt.Errorf("Cwd property must not be empty")
|
return fmt.Errorf("Cwd property must not be empty")
|
||||||
}
|
}
|
||||||
|
@ -213,7 +211,7 @@ func validateSpec(spec *specs.LinuxSpec) error {
|
||||||
|
|
||||||
// loadSpec loads the specification from the provided path.
|
// loadSpec loads the specification from the provided path.
|
||||||
// If the path is empty then the default path will be "config.json"
|
// If the path is empty then the default path will be "config.json"
|
||||||
func loadSpec(cPath string) (spec *specs.LinuxSpec, err error) {
|
func loadSpec(cPath string) (spec *specs.Spec, err error) {
|
||||||
cf, err := os.Open(cPath)
|
cf, err := os.Open(cPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
@ -229,7 +227,7 @@ func loadSpec(cPath string) (spec *specs.LinuxSpec, err error) {
|
||||||
return spec, validateSpec(spec)
|
return spec, validateSpec(spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*configs.Config, error) {
|
func createLibcontainerConfig(cgroupName string, spec *specs.Spec) (*configs.Config, error) {
|
||||||
// runc's cwd will always be the bundle path
|
// runc's cwd will always be the bundle path
|
||||||
rcwd, err := os.Getwd()
|
rcwd, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -280,7 +278,7 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*config
|
||||||
if err := setupUserNamespace(spec, config); err != nil {
|
if err := setupUserNamespace(spec, config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, rlimit := range spec.Linux.Rlimits {
|
for _, rlimit := range spec.Process.Rlimits {
|
||||||
rl, err := createLibContainerRlimit(rlimit)
|
rl, err := createLibContainerRlimit(rlimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -295,11 +293,13 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*config
|
||||||
// set extra path masking for libcontainer for the various unsafe places in proc
|
// set extra path masking for libcontainer for the various unsafe places in proc
|
||||||
config.MaskPaths = maskedPaths
|
config.MaskPaths = maskedPaths
|
||||||
config.ReadonlyPaths = readonlyPaths
|
config.ReadonlyPaths = readonlyPaths
|
||||||
seccomp, err := setupSeccomp(&spec.Linux.Seccomp)
|
if spec.Linux.Seccomp != nil {
|
||||||
if err != nil {
|
seccomp, err := setupSeccomp(spec.Linux.Seccomp)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.Seccomp = seccomp
|
||||||
}
|
}
|
||||||
config.Seccomp = seccomp
|
|
||||||
config.Sysctl = spec.Linux.Sysctl
|
config.Sysctl = spec.Linux.Sysctl
|
||||||
if oomScoreAdj := spec.Linux.Resources.OOMScoreAdj; oomScoreAdj != nil {
|
if oomScoreAdj := spec.Linux.Resources.OOMScoreAdj; oomScoreAdj != nil {
|
||||||
config.OomScoreAdj = *oomScoreAdj
|
config.OomScoreAdj = *oomScoreAdj
|
||||||
|
@ -330,7 +330,7 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createCgroupConfig(name string, spec *specs.LinuxSpec) (*configs.Cgroup, error) {
|
func createCgroupConfig(name string, spec *specs.Spec) (*configs.Cgroup, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
myCgroupPath string
|
myCgroupPath string
|
||||||
|
@ -506,7 +506,7 @@ func stringToDeviceRune(s string) (rune, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDevices(spec *specs.LinuxSpec, config *configs.Config) error {
|
func createDevices(spec *specs.Spec, config *configs.Config) error {
|
||||||
// add whitelisted devices
|
// add whitelisted devices
|
||||||
config.Devices = []*configs.Device{
|
config.Devices = []*configs.Device{
|
||||||
{
|
{
|
||||||
|
@ -591,7 +591,7 @@ func createDevices(spec *specs.LinuxSpec, config *configs.Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupUserNamespace(spec *specs.LinuxSpec, config *configs.Config) error {
|
func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
|
||||||
if len(spec.Linux.UIDMappings) == 0 {
|
if len(spec.Linux.UIDMappings) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -776,7 +776,7 @@ func setupSeccomp(config *specs.Seccomp) (*configs.Seccomp, error) {
|
||||||
return newConfig, nil
|
return newConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createHooks(rspec *specs.LinuxSpec, config *configs.Config) {
|
func createHooks(rspec *specs.Spec, config *configs.Config) {
|
||||||
config.Hooks = &configs.Hooks{}
|
config.Hooks = &configs.Hooks{}
|
||||||
for _, h := range rspec.Hooks.Prestart {
|
for _, h := range rspec.Hooks.Prestart {
|
||||||
cmd := configs.Command{
|
cmd := configs.Command{
|
||||||
|
|
|
@ -6,13 +6,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLinuxCgroupsPathSpecified(t *testing.T) {
|
func TestLinuxCgroupsPathSpecified(t *testing.T) {
|
||||||
cgroupsPath := "/user/cgroups/path/id"
|
cgroupsPath := "/user/cgroups/path/id"
|
||||||
|
|
||||||
spec := &specs.LinuxSpec{}
|
spec := &specs.Spec{}
|
||||||
spec.Linux.CgroupsPath = &cgroupsPath
|
spec.Linux.CgroupsPath = &cgroupsPath
|
||||||
|
|
||||||
cgroup, err := createCgroupConfig("ContainerID", spec)
|
cgroup, err := createCgroupConfig("ContainerID", spec)
|
||||||
|
@ -26,7 +26,7 @@ func TestLinuxCgroupsPathSpecified(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLinuxCgroupsPathNotSpecified(t *testing.T) {
|
func TestLinuxCgroupsPathNotSpecified(t *testing.T) {
|
||||||
spec := &specs.LinuxSpec{}
|
spec := &specs.Spec{}
|
||||||
|
|
||||||
cgroup, err := createCgroupConfig("ContainerID", spec)
|
cgroup, err := createCgroupConfig("ContainerID", spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
4
start.go
4
start.go
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/coreos/go-systemd/activation"
|
"github.com/coreos/go-systemd/activation"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// default action is to start a container
|
// default action is to start a container
|
||||||
|
@ -91,7 +91,7 @@ var initCommand = cli.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func startContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
|
func startContainer(context *cli.Context, spec *specs.Spec) (int, error) {
|
||||||
id := context.Args().First()
|
id := context.Args().First()
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return -1, errEmptyID
|
return -1, errEmptyID
|
||||||
|
|
2
state.go
2
state.go
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
// cState represents the platform agnostic pieces relating to a running
|
// cState represents the platform agnostic pieces relating to a running
|
||||||
// container's status and state. Note: The fields in this structure adhere to
|
// container's status and state. Note: The fields in this structure adhere to
|
||||||
// the opencontainers/specs requirement for json fields that must be returned
|
// the opencontainers/specs/specs-go requirement for json fields that must be returned
|
||||||
// in a state command.
|
// in a state command.
|
||||||
type cState struct {
|
type cState struct {
|
||||||
// Version is the OCI version for the container
|
// Version is the OCI version for the container
|
||||||
|
|
6
utils.go
6
utils.go
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
const wildcard = -1
|
const wildcard = -1
|
||||||
|
@ -264,7 +264,7 @@ func dupStdio(process *libcontainer.Process, rootuid int) error {
|
||||||
|
|
||||||
// If systemd is supporting sd_notify protocol, this function will add support
|
// If systemd is supporting sd_notify protocol, this function will add support
|
||||||
// for sd_notify protocol from within the container.
|
// for sd_notify protocol from within the container.
|
||||||
func setupSdNotify(spec *specs.LinuxSpec, notifySocket string) {
|
func setupSdNotify(spec *specs.Spec, notifySocket string) {
|
||||||
spec.Mounts = append(spec.Mounts, specs.Mount{Destination: notifySocket, Type: "bind", Source: notifySocket, Options: []string{"bind"}})
|
spec.Mounts = append(spec.Mounts, specs.Mount{Destination: notifySocket, Type: "bind", Source: notifySocket, Options: []string{"bind"}})
|
||||||
spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notifySocket))
|
spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notifySocket))
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ func createPidFile(path string, process *libcontainer.Process) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createContainer(context *cli.Context, id string, spec *specs.LinuxSpec) (libcontainer.Container, error) {
|
func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcontainer.Container, error) {
|
||||||
config, err := createLibcontainerConfig(id, spec)
|
config, err := createLibcontainerConfig(id, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue