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