Source full path
[platform/adaptation/setup-scripts.git] / setup-ivi-bootloader-conf
1 #!/bin/sh -euf
2
3 # Copyright 2013 Intel Corporation
4 # Author: Artem Bityutskiy
5 # License: GPLv2
6
7 PROG="setup-ivi-bootloader-conf"
8 VER="1.0"
9
10 srcdir="$(readlink -ev -- ${0%/*})"
11 PATH="/usr/share/setup-ivi:$srcdir:$PATH"
12
13 . "$srcdir/setup-ivi-sh-functions"
14 . "$srcdir/installerfw-sh-functions"
15
16 # This is a small trick which I use to make sure my scripts are portable -
17 # check if 'dash' is present, and if yes - use it.
18 if can_switch_to_dash; then
19         exec dash -euf "$srcdir/$PROG" "$@"
20         exit $?
21 fi
22
23 # Preparation stuff common for all subcommands
24 prepare()
25 {
26         # Get the installer framework environment
27         installerfw_restore_env
28
29         bootdir="$(installerfw_mnt_prefix "/boot")"
30
31         if installerfw_is_efi_boot_system; then
32                 boot="gummiboot"
33         else
34                 boot="extlinux"
35         fi
36 }
37
38 #
39 # -----------------------------------------------------------------------------
40 # The "add" subcommand
41 # -----------------------------------------------------------------------------
42 #
43
44 show_add_usage()
45 {
46         cat <<-EOF
47 Usage: $PROG add [options] <kernel>
48
49 Add bootloader entries for kernel <kernel>.
50
51 Options:
52   -f, --force  if bootloader entries for <kernel> already exist in bootloader's
53                config file(s) - re-write them, if <kernel> does not exist - do
54                not fail
55   -h, --help   show this text and exit
56 EOF
57 }
58
59 show_add_usage_fail()
60 {
61         IFS= printf "%s\n\n" "$PROG: error: $*" >&2
62         show_add_usage >&2
63         exit 1
64 }
65
66 add_subcommand()
67 {
68         if [ "$#" -eq 0  ]; then
69                 show_add_usage
70                 exit 0
71         fi
72
73         local tmp
74         tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
75                 show_add_usage_fail "cannot parse command-line options"
76         eval set -- "$tmp"
77
78         local force=
79         while true; do
80                 case "$1" in
81                 -f|--force)
82                         force="-f"
83                         ;;
84                 -h|--help)
85                         show_add_usage
86                         exit 0
87                         ;;
88                 --) shift; break
89                         ;;
90                 *) show_add_usage_fail "unrecognized option \"$1\""
91                         ;;
92                 esac
93                 shift
94         done
95
96         if [ "$#" -lt 1 ]; then
97                 show_add_usage_fail "please, specify the kernel"
98         fi
99         if [ "$#" -gt 1 ]; then
100                 show_add_usage_fail "too many arguments: \"$1\""
101         fi
102
103         prepare
104
105         local kernel="$1"
106         local kernel_path="$bootdir/$kernel"
107
108         if ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
109                 fatal "cannot find kernel \"$kernel_path\"" \
110                       "(use -f to ignore this error)"
111         fi
112
113         # Get root partition PARTUUID
114         installerfw_get_part_info "/" "PARTUUID" "root_partuuid"
115         [ -n "$root_partuuid" ] || \
116                 fatal "cannot find PARTUUID of the root partition"
117
118         # Get kernel options
119         local options="${INSTALLERFW_KERNEL_OPTS:-} root=PARTUUID=$root_partuuid"
120
121         # Get OS name
122         local os_name=
123         get_os_name "os_name"
124
125         # Add the bootloader entry
126         setup-$boot-conf $verbose --bootdir "$bootdir" add $force \
127                 "$kernel" "$os_name" "$kernel" "$options"
128
129         # If there is the "quiet" option, create a non-quiet configuration
130         local dbgopts="$(printf "%s" "$options" | LC_ALL=C \
131                                 sed -e "s/[[:blank:]]\+quiet[[:blank:]]\+/ /
132                                         s/^quiet[[:blank:]]\+//
133                                         s/[[:blank:]]\+quiet$//
134                                         s/^quiet$//")"
135
136         dbgopts="$dbgopts ignore_loglevel initcall_debug log_buf_len=2M"
137
138         setup-$boot-conf $verbose --bootdir "$bootdir" add \
139                 $force "$kernel-debug" "$os_name (debug)" \
140                 "$kernel" "$dbgopts"
141 }
142
143 #
144 # -----------------------------------------------------------------------------
145 # The "remove" subcommand
146 # -----------------------------------------------------------------------------
147 #
148
149 show_remove_usage()
150 {
151         cat <<-EOF
152 Usage: $PROG remove [options] <kernel>
153
154 Delete bootloader entries for kernel <kernel> (only those which were previously
155 created with "$PROG add").
156
157 Options:
158   -f, --force  do not fail if <kernel> does not have corresponding bootloader
159                entries
160   -h, --help   show this text and exit
161 EOF
162 }
163
164 show_remove_usage_fail()
165 {
166         IFS= printf "%s\n\n" "$PROG: error: $*" >&2
167         show_remove_usage >&2
168         exit 1
169 }
170
171 remove_subcommand()
172 {
173         if [ "$#" -eq 0  ]; then
174                 show_remove_usage
175                 exit 0
176         fi
177
178         local tmp
179         tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
180                 show_remove_usage_fail "cannot parse command-line options"
181         eval set -- "$tmp"
182
183         local force=
184         while true; do
185                 case "$1" in
186                 -f|--force)
187                         force="-f"
188                         ;;
189                 -h|--help)
190                         show_remove_usage
191                         exit 0
192                         ;;
193                 --) shift; break
194                         ;;
195                 *) show_remove_usage_fail "unrecognized option \"$1\""
196                         ;;
197                 esac
198                 shift
199         done
200
201         if [ "$#" -lt 1 ]; then
202                 show_add_usage_fail "please, specify the kernel"
203         fi
204         if [ "$#" -gt 1 ]; then
205                 show_remove_usage_fail "too many arguments: \"$1\""
206         fi
207
208         local kernel="$1"
209
210         prepare
211
212         # Get the current default entry
213         local default="$(setup-$boot-conf $verbose --bootdir "$bootdir" \
214                                               default $force)"
215         [ $? -eq 0 ] || \
216                 fatal "cannot get the default kernel, setup-$boot-conf failed"
217
218         local default_kernel="$(printf "%s" "$default" | LC_ALL=C \
219                          sed -n -e 's/^kernel: \(.\+\)$/\1/p')"
220
221         if [ -n "$default_kernel" ]; then
222                 verbose "current default boot kernel is " \
223                         "\"$default_kernel\""
224         else
225                 verbose "did not find the default kernel," \
226                       "setup-$boot-conf returned: $default"
227         fi
228
229         # Remove the kernel
230         setup-$boot-conf $verbose --bootdir "$bootdir" \
231                              remove $force "$kernel" || \
232                 fatal "setup-$boot-conf failed to remove" \
233                       "entry \"$kernel\""
234         setup-$boot-conf $verbose --bootdir "$bootdir" \
235                              remove $force "$kernel-verbose" || \
236                 fatal "setup-$boot-conf failed to remove" \
237                       "entry \"$kernel-verbose\""
238
239         # If this is not the default kernel, we are done
240         [ "$kernel" = "$default_kernel" ] || return 0
241
242         # We've just removed the default kernel, find the kernel with the
243         # latest version and make it to be the default
244
245         verbose "removed the default kernel, find the newest available"
246
247         local newest_kernel="$(get_newest_kernel "$bootdir" "$kernel")"
248
249         if [ -z "$newest_kernel" ]; then
250                 verbose "no more kernels, set the kernel to none"
251                 setup-$boot-conf $verbose --bootdir "$bootdir" \
252                                      default --force "<none>"
253         else
254                 verbose "new default kernel is \"$newest_kernel\""
255                 setup-$boot-conf $verbose --bootdir "$bootdir" \
256                                      default "$newest_kernel"
257         fi
258
259         if [ "$?" -ne 0 ]; then
260                 fatal "cannot set default kernel, \"setup-$boot-conf\" failed"
261         fi
262 }
263
264 #
265 # -----------------------------------------------------------------------------
266 # The "default" subcommand
267 # -----------------------------------------------------------------------------
268 #
269
270 show_default_usage()
271 {
272         cat <<-EOF
273 Usage: $PROG default [options] <kernel>
274
275 Set the default boot kernel to <kernel>. If <kernel> is omited, print the
276 current default boot kernel name.
277
278 Options:
279   -f, --force  do not fail if <kernel> doesn't exist
280   -h, --help   show this text and exit
281 EOF
282 }
283
284 show_default_usage_fail()
285 {
286         IFS= printf "%s\n\n" "$PROG: error: $*" >&2
287         show_default_usage >&2
288         exit 1
289 }
290
291 default_subcommand()
292 {
293         local tmp
294         tmp=`getopt -n $PROG -o f,h --long force,help -- "$@"` ||
295                 show_default_usage_fail "cannot parse command-line options"
296         eval set -- "$tmp"
297
298         local force=
299         while true; do
300                 case "$1" in
301                 -f|--force)
302                         force="-f"
303                         ;;
304                 -h|--help)
305                         show_default_usage
306                         exit 0
307                         ;;
308                 --) shift; break
309                         ;;
310                 *) show_default_usage_fail "unrecognized option \"$1\""
311                         ;;
312                 esac
313                 shift
314         done
315
316         if [ "$#" -gt 1 ]; then
317                 show_default_usage_fail "too many arguments: \"$1\""
318         fi
319
320         prepare
321
322         local kernel="${1:-}"
323         local kernel_path="$bootdir/$kernel"
324
325         if [ -n "$kernel" ] && ! [ -f "$kernel_path" ] && [ -z "$force" ]; then
326                 fatal "cannot find kernel \"$kernel_path\"" \
327                       "(use -f to ignore this error)"
328         fi
329
330         setup-$boot-conf $verbose --bootdir "$bootdir" default $force "$kernel"
331 }
332
333 #
334 # -----------------------------------------------------------------------------
335 #
336
337 show_usage()
338 {
339         cat <<-EOF
340 Usage: $PROG [options] <subcommand> [options] <arguments>
341
342 This program adds or removes a kernel to/from the bootloader configuration
343 file(s). This is a Tizen IVI-specific program and it currently supports only 2
344 bootloader types - extlinux and gummiboot. Each new kernel gets 2 boot menu
345 entries - the default and verbose, and both of these are removed by the
346 "remove" subcommand.
347
348 The supported subcommands are:
349    add     - add bootloader entries for a kernel
350    remove  - remove bootloader entries for a kernel
351    default - get or set the default boot kernel
352
353 Run "$PROG <subcommand>" to see subcommand-specific help.
354
355 Options:
356   --version      show the program version and exit
357   -v, --verbose  be verbose
358   -h, --help     show this text and exit
359 EOF
360 }
361
362 show_usage_fail()
363 {
364         IFS= printf "%s\n\n" "$PROG: error: $*" >&2
365         show_usage >&2
366         exit 1
367 }
368
369 verbose=
370 while [ -n "${1:-""}" ] && [ -z "${1##-*}" ]; do
371         case "$1" in
372         --version)
373                 printf "%s\n" "$VER"
374                 exit 0
375                 ;;
376         -v|--verbose)
377                 verbose="-v"
378                 ;;
379         -h|--help)
380                 show_usage
381                 exit 0
382                 ;;
383         --) shift; break
384                 ;;
385         *) show_usage_fail "unrecognized option \"$1\""
386                 ;;
387         esac
388         shift
389 done
390
391 if [ "$#" -eq 0 ]; then
392         show_usage
393         exit 0
394 fi
395
396 # Parse subcommands
397
398 subcommand="$1"; shift
399
400 case "$subcommand" in
401 add)
402         add_subcommand "$@"
403         break
404         ;;
405 remove)
406         remove_subcommand "$@"
407         break
408         ;;
409 default)
410         default_subcommand "$@"
411         break
412         ;;
413 *) show_usage_fail "unrecognized subcommand \"$subcommand\""
414         ;;
415 esac