diff options
author | Daniel Baumann <daniel.baumann@open-infrastructure.net> | 2016-03-12 06:18:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@open-infrastructure.net> | 2016-03-31 14:30:16 +0000 |
commit | d753cad06ca3aa6cd33a89a964802b35139ea70f (patch) | |
tree | c80a5743a7aeee1aac28fe2d0e1148fcd9c9527f /share/scripts/debconf | |
parent | Adding blockio, cpu, memory and tasks limit config options. (diff) | |
download | compute-tools-d753cad06ca3aa6cd33a89a964802b35139ea70f.tar.xz compute-tools-d753cad06ca3aa6cd33a89a964802b35139ea70f.zip |
Adding debconf script.
Signed-off-by: Daniel Baumann <daniel.baumann@open-infrastructure.net>
Diffstat (limited to 'share/scripts/debconf')
-rwxr-xr-x | share/scripts/debconf | 974 |
1 files changed, 974 insertions, 0 deletions
diff --git a/share/scripts/debconf b/share/scripts/debconf new file mode 100755 index 0000000..5b73bd0 --- /dev/null +++ b/share/scripts/debconf @@ -0,0 +1,974 @@ +#!/bin/sh + +# Open Infrastructure: container-tools +# 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 |