diff --git a/00-deps.sh b/00-deps.sh index dc6eab4..6ecd89d 100644 --- a/00-deps.sh +++ b/00-deps.sh @@ -10,6 +10,6 @@ fi curl -JLO https://github.com/buildroot/buildroot/archive/2020.02.10.tar.gz tar xf buildroot-2020.02.10.tar.gz mkdir buildroot-2020.02.10/butterknife/ -tar xf overlay.tar -C buildroot-2020.02.10/butterknife/ +cp -r overlay/ buildroot-2020.02.10/butterknife/ mkdir bin/ diff --git a/overlay.tar b/overlay.tar deleted file mode 100644 index 1d19d03..0000000 Binary files a/overlay.tar and /dev/null differ diff --git a/overlay/etc/motd b/overlay/etc/motd new file mode 100644 index 0000000..b57bf31 --- /dev/null +++ b/overlay/etc/motd @@ -0,0 +1,13 @@ + + █ █ █ ▒██ + █ █ █ █ █░ + █ █ █ █ █ + █▓██ █ █ █████ █████ ███ █▒██▒ █ ▒█ █▒██▒ ███ █████ ███ + █▓ ▓█ █ █ █ █ ▓▓ ▒█ ██ █ █ ▒█ █▓ ▒█ █ █ ▓▓ ▒█ + █ █ █ █ █ █ █ █ █ █▒█ █ █ █ █ █ █ + █ █ █ █ █ █ █████ █ ██▓ █ █ █ █ █████ + █ █ █ █ █ █ █ █ █░█░ █ █ █ █ █ + █▓ ▓█ █▒ ▓█ █░ █░ ▓▓ █ █ █ ░█ █ █ █ █ ▓▓ █ + █▓██ ▒██▒█ ▒██ ▒██ ███▒ █ █ ▒█ █ █ █████ █ ███▒ + + https://github.com/laurivosandi/butterknife diff --git a/overlay/sbin/butterknife-advanced-options b/overlay/sbin/butterknife-advanced-options new file mode 100755 index 0000000..ff0d60d --- /dev/null +++ b/overlay/sbin/butterknife-advanced-options @@ -0,0 +1,90 @@ +#!/bin/sh + +set -e + +action=$(dialog --menu "Advanced options, consider your warranty VOID!" 0 0 0 \ + shell "Drop to shell" \ + instance "Instance maintenance and recovery" \ + subvol "Delete instances/templates" \ + restore "Restore Windows master boot record" \ + 2>&1 >$(tty)) +clear + +case $action in + shell) + sh + ;; + instance) + export BUTTERKNIFE_PARTITION=$(butterknife-select-btrfs-filesystem 2>&1 >$(tty)) + + # Probe instances + pool_mountpoint=$(mktemp -d) + subvols=$(mktemp) + mount $BUTTERKNIFE_PARTITION $pool_mountpoint -o subvol=/ + for subvol in $(ls $pool_mountpoint | grep "^@root:" | sort -r); do + echo "$subvol \"\"" + done > $subvols + if [ -d $pool_mountpoint/deployments ]; then + for timestamp in $(ls $pool_mountpoint/deployments | sort -r); do + echo "deployments/$timestamp \"\"" + done >> $subvols + fi + umount $pool_mountpoint + rmdir $pool_mountpoint + + # Select instance + export BUTTERKNIFE_DEPLOY_SUBVOL=$(dialog \ + --menu "Select instance" 0 0 0 \ + --file $subvols 2>&1 >$(tty)) + + # TODO: Export BUTTERKNIFE_DISK for grub-install MBR + instance_mountpoint=$(mktemp -d) + mount $BUTTERKNIFE_PARTITION -o subvol=$BUTTERKNIFE_DEPLOY_SUBVOL $instance_mountpoint + mount --bind /dev $instance_mountpoint/dev + mount --bind /sys $instance_mountpoint/sys + mount --bind /proc $instance_mountpoint/proc + if [ -d $instance_mountpoint/var/lib/butterknife/persistent ]; then + mount --bind /proc $instance_mountpoint/var/lib/butterknife/persistent + fi + clear + echo "Mounted $BUTTERKNIFE_PARTITION$BUTTERKNIFE_DEPLOY_SUBVOL at $instance_mountpoint" + echo "Chrooting into $instance_mountpoint" + hostname $(cat $instance_mountpoint/etc/hostname) + cat /etc/resolv.conf > $instance_mountpoint/etc/resolv.conf + # Export sensible PATH + export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + chroot $instance_mountpoint butterknife-maintenance + umount -a + rmdir $instance_mountpoint + ;; + subvol) + BUTTERKNIFE_PARTITION=$(butterknife-select-btrfs-filesystem 2>&1 >$(tty)) + mountpoint=$(mktemp -d) + mount $BUTTERKNIFE_PARTITION -o subvol=/ $mountpoint + subvols=$(mktemp) + for subvol in $(btrfs subvol list $mountpoint | cut -d ' ' -f 9 | sort -r); do + echo "$subvol \"\"" + done > $subvols + selected_subvol=$(dialog --menu "Select subvolume to delete on $BUTTERKNIFE_PARTITION" 0 0 0 \ + --file $subvols 2>&1 >$(tty)) + rm -f $subvols + btrfs subvol delete -c $mountpoint/$selected_subvol + umount $mountpoint + rmdir $mountpoint + ;; + restore) + disk=$(butterknife-select-disk 2>&1 >$(tty)) + + # Select MBR type + action=$(dialog --menu "What kind of master boot record would you like to restore? You might have to mark partition bootable using fdisk." 0 0 0 \ + mbr7 "Windows 7/8/10" \ + mbrvista "Windows Vista" \ + mbr "Windows 2000/XP/2003" \ + 2>&1 >$(tty)) + + cmd="ms-sys --$action /dev/$disk" + $cmd | dialog --programbox "$cmd" 10 76 + + ;; +esac + diff --git a/overlay/sbin/butterknife-discover b/overlay/sbin/butterknife-discover new file mode 100755 index 0000000..8a0dfa6 --- /dev/null +++ b/overlay/sbin/butterknife-discover @@ -0,0 +1,12 @@ +dig -t ANY @224.0.0.251 -p5353 +noall +answer _butterknife._tcp.local | grep "IN SRV" | while read line; do + hostname=$(echo $line | cut -d " " -f 8) + address=$(dig +short +noall +answer @224.0.0.251 -p5353 $hostname | head -n1) + port=$(echo $line | cut -d " " -f 7) + title=$(echo $line | cut -d "." -f 1 | sed -e 's/\032/ /g') + if [ $port -eq 80 ]; then + echo "http://$address \"$title\"" + else + echo "http://$address:$port \"$title\"" + fi +done + diff --git a/overlay/sbin/butterknife-partition-size b/overlay/sbin/butterknife-partition-size new file mode 100755 index 0000000..df90dc3 --- /dev/null +++ b/overlay/sbin/butterknife-partition-size @@ -0,0 +1,12 @@ +#!/bin/sh + +partition_slug=$(echo $1 | cut -d "/" -f 3) +sys_part="/sys/block/*/$partition_slug" +sys_disk=$(dirname $sys_part) +sector_count=$(cat $sys_part/size) +sector_size=$(cat $sys_disk/queue/hw_sector_size) +size=$(expr $sector_count / 1000000 \* $sector_size / 1000)G +if [ $size == "G" ]; then + size=$(expr $sector_count / 1000 \* $sector_size / 1000)M +fi +echo $size diff --git a/overlay/sbin/butterknife-provision b/overlay/sbin/butterknife-provision new file mode 100755 index 0000000..3bfb25f --- /dev/null +++ b/overlay/sbin/butterknife-provision @@ -0,0 +1,440 @@ +#!/bin/sh + +# TODO: Make sure fdisk from busybox is NOT used, it's counting sectors incorrectly (?!) +# TODO: Check connectivity with API server + +BUTTERKNIFE_POOL_MOUNTPOINT=/var/lib/butterknife/pool +TARGET_MOUNTPOINT=/mnt/target + +AGENT="Butterknife-Provisioning-Image/0.2" +URL_LOCAL=http://butterknife + + +####################################### +### Check for presence of utilities ### +####################################### +for util in btrfs jq fdisk find ntfsresize udp-sender udp-receiver ntpdate curl ms-sys mktemp test true sort uniq dig; do + if [ -z "$(which $util)" ]; then + echo "Butterknife was unable to locate $util," \ + "are you sure the provisioning image was compiled properly?" + exit 253 + else + echo "Found $util..." + fi +done + +#for i in $(cat /proc/cmdline); do +# case i in +# bk_debug) + set -x # Echo +# ;; +# esac +#done + + +set -e # Bail on error + +####################################### +### Transfer method selection phase ### +####################################### + +if [ -z $BUTTERKNIFE_TRANSFER_METHOD ]; then + BUTTERKNIFE_TRANSFER_METHOD=$(dialog --menu "Select transfer method" 0 0 0 \ + http "HTTP-only" \ + multicast "Multicast receive" \ + tee "Multicast via HTTP and write" \ + proxy "Only proxy HTTP to multicast" 2>&1 >$(tty)) + clear +fi + + +################################## +### Harddisk preparation phase ### +################################## + +case $BUTTERKNIFE_TRANSFER_METHOD in + http|multicast|tee) + ############################# + ### Target disk selection ### + ############################# + + if [ -z $bk_disk_slug ]; then + bk_disk_slug=$(butterknife-select-disk 2>&1 >$(tty)) + fi + BUTTERKNIFE_DISK=/dev/$bk_disk_slug + + if [ -z $BUTTERKNIFE_PARTITIONING_METHOD ]; then + + BUTTERKNIFE_PARTITIONING_METHOD=$(dialog --menu "Partitioning $BUTTERKNIFE_DISK" 0 0 0 \ + receive "Receive into existing btrfs filesystem" \ + unpartitioned "Use unpartitioned area" \ + resize "Resize last partition" \ + reformat "Reformat partition" \ + mbr "Wipe <2TB disk" \ + gpt "Wipe 2TB+ disk" \ + efi "Wipe and do EFI install" \ + 2>&1 >$(tty)) + clear + fi + + # TODO: deploy "Deploy received template" \ + # TODO: postinstall "Run postinstall scripts (reinstall GRUB)" \ + case $BUTTERKNIFE_PARTITIONING_METHOD in + unpartitioned) + echo "Attempting to create new partition in unpartitioned space" + echo -e "n\np\n\n\n\nw" | fdisk $BUTTERKNIFE_DISK + ;; + resize) + NTFS_PARTITION=$(ls $BUTTERKNIFE_DISK? | tail -n 1) + # TODO: Assert last one is NTFS + # TODO: Suggested size heuristics + MINSIZE=$(ntfsresize $NTFS_PARTITION -m | grep Minsize | cut -d ':' -f 2) + SUGGESTED=${MINSIZE}M + SIZE=$(dialog --inputbox "Enter new filesystem size of at least ${MINSIZE}M" 0 0 $SUGGESTED 2>&1 >$(tty)) + clear + ntfsresize -s $SIZE $NTFS_PARTITION + echo -e "d\n\nw" | fdisk $BUTTERKNIFE_DISK # Remove last partition + echo -e "n\np\n\n\n+$SIZE\nt\n\n7\nw" | fdisk $BUTTERKNIFE_DISK # Re-create NTFS + echo -e "n\np\n\n\n\nw" | fdisk $BUTTERKNIFE_DISK # Create partition for btrfs + ;; + mbr) + echo "Purging whole disk" + echo -e "o\nn\np\n\n\n\na\n1\nw" | fdisk $BUTTERKNIFE_DISK + ;; + gpt) + sgdisk $BUTTERKNIFE_DISK -o -g \ + -n 1::+2MB -t 1:ef02 -c 1:"BIOS Boot Partition" \ + -n 2 -t 2:8300 -c 2:"Butterknife pool" -p + ;; + efi) + sgdisk $BUTTERKNIFE_DISK -o -g \ + -n 1::+100MB -t 1:ef00 -c 1:"EFI System Partition" \ + -n 2 -t 2:8300 -c 2:"Butterknife pool" -p + ;; + reformat|receive) + # NOOP + ;; + *) + echo "Invalid partitioning method $BUTTERKNIFE_PARTITIONING_METHOD" + exit 255 + ;; + esac + + + ############################################ + ### Target partition determination phase ### + ############################################ + case $BUTTERKNIFE_PARTITIONING_METHOD in + reformat|receive) + # Dialog to select partition for reformat or receive + for partition in $BUTTERKNIFE_DISK?; do + partition_slug=$(echo $BUTTERKNIFE_PARTITION | cut -d "/" -f 3) + sector_count=$(cat /sys/block/$bk_disk_slug/$BUTTERKNIFE_PARTITION_slug/size) + sector_size=$(cat /sys/block/$bk_disk_slug/queue/hw_sector_size) + size=$(expr $sector_count / 1000000 \* $sector_size / 1000 || true)G + if [ $size == "0G" ]; then + size=$(expr $sector_count / 1000 \* $sector_size / 1000 || true)M + fi + echo "$BUTTERKNIFE_PARTITION \"$size\""; + done > /tmp/partitions + + BUTTERKNIFE_PARTITION=$(dialog \ + --menu "Target partition" 0 0 0 \ + --file /tmp/partitions \ + 2>&1 >$(tty)) + clear + ;; + unpartitioned|resize|mbr|gpt|efi) + # Assume last partition + BUTTERKNIFE_PARTITION=$(ls $BUTTERKNIFE_DISK? | tail -n 1) + ;; + *) + echo "Invalid partitioning method $BUTTERKNIFE_PARTITIONING_METHOD" + exit 255 + ;; + esac + + PARTITION_SLUG=$(echo $BUTTERKNIFE_PARTITION | cut -d "/" -f 3) + + + ######################################## + ### Target filesystem creation phase ### + ######################################## + case $BUTTERKNIFE_PARTITIONING_METHOD in + efi) + mkfs.vfat ${BUTTERKNIFE_DISK}1 + ;; + esac + + case $BUTTERKNIFE_PARTITIONING_METHOD in + mbr|gpt|efi|reformat|unpartitioned|resize) + echo "Creating clean btrfs filesystem on $PARTITON" + mkfs.btrfs -f $BUTTERKNIFE_PARTITION + ;; + esac + + # Attempt to mount target directory + mkdir -p $BUTTERKNIFE_POOL_MOUNTPOINT + mount $BUTTERKNIFE_PARTITION $BUTTERKNIFE_POOL_MOUNTPOINT -o subvol=/ -t btrfs + if [ $? -ne 0 ]; then + dialog --msgbox "Mounting $BUTTERKNIFE_PARTITION at $BUTTERKNIFE_POOL_MOUNTPOINT failed, are you sure kernel has btrfs support built-in?" 0 0 + exit 255 + fi + + ################ + ### Clean up ### + ################ + + for subvol in $(ls $BUTTERKNIFE_POOL_MOUNTPOINT | (grep "^@template:" || true)); do + set +e + touch $BUTTERKNIFE_POOL_MOUNTPOINT/$subvol/.test + if [ $? -eq 0 ]; then + set -e + btrfs subvol delete $BUTTERKNIFE_POOL_MOUNTPOINT/$subvol + fi + set -e + done + ;; + *) + BUTTERKNIFE_PARTITIONING_METHOD="pass" + ;; +esac + +############################## +### Determine architecture ### +############################## + +bk_arch=$(uname -m | sed 's/^i.86$/x86/') + +case $BUTTERKNIFE_TRANSFER_METHOD in + http|tee|proxy) + ############################## + ### Server selection phase ### + ############################## + if [ -z $bk_url ]; then + + bk_url=$(dialog --menu "Select server" 0 0 0 \ + mdns:// "Autodiscover" \ + $URL_LOCAL "Manually enter" \ + https://butterknife.k-space.ee "K-SPACE MTÜ" 2>&1 >$(tty)) + + if [ "$bk_url" == "mdns://" ]; then + butterknife-discover > /tmp/discovered_servers + bk_url=$(dialog --menu "Select one of discovered servers" \ + 0 0 0 --file /tmp/discovered_servers 2>&1 >$(tty)) + elif [ "$bk_url" == $URL_LOCAL ]; then + bk_url=$(dialog --inputbox "Manually enter the URL of Butterknife server" \ + 0 0 $URL_LOCAL 2>&1 >$(tty)) + fi + clear + fi + + + ################################ + ### Template selection phase ### + ################################ + + if [ -z $bk_template ]; then + # Fetch template list + curl -A $AGENT -s $bk_url/api/template \ + | jq '.templates[] | .namespace + "." + .identifier + " \"" + .description + "\""' -r \ + > /tmp/available_templates + + bk_template=$(dialog \ + --menu "Select template to deploy" 0 0 0 \ + --file /tmp/available_templates \ + 2>&1 >$(tty)) + clear + + fi + + ############################### + ### Version selection phase ### + ############################### + if [ -z $bk_version ]; then + # Fetch version list + curl -A $AGENT -s $bk_url/api/template/$bk_template/arch/$bk_arch/version \ + > /tmp/available_versions.json + + cat /tmp/available_versions.json \ + | jq '.versions[] | .identifier + " \"" + .comment + "\""' -r \ + | head -n 100 \ + > /tmp/available_versions + + bk_version=$(dialog \ + --menu "Select version to deploy" 0 0 0 \ + --file /tmp/available_versions \ + 2>&1 >$(tty)) + clear + fi + + BUTTERKNIFE_TEMPLATE_SUBVOL="@template:$bk_template:$bk_arch:$bk_version" + + + + ##################################### + ### Stream URL construction phase ### + ##################################### + + # Build btrfs-stream URL + STREAM="$bk_url/$BUTTERKNIFE_TEMPLATE_SUBVOL" + ;; +esac + + +############################################## +### Allow differential versions using HTTP ### +############################################## + +case $BUTTERKNIFE_TRANSFER_METHOD in + http) + # Determine differential version parent + cat /tmp/available_versions.json | jq -r '.versions[] .identifier' > /tmp/available_version_names + ls $BUTTERKNIFE_POOL_MOUNTPOINT | (grep "^@template:$bk_template:$bk_arch:" || true) | cut -d ":" -f 4 > /tmp/local_version_names + PARENT=$(cat /tmp/local_version_names /tmp/available_version_names | sort | grep -v $bk_version | uniq -d | sort -t p -k 2n | tail -n 1) + if [ -z $PARENT ]; then + echo "Could not determine parent, falling back to full snapshot" + else + STREAM="$STREAM?parent=@template:$bk_template:$bk_arch:$PARENT" + fi + echo "Final URL is $STREAM" + ;; +esac + +#################################################### +### Enable compression if we're going over HTTPS ### +#################################################### + +case $STREAM in + https://*) + STREAM="--compressed $STREAM" + ;; +esac + + +###################### +### Transfer phase ### +###################### + +case $BUTTERKNIFE_TRANSFER_METHOD in + multicast) + ls $BUTTERKNIFE_POOL_MOUNTPOINT | (grep "^@template:" || true) > /tmp/local_templates + udp-receiver --nokbd | btrfs receive $BUTTERKNIFE_POOL_MOUNTPOINT + # Heuristics to determine name of received snapshot + ls $BUTTERKNIFE_POOL_MOUNTPOINT | (grep "^@template:" || true) > /tmp/new_templates + BUTTERKNIFE_TEMPLATE_SUBVOL=$(cat /tmp/local_templates /tmp/new_templates | sort | uniq -u) + # TODO: Break here if we got garbage + bk_template=$(echo $BUTTERKNIFE_TEMPLATE_SUBVOL | cut -d ":" -f 2) + bk_arch=$(echo $BUTTERKNIFE_TEMPLATE_SUBVOL | cut -d ":" -f 3) + bk_version=$(echo $BUTTERKNIFE_TEMPLATE_SUBVOL | cut -d ":" -f 4) + ;; + http) + curl -A $AGENT $STREAM | btrfs receive $BUTTERKNIFE_POOL_MOUNTPOINT + ;; + tee) + dialog --msgbox "Press enter once all the other machines are ready to receive" 0 0 + mkfifo /tmp/multicast_stream /tmp/local_stream + cat /tmp/local_stream | btrfs receive $BUTTERKNIFE_POOL_MOUNTPOINT & + sleep 1 + udp-sender --nokbd --no-progress --min-receivers 1 --min-wait 5 /tmp/multicast_stream & + sleep 1 + curl -A $AGENT -s $STREAM | tee /tmp/multicast_stream > /tmp/local_stream + sleep 2 + # TODO: Ensure btrfs receive has finished + ;; + proxy) + dialog --msgbox "Press enter once all the other machines are ready to receive" 0 0 + curl -A $AGENT -s $STREAM \ + | udp-sender --nokbd --min-receivers 1 --min-wait 5 + ;; +esac + +sync + +case $BUTTERKNIFE_PARTITIONING_METHOD in + pass) + echo "Skipping template deployment" + ;; + *) + ################################# + ### Template deployment phase ### + ################################# + + BUTTERKNIFE_DEPLOY_SUBVOL="@root:$bk_template:$bk_arch:$bk_version" + btrfs subvolume snapshot \ + $BUTTERKNIFE_POOL_MOUNTPOINT/$BUTTERKNIFE_TEMPLATE_SUBVOL \ + $BUTTERKNIFE_POOL_MOUNTPOINT/$BUTTERKNIFE_DEPLOY_SUBVOL + + # Symlink @root:active to current deployment subvol + rm -f $BUTTERKNIFE_POOL_MOUNTPOINT/@root:active + ln -s \ + $BUTTERKNIFE_DEPLOY_SUBVOL \ + $BUTTERKNIFE_POOL_MOUNTPOINT/@root:active + + + ############################### + ### Run post-deploy scripts ### + ############################### + + # Mount deployment subvolume at target directory + mkdir -p $TARGET_MOUNTPOINT + mount -o subvol=$BUTTERKNIFE_DEPLOY_SUBVOL \ + $BUTTERKNIFE_PARTITION \ + $TARGET_MOUNTPOINT + + # Mount pool also for chroot + mkdir -p $TARGET_MOUNTPOINT$BUTTERKNIFE_POOL_MOUNTPOINT + mount -o subvol=/ \ + $BUTTERKNIFE_PARTITION \ + $TARGET_MOUNTPOINT$BUTTERKNIFE_POOL_MOUNTPOINT + + # Mount stuff for chroot + mount --bind /dev/ $TARGET_MOUNTPOINT/dev/ + mount --bind /sys/ $TARGET_MOUNTPOINT/sys/ + mount --bind /proc/ $TARGET_MOUNTPOINT/proc/ + mount --bind /run/ $TARGET_MOUNTPOINT/run/ + mount none $TARGET_MOUNTPOINT/tmp/ -t tmpfs + + case $BUTTERKNIFE_PARTITIONING_METHOD in + efi) + mount ${BUTTERKNIFE_DISK}1 $TARGET_MOUNTPOINT/boot/efi + ;; + esac + + # Export variables for postinstall scripts + export BUTTERKNIFE_DOMAIN + export BUTTERKNIFE_TEMPLATE_SUBVOL + export BUTTERKNIFE_DEPLOY_SUBVOL + export BUTTERKNIFE_PARTITION + export BUTTERKNIFE_DISK + export BUTTERKNIFE_POOL_MOUNTPOINT + export BUTTERKNIFE_PARTITIONING_METHOD + export BUTTERKNIFE_TRANSFER_METHOD + export BUTTERKNIFE_POOL_UUID=$(blkid -s UUID -o value $BUTTERKNIFE_PARTITION) + + # Copy DNS config + mkdir -p /run/resolvconf + mkdir -p /run/systemd/resolve + cat /etc/resolv.conf > $TARGET_MOUNTPOINT/etc/resolv.conf + + # Export sensible PATH + export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + + # Run postinstall scripts, presumably in sorted order + chroot $TARGET_MOUNTPOINT butterknife-deploy + chroot $TARGET_MOUNTPOINT butterknife-maintenance + + # Be forgiving from now on + set +e + + # Unmount directories + echo "Unmounting filesystems" + umount -a + echo "Flushing buffers" + sync + sleep 1 + echo "Rebooting machine" + reboot -f + ;; +esac + diff --git a/overlay/sbin/butterknife-select-btrfs-filesystem b/overlay/sbin/butterknife-select-btrfs-filesystem new file mode 100755 index 0000000..48d7ff7 --- /dev/null +++ b/overlay/sbin/butterknife-select-btrfs-filesystem @@ -0,0 +1,19 @@ +#!/bin/sh + +volumes=$(mktemp) + +unset partition +for partition in $(blkid -t TYPE=btrfs | cut -d ":" -f 1); do + echo "$partition \"$(butterknife-partition-size $partition)\""; +done > $volumes + +if [ -z $partition ]; then + dialog --msgbox "Unable to detect any Butterknife filesystems" 0 0 + return 1 +else + dialog \ + --menu "Select btrfs filesystem" 0 0 0 \ + --file $volumes +fi + +rm -f $volumes diff --git a/overlay/sbin/butterknife-select-disk b/overlay/sbin/butterknife-select-disk new file mode 100755 index 0000000..547a6cb --- /dev/null +++ b/overlay/sbin/butterknife-select-disk @@ -0,0 +1,33 @@ +#!/bin/sh + +if [ -z "$(ls /sys/class/block/)" ]; then + dialog --msgbox "Butterknife was unable to detect any harddisks,\ + are you sure harddisk is connected and we have drivers for it?" 0 0 + exit 255 +fi + +for disk in /sys/class/block/*; do + if [ -d $disk/device ]; then + slug=$(basename $disk) + sector_count=$(cat $disk/size) + sector_size=$(cat $disk/queue/hw_sector_size) + # Hack around these dumbass cardreaders + + if [ "$sector_count" == "0" ]; then + continue + fi + size=$(expr $sector_count / 1000000 \* $sector_size / 1000 || true)G + + if [ -f $disk/device/model ]; then + echo "$slug \"$(cat $disk/device/model | xargs) ($size)\""; + else + echo "$slug \"$size\""; + fi + fi +done > /tmp/disks + +dialog \ + --menu "Target disk" 0 0 0 \ + --file /tmp/disks + + diff --git a/overlay/sbin/init b/overlay/sbin/init new file mode 100755 index 0000000..8a3bb12 --- /dev/null +++ b/overlay/sbin/init @@ -0,0 +1,70 @@ +#!/bin/sh + +clear + +if [ -f /etc/motd ]; then + cat /etc/motd +fi + +# Note that /dev should be handled by devtmpfs +# Make sure this file will be executable + +mount -t proc none /proc +mount -t sysfs sysfs /sys + +################################################################# +### There should be at least one network interface to proceed ### +################################################################# + +echo "Discovering network interfaces..." +sleep 5 + +if [ -z "$(ls /sys/class/net/ | grep -v '^lo$')" ]; then + dialog --msgbox "Butterknife was unable to detect any network interfaces,\ + are you sure network interface is attached properly and we have drivers for it?" 0 0 + exit 254 +fi + +echo "Asking for IP using DHCP ..." +udhcpc + +if [ -z "$bk_timeserver" ]; then + echo "No timeserver specified, skipping ntpdate" +else + echo "Adjusting time ..." + ntpdate $bk_timeserver +fi + +if [ $bk_action == "provision" ]; then + butterknife-provision + sync + sleep 10 + poweroff -f +fi + +while [ 1 ]; do + action=$(dialog --no-cancel --menu "What do you want to do" 0 0 0 \ + provision "Provision this machine" \ + advanced "Advanced options" \ + reboot "Reboot" \ + poweroff "Shutdown" 2>&1 >$(tty)) + + clear + + case $action in + reboot) + reboot -f + ;; + poweroff) + poweroff -f + ;; + provision) + butterknife-provision + read -p "Press Enter to continue..." + + ;; + advanced) + butterknife-advanced-options + ;; + esac +done