github: don't run CI tests job twice #272
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Tests | |
on: | |
push: | |
branches: | |
- main | |
pull_request: | |
permissions: | |
contents: read | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
static-analysis: | |
name: Static analysis | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install dependencies | |
run: | | |
set -x | |
sudo apt-get update | |
sudo apt-get install --no-install-recommends tox | |
- name: Run static analysis | |
run: tox -vve static | |
- name: Run linters | |
run: tox -vve lint | |
integration-tests: | |
name: Juju tests | |
runs-on: ubuntu-24.04 | |
needs: | |
- static-analysis | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install dependencies | |
run: | | |
set -x | |
sudo apt-get autopurge -y containerd.io docker-ce podman uidmap | |
sudo ip link delete docker0 | |
sudo nft flush ruleset | |
sudo snap install lxd --channel=latest/edge | |
sudo snap set lxd daemon.group=adm | |
sudo lxd waitready | |
sudo lxd init --auto --storage-backend=zfs --storage-create-loop=10 | |
sudo snap install charmcraft --classic | |
sudo snap install juju | |
snap list --all | |
- name: Build charms | |
run: | | |
set -eux | |
# Charms are normally built without binary deps but that is slow as pyca/cryptography (rust) takes a long time to build. | |
# Not depending on binaries is a good thing for arches lacking some wheels but in CI, we only care about amd64 which has | |
# all the needed wheels. As such, tweak the charmcraft.yaml to include the requirements as binary packages and skip the | |
# lengthy compilations. The official build happening on Launchpad will use the proper/unmangled charmcraft.yaml files. | |
./.github/scripts/charmcraft-tweak.py . "cargo,libffi-dev,libssl-dev,pkg-config,python3-dev,rustc" | |
./.github/scripts/charmcraft-tweak.py examples/https-client/ "cargo,libffi-dev,libssl-dev,pkg-config,python3-dev,rustc" | |
charmcraft pack -v | |
echo "==> ancillary charm for testing purposes" | |
charmcraft pack -v --project-dir examples/https-client | |
echo "==> cleanup project to reclaim space" | |
lxc list --project charmcraft -c n -f csv | xargs --no-run-if-empty lxc delete --project charmcraft | |
- name: Upload charms | |
uses: actions/upload-artifact@v4 | |
with: | |
name: charms | |
path: ./*.charm | |
- name: Bootstrap Juju | |
run: | | |
set -eux | |
lxc network set lxdbr0 ipv6.address=none | |
juju bootstrap lxd local | |
- name: Exercice lxd-https relation | |
run: | | |
set -eux | |
STEP_NAME="lxd-https relation" | |
echo "# === $STEP_NAME starts === #" >> juju-debug.log | |
# Valid statuses list: https://juju.is/docs/juju/status | |
juju_wait() { | |
# XXX: wait-for may timeout while things are usable so continue on error | |
juju wait-for model ci-testing --query='life=="alive" && status=="available" && len(applications) > 0 && forEach(applications, app => app.status == "active") && len(units) > 0 && forEach(units, unit => unit.workload-status == "active" && unit.agent-status == "idle")' || true | |
} | |
# capture juju's logs on error | |
debug() { | |
rc="$?" | |
set +e | |
juju debug-log --replay --level debug >> juju-debug.log | |
echo "# === $STEP_NAME ends === #" >> juju-debug.log | |
juju status --relations >> juju-debug.log | |
exit "$rc" | |
} | |
trap debug err exit | |
juju add-model ci-testing | |
juju model-config logging-config="<root>=WARNING;unit=DEBUG" | |
echo "==> Test 20.04 charm in standalone mode" | |
juju deploy ./lxd_ubuntu-20.04-amd64.charm --num-units 1 --config lxd-listen-https=true --config snap-channel="5.0/stable" | |
juju deploy ./https-client_ubuntu-22.04-amd64.charm | |
juju relate https-client lxd | |
juju_wait | |
juju status --relations | |
echo "==> list trusted client certs" | |
juju exec --unit lxd/leader -- lxc config trust list --format csv | |
echo "==> confirm lxd now trusts the client cert" | |
juju exec --unit lxd/leader -- lxc config trust list --format csv | grep -E ",juju-relation-https-client/[0-9]+," | |
echo "==> break the relationship to have the client cert removed" | |
juju remove-relation https-client lxd | |
juju_wait | |
echo "==> check that the client cert was not left behind" | |
! juju exec --unit lxd/leader -- lxc config trust list --format csv | grep -E ",juju-relation-https-client/[0-9]+," || false | |
echo "==> set the projects config and re-establish the relation" | |
juju config https-client projects="default" | |
juju relate https-client lxd | |
juju_wait | |
echo "==> check that the client cert is now restricted" | |
FINGERPRINT="$(juju exec --unit lxd/leader -- lxc config trust list --format csv | awk -F, '/,juju-relation-https-client/ {print $4}')" | |
juju exec --unit lxd/leader -- lxc config trust show "$FINGERPRINT" | |
juju exec --unit lxd/leader -- lxc config trust show "$FINGERPRINT" | grep -xF 'restricted: true' | |
echo "==> removing the https-client application will break the relation causing the removal of the cert" | |
juju remove-application --no-prompt https-client | |
juju_wait | |
! juju exec --unit lxd/leader -- lxc config trust list --format csv | grep -E ",juju-relation-https-client/[0-9]+," || false | |
juju status --relations | |
- name: Test opening/closing ports | |
run: | | |
set -eux | |
echo "==> open the dns, bgp and metrics ports" | |
juju config lxd lxd-listen-dns=true lxd-listen-bgp=true lxd-listen-metrics=true | |
juju wait-for application lxd --query='status=="active"' | |
juju status | |
echo "==> check that the dns, bgp, https and metrics ports are opened" | |
OPENED_PORTS="$(juju exec --unit lxd/leader "opened-ports" | grep -cE '^(53|179|8443|9100)/tcp$')" | |
[ "$OPENED_PORTS" -eq 4 ] | |
echo "==> close the dns, bgp and metrics ports" | |
juju config lxd lxd-listen-dns=false lxd-listen-bgp=false lxd-listen-metrics=false | |
juju wait-for application lxd --query='status=="active"' | |
juju status | |
echo "==> check that only the https port remains opened" | |
HTTPS_PORT="$(juju exec --unit lxd/leader "opened-ports" | grep -E '^[0-9]+/tcp$')" | |
[ "$HTTPS_PORT" = "8443/tcp" ] | |
- name: Scale the number of lxd units | |
run: | | |
set -eux | |
echo "==> Add a LXD unit" | |
juju add-unit lxd | |
juju wait-for application lxd --query='status=="active"' | |
juju status | |
- name: Test add-trusted-client/remove-trusted-client actions | |
run: | | |
set -eux | |
CERT_NAME="trusted-client-$$" | |
echo "==> Generate local cert/key" | |
rm -rf ~/snap/lxd/common/config/ | |
lxc remote add localhost --accept-certificate --password=abc 2>/dev/null || true | |
echo "==> Add trusted client cert" | |
juju run --wait=2m lxd/leader add-trusted-client name="$CERT_NAME" cert="$(cat ~/snap/lxd/common/config/client.crt)" | grep -F 'result: The client certificate is now trusted' | |
echo "==> Confirm the user's cert was added to the trusted list" | |
juju exec --unit lxd/leader -- lxc config trust list -f csv | grep "^client,${CERT_NAME}," | |
echo "==> Remove trusted client cert" | |
juju run --wait=2m lxd/leader remove-trusted-client fingerprint="$(openssl x509 -noout -fingerprint -sha256 -in ~/snap/lxd/common/config/client.crt)" | grep -F 'result: The client certificate is no longer trusted' | |
echo "==> Confirm the user's cert was removed from the trusted list" | |
! juju exec --unit lxd/leader -- lxc config trust list -f csv | grep "^client,${CERT_NAME}," || false | |
- name: Cleanup standalone lxd units | |
run: | | |
set -eux | |
juju remove-application --no-prompt --force lxd | |
sleep 10 | |
juju status | |
- name: Cluster tests | |
run: | | |
set -eux | |
STEP_NAME="cluster tests" | |
echo "# === $STEP_NAME starts === #" >> juju-debug.log | |
# capture juju's logs on error | |
debug() { | |
rc="$?" | |
set +e | |
juju debug-log --replay --level debug >> juju-debug.log | |
echo "# === $STEP_NAME ends === #" >> juju-debug.log | |
juju status --relations >> juju-debug.log | |
exit "$rc" | |
} | |
trap debug err exit | |
echo "==> Test 22.04 charm in cluster mode" | |
NODE_CREATED="3" | |
juju deploy ./lxd_ubuntu-22.04-amd64.charm --num-units "$NODE_CREATED" --config mode=cluster --config lxd-listen-https=true | |
juju wait-for application lxd --query='life=="alive" && status=="available" && forEach(units, unit => unit.life=="alive")' || true # wait for leader-election | |
juju status --relations | |
echo "==> Check that all members are online and fully operational" | |
NODE_JOINED="$(juju exec --unit lxd/leader -- lxc cluster list --format csv | grep -cF ',ONLINE,Fully operational')" | |
[ "$NODE_JOINED" -eq "$NODE_CREATED" ] | |
- name: Test get-client-token action | |
run: | | |
set -eux | |
CERT_NAME="get-client-token-$$" | |
REMOTE_NAME="rmt-$$" | |
echo "==> Obtain a client-token" | |
token="$(juju run --wait=2m lxd/leader get-client-token name="$CERT_NAME" | sed -n '/^\s\+Client [^ ]\+ certificate add token:$/,+1 p' | sed '/^\s\+Client /d; s/^\s\+//')" | |
lxc remote add "$REMOTE_NAME" "$token" | |
echo "==> Test the newly added remote" | |
lxc config show "$REMOTE_NAME": | |
echo "==> Confirm the user's cert was added to the trusted list" | |
juju exec --unit lxd/leader -- lxc config trust list -f csv | grep "^client,${CERT_NAME}," | |
- name: Check for errors | |
run: | | |
set -eux | |
if juju status --format=oneline | grep -qF workload:error; then | |
echo "Juju failed to deploy" | |
juju status --format=oneline | |
exit 1 | |
fi | |
- name: Juju debug-log | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: juju-debug-logs ${{ github.job }} | |
path: juju-debug.log | |
retention-days: 5 |