From f759784652ff8495f396e140b8238cedb8c8a696 Mon Sep 17 00:00:00 2001 From: jalr Date: Thu, 1 Mar 2018 19:49:58 +0100 Subject: [PATCH 1/4] Add lvm --- packer/debian-stretch.json | 8 +- packer/initramfs/labsync | 273 +++++++++++++++++++------------------ 2 files changed, 144 insertions(+), 137 deletions(-) diff --git a/packer/debian-stretch.json b/packer/debian-stretch.json index 392c70a..298fcff 100644 --- a/packer/debian-stretch.json +++ b/packer/debian-stretch.json @@ -29,6 +29,12 @@ "source": "initramfs/labsync", "destination": "/etc/initramfs-tools/scripts/" }, + { + "type": "shell", + "inline": [ + "sed -i 's/@@CI_REPOSITORY_URL@@/{{user `ci_repository_url`}}/' /etc/initramfs-tools/scripts/labsync" + ] + }, { "type": "file", "source": "initramfs/labsync-prereqs", @@ -44,7 +50,7 @@ "echo \"commit ref slug: {{user `ci_commit_ref_slug`}}\" >> /.build-info", "apt-get update", "apt-get -y dist-upgrade", - "apt-get -y install aria2 initramfs-tools linux-image-amd64 openssh-server python", + "apt-get -y install aria2 initramfs-tools linux-image-amd64 lvm2 openssh-server python", "echo 'RESUME=none' > /etc/initramfs-tools/conf.d/resume", "echo squashfs >> /etc/initramfs-tools/modules", "echo overlay >> /etc/initramfs-tools/modules", diff --git a/packer/initramfs/labsync b/packer/initramfs/labsync index bad7984..6c1787e 100755 --- a/packer/initramfs/labsync +++ b/packer/initramfs/labsync @@ -1,152 +1,153 @@ #!/bin/sh -labsync_mount_root() { - ## - # FUNCTION DEFINITIONS - ## +labsync_create_or_resize_lv() { + vg="$1" + lv="$2" + new_size_bytes="$3" + minimum_size_bytes="$4" + current_lv_size_bytes="$(lvm lvs "$vg/$lv" -o LV_SIZE --noheadings --units b --nosuffix 2>/dev/null | sed 's/\s//g')" - 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 - ' - - # Check if mandatory parameters are missing - - if [ -z "$disk" ];then - error_fatal "The disk parameter is missing" + if [ -z "$current_lv_size_bytes" ]; then + # no size returned, it's likely that lv doesn't exist + lvm lvcreate -L ${new_size_bytes}b -n "$lv" "$vg" + elif [ "$minimum_size_bytes" != "" ] && [ $minimum_size_bytes -gt 0 ]; then + # lv already exists + if [ $current_lv_size_bytes -lt $minimum_size_bytes ]; then + lvm lvextend -L ${new_size_bytes}b "$vg/$lv" + fi 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 - if [ -z "$torrent_file" ];then - error_fatal "The torrent_file 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 - - ## - # TEMPORARY NETWORK CONFIG (only for qemu) - ## - - configure_networking - - #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 - - ## - # DOWNLOAD SQUASHFS - ## - - print_waiting "Downloading root filesystem image via $torrent" - # --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 - ip a - sleep 1 - - #wget -O /tmp/torrent "$torrent" - - (cd /tmp - ln -s "${disk}1" "$torrent_file" - aria2c \ - --allow-overwrite \ - --check-integrity \ - --seed-time=0 \ - --summary-interval=10 \ - --file-allocation=none \ - --enable-dht=false \ - "$torrent" - ) - print_done - - modprobe overlay - mkdir -p /root - mkdir /ro_root /rw_root - mount -t squashfs /dev/sda1 /ro_root - mke2fs -q -F -t ext4 /dev/sdb1 - mount -t ext4 /dev/sdb1 /rw_root - mkdir -p /rw_root/upper /rw_root/work - mount -t overlay overlay -o lowerdir=/ro_root,upperdir=/rw_root/upper,workdir=/rw_root/work /root - sleep 10 +labsync_info() { + echo -e "\n\033[36m${1}... \033[0m" +} +labsync_warn() { + echo -e "\n\033[31mWARNING: ${1}\033[0m" +} +labsync_err() { + labsync_warn "$1; interrupting startup" + read x } labsync_top() { - : + # Check if mandatory parameters are missing + if [ -z "${labsync_disk}" ]; then + labsync_err "The disk parameter is missing" + fi + if [ -z "${labsync_partsize_boot}" ]; then + labsync_err "The partsize_boot parameter is missing" + fi + if [ -z "${labsync_torrent}" ]; then + labsync_err "The torrent parameter is missing" + fi + + cat << EOM +Starting + ""# # + # mmm #mmm mmm m m m mm mmm + # " # #" "# # " "m m" #" # #" " + # m"""# # # """m #m# # # # + "mm "mm"# ##m#" "mmm" "# # # "#mm" + m" + "" +@@CI_REPOSITORY_URL@@ + +EOM } labsync_premount() { - : + labsync_info "Configuring networking" + configure_networking +} + + +labsync_mount_root() { + labsync_info "Downloading torrent file from ${labsync_torrent}" + while ! wget -T 10 -O /tmp/torrent "${labsync_torrent}"; do sleep 1; done + aria2c -S -T /tmp/torrent > /tmp/torrent_info + squashfs_file="$(sed -n '/idx|path\/length/,${s/\s*1|\(.*\)$/\1/p}' /tmp/torrent_info)" + image_size_bytes="$(sed -n 's/Total Length: .*(\([0-9,]*\)).*$/\1/p' /tmp/torrent_info | tr -d ',')" + torrent_name="$(sed -n 's/^Name: \(.*\)$/\1/p' /tmp/torrent_info)" + + labsync_info "Updating partitions" + size_disk=$(blockdev --getsz ${labsync_disk}) + size_part_1=$((labsync_partsize_boot * 1024 * 1024 / 512)) + size_part_2=$(((size_disk - labsync_partsize_boot) * 1024 * 1024 / 512)) + start_part_2=$((size_part_1 + 2048)) + + sfdisk -q ${labsync_disk} << PARTTABLE +label: dos +label-id: 0xdeadbeef +device: ${labsync_disk} +unit: sectors + +${labsync_disk}1 : start= 2048, size= $size_part_1, type=83 +${labsync_disk}2 : start=$start_part_2, size= $size_part_2, type=8e +PARTTABLE + + + labsync_info "Doing lvm stuff" + pv_device="${labsync_disk}2" + vg_name="vglab" + lv_name_sqashfs="sqfs-$torrent_name" + lv_name_overlay="ovly-$torrent_name" + + lvm pvcreate -t "$pv_device" + pvstatus=$? + if [ $pvstatus -eq 0 ]; then + # is not a physical volume + lvm pvcreate "$pv_device" + fi + + lvm vgcreate -t "$vg_name" "$pv_device" + vgstatus=$? + if [ $? -eq 0 ]; then + lvm vgcreate "$vg_name" "$pv_device" + fi + + labsync_create_or_resize_lv "$vg_name" "$lv_name_sqashfs" $((image_size_bytes * 2)) $image_size_bytes + labsync_create_or_resize_lv "$vg_name" "$lv_name_overlay" $((500 * 1024 * 1024)) + + #lvm vgchange -ay "$vg_name" + #lvm lvscan -a --ignorelockingfailure + #lvm lvchange -aly --ignorelockingfailure "$vg_name/$lv_name_sqashfs" + lv_path_squashfs="$(lvm lvs "$vg_name/$lv_name_sqashfs" -o LV_PATH --noheadings --units b --nosuffix | sed 's/\s//g')" + lv_path_overlay="$(lvm lvs "$vg_name/$lv_name_overlay" -o LV_PATH --noheadings --units b --nosuffix | sed 's/\s//g')" + + labsync_info "Downloading squashfs image $squashfs_file to $lv_path_squashfs" + (cd /tmp + ln -s "$(realpath "$lv_path_squashfs")" "$squashfs_file" + aria2c \ + --console-log-level=warn \ + --allow-overwrite \ + --check-integrity \ + --seed-time=0 \ + --summary-interval=0 \ + --file-allocation=none \ + --enable-dht=false \ + /tmp/torrent + ) + + labsync_info "Mounting squashfs and overlay" + modprobe overlay + mkdir -p /root + mkdir /ro_root /rw_root + mount -t squashfs "$(realpath "$lv_path_squashfs")" /ro_root + mke2fs -q -F -t ext4 "$lv_path_overlay" + mount -t ext4 "$lv_path_overlay" /rw_root + mkdir -p /rw_root/upper /rw_root/work + mount -t overlay overlay -o lowerdir=/ro_root,upperdir=/rw_root/upper,workdir=/rw_root/work /root + + case "$labsync_wait" in + pause) + read x + ;; + *) + sleep $labsync_wait + ;; + esac } labsync_bottom() { From bc4d1af4288315996edd11b402f7c0afa8ebf207 Mon Sep 17 00:00:00 2001 From: jalr Date: Thu, 1 Mar 2018 19:52:24 +0100 Subject: [PATCH 2/4] Rename squashfs file, add .squashfs syntax --- Makefile | 10 +++++++--- mktorrent/entrypoint.sh | 15 ++++++++++++--- packer/docker/entrypoint.sh | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f2fab2a..56a9fd9 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,11 @@ WEBSEED ?= http://10.2.2.1 PACKER_DOCKER_IMAGE ?= labsync-packer MKTORRENT_DOCKER_IMAGE ?= labsync-mktorrent +CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) + +.PHONY: default +default: clean dockerimg images/debian-stretch.squashfs images/debian-stretch.torrent + .PHONY: clean clean: rm -f images/* @@ -15,7 +20,7 @@ dockerimg: docker build -t "$(PACKER_DOCKER_IMAGE)" --build-arg "PACKER_VERSION=$(PACKER_VERSION)" packer/docker docker build -t "$(MKTORRENT_DOCKER_IMAGE)" mktorrent -images/debian-stretch: +images/debian-stretch.squashfs: docker run \ --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ @@ -26,7 +31,6 @@ images/debian-stretch: "$(PACKER_DOCKER_IMAGE)" \ debian-stretch -#images/debian-stretch.squashfs images/debian-stretch.torrent: docker run \ --rm \ @@ -36,4 +40,4 @@ images/debian-stretch.torrent: -e "ANNOUNCE=$(ANNOUNCE)" \ -e "WEBSEED=$(WEBSEED)" \ "$(MKTORRENT_DOCKER_IMAGE)" \ - debian-stretch + debian-stretch.squashfs diff --git a/mktorrent/entrypoint.sh b/mktorrent/entrypoint.sh index d09f4f6..fc058b9 100755 --- a/mktorrent/entrypoint.sh +++ b/mktorrent/entrypoint.sh @@ -2,7 +2,10 @@ set -e -NAME="$1" +if [ "$NAME" = "" ]; then + # remove file extension + NAME="$(echo "$1" | sed 's/\.[^.]*//')" +fi if [ "$WEBSEED" = "" ]; then echo '$WEBSEED not provided' >&2 @@ -14,11 +17,17 @@ if [ "$ANNOUNCE" = "" ]; then fi TORRENT_FILE="$NAME.torrent" -WEBSEED_URL="$WEBSEED/$NAME" +WEBSEED_URL="$WEBSEED/$1" if [ -e "$TORRENT_FILE" ]; then rm "$TORRENT_FILE"; fi -mktorrent-borg -a "$ANNOUNCE" -o "$TORRENT_FILE" -l 22 -w "$WEBSEED_URL" "$NAME" +mktorrent-borg \ + -n "$NAME" \ + -a "$ANNOUNCE" \ + -o "$TORRENT_FILE" \ + -l 22 \ + -w "$WEBSEED_URL" \ + "$1" if [ "$user" != "" ] && [ "$group" != "" ]; then chown "$user:$group" "$TORRENT_FILE" diff --git a/packer/docker/entrypoint.sh b/packer/docker/entrypoint.sh index b0211ec..5261f98 100755 --- a/packer/docker/entrypoint.sh +++ b/packer/docker/entrypoint.sh @@ -12,7 +12,7 @@ fi PACKER_JSON="$NAME.json" INITRAMFS_FILE="$NAME.initramfs" LINUX_FILE="$NAME.linux" -SQUASHFS_FILE="$NAME" +SQUASHFS_FILE="$NAME.squashfs" packer build "$PACKER_JSON" From a4789e6902d532e86309d4026c4fdef45cbcf409 Mon Sep 17 00:00:00 2001 From: jalr Date: Thu, 8 Mar 2018 23:59:26 +0100 Subject: [PATCH 3/4] Add tftp for qemu; Include qemu in Makefile --- Makefile | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- qemu.sh | 35 -------------------- txt.cfg | 10 ++++++ 3 files changed, 104 insertions(+), 39 deletions(-) delete mode 100755 qemu.sh create mode 100644 txt.cfg diff --git a/Makefile b/Makefile index 56a9fd9..deff150 100644 --- a/Makefile +++ b/Makefile @@ -7,20 +7,36 @@ MKTORRENT_DOCKER_IMAGE ?= labsync-mktorrent CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) +qemu_ifname_br = brlabsync +qemu_ifname_tap = taplabsync +qemu_hostname = qemumachine +qemu_host_ip = 10.2.2.1 +qemu_netmask = 24 +qemu_vm_ip = 10.2.2.10 +qemu_disk = tmp/qemu-disk.img +qemu_target ?= debian-stretch +qemu_kernel = $(qemu_target).linux +qemu_initramfs = $(qemu_target).initramfs.dev +qemu_torrent = $(qemu_target).torrent + .PHONY: default -default: clean dockerimg images/debian-stretch.squashfs images/debian-stretch.torrent +default: dockerimg images/debian-stretch.squashfs images/debian-stretch.torrent .PHONY: clean clean: rm -f images/* - rm -f tmp/* + rm -rf tmp .PHONY: dockerimg dockerimg: docker build -t "$(PACKER_DOCKER_IMAGE)" --build-arg "PACKER_VERSION=$(PACKER_VERSION)" packer/docker docker build -t "$(MKTORRENT_DOCKER_IMAGE)" mktorrent -images/debian-stretch.squashfs: +images: + [ ! -d "$@" ] && mkdir "$@" + touch "$@" + +images/debian-stretch.squashfs: images docker run \ --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ @@ -31,7 +47,7 @@ images/debian-stretch.squashfs: "$(PACKER_DOCKER_IMAGE)" \ debian-stretch -images/debian-stretch.torrent: +images/debian-stretch.torrent: images docker run \ --rm \ -v "${PWD}/images:/workdir" \ @@ -41,3 +57,77 @@ images/debian-stretch.torrent: -e "WEBSEED=$(WEBSEED)" \ "$(MKTORRENT_DOCKER_IMAGE)" \ debian-stretch.squashfs + +# updates the initramfs +# only used for development +images/debian-stretch.initramfs.dev: tmp/initramfs-extracted/debian-stretch packer/initramfs/labsync + cp packer/initramfs/labsync tmp/initramfs-extracted/debian-stretch/scripts/labsync + (cd tmp/initramfs-extracted/debian-stretch && find . | cpio -H newc -o | gzip > $(CWD)/images/debian-stretch.initramfs.dev) + +tmp: + [ ! -d "$@" ] && mkdir "$@" || true + +tmp/initramfs-extracted/debian-stretch: images/debian-stretch.initramfs + rm -rf tmp/initramfs-extracted/debian-stretch + mkdir -p tmp/initramfs-extracted/debian-stretch + (cd tmp/initramfs-extracted/debian-stretch && zcat "$(CWD)/images/debian-stretch.initramfs" | cpio -i) + touch tmp/initramfs-extracted/debian-stretch + +$(qemu_disk): tmp + qemu-img create "$@" 4G + +tmp/netboot.tar.gz: tmp + wget -O "$@" https://cdn-aws.deb.debian.org/debian/dists/stretch/main/installer-amd64/current/images/netboot/netboot.tar.gz + touch "$@" + +tmp/tftproot: tmp/netboot.tar.gz + [ ! -d tmp/tftproot ] && mkdir tmp/tftproot || true + tar -xzf "$<" -C "$@" + rm tmp/tftproot/debian-installer/amd64/boot-screens/txt.cfg + +tmp/tftproot/images: tmp/tftproot + ln -s ../../images tmp/tftproot/images + +tmp/tftproot/debian-installer/amd64/boot-screens/txt.cfg: txt.cfg + ln -s ../../../../../txt.cfg "$@" + + +/sys/devices/virtual/net/$(qemu_ifname_tap): + sudo ip tuntap add dev $(qemu_ifname_tap) mode tap user $(USER) + +/sys/devices/virtual/net/$(qemu_ifname_br): + sudo brctl addbr $(qemu_ifname_br) + +/sys/devices/virtual/net/$(qemu_ifname_br)/brif/$(qemu_ifname_tap): /sys/devices/virtual/net/$(qemu_ifname_tap) /sys/devices/virtual/net/$(qemu_ifname_br) + sudo brctl addif $(qemu_ifname_br) $(qemu_ifname_tap) + +.PHONY: qemu-network +qemu-network: /sys/devices/virtual/net/$(qemu_ifname_br)/brif/$(qemu_ifname_tap) + if ! ip addr show dev $(qemu_ifname_br) | grep -F "$(qemu_host_ip)/$(qemu_netmask)"; then \ + sudo ip addr add $(qemu_host_ip)/$(qemu_netmask) dev $(qemu_ifname_br); \ + fi + sudo ip link set $(qemu_ifname_tap) up + sudo ip link set $(qemu_ifname_br) up + +.PHONY: qemu +qemu: qemu-network $(qemu_disk) + qemu-system-x86_64 \ + -kernel "images/$(qemu_kernel)" \ + -initrd "images/$(qemu_initramfs)" \ + -drive format=raw,file="$(qemu_disk)" \ + -append "boot=labsync labsync_disk=/dev/sda labsync_partsize_boot=512 labsync_torrent=http://10.2.2.1/$(qemu_torrent) quiet vga=792 ip=$(qemu_vm_ip):::255.255.255.0:$(qemu_hostname):ens3:off labsync_wait=pause" \ + -enable-kvm \ + -m 1G \ + -net nic \ + -net tap,ifname=$(qemu_ifname_tap),script=no,downscript=no + +.PHONY: qemu-tftp +qemu-tftp: tmp/tftproot tmp/tftproot/images tmp/tftproot/debian-installer/amd64/boot-screens/txt.cfg qemu-network $(qemu_disk) + qemu-system-x86_64 \ + -net nic -net tap,ifname=$(qemu_ifname_tap),script=no,downscript=no \ + -net nic -net user,tftp=.,bootfile=/tmp/tftproot/pxelinux.0 \ + -enable-kvm \ + -m 1G \ + -drive format=raw,file="$(qemu_disk)" \ + -boot n + diff --git a/qemu.sh b/qemu.sh deleted file mode 100755 index 26f93eb..0000000 --- a/qemu.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -ifname_tap=taplabsync -ifname_br=brlabsync - -TORRENT="$1.torrent" -KERNEL="$1.linux" -INITRAMFS="$1.initramfs" -SQUASHFS="$1" - -if [ "$1" = "" ]; then - echo "you must supply an image name!" >&2 - exit 1 -fi - -mkdir -p ./tmp -[ -e tmp/qemu-disk.img ] || qemu-img create tmp/qemu-disk.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 $ifname_br -sudo ip link set taplabsync up -sudo ip link set brlabsync up - -qemu-system-x86_64 \ - -kernel "images/$KERNEL" \ - -initrd "images/$INITRAMFS" \ - -drive format=raw,file=tmp/qemu-disk.img \ - -drive format=raw,file=tmp/qemu-disk2.img \ - -append "boot=labsync disk=/dev/sda partsize=3072 torrent=http://10.2.2.1/$TORRENT torrent_file=$SQUASHFS quiet vga=792 ip=10.2.2.2:::255.255.255.0:qemumachine:ens3:off" \ - -enable-kvm \ - -m 1G \ - -net nic \ - -net tap,ifname=$ifname_tap,script=no,downscript=no diff --git a/txt.cfg b/txt.cfg new file mode 100644 index 0000000..b1119e0 --- /dev/null +++ b/txt.cfg @@ -0,0 +1,10 @@ +label labsync + menu label ^labsync + kernel images/debian-stretch.linux + append initrd=images/debian-stretch.initramfs.dev boot=labsync labsync_disk=/dev/sda labsync_partsize_boot=512 labsync_torrent=http://10.2.2.1/debian-stretch.torrent quiet vga=792 ip=10.2.2.10:::255.255.255.0:qemu-host:ens3:off labsync_wait=pause + +label install + menu label ^Install + kernel debian-installer/amd64/linux + append vga=788 initrd=debian-installer/amd64/initrd.gz --- quiet + From ce5ed5d1de0a9fcca0d30eedc161ff875dae1981 Mon Sep 17 00:00:00 2001 From: jalr Date: Sun, 11 Mar 2018 15:52:00 +0100 Subject: [PATCH 4/4] use resuming for wget --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index deff150..5f2de08 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ $(qemu_disk): tmp qemu-img create "$@" 4G tmp/netboot.tar.gz: tmp - wget -O "$@" https://cdn-aws.deb.debian.org/debian/dists/stretch/main/installer-amd64/current/images/netboot/netboot.tar.gz + wget -c -O "$@" https://cdn-aws.deb.debian.org/debian/dists/stretch/main/installer-amd64/current/images/netboot/netboot.tar.gz touch "$@" tmp/tftproot: tmp/netboot.tar.gz