diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1886e85 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +pladde.img +initrd.gz +vmlinuz diff --git a/.gitignore b/.gitignore index 545b0c9..63d55c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ ansible/**/*.retry -build bin +build +initrd.gz +pladde.img +vmlinuz diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8beb388 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM debian:stretch + +RUN apt-get update \ + && apt-get -y install \ + initramfs-tools \ + linux-image-amd64 \ + aria2 \ + xxd + +COPY imagesync.sh /etc/initramfs-tools/scripts/local-premount/ + +RUN echo 'RESUME=none' > /etc/initramfs-tools/conf.d/resume \ + && mkinitramfs -o /tmp/initrd.gz $(find /boot -name 'vmlinuz-*' -printf '%f\n' | sed 's/^vmlinuz-//') diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..feef0a4 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +docker build -t initramfs:debian . +docker run --rm -v "$PWD:/artifacts" initramfs:debian sh -c 'cp /boot/vmlinuz-* /artifacts/vmlinuz && cp /tmp/initrd.gz /artifacts' diff --git a/imagesync.sh b/imagesync.sh new file mode 100755 index 0000000..52de3bd --- /dev/null +++ b/imagesync.sh @@ -0,0 +1,227 @@ +#!/bin/sh + +case $1 in +prereqs) + ## + # GET EXECUTED WHEN BUILDING INITRAMFS + # + . /usr/share/initramfs-tools/hook-functions + copy_exec /usr/bin/aria2c + copy_exec /sbin/sfdisk + copy_exec /sbin/mke2fs + copy_exec /sbin/e2fsck + copy_file cert /etc/ssl/certs/ca-certificates.crt + exit 0 + ;; +esac + +## +# FUNCTION DEFINITIONS +## + +print_waiting() { + echo -en "\033[36m${1}... \033[0m" +} + +print_warning() { + echo -e "\n\033[31mWARNING: ${1}\033[0m" +} + +print_done() { + echo -e "\033[32mdone.\033[0m" +} + +error_fatal() { + print_warning "$1; interrupting startup" + while sleep 3600;do sleep 3600;done +} + +## +# SHOW BRANDING +## + +echo -e ' +Starting + ""# # + # mmm #mmm mmm m m m mm mmm + # " # #" "# # " "m m" #" # #" " + # m"""# # # """m #m# # # # + "mm "mm"# ##m#" "mmm" "# # # "#mm" + m" + "" +https://gitlab.jalr.de/fablab/initramfs +' + +## +# READ CONFIGURATION PARAMETERS FROM KERNEL PARAMETERS +## + +print_waiting "Reading configuration parameters" +set -- $(cat /proc/cmdline) +for x in "$@"; do + case "$(echo $x | cut -d= -f1)" in + disk) + disk="$(echo $x | cut -d= -f2)" + ;; + root) + root="$(echo $x | cut -d= -f2)" + ;; + partsize) + partsize="$(echo $x | cut -d= -f2)" + ;; + torrent) + torrent="$(echo $x | cut -d= -f2)" + ;; + qemu) + qemu="$(echo $x | cut -d= -f2)" + ;; + esac +done + +# Check if mandatory parameters are missing + +if [ -z "$disk" ];then + error_fatal "The disk parameter is missing" +fi +if [ -z "$root" ];then + error_fatal "The root parameter is missing" +fi +if [ -z "$partsize" ];then + error_fatal "The partsize parameter is missing" +fi +if [ -z "$torrent" ];then + error_fatal "The torrent parameter is missing" +fi +print_done + +## +# PARTITIONING OF DISK +## + +size_part_1=$(($partsize * 1024 * 1024 / 512)) + +parttable="label: dos +label-id: 0xdeadbeef +device: $disk +unit: sectors + +$root : start= 2048, size= $size_part_1, type=83" + +readtable="$(sfdisk -d $disk)" # wtf? but it is needed + +print_waiting "Checking partition tables" +if [ "$parttable" != "$readtable" ];then + print_done + print_waiting "Partition tables do not match; partitioning disk" + rewrite_rootfs=true +sfdisk -q $disk << PARTTABLE +$parttable +PARTTABLE + print_done +else + print_done +fi + +print_waiting "Checking root filesystem" +e2fsck -y $root &> /dev/null +fsck=$? +if [ "$fsck" != 0 ] && [ "$fsck" != 1 ] || [ "$rewrite_rootfs" == "true" ];then + print_done + print_waiting "Creating root filesystem" + mke2fs -q -F -t ext4 $root + print_done +else + print_done +fi + +## +# TEMPORARY NETWORK CONFIG (only for qemu) +## + +if ! [ -z "$qemu" ];then + print_waiting "Setting up temporary network config" + ip addr add 10.2.2.2/24 dev ens3 + ip link set ens3 up + print_done +else + print_waiting "Setting up interfaces with DHCP" + ipconfig all + print_done +fi + +## +# MOUNT TEMPORARY ROOTFS +## + +print_waiting "Mounting temporary root filesystem" +mkdir -p /tmp_root +mount -t ext4 $root /tmp_root +cd /tmp_root +print_done + +## +# DOWNLOAD FS IMAGE +## + +print_waiting "Downloading root filesystem image" +# --allow-overwrite: do not rename the torrent file +# --check-integrity: verify downloaded file and do not complain about missing controll file +# --seed-time=0: do not wait until ratio 1, we seed when we’re booted +# --summary-interval=0: do not show summary while downloading +# --console-log-level=error: Only show errors +# --download-result=hide: Do not show download results +download=true +while [ "$download" == true ];do + aria2c \ + --allow-overwrite \ + --check-integrity \ + --seed-time=0 \ + --summary-interval=0 \ + --console-log-level=error \ + --download-result=hide \ + $torrent 2>&1 | grep -v 'DHT routing table' + if [ $? == 0 ];then + download=false + else + rm rootfs.tar.gz rootfs.torrent + fi +done +print_done + +print_waiting "Comparing installed and remote image" +if [ -f /tmp_root/.build_uuid ];then + cd /tmp + tar xzf /tmp_root/rootfs.tar.gz .build_uuid + if [ "$(cat .build_uuid)" == "$(cat /tmp_root/.build_uuid)" ];then + sync=false + print_done + else + sync=true + print_done + print_waiting "Deleting old filesystem" + cd /tmp_root + rm -rf $(tar tzf rootfs.tar.gz|grep '^[^/]*/$' ) + cd /tmp + print_done + fi + rm .build_uuid + cd /tmp_root +else + sync=true + print_done +fi + +if [ "$sync" == "true" ];then + print_waiting "Extracting root filesystem image" + tar xzf rootfs.tar.gz + print_done +fi + +## +# UNMOUNT TEMPORARY ROOTFS +## + +print_waiting "Unmounting temporary root filesystem" +cd / +umount /tmp_root +print_done diff --git a/qemu.sh b/qemu.sh new file mode 100755 index 0000000..53b7030 --- /dev/null +++ b/qemu.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +ifname_tap=taptstsync +ifname_br=brtstsync + +[ -e pladde.img ] || qemu-img create pladde.img 4G + +sudo ip tuntap add dev $ifname_tap mode tap user $USER +sudo brctl addbr $ifname_br +sudo brctl addif $ifname_br $ifname_tap +sudo ip addr add 10.2.2.1/24 dev brtstsync +sudo ip link set taptstsync up +sudo ip link set brtstsync up + +qemu-system-x86_64 \ + -kernel vmlinuz \ + -initrd initrd.gz \ + -drive format=raw,file=pladde.img \ + -append "disk=/dev/sda root=/dev/sda1 partsize=3072 torrent=http://10.2.2.1:8081/rootfs.torrent qemu quiet" \ + -curses \ + -enable-kvm \ + -m 1G \ + -net nic \ + -net tap,ifname=$ifname_tap,script=no,downscript=no