#!/bin/bash -e if test -f /etc/setup-debootstrap.conf; then . /etc/setup-debootstrap.conf fi if test -f ~/setup-debootstrap.conf; then . ~/setup-debootstrap.conf fi tmpdir=${tmpdir:-"/var/tmp/chroots"} test -d "${tmpdir}" || mkdir -p "${tmpdir}" if test -z "${ports[@]}"; then #ports=( armhf powerpc ppc64el s390x arm64 ) #qemus=( arm ppc ppc64 s390x aarch64 ) ports=( armhf ) qemus=( arm ) fi numports=${#ports[@]} if test -z "$archs"; then case "$(dpkg --print-architecture)" in (amd64) archs="amd64 i386";; (*) archs=$(dpkg --print-architecture);; esac for ((i=0; i<$numports; ++i)); do if test -x /usr/bin/qemu-${qemus[$i]}-static; then archs+=" ${ports[$i]}" fi done fi excludes="precise-armhf stretch-armhf" ubuntu="bionic artful xenial trusty" debian="buster stretch jessie sid" # not yet successfully installable: ubuntu zesty, debian buster distros=(${distros:-"${ubuntu[@]}" "${debian[@]}"}) packages_qt5="libpoppler-qt5-dev libpodofo-dev libqt5designer5 libqt5svg5-dev libqt5webkit5-dev qt5-default qt5-qmake qtbase5-dev qtbase5-dev-tools qttools5-dev qttools5-dev-tools" packages_base="apt-transport-https automake autotools-dev binutils-dev debhelper default-jdk-headless doxygen dpkg-dev g++ git graphviz libboost-thread-dev libcppunit-dev liblog4cxx-dev libpcsclite-dev libpkcs11-helper1-dev libproxy-dev libssl-dev libtool libz-dev lsb-release mscgen nodejs pandoc pkg-config software-properties-common subversion subversion-tools xvfb texinfo" #package_not_in_bionic="libpoppler-qt5-dev libqt5webkit5-dev texinfo libcppunit-dev liblog4cxx-dev mscgen nodejs pandoc xvfb libpodofo-dev libqt5designer5 qt5-default qttools5-dev-tools qttools5-dev" #package_not_in_artful="libpoppler-qt5-dev libqt5webkit5-dev texinfo libcppunit-dev liblog4cxx-dev mscgen nodejs pandoc xvfb libpodofo-dev libqt5designer5 qt5-default qttools5-dev-tools qttools5-dev" package_not_in_stretch="libssl-dev" #package_not_in_zesty="texinfo libcppunit-dev liblog4cxx-dev mscgen nodejs pandoc xvfb libpodofo-dev libqt5designer5 qt5-default qttools5-dev-tools qttools5-dev" #package_not_in_yakkety="default-jdk-headless" package_not_in_wily="default-jdk-headless" package_not_in_vivid="default-jdk-headless liblog4cxx-dev" package_not_in_trusty="default-jdk-headless liblog4cxx-dev" package_not_in_jessie="default-jdk-headless liblog4cxx-dev" package_not_in_precise="default-jdk-headless liblog4cxx-dev" package_not_in_wheezy="default-jdk-headless liblog4cxx-dev nodejs" if test -z "${packages}"; then packages="${packages_base} ${packages_qt5}" fi fastmode=0; declare -a limit=() arch= docker_user=${docker_user:-${USER:-$(id -un)}} while [ $# -gt 0 ]; do case "$1" in (-h|--help) cat < limit to given ditribution (can be called multiple times) -a, --arch limit to given architecture (can be called multiple times) -u, --user docker hub user name VARIABLES: docker_user docker hub user name (${docker_user}) tmpdir temporary directory (${tmpdir}) archs list of architectures to build for (${archs}) DESCRIPTION: Bootstraps chroots in ${tmpdir} for distro ubuntu and debian distributions of architecture ${archs// /, }, updates them and creates docker images on docker hub with tag ${docker_user}/:-. You should have a repositories named ubuntu and debian. You can the use these images e.g. for compiling packages in jenkins. If you have your own repository, you can also prepend it to docker hub user name, e.g. my.repo.url:5000/myname the script will then append ubuntu or debian, e.g. to my.repo.url:5000/myname/ubuntu:trusty-amd64. Please login to docker hub before you start this script. EOF exit 0;; (-f|--fastmode) fastmode=1;; (-l|--limit) shift; limit+=( "$1" );; (-a|--arch) shift; arch+=" $1";; (-u|--user) shift; docker_user=$1;; (*) echo "**** ERROR: unknown option $1" 1>&2 exit 1;; esac shift done error() { tmpdir=$2 disto=$3 arch=$4 echo "**** ERROR at ${0}:${1}" 1>&2 echo ".... on $(eval echo \"${BASH_COMMAND}\")" 1>&2 echo ".... tmpdir=$tmpdir arch=$arch distro=$distro" 1>&2 exit 1 } if test ${#limit[@]} -gt 0; then distros=( "${limit[@]}" ) fi for ((i=0; i<${#distros[@]}; ++i)); do for distro in ${distros[$i]}; do prevent=package_not_in_${distro} distropkgs=packages_${distro} instpkgs="${packages} ${!distropkgs}" for pkg in ${!prevent}; do instpkgs=${instpkgs//${pkg}/} done if ! test -e /usr/share/debootstrap/scripts/${distro}; then echo "**** WARNING: skipping unsupported ${distro}" 1>&2 continue; fi ubuntus="${ubuntu[@]}" if test "${ubuntus//${distro}/}" != "${ubuntus}"; then type="ubuntu" else type="debian" fi for arch in ${arch:-$archs}; do if [[ "${distro}-${arch}" = "$excludes" ]]; then continue; fi trap 'error "${LINENO}" "${tmpdir}" "${disto}" "${arch}"' ERR SIGINT echo "******** process $type $distro $arch ********" 1>&2 if test -d "${tmpdir}/${distro}-${arch}"; then echo " ++++ already exists ${tmpdir}/${distro}-${arch}" 1>&2 if test $fastmode -eq 1; then continue; fi else if test "$(dpkg --print-architecture)" = "$arch" -o \( "$(dpkg --print-architecture)" = amd64 -a "$arch" = i386 \) ; then echo " ---- install ${tmpdir}/${distro}-${arch}" 1>&2 sudo debootstrap --arch="$arch" "$distro" "${tmpdir}/${distro}-${arch}" else for ((j=0; j<$numports; ++j)); do if test "${ports[$j]}" = "${arch}"; then break; fi done qemu="${qemus[$j]}" if ! test -e /usr/bin/qemu-${qemu}-static; then echo "**** WARNING: no emulator ${qemu} found, skipping ${arch}" 1>&2 continue; fi arch=${arch#*-} echo " ---- install on $qemu ${tmpdir}/${distro}-${arch}" 1>&2 sudo debootstrap --foreign --arch="$arch" "$distro" "${tmpdir}/${distro}-${arch}" sudo cp /usr/bin/qemu-${qemu}-static "${tmpdir}/${distro}-${arch}/usr/bin/qemu-${qemu}-static" if test -f "${tmpdir}/${distro}-${arch}"/debootstrap/debootstrap; then ls -l "${tmpdir}/${distro}-${arch}"/debootstrap/debootstrap fi sudo DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot "${tmpdir}/${distro}-${arch}" dpkg --configure -a fi fi echo " ---- mount filesystems in ${tmpdir}/${distro}-${arch}" 1>&2 for x in proc sys dev; do if mount | grep -q "${tmpdir}/${distro}-${arch}"/$x; then sudo umount -flr "${tmpdir}/${distro}-${arch}"/$x fi done sudo mount -t proc proc "${tmpdir}/${distro}-${arch}"/proc sudo mount -t sysfs sys "${tmpdir}/${distro}-${arch}"/sys sudo mount -o bind /dev "${tmpdir}/${distro}-${arch}"/dev echo " ---- preconfigure debian packages in ${tmpdir}/${distro}-${arch}" 1>&2 sudo chroot "${tmpdir}/${distro}-${arch}" debconf-set-selections <&2 for f in "dbus" "libpam-systemd*" "packagekit*" "policykit*" "colord"; do sudo chroot "${tmpdir}/${distro}-${arch}" <> /etc/apt/preferences <&2 sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true update sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true -y -f install sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true -y upgrade sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true install -y python-software-properties software-properties-common || \ sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true install -y software-properties-common if [ "$type" != "debian" ]; then sudo chroot "${tmpdir}/${distro}-${arch}" add-apt-repository universe || \ sudo chroot "${tmpdir}/${distro}-${arch}" add-apt-repository "deb http://archive.ubuntu.com/ubuntu ${distro} universe" fi sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true update sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true -y dist-upgrade echo " ---- install ${instpkgs} to ${tmpdir}/${distro}-${arch}" 1>&2 sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true install -y ${instpkgs} echo " ---- cleanup ${instpkgs} to ${tmpdir}/${distro}-${arch}" 1>&2 sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true autoremove --purge -y sudo chroot "${tmpdir}/${distro}-${arch}" apt-get -o Acquire::ForceIPv4=true clean sudo rm -rf "${tmpdir}/${distro}-${arch}"/var/lib/apt/lists/* echo " ---- unmount filesystems in ${tmpdir}/${distro}-${arch}" 1>&2 for x in proc sys dev; do if mount | grep -q "${tmpdir}/${distro}-${arch}"/$x; then sudo umount -flr "${tmpdir}/${distro}-${arch}"/$x fi done echo " ---- import ${tmpdir}/${distro}-${arch} to ${docker_user}/${type}:${distro}-${arch}" 1>&2 cd "${tmpdir}/${distro}-${arch}" sudo tar c . | docker import - "${docker_user}/${type}:${distro}-${arch}" echo " ---- push ${tmpdir}/${distro}-${arch} to ${docker_user}/${type}:${distro}-${arch}" 1>&2 docker push "${docker_user}/${type}:${distro}-${arch}" done done done