* 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.
$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
+}
--- /dev/null
+#!/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
--- /dev/null
+#!/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
+<network>
+ <name>default</name>
+ <bridge name="virbr0"/>
+ <forward mode="nat"/>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254"/>
+ </dhcp>
+ </ip>
+</network>
+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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+- 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