Add detach to runc
By adding detach to runc the container process is the only thing running on the system is the containers process. This allows better usage of memeory and no runc process being long lived. With this addition you also need a delete command because the detached container will not be able to remove state and the left over cgroups directories. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
480e5f4416
commit
bb6a747825
|
@ -0,0 +1,15 @@
|
|||
package main
|
||||
|
||||
import "github.com/codegangsta/cli"
|
||||
|
||||
var deleteCommand = cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "delete any resources held by the container often used with detached containers",
|
||||
Action: func(context *cli.Context) {
|
||||
container, err := getContainer(context)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
destroy(container)
|
||||
},
|
||||
}
|
|
@ -219,5 +219,8 @@ func (n *createdState) transition(s containerState) error {
|
|||
}
|
||||
|
||||
func (n *createdState) destroy() error {
|
||||
return nil
|
||||
if err := n.c.refreshState(); err != nil {
|
||||
return err
|
||||
}
|
||||
return n.c.state.destroy()
|
||||
}
|
||||
|
|
14
main.go
14
main.go
|
@ -70,16 +70,18 @@ func main() {
|
|||
},
|
||||
}
|
||||
app.Commands = []cli.Command{
|
||||
startCommand,
|
||||
checkpointCommand,
|
||||
deleteCommand,
|
||||
eventsCommand,
|
||||
restoreCommand,
|
||||
killCommand,
|
||||
specCommand,
|
||||
pauseCommand,
|
||||
resumeCommand,
|
||||
execCommand,
|
||||
execCommand,
|
||||
killCommand,
|
||||
listCommand,
|
||||
pauseCommand,
|
||||
restoreCommand,
|
||||
resumeCommand,
|
||||
specCommand,
|
||||
startCommand,
|
||||
}
|
||||
app.Before = func(context *cli.Context) error {
|
||||
if context.GlobalBool("debug") {
|
||||
|
|
72
start.go
72
start.go
|
@ -7,6 +7,7 @@ import (
|
|||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/codegangsta/cli"
|
||||
|
@ -31,6 +32,15 @@ var startCommand = cli.Command{
|
|||
Value: "",
|
||||
Usage: "specify the pty slave path for use with the container",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "detach,d",
|
||||
Usage: "detach from the container's process",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pid-file",
|
||||
Value: "",
|
||||
Usage: "specify the file to write the process id to",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) {
|
||||
bundle := context.String("bundle")
|
||||
|
@ -107,10 +117,11 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec, rspec *specs.Li
|
|||
}
|
||||
// ensure that the container is always removed if we were the process
|
||||
// that created it.
|
||||
defer destroy(container)
|
||||
|
||||
detach := context.Bool("detach")
|
||||
if !detach {
|
||||
defer destroy(container)
|
||||
}
|
||||
process := newProcess(spec.Process)
|
||||
|
||||
// Support on-demand socket activation by passing file descriptors into the container init process.
|
||||
if os.Getenv("LISTEN_FDS") != "" {
|
||||
listenFdsInt, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
|
||||
|
@ -121,18 +132,63 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec, rspec *specs.Li
|
|||
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), ""))
|
||||
}
|
||||
}
|
||||
tty, err := newTty(spec.Process.Terminal, process, rootuid, context.String("console"))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
var tty *tty
|
||||
if spec.Process.Terminal {
|
||||
if tty, err = createTty(process, rootuid, context.String("console")); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
} else if detach {
|
||||
if err := dupStdio(process, rootuid); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
} else {
|
||||
if tty, err = createStdioPipes(process, rootuid); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
handler := newSignalHandler(tty)
|
||||
defer handler.Close()
|
||||
if err := container.Start(process); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if pidFile := context.String("pid-file"); pidFile != "" {
|
||||
pid, err := process.Pid()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
f, err := os.Create(pidFile)
|
||||
if err != nil {
|
||||
logrus.WithField("pid", pid).Error("create pid file")
|
||||
} else {
|
||||
_, err = fmt.Fprintf(f, "%d", pid)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
logrus.WithField("error", err).Error("write pid file")
|
||||
}
|
||||
}
|
||||
}
|
||||
if detach {
|
||||
return 0, nil
|
||||
}
|
||||
handler := newSignalHandler(tty)
|
||||
defer handler.Close()
|
||||
return handler.forward(process)
|
||||
}
|
||||
|
||||
func dupStdio(process *libcontainer.Process, rootuid int) error {
|
||||
process.Stdin = os.Stdin
|
||||
process.Stdout = os.Stdout
|
||||
process.Stderr = os.Stderr
|
||||
for _, fd := range []uintptr{
|
||||
os.Stdin.Fd(),
|
||||
os.Stdout.Fd(),
|
||||
os.Stderr.Fd(),
|
||||
} {
|
||||
if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// If systemd is supporting sd_notify protocol, this function will add support
|
||||
// for sd_notify protocol from within the container.
|
||||
func setupSdNotify(spec *specs.LinuxSpec, rspec *specs.LinuxRuntimeSpec, notifySocket string) {
|
||||
|
|
Loading…
Reference in New Issue