#### begin configuration
-bootn=1
+bootn=3
+rootn=1
swapn=2
-rootn=3
bios_grubn=4
-boot_end=804
+boot_mib=750
lastn=$bios_grubn
if ifclass VM; then
crypt=/dev/mapper/crypt_dev_${d##/dev/}a$rootn
-
-if ifclass frodo; then
- # next upgrade is prolly 16 gigs of memory, across ~8 devices
- swap_end=$((3500 + boot_end))
-else
- # 1.5 x based on https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/sect-disk-partitioning-setup-x86.html#sect-custom-partitioning-x86
- swap_end=$(( $(grep ^MemTotal: /proc/meminfo| awk '{print $2}') * 3/(${#devs[@]} * 2 ) / 1000 + boot_end ))
-fi
+bios_grub_end=4
+# 1.5 x based on https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/sect-disk-partitioning-setup-x86.html#sect-custom-partitioning-x86
+swap_mib=$(( $(grep ^MemTotal: /proc/meminfo | \
+ awk '{print $2}') * 3/(${#devs[@]} * 2 ) / 1024 ))
+# parted will round up the disk size. Do -1 so we can have
+# fully 1MiB unit partitions for easy resizing of the last partition.
+# Otherwise we would pass in -0 for the end argument for the last partition.
+disk_mib=$(( $(parted -m ${devs[0]} unit MiB print | \
+ sed -nr "s#^${devs[0]}:([0-9]+).*#\1#p") - 1))
+root_end=$(( disk_mib - swap_mib - boot_mib ))
+swap_end=$(( root_end + swap_mib))
mkdir -p /tmp/fai
shopt -s nullglob
done
for dev in ${devs[@]}; do
parted -s $dev mklabel gpt
- # gpt ubuntu cloud image uses ~4. fai uses 1 MiB. ehh, i'll do 4.
- # also, using MB instead of MiB causes complains about alignment.
+ # gpt ubuntu cloud image uses ~4. fai uses 1 MiB.
+ # I read something in the parted manual saying cheap flash media
+ # likes to start at 4.
+ # MiB because parted complains about alignment otherwise.
pcmd="parted -a optimal -s -- $dev"
- $pcmd mkpart primary "ext3" 4MB ${boot_end}MiB
- $pcmd mkpart primary "linux-swap" ${boot_end}MiB ${swap_end}MiB
- $pcmd mkpart primary "" ${swap_end}MiB -0
+ $pcmd mkpart primary "ext3" 4MiB ${root_end}MiB
+ $pcmd mkpart primary "linux-swap" ${root_end}MiB ${swap_end}MiB
+ $pcmd mkpart primary "" ${swap_end}MiB ${disk_mib}MiB
$pcmd mkpart primary "" 1MiB 4MiB
$pcmd set $bios_grubn bios_grub on
$pcmd set $bootn boot on # generally not needed on modern systems
# the mkfs failed randomly on a vm, so I threw a sleep in here.
sleep .1
-
luks_dev=$dev$rootn
yes YES | cryptsetup luksFormat $luks_dev $luks_dir/host-$HOSTNAME \
-c aes-cbc-essiv:sha256 -s 256 || [[ $? == 141 ]]
--- /dev/null
+#!/bin/bash
+
+shopt -s extdebug
+bash-trace() {
+ # shows function args when: shopt -s extdebug
+ local -i argc_index=0 arg frame i start=${1:-1} max_indent=8 indent
+ local source
+ local extdebug=false
+ if [[ $(shopt -p extdebug) == *-s* ]]; then
+ extdebug=true
+ fi
+
+ for ((frame=0; frame < ${#FUNCNAME[@]}-1; frame++)); do
+ argc=${BASH_ARGC[frame]}
+ argc_index+=$argc
+ ((frame < start)) && continue
+ if (( ${#BASH_SOURCE[@]} > 1 )); then
+ source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:"
+ fi
+ indent=$((frame-start+1))
+ indent=$((indent < max_indent ? indent : max_indent))
+ printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}"
+ if $extdebug; then
+ for ((i=argc_index-1; i >= argc_index-argc; i--)); do
+ printf " %s" "${BASH_ARGV[i]}"
+ done
+ fi
+ echo \'
+ done
+}
+
+
+errcatch() {
+ set -E; shopt -s extdebug
+ _err-trap() {
+ err=$?
+ exec >&2
+ echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err"
+ bash-trace 2
+ echo "$0: exiting with code $err"
+ exit $err
+ }
+ trap _err-trap ERR
+ set -o pipefail
+}
+
+errcatch
+
+[[ $EUID == 0 ]] || sudo "$BASH_SOURCE" "$@"
+
+usage() {
+ cat <<EOF
+Usage: ${0##*/} [-n] +/-SIZE[g] swap|boot
+
+Assuming Ian Kelling's partition scheme,
+Resize swap or boot, expanding or shrinking the root fs and partition to compensate.
+
+-n Dry run
+
+SIZE is MiB, or if g is specified, GiB.
+
+If using multiple devices, SIZE is applied to each device, so total change is
+SIZE * devices.
+
+
+EOF
+ exit $1
+}
+
+dry_run=false
+case $1 in
+ -n) dry_run=true; shift ;;
+ -h|--help) usage ;;
+esac
+
+#### begin arg error checking ####
+
+if [[ $# != 2 ]]; then
+ echo "$0: error: expected 2 arguments"
+ usage 1
+fi
+
+if [[ $1 != [+-][0-9]* ]]; then
+ echo "$0: error: bad 1st arg: $1"
+ usage 1
+fi
+
+if ! which parted &>/dev/null; then
+ echo "$0: error: install parted"
+ exit 1
+fi
+
+case $2 in swap|boot) : ;; *) echo "$0: error: bad 2nd arg"; usage 1 ;; esac
+
+#### end arg error checking ####
+
+
+boot=true
+[[ $2 == boot ]] || boot=false
+
+#size=${x#[+-]}
+op_size=$1 # operator plus size
+[[ $op_size != *g ]] || op_size=$(( ${op_size%g} / 1024 ))
+size=${op_size#[+-]}
+
+if [[ $op_size == +* ]]; then
+ op_size_rev=-$size # rev = reverse
+ grow=true
+else
+ op_size_rev=+$size
+ grow=false
+fi
+
+##### end command line parsing ########
+
+rootn=1
+swapn=2
+bootn=3
+needs_reboot=false
+
+pmk() {
+ part=$1
+ start_op=$2
+ end_op=$3
+ read start end < <(echo ${ptable[$part]})
+ p mkpart primary "$4" $((start $start_op)) $((end $end_op))
+}
+
+
+swapoff -a
+
+while read devid dev; do
+ if $dry_run; then
+ e() { echo "+ $@"; }
+ else
+ e() { echo "+ $@"; "$@"; }
+ fi
+ ptable=()
+ while IFS=: read id start end _; do
+ [[ $id == [0-9] ]] || continue
+ end=${end%MiB}
+ start=${start%MiB}
+ start=${start%.*} # small enough number that parted uses a decimal
+ ptable[$id]="$start $end"
+ done < <(parted -m /dev/$dev unit MiB print)
+ parted /dev/$dev unit MiB print | tee /root/backup_partition
+ p() { e parted -a optimal -s -- /dev/$dev unit MiB "$@"; }
+ e systemctl stop systemd-cryptsetup@crypt_swap_$dev$swapn
+ sleep 1
+ # These partition comments seems a little verbose now, but I bet they
+ # will be helpfull if I read this in more than a week from now.
+ # <> = deleted partition, () = partition
+ p rm $swapn # ( root )< swap >( boot )
+
+ root_resize_cmd="e btrfs fi resize $devid:$op_size_rev /"
+ if $grow; then $root_resize_cmd; fi
+ # if $grow; then
+ # < root >< swap >( boot )
+ # ( root ) >< swap >( boot )
+ # else
+ # < root >< swap >( boot )
+ # ( root >< ) swap >( boot )
+
+ out=$(p rm $rootn 2>&1)
+ echo "$out"
+
+ pmk $rootn "" $op_size_rev
+ if ! $grow; then
+ if echo "$out" | \
+ grep "but we have been unable to inform the kernel" &>/dev/null; then
+ e systemctl mask dev-mapper-crypt_swap_$dev$swapn.swap
+ e systemctl mask systemd-cryptsetup@crypt_swap_$dev$swapn.service
+ if ! $needs_reboot; then
+ needs_reboot=true
+ echo "$0: reboot and run /root/finish-resize to finish.
+The following commands are what will be executed:"
+ rm -rf /root/finish-resize
+ cat >/root/finish-resize <<'EOF'
+#!/bin/bash -x
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+EOF
+ chmod +x /root/finish-resize
+ fi
+ e() { echo "$@" | tee -a /root/finish-resize; }
+ e systemctl unmask systemd-cryptsetup@crypt_swap_$dev$swapn.service
+ e systemctl unmask dev-mapper-crypt_swap_$dev$swapn.swap
+ # todo, disable swap for the next boot. currently have to wait
+ # 1:30 for it to fail.
+ fi
+ $root_resize_cmd
+ fi
+ if $boot; then
+ boot_devid=$(btrfs fi show /boot | \
+ sed -rn "s#^\s*devid\s+(\S+)\s.*$dev[0-9]#\1#p")
+
+ if ! $grow; then
+ # shrink boot, move it to a temp file
+ e btrfs fi resize $boot_devid:$op_size /boot
+ temp_boot=/root/temp_boot_dd
+ e dd bs=1M if=/dev/$dev$bootn of=$temp_boot count=$size
+ fi
+ # if $grow; then
+ # ( root ) >< swap >< boot >
+ # ( root )( >< swap ) >< boot >
+ # ( root )( >< swap )( >< boot )
+ # else
+ # ( root >< ) swap >< boot >
+ # ( root >< )( swap >< ) boot >
+ # ( root >< )( swap >< )( boot )
+ e umount /boot
+ p rm $bootn
+ pmk $swapn $op_size_rev $op_size_rev "linux-swap"
+ pmk $bootn $op_size_rev ""
+
+ if $grow; then
+ e dd bs=1M if=/dev/$dev$bootn of=/dev/$dev$bootn skip=$size
+ e btrfs fi resize $boot_devid:$op_size /boot
+ else
+ e dd bs=1M if=$temp_boot of=/dev/$dev$bootn
+ fi
+ e mount /boot
+ else
+ # if $grow; then ( root )( >< swap )( boot )
+ # else ( root >< )( swap )( boot )
+ pmk $swapn $op_size_rev "" "linux-swap"
+ fi
+done < <(btrfs fi show / | \
+ sed -nr 's#^\s*devid\s*(\S+)\s.*_([^_ ]+)[0-9]\s*$#\1 \2#p')
+
+if $boot; then
+ e rm -rf $temp_boot
+ e rm /root/finish-resize
+fi
+
+if $needs_reboot; then
+ echo "$0: reminder, reboot then /root/finish-resize"
+fi
+
+#for dev in ${devs[@]}; do