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

Pavel Hrdina phrdina at redhat.com
Tue Oct 17 15:57:30 UTC 2017


On Mon, Oct 16, 2017 at 06:02:06PM +0200, Andrea Bolognani wrote:
> 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

I wouldn't include Ubuntu related things.  Yes, we use travis where they
have Ubuntu nodes, but this is jenkins-ci repository where we don't use
Ubuntu at all.

>  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

Currently we have 15 GiB per guest and in some cases we are able to run
out of space.  Let's use 15 GiB.

> +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

I would add "console=ttyS0" into EXTRA_ARGS to get serial console
working.

> +
> +    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" \

Don't use --ram, that is deprecated, --memory should be used instead.

> +        --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"

and we might add:

    --cpu host-passthrough  // we will not migrate the guest
    --graphics none         // we use only ssh to the CI host
    --serial pty            // if something is really wrong with the guest
    --autostart

Pavel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20171017/d68d4e84/attachment-0001.sig>


More information about the libvir-list mailing list