aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbootstrap42
-rwxr-xr-xbuildos76
-rw-r--r--buildos.service22
-rwxr-xr-xinit2
4 files changed, 129 insertions, 13 deletions
diff --git a/bootstrap b/bootstrap
index d2c2be0..16b42b5 100755
--- a/bootstrap
+++ b/bootstrap
@@ -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"
diff --git a/buildos b/buildos
new file mode 100755
index 0000000..fd0f8c2
--- /dev/null
+++ b/buildos
@@ -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
diff --git a/init b/init
index 80bab77..7b869cb 100755
--- a/init
+++ b/init
@@ -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" |