summaryrefslogtreecommitdiffstats
path: root/share/scripts/debconf
diff options
context:
space:
mode:
Diffstat (limited to 'share/scripts/debconf')
-rwxr-xr-xshare/scripts/debconf974
1 files changed, 974 insertions, 0 deletions
diff --git a/share/scripts/debconf b/share/scripts/debconf
new file mode 100755
index 0000000..cbde345
--- /dev/null
+++ b/share/scripts/debconf
@@ -0,0 +1,974 @@
+#!/bin/sh
+
+# container-tools - Manage systemd-nspawn containers
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+SCRIPT="${0}"
+
+CONFIG="/etc/container-tools/config"
+MACHINES="/var/lib/machines"
+
+Parameters ()
+{
+ LONG_OPTIONS="bind:,script:,name:,preseed-file:"
+ OPTIONS="b:,s:,n:,p:"
+
+ PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${SCRIPT} --options ${OPTIONS} --shell sh -- ${@})"
+
+ if [ "${?}" != "0" ]
+ then
+ echo "'${SCRIPT}': getopt exit" >&2
+ exit 1
+ fi
+
+ eval set -- "${PARAMETERS}"
+
+ while true
+ do
+ case "${1}" in
+ -b|--bind)
+ # ignore
+ shift 2
+ ;;
+
+ --cnt.autostart)
+ # ignore
+ shift 2
+ ;;
+
+ -s|--script)
+ # ignore
+ shift 2
+ ;;
+
+ -n|--name)
+ NAME="${2}"
+ shift 2
+ ;;
+
+ --preseed-file)
+ PRESEED_FILE="${2}"
+ shift 2
+ ;;
+
+ --)
+ shift 1
+ break
+ ;;
+
+ *)
+ echo "'${SCRIPT}': getopt error" >&2
+ exit 1
+ ;;
+ esac
+ done
+}
+
+Usage ()
+{
+ echo "Usage: container create -n|--name NAME -s|--script ${SCRIPT} [-p|--preseed-file FILE]" >&2
+ exit 1
+}
+
+Parameters "${@}"
+
+if [ -z "${NAME}" ]
+then
+ Usage
+fi
+
+if [ -e "${MACHINES}/${NAME}" ]
+then
+ echo "'${NAME}': container already exists" >&2
+ exit 1
+fi
+
+if [ ! -x /usr/sbin/debootstrap ]
+then
+ echo "'${NAME}': /usr/sbin/debootstrap - no such file." >&2
+ exit 1
+fi
+
+if [ "$(id -u)" -ne 0 ]
+then
+ echo "'${NAME}': need root privileges" >&2
+ exit 1
+fi
+
+Chroot ()
+{
+ CHROOT="${1}"
+ shift
+
+ chroot "${CHROOT}" /usr/bin/env -i \
+ LC_ALL="C" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games" TERM="${TERM}" \
+ DEBIAN_FRONTEND="${DEBCONF_FRONTEND}" DEBIAN_PRIORITY="${DEBCONF_PRIORITY}" \
+ DEBCONF_NONINTERACTIVE_SEEN="true" DEBCONF_NOWARNINGS="true" \
+ ftp_proxy="${ftp_proxy}" http_proxy="${http_proxy}" \
+ ${@}
+}
+
+Upgrade_system ()
+{
+ DIRECTORY="${1}"
+
+ # Mount pseudo-filesystems
+ mount -o bind /dev/pts "${DIRECTORY}/dev/pts"
+ mount -o bind /proc "${DIRECTORY}/proc"
+ mount -o bind /sys "${DIRECTORY}/sys"
+
+ # Bind mount systems apt cache
+ mount -o bind /var/cache/apt/archives "${DIRECTORY}/var/cache/apt/archives"
+
+ # Disable dpkg syncing
+
+cat > "${DIRECTORY}/etc/dpkg/dpkg.cfg.d/container-tools" << EOF
+force-unsafe-io
+EOF
+
+ # Create policy-rc.d file
+
+cat > "${DIRECTORY}/usr/sbin/policy-rc.d" << EOF
+#!/bin/sh
+echo "All runlevel operations denied by policy" >&2
+exit 101
+EOF
+
+ chmod 0755 "${DIRECTORY}/usr/sbin/policy-rc.d"
+
+ # Upgrade system
+ Chroot "${DIRECTORY}" "apt-get update"
+ Chroot "${DIRECTORY}" "apt-get --yes --option APT::Force-LoopBreak=true upgrade"
+ Chroot "${DIRECTORY}" "apt-get --yes --option APT::Force-LoopBreak=true dist-upgrade"
+
+ # Unmount systems apt cache
+ umount "${DIRECTORY}/var/cache/apt/archives"
+
+ Chroot "${DIRECTORY}" "apt-get clean"
+}
+
+Cleanup_system ()
+{
+ DIRECTORY="${1}"
+
+ Chroot "${DIRECTORY}" "apt-get --yes autoremove"
+ Chroot "${DIRECTORY}" "apt-get clean"
+
+ # Cleanup
+ rm -f "${DIRECTORY}/etc/dpkg/dpkg.cfg.d/container-tools"
+ rm -f "${DIRECTORY}/usr/sbin/policy-rc.d"
+
+ # Unmount pseudo-filesystems
+ umount "${DIRECTORY}/dev/pts"
+ umount "${DIRECTORY}/proc"
+ umount "${DIRECTORY}/sys"
+}
+
+Debconf ()
+{
+ # Configure local debconf
+ mkdir -p /tmp/container-tools
+ DEBCONF_TMPDIR="$(mktemp -d -p /tmp/container-tools -t $(basename ${0}).XXXX)"
+ export DEBCONF_TMPDIR
+
+ mkdir -p "${DEBCONF_TMPDIR}/debconf"
+
+cat > "${DEBCONF_TMPDIR}/debconf.systemrc" << EOF
+Config: configdb
+Templates: templatedb
+
+Name: config
+Driver: File
+Mode: 644
+Reject-Type: password
+Filename: ${DEBCONF_TMPDIR}/debconf/config.dat
+
+Name: passwords
+Driver: File
+Mode: 600
+Backup: false
+Required: false
+Accept-Type: password
+Filename: ${DEBCONF_TMPDIR}/debconf/passwords.dat
+
+Name: configdb
+Driver: Stack
+Stack: config, passwords
+
+Name: templatedb
+Driver: File
+Mode: 644
+Filename: ${DEBCONF_TMPDIR}/debconf/templates.dat
+EOF
+
+ DEBCONF_SYSTEMRC="${DEBCONF_TMPDIR}/debconf.systemrc"
+ export DEBCONF_SYSTEMRC
+}
+
+Debootstrap ()
+{
+ DIRECTORY="${1}"
+
+ # FIXME: trim down, debootstrap variants?
+ case "${MODE}" in
+ debian)
+ INCLUDE="--include=ifupdown,locales,libui-dialog-perl,dialog,isc-dhcp-client,netbase,net-tools,iproute,wget,dbus"
+ ;;
+
+ progress-linux)
+ INCLUDE="--include=apt-utils,ifupdown,locales-all,libui-dialog-perl,dialog,isc-dhcp-client,netbase,net-tools,iproute,openssh-server,wget,dbus,libpam-systemd"
+ ;;
+ esac
+
+ mkdir -p "$(dirname ${DIRECTORY})"
+ debootstrap --verbose --arch=${ARCHITECTURE} --components=${PARENT_ARCHIVE_AREAS} ${INCLUDE} \
+ ${PARENT_DISTRIBUTION} "${DIRECTORY}" ${PARENT_MIRROR}
+}
+
+Configure_apt ()
+{
+ DIRECTORY="${1}"
+
+ # Configure apt
+ rm -f "${DIRECTORY}/etc/apt/sources.list"
+
+ PARENT_AREA="$(echo ${PARENT_ARCHIVE_AREAS} | sed -e 's|,| |g')"
+ PARENT_DIST="$(echo ${PARENT_DISTRIBUTION} | sed -e 's|-backports||')"
+
+ echo "deb ${PARENT_MIRROR} ${PARENT_DIST} ${PARENT_AREA}" > "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+
+ case "${MODE}" in
+ progress-linux)
+ AREA="$(echo ${ARCHIVE_AREAS} | sed -e 's|,| |g')"
+ DIST="$(echo ${DISTRIBUTION} | sed -e 's|-backports||')"
+
+ echo "deb ${MIRROR} ${DIST} ${AREA}" > "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+
+ case "${DISTRIBUTION}" in
+ *-backports)
+ echo "deb ${MIRROR} ${DIST}-backports ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+ esac
+
+cat > "${DIRECTORY}/etc/apt/preferences.d/progress-linux.pref" << EOF
+Package: *
+Pin: release n=${DIST}
+Pin-Priority: 999
+
+Package: *
+Pin: release n=${DIST}-security
+Pin-Priority: 999
+
+Package: *
+Pin: release n=${DIST}-updates
+Pin-Priority: 999
+
+Package: *
+Pin: release n=${DIST}-lts
+Pin-Priority: 999
+
+Package: *
+Pin: release n=${DIST}-extras
+Pin-Priority: 999
+EOF
+ case "${DISTRIBUTION}" in
+ *-backports)
+
+cat >> "${DIRECTORY}/etc/apt/preferences.d/progress-linux.pref" << EOF
+
+Package: *
+Pin: release n=${DIST}-backports
+Pin-Priority: 999
+
+Package: *
+Pin: release n=${DIST}-backports-extras
+Pin-Priority: 999
+EOF
+
+ ;;
+
+ *)
+
+cat >> "${DIRECTORY}/etc/apt/preferences.d/progress-linux.pref" << EOF
+
+#Package: *
+#Pin: release n=${DIST}-backports
+#Pin-Priority: 999
+
+#Package: *
+#Pin: release n=${DIST}-backports-extras
+#Pin-Priority: 999
+EOF
+
+ ;;
+ esac
+
+ # Import archive keys
+ case "${DISTRIBUTION}" in
+ *-backports)
+ KEYS="project/pgp/archive-key-${DIST}.asc project/pgp/archive-key-${DIST}-backports.asc"
+ ;;
+
+ *)
+ KEYS="project/pgp/archive-key-${DIST}.asc"
+ ;;
+ esac
+
+ for KEY in ${KEYS}
+ do
+ KEY_NAME="$(basename ${KEY})"
+ echo "P: Fetching archive-key ${KEY_NAME}..."
+
+ wget -q "${MIRROR}/${KEY}" -O "${DIRECTORY}/key.asc"
+ wget -q "${MIRROR}/${KEY}.sig" -O "${DIRECTORY}/key.asc.sig"
+
+ if [ -e /usr/bin/gpgv ]
+ then
+ if [ -e /usr/share/keyrings/debian-keyring.gpg ] || [ -e /usr/share/keyrings/debian-maintainers.gpg ]
+ then
+ KEY_VALID=""
+
+ for KEYRING in /usr/share/keyrings/debian-keyring.gpg /usr/share/keyrings/debian-maintainers.gpg
+ do
+ if [ -e "${KEYRING}" ]
+ then
+ echo -n "I: Verifying archive-key ${KEY_NAME} against $(basename ${KEYRING} .gpg | sed -e 's|-keyring||') keyring..."
+
+ # FIXME: doesn't work anymore when the template eventually be run with 'set -e'
+ /usr/bin/gpgv --quiet --keyring ${KEYRING} "${DIRECTORY}/key.asc.sig" "${DIRECTORY}/key.asc" > /dev/null 2>&1 && KEY_VALID="true" && break
+ fi
+ done
+
+ case "${KEY_VALID}" in
+ true)
+ echo " successful."
+ ;;
+
+ *)
+ echo " failed."
+ return 1
+ ;;
+ esac
+ else
+ echo "W: Skipping archive-key ${KEY_NAME} verification, debian-keyring not available..."
+ fi
+ else
+ echo "W: Skipping archive-key ${KEY_NAME} verification, gpgv not available..."
+ fi
+
+ echo "P: Importing archive-key ${KEY_NAME}..."
+
+ Chroot "${DIRECTORY}" "apt-key add key.asc"
+ rm -f "${DIRECTORY}/key.asc"
+ rm -f "${DIRECTORY}/key.asc.sig"
+ done
+
+ Chroot "${DIRECTORY}" "apt-get update"
+ ;;
+ esac
+}
+
+Deconfigure_system ()
+{
+ DIRECTORY="${1}"
+
+ # Configure fstab
+
+cat > "${DIRECTORY}/etc/fstab" << EOF
+# /etc/fstab: static file system information.
+#
+# Use 'blkid' to print the universally unique identifier for a
+# device; this may be used with UUID= as a more robust way to name devices
+# that works even if disks are added and removed. See fstab(5).
+#
+# <file system> <mount point> <type> <options> <dump> <pass>
+
+EOF
+
+ # Fix /etc/mtab
+ rm -f "${DIRECTORY}/etc/mtab"
+ ln -s /proc/self/mounts "${DIRECTORY}/etc/mtab"
+
+ # Temporary hack for dpkg
+ if [ -e "${DIRECTORY}/etc/dpkg/origins/default" ]
+ then
+ rm -f "${DIRECTORY}/etc/dpkg/origins/default"
+ Chroot "${DIRECTORY}" "dpkg-reconfigure base-files"
+ fi
+
+ # Temporary hack for base-files
+ for FILE in motd.tail motd profile
+ do
+ if [ -e "${DIRECTORY}/usr/share/base-files/${FILE}" ]
+ then
+ rm -f "${DIRECTORY}/etc/${FILE}"
+ cp "${DIRECTORY}/usr/share/base-files/${FILE}" "${DIRECTORY}/etc"
+ fi
+ done
+
+ # Temporary hack for readline
+ if [ -e "${DIRECTORY}/etc/inputrc" ]
+ then
+ rm -f "${DIRECTORY}/etc/inputrc"
+ cp "${DIRECTORY}/usr/share/readline/inputrc" "${DIRECTORY}/etc"
+ fi
+
+ # Temporary hack for sysvinit
+ if [ -e "${DIRECTORY}/etc/inittab" ]
+ then
+ rm -f "${DIRECTORY}/etc/inittab"
+ cp "${DIRECTORY}/usr/share/sysvinit/inittab" "${DIRECTORY}/etc/inittab"
+ fi
+
+ # Removing resolv.conf
+ #rm -f "${DIRECTORY}/etc/resolv.conf"
+ # FIXME: needs to stay for the moment
+ rm -f "${DIRECTORY}/etc/resolv.conf"
+ cp /etc/resolv.conf "${DIRECTORY}/etc"
+
+ # Removing hosts/hostname
+ rm -f "${DIRECTORY}"/etc/hosts
+ rm -f "${DIRECTORY}"/etc/hostname
+
+ # Removing openssh-server host keys
+ rm -f "${DIRECTORY}"/etc/ssh/ssh_host_*_key
+ rm -f "${DIRECTORY}"/etc/ssh/ssh_host_*_key.pub
+}
+
+Configure_system ()
+{
+ DIRECTORY="${1}"
+
+ # Overwrite resolv.conf from cache with hosts resolv.conf
+ rm -f "${DIRECTORY}/etc/resolv.conf"
+ cp /etc/resolv.conf "${DIRECTORY}/etc"
+
+ echo "${NAME}" > "${DIRECTORY}/etc/hostname"
+
+ # Configure apt
+ rm -f "${DIRECTORY}/etc/apt/sources.list"
+
+ PARENT_AREA="$(echo ${PARENT_ARCHIVE_AREAS} | sed -e 's|,| |g')"
+ PARENT_DIST="$(echo ${PARENT_DISTRIBUTION} | sed -e 's|-backports||')"
+
+ echo "deb ${PARENT_MIRROR} ${PARENT_DIST} ${PARENT_AREA}" > "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+
+ for PARENT_REPO in ${PARENT_ARCHIVES}
+ do
+ case "${PARENT_REPO}" in
+ ${PARENT_DIST}-security)
+ echo "deb ${PARENT_MIRROR_SECURITY} ${PARENT_DIST}/updates ${PARENT_AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+ ;;
+
+ ${PARENT_DIST}-updates)
+ echo "deb ${PARENT_MIRROR} ${PARENT_DIST}-updates ${PARENT_AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+ ;;
+
+ ${PARENT_DIST}-lts)
+ echo "deb ${PARENT_MIRROR} ${PARENT_DIST}-lts ${PARENT_AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+ ;;
+
+ ${PARENT_DIST}-backports)
+ echo "deb ${PARENT_MIRROR} ${PARENT_DIST}-backports ${PARENT_AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+ ;;
+
+ ${PARENT_DIST}-proposed-updates)
+ echo "deb ${PARENT_MIRROR} ${PARENT_DIST}-proposed-updates ${PARENT_AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+ ;;
+
+ experimental)
+ echo "deb ${PARENT_MIRROR} experimental ${PARENT_AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/debian.list"
+ ;;
+ esac
+ done
+
+ case "${MODE}" in
+ progress-linux)
+ AREA="$(echo ${ARCHIVE_AREAS} | sed -e 's|,| |g')"
+ DIST="$(echo ${DISTRIBUTION} | sed -e 's|-backports||')"
+
+ echo "deb ${MIRROR} ${DIST} ${AREA}" > "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+
+ for REPO in ${ARCHIVES}
+ do
+ case "${REPO}" in
+ ${DIST}-staging)
+ echo "deb ${MIRROR} ${DIST}-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-security)
+ echo "deb ${MIRROR_SECURITY} ${DIST}-security ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-security-staging)
+ echo "deb ${MIRROR_SECURITY} ${DIST}-security-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-updates)
+ echo "deb ${MIRROR} ${DIST}-updates ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-updates-staging)
+ echo "deb ${MIRROR} ${DIST}-updates-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-lts)
+ echo "deb ${MIRROR} ${DIST}-lts ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-lts-staging)
+ echo "deb ${MIRROR} ${DIST}-lts-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-extras)
+ echo "deb ${MIRROR} ${DIST}-extras ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-extras-staging)
+ echo "deb ${MIRROR} ${DIST}-extras-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-backports)
+ echo "deb ${MIRROR} ${DIST}-backports ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-backports-staging)
+ echo "deb ${MIRROR} ${DIST}-backports-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-backports-extras)
+ echo "deb ${MIRROR} ${DIST}-backports-extras ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+
+ ${DIST}-backports-extras-staging)
+ echo "deb ${MIRROR} ${DIST}-backports-extras-staging ${AREA}" >> "${DIRECTORY}/etc/apt/sources.list.d/progress-linux.list"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ if [ "${APT_RECOMMENDS}" = "false" ]
+ then
+
+cat > "${DIRECTORY}/etc/apt/apt.conf.d/recommends.conf" << EOF
+APT::Install-Recommends "false";
+EOF
+
+ fi
+
+ # Add local archives configured from preseed file
+ if ls "${DEBCONF_TMPDIR}/apt"/*.list > /dev/null 2>&1
+ then
+ cp "${DEBCONF_TMPDIR}/apt"/*.list "${DIRECTORY}/etc/apt/sources.list.d"
+
+ if ls "${DEBCONF_TMPDIR}/apt"/*.key > /dev/null 2>&1
+ then
+ for KEY in "${DEBCONF_TMPDIR}/apt"/*.key
+ do
+ cp "${KEY}" "${DIRECTORY}"
+ Chroot "${DIRECTORY}" "apt-key add $(basename ${KEY})"
+ rm -f "${DIRECTORY}/$(basename ${KEY})"
+ done
+ fi
+
+ if ls "${DEBCONF_TMPDIR}/apt"/*.pref > /dev/null 2>&1
+ then
+ cp "${DEBCONF_TMPDIR}/apt"/*.pref "${DIRECTORY}/etc/apt/preferences.d"
+ fi
+ fi
+
+ Upgrade_system "${DIRECTORY}"
+
+ # Preseed system
+ if [ -n "${PRESEED_FILE}" ]
+ then
+ for FILE in ${PRESEED_FILE}
+ do
+ cat "${FILE}" >> "${DIRECTORY}/preseed.cfg"
+ done
+
+ Chroot "${DIRECTORY}" "debconf-set-selections preseed.cfg"
+
+ rm -f "${DIRECTORY}/preseed.cfg"
+ fi
+
+ # FIXME: All packages of priority of essential need to be reconfigured to reflect choices from preseeding
+ # -> fix: use two-stage bootstrap (foreign) and inject preseeds in between
+
+ # Manual hack to workaround broken preseeding in locales package
+ if [ -n "${PRESEED_FILE}" ]
+ then
+ for FILE in ${PRESEED_FILE}
+ do
+ if grep -qs locales "${FILE}"
+ then
+ if [ -e "${DIRECTORY}/var/lib/dpkg/info/locales.list" ]
+ then
+ rm -f "${DIRECTORY}/etc/default/locale" "${DIRECTORY}/etc/locale.gen"
+ Chroot "${DIRECTORY}" "DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=criticial dpkg-reconfigure locales"
+
+ break
+ fi
+ fi
+ done
+ fi
+
+ # Manual hack to create conffiles when using locales-all instead of locales
+ if [ ! -e "${DIRECTORY}/etc/environment" ]
+ then
+ echo "LANG=C.UTF-8" >> "${DIRECTORY}/etc/environment"
+ fi
+
+ if [ ! -e "${DIRECTORY}/etc/default/locale" ]
+ then
+ echo "LANG=C.UTF-8" >> "${DIRECTORY}/etc/default/locale"
+ fi
+
+ # Manual hack to workaround broken preseeding in tzdata package
+ if [ -n "${PRESEED_FILE}" ]
+ then
+ for FILE in ${PRESEED_FILE}
+ do
+ if grep -qs tzdata "${FILE}"
+ then
+ rm -f "${DIRECTORY}/etc/timezone"
+ Chroot "${DIRECTORY}" "DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=criticial dpkg-reconfigure tzdata"
+
+ break
+ fi
+ done
+ fi
+
+ # Temporary hack for base-files (base-files gets upgraded, so run it second time)
+ for FILE in motd.tail motd profile
+ do
+ if [ -e "${DIRECTORY}/usr/share/base-files/${FILE}" ]
+ then
+ rm -f "${DIRECTORY}/etc/${FILE}"
+ cp "${DIRECTORY}/usr/share/base-files/${FILE}" "${DIRECTORY}/etc"
+ fi
+ done
+
+ rm -f "${DIRECTORY}/preseed.cfg"
+
+ # FIXME: Install additional packages after lxc-support has been run.
+ # This is suboptimal, ideally we should install all packages but not run the maintainer scripts,
+ # then run lxc-support, and run the maintainer scripts. This way, lxc-support would see
+ # all the installed packages and could skip those scripts entirely when a certain package is not
+ # installed. Unfortunately, that is not possible in any reasonable way with apt-get.
+ # FTR: The only known workaround for now would be to first apt-get install --download-only all
+ # packages, then unpack them with dpkg, run lxc-support, and dpkg --configure them.
+ # For the time being, it's better to have lxc-support see no packages at all and be run before
+ # packages are installed, than the other way around.
+ # Workaround: We're running lxc-support at the end of the template again.
+ if [ -n "${PACKAGES}" ]
+ then
+ case "${DEBCONF_FRONTEND}" in
+ noninteractive)
+ Chroot "${DIRECTORY}" apt-get --option APT::Force-LoopBreak=true --option Dpkg::Options::="--force-overwrite" --option Dpkg::Options::="--force-confold" --yes install ${PACKAGES}
+ ;;
+
+ *)
+ Chroot "${DIRECTORY}" "apt-get --option APT::Force-LoopBreak=true --yes install ${PACKAGES}"
+ ;;
+ esac
+ fi
+
+ # Manual hack to regenerate ssh keys
+ if [ -e "${DIRECTORY}/var/lib/dpkg/info/openssh-server.postinst" ] && \
+ ! ls "${DIRECTORY}"/etc/ssh/ssh_host_*_key > /dev/null 2>&1
+ then
+ Chroot "${DIRECTORY}" "DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=criticial dpkg-reconfigure openssh-server"
+ fi
+
+ # container command
+ if [ -n "${CONTAINER_COMMAND}" ]
+ then
+ echo "${CONTAINER_COMMAND}" > "${DIRECTORY}/.container-command"
+
+ chmod 0755 "sh /.container-command"
+ Chroot "${DIRECTORY}" "sh /.container-command"
+
+ rm -f "${DIRECTORY}/.container-command"
+ fi
+
+}
+
+Configure_network ()
+{
+ # Create /etc/network/interfaces
+
+ DIRECTORY="${1}"
+
+cat > "${DIRECTORY}/etc/network/interfaces.tmp" << EOF
+# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or
+# /usr/share/doc/ifupdown/examples for more information.
+EOF
+
+ for NUMBER in $(seq 0 ${NETWORK_NUMBER})
+ do
+ eval IPV4_COMMENT="$`echo NETWORK${NUMBER}_IPV4_COMMENT`"
+ eval IPV4_METHOD="$`echo NETWORK${NUMBER}_IPV4_METHOD`"
+ eval IPV4_ADDRESS="$`echo NETWORK${NUMBER}_IPV4_ADDRESS`"
+ eval IPV4_BROADCAST="$`echo NETWORK${NUMBER}_IPV4_BROADCAST`"
+ eval IPV4_GATEWAY="$`echo NETWORK${NUMBER}_IPV4_GATEWAY`"
+ eval IPV4_NETMASK="$`echo NETWORK${NUMBER}_IPV4_NETMASK`"
+ eval IPV4_NETWORK="$`echo NETWORK${NUMBER}_IPV4_NETWORK`"
+ eval IPV4_POST_UP="$`echo NETWORK${NUMBER}_IPV4_POST_UP`"
+ eval IPV4_POST_DOWN="$`echo NETWORK${NUMBER}_IPV4_POST_DOWN`"
+
+ if [ -z "${IPV4_METHOD}" ]
+ then
+ continue
+ fi
+
+ echo >> "${DIRECTORY}/etc/network/interfaces.tmp"
+
+ if [ -n "${IPV4_COMMENT}" ]
+ then
+ echo "# ${IPV4_COMMENT}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+
+ case "${IPV4_METHOD}" in
+ none)
+
+cat >> "${DIRECTORY}/etc/network/interfaces.tmp" << EOF
+iface host${NUMBER} inet manual
+EOF
+
+ ;;
+
+ dhcp)
+
+cat >> "${DIRECTORY}/etc/network/interfaces.tmp" << EOF
+auto host${NUMBER}
+iface host${NUMBER} inet dhcp
+EOF
+
+ ;;
+
+ static)
+
+cat >> "${DIRECTORY}/etc/network/interfaces.tmp" << EOF
+auto host${NUMBER}
+iface host${NUMBER} inet static
+ address ${IPV4_ADDRESS}
+EOF
+
+ if [ -n "${IPV4_BROADCAST}" ]
+ then
+ echo " broadcast ${IPV4_BROADCAST}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+
+ if [ -n "${IPV4_GATEWAY}" ]
+ then
+ echo " gateway ${IPV4_GATEWAY}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+
+ if [ -n "${IPV4_NETMASK}" ]
+ then
+ echo " netmask ${IPV4_NETMASK}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+
+ if [ -n "${IPV4_NETWORK}" ]
+ then
+ echo " network ${IPV4_NETWORK}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+
+ if [ -n "${IPV4_POST_UP}" ]
+ then
+ echo " post-up ${IPV4_POST_UP}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+
+ if [ -n "${IPV4_POST_DOWN}" ]
+ then
+ echo " post-down ${IPV4_POST_DOWN}" >> "${DIRECTORY}/etc/network/interfaces.tmp"
+ fi
+ ;;
+ esac
+
+ NUMBER="$((${NUMBER} + 1))"
+ done
+
+ mv "${DIRECTORY}/etc/network/interfaces.tmp" "${DIRECTORY}/etc/network/interfaces"
+
+ # create /etc/resolv.conf
+ rm -f "${DIRECTORY}/etc/resolv.conf.tmp"
+
+ if [ -n "${NAMESERVER_DOMAIN}" ]
+ then
+ echo "domain ${NAMESERVER_DOMAIN}" >> "${DIRECTORY}/etc/resolv.conf.tmp"
+ fi
+
+ if [ -n "${NAMESERVER_SEARCH}" ]
+ then
+ echo "search ${NAMESERVER_SEARCH}" >> "${DIRECTORY}/etc/resolv.conf.tmp"
+ fi
+
+ if [ -n "${NAMESERVER_SERVER}" ]
+ then
+ if [ -e "${DIRECTORY}/etc/resolv.conf.tmp" ]
+ then
+ echo "" >> "${DIRECTORY}/etc/resolv.conf.tmp"
+ fi
+
+ for NAMESERVER in $(echo ${NAMESERVER_SERVER} | sed -e 's|,| |g')
+ do
+ echo "nameserver ${NAMESERVER}" >> "${DIRECTORY}/etc/resolv.conf.tmp"
+ done
+ fi
+
+ if [ -n "${NAMESERVER_OPTIONS}" ]
+ then
+ if [ -e "${DIRECTORY}/etc/resolv.conf.tmp" ]
+ then
+ echo "" >> "${DIRECTORY}/etc/resolv.conf.tmp"
+ fi
+
+ echo "options ${NAMESERVER_OPTIONS}" >> "${DIRECTORY}/etc/resolv.conf.tmp"
+ fi
+
+ if [ -e "${DIRECTORY}/etc/resolv.conf.tmp" ]
+ then
+ mv "${DIRECTORY}/etc/resolv.conf.tmp" "${DIRECTORY}/etc/resolv.conf"
+ fi
+
+ # Create /etc/hosts
+ case "${NETWORK0_IPV4_METHOD}" in
+ none|dhcp)
+
+cat > "${DIRECTORY}/etc/hosts.tmp" << EOF
+127.0.0.1 localhost ${NAME}
+
+# The following lines are desirable for IPv6 capable hosts
+::1 ip6-localhost ip6-loopback
+fe00::0 ip6-localnet
+ff00::0 ip6-mcastprefix
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
+EOF
+
+ ;;
+
+ static)
+
+cat > "${DIRECTORY}/etc/hosts.tmp" << EOF
+127.0.0.1 localhost
+${NETWORK0_IPV4_ADDRESS} ${NAME}
+
+# The following lines are desirable for IPv6 capable hosts
+::1 ip6-localhost ip6-loopback
+fe00::0 ip6-localnet
+ff00::0 ip6-mcastprefix
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
+EOF
+
+ ;;
+ esac
+
+ mv "${DIRECTORY}/etc/hosts.tmp" "${DIRECTORY}/etc/hosts"
+}
+
+Commands ()
+{
+ DIRECTORY="${1}"
+
+ if [ -n "${HOST_COMMAND}" ]
+ then
+ echo "${HOST_COMMAND}" > "${DIRECTORY}/.host-command"
+
+ cd "${DIRECTORY}"
+ sh "${DIRECTORY}/.host-command"
+ cd "${OLDPWD}"
+
+ rm -f "${DIRECTORY}/.host-command"
+ fi
+
+ # config (FIXME)
+ sed -i -e "s|^network-bridge=.*|network-bridge=${NETWORK0_BRIDGE}|" "${CONFIG}/${NAME}.conf"
+
+ # Setting root password
+ echo root:${ROOT_PASSWORD} | chroot "${DIRECTORY}" chpasswd
+
+ case "${ROOT_RANDOM_PASSWORD}" in
+ true)
+ echo "${NAME}: root password set to '${ROOT_PASSWORD}'."
+ ;;
+ esac
+}
+
+umask 0022
+
+# Get distributor from template filename
+MODE="$(basename ${SCRIPT})"
+
+case "${MODE}" in
+ debconf)
+ MODE="debian"
+ ;;
+esac
+
+export MODE
+
+CACHE="/var/cache/container-tools/${MODE}"
+SYSTEM="${MACHINES}/${NAME}"
+
+Debconf
+
+# Run debconf parts
+for SCRIPT in /usr/share/container-tools/scripts/debconf.d/*
+do
+ if [ -x "${SCRIPT}" ]
+ then
+ # FIXME
+ # debconf -ocontainer-tools "${SCRIPT}"
+ "${SCRIPT}"
+ fi
+done
+
+# Read-in configuration from debconf
+. "${DEBCONF_TMPDIR}/debconf.default"
+
+## Generic parts
+if [ ! -e "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}" ]
+then
+ Debootstrap "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}.tmp"
+ Configure_apt "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}.tmp"
+ Deconfigure_system "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}.tmp"
+
+ mv "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}.tmp" "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}"
+fi
+
+Upgrade_system "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}" || echo "W: If upgrading the system failed, try removing the cache for your distribution in /var/cache/container-tools"
+Cleanup_system "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}"
+
+## Specific parts
+cp -a "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}" "${MACHINES}/${NAME}"
+
+Configure_system "${MACHINES}/${NAME}"
+Configure_network "${MACHINES}/${NAME}"
+Cleanup_system "${MACHINES}/${NAME}"
+
+Commands "${MACHINES}/${NAME}"
+
+# remove debconf temporary files
+#FIXME
+#echo rm --preserve-root --one-file-system -rf "${DEBCONF_TMPDIR}"
+rmdir --ignore-fail-on-non-empty /tmp/container-tools || true