Last active
November 15, 2017 21:29
-
-
Save pottedplant/2afff9442de1caeb0f2ae2aa495dd04a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# static apk: tar xf apk-tools-static-*.apk # http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/x86_64/ | |
# setup alpine folder: apk.static -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main -U --allow-untrusted --root root --initdb add alpine-base util-linux btrfs-progs bash | |
# remove all tty\d+ consoles from /etc/inittab (inits will conflict otherwise) | |
# mk initramfs: (cd root && find . -print0 | cpio --null -ov --format=newc | xz --check=crc32 ) > ./initramfs | |
# append kernel modules: (cd / && find "./lib/modules/${KERNEL}" -print0 | cpio --null -ov --format=newc | xz --check=crc32 ) >> ./initramfs | |
function step() { | |
echo "step: $*" | |
} | |
function panic() { | |
echo "PANIC: $*" | |
sleep 5 | |
echo b >/proc/sysrq-trigger | |
exit -1 | |
} | |
# prepare /next | |
step "prepare next directory" | |
test -e /next || mkdir /next || panic "unable to create /next" | |
mount --bind /next /next || panic "unable to bind mount /next" | |
mount --make-shared /next || panic "unable to make mount /next shared" | |
# spawn alpine init | |
step "spawn alpine init in new namespace" | |
unshare --mount --propagation unchanged --uts --cgroup --ipc --pid --fork /sbin/init & | |
# wait for switch signal | |
while [ ! -e /next/do_switch ]; do | |
sleep 1 | |
kill -0 %1 || panic "alpine init vanished" | |
done | |
echo "/next/do_switch found" | |
# kill everything | |
step "terminating all processes" | |
kill -s KILL -- -1 | |
step "waiting for alpine to die" | |
wait | |
# custom init | |
step "custom init?" | |
test -e /next/init && exec /next/init | |
# temp proc, sys | |
step "temporarily mounting proc and sys" | |
mount -t proc proc /proc || panic "unable to mount /proc" | |
mount -t sysfs none /sys || panic "unable to mount /sys" | |
# flush net | |
step "flushing network devices" | |
for i in /sys/class/net/*; do | |
i=`basename $i` | |
ip address flush $i | |
ip route flush dev $i | |
done | |
# move root | |
step "moving /next/root to /newroot" | |
test ! -e /newroot && mkdir /newroot || panic "unable to create /newroot" | |
mount --rbind /next/root /newroot || panic "rbind mount failed" | |
mount --make-private /newroot || panic "unable to make newroot mount private" | |
umount -R /next/root || panic "unable to umount /next/root" | |
# cleanup | |
echo "cleanup: unmounting sys, proc" | |
umount -R /sys || panic "unable to umount /sys" | |
umount -R /proc || panic "unable to umount /proc" | |
# switch root | |
step "switching root" | |
exec busybox switch_root /newroot /sbin/init | |
panic "unable to call switch_root" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment