#!/bin/sh # $Id: create_slackware_openvz_template.sh,v 1.5 2015/05/20 09:48:11 root Exp root $ # Copyright 2014, 2015 Eric Hameleers, Eindhoven, NL # All rights reserved. # # Permission to use, copy, modify, and distribute this software for # any purpose with or without fee is hereby granted, provided that # the above copyright notice and this permission notice appear in all # copies. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ----------------------------------------------------------------------------- # # This script creates a template for a Slackware OS, to be deployed with openvz. # Stamp today in the filename: THEDATE=$(date +%Y%m%d) # Slackware version to install: SL_VERSION=${SL_VERSION:-"14.1"} # Slackware architecture to install: SL_ARCH=${SL_ARCH:-"x86_64"} # Directory suffix, arch dependent: if [ "$SL_ARCH" = "x86_64" ]; then DIRSUFFIX="64" else DIRSUFFIX="" fi # Root directory of a Slackware local mirror tree: SL_REPO=${SL_REPO:-"/home/ftp/pub/Linux/Slackware"} # Package root directory: SL_PKGROOT=${SL_REPO}/slackware${DIRSUFFIX}-${SL_VERSION}/slackware${DIRSUFFIX} # Patches root directory: SL_PATCHROOT=${SL_REPO}/slackware${DIRSUFFIX}-${SL_VERSION}/patches/packages # Directory where we will install the root filesystem: VZ_ROOTDIR=${VZ_ROOTDIR:-"/mnt/openzvz_temp"} # Directory where the template archive will be written: OUTPUT=${OUTPUT:-"/tmp"} # Slackware minimal package list: SL_PKGLIST=" aaa_base aaa_elflibs aaa_terminfo acl attr bash bin binutils bison bzip2 coreutils cpio cxxlibs dcron dev86 devs dhcpcd dialog diffutils dmidecode e2fsprogs elvis etc file findutils flex floppy gawk gcc glibc-solibs glibc-zoneinfo gnupg gnutls gptfdisk grep groff gzip infozip iptables iputils kernel-firmware kernel-headers kmod less libmpc libtermcap lilo links logrotate lvm2 make man man-pages mkinitrd mpfr mtr nano ncurses net-tools network-scripts openssh openssl-solibs parted pkgtools polkit procps quota rsync screen sed shadow sharutils slackpkg slocate strace sudo sysklogd syslinux sysvinit sysvinit-scripts tar udev usbutils utempter util-linux wget which whois xz " # Action! # Some sanity checks first. if [ ! -d ${SL_REPO} ]; then echo "-- Slackware repository root '${SL_REPO}' does not exist! Exiting." exit 1 fi # Create output directory for template file: mkdir -p ${OUTPUT} if [ $? -ne 0 ]; then echo "-- Creation of output directory '${OUTPUT}' failed! Exiting." exit 1 fi # Create working directory: if [ ! -d ${VZ_ROOTDIR} ]; then mkdir -p ${VZ_ROOTDIR} if [ $? -ne 0 ]; then echo "-- Creation of working directory '${VZ_ROOTDIR}' failed! Exiting." exit 1 fi else echo "-- Found an existing openvz root filesystem at '${VZ_ROOTDIR}'". echo "-- After 10 seconds we will proceed and wipe it." echo "-- If you do not want to delete this, please press Ctrl-C now!" read -t 10 -p "-- Continue [Y/n] ?" if [ "x$REPLY" = "xn" -o "x$REPLY" = "xN" ]; then echo "-- OK: exiting now." fi fi echo rm -rf --one-file-system ${VZ_ROOTDIR}/* chmod 775 ${VZ_ROOTDIR} # Find packages and install them into the temporary root: for PKG in $(echo $SL_PKGLIST); do FULLPKG=$(find ${SL_PATCHROOT} -name "${PKG}-*.t?z" | grep -E "${PKG}-[^-]+-[^-]+-[^-]+.t?z") if [ "x${FULLPKG}" = "x" ]; then FULLPKG=$(find ${SL_PKGROOT} -name "${PKG}-*.t?z" | grep -E "${PKG}-[^-]+-[^-]+-[^-]+.t?z") else echo "-- $PKG found in patches" fi if [ "x${FULLPKG}" = "x" ]; then echo "-- Package $PKG was not found in Slackware ${SL_VERSION} !" else installpkg --terse --root ${VZ_ROOTDIR} ${FULLPKG} fi done # Next step, prepare the root filesystem for use as an openvz container. # Clean out the unneeded stuff: rm -f ${VZ_ROOTDIR}/boot/* rm -f ${VZ_ROOTDIR}/tmp/[A-Za-z]* rm -f ${VZ_ROOTDIR}/var/mail/* # Disable unneeded services: [ -f ${VZ_ROOTDIR}/etc/rc.d/rc.acpid ] && chmod -x ${VZ_ROOTDIR}/etc/rc.d/rc.acpid [ -f ${VZ_ROOTDIR}/etc/rc.d/rc.pcmcia ] && chmod -x ${VZ_ROOTDIR}/etc/rc.d/rc.pcmcia [ -f ${VZ_ROOTDIR}/etc/rc.d/rc.udev ] && chmod -x ${VZ_ROOTDIR}/etc/rc.d/rc.udev # Remove ssh server keys - new unique keys will be generated # at first boot of a container: rm -f ${VZ_ROOTDIR}/etc/ssh/*key* # Delete /etc/mtab and make it a symlink to /proc/mounts: rm -f ${VZ_ROOTDIR}/etc/mtab ln -s /proc/mounts ${VZ_ROOTDIR}/etc/mtab # Change /etc/rc.d/rc.S so that Slackware does not remove our /etc/mtab symlink: sed -i -e '/ \/etc\/mtab/s/^/# /' ${VZ_ROOTDIR}/etc/rc.d/rc.S # No hardware clock present: sed -i -e '/^if \[ -x \/sbin\/hwclock/,/^fi$/s/^/#/' ${VZ_ROOTDIR}/etc/rc.d/rc.S # We need this to skip the WRITE check at next boot, which would drop us in a # recovery shell and halt the boot process: sed -i -e '/^if touch \/fsrwtestfile/,/^fi$/s/^/#/' ${VZ_ROOTDIR}/etc/rc.d/rc.S # Better to disable the root filesystem check altogether: sed -i -e '/^if \[ ! \$READWRITE = yes/,/^fi # Done checking root filesystem/s/^/#/' ${VZ_ROOTDIR}/etc/rc.d/rc.S # Setterm is not useful here: sed -i -e '/\/bin\/setterm/s/^/# /' ${VZ_ROOTDIR}/etc/rc.d/rc.M # We can not write to the hardware clock: sed -i -e '/systohc/s/^/# /' ${VZ_ROOTDIR}/etc/rc.d/rc.6 # Skip all filesystem checks at boot: touch ${VZ_ROOTDIR}/etc/fastboot # Sanitize /etc/fstab : cat < ${VZ_ROOTDIR}/etc/fstab devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs defaults,nodev,nosuid,mode=1777 0 0 EOT # Edit /etc/inittab so that console login processes are not spawned: sed -i -e "/agetty/s/^c/#c/" ${VZ_ROOTDIR}/etc/inittab # Reduce the number of local consoles, two should be enough: sed -i -e '/^c3\|^c4\|^c5\|^c6/s/^/# /' ${VZ_ROOTDIR}/etc/inittab # Edit /etc/shadow and invalidate the root password. # The openvz tools will set the password instead: sed -i -e '/^root/s/^root::/root:!:/' ${VZ_ROOTDIR}/etc/shadow # Make sure we can access DNS: cat <> ${VZ_ROOTDIR}/etc/resolv.conf nameserver 8.8.4.4 nameserver 8.8.8.8 EOT # Enable a Slackware mirror for slackpkg: cat <> ${VZ_ROOTDIR}/etc/slackpkg/mirrors http://mirrors.slackware.com/slackware/slackware${DIRSUFFIX}-${SL_VERSION}/ EOT # Blacklist the l10n packages; cat << EOT >> ${VZ_ROOTDIR}/etc/slackpkg/blacklist # Blacklist the l10n packages; calligra-l10n- kde-l10n- EOT # Update the cache for slackpkg: echo "-- Creating slackpkg cache, takes a few seconds..." chroot ${VZ_ROOTDIR} /usr/sbin/slackpkg update gpg 2>/dev/null chroot ${VZ_ROOTDIR} /usr/sbin/slackpkg update 2>/dev/null # Create a locate cache: echo "-- Creating locate cache, takes a few seconds..." chroot ${VZ_ROOTDIR} /etc/cron.daily/slocate 2>/dev/null # Compress the tree into an OpenVZ template: echo "-- Creating the template..." cd ${VZ_ROOTDIR} tar -Jcvf ${OUTPUT}/slackware-${SL_VERSION}-${SL_ARCH}-minimal-${THEDATE}.tar.xz . if [ $? -eq 0 ]; then echo "-- Created ${OUTPUT}/slackware-${SL_VERSION}-${SL_ARCH}-minimal-${THEDATE}.tar.xz" else echo "-- Non-zero exitcode, something went wrong." fi cd -