From nobody Thu May 15 20:19:16 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1508346728517925.7783977661962; Wed, 18 Oct 2017 10:12:08 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CC5991455F7; Wed, 18 Oct 2017 17:12:06 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A6CFF77D6D; Wed, 18 Oct 2017 17:12:05 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AA61F1800C9D; Wed, 18 Oct 2017 17:12:03 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v9IHC2aI011783 for ; Wed, 18 Oct 2017 13:12:02 -0400 Received: by smtp.corp.redhat.com (Postfix) id 3F6F36A519; Wed, 18 Oct 2017 17:12:02 +0000 (UTC) Received: from inaba.usersys.redhat.com (unknown [10.40.205.73]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6503A5C89F for ; Wed, 18 Oct 2017 17:12:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com CC5991455F7 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Andrea Bolognani To: libvir-list@redhat.com Date: Wed, 18 Oct 2017 19:11:49 +0200 Message-Id: <20171018171151.12789-5-abologna@redhat.com> In-Reply-To: <20171018171151.12789-1-abologna@redhat.com> References: <20171018171151.12789-1-abologna@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [libvirt-jenkins-ci PATCH v2 4/6] guests: Add unattended installation support X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 18 Oct 2017 17:12:07 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The lcitool script can now be used to install most known guests without requiring user interaction. Signed-off-by: Andrea Bolognani --- guests/group_vars/all/install.yml | 11 +++ guests/host_vars/libvirt-centos-6/install.yml | 3 + guests/host_vars/libvirt-centos-7/install.yml | 3 + guests/host_vars/libvirt-debian-8/install.yml | 3 + guests/host_vars/libvirt-debian-9/install.yml | 3 + guests/host_vars/libvirt-fedora-25/install.yml | 3 + guests/host_vars/libvirt-fedora-26/install.yml | 3 + .../host_vars/libvirt-fedora-rawhide/install.yml | 3 + guests/host_vars/libvirt-ubuntu-12/install.yml | 3 + guests/host_vars/libvirt-ubuntu-14/install.yml | 3 + guests/host_vars/libvirt-ubuntu-16/install.yml | 3 + guests/kickstart.cfg | 60 +++++++++++++++ guests/lcitool | 82 ++++++++++++++++++= +++ guests/preseed.cfg | 85 ++++++++++++++++++= ++++ 14 files changed, 268 insertions(+) create mode 100644 guests/group_vars/all/install.yml create mode 100644 guests/host_vars/libvirt-centos-6/install.yml create mode 100644 guests/host_vars/libvirt-centos-7/install.yml create mode 100644 guests/host_vars/libvirt-debian-8/install.yml create mode 100644 guests/host_vars/libvirt-debian-9/install.yml create mode 100644 guests/host_vars/libvirt-fedora-25/install.yml create mode 100644 guests/host_vars/libvirt-fedora-26/install.yml create mode 100644 guests/host_vars/libvirt-fedora-rawhide/install.yml create mode 100644 guests/host_vars/libvirt-ubuntu-12/install.yml create mode 100644 guests/host_vars/libvirt-ubuntu-14/install.yml create mode 100644 guests/host_vars/libvirt-ubuntu-16/install.yml create mode 100644 guests/kickstart.cfg create mode 100644 guests/preseed.cfg diff --git a/guests/group_vars/all/install.yml b/guests/group_vars/all/inst= all.yml new file mode 100644 index 0000000..94b752f --- /dev/null +++ b/guests/group_vars/all/install.yml @@ -0,0 +1,11 @@ +--- +# Sizes are in GiB +install_virt_type: kvm +install_arch: x86_64 +install_machine: pc +install_cpu_model: host-passthrough +install_vcpus: 2 +install_memory_size: 2 +install_disk_size: 15 +install_storage_pool: default +install_network: default diff --git a/guests/host_vars/libvirt-centos-6/install.yml b/guests/host_va= rs/libvirt-centos-6/install.yml new file mode 100644 index 0000000..3a9459b --- /dev/null +++ b/guests/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/guests/host_vars/libvirt-centos-7/install.yml b/guests/host_va= rs/libvirt-centos-7/install.yml new file mode 100644 index 0000000..f003b89 --- /dev/null +++ b/guests/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/guests/host_vars/libvirt-debian-8/install.yml b/guests/host_va= rs/libvirt-debian-8/install.yml new file mode 100644 index 0000000..a2c8341 --- /dev/null +++ b/guests/host_vars/libvirt-debian-8/install.yml @@ -0,0 +1,3 @@ +--- +install_url: http://deb.debian.org/debian/dists/jessie/main/installer-amd6= 4/ +install_config: preseed.cfg diff --git a/guests/host_vars/libvirt-debian-9/install.yml b/guests/host_va= rs/libvirt-debian-9/install.yml new file mode 100644 index 0000000..5b1da76 --- /dev/null +++ b/guests/host_vars/libvirt-debian-9/install.yml @@ -0,0 +1,3 @@ +--- +install_url: http://deb.debian.org/debian/dists/stretch/main/installer-amd= 64/ +install_config: preseed.cfg diff --git a/guests/host_vars/libvirt-fedora-25/install.yml b/guests/host_v= ars/libvirt-fedora-25/install.yml new file mode 100644 index 0000000..bb4bde3 --- /dev/null +++ b/guests/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/guests/host_vars/libvirt-fedora-26/install.yml b/guests/host_v= ars/libvirt-fedora-26/install.yml new file mode 100644 index 0000000..eff160d --- /dev/null +++ b/guests/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/guests/host_vars/libvirt-fedora-rawhide/install.yml b/guests/h= ost_vars/libvirt-fedora-rawhide/install.yml new file mode 100644 index 0000000..2216e81 --- /dev/null +++ b/guests/host_vars/libvirt-fedora-rawhide/install.yml @@ -0,0 +1,3 @@ +--- +install_url: https://download.fedoraproject.org/pub/fedora/linux/developme= nt/rawhide/Everything/x86_64/os +install_config: kickstart.cfg diff --git a/guests/host_vars/libvirt-ubuntu-12/install.yml b/guests/host_v= ars/libvirt-ubuntu-12/install.yml new file mode 100644 index 0000000..997304f --- /dev/null +++ b/guests/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/guests/host_vars/libvirt-ubuntu-14/install.yml b/guests/host_v= ars/libvirt-ubuntu-14/install.yml new file mode 100644 index 0000000..d7862a5 --- /dev/null +++ b/guests/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/guests/host_vars/libvirt-ubuntu-16/install.yml b/guests/host_v= ars/libvirt-ubuntu-16/install.yml new file mode 100644 index 0000000..a7bb2da --- /dev/null +++ b/guests/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/guests/kickstart.cfg b/guests/kickstart.cfg new file mode 100644 index 0000000..603c0ae --- /dev/null +++ b/guests/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 UTC + + +# User creation +# +# We don't create any user except for root. We can use a very insecure +# root password here because it will be replaced with a used-defined one +# with Ansible immediately after installation +authconfig --enableshadow --passalgo=3Dsha512 +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=3Dvda +zerombr +clearpart --none +part / --fstype=3Dext4 --size=3D2048 --grow +part swap --fstype=3Dswap --size=3D256 + + +# Install bootloader +# +# The bootloader will be installed in the MBR +bootloader --location=3Dmbr --timeout=3D1 + + +# Configure networking +# +# The only network interface available to the guest will come up +# at boot using IPv4-only DHCP +network --bootproto=3Ddhcp --noipv6 --activate --onboot=3Dyes + + +# Software installation +# +# Only install the very base packages: everything else will be +# installed later using Ansible +%packages +@core +%end diff --git a/guests/lcitool b/guests/lcitool index 10a72cf..c10b49b 100755 --- a/guests/lcitool +++ b/guests/lcitool @@ -25,6 +25,34 @@ print(crypt.crypt(password, crypt.mksalt(crypt.METHOD_SHA512)))" } =20 +# 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=3D${INSTALL_URL:-$(yaml_var "$1" install_url)} + INSTALL_CONFIG=3D${INSTALL_CONFIG:-$(yaml_var "$1" install_config)} + INSTALL_VIRT_TYPE=3D${INSTALL_ARCH:-$(yaml_var "$1" install_virt_type)} + INSTALL_ARCH=3D${INSTALL_ARCH:-$(yaml_var "$1" install_arch)} + INSTALL_MACHINE=3D${INSTALL_MACHINE:-$(yaml_var "$1" install_machine)} + INSTALL_CPU_MODEL=3D${INSTALL_CPU_MODEL:-$(yaml_var "$1" install_cpu_m= odel)} + INSTALL_VCPUS=3D${INSTALL_VCPUS:-$(yaml_var "$1" install_vcpus)} + INSTALL_MEMORY_SIZE=3D${INSTALL_MEMORY_SIZE:-$(yaml_var "$1" install_m= emory_size)} + INSTALL_DISK_SIZE=3D${INSTALL_DISK_SIZE:-$(yaml_var "$1" install_disk_= size)} + INSTALL_STORAGE_POOL=3D${INSTALL_STORAGE_POOL:-$(yaml_var "$1" install= _storage_pool)} + INSTALL_NETWORK=3D${INSTALL_NETWORK:-$(yaml_var "$1" install_network)} +} + # ---------------------- # User-visible actions # ---------------------- @@ -35,6 +63,7 @@ Usage: $CALL_NAME ACTION [OPTIONS] =20 Actions: list List known guests + install GUEST Install GUEST prepare GUEST|all Prepare or update GUEST. Can be run multiple times update GUEST|all Alias for prepare help Display this help" @@ -46,6 +75,58 @@ do_list() { grep -vE '^#|^\[|^$' inventory | sort -u } =20 +do_install() +{ + GUEST=3D"$1" + + test "$GUEST" || { + die "$(do_help)" + } + 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 i= nstalled 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 wan= ts + # disk size in GiB and memory size in *MiB*, so perform conversion here + INSTALL_MEMORY_SIZE=3D$(expr "$INSTALL_MEMORY_SIZE" \* 1024 2>/dev/nul= l) + + # 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=3D"ks=3Dfile:/${INSTALL_CONFIG##*/}" = ;; + esac + + virt-install \ + --name "$GUEST" \ + --location "$INSTALL_URL" \ + --virt-type "$INSTALL_VIRT_TYPE" \ + --arch "$INSTALL_ARCH" \ + --machine "$INSTALL_MACHINE" \ + --cpu "$INSTALL_CPU_MODEL" \ + --vcpus "$INSTALL_VCPUS" \ + --memory "$INSTALL_MEMORY_SIZE" \ + --disk "size=3D$INSTALL_DISK_SIZE,pool=3D$INSTALL_STORAGE_POOL,bus= =3Dvirtio" \ + --network "network=3D$INSTALL_NETWORK,model=3Dvirtio" \ + --graphics none \ + --console pty \ + --sound none \ + --controller usb,model=3Dnone \ + --initrd-inject "$INSTALL_CONFIG" \ + --extra-args "console=3DttyS0 $EXTRA_ARGS" \ + --autostart \ + --wait 0 +} + do_prepare() { GUEST=3D"$1" =20 @@ -95,6 +176,7 @@ test -f "$PROGRAM_NAME" || { =20 case "$1" in list) do_list ;; + install) do_install "$2" ;; prepare|update) do_prepare "$2" ;; *help) do_help ;; *) die "$(do_help)" ;; diff --git a/guests/preseed.cfg b/guests/preseed.cfg new file mode 100644 index 0000000..00fd20d --- /dev/null +++ b/guests/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 UTC +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 here because it will be replaced with a used-defined one +# with Ansible immediately after installation +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 2048 -1 ext4 \ + $primary{ } $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 256 256 256 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/^#*\s*PermitRootLogin\= s*.*$/PermitRootLogin yes/g' /etc/ssh/sshd_config --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list