-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathutils.sh
234 lines (179 loc) · 5.36 KB
/
utils.sh
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
# vim: set ts=4:
ROOT_DIR="$(pwd)/build/raspbian"
die() {
# bold red
printf '\033[1;31mERROR:\033[0m %s\n' "$1" >&2
shift
printf ' %s\n' "$@"
exit 2
}
einfo() {
# bold cyan
printf '\033[1;36m> %s\033[0m\n' "$@" >&2
}
ewarn() {
# bold yellow
printf '\033[1;33m> %s\033[0m\n' "$@" >&2
}
_step_counter=0
step() {
_step_counter=$(( _step_counter + 1 ))
printf '\n\033[1;36m%d) %s\033[0m\n' $_step_counter "$@" >&2 # bold cyan
}
has() {
command -v "$1" >/dev/null 2>&1
}
check_is_run_as_root() {
if [ "$EUID" -ne 0 ]; then
die "Please run as root"
fi
}
check_commands() {
for command in $@; do
has "$command" && continue
die "$command is not installed."
done
}
check_sha256_sum() {
# usage: check_sha256_sum file_path sha256
if ! echo "$2 $1" | sha256sum --check --status; then
die "Bad sha256"
fi
}
img_resize() {
# usage: img_resize img_path size_in_MB
dd if=/dev/zero bs=1M count=$(($2 + 1)) >> "$1"
parted_output=$(parted -ms "$1" unit MB print | tail -n 1)
partstart=$(echo "$parted_output" | cut -d ':' -f 2 | tr -d 'MB')
partend=$(echo "$parted_output" | cut -d ':' -f 3 | tr -d 'MB')
# echo "$partstart $partend"
loopback=$(losetup -f -P --show "$1")
# parted $loopback unit MB print
parted $loopback rm 2
parted $loopback unit MB mkpart primary $partstart $(($partend + $2))
e2fsck -y -f "$loopback"p2
resize2fs "$loopback"p2
# parted $loopback unit MB print
losetup -d "$loopback"
}
img_mount() {
# usage: mount_img img_path
if is_mounted "${ROOT_DIR}/boot"; then
img_umount "$1"
fi
kpart_output=$(kpartx -v -a -s "$1")
loop_boot=/dev/mapper/$(echo "$kpart_output" | awk 'NR==1{print $3}')
loop_root=/dev/mapper/$(echo "$kpart_output" | awk 'NR==2{print $3}')
while ! check_loops "${IMAGE}"; do
echo "Waiting for loop devices"
sleep 1
done
mkdir -p "$ROOT_DIR"
mount -o rw "${loop_root}" "${ROOT_DIR}"
mount -o rw "${loop_boot}" "${ROOT_DIR}/boot"
while ! is_mounted "${ROOT_DIR}/boot"; do
echo "Waiting for mount"
sleep 1
done
}
img_umount() {
kpart_output=$(kpartx -v -a -s "$1")
loop_root=/dev/mapper/$(echo "$kpart_output" | awk 'NR==2{print $3}')
umount -l "${ROOT_DIR}/boot"
while is_mounted "${ROOT_DIR}/boot"; do
sleep 1
done
umount -l "${ROOT_DIR}"
while is_mounted "${ROOT_DIR}"; do
sleep 1
done
rmdir "${ROOT_DIR}"
kpartx -d -v "${IMAGE}"
while check_loops "${IMAGE}"; do
sleep 1
done
echo "Unmounted"
}
is_mounted() {
mount | awk -v DIR="$1" '{if ($3 == DIR) { exit 0}} ENDFILE{exit -1}'
}
check_loops() {
losetup -l | grep -q "$(basename "$1")"
}
chroot_enable() {
# # uncoment for use command chroot
# mount --bind /dev "${ROOT_DIR}/dev/"
# mount --bind /dev/pts "${ROOT_DIR}/dev/pts"
# mount --bind /sys "${ROOT_DIR}/sys/"
# mount -t proc proc "${ROOT_DIR}/proc/"
# mount --bind /etc/resolv.conf "${ROOT_DIR}/etc/resolv.conf"
cp /usr/bin/qemu-arm-static "${ROOT_DIR}/usr/bin"
cp ${ROOT_DIR}/bin/true ${ROOT_DIR}/usr/bin/ischroot
sed -i 's/^\//#CHROOT \//g' "${ROOT_DIR}/etc/ld.so.preload"
echo "Disable IPv6 in APT"
echo 'Acquire::ForceIPv4 "true";' >> "$ROOT_DIR/etc/apt/apt.conf.d/99force-ipv4"
echo "Modify source.list"
}
chroot_disable() {
echo "Enable IPv6 in APT"
rm "$ROOT_DIR/etc/apt/apt.conf.d/99force-ipv4"
echo "Remove modify source.list"
sed -r -i'' "s/reflection.oss.ou.edu\/raspbian\/raspbian/raspbian.raspberrypi.org\/raspbian/g" "$ROOT_DIR/etc/apt/sources.list"
rm -f "${ROOT_DIR}/usr/bin/qemu-arm-static"
rm -f "${ROOT_DIR}/usr/bin/ischroot"
sed -i 's/^#CHROOT //g' "${ROOT_DIR}/etc/ld.so.preload"
}
chroot_bash() {
systemd-nspawn -D "${ROOT_DIR}" -E HOME=/home/pi -E LC_ALL='C.UTF-8' --pipe -u 1000 bin/bash
}
chroot_cmd() {
echo "$@" | chroot_bash
}
img_shrink() {
beforesize=$(ls -lh "$1" | cut -d ' ' -f 5)
parted_output=$(parted -ms "$1" unit B print | tail -n 1)
partnum=$(echo "$parted_output" | cut -d ':' -f 1)
partstart=$(echo "$parted_output" | cut -d ':' -f 2 | tr -d 'B')
loopback=$(losetup -f --show -o $partstart "$1")
tune2fs_output=$(tune2fs -l "$loopback")
currentsize=$(echo "$tune2fs_output" | grep '^Block count:' | tr -d ' ' | cut -d ':' -f 2)
blocksize=$(echo "$tune2fs_output" | grep '^Block size:' | tr -d ' ' | cut -d ':' -f 2)
#Make sure filesystem is ok
e2fsck -p -f "$loopback"
minsize=$(resize2fs -P "$loopback" | cut -d ':' -f 2 | tr -d ' ')
if [[ $currentsize -eq $minsize ]]; then
echo "Image already shrunk to smallest size"
echo "currentsize: $currentsize minsize: $minsize"
losetup -d "$loopback"
return 0
fi
#Add some free space to the end of the filesystem
extra_space=$(($currentsize - $minsize))
for space in 5000 1000 100; do
if [[ $extra_space -gt $space ]]; then
minsize=$(($minsize + $space))
break
fi
done
#Shrink filesystem
resize2fs -p "$loopback" $minsize
if [[ $? != 0 ]]; then
losetup -d "$loopback"
die "ERROR: resize2fs failed..."
fi
losetup -d "$loopback"
while ! check_loops "${IMAGE}"; do
echo "Waiting for loop devices"
sleep 1
done
#Shrink partition
partnewsize=$(($minsize * $blocksize))
newpartend=$(($partstart + $partnewsize))
parted -s -a minimal "$1" rm $partnum >/dev/null
parted -s "$1" unit B mkpart primary $partstart $newpartend >/dev/null
#Truncate the file
endresult=$(parted -ms "$1" unit B print free | tail -1 | cut -d ':' -f 2 | tr -d 'B')
truncate -s $endresult "$1"
aftersize=$(ls -lh "$1" | cut -d ' ' -f 5)
echo "Shrunk $1 from $beforesize to $aftersize"
}