Fix SystemError and env lookup
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
b9bc020f0d
commit
6eba9b8ffb
22
create.go
22
create.go
|
@ -43,30 +43,18 @@ command(s) that get executed on start, edit the args parameter of the spec. See
|
||||||
Usage: "do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk",
|
Usage: "do not use pivot root to jail process inside rootfs. This should be used whenever the rootfs is on top of a ramdisk",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) {
|
Action: func(context *cli.Context) error {
|
||||||
bundle := context.String("bundle")
|
spec, err := setupSpec(context)
|
||||||
if bundle != "" {
|
|
||||||
if err := os.Chdir(bundle); err != nil {
|
|
||||||
fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spec, err := loadSpec(specConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err)
|
return err
|
||||||
}
|
|
||||||
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
|
||||||
if notifySocket != "" {
|
|
||||||
setupSdNotify(spec, notifySocket)
|
|
||||||
}
|
|
||||||
if os.Geteuid() != 0 {
|
|
||||||
fatalf("runc should be run as root")
|
|
||||||
}
|
}
|
||||||
status, err := startContainer(context, spec, true)
|
status, err := startContainer(context, spec, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
// exit with the container's exit status so any external supervisor is
|
// exit with the container's exit status so any external supervisor is
|
||||||
// notified of the exit with the correct exit status.
|
// notified of the exit with the correct exit status.
|
||||||
os.Exit(status)
|
os.Exit(status)
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
11
delete.go
11
delete.go
|
@ -3,9 +3,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
|
@ -20,7 +20,7 @@ Where "<container-id>" is the name for the instance of the container.
|
||||||
|
|
||||||
EXAMPLE:
|
EXAMPLE:
|
||||||
For example, if the container id is "ubuntu01" and runc list currently shows the
|
For example, if the container id is "ubuntu01" and runc list currently shows the
|
||||||
status of "ubuntu01" as "destroyed" the following will delete resources held for
|
status of "ubuntu01" as "stopped" the following will delete resources held for
|
||||||
"ubuntu01" removing "ubuntu01" from the runc list of containers:
|
"ubuntu01" removing "ubuntu01" from the runc list of containers:
|
||||||
|
|
||||||
# runc delete ubuntu01`,
|
# runc delete ubuntu01`,
|
||||||
|
@ -38,8 +38,11 @@ status of "ubuntu01" as "destroyed" the following will delete resources held for
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
s, err := container.Status()
|
s, err := container.Status()
|
||||||
if err == nil && s == libcontainer.Created {
|
if err != nil {
|
||||||
container.Signal(syscall.SIGKILL)
|
return err
|
||||||
|
}
|
||||||
|
if s != libcontainer.Stopped {
|
||||||
|
return fmt.Errorf("cannot delete container that is not stopped: %s", s)
|
||||||
}
|
}
|
||||||
destroy(container)
|
destroy(container)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -76,13 +76,13 @@ type BaseContainer interface {
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// ContainerDestroyed - Container no longer exists,
|
// ContainerDestroyed - Container no longer exists,
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
Status() (Status, error)
|
Status() (Status, error)
|
||||||
|
|
||||||
// State returns the current container's state information.
|
// State returns the current container's state information.
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
State() (*State, error)
|
State() (*State, error)
|
||||||
|
|
||||||
// Returns the current config of the container.
|
// Returns the current config of the container.
|
||||||
|
@ -92,7 +92,7 @@ type BaseContainer interface {
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// ContainerDestroyed - Container no longer exists,
|
// ContainerDestroyed - Container no longer exists,
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
//
|
//
|
||||||
// Some of the returned PIDs may no longer refer to processes in the Container, unless
|
// Some of the returned PIDs may no longer refer to processes in the Container, unless
|
||||||
// the Container state is PAUSED in which case every PID in the slice is valid.
|
// the Container state is PAUSED in which case every PID in the slice is valid.
|
||||||
|
@ -102,7 +102,7 @@ type BaseContainer interface {
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// ContainerDestroyed - Container no longer exists,
|
// ContainerDestroyed - Container no longer exists,
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
Stats() (*Stats, error)
|
Stats() (*Stats, error)
|
||||||
|
|
||||||
// Set resources of container as configured
|
// Set resources of container as configured
|
||||||
|
@ -110,7 +110,7 @@ type BaseContainer interface {
|
||||||
// We can use this to change resources when containers are running.
|
// We can use this to change resources when containers are running.
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
Set(config configs.Config) error
|
Set(config configs.Config) error
|
||||||
|
|
||||||
// Start a process inside the container. Returns error if process fails to
|
// Start a process inside the container. Returns error if process fails to
|
||||||
|
@ -120,7 +120,7 @@ type BaseContainer interface {
|
||||||
// ContainerDestroyed - Container no longer exists,
|
// ContainerDestroyed - Container no longer exists,
|
||||||
// ConfigInvalid - config is invalid,
|
// ConfigInvalid - config is invalid,
|
||||||
// ContainerPaused - Container is paused,
|
// ContainerPaused - Container is paused,
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
Start(process *Process) (err error)
|
Start(process *Process) (err error)
|
||||||
|
|
||||||
// StartI immediatly starts the process inside the conatiner. Returns error if process
|
// StartI immediatly starts the process inside the conatiner. Returns error if process
|
||||||
|
@ -131,7 +131,7 @@ type BaseContainer interface {
|
||||||
// ContainerDestroyed - Container no longer exists,
|
// ContainerDestroyed - Container no longer exists,
|
||||||
// ConfigInvalid - config is invalid,
|
// ConfigInvalid - config is invalid,
|
||||||
// ContainerPaused - Container is paused,
|
// ContainerPaused - Container is paused,
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
StartI(process *Process) (err error)
|
StartI(process *Process) (err error)
|
||||||
|
|
||||||
// Destroys the container after killing all running processes.
|
// Destroys the container after killing all running processes.
|
||||||
|
@ -140,12 +140,12 @@ type BaseContainer interface {
|
||||||
// No error is returned if the container is already destroyed.
|
// No error is returned if the container is already destroyed.
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
Destroy() error
|
Destroy() error
|
||||||
|
|
||||||
// Signal sends the provided signal code to the container's initial process.
|
// Signal sends the provided signal code to the container's initial process.
|
||||||
//
|
//
|
||||||
// errors:
|
// errors:
|
||||||
// Systemerror - System error.
|
// SystemError - System error.
|
||||||
Signal(s os.Signal) error
|
Signal(s os.Signal) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -1096,11 +1096,9 @@ func (c *linuxContainer) runType() (Status, error) {
|
||||||
return Stopped, newSystemErrorWithCausef(err, "reading /proc/%d/environ", pid)
|
return Stopped, newSystemErrorWithCausef(err, "reading /proc/%d/environ", pid)
|
||||||
}
|
}
|
||||||
check := []byte("_LIBCONTAINER")
|
check := []byte("_LIBCONTAINER")
|
||||||
for _, v := range bytes.Split(environ, []byte("\x00")) {
|
if bytes.Contains(environ, check) {
|
||||||
if bytes.Contains(v, check) {
|
|
||||||
return Created, nil
|
return Created, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return Running, nil
|
return Running, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ func newTemplateConfig(rootfs string) *configs.Config {
|
||||||
Flags: defaultMountFlags,
|
Flags: defaultMountFlags,
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
|
CI is broken on the debian based kernels with this
|
||||||
{
|
{
|
||||||
Source: "mqueue",
|
Source: "mqueue",
|
||||||
Destination: "/dev/mqueue",
|
Destination: "/dev/mqueue",
|
||||||
|
|
46
run.go
46
run.go
|
@ -3,12 +3,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/coreos/go-systemd/activation"
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// default action is to start a container
|
// default action is to start a container
|
||||||
|
@ -58,23 +55,10 @@ command(s) that get executed on start, edit the args parameter of the spec. See
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
bundle := context.String("bundle")
|
spec, err := setupSpec(context)
|
||||||
if bundle != "" {
|
|
||||||
if err := os.Chdir(bundle); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spec, err := loadSpec(specConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
|
||||||
if notifySocket != "" {
|
|
||||||
setupSdNotify(spec, notifySocket)
|
|
||||||
}
|
|
||||||
if os.Geteuid() != 0 {
|
|
||||||
return fmt.Errorf("runc should be run as root")
|
|
||||||
}
|
|
||||||
status, err := startContainer(context, spec, false)
|
status, err := startContainer(context, spec, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// exit with the container's exit status so any external supervisor is
|
// exit with the container's exit status so any external supervisor is
|
||||||
|
@ -84,31 +68,3 @@ command(s) that get executed on start, edit the args parameter of the spec. See
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, error) {
|
|
||||||
id := context.Args().First()
|
|
||||||
if id == "" {
|
|
||||||
return -1, errEmptyID
|
|
||||||
}
|
|
||||||
container, err := createContainer(context, id, spec)
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
detach := context.Bool("detach")
|
|
||||||
// Support on-demand socket activation by passing file descriptors into the container init process.
|
|
||||||
listenFDs := []*os.File{}
|
|
||||||
if os.Getenv("LISTEN_FDS") != "" {
|
|
||||||
listenFDs = activation.Files(false)
|
|
||||||
}
|
|
||||||
r := &runner{
|
|
||||||
enableSubreaper: !context.Bool("no-subreaper"),
|
|
||||||
shouldDestroy: true,
|
|
||||||
container: container,
|
|
||||||
listenFDs: listenFDs,
|
|
||||||
console: context.String("console"),
|
|
||||||
detach: detach,
|
|
||||||
pidFile: context.String("pid-file"),
|
|
||||||
create: create,
|
|
||||||
}
|
|
||||||
return r.run(&spec.Process)
|
|
||||||
}
|
|
||||||
|
|
23
start.go
23
start.go
|
@ -1,32 +1,39 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var startCommand = cli.Command{
|
var startCommand = cli.Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Usage: "start signals a created container to execute the users defined process",
|
Usage: "start signals a created container to execute the user defined process",
|
||||||
ArgsUsage: `<container-id>
|
ArgsUsage: `<container-id>
|
||||||
|
|
||||||
Where "<container-id>" is your name for the instance of the container that you
|
Where "<container-id>" is your name for the instance of the container that you
|
||||||
are starting. The name you provide for the container instance must be unique on
|
are starting. The name you provide for the container instance must be unique on
|
||||||
your host.`,
|
your host.`,
|
||||||
Description: `The start command signals the container to start the user's defined process.`,
|
Description: `The start command signals the container to start the user's defined process.`,
|
||||||
Action: func(context *cli.Context) {
|
Action: func(context *cli.Context) error {
|
||||||
container, err := getContainer(context)
|
container, err := getContainer(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
status, err := container.Status()
|
status, err := container.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err)
|
return err
|
||||||
}
|
|
||||||
if status == libcontainer.Created {
|
|
||||||
if err := container.Signal(libcontainer.InitContinueSignal); err != nil {
|
|
||||||
fatal(err)
|
|
||||||
}
|
}
|
||||||
|
switch status {
|
||||||
|
case libcontainer.Created:
|
||||||
|
return container.Signal(libcontainer.InitContinueSignal)
|
||||||
|
case libcontainer.Stopped:
|
||||||
|
return fmt.Errorf("cannot start a container that has run and stopped")
|
||||||
|
case libcontainer.Running:
|
||||||
|
return fmt.Errorf("cannot start an already running container")
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("cannot start a container in the %s state", status)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
24
utils.go
24
utils.go
|
@ -5,6 +5,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fatal prints the error's details if it is a libcontainer specific error type
|
// fatal prints the error's details if it is a libcontainer specific error type
|
||||||
|
@ -15,3 +17,25 @@ func fatal(err error) {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setupSpec performs inital setup based on the cli.Context for the container
|
||||||
|
func setupSpec(context *cli.Context) (*specs.Spec, error) {
|
||||||
|
bundle := context.String("bundle")
|
||||||
|
if bundle != "" {
|
||||||
|
if err := os.Chdir(bundle); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spec, err := loadSpec(specConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
||||||
|
if notifySocket != "" {
|
||||||
|
setupSdNotify(spec, notifySocket)
|
||||||
|
}
|
||||||
|
if os.Geteuid() != 0 {
|
||||||
|
return nil, fmt.Errorf("runc should be run as root")
|
||||||
|
}
|
||||||
|
return spec, nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
"github.com/coreos/go-systemd/activation"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
||||||
"github.com/opencontainers/runc/libcontainer/specconv"
|
"github.com/opencontainers/runc/libcontainer/specconv"
|
||||||
|
@ -290,3 +291,31 @@ func validateProcessSpec(spec *specs.Process) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, error) {
|
||||||
|
id := context.Args().First()
|
||||||
|
if id == "" {
|
||||||
|
return -1, errEmptyID
|
||||||
|
}
|
||||||
|
container, err := createContainer(context, id, spec)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
detach := context.Bool("detach")
|
||||||
|
// Support on-demand socket activation by passing file descriptors into the container init process.
|
||||||
|
listenFDs := []*os.File{}
|
||||||
|
if os.Getenv("LISTEN_FDS") != "" {
|
||||||
|
listenFDs = activation.Files(false)
|
||||||
|
}
|
||||||
|
r := &runner{
|
||||||
|
enableSubreaper: !context.Bool("no-subreaper"),
|
||||||
|
shouldDestroy: true,
|
||||||
|
container: container,
|
||||||
|
listenFDs: listenFDs,
|
||||||
|
console: context.String("console"),
|
||||||
|
detach: detach,
|
||||||
|
pidFile: context.String("pid-file"),
|
||||||
|
create: create,
|
||||||
|
}
|
||||||
|
return r.run(&spec.Process)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue