Drop unmaintained THANKS file
[grml-debootstrap.git] / chroot-script
1 #!/bin/bash
2 # Filename:      /etc/debootstrap/chroot-script
3 # Purpose:       script executed in chroot when installing Debian via grml-debootstrap
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8 # GRML_CHROOT_SCRIPT_MARKER - do not remove this line unless you want to keep
9 # this script as /bin/chroot-script on your new installed system
10 ################################################################################
11
12 # error_handler {{{
13 if [ "$REPORT_TRAP_ERR" = "yes" ] || [ "$FAIL_TRAP_ERR" = "yes" ]; then
14    set -E
15    set -o pipefail
16    trap "error_handler" ERR
17 fi
18 # }}}
19
20 . /etc/debootstrap/config    || exit 1
21 . /etc/debootstrap/variables || exit 1
22
23 [ -r /proc/1 ] || mount -t proc none /proc
24
25 # variable checks {{{
26
27 # use aptitude only if it's available
28 if [ -x /usr/bin/aptitude ] ; then
29    APTUPDATE="aptitude update $DPKG_OPTIONS"
30    # Debian ISOs do not contain signed Release files
31    if [ -n "$ISO" ] ; then
32       APTINSTALL="aptitude -y --allow-untrusted --without-recommends install $DPKG_OPTIONS"
33       APTUPGRADE="aptitude -y --allow-untrusted safe-upgrade $DPKG_OPTIONS"
34    else
35       APTINSTALL="aptitude -y --without-recommends install $DPKG_OPTIONS"
36       APTUPGRADE="aptitude -y safe-upgrade $DPKG_OPTIONS"
37    fi
38 else
39    APTINSTALL="apt-get --force-yes -y --no-install-recommends install $DPKG_OPTIONS"
40    APTUPDATE="apt-get update $DPKG_OPTIONS"
41    APTUPGRADE="apt-get --force-yes -y upgrade $DPKG_OPTIONS"
42 fi
43
44 if [ -z "$STAGES" ] ; then
45    STAGES='/etc/debootstrap/stages'
46    [ -d "$STAGES" ] || mkdir -p "$STAGES"
47 fi
48 # }}}
49
50 # helper functions {{{
51 stage() {
52   if [ -n "$2" ] ; then
53      echo "$2" > "$STAGES/$1"
54      return 0
55   elif grep -q 'done' "$STAGES/$1" 2>/dev/null ; then
56      echo "   [*] Notice: stage $1 has been executed already, skipping execution therefore.">&2
57      return 1
58   fi
59   echo "   Executing stage ${1}"
60   return 0
61 }
62
63 askpass() {
64   # read -s emulation for dash. result is in $resp.
65   set -o noglob
66   [ -t 0 ] && stty -echo
67   read resp
68   [ -t 0 ] && stty echo
69   set +o noglob
70 }
71 # }}}
72
73 # define chroot mirror {{{
74 chrootmirror() {
75   if [ -n "$KEEP_SRC_LIST" ] ; then
76     echo "KEEP_SRC_LIST has been set, skipping chrootmirror stage."
77     return
78   fi
79
80   if [ -z "$COMPONENTS" ] ; then
81     COMPONENTS='main'
82   fi
83   echo "Using repository components $COMPONENTS"
84
85   if [ -n "$ISO" ] ; then
86     echo "Adjusting sources.list for ISO (${ISO})."
87     echo "deb $ISO $RELEASE $COMPONENTS" > /etc/apt/sources.list
88
89     if [ -n "$MIRROR" ] ; then
90       echo "Adding mirror entry (${MIRROR}) to sources.list."
91       echo "deb $MIRROR $RELEASE $COMPONENTS" >> /etc/apt/sources.list
92     fi
93   else
94     if [ -n "$MIRROR" ] ; then
95       echo "Adjusting sources.list for mirror (${MIRROR})."
96       echo "deb $MIRROR $RELEASE $COMPONENTS" > /etc/apt/sources.list
97     fi
98   fi
99
100   # LTS support
101   case "$RELEASE" in
102     squeeze)
103       if [ -n "$MIRROR" ] ; then
104         echo "Release matching $RELEASE - enabling LTS support in sources.list"
105         echo "deb $MIRROR ${RELEASE}-lts $COMPONENTS" >> /etc/apt/sources.list
106       fi
107       ;;
108   esac
109
110   # add security.debian.org:
111   case "$RELEASE" in
112     unstable|sid|lenny) ;;  # no security pool available
113     *)
114       echo "Adding security.debian.org to sources.list."
115       echo "deb http://security.debian.org ${RELEASE}/updates $COMPONENTS" >> /etc/apt/sources.list
116       ;;
117   esac
118 }
119 # }}}
120
121 # remove local chroot mirror {{{
122 remove_chrootmirror() {
123   if [ -n "$KEEP_SRC_LIST" ] ; then
124     echo "KEEP_SRC_LIST has been set, skipping remove_chrootmirror stage."
125     return
126   fi
127
128   if [ -n "$ISO" ] ; then
129     echo "Removing ISO (${ISO}) from sources.list."
130     TMP_ISO=$(echo "$ISO" |sed 's#/#\\/#g')
131     sed -i "/deb $TMP_ISO $RELEASE $COMPONENTS/ D" /etc/apt/sources.list
132   else
133     if [ -n "$MIRROR" ] && echo "$MIRROR" | grep -q 'file:' ; then
134       echo "Removing local mirror (${MIRROR}) from sources.list."
135       TMP_MIRROR=$(echo "$MIRROR" |sed 's#/#\\/#g')
136       sed -i "/deb $TMP_MIRROR $RELEASE $COMPONENTS/ D" /etc/apt/sources.list
137       echo "Adding fallback mirror entry (${FALLBACK_MIRROR}) to sources.list instead."
138       echo "deb $FALLBACK_MIRROR $RELEASE $COMPONENTS" >> /etc/apt/sources.list
139     fi
140   fi
141 }
142 # }}}
143
144 # set up grml repository {{{
145 grmlrepos() {
146   if [ -n "$GRMLREPOS" ] ; then
147      # user might have provided their own apt sources.list
148      if ! grep -q grml /etc/apt/sources.list.d/grml.list 2>/dev/null ; then
149         cat >> /etc/apt/sources.list.d/grml.list << EOF
150 # grml: stable repository:
151   deb     http://deb.grml.org/ grml-stable  main
152   deb-src http://deb.grml.org/ grml-stable  main
153
154 # grml: testing/development repository:
155   deb     http://deb.grml.org/ grml-testing main
156   deb-src http://deb.grml.org/ grml-testing main
157 EOF
158      fi
159
160      if apt-get update $DPKG_OPTIONS; then
161        apt-get -y --allow-unauthenticated install grml-debian-keyring $DPKG_OPTIONS
162        apt-get update $DPKG_OPTIONS
163      else
164        # make sure we have the keys available for aptitude
165        gpg --keyserver subkeys.pgp.net --recv-keys 709BCE51568573EBC160E590F61E2E7CECDEA787
166        gpg --export 709BCE51568573EBC160E590F61E2E7CECDEA787 | apt-key add - || true # not yet sure
167        # why it's necessary, sometimes we get an error even though it works [mika]
168      fi
169
170      # make sure we install packages from Grml's pool only if not available
171      # from Debian!
172      if ! grep -q grml /etc/apt/preferences 2>/dev/null ; then
173         cat >> /etc/apt/preferences << EOF
174 // debian pool (default):
175 Package: *
176 Pin: release o=Debian
177 Pin-Priority: 996
178
179 // main grml-repository:
180 Package: *
181 Pin: origin deb.grml.org
182 Pin-Priority: 991
183 EOF
184      fi
185   fi
186 }
187 # }}}
188
189 # check available backports release version {{{
190 checkbackports() {
191   wget -q -O/dev/null "http://backports.debian.org/debian-backports/dists/${1}-backports/Release"
192 }
193 # }}}
194
195 # feature to provide Debian backports repos {{{
196 backportrepos() {
197     if [ -n "$BACKPORTREPOS" ] ; then
198         if ! checkbackports "$RELEASE" ; then
199             echo "Backports for ${RELEASE} are not available." >&2
200             exit 1
201         else
202             # user might have provided their own apt sources.list
203             if ! grep -q backports /etc/apt/sources.list.d/backports.list 2>/dev/null ; then
204                 cat >> /etc/apt/sources.list.d/backports.list << EOF
205 # debian backports: ${RELEASE}-backports repository:
206 deb     http://backports.debian.org/debian-backports ${RELEASE}-backports main
207 deb-src http://backports.debian.org/debian-backports ${RELEASE}-backports main
208 EOF
209             fi
210         fi
211     fi
212 }
213 # }}}
214
215 # set up kernel-img.conf {{{
216 kernelimg_conf() {
217   if ! [ -r /etc/kernel-img.conf ] ; then
218      echo "Setting up /etc/kernel-img.conf"
219      cat > /etc/kernel-img.conf << EOF
220 # Kernel Image management overrides
221 # See kernel-img.conf(5) for details
222 do_initrd = Yes
223 do_symlinks = Yes
224 EOF
225   fi
226 }
227 # }}}
228
229 # make sure services do not start up {{{
230 install_policy_rcd() {
231   if ! [ -r /usr/sbin/policy-rc.d ] ; then
232      export POLICYRCD=1
233      cat > /usr/sbin/policy-rc.d << EOF
234 #!/bin/sh
235 exit 101
236 EOF
237      chmod 775 /usr/sbin/policy-rc.d
238   fi
239 }
240 # }}}
241
242 # make sure we have an up2date system {{{
243 upgrade_system() {
244   if [ "$UPGRADE_SYSTEM" = "yes" ] ; then
245     echo "Running update + upgrade"
246     $APTUPDATE
247     DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTUPGRADE
248   else
249     echo "Not running update + upgrade as \$UPDATE_AND_UPGRADE is not set to 'yes'."
250   fi
251 }
252
253 # }}}
254 # remove now useless apt cache {{{
255 remove_apt_cache() {
256   if [ "$RM_APTCACHE" = 'yes' ] ; then
257     echo "Cleaning apt cache."
258     apt-get clean $DPKG_OPTIONS
259   else
260     echo "Not cleaning apt cache as \$RM_APTCACHE is unset."
261   fi
262 }
263 # }}}
264
265 # install additional packages {{{
266 packages() {
267   # Pre-seed the debconf database with answers. Each question will be marked
268   # as seen to prevent debconf from asking the question interactively.
269   [ -f /etc/debootstrap/debconf-selections ] && {
270     echo "Preseeding the debconf database, some lines might be skipped..."
271     debconf-set-selections < /etc/debootstrap/debconf-selections
272   }
273
274   if [ "$PACKAGES" = 'yes' ] ; then
275      if ! [ -r /etc/debootstrap/packages ] ; then
276        echo "Error: /etc/debootstrap/packages (inside chroot) not found, exiting." >&2
277        exit 1
278      else
279        $APTUPDATE
280        DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL $(grep -v '^#' /etc/debootstrap/packages) $GRMLPACKAGES
281      fi
282   fi
283 }
284 # }}}
285
286 # install extra packages {{{
287 extrapackages() {
288     if [ "$EXTRAPACKAGES" = 'yes' ] ; then
289         PACKAGELIST=$(find /etc/debootstrap/extrapackages -type f -name '*.deb')
290         if [ -n "$PACKAGELIST" ]; then
291             dpkg -i $PACKAGELIST
292             # run apt again to resolve any deps
293             DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL
294         fi
295     fi
296 }
297 # }}}
298
299 # check if the specified Debian package exists
300 package_exists() {
301   output=$(apt-cache show "$1" 2>/dev/null)
302   [ -n "$output" ]
303   return $?
304 }
305
306
307 # determine the kernel version postfix
308 get_kernel_version() {
309   # do not override $KERNEL if set via config file
310   if [ -n "$KERNEL" ] ; then
311     echo "$KERNEL"
312     return 0
313   fi
314
315   local KARCH
316
317   case "$ARCH" in
318     i386)
319       case "$RELEASE" in
320         lenny|squeeze|wheezy) KARCH='686' ;;
321         # since jessie the linux-image-686 image doesn't exist any longer
322         *) KARCH='686-pae' ;;
323       esac
324       ;;
325     amd64)
326       KARCH='amd64'
327       ;;
328     *)
329       echo "Only i386 and amd64 are currently supported" >&2
330       return 1
331   esac
332
333   for KPREFIX in "" "2.6-" ; do  # iterate through the kernel prefixes,
334                                  # currently "" and "2.6-"
335     if package_exists linux-image-${KPREFIX}${KARCH} ; then
336       echo ${KPREFIX}${KARCH}
337       return 0
338     fi
339
340   done
341 }
342
343 # install kernel packages {{{
344 kernel() {
345   if [ -n "$NOKERNEL" ] ; then
346     echo "Skipping installation of kernel packages as requested via --nokernel"
347     return 0
348   fi
349
350   $APTUPDATE
351   KVER=$(get_kernel_version)
352   if [ -n "$KVER" ] ; then
353      # note: install busybox to be able to debug initramfs
354      KERNELPACKAGES="linux-image-$KVER linux-headers-$KVER busybox firmware-linux-free"
355      # only add firmware-linux if we have non-free as a component
356      if expr "$COMPONENTS" : '.*non-free' >/dev/null ; then
357        KERNELPACKAGES="$KERNELPACKAGES firmware-linux"
358      fi
359      DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL $KERNELPACKAGES
360   else
361      echo "Warning: Could not find a kernel for your system. Your system won't be able to boot itself!"
362   fi
363 }
364 # }}}
365
366 # reconfigure packages {{{
367 reconfigure() {
368   if [ -n "$RECONFIGURE" ] ; then
369      for package in $RECONFIGURE ; do
370          if dpkg --list $package >/dev/null 2>&1 | grep -q '^ii' ; then
371            DEBIAN_FRONTEND=$DEBIAN_FRONTEND dpkg-reconfigure $package || \
372            echo "Warning: $package does not exist, can not reconfigure it."
373          fi
374      done
375   fi
376 }
377 # }}}
378
379 # set password of user root {{{
380 passwords()
381 {
382   if [ -n "$NOPASSWORD" ] ; then
383     echo "Skip setting root password as requested."
384     return 0
385   fi
386
387   echo "Activating shadow passwords."
388   shadowconfig on
389
390   CHPASSWD_OPTION=
391   if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
392      CHPASSWD_OPTION='-m'
393   fi
394
395   if [ -n "$ROOTPASSWORD" ] ; then
396      echo root:"$ROOTPASSWORD" | chpasswd $CHPASSWD_OPTION
397      export ROOTPASSWORD=''
398   else
399     a='1'
400     b='2'
401      echo "Setting password for user root:"
402      while [ "$a" != "$b" ] ; do
403        printf "Enter new UNIX password for user root: "
404        askpass
405        a="$resp"
406        unset resp
407        echo
408        printf "Retype new UNIX password for user root: "
409        askpass
410        b="$resp"
411        unset resp
412        echo
413        if [ "$a" != "$b" ] ; then
414          echo "Sorry, passwords do not match. Retry."
415          a='1'
416          b='2'
417        else
418          echo root:"$a" | chpasswd $CHPASSWD_OPTION
419          unset a
420          unset b
421        fi
422      done
423   fi
424 }
425 # }}}
426
427 # set up /etc/hosts {{{
428 hosts() {
429   if [ -f /etc/hosts ] ; then
430      sed -i "s#127.0.0.1 .*#127.0.0.1       localhost  $HOSTNAME#" /etc/hosts
431      [ -n "$HOSTNAME" ] && sed -i "s/grml/$HOSTNAME/g" /etc/hosts
432   else
433      cat > /etc/hosts << EOF
434 127.0.0.1       localhost $HOSTNAME
435
436 #127.0.0.1       localhost
437 #127.0.1.1       $HOSTNAME.example.org $HOSTNAME
438
439 # The following lines are desirable for IPv6 capable hosts
440 #::1     ip6-localhost ip6-loopback $HOSTNAME
441 ::1     ip6-localhost ip6-loopback
442 fe00::0 ip6-localnet
443 ff00::0 ip6-mcastprefix
444 ff02::1 ip6-allnodes
445 ff02::2 ip6-allrouters
446 ff02::3 ip6-allhosts
447 EOF
448   fi
449 }
450 # }}}
451
452 # set default locales {{{
453 default_locales() {
454   if [ -n "$DEFAULT_LOCALES" ] ; then
455     if ! [ -x /usr/sbin/update-locale ] ; then
456       echo "Warning: update-locale executable not available (no locales package installed?)"
457       echo "Ignoring request to run update-locale for $DEFAULT_LOCALES therefore"
458       return 0
459     fi
460
461     /usr/sbin/update-locale LANGUAGE="$DEFAULT_LANGUAGE" LANG="$DEFAULT_LOCALES"
462   fi
463 }
464 # }}}
465
466 # adjust timezone {{{
467 timezone() {
468   if [ -n "$TIMEZONE" ] ; then
469      echo "Adjusting /etc/localtime"
470      ln -sf "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime
471   fi
472 }
473 # }}}
474
475 # helper function for fstab() {{{
476 createfstab(){
477      echo "Setting up /etc/fstab"
478 if [ -n "$TARGET_UUID" ] ; then
479    echo "/dev/disk/by-uuid/${TARGET_UUID} /  auto    defaults,errors=remount-ro 0   1" > /etc/fstab
480 else
481    echo "${TARGET} /  auto    defaults,errors=remount-ro 0   1" > /etc/fstab
482 fi
483
484 cat >> /etc/fstab << EOF
485 proc           /proc        proc    defaults                      0   0
486 /dev/cdrom     /mnt/cdrom0  iso9660 ro,user,noauto                0   0
487 # some other examples:
488 # /dev/sda2       none         swap    sw,pri=0             0   0
489 # /dev/hda1       /Grml        ext3    dev,suid,user,noauto 0  2
490 # //1.2.3.4/pub   /smb/pub     cifs    user,noauto,uid=grml,gid=grml 0 0
491 # linux:/pub      /beer        nfs     defaults             0  0
492 # tmpfs           /tmp         tmpfs   size=300M            0  0
493 # /dev/sda5       none         swap    sw                   0  0
494 EOF
495 }
496 # }}}
497
498 # generate /etc/fstab {{{
499 fstab() {
500   # set up /etc/fstab if file is not present (cdebootstrap)
501   if [ ! -f /etc/fstab  ] ; then
502      createfstab
503   fi
504
505   # set up /etc/fstab if file is UNCONFIGURED (debootstrap)
506   if grep -q UNCONFIGURED /etc/fstab ; then
507      createfstab
508   fi
509 }
510 # }}}
511
512 # set up hostname {{{
513 hostname() {
514   if [ -n "$HOSTNAME" ] ; then
515      echo "Setting hostname to ${HOSTNAME}."
516      echo "$HOSTNAME" > /etc/hostname
517
518      # adjust postfix configuration
519      if [ -r /etc/postfix/main.cf ] ; then
520         # adjust hostname related options:
521         sed -i "s/grml/$HOSTNAME/g" /etc/postfix/main.cf
522
523         # listen on loopback interface only:
524         sed -i "s/^inet_interfaces = .*/inet_interfaces = loopback-only/" /etc/postfix/main.cf
525         grep -q inet_interfaces /etc/postfix/main.cf || echo 'inet_interfaces = loopback-only' >> /etc/postfix/main.cf
526      fi
527      if [ -r /etc/mailname ] ; then
528         # adjust /etc/mailname
529         local etc_mail_domain=$(/bin/dnsdomainname 2>/dev/null || echo localdomain)
530         case "$HOSTNAME" in
531           *.*)
532             local mailname="$HOSTNAME"
533             ;;
534           *)
535             local mailname="${HOSTNAME}.${etc_mail_domain}"
536             ;;
537         esac
538         echo "Setting mailname to ${mailname}"
539         echo "$mailname" > /etc/mailname
540      fi
541   fi
542 }
543 # }}}
544
545 # generate initrd/initramfs {{{
546 initrd() {
547   # assume the first available kernel as our main kernel
548   KERNELIMG=$(ls -1 /boot/vmlinuz-* 2>/dev/null | head -1)
549   if [ -z "$KERNELIMG" ] ; then
550      echo 'No kernel image found, skipping initrd stuff.'>&2
551      return
552   fi
553
554   KERNELVER=${KERNELIMG#/boot/vmlinuz-}
555
556   # generate initrd
557   if [ -n "$INITRD" ] ; then
558      echo "Generating initrd."
559      update-initramfs -c -t -k "$KERNELVER"
560   fi
561 }
562 # }}}
563
564 # grub configuration/installation {{{
565 grub_install() {
566
567   if [ -z "$GRUB" ] ; then
568     echo "Notice: \$GRUB not defined, will not install grub inside chroot at this stage."
569     return 0
570   fi
571
572   if ! dpkg --list grub-pc 2>/dev/null | grep -q '^ii' ; then
573     echo "Notice: grub option set but no grub-pc package, installing it therefore."
574     DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL grub-pc
575   fi
576
577   if ! [ -x "$(which grub-install)" ] ; then
578      echo "Error: grub-install not available. (Error while installing grub package?)" >&2
579      return 1
580   fi
581
582   if [ -n "$SELECTED_PARTITIONS" ] ; then # using sw-raid
583      for device in $SELECTED_PARTITIONS ; do
584         GRUB="${device%%[0-9]}"
585         echo "Installing grub on ${GRUB}:"
586         grub-install --no-floppy "$GRUB"
587      done
588      rm -f /boot/grub/device.map
589   else
590      echo "Installing grub on ${GRUB}:"
591      case "$RELEASE" in
592        lenny|squeeze|wheezy)
593          grub-install --no-floppy "$(readlink -f "${GRUB}")"
594          rm -f /boot/grub/device.map
595          ;;
596        *)
597          echo "(hd0) ${GRUB}" > /boot/grub/device.map
598          grub-install "(hd0)"
599          rm /boot/grub/device.map
600          ;;
601      esac
602   fi
603
604   echo "Adjusting grub configuration for use on ${GRUB}."
605
606   # finally install grub
607   if [ -x /usr/sbin/update-grub ] ; then
608      UPDATEGRUB='/usr/sbin/update-grub'
609   elif [ -x /sbin/update-grub ] ; then
610      UPDATEGRUB='/sbin/update-grub'
611   else
612     echo "Error: update-grub not available, can not execute it." >&2
613     return 1
614   fi
615
616   $UPDATEGRUB
617 }
618 # }}}
619
620 # execute all scripts present in /etc/debootstrap/chroot-scripts/ {{{
621 custom_scripts() {
622   [ -d /etc/debootstrap/chroot-scripts/ ] || return 0
623
624   for script in /etc/debootstrap/chroot-scripts/* ; do
625       echo "Executing script $script"
626       $script && echo "done" || echo "failed"
627   done
628 }
629 # }}}
630
631 # make sure we don't have any running processes left {{{
632 services() {
633   for service in ssh mdadm mdadm-raid ; do
634     if [ -x /etc/init.d/"$service" ] ; then
635        /etc/init.d/"$service" stop || true
636     fi
637   done
638 }
639 # }}}
640
641 # unmount /proc and make sure nothing is left {{{
642 finalize() {
643   # make sure we don't leave any sensible data
644   rm -f /etc/debootstrap/variables
645
646   [ -n "$POLICYRCD" ] && rm -f /usr/sbin/policy-rc.d
647
648   umount /proc >/dev/null 2>/dev/null || true
649 }
650 # }}}
651
652 # signal handler {{{
653 signal_handler() {
654   finalize
655   [ -n "$1" ] && EXIT="$1" || EXIT="1"
656   exit "$EXIT"
657 }
658 # }}}
659
660 # set signal handler {{{
661 trap signal_handler HUP INT QUIT TERM
662 # }}}
663
664 # execute the functions {{{
665
666  # always execute install_policy_rcd
667  install_policy_rcd
668
669  for i in chrootmirror grmlrepos backportrepos kernelimg_conf \
670      kernel packages extrapackages reconfigure hosts \
671      default_locales timezone fstab hostname initrd grub_install passwords \
672      custom_scripts upgrade_system remove_apt_cache services \
673      remove_chrootmirror; do
674      if stage $i ; then
675        $i && stage $i 'done' || exit 1
676      fi
677   done
678   # always execute the finalize stage:
679   finalize
680 # }}}
681
682 # finally exit the chroot {{{
683   echo "Finished chroot installation, exiting."
684   exit 0
685 # }}}
686
687 ## END OF FILE #################################################################
688 # vim: ai tw=80 expandtab foldmethod=marker