fix bugs in resize script, support multi disk
[automated-distro-installer] / fresize
diff --git a/fresize b/fresize
index 90f19982145fb15fd246f5f783108c6f54b7ac0b..7a6688f2d127b29ff244275463368ec1fd2ad47f 100755 (executable)
--- a/fresize
+++ b/fresize
@@ -55,7 +55,9 @@ 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.
 
 Assuming Ian Kelling's partition scheme,
 Resize swap or boot, expanding or shrinking the root fs and partition to compensate.
 
--n   Dry run
+-n         Dry run
+-r         Reboot now if it's needed.
+-h|--help  Print help.
 
 SIZE is MiB, or if g is specified, GiB.
 
 
 SIZE is MiB, or if g is specified, GiB.
 
@@ -67,11 +69,16 @@ EOF
     exit $1
 }
 
     exit $1
 }
 
+reboot_not=false
 dry_run=false
 dry_run=false
-case $1 in
-    -n) dry_run=true; shift ;;
-    -h|--help) usage ;;
-esac
+while true; do
+    case $1 in
+        -r) reboot_now=true; shift ;;
+        -n) dry_run=true; shift ;;
+        -h|--help) usage ;;
+        *) break ;;
+    esac
+done
 
 #### begin arg error checking ####
 
 
 #### begin arg error checking ####
 
@@ -98,7 +105,6 @@ case $2 in swap|boot) : ;; *) echo "$0: error: bad 2nd arg"; usage 1 ;; esac
 boot=true
 [[ $2 == boot ]] || boot=false
 
 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#[+-]}
 op_size=$1 # operator plus size
 [[ $op_size != *g ]] || op_size=$(( ${op_size%g} / 1024 ))
 size=${op_size#[+-]}
@@ -111,48 +117,56 @@ else
     grow=false
 fi
 
     grow=false
 fi
 
+
 ##### end command line parsing ########
 
 rootn=1
 swapn=2
 bootn=3
 needs_reboot=false
 ##### end command line parsing ########
 
 rootn=1
 swapn=2
 bootn=3
 needs_reboot=false
+reboot_script_initialized=false
 
 pmk() {
     part=$1
     start_op=$2
     end_op=$3
 
 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))
+    p mkpart primary "$4" \
+      $((${ptable[start$part]} $start_op)) $((${ptable[end$part]} $end_op))
 }
 
 }
 
-
-swapoff -a
-
-while read devid dev; do
+def-e() {
     if $dry_run; then
         e() { echo "+ $@"; }
     else
         e() { echo "+ $@"; "$@"; }
     fi
     if $dry_run; then
         e() { echo "+ $@"; }
     else
         e() { echo "+ $@"; "$@"; }
     fi
-    ptable=()
-    while IFS=: read id start end _; do
+}
+
+def-e
+e swapoff -a
+
+while read devid dev; do
+    echo skip=$size
+    def-e
+    declare -A ptable
+    while IFS=: read id start end psize _; do
         [[ $id == [0-9] ]] || continue
         [[ $id == [0-9] ]] || continue
-        end=${end%MiB}
-        start=${start%MiB}
-        start=${start%.*} # small enough number that parted uses a decimal
-        ptable[$id]="$start $end"
+        ptable[start$id]=start=${start%%[^0-9]*}
+        ptable[end$id]=${end%%[^0-9]*}
+        ptable[size$id]=${psize%%[^0-9]*}
     done < <(parted -m /dev/$dev unit MiB print)
     done < <(parted -m /dev/$dev unit MiB print)
-    parted /dev/$dev unit MiB print | tee /root/backup_partition
+    parted /dev/$dev unit MiB print | tee /root/backup_partition_table_$dev
     p() { e parted -a optimal -s -- /dev/$dev unit MiB "$@"; }
     e systemctl stop systemd-cryptsetup@crypt_swap_$dev$swapn
     p() { e parted -a optimal -s -- /dev/$dev unit MiB "$@"; }
     e systemctl stop systemd-cryptsetup@crypt_swap_$dev$swapn
-    sleep 1
+    sleep 1 # dunno if this is needed,
+    # but systemd likes to do these kind of things in the background.
+
     # 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 )
 
     # 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 /"
+    root_resize_cmd="e btrfs fi resize $devid:${op_size_rev}M /"
     if $grow; then $root_resize_cmd; fi
     # if $grow; then
     # < root >< swap >( boot )
     if $grow; then $root_resize_cmd; fi
     # if $grow; then
     # < root >< swap >( boot )
@@ -165,15 +179,18 @@ while read devid dev; do
     echo "$out"
 
     pmk $rootn "" $op_size_rev
     echo "$out"
 
     pmk $rootn "" $op_size_rev
+
+    if echo "$out" | \
+            grep "but we have been unable to inform the kernel" &>/dev/null; then
+        needs_reboot=true
+    fi
     if ! $grow; then
     if ! $grow; then
-        if echo "$out" | \
-                grep "but we have been unable to inform the kernel" &>/dev/null; then
+        if $needs_reboot; then
             e systemctl mask dev-mapper-crypt_swap_$dev$swapn.swap
             e systemctl mask systemd-cryptsetup@crypt_swap_$dev$swapn.service
             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:"
+            e() { echo "$@" >> /root/finish-resize; }
+            if ! $reboot_script_initialized; then
+                reboot_script_initialized=true
                 rm -rf /root/finish-resize
                 cat >/root/finish-resize <<'EOF'
 #!/bin/bash -x
                 rm -rf /root/finish-resize
                 cat >/root/finish-resize <<'EOF'
 #!/bin/bash -x
@@ -182,11 +199,8 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
 EOF
                 chmod +x /root/finish-resize
             fi
 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
             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
         fi
         $root_resize_cmd
     fi
@@ -196,9 +210,13 @@ EOF
 
         if ! $grow; then
             # shrink boot, move it to a temp file
 
         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
+            e btrfs fi resize $boot_devid:${op_size}M /boot
+            e umount /boot
+            temp_boot=/root/temp_boot_$dev
+            e dd bs=1M if=/dev/$dev$bootn of=$temp_boot \
+              count=$((${ptable[size$bootn]} $op_size))
+        else
+            e umount /boot
         fi
         # if $grow; then
         # ( root ) >< swap >< boot >
         fi
         # if $grow; then
         # ( root ) >< swap >< boot >
@@ -208,33 +226,44 @@ EOF
         # ( root >< ) swap >< boot >
         # ( root >< )( swap >< ) boot >
         # ( root >< )( swap >< )( boot )
         # ( 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
         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
+            e mount /boot
+            e btrfs fi resize $boot_devid:${op_size}M /boot
         else
             e dd bs=1M if=$temp_boot of=/dev/$dev$bootn
         else
             e dd bs=1M if=$temp_boot of=/dev/$dev$bootn
+            e mount /boot
         fi
         fi
-        e mount /boot
     else
         # if $grow; then  ( root )( >< swap )( boot )
         # else            ( root >< )( swap )( boot )
         pmk $swapn $op_size_rev "" "linux-swap"
     else
         # if $grow; then  ( root )( >< swap )( boot )
         # else            ( root >< )( swap )( boot )
         pmk $swapn $op_size_rev "" "linux-swap"
+        e systemctl start systemd-cryptsetup@crypt_swap_$dev$swapn
     fi
 done < <(btrfs fi show / | \
                 sed -nr 's#^\s*devid\s*(\S+)\s.*_([^_ ]+)[0-9]\s*$#\1 \2#p')
 
     fi
 done < <(btrfs fi show / | \
                 sed -nr 's#^\s*devid\s*(\S+)\s.*_([^_ ]+)[0-9]\s*$#\1 \2#p')
 
+
 if $boot; then
 if $boot; then
-    e rm -rf $temp_boot
-    e rm /root/finish-resize
+    e rm -rf "/root/temp_boot_*"
+    e rm -f /root/finish-resize
 fi
 
 if $needs_reboot; then
 fi
 
 if $needs_reboot; then
-    echo "$0: reminder, reboot then /root/finish-resize"
+    if ! $grow; then
+        echo "$0: Reboot, run /root/finish-resize. It's contents:"
+        cat /root/finish-resize
+    else
+        echo "$0: If you want to resize again later, a reboot is required first."
+    fi
+    if $reboot_now; then
+        echo "$0: rebooting now"
+        reboot now
+        exit
+    fi
 fi
 
 fi
 
-#for dev in ${devs[@]}; do