diff --git a/pkg/containerd/Dockerfile b/pkg/containerd/Dockerfile index 48184b5f8..28c1386cc 100644 --- a/pkg/containerd/Dockerfile +++ b/pkg/containerd/Dockerfile @@ -23,6 +23,7 @@ RUN cp bin/containerd bin/ctr bin/containerd-shim /usr/bin/ ADD cmd /go/src/cmd RUN cd /go/src/cmd/service && ./skanky-vendor.sh $GOPATH/src/github.com/containerd/containerd RUN go-compile.sh /go/src/cmd/service +RUN mkdir -p /etc/init.d && ln -s /usr/bin/service /etc/init.d/020-containerd WORKDIR / COPY . . @@ -33,4 +34,5 @@ WORKDIR / COPY --from=alpine /usr/bin/containerd /usr/bin/ctr /usr/bin/containerd-shim /go/bin/service /usr/bin/ COPY --from=alpine /etc/containerd/config.toml /etc/containerd/ COPY --from=alpine /usr/share/zoneinfo/UTC /etc/localtime +COPY --from=alpine /etc/init.d/ /etc/init.d/ COPY etc etc/ diff --git a/pkg/containerd/Makefile b/pkg/containerd/Makefile index 838de4d29..33694b2e3 100644 --- a/pkg/containerd/Makefile +++ b/pkg/containerd/Makefile @@ -1,5 +1,5 @@ IMAGE=containerd NETWORK=1 -DEPS=$(wildcard etc/init.d/*) $(wildcard cmd/service/*.go) etc/containerd/config.toml +DEPS=$(wildcard cmd/service/*.go) etc/containerd/config.toml include ../package.mk diff --git a/pkg/containerd/cmd/service/main.go b/pkg/containerd/cmd/service/main.go index 3d6957f5c..bf68a3f2c 100644 --- a/pkg/containerd/cmd/service/main.go +++ b/pkg/containerd/cmd/service/main.go @@ -66,9 +66,8 @@ func main() { args := flag.Args() if len(args) < 1 { - fmt.Printf("Please specify a command.\n\n") - flag.Usage() - os.Exit(1) + systemInitCmd(args) + os.Exit(0) } switch args[0] { diff --git a/pkg/containerd/cmd/service/prepare.go b/pkg/containerd/cmd/service/prepare.go new file mode 100644 index 000000000..5afde41b8 --- /dev/null +++ b/pkg/containerd/cmd/service/prepare.go @@ -0,0 +1,21 @@ +package main + +// Please note this file is shared between pkg/runc and pkg/containerd +// Update it in both places if you make changes + +import ( + "path/filepath" + "syscall" +) + +func prepare(path string) error { + rootfs := filepath.Join(path, "rootfs") + if err := syscall.Mount(rootfs, rootfs, "", syscall.MS_BIND, ""); err != nil { + return err + } + // remount rw + if err := syscall.Mount("", rootfs, "", syscall.MS_REMOUNT, ""); err != nil { + return err + } + return nil +} diff --git a/pkg/containerd/cmd/service/start.go b/pkg/containerd/cmd/service/start.go index e34c969dd..6e37b3b99 100644 --- a/pkg/containerd/cmd/service/start.go +++ b/pkg/containerd/cmd/service/start.go @@ -58,6 +58,10 @@ func startCmd(args []string) { func start(service, sock, path, dumpSpec string) (string, uint32, string, error) { rootfs := filepath.Join(path, service, "rootfs") + if err := prepare(filepath.Join(path, service)); err != nil { + return "", 0, "preparing rootfs", err + } + client, err := containerd.New(sock) if err != nil { return "", 0, "creating containerd client", err diff --git a/pkg/containerd/etc/init.d/020-containerd b/pkg/containerd/etc/init.d/020-containerd deleted file mode 100755 index 845a09b1b..000000000 --- a/pkg/containerd/etc/init.d/020-containerd +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -# start service containers - -if [ -d /containers/services ] -then - for f in $(find /containers/services -mindepth 1 -maxdepth 1 | sort) - do - /bin/mount --bind "$f/rootfs" "$f/rootfs" - mount -o remount,rw "$f/rootfs" - done -fi - -service system-init diff --git a/pkg/init/bin/rc.init b/pkg/init/bin/rc.init index 883c655a0..1601b6a7a 100755 --- a/pkg/init/bin/rc.init +++ b/pkg/init/bin/rc.init @@ -99,7 +99,7 @@ ip route add 127.0.0.0/8 dev lo scope host ip link set lo up # for containerizing dhcpcd and other containers that need writable /etc/resolv.conf -[ -L /etc/resolv.conf ] && mkdir -p $(dirname $(readlink -n /etc/resolv.conf)) +[ -L /etc/resolv.conf ] && mkdir -p $(dirname $(readlink -n /etc/resolv.conf)) && touch /etc/resolv.conf # remount rootfs as readonly mount -o remount,ro / @@ -117,7 +117,7 @@ ulimit -n 1048576 ulimit -p unlimited # execute other init processes -INITS="$(find /etc/init.d -type f 2>/dev/null | sort)" +INITS="$(find /etc/init.d ! -type d 2>/dev/null | sort)" for f in $INITS do $f diff --git a/pkg/init/bin/rc.shutdown b/pkg/init/bin/rc.shutdown index 02ae06587..6d3880145 100755 --- a/pkg/init/bin/rc.shutdown +++ b/pkg/init/bin/rc.shutdown @@ -1,7 +1,7 @@ #!/bin/sh # execute other shutdown processes -SHUTS="$(find /etc/shutdown.d -type f 2>/dev/null | sort)" +SHUTS="$(find /etc/shutdown.d ! -type d 2>/dev/null | sort)" for f in $SHUTS do $f diff --git a/pkg/runc/Dockerfile b/pkg/runc/Dockerfile index e02247b98..3cbc010b2 100644 --- a/pkg/runc/Dockerfile +++ b/pkg/runc/Dockerfile @@ -1,4 +1,4 @@ -FROM linuxkit/alpine:8bb8664eec04e02a8a131c53aa7d5d94119270ef as alpine +FROM linuxkit/alpine:a39a433162a873519910a07beeb3e8db22529956 as alpine RUN \ apk add \ bash \ @@ -10,7 +10,7 @@ RUN \ linux-headers \ make \ && true -ENV GOPATH=/root/go +ENV GOPATH=/go PATH=$PATH:/go/bin ENV RUNC_COMMIT=429a5387123625040bacfbb60d96b1cbd02293ab RUN mkdir -p $GOPATH/src/github.com/opencontainers && \ cd $GOPATH/src/github.com/opencontainers && \ @@ -20,8 +20,14 @@ RUN git checkout $RUNC_COMMIT RUN make static BUILDTAGS="seccomp" EXTRA_FLAGS="-buildmode pie" EXTRA_LDFLAGS="-extldflags \\\"-fno-PIC -static\\\"" RUN cp runc /usr/bin/ +ADD cmd /go/src/cmd +RUN go-compile.sh /go/src/cmd/onboot +RUN mkdir -p /etc/init.d && ln -s /usr/bin/onboot /etc/init.d/010-onboot +RUN mkdir -p /etc/shutdown.d && ln -s /usr/bin/onboot /etc/shutdown.d/010-onshutdown + FROM scratch WORKDIR / ENTRYPOINT [] -COPY --from=alpine /usr/bin/runc /usr/bin/ -COPY etc etc/ +COPY --from=alpine /usr/bin/runc /go/bin/onboot /usr/bin/ +COPY --from=alpine /etc/init.d/ /etc/init.d/ +COPY --from=alpine /etc/shutdown.d/ /etc/shutdown.d/ diff --git a/pkg/runc/Makefile b/pkg/runc/Makefile index c56c7dfe1..5691a025d 100644 --- a/pkg/runc/Makefile +++ b/pkg/runc/Makefile @@ -1,5 +1,5 @@ IMAGE=runc NETWORK=1 -DEPS=$(wildcard etc/init.d/*) +DEPS=$(wildcard cmd/onboot/*.go) include ../package.mk diff --git a/pkg/runc/cmd/onboot/main.go b/pkg/runc/cmd/onboot/main.go new file mode 100644 index 000000000..da1a59ca7 --- /dev/null +++ b/pkg/runc/cmd/onboot/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +const ( + runcBinary = "/usr/bin/runc" + onbootPath = "/containers/onboot" + shutdownPath = "/containers/onshutdown" +) + +func main() { + // try to work out how we are being called + command := os.Args[0] + if len(os.Args) > 1 { + command = os.Args[1] + } + var path = onbootPath + switch { + case strings.Contains(command, "boot"): + path = onbootPath + case strings.Contains(command, "shutdown"): + path = shutdownPath + } + + // do nothing if the path does not exist + if _, err := os.Stat(path); err != nil && os.IsNotExist(err) { + os.Exit(0) + } + + // get files; note ReadDir already sorts them + files, err := ioutil.ReadDir(path) + if err != nil { + log.Fatalf("Cannot read files in %s: %v", path, err) + } + + status := 0 + + for _, file := range files { + name := file.Name() + fullPath := filepath.Join(path, name) + if err := prepare(fullPath); err != nil { + log.Printf("Error preparing %s: %v", name, err) + status = 1 + continue + } + cmd := exec.Command(runcBinary, "run", "--bundle", fullPath, name) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + log.Printf("Error running %s: %v", name, err) + status = 1 + } + } + + os.Exit(status) +} diff --git a/pkg/runc/cmd/onboot/prepare.go b/pkg/runc/cmd/onboot/prepare.go new file mode 100644 index 000000000..5afde41b8 --- /dev/null +++ b/pkg/runc/cmd/onboot/prepare.go @@ -0,0 +1,21 @@ +package main + +// Please note this file is shared between pkg/runc and pkg/containerd +// Update it in both places if you make changes + +import ( + "path/filepath" + "syscall" +) + +func prepare(path string) error { + rootfs := filepath.Join(path, "rootfs") + if err := syscall.Mount(rootfs, rootfs, "", syscall.MS_BIND, ""); err != nil { + return err + } + // remount rw + if err := syscall.Mount("", rootfs, "", syscall.MS_REMOUNT, ""); err != nil { + return err + } + return nil +} diff --git a/pkg/runc/etc/init.d/010-onboot b/pkg/runc/etc/init.d/010-onboot deleted file mode 100755 index f316605ea..000000000 --- a/pkg/runc/etc/init.d/010-onboot +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# start onboot containers, run to completion - -if [ -d /containers/onboot ] -then - for f in $(find /containers/onboot -mindepth 1 -maxdepth 1 | sort) - do - base="$(basename $f)" - /bin/mount --bind "$f/rootfs" "$f/rootfs" - mount -o remount,rw "$f/rootfs" - /usr/bin/runc run --bundle "$f" "$(basename $f)" - printf " - $base\n" - done -fi diff --git a/pkg/runc/etc/shutdown.d/010-onshutdown b/pkg/runc/etc/shutdown.d/010-onshutdown deleted file mode 100755 index 1f72d37cc..000000000 --- a/pkg/runc/etc/shutdown.d/010-onshutdown +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# start onshutdown containers, run to completion - -if [ -d /containers/onshutdown ] -then - for f in $(find /containers/onshutdown -mindepth 1 -maxdepth 1 | sort) - do - base="$(basename $f)" - /bin/mount --bind "$f/rootfs" "$f/rootfs" - mount -o remount,rw "$f/rootfs" - /usr/bin/runc run --bundle "$f" "$(basename $f)" - printf " - $base\n" - done -fi