root / snf-image-helper / common.sh @ 365b2ed3
History | View | Annotate | Download (14.9 kB)
1 | fcae4e91 | Nikos Skalkotos | # Copyright (C) 2011, 2012, 2013 GRNET S.A. |
---|---|---|---|
2 | 7e5d635b | Nikos Skalkotos | # Copyright (C) 2007, 2008, 2009 Google Inc. |
3 | 54080484 | Nikos Skalkotos | # |
4 | 7e5d635b | Nikos Skalkotos | # This program is free software; you can redistribute it and/or modify |
5 | 7e5d635b | Nikos Skalkotos | # it under the terms of the GNU General Public License as published by |
6 | 7e5d635b | Nikos Skalkotos | # the Free Software Foundation; either version 2 of the License, or |
7 | 7e5d635b | Nikos Skalkotos | # (at your option) any later version. |
8 | 54080484 | Nikos Skalkotos | # |
9 | 7e5d635b | Nikos Skalkotos | # This program is distributed in the hope that it will be useful, but |
10 | 7e5d635b | Nikos Skalkotos | # WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | 7e5d635b | Nikos Skalkotos | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | 7e5d635b | Nikos Skalkotos | # General Public License for more details. |
13 | 54080484 | Nikos Skalkotos | # |
14 | 7e5d635b | Nikos Skalkotos | # You should have received a copy of the GNU General Public License |
15 | 7e5d635b | Nikos Skalkotos | # along with this program; if not, write to the Free Software |
16 | 7e5d635b | Nikos Skalkotos | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 7e5d635b | Nikos Skalkotos | # 02110-1301, USA. |
18 | 54080484 | Nikos Skalkotos | |
19 | f6e23601 | Nikos Skalkotos | PROGNAME=$(basename $0) |
20 | 54080484 | Nikos Skalkotos | |
21 | 8cd155a3 | Nikos Skalkotos | PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin |
22 | 8cd155a3 | Nikos Skalkotos | |
23 | 54080484 | Nikos Skalkotos | # Programs |
24 | 54080484 | Nikos Skalkotos | XMLSTARLET=xmlstarlet |
25 | b97ada71 | Nikos Skalkotos | TUNE2FS=tune2fs |
26 | c349d1b3 | Nikos Skalkotos | RESIZE2FS=resize2fs |
27 | 42f09a19 | Nikos Skalkotos | PARTED=parted |
28 | b126203e | Nikos Skalkotos | SFDISK=sfdisk |
29 | bc9d337a | Nikos Skalkotos | MKSWAP=mkswap |
30 | bc9d337a | Nikos Skalkotos | BLKID=blkid |
31 | 8576747b | Nikos Skalkotos | BLOCKDEV=blockdev |
32 | ec728294 | Nikos Skalkotos | REGLOOKUP=reglookup |
33 | ec728294 | Nikos Skalkotos | CHNTPW=chntpw |
34 | b0cb7802 | Nikos Skalkotos | SGDISK=sgdisk |
35 | b1cb73f2 | Nikos Skalkotos | GROWFS_UFS=growfs.ufs |
36 | 1876c955 | Nikos Skalkotos | DUMPFS_UFS=dumpfs.ufs |
37 | 365b2ed3 | Nikos Skalkotos | GROWFS_OPENBSD=growfs.openbsd |
38 | 365b2ed3 | Nikos Skalkotos | DUMPFS_OPENBSD=dumpfs.openbsd |
39 | 603c05f7 | Nikos Skalkotos | DATE="date -u" # Time in UTC |
40 | beeb8f9f | Nikos Skalkotos | EATMYDATA=eatmydata |
41 | 107e56e0 | Nikos Skalkotos | MOUNT="mount -n" |
42 | 54080484 | Nikos Skalkotos | |
43 | 54080484 | Nikos Skalkotos | CLEANUP=( ) |
44 | 2a0ab295 | Nikos Skalkotos | ERRORS=( ) |
45 | 2a0ab295 | Nikos Skalkotos | WARNINGS=( ) |
46 | 54080484 | Nikos Skalkotos | |
47 | f32664b2 | Nikos Skalkotos | MSG_TYPE_TASK_START="TASK_START" |
48 | f32664b2 | Nikos Skalkotos | MSG_TYPE_TASK_END="TASK_END" |
49 | f32664b2 | Nikos Skalkotos | |
50 | f32664b2 | Nikos Skalkotos | STDERR_LINE_SIZE=10 |
51 | a50a2bff | Nikos Skalkotos | |
52 | fcae4e91 | Nikos Skalkotos | add_cleanup() { |
53 | fcae4e91 | Nikos Skalkotos | local cmd="" |
54 | fcae4e91 | Nikos Skalkotos | for arg; do cmd+=$(printf "%q " "$arg"); done |
55 | fcae4e91 | Nikos Skalkotos | CLEANUP+=("$cmd") |
56 | fcae4e91 | Nikos Skalkotos | } |
57 | 72052003 | Dimitris Aragiorgis | |
58 | fcae4e91 | Nikos Skalkotos | close_fd() { |
59 | fcae4e91 | Nikos Skalkotos | local fd=$1 |
60 | fcae4e91 | Nikos Skalkotos | |
61 | fcae4e91 | Nikos Skalkotos | exec {fd}>&- |
62 | 72052003 | Dimitris Aragiorgis | } |
63 | 72052003 | Dimitris Aragiorgis | |
64 | d509231b | Nikos Skalkotos | send_result_kvm() { |
65 | d509231b | Nikos Skalkotos | echo "$@" > /dev/ttyS1 |
66 | d509231b | Nikos Skalkotos | } |
67 | d509231b | Nikos Skalkotos | |
68 | d509231b | Nikos Skalkotos | send_monitor_message_kvm() { |
69 | d509231b | Nikos Skalkotos | echo "$@" > /dev/ttyS2 |
70 | d509231b | Nikos Skalkotos | } |
71 | d509231b | Nikos Skalkotos | |
72 | d509231b | Nikos Skalkotos | send_result_xen() { |
73 | d509231b | Nikos Skalkotos | xenstore-write /local/domain/0/snf-image-helper/$DOMID "$*" |
74 | d509231b | Nikos Skalkotos | } |
75 | d509231b | Nikos Skalkotos | |
76 | d509231b | Nikos Skalkotos | send_monitor_message_xen() { |
77 | b2592d38 | Nikos Skalkotos | #Broadcast the message |
78 | 21063d2d | Nikos Skalkotos | echo "$@" | socat "STDIO" "UDP-DATAGRAM:${BROADCAST}:${MONITOR_PORT},broadcast" |
79 | d509231b | Nikos Skalkotos | } |
80 | d509231b | Nikos Skalkotos | |
81 | fcae4e91 | Nikos Skalkotos | prepare_helper() { |
82 | fcae4e91 | Nikos Skalkotos | local cmdline item key val hypervisor domid |
83 | 72052003 | Dimitris Aragiorgis | |
84 | fcae4e91 | Nikos Skalkotos | read -a cmdline < /proc/cmdline |
85 | fcae4e91 | Nikos Skalkotos | for item in "${cmdline[@]}"; do |
86 | 21063d2d | Nikos Skalkotos | key=$(cut -d= -f1 <<< "$item") |
87 | 21063d2d | Nikos Skalkotos | val=$(cut -d= -f2 <<< "$item") |
88 | 21063d2d | Nikos Skalkotos | if [ "$key" = "hypervisor" ]; then |
89 | 21063d2d | Nikos Skalkotos | hypervisor="$val" |
90 | 21063d2d | Nikos Skalkotos | fi |
91 | 21063d2d | Nikos Skalkotos | if [ "$key" = "rules_dev" ]; then |
92 | 21063d2d | Nikos Skalkotos | export RULES_DEV="$val" |
93 | 21063d2d | Nikos Skalkotos | fi |
94 | 21063d2d | Nikos Skalkotos | if [ "$key" = "helper_ip" ]; then |
95 | 21063d2d | Nikos Skalkotos | export IP="$val" |
96 | 21063d2d | Nikos Skalkotos | export NETWORK="$IP/24" |
97 | 21063d2d | Nikos Skalkotos | export BROADCAST="${IP%.*}.255" |
98 | 21063d2d | Nikos Skalkotos | fi |
99 | 21063d2d | Nikos Skalkotos | if [ "$key" = "monitor_port" ]; then |
100 | 21063d2d | Nikos Skalkotos | export MONITOR_PORT="$val" |
101 | 21063d2d | Nikos Skalkotos | fi |
102 | fcae4e91 | Nikos Skalkotos | done |
103 | fcae4e91 | Nikos Skalkotos | |
104 | fcae4e91 | Nikos Skalkotos | case "$hypervisor" in |
105 | fcae4e91 | Nikos Skalkotos | kvm) |
106 | d509231b | Nikos Skalkotos | HYPERVISOR=kvm |
107 | 1ea8db72 | Dimitris Aragiorgis | ;; |
108 | fcae4e91 | Nikos Skalkotos | xen-hvm|xen-pvm) |
109 | 21063d2d | Nikos Skalkotos | if [ -z "$IP" ]; then |
110 | 21063d2d | Nikos Skalkotos | echo "ERROR: \`helper_ip' not defined or empty" >&2 |
111 | 21063d2d | Nikos Skalkotos | exit 1 |
112 | 21063d2d | Nikos Skalkotos | fi |
113 | 21063d2d | Nikos Skalkotos | if [ -z "$MONITOR_PORT" ]; then |
114 | 21063d2d | Nikos Skalkotos | echo "ERROR: \`monitor_port' not defined or empty" >&2 |
115 | 21063d2d | Nikos Skalkotos | exit 1 |
116 | 21063d2d | Nikos Skalkotos | fi |
117 | d509231b | Nikos Skalkotos | $MOUNT -t xenfs xenfs /proc/xen |
118 | b2592d38 | Nikos Skalkotos | ip addr add "$NETWORK" dev eth0 |
119 | d509231b | Nikos Skalkotos | ip link set eth0 up |
120 | b2592d38 | Nikos Skalkotos | ip route add default dev eth0 |
121 | d509231b | Nikos Skalkotos | export DOMID=$(xenstore-read domid) |
122 | d509231b | Nikos Skalkotos | HYPERVISOR=xen |
123 | fcae4e91 | Nikos Skalkotos | ;; |
124 | fcae4e91 | Nikos Skalkotos | *) |
125 | fcae4e91 | Nikos Skalkotos | echo "ERROR: Unknown hypervisor: \`$hypervisor'" >&2 |
126 | fcae4e91 | Nikos Skalkotos | exit 1 |
127 | 1ea8db72 | Dimitris Aragiorgis | ;; |
128 | 1ea8db72 | Dimitris Aragiorgis | esac |
129 | 72052003 | Dimitris Aragiorgis | |
130 | d509231b | Nikos Skalkotos | export HYPERVISOR |
131 | bad5ca1f | Nikos Skalkotos | } |
132 | bad5ca1f | Nikos Skalkotos | |
133 | 9c4a2181 | Nikos Skalkotos | report_error() { |
134 | d509231b | Nikos Skalkotos | msg="" |
135 | 9c4a2181 | Nikos Skalkotos | if [ ${#ERRORS[*]} -eq 0 ]; then |
136 | 9c4a2181 | Nikos Skalkotos | # No error message. Print stderr |
137 | 7fd2dad2 | Nikos Skalkotos | local lines stderr |
138 | 7fd2dad2 | Nikos Skalkotos | stderr="$(tail --lines=${STDERR_LINE_SIZE} "$STDERR_FILE")" |
139 | 7fd2dad2 | Nikos Skalkotos | lines=$(wc -l <<< "$stderr") |
140 | 7fd2dad2 | Nikos Skalkotos | msg="STDERR:${lines}:$stderr" |
141 | 9c4a2181 | Nikos Skalkotos | else |
142 | 9c4a2181 | Nikos Skalkotos | for line in "${ERRORS[@]}"; do |
143 | d509231b | Nikos Skalkotos | msg+="ERROR:$line"$'\n' |
144 | 9c4a2181 | Nikos Skalkotos | done |
145 | 9c4a2181 | Nikos Skalkotos | fi |
146 | d509231b | Nikos Skalkotos | |
147 | d509231b | Nikos Skalkotos | send_monitor_message_${HYPERVISOR} "$msg" |
148 | 9c4a2181 | Nikos Skalkotos | } |
149 | 9c4a2181 | Nikos Skalkotos | |
150 | 54080484 | Nikos Skalkotos | log_error() { |
151 | 7a7e0f27 | Nikos Skalkotos | ERRORS+=("$*") |
152 | f7a4021c | Nikos Skalkotos | |
153 | d509231b | Nikos Skalkotos | send_result_${HYPERVISOR} "ERROR: $@" |
154 | b3aefbbc | Nikos Skalkotos | |
155 | b3aefbbc | Nikos Skalkotos | # Use return instead of exit. The set -x options will terminate the script |
156 | b3aefbbc | Nikos Skalkotos | # but will also trigger ERR traps if defined. |
157 | b3aefbbc | Nikos Skalkotos | return 1 |
158 | 54080484 | Nikos Skalkotos | } |
159 | 54080484 | Nikos Skalkotos | |
160 | f6e23601 | Nikos Skalkotos | warn() { |
161 | f6e23601 | Nikos Skalkotos | echo "Warning: $@" >&2 |
162 | d509231b | Nikos Skalkotos | send_monitor_message_${HYPERVISOR} "WARNING: $@" |
163 | f6e23601 | Nikos Skalkotos | } |
164 | f6e23601 | Nikos Skalkotos | |
165 | a50a2bff | Nikos Skalkotos | report_task_start() { |
166 | d509231b | Nikos Skalkotos | send_monitor_message_${HYPERVISOR} "$MSG_TYPE_TASK_START:${PROGNAME:2}" |
167 | 2a0ab295 | Nikos Skalkotos | } |
168 | 2a0ab295 | Nikos Skalkotos | |
169 | a50a2bff | Nikos Skalkotos | report_task_end() { |
170 | d509231b | Nikos Skalkotos | send_monitor_message_${HYPERVISOR} "$MSG_TYPE_TASK_END:${PROGNAME:2}" |
171 | 2a0ab295 | Nikos Skalkotos | } |
172 | 2a0ab295 | Nikos Skalkotos | |
173 | b2bffe91 | Nikos Skalkotos | system_poweroff() { |
174 | 81ca2790 | Nikos Skalkotos | while [ 1 ]; do |
175 | 81ca2790 | Nikos Skalkotos | # Credits to psomas@grnet.gr for this ... |
176 | 81ca2790 | Nikos Skalkotos | echo o > /proc/sysrq-trigger |
177 | 81ca2790 | Nikos Skalkotos | sleep 1 |
178 | 81ca2790 | Nikos Skalkotos | done |
179 | 2a0ab295 | Nikos Skalkotos | } |
180 | 2a0ab295 | Nikos Skalkotos | |
181 | 54080484 | Nikos Skalkotos | get_base_distro() { |
182 | 54080484 | Nikos Skalkotos | local root_dir=$1 |
183 | 54080484 | Nikos Skalkotos | |
184 | 54080484 | Nikos Skalkotos | if [ -e "$root_dir/etc/debian_version" ]; then |
185 | 54080484 | Nikos Skalkotos | echo "debian" |
186 | 54080484 | Nikos Skalkotos | elif [ -e "$root_dir/etc/redhat-release" ]; then |
187 | 54080484 | Nikos Skalkotos | echo "redhat" |
188 | 54080484 | Nikos Skalkotos | elif [ -e "$root_dir/etc/slackware-version" ]; then |
189 | 54080484 | Nikos Skalkotos | echo "slackware" |
190 | b5294d61 | Nikos Skalkotos | elif [ -e "$root_dir/etc/SuSE-release" ]; then |
191 | 54080484 | Nikos Skalkotos | echo "suse" |
192 | b5294d61 | Nikos Skalkotos | elif [ -e "$root_dir/etc/gentoo-release" ]; then |
193 | 54080484 | Nikos Skalkotos | echo "gentoo" |
194 | 9eaa21c5 | Nikos Skalkotos | elif [ -e "$root_dir/etc/arch-release" ]; then |
195 | 9eaa21c5 | Nikos Skalkotos | echo "arch" |
196 | b1cb73f2 | Nikos Skalkotos | elif [ -e "$root_dir/etc/freebsd-update.conf" ]; then |
197 | b1cb73f2 | Nikos Skalkotos | echo "freebsd" |
198 | 5ff568d5 | Nikos Skalkotos | elif [ -e "$root_dir/etc/release" ]; then |
199 | 9787f9c2 | Nikos Skalkotos | if grep -i netbsd "$root_dir/etc/release" &> /dev/null; then |
200 | 5ff568d5 | Nikos Skalkotos | echo "netbsd" |
201 | 5ff568d5 | Nikos Skalkotos | else |
202 | 5ff568d5 | Nikos Skalkotos | warn "Unknown Unix flavor." |
203 | 5ff568d5 | Nikos Skalkotos | fi |
204 | 9787f9c2 | Nikos Skalkotos | elif [ -e "$root_dir/etc/motd" ]; then |
205 | 9787f9c2 | Nikos Skalkotos | if grep -i ^openbsd <(head -1 "$root_dir/etc/motd") &> /dev/null; then |
206 | 1722e242 | Nikos Skalkotos | echo "openbsd" |
207 | 1722e242 | Nikos Skalkotos | else |
208 | 1722e242 | Nikos Skalkotos | warn "Unknown Unix flavor" |
209 | 1722e242 | Nikos Skalkotos | fi |
210 | 2755bb06 | Nikos Skalkotos | else |
211 | 2755bb06 | Nikos Skalkotos | warn "Unknown base distro." |
212 | 54080484 | Nikos Skalkotos | fi |
213 | 54080484 | Nikos Skalkotos | } |
214 | 54080484 | Nikos Skalkotos | |
215 | 54080484 | Nikos Skalkotos | get_distro() { |
216 | 995a47c9 | Nikos Skalkotos | local root_dir distro |
217 | 995a47c9 | Nikos Skalkotos | root_dir=$1 |
218 | 54080484 | Nikos Skalkotos | |
219 | 54080484 | Nikos Skalkotos | if [ -e "$root_dir/etc/debian_version" ]; then |
220 | 54080484 | Nikos Skalkotos | distro="debian" |
221 | 54080484 | Nikos Skalkotos | if [ -e ${root_dir}/etc/lsb-release ]; then |
222 | df8b2f85 | Nikos Skalkotos | ID=$(grep ^DISTRIB_ID= ${root_dir}/etc/lsb-release | cut -d= -f2) |
223 | 54080484 | Nikos Skalkotos | if [ "x$ID" = "xUbuntu" ]; then |
224 | 54080484 | Nikos Skalkotos | distro="ubuntu" |
225 | 54080484 | Nikos Skalkotos | fi |
226 | 54080484 | Nikos Skalkotos | fi |
227 | 54080484 | Nikos Skalkotos | echo "$distro" |
228 | 54080484 | Nikos Skalkotos | elif [ -e "$root_dir/etc/fedora-release" ]; then |
229 | 54080484 | Nikos Skalkotos | echo "fedora" |
230 | a93a31ee | Nikos Skalkotos | elif [ -e "$root_dir/etc/centos-release" ]; then |
231 | 54080484 | Nikos Skalkotos | echo "centos" |
232 | 54080484 | Nikos Skalkotos | elif [ -e "$root_dir/etc/redhat-release" ]; then |
233 | 54080484 | Nikos Skalkotos | echo "redhat" |
234 | 54080484 | Nikos Skalkotos | elif [ -e "$root_dir/etc/slackware-version" ]; then |
235 | 54080484 | Nikos Skalkotos | echo "slackware" |
236 | b5294d61 | Nikos Skalkotos | elif [ -e "$root_dir/etc/SuSE-release" ]; then |
237 | 54080484 | Nikos Skalkotos | echo "suse" |
238 | b5294d61 | Nikos Skalkotos | elif [ -e "$root_dir/etc/gentoo-release" ]; then |
239 | 54080484 | Nikos Skalkotos | echo "gentoo" |
240 | 9eaa21c5 | Nikos Skalkotos | elif [ -e "$root_dir/etc/arch-release" ]; then |
241 | 9eaa21c5 | Nikos Skalkotos | echo "arch" |
242 | b1cb73f2 | Nikos Skalkotos | elif [ -e "$root_dir/etc/freebsd-update.conf" ]; then |
243 | b1cb73f2 | Nikos Skalkotos | echo "freebsd" |
244 | 5ff568d5 | Nikos Skalkotos | elif [ -e "$root_dir/etc/release" ]; then |
245 | 5ff568d5 | Nikos Skalkotos | if grep -in netbsd "$root_dir/etc/release" &> /dev/null; then |
246 | 5ff568d5 | Nikos Skalkotos | echo "netbsd" |
247 | 5ff568d5 | Nikos Skalkotos | else |
248 | 5ff568d5 | Nikos Skalkotos | warn "Unknown Unix flavor" |
249 | 5ff568d5 | Nikos Skalkotos | fi |
250 | 9787f9c2 | Nikos Skalkotos | elif [ -e "$root_dir/etc/motd" ]; then |
251 | 9787f9c2 | Nikos Skalkotos | if grep -i ^openbsd <(head -1 "$root_dir/etc/motd") &> /dev/null; then |
252 | 1722e242 | Nikos Skalkotos | echo "openbsd" |
253 | 1722e242 | Nikos Skalkotos | else |
254 | 1722e242 | Nikos Skalkotos | warn "Unknown Unix flavor" |
255 | 1722e242 | Nikos Skalkotos | fi |
256 | 2755bb06 | Nikos Skalkotos | else |
257 | 2755bb06 | Nikos Skalkotos | warn "Unknown distro." |
258 | 54080484 | Nikos Skalkotos | fi |
259 | 54080484 | Nikos Skalkotos | } |
260 | 54080484 | Nikos Skalkotos | |
261 | 01da0f7d | Nikos Skalkotos | get_partition_table() { |
262 | 995a47c9 | Nikos Skalkotos | local dev output |
263 | 995a47c9 | Nikos Skalkotos | dev="$1" |
264 | 8576747b | Nikos Skalkotos | # If the partition table is gpt then parted will raise an error if the |
265 | 8576747b | Nikos Skalkotos | # secondary gpt is not it the end of the disk, and a warning that has to |
266 | 8576747b | Nikos Skalkotos | # do with the "Last Usable LBA" entry in gpt. |
267 | 8576747b | Nikos Skalkotos | if ! output="$("$PARTED" -s -m "$dev" unit s print | grep -E -v "^(Warning|Error): ")"; then |
268 | 90db2151 | Nikos Skalkotos | log_error "Unable to read partition table for device \`${dev}'. The image seems corrupted." |
269 | 01da0f7d | Nikos Skalkotos | fi |
270 | 01da0f7d | Nikos Skalkotos | |
271 | b126203e | Nikos Skalkotos | echo "$output" |
272 | b126203e | Nikos Skalkotos | } |
273 | b126203e | Nikos Skalkotos | |
274 | b126203e | Nikos Skalkotos | get_partition_table_type() { |
275 | 995a47c9 | Nikos Skalkotos | local ptable dev field |
276 | 995a47c9 | Nikos Skalkotos | ptable="$1" |
277 | b126203e | Nikos Skalkotos | |
278 | 995a47c9 | Nikos Skalkotos | dev="$(sed -n 2p <<< "$ptable")" |
279 | b126203e | Nikos Skalkotos | IFS=':' read -ra field <<< "$dev" |
280 | b126203e | Nikos Skalkotos | |
281 | b126203e | Nikos Skalkotos | echo "${field[5]}" |
282 | b126203e | Nikos Skalkotos | } |
283 | b126203e | Nikos Skalkotos | |
284 | b126203e | Nikos Skalkotos | get_partition_count() { |
285 | b126203e | Nikos Skalkotos | local ptable="$1" |
286 | b126203e | Nikos Skalkotos | |
287 | b126203e | Nikos Skalkotos | expr $(echo "$ptable" | wc -l) - 2 |
288 | eb8e3364 | Nikos Skalkotos | } |
289 | eb8e3364 | Nikos Skalkotos | |
290 | 8576747b | Nikos Skalkotos | get_partition_by_num() { |
291 | 01da0f7d | Nikos Skalkotos | local ptable="$1" |
292 | 01da0f7d | Nikos Skalkotos | local id="$2" |
293 | 01da0f7d | Nikos Skalkotos | |
294 | 01da0f7d | Nikos Skalkotos | grep "^$id:" <<< "$ptable" |
295 | 01da0f7d | Nikos Skalkotos | } |
296 | 01da0f7d | Nikos Skalkotos | |
297 | 42f09a19 | Nikos Skalkotos | get_last_partition() { |
298 | b126203e | Nikos Skalkotos | local ptable="$1" |
299 | 42f09a19 | Nikos Skalkotos | |
300 | b126203e | Nikos Skalkotos | echo "$ptable" | tail -1 |
301 | 42f09a19 | Nikos Skalkotos | } |
302 | 42f09a19 | Nikos Skalkotos | |
303 | b126203e | Nikos Skalkotos | is_extended_partition() { |
304 | 42f09a19 | Nikos Skalkotos | local dev="$1" |
305 | b126203e | Nikos Skalkotos | local part_num="$2" |
306 | 42f09a19 | Nikos Skalkotos | |
307 | 2b79f174 | Nikos Skalkotos | id=$($SFDISK --force --print-id "$dev" "$part_num") |
308 | 834f8fc0 | Nikos Skalkotos | if [ "$id" = "5" -o "$id" = "f" ]; then |
309 | b126203e | Nikos Skalkotos | echo "yes" |
310 | b126203e | Nikos Skalkotos | else |
311 | b126203e | Nikos Skalkotos | echo "no" |
312 | b126203e | Nikos Skalkotos | fi |
313 | 42f09a19 | Nikos Skalkotos | } |
314 | 42f09a19 | Nikos Skalkotos | |
315 | b126203e | Nikos Skalkotos | get_extended_partition() { |
316 | 995a47c9 | Nikos Skalkotos | local ptable dev |
317 | 995a47c9 | Nikos Skalkotos | ptable="$1" |
318 | 995a47c9 | Nikos Skalkotos | dev="$(echo "$ptable" | sed -n 2p | cut -d':' -f1)" |
319 | 42f09a19 | Nikos Skalkotos | |
320 | b126203e | Nikos Skalkotos | tail -n +3 <<< "$ptable" | while read line; do |
321 | b126203e | Nikos Skalkotos | part_num=$(cut -d':' -f1 <<< "$line") |
322 | b126203e | Nikos Skalkotos | if [ $(is_extended_partition "$dev" "$part_num") == "yes" ]; then |
323 | b126203e | Nikos Skalkotos | echo "$line" |
324 | b126203e | Nikos Skalkotos | return 0 |
325 | b126203e | Nikos Skalkotos | fi |
326 | b126203e | Nikos Skalkotos | done |
327 | b126203e | Nikos Skalkotos | echo "" |
328 | b126203e | Nikos Skalkotos | } |
329 | b126203e | Nikos Skalkotos | |
330 | b126203e | Nikos Skalkotos | get_logical_partitions() { |
331 | 995a47c9 | Nikos Skalkotos | local ptable part_num |
332 | 995a47c9 | Nikos Skalkotos | ptable="$1" |
333 | b126203e | Nikos Skalkotos | |
334 | b126203e | Nikos Skalkotos | tail -n +3 <<< "$ptable" | while read line; do |
335 | b126203e | Nikos Skalkotos | part_num=$(cut -d':' -f1 <<< "$line") |
336 | b126203e | Nikos Skalkotos | if [ $part_num -ge 5 ]; then |
337 | b126203e | Nikos Skalkotos | echo "$line" |
338 | b126203e | Nikos Skalkotos | fi |
339 | b126203e | Nikos Skalkotos | done |
340 | b126203e | Nikos Skalkotos | |
341 | b126203e | Nikos Skalkotos | return 0 |
342 | b126203e | Nikos Skalkotos | } |
343 | b126203e | Nikos Skalkotos | |
344 | b126203e | Nikos Skalkotos | get_last_primary_partition() { |
345 | 995a47c9 | Nikos Skalkotos | local ptable dev output |
346 | 995a47c9 | Nikos Skalkotos | ptable="$1" |
347 | 995a47c9 | Nikos Skalkotos | dev=$(echo "ptable" | sed -n 2p | cut -d':' -f1) |
348 | b126203e | Nikos Skalkotos | |
349 | b126203e | Nikos Skalkotos | for i in 4 3 2 1; do |
350 | b126203e | Nikos Skalkotos | if output=$(grep "^$i:" <<< "$ptable"); then |
351 | b126203e | Nikos Skalkotos | echo "$output" |
352 | b126203e | Nikos Skalkotos | return 0 |
353 | b126203e | Nikos Skalkotos | fi |
354 | b126203e | Nikos Skalkotos | done |
355 | b126203e | Nikos Skalkotos | echo "" |
356 | b126203e | Nikos Skalkotos | } |
357 | b126203e | Nikos Skalkotos | |
358 | 8576747b | Nikos Skalkotos | get_partition_to_resize() { |
359 | 995a47c9 | Nikos Skalkotos | local dev table table_type last_part last_part_num extended last_primary \ |
360 | 995a47c9 | Nikos Skalkotos | ext_num prim_num |
361 | 995a47c9 | Nikos Skalkotos | dev="$1" |
362 | 8576747b | Nikos Skalkotos | |
363 | 8576747b | Nikos Skalkotos | table=$(get_partition_table "$dev") |
364 | 3bb66fac | Nikos Skalkotos | if [ -z "$table" ]; then |
365 | 3bb66fac | Nikos Skalkotos | return 0 |
366 | 3bb66fac | Nikos Skalkotos | fi |
367 | 8576747b | Nikos Skalkotos | |
368 | 8576747b | Nikos Skalkotos | if [ $(get_partition_count "$table") -eq 0 ]; then |
369 | 8576747b | Nikos Skalkotos | return 0 |
370 | 8576747b | Nikos Skalkotos | fi |
371 | 8576747b | Nikos Skalkotos | |
372 | 8576747b | Nikos Skalkotos | table_type=$(get_partition_table_type "$table") |
373 | 8576747b | Nikos Skalkotos | last_part=$(get_last_partition "$table") |
374 | 8576747b | Nikos Skalkotos | last_part_num=$(cut -d: -f1 <<< "$last_part") |
375 | 8576747b | Nikos Skalkotos | |
376 | 8576747b | Nikos Skalkotos | if [ "$table_type" == "msdos" -a $last_part_num -gt 4 ]; then |
377 | 8576747b | Nikos Skalkotos | extended=$(get_extended_partition "$table") |
378 | 8576747b | Nikos Skalkotos | last_primary=$(get_last_primary_partition "$table") |
379 | 8576747b | Nikos Skalkotos | ext_num=$(cut -d: -f1 <<< "$extended") |
380 | 0e707fe3 | Nikos Skalkotos | last_prim_num=$(cut -d: -f1 <<< "$last_primary") |
381 | 8576747b | Nikos Skalkotos | |
382 | 8576747b | Nikos Skalkotos | if [ "$ext_num" != "$last_prim_num" ]; then |
383 | 8576747b | Nikos Skalkotos | echo "$last_prim_num" |
384 | 8576747b | Nikos Skalkotos | else |
385 | 8576747b | Nikos Skalkotos | echo "$last_part_num" |
386 | 8576747b | Nikos Skalkotos | fi |
387 | 8576747b | Nikos Skalkotos | else |
388 | 8576747b | Nikos Skalkotos | echo "$last_part_num" |
389 | 8576747b | Nikos Skalkotos | fi |
390 | 8576747b | Nikos Skalkotos | } |
391 | 8576747b | Nikos Skalkotos | |
392 | b126203e | Nikos Skalkotos | create_partition() { |
393 | 01da0f7d | Nikos Skalkotos | local device="$1" |
394 | 01da0f7d | Nikos Skalkotos | local part="$2" |
395 | 01da0f7d | Nikos Skalkotos | local ptype="$3" |
396 | b126203e | Nikos Skalkotos | |
397 | 995a47c9 | Nikos Skalkotos | local fields=() |
398 | b126203e | Nikos Skalkotos | IFS=":;" read -ra fields <<< "$part" |
399 | 01da0f7d | Nikos Skalkotos | local id="${fields[0]}" |
400 | 01da0f7d | Nikos Skalkotos | local start="${fields[1]}" |
401 | 01da0f7d | Nikos Skalkotos | local end="${fields[2]}" |
402 | 01da0f7d | Nikos Skalkotos | local size="${fields[3]}" |
403 | 01da0f7d | Nikos Skalkotos | local fs="${fields[4]}" |
404 | 01da0f7d | Nikos Skalkotos | local name="${fields[5]}" |
405 | 01da0f7d | Nikos Skalkotos | local flags="${fields[6]//,/ }" |
406 | 01da0f7d | Nikos Skalkotos | |
407 | 9ec298c7 | Nikos Skalkotos | if [ "$ptype" = "primary" -o "$ptype" = "logical" -o "$ptype" = "extended" ]; then |
408 | 9ec298c7 | Nikos Skalkotos | $PARTED -s -m -- $device mkpart "$ptype" $fs "$start" "$end" |
409 | 9ec298c7 | Nikos Skalkotos | for flag in $flags; do |
410 | 9ec298c7 | Nikos Skalkotos | $PARTED -s -m $device set "$id" "$flag" on |
411 | 9ec298c7 | Nikos Skalkotos | done |
412 | 9ec298c7 | Nikos Skalkotos | else |
413 | 9ec298c7 | Nikos Skalkotos | # For gpt |
414 | 9ec298c7 | Nikos Skalkotos | start=${start:0:${#start}-1} # remove the s at the end |
415 | 9ec298c7 | Nikos Skalkotos | end=${end:0:${#end}-1} # remove the s at the end |
416 | 9ec298c7 | Nikos Skalkotos | $SGDISK -n "$id":"$start":"$end" -t "$id":"$ptype" "$device" |
417 | 9ec298c7 | Nikos Skalkotos | fi |
418 | b126203e | Nikos Skalkotos | } |
419 | b126203e | Nikos Skalkotos | |
420 | b126203e | Nikos Skalkotos | enlarge_partition() { |
421 | 995a47c9 | Nikos Skalkotos | local device part ptype new_end fields new_part table logical id |
422 | 995a47c9 | Nikos Skalkotos | device="$1" |
423 | 995a47c9 | Nikos Skalkotos | part="$2" |
424 | 995a47c9 | Nikos Skalkotos | ptype="$3" |
425 | 995a47c9 | Nikos Skalkotos | new_end="$4" |
426 | 01da0f7d | Nikos Skalkotos | |
427 | 01da0f7d | Nikos Skalkotos | if [ -z "$new_end" ]; then |
428 | 01da0f7d | Nikos Skalkotos | new_end=$(cut -d: -f 3 <<< "$(get_last_free_sector "$device")") |
429 | 01da0f7d | Nikos Skalkotos | fi |
430 | b126203e | Nikos Skalkotos | |
431 | 995a47c9 | Nikos Skalkotos | fields=() |
432 | b126203e | Nikos Skalkotos | IFS=":;" read -ra fields <<< "$part" |
433 | b126203e | Nikos Skalkotos | fields[2]="$new_end" |
434 | b126203e | Nikos Skalkotos | |
435 | 995a47c9 | Nikos Skalkotos | new_part="" |
436 | b126203e | Nikos Skalkotos | for ((i = 0; i < ${#fields[*]}; i = i + 1)); do |
437 | b126203e | Nikos Skalkotos | new_part="$new_part":"${fields[$i]}" |
438 | b126203e | Nikos Skalkotos | done |
439 | b126203e | Nikos Skalkotos | new_part=${new_part:1} |
440 | b126203e | Nikos Skalkotos | |
441 | b126203e | Nikos Skalkotos | # If this is an extended partition, removing it will also remove the |
442 | b126203e | Nikos Skalkotos | # logical partitions it contains. We need to save them for later. |
443 | b126203e | Nikos Skalkotos | if [ "$ptype" = "extended" ]; then |
444 | 995a47c9 | Nikos Skalkotos | table="$(get_partition_table "$device")" |
445 | 995a47c9 | Nikos Skalkotos | logical="$(get_logical_partitions "$table")" |
446 | b126203e | Nikos Skalkotos | fi |
447 | b126203e | Nikos Skalkotos | |
448 | b126203e | Nikos Skalkotos | id=${fields[0]} |
449 | b126203e | Nikos Skalkotos | $PARTED -s -m "$device" rm "$id" |
450 | b126203e | Nikos Skalkotos | create_partition "$device" "$new_part" "$ptype" |
451 | b126203e | Nikos Skalkotos | |
452 | b126203e | Nikos Skalkotos | if [ "$ptype" = "extended" ]; then |
453 | b126203e | Nikos Skalkotos | # Recreate logical partitions |
454 | b126203e | Nikos Skalkotos | echo "$logical" | while read logical_part; do |
455 | b126203e | Nikos Skalkotos | create_partition "$device" "$logical_part" "logical" |
456 | b126203e | Nikos Skalkotos | done |
457 | b126203e | Nikos Skalkotos | fi |
458 | 42f09a19 | Nikos Skalkotos | } |
459 | 42f09a19 | Nikos Skalkotos | |
460 | 42f09a19 | Nikos Skalkotos | get_last_free_sector() { |
461 | 995a47c9 | Nikos Skalkotos | local dev unit last_line ptype |
462 | 995a47c9 | Nikos Skalkotos | dev="$1" |
463 | 995a47c9 | Nikos Skalkotos | unit="$2" |
464 | 01da0f7d | Nikos Skalkotos | |
465 | 01da0f7d | Nikos Skalkotos | if [ -n "$unit" ]; then |
466 | 01da0f7d | Nikos Skalkotos | unit="unit $unit" |
467 | 01da0f7d | Nikos Skalkotos | fi |
468 | 01da0f7d | Nikos Skalkotos | |
469 | 995a47c9 | Nikos Skalkotos | last_line="$($PARTED -s -m "$dev" "$unit" print free | tail -1)" |
470 | 995a47c9 | Nikos Skalkotos | ptype="$(cut -d: -f 5 <<< "$last_line")" |
471 | 42f09a19 | Nikos Skalkotos | |
472 | b126203e | Nikos Skalkotos | if [ "$ptype" = "free;" ]; then |
473 | 01da0f7d | Nikos Skalkotos | echo "$last_line" |
474 | 42f09a19 | Nikos Skalkotos | fi |
475 | 42f09a19 | Nikos Skalkotos | } |
476 | 42f09a19 | Nikos Skalkotos | |
477 | 2a5be644 | Nikos Skalkotos | get_unattend() { |
478 | 995a47c9 | Nikos Skalkotos | local target exists |
479 | 995a47c9 | Nikos Skalkotos | target="$1" |
480 | 2a5be644 | Nikos Skalkotos | |
481 | 2a5be644 | Nikos Skalkotos | # Workaround to search for $target/Unattend.xml in an case insensitive way. |
482 | 2a5be644 | Nikos Skalkotos | exists=$(find "$target"/ -maxdepth 1 -iname unattend.xml) |
483 | 2a5be644 | Nikos Skalkotos | if [ $(wc -l <<< "$exists") -gt 1 ]; then |
484 | 2a5be644 | Nikos Skalkotos | log_error "Found multiple Unattend.xml files in the image:" $exists |
485 | 2a5be644 | Nikos Skalkotos | fi |
486 | 2a5be644 | Nikos Skalkotos | |
487 | 2a5be644 | Nikos Skalkotos | echo "$exists" |
488 | 2a5be644 | Nikos Skalkotos | } |
489 | 2a5be644 | Nikos Skalkotos | |
490 | e2510438 | Nikos Skalkotos | umount_all() { |
491 | e2510438 | Nikos Skalkotos | local target mpoints |
492 | e2510438 | Nikos Skalkotos | target="$1" |
493 | e2510438 | Nikos Skalkotos | |
494 | e2510438 | Nikos Skalkotos | # Unmount file systems mounted under directory `target' |
495 | e2510438 | Nikos Skalkotos | mpoints="$({ awk "{ if (match(\$2, \"^$target\")) { print \$2 } }" < /proc/mounts; } | sort -rbd | uniq)" |
496 | e2510438 | Nikos Skalkotos | |
497 | e2510438 | Nikos Skalkotos | for mpoint in $mpoints; do |
498 | e2510438 | Nikos Skalkotos | umount $mpoint |
499 | e2510438 | Nikos Skalkotos | done |
500 | e2510438 | Nikos Skalkotos | } |
501 | e2510438 | Nikos Skalkotos | |
502 | 84d01e3e | Nikos Skalkotos | get_ufstype() { |
503 | 84d01e3e | Nikos Skalkotos | local device ufs |
504 | 84d01e3e | Nikos Skalkotos | |
505 | 84d01e3e | Nikos Skalkotos | device="$1" |
506 | f80d3498 | Nikos Skalkotos | ufs="$($DUMPFS_UFS "$device" | head -1 | awk -F "[()]" '{ for (i=2; i<NF; i+=2) print $i }')" |
507 | 84d01e3e | Nikos Skalkotos | |
508 | 84d01e3e | Nikos Skalkotos | case "$ufs" in |
509 | 84d01e3e | Nikos Skalkotos | UFS1) |
510 | 84d01e3e | Nikos Skalkotos | echo 44bsd |
511 | 84d01e3e | Nikos Skalkotos | ;; |
512 | 84d01e3e | Nikos Skalkotos | UFS2) |
513 | 84d01e3e | Nikos Skalkotos | echo ufs2 |
514 | 84d01e3e | Nikos Skalkotos | ;; |
515 | 84d01e3e | Nikos Skalkotos | *) |
516 | 84d01e3e | Nikos Skalkotos | log_error "Unsupported UFS type: \`$ufs' in device $device" |
517 | 84d01e3e | Nikos Skalkotos | echo "" |
518 | 84d01e3e | Nikos Skalkotos | ;; |
519 | 84d01e3e | Nikos Skalkotos | esac |
520 | 84d01e3e | Nikos Skalkotos | } |
521 | 84d01e3e | Nikos Skalkotos | |
522 | 54080484 | Nikos Skalkotos | cleanup() { |
523 | 6a95db10 | Vangelis Koukis | # if something fails here, it shouldn't call cleanup again... |
524 | 54080484 | Nikos Skalkotos | trap - EXIT |
525 | 54080484 | Nikos Skalkotos | |
526 | 54080484 | Nikos Skalkotos | if [ ${#CLEANUP[*]} -gt 0 ]; then |
527 | 54080484 | Nikos Skalkotos | LAST_ELEMENT=$((${#CLEANUP[*]}-1)) |
528 | 54080484 | Nikos Skalkotos | REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0) |
529 | 54080484 | Nikos Skalkotos | for i in $REVERSE_INDEXES; do |
530 | 54080484 | Nikos Skalkotos | # If something fails here, it's better to retry it for a few times |
531 | 54080484 | Nikos Skalkotos | # before we give up with an error. This is needed for kpartx when |
532 | 54080484 | Nikos Skalkotos | # dealing with ntfs partitions mounted through fuse. umount is not |
533 | 54080484 | Nikos Skalkotos | # synchronous and may return while the partition is still busy. A |
534 | 01da0f7d | Nikos Skalkotos | # premature attempt to delete partition mappings through kpartx on |
535 | 01da0f7d | Nikos Skalkotos | # a device that hosts previously mounted ntfs partition may fail |
536 | 01da0f7d | Nikos Skalkotos | # with a `device-mapper: remove ioctl failed: Device or resource |
537 | 01da0f7d | Nikos Skalkotos | # busy' error. A sensible workaround for this is to wait for a |
538 | 01da0f7d | Nikos Skalkotos | # while and then try again. |
539 | 54080484 | Nikos Skalkotos | local cmd=${CLEANUP[$i]} |
540 | 54080484 | Nikos Skalkotos | $cmd || for interval in 0.25 0.5 1 2 4; do |
541 | 54080484 | Nikos Skalkotos | echo "Command $cmd failed!" |
542 | 54080484 | Nikos Skalkotos | echo "I'll wait for $interval secs and will retry..." |
543 | 54080484 | Nikos Skalkotos | sleep $interval |
544 | 54080484 | Nikos Skalkotos | $cmd && break |
545 | 54080484 | Nikos Skalkotos | done |
546 | 76009480 | Nikos Skalkotos | if [ "$?" != "0" ]; then |
547 | 76009480 | Nikos Skalkotos | echo "Giving Up..." |
548 | 76009480 | Nikos Skalkotos | exit 1; |
549 | 76009480 | Nikos Skalkotos | fi |
550 | 54080484 | Nikos Skalkotos | done |
551 | 54080484 | Nikos Skalkotos | fi |
552 | 54080484 | Nikos Skalkotos | } |
553 | 54080484 | Nikos Skalkotos | |
554 | 2a0ab295 | Nikos Skalkotos | task_cleanup() { |
555 | 995a47c9 | Nikos Skalkotos | local rc=$? |
556 | 2a0ab295 | Nikos Skalkotos | |
557 | 2a0ab295 | Nikos Skalkotos | if [ $rc -eq 0 ]; then |
558 | a50a2bff | Nikos Skalkotos | report_task_end |
559 | 2a0ab295 | Nikos Skalkotos | else |
560 | 2a0ab295 | Nikos Skalkotos | report_error |
561 | 2a0ab295 | Nikos Skalkotos | fi |
562 | 2a0ab295 | Nikos Skalkotos | |
563 | 2a0ab295 | Nikos Skalkotos | cleanup |
564 | 2a0ab295 | Nikos Skalkotos | } |
565 | 2a0ab295 | Nikos Skalkotos | |
566 | e7cbe965 | Nikos Skalkotos | check_if_excluded() { |
567 | 995a47c9 | Nikos Skalkotos | local name exclude |
568 | 995a47c9 | Nikos Skalkotos | name="$(tr [a-z] [A-Z] <<< ${PROGNAME:2})" |
569 | 995a47c9 | Nikos Skalkotos | exclude="SNF_IMAGE_PROPERTY_EXCLUDE_TASK_${name}" |
570 | 7ee2a43d | Nikos Skalkotos | if [ -n "${!exclude}" ]; then |
571 | f32664b2 | Nikos Skalkotos | warn "Task ${PROGNAME:2} was excluded and will not run." |
572 | e7cbe965 | Nikos Skalkotos | exit 0 |
573 | e7cbe965 | Nikos Skalkotos | fi |
574 | e7cbe965 | Nikos Skalkotos | |
575 | e7cbe965 | Nikos Skalkotos | return 0 |
576 | e7cbe965 | Nikos Skalkotos | } |
577 | e7cbe965 | Nikos Skalkotos | |
578 | e9413eab | Dimitris Aragiorgis | return_success() { |
579 | d509231b | Nikos Skalkotos | send_result_${HYPERVISOR} "SUCCESS" |
580 | e9413eab | Dimitris Aragiorgis | } |
581 | e9413eab | Dimitris Aragiorgis | |
582 | de7269cd | Nikos Skalkotos | trap cleanup EXIT |
583 | 88262dba | Nikos Skalkotos | set -o pipefail |
584 | 01da0f7d | Nikos Skalkotos | |
585 | 2a0ab295 | Nikos Skalkotos | STDERR_FILE=$(mktemp) |
586 | 2a0ab295 | Nikos Skalkotos | add_cleanup rm -f "$STDERR_FILE" |
587 | 2a0ab295 | Nikos Skalkotos | exec 2> >(tee -a "$STDERR_FILE" >&2) |
588 | 2a0ab295 | Nikos Skalkotos | |
589 | 54080484 | Nikos Skalkotos | # vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |