From c51505dc0485b1434c73cdea2b3f98a568fb9110 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Thu, 28 Sep 2017 16:03:01 +0100 Subject: xci: scripts: start-new-vm.sh: Use Docker to build OS images Use a docker container to build the OS images so we can build images and start new virtual machines on all supported operating systems. This way all developers can now launch a virtual machine to quickly reproduce Jenkins results which should assist with debugging problems. Since the container runs with elevated privileges it's best to ensure that we have exclusive access to devices. Finally, we remove the build-dib-os.sh script which is now part of the container itself. The build image process now becomes more stable since it runs on clean evnironment all the time so the only external factor is the upstream distribution repositories. Change-Id: I6b443192419ee2546a23430f421b152766d16333 Signed-off-by: Markos Chandras --- xci/scripts/vm/build-dib-os.sh | 65 --------------------- xci/scripts/vm/start-new-vm.sh | 124 ++++++++++++++++++++++++++++------------- 2 files changed, 85 insertions(+), 104 deletions(-) delete mode 100755 xci/scripts/vm/build-dib-os.sh (limited to 'xci/scripts') diff --git a/xci/scripts/vm/build-dib-os.sh b/xci/scripts/vm/build-dib-os.sh deleted file mode 100755 index a09ee3c6..00000000 --- a/xci/scripts/vm/build-dib-os.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -############################################################################## -# Copyright (c) 2017 SUSE LINUX GmbH. -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -set -e - -# This only works on ubuntu hosts -lsb_release -i | grep -q -i ubuntu || { echo "This script only works on Ubuntu distros"; exit 1; } - -declare -A flavors=( ["ubuntu-minimal"]="xenial" ["opensuse-minimal"]="42.3" ["centos-minimal"]="7" ) -declare -r elements="vm simple-init devuser growroot openssh-server" -declare -r one_distro=${1} -declare -r BASE_PATH=$(dirname $(readlink -f $0) | sed "s@/xci/.*@@") - -if [[ -n ${one_distro} ]]; then - case ${one_distro} in - centos|ubuntu|opensuse) : ;; - *) echo "unsupported distribution"; exit 1 ;; - esac -fi - -# devuser logins -echo "Configuring devuser..." -export DIB_DEV_USER_USERNAME=devuser -export DIB_DEV_USER_PWDLESS_SUDO=1 -export DIB_DEV_USER_AUTHORIZED_KEYS=${BASE_PATH}/xci/scripts/vm/id_rsa_for_dib.pub -export DIB_DEV_USER_PASSWORD=linux - -echo "Installing base dependencies..." -sudo apt-get install -y -q=3 yum yum-utils rpm zypper kpartx python-pip debootstrap gnupg2 - -echo "Installing diskimage-builder" - -sudo -H pip install -q diskimage-builder==2.9.0 - -echo "Removing old files..." -sudo rm -rf *.qcow2 *.sha256.txt - -do_build() { - local image=${1}-minimal - local image_name=${1} - echo "Building ${image}-${flavors[$image]}..." - export DIB_RELEASE=${flavors[$image]} - # Some defaults - export DIB_YUM_MINIMAL_CREATE_INTERFACES=1 # centos dhcp setup - disk-image-create --no-tmpfs -o ${image_name}.qcow2 ${elements} $image - sha256sum ${image_name}.qcow2 > ${image_name}.sha256.txt - echo "Done!" -} - -if [[ -n ${one_distro} ]]; then - do_build ${one_distro} -else - for image in "${!flavors[@]}"; do - image_name=${image/-minimal} - do_build $image_name - done -fi - -exit 0 diff --git a/xci/scripts/vm/start-new-vm.sh b/xci/scripts/vm/start-new-vm.sh index 65133edc..8f2eff1f 100755 --- a/xci/scripts/vm/start-new-vm.sh +++ b/xci/scripts/vm/start-new-vm.sh @@ -10,8 +10,6 @@ set -e -lsb_release -i | grep -q -i ubuntu || { echo "This script only works on Ubuntu distros"; exit 1; } - export DEFAULT_XCI_TEST=${DEFAULT_XCI_TEST:-false} grep -q -i ^Y$ /sys/module/kvm_intel/parameters/nested || { echo "Nested virtualization is not enabled but it's needed for XCI to work"; exit 1; } @@ -30,41 +28,86 @@ declare -r CPU=host declare -r NCPUS=24 declare -r MEMORY=49152 declare -r DISK=500 -declare -r NAME=${1}_xci_vm +declare -r VM_NAME=${1}_xci_vm declare -r OS=${1} declare -r NETWORK="jenkins-test" declare -r BASE_PATH=$(dirname $(readlink -f $0) | sed "s@/xci/.*@@") -echo "Preparing new virtual machine '${NAME}'..." +echo "Preparing new virtual machine '${VM_NAME}'..." + +source /etc/os-release +echo "Installing host (${ID,,}) dependencies..." +# check we can run sudo +if ! sudo -n "true"; then + echo "" + echo "passwordless sudo is needed for '$(id -nu)' user." + echo "Please fix your /etc/sudoers file. You likely want an" + echo "entry like the following one..." + echo "" + echo "$(id -nu) ALL=(ALL) NOPASSWD: ALL" + exit 1 +fi +case ${ID,,} in + *suse) sudo zypper -q -n in virt-manager qemu-kvm qemu-tools libvirt-daemon docker libvirt-client libvirt-daemon-driver-qemu iptables ebtables dnsmasq + ;; + centos) sudo yum install -q -y epel-release + sudo yum install -q -y in virt-manager qemu-kvm qemu-kvm-tools qemu-img libvirt-daemon-kvm docker iptables ebtables dnsmasq + ;; + ubuntu) sudo apt-get install -y -q=3 virt-manager qemu-kvm libvirt-bin qemu-utils docker.io docker iptables ebtables dnsmasq + ;; +esac + +echo "Ensuring libvirt and docker services are running..." +sudo systemctl -q start libvirtd +sudo systemctl -q start docker + +echo "Building new ${OS} image..." -# NOTE(hwoarang) This should be removed when we move the dib images to a central place _retries=20 -echo "Building '${OS}' image (tail build.log for progress and failures)..." -while [[ $_retries -ne 0 ]]; do - if pgrep build-dib-os.sh &>/dev/null; then +while [[ $_retries -gt 0 ]]; do + if pgrep -a docker | grep -q docker-dib-xci &> /dev/null; then echo "There is another dib process running... ($_retries retries left)" sleep 60 (( _retries = _retries - 1 )) else - if [[ -n ${JENKINS_HOME} ]]; then - $BASE_PATH/xci/scripts/vm/build-dib-os.sh ${OS} 2>&1 | tee build.log - else - $BASE_PATH/xci/scripts/vm/build-dib-os.sh ${OS} > build.log 2>&1 + docker_cmd="sudo docker" + # See if we can run docker as regular user. + docker ps &> /dev/null && docker_cmd="docker" + docker_name="docker_xci_builder_${OS}" + # Destroy previous containers + if eval $docker_cmd ps -a | grep -q ${docker_name} &>/dev/null; then + echo "Destroying previous container..." + eval $docker_cmd rm -f ${docker_name} fi + # Prepare new working directory + dib_workdir="$(pwd)/docker_dib_xci_workdir" + [[ ! -d $dib_workdir ]] && mkdir $dib_workdir + chmod 777 -R $dib_workdir + uid=$(id -u) + gid=$(id -g) + # Get rid of stale files + rm -rf $dib_workdir/*.qcow2 $dib_workdir/*.sha256.txt $dib_workdir/*.d + echo "Getting the latest docker image..." + eval $docker_cmd pull hwoarang/docker-dib-xci:latest + echo "Initiating dib build..." + eval $docker_cmd run --name ${docker_name} \ + --rm --privileged=true -e ONE_DISTRO=${OS} \ + -t -v $dib_workdir:$dib_workdir -w $dib_workdir \ + hwoarang/docker-dib-xci '/usr/bin/do-build.sh' + sudo chown $uid:$gid $dib_workdir/${OS}.qcow2 + declare -r OS_IMAGE_FILE=$dib_workdir/${OS}.qcow2 + break fi done -[[ ! -e ${OS}.qcow2 ]] && echo "${OS}.qcow2 not found! This should never happen!" && exit 1 - -sudo apt-get install -y -q=3 virt-manager qemu-kvm libvirt-bin qemu-utils -sudo systemctl -q start libvirtd +[[ ! -e ${OS_IMAGE_FILE} ]] && echo "${OS_IMAGE_FILE} not found! This should never happen!" && exit 1 echo "Resizing disk image '${OS}' to ${DISK}G..." -qemu-img resize ${OS}.qcow2 ${DISK}G +qemu-img resize ${OS_IMAGE_FILE} ${DISK}G echo "Creating new network '${NETWORK}' if it does not exist already..." -if ! sudo virsh net-list --name | grep -q ${NETWORK}; then +if ! sudo virsh net-list --name --all | grep -q ${NETWORK}; then cat > /tmp/${NETWORK}.xml < ${NETWORK} @@ -82,38 +125,39 @@ if ! sudo virsh net-list --name | grep -q ${NETWORK}; then EOF sudo virsh net-define /tmp/${NETWORK}.xml - sudo virsh net-autostart ${NETWORK} - sudo virsh net-start ${NETWORK} fi +sudo virsh net-list --autostart | grep -q ${NETWORK} || sudo virsh net-autostart ${NETWORK} +sudo virsh net-list --inactive | grep -q ${NETWORK} && sudo virsh net-start ${NETWORK} + echo "Destroying previous instances if necessary..." -sudo virsh destroy ${NAME} || true -sudo virsh undefine ${NAME} || true +sudo virsh destroy ${VM_NAME} || true +sudo virsh undefine ${VM_NAME} || true -echo "Installing virtual machine '${NAME}'..." -sudo virt-install -n ${NAME} --memory ${MEMORY} --vcpus ${NCPUS} --cpu ${CPU} \ - --import --disk=${OS}.qcow2,cache=unsafe --network network=${NETWORK} \ +echo "Installing virtual machine '${VM_NAME}'..." +sudo virt-install -n ${VM_NAME} --memory ${MEMORY} --vcpus ${NCPUS} --cpu ${CPU} \ + --import --disk=${OS_IMAGE_FILE},cache=unsafe --network network=${NETWORK} \ --graphics none --hvm --noautoconsole _retries=30 while [[ $_retries -ne 0 ]]; do - _ip=$(sudo virsh domifaddr ${NAME} | grep -o --colour=never 192.168.140.[[:digit:]]* | cat ) + _ip=$(sudo virsh domifaddr ${VM_NAME} | grep -o --colour=never 192.168.140.[[:digit:]]* | cat ) if [[ -z ${_ip} ]]; then - echo "Waiting for '${NAME}' virtual machine to boot ($_retries retries left)..." + echo "Waiting for '${VM_NAME}' virtual machine to boot ($_retries retries left)..." sleep 5 (( _retries = _retries - 1 )) else break fi done -[[ -n $_ip ]] && echo "'${NAME}' virtual machine is online at $_ip" -[[ -z $_ip ]] && echo "'${NAME}' virtual machine did not boot on time" && exit 1 +[[ -n $_ip ]] && echo "'${VM_NAME}' virtual machine is online at $_ip" +[[ -z $_ip ]] && echo "'${VM_NAME}' virtual machine did not boot on time" && exit 1 # Fix up perms if needed to make ssh happy chmod 600 ${BASE_PATH}/xci/scripts/vm/id_rsa_for_dib* # Remove it from known_hosts ssh-keygen -R $_ip || true -ssh-keygen -R ${NAME} || true +ssh-keygen -R ${VM_NAME} || true declare -r vm_ssh="ssh -o StrictHostKeyChecking=no -i ${BASE_PATH}/xci/scripts/vm/id_rsa_for_dib -l devuser" @@ -131,13 +175,13 @@ while [[ $_retries -ne 0 ]]; do (( _retries = _retries - 1 )) fi done -[[ $_ssh_exit != 0 ]] && echo "Failed to SSH to the virtual machine '${NAME}'! This should never happen!" && exit 1 +[[ $_ssh_exit != 0 ]] && echo "Failed to SSH to the virtual machine '${VM_NAME}'! This should never happen!" && exit 1 -echo "Congratulations! Your shiny new '${NAME}' virtual machine is fully operational! Enjoy!" +echo "Congratulations! Your shiny new '${VM_NAME}' virtual machine is fully operational! Enjoy!" -echo "Adding ${NAME}_xci_vm entry to /etc/hosts" -sudo sed -i "/.*${NAME}.*/d" /etc/hosts -sudo bash -c "echo '${_ip} ${NAME}' >> /etc/hosts" +echo "Adding ${VM_NAME}_xci_vm entry to /etc/hosts" +sudo sed -i "/.*${VM_NAME}.*/d" /etc/hosts +sudo bash -c "echo '${_ip} ${VM_NAME}' >> /etc/hosts" echo "Dropping a minimal .ssh/config file" cat > $HOME/.ssh/config< /etc/resolv.conf"' $vm_ssh $_ip 'sudo bash -c "echo nameserver 8.8.4.4 >> /etc/resolv.conf"' cat > ${BASE_PATH}/vm_hosts.txt <