Skip to content

Commit

Permalink
Merge pull request #429 from charliemirabile/systemd_activation
Browse files Browse the repository at this point in the history
Support systemd socket activation
  • Loading branch information
AkihiroSuda committed Mar 30, 2024
2 parents 8d13cca + 040875c commit 2356582
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
17 changes: 17 additions & 0 deletions hack/integration-systemd-socket.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh
set -e
if [ -z "$EXECED" ]
then
systemd-socket-activate -E EXECED=1 -l /tmp/activate.sock socat ACCEPT-FD:3 EXEC:"rootlesskit $0",nofork 2>/dev/null &
OUTPUT="$(curl --unix-socket /tmp/activate.sock http://localhost/hello 2>/dev/null)"
[ "$(printf 'Hello\n' )" = "$OUTPUT" ] || exit 1
else
[ "$LISTEN_FDS" = "1" ] || exit 1
read -r REQUEST
if [ "$(printf 'GET /hello HTTP/1.1\r\n')" = "$REQUEST" ]
then
printf 'HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nHello\n'
else
printf 'HTTP/1.1 400 Bad Request\r\nContent-Length: 5\r\n\r\nBad!\n'
fi
fi
18 changes: 18 additions & 0 deletions pkg/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ var propagationStates = map[string]uintptr{
"rslave": uintptr(unix.MS_REC | unix.MS_SLAVE),
}

func setupFiles(cmd *exec.Cmd) {
// 0 1 and 2 are used for stdin. stdout, and stderr
const firstExtraFD = 3
systemdActivationFDs := 0
// check for systemd socket activation sockets
if v := os.Getenv("LISTEN_FDS"); v != "" {
if num, err := strconv.Atoi(v); err == nil {
systemdActivationFDs = num
cmd.ExtraFiles = make([]*os.File, systemdActivationFDs)
}
}
for fd := 0; fd < systemdActivationFDs; fd++ {
cmd.ExtraFiles[fd] = os.NewFile(uintptr(firstExtraFD + fd), "")
}
}


func createCmd(targetCmd []string) (*exec.Cmd, error) {
var args []string
if len(targetCmd) > 1 {
Expand All @@ -47,6 +64,7 @@ func createCmd(targetCmd []string) (*exec.Cmd, error) {
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,
}
setupFiles(cmd)
return cmd, nil
}

Expand Down
24 changes: 22 additions & 2 deletions pkg/parent/parent.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,27 @@ func LockStateDir(stateDir string) (*flock.Flock, error) {
return lock, nil
}

func setupFilesAndEnv(cmd *exec.Cmd, readPipe *os.File, writePipe *os.File, envKey string) {
// 0 1 and 2 are used for stdin. stdout, and stderr
const firstExtraFD = 3
systemdActivationFDs := 0
// check for systemd socket activation sockets
if v := os.Getenv("LISTEN_FDS"); v != "" {
if num, err := strconv.Atoi(v); err == nil {
systemdActivationFDs = num
}
}
cmd.ExtraFiles = make([]*os.File, systemdActivationFDs + 2)
for fd := 0; fd < systemdActivationFDs; fd++ {
cmd.ExtraFiles[fd] = os.NewFile(uintptr(firstExtraFD + fd), "")
}
readIndex := systemdActivationFDs
writeIndex := readIndex + 1
cmd.ExtraFiles[readIndex] = readPipe
cmd.ExtraFiles[writeIndex] = writePipe
cmd.Env = append(os.Environ(), envKey+"="+strconv.Itoa(firstExtraFD+readIndex)+","+strconv.Itoa(firstExtraFD+writeIndex))
}

func Parent(opt Opt) error {
if err := checkPreflight(opt); err != nil {
return err
Expand Down Expand Up @@ -178,8 +199,7 @@ func Parent(opt Opt) error {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.ExtraFiles = []*os.File{pipeR, pipe2W}
cmd.Env = append(os.Environ(), opt.PipeFDEnvKey+"=3,4")
setupFilesAndEnv(cmd, pipeR, pipe2W, opt.PipeFDEnvKey)
if opt.StateDirEnvKey != "" {
cmd.Env = append(cmd.Env, opt.StateDirEnvKey+"="+opt.StateDir)
}
Expand Down

0 comments on commit 2356582

Please sign in to comment.