[libvirt] [libvirt-jenkins-ci PATCH 3/5] ansible: Add unattended installation support

Andrea Bolognani abologna at redhat.com
Mon Oct 16 16:02:06 UTC 2017


The 'manage' tool can now be used to install most known guests
without requiring user interaction.

Signed-off-by: Andrea Bolognani <abologna at redhat.com>
---
 ansible/group_vars/all/install.yml                 | 10 +++
 ansible/host_vars/libvirt-centos-6/install.yml     |  3 +
 ansible/host_vars/libvirt-centos-7/install.yml     |  3 +
 ansible/host_vars/libvirt-debian-8/install.yml     |  3 +
 ansible/host_vars/libvirt-debian-9/install.yml     |  3 +
 ansible/host_vars/libvirt-fedora-25/install.yml    |  3 +
 ansible/host_vars/libvirt-fedora-26/install.yml    |  3 +
 .../host_vars/libvirt-fedora-rawhide/install.yml   |  3 +
 ansible/host_vars/libvirt-ubuntu-12/install.yml    |  3 +
 ansible/host_vars/libvirt-ubuntu-14/install.yml    |  3 +
 ansible/host_vars/libvirt-ubuntu-16/install.yml    |  3 +
 ansible/kickstart.cfg                              | 60 +++++++++++++++
 ansible/manage                                     | 74 +++++++++++++++++++
 ansible/preseed.cfg                                | 85 ++++++++++++++++++++++
 14 files changed, 259 insertions(+)
 create mode 100644 ansible/group_vars/all/install.yml
 create mode 100644 ansible/host_vars/libvirt-centos-6/install.yml
 create mode 100644 ansible/host_vars/libvirt-centos-7/install.yml
 create mode 100644 ansible/host_vars/libvirt-debian-8/install.yml
 create mode 100644 ansible/host_vars/libvirt-debian-9/install.yml
 create mode 100644 ansible/host_vars/libvirt-fedora-25/install.yml
 create mode 100644 ansible/host_vars/libvirt-fedora-26/install.yml
 create mode 100644 ansible/host_vars/libvirt-fedora-rawhide/install.yml
 create mode 100644 ansible/host_vars/libvirt-ubuntu-12/install.yml
 create mode 100644 ansible/host_vars/libvirt-ubuntu-14/install.yml
 create mode 100644 ansible/host_vars/libvirt-ubuntu-16/install.yml
 create mode 100644 ansible/kickstart.cfg
 create mode 100644 ansible/preseed.cfg

diff --git a/ansible/group_vars/all/install.yml b/ansible/group_vars/all/install.yml
new file mode 100644
index 0000000..714328e
--- /dev/null
+++ b/ansible/group_vars/all/install.yml
@@ -0,0 +1,10 @@
+---
+# Sizes are in GiB
+install_virt_type: kvm
+install_arch: x86_64
+install_machine: pc
+install_vcpus: 2
+install_memory_size: 2
+install_disk_size: 10
+install_storage_pool: default
+install_network: default
diff --git a/ansible/host_vars/libvirt-centos-6/install.yml b/ansible/host_vars/libvirt-centos-6/install.yml
new file mode 100644
index 0000000..3a9459b
--- /dev/null
+++ b/ansible/host_vars/libvirt-centos-6/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://mirror.centos.org/centos/6/os/x86_64/
+install_config: kickstart.cfg
diff --git a/ansible/host_vars/libvirt-centos-7/install.yml b/ansible/host_vars/libvirt-centos-7/install.yml
new file mode 100644
index 0000000..f003b89
--- /dev/null
+++ b/ansible/host_vars/libvirt-centos-7/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://mirror.centos.org/centos/7/os/x86_64/
+install_config: kickstart.cfg
diff --git a/ansible/host_vars/libvirt-debian-8/install.yml b/ansible/host_vars/libvirt-debian-8/install.yml
new file mode 100644
index 0000000..a2c8341
--- /dev/null
+++ b/ansible/host_vars/libvirt-debian-8/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://deb.debian.org/debian/dists/jessie/main/installer-amd64/
+install_config: preseed.cfg
diff --git a/ansible/host_vars/libvirt-debian-9/install.yml b/ansible/host_vars/libvirt-debian-9/install.yml
new file mode 100644
index 0000000..5b1da76
--- /dev/null
+++ b/ansible/host_vars/libvirt-debian-9/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://deb.debian.org/debian/dists/stretch/main/installer-amd64/
+install_config: preseed.cfg
diff --git a/ansible/host_vars/libvirt-fedora-25/install.yml b/ansible/host_vars/libvirt-fedora-25/install.yml
new file mode 100644
index 0000000..bb4bde3
--- /dev/null
+++ b/ansible/host_vars/libvirt-fedora-25/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: https://download.fedoraproject.org/pub/fedora/linux/releases/25/Server/x86_64/os
+install_config: kickstart.cfg
diff --git a/ansible/host_vars/libvirt-fedora-26/install.yml b/ansible/host_vars/libvirt-fedora-26/install.yml
new file mode 100644
index 0000000..eff160d
--- /dev/null
+++ b/ansible/host_vars/libvirt-fedora-26/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: https://download.fedoraproject.org/pub/fedora/linux/releases/26/Server/x86_64/os
+install_config: kickstart.cfg
diff --git a/ansible/host_vars/libvirt-fedora-rawhide/install.yml b/ansible/host_vars/libvirt-fedora-rawhide/install.yml
new file mode 100644
index 0000000..2216e81
--- /dev/null
+++ b/ansible/host_vars/libvirt-fedora-rawhide/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: https://download.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/x86_64/os
+install_config: kickstart.cfg
diff --git a/ansible/host_vars/libvirt-ubuntu-12/install.yml b/ansible/host_vars/libvirt-ubuntu-12/install.yml
new file mode 100644
index 0000000..997304f
--- /dev/null
+++ b/ansible/host_vars/libvirt-ubuntu-12/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://archive.ubuntu.com/ubuntu/dists/precise/main/installer-amd64/
+install_config: preseed.cfg
diff --git a/ansible/host_vars/libvirt-ubuntu-14/install.yml b/ansible/host_vars/libvirt-ubuntu-14/install.yml
new file mode 100644
index 0000000..d7862a5
--- /dev/null
+++ b/ansible/host_vars/libvirt-ubuntu-14/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://archive.ubuntu.com/ubuntu/dists/trusty/main/installer-amd64/
+install_config: preseed.cfg
diff --git a/ansible/host_vars/libvirt-ubuntu-16/install.yml b/ansible/host_vars/libvirt-ubuntu-16/install.yml
new file mode 100644
index 0000000..a7bb2da
--- /dev/null
+++ b/ansible/host_vars/libvirt-ubuntu-16/install.yml
@@ -0,0 +1,3 @@
+---
+install_url: http://archive.ubuntu.com/ubuntu/dists/xenial/main/installer-amd64/
+install_config: preseed.cfg
diff --git a/ansible/kickstart.cfg b/ansible/kickstart.cfg
new file mode 100644
index 0000000..c28f275
--- /dev/null
+++ b/ansible/kickstart.cfg
@@ -0,0 +1,60 @@
+# Installer configuration
+#
+# Perform a text based installation followed by a reboot, and disable
+# the first boot assistant
+text
+install
+reboot
+firstboot --disable
+
+
+# Environment configuration
+#
+# Locale, keyboard and timezone. All these will be configured again
+# later with Ansible, but they're required information so we must
+# provide them
+lang en_US.UTF-8
+keyboard us
+timezone --utc Europe/Prague
+
+
+# User creation
+#
+# We don't create any user except for root. We can use a very insecure
+# root password because the guest will not be exposed to the Internet:
+# it will only be accessible from the host itself
+authconfig --enableshadow --passalgo=sha512
+rootpw --plaintext root
+
+
+# Partition disk
+#
+# Erase everything and set up a 2 GiB swap partition, then assign all
+# remaining space to the root partition
+ignoredisk --only-use=vda
+zerombr
+clearpart --none
+part / --fstype=ext4 --size=2048 --grow
+part swap --fstype=swap --size=2048
+
+
+# Install bootloader
+#
+# The bootloader will be installed in the MBR
+bootloader --location=mbr --timeout=1
+
+
+# Configure networking
+#
+# The only network interface available to the guest will come up
+# at boot using IPv4-only DHCP
+network --bootproto=dhcp --noipv6 --activate --onboot=yes
+
+
+# Software installation
+#
+# Only install the very base packages: everything else will be
+# installed later using Ansible
+%packages
+ at core
+%end
diff --git a/ansible/manage b/ansible/manage
index 46bec6c..d84b8b0 100755
--- a/ansible/manage
+++ b/ansible/manage
@@ -14,6 +14,33 @@ die() {
     exit 1
 }
 
+# yaml_var FILE VAR
+#
+# Read $FILE and output the value of YAML variable $VAR. Only trivial YAML
+# values are supported, eg. strings and numbers that don't depend on the
+# value of other variables. That's enough for our use case.
+yaml_var() {
+    grep "^$2:\\s*" "$1" 2>/dev/null | tail -1 | sed "s/$2:\\s*//g"
+}
+
+# load_config FILE
+#
+# Read all known configuration variables from $FILE and set them in the
+# environment. Configuration variables that have already been set in
+# the environment will not be updated.
+load_config() {
+    INSTALL_URL=${INSTALL_URL:-$(yaml_var "$1" install_url)}
+    INSTALL_CONFIG=${INSTALL_CONFIG:-$(yaml_var "$1" install_config)}
+    INSTALL_VIRT_TYPE=${INSTALL_ARCH:-$(yaml_var "$1" install_virt_type)}
+    INSTALL_ARCH=${INSTALL_ARCH:-$(yaml_var "$1" install_arch)}
+    INSTALL_MACHINE=${INSTALL_MACHINE:-$(yaml_var "$1" install_machine)}
+    INSTALL_VCPUS=${INSTALL_VCPUS:-$(yaml_var "$1" install_vcpus)}
+    INSTALL_MEMORY_SIZE=${INSTALL_MEMORY_SIZE:-$(yaml_var "$1" install_memory_size)}
+    INSTALL_DISK_SIZE=${INSTALL_DISK_SIZE:-$(yaml_var "$1" install_disk_size)}
+    INSTALL_STORAGE_POOL=${INSTALL_STORAGE_POOL:-$(yaml_var "$1" install_storage_pool)}
+    INSTALL_NETWORK=${INSTALL_NETWORK:-$(yaml_var "$1" install_network)}
+}
+
 # ----------------------
 #  User-visible actions
 # ----------------------
@@ -24,6 +51,7 @@ Usage: $PROGRAM_NAME ACTION [OPTIONS]
 
 Actions:
   list             List known guests
+  install GUEST    Install GUEST
   prepare GUEST    Prepare or update GUEST. Can be run as many times as needed
   update GUEST     Alias for prepare
   help             Display this help"
@@ -36,6 +64,51 @@ do_list() {
     grep -v '^\[' "$INVENTORY" | sort -u
 }
 
+do_install()
+{
+    GUEST="$1"
+
+    test "$GUEST" || {
+        die "Usage: $PROGRAM_NAME install GUEST"
+    }
+    do_list | grep -q "$GUEST" || {
+        die "$PROGRAM_NAME: $GUEST: Unknown guest"
+    }
+    test -f "host_vars/$GUEST/install.yml" || {
+        die "$PROGRAM_NAME: $GUEST: Missing configuration, guest must be installed manually"
+    }
+
+    # Load configuration files. Values don't get overwritten after being
+    # set the first time, so loading the host-specific configuration before
+    # the group configuration ensures overrides work as expected
+    load_config "host_vars/$GUEST/install.yml"
+    load_config "group_vars/all/install.yml"
+
+    # Both memory size and disk size use GiB as unit, but virt-install wants
+    # disk size in GiB and memory size in *MiB*, so perform conversion here
+    INSTALL_MEMORY_SIZE=$(expr "$INSTALL_MEMORY_SIZE" \* 1024 2>/dev/null)
+
+    # preseed files must use a well-known name to be picked up by d-i;
+    # for kickstart files, we can use whatever name we please but we need
+    # to point anaconda in the right direction through a kernel argument
+    case "$INSTALL_CONFIG" in
+        *kickstart*|*ks*) EXTRA_ARGS="ks=file:/${INSTALL_CONFIG##*/}" ;;
+    esac
+
+    virt-install \
+        --name "$GUEST" \
+        --location "$INSTALL_URL" \
+        --virt-type "$INSTALL_VIRT_TYPE" \
+        --arch "$INSTALL_ARCH" \
+        --machine "$INSTALL_MACHINE"  \
+        --vcpus "$INSTALL_VCPUS" \
+        --ram "$INSTALL_MEMORY_SIZE" \
+        --disk "size=$INSTALL_DISK_SIZE,pool=$INSTALL_STORAGE_POOL,bus=virtio" \
+        --network "network=$INSTALL_NETWORK,model=virtio" \
+        --initrd-inject "$INSTALL_CONFIG" \
+        --extra-args "$EXTRA_ARGS"
+}
+
 do_prepare() {
     GUEST="$1"
 
@@ -51,6 +124,7 @@ do_prepare() {
 
 case "$1" in
     list)           do_list ;;
+    install)        do_install "$2" ;;
     prepare|update) do_prepare "$2" ;;
     *help)          do_help ;;
     *)              die "Usage: $PROGRAM_NAME ACTION [OPTIONS]" ;;
diff --git a/ansible/preseed.cfg b/ansible/preseed.cfg
new file mode 100644
index 0000000..192118e
--- /dev/null
+++ b/ansible/preseed.cfg
@@ -0,0 +1,85 @@
+# Installer configuration
+#
+# Perform an automated installation where only critical questions
+# are asked interactively
+d-i auto-install/enable boolean true
+d-i debconf/priority string critical
+d-i finish-install/reboot_in_progress note
+
+
+# Environment configuration
+#
+# Locale, keyboard and timezone. All these will be configured again
+# later with Ansible, but they're required information so we must
+# provide them
+d-i debian-installer/locale string en_US.UTF-8
+d-i keyboard-configuration/xkb-keymap select us
+d-i time/zone string Europe/Prague
+d-i clock-setup/utc boolean true
+d-i clock-setup/ntp boolean true
+
+
+# User creation
+#
+# We don't create any user except for root. We can use a very insecure
+# root password because the guest will not be exposed to the Internet:
+# it will only be accessible from the host itself
+d-i passwd/make-user boolean false
+d-i passwd/root-login boolean true
+d-i passwd/root-password password root
+d-i passwd/root-password-again password root
+d-i user-setup/allow-password-weak boolean true
+
+
+# Partition disk
+#
+# Erase everything and set up a 2 GiB swap partition, then assign all
+# remaining space to the root partition
+d-i partman-auto/disk string /dev/vda
+d-i partman-auto/method string regular
+d-i partman-auto/expert_recipe string \
+    custom :: \
+        2048 4096 -1 ext4 \
+            $primary{ } $bootable{ } \
+            method{ format } format{ } \
+            use_filesystem{ } filesystem{ ext4 } \
+            mountpoint{ / } \
+        . \
+        2048 2048 2048 linux-swap \
+            $primary{ } \
+            method{ swap } format{ } \
+        .
+d-i partman-partitioning/confirm_write_new_label boolean true
+d-i partman/choose_partition select finish
+d-i partman/confirm boolean true
+d-i partman/confirm_nooverwrite boolean true
+
+
+# Install bootloader
+#
+# The bootloader will be installed in the MBR
+d-i grub-installer/skip boolean false
+d-i grub-installer/bootdev string /dev/vda
+d-i grub-installer/only_debian boolean true
+
+
+# Configure networking
+#
+# The only network interface available to the guest will come up
+# at boot using DHCP
+d-i netcfg/enable boolean true
+d-i netcfg/choose_interface select auto
+d-i netcfg/get_hostname string localhost
+d-i netcfg/get_domain string localdomain
+
+
+# Software installation
+#
+# Only install the very base packages: everything else will be
+# installed later using Ansible. We need to install openssh-server
+# and configure it to permit root login now, though, otherwise we
+# won't be able to access the machine for Ansible use later on
+tasksel tasksel/first multiselect standard
+d-i pkgsel/upgrade select none
+d-i pkgsel/include string openssh-server
+d-i preseed/late_command string in-target sed -i 's/^#* *PermitRootLogin .*$/PermitRootLogin yes/g' /etc/ssh/sshd_config
-- 
2.13.6




More information about the libvir-list mailing list