diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 4a7ae3a..da4ea39 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -1,11 +1,16 @@ -name: Check workflow running linter, unit and functional tests +# This file is centrally managed as a template file in https://github.com/canonical/solutions-engineering-automation +# To update the file: +# - Edit it in the canonical/solutions-engineering-automation repository. +# - Open a PR with the changes. +# - When the PR merges, the soleng-terraform bot will open a PR to the target repositories with the changes. +name: Tests on: workflow_call: workflow_dispatch: pull_request: types: [opened, synchronize, reopened] - branches: [master, main] + branches: [main] paths-ignore: - "**.md" - "**.rst" @@ -15,28 +20,155 @@ concurrency: cancel-in-progress: true jobs: - lint-unit: - uses: canonical/bootstack-actions/.github/workflows/lint-unit.yaml@v2 + lint: + name: Lint strategy: fail-fast: false matrix: python-version: ["3.8", "3.10"] - with: - python-version: ${{ matrix.python-version }} - working-directory: ./src + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + # pin tox to the current major version to avoid + # workflows breaking all at once when a new major version is released. + python -m pip install 'tox<5' + + - name: Run linters + run: tox -e lint + + unit: + name: Unit + strategy: + fail-fast: false + matrix: + python-version: ["3.8", "3.10"] + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install 'tox<5' + + - name: Run unit tests + run: tox -e unit func: - uses: canonical/bootstack-actions/.github/workflows/func.yaml@v2 - needs: lint-unit + needs: + - lint + - unit + name: functional tests + runs-on: ${{ matrix.runs-on }} + timeout-minutes: 120 strategy: fail-fast: false matrix: - command: ['TEST_JUJU3=1 make functional'] # TEST_JUJU3 needed due https://github.com/openstack-charmers/zaza/blob/b22c2eed4c322f1dfc14ffb2d31e0dd18c911a40/setup.py#L47 to support Juju3+ - juju-channel: ['3.4/stable'] - with: - command: ${{ matrix.command }} - juju-channel: ${{ matrix.juju-channel }} - nested-containers: false - provider: "lxd" - python-version: "3.10" - timeout-minutes: 120 + runs-on: [[ubuntu-22.04]] + test-command: ['tox -e func'] + juju-channel: ["3.4/stable"] + steps: + + - uses: actions/checkout@v4 + with: + submodules: true + + # arm64 runners don't have gcc installed by default + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y gcc + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Setup Juju environment + uses: charmed-kubernetes/actions-operator@main + with: + provider: "lxd" + juju-channel: ${{ matrix.juju-channel }} + charmcraft-channel: "2.x/stable" + + # This is used by zaza in the functional tests for non-amd64 architectures (if applicable) + - name: Set zaza juju model constraints for architecture + run: | + if [ "$(uname -m)" = "aarch64" ]; then + echo "TEST_MODEL_CONSTRAINTS=arch=arm64" >> "$GITHUB_ENV" + fi + + - name: Build the charm + run: charmcraft -v pack + + - name: Run tests + run: | + # These variables are for a consistent method to find the charm file(s) across all projects. + # It is designed to work both with charms that output one file per base, + # and charms that output a single file to run on all bases. + # Not all charms will use them, and for some charms the variables will resolve to the same file. + export CHARM_PATH_NOBLE="$(pwd)/$(ls | grep '.*24.04.*\.charm$')" + echo "$CHARM_PATH_NOBLE" + export CHARM_PATH_JAMMY="$(pwd)/$(ls | grep '.*22.04.*\.charm$')" + echo "$CHARM_PATH_JAMMY" + export CHARM_PATH_FOCAL="$(pwd)/$(ls | grep '.*20.04.*\.charm$')" + echo "$CHARM_PATH_FOCAL" + ${{ matrix.test-command }} + env: + TEST_JUJU3: "1" # https://github.com/openstack-charmers/zaza/pull/653 + TEST_JUJU_CHANNEL: ${{ matrix.juju-channel }} + + # Save output for debugging + + - name: Generate debugging information + if: always() + run: | + set -x + # install dependencies + sudo snap install --classic juju-crashdump + sudo apt install -y jq uuid + + # Print juju controller information for debugging + # to check controller and client are compatible versions; + # we can have a mismatch if using an external controller. + juju version + juju controllers + + models="$(juju models --format json | jq -r '.models[]."short-name"')" + dir="$(mktemp -d)" + # Use a different dir to avoid charmed-kubernetes/actions-operator from also trying to upload crashdumps. + # We don't want to rely on that action, because it doesn't use a descriptive enough name for the artefact, + # and we may stop using that action soon. + echo "CRASHDUMPS_DIR=$dir" | tee -a "$GITHUB_ENV" + echo "CRASHDUMPS_ARTEFACT_SUFFIX=$(uuid)-$(uname -m)" | tee -a "$GITHUB_ENV" + + for model in $models; do + # show status here for quick debugging + juju status -m "$model" + juju-crashdump --as-root -m "$model" -u "$model-$(uname -m)" -o "$dir" + done + + - name: Upload juju crashdumps + uses: actions/upload-artifact@v4 + if: always() + with: + name: "juju-crashdumps-${{ env.CRASHDUMPS_ARTEFACT_SUFFIX }}" + path: "${{ env.CRASHDUMPS_DIR }}/juju-crashdump-*.tar.xz" diff --git a/.github/workflows/promote.yaml b/.github/workflows/promote.yaml index aa53c2e..e6b4f64 100644 --- a/.github/workflows/promote.yaml +++ b/.github/workflows/promote.yaml @@ -1,25 +1,40 @@ -name: Promote charm to other tracks and channels +# This file is centrally managed as a template file in https://github.com/canonical/solutions-engineering-automation +# To update the file: +# - Edit it in the canonical/solutions-engineering-automation repository. +# - Open a PR with the changes. +# - When the PR merges, the soleng-terraform bot will open a PR to the target repositories with the changes. +name: Promote charm to default track, standard risk levels. on: workflow_dispatch: inputs: - destination-channel: - description: 'Destination Channel, e.g. latest/candidate' - required: true - origin-channel: - description: 'Origin Channel, e.g. latest/edge' + channel-promotion: + description: 'Channel Promotion, e.g. latest/edge -> latest/candidate' required: true + type: choice + options: + - 'latest/edge -> latest/candidate' + - 'latest/candidate -> latest/stable' jobs: promote-charm: name: Promote charm - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + - name: Set channels + id: set-channels + run: | + channel_promotion="${{ github.event.inputs.channel-promotion }}" + origin=$(echo "$channel_promotion" | sed 's/\s*->.*//') + destination=$(echo "$channel_promotion" | sed 's/.*->\s*//') + echo "destination-channel=$destination" >> $GITHUB_OUTPUT + echo "origin-channel=$origin" >> $GITHUB_OUTPUT - name: Release charm to channel - uses: canonical/charming-actions/release-charm@2.4.0 + uses: canonical/charming-actions/release-charm@2.6.2 with: credentials: ${{ secrets.CHARMHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} - destination-channel: ${{ github.event.inputs.destination-channel }} - origin-channel: ${{ github.event.inputs.origin-channel }} + destination-channel: ${{ steps.set-channels.outputs.destination-channel }} + origin-channel: ${{ steps.set-channels.outputs.origin-channel }} + charmcraft-channel: "2.x/stable" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3b01e7e..539925c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,3 +1,8 @@ +# This file is centrally managed as a template file in https://github.com/canonical/solutions-engineering-automation +# To update the file: +# - Edit it in the canonical/solutions-engineering-automation repository. +# - Open a PR with the changes. +# - When the PR merges, the soleng-terraform bot will open a PR to the target repositories with the changes. name: Release to Edge on: @@ -13,17 +18,26 @@ jobs: release: needs: check - runs-on: ubuntu-latest + runs-on: ${{ matrix.runs-on }} + strategy: + fail-fast: false + matrix: + runs-on: [[ubuntu-22.04]] steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: true + - name: Initialize lxd # This should dropped once it's implemented on charming-actions itself. https://github.com/canonical/charming-actions/issues/140 - uses: canonical/setup-lxd@v0.1.1 - - name: Upload charm to charmhub - uses: canonical/charming-actions/upload-charm@2.4.0 + # revision is latest main at time of writing; using because it contains a fix to https://github.com/canonical/setup-lxd/issues/19 + uses: canonical/setup-lxd@2aa6f7caf7d1484298a64192f7f63a6684e648a4 + + - name: Pack and upload to charmhub + uses: canonical/charming-actions/upload-charm@2.6.2 with: + charmcraft-channel: "2.x/stable" credentials: "${{ secrets.CHARMHUB_TOKEN }}" github-token: "${{ secrets.GITHUB_TOKEN }}" - channel: "latest/edge" - # Note(rgildein): Right now we are not using destructive-mode, since our charmcraft.yaml is designed with a single build-on and the ability to run-on multiple bases. Running with destructive-mode would require aligning the base defined in this job with the one defined in charmcraft.yaml (build-on). + # Ensure the charm is built in an isolated environment and on the correct base in an lxd container. destructive-mode: false diff --git a/Makefile b/Makefile deleted file mode 100644 index 07b952d..0000000 --- a/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -PYTHON := /usr/bin/python3 - -PROJECTPATH=$(dir $(realpath $(MAKEFILE_LIST))) -ifndef CHARM_BUILD_DIR - CHARM_BUILD_DIR=${PROJECTPATH}/build -endif -ifndef CHARM_LAYERS_DIR - CHARM_LAYERS_DIR=${PROJECTPATH}/layers -endif -ifndef CHARM_INTERFACES_DIR - CHARM_INTERFACES_DIR=${PROJECTPATH}/interfaces -endif -ifdef CONTAINER - BUILD_ARGS="--destructive-mode" -endif -METADATA_FILE="src/metadata.yaml" -CHARM_NAME=$(shell cat ${PROJECTPATH}/${METADATA_FILE} | grep -E "^name:" | awk '{print $$2}') - -help: - @echo "This project supports the following targets" - @echo "" - @echo " make help - show this text" - @echo " make clean - remove unneeded files" - @echo " make submodules - make sure that the submodules are up-to-date" - @echo " make submodules-update - update submodules to latest changes on remote branch" - @echo " make build - build the charm" - @echo " make release - run clean, submodules, and build targets" - @echo " make lint - run flake8 and black --check" - @echo " make black - run black and reformat files" - @echo " make proof - run charm proof" - @echo " make unittests - run the tests defined in the unittest subdirectory" - @echo " make functional - run the tests defined in the functional subdirectory" - @echo " make test - run lint, proof, unittests and functional targets" - @echo "" - -clean: - @echo "Cleaning files" - @git clean -ffXd -e '!.idea' - @echo "Cleaning existing build" - @rm -rf ${CHARM_BUILD_DIR}/${CHARM_NAME} - @rm -rf ${PROJECTPATH}/${CHARM_NAME}.charm - @charmcraft clean - -submodules: - # @git submodule update --init --recursive - @echo "No submodules. Skipping." - -submodules-update: - # @git submodule update --init --recursive --remote --merge - @echo "No submodules. Skipping." - -build: clean - @echo "Building charm" - @-git rev-parse --abbrev-ref HEAD > ./src/repo-info - @charmcraft -v pack ${BUILD_ARGS} - @bash -c ./rename.sh - @mkdir -p ${CHARM_BUILD_DIR}/${CHARM_NAME} - -release: clean build - @echo "Charm is built at ${CHARM_BUILD_DIR}/${CHARM_NAME}" - -lint: - @echo "Running lint checks" - @cd src && tox -e lint - -black: - @echo "Reformat files with black" - @cd src && tox -e black - -proof: build - @echo "Running charm proof" - @charm proof ${CHARM_BUILD_DIR}/${CHARM_NAME} - -unittests: - # @cd src && tox -e unit - @echo "No unit tests. Skipping." - -functional: build - @echo "Executing functional tests in ${CHARM_BUILD_DIR}" - @cd src && CHARM_LOCATION=${PROJECTPATH} tox -e func - -test: lint proof unittests functional - @echo "Tests completed for charm ${CHARM_NAME}." - -# The targets below don't depend on a file -.PHONY: help submodules submodules-update clean build release lint black proof unittests functional test diff --git a/charmcraft.yaml b/charmcraft.yaml index b9a51c4..ece53b7 100644 --- a/charmcraft.yaml +++ b/charmcraft.yaml @@ -1,7 +1,7 @@ type: charm parts: charm: - source: src + source: . plugin: reactive build-snaps: [charm] build-packages: [python3-dev] diff --git a/src/config.yaml b/config.yaml similarity index 100% rename from src/config.yaml rename to config.yaml diff --git a/src/copyright b/copyright similarity index 100% rename from src/copyright rename to copyright diff --git a/src/icon.svg b/icon.svg similarity index 100% rename from src/icon.svg rename to icon.svg diff --git a/src/layer.yaml b/layer.yaml similarity index 100% rename from src/layer.yaml rename to layer.yaml diff --git a/metadata.yaml b/metadata.yaml deleted file mode 120000 index 0768683..0000000 --- a/metadata.yaml +++ /dev/null @@ -1 +0,0 @@ -src/metadata.yaml \ No newline at end of file diff --git a/metadata.yaml b/metadata.yaml new file mode 100644 index 0000000..aed47d5 --- /dev/null +++ b/metadata.yaml @@ -0,0 +1,24 @@ +name: prometheus-blackbox-exporter +summary: Blackbox exporter for Prometheus +maintainer: Llama (LMA) Charmers +description: | + The blackbox exporter allows blackbox probing of + endpoints over HTTP, HTTPS, DNS, TCP and ICMP. +tags: + - monitoring +series: [] +subordinate: false +provides: + blackbox-exporter: + interface: http + nrpe-external-master: + interface: nrpe-external-master + scope: container + dashboards: + interface: grafana-dashboard +resources: + dashboards: + type: file + filename: grafana-dashboards.zip + description: + Zip file to provide grafana dashboards diff --git a/src/reactive/prometheus_blackbox_exporter.py b/reactive/prometheus_blackbox_exporter.py similarity index 100% rename from src/reactive/prometheus_blackbox_exporter.py rename to reactive/prometheus_blackbox_exporter.py diff --git a/rename.sh b/rename.sh deleted file mode 100755 index bc8697f..0000000 --- a/rename.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -charm=$(grep -E "^name:" src/metadata.yaml | awk '{print $2}') -echo "renaming ${charm}_*.charm to ${charm}.charm" -echo -n "pwd: " -pwd -ls -al -echo "Removing previous charm if it exists" -if [[ -e "${charm}.charm" ]]; -then - rm "${charm}.charm" -fi -echo "Renaming charm here." -mv ${charm}_*.charm ${charm}.charm diff --git a/src/requirements.txt b/requirements.txt similarity index 100% rename from src/requirements.txt rename to requirements.txt diff --git a/src/metadata.yaml b/src/metadata.yaml deleted file mode 100644 index aed47d5..0000000 --- a/src/metadata.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: prometheus-blackbox-exporter -summary: Blackbox exporter for Prometheus -maintainer: Llama (LMA) Charmers -description: | - The blackbox exporter allows blackbox probing of - endpoints over HTTP, HTTPS, DNS, TCP and ICMP. -tags: - - monitoring -series: [] -subordinate: false -provides: - blackbox-exporter: - interface: http - nrpe-external-master: - interface: nrpe-external-master - scope: container - dashboards: - interface: grafana-dashboard -resources: - dashboards: - type: file - filename: grafana-dashboards.zip - description: - Zip file to provide grafana dashboards diff --git a/src/tests/functional/tests/bundles/overlays/focal.yaml.j2 b/src/tests/functional/tests/bundles/overlays/focal.yaml.j2 deleted file mode 100644 index d3f46ab..0000000 --- a/src/tests/functional/tests/bundles/overlays/focal.yaml.j2 +++ /dev/null @@ -1 +0,0 @@ -series: focal diff --git a/src/tests/functional/tests/bundles/overlays/jammy.yaml.j2 b/src/tests/functional/tests/bundles/overlays/jammy.yaml.j2 deleted file mode 100644 index 63f8d44..0000000 --- a/src/tests/functional/tests/bundles/overlays/jammy.yaml.j2 +++ /dev/null @@ -1,4 +0,0 @@ -series: jammy -applications: - prometheus: - series: focal \ No newline at end of file diff --git a/src/tests/functional/tests/bundles/overlays/local-charm-overlay.yaml.j2 b/src/tests/functional/tests/bundles/overlays/local-charm-overlay.yaml.j2 deleted file mode 100644 index 45065bc..0000000 --- a/src/tests/functional/tests/bundles/overlays/local-charm-overlay.yaml.j2 +++ /dev/null @@ -1,3 +0,0 @@ -applications: - {{ charm_name }}: - charm: "{{ CHARM_LOCATION }}/{{ charm_name }}.charm" diff --git a/src/templates/blackbox.yaml.j2 b/templates/blackbox.yaml.j2 similarity index 100% rename from src/templates/blackbox.yaml.j2 rename to templates/blackbox.yaml.j2 diff --git a/src/tests/functional/requirements.txt b/tests/functional/requirements.txt similarity index 100% rename from src/tests/functional/requirements.txt rename to tests/functional/requirements.txt diff --git a/src/tests/functional/tests/__init__.py b/tests/functional/tests/__init__.py similarity index 100% rename from src/tests/functional/tests/__init__.py rename to tests/functional/tests/__init__.py diff --git a/src/tests/functional/tests/bundles/base.yaml b/tests/functional/tests/bundles/base.yaml similarity index 100% rename from src/tests/functional/tests/bundles/base.yaml rename to tests/functional/tests/bundles/base.yaml diff --git a/src/tests/functional/tests/bundles/focal.yaml b/tests/functional/tests/bundles/focal.yaml similarity index 100% rename from src/tests/functional/tests/bundles/focal.yaml rename to tests/functional/tests/bundles/focal.yaml diff --git a/src/tests/functional/tests/bundles/jammy.yaml b/tests/functional/tests/bundles/jammy.yaml similarity index 100% rename from src/tests/functional/tests/bundles/jammy.yaml rename to tests/functional/tests/bundles/jammy.yaml diff --git a/tests/functional/tests/bundles/overlays/focal.yaml.j2 b/tests/functional/tests/bundles/overlays/focal.yaml.j2 new file mode 100644 index 0000000..c61fa26 --- /dev/null +++ b/tests/functional/tests/bundles/overlays/focal.yaml.j2 @@ -0,0 +1,4 @@ +series: focal +applications: + {{ charm_name }}: + charm: "{{ CHARM_PATH_FOCAL }}" diff --git a/tests/functional/tests/bundles/overlays/jammy.yaml.j2 b/tests/functional/tests/bundles/overlays/jammy.yaml.j2 new file mode 100644 index 0000000..d592c60 --- /dev/null +++ b/tests/functional/tests/bundles/overlays/jammy.yaml.j2 @@ -0,0 +1,6 @@ +series: jammy +applications: + prometheus: + series: focal + {{ charm_name }}: + charm: "{{ CHARM_PATH_JAMMY }}" diff --git a/src/tests/functional/tests/test_prometheus_blackbox_exporter.py b/tests/functional/tests/test_prometheus_blackbox_exporter.py similarity index 100% rename from src/tests/functional/tests/test_prometheus_blackbox_exporter.py rename to tests/functional/tests/test_prometheus_blackbox_exporter.py diff --git a/src/tests/functional/tests/tests.yaml b/tests/functional/tests/tests.yaml similarity index 100% rename from src/tests/functional/tests/tests.yaml rename to tests/functional/tests/tests.yaml diff --git a/src/tests/unit/requirements.txt b/tests/unit/requirements.txt similarity index 100% rename from src/tests/unit/requirements.txt rename to tests/unit/requirements.txt diff --git a/src/tox.ini b/tox.ini similarity index 100% rename from src/tox.ini rename to tox.ini