diff options
-rwxr-xr-x | bootstrap | 42 | ||||
-rwxr-xr-x | buildos | 76 | ||||
-rw-r--r-- | buildos.service | 22 | ||||
-rwxr-xr-x | init | 2 |
4 files changed, 129 insertions, 13 deletions
@@ -140,7 +140,7 @@ if [ "$stage" -eq "1" ]; then # # - systemd-container seems to be required by host systemd-nspawn. # - pkgs="locales,klibc-utils,systemd-container" + pkgs="locales,klibc-utils,sudo,systemd-container" pkgs+=",linux-image-amd64,irqbalance,pciutils" @@ -281,6 +281,12 @@ trap "exit 1" ERR set -x +# Create the build user, /build home directory. Make a password-less sudo'er. +# +adduser --home /build --gecos "" --disabled-password build +echo "build ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/build +chmod 0440 /etc/sudoers.d/build + # Clean up package cache. # apt-get clean @@ -301,9 +307,9 @@ EOF # Note that when started via systemd-nspawn, we get /dev/console, not # /dev/tty0. # - write <<EOF /usr/lib/systemd/system/setup.service + write <<EOF /usr/lib/systemd/system/buildos-setup.service [Unit] -Description=Setup Service +Description=Build OS Setup After=default.target Conflicts=console-getty.service @@ -324,8 +330,8 @@ WantedBy=default.target EOF sudo mkdir -p "$root/usr/lib/systemd/system/default.target.wants" - sudo ln -sf "$root/usr/lib/systemd/system/setup.service" \ - "$root/usr/lib/systemd/system/default.target.wants/setup.service" + sudo ln -sf "$root/usr/lib/systemd/system/buildos-setup.service" \ + "$root/usr/lib/systemd/system/default.target.wants/buildos-setup.service" nspawn --boot @@ -342,16 +348,15 @@ if [ "$stage" -le "4" ]; then # Quite a few files/directories are only accessible by root (e.g., /root) so # we run under sudo. # - cd "$root" - root_dirs="dev etc mnt root usr var" root_links="bin sbin lib lib32 lib64" info "generating buildos-rootfs.cpio.gz..." + + cd "$root" sudo find $root_dirs $root_links -print0 | \ sudo cpio --null -o -H newc | \ gzip -9 > "$owd/buildos-rootfs.cpio.gz" - cd "$owd" subvol_snapshot -r "$root" "$root-4" @@ -361,14 +366,25 @@ fi # if [ "$stage" -le "5" ]; then - # @@ TODO: init location + # Install init and buildos monitor. # - sudo cp -f ./init "$root/" + sudo install -m 755 ./init "$root/" + sudo install -m 755 ./buildos "$root/usr/sbin/" + sudo install -m 755 ./buildos.service "$root/usr/lib/systemd/system/" + sudo ln -sf "$root/usr/lib/systemd/system/buildos.service" \ + "$root/usr/lib/systemd/system/default.target.wants/buildos.service" info "generating buildos-init.cpio.gz..." - sudo echo 'init' | \ - sudo cpio -o -H newc | \ + + cd "$root" + sudo cpio -o -H newc <<EOF | \ gzip -9 > "$owd/buildos-init.cpio.gz" +init +usr/sbin/buildos +usr/lib/systemd/system/buildos.service +usr/lib/systemd/system/default.target.wants/buildos.service +EOF + cd "$owd" cat buildos-rootfs.cpio.gz buildos-init.cpio.gz >buildos-initrd @@ -396,4 +412,4 @@ sudo kvm \ -device "scsi-hd,drive=disk1" \ -drive "if=none,id=disk1,file=/tmp/buildos-disk,format=raw" \ -kernel buildos-image -initrd buildos-initrd \ - -append "buildos.smtp_relay=build2.org buildos.admin_email=admin@build.org" + -append "buildos.smtp_relay=build2.org buildos.admin_email=admin@build2.org" @@ -0,0 +1,76 @@ +#!/bin/bash + +# Build OS monitor. It starts as a systemd service and performs the following +# steps: +# +# 1. Bootstrap the build2 toolchain. +# 2. Build and start bbot. +# 3. Build and start bslave. +# 4. Monitor for OS and toolchain changes and reboot if detected. +# + +# @@ What do we do in case or error, trap? Send email? Reboot? Probably +# reboot bad idea since someone may need to login to examine what's +# going on. +# +# @@ What will systemd do if we fail? Perhaps configure it to restart +# us? Or not since we may hose the logs. +# +trap "exit 1" ERR +set -o errtrace # Trap in functions. + +# Note: diagnostics goes to stdout. +# +function info () { echo "$*" 1>&2; } +function error () +{ + if [ "$#" -gt 0 ]; then + info "$*"; + fi + + exit 1 +} + +info "starting buildos monitor..." + +# Parse the kernel command line. This is complicated by the fact that the +# values can be quoted, for example: +# +# foo='foo fox' +# bar="bar 'box'" +# +# First we separete quoted variables and arguments with newlines (giving +# priority to assignments). Then we replace whitespaces with newline on +# lines that don't contain quites. Finally, clean up by removing blank +# lines. +# +# Note: the same code as in init. +# +readarray -t cmdline < <(cat /proc/cmdline | \ + sed -r -e "s/([^ ]+=)?('[^']*'|\"[^\"]*\")/\n\1\2\n/g" | \ + sed -r -e "/['\"]/!s/ /\n/g" | + sed -r -e '/^\s*$/d') + +# Enter all buildos variables as bash variables. +# +for v in "${cmdline[@]}"; do + var="$(sed -r -n -e 's/^buildos\.([^=]+)=.*$/\1/p' <<<"$v")" # Extract name. + + if [ -n "$var" ]; then + val="$(sed -r -e 's/^[^=]+=(.*)$/\1/' <<<"$v")" # Extract value. + val="$(sed -r -e "s/^('(.*)'|\"(.*)\")$/\2\3/" <<<"$val")" # Strip quoted. + declare "$var=$val" + fi +done + +function email () # <subject> < <body> +{ + (echo -e "Subject: $1\n"; cat -) | sendmail -i "$admin_email" +} + +email "starting buildos monitor on $(hostname)" <<<"" + +while true; do + info "monitoring..." + sleep 2 +done diff --git a/buildos.service b/buildos.service new file mode 100644 index 0000000..b1aedf1 --- /dev/null +++ b/buildos.service @@ -0,0 +1,22 @@ +[Unit] +Description=Build OS Monitor +After=default.target +Conflicts=getty@tty1.service + +[Service] +Type=idle +TimeoutStartSec=infinity +RemainAfterExit=true +ExecStart=/usr/sbin/buildos +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +TTYPath=/dev/tty1 +TTYReset=yes +TTYVHangup=yes +User=build +Group=build +WorkingDirectory=~ + +[Install] +WantedBy=default.target @@ -77,6 +77,8 @@ udevadm settle || true # lines that don't contain quites. Finally, clean up by removing blank # lines. # +# Note: the same code as in buildos. +# readarray -t cmdline < <(cat /proc/cmdline | \ sed -r -e "s/([^ ]+=)?('[^']*'|\"[^\"]*\")/\n\1\2\n/g" | \ sed -r -e "/['\"]/!s/ /\n/g" | |