From 0eb317e1191ea827d79240f98d755d20a90850b0 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 19 Dec 2014 11:26:49 -0800 Subject: [PATCH] stage1: componentize stage1 rootfs construction and use make * Move stage1/*.go to stage1/init/ * Split stage1/mkrootfs.sh's logical components into subdirs of stage1/rootfs: - Deriving tree from CoreOS image and caching: rootfs/usr * Cache management in cache.sh * File extraction and picking in mkbase.sh * File inclusions split under usr/manifest.d - Fakesdboot: rootfs/shim/ * Renamed to 'shim' since we've gone past just tricking nspawn - Root compositing and aggregation of odds and ends: rootfs/aggregate * Introduction of Makefiles for every component and a simple recursive parallel-capable make for the rootfs tip. * Update toplevel build script to invoke make on stage1/rootfs and find init sources in stage1/init, .gitignore additions as well. * Removed stage1/mkrootfs.sh Since the image cache has moved there will be an image download on first build in the new arrangement. The caching has also been improved to handle CoreOS image revision changes by naming the cached signature with a hash of the URL. --- .gitignore | 8 + build | 15 +- stage1/{ => init}/container.go | 0 stage1/{ => init}/init.go | 0 stage1/{ => init}/path.go | 0 stage1/mkrootfs.sh | 507 ------------------ stage1/rootfs/Makefile | 17 + stage1/rootfs/aggregate/Makefile | 19 + stage1/rootfs/aggregate/aggregate.sh | 34 ++ stage1/rootfs/aggregate/scripts/reaper.sh | 12 + stage1/rootfs/aggregate/units/default.target | 3 + .../aggregate/units/exit-watcher.service | 8 + stage1/rootfs/aggregate/units/local-fs.target | 4 + stage1/rootfs/aggregate/units/reaper.service | 7 + stage1/rootfs/aggregate/units/sockets.target | 3 + stage1/rootfs/shim/Makefile | 12 + stage1/rootfs/shim/shim.c | 91 ++++ stage1/rootfs/usr/Makefile | 16 + stage1/rootfs/usr/cache.sh | 184 +++++++ stage1/rootfs/usr/manifest.d/bash | 14 + stage1/rootfs/usr/manifest.d/sleep | 5 + stage1/rootfs/usr/manifest.d/systemd | 105 ++++ stage1/rootfs/usr/mkbase.sh | 36 ++ 23 files changed, 582 insertions(+), 518 deletions(-) rename stage1/{ => init}/container.go (100%) rename stage1/{ => init}/init.go (100%) rename stage1/{ => init}/path.go (100%) delete mode 100755 stage1/mkrootfs.sh create mode 100644 stage1/rootfs/Makefile create mode 100644 stage1/rootfs/aggregate/Makefile create mode 100755 stage1/rootfs/aggregate/aggregate.sh create mode 100644 stage1/rootfs/aggregate/scripts/reaper.sh create mode 100644 stage1/rootfs/aggregate/units/default.target create mode 100644 stage1/rootfs/aggregate/units/exit-watcher.service create mode 100644 stage1/rootfs/aggregate/units/local-fs.target create mode 100644 stage1/rootfs/aggregate/units/reaper.service create mode 100644 stage1/rootfs/aggregate/units/sockets.target create mode 100644 stage1/rootfs/shim/Makefile create mode 100644 stage1/rootfs/shim/shim.c create mode 100644 stage1/rootfs/usr/Makefile create mode 100755 stage1/rootfs/usr/cache.sh create mode 100644 stage1/rootfs/usr/manifest.d/bash create mode 100644 stage1/rootfs/usr/manifest.d/sleep create mode 100644 stage1/rootfs/usr/manifest.d/systemd create mode 100755 stage1/rootfs/usr/mkbase.sh diff --git a/.gitignore b/.gitignore index b18f07c..46863cc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,12 @@ gopath/ stage0/stage1_init/ stage0/stage1_rootfs/ stage1/cache/ +stage1/rootfs/usr/cache/ +stage1/rootfs/aggregate/s1rootfs/ +stage1/rootfs/shim/shim.so +stage1/rootfs/usr/manifest.txt +stage1/rootfs/usr/rootfs/ +stage1/rootfs/aggregate/s1rootfs.tar +stage1/rootfs/usr/usr.done +stage1/rootfs/usr/usr.squashfs *.sw[ponm] diff --git a/build b/build index 0418b69..da8e4d9 100755 --- a/build +++ b/build @@ -15,10 +15,9 @@ eval $(go env) if [[ "$OSTYPE" == "linux-gnu" ]]; then echo "Building init (stage1)..." - go build -o $GOBIN/init ${REPO_PATH}/stage1 + go build -o $GOBIN/init ${REPO_PATH}/stage1/init - S1BINS=${PWD}/stage0 - S1INIT=${S1BINS}/stage1_init + S1INIT=${PWD}/stage0/stage1_init if [ $GOBIN/init -nt $S1INIT/bin.go ]; then echo "Packaging init (stage1)..." TMP=$(mktemp -d -t rocket-XXXXXX) @@ -27,14 +26,8 @@ if [[ "$OSTYPE" == "linux-gnu" ]]; then go-bindata -o $S1INIT/bin.go -pkg="stage1_init" -prefix=$TMP $TMP fi - S1ROOTFS=${S1BINS}/stage1_rootfs - if [ stage1/mkrootfs.sh -nt $S1ROOTFS/bin.go ]; then - echo "Generating and packaging rootfs (stage1)..." - [ -d "${S1ROOTFS}" ] || mkdir -p "${S1ROOTFS}" - pushd stage1 - OUTPUT=$S1ROOTFS/bin.go ./mkrootfs.sh - popd - fi + echo "Building rootfs (stage1)..." + make -C stage1/rootfs fi echo "Building rkt (stage0)..." diff --git a/stage1/container.go b/stage1/init/container.go similarity index 100% rename from stage1/container.go rename to stage1/init/container.go diff --git a/stage1/init.go b/stage1/init/init.go similarity index 100% rename from stage1/init.go rename to stage1/init/init.go diff --git a/stage1/path.go b/stage1/init/path.go similarity index 100% rename from stage1/path.go rename to stage1/init/path.go diff --git a/stage1/mkrootfs.sh b/stage1/mkrootfs.sh deleted file mode 100755 index dbc5c4f..0000000 --- a/stage1/mkrootfs.sh +++ /dev/null @@ -1,507 +0,0 @@ -#!/bin/bash -e - -# Derive a minimal rootfs for hosting systemd from a coreos release pxe image -# This is only done when we need to update ../cmd/s1rootfs.go - -IMG_RELEASE="444.5.0" -IMG_URL="http://stable.release.core-os.net/amd64-usr/${IMG_RELEASE}/coreos_production_pxe_image.cpio.gz" - -function req() { - what=$1 - - which "${what}" >/dev/null || { echo "${what} required"; exit 1; } -} - -req cpio -req curl -req gcc -req go-bindata -req gpg -req gzip -req install -req mktemp -req tar -req unsquashfs - -# coreos gpg signing key -GPG_LONG_ID="50E0885593D2DCB4" -GPG_KEY="-----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2 - -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 -Pg== -=LY4G ------END PGP PUBLIC KEY BLOCK----- -" - -# gpg verify a file using the provided key -function gpg_verify() { - sigfile=$1 #signature file (assumed to be suffixed form of file to verify) - key=$2 #signing key - keyid=$3 #signing key signature - - gpghome=$(mktemp -d) - gpg --homedir="${gpghome}" --batch --quiet --import <<<"${key}" - gpg --homedir="${gpghome}" --batch --trusted-key "${keyid}" --verify "${sigfile}" - RES=$? - - rm -Rf "${gpghome}" - - return ${RES} -} - -# maintain an gpg-verified url cache, assumes signature available @ $url.sig -function cache_url() { - cache=$1 - url=$2 - key=$3 - keyid=$4 - sigfile="${cache}.sig" - sigurl="${url}.sig" - - # ensure the cache directory exists - mkdir -p $(dirname "${cache}") - - # verify the cached copy if it exists - if ! gpg_verify "${sigfile}" "${key}" "${keyid}"; then - - # refresh the cache on failure, and verify it again - curl --location --output "${cache}" "${url}" - curl --location --output "${sigfile}" "${sigurl}" - - gpg_verify "${sigfile}" "${key}" "${keyid}" || return 1 - fi - - # file $cache exists and can be trusted -} - -CACHED_IMG="${PWD}/cache/pxe.img" -WORK="mkroot" -USRFS="usr.squashfs" -ROOTDIR="${WORK}/rootfs" -BINDIR="${WORK}/bins" -USR="rootfs/usr" -FILELIST="filelist.txt" -OUTPUT=${OUTPUT:="../stage0/stage1_rootfs/bin.go"} - -# cache pxe image -cache_url "${CACHED_IMG}" "${IMG_URL}" "${GPG_KEY}" "${GPG_LONG_ID}" - -[ -e "${WORK}" ] && rm -Rf "${WORK}" - -mkdir -p "${ROOTDIR}" - -# derive $USRFS from $CACHED_IMG -pushd "${WORK}" -gzip -cd "${CACHED_IMG}" | cpio --extract "${USRFS}" - -# extra stuff for stage1 which will come/go as things mature (reaper in bash for now) -EXTRAS="bin/bash - lib64/libreadline.so - lib64/libreadline.so.6 - lib64/libreadline.so.6.2 - lib64/libncurses.so - lib64/libncurses.so.5 - lib64/libncurses.so.5.9 - lib64/libdl.so - lib64/libdl.so.2 - lib64/libdl-2.17.so - bin/sleep" - -# systemd and dependencies -cat > "${FILELIST}" <<-EOF - ${EXTRAS} - bin/journalctl - bin/systemctl - bin/systemd-analyze - bin/systemd-ask-password - bin/systemd-cat - bin/systemd-cgls - bin/systemd-cgtop - bin/systemd-coredumpctl - bin/coredumpctl - bin/systemd-delta - bin/systemd-detect-virt - bin/systemd-inhibit - bin/systemd-machine-id-setup - bin/systemd-notify - bin/systemd-nspawn - bin/systemd-path - bin/systemd-run - bin/systemd-stdio-bridge - bin/systemd-sysusers - bin/systemd-tmpfiles - bin/systemd-tty-ask-password-agent - lib - lib64/libattr.so - lib64/libitm.so - lib64/libitm.so.1 - lib64/libitm.so.1.0.0 - lib64/libblkid.so - lib64/libblkid.so.1 - lib64/libblkid.so.1.1.0 - lib64/libuuid.so.1 - lib64/libuuid.so.1.3.0 - lib64/libuuid.so - lib64/libstdc++.so - lib64/libstdc++.so.6 - lib64/libstdc++.so.6.0.17 - lib64/libgcc_s.so - lib64/libgcc_s.so.1 - lib64/librt-2.17.so - lib64/libz.so.1 - lib64/libc.so - lib64/libz.so.1.2.8 - lib64/libattr.so.1.1.0 - lib64/libpthread.so.0 - lib64/libz.so - lib64/libseccomp.so.2.1.1 - lib64/libseccomp.so - lib64/libpthread.so - lib64/libcap.so.2.22 - lib64/libpthread-2.17.so - lib64/libkmod.so.2 - lib64/ld-linux-x86-64.so.2 - lib64/ld-2.17.so - lib64/librt.so.1 - lib64/libkmod.so - lib64/libcap.so - lib64/libc-2.17.so - lib64/librt.so - lib64/libseccomp.so.2 - lib64/libattr.so.1 - lib64/libkmod.so.2.2.5 - lib64/libcap.so.2 - lib64/libc.so.6 - lib64/systemd/systemd-backlight - lib64/systemd/systemd-update-utmp - lib64/systemd/systemd-vconsole-setup - lib64/systemd/systemd-journal-remote - lib64/systemd/systemd-modules-load - lib64/systemd/systemd-resolved - lib64/systemd/systemd-bus-proxyd - lib64/systemd/systemd-ac-power - lib64/systemd/systemd-bootchart - lib64/systemd/systemd-initctl - lib64/systemd/systemd-shutdown - lib64/systemd/systemd-multi-seat-x - lib64/systemd/systemd-rfkill - lib64/systemd/systemd-networkd - lib64/systemd/systemd-activate - lib64/systemd/systemd-readahead - lib64/systemd/systemd-hostnamed - lib64/systemd/systemd-random-seed - lib64/systemd/systemd-cgroups-agent - lib64/systemd/systemd-udevd - lib64/systemd/systemd-shutdownd - lib64/systemd/systemd-logind - lib64/systemd/systemd - lib64/systemd/systemd-update-done - lib64/systemd/systemd-machined - lib64/systemd/systemd-user-sessions - lib64/systemd/systemd-sysctl - lib64/systemd/systemd-journald - lib64/systemd/systemd-timedated - lib64/systemd/systemd-networkd-wait-online - lib64/systemd/systemd-localed - lib64/systemd/systemd-cryptsetup - lib64/systemd/user-generators - lib64/systemd/systemd-remount-fs - lib64/systemd/systemd-coredump - lib64/systemd/systemd-timesyncd - lib64/systemd/systemd-socket-proxyd - lib64/systemd/system-shutdown - lib64/systemd/systemd-binfmt - lib64/systemd/systemd-fsck - lib64/systemd/system-sleep - lib64/systemd/systemd-sleep - lib64/systemd/systemd-reply-password - lib64/systemd/systemd-journal-gatewayd -EOF - -unsquashfs -d "${USR}" -ef "${FILELIST}" "${USRFS}" - -popd - -# populate usr/lib/systemd/system with the necessary static stuff -install -d -m 0755 "${ROOTDIR}/usr/lib/systemd/system" - -function putunit { - path="${ROOTDIR}/usr/lib/systemd/system/$1" - cat > "${path}" -} - -putunit default.target < "${ROOTDIR}/reaper.sh" <<-'EOF' -#!/usr/bin/bash -shopt -s nullglob - -SYSCTL=/usr/bin/systemctl - -cd /opt/stage2 -for app in *; do - status=$(${SYSCTL} show --property ExecMainStatus "${app}.service") - echo "${status#*=}" > "/rkt/status/$app" -done - -${SYSCTL} halt --force -EOF -chmod 755 "${ROOTDIR}/reaper.sh" - -# LD_PRELOAD shim to trick the sd_booted() "/run/systemd/system" check in systemd-nspawn -# XXX abused further for lockfd retention and container pid recording -gcc -shared -fPIC -x c -pipe -Wl,--no-as-needed -ldl -lc -o ${ROOTDIR}/fakesdboot.so - <<'EOF' -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* hack to make systemd-nspawn execute on non-sysd systems: - * - intercept lstat() so lstat of /run/systemd/system always succeeds and returns a directory - * - intercept close() to prevent nspawn closing the rkt lock, set it to CLOEXEC instead - * - intercept syscall(SYS_clone) to record the container's pid - */ - -#define ENV_LOCKFD "RKT_LOCK_FD" -#define PIDFILE_TMP "pid.tmp" -#define PIDFILE "pid" - -static int (*libc_lxstat)(int, const char *, struct stat *); -static int (*libc_close)(int); -static long (*libc_syscall)(long number, ...); -static int lock_fd = -1; - -static __attribute__((constructor)) void wrapper_init(void) -{ - char *env; - if(env = getenv(ENV_LOCKFD)) - lock_fd = atoi(env); - libc_lxstat = dlsym(RTLD_NEXT, "__lxstat"); - libc_close = dlsym(RTLD_NEXT, "close"); - libc_syscall = dlsym(RTLD_NEXT, "syscall"); -} - -int __lxstat(int ver, const char *path, struct stat *stat) -{ - int ret = libc_lxstat(ver, path, stat); - - if(ret == -1 && !strcmp(path, "/run/systemd/system/")) { - stat->st_mode = S_IFDIR; - ret = 0; - } - - return ret; -} - -int close(int fd) -{ - if(lock_fd != -1 && fd == lock_fd) - return fcntl(fd, F_SETFD, FD_CLOEXEC); - - return libc_close(fd); -} - -long syscall(long number, ...) -{ - unsigned long clone_flags; - va_list ap; - long ret; - - /* XXX: we're targeting systemd-nspawn with this shim, its only syscall() use is __NR_clone */ - if(number != __NR_clone) - return -1; - - va_start(ap, number); - clone_flags = va_arg(ap, unsigned long); - va_end(ap); - - ret = libc_syscall(number, clone_flags, NULL); - - if(ret > 0) { - int fd; - /* in parent; try record the container's pid */ - if((fd = open(PIDFILE_TMP, O_CREAT|O_WRONLY|O_SYNC, 0640)) != -1) { - int len; - char buf[20]; - - if((len = snprintf(buf, sizeof(buf), "%li\n", ret)) != -1) - if(write(fd, buf, len) == len) - rename(PIDFILE_TMP, PIDFILE); - - libc_close(fd); - } - } - - return ret; -} -EOF - -install -d "${ROOTDIR}/etc" -echo "rocket" > "${ROOTDIR}/etc/os-release" - -# parent dir for the stage2 bind mounts -install -d "${ROOTDIR}/opt/stage2" - -# dir for result code files -install -d "${ROOTDIR}/rkt/status" - -# fin -mkdir "${BINDIR}" -tar cf "${BINDIR}/s1rootfs.tar" -C "${ROOTDIR}" . -OUTDIR=$(dirname "${OUTPUT}") -[ -d "$OUTDIR" ] || mkdir -p "${OUTDIR}" -go-bindata -o "${OUTPUT}" -prefix "${PWD}/${BINDIR}" -pkg=stage1_rootfs "${BINDIR}" -rm -Rf "${WORK}" diff --git a/stage1/rootfs/Makefile b/stage1/rootfs/Makefile new file mode 100644 index 0000000..5cd4f51 --- /dev/null +++ b/stage1/rootfs/Makefile @@ -0,0 +1,17 @@ +_SUBDIRS=usr shim +SUBDIRS=$(_SUBDIRS) aggregate +export CFLAGS=-Wall -Os + +.PHONY: test clean subdirs $(SUBDIRS) + +subdirs: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) + +clean: $(SUBDIRS) + rm -Rf $(S1) $(S1TAR) + +test: $(SUBDIRS) + +aggregate: $(_SUBDIRS) diff --git a/stage1/rootfs/aggregate/Makefile b/stage1/rootfs/aggregate/Makefile new file mode 100644 index 0000000..23b4a62 --- /dev/null +++ b/stage1/rootfs/aggregate/Makefile @@ -0,0 +1,19 @@ +S1=s1rootfs +S1TAR=$(S1).tar + +../../../stage0/stage1_rootfs/bin.go: $(S1TAR) Makefile + @mkdir -p $$(dirname $@) + TMP=$$(mktemp -d -t stage1-XXXXXX) && \ + ln -s "$(CURDIR)/$(S1TAR)" "$$TMP" && \ + go-bindata -o $@ -prefix="$$TMP" -pkg=stage1_rootfs "$$TMP" && \ + rm -Rf "$$TMP" + +$(S1TAR): aggregate.sh Makefile scripts/* units/* + @./aggregate.sh && tar cf $(S1TAR) -C $(S1) . + +.PHONY: clean +clean: + rm -Rf $(S1) $(S1TAR) + +test: + echo TODO diff --git a/stage1/rootfs/aggregate/aggregate.sh b/stage1/rootfs/aggregate/aggregate.sh new file mode 100755 index 0000000..ef39b29 --- /dev/null +++ b/stage1/rootfs/aggregate/aggregate.sh @@ -0,0 +1,34 @@ +#!/bin/bash -e + +# aggregate everything into a single rootfs tree + +RD=s1rootfs + +# always start over +[ -e "$RD" ] && rm -Rf "$RD" + +# start with the usr/rootfs +cp -a ../usr/rootfs "$RD" + +# populate the systemd units +install -d -m 0755 "$RD/usr/lib/systemd/system" +install -d -m 0755 "$RD/usr/lib/systemd/system/default.target.wants" +install -d -m 0755 "$RD/usr/lib/systemd/system/sockets.target.wants" +install -m 0644 units/default.target "$RD/usr/lib/systemd/system" +install -m 0644 units/exit-watcher.service "$RD/usr/lib/systemd/system" +install -m 0644 units/local-fs.target "$RD/usr/lib/systemd/system" +install -m 0644 units/reaper.service "$RD/usr/lib/systemd/system" +install -m 0644 units/sockets.target "$RD/usr/lib/systemd/system" +install -m 0755 scripts/reaper.sh "$RD" +install -m 0755 ../shim/shim.so "$RD" +ln -s shim.so "$RD/fakesdboot.so" + +install -d "$RD/etc" +echo "rocket" > "$RD/etc/os-release" + +# parent dir for the stage2 bind mounts +install -d "$RD/opt/stage2" + +# dir for result code files +install -d "$RD/rkt/status" + diff --git a/stage1/rootfs/aggregate/scripts/reaper.sh b/stage1/rootfs/aggregate/scripts/reaper.sh new file mode 100644 index 0000000..a83aed1 --- /dev/null +++ b/stage1/rootfs/aggregate/scripts/reaper.sh @@ -0,0 +1,12 @@ +#!/usr/bin/bash +shopt -s nullglob + +SYSCTL=/usr/bin/systemctl + +cd /opt/stage2 +for app in *; do + status=$(${SYSCTL} show --property ExecMainStatus "${app}.service") + echo "${status#*=}" > "/rkt/status/$app" +done + +${SYSCTL} halt --force diff --git a/stage1/rootfs/aggregate/units/default.target b/stage1/rootfs/aggregate/units/default.target new file mode 100644 index 0000000..6fe7fd4 --- /dev/null +++ b/stage1/rootfs/aggregate/units/default.target @@ -0,0 +1,3 @@ +[Unit] +Description=Rocket apps target +DefaultDependencies=false diff --git a/stage1/rootfs/aggregate/units/exit-watcher.service b/stage1/rootfs/aggregate/units/exit-watcher.service new file mode 100644 index 0000000..81950d7 --- /dev/null +++ b/stage1/rootfs/aggregate/units/exit-watcher.service @@ -0,0 +1,8 @@ +[Unit] +Description=Graceful exit watcher +StopWhenUnneeded=true +DefaultDependencies=false + +[Service] +ExecStart=/usr/bin/sleep 9999999999d +ExecStopPost=/usr/bin/systemctl isolate reaper.service diff --git a/stage1/rootfs/aggregate/units/local-fs.target b/stage1/rootfs/aggregate/units/local-fs.target new file mode 100644 index 0000000..01943e6 --- /dev/null +++ b/stage1/rootfs/aggregate/units/local-fs.target @@ -0,0 +1,4 @@ +[Unit] +Description=Hook into early systemd for socket-activated systemd instances +DefaultDependencies=false +Requires=sockets.target diff --git a/stage1/rootfs/aggregate/units/reaper.service b/stage1/rootfs/aggregate/units/reaper.service new file mode 100644 index 0000000..1cbd43d --- /dev/null +++ b/stage1/rootfs/aggregate/units/reaper.service @@ -0,0 +1,7 @@ +[Unit] +Description=Rocket apps reaper +AllowIsolate=true +DefaultDependencies=false + +[Service] +ExecStart=/reaper.sh diff --git a/stage1/rootfs/aggregate/units/sockets.target b/stage1/rootfs/aggregate/units/sockets.target new file mode 100644 index 0000000..4d70f42 --- /dev/null +++ b/stage1/rootfs/aggregate/units/sockets.target @@ -0,0 +1,3 @@ +[Unit] +Description=Sockets +DefaultDependencies=false diff --git a/stage1/rootfs/shim/Makefile b/stage1/rootfs/shim/Makefile new file mode 100644 index 0000000..f7636f1 --- /dev/null +++ b/stage1/rootfs/shim/Makefile @@ -0,0 +1,12 @@ +BIN=shim.so +SRC=shim.c + +$(BIN): $(SRC) Makefile + $(CC) $(CFLAGS) $(SRC) -o $(BIN) -shared -fPIC -Wl,--no-as-needed -ldl -lc + +.PHONY: clean +clean: + rm -f $(BIN) + +test: + echo TODO diff --git a/stage1/rootfs/shim/shim.c b/stage1/rootfs/shim/shim.c new file mode 100644 index 0000000..0e2bf76 --- /dev/null +++ b/stage1/rootfs/shim/shim.c @@ -0,0 +1,91 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* hack to make systemd-nspawn execute on non-sysd systems: + * - intercept lstat() so lstat of /run/systemd/system always succeeds and returns a directory + * - intercept close() to prevent nspawn closing the rkt lock, set it to CLOEXEC instead + * - intercept syscall(SYS_clone) to record the container's pid + */ + +#define ENV_LOCKFD "RKT_LOCK_FD" +#define PIDFILE_TMP "pid.tmp" +#define PIDFILE "pid" + +static int (*libc_lxstat)(int, const char *, struct stat *); +static int (*libc_close)(int); +static long (*libc_syscall)(long number, ...); +static int lock_fd = -1; + +static __attribute__((constructor)) void wrapper_init(void) +{ + char *env; + if(env = getenv(ENV_LOCKFD)) + lock_fd = atoi(env); + libc_lxstat = dlsym(RTLD_NEXT, "__lxstat"); + libc_close = dlsym(RTLD_NEXT, "close"); + libc_syscall = dlsym(RTLD_NEXT, "syscall"); +} + +int __lxstat(int ver, const char *path, struct stat *stat) +{ + int ret = libc_lxstat(ver, path, stat); + + if(ret == -1 && !strcmp(path, "/run/systemd/system/")) { + stat->st_mode = S_IFDIR; + ret = 0; + } + + return ret; +} + +int close(int fd) +{ + if(lock_fd != -1 && fd == lock_fd) + return fcntl(fd, F_SETFD, FD_CLOEXEC); + + return libc_close(fd); +} + +long syscall(long number, ...) +{ + unsigned long clone_flags; + va_list ap; + long ret; + + /* XXX: we're targeting systemd-nspawn with this shim, its only syscall() use is __NR_clone */ + if(number != __NR_clone) + return -1; + + va_start(ap, number); + clone_flags = va_arg(ap, unsigned long); + va_end(ap); + + ret = libc_syscall(number, clone_flags, NULL); + + if(ret > 0) { + int fd; + /* in parent; try record the container's pid */ + if((fd = open(PIDFILE_TMP, O_CREAT|O_WRONLY|O_SYNC, 0640)) != -1) { + int len; + char buf[20]; + + if((len = snprintf(buf, sizeof(buf), "%li\n", ret)) != -1) + if(write(fd, buf, len) == len) + rename(PIDFILE_TMP, PIDFILE); + + libc_close(fd); + } + } + + return ret; +} diff --git a/stage1/rootfs/usr/Makefile b/stage1/rootfs/usr/Makefile new file mode 100644 index 0000000..6d9a302 --- /dev/null +++ b/stage1/rootfs/usr/Makefile @@ -0,0 +1,16 @@ +# base just derives a base root fs from a CoreOS image downloaded and verified + + +usr.done: mkbase.sh cache/pxe.img + ./mkbase.sh && touch usr.done + +cache/pxe.img: cache.sh + ./cache.sh + +.PHONY: clean +clean: + rm -Rf rootfs usr.squashfs usr.done manifest.txt + +# TODO cleaner target for clearing cache? +test: + echo TODO diff --git a/stage1/rootfs/usr/cache.sh b/stage1/rootfs/usr/cache.sh new file mode 100755 index 0000000..9f753bf --- /dev/null +++ b/stage1/rootfs/usr/cache.sh @@ -0,0 +1,184 @@ +#!/bin/bash -e + +# maintain a cached copy of coreos pxe image + +IMG_RELEASE="444.5.0" +IMG_URL="http://stable.release.core-os.net/amd64-usr/${IMG_RELEASE}/coreos_production_pxe_image.cpio.gz" + +function req() { + what=$1 + + which "${what}" >/dev/null || { echo "${what} required"; exit 1; } +} + +req curl +req gpg +req mktemp +req md5sum + +# coreos gpg signing key +GPG_LONG_ID="50E0885593D2DCB4" +GPG_KEY="-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +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 +Pg== +=LY4G +-----END PGP PUBLIC KEY BLOCK----- +" + +# gpg verify a file using the provided key +function gpg_verify() { + file=$1 + sigfile=$2 #signature file (assumed to be suffixed form of file to verify) + key=$3 #signing key + keyid=$4 #signing key signature + + gpghome=$(mktemp -d) + gpg --homedir="${gpghome}" --batch --quiet --import <<<"${key}" + gpg --homedir="${gpghome}" --batch --trusted-key "${keyid}" --verify "${sigfile}" "${cache}" + RES=$? + + rm -Rf "${gpghome}" + + return ${RES} +} + +# maintain an gpg-verified url cache, assumes signature available @ $url.sig +function cache_url() { + cache=$1 + url=$2 + key=$3 + keyid=$4 + + urlhash=$(echo -n "${url}" | md5sum) + sigfile="${cache}.${urlhash%% *}.sig" + sigurl="${url}.sig" + + # ensure the cache directory exists + mkdir -p $(dirname "${cache}") + + # verify the cached copy if it exists + if ! gpg_verify "${cache}" "${sigfile}" "${key}" "${keyid}"; then + + # refresh the cache on failure, and verify it again + curl --location --output "${cache}" "${url}" + curl --location --output "${sigfile}" "${sigurl}" + + gpg_verify "${cache}" "${sigfile}" "${key}" "${keyid}" || return 1 + fi + + # file $cache exists and can be trusted + touch ${cache} +} + +CACHED_IMG="cache/pxe.img" +USRFS="usr.squashfs" +ROOTDIR="rootfs" +USR="rootfs/usr" +FILELIST="manifest.txt" + +# cache pxe image +cache_url "${CACHED_IMG}" "${IMG_URL}" "${GPG_KEY}" "${GPG_LONG_ID}" diff --git a/stage1/rootfs/usr/manifest.d/bash b/stage1/rootfs/usr/manifest.d/bash new file mode 100644 index 0000000..14ce235 --- /dev/null +++ b/stage1/rootfs/usr/manifest.d/bash @@ -0,0 +1,14 @@ +bin/bash +lib64/ld-2.17.so +lib64/ld-linux-x86-64.so.2 +lib64/libc-2.17.so +lib64/libc.so.6 +lib64/libdl-2.17.so +lib64/libdl.so +lib64/libdl.so.2 +lib64/libncurses.so +lib64/libncurses.so.5 +lib64/libncurses.so.5.9 +lib64/libreadline.so +lib64/libreadline.so.6 +lib64/libreadline.so.6.2 diff --git a/stage1/rootfs/usr/manifest.d/sleep b/stage1/rootfs/usr/manifest.d/sleep new file mode 100644 index 0000000..835caa0 --- /dev/null +++ b/stage1/rootfs/usr/manifest.d/sleep @@ -0,0 +1,5 @@ +bin/sleep +lib64/ld-2.17.so +lib64/ld-linux-x86-64.so.2 +lib64/libc-2.17.so +lib64/libc.so.6 diff --git a/stage1/rootfs/usr/manifest.d/systemd b/stage1/rootfs/usr/manifest.d/systemd new file mode 100644 index 0000000..6304d10 --- /dev/null +++ b/stage1/rootfs/usr/manifest.d/systemd @@ -0,0 +1,105 @@ +bin/coredumpctl +bin/journalctl +bin/systemctl +bin/systemd-analyze +bin/systemd-ask-password +bin/systemd-cat +bin/systemd-cgls +bin/systemd-cgtop +bin/systemd-coredumpctl +bin/systemd-delta +bin/systemd-detect-virt +bin/systemd-inhibit +bin/systemd-machine-id-setup +bin/systemd-notify +bin/systemd-nspawn +bin/systemd-path +bin/systemd-run +bin/systemd-stdio-bridge +bin/systemd-sysusers +bin/systemd-tmpfiles +bin/systemd-tty-ask-password-agent +lib +lib64/ld-2.17.so +lib64/ld-linux-x86-64.so.2 +lib64/libattr.so +lib64/libattr.so.1 +lib64/libattr.so.1.1.0 +lib64/libblkid.so +lib64/libblkid.so.1 +lib64/libblkid.so.1.1.0 +lib64/libc-2.17.so +lib64/libcap.so +lib64/libcap.so.2 +lib64/libcap.so.2.22 +lib64/libc.so.6 +lib64/libgcc_s.so +lib64/libgcc_s.so.1 +lib64/libitm.so +lib64/libitm.so.1 +lib64/libitm.so.1.0.0 +lib64/libkmod.so +lib64/libkmod.so.2 +lib64/libkmod.so.2.2.5 +lib64/libpthread-2.17.so +lib64/libpthread.so +lib64/libpthread.so.0 +lib64/librt-2.17.so +lib64/librt.so +lib64/librt.so.1 +lib64/libseccomp.so +lib64/libseccomp.so.2 +lib64/libseccomp.so.2.1.1 +lib64/libstdc++.so +lib64/libstdc++.so.6 +lib64/libstdc++.so.6.0.17 +lib64/libuuid.so +lib64/libuuid.so.1 +lib64/libuuid.so.1.3.0 +lib64/libz.so +lib64/libz.so.1 +lib64/libz.so.1.2.8 +lib64/systemd/systemd +lib64/systemd/systemd-ac-power +lib64/systemd/systemd-activate +lib64/systemd/systemd-backlight +lib64/systemd/systemd-binfmt +lib64/systemd/systemd-bootchart +lib64/systemd/systemd-bus-proxyd +lib64/systemd/systemd-cgroups-agent +lib64/systemd/systemd-coredump +lib64/systemd/systemd-cryptsetup +lib64/systemd/systemd-fsck +lib64/systemd/systemd-hostnamed +lib64/systemd/systemd-initctl +lib64/systemd/systemd-journald +lib64/systemd/systemd-journal-gatewayd +lib64/systemd/systemd-journal-remote +lib64/systemd/systemd-localed +lib64/systemd/systemd-logind +lib64/systemd/systemd-machined +lib64/systemd/systemd-modules-load +lib64/systemd/systemd-multi-seat-x +lib64/systemd/systemd-networkd +lib64/systemd/systemd-networkd-wait-online +lib64/systemd/systemd-random-seed +lib64/systemd/systemd-readahead +lib64/systemd/systemd-remount-fs +lib64/systemd/systemd-reply-password +lib64/systemd/systemd-resolved +lib64/systemd/systemd-rfkill +lib64/systemd/systemd-shutdown +lib64/systemd/systemd-shutdownd +lib64/systemd/systemd-sleep +lib64/systemd/systemd-socket-proxyd +lib64/systemd/systemd-sysctl +lib64/systemd/systemd-timedated +lib64/systemd/systemd-timesyncd +lib64/systemd/systemd-udevd +lib64/systemd/systemd-update-done +lib64/systemd/systemd-update-utmp +lib64/systemd/systemd-user-sessions +lib64/systemd/systemd-vconsole-setup +lib64/systemd/system-shutdown +lib64/systemd/system-sleep +lib64/systemd/user-generators diff --git a/stage1/rootfs/usr/mkbase.sh b/stage1/rootfs/usr/mkbase.sh new file mode 100755 index 0000000..8921413 --- /dev/null +++ b/stage1/rootfs/usr/mkbase.sh @@ -0,0 +1,36 @@ +#!/bin/bash -e + +# Derive a minimal base tree for hosting systemd from a cached coreos release pxe image + +shopt -s nullglob + +function req() { + what=$1 + + which "${what}" >/dev/null || { echo "${what} required"; exit 1; } +} + +req cpio +req gzip +req unsquashfs +req sort + +CACHED_IMG="cache/pxe.img" +SQUASH="usr.squashfs" +ROOTFS="rootfs" +USR="rootfs/usr" +FILELIST="manifest.txt" + +# always start with an empty rootfs +[ -e "${ROOTFS}" ] && rm -Rf "${ROOTFS}" + +mkdir -p "${ROOTFS}" + +# create consolidated file list +cat manifest.d/* | sort -u > "${FILELIST}" + +# derive $SQUASH from $CACHED_IMG +gzip -cd "${CACHED_IMG}" | cpio --unconditional --extract "${SQUASH}" +unsquashfs -d "${USR}" -ef "${FILELIST}" "${SQUASH}" + +# just leave the desired tree @ ${ROOTFS}