-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyastfli
executable file
·296 lines (273 loc) · 9.19 KB
/
yastfli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2024-2025, Manuel Fombuena <[email protected]>
#
# yastfli - Yet Another Script To Flash LiveOS ISOs
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
export PATH=/sbin:/usr/sbin:$PATH
### HELP STARTS ###
usage() {
echo "
SYNTAX
(sudo) yastfli [options] --iso <path> --target <device>
OPTIONS
--directory|-d
Use a directory overlay instead of an image file.
It can't be used with fat32. Size option would be ignored.
Default is false.
--filesystem|-f [ext4|fat32]
Filesystem of the data partition.
Default is ext4.
--iso|-i
Path to Live ISO file.
--label|-l
Label of the data partition.
Default is LIVE.
--no-overlay|-n
Don't create an overlay.
Default is false.
--preserve|-p
Don't format EFI and data partitions.
Delete EFI, images and LiveOS folders instead. Deletes overlay.
Default is false.
--size-mb|-s
Size in MB of the overlay file.
It can't be more than 4095 for fat32 data partitions.
Default is 512.
--target|-t
Target device e.g. /dev/sda.
--help|-h
This help.
"
exit 1
}
### HELP ENDS ###
### root CHECK STARTS ###
if [[ $(id -u) -ne 0 ]]; then
echo "ERROR: yastfli must be run as root"
exit 1
fi
### root CHECK ENDS ###
### VARIABLE INITIALIZATION STARTS ###
datafs='ext4'
dirovl=false
iso=''
label='LIVE'
nofmt=false
noovl=false
size=512
tgt=''
green='\033[0;32m'
nc='\033[0m' # no color
### VARIABLE INITIALIZATION ENDS ###
### ARGUMENT PROCESSING STARTS ###
while true ; do
case $1 in
--help|-h)
usage
;;
--directory|-d)
dirovl=true
shift 0
;;
--filesystem|-f)
datafs="${2}"
shift
;;
--iso|-i)
iso="${2}"
shift
;;
--label|-l)
label="${2}"
shift
;;
--no-overlay|-n)
noovl=true
shift 0
;;
--preserve|-p)
nofmt=true
shift 0
;;
--size-mb|-s)
size="${2}"
shift
;;
--target|-t)
tgt="${2}"
shift
;;
--*|-*)
echo "ERROR: invalid syntax. Use -h for help"
exit 1
;;
*)
break
esac
shift
done
### ARGUMENT PROCESSING ENDS ###
### ARGUMENT HANDLING STARTS ###
[[ "${tgt}" = *?[0-9] ]] && tgtp1="${tgt}"p1 || tgtp1="${tgt}"1 # e.g. /dev/mmcblk0p1 || /dev/sda1
[[ "${tgt}" = *?[0-9] ]] && tgtp2="${tgt}"p2 || tgtp2="${tgt}"2 # e.g. /dev/mmcblk0p2 || /dev/sda2
[[ -n "${tgt}" && -n $(parted -s "${tgtp1}" print 2>/dev/null | grep fat32) ]] && tgtp1fs="fat32"
[[ -n "${tgt}" && -n $(parted -s "${tgtp2}" print 2>/dev/null | grep ext4) ]] && tgtp2fs="ext4"
[[ -n "${tgt}" && -n $(parted -s "${tgtp2}" print 2>/dev/null | grep fat32) ]] && tgtp2fs="fat32"
if [[ -z "${iso}" || -z "${tgt}" ]]; then
echo "ERROR: invalid syntax. You need at least -i <iso> -t <device>"
exit 1
elif ! [[ -f "${iso}" ]]; then
echo "ERROR: ISO file "${iso}" doesn't exist"
exit 1
elif ! [[ -b "${tgt}" ]]; then
echo "ERROR: "${tgt}" not present"
exit 1
elif [[ "${datafs}" != "ext4" && "${datafs}" != "fat32" ]]; then
echo "ERROR: invalid data partition filesystem "${datafs}". It can only be ext4 or fat32"
exit 1
elif [[ ${nofmt} == true && \
(( "${tgtp1fs}" != "fat32" ) || ("${tgtp2fs}" != "ext4" && "${tgtp2fs}" != "fat32" )) ]]; then
echo "ERROR: preserve mode can't be used with this device. Was yastfli used to create the Live OS?"
exit 1
elif [[ ( "${datafs}" == "fat32" || "${tgtp2fs}" == "fat32" ) && \
${dirovl} == true && ${noovl} == false ]]; then
echo "ERROR: directory overlay can't be used with fat32 on "${tgtp2}""
exit 1
fi
if [[ ${nofmt} == true ]]; then
echo "INFO: filesystem on "${tgtp2}" is "${tgtp2fs}"."
datafs="${tgtp2fs}"
fi
if [[ "${datafs}" == "fat32" && ${size} -gt 4095 && ${noovl} == false ]]; then
echo "INFO: fat32 can't hold an overlay of "${size}"M. Reduced to 4095M"
size=4095
elif [[ ${noovl} == true ]]; then
echo "INFO: overlay set no. Any overlay options will be ignored"
fi
### ARGUMENT HANDLING ENDS ###
### DEVICE PREP STARTS ###
ls "${tgt}"* | xargs -n1 umount -l >/dev/null 2>&1
isoloop=$(losetup -Pf "${iso}" --show)
isodata=$(mktemp -d)
mount "${isoloop}" "${isodata}" >/dev/null 2>&1
### DEVICE PREP ENDS ###
### EFI PARTITION STARTS ###
if [[ ${nofmt} != true ]]; then # format on normal mode
echo -e "${green}[1/7]${nc} formatting EFI partition"
parted -s "${tgt}" mklabel gpt
parted -s "${tgt}" mkpart '"EFI System Partition"' fat32 1MiB 257MiB
parted -s "${tgt}" set 1 esp on
mkfs.fat -n ESP -F32 "${tgtp1}" &> /dev/null
fsck.fat -aVw "${tgtp1}" &> /dev/null
fi
espmnt=$(mktemp -d)
mount "${tgtp1}" "${espmnt}"
if [[ ${nofmt} == true ]]; then # delete folders on preserve mode
echo -e "${green}[1/7]${nc} preserving EFI partition. Deleting EFI and images folders"
rm -fr "${espmnt}"/{"EFI","images"}
sync -f "${espmnt}"/
fi
echo -e "${green}[2/7]${nc} copying data to EFI partition"
rsync -a --progress "${isodata}"/{"EFI","images"} "${espmnt}"/
echo "INFO: syncing filesystem writes to disk. Please wait"
sync -f "${espmnt}"/
### EFI PARTITION ENDS ###
### DATA PARTITION STARTS ###
if [[ ${nofmt} != true ]]; then # format on normal mode
echo -e "${green}[3/7]${nc} formatting "${label}" partition"
parted -s "${tgt}" mkpart '"Main Data Partition"' "${datafs}" 257MiB 100%
case "${datafs}" in
ext4)
mkfs.ext4 -F -L "${label}" -O ^64bit -j "${tgtp2}" &> /dev/null
tune2fs -c0 -i0 -ouser_xattr,acl "${tgtp2}" &> /dev/null
e2fsck -yf "${tgtp2}" &> /dev/null
;;
fat32)
mkfs.fat -n "${label}" -F32 "${tgtp2}" &> /dev/null
fsck.fat -aVw "${tgtp2}" &> /dev/null
;;
*)
echo "ERROR: invalid "${label}" file system "${datafs}". It can only be ext4 or fat32"
exit 1
;;
esac
fi
datamnt=$(mktemp -d)
mount "${tgtp2}" "${datamnt}"
if [[ ${nofmt} == true ]]; then # delete folders on preserve mode
echo -e "${green}[3/7]${nc} preserving "${label}" partition. Deleting LiveOS folder"
rm -fr "${datamnt}"/LiveOS
sync -f "${datamnt}"/
fi
echo -e "${green}[4/7]${nc} copying data to "${label}" partition"
rsync -a --progress --exclude={"EFI","images","boot"} "${isodata}/" "${datamnt}"
echo "INFO: syncing filesystem writes to disk. This may take a while..."
sync -f "${datamnt}"/
### DATA PARTITION ENDS ###
### OVERLAY STARTS ###
tgtuuid=($(lsblk -no UUID "${tgtp2}" || :)) # out of if statement because it's always needed
if [[ ${noovl} != true ]]; then # create on normal mode
tgtlabel=($(lsblk -no LABEL "${tgtp2}" || :))
tgtfile=overlay-"${tgtlabel}"-"${tgtuuid}"
ovlpath="${datamnt}"/LiveOS/"${tgtfile}"
echo -e "${green}[5/7]${nc} initializing persistent overlay LiveOS/"${tgtfile}" on "${tgtp2}""
if [[ ${dirovl} == true && "${datafs}" == "ext4" ]]; then
mkdir -m 0755 --context=system_u:object_r:root_t:s0 $datamnt/LiveOS/overlayfs $datamnt/LiveOS/ovlwork
else
truncate -s 0 "${ovlpath}"
[[ "${datafs}" == "fat32" ]] && \
echo "INFO: allocating disk space for overlay file. This may take a while"
fallocate -x -l ${size}M "${ovlpath}"
[[ "${datafs}" == "fat32" ]] && \
echo "INFO: syncing filesystem writes to disk"
sync -f "${ovlpath}"
mkfs.ext4 -F -L OVERLAY -O ^64bit -j -E nodiscard "${ovlpath}" &> /dev/null
tune2fs -c0 -i0 -ouser_xattr,acl "${ovlpath}" &> /dev/null
e2fsck -yf "${ovlpath}" &> /dev/null
ovl=$(mktemp -d)
mount "${ovlpath}" "${ovl}"
mkdir -m 0755 --context=system_u:object_r:root_t:s0 $ovl/overlayfs $ovl/ovlwork
umount $ovl
chmod 0600 "${ovlpath}" &> /dev/null || :
fi
else
echo -e "${green}[5/7]${nc} skipping persistent overlay initialization"
fi
### OVERLAY ENDS ###
### GRUB STARTS ###
echo -e "${green}[6/7]${nc} updating EFI/BOOT/grub.cfg on "${tgtp1}""
isolabel=($(lsblk -no LABEL "${isoloop}" || :))
sed -i -r "s/root=live:CDLABEL="${isolabel}"/root=live:UUID="${tgtuuid}"/" "${espmnt}"/EFI/BOOT/grub.cfg
sed -i -r "s/set default=\"1\"/set default=\"0\"/" "${espmnt}"/EFI/BOOT/grub.cfg
if [[ ${noovl} != true ]]; then # update on normal mode
if [[ ${dirovl} == true && "${datafs}" == "ext4" ]]; then
sed -i -r "s/rd\.live\.image|liveimg/& rd.live.overlay=UUID="${tgtuuid}":\/LiveOS\/overlayfs rd.live.overlay.overlayfs/" "${espmnt}"/EFI/BOOT/grub.cfg
else
sed -i -r "s/rd\.live\.image|liveimg/& rd.live.overlay=UUID="${tgtuuid}" rd.live.overlay.overlayfs/" "${espmnt}"/EFI/BOOT/grub.cfg
fi
fi
### GRUB ENDS ###
### CLEAN UP STARTS ###
echo -e "${green}[7/7]${nc} cleaning up"
umount "${isoloop}"
losetup -d "${isoloop}"
umount "${espmnt}"
umount "${datamnt}"
eject "${tgt}"
udisksctl power-off -b "${tgt}"
echo "INFO: finished. You can unplug your device now"
### CLEAN UP ENDS ###