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",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) {
|
||||
bundle := context.String("bundle")
|
||||
if bundle != "" {
|
||||
if err := os.Chdir(bundle); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
}
|
||||
spec, err := loadSpec(specConfig)
|
||||
Action: func(context *cli.Context) error {
|
||||
spec, err := setupSpec(context)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
||||
if notifySocket != "" {
|
||||
setupSdNotify(spec, notifySocket)
|
||||
}
|
||||
if os.Geteuid() != 0 {
|
||||
fatalf("runc should be run as root")
|
||||
return err
|
||||
}
|
||||
status, err := startContainer(context, spec, true)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
return err
|
||||
}
|
||||
// exit with the container's exit status so any external supervisor is
|
||||
// notified of the exit with the correct exit status.
|
||||
os.Exit(status)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
11
delete.go
11
delete.go
|
@ -3,9 +3,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
|
@ -20,7 +20,7 @@ Where "<container-id>" is the name for the instance of the container.
|
|||
|
||||
EXAMPLE:
|
||||
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:
|
||||
|
||||
# runc delete ubuntu01`,
|
||||
|
@ -38,8 +38,11 @@ status of "ubuntu01" as "destroyed" the following will delete resources held for
|
|||
return nil
|
||||
}
|
||||
s, err := container.Status()
|
||||
if err == nil && s == libcontainer.Created {
|
||||
container.Signal(syscall.SIGKILL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s != libcontainer.Stopped {
|
||||
return fmt.Errorf("cannot delete container that is not stopped: %s", s)
|
||||
}
|
||||
destroy(container)
|
||||
return nil
|
||||
|
|
|
@ -76,13 +76,13 @@ type BaseContainer interface {
|
|||
//
|
||||
// errors:
|
||||
// ContainerDestroyed - Container no longer exists,
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
Status() (Status, error)
|
||||
|
||||
// State returns the current container's state information.
|
||||
//
|
||||
// errors:
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
State() (*State, error)
|
||||
|
||||
// Returns the current config of the container.
|
||||
|
@ -92,7 +92,7 @@ type BaseContainer interface {
|
|||
//
|
||||
// errors:
|
||||
// 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
|
||||
// the Container state is PAUSED in which case every PID in the slice is valid.
|
||||
|
@ -102,7 +102,7 @@ type BaseContainer interface {
|
|||
//
|
||||
// errors:
|
||||
// ContainerDestroyed - Container no longer exists,
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
Stats() (*Stats, error)
|
||||
|
||||
// Set resources of container as configured
|
||||
|
@ -110,7 +110,7 @@ type BaseContainer interface {
|
|||
// We can use this to change resources when containers are running.
|
||||
//
|
||||
// errors:
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
Set(config configs.Config) error
|
||||
|
||||
// Start a process inside the container. Returns error if process fails to
|
||||
|
@ -120,7 +120,7 @@ type BaseContainer interface {
|
|||
// ContainerDestroyed - Container no longer exists,
|
||||
// ConfigInvalid - config is invalid,
|
||||
// ContainerPaused - Container is paused,
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
Start(process *Process) (err error)
|
||||
|
||||
// StartI immediatly starts the process inside the conatiner. Returns error if process
|
||||
|
@ -131,7 +131,7 @@ type BaseContainer interface {
|
|||
// ContainerDestroyed - Container no longer exists,
|
||||
// ConfigInvalid - config is invalid,
|
||||
// ContainerPaused - Container is paused,
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
StartI(process *Process) (err error)
|
||||
|
||||
// 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.
|
||||
//
|
||||
// errors:
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
Destroy() error
|
||||
|
||||
// Signal sends the provided signal code to the container's initial process.
|
||||
//
|
||||
// errors:
|
||||
// Systemerror - System error.
|
||||
// SystemError - System error.
|
||||
Signal(s os.Signal) error
|
||||
}
|
||||
|
|
|
@ -1096,10 +1096,8 @@ func (c *linuxContainer) runType() (Status, error) {
|
|||
return Stopped, newSystemErrorWithCausef(err, "reading /proc/%d/environ", pid)
|
||||
}
|
||||
check := []byte("_LIBCONTAINER")
|
||||
for _, v := range bytes.Split(environ, []byte("\x00")) {
|
||||
if bytes.Contains(v, check) {
|
||||
return Created, nil
|
||||
}
|
||||
if bytes.Contains(environ, check) {
|
||||
return Created, nil
|
||||
}
|
||||
return Running, nil
|
||||
}
|
||||
|
|
|
@ -90,12 +90,13 @@ func newTemplateConfig(rootfs string) *configs.Config {
|
|||
Flags: defaultMountFlags,
|
||||
},
|
||||
/*
|
||||
{
|
||||
Source: "mqueue",
|
||||
Destination: "/dev/mqueue",
|
||||
Device: "mqueue",
|
||||
Flags: defaultMountFlags,
|
||||
},
|
||||
CI is broken on the debian based kernels with this
|
||||
{
|
||||
Source: "mqueue",
|
||||
Destination: "/dev/mqueue",
|
||||
Device: "mqueue",
|
||||
Flags: defaultMountFlags,
|
||||
},
|
||||
*/
|
||||
{
|
||||
Source: "sysfs",
|
||||
|
|
46
run.go
46
run.go
|
@ -3,12 +3,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/coreos/go-systemd/activation"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
bundle := context.String("bundle")
|
||||
if bundle != "" {
|
||||
if err := os.Chdir(bundle); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
spec, err := loadSpec(specConfig)
|
||||
spec, err := setupSpec(context)
|
||||
if err != nil {
|
||||
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)
|
||||
if err == nil {
|
||||
// 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
|
||||
},
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
)
|
||||
|
||||
var startCommand = cli.Command{
|
||||
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>
|
||||
|
||||
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
|
||||
your host.`,
|
||||
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)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
return err
|
||||
}
|
||||
status, err := container.Status()
|
||||
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"
|
||||
|
||||
"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
|
||||
|
@ -15,3 +17,25 @@ func fatal(err error) {
|
|||
fmt.Fprintln(os.Stderr, err)
|
||||
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/codegangsta/cli"
|
||||
"github.com/coreos/go-systemd/activation"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
||||
"github.com/opencontainers/runc/libcontainer/specconv"
|
||||
|
@ -290,3 +291,31 @@ func validateProcessSpec(spec *specs.Process) error {
|
|||
}
|
||||
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