1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
|
#!/bin/bash
set -e
set -o pipefail
set -o errtrace
set -o functrace
# defaults
GRML_DEBOOTSTRAP='grml-debootstrap'
TARGET='/mnt'
INSTALL_TARGET='/dev/sda1'
GRUB_TARGET='/dev/sda'
## validation / checks
[ -f /etc/grml_cd ] || { echo "File /etc/grml_cd doesn't exist, not executing script to avoid data loss." >&2 ; exit 1 ; }
if [ -z "$DEBIAN_VERSION" ] ; then
echo "* Error: DEBIAN_VERSION environment variable is undefined. Exiting." >&2
exit 1
fi
## debugging
# if we notice an error then do NOT immediately return but provide
# user a chance to debug the VM
bailout() {
echo "* Noticed problem during execution (line ${1}, exit code ${2}), sleeping for 9999 seconds to provide debugging option"
sleep 9999
echo "* Finally exiting with return code 1"
exit "$2"
}
trap 'bailout ${LINENO} $?' ERR
## helper functions
virtualbox_setup() {
if ! mountpoint "${TARGET}" &>/dev/null ; then
echo "* Mounting target system"
mount "${INSTALL_TARGET}" "${TARGET}"
fi
echo "* Installing packages for Virtualbox Guest Additions"
chroot ${TARGET} apt-get -y install make gcc dkms
echo "* Installing Virtualbox Guest Additions"
isofile="${HOME}/VBoxGuestAdditions.iso"
KERNELHEADERS=$(basename $(find $TARGET/usr/src/ -maxdepth 1 -name linux-headers\* ! -name \*common) | sort -u -r -V | head -1)
if [ -z "$KERNELHEADERS" ] ; then
echo "Error: no kernel headers found for building the VirtualBox Guest Additions kernel module." >&2
exit 1
fi
KERNELVERSION=${KERNELHEADERS##linux-headers-}
if [ -z "$KERNELVERSION" ] ; then
echo "Error: no kernel version could be identified." >&2
exit 1
fi
cp /tmp/fake-uname.so "${TARGET}/tmp/fake-uname.so"
mkdir -p "${TARGET}/media/cdrom"
mountpoint "${TARGET}/media/cdrom" >/dev/null && umount "${TARGET}/media/cdrom"
mount -t iso9660 $isofile "${TARGET}/media/cdrom/"
UTS_RELEASE=$KERNELVERSION LD_PRELOAD=/tmp/fake-uname.so grml-chroot "$TARGET" /media/cdrom/VBoxLinuxAdditions.run --nox11 || true
if grep -q "make: .*vboxguest.*Error 2" "${TARGET}/var/log/vboxadd-install.log" ; then
echo "Error: looks like a fatal error happened during installation of VirtualBox Guest Additions." >&2
exit 1
fi
[ -r "${TARGET}/var/log/VBoxGuestAdditions.log" ] && tail -10 "${TARGET}/var/log/VBoxGuestAdditions.log"
[ -r "${TARGET}/var/log/vboxadd-install.log" ] && tail -10 "${TARGET}/var/log/vboxadd-install.log"
[ -r "${TARGET}/var/log/vboxadd-setup.log" ] && tail -10 "${TARGET}/var/log/vboxadd-setup.log"
umount "${TARGET}/media/cdrom/"
# work around bug in VirtualBox 4.3.18 which leaves process behind,
# causing unmount of "$TARGET" to fail
grml-chroot "$TARGET" /etc/init.d/vboxadd-service stop || true
# left behind by VBoxService
umount "$TARGET"/dev || true
# work around regression in virtualbox-guest-additions-iso 4.3.10
if [ -d ${TARGET}/opt/VBoxGuestAdditions-4.3.10 ] ; then
ln -s /opt/VBoxGuestAdditions-4.3.10/lib/VBoxGuestAdditions ${TARGET}/usr/lib/VBoxGuestAdditions
fi
if mountpoint "${TARGET}" &>/dev/null ; then
echo "* Unmounting target system"
umount "${TARGET}"
fi
}
vagrant_setup() {
if ! mountpoint "${TARGET}" &>/dev/null ; then
echo "* Mounting target system"
mount "${INSTALL_TARGET}" "${TARGET}"
fi
echo "* Setting password for user root to 'vagrant'"
echo root:vagrant | chroot ${TARGET} chpasswd
echo "* Installing sudo package"
chroot ${TARGET} apt-get -y install sudo
echo "* Adding Vagrant user"
chroot ${TARGET} useradd -d /home/vagrant -m -u 1000 vagrant -s /bin/bash
echo "* Installing Vagrant ssh key"
mkdir -m 0700 -p ${TARGET}/home/vagrant/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key" >> ${TARGET}/home/vagrant/.ssh/authorized_keys
chmod 0600 ${TARGET}/home/vagrant/.ssh/authorized_keys
chroot ${TARGET} chown vagrant:vagrant /home/vagrant/.ssh /home/vagrant/.ssh/authorized_keys
echo "* Setting up sudo configuration for user vagrant"
echo "vagrant ALL=(ALL) NOPASSWD: ALL" > "${TARGET}/etc/sudoers.d/vagrant"
chmod 0440 "${TARGET}/etc/sudoers.d/vagrant"
host="$(cat ${TARGET}/etc/hostname)"
if ! grep -q "${host}$" "${TARGET}"/etc/hosts ; then
echo "* Setting up localhost entry for hostname $host in /etc/hosts"
cat >> "${TARGET}"/etc/hosts << EOF
# Added by grml-debootstrap/provision to make sure host is resolvable for sudo:
127.0.0.2 ${host}.local $host
EOF
fi
echo "* Setting up stdin/tty workaround in /root/.profile"
sed -i "s;^mesg n$;# modified via grml-debootstrap/provision script to work around stdin/tty issue:\ntty -s \&\& mesg n;g" "${TARGET}"/root/.profile
if [ -f ${TARGET}/etc/ssh/sshd_config ] && ! grep -q '^UseDNS' ${TARGET}/etc/ssh/sshd_config ; then
echo "* Disabling UseDNS in sshd config"
echo "UseDNS no" >> ${TARGET}/etc/ssh/sshd_config
fi
if mountpoint "${TARGET}" &>/dev/null ; then
echo "* Unmounting target system"
umount "${TARGET}"
fi
}
partition_setup() {
echo "* Executing automated partition setup"
cat > /tmp/partition_setup.txt << EOF
disk_config sda disklabel:msdos bootable:1
primary / 800M- ext4 rw
EOF
export LOGDIR='/tmp/setup-storage'
mkdir -p $LOGDIR
export disklist=$(/usr/lib/fai/fai-disk-info | sort)
PATH=/usr/lib/fai:${PATH} setup-storage -f /tmp/partition_setup.txt -X
}
sources_list_setup() {
# This is ugly because it's 'testing' no matter what ISO we're using, but otherwise we're running into
# W: Failed to fetch http://snapshot.debian.org/archive/debian/20141114/dists/testing/main/binary-amd64/Packages 404 Not Found [IP: 193.62.202.30 80]
echo "* Setting up /etc/apt/sources.list.d/debian.list to avoid snapshot.debian.org usage causing possible failures"
cat > /etc/apt/sources.list.d/debian.list << EOF
deb http://ftp.debian.org/debian testing main
EOF
}
grml_debootstrap_setup() {
echo "* grml-debootstrap setup"
if [ "$GRML_DEBOOTSTRAP_VERSION" = "latest" ] ; then
echo "** GRML_DEBOOTSTRAP_VERSION is set to '$GRML_DEBOOTSTRAP_VERSION'"
echo "** Setting up grml-debootstrap from CI repository from jenkins.grml.org"
cat > /etc/apt/sources.list.d/grml-debootstrap.list << EOF
deb http://jenkins.grml.org/debian grml-debootstrap main
EOF
wget -O - http://jenkins.grml.org/debian/C525F56752D4A654.asc | apt-key add -
apt-get update
apt-get -y install grml-debootstrap
elif [ "$GRML_DEBOOTSTRAP_VERSION" = "stable" ] ; then
echo "** GRML_DEBOOTSTRAP_VERSION is set to '$GRML_DEBOOTSTRAP_VERSION'"
echo "** Using latest stable grml-debootstrap version"
apt-get update
apt-get -y install grml-debootstrap
elif [ "$GRML_DEBOOTSTRAP_VERSION" = "git" ] ; then
echo "** GRML_DEBOOTSTRAP_VERSION is set to '$GRML_DEBOOTSTRAP_VERSION'"
echo "** Using grml-debootstrap from Git repository"
git clone https://github.com/grml/grml-debootstrap.git
cd grml-debootstrap
GRML_DEBOOTSTRAP="CONFFILES=$(pwd) $(pwd)/grml-debootstrap"
elif [ "$GRML_DEBOOTSTRAP_VERSION" = "local" ] ; then
echo "** GRML_DEBOOTSTRAP_VERSION is set to '$GRML_DEBOOTSTRAP_VERSION'"
echo "** Using /tmp/grml-debootstrap derived from local system"
cd /tmp/grml-debootstrap
export CONFFILES=$(pwd)/etc/debootstrap
GRML_DEBOOTSTRAP="bash $(pwd)/usr/sbin/grml-debootstrap"
elif [ "$GRML_DEBOOTSTRAP_VERSION" = "iso" ] ; then
echo "** GRML_DEBOOTSTRAP_VERSION is set to '$GRML_DEBOOTSTRAP_VERSION'"
echo "** Using grml-debootstrap as provided on ISO"
fi
}
grml_debootstrap_execution() {
echo "* Installing Debian"
echo "** Executing: $GRML_DEBOOTSTRAP --hostname $DEBIAN_VERSION --release $DEBIAN_VERSION --target ${INSTALL_TARGET} --grub ${GRUB_TARGET} --password grml --force $GRML_DEB_OPTIONS" | tee -a /tmp/grml-debootstrap.log
$GRML_DEBOOTSTRAP --hostname "${DEBIAN_VERSION}" --release "${DEBIAN_VERSION}" --target "${INSTALL_TARGET}" --grub "${GRUB_TARGET}" --password grml --force $GRML_DEB_OPTIONS 2>&1 | tee -a /tmp/grml-debootstrap.log
}
apply_nic_workaround() {
# release specific stuff
case "$DEBIAN_VERSION" in
bullseye|bookworm|trixie|unstable|sid)
;;
*)
echo "* Debian $DEBIAN_VERSION doesn't require NIC workaround"
return 0
;;
esac
if ! mountpoint "${TARGET}" &>/dev/null ; then
echo "* Mounting target system"
mount "${INSTALL_TARGET}" "${TARGET}"
fi
echo "* Disabling predictable network interface names for Debian $DEBIAN_VERSION"
ln -s /dev/null "${TARGET}/etc/udev/rules.d/80-net-setup-link.rules"
echo "* Rebuilding initramfs to include udev configuration change"
chroot "${TARGET}" update-initramfs -u -k all
}
log_system_information() {
if ! mountpoint "${TARGET}" &>/dev/null ; then
echo "* Mounting target system"
mount "${INSTALL_TARGET}" "${TARGET}"
fi
local debian_version="$(cat ${TARGET}/etc/debian_version)"
echo "* Installed Debian version $debian_version"
echo "* Logging build information to /etc/grml_debootstrap.info"
echo "Debian $debian_version installed by grml-debootstrap/provision on $(date)" > ${TARGET}/etc/grml_debootstrap.info
$GRML_DEBOOTSTRAP --version | head -1 >> ${TARGET}/etc/grml_debootstrap.info || true
if mountpoint "${TARGET}" &>/dev/null ; then
echo "* Unmounting target system"
umount "${TARGET}"
fi
}
clean_apt_files() {
if ! mountpoint "${TARGET}" &>/dev/null ; then
echo "* Mounting target system"
mount "${INSTALL_TARGET}" "${TARGET}"
fi
echo "* Cleaning up apt stuff"
chroot ${TARGET} apt-get clean
rm -f ${TARGET}/var/lib/apt/lists/*Packages \
${TARGET}/var/lib/apt/lists/*Release \
${TARGET}/var/lib/apt/lists/*Sources \
${TARGET}/var/lib/apt/lists/*Index* \
${TARGET}/var/lib/apt/lists/*Translation* \
${TARGET}/var/lib/apt/lists/*.gpg \
${TARGET}/var/cache/apt-show-versions/* \
${TARGET}/var/cache/debconf/*.dat-old \
${TARGET}/var/cache/apt/*.bin \
${TARGET}/var/lib/aptitude/pkgstates.old
if mountpoint "${TARGET}" &>/dev/null ; then
echo "* Unmounting target system"
umount "${TARGET}"
fi
}
automated_tests() {
echo "* Checking for bats"
if dpkg --list bats >/dev/null 2>&1 ; then
echo "* bats is already present, nothing to do."
else
echo "* Installing bats"
apt-get update
apt-get -y install bats
fi
echo "* Running tests to verify grml-debootstrap system"
bats /tmp/debian64.bats -t
}
## main execution
sources_list_setup
partition_setup
grml_debootstrap_setup
grml_debootstrap_execution
virtualbox_setup
vagrant_setup
apply_nic_workaround
log_system_information
clean_apt_files
automated_tests
echo "* Finished execution of $0"
|