Merge pull request #231 from shishir-a412ed/socket_activation

Systemd integration with runc, for on-demand socket activation
This commit is contained in:
Mrunal Patel 2015-08-28 11:28:46 -07:00
commit 525b3710d8
1 changed files with 29 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
"strconv"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
@ -13,6 +14,8 @@ import (
"github.com/opencontainers/specs" "github.com/opencontainers/specs"
) )
const SD_LISTEN_FDS_START = 3
var startCommand = cli.Command{ var startCommand = cli.Command{
Name: "start", Name: "start",
Usage: "create and run a container", Usage: "create and run a container",
@ -27,6 +30,13 @@ var startCommand = cli.Command{
setupSdNotify(spec, notifySocket) setupSdNotify(spec, notifySocket)
} }
listenFds := os.Getenv("LISTEN_FDS")
listenPid := os.Getenv("LISTEN_PID")
if listenFds != "" && listenPid == strconv.Itoa(os.Getpid()) {
setupSocketActivation(spec, listenFds)
}
if os.Geteuid() != 0 { if os.Geteuid() != 0 {
logrus.Fatal("runc should be run as root") logrus.Fatal("runc should be run as root")
} }
@ -79,6 +89,19 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
// that created it. // that created it.
defer destroy(container) defer destroy(container)
process := newProcess(spec.Process) 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"))
if err != nil {
return -1, err
}
for i := SD_LISTEN_FDS_START; i < (listenFdsInt + SD_LISTEN_FDS_START); i++ {
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), ""))
}
}
tty, err := newTty(spec.Process.Terminal, process, rootuid) tty, err := newTty(spec.Process.Terminal, process, rootuid)
if err != nil { if err != nil {
return -1, err return -1, err
@ -100,6 +123,12 @@ func setupSdNotify(spec *specs.LinuxSpec, notifySocket string) {
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))
} }
// If systemd is supporting on-demand socket activation, this function will add support
// for on-demand socket activation for the containerized service.
func setupSocketActivation(spec *specs.LinuxSpec, listenFds string) {
spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("LISTEN_FDS=%s", listenFds), "LISTEN_PID=1")
}
func destroy(container libcontainer.Container) { func destroy(container libcontainer.Container) {
status, err := container.Status() status, err := container.Status()
if err != nil { if err != nil {