aboutsummaryrefslogtreecommitdiff
path: root/kvmx-create
diff options
context:
space:
mode:
authorSilvio Rhatto <rhatto@riseup.net>2017-03-09 19:04:24 -0300
committerSilvio Rhatto <rhatto@riseup.net>2017-03-09 19:04:24 -0300
commit1cddbe0234efe158b6c05f21d742eb9489887cc4 (patch)
treee40bab6faf590e6d22e7b2360904155bbb0cef58 /kvmx-create
parent65f7ac258a41402bb9b00c87af621a65dfbfa6e0 (diff)
downloadkvmx-1cddbe0234efe158b6c05f21d742eb9489887cc4.tar.gz
kvmx-1cddbe0234efe158b6c05f21d742eb9489887cc4.tar.bz2
Project revamp: full workflow
Diffstat (limited to 'kvmx-create')
-rwxr-xr-xkvmx-create246
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