Upgrade grub-pc with kernel-cn.
[carnet-upgrade.git] / src / functions.sh
index 79c2bfd..1d94faa 100644 (file)
@@ -35,24 +35,6 @@ log() {
   chmod og= $logfile
 }
 
-# find first free uid/gid in range
-# find_id passwd 100 999
-find_id() {
-  local i db first last ids
-  db=$1
-  first=$2
-  last=$3
-  ids=$(getent $db | awk -F: "\$3 >= $first && \$3 <= $last {print \$3}")
-  for i in $(seq $first $last)
-  do
-    if ! echo $ids | grep -q $i; then
-      echo $i
-      return 0
-    fi
-  done
-  return 1
-}
-
 # safe in-place s///
 check_and_sed() {
   [ "$DEBIAN_SCRIPT_DEBUG" ] && set -vx
@@ -79,27 +61,6 @@ check_and_sed() {
   return $ret
 }
 
-#
-# Update uid for user from reserved system range (0-99) to dynamic system
-# range (100-999).  Optionally update ownerships of given directories.
-# $0 user [directory ...]
-#
-check_and_update_ugid() {
-  local user newgid newuid
-  user=$1
-  if [ "$(getent passwd $user | awk -F: '$3 >= 100 {print "ok"; exit 0}')" ]; then
-    return 0
-  fi
-  shift
-  newgid=$(find_id group 100 999)
-  newuid=$(find_id passwd 100 999)
-  # other directories/files
-  chown -R $newuid:$newgid $*
-  groupmod -g $newgid $user
-  usermod -u $newuid -g $newgid $user
-  log "Fixed $user user uid/gid."
-}
-
 pkgadd () {
   [ -n "$*" ] || return 0
   log "Installing $* ..."
@@ -159,11 +120,34 @@ dist_upgrade () {
   }
 }
 
+apt_autoremove () {
+  log "Running autoremove ..."
+  apt-get -y$s --purge autoremove || {
+    dpkg --configure -a
+    apt-get -yf install
+  }
+}
+
+# remove stale package information from available
+#   warning, in file '/var/lib/dpkg/available'
+#   near line 58185 package 'vim-cn': missing architecture
+cleanup_available () {
+  log "Cleaning dpkg available file"
+
+  available=$(mktemp /var/lib/carnet-upgrade/available.XXXXXX)
+  apt-cache dumpavail > $available
+
+  dpkg --clear-avail
+  dpkg --update-avail $available
+
+  rm -f $available
+}
+
 remove_x() {
   LC_MESSAGES=hr_HR dialog --backtitle "$title" --yesno "$msg_remove_x" 18 75
   if [ $? -eq 0 ]; then
     log "Removing X Window System"
-    pkgrm x11-common
+    pkgrm xserver-xorg
   else
     log "Skipping X Window System removal"
   fi
@@ -217,6 +201,7 @@ remove_bloat() {
       fi
     done
   done
+  IFS="$oldifs"
   [ "$DEBUG" ] && echo "DEBUG: pkgs_to_remove=$pkgs_to_remove" 1>&2
   # Finally, remove those
   if [ -n "$update_selections" ]; then
@@ -398,38 +383,6 @@ Nakon toga ponovno pozovite ovu skriptu."
   fi
 }
 
-# update sarge urls in sources list
-fix_sarge_sources () {
-  local apt_sources='/etc/apt/sources.list'
-  local fixed_sources=$(mktemp /var/lib/carnet-upgrade/sources.list.XXXXXX)
-
-  # sarge (oldstable) was archived recently -> sources.list needs update
-  awk -v archive='http://archive.debian.org/debian' \
-      -v security='http://archive.debian.org/debian-security' \
-      '$3 == "sarge" && $2 ~ /[/]debian$/ { $2 = archive }
-       $3 == "sarge/updates" && $2 ~ /security\.debian\.org$/ { $2 = security }
-       { print }' $apt_sources > $fixed_sources
-
-  # did anything get updated
-  if ! cmp $apt_sources $fixed_sources >/dev/null; then
-      log "sources.list fixed to use archive.debian.org"
-
-      # backup current version
-      if [ ! -f "$apt_sources.$backup_ext.sarge" ]; then
-          cp -av $apt_sources "$apt_sources.$backup_ext.sarge"
-      fi
-
-      # install fixed version
-      cp -av $fixed_sources $apt_sources
-
-      # update the database
-      apt_update
-  fi
-
-  # delete temporary
-  rm -f $fixed_sources
-}
-
 # try to check if we are using the latest version of carnet-upgrade script
 check_my_version () {
   local packages latest_version
@@ -453,79 +406,6 @@ check_my_version () {
   rm -f $packages
 }
 
-# if php is installed make sure it's version 5
-check_php_version () {
-
-  if pkg php4-cn && ! pkg php5-cn; then
-    # prepare for php upgrade by installing php5 extensions
-    install_php5_extensions
-
-    notice "
-Prije prelaska na Debian Squeeze potrebno je napraviti nadogradnju sa PHP 4 na PHP 5.
-
-Pokrenite:
-  # apt-get update
-  # apt-get install php5-cn
-  
-Nakon sto provjerite da sve web aplikacije rade ispravno, ponovno pozovite ovu skriptu."
-    log "carnet-upgrade aborted, upgrade to php5-cn needed."
-    exit 1
-  fi
-}
-
-# install php5 extensions based on installed php4 extensions
-install_php5_extensions () {
-  local php4_list php5_pkg
-
-  # get a list of installed php4 packages
-  php4_list=$(mktemp /var/lib/carnet-upgrade/php4_list.XXXXXX)
-  dpkg -l php4-\* | awk '/^ii/ {
-    pkg=$2; sub("^php4", "php5", pkg); print pkg }' > $php4_list
-
-  # compare it with the list of available php5 packages
-  php5_pkg=$(apt-cache search -n ^php5- | cut -d' ' -f 1 \
-    | grep -F -x -f $php4_list | grep -F -x -v php5-cn)
-
-  # handle special cases
-  if pkg php4-xslt; then
-     php5_pkg="$php5_pkg php5-xsl"
-  fi
-
-  # install the required php5 modules
-  if [ "$php5_pkg" ]; then
-     pkgadd $php5_pkg
-  fi
-
-  # cleanup
-  rm -f $php4_list
-}
-
-# if grsec is installed make sure it is fresh
-check_grsec_kernel () {
-  local ver=`uname -r`
-
-  log "Kernel version: $ver"
-  if [ "$ver" = "${ver%-grsec}" ]; then
-    # not grsec variant
-    return 0
-  fi
-
-  if [ "$ver" = "${ver#2.6.2[4-9]}" ]; then
-    # kernel too old
-    notice "
-Prije prelaska na Debian Squeeze potrebno je napraviti nadogradnju na najnoviji kernel.
-
-Pokrenite:
-  # apt-get update
-  # apt-get install kernel-2.6-cn
-  # reboot
-  
-Nakon toga ponovno pozovite ovu skriptu."
-    log "carnet-upgrade aborted, kernel upgrade needed."
-    exit 1
-  fi
-}
-
 check_reboot () {
   reboot_required || return 0
 
@@ -600,7 +480,9 @@ reboot_required () {
   running_version=$( uname -v )
   log "Running kernel: $running_release $running_version"
 
-  if grep -q "$running_release .* $running_version" $default_kernel; then
+  if [ "$kernel_package" != "${kernel_package#linux-image-3.2.0-}" ] ||
+     grep -q "$running_release .* $running_version" $default_kernel
+  then
       log "Latest kernel version is running." 
       return 1
   else
@@ -636,7 +518,12 @@ install_new () {
 create_sources_list () {
     local sl sl_new
     sl=/etc/apt/sources.list
-    sl_new=/usr/share/carnet-upgrade/files/etc/apt/sources.list
+    sl_new=$( copy_template $sl )
+
+    # comment aai repository if not in use
+    if ! pkg srce-keyring; then
+        sed -i 's/^\(deb.*ftp.srce.hr\)/#\1/' $sl_new
+    fi
 
     # check if already installed
     if ! cmp $sl $sl_new >/dev/null; then
@@ -652,8 +539,9 @@ create_sources_list () {
 
 `cat /etc/apt/sources.list`"
     fi
-}
 
+    rm $sl_new
+}
 
 # funkcija koja brise grupu proc
 remove_group_proc () {
@@ -737,22 +625,6 @@ backup_etc_dir () {
   fi
 }
 
-# fixaj /etc/default/raid2
-fix_etc_default_raid2 () {
-  if [ -f /etc/default/raid2 ]; then
-    sed "s/^AUTOSTART.*/AUTOSTART=true/g" /etc/default/raid2 > /etc/default/raid2.$backup_ext.$$
-    chown --reference=/etc/default/raid2 /etc/default/raid2.$backup_ext.$$
-    chmod --reference=/etc/default/raid2 /etc/default/raid2.$backup_ext.$$
-
-    if ! cmp -s /etc/default/raid2.$backup_ext.$$ /etc/default/raid2; then
-      log "Fixed /etc/default/raid2 AUTOSTART option."
-      mv -v /etc/default/raid2.$backup_ext.$$ /etc/default/raid2
-    else
-      rm -v /etc/default/raid2.$backup_ext.$$
-    fi
-  fi
-}
-
 # restore a configuration file if it contains only CN modifications
 restore_file () {
   local file file_expect file_restore file_backup
@@ -823,73 +695,42 @@ restore_configs () {
   local hostname domain config_new memtotal memlimit
 
   # restore simple configs
-  if pkg ntp-cn && pkg ntp lt 1:4.2.6.p2+dfsg-1+b1; then
+  if pkg ntp-cn && pkg ntp lt 1:4.2.6.p5+dfsg-2; then
      if restore_file /etc/ntp.conf; then
         postupgrade_reconfigure ntp-cn
      fi
   fi
 
-  if pkg kernel-2.6-cn && pkg procps lt 1:3.2.8-9; then
-     if restore_file /etc/sysctl.conf; then
-        postupgrade_reconfigure kernel-2.6-cn
-     fi
-  fi
-
-  if pkg kernel-2.6-cn && pkg libpam-modules lt 1.1.1-6.1; then
-     if restore_file /etc/security/limits.conf; then
-        postupgrade_reconfigure kernel-2.6-cn
-     fi
-  fi
-
-  if pkg vsftpd-cn && pkg vsftpd lt 2.3.2-3+squeeze2; then
+  if pkg vsftpd-cn && pkg vsftpd lt 2.3.5-3; then
      if restore_file /etc/vsftpd.conf; then
         postupgrade_reconfigure vsftpd-cn
      fi
   fi
 
-  if pkg squirrelmail-cn && pkg squirrelmail lt 2:1.4.21-2; then
-     if restore_file /etc/squirrelmail/apache.conf; then
-        postupgrade_reconfigure squirrelmail-cn
+  if pkg amavisd-cn && pkg amavisd-new lt 1:2.7.1-2; then
+     if restore_file /etc/cron.d/amavisd-new; then
+        rm -f /etc/cron.d/amavisd-new.$backup_ext
+        postupgrade_reconfigure amavisd-cn
      fi
   fi
 
-  if pkg spamassassin-cn && pkg spamassassin lt 3.3.1-1; then
-     if restore_file /etc/spamassassin/v310.pre; then
-        postupgrade_reconfigure spamassassin-cn
+  if pkg ossec-hids lt 2.7-1; then
+     if restore_file /var/ossec/rules/local_rules.xml; then
+        postupgrade_reconfigure ossec-hids-cn
      fi
   fi
 
-  if pkg amavisd-cn && pkg amavisd-new lt 1:2.6.4-3; then
-     if restore_file /etc/cron.daily/amavisd-new; then
-        rm -f /etc/cron.daily/amavisd-new.$backup_ext
-        postupgrade_reconfigure amavisd-cn
-     fi
-
-     if restore_file /etc/amavis/conf.d/15-av_scanners; then
-        rm -f /etc/amavis/conf.d/15-av_scanners.$backup_ext
-        postupgrade_reconfigure amavisd-cn
+  if pkg sasl2-bin lt 2.1.25.dfsg1-6+deb7u1; then
+     if restore_file /etc/default/saslauthd; then
+        postupgrade_reconfigure postfix-cn
      fi
   fi
 
-  if pkg amavisd-cn lt 3:2.6.5; then
-     restore_file /etc/init.d/amavisd-cn
-  fi
-
-  if pkg console-tools lt 1:0.2.3dbs-69.1; then
-     restore_file /etc/console-tools/config
-  fi
-
-  if pkg base-files lt 6.0squeeze2; then
+  if pkg base-files lt 7.1wheezy2; then
      restore_file /etc/issue
      restore_file /etc/issue.net
   fi
 
-  # dovecot won't start with these options
-  if pkg dovecot-cn && pkg dovecot-common lt 1:1.2.15-7; then
-     sed -i 's/^\( *\)\(sieve\(_storage\)\?=.*\)/\1#\2/' \
-         /etc/dovecot/dovecot.conf
-  fi
-
   # check if monitrc is template based
   if [ -e /etc/monit/monitrc ]; then # monit is removed at this point
      # regenerate config from template
@@ -913,15 +754,14 @@ apt_listchanges () {
       case $command in
            disable)
                if [ -f $file ]; then
-                   dpkg-divert --local --rename --divert $file.$backup_ext \
+                   dpkg-divert --local --rename --divert $file.disabled \
                                --add $file || true
                fi
                ;;
 
            enable)
-               if [ -f $file.$backup_ext ]; then
-                   dpkg-divert --remove $file || true
-               fi
+               # cleanup the diversion even if the file is already removed
+               dpkg-divert --rename --remove $file || true
                ;;
      esac
   done
@@ -929,29 +769,15 @@ apt_listchanges () {
 
 # make a silent installation of carnet and srce keyrings
 install_keyrings () {
-  pkgadd carnet-keyring srce-keyring debian-archive-keyring
-  pkgupgrade dpkg apt debconf python-apt dpkg-dev
-
-  dpkg-reconfigure carnet-keyring srce-keyring debian-archive-keyring
-  apt_update
-}
-
-# remove skey (not supported anymore)
-remove_skey () {
-  pkgrm skey-cn libpam-skey
+  pkgadd carnet-keyring debian-archive-keyring
+  dpkg-reconfigure carnet-keyring debian-archive-keyring
 
-  if getent group skey > /dev/null; then
-    groupdel skey || true
-    log "groupdel skey"
+  if pkg srce-keyring; then
+    pkgadd srce-keyring
+    dpkg-reconfigure srce-keyring
   fi
-}
 
-# remove unsupported php version
-# but leave the configuration just in case
-remove_php4 () {
-  if pkg php5-cn && pkg php4-common; then
-     pkgrm_only php4-common
-  fi
+  apt_update
 }
 
 # check if package is orphaned (nothing depends on it)
@@ -969,13 +795,20 @@ is_orphaned () {
 
 # remove old and unused libraries
 remove_orphaned () {
-  local package
+  local package remove
 
+  apt_autoremove
+
+  remove=
   for package in $orphaned_packages; do
     if is_orphaned $package; then
-      pkgrm $package
+      remove="$remove $package"
     fi
   done
+
+  if [ "$remove" ]; then
+    pkgrm $remove
+  fi
 }
 
 # monit it causing problems for postinst scripts
@@ -991,9 +824,19 @@ disable_monit () {
     apt-get remove --yes monit
     # stop the binary
     pkill -9 monit || true
+    # move away init for insserv to work
+    mv /etc/init.d/monit /var/lib/carnet-upgrade/
   fi
 }
 
+# allow monit to run again
+enable_monit () {
+  if [ -f /var/lib/carnet-upgrade/monit ]; then
+    mv /var/lib/carnet-upgrade/monit /etc/init.d/monit
+    pkgadd monit-cn
+  fi 
+}
+
 # check which of the given packages are installed
 grep_installed () {
   local package installed
@@ -1026,8 +869,9 @@ upgrade_libc () {
 # upgrade apache2/php5
 upgrade_apache2 () {
   pkgrm apache-common # prevents installation of apache2-suexec
+  pkgrm php5-suhosin # not available for wheezy
   pkgupgrade libapache2-mod-php5 php5-cli php5-cn apache2-cn \
-    php5-odbc php5-suhosin php-suhosin-cn
+    php5-odbc
 }
 
 upgrade_amavis () {
@@ -1047,58 +891,12 @@ upgrade_amavis () {
   /etc/init.d/amavisd-cn restart
 }
 
-# handle freerdius upgrade
-upgrade_freeradius () {
-  local template config_new password realm hostname basedn
-
-  pkg freeradius-aai lt 2.1.3-0lenny0 || return 0
-
-  # aai team prevents a clean upgrade
-  cp -av /etc/freeradius /etc/freeradius.$backup_ext
-  pkgrm freeradius-aai freeradius-ldap freeradius
-  pkgadd freeradius-aai
-}
-
-# prepare for slapd upgrade (caused by freeradius installation)
-prepare_openldap () {
-  pkg openldap-aai lt 2.4 || return 0
-
-  # openldap-aai expects org.ldif to exists
-  local ldif=/var/lib/ldap/org.ldif
-  local ldif_backup=/var/lib/carnet-upgrade/org.ldif
-  if [ -f $ldif ]; then
-    cp -v $ldif $ldif_backup
-  fi
-}
-
-# fix openldap-aai postinst user handling
-upgrade_openldap () {
-  pkg openldap-aai lt 2.4 || return 0
-
-  # slapd postinst fails if move_old_database is false
-  echo 'slapd slapd/move_old_database boolean true' | debconf-set-selections 
-  pkgadd slapd
-
-  # slapd removes org.ldif during switch from ldap -> openldap user
-  local ldif=/var/lib/ldap/org.ldif
-  local ldif_backup=/var/lib/carnet-upgrade/org.ldif
-  if [ -f $ldif_backup -a ! -f $ldif ]; then
-    cp -v $ldif_backup $ldif
-  fi
-
-  # openldap-aai postinst fails here because of database permissions
-  apt-get -y install openldap-aai || true
-  chown -R openldap:openldap /var/lib/ldap
-  /etc/init.d/slapd restart
-  dpkg --configure -a
-
-  # remove ldap user if openldap works
-  if getent passwd ldap      > /dev/null && \
-     getent passwd openldap  > /dev/null && \
-     pgrep -U openldap slapd > /dev/null
-  then
-     log "userdel ldap (replaced by openldap)"
-     userdel ldap || true
+# handle mysql 5.0 to 5.1 upgrade
+upgrade_mysql () {
+  if pkg mysql-server || pkg mysql-server-5.1; then
+     pkgadd mysql-server
+     dpkg -P mysql-server-5.1
+     /etc/init.d/mysql restart
   fi
 }
 
@@ -1118,6 +916,44 @@ upgrade_postfix () {
   fi
 }
 
+# upgrade the IMAP server
+upgrade_dovecot() {
+  if [ ! -f /etc/dovecot/conf.d/95-local ]; then
+     pkgrm dovecot-cn
+
+     # restore config
+     if [ ! -f /etc/dovecot/dovecot.conf.$backup_ext ]; then
+        mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.$backup_ext
+        cp /usr/share/dovecot/dovecot.conf /etc/dovecot/dovecot.conf
+     fi
+
+     # copy SSL certificates
+     OLD_SSL_CERT="/etc/ssl/certs/dovecot.pem"
+     OLD_SSL_KEY="/etc/ssl/private/dovecot.pem"
+     SSL_CERT="/etc/dovecot/dovecot.pem"
+     SSL_KEY="/etc/dovecot/private/dovecot.pem"
+     if [ -f $OLD_SSL_CERT -a -f $OLD_SSL_KEY -a ! -f $SSL_CERT -a ! -f $SSL_KEY ]; then
+        if [ ! -e /etc/dovecot/private ]; then
+           install -d -o root -g root -m0700 /etc/dovecot/private
+        fi
+
+        cp -av $OLD_SSL_CERT $SSL_CERT
+        cp -av $OLD_SSL_KEY $SSL_KEY
+
+        chown root:dovecot $SSL_CERT
+        chmod 0644 $SSL_CERT
+        chown root:dovecot $SSL_KEY
+        chmod 0600 $SSL_KEY
+     fi
+
+     # install new version and restore local changes
+     pkgadd dovecot-core
+     doveconf -n -c /etc/dovecot/dovecot.conf.$backup_ext > /etc/dovecot/conf.d/95-local
+
+     pkgadd dovecot-cn
+  fi
+}
+
 # upgrade bind separately so DNS is not down for too long
 # or breaks postinst scripts of other cn packages that depend on
 # working resolver
@@ -1125,6 +961,39 @@ upgrade_bind() {
   pkgadd bind9-cn
 }
 
+# handle fail2ban upgrade due to error:
+# trying to overwrite '/etc/fail2ban/filter.d/dovecot.conf', which is also in package fail2ban-cn
+upgrade_fail2ban() {
+  if pkg fail2ban-cn && dpkg -L fail2ban-cn | grep -qF dovecot.conf; then
+    pkgrm fail2ban-cn
+    pkgadd fail2ban
+    pkgadd fail2ban-cn
+  fi
+}
+
+# manual upgrade of mailman to avoid two copies of mailman running
+# first started by python upgrade and second started by mailman itself
+upgrade_mailman() {
+  if pkg mailman-cn lt 2:2.1.15~cn0; then
+    /etc/init.d/mailman stop || true
+    pkgadd python
+    pkgadd mailman mailman-cn
+  fi
+}
+
+# manual upgrade of kernel due to new packet name
+upgrade_kernel() {
+  if pkg kernel-2.6-cn; then
+    pkgrm kernel-2.6-cn
+
+    if pkg grub-pc; then
+      pkgadd kernel-cn grub-pc
+    else
+      pkgadd kernel-cn
+    fi
+  fi
+}
+
 get_variable () {
   local name=$1 file=$2 val
 
@@ -1140,6 +1009,12 @@ get_variable () {
 upgrade_munin () {
   local config backup hostname domain
 
+  # new htmldir location
+  if [ -d /var/www/munin -a ! -e /var/cache/munin/www ]; then
+    mkdir -p /var/cache/munin
+    mv /var/www/munin /var/cache/munin/www
+  fi
+
   for pkg_name in munin munin-node; do
      pkg $pkg_name lt '1.4.5-3' || continue
 
@@ -1161,55 +1036,6 @@ upgrade_munin () {
   dpkg-reconfigure munin-cn
 }
 
-# udev.preinst fails if devfs configs still exist
-upgrade_udev () {
-  local config
-
-  for config in /etc/udev/rules.d/devfs.rules \
-                /etc/udev/rules.d/compat-full.rules \
-                /etc/udev/rules.d/compat.rules
-  do
-     if [ -e $config ]; then
-        rm -v -f $config
-     fi
-  done
-
-  if [ -f /etc/udev/udev.rules -a ! -f /etc/udev/rules.d/udev.rules ]; then
-     ln -sfv ../udev.rules /etc/udev/rules.d/
-  fi
-
-  pkgadd udev
-}
-
-# fix /etc/dpkg/dpkg.cfg
-comment_force_overwrite () {
-  if [ -f /etc/dpkg/dpkg.cfg ]; then
-    if check_and_sed '^force-overwrite' \
-                  's,\(^force-overwrite\),#\1,' \
-                  /etc/dpkg/dpkg.cfg; then
-      notice "$msg_comment_force_overwrite"
-    fi
-  fi
-}
-
-# try not to overwrite user modified issue files
-fix_issue () {
-  if cmp /etc/issue $cnup/files/etc/issue.expect.new >/dev/null; then
-    cp -av /etc/issue /etc/issue.$backup_ext
-    cat > /etc/issue <<EOF
-Debian GNU/Linux 6.0 (CARNet Debian 6.0) \\n \\l
-
-EOF
-  fi
-
-  if cmp /etc/issue.net $cnup/files/etc/issue.net.expect.new >/dev/null; then
-    cp -av /etc/issue.net /etc/issue.net.$backup_ext
-    cat > /etc/issue.net <<EOF
-Debian GNU/Linux 6.0 (CARNet Debian 6.0) %h
-EOF
-  fi
-}
-
 check_archives_space() {
   local available_disk_space archives_size
   available_disk_space=$(free_space /var/cache/apt/archives/)
@@ -1230,16 +1056,29 @@ check_archives_space() {
   fi
 }
 
-check_kernel_space() {
-  local available_disk_space kernel_size linux_images metapkg pkg ret
-  available_disk_space=$(free_space /)
-  linux_images=$(apt-cache show kernel-2.6-cn | grep ^Depends: \
+# calculate the list of linux-image packages from kernel-cn dependencies
+get_cn_kernels() {
+  local cn_kernels linux_images metapkg pkg
+
+  cn_kernels=
+  linux_images=$(apt-cache show kernel-cn | grep ^Depends: \
     | grep -o 'linux-image[^, ]*')
   for metapkg in $linux_images; do
     pkg=$(apt-cache show $metapkg | grep ^Depends: \
           | grep -o 'linux-image[^, ]*' | head -1)
-    [ "$pkg" ] || continue
+    [ "$pkg" ] && cn_kernels="$cn_kernels $pkg"
+  done
+
+  echo $cn_kernels
+}
+
+# check if there is enough space on / for the new kernel package
+check_kernel_space() {
+  local available_disk_space kernel_size linux_images pkg ret
+  available_disk_space=$(free_space /)
 
+  linux_images=$( get_cn_kernels )
+  for pkg in $linux_images; do
     kernel_size=$(installed_size $pkg)
     ret=$?
     [ $ret -eq 0 ] && break
@@ -1254,10 +1093,10 @@ check_kernel_space() {
   log "Kernel package: $pkg"
   log "Kernel size: ${kernel_size}MB"
 
-  if LC_ALL=C apt-get -s install kernel-2.6-cn \
-     | grep -q '^kernel-2.6-cn is already the newest version.$'
+  if LC_ALL=C apt-get -s install kernel-cn 2>/dev/null \
+     | grep -q '^kernel-cn is already the newest version.$'
   then
-     log "Not checking free space in /: kernel-2.6-cn already installed"
+     log "Not checking free space in /: kernel-cn already installed"
      return
   fi
 
@@ -1268,6 +1107,82 @@ check_kernel_space() {
   fi
 }
 
+# free some space on / partition by cleaning old unused kernels
+clean_old_kernels() {
+  local installed keep pkg keep remove delete name dialog_list selection
+
+  # find all installed kernels
+  installed=$(
+    dpkg -l | egrep '^ii  linux-image-[0-9]+[.][0-9]+[.][0-9]+-' \
+    | awk '{print $2}'
+  )
+  log "Found kernel packages: $installed"
+
+  # leave current and new kernels
+  keep="linux-image-$(uname -r) $(get_cn_kernels)"
+  log "Keep kernel packages: $keep"
+
+  # check what to remove
+  remove=
+  for pkg in $installed; do
+    delete=yes
+    for name in $keep; do
+      [ "$pkg" = "$name" ] && delete=
+    done
+    if [ "$delete" = yes ]; then
+      remove="$remove $pkg"
+    fi
+  done
+  log "Obsolete kernel packages: $remove"
+
+  if [ "$remove" ]; then
+    for pkg in $remove; do
+      dialog_list="$dialog_list $pkg '' off"
+    done
+
+    # user selects the packages to delete
+    selection=$( mktemp /var/lib/carnet-upgrade/selection.XXXXXX )
+    eval LC_MESSAGES=hr_HR dialog --nocancel --backtitle \""$title"\" \
+      --checklist \""$msg_remove_kernels"\" 20 75 6 $dialog_list 2>$selection
+
+    selected=$( tr -d \" < $selection )
+    rm -f $selection
+
+    if [ "$selected" ]; then
+      log "Removing kernel packages: $selected"
+      pkgrm $selected
+    fi
+  fi
+}
+
+# prevent sysv-rc migration problems
+clean_initd_packages() {
+  local list removed pkg dialog_list selection selected
+
+  list=$( dpkg -S /etc/init.d/\* | grep -v ^diversion | cut -d: -f1 | sort -u )
+  removed=$( dpkg -l $list | sed -n 's/^r.[[:space:]]\+\([^[:space:]]\+\).*/\1/p' )
+  log "Found removed packages: $removed"
+
+  if [ "$removed" ]; then
+    for pkg in $removed; do
+      dialog_list="$dialog_list $pkg '' off"
+    done
+
+    # user selects the packages to delete
+    selection=$( mktemp /var/lib/carnet-upgrade/selection.XXXXXX )
+    eval LC_MESSAGES=hr_HR dialog --nocancel --backtitle \""$title"\" \
+      --checklist \""$msg_remove_initd"\" 20 75 6 $dialog_list 2>$selection
+
+    selected=$( tr -d \" < $selection )
+    rm -f $selection
+
+    if [ "$selected" ]; then
+      log "Purging packages: $selected"
+      dpkg -P $selected
+    fi
+  fi
+}
+
 free_space() {
   df --portability --block-size=1M "$1" | tail -1 | awk '{print $4}'
 }