Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Libvirt e2e CI for pull requests #1318

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .github/workflows/caa_build_and_push.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: (Callable) Build and push cloud-api-adaptor image

on:
workflow_call:
inputs:
registry:
default: 'quay.io/confidential-containers'
description: 'Image registry (e.g. "ghcr.io/confidential-containers") where the built image will be pushed to'
required: false
type: string
dev_arches:
default: 'linux/amd64'
description: 'Dev build arches. Expected a docker buildx "--platform" string format'
required: false
type: string
dev_tags:
default: ''
description: 'Comma-separated list of tags for the dev built image (e.g. latest,ci-dev). By default uses the values from hack/build.sh'
required: false
type: string
release_arches:
default: 'linux/amd64,linux/s390x,linux/ppc64le'
description: 'Release build arches. Expected a docker buildx "--platform" string format'
required: false
type: string
release_tags:
default: ''
description: 'Likewise but for the release built image'
required: false
type: string

env:
GO_VERSION: "1.20.6"

jobs:
build_push_job:
name: build and push
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- type: dev
arches: ${{ inputs.dev_arches }}
- type: release
arches: ${{ inputs.release_arches }}
steps:
- name: Checkout the code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Golang version ${{ env.GO_VERSION }}
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Install build dependencies
if: matrix.type == 'dev'
run: |
sudo apt-get update -y
sudo apt-get install -y libvirt-dev
- name: Login to quay Container Registry
if: ${{ startsWith(inputs.registry, 'quay.io') }}
uses: docker/login-action@v2
with:
registry: ${{ inputs.registry }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}

- name: Login to Github Container Registry
if: ${{ startsWith(inputs.registry, 'ghcr.io') }}
uses: docker/login-action@v2
with:
registry: ${{ inputs.registry }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push image
uses: nick-fields/retry@v2
with:
# We are not interested in timeout but this field is required
# so setting to 4x the time it usually take to complete.
timeout_minutes: 60
retry_wait_seconds: 120
max_attempts: 3
command: |
if [ ${{ matrix.type }} == "release" ]; then
ARCHES=${{matrix.arches}} RELEASE_BUILD=true RELEASE_TAGS=${{ inputs.release_tags}} make image registry=${{ inputs.registry }}
else
ARCHES=${{matrix.arches}} RELEASE_BUILD=false DEV_TAGS=${{ inputs.dev_tags }} make image registry=${{ inputs.registry }}
fi
188 changes: 188 additions & 0 deletions .github/workflows/e2e_libvirt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# (C) Copyright Confidential Containers Contributors 2023.
# SPDX-License-Identifier: Apache-2.0
#
# Run libvirt e2e tests.
name: (Callable) libvirt e2e tests

on:
workflow_call:
inputs:
qcow2_artifact:
required: true
type: string
install_directory_artifact:
description: The archive name of the install directory
default: ''
required: false
type: string

env:
CLOUD_PROVIDER: libvirt
GO_VERSION: "1.20.7"
DEBIAN_FRONTEND: noninteractive

jobs:
test:
runs-on: az-ubuntu-2204
steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Setup Golang version ${{ env.GO_VERSION }}
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}

- uses: actions/download-artifact@v3
with:
name: ${{ inputs.qcow2_artifact }}
path: podvm

- name: Get the install directory
if: ${{ inputs.install_directory_artifact != '' }}
uses: actions/download-artifact@v3
with:
name: ${{ inputs.install_directory_artifact }}
path: install

- name: Install Libvirt
run: |
set -o pipefail
echo "::group::Install packages"
sudo apt-get update
sudo apt-get install -y qemu-kvm libvirt-daemon-system libvirt-dev
stevenhorsman marked this conversation as resolved.
Show resolved Hide resolved
echo "::endgroup::"
kvm-ok
# Create the default storage pool if not defined.
echo "::group::Setup Libvirt default storage pool"
if ! sudo virsh pool-list --all | grep default >/dev/null; then
sudo virsh pool-define-as default dir - - - - "/var/lib/libvirt/images"
sudo virsh pool-build default
fi
sudo virsh pool-start default || true
echo "::endgroup::"

sudo setfacl -m "u:${USER}:rwx" /var/lib/libvirt/images
sudo adduser "$USER" libvirt
# Although it adds the runner user to libvirt's group, it is getting
# hard to re-load the actual session so that it takes effect. As
# an alternative, let's set the permission on the libvirt's socket
# file directly.
sudo setfacl -m "u:${USER}:rwx" /var/run/libvirt/libvirt-sock

- name: Install kcli
run: |
echo "::group::Install dependencies"
sudo apt-get install -y genisoimage
echo "::endgroup::"

echo "::group::Install kcli"
curl https://raw.githubusercontent.com/karmab/kcli/main/install.sh | sudo bash
echo "::endgroup::"

# kcli needs a pair of keys to setup the VMs
[ -f ~/.ssh/id_rsa ] || \
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ""

# Newest version of kcli does not index old Ubuntu images like 20.04
echo "::group::Download Ubuntu 20.04 image"
kcli download image -u https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img ubuntu2004
echo "::endgroup::"

# This is the key used by cloud-api-adaptor to connect to libvirt
- name: Generate the SSH key
run: |
ssh-keygen -f ./id_rsa -N ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wainersm Shouldn't this be a required step for Install kcli rather than handling ssh-keygen there as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @ldoktor , I'm glad to see you here :)

This key is used by cloud-api-adaptor to connect to the Libvirt on host. It could be the same key as used by the kcli to install the cluster, but I prefer to keep them two separated keys.

mkdir -p ~/.ssh
cat id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
working-directory: install/overlays/libvirt

- name: Verify the connection with Libvirt
id: verify_libvirt_connection
run: |
IP="$(hostname -I | cut -d' ' -f1)"
echo "ip=${IP}" >> "$GITHUB_OUTPUT"

virsh -c "qemu+ssh://$USER@${IP}/system?keyfile=$(pwd)/id_rsa&no_verify=1" nodeinfo
working-directory: install/overlays/libvirt

- name: Create the e2e properties file
run: |
IP=${{ steps.verify_libvirt_connection.outputs.ip }}
[[ -n "$IP" ]] || exit 1
echo "libvirt_uri=\"qemu+ssh://$USER@${IP}/system?no_verify=1\"" >> libvirt.properties
echo "libvirt_ssh_key_file=\"id_rsa\"" >> libvirt.properties
# For debugging
cat libvirt.properties

- name: Install tests dependencies
run: |
K8S_VERSION="v1.27.1"
KUSTOMIZE_VERSION="3.8.7"

if ! command -v kubectl >/dev/null; then
sudo curl "https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl" \
-o /usr/local/bin/kubectl
sudo chmod +x /usr/local/bin/kubectl
fi

if ! command -v kustomize >/dev/null; then
curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | \
sudo bash -s -- "${KUSTOMIZE_VERSION}" /usr/local/bin
sudo chmod +x /usr/local/bin/kustomize
fi

sudo apt-get install -y build-essential

- name: run tests
id: runTests
run: |
export TEST_PROVISION="yes"
export TEST_TEARDOWN="no"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might come to it in a later commit, but is Teardown no so we can get debug info and the test runner node should be cleaned up anyway at the end of the workflow?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly Steve!

export TEST_PROVISION_FILE="$PWD/libvirt.properties"
export TEST_PODVM_IMAGE="${PWD}/podvm/${{ inputs.qcow2_artifact }}"
export TEST_E2E_TIMEOUT="50m"

make test-e2e

- name: Debug tests failure
if: failure() && steps.runTests.outcome == 'failure'
run: |
export KUBECONFIG="${HOME}/.kcli/clusters/peer-pods/auth/kubeconfig"

echo "::group::CoCo and Peer Pods installation"
kubectl get pods -n confidential-containers-system
echo "::endgroup::"

echo "::group::cloud-api-adaptor logs"
kubectl logs -l app=cloud-api-adaptor -n confidential-containers-system
echo "::endgroup::"

for pod in $(kubectl get pods -o name 2>/dev/null); do
echo "::group::Describe $pod"
kubectl describe "$pod"
echo "::endgroup::"
done

echo "::group::Libvirt domains"
sudo virsh list
echo "::endgroup::"

for podvm in $(sudo virsh list --name | grep "podvm-"); do
echo "::group::podvm $podvm"
sudo virsh dominfo "$podvm"
sudo virsh domifaddr "$podvm"
echo "::endgroup::"
done

echo "::group::podvm base volume"
sudo virsh vol-info --pool default podvm-base.qcow2
ls -lh /var/lib/libvirt/images/podvm-base.qcow2
echo "::endgroup::"

echo "::group::Check podvm base volume integrity"
sudo qemu-img check /var/lib/libvirt/images/podvm-base.qcow2
echo "::endgroup::"
# Avoid running with `set -e` as command fails should be allowed
shell: bash {0}
Loading