From: Ionut Balutoiu Date: Thu, 18 Nov 2021 14:30:28 +0000 (+0200) Subject: [wnbd-build] Add Jenkins job to build the wnbd project X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3949748980f2bc8b3c77dee9f7080d1b13a4ebf2;p=ceph-build.git [wnbd-build] Add Jenkins job to build the wnbd project * Add the Jenkins job used to build the `wnbd` project. * Add the following utils functions: `ssh_exec`, `scp_upload`, `scp_download`. * Add `./scripts/ceph-windows/cleanup` script that can be used as a post-build step to clean up the Windows test / build environment. * Add `./scripts/ceph-windows/setup_libvirt_vm` script used to spawn a libvirt VM with the Windows test / build environment. * Upload the build artifact to chacra. --- diff --git a/scripts/build_utils.sh b/scripts/build_utils.sh index 6ba86d29..74a58618 100644 --- a/scripts/build_utils.sh +++ b/scripts/build_utils.sh @@ -1621,3 +1621,55 @@ function cleanup_windows_tests_env() { $WORKSPACE/ceph.zip $WORKSPACE/known_hosts \ /etc/ceph /var/log/ceph /var/lib/ceph /var/run/ceph } + +function ssh_exec() { + if [[ -z $SSH_ADDRESS ]]; then + echo "ERROR: Env variable SSH_ADDRESS is not set" + exit 1 + fi + if [[ -z $SSH_USER ]]; then + echo "ERROR: Env variable SSH_USER is not set" + exit 1 + fi + local SSH_OPTS="" + if [[ ! -z $SSH_KNOWN_HOSTS_FILE ]]; then + SSH_OPTS="$SSH_OPTS -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE" + fi + timeout ${SSH_TIMEOUT:-"30s"} ssh -i ${SSH_KEY:-"$HOME/.ssh/id_rsa"} $SSH_OPTS ${SSH_USER}@${SSH_ADDRESS} ${@} +} + +function scp_upload() { + local LOCAL_FILE="$1" + local REMOTE_FILE="$2" + if [[ -z $SSH_ADDRESS ]]; then + echo "ERROR: Env variable SSH_ADDRESS is not set" + exit 1 + fi + if [[ -z $SSH_USER ]]; then + echo "ERROR: Env variable SSH_USER is not set" + exit 1 + fi + local SSH_OPTS="" + if [[ ! -z $SSH_KNOWN_HOSTS_FILE ]]; then + SSH_OPTS="$SSH_OPTS -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE" + fi + timeout ${SSH_TIMEOUT:-"30s"} scp -i ${SSH_KEY:-"$HOME/.ssh/id_rsa"} $SSH_OPTS -r $LOCAL_FILE ${SSH_USER}@${SSH_ADDRESS}:${REMOTE_FILE} +} + +function scp_download() { + local REMOTE_FILE="$1" + local LOCAL_FILE="$2" + if [[ -z $SSH_ADDRESS ]]; then + echo "ERROR: Env variable SSH_ADDRESS is not set" + exit 1 + fi + if [[ -z $SSH_USER ]]; then + echo "ERROR: Env variable SSH_USER is not set" + exit 1 + fi + local SSH_OPTS="" + if [[ ! -z $SSH_KNOWN_HOSTS_FILE ]]; then + SSH_OPTS="$SSH_OPTS -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE" + fi + timeout ${SSH_TIMEOUT:-"30s"} scp -i ${SSH_KEY:-"$HOME/.ssh/id_rsa"} $SSH_OPTS -r ${SSH_USER}@${SSH_ADDRESS}:${REMOTE_FILE} $LOCAL_FILE +} diff --git a/scripts/ceph-windows/cleanup b/scripts/ceph-windows/cleanup new file mode 100644 index 00000000..9ef882f6 --- /dev/null +++ b/scripts/ceph-windows/cleanup @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + + +# Cleanup libvirt VMs / networks +delete_libvirt_vms +clear_libvirt_networks + +# Cleanup Ceph clusters spawned via cephadm +if [[ -x $WORKSPACE/cephadm ]] && [[ -d /var/lib/ceph ]]; then + for FSID in $(sudo ls /var/lib/ceph); do + echo "Removing Ceph cluster $FSID" + sudo $WORKSPACE/cephadm rm-cluster --fsid $FSID --force + done +fi + +# Cleanup remaning files / directories +sudo rm -rf \ + $WORKSPACE/ceph.conf $WORKSPACE/keyring $WORKSPACE/cephadm \ + $WORKSPACE/ceph.zip $WORKSPACE/known_hosts \ + /etc/ceph /var/log/ceph /var/lib/ceph /var/run/ceph diff --git a/scripts/ceph-windows/setup_libvirt_vm b/scripts/ceph-windows/setup_libvirt_vm new file mode 100644 index 00000000..d094b7bc --- /dev/null +++ b/scripts/ceph-windows/setup_libvirt_vm @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + +if [[ -z $CEPH_WIN_CI_KEY ]]; then + echo "ERROR: The CI SSH private key secret (CEPH_WIN_CI_KEY) is not set" + exit 1 +fi + +export VM_IMAGE_URL=${VM_IMAGE_URL:-"https://filedump.ceph.com/windows/ceph-win-ltsc2019-ci-image.qcow2"} +export VM_NAME=${VM_NAME:-"ceph-win-ltsc2019-${JOB_NAME}-${BUILD_ID}"} + +export SSH_USER="administrator" +export SSH_KNOWN_HOSTS_FILE="$WORKSPACE/known_hosts" +export SSH_KEY="$CEPH_WIN_CI_KEY" + + +# +# Install requirements (if needed) +# +if ! which virt-install >/dev/null; then + sudo apt-get update + sudo apt-get install -y virtinst +fi +if ! sudo virsh net-info default &>/dev/null; then + cat << EOF > $WORKSPACE/default-net.xml + + default + + + + + + + + +EOF + sudo virsh net-define $WORKSPACE/default-net.xml + sudo virsh net-start default + sudo virsh net-autostart default + rm $WORKSPACE/default-net.xml +fi + +# +# Download the Windows qcow2 image +# +IMAGE_FILE="$(basename $VM_IMAGE_URL)" +echo "Downloading VM image from $VM_IMAGE_URL" +curl -L -o ${WORKSPACE}/${IMAGE_FILE} $VM_IMAGE_URL + +# +# Start the Windows testing VM +# +sudo virt-install \ + --name $VM_NAME \ + --os-variant win2k19 \ + --boot hd \ + --virt-type kvm \ + --graphics spice \ + --cpu host \ + --vcpus 4 \ + --memory 4096 \ + --disk ${WORKSPACE}/${IMAGE_FILE},bus=virtio \ + --network network=default,model=virtio \ + --controller type=virtio-serial \ + --channel unix,target_type=virtio,name=org.qemu.guest_agent.0 \ + --noautoconsol + +# +# Wait until the QEMU agent reports the VM IP, and it's reachable via SSH +# +SECONDS=0 +TIMEOUT=600 +SLEEP_SECS=10 +while true; do + if [[ $SECONDS -gt $TIMEOUT ]]; then + echo "Timeout waiting for the VM to start" + exit 1 + fi + VM_IP=$(sudo virsh domifaddr --source agent --interface Ethernet --full $VM_NAME | grep ipv4 | awk '{print $4}' | cut -d '/' -f1) || { + echo "Retrying in $SLEEP_SECS seconds" + sleep $SLEEP_SECS + continue + } + ssh-keyscan -H $VM_IP &> ${WORKSPACE}/known_hosts || { + echo "SSH is not reachable yet" + sleep $SLEEP_SECS + continue + } + SSH_ADDRESS=$VM_IP ssh_exec hostname || { + echo "Cannot execute SSH commands yet" + sleep $SLEEP_SECS + continue + } + break +done +export SSH_ADDRESS=$VM_IP diff --git a/wnbd-build/build/build b/wnbd-build/build/build new file mode 100644 index 00000000..4857db06 --- /dev/null +++ b/wnbd-build/build/build @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + +BUILD_CONFIGURATION=${BUILD_CONFIGURATION:-"Release"} + + +# +# Install requirements (if needed) +# +if ! which zip >/dev/null; then + sudo apt-get update + sudo apt-get install -y zip +fi + +# +# Upload wnbd repo to the Windows VM +# +scp_upload $WORKSPACE/wnbd /workspace/wnbd + +# +# Build the Visual Studio project +# +BUILD_CMD="MSBuild.exe %SystemDrive%\\workspace\\wnbd\\vstudio\\wnbd.sln /p:Configuration=${BUILD_CONFIGURATION}" +SSH_TIMEOUT=30m ssh_exec "\"%ProgramFiles(x86)%\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x86_amd64 & ${BUILD_CMD}" + +# +# Install the driver in the testing Windows VM +# +ssh_exec powershell.exe "Import-Certificate -FilePath /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd.cer -Cert Cert:\LocalMachine\Root" +ssh_exec powershell.exe "Import-Certificate -FilePath /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd.cer -Cert Cert:\LocalMachine\TrustedPublisher" +ssh_exec /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd-client.exe uninstall-driver +ssh_exec /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd-client.exe install-driver /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/driver/wnbd.inf + +# +# Download the build artifacts +# +mkdir -p $WORKSPACE/build/wnbd/driver +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/driver/* $WORKSPACE/build/wnbd/driver/ +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd.cer $WORKSPACE/build/wnbd/driver/ + +mkdir -p $WORKSPACE/build/wnbd/binaries +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/libwnbd.dll $WORKSPACE/build/wnbd/binaries/ +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd-client.exe $WORKSPACE/build/wnbd/binaries/ +scp_download /workspace/wnbd/vstudio/wnbdevents.xml /$WORKSPACE/build/wnbd/binaries/ + +mkdir -p $WORKSPACE/build/wnbd/symbols +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/pdb/driver/* $WORKSPACE/build/wnbd/symbols/ +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/pdb/libwnbd/* $WORKSPACE/build/wnbd/symbols/ +scp_download /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/pdb/wnbd-client/* $WORKSPACE/build/wnbd/symbols/ + +# +# Package the build artifacts into a zip file +# +cd $WORKSPACE/build +zip -r $WORKSPACE/wnbd.zip wnbd + +# +# Upload the the zip file to Chacra +# +if [ "$THROWAWAY" = false ]; then + # push binaries to chacra + chacra_binary="$VENV/chacractl binary" + [ "$FORCE" = true ] && chacra_binary="$chacra_binary --force" + + ls $WORKSPACE/wnbd.zip | $chacra_binary create ${chacra_binary_endpoint} + + vers=$(ssh_exec /workspace/wnbd/vstudio/x64/${BUILD_CONFIGURATION}/wnbd-client.exe -v | grep wnbd-client.exe | cut -d ':' -f2 | tr -d '[:space:]') + + # write json file with build info + cat > $WORKSPACE/repo-extra.json << EOF +{ + "version":"$vers", + "package_manager_version":"", + "build_url":"$BUILD_URL", + "root_build_cause":"$ROOT_BUILD_CAUSE", + "node_name":"$NODE_NAME", + "job_name":"$JOB_NAME" +} +EOF + # post the json to repo-extra json to chacra + curl --fail -X POST -H "Content-Type:application/json" --data "@$WORKSPACE/repo-extra.json" -u $CHACRACTL_USER:$CHACRACTL_KEY ${chacra_url}repos/${chacra_repo_endpoint}/extra/ + # start repo creation + $VENV/chacractl repo update ${chacra_repo_endpoint} + + echo "Check the status of the repo at: https://shaman.ceph.com/api/repos/${chacra_repo_endpoint}/" +fi + +# update shaman with the completed build status +update_build_status "completed" "wnbd" $DISTRO $DISTRO_VERSION $ARCH diff --git a/wnbd-build/build/failure b/wnbd-build/build/failure new file mode 100644 index 00000000..344d10dd --- /dev/null +++ b/wnbd-build/build/failure @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + +FLAVOR="default" + +BRANCH=`branch_slash_filter $BRANCH` + +# update shaman with the failed build status +failed_build_status "wnbd" $NORMAL_DISTRO $NORMAL_DISTRO_VERSION $NORMAL_ARCH diff --git a/wnbd-build/build/setup b/wnbd-build/build/setup new file mode 100644 index 00000000..529eaeca --- /dev/null +++ b/wnbd-build/build/setup @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -o errexit +set -o pipefail + +DISTRO="windows" +DISTRO_VERSION="1809" +ARCH="x86_64" +FLAVOR="default" + +BRANCH=`branch_slash_filter $BRANCH` +SHA1="$GIT_COMMIT" + +pkgs=( "chacractl>=0.0.21" ) +TEMPVENV=$(create_venv_dir) +VENV=${TEMPVENV}/bin +install_python_packages $TEMPVENV "pkgs[@]" + +# ask shaman which chacra instance to use +chacra_url=`curl -u $SHAMAN_API_USER:$SHAMAN_API_KEY https://shaman.ceph.com/api/nodes/next/` +# create the .chacractl config file using global variables +make_chacractl_config $chacra_url + +chacra_endpoint="wnbd/${BRANCH}/${SHA1}/${DISTRO}/${DISTRO_VERSION}" +chacra_binary_endpoint="${chacra_endpoint}/${ARCH}/flavors/${FLAVOR}" +chacra_repo_endpoint="${chacra_endpoint}/flavors/${FLAVOR}" +chacra_check_url="${chacra_binary_endpoint}/wnbd.zip" + +if [ "$THROWAWAY" = false ] ; then + # this exists in scripts/build_utils.sh + check_binary_existence $VENV $chacra_check_url +fi + +# create build status in shaman +update_build_status "started" "wnbd" $DISTRO $DISTRO_VERSION $ARCH diff --git a/wnbd-build/config/definitions/wnbd-build.yml b/wnbd-build/config/definitions/wnbd-build.yml new file mode 100644 index 00000000..31f3d4ad --- /dev/null +++ b/wnbd-build/config/definitions/wnbd-build.yml @@ -0,0 +1,95 @@ +- job: + name: wnbd-build + description: 'Builds the Windows Network Block Device (WNBD) project.' + node: amd64 && focal && libvirt + project-type: freestyle + defaults: global + concurrent: true + display-name: 'wnbd-build' + properties: + - build-discarder: + days-to-keep: 30 + num-to-keep: 30 + artifact-days-to-keep: 30 + artifact-num-to-keep: 30 + + parameters: + - string: + name: BRANCH + description: "The git branch (or tag) to build" + default: "master" + + - bool: + name: THROWAWAY + description: | + Default: False. When True it will not POST binaries to chacra. Artifacts will not be around for long. Useful to test builds. + default: false + + - bool: + name: FORCE + description: | + If this is unchecked, then nothing is built or pushed if they already exist in chacra. This is the default. + + If this is checked, then the binaries will be built and pushed to chacra even if they already exist in chacra. + + scm: + - git: + url: https://github.com/ceph/wnbd.git + branches: + - $BRANCH + timeout: 20 + wipe-workspace: true + basedir: wnbd + + builders: + - shell: + !include-raw: + - ../../../scripts/build_utils.sh + - ../../build/setup + - ../../../scripts/ceph-windows/setup_libvirt_vm + - ../../build/build + + wrappers: + - inject-passwords: + global: true + mask-password-params: true + - credentials-binding: + - file: + credential-id: ceph_win_ci_private_key + variable: CEPH_WIN_CI_KEY + - text: + credential-id: chacractl-key + variable: CHACRACTL_KEY + - text: + credential-id: shaman-api-key + variable: SHAMAN_API_KEY + + publishers: + - postbuildscript: + builders: + - role: SLAVE + build-on: + - SUCCESS + - UNSTABLE + - FAILURE + - ABORTED + build-steps: + - shell: + !include-raw: + - ../../../scripts/build_utils.sh + - ../../../scripts/ceph-windows/cleanup + + - postbuildscript: + builders: + - role: SLAVE + build-on: + - FAILURE + - ABORTED + build-steps: + - inject: + properties-file: ${WORKSPACE}/build_info + + - shell: + !include-raw: + - ../../../scripts/build_utils.sh + - ../../build/failure