Skip to content

Commit

Permalink
Systemd integration with runc, for on-demand socket activation
Browse files Browse the repository at this point in the history
Signed-off-by: Shishir Mahajan <shishir.mahajan@redhat.com>
  • Loading branch information
Shishir Mahajan committed Aug 27, 2015
1 parent 7797873 commit d6e4ed9
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import (
"fmt"
"os"
"runtime"
"strconv"

"github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/specs"
)

const SD_LISTEN_FDS_START = 3

var startCommand = cli.Command{
Name: "start",
Usage: "create and run a container",
Expand All @@ -27,6 +30,13 @@ var startCommand = cli.Command{
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 {
logrus.Fatal("runc should be run as root")
}
Expand Down Expand Up @@ -79,6 +89,19 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
// that created it.
defer destroy(container)
process := newProcess(spec.Process)

//support for on-demand socket activation: leak file descriptors into the container.
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)
if err != nil {
return -1, err
Expand All @@ -100,6 +123,13 @@ func setupSdNotify(spec *specs.LinuxSpec, notifySocket string) {
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))
spec.Process.Env = append(spec.Process.Env, "LISTEN_PID=1")
}

func destroy(container libcontainer.Container) {
status, err := container.Status()
if err != nil {
Expand Down

0 comments on commit d6e4ed9

Please sign in to comment.