diff options
author | Silvio Rhatto <rhatto@riseup.net> | 2017-03-09 19:04:24 -0300 |
---|---|---|
committer | Silvio Rhatto <rhatto@riseup.net> | 2017-03-09 19:04:24 -0300 |
commit | 1cddbe0234efe158b6c05f21d742eb9489887cc4 (patch) | |
tree | e40bab6faf590e6d22e7b2360904155bbb0cef58 /kvmx-create | |
parent | 65f7ac258a41402bb9b00c87af621a65dfbfa6e0 (diff) | |
download | kvmx-1cddbe0234efe158b6c05f21d742eb9489887cc4.tar.gz kvmx-1cddbe0234efe158b6c05f21d742eb9489887cc4.tar.bz2 |
Project revamp: full workflow
Diffstat (limited to 'kvmx-create')
-rwxr-xr-x | kvmx-create | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/kvmx-create b/kvmx-create new file mode 100755 index 0000000..2eb97d5 --- /dev/null +++ b/kvmx-create @@ -0,0 +1,246 @@ +#!/bin/bash +# +# System installer, vmdebootstrap version. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/>. + + +# Parameters +BASENAME="`basename $0`" + +# Load configuration +function kvmx_config_load { + if [ ! -z "$1" ] && [ -e "$1" ]; then + source $1 + fi +} + +# Read a parameter from user +function kvmx_user_input { + local input + local param="$1" + local default="$2" + shift 2 + + if echo $param | grep -q 'passwd'; then + read -s -rep "$* (defaults to $default): " input + else + read -rep "$* (defaults to $default): " input + fi + + if [ -z "$input" ]; then + export $param="$default" + else + export $param="$input" + fi +} + +# Get a configuration parameter if not previously defined by a sourced file +function kvmx_user_config { + local param="$1" + local default="$2" + shift 2 + + if [ -z "`eval echo '$'$param`" ]; then + kvmx_user_input $param $default $* + fi +} + +# Install a package +function kvmx_install_package { + if [ -z "$1" ]; then + return + fi + + dpkg -s $1 &> /dev/null + + if [ "$?" == "1" ]; then + echo "Installing package $1..." + DEBIAN_FRONTEND=noninteractive $SUDO apt-get install $1 -y || exit 1 + fi +} + +# Abort on error +function kvmx_exit_on_error { + if [ "$?" != "0" ]; then + echo "Error: $*" + exit 1 + fi +} + +# Run a command using sudo and abort on error +function kvmx_sudo_run { + if [ "`whoami`" != 'root' ]; then + SUDO="sudo" + fi + + $SUDO $* + kvmx_exit_on_error $* +} + +# Make sure there is provision config. +function kvmx_config { + kvmx_user_config image /var/cache/qemu/debian/box.img "Destination image" + kvmx_user_config size 3G "Image size" + kvmx_user_config format qcow2 "Image format: raw or qcow2" + kvmx_user_config method custom "Bootstrap method: custom or vmdeboostrap" + kvmx_user_config hostname machine "Hostname" + kvmx_user_config domain example.org "Domain" + kvmx_user_config arch amd64 "System arch" + kvmx_user_config version stretch "Distro version" + kvmx_user_config mirror http://http.debian.net/debian/ "Debian mirror" +} + +# Load config file +kvmx_config_load $1 + +# Get config parameters +kvmx_config + +# Check +if [ -e "$image" ]; then + echo "error: $image already exists." + exit 1 +fi + +# Ensure base folder exists +kvmx_sudo_run mkdir -p `dirname $image` + +# +# vmdebootstrap version +# +function kvmx_create_vmdebootstrap { + # Check for requirements + for req in vmdebootstrap mbr; do + kvmx_install_package $req + done + + # Image format + if [ "$format" == "qcow2" ]; then + format="--convert-qcow2" + else + formt="" + fi + + # Run + kvmx_sudo_run vmdebootstrap --verbose --image=$image --size=$size --distribution=$version \ + --mirror=$mirror --arch=$arch --hostname=$hostname.$domain \ + --grub $format + + # Fix permissions + kvmx_sudo_run chown -R `whoami`. `dirname $image` + + # Cleanup + kvmx_sudo_run rm debootstrap.log + kvmx_sudo_run rm ${image}.raw +} + +# +# Custom version +# +function kvmx_create_custom { + WORK="`mktemp -d`" + + # Check for requirements. + for req in debootstrap grub-pc parted; do + kvmx_install_package $req + done + + echo "Creating image..." + #kvmx_sudo_run dd if=/dev/zero of=$image bs=$size count=1 + kvmx_sudo_run qemu-img create -f raw $image $size + device="`sudo losetup --find --show $image`" + + echo "Partitioning image at $device..." + kvmx_sudo_run parted -s -- $device mklabel gpt + kvmx_sudo_run parted -s -- $device unit MB mkpart non-fs 2 3 + kvmx_sudo_run parted -s -- $device set 1 bios_grub on + kvmx_sudo_run parted -s -- $device unit MB mkpart ext2 3 -1 + kvmx_sudo_run parted -s -- $device set 2 boot on + kvmx_sudo_run mkfs.ext4 ${device}p2 + kvmx_sudo_run mount ${device}p2 $WORK/ + + # Non-interactive installation + APT_INSTALL="kvmx_sudo_run LC_ALL=C DEBIAN_FRONTEND=noninteractive chroot $WORK/ apt-get install -y" + + # Initial system install. + echo "Installing base system..." + kvmx_sudo_run LC_ALL=C DEBIAN_FRONTEND=noninteractive debootstrap --arch=$arch $version $WORK/ $mirror + + # Initial configuration. + echo "Applying initial configuration..." + kvmx_sudo_run mount none -t proc $WORK/proc + kvmx_sudo_run mount none -t sysfs $WORK/sys + kvmx_sudo_run mount -o bind /dev/ $WORK/dev + echo LANG=C | $SUDO tee $WORK/etc/default/locale > /dev/null + + # Hostname configuration. + echo $hostname.$domain | $SUDO tee $WORK/etc/hostname > /dev/null + echo "127.0.0.1 localhost" | $SUDO tee -a $WORK/etc/hosts > /dev/null + + # This ordering is important for facter correctly guess the domain name + echo "127.0.0.1 $hostname.$domain $hostname" | $SUDO tee -a $WORK/etc/hosts > /dev/null + + # Invert hostname contents to avoid http://projects.puppetlabs.com/issues/2533 + tac $WORK/etc/hosts | $SUDO tee $WORK/etc/hosts.new > /dev/null + kvmx_sudo_run mv $WORK/etc/hosts.new $WORK/etc/hosts + + # Initial upgrade + echo "Applying initial upgrades..." + kvmx_sudo_run chroot $WORK/ apt-get update + kvmx_sudo_run chroot $WORK/ apt-get upgrade -y + + if [ "$arch" == "i386" ]; then + kernel_arch="686" + else + kernel_arch="$arch" + fi + + $APT_INSTALL locales + $APT_INSTALL screen cron lsb-release openssl -y + $APT_INSTALL linux-image-$kernel_arch -y + $APT_INSTALL grub-pc -y + kvmx_sudo_run chroot $WORK/ update-grub + kvmx_sudo_run chroot $WORK/ grub-install $device + + # Teardown + kvmx_sudo_run umount $WORK/proc + kvmx_sudo_run umount $WORK/sys + kvmx_sudo_run umount $WORK/dev + kvmx_sudo_run umount $WORK + kvmx_sudo_run rmdir $WORK + kvmx_sudo_run losetup -d $device + + # Image conversion + if [ "$format" == "qcow2" ]; then + echo "Converting raw image to qcow2..." + kvmx_sudo_run mv $image $image.raw + kvmx_sudo_run qemu-img convert -O qcow2 ${image}.raw $image + kvmx_sudo_run rm ${image}.raw + fi + + # Fix permissions + kvmx_sudo_run chown -R `whoami`. `dirname $image` +} + +# Dispatch +if [ "$method" == "custom" ]; then + kvmx_create_custom +elif [ "$method" == "vmdebootstrap" ]; then + kvmx_create_vmdebootstrap +else + echo "$BASENAME: invalid method $method" + exit 1 +fi |