Würgaround for changed chpasswd options
[grml-debootstrap.git] / chroot-script
index 5b68a0b..347bead 100755 (executable)
@@ -17,10 +17,10 @@ set -e # exit on any error
 
 # use aptitude only if it's available
 if [ -x /usr/bin/aptitude ] ; then
-   APTINSTALL='aptitude -y --without-recommends install '
+   APTINSTALL="aptitude -y --without-recommends install $DPKG_OPTIONS"
    APTUPDATE='aptitude update'
 else
-   APTINSTALL='apt-get --force-yes -y install'
+   APTINSTALL="apt-get --force-yes -y install $DPKG_OPTIONS"
    APTUPDATE='apt-get update'
 fi
 
@@ -36,20 +36,25 @@ stage() {
      echo "$2" > "$STAGES/$1"
      return 0
   elif grep -q done "$STAGES/$1" 2>/dev/null ; then
-     echo "[*] Notice: stage $1 has been executed already, skipping execution therefore.">&2
+     echo "   [*] Notice: stage $1 has been executed already, skipping execution therefore.">&2
      return 1
   fi
+  echo "   Executing stage ${1}"
+  return 0
 }
 # }}}
 
 # define chroot mirror {{{
 chrootmirror() {
+  [ -n "$KEEP_SRC_LIST" ] && return
+  [ -z "$COMPONENTS" ]    && COMPONENTS='main contrib non-free'
+
   if [ -n "$ISO" ] ; then
-     echo "deb $ISO $RELEASE main contrib" > /etc/apt/sources.list
-     [ -n "$CHROOTMIRROR" ] && echo "deb $CHROOTMIRROR $RELEASE main contrib non-free" >> /etc/apt/sources.list
+     echo "deb $ISO $RELEASE $COMPONENTS" > /etc/apt/sources.list
+     [ -n "$MIRROR" ] && echo "deb $MIRROR $RELEASE $COMPONENTS" >> /etc/apt/sources.list || /bin/true
   else
-    if [ -n "$CHROOTMIRROR" ] ; then
-       echo "deb $CHROOTMIRROR $RELEASE main contrib non-free" > /etc/apt/sources.list
+    if [ -n "$MIRROR" ] ; then
+       echo "deb $MIRROR $RELEASE $COMPONENTS" > /etc/apt/sources.list
     fi
   fi
 }
@@ -58,7 +63,9 @@ chrootmirror() {
 # set up grml repository {{{
 grmlrepos() {
   if [ -n "$GRMLREPOS" ] ; then
-     cat >> /etc/apt/sources.list << EOF
+     # user might have provided their own apt sources.list
+     if ! grep -q grml /etc/apt/sources.list 2>/dev/null ; then
+        cat >> /etc/apt/sources.list << EOF
 
 # grml: stable repository:
   deb     http://deb.grml.org/ grml-stable  main
@@ -69,6 +76,8 @@ grmlrepos() {
   deb-src http://deb.grml.org/ grml-testing main
 
 EOF
+     fi
+
      # make sure we have the keys available for aptitude
      gpg --keyserver subkeys.pgp.net --recv-keys F61E2E7CECDEA787
      gpg --export F61E2E7CECDEA787 | apt-key add - || /bin/true # not yet sure
@@ -131,6 +140,13 @@ EOF
 
 # install additional packages {{{
 packages() {
+  # Pre-seed the debconf database with answers. Each question will be marked
+  # as seen to prevent debconf from asking the question interactively.
+  [ -f /etc/debootstrap/debconf-selections ] && {
+    echo "Preseeding the debconf database, some lines might be skipped..."
+    cat /etc/debootstrap/debconf-selections | debconf-set-selections
+  }
+
   if [ "$PACKAGES" = 'yes' ] ; then
      if ! [ -r /etc/debootstrap/packages ] ; then
        echo "Error: /etc/debootstrap/packages not found, exiting."
@@ -205,8 +221,14 @@ passwords()
   echo "Activating shadow passwords."
   shadowconfig on
 
+  CHPASSWD_OPTION=
+  if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
+     CHPASSWD_OPTION='-m'
+  fi
+
+
   if [ -n "$ROOTPASSWORD" ] ; then
-     echo root:"$ROOTPASSWORD" | chpasswd -m
+     echo root:"$ROOTPASSWORD" | chpasswd $CHPASSWD_OPTION
      export ROOTPASSWORD=''
   else
     a='1'
@@ -224,7 +246,7 @@ passwords()
          a='1'
          b='2'
        else
-         echo root:"$a" | chpasswd -m
+         echo root:"$a" | chpasswd $CHPASSWD_OPTION
          unset a
          unset b
        fi
@@ -235,16 +257,32 @@ passwords()
 
 # set up /etc/hosts {{{
 hosts() {
-  if ! [ -f /etc/hosts ] ; then
-     echo "Setting up /etc/hosts"
-     echo "127.0.0.1       localhost  $HOSTNAME" > /etc/hosts
+  if [ -f /etc/hosts ] ; then
+     sed -i "s#127.0.0.1 .*#127.0.0.1       localhost  $HOSTNAME#" /etc/hosts
+     [ -n "$HOSTNAME" ] && sed -i "s/grml/$HOSTNAME/g" /etc/hosts
+  else
+     cat > /etc/hosts << EOF
+127.0.0.1       localhost $HOSTNAME
+
+#127.0.0.1       localhost
+#127.0.1.1       $HOSTNAME.example.org $HOSTNAME
+
+# The following lines are desirable for IPv6 capable hosts
+#::1     ip6-localhost ip6-loopback $HOSTNAME
+::1     ip6-localhost ip6-loopback
+fe00::0 ip6-localnet
+ff00::0 ip6-mcastprefix
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
+ff02::3 ip6-allhosts
+EOF
   fi
 }
 # }}}
 
 # set up /etc/network/interfaces {{{
 interfaces() {
-  if ! [ -r /etc/network/interfaces ] ; then
+  if ! [ -r /etc/network/interfaces ] || ! grep -q "auto lo" /etc/network/interfaces ; then
      echo "Setting up /etc/network/interfaces"
      cat >> /etc/network/interfaces << EOF
 
@@ -312,6 +350,18 @@ hostname() {
   if [ -n "$HOSTNAME" ] ; then
      echo "Setting hostname to ${HOSTNAME}."
      echo "$HOSTNAME" > /etc/hostname
+
+     # adjust postfix configuration
+     if [ -r /etc/postfix/main.cf ] ; then
+        # adjust hostname related options:
+        sed -i "s/grml/$HOSTNAME/g" /etc/postfix/main.cf
+        sed -i "s/^myhostname = .*/myhostname = $HOSTNAME/" /etc/postfix/main.cf
+        sed -i "s/^mydestination = .*/mydestination = localdomain, localhost, localhost.localdomain, $HOSTNAME/" /etc/postfix/main.cf
+
+        # listen on loopback interface only:
+        sed -i "s/^inet_interfaces = .*/inet_interfaces = loopback-only/" /etc/postfix/main.cf
+        grep -q inet_interfaces /etc/postfix/main.cf || echo 'inet_interfaces = loopback-only' >> /etc/postfix/main.cf
+     fi
   fi
 }
 # }}}
@@ -319,7 +369,12 @@ hostname() {
 # generate initrd/initramfs {{{
 initrd() {
   # assume the first available kernel as our main kernel
-  KERNELIMG=$(ls -1 /boot/vmlinuz-* | head -1)
+  KERNELIMG=$(ls -1 /boot/vmlinuz-* 2>/dev/null | head -1)
+  if [ -z "$KERNELIMG" ] ; then
+     echo 'No kernel image found, skipping initrd stuff.'>&2
+     return
+  fi
+
   KERNELVER=${KERNELIMG#/boot/vmlinuz-}
 
   # generate initrd
@@ -363,11 +418,20 @@ grub() {
      $UPDATEGRUB -y
      if [ -f /boot/grub/menu.lst ] ; then
         sed -i "s/^# groot=.*/# groot=(${GROOT})/g" /boot/grub/menu.lst
-       if [ -n "$TARGET_UUID" ] ; then
-          sed -i "s|^# kopt=root=.*|# kopt=root=UUID=${TARGET_UUID} ro ${BOOT_APPEND}|g" /boot/grub/menu.lst
-       else
-          sed -i "s|^# kopt=root=.*|# kopt=root=${TARGET} ro ${BOOT_APPEND}|g" /boot/grub/menu.lst
-       fi
+        case "$TARGET" in
+             # do NOT use uuid with SW-RAID
+             /dev/md*)
+               sed -i "s|^# kopt=root=.*|# kopt=root=${TARGET} ro ${BOOT_APPEND}|g" /boot/grub/menu.lst
+               ;;
+             *)
+               if [ -n "$TARGET_UUID" ] ; then
+                 sed -i "s|^# kopt=root=.*|# kopt=root=UUID=${TARGET_UUID} ro ${BOOT_APPEND}|g" /boot/grub/menu.lst
+               else
+                 sed -i "s|^# kopt=root=.*|# kopt=root=${TARGET} ro ${BOOT_APPEND}|g" /boot/grub/menu.lst
+               fi
+               ;;
+        esac
+
         # not sure why savedefault does not work for me; any ideas?
         sed -i "s/^savedefault.*/# &/g" /boot/grub/menu.lst
         $UPDATEGRUB -y
@@ -376,6 +440,17 @@ grub() {
 }
 # }}}
 
+# execute all scripts present in /etc/debootstrap/chroot-scripts/ {{{
+custom_scripts() {
+  [ -d /etc/debootstrap/chroot-scripts/ ] || return 0
+
+  for script in /etc/debootstrap/chroot-scripts/* ; do
+      echo "Executing script $script"
+      $script && echo "done" || echo "failed"
+  done
+}
+# }}}
+
 # make sure we don't have any running processes left {{{
 services() {
   for service in ssh mdadm mdadm-raid ; do
@@ -400,12 +475,14 @@ finalize() {
 
 # execute the functions {{{
  for i in chrootmirror grmlrepos kernelimg_conf makedev install_policy_rcd \
-     packages extrapackages mkinitrd kernel reconfigure hosts interfaces   \
-     timezone fstab hostname initrd grub passwords services finalize ; do
-    if stage $i ; then
+     kernel packages extrapackages mkinitrd reconfigure hosts interfaces   \
+     timezone fstab hostname initrd grub passwords custom_scripts services ; do
+     if stage $i ; then
        $i && stage $i done || exit 1
-    fi
+     fi
   done
+  # always execute the finalize stage:
+  finalize
 # }}}
 
 # finally exit the chroot {{{