diff options
author | Markos Chandras <mchandras@suse.de> | 2017-09-28 16:03:01 +0100 |
---|---|---|
committer | Markos Chandras <mchandras@suse.de> | 2017-10-02 16:18:36 +0100 |
commit | c51505dc0485b1434c73cdea2b3f98a568fb9110 (patch) | |
tree | 891e531177c7cdcd22f2f8620439d06f71caac96 | |
parent | 869ae6cb904098b53da9bba010b1a9c95749c05d (diff) |
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 <mchandras@suse.de>
-rwxr-xr-x | xci/scripts/vm/build-dib-os.sh | 65 | ||||
-rwxr-xr-x | xci/scripts/vm/start-new-vm.sh | 124 |
2 files changed, 85 insertions, 104 deletions
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 <<EOF <network> <name>${NETWORK}</name> @@ -82,38 +125,39 @@ if ! sudo virsh net-list --name | grep -q ${NETWORK}; then </network> 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<<EOF @@ -157,24 +201,26 @@ EOF echo "Preparing test environment..." # *_xci_vm hostname is invalid. Letst just use distro name -$vm_ssh $_ip "sudo hostname ${NAME/_xci*}" +$vm_ssh $_ip "sudo hostname ${VM_NAME/_xci*}" # Start with good dns $vm_ssh $_ip 'sudo bash -c "echo nameserver 8.8.8.8 > /etc/resolv.conf"' $vm_ssh $_ip 'sudo bash -c "echo nameserver 8.8.4.4 >> /etc/resolv.conf"' cat > ${BASE_PATH}/vm_hosts.txt <<EOF -127.0.0.1 localhost ${NAME/_xci*} +127.0.0.1 localhost ${VM_NAME/_xci*} ::1 localhost ipv6-localhost ipv6-loopback fe00::0 ipv6-localnet fe00::1 ipv6-allnodes fe00::2 ipv6-allrouters ff00::3 ipv6-allhosts -$_ip ${NAME/_xci*} +$_ip ${VM_NAME/_xci*} EOF # Need to copy releng-xci to the vm so we can execute stuff do_copy() { rsync -a \ - --exclude "${NAME}*" \ + --exclude "${VM_NAME}*" \ + --exclude "${OS}*" \ + --exclude "$dib_workdir*" \ --exclude "build.log" \ -e "$vm_ssh" ${BASE_PATH}/* $_ip:~/releng-xci/ } |