Cette révision appartient à :
Peter Bourgon
2015-09-28 22:30:44 +02:00
Parent 05fe1d1fa6
révision 819c47186c
10 fichiers modifiés avec 142 ajouts et 48 suppressions
+3
Voir le fichier
@@ -1,6 +1,9 @@
runsvinit runsvinit
runsvinit-*-* runsvinit-*-*
examples/runsvinit-linux-amd64* examples/runsvinit-linux-amd64*
zombietest/zombie
zombietest/runsvinit
*.uptodate
# Compiled Object files, Static and Dynamic libs (Shared Objects) # Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o *.o
+17 -6
Voir le fichier
@@ -1,6 +1,7 @@
package main package main
import ( import (
"flag"
"log" "log"
"os" "os"
"os/exec" "os/exec"
@@ -13,6 +14,9 @@ import (
const etcService = "/etc/service" const etcService = "/etc/service"
func main() { func main() {
reap := flag.Bool("reap", true, "reap orphan children")
flag.Parse()
log.SetFlags(0) log.SetFlags(0)
runsvdir, err := exec.LookPath("runsvdir") runsvdir, err := exec.LookPath("runsvdir")
@@ -35,7 +39,12 @@ func main() {
log.Printf("warning: I'm not PID 1, I'm PID %d", pid) log.Printf("warning: I'm not PID 1, I'm PID %d", pid)
} }
go reapAll() if *reap {
log.Print("reaping zombies")
go reapLoop()
} else {
log.Print("NOT reaping zombies")
}
supervisor := cmd(runsvdir, etcService) supervisor := cmd(runsvdir, etcService)
if err := supervisor.Start(); err != nil { if err := supervisor.Start(); err != nil {
@@ -53,16 +62,17 @@ func main() {
} }
} }
func reapAll() { // From https://github.com/ramr/go-reaper/blob/master/reaper.go
func reapLoop() {
c := make(chan os.Signal) c := make(chan os.Signal)
signal.Notify(c, syscall.SIGCHLD) signal.Notify(c, syscall.SIGCHLD)
for range c { for range c {
go reapOne() reapChildren()
} }
} }
// From https://github.com/ramr/go-reaper/blob/master/reaper.go func reapChildren() {
func reapOne() { for {
var ( var (
ws syscall.WaitStatus ws syscall.WaitStatus
pid int pid int
@@ -75,9 +85,10 @@ func reapOne() {
} }
} }
if err == syscall.ECHILD { if err == syscall.ECHILD {
return return // done
} }
log.Printf("reaped child process %d (%+v)", pid, ws) log.Printf("reaped child process %d (%+v)", pid, ws)
}
} }
type signaler interface { type signaler interface {
+11
Voir le fichier
@@ -0,0 +1,11 @@
FROM alpine:latest
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/testing" >>/etc/apk/repositories && \
apk add --update runit && \
rm -rf /var/cache/apk/*
COPY zombie /
RUN mkdir -p /etc/service/zombie
COPY run-zombie /etc/service/zombie/run
COPY /runsvinit /
+23
Voir le fichier
@@ -0,0 +1,23 @@
.PHONY: test clean
test: .test.uptodate
./test.bash
.test.uptodate: runsvinit zombie run-zombie Dockerfile
docker build -t zombietest .
touch $@
runsvinit: ../*.go
env GOOS=linux GOARCH=amd64 go build -o $@ github.com/peterbourgon/runsvinit
zombie: .build.uptodate
docker run --rm -v $(shell pwd):/mount zombietest-build cc -Wall -Werror -o /mount/zombie /zombie.c
.build.uptodate: build/zombie.c build/Dockerfile
docker build -t zombietest-build build/
touch $@
clean:
rm -rf .test.uptodate .build.uptodate runsvinit zombie
docker stop zombietest zombietest-build >/dev/null 2>&1 || true
docker rm zombietest zombietest-build >/dev/null 2>&1 || true
+24
Voir le fichier
@@ -0,0 +1,24 @@
# zombietest
This directory contains an integration test to prove runsvinit is actually
reaping zombies. `make` builds and executes the test as follows:
1. We produce a linux/amd64 runsvinit binary by setting GOOS/GOARCH and
invoking the Go compiler. Requires Go 1.5, or Go 1.4 built with the
appropriate cross-compile options.
2. The build/zombie.c program spawns five zombies and exits. We compile it for
linux/amd64 via a zombietest-build container. We do this so `make` works
from a Mac. This requires a working Docker installation.
3. Once we have linux/amd64 runsvinit and zombie binaries, we produce a
zombietest container via the Dockerfile. That container contains a single
runit service, /etc/service/zombie, which supervises the zombie binary. We
provide no default ENTRYPOINT, so we can supply it at runtime.
4. Once the zombietest container is built, we invoke the test.bash script.
That launches a version of the container with runsvinit set to NOT reap
zombies, and after 1 second, verifies that zombies exist. Then, it launches
a version of the container with runsvinit set to reap zombies, and after 1
second, verifies that no zombies exist.
+2 -8
Voir le fichier
@@ -1,9 +1,3 @@
FROM golang:1.5.1 FROM alpine:latest
RUN apk add --update gcc musl-dev && rm -rf /var/cache/apk/*
COPY ../../*.go /go/src/github.com/peterbourgon/runsvinit
RUN go install -v github.com/peterbourgon/runsvinit
RUN mv /go/bin/runsvinit /mount/
COPY zombie.c / COPY zombie.c /
RUN cc -Wall -Werror -o /zombie /zombie.c
RUN mv /zombie /mount/
-9
Voir le fichier
@@ -1,9 +0,0 @@
.PHONY: all
all: zombie runsvinit
zombie runsvinit: .uptodate
docker run -ti --rm -v $(shell pwd):/mount zombie-build
.uptodate: Dockerfile ../../*.go
docker build -t zombie-build .
touch $@
+11 -11
Voir le fichier
@@ -1,18 +1,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
int main () int main() {
{ pid_t pid;
pid_t child_pid; int i;
for (i = 0; i<5; i++) {
child_pid = fork (); pid = fork();
if (child_pid > 0) { if (pid > 0) {
sleep (60); printf("Zombie #%d born\n", i + 1);
} else {
printf("Brains...\n");
exit(0);
} }
else {
exit (0);
} }
return 0; return 0;
} }
Fichier exécutable
+3
Voir le fichier
@@ -0,0 +1,3 @@
#!/bin/sh
exec /zombie
Fichier exécutable
+34
Voir le fichier
@@ -0,0 +1,34 @@
#!/bin/bash
RC=0
SLEEP=1
C=$(docker run -d zombietest /runsvinit -reap=false)
sleep $SLEEP
NOREAP=$(docker exec $C ps -o pid,stat | grep Z | wc -l)
echo -n without reaping, we have $NOREAP zombies...
if [ "$NOREAP" -le "0" ]
then
echo " FAIL"
RC=1
else
echo " good"
fi
docker stop $C >/dev/null
docker rm $C >/dev/null
C=$(docker run -d zombietest /runsvinit)
sleep $SLEEP
YESREAP=$(docker exec $C ps -o pid,stat | grep Z | wc -l)
echo -n with reaping, we have $YESREAP zombies...
if [ "$YESREAP" -gt "0" ]
then
echo " FAIL"
RC=1
else
echo " good"
fi
docker stop $C >/dev/null
docker rm $C >/dev/null
exit $RC