Skip to content

Commit bac2848

Browse files
committed
Module partitioner: frontend for new armbian-install
1 parent 5bfd0a7 commit bac2848

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
declare -A module_options
2+
module_options+=(
3+
["module_partitioner,author"]="@igorpecovnik"
4+
["module_partitioner,maintainer"]="@igorpecovnik"
5+
["module_partitioner,feature"]="module_partitioner"
6+
["module_partitioner,example"]="new run create delete show getroot autoinstall help"
7+
["module_partitioner,desc"]="Partitioner manager TUI"
8+
["module_partitioner,status"]="review"
9+
["module_partitioner,doc_link"]="https://docs.armbian.com"
10+
["module_partitioner,group"]="System"
11+
["module_partitioner,port"]=""
12+
["module_partitioner,arch"]=""
13+
)
14+
15+
function module_partitioner() {
16+
local title="Partitioner"
17+
local condition=$(which "$title" 2>/dev/null)
18+
19+
# Read boot loader functions
20+
[[ -f /usr/lib/u-boot/platform_install.sh ]] && source /usr/lib/u-boot/platform_install.sh
21+
22+
# Start mtdcheck with probable MTD block device partitions:
23+
mtdcheck=$(grep 'mtdblock' /proc/partitions | awk '{print $NF}' | xargs)
24+
# Append mtdcheck with probable MTD char devices filtered for partition name(s)
25+
# containing "spl" or "boot" case insensitive,
26+
# since we are currently interested in MTD partitions for boot flashing only.
27+
# Note: The following statement will add matching MTD char device names
28+
# combined with partition name (separated from devicename by a :colon:):
29+
# mtd0:partition0_name mtd1:partition1_name ... mtdN:partitionN_name
30+
[[ -f /proc/mtd ]] && mtdcheck="$mtdcheck${mtdcheck:+ }$(grep -i -E '^mtd[0-9]+:.*(spl|boot).*' /proc/mtd | awk '{print $1$NF}' | sed 's/\"//g' | xargs)"
31+
32+
apt -y install ntfs-3g bc
33+
34+
# Convert the example string to an array
35+
local commands
36+
IFS=' ' read -r -a commands <<< "${module_options["module_partitioner,example"]}"
37+
38+
case "$1" in
39+
"${commands[0]}")
40+
echo "Install to partition $2"
41+
exit
42+
;;
43+
"${commands[1]}")
44+
45+
while true; do
46+
47+
# get all available targets
48+
${module_options["module_partitioner,feature"]} ${commands[4]}
49+
50+
list=()
51+
periodic=1
52+
while IFS== read key value; do
53+
case "$key" in
54+
"name") name="$value" ;;
55+
"size") size=$(printf "%14s" "$value") ;;
56+
"type") type=$(printf "%4s" "$value") ;;
57+
"fsused") fsused="$value" ;;
58+
"fstype") fstype="$value" ;;
59+
"mountpoint") mountpoint="$value" ;;
60+
esac
61+
if [ "$(($periodic % 6))" -eq 0 ]; then
62+
if [[ "$type" == "disk" ]]; then
63+
# recognize devices features
64+
driveinfo=$(udevadm info --query=all --name=$name | grep 'ID_MODEL=' | cut -d"=" -f2 | sed "s/_/ /g")
65+
drivebus=$(udevadm info --query=all --name=$name | grep 'ID_BUS=' | cut -d"=" -f2 | sed "s/_/ /g")
66+
[[ $name == *mtdb* ]] && driveinfo="SPI flash"
67+
[[ $name == *nvme* ]] && driveinfo="M2 NVME solid state drive $driveinfo"
68+
# if smartmontools are installed, lets query more info
69+
if [[ $name == *nvme* ]] && command -v smartctl >/dev/null; then
70+
mapfile -t array < <(smartctl -ija $name | jq -r '
71+
.model_name,
72+
.nvme_smart_health_information_log.data_units_written,
73+
.temperature.current'
74+
)
75+
tbw=$(echo ${array[1]} | awk '{ printf "%.0f\n", $1*500/1024/1024/1024; }')""
76+
temperature=$(echo ${array[2]})""
77+
driveinfo="${array[0]} | TBW: ${tbw} | Temperature: ${temperature}"
78+
fi
79+
[[ $name == *mmc* ]] && driveinfo="eMMC or SD card"
80+
[[ $name == *sd* && $drivebus == usb ]] && driveinfo="USB storage $driveinfo"
81+
list+=("${name}" "$(printf "%-30s%12s" $name $size)" "$driveinfo")
82+
fi # type is disk
83+
fi
84+
periodic=$(($periodic + 1))
85+
done <<< "$devices"
86+
87+
list_length=$((${#list[@]} / 3))
88+
selected_disk=$(dialog \
89+
--notags \
90+
--cancel-label "Cancel" \
91+
--ok-label "Install" \
92+
--extra-button \
93+
--extra-label "Advanced" \
94+
--erase-on-exit \
95+
--item-help \
96+
--title "Select destination drive" \
97+
--menu "\n Storage device Size" \
98+
$((${list_length} + 8)) 48 $((${list_length} + 1)) \
99+
"${list[@]}" 3>&1 1>&2 2>&3)
100+
exitstatus=$?
101+
102+
case "$exitstatus" in
103+
0) ${module_options["module_partitioner,feature"]} ${commands[5]} # auto install
104+
;;
105+
1) break
106+
;;
107+
3)
108+
# drive partitioning
109+
devices=$(
110+
lsblk -Alnp -io NAME,SIZE,FSUSED,TYPE,FSTYPE,MOUNTPOINT -e 252 --json \
111+
| jq --arg selected_disk "$selected_disk" '.blockdevices[]?
112+
| select((.name | test ($selected_disk))
113+
and (.name | test ("mtdblock0|nvme|mmcblk|sd"))
114+
and (.name | test ("boot") | not ))' \
115+
| jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]'
116+
)
117+
list=()
118+
periodic=1
119+
while IFS== read key value; do
120+
case "$key" in
121+
"name") name="$value" ;;
122+
"size") size=$(printf "%14s" "$value") ;;
123+
"type") type=$(printf "%4s" "$value") ;;
124+
"fsused") fsused="$value" ;;
125+
"fstype") fstype="$value" ;;
126+
"mountpoint") mountpoint="$value" ;;
127+
esac
128+
if [ "$(($periodic % 6))" -eq 0 ]; then
129+
if [[ "$type" == "part" ]]; then
130+
#echo "$periodic $name $size $type $fsused $fstype $mountpoint"
131+
driveinfo=$(udevadm info --query=all --name=$name | grep 'ID_MODEL=' | cut -d"=" -f2 | sed "s/_/ /g")
132+
drivebus=$(udevadm info --query=all --name=$name | grep 'ID_BUS=' | cut -d"=" -f2 | sed "s/_/ /g")
133+
[[ $fstype == null ]] && fstype=""
134+
[[ $fsused == null ]] && fsused=""
135+
[[ $name == *mtdb* ]] && driveinfo="SPI flash"
136+
[[ $name == *nvme* ]] && driveinfo="M2 NVME solid state drive $driveinfo"
137+
[[ $name == *mmc* ]] && driveinfo="eMMC or SD card"
138+
[[ $name == *sd* && $drivebus == usb ]] && driveinfo="USB storage $driveinfo"
139+
list+=("${name}" "$(printf "%-10s%14s%9s%9s" ${name} ${fstype} ${size} ${fsused})" "$driveinfo")
140+
fi
141+
fi
142+
periodic=$(($periodic + 1))
143+
done <<< "$devices"
144+
;;
145+
esac
146+
list_length=$((${#list[@]} / 3))
147+
partitioner=$(dialog \
148+
--notags \
149+
--cancel-label "Cancel" \
150+
--ok-label "Install" \
151+
--erase-on-exit \
152+
--extra-button \
153+
--item-help \
154+
--extra-label "Manage" \
155+
--title "Select or manage partitions" \
156+
--menu "\n Partition FS type Size Used" \
157+
$((${list_length} + 8)) 48 $((${list_length} + 1)) \
158+
"${list[@]}" 3>&1 1>&2 2>&3)
159+
exitstatus=$?
160+
case "$exitstatus" in
161+
*) ${module_options["module_partitioner,feature"]} ${commands[${exitstatus}]} $partitioner ;;
162+
1) break ;;
163+
esac
164+
done
165+
;;
166+
"${commands[2]}")
167+
echo "Select $3"
168+
exit
169+
;;
170+
"${commands[3]}")
171+
# get additional info from partition
172+
local size=$(lsblk -Alnbp -io SIZE $2 | xargs -I {} echo "scale=0;{}/1024/1024/1024" | bc -l)
173+
local fstype=$(lsblk -Alnbp -io FSTYPE $2)
174+
local minimal=$(ntfsresize --info $2 -m | tail -1 | grep -Eo '[0-9]{1,10}' | xargs -I {} echo "scale=0;{}/1024" | bc -l)
175+
while true; do
176+
shrinkedsize=$(dialog --title "Shrinking $fstype partition $2" \
177+
--inputbox "\nValid size between ${minimal}-${size} GB" 9 50 "$(( minimal + size / 2 ))" 3>&1 1>&2 2>&3)
178+
exitstatus=$?
179+
if [[ $shrinkedsize -ge $minimal ]]; then
180+
break
181+
fi
182+
done
183+
ntfsresize --no-action --size "${shrinkedsize}G" $2 >/dev/null
184+
if [[ $exitstatus -ne 1 && $? -eq 0 ]]; then
185+
ntfsresize -f --size "${shrinkedsize}G" $2
186+
fi
187+
read
188+
# Removal logic here
189+
;;
190+
"${commands[4]}")
191+
#recognize_root
192+
root_uuid=$(sed -e 's/^.*root=//' -e 's/ .*$//' < /proc/cmdline)
193+
root_partition=$(blkid | tr -d '":' | grep "${root_uuid}" | awk '{print $1}')
194+
root_partition_name=$(echo $root_partition | sed 's/\/dev\///g')
195+
root_partition_device_name=$(lsblk -ndo pkname $root_partition)
196+
root_partition_device=/dev/$root_partition_device_name
197+
# list all devices except rootfs
198+
devices=$(
199+
lsblk -Alnp -io NAME,SIZE,FSUSED,TYPE,FSTYPE,MOUNTPOINT -e 252 --json \
200+
| jq --arg root_partition_device "$root_partition_device" '.blockdevices[]?
201+
| select((.name | test ($root_partition_device) | not)
202+
and (.name | test ("mtdblock0|nvme|mmcblk|sd"))
203+
and (.name | test ("boot|mtdb") | not ))' \
204+
| jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]'
205+
)
206+
;;
207+
"${commands[6]}")
208+
209+
if [[ $(type -t write_uboot_platform_mtd) == function ]]; then
210+
dialog --title "$title" --backtitle "$backtitle" --yesno \
211+
"Do you want to write the bootloader to MTD Flash?\n\nIt is required if you have not done it before or if you have some non-Armbian bootloader in this flash." 8 60
212+
213+
if [[ $? -eq 0 ]]; then
214+
write_uboot_to_mtd_flash "$DIR" "$mtdcheck"
215+
fi
216+
fi
217+
218+
echo "Delete $2"
219+
read
220+
# Removal logic here
221+
;;
222+
"${commands[7]}")
223+
echo -e "\nUsage: ${module_options["module_partitioner,feature"]} <command>"
224+
echo -e "Commands: ${module_options["module_partitioner,example"]}"
225+
echo "Available commands:"
226+
echo -e "\trun\t- Run $title."
227+
echo
228+
;;
229+
*)
230+
${module_options["module_partitioner,feature"]} ${commands[7]}
231+
;;
232+
esac
233+
}
234+
235+
# uncomment to test the module
236+
module_partitioner "$1"
237+
238+
239+
240+

0 commit comments

Comments
 (0)