From a3eba54d8a0b8a3cd2b27f429184582d38e10ecc Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 10:00:29 -0400 Subject: [PATCH 001/108] feat: COS Lite upgrade test with TF --- .github/workflows/terraform.yml | 14 +- justfile | 5 + pyproject.toml | 12 ++ tests/integration/conftest.py | 20 +++ tests/integration/cos-lite.tf | 13 ++ tests/integration/test_terraform.py | 49 ++++++ uv.lock | 238 ++++++++++++++++++++++++++++ 7 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 pyproject.toml create mode 100644 tests/integration/conftest.py create mode 100644 tests/integration/cos-lite.tf create mode 100644 tests/integration/test_terraform.py create mode 100644 uv.lock diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index cb3ee2a4..d5b2320a 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -5,7 +5,7 @@ on: branches: - main paths: - - '**/*.tf' + - "**/*.tf" jobs: lint-terraform: @@ -45,3 +45,15 @@ jobs: sudo snap install just --classic - name: Validate the Terraform modules run: just validate-terraform + terraform-integration: + name: Test deploy/upgrade Terraform product modules + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install terraform --classic + sudo snap install just --classic + - name: Validate the Terraform modules + run: just integration diff --git a/justfile b/justfile index 0af86ca5..866ac82d 100644 --- a/justfile +++ b/justfile @@ -49,3 +49,8 @@ format-terraform-docs: validate-terraform: if [ -z "${terraform}" ]; then echo "ERROR: please install terraform or opentofu"; exit 1; fi set -e; for repo in */; do (cd "$repo" && echo "Processing ${repo%/}..." && $terraform init -upgrade -reconfigure && $terraform validate) || exit 1; done + +# Run solution tests +[working-directory("./tests/integration")] +integration: + uv run pytest \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..ffba1a71 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,12 @@ +# Copyright 2025 Canonical Ltd. +# See LICENSE file for licensing details. + +[project] +name = "observability-stack" +version = "0.0.0" + +dependencies = [ + "jubilant", + "pytest", + "sh", +] diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 00000000..5c888d24 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# Copyright 2025 Canonical Ltd. +# See LICENSE file for licensing details. +"""Conftest file for integration tests.""" + +import logging +import os + +import pytest + +import jubilant + +logger = logging.getLogger(__name__) + + +@pytest.fixture(scope="module") +def juju(): + keep_models: bool = os.environ.get("KEEP_MODELS") is not None + with jubilant.temp_model(keep=keep_models) as juju: + yield juju diff --git a/tests/integration/cos-lite.tf b/tests/integration/cos-lite.tf new file mode 100644 index 00000000..3c7cccff --- /dev/null +++ b/tests/integration/cos-lite.tf @@ -0,0 +1,13 @@ +module "cos-lite" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" + model = var.model + channel = var.channel +} + +variable "model" { + type = string +} + +variable "channel" { + type = string +} diff --git a/tests/integration/test_terraform.py b/tests/integration/test_terraform.py new file mode 100644 index 00000000..2ecb3844 --- /dev/null +++ b/tests/integration/test_terraform.py @@ -0,0 +1,49 @@ +# 1. We could try to test TLS transition scenarios +# No TLS -> TLS +import pytest +import sh +import jubilant +import shutil +import os + + +def test_init_cos_lite(tmpdir): + temp_tf_dir = tmpdir.mkdir("terraform") + shutil.copy("cos-lite.tf", temp_tf_dir) + os.chdir(temp_tf_dir) + sh.terraform("init") + + +@pytest.mark.abort_on_fail +def test_terraform_upgrade(juju: jubilant.Juju): + sh.terraform( + "apply", + "-var", + "channel=1/stable", + "-var", + f"model={juju.model}", + "-auto-approve", + ) + juju.wait(jubilant.all_agents_idle, delay=30, timeout=60 * 10) + sh.terraform( + "apply", + "-var", + "channel=2/edge", + "-var", + f"model={juju.model}", + "-auto-approve", + ) + juju.wait(jubilant.all_agents_idle, delay=30, timeout=60 * 10) + + +@pytest.mark.abort_on_fail +# @pytest.mark.skip(reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"') +def test_terraform_destroy(juju: jubilant.Juju): + sh.terraform( + "destroy", + "-var", + "channel=2/edge", + "-var", + f"model={juju.model}", + "-auto-approve", + ) diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..1677074e --- /dev/null +++ b/uv.lock @@ -0,0 +1,238 @@ +version = 1 +revision = 3 +requires-python = ">=3.10" + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "jubilant" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/1a/ba5838825ac99db4ceec68fa146b594c97b682cf3ccf670b1ecf1261209d/jubilant-1.4.0.tar.gz", hash = "sha256:aa377699a8811fea29bfe0febb6b552d4593c02e666f5ba8c3fba24258700199", size = 27502, upload-time = "2025-08-27T00:11:46.295Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/06/4965ed70d4b9d405c8bdefc4926d94cae202014b4488a25aa8c1fe9fb462/jubilant-1.4.0-py3-none-any.whl", hash = "sha256:1df7eaf125fad8d0d3d35e6d83eca43bfbb7884debcd6c7f4b0822600e2a485c", size = 27185, upload-time = "2025-08-27T00:11:44.851Z" }, +] + +[[package]] +name = "observability-stack" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "jubilant" }, + { name = "pytest" }, + { name = "sh" }, +] + +[package.metadata] +requires-dist = [ + { name = "jubilant" }, + { name = "pytest" }, + { name = "sh" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "sh" +version = "2.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/52/f43920223c93e31874677c681b8603d36a40d3d8502d3a37f80d3995d43e/sh-2.2.2.tar.gz", hash = "sha256:653227a7c41a284ec5302173fbc044ee817c7bad5e6e4d8d55741b9aeb9eb65b", size = 345866, upload-time = "2025-02-24T07:16:25.363Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl", hash = "sha256:e0b15b4ae8ffcd399bc8ffddcbd770a43c7a70a24b16773fbb34c001ad5d52af", size = 38295, upload-time = "2025-02-24T07:16:23.782Z" }, +] + +[[package]] +name = "tomli" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, + { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, + { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, + { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, + { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, + { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, + { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, + { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] From ddb19dc4fcc0dc7d336b7335a3fa6a834dd8dcd3 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 10:05:09 -0400 Subject: [PATCH 002/108] chore: Add uv dep to CI workflow --- .github/workflows/terraform.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index d5b2320a..83b40dde 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -55,5 +55,6 @@ jobs: run: | sudo snap install terraform --classic sudo snap install just --classic + sudo snap install astral-uv --classic - name: Validate the Terraform modules run: just integration From 61b2489793df924522cb2286f7bbaa4ed9e699ae Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 10:22:23 -0400 Subject: [PATCH 003/108] chore: Add concierge dep to CI workflow --- .github/workflows/terraform.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 83b40dde..3b644909 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -53,8 +53,7 @@ jobs: uses: actions/checkout@v4 - name: Install dependencies run: | - sudo snap install terraform --classic - sudo snap install just --classic - sudo snap install astral-uv --classic + sudo snap install concierge --classic + sudo concierge prepare -p ${{ inputs.provider }} --extra-snaps just,astral-uv,terraform - name: Validate the Terraform modules run: just integration From a2e68ed1634e46a8936fcbe933b7fa5971fecbf8 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 10:24:52 -0400 Subject: [PATCH 004/108] chore: Add concierge dep to CI workflow --- .github/workflows/terraform.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 3b644909..22978c6e 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -6,6 +6,15 @@ on: - main paths: - "**/*.tf" + workflow_call: + inputs: + provider: + description: | + The substrate to set up prior to running the test + (a concierge preset, e.g. 'machine' or 'microk8s'). + default: 'microk8s' + required: false + type: string jobs: lint-terraform: From f84b37109e2985afa9226d39239de7b9db837d8f Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 10:30:12 -0400 Subject: [PATCH 005/108] chore: Add concierge dep to CI workflow --- .github/workflows/terraform.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 22978c6e..520d77a8 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -6,15 +6,6 @@ on: - main paths: - "**/*.tf" - workflow_call: - inputs: - provider: - description: | - The substrate to set up prior to running the test - (a concierge preset, e.g. 'machine' or 'microk8s'). - default: 'microk8s' - required: false - type: string jobs: lint-terraform: @@ -63,6 +54,6 @@ jobs: - name: Install dependencies run: | sudo snap install concierge --classic - sudo concierge prepare -p ${{ inputs.provider }} --extra-snaps just,astral-uv,terraform + sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Validate the Terraform modules run: just integration From 7a0cfc12ca0ec3805b2e5b1fbedab24db7d657bd Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 13:39:57 -0400 Subject: [PATCH 006/108] chore: Add buffered output --- justfile | 2 +- tests/integration/helpers.py | 28 ++++++++++++++++++++ tests/integration/test_terraform.py | 40 +++++++++-------------------- 3 files changed, 41 insertions(+), 29 deletions(-) create mode 100644 tests/integration/helpers.py diff --git a/justfile b/justfile index 866ac82d..16446df7 100644 --- a/justfile +++ b/justfile @@ -53,4 +53,4 @@ validate-terraform: # Run solution tests [working-directory("./tests/integration")] integration: - uv run pytest \ No newline at end of file + uv run pytest -vvs diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py new file mode 100644 index 00000000..ccf3435e --- /dev/null +++ b/tests/integration/helpers.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +# Copyright 2025 Canonical Ltd. +# See LICENSE file for licensing details. +"""Helper functions for integration tests.""" + +import logging +import shlex +import subprocess + +logger = logging.getLogger(__name__) + + +def run_live(cmd): + proc = subprocess.Popen( + shlex.split(cmd), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1, + ) + lines = [] + try: + for line in proc.stdout: + print(line, end="", flush=True) + lines.append(line) + finally: + proc.wait() + assert proc.returncode == 0 diff --git a/tests/integration/test_terraform.py b/tests/integration/test_terraform.py index 2ecb3844..f399afd3 100644 --- a/tests/integration/test_terraform.py +++ b/tests/integration/test_terraform.py @@ -1,49 +1,33 @@ -# 1. We could try to test TLS transition scenarios -# No TLS -> TLS +import os +import shutil + import pytest -import sh +from helpers import run_live + import jubilant -import shutil -import os def test_init_cos_lite(tmpdir): temp_tf_dir = tmpdir.mkdir("terraform") shutil.copy("cos-lite.tf", temp_tf_dir) os.chdir(temp_tf_dir) - sh.terraform("init") + run_live("terraform init") @pytest.mark.abort_on_fail def test_terraform_upgrade(juju: jubilant.Juju): - sh.terraform( - "apply", - "-var", - "channel=1/stable", - "-var", - f"model={juju.model}", - "-auto-approve", + run_live( + f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" ) juju.wait(jubilant.all_agents_idle, delay=30, timeout=60 * 10) - sh.terraform( - "apply", - "-var", - "channel=2/edge", - "-var", - f"model={juju.model}", - "-auto-approve", + run_live( + f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" ) juju.wait(jubilant.all_agents_idle, delay=30, timeout=60 * 10) @pytest.mark.abort_on_fail -# @pytest.mark.skip(reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"') def test_terraform_destroy(juju: jubilant.Juju): - sh.terraform( - "destroy", - "-var", - "channel=2/edge", - "-var", - f"model={juju.model}", - "-auto-approve", + run_live( + f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" ) From 97ac05e50f2a8fd4223b9daef7ced4c7b76a5a91 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 14:15:14 -0400 Subject: [PATCH 007/108] chore: Add skip tfd --- tests/integration/test_terraform.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/integration/test_terraform.py b/tests/integration/test_terraform.py index f399afd3..3b128044 100644 --- a/tests/integration/test_terraform.py +++ b/tests/integration/test_terraform.py @@ -27,7 +27,10 @@ def test_terraform_upgrade(juju: jubilant.Juju): @pytest.mark.abort_on_fail +@pytest.mark.skip(reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"') def test_terraform_destroy(juju: jubilant.Juju): run_live( f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" ) + +# FIXME: We let jubilant forcefully tear down the model since TF cannot From aa17bc64f4e344441a4c98a117c44e4418fccb8a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 10 Oct 2025 17:28:29 -0400 Subject: [PATCH 008/108] chore: reduce delay in juju.wait --- tests/integration/test_terraform.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_terraform.py b/tests/integration/test_terraform.py index 3b128044..7dcd6100 100644 --- a/tests/integration/test_terraform.py +++ b/tests/integration/test_terraform.py @@ -19,11 +19,13 @@ def test_terraform_upgrade(juju: jubilant.Juju): run_live( f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" ) - juju.wait(jubilant.all_agents_idle, delay=30, timeout=60 * 10) + print("waiting for the model to settle ...") + juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) run_live( f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" ) - juju.wait(jubilant.all_agents_idle, delay=30, timeout=60 * 10) + print("waiting for the model to settle ...") + juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) @pytest.mark.abort_on_fail From 0b6ce3ae61cc5960d260eb7d45cdb593f5f10a1c Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 14 Oct 2025 08:25:17 -0400 Subject: [PATCH 009/108] feat: GH manual trigger --- .github/workflows/terraform.yml | 1 + .../conftest.cpython-310-pytest-8.4.2.pyc | Bin 0 -> 732 bytes ...est_terraform.cpython-310-pytest-8.4.2.pyc | Bin 0 -> 1564 bytes tests/integration/helpers.py | 28 ----------- tests/integration/test_terraform.py | 46 ++++++++++++------ 5 files changed, 32 insertions(+), 43 deletions(-) create mode 100644 tests/integration/__pycache__/conftest.cpython-310-pytest-8.4.2.pyc create mode 100644 tests/integration/__pycache__/test_terraform.cpython-310-pytest-8.4.2.pyc delete mode 100644 tests/integration/helpers.py diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 520d77a8..718c3333 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -6,6 +6,7 @@ on: - main paths: - "**/*.tf" + workflow_dispatch: jobs: lint-terraform: diff --git a/tests/integration/__pycache__/conftest.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/conftest.cpython-310-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81c65765b1281e86e9e0ca1cac09ab9bffbeb0f4 GIT binary patch literal 732 zcmYjP&2Q5%6t|tU`Dir$yYA$FK~h9ludQ?-pl(vzi*4dAVhG!J^Xe09V7J9D!a!4I{;bijjrk2%b}!mPu(U(h9{_ZXR> zvG?)Op{N#`D?M6d1s^Sh9A%Z}OPT0QR3mFqliyGaIyT)>u%_T+Y&t3xHBT*kdkFma zKo(RlfPF?9<@g#3zrhSO_yTDsch3v8 zCce||$Mwc$m?R2P+dWJqU&~B$6Wl?@yTw9qw%6lC8m|z`WmYX^2U45v)*$U(OaRk4 z0xOrskK-ySIh4?~_W|)1*$3T7-qzTTWry{wyZ>~%{b%rMk+SW%&OY(6Pka)R(AmTP E0PwTN0{{R3 literal 0 HcmV?d00001 diff --git a/tests/integration/__pycache__/test_terraform.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/test_terraform.cpython-310-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79869395647923e11bcb5f6828b102423ffbf4d9 GIT binary patch literal 1564 zcmah|&u`l{6ejh{vK=RF))w8m4njI$@WB>3>@;jcft|KPF57@X7l9V(h_)mOB$d=g zc51J=?KTW>j{TQ--KmHD13fHzq!TagHdF#1^&TIo_rC9=7>x!9p6{YR%Zm`9Kdf{6 zff#xQL;VVdB8n@NVK;lV?;(upAPez!CCVbV(#v{oj z%(n7xVW=;_oTClYeu;m<8gD%6o#RUnBkgYj_`>iNZX(^=#MHlZK1FbHaBTXTNlE5H z*6U#*)TH8?P4#@ezl$fl;d^V#=96I()r0W(Ev!P~no9lTF&MPEGQ2m>q(o)nct#x`Pu=FdW1cd}y@6+S~XPpQAU z3m;&AcTeyAdmJ_K@%quOm4viywMr(ZL?*SMtonNW>DDVs(lp>dO#zfy#gYl>w3tA? z6sK(c>2&(q>WKdgiUN*8IGn6ZPxG3IPQN*N`!}Db zjGnynlW|{KIAz}&i>@4k0lC;hP1s7H$ON_!6E8ZTkbr+cswyWZtkEjxv|_KYykoao zF>KAgJ>-GoZ-+zPwZJuHcVSI^3?}dbyytm;1y^zJ5C`zycn`3A1PSZ;kCL!CUnV8j zDgmtn5CD~CiD(iE>X2e(0s03V+A#}IDa10F6J9a;WpX50!T2eg6l78`sV5R(vYMOB zq*$`%XpBuH8BwD7e+_*C_54c@I}JJ3{p0oHUAH&o-R521gG0vQe<3dK!;<{Sn)jf1 z-S%gYsw`naxWz5Ll8?b1e_-NS$14zyGJDV3Rlf5+%-fZvWJ(lVNDIJJvNH+S%Jg?3 z)4PccV6$V8NEz9}0x%}p2Dd#p!928U+iO@8xy(jnCZx_qlUo8z@IBm3N2dwYlDDqP pTTQxlonGRvKy_WkzOk3rDdY&nIQC%J*N;FY(ftT}IJkP~{|#kZq+kF5 literal 0 HcmV?d00001 diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py deleted file mode 100644 index ccf3435e..00000000 --- a/tests/integration/helpers.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2025 Canonical Ltd. -# See LICENSE file for licensing details. -"""Helper functions for integration tests.""" - -import logging -import shlex -import subprocess - -logger = logging.getLogger(__name__) - - -def run_live(cmd): - proc = subprocess.Popen( - shlex.split(cmd), - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - bufsize=1, - ) - lines = [] - try: - for line in proc.stdout: - print(line, end="", flush=True) - lines.append(line) - finally: - proc.wait() - assert proc.returncode == 0 diff --git a/tests/integration/test_terraform.py b/tests/integration/test_terraform.py index 7dcd6100..74836825 100644 --- a/tests/integration/test_terraform.py +++ b/tests/integration/test_terraform.py @@ -2,8 +2,8 @@ import shutil import pytest -from helpers import run_live - +import subprocess +import shlex import jubilant @@ -11,28 +11,44 @@ def test_init_cos_lite(tmpdir): temp_tf_dir = tmpdir.mkdir("terraform") shutil.copy("cos-lite.tf", temp_tf_dir) os.chdir(temp_tf_dir) - run_live("terraform init") + subprocess.run(shlex.split(("terraform init"))) @pytest.mark.abort_on_fail -def test_terraform_upgrade(juju: jubilant.Juju): - run_live( - f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" +def test_terraform_deploy(juju: jubilant.Juju): + subprocess.run( + shlex.split( + ( + f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" + ) + ) ) - print("waiting for the model to settle ...") + print("\nwaiting for the model to settle ...\n") juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - run_live( - f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" + + +@pytest.mark.abort_on_fail +def test_terraform_upgrade(juju: jubilant.Juju): + subprocess.run( + shlex.split( + ( + f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" + ) + ) ) - print("waiting for the model to settle ...") + print("\nwaiting for the model to settle ...\n") juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) @pytest.mark.abort_on_fail -@pytest.mark.skip(reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"') +@pytest.mark.skip( + reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"' +) def test_terraform_destroy(juju: jubilant.Juju): - run_live( - f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" + subprocess.run( + shlex.split( + ( + f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" + ) + ) ) - -# FIXME: We let jubilant forcefully tear down the model since TF cannot From 6d5d1f0f595fc0337f73ebdbcd5a6826c5abd3b3 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 14 Oct 2025 08:55:16 -0400 Subject: [PATCH 010/108] test manual trigger --- .github/workflows/terraform.yml | 17 +++++- justfile | 4 +- ..._lite_upgrade.cpython-310-pytest-8.4.2.pyc | Bin 0 -> 934 bytes ...t_cos_upgrade.cpython-310-pytest-8.4.2.pyc | Bin 0 -> 914 bytes ...est_terraform.cpython-310-pytest-8.4.2.pyc | Bin 1564 -> 1073 bytes tests/integration/cos.tf | 13 +++++ tests/integration/test_cos_lite_upgrade.py | 55 ++++++++++++++++++ tests/integration/test_cos_upgrade.py | 54 +++++++++++++++++ tests/integration/test_terraform.py | 54 ----------------- 9 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 tests/integration/__pycache__/test_cos_lite_upgrade.cpython-310-pytest-8.4.2.pyc create mode 100644 tests/integration/__pycache__/test_cos_upgrade.cpython-310-pytest-8.4.2.pyc create mode 100644 tests/integration/cos.tf create mode 100644 tests/integration/test_cos_lite_upgrade.py create mode 100644 tests/integration/test_cos_upgrade.py delete mode 100644 tests/integration/test_terraform.py diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 718c3333..68473121 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -7,6 +7,15 @@ on: paths: - "**/*.tf" workflow_dispatch: + inputs: + cos: + description: 'Deploy the COS TF product module' + required: true + default: false + cos-lite: + description: 'Deploy the COS Lite TF product module' + required: true + default: false jobs: lint-terraform: @@ -56,5 +65,9 @@ jobs: run: | sudo snap install concierge --classic sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - - name: Validate the Terraform modules - run: just integration + - name: Deploy the COS Lite TF product module + if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') + run: just integration "test_cos_upgrade.py" + - name: Deploy the COS TF product module + if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos-lite == 'true') + run: just integration "test_cos_lite_upgrade.py" diff --git a/justfile b/justfile index 16446df7..27b488da 100644 --- a/justfile +++ b/justfile @@ -52,5 +52,5 @@ validate-terraform: # Run solution tests [working-directory("./tests/integration")] -integration: - uv run pytest -vvs +integration *args='': + uv run pytest -vvs "${args}" diff --git a/tests/integration/__pycache__/test_cos_lite_upgrade.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/test_cos_lite_upgrade.cpython-310-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd5095b26c0722d746c2c43f0cf56bd01f3f8218 GIT binary patch literal 934 zcmYjQJ#W)M7`{7y#z_M$5)xa5goKC26iQhLD&k}8g2Z4US&r{aOl+TZccD#`EWpIZ z&XA1!rCXU;_yLuWc+ak?ob`S^ul?LTuWi1!7a&+aUjLo`a}fG%irqz^I0KXK!BIqU ziDKMFQdtCHRN1kEyN(;XZO4nfHu|yO#$McOV-N>z?8kjdsPzrS1B&0F(EbD5=sd$F zTrUrzu~%U7J2;Bhn36SF;T4&YwY9S3kwP0xA8Or4+PE?V2v zrQXUeFyxN1plh$3E&htXfEpXEF_;DHXyZ_Si`TAlHy-V++%3UK`5TjAqZ7^>oG<;1 z%fqrz>}`mz$aoy$<-vo8&EhzehvV^~Nl!um?yQe?izmCq z3+ yc*Z15R!&QHsr^rL(3RGzJwZE;9e3M2?LV(LotNx|`2*w-+J!YE)FpO literal 0 HcmV?d00001 diff --git a/tests/integration/__pycache__/test_cos_upgrade.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/test_cos_upgrade.cpython-310-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da69b7933cbb7eabd745486b2d4b6feb4acfd15b GIT binary patch literal 914 zcmYjQOOMkq5VoCX(}&naLgKbULL!H4cr43>qD4H8dqDyzmne-L8k)qB?Xugdy#ObE z14!+WzvL??4)6o^#5h^4>S(^1`6ik8n>c(p3=piJum8>dItcwX$^IgcoPo*r02EPN zq8PWHR2D%PRd(#)uHwdSTk&GA^?vNPz8CjeAH+fH`*EKVYJEfTfZ}&3wEsYFbe>`3 zu9pYi*efvk9f0Bures6bcunSHW34TDtk4!yh;mGA!{=mY0|)o)aO=qqQ|AY{gElsG zskgQZ46&musM>31hri-4pvFcU3}!)hv~{Sz!y8w*TaWhE?v7xj{H=+w(Fywv&b5_s z`8LE?WHJfy>hS)9X899lGp;yz{zTqO38$3Yp0? zC(q)(VpWr9i;dwLF$8 z&E}C2FQcMX?4xKkv`hj6N)`=Jl#M~cu$@s+7s^!336?%UjsrZvBPHV%6u&!v#Bq{}w&J6Rp+Z6;Lt{QlSqLg1I(9)U9~VBJuzEGp2# z791SawLaQ3o^BdXYNI~r*{1P4Y{|5!A~}q7Uc_(1@Gjp6BUYqAA%io<$3YU8tjvH^ z01TK2*Z^AdIUZ!de|jKfoQwlaUIbYw(~sP6FrMhTVLc$QV>*x&K(RTd;T;TBlj(EvXM;`#=1os2gDW-hz~)8YCIep7=cSHm69 zROg?1c69KrhI;_rE#(a+SuV3usJ3qMwY3-3v+mVxhk5mQdd7i`YF@ik1{G&XDqyN&l&9y)`!s=`#-%h(FlB6%Y>GE^doKz`Cwcl(|AOKMz3>@;jcft|KPF57@X7l9V(h_)mOB$d=g zc51J=?KTW>j{TQ--KmHD13fHzq!TagHdF#1^&TIo_rC9=7>x!9p6{YR%Zm`9Kdf{6 zff#xQL;VVdB8n@NVK;lV?;(upAPez!CCVbV(#v{oj z%(n7xVW=;_oTClYeu;m<8gD%6o#RUnBkgYj_`>iNZX(^=#MHlZK1FbHaBTXTNlE5H z*6U#*)TH8?P4#@ezl$fl;d^V#=96I()r0W(Ev!P~no9lTF&MPEGQ2m>q(o)nct#x`Pu=FdW1cd}y@6+S~XPpQAU z3m;&AcTeyAdmJ_K@%quOm4viywMr(ZL?*SMtonNW>DDVs(lp>dO#zfy#gYl>w3tA? z6sK(c>2&(q>WKdgiUN*8IGn6ZPxG3IPQN*N`!}Db zjGnynlW|{KIAz}&i>@4k0lC;hP1s7H$ON_!6E8ZTkbr+cswyWZtkEjxv|_KYykoao zF>KAgJ>-GoZ-+zPwZJuHcVSI^3?}dbyytm;1y^zJ5C`zycn`3A1PSZ;kCL!CUnV8j zDgmtn5CD~CiD(iE>X2e(0s03V+A#}IDa10F6J9a;WpX50!T2eg6l78`sV5R(vYMOB zq*$`%XpBuH8BwD7e+_*C_54c@I}JJ3{p0oHUAH&o-R521gG0vQe<3dK!;<{Sn)jf1 z-S%gYsw`naxWz5Ll8?b1e_-NS$14zyGJDV3Rlf5+%-fZvWJ(lVNDIJJvNH+S%Jg?3 z)4PccV6$V8NEz9}0x%}p2Dd#p!928U+iO@8xy(jnCZx_qlUo8z@IBm3N2dwYlDDqP pTTQxlonGRvKy_WkzOk3rDdY&nIQC%J*N;FY(ftT}IJkP~{|#kZq+kF5 diff --git a/tests/integration/cos.tf b/tests/integration/cos.tf new file mode 100644 index 00000000..cde8030e --- /dev/null +++ b/tests/integration/cos.tf @@ -0,0 +1,13 @@ +module "cos" { + source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" + model = var.model + channel = var.channel +} + +variable "model" { + type = string +} + +variable "channel" { + type = string +} diff --git a/tests/integration/test_cos_lite_upgrade.py b/tests/integration/test_cos_lite_upgrade.py new file mode 100644 index 00000000..6e4b01c5 --- /dev/null +++ b/tests/integration/test_cos_lite_upgrade.py @@ -0,0 +1,55 @@ +import os +import shutil + +import pytest +import subprocess +import shlex +import jubilant + + +def test_init_cos_lite(tmpdir): + assert "cos lite" == False + temp_tf_dir = tmpdir.mkdir("terraform") + shutil.copy("cos-lite.tf", temp_tf_dir) + os.chdir(temp_tf_dir) + # subprocess.run(shlex.split(("terraform init"))) + + +# @pytest.mark.abort_on_fail +# def test_terraform_deploy(juju: jubilant.Juju): +# subprocess.run( +# shlex.split( +# ( +# f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" +# ) +# ) +# ) +# print("\nwaiting for the model to settle ...\n") +# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) + + +# @pytest.mark.abort_on_fail +# def test_terraform_upgrade(juju: jubilant.Juju): +# subprocess.run( +# shlex.split( +# ( +# f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" +# ) +# ) +# ) +# print("\nwaiting for the model to settle ...\n") +# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) + + +# @pytest.mark.abort_on_fail +# @pytest.mark.skip( +# reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"' +# ) +# def test_terraform_destroy(juju: jubilant.Juju): +# subprocess.run( +# shlex.split( +# ( +# f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" +# ) +# ) +# ) diff --git a/tests/integration/test_cos_upgrade.py b/tests/integration/test_cos_upgrade.py new file mode 100644 index 00000000..d3c52ec1 --- /dev/null +++ b/tests/integration/test_cos_upgrade.py @@ -0,0 +1,54 @@ +import os +import shutil + +import pytest +import subprocess +import shlex +import jubilant + + +def test_init_cos(tmpdir): + assert "cos" == False + temp_tf_dir = tmpdir.mkdir("terraform") + shutil.copy("cos.tf", temp_tf_dir) + os.chdir(temp_tf_dir) + # subprocess.run(shlex.split(("terraform init"))) + +# @pytest.mark.abort_on_fail +# def test_terraform_deploy(juju: jubilant.Juju): +# subprocess.run( +# shlex.split( +# ( +# f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" +# ) +# ) +# ) +# print("\nwaiting for the model to settle ...\n") +# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) + + +# @pytest.mark.abort_on_fail +# def test_terraform_upgrade(juju: jubilant.Juju): +# subprocess.run( +# shlex.split( +# ( +# f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" +# ) +# ) +# ) +# print("\nwaiting for the model to settle ...\n") +# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) + + +# @pytest.mark.abort_on_fail +# @pytest.mark.skip( +# reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"' +# ) +# def test_terraform_destroy(juju: jubilant.Juju): +# subprocess.run( +# shlex.split( +# ( +# f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" +# ) +# ) +# ) diff --git a/tests/integration/test_terraform.py b/tests/integration/test_terraform.py deleted file mode 100644 index 74836825..00000000 --- a/tests/integration/test_terraform.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import shutil - -import pytest -import subprocess -import shlex -import jubilant - - -def test_init_cos_lite(tmpdir): - temp_tf_dir = tmpdir.mkdir("terraform") - shutil.copy("cos-lite.tf", temp_tf_dir) - os.chdir(temp_tf_dir) - subprocess.run(shlex.split(("terraform init"))) - - -@pytest.mark.abort_on_fail -def test_terraform_deploy(juju: jubilant.Juju): - subprocess.run( - shlex.split( - ( - f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" - ) - ) - ) - print("\nwaiting for the model to settle ...\n") - juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - - -@pytest.mark.abort_on_fail -def test_terraform_upgrade(juju: jubilant.Juju): - subprocess.run( - shlex.split( - ( - f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" - ) - ) - ) - print("\nwaiting for the model to settle ...\n") - juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - - -@pytest.mark.abort_on_fail -@pytest.mark.skip( - reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"' -) -def test_terraform_destroy(juju: jubilant.Juju): - subprocess.run( - shlex.split( - ( - f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" - ) - ) - ) From f552ae519ee79044a65316e9a176af7afdf9e2c5 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 14 Oct 2025 09:02:02 -0400 Subject: [PATCH 011/108] chore: Speed up tests --- .github/workflows/terraform.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 68473121..5e03d7e7 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -61,10 +61,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install dependencies - run: | - sudo snap install concierge --classic - sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + # - name: Install dependencies + # run: | + # sudo snap install concierge --classic + # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Deploy the COS Lite TF product module if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') run: just integration "test_cos_upgrade.py" From 82cb4ba788676231ded27ac817ae7432e51962aa Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 14 Oct 2025 09:23:35 -0400 Subject: [PATCH 012/108] test --- .github/workflows/terraform.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 5e03d7e7..a7e8d75a 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -65,9 +65,14 @@ jobs: # run: | # sudo snap install concierge --classic # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - - name: Deploy the COS Lite TF product module - if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') - run: just integration "test_cos_upgrade.py" - name: Deploy the COS TF product module + if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') + run: | + just --list + just integration + just integration "test_cos_upgrade.py" + - name: Deploy the COS Lite TF product module if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos-lite == 'true') - run: just integration "test_cos_lite_upgrade.py" + run: | + just --list + just integration "test_cos_lite_upgrade.py" From ba3c9fbab70266a8502de576c8b70b1de4c51d61 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 14 Oct 2025 09:26:26 -0400 Subject: [PATCH 013/108] chore: deps --- .github/workflows/terraform.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index a7e8d75a..74f9c600 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -61,10 +61,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - # - name: Install dependencies - # run: | - # sudo snap install concierge --classic - # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + - name: Install dependencies + run: | + sudo snap install --classic astral-uv + sudo snap install just --classic + # sudo snap install concierge --classic + # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Deploy the COS TF product module if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') run: | From ab67f4a0d2e2b2514a9ceab7fd8796954d28a3f1 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 14 Oct 2025 09:28:54 -0400 Subject: [PATCH 014/108] chore --- .github/workflows/terraform.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 74f9c600..5046ee14 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -70,11 +70,8 @@ jobs: - name: Deploy the COS TF product module if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') run: | - just --list - just integration just integration "test_cos_upgrade.py" - name: Deploy the COS Lite TF product module if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos-lite == 'true') run: | - just --list just integration "test_cos_lite_upgrade.py" From 63bab2a05682ec16facad3069ea54e6937d7b328 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 17 Oct 2025 09:36:59 -0400 Subject: [PATCH 015/108] chore --- .github/workflows/terraform.yml | 28 ++------ .github/workflows/upgrade.yaml | 36 ++++++++++ .gitignore | 3 + pyproject.toml | 1 - .../conftest.cpython-310-pytest-8.4.2.pyc | Bin 732 -> 0 bytes ..._lite_upgrade.cpython-310-pytest-8.4.2.pyc | Bin 934 -> 0 bytes ...t_cos_upgrade.cpython-310-pytest-8.4.2.pyc | Bin 914 -> 0 bytes ...est_terraform.cpython-310-pytest-8.4.2.pyc | Bin 1073 -> 0 bytes tests/integration/conftest.py | 18 +++-- tests/integration/cos-lite.tf | 13 ---- .../tls_external/test_upgrade_tls_external.py | 37 ++++++++++ .../cos-lite/tls_external/track-1.tf | 21 ++++++ .../cos-lite/tls_external/track-2.tf | 20 ++++++ .../tls_full/test_upgrade_tls_full.py | 37 ++++++++++ .../integration/cos-lite/tls_full/track-1.tf | 21 ++++++ .../integration/cos-lite/tls_full/track-2.tf | 20 ++++++ .../tls_internal/test_upgrade_tls_internal.py | 28 ++++++++ .../cos-lite/tls_internal/track-1.tf | 11 +++ .../cos-lite/tls_internal/track-2.tf | 10 +++ .../tls_none/test_upgrade_tls_none.py | 28 ++++++++ .../integration/cos-lite/tls_none/track-1.tf | 10 +++ .../integration/cos-lite/tls_none/track-2.tf | 10 +++ tests/integration/cos.tf | 13 ---- tests/integration/helpers.py | 65 ++++++++++++++++++ tests/integration/test_cos_lite_upgrade.py | 55 --------------- tests/integration/test_cos_upgrade.py | 54 --------------- uv.lock | 11 --- 27 files changed, 376 insertions(+), 174 deletions(-) create mode 100644 .github/workflows/upgrade.yaml delete mode 100644 tests/integration/__pycache__/conftest.cpython-310-pytest-8.4.2.pyc delete mode 100644 tests/integration/__pycache__/test_cos_lite_upgrade.cpython-310-pytest-8.4.2.pyc delete mode 100644 tests/integration/__pycache__/test_cos_upgrade.cpython-310-pytest-8.4.2.pyc delete mode 100644 tests/integration/__pycache__/test_terraform.cpython-310-pytest-8.4.2.pyc delete mode 100644 tests/integration/cos-lite.tf create mode 100644 tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py create mode 100644 tests/integration/cos-lite/tls_external/track-1.tf create mode 100644 tests/integration/cos-lite/tls_external/track-2.tf create mode 100644 tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py create mode 100644 tests/integration/cos-lite/tls_full/track-1.tf create mode 100644 tests/integration/cos-lite/tls_full/track-2.tf create mode 100644 tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py create mode 100644 tests/integration/cos-lite/tls_internal/track-1.tf create mode 100644 tests/integration/cos-lite/tls_internal/track-2.tf create mode 100644 tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py create mode 100644 tests/integration/cos-lite/tls_none/track-1.tf create mode 100644 tests/integration/cos-lite/tls_none/track-2.tf delete mode 100644 tests/integration/cos.tf create mode 100644 tests/integration/helpers.py delete mode 100644 tests/integration/test_cos_lite_upgrade.py delete mode 100644 tests/integration/test_cos_upgrade.py diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 5046ee14..7bf5cad0 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -6,16 +6,6 @@ on: - main paths: - "**/*.tf" - workflow_dispatch: - inputs: - cos: - description: 'Deploy the COS TF product module' - required: true - default: false - cos-lite: - description: 'Deploy the COS Lite TF product module' - required: true - default: false jobs: lint-terraform: @@ -55,23 +45,15 @@ jobs: sudo snap install just --classic - name: Validate the Terraform modules run: just validate-terraform - terraform-integration: - name: Test deploy/upgrade Terraform product modules + test-integration: + name: Terraform validate runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install dependencies run: | - sudo snap install --classic astral-uv + sudo snap install terraform --classic sudo snap install just --classic - # sudo snap install concierge --classic - # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - - name: Deploy the COS TF product module - if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos == 'true') - run: | - just integration "test_cos_upgrade.py" - - name: Deploy the COS Lite TF product module - if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.cos-lite == 'true') - run: | - just integration "test_cos_lite_upgrade.py" + - name: Validate the Terraform modules + run: just integration \ No newline at end of file diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yaml new file mode 100644 index 00000000..319df3a8 --- /dev/null +++ b/.github/workflows/upgrade.yaml @@ -0,0 +1,36 @@ +name: Test the Terraform product module + +on: + workflow_dispatch: + inputs: + product: + description: "The type of the product module" + required: true + type: choice + options: + - cos + - cos-lite + scenario: + description: "The cross-track upgrade scenario" + required: true + type: choice + options: + - tls_none + - tls_internal + - tls_none + - tls_full + +jobs: + terraform-test: + name: Test the Terraform product module + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install concierge --classic + sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + - name: Test deployment + run: | + just test tests/integration/${{ inputs.product }}/${{ inputs.scenario }}/test_upgrade_${{ inputs.scenario }}.py diff --git a/.gitignore b/.gitignore index 7c45b081..6f670aa6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Python +__pycache__ + # Terraform **/.terraform/* *.tfstate diff --git a/pyproject.toml b/pyproject.toml index ffba1a71..5d68be1e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,5 +8,4 @@ version = "0.0.0" dependencies = [ "jubilant", "pytest", - "sh", ] diff --git a/tests/integration/__pycache__/conftest.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/conftest.cpython-310-pytest-8.4.2.pyc deleted file mode 100644 index 81c65765b1281e86e9e0ca1cac09ab9bffbeb0f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 732 zcmYjP&2Q5%6t|tU`Dir$yYA$FK~h9ludQ?-pl(vzi*4dAVhG!J^Xe09V7J9D!a!4I{;bijjrk2%b}!mPu(U(h9{_ZXR> zvG?)Op{N#`D?M6d1s^Sh9A%Z}OPT0QR3mFqliyGaIyT)>u%_T+Y&t3xHBT*kdkFma zKo(RlfPF?9<@g#3zrhSO_yTDsch3v8 zCce||$Mwc$m?R2P+dWJqU&~B$6Wl?@yTw9qw%6lC8m|z`WmYX^2U45v)*$U(OaRk4 z0xOrskK-ySIh4?~_W|)1*$3T7-qzTTWry{wyZ>~%{b%rMk+SW%&OY(6Pka)R(AmTP E0PwTN0{{R3 diff --git a/tests/integration/__pycache__/test_cos_lite_upgrade.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/test_cos_lite_upgrade.cpython-310-pytest-8.4.2.pyc deleted file mode 100644 index cd5095b26c0722d746c2c43f0cf56bd01f3f8218..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 934 zcmYjQJ#W)M7`{7y#z_M$5)xa5goKC26iQhLD&k}8g2Z4US&r{aOl+TZccD#`EWpIZ z&XA1!rCXU;_yLuWc+ak?ob`S^ul?LTuWi1!7a&+aUjLo`a}fG%irqz^I0KXK!BIqU ziDKMFQdtCHRN1kEyN(;XZO4nfHu|yO#$McOV-N>z?8kjdsPzrS1B&0F(EbD5=sd$F zTrUrzu~%U7J2;Bhn36SF;T4&YwY9S3kwP0xA8Or4+PE?V2v zrQXUeFyxN1plh$3E&htXfEpXEF_;DHXyZ_Si`TAlHy-V++%3UK`5TjAqZ7^>oG<;1 z%fqrz>}`mz$aoy$<-vo8&EhzehvV^~Nl!um?yQe?izmCq z3+ yc*Z15R!&QHsr^rL(3RGzJwZE;9e3M2?LV(LotNx|`2*w-+J!YE)FpO diff --git a/tests/integration/__pycache__/test_cos_upgrade.cpython-310-pytest-8.4.2.pyc b/tests/integration/__pycache__/test_cos_upgrade.cpython-310-pytest-8.4.2.pyc deleted file mode 100644 index da69b7933cbb7eabd745486b2d4b6feb4acfd15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 914 zcmYjQOOMkq5VoCX(}&naLgKbULL!H4cr43>qD4H8dqDyzmne-L8k)qB?Xugdy#ObE z14!+WzvL??4)6o^#5h^4>S(^1`6ik8n>c(p3=piJum8>dItcwX$^IgcoPo*r02EPN zq8PWHR2D%PRd(#)uHwdSTk&GA^?vNPz8CjeAH+fH`*EKVYJEfTfZ}&3wEsYFbe>`3 zu9pYi*efvk9f0Bures6bcunSHW34TDtk4!yh;mGA!{=mY0|)o)aO=qqQ|AY{gElsG zskgQZ46&musM>31hri-4pvFcU3}!)hv~{Sz!y8w*TaWhE?v7xj{H=+w(Fywv&b5_s z`8LE?WHJfy>hS)9X899lGp;yz{zTqO38$3Yp0? zC(q)(VpWr9i;dwLF$8 z&E}C2FQcMX?4xKkv`hj6N)`=Jl#M~cu$@s+7s^!336?%UjsrZvBPHV%6u&!v#Bq{}w&J6Rp+Z6;Lt{QlSqLg1I(9)U9~VBJuzEGp2# z791SawLaQ3o^BdXYNI~r*{1P4Y{|5!A~}q7Uc_(1@Gjp6BUYqAA%io<$3YU8tjvH^ z01TK2*Z^AdIUZ!de|jKfoQwlaUIbYw(~sP6FrMhTVLc$QV>*x&K(RTd;T;TBlj(EvXM;`#=1os2gDW-hz~)8YCIep7=cSHm69 zROg?1c69KrhI;_rE#(a+SuV3usJ3qMwY3-3v+mVxhk5mQdd7i`YF@ik1{G&XDqyN&l&9y)`!s=`#-%h(FlB6%Y>GE^doKz`Cwcl(|AOKMz str: + target_arg = f"-target module.{target}" if target else "" + var_args = " ".join(f"-var {k}={v}" for k, v in kwargs.items()) + return "-auto-approve " + f"{target_arg} " + var_args + + def apply(self, target: Optional[str] = None, **kwargs): + cmd_str = "terraform apply " + self._args_str(target, **kwargs) + with chdir(self.dir): + subprocess.run(shlex.split(cmd_str), check=True) + + def destroy(self, **kwargs): + cmd_str = "terraform destroy " + self._args_str(None, **kwargs) + with chdir(self.dir): + subprocess.run(shlex.split(cmd_str), check=True) + + +def wait_for_active_idle_without_error(jujus: List[jubilant.Juju]): + for juju in jujus: + print(f"\nwaiting for the model ({juju.model}) to settle ...\n") + juju.wait( + jubilant.all_active, delay=5, timeout=60 * 10, error=jubilant.any_error + ) + juju.wait( + jubilant.all_agents_idle, + delay=5, + timeout=60 * 10, + error=jubilant.any_error, + ) diff --git a/tests/integration/test_cos_lite_upgrade.py b/tests/integration/test_cos_lite_upgrade.py deleted file mode 100644 index 6e4b01c5..00000000 --- a/tests/integration/test_cos_lite_upgrade.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import shutil - -import pytest -import subprocess -import shlex -import jubilant - - -def test_init_cos_lite(tmpdir): - assert "cos lite" == False - temp_tf_dir = tmpdir.mkdir("terraform") - shutil.copy("cos-lite.tf", temp_tf_dir) - os.chdir(temp_tf_dir) - # subprocess.run(shlex.split(("terraform init"))) - - -# @pytest.mark.abort_on_fail -# def test_terraform_deploy(juju: jubilant.Juju): -# subprocess.run( -# shlex.split( -# ( -# f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" -# ) -# ) -# ) -# print("\nwaiting for the model to settle ...\n") -# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - - -# @pytest.mark.abort_on_fail -# def test_terraform_upgrade(juju: jubilant.Juju): -# subprocess.run( -# shlex.split( -# ( -# f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" -# ) -# ) -# ) -# print("\nwaiting for the model to settle ...\n") -# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - - -# @pytest.mark.abort_on_fail -# @pytest.mark.skip( -# reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"' -# ) -# def test_terraform_destroy(juju: jubilant.Juju): -# subprocess.run( -# shlex.split( -# ( -# f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" -# ) -# ) -# ) diff --git a/tests/integration/test_cos_upgrade.py b/tests/integration/test_cos_upgrade.py deleted file mode 100644 index d3c52ec1..00000000 --- a/tests/integration/test_cos_upgrade.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import shutil - -import pytest -import subprocess -import shlex -import jubilant - - -def test_init_cos(tmpdir): - assert "cos" == False - temp_tf_dir = tmpdir.mkdir("terraform") - shutil.copy("cos.tf", temp_tf_dir) - os.chdir(temp_tf_dir) - # subprocess.run(shlex.split(("terraform init"))) - -# @pytest.mark.abort_on_fail -# def test_terraform_deploy(juju: jubilant.Juju): -# subprocess.run( -# shlex.split( -# ( -# f"terraform apply -var model={juju.model} -var channel=1/stable -auto-approve" -# ) -# ) -# ) -# print("\nwaiting for the model to settle ...\n") -# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - - -# @pytest.mark.abort_on_fail -# def test_terraform_upgrade(juju: jubilant.Juju): -# subprocess.run( -# shlex.split( -# ( -# f"terraform apply -var model={juju.model} -var channel=2/edge -auto-approve" -# ) -# ) -# ) -# print("\nwaiting for the model to settle ...\n") -# juju.wait(jubilant.all_agents_idle, delay=5, timeout=60 * 10) - - -# @pytest.mark.abort_on_fail -# @pytest.mark.skip( -# reason='Traefik hits error state on destroying the model due to hook failed: "receive-ca-cert-relation-broken"' -# ) -# def test_terraform_destroy(juju: jubilant.Juju): -# subprocess.run( -# shlex.split( -# ( -# f"terraform destroy -var model={juju.model} -var channel=2/edge -auto-approve" -# ) -# ) -# ) diff --git a/uv.lock b/uv.lock index 1677074e..aff80395 100644 --- a/uv.lock +++ b/uv.lock @@ -51,14 +51,12 @@ source = { virtual = "." } dependencies = [ { name = "jubilant" }, { name = "pytest" }, - { name = "sh" }, ] [package.metadata] requires-dist = [ { name = "jubilant" }, { name = "pytest" }, - { name = "sh" }, ] [[package]] @@ -170,15 +168,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] -[[package]] -name = "sh" -version = "2.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/59/52/f43920223c93e31874677c681b8603d36a40d3d8502d3a37f80d3995d43e/sh-2.2.2.tar.gz", hash = "sha256:653227a7c41a284ec5302173fbc044ee817c7bad5e6e4d8d55741b9aeb9eb65b", size = 345866, upload-time = "2025-02-24T07:16:25.363Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/98/d82f14ac7ffedbd38dfa2383f142b26d18d23ca6cf35a40f4af60df666bd/sh-2.2.2-py3-none-any.whl", hash = "sha256:e0b15b4ae8ffcd399bc8ffddcbd770a43c7a70a24b16773fbb34c001ad5d52af", size = 38295, upload-time = "2025-02-24T07:16:23.782Z" }, -] - [[package]] name = "tomli" version = "2.3.0" From 77eadddc889f465564e18186fd0ce318ab75a082 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 17 Oct 2025 09:39:55 -0400 Subject: [PATCH 016/108] chore --- .github/workflows/terraform.yml | 6 +++--- .github/workflows/upgrade.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 7bf5cad0..0c5a1d69 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -46,14 +46,14 @@ jobs: - name: Validate the Terraform modules run: just validate-terraform test-integration: - name: Terraform validate + name: Terraform integration runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install dependencies run: | - sudo snap install terraform --classic - sudo snap install just --classic + sudo snap install concierge --classic + sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Validate the Terraform modules run: just integration \ No newline at end of file diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yaml index 319df3a8..5ef61a87 100644 --- a/.github/workflows/upgrade.yaml +++ b/.github/workflows/upgrade.yaml @@ -17,7 +17,7 @@ on: options: - tls_none - tls_internal - - tls_none + - tls_external - tls_full jobs: From 703686f3ce29dfce632881477a058f3e54a2e5a1 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 17 Oct 2025 13:12:23 -0400 Subject: [PATCH 017/108] chore: PR convo updates --- .github/workflows/terraform.yml | 2 +- .github/workflows/upgrade.yaml | 2 +- .../tls_external/test_upgrade_tls_external.py | 13 ++++++++----- tests/integration/cos-lite/tls_external/track-1.tf | 1 - .../cos-lite/tls_full/test_upgrade_tls_full.py | 13 ++++++++----- tests/integration/cos-lite/tls_full/track-1.tf | 1 - .../tls_internal/test_upgrade_tls_internal.py | 13 ++++++++----- tests/integration/cos-lite/tls_internal/track-1.tf | 1 - .../cos-lite/tls_none/test_upgrade_tls_none.py | 13 ++++++++----- tests/integration/helpers.py | 1 + 10 files changed, 35 insertions(+), 25 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 0c5a1d69..b704ebec 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -55,5 +55,5 @@ jobs: run: | sudo snap install concierge --classic sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - - name: Validate the Terraform modules + - name: Test Terraform product module upgrade scenarios run: just integration \ No newline at end of file diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yaml index 5ef61a87..05dc2a99 100644 --- a/.github/workflows/upgrade.yaml +++ b/.github/workflows/upgrade.yaml @@ -33,4 +33,4 @@ jobs: sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Test deployment run: | - just test tests/integration/${{ inputs.product }}/${{ inputs.scenario }}/test_upgrade_${{ inputs.scenario }}.py + just integration ${{ inputs.product }}/${{ inputs.scenario }}/test_upgrade_${{ inputs.scenario }}.py diff --git a/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py b/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py index 610924e9..68a4fd4b 100644 --- a/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py +++ b/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py @@ -1,3 +1,9 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with external TLS, and without internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + from pathlib import Path import jubilant @@ -12,9 +18,8 @@ def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): - # GIVEN a module sourced from track n-1 + # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply( # NOTE: "Terraform cannot predict how many instances will be created. To work around this, # use the -target argument to first apply only the resources that the count depends on." @@ -23,15 +28,13 @@ def test_deploy_from_track( cos_model=cos_model.model, ) tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - # THEN the model is active/idle wait_for_active_idle_without_error([ca_model, cos_model]) @pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - # GIVEN a module sourced from track n + # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) # THEN the model is upgraded and is active/idle wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos-lite/tls_external/track-1.tf b/tests/integration/cos-lite/tls_external/track-1.tf index 69fc6d25..abcd6b3b 100644 --- a/tests/integration/cos-lite/tls_external/track-1.tf +++ b/tests/integration/cos-lite/tls_external/track-1.tf @@ -8,7 +8,6 @@ variable "ca_model" { } module "cos-lite" { - # TODO: Add a branch to the module source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" model = var.cos_model channel = "1/stable" diff --git a/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py b/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py index 610924e9..cf43696d 100644 --- a/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py +++ b/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py @@ -1,3 +1,9 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with external and internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + from pathlib import Path import jubilant @@ -12,9 +18,8 @@ def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): - # GIVEN a module sourced from track n-1 + # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply( # NOTE: "Terraform cannot predict how many instances will be created. To work around this, # use the -target argument to first apply only the resources that the count depends on." @@ -23,15 +28,13 @@ def test_deploy_from_track( cos_model=cos_model.model, ) tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - # THEN the model is active/idle wait_for_active_idle_without_error([ca_model, cos_model]) @pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - # GIVEN a module sourced from track n + # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) # THEN the model is upgraded and is active/idle wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos-lite/tls_full/track-1.tf b/tests/integration/cos-lite/tls_full/track-1.tf index 44982b8f..4adf596a 100644 --- a/tests/integration/cos-lite/tls_full/track-1.tf +++ b/tests/integration/cos-lite/tls_full/track-1.tf @@ -8,7 +8,6 @@ variable "ca_model" { } module "cos-lite" { - # TODO: Add a branch to the module source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" model = var.cos_model channel = "1/stable" diff --git a/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py b/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py index 751692af..a514266e 100644 --- a/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py +++ b/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py @@ -1,3 +1,9 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with internal TLS, and without external TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + from pathlib import Path import jubilant @@ -10,19 +16,16 @@ @pytest.mark.abort_on_fail def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): - # GIVEN a module sourced from track n-1 + # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply(model=cos_model.model) - # THEN the model is active/idle wait_for_active_idle_without_error([cos_model]) @pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): - # GIVEN a module sourced from track n + # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply(model=cos_model.model) # THEN the model is upgraded and is active/idle wait_for_active_idle_without_error([cos_model]) diff --git a/tests/integration/cos-lite/tls_internal/track-1.tf b/tests/integration/cos-lite/tls_internal/track-1.tf index 6d3a6746..e6f5248b 100644 --- a/tests/integration/cos-lite/tls_internal/track-1.tf +++ b/tests/integration/cos-lite/tls_internal/track-1.tf @@ -1,5 +1,4 @@ module "cos-lite" { - # TODO: Add a branch to the module source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite" model = var.model channel = "1/stable" diff --git a/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py b/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py index 751692af..94b324d3 100644 --- a/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py +++ b/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py @@ -1,3 +1,9 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS without external and internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + from pathlib import Path import jubilant @@ -10,19 +16,16 @@ @pytest.mark.abort_on_fail def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): - # GIVEN a module sourced from track n-1 + # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply(model=cos_model.model) - # THEN the model is active/idle wait_for_active_idle_without_error([cos_model]) @pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): - # GIVEN a module sourced from track n + # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) - # WHEN deployed with Terraform tf_manager.apply(model=cos_model.model) # THEN the model is upgraded and is active/idle wait_for_active_idle_without_error([cos_model]) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 6461ffe4..837bc688 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -54,6 +54,7 @@ def destroy(self, **kwargs): def wait_for_active_idle_without_error(jujus: List[jubilant.Juju]): for juju in jujus: print(f"\nwaiting for the model ({juju.model}) to settle ...\n") + juju.wait(jubilant.all_active, delay=5, timeout=60 * 10) juju.wait( jubilant.all_active, delay=5, timeout=60 * 10, error=jubilant.any_error ) From d799a71e169f4d9ffb5c37fb6288489425a57584 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Sun, 19 Oct 2025 10:26:54 -0400 Subject: [PATCH 018/108] GH CI microceph job --- .github/workflows/_setup_microceph.yml | 22 ++++++++ .github/workflows/terraform.yml | 3 + .../workflows/{upgrade.yaml => upgrade.yml} | 0 pyproject.toml | 1 + terraform/cos/variables.tf | 3 + terraform/loki/variables.tf | 2 +- terraform/mimir/variables.tf | 2 +- terraform/tempo/variables.tf | 2 +- .../tls_external/test_upgrade_tls_external.py | 55 +++++++++++++++++++ tests/integration/cos/tls_external/track-2.tf | 45 +++++++++++++++ .../cos/tls_full/test_upgrade_tls_full.py | 55 +++++++++++++++++++ tests/integration/cos/tls_full/track-2.tf | 45 +++++++++++++++ .../tls_internal/test_upgrade_tls_internal.py | 37 +++++++++++++ tests/integration/cos/tls_internal/track-2.tf | 35 ++++++++++++ .../cos/tls_none/test_upgrade_tls_none.py | 37 +++++++++++++ tests/integration/cos/tls_none/track-2.tf | 35 ++++++++++++ tests/integration/helpers.py | 15 ++--- uv.lock | 11 ++++ 18 files changed, 391 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/_setup_microceph.yml rename .github/workflows/{upgrade.yaml => upgrade.yml} (100%) create mode 100644 tests/integration/cos/tls_external/test_upgrade_tls_external.py create mode 100644 tests/integration/cos/tls_external/track-2.tf create mode 100644 tests/integration/cos/tls_full/test_upgrade_tls_full.py create mode 100644 tests/integration/cos/tls_full/track-2.tf create mode 100644 tests/integration/cos/tls_internal/test_upgrade_tls_internal.py create mode 100644 tests/integration/cos/tls_internal/track-2.tf create mode 100644 tests/integration/cos/tls_none/test_upgrade_tls_none.py create mode 100644 tests/integration/cos/tls_none/track-2.tf diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml new file mode 100644 index 00000000..1b323a9c --- /dev/null +++ b/.github/workflows/_setup_microceph.yml @@ -0,0 +1,22 @@ +name: Terraform + +on: + workflow_call: + +jobs: + microceph: + name: microceph + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install and configure microceph + run: | + set -euo pipefail + sudo snap install microceph + sudo snap refresh --hold microceph + sudo microceph cluster bootstrap + sudo microceph disk add loop,4G,3 + sudo microceph enable rgw --port 8080 --ssl-port 8443 + sudo microceph.radosgw-admin user create --uid=user --display-name=User + sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key \ No newline at end of file diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index b704ebec..a95b20d2 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -51,6 +51,9 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Install and setup Microceph + # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade - name: Install dependencies run: | sudo snap install concierge --classic diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yml similarity index 100% rename from .github/workflows/upgrade.yaml rename to .github/workflows/upgrade.yml diff --git a/pyproject.toml b/pyproject.toml index 5d68be1e..f5f39b74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,4 +8,5 @@ version = "0.0.0" dependencies = [ "jubilant", "pytest", + "tenacity", ] diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 2207f44d..52f72e8b 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -71,18 +71,21 @@ variable "loki_bucket" { description = "Loki bucket name" type = string sensitive = true + default = "loki" } variable "mimir_bucket" { description = "Mimir bucket name" type = string sensitive = true + default = "tempo" } variable "tempo_bucket" { description = "Tempo bucket name" type = string sensitive = true + default = "tempo" } # -------------- # Application configurations -------------- diff --git a/terraform/loki/variables.tf b/terraform/loki/variables.tf index 0803d03e..087d6be7 100644 --- a/terraform/loki/variables.tf +++ b/terraform/loki/variables.tf @@ -161,7 +161,7 @@ variable "worker_revision" { variable "s3_integrator_revision" { description = "Revision number of the s3-integrator application" type = number - default = 157 # FIXME: https://github.com/canonical/observability/issues/342 + default = null } # -------------- # Storage directives -------------- diff --git a/terraform/mimir/variables.tf b/terraform/mimir/variables.tf index b6b4e8d2..e34dd40b 100644 --- a/terraform/mimir/variables.tf +++ b/terraform/mimir/variables.tf @@ -161,7 +161,7 @@ variable "worker_revision" { variable "s3_integrator_revision" { description = "Revision number of the s3-integrator application" type = number - default = 157 # FIXME: https://github.com/canonical/observability/issues/342 + default = null } # -------------- # Storage directives -------------- diff --git a/terraform/tempo/variables.tf b/terraform/tempo/variables.tf index 4c99c1bd..c0cee7a7 100644 --- a/terraform/tempo/variables.tf +++ b/terraform/tempo/variables.tf @@ -197,7 +197,7 @@ variable "worker_revision" { variable "s3_integrator_revision" { description = "Revision number of the s3-integrator application" type = number - default = 157 # FIXME: https://github.com/canonical/observability/issues/342 + default = null } # -------------- # Storage directives -------------- diff --git a/tests/integration/cos/tls_external/test_upgrade_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_tls_external.py new file mode 100644 index 00000000..3ccbf289 --- /dev/null +++ b/tests/integration/cos/tls_external/test_upgrade_tls_external.py @@ -0,0 +1,55 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with external TLS, and without internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +from pathlib import Path +from subprocess import CalledProcessError + +import jubilant +from helpers import wait_for_active_idle_without_error +from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +S3_ENDPOINT = { + "s3_endpoint": "http://192.168.88.12:8080", + "s3_secret_key": "secret-key", + "s3_access_key": "access-key", +} + + +@retry( + retry=retry_if_exception_type(CalledProcessError), + wait=wait_fixed(10), + stop=stop_after_attempt(3), + reraise=True, +) +def apply_with_retry(tf_manager, **kwargs): + # FIXME: https://github.com/juju/terraform-provider-juju/issues/955 + tf_manager.apply(**kwargs) + + +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + # NOTE: "Terraform cannot predict how many instances will be created. To work around this, + # use the -target argument to first apply only the resources that the count depends on." + apply_with_retry( + tf_manager, + **{ + **{ + "target": "ssc", + "ca_model": ca_model.model, + "cos_model": cos_model.model, + }, + **S3_ENDPOINT, + }, + ) + apply_with_retry( + tf_manager, + **{**{"ca_model": ca_model.model, "cos_model": cos_model.model}, **S3_ENDPOINT}, + ) + wait_for_active_idle_without_error([cos_model], timeout=2400) diff --git a/tests/integration/cos/tls_external/track-2.tf b/tests/integration/cos/tls_external/track-2.tf new file mode 100644 index 00000000..69969507 --- /dev/null +++ b/tests/integration/cos/tls_external/track-2.tf @@ -0,0 +1,45 @@ +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model = var.ca_model +} + +variable "ca_model" { + type = string +} + +module "cos" { + # source = "git::https://github.com/canonical/observability-stack//terraform/cos" + source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" + model = var.cos_model + channel = "2/edge" + internal_tls = "false" + external_certificates_offer_url = module.ssc.offers.certificates.url + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + s3_integrator = { revision = 243 } + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} + +variable "cos_model" { + type = string +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} diff --git a/tests/integration/cos/tls_full/test_upgrade_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_tls_full.py new file mode 100644 index 00000000..63877895 --- /dev/null +++ b/tests/integration/cos/tls_full/test_upgrade_tls_full.py @@ -0,0 +1,55 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with external and internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +from pathlib import Path +from subprocess import CalledProcessError + +import jubilant +from helpers import wait_for_active_idle_without_error +from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +S3_ENDPOINT = { + "s3_endpoint": "http://192.168.88.12:8080", + "s3_secret_key": "secret-key", + "s3_access_key": "access-key", +} + + +@retry( + retry=retry_if_exception_type(CalledProcessError), + wait=wait_fixed(10), + stop=stop_after_attempt(3), + reraise=True, +) +def apply_with_retry(tf_manager, **kwargs): + # FIXME: https://github.com/juju/terraform-provider-juju/issues/955 + tf_manager.apply(**kwargs) + + +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + # NOTE: "Terraform cannot predict how many instances will be created. To work around this, + # use the -target argument to first apply only the resources that the count depends on." + apply_with_retry( + tf_manager, + **{ + **{ + "target": "ssc", + "ca_model": ca_model.model, + "cos_model": cos_model.model, + }, + **S3_ENDPOINT, + }, + ) + apply_with_retry( + tf_manager, + **{**{"ca_model": ca_model.model, "cos_model": cos_model.model}, **S3_ENDPOINT}, + ) + wait_for_active_idle_without_error([cos_model], timeout=2400) diff --git a/tests/integration/cos/tls_full/track-2.tf b/tests/integration/cos/tls_full/track-2.tf new file mode 100644 index 00000000..a7828cd8 --- /dev/null +++ b/tests/integration/cos/tls_full/track-2.tf @@ -0,0 +1,45 @@ +module "ssc" { + source = "git::https://github.com/canonical/self-signed-certificates-operator//terraform" + model = var.ca_model +} + +variable "ca_model" { + type = string +} + +module "cos" { + # source = "git::https://github.com/canonical/observability-stack//terraform/cos" + source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" + model = var.cos_model + channel = "2/edge" + internal_tls = "true" + external_certificates_offer_url = module.ssc.offers.certificates.url + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + s3_integrator = { revision = 243 } + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} + +variable "cos_model" { + type = string +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} diff --git a/tests/integration/cos/tls_internal/test_upgrade_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_tls_internal.py new file mode 100644 index 00000000..f934df70 --- /dev/null +++ b/tests/integration/cos/tls_internal/test_upgrade_tls_internal.py @@ -0,0 +1,37 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with internal TLS, and without external TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +from pathlib import Path +from subprocess import CalledProcessError + +import jubilant +from helpers import wait_for_active_idle_without_error +from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +S3_ENDPOINT = { + "s3_endpoint": "http://192.168.88.12:8080", + "s3_secret_key": "secret-key", + "s3_access_key": "access-key", +} + + +@retry( + retry=retry_if_exception_type(CalledProcessError), + wait=wait_fixed(10), + stop=stop_after_attempt(3), + reraise=True, +) +def apply_with_retry(tf_manager, **kwargs): + # FIXME: https://github.com/juju/terraform-provider-juju/issues/955 + tf_manager.apply(**kwargs) + + +def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + apply_with_retry(tf_manager, **{**{"model": cos_model.model}, **S3_ENDPOINT}) + wait_for_active_idle_without_error([cos_model], timeout=2400) diff --git a/tests/integration/cos/tls_internal/track-2.tf b/tests/integration/cos/tls_internal/track-2.tf new file mode 100644 index 00000000..0fb3a557 --- /dev/null +++ b/tests/integration/cos/tls_internal/track-2.tf @@ -0,0 +1,35 @@ +module "cos" { + # source = "git::https://github.com/canonical/observability-stack//terraform/cos" + source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" + model = var.model + channel = "2/edge" + internal_tls = "true" + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + s3_integrator = { revision = 243 } + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} + +variable "model" { + type = string +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} diff --git a/tests/integration/cos/tls_none/test_upgrade_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_tls_none.py new file mode 100644 index 00000000..fd85953a --- /dev/null +++ b/tests/integration/cos/tls_none/test_upgrade_tls_none.py @@ -0,0 +1,37 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS without external and internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +from pathlib import Path +from subprocess import CalledProcessError + +import jubilant +from helpers import wait_for_active_idle_without_error +from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +S3_ENDPOINT = { + "s3_endpoint": "http://192.168.88.12:8080", + "s3_secret_key": "secret-key", + "s3_access_key": "access-key", +} + + +@retry( + retry=retry_if_exception_type(CalledProcessError), + wait=wait_fixed(10), + stop=stop_after_attempt(3), + reraise=True, +) +def apply_with_retry(tf_manager, **kwargs): + # FIXME: https://github.com/juju/terraform-provider-juju/issues/955 + tf_manager.apply(**kwargs) + + +def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + apply_with_retry(tf_manager, **{**{"model": cos_model.model}, **S3_ENDPOINT}) + wait_for_active_idle_without_error([cos_model], timeout=2400) diff --git a/tests/integration/cos/tls_none/track-2.tf b/tests/integration/cos/tls_none/track-2.tf new file mode 100644 index 00000000..d4bb294f --- /dev/null +++ b/tests/integration/cos/tls_none/track-2.tf @@ -0,0 +1,35 @@ +module "cos" { + # source = "git::https://github.com/canonical/observability-stack//terraform/cos" + source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" # TODO: + model = var.model + channel = "2/edge" + internal_tls = "false" + + s3_endpoint = var.s3_endpoint + s3_secret_key = var.s3_secret_key + s3_access_key = var.s3_access_key + + s3_integrator = { revision = 243 } + loki_coordinator = { units = 1 } + loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } + mimir_coordinator = { units = 1 } + mimir_worker = { backend_units = 1, read_units = 1, write_units = 1 } + tempo_coordinator = { units = 1 } + tempo_worker = { compactor_units = 1, distributor_units = 1, ingester_units = 1, metrics_generator_units = 1, querier_units = 1, query_frontend_units = 1 } +} + +variable "model" { + type = string +} + +variable "s3_endpoint" { + type = string +} + +variable "s3_secret_key" { + type = string +} + +variable "s3_access_key" { + type = string +} diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 837bc688..6cf71526 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -51,16 +51,9 @@ def destroy(self, **kwargs): subprocess.run(shlex.split(cmd_str), check=True) -def wait_for_active_idle_without_error(jujus: List[jubilant.Juju]): +def wait_for_active_idle_without_error(jujus: List[jubilant.Juju], timeout: int = 600): for juju in jujus: print(f"\nwaiting for the model ({juju.model}) to settle ...\n") - juju.wait(jubilant.all_active, delay=5, timeout=60 * 10) - juju.wait( - jubilant.all_active, delay=5, timeout=60 * 10, error=jubilant.any_error - ) - juju.wait( - jubilant.all_agents_idle, - delay=5, - timeout=60 * 10, - error=jubilant.any_error, - ) + juju.wait(jubilant.all_active, delay=5, timeout=timeout) + juju.wait(jubilant.all_active, delay=5, timeout=60, error=jubilant.any_error) + # juju.wait(jubilant.all_agents_idle, delay=5, timeout=60, error=jubilant.any_error) diff --git a/uv.lock b/uv.lock index aff80395..ba942eb0 100644 --- a/uv.lock +++ b/uv.lock @@ -51,12 +51,14 @@ source = { virtual = "." } dependencies = [ { name = "jubilant" }, { name = "pytest" }, + { name = "tenacity" }, ] [package.metadata] requires-dist = [ { name = "jubilant" }, { name = "pytest" }, + { name = "tenacity" }, ] [[package]] @@ -168,6 +170,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] +[[package]] +name = "tenacity" +version = "9.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" }, +] + [[package]] name = "tomli" version = "2.3.0" From b0f97387e35e5d755a096f4de64a6209d45c9c91 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Sun, 19 Oct 2025 10:31:26 -0400 Subject: [PATCH 019/108] chore --- .github/workflows/terraform.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index a95b20d2..9126be87 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -45,15 +45,21 @@ jobs: sudo snap install just --classic - name: Validate the Terraform modules run: just validate-terraform + setup-microceph: + name: Install and setup Microceph + uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch + if: needs.ci-ignore.outputs.any_modified == 'true' + secrets: inherit + # with: + # charm-path: ${{ inputs.charm-path }} test-integration: name: Terraform integration runs-on: ubuntu-latest + needs: + - setup-microceph steps: - name: Checkout uses: actions/checkout@v4 - - name: Install and setup Microceph - # TODO: Fix branch - uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade - name: Install dependencies run: | sudo snap install concierge --classic From e87fe63fb7b14d642a6eede2a172bd69b2e85163 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Sun, 19 Oct 2025 10:32:22 -0400 Subject: [PATCH 020/108] test --- .github/workflows/terraform.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 9126be87..39d1c53f 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -48,7 +48,6 @@ jobs: setup-microceph: name: Install and setup Microceph uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch - if: needs.ci-ignore.outputs.any_modified == 'true' secrets: inherit # with: # charm-path: ${{ inputs.charm-path }} From a84328629811f138283483fee8e7f0eab9939591 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Sun, 19 Oct 2025 10:42:24 -0400 Subject: [PATCH 021/108] test --- .github/workflows/upgrade.yml | 2 +- ...upgrade_tls_external.py => test_upgrade_cos_tls_external.py} | 0 .../{test_upgrade_tls_full.py => test_upgrade_cos_tls_full.py} | 0 ...upgrade_tls_internal.py => test_upgrade_cos_tls_internal.py} | 0 .../{test_upgrade_tls_none.py => test_upgrade_cos_tls_none.py} | 0 .../tls_external/test_upgrade_cos_lite_tls_external.py} | 0 .../integration/{cos-lite => cos_lite}/tls_external/track-1.tf | 0 .../integration/{cos-lite => cos_lite}/tls_external/track-2.tf | 0 .../tls_full/test_upgrade_cos_lite_tls_full.py} | 0 tests/integration/{cos-lite => cos_lite}/tls_full/track-1.tf | 0 tests/integration/{cos-lite => cos_lite}/tls_full/track-2.tf | 0 .../tls_internal/test_upgrade_cos_lite_tls_internal.py} | 0 .../integration/{cos-lite => cos_lite}/tls_internal/track-1.tf | 0 .../integration/{cos-lite => cos_lite}/tls_internal/track-2.tf | 0 .../tls_none/test_upgrade_cos_lite_tls_none.py} | 0 tests/integration/{cos-lite => cos_lite}/tls_none/track-1.tf | 0 tests/integration/{cos-lite => cos_lite}/tls_none/track-2.tf | 0 17 files changed, 1 insertion(+), 1 deletion(-) rename tests/integration/cos/tls_external/{test_upgrade_tls_external.py => test_upgrade_cos_tls_external.py} (100%) rename tests/integration/cos/tls_full/{test_upgrade_tls_full.py => test_upgrade_cos_tls_full.py} (100%) rename tests/integration/cos/tls_internal/{test_upgrade_tls_internal.py => test_upgrade_cos_tls_internal.py} (100%) rename tests/integration/cos/tls_none/{test_upgrade_tls_none.py => test_upgrade_cos_tls_none.py} (100%) rename tests/integration/{cos-lite/tls_external/test_upgrade_tls_external.py => cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py} (100%) rename tests/integration/{cos-lite => cos_lite}/tls_external/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_external/track-2.tf (100%) rename tests/integration/{cos-lite/tls_full/test_upgrade_tls_full.py => cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py} (100%) rename tests/integration/{cos-lite => cos_lite}/tls_full/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_full/track-2.tf (100%) rename tests/integration/{cos-lite/tls_internal/test_upgrade_tls_internal.py => cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py} (100%) rename tests/integration/{cos-lite => cos_lite}/tls_internal/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_internal/track-2.tf (100%) rename tests/integration/{cos-lite/tls_none/test_upgrade_tls_none.py => cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py} (100%) rename tests/integration/{cos-lite => cos_lite}/tls_none/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_none/track-2.tf (100%) diff --git a/.github/workflows/upgrade.yml b/.github/workflows/upgrade.yml index 05dc2a99..bf522551 100644 --- a/.github/workflows/upgrade.yml +++ b/.github/workflows/upgrade.yml @@ -33,4 +33,4 @@ jobs: sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Test deployment run: | - just integration ${{ inputs.product }}/${{ inputs.scenario }}/test_upgrade_${{ inputs.scenario }}.py + just integration ${{ inputs.product }}/${{ inputs.scenario }}/test_upgrade_${{ inputs.product }}_${{ inputs.scenario }}.py diff --git a/tests/integration/cos/tls_external/test_upgrade_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py similarity index 100% rename from tests/integration/cos/tls_external/test_upgrade_tls_external.py rename to tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py diff --git a/tests/integration/cos/tls_full/test_upgrade_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py similarity index 100% rename from tests/integration/cos/tls_full/test_upgrade_tls_full.py rename to tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py diff --git a/tests/integration/cos/tls_internal/test_upgrade_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py similarity index 100% rename from tests/integration/cos/tls_internal/test_upgrade_tls_internal.py rename to tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py diff --git a/tests/integration/cos/tls_none/test_upgrade_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py similarity index 100% rename from tests/integration/cos/tls_none/test_upgrade_tls_none.py rename to tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py diff --git a/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py similarity index 100% rename from tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py rename to tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py diff --git a/tests/integration/cos-lite/tls_external/track-1.tf b/tests/integration/cos_lite/tls_external/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_external/track-1.tf rename to tests/integration/cos_lite/tls_external/track-1.tf diff --git a/tests/integration/cos-lite/tls_external/track-2.tf b/tests/integration/cos_lite/tls_external/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_external/track-2.tf rename to tests/integration/cos_lite/tls_external/track-2.tf diff --git a/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py similarity index 100% rename from tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py rename to tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py diff --git a/tests/integration/cos-lite/tls_full/track-1.tf b/tests/integration/cos_lite/tls_full/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_full/track-1.tf rename to tests/integration/cos_lite/tls_full/track-1.tf diff --git a/tests/integration/cos-lite/tls_full/track-2.tf b/tests/integration/cos_lite/tls_full/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_full/track-2.tf rename to tests/integration/cos_lite/tls_full/track-2.tf diff --git a/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py b/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py similarity index 100% rename from tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py rename to tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py diff --git a/tests/integration/cos-lite/tls_internal/track-1.tf b/tests/integration/cos_lite/tls_internal/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_internal/track-1.tf rename to tests/integration/cos_lite/tls_internal/track-1.tf diff --git a/tests/integration/cos-lite/tls_internal/track-2.tf b/tests/integration/cos_lite/tls_internal/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_internal/track-2.tf rename to tests/integration/cos_lite/tls_internal/track-2.tf diff --git a/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py b/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py similarity index 100% rename from tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py rename to tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py diff --git a/tests/integration/cos-lite/tls_none/track-1.tf b/tests/integration/cos_lite/tls_none/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_none/track-1.tf rename to tests/integration/cos_lite/tls_none/track-1.tf diff --git a/tests/integration/cos-lite/tls_none/track-2.tf b/tests/integration/cos_lite/tls_none/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_none/track-2.tf rename to tests/integration/cos_lite/tls_none/track-2.tf From 06ae8a135e4da22698963a69686cc2f60a817350 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Sun, 19 Oct 2025 11:23:49 -0400 Subject: [PATCH 022/108] test --- terraform/cos/variables.tf | 3 --- terraform/loki/variables.tf | 2 +- terraform/mimir/variables.tf | 2 +- terraform/tempo/variables.tf | 2 +- tests/integration/cos/tls_external/track-2.tf | 3 +-- tests/integration/cos/tls_full/track-2.tf | 3 +-- tests/integration/cos/tls_internal/track-2.tf | 4 +--- tests/integration/cos/tls_none/track-2.tf | 3 +-- 8 files changed, 7 insertions(+), 15 deletions(-) diff --git a/terraform/cos/variables.tf b/terraform/cos/variables.tf index 52f72e8b..2207f44d 100644 --- a/terraform/cos/variables.tf +++ b/terraform/cos/variables.tf @@ -71,21 +71,18 @@ variable "loki_bucket" { description = "Loki bucket name" type = string sensitive = true - default = "loki" } variable "mimir_bucket" { description = "Mimir bucket name" type = string sensitive = true - default = "tempo" } variable "tempo_bucket" { description = "Tempo bucket name" type = string sensitive = true - default = "tempo" } # -------------- # Application configurations -------------- diff --git a/terraform/loki/variables.tf b/terraform/loki/variables.tf index 087d6be7..0803d03e 100644 --- a/terraform/loki/variables.tf +++ b/terraform/loki/variables.tf @@ -161,7 +161,7 @@ variable "worker_revision" { variable "s3_integrator_revision" { description = "Revision number of the s3-integrator application" type = number - default = null + default = 157 # FIXME: https://github.com/canonical/observability/issues/342 } # -------------- # Storage directives -------------- diff --git a/terraform/mimir/variables.tf b/terraform/mimir/variables.tf index e34dd40b..b6b4e8d2 100644 --- a/terraform/mimir/variables.tf +++ b/terraform/mimir/variables.tf @@ -161,7 +161,7 @@ variable "worker_revision" { variable "s3_integrator_revision" { description = "Revision number of the s3-integrator application" type = number - default = null + default = 157 # FIXME: https://github.com/canonical/observability/issues/342 } # -------------- # Storage directives -------------- diff --git a/terraform/tempo/variables.tf b/terraform/tempo/variables.tf index c0cee7a7..4c99c1bd 100644 --- a/terraform/tempo/variables.tf +++ b/terraform/tempo/variables.tf @@ -197,7 +197,7 @@ variable "worker_revision" { variable "s3_integrator_revision" { description = "Revision number of the s3-integrator application" type = number - default = null + default = 157 # FIXME: https://github.com/canonical/observability/issues/342 } # -------------- # Storage directives -------------- diff --git a/tests/integration/cos/tls_external/track-2.tf b/tests/integration/cos/tls_external/track-2.tf index 69969507..43271775 100644 --- a/tests/integration/cos/tls_external/track-2.tf +++ b/tests/integration/cos/tls_external/track-2.tf @@ -8,8 +8,7 @@ variable "ca_model" { } module "cos" { - # source = "git::https://github.com/canonical/observability-stack//terraform/cos" - source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=feat/refactor-buckets" model = var.cos_model channel = "2/edge" internal_tls = "false" diff --git a/tests/integration/cos/tls_full/track-2.tf b/tests/integration/cos/tls_full/track-2.tf index a7828cd8..aad5ef04 100644 --- a/tests/integration/cos/tls_full/track-2.tf +++ b/tests/integration/cos/tls_full/track-2.tf @@ -8,8 +8,7 @@ variable "ca_model" { } module "cos" { - # source = "git::https://github.com/canonical/observability-stack//terraform/cos" - source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=feat/refactor-buckets" model = var.cos_model channel = "2/edge" internal_tls = "true" diff --git a/tests/integration/cos/tls_internal/track-2.tf b/tests/integration/cos/tls_internal/track-2.tf index 0fb3a557..b14e18d4 100644 --- a/tests/integration/cos/tls_internal/track-2.tf +++ b/tests/integration/cos/tls_internal/track-2.tf @@ -1,7 +1,5 @@ module "cos" { - # source = "git::https://github.com/canonical/observability-stack//terraform/cos" - source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" - model = var.model + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=feat/refactor-buckets" channel = "2/edge" internal_tls = "true" diff --git a/tests/integration/cos/tls_none/track-2.tf b/tests/integration/cos/tls_none/track-2.tf index d4bb294f..048338d6 100644 --- a/tests/integration/cos/tls_none/track-2.tf +++ b/tests/integration/cos/tls_none/track-2.tf @@ -1,6 +1,5 @@ module "cos" { - # source = "git::https://github.com/canonical/observability-stack//terraform/cos" - source = "/home/mt/work/canonical/repos/observability-stack/terraform/cos" # TODO: + source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=feat/refactor-buckets" model = var.model channel = "2/edge" internal_tls = "false" From 3e51b56019c44a08b0a12349d5b36b57181e1a59 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 08:57:24 -0400 Subject: [PATCH 023/108] remove revision pin --- tests/integration/cos/tls_external/track-2.tf | 1 - tests/integration/cos/tls_full/track-2.tf | 1 - tests/integration/cos/tls_internal/track-2.tf | 2 +- tests/integration/cos/tls_none/track-2.tf | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/integration/cos/tls_external/track-2.tf b/tests/integration/cos/tls_external/track-2.tf index 43271775..76f8dabb 100644 --- a/tests/integration/cos/tls_external/track-2.tf +++ b/tests/integration/cos/tls_external/track-2.tf @@ -18,7 +18,6 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key - s3_integrator = { revision = 243 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } diff --git a/tests/integration/cos/tls_full/track-2.tf b/tests/integration/cos/tls_full/track-2.tf index aad5ef04..1fb3ab6d 100644 --- a/tests/integration/cos/tls_full/track-2.tf +++ b/tests/integration/cos/tls_full/track-2.tf @@ -18,7 +18,6 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key - s3_integrator = { revision = 243 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } diff --git a/tests/integration/cos/tls_internal/track-2.tf b/tests/integration/cos/tls_internal/track-2.tf index b14e18d4..580a14a4 100644 --- a/tests/integration/cos/tls_internal/track-2.tf +++ b/tests/integration/cos/tls_internal/track-2.tf @@ -1,5 +1,6 @@ module "cos" { source = "git::https://github.com/canonical/observability-stack//terraform/cos?ref=feat/refactor-buckets" + model = var.model channel = "2/edge" internal_tls = "true" @@ -7,7 +8,6 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key - s3_integrator = { revision = 243 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } diff --git a/tests/integration/cos/tls_none/track-2.tf b/tests/integration/cos/tls_none/track-2.tf index 048338d6..d7825a0c 100644 --- a/tests/integration/cos/tls_none/track-2.tf +++ b/tests/integration/cos/tls_none/track-2.tf @@ -8,7 +8,6 @@ module "cos" { s3_secret_key = var.s3_secret_key s3_access_key = var.s3_access_key - s3_integrator = { revision = 243 } loki_coordinator = { units = 1 } loki_worker = { backend_units = 1, read_units = 1, write_units = 1 } mimir_coordinator = { units = 1 } From 5b40cc60738e023a155ae82f4f1edbbb45bc5686 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 09:52:57 -0400 Subject: [PATCH 024/108] test --- .github/workflows/_setup_microceph.yml | 2 ++ .github/workflows/terraform.yml | 28 +++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 1b323a9c..9feffdeb 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -17,6 +17,8 @@ jobs: sudo snap refresh --hold microceph sudo microceph cluster bootstrap sudo microceph disk add loop,4G,3 + sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 + sudo microceph.ceph -s sudo microceph.radosgw-admin user create --uid=user --display-name=User sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key \ No newline at end of file diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 39d1c53f..dbe58924 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -51,17 +51,17 @@ jobs: secrets: inherit # with: # charm-path: ${{ inputs.charm-path }} - test-integration: - name: Terraform integration - runs-on: ubuntu-latest - needs: - - setup-microceph - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install dependencies - run: | - sudo snap install concierge --classic - sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - - name: Test Terraform product module upgrade scenarios - run: just integration \ No newline at end of file + # test-integration: + # name: Terraform integration + # runs-on: ubuntu-latest + # needs: + # - setup-microceph + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # - name: Install dependencies + # run: | + # sudo snap install concierge --classic + # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + # - name: Test Terraform product module upgrade scenarios + # run: just integration \ No newline at end of file From 7f49b702f9e8f311bf671d431486ab04bec46544 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 09:59:24 -0400 Subject: [PATCH 025/108] chore: reduce Ceph disk size --- .github/workflows/_setup_microceph.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 9feffdeb..9df907e6 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -16,7 +16,7 @@ jobs: sudo snap install microceph sudo snap refresh --hold microceph sudo microceph cluster bootstrap - sudo microceph disk add loop,4G,3 + sudo microceph disk add loop,2G,3 sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.ceph -s From 26c5ba44cf7a9cdca2da5ecd110106f4eaf389b2 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 10:26:25 -0400 Subject: [PATCH 026/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 9df907e6..ac00f133 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -16,7 +16,7 @@ jobs: sudo snap install microceph sudo snap refresh --hold microceph sudo microceph cluster bootstrap - sudo microceph disk add loop,2G,3 + sudo microceph disk add loop,2G,1 sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.ceph -s From c5f907ee2a9297d76fb6149d2633bb65a9f5c223 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 10:40:14 -0400 Subject: [PATCH 027/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index ac00f133..99e48196 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -14,9 +14,12 @@ jobs: run: | set -euo pipefail sudo snap install microceph - sudo snap refresh --hold microceph + # sudo snap refresh --hold microceph sudo microceph cluster bootstrap - sudo microceph disk add loop,2G,1 + sudo ceph config set mon osd_pool_default_size 1 + sudo ceph config set mon osd_pool_default_min_size 1 + sudo ceph status + sudo microceph disk add loop,4G,1 sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.ceph -s From bf047ac19fd266abe9d88ccfedf1f29d901df98b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 10:49:17 -0400 Subject: [PATCH 028/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 99e48196..130a6a26 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -16,10 +16,10 @@ jobs: sudo snap install microceph # sudo snap refresh --hold microceph sudo microceph cluster bootstrap - sudo ceph config set mon osd_pool_default_size 1 - sudo ceph config set mon osd_pool_default_min_size 1 + # sudo ceph config set mon osd_pool_default_size 1 + sudo ceph status + sudo microceph disk add loop,4G,3 sudo ceph status - sudo microceph disk add loop,4G,1 sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.ceph -s From c428a1a89449e8fc4f3dbb3d6fa2971a811a8d6e Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:03:07 -0400 Subject: [PATCH 029/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 130a6a26..ecd1c629 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -12,16 +12,13 @@ jobs: uses: actions/checkout@v4 - name: Install and configure microceph run: | - set -euo pipefail sudo snap install microceph - # sudo snap refresh --hold microceph sudo microceph cluster bootstrap # sudo ceph config set mon osd_pool_default_size 1 - sudo ceph status + sudo microceph status sudo microceph disk add loop,4G,3 - sudo ceph status + sudo microceph status sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 - sudo microceph.ceph -s sudo microceph.radosgw-admin user create --uid=user --display-name=User sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key \ No newline at end of file From 5786518f8ac2296e2869459619ad3748cb5b2e0c Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:04:53 -0400 Subject: [PATCH 030/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index ecd1c629..69b0f474 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -21,4 +21,5 @@ jobs: sudo ceph status sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.radosgw-admin user create --uid=user --display-name=User - sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key \ No newline at end of file + sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key + sudo microceph status \ No newline at end of file From 07327cf578cba821457631ee46ea977fb7976824 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:06:19 -0400 Subject: [PATCH 031/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 69b0f474..3003fd3d 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -22,4 +22,5 @@ jobs: sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.radosgw-admin user create --uid=user --display-name=User sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key - sudo microceph status \ No newline at end of file + sudo microceph status + sudo ceph status \ No newline at end of file From 33519030901baaca42def64bed1d57b793e7c550 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:13:59 -0400 Subject: [PATCH 032/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 3003fd3d..625cb7f8 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -14,11 +14,24 @@ jobs: run: | sudo snap install microceph sudo microceph cluster bootstrap - # sudo ceph config set mon osd_pool_default_size 1 sudo microceph status sudo microceph disk add loop,4G,3 - sudo microceph status - sudo ceph status + function check_ceph_ok_or_exit () { + i=0 + for i in {1..5}; do + if sudo microceph.ceph status | grep HEALTH_OK; then + break + else + sudo microceph.ceph status + sleep 30 + sudo microceph.ceph health detail + fi + done + if [ "$i" -eq 5 ]; then + exit 1 + fi + } + check_ceph_ok_or_exit sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.radosgw-admin user create --uid=user --display-name=User sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key From 2800b9b113328be283ef0a32b53d76312d40cb2b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:17:59 -0400 Subject: [PATCH 033/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index 625cb7f8..b7a8e28f 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -15,7 +15,7 @@ jobs: sudo snap install microceph sudo microceph cluster bootstrap sudo microceph status - sudo microceph disk add loop,4G,3 + sudo microceph disk add loop,5G,3 function check_ceph_ok_or_exit () { i=0 for i in {1..5}; do From 9b26e8db12cd4f43f96f4e352dfcce6327ae8c14 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:26:32 -0400 Subject: [PATCH 034/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index b7a8e28f..ba61d0bb 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -12,10 +12,6 @@ jobs: uses: actions/checkout@v4 - name: Install and configure microceph run: | - sudo snap install microceph - sudo microceph cluster bootstrap - sudo microceph status - sudo microceph disk add loop,5G,3 function check_ceph_ok_or_exit () { i=0 for i in {1..5}; do @@ -31,7 +27,14 @@ jobs: exit 1 fi } + + sudo snap install microceph + sudo microceph cluster bootstrap + sleep 30s + sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 + sudo microceph disk add loop,5G,3 check_ceph_ok_or_exit + sudo microceph enable rgw --port 8080 --ssl-port 8443 sudo microceph.radosgw-admin user create --uid=user --display-name=User sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key From 13dfcb5c17dc03d09317d54d34beff6f9749e5a0 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 11:30:22 -0400 Subject: [PATCH 035/108] chore: Redo TF tests --- .github/workflows/terraform.yml | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index dbe58924..ad4bb1cf 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -49,19 +49,17 @@ jobs: name: Install and setup Microceph uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch secrets: inherit - # with: - # charm-path: ${{ inputs.charm-path }} - # test-integration: - # name: Terraform integration - # runs-on: ubuntu-latest - # needs: - # - setup-microceph - # steps: - # - name: Checkout - # uses: actions/checkout@v4 - # - name: Install dependencies - # run: | - # sudo snap install concierge --classic - # sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - # - name: Test Terraform product module upgrade scenarios - # run: just integration \ No newline at end of file + test-integration: + name: Terraform integration + runs-on: ubuntu-latest + needs: + - setup-microceph + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install concierge --classic + sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + - name: Test Terraform product module upgrade scenarios + run: just integration \ No newline at end of file From f11c5645df46ba9a849f27d3d48a48f4b921d88f Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 13:35:06 -0400 Subject: [PATCH 036/108] use `chdir` in TF commands --- tests/integration/helpers.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 837bc688..94efb13d 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -2,22 +2,11 @@ import shlex import shutil import subprocess -from contextlib import contextmanager from typing import List, Optional import jubilant -@contextmanager -def chdir(path): - old = os.getcwd() - try: - os.chdir(path) - yield - finally: - os.chdir(old) - - class TfDirManager: def __init__(self, base_tmpdir): self.base: str = str(base_tmpdir) @@ -28,10 +17,9 @@ def init(self, tf_file: str): tf_dir = os.path.join(self.base, "terraform") os.makedirs(tf_dir, exist_ok=True) shutil.copy(tf_file, os.path.join(tf_dir, "main.tf")) - - with chdir(tf_dir): - subprocess.run(shlex.split("terraform init -upgrade"), check=True) - + subprocess.run( + shlex.split(f"terraform -chdir={tf_dir} init -upgrade"), check=True + ) self.dir = tf_dir @staticmethod @@ -41,14 +29,16 @@ def _args_str(target: Optional[str] = None, **kwargs) -> str: return "-auto-approve " + f"{target_arg} " + var_args def apply(self, target: Optional[str] = None, **kwargs): - cmd_str = "terraform apply " + self._args_str(target, **kwargs) - with chdir(self.dir): - subprocess.run(shlex.split(cmd_str), check=True) + cmd_str = f"terraform -chdir={self.dir} apply " + self._args_str( + target, **kwargs + ) + subprocess.run(shlex.split(cmd_str), check=True) def destroy(self, **kwargs): - cmd_str = "terraform destroy " + self._args_str(None, **kwargs) - with chdir(self.dir): - subprocess.run(shlex.split(cmd_str), check=True) + cmd_str = f"terraform -chdir={self.dir} destroy " + self._args_str( + None, **kwargs + ) + subprocess.run(shlex.split(cmd_str), check=True) def wait_for_active_idle_without_error(jujus: List[jubilant.Juju]): From 942353e99bc74c5a789cdf712959503c02f7225e Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 13:39:08 -0400 Subject: [PATCH 037/108] chore --- tests/integration/helpers.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 94efb13d..585335bd 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -11,15 +11,14 @@ class TfDirManager: def __init__(self, base_tmpdir): self.base: str = str(base_tmpdir) self.dir: str = "" + self.tf_cmd = f"terraform -chdir={self.dir}" def init(self, tf_file: str): """Initialize a Terraform module in a subdirectory.""" tf_dir = os.path.join(self.base, "terraform") os.makedirs(tf_dir, exist_ok=True) shutil.copy(tf_file, os.path.join(tf_dir, "main.tf")) - subprocess.run( - shlex.split(f"terraform -chdir={tf_dir} init -upgrade"), check=True - ) + subprocess.run(shlex.split(f"{self.tf_cmd} init -upgrade"), check=True) self.dir = tf_dir @staticmethod @@ -29,15 +28,11 @@ def _args_str(target: Optional[str] = None, **kwargs) -> str: return "-auto-approve " + f"{target_arg} " + var_args def apply(self, target: Optional[str] = None, **kwargs): - cmd_str = f"terraform -chdir={self.dir} apply " + self._args_str( - target, **kwargs - ) + cmd_str = f"{self.tf_cmd} apply " + self._args_str(target, **kwargs) subprocess.run(shlex.split(cmd_str), check=True) def destroy(self, **kwargs): - cmd_str = f"terraform -chdir={self.dir} destroy " + self._args_str( - None, **kwargs - ) + cmd_str = f"{self.tf_cmd} destroy " + self._args_str(None, **kwargs) subprocess.run(shlex.split(cmd_str), check=True) From d8c9b3073cb96e97af0949b1d530542d14dc923f Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Mon, 20 Oct 2025 14:48:14 -0400 Subject: [PATCH 038/108] chore: try Ceph spec options --- .github/workflows/_setup_microceph.yml | 3 ++- .github/workflows/terraform.yml | 6 +++++- .../cos/tls_external/test_upgrade_cos_tls_external.py | 7 ++++--- .../integration/cos/tls_full/test_upgrade_cos_tls_full.py | 7 ++++--- .../cos/tls_internal/test_upgrade_cos_tls_internal.py | 7 ++++--- .../integration/cos/tls_none/test_upgrade_cos_tls_none.py | 7 ++++--- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml index ba61d0bb..ff5c4f54 100644 --- a/.github/workflows/_setup_microceph.yml +++ b/.github/workflows/_setup_microceph.yml @@ -12,6 +12,7 @@ jobs: uses: actions/checkout@v4 - name: Install and configure microceph run: | + # https://github.com/canonical/microceph-action/blob/main/microceph.sh function check_ceph_ok_or_exit () { i=0 for i in {1..5}; do @@ -32,7 +33,7 @@ jobs: sudo microceph cluster bootstrap sleep 30s sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 - sudo microceph disk add loop,5G,3 + sudo microceph disk add loop,2G,3 check_ceph_ok_or_exit sudo microceph enable rgw --port 8080 --ssl-port 8443 diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index ad4bb1cf..799e62f1 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -62,4 +62,8 @@ jobs: sudo snap install concierge --classic sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Test Terraform product module upgrade scenarios - run: just integration \ No newline at end of file + run: | + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key + just integration \ No newline at end of file diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 3ccbf289..60a29254 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -4,6 +4,7 @@ For more further TLS configuration details, refer to our documentation: https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" +import os from pathlib import Path from subprocess import CalledProcessError @@ -13,9 +14,9 @@ TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" S3_ENDPOINT = { - "s3_endpoint": "http://192.168.88.12:8080", - "s3_secret_key": "secret-key", - "s3_access_key": "access-key", + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), } diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 63877895..9a5c7125 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -4,6 +4,7 @@ For more further TLS configuration details, refer to our documentation: https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" +import os from pathlib import Path from subprocess import CalledProcessError @@ -13,9 +14,9 @@ TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" S3_ENDPOINT = { - "s3_endpoint": "http://192.168.88.12:8080", - "s3_secret_key": "secret-key", - "s3_access_key": "access-key", + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), } diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index f934df70..0189fcd3 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -4,6 +4,7 @@ For more further TLS configuration details, refer to our documentation: https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" +import os from pathlib import Path from subprocess import CalledProcessError @@ -13,9 +14,9 @@ TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" S3_ENDPOINT = { - "s3_endpoint": "http://192.168.88.12:8080", - "s3_secret_key": "secret-key", - "s3_access_key": "access-key", + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), } diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index fd85953a..5281feda 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -4,6 +4,7 @@ For more further TLS configuration details, refer to our documentation: https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" +import os from pathlib import Path from subprocess import CalledProcessError @@ -13,9 +14,9 @@ TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" S3_ENDPOINT = { - "s3_endpoint": "http://192.168.88.12:8080", - "s3_secret_key": "secret-key", - "s3_access_key": "access-key", + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), } From e8b48adeab4b4c074cb4f6d5734bf2dcc79317b1 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Oct 2025 10:04:57 -0400 Subject: [PATCH 039/108] chore: try Ceph spec options --- .github/workflows/terraform.yml | 24 ++++++++-- .../test_upgrade_cos_tls_external.py | 2 +- .../cos/tls_full/test_upgrade_cos_tls_full.py | 2 +- .../test_upgrade_cos_tls_internal.py | 2 +- .../cos/tls_none/test_upgrade_cos_tls_none.py | 2 +- .../test_upgrade_cos_lite_tls_external.py | 46 +++++++++---------- .../test_upgrade_cos_lite_tls_full.py | 46 +++++++++---------- .../test_upgrade_cos_lite_tls_internal.py | 3 -- .../test_upgrade_cos_lite_tls_none.py | 3 -- 9 files changed, 69 insertions(+), 61 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 799e62f1..e0bf8a60 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -49,8 +49,8 @@ jobs: name: Install and setup Microceph uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch secrets: inherit - test-integration: - name: Terraform integration + test-integration-cos-lite: + name: Terraform integration COS Lite runs-on: ubuntu-latest needs: - setup-microceph @@ -66,4 +66,22 @@ jobs: export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key - just integration \ No newline at end of file + just integration cos_lite + test-integration-cos: + name: Terraform integration COS + runs-on: ubuntu-latest + needs: + - setup-microceph + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install concierge --classic + sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + - name: Test Terraform product module upgrade scenarios + run: | + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key + just integration cos \ No newline at end of file diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 60a29254..8a1bf7a0 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -18,7 +18,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } - +print(f"+++{S3_ENDPOINT}") @retry( retry=retry_if_exception_type(CalledProcessError), diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 9a5c7125..e1d90af4 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -18,7 +18,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } - +print(f"+++{S3_ENDPOINT}") @retry( retry=retry_if_exception_type(CalledProcessError), diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 0189fcd3..6b1dd901 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -18,7 +18,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } - +print(f"+++{S3_ENDPOINT}") @retry( retry=retry_if_exception_type(CalledProcessError), diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index 5281feda..0e35a537 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -18,7 +18,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } - +print(f"+++{S3_ENDPOINT}") @retry( retry=retry_if_exception_type(CalledProcessError), diff --git a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py index 68a4fd4b..a11eee5a 100644 --- a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py +++ b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py @@ -14,27 +14,25 @@ TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n-1 - tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply( - # NOTE: "Terraform cannot predict how many instances will be created. To work around this, - # use the -target argument to first apply only the resources that the count depends on." - target="ssc", - ca_model=ca_model.model, - cos_model=cos_model.model, - ) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - wait_for_active_idle_without_error([ca_model, cos_model]) - - -@pytest.mark.abort_on_fail -def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - # WHEN upgraded to track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([ca_model, cos_model]) +# def test_deploy_from_track( +# tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +# ): +# # GIVEN a module deployed from track n-1 +# tf_manager.init(TRACK_1_TF_FILE) +# tf_manager.apply( +# # NOTE: "Terraform cannot predict how many instances will be created. To work around this, +# # use the -target argument to first apply only the resources that the count depends on." +# target="ssc", +# ca_model=ca_model.model, +# cos_model=cos_model.model, +# ) +# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) +# wait_for_active_idle_without_error([ca_model, cos_model]) + + +# def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): +# # WHEN upgraded to track n +# tf_manager.init(TRACK_2_TF_FILE) +# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) +# # THEN the model is upgraded and is active/idle +# wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py index cf43696d..680115c9 100644 --- a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py +++ b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py @@ -14,27 +14,25 @@ TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n-1 - tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply( - # NOTE: "Terraform cannot predict how many instances will be created. To work around this, - # use the -target argument to first apply only the resources that the count depends on." - target="ssc", - ca_model=ca_model.model, - cos_model=cos_model.model, - ) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - wait_for_active_idle_without_error([ca_model, cos_model]) - - -@pytest.mark.abort_on_fail -def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - # WHEN upgraded to track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([ca_model, cos_model]) +# def test_deploy_from_track( +# tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +# ): +# # GIVEN a module deployed from track n-1 +# tf_manager.init(TRACK_1_TF_FILE) +# tf_manager.apply( +# # NOTE: "Terraform cannot predict how many instances will be created. To work around this, +# # use the -target argument to first apply only the resources that the count depends on." +# target="ssc", +# ca_model=ca_model.model, +# cos_model=cos_model.model, +# ) +# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) +# wait_for_active_idle_without_error([ca_model, cos_model]) + + +# def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): +# # WHEN upgraded to track n +# tf_manager.init(TRACK_2_TF_FILE) +# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) +# # THEN the model is upgraded and is active/idle +# wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py b/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py index a514266e..5575cba1 100644 --- a/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py +++ b/tests/integration/cos_lite/tls_internal/test_upgrade_cos_lite_tls_internal.py @@ -7,14 +7,12 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) @@ -22,7 +20,6 @@ def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): wait_for_active_idle_without_error([cos_model]) -@pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py b/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py index 94b324d3..f895d36c 100644 --- a/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py +++ b/tests/integration/cos_lite/tls_none/test_upgrade_cos_lite_tls_none.py @@ -7,14 +7,12 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) @@ -22,7 +20,6 @@ def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): wait_for_active_idle_without_error([cos_model]) -@pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) From f8daef369ded3abc9a137e47ef11299c10ebbf25 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Oct 2025 12:53:25 -0400 Subject: [PATCH 040/108] chore: Fix chdir in TF commands --- tests/integration/helpers.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 585335bd..41e077e0 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -11,15 +11,17 @@ class TfDirManager: def __init__(self, base_tmpdir): self.base: str = str(base_tmpdir) self.dir: str = "" - self.tf_cmd = f"terraform -chdir={self.dir}" + + @property + def tf_cmd(self): + return f"terraform -chdir={self.dir}" def init(self, tf_file: str): """Initialize a Terraform module in a subdirectory.""" - tf_dir = os.path.join(self.base, "terraform") - os.makedirs(tf_dir, exist_ok=True) - shutil.copy(tf_file, os.path.join(tf_dir, "main.tf")) + self.dir = os.path.join(self.base, "terraform") + os.makedirs(self.dir, exist_ok=True) + shutil.copy(tf_file, os.path.join(self.dir, "main.tf")) subprocess.run(shlex.split(f"{self.tf_cmd} init -upgrade"), check=True) - self.dir = tf_dir @staticmethod def _args_str(target: Optional[str] = None, **kwargs) -> str: From 159402dca079be33e43abef85e0df33d2851ff6b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Oct 2025 13:20:53 -0400 Subject: [PATCH 041/108] chore: assert env vars --- justfile | 2 +- .../test_upgrade_cos_tls_external.py | 11 ++++- .../cos/tls_full/test_upgrade_cos_tls_full.py | 9 +++- .../test_upgrade_cos_tls_internal.py | 9 +++- .../cos/tls_none/test_upgrade_cos_tls_none.py | 11 ++++- .../test_upgrade_cos_lite_tls_external.py | 45 +++++++++---------- .../test_upgrade_cos_lite_tls_full.py | 45 +++++++++---------- 7 files changed, 81 insertions(+), 51 deletions(-) diff --git a/justfile b/justfile index 27b488da..7caf9d76 100644 --- a/justfile +++ b/justfile @@ -53,4 +53,4 @@ validate-terraform: # Run solution tests [working-directory("./tests/integration")] integration *args='': - uv run pytest -vvs "${args}" + uv run pytest -vv --capture=no --exitfirst "${args}" diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 8a1bf7a0..7d6bb20d 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -9,6 +9,7 @@ from subprocess import CalledProcessError import jubilant +import pytest from helpers import wait_for_active_idle_without_error from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed @@ -18,7 +19,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } -print(f"+++{S3_ENDPOINT}") + @retry( retry=retry_if_exception_type(CalledProcessError), @@ -31,6 +32,14 @@ def apply_with_retry(tf_manager, **kwargs): tf_manager.apply(**kwargs) +def test_envvars(): + print(f"+++{S3_ENDPOINT}") + assert all(S3_ENDPOINT.values()) + + +@pytest.mark.xfail( + reason="When host is resource-constrained, model can take too long to settle" +) def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index e1d90af4..cde837a4 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -9,6 +9,7 @@ from subprocess import CalledProcessError import jubilant +import pytest from helpers import wait_for_active_idle_without_error from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed @@ -18,7 +19,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } -print(f"+++{S3_ENDPOINT}") + @retry( retry=retry_if_exception_type(CalledProcessError), @@ -31,6 +32,12 @@ def apply_with_retry(tf_manager, **kwargs): tf_manager.apply(**kwargs) +def test_envvars(): + print(f"+++{S3_ENDPOINT}") + assert all(S3_ENDPOINT.values()) + + +@pytest.mark.xfail(reason="When host is resource-constrained, model can take too long to settle") def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 6b1dd901..6103aa7d 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -9,6 +9,7 @@ from subprocess import CalledProcessError import jubilant +import pytest from helpers import wait_for_active_idle_without_error from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed @@ -18,7 +19,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } -print(f"+++{S3_ENDPOINT}") + @retry( retry=retry_if_exception_type(CalledProcessError), @@ -31,6 +32,12 @@ def apply_with_retry(tf_manager, **kwargs): tf_manager.apply(**kwargs) +def test_envvars(): + print(f"+++{S3_ENDPOINT}") + assert all(S3_ENDPOINT.values()) + + +@pytest.mark.xfail(reason="When host is resource-constrained, model can take too long to settle") def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index 0e35a537..c5bbdcab 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -9,6 +9,7 @@ from subprocess import CalledProcessError import jubilant +import pytest from helpers import wait_for_active_idle_without_error from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed @@ -18,7 +19,7 @@ "s3_secret_key": os.getenv("S3_SECRET_KEY"), "s3_access_key": os.getenv("S3_ACCESS_KEY"), } -print(f"+++{S3_ENDPOINT}") + @retry( retry=retry_if_exception_type(CalledProcessError), @@ -31,6 +32,14 @@ def apply_with_retry(tf_manager, **kwargs): tf_manager.apply(**kwargs) +def test_envvars(): + print(f"+++{S3_ENDPOINT}") + assert all(S3_ENDPOINT.values()) + + +@pytest.mark.xfail( + reason="When host is resource-constrained, model can take too long to settle" +) def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py index a11eee5a..c616c52c 100644 --- a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py +++ b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py @@ -7,32 +7,31 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -# def test_deploy_from_track( -# tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -# ): -# # GIVEN a module deployed from track n-1 -# tf_manager.init(TRACK_1_TF_FILE) -# tf_manager.apply( -# # NOTE: "Terraform cannot predict how many instances will be created. To work around this, -# # use the -target argument to first apply only the resources that the count depends on." -# target="ssc", -# ca_model=ca_model.model, -# cos_model=cos_model.model, -# ) -# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) -# wait_for_active_idle_without_error([ca_model, cos_model]) - - -# def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): -# # WHEN upgraded to track n -# tf_manager.init(TRACK_2_TF_FILE) -# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) -# # THEN the model is upgraded and is active/idle -# wait_for_active_idle_without_error([ca_model, cos_model]) +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n-1 + tf_manager.init(TRACK_1_TF_FILE) + tf_manager.apply( + # NOTE: "Terraform cannot predict how many instances will be created. To work around this, + # use the -target argument to first apply only the resources that the count depends on." + target="ssc", + ca_model=ca_model.model, + cos_model=cos_model.model, + ) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) + wait_for_active_idle_without_error([ca_model, cos_model]) + + +def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): + # WHEN upgraded to track n + tf_manager.init(TRACK_2_TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) + # THEN the model is upgraded and is active/idle + wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py index 680115c9..8f103bb7 100644 --- a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py +++ b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py @@ -7,32 +7,31 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -# def test_deploy_from_track( -# tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -# ): -# # GIVEN a module deployed from track n-1 -# tf_manager.init(TRACK_1_TF_FILE) -# tf_manager.apply( -# # NOTE: "Terraform cannot predict how many instances will be created. To work around this, -# # use the -target argument to first apply only the resources that the count depends on." -# target="ssc", -# ca_model=ca_model.model, -# cos_model=cos_model.model, -# ) -# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) -# wait_for_active_idle_without_error([ca_model, cos_model]) - - -# def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): -# # WHEN upgraded to track n -# tf_manager.init(TRACK_2_TF_FILE) -# tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) -# # THEN the model is upgraded and is active/idle -# wait_for_active_idle_without_error([ca_model, cos_model]) +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n-1 + tf_manager.init(TRACK_1_TF_FILE) + tf_manager.apply( + # NOTE: "Terraform cannot predict how many instances will be created. To work around this, + # use the -target argument to first apply only the resources that the count depends on." + target="ssc", + ca_model=ca_model.model, + cos_model=cos_model.model, + ) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) + wait_for_active_idle_without_error([ca_model, cos_model]) + + +def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): + # WHEN upgraded to track n + tf_manager.init(TRACK_2_TF_FILE) + tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) + # THEN the model is upgraded and is active/idle + wait_for_active_idle_without_error([ca_model, cos_model]) From 279c8221c57092cc72e15a98845b65a8b17760cc Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Oct 2025 16:54:05 -0400 Subject: [PATCH 042/108] test --- .github/workflows/terraform.yml | 62 +++++++++++++++++-- .../test_upgrade_cos_tls_external.py | 25 +++----- .../cos/tls_full/test_upgrade_cos_tls_full.py | 33 +++++----- .../test_upgrade_cos_tls_internal.py | 6 +- .../cos/tls_none/test_upgrade_cos_tls_none.py | 6 +- 5 files changed, 91 insertions(+), 41 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index e0bf8a60..7b76d137 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -60,14 +60,14 @@ jobs: - name: Install dependencies run: | sudo snap install concierge --classic - sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform - name: Test Terraform product module upgrade scenarios run: | export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key just integration cos_lite - test-integration-cos: + test-integration-cos-0: name: Terraform integration COS runs-on: ubuntu-latest needs: @@ -78,10 +78,64 @@ jobs: - name: Install dependencies run: | sudo snap install concierge --classic - sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform + sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform - name: Test Terraform product module upgrade scenarios run: | export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key - just integration cos \ No newline at end of file + just integration cos/tls_none + test-integration-cos-1: + name: Terraform integration COS + runs-on: ubuntu-latest + needs: + - setup-microceph + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install concierge --classic + sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform + - name: Test Terraform product module upgrade scenarios + run: | + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key + just integration cos/tls_full + test-integration-cos-2: + name: Terraform integration COS + runs-on: ubuntu-latest + needs: + - setup-microceph + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install concierge --classic + sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform + - name: Test Terraform product module upgrade scenarios + run: | + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key + just integration cos/tls_full + test-integration-cos-4: + name: Terraform integration COS + runs-on: ubuntu-latest + needs: + - setup-microceph + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo snap install concierge --classic + sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform + - name: Test Terraform product module upgrade scenarios + run: | + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key + just integration cos/tls_internal \ No newline at end of file diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 7d6bb20d..1e31612d 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -33,7 +33,6 @@ def apply_with_retry(tf_manager, **kwargs): def test_envvars(): - print(f"+++{S3_ENDPOINT}") assert all(S3_ENDPOINT.values()) @@ -47,19 +46,15 @@ def test_deploy_from_track( tf_manager.init(TRACK_2_TF_FILE) # NOTE: "Terraform cannot predict how many instances will be created. To work around this, # use the -target argument to first apply only the resources that the count depends on." - apply_with_retry( - tf_manager, - **{ - **{ - "target": "ssc", - "ca_model": ca_model.model, - "cos_model": cos_model.model, - }, - **S3_ENDPOINT, - }, + tf_manager.apply( + target="ssc", + ca_model=ca_model.model, + cos_model=cos_model.model, + **S3_ENDPOINT, ) - apply_with_retry( - tf_manager, - **{**{"ca_model": ca_model.model, "cos_model": cos_model.model}, **S3_ENDPOINT}, + tf_manager.apply( + ca_model=ca_model.model, + cos_model=cos_model.model, + **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=2400) + wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index cde837a4..42275f30 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -33,11 +33,12 @@ def apply_with_retry(tf_manager, **kwargs): def test_envvars(): - print(f"+++{S3_ENDPOINT}") assert all(S3_ENDPOINT.values()) -@pytest.mark.xfail(reason="When host is resource-constrained, model can take too long to settle") +@pytest.mark.xfail( + reason="When host is resource-constrained, model can take too long to settle" +) def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): @@ -45,19 +46,19 @@ def test_deploy_from_track( tf_manager.init(TRACK_2_TF_FILE) # NOTE: "Terraform cannot predict how many instances will be created. To work around this, # use the -target argument to first apply only the resources that the count depends on." - apply_with_retry( - tf_manager, - **{ - **{ - "target": "ssc", - "ca_model": ca_model.model, - "cos_model": cos_model.model, - }, - **S3_ENDPOINT, - }, + tf_manager.apply( + target="ssc", + ca_model=ca_model.model, + cos_model=cos_model.model, + **S3_ENDPOINT, ) - apply_with_retry( - tf_manager, - **{**{"ca_model": ca_model.model, "cos_model": cos_model.model}, **S3_ENDPOINT}, + tf_manager.apply( + ca_model=ca_model.model, + cos_model=cos_model.model, + **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=2400) + # apply_with_retry( + # tf_manager, + # **{**{"ca_model": ca_model.model, "cos_model": cos_model.model}, **S3_ENDPOINT}, + # ) + wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 6103aa7d..133074d1 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -33,7 +33,6 @@ def apply_with_retry(tf_manager, **kwargs): def test_envvars(): - print(f"+++{S3_ENDPOINT}") assert all(S3_ENDPOINT.values()) @@ -41,5 +40,6 @@ def test_envvars(): def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) - apply_with_retry(tf_manager, **{**{"model": cos_model.model}, **S3_ENDPOINT}) - wait_for_active_idle_without_error([cos_model], timeout=2400) + tf_manager.apply(model=cos_model.model, **S3_ENDPOINT) + # apply_with_retry(tf_manager, **{**{"model": cos_model.model}, **S3_ENDPOINT}) + wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index c5bbdcab..5c1c3c46 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -33,7 +33,6 @@ def apply_with_retry(tf_manager, **kwargs): def test_envvars(): - print(f"+++{S3_ENDPOINT}") assert all(S3_ENDPOINT.values()) @@ -43,5 +42,6 @@ def test_envvars(): def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) - apply_with_retry(tf_manager, **{**{"model": cos_model.model}, **S3_ENDPOINT}) - wait_for_active_idle_without_error([cos_model], timeout=2400) + tf_manager.apply(model=cos_model.model, **S3_ENDPOINT) + # apply_with_retry(tf_manager, **{**{"model": cos_model.model}, **S3_ENDPOINT}) + wait_for_active_idle_without_error([cos_model], timeout=21600) From 0e588088cbe92385424600229f815715cb67232a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Oct 2025 17:03:25 -0400 Subject: [PATCH 043/108] test --- .github/workflows/terraform.yml | 7 ++++++- .github/workflows/upgrade.yaml | 24 ++++++------------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index b704ebec..1141b3f4 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -48,6 +48,11 @@ jobs: test-integration: name: Terraform integration runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + product: [ "cos", "cos-lite" ] + scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout uses: actions/checkout@v4 @@ -56,4 +61,4 @@ jobs: sudo snap install concierge --classic sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Test Terraform product module upgrade scenarios - run: just integration \ No newline at end of file + run: just integration ${{ matrix.product }}/${{ matrix.scenario }}/test_upgrade_${{ matrix.scenario }}.py \ No newline at end of file diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yaml index 05dc2a99..1449678a 100644 --- a/.github/workflows/upgrade.yaml +++ b/.github/workflows/upgrade.yaml @@ -2,28 +2,16 @@ name: Test the Terraform product module on: workflow_dispatch: - inputs: - product: - description: "The type of the product module" - required: true - type: choice - options: - - cos - - cos-lite - scenario: - description: "The cross-track upgrade scenario" - required: true - type: choice - options: - - tls_none - - tls_internal - - tls_external - - tls_full jobs: terraform-test: name: Test the Terraform product module runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + product: [ "cos", "cos-lite" ] + scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout uses: actions/checkout@v4 @@ -33,4 +21,4 @@ jobs: sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - name: Test deployment run: | - just integration ${{ inputs.product }}/${{ inputs.scenario }}/test_upgrade_${{ inputs.scenario }}.py + just integration ${{ matrix.product }}/${{ matrix.scenario }}/test_upgrade_${{ matrix.scenario }}.py From 30ff5750f112431df4ce3f7eb03dc3ad53365aaf Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 21 Oct 2025 17:12:37 -0400 Subject: [PATCH 044/108] chore: remove cos product --- .github/workflows/terraform.yml | 2 +- .github/workflows/upgrade.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 1141b3f4..cff94254 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - product: [ "cos", "cos-lite" ] + product: [ "cos-lite" ] scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/upgrade.yaml index 1449678a..57f47d32 100644 --- a/.github/workflows/upgrade.yaml +++ b/.github/workflows/upgrade.yaml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - product: [ "cos", "cos-lite" ] + product: [ "cos-lite" ] scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout From 2227e3cd2a19d1e0a51bd0af23e005e16e19e173 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 11:47:13 -0400 Subject: [PATCH 045/108] chore: skip COS tests --- .../cos/tls_external/test_upgrade_cos_tls_external.py | 3 ++- tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py | 3 ++- .../cos/tls_internal/test_upgrade_cos_tls_internal.py | 3 ++- tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py | 5 +++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index f89f7a3f..8792326c 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -36,6 +36,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) @@ -58,4 +59,4 @@ def test_deploy_from_track( cos_model=cos_model.model, **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=21600) + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 732817e0..a9ecd092 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -36,6 +36,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) @@ -58,4 +59,4 @@ def test_deploy_from_track( cos_model=cos_model.model, **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=21600) + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 3417e2bf..606a6034 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -36,9 +36,10 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail(reason="When host is resource-constrained, model can take too long to settle") def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) apply_with_retry(tf_manager, model=cos_model.model, **S3_ENDPOINT) - wait_for_active_idle_without_error([cos_model], timeout=21600) + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index e68f197c..32293c5f 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -36,11 +36,12 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(tf_manager, model=cos_model.model, **S3_ENDPOINT) - wait_for_active_idle_without_error([cos_model], timeout=21600) + apply_with_retry(tf_manager, model=cos_model.model, **S3_ENDPOINT) + wait_for_active_idle_without_error([cos_model], timeout=7200) From a1ae829d769ad54c0af91918b713d248b034dd48 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 11:54:21 -0400 Subject: [PATCH 046/108] chore: cleanup --- .github/workflows/terraform.yml | 2 +- .../tls_external/test_upgrade_tls_external.py | 3 --- .../{cos-lite => cos_lite}/tls_external/track-1.tf | 0 .../{cos-lite => cos_lite}/tls_external/track-2.tf | 0 .../tls_full/test_upgrade_tls_full.py | 3 --- .../{cos-lite => cos_lite}/tls_full/track-1.tf | 0 .../{cos-lite => cos_lite}/tls_full/track-2.tf | 0 .../tls_internal/test_upgrade_tls_internal.py | 3 --- .../{cos-lite => cos_lite}/tls_internal/track-1.tf | 0 .../{cos-lite => cos_lite}/tls_internal/track-2.tf | 0 .../tls_none/test_upgrade_tls_none.py | 5 +---- .../{cos-lite => cos_lite}/tls_none/track-1.tf | 0 .../{cos-lite => cos_lite}/tls_none/track-2.tf | 0 tests/integration/helpers.py | 8 ++++---- 14 files changed, 6 insertions(+), 18 deletions(-) rename tests/integration/{cos-lite => cos_lite}/tls_external/test_upgrade_tls_external.py (95%) rename tests/integration/{cos-lite => cos_lite}/tls_external/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_external/track-2.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_full/test_upgrade_tls_full.py (95%) rename tests/integration/{cos-lite => cos_lite}/tls_full/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_full/track-2.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_internal/test_upgrade_tls_internal.py (94%) rename tests/integration/{cos-lite => cos_lite}/tls_internal/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_internal/track-2.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_none/test_upgrade_tls_none.py (89%) rename tests/integration/{cos-lite => cos_lite}/tls_none/track-1.tf (100%) rename tests/integration/{cos-lite => cos_lite}/tls_none/track-2.tf (100%) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index cff94254..a8000a8a 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - product: [ "cos-lite" ] + product: [ "cos_lite" ] scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout diff --git a/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py similarity index 95% rename from tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py rename to tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py index 68a4fd4b..c616c52c 100644 --- a/tests/integration/cos-lite/tls_external/test_upgrade_tls_external.py +++ b/tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py @@ -7,14 +7,12 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): @@ -31,7 +29,6 @@ def test_deploy_from_track( wait_for_active_idle_without_error([ca_model, cos_model]) -@pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos-lite/tls_external/track-1.tf b/tests/integration/cos_lite/tls_external/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_external/track-1.tf rename to tests/integration/cos_lite/tls_external/track-1.tf diff --git a/tests/integration/cos-lite/tls_external/track-2.tf b/tests/integration/cos_lite/tls_external/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_external/track-2.tf rename to tests/integration/cos_lite/tls_external/track-2.tf diff --git a/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py similarity index 95% rename from tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py rename to tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py index cf43696d..8f103bb7 100644 --- a/tests/integration/cos-lite/tls_full/test_upgrade_tls_full.py +++ b/tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py @@ -7,14 +7,12 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): @@ -31,7 +29,6 @@ def test_deploy_from_track( wait_for_active_idle_without_error([ca_model, cos_model]) -@pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos-lite/tls_full/track-1.tf b/tests/integration/cos_lite/tls_full/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_full/track-1.tf rename to tests/integration/cos_lite/tls_full/track-1.tf diff --git a/tests/integration/cos-lite/tls_full/track-2.tf b/tests/integration/cos_lite/tls_full/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_full/track-2.tf rename to tests/integration/cos_lite/tls_full/track-2.tf diff --git a/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py b/tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py similarity index 94% rename from tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py rename to tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py index a514266e..5575cba1 100644 --- a/tests/integration/cos-lite/tls_internal/test_upgrade_tls_internal.py +++ b/tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py @@ -7,14 +7,12 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) @@ -22,7 +20,6 @@ def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): wait_for_active_idle_without_error([cos_model]) -@pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos-lite/tls_internal/track-1.tf b/tests/integration/cos_lite/tls_internal/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_internal/track-1.tf rename to tests/integration/cos_lite/tls_internal/track-1.tf diff --git a/tests/integration/cos-lite/tls_internal/track-2.tf b/tests/integration/cos_lite/tls_internal/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_internal/track-2.tf rename to tests/integration/cos_lite/tls_internal/track-2.tf diff --git a/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py b/tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py similarity index 89% rename from tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py rename to tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py index 94b324d3..fef51262 100644 --- a/tests/integration/cos-lite/tls_none/test_upgrade_tls_none.py +++ b/tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py @@ -7,14 +7,12 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -@pytest.mark.abort_on_fail def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) @@ -22,10 +20,9 @@ def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): wait_for_active_idle_without_error([cos_model]) -@pytest.mark.abort_on_fail def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): # WHEN upgraded to track n tf_manager.init(TRACK_2_TF_FILE) tf_manager.apply(model=cos_model.model) # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([cos_model]) + wait_for_active_idle_without_error([cos_model], ) diff --git a/tests/integration/cos-lite/tls_none/track-1.tf b/tests/integration/cos_lite/tls_none/track-1.tf similarity index 100% rename from tests/integration/cos-lite/tls_none/track-1.tf rename to tests/integration/cos_lite/tls_none/track-1.tf diff --git a/tests/integration/cos-lite/tls_none/track-2.tf b/tests/integration/cos_lite/tls_none/track-2.tf similarity index 100% rename from tests/integration/cos-lite/tls_none/track-2.tf rename to tests/integration/cos_lite/tls_none/track-2.tf diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 41e077e0..5295e63e 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -38,16 +38,16 @@ def destroy(self, **kwargs): subprocess.run(shlex.split(cmd_str), check=True) -def wait_for_active_idle_without_error(jujus: List[jubilant.Juju]): +def wait_for_active_idle_without_error(jujus: List[jubilant.Juju], timeout: int = 60 * 20): for juju in jujus: print(f"\nwaiting for the model ({juju.model}) to settle ...\n") - juju.wait(jubilant.all_active, delay=5, timeout=60 * 10) + juju.wait(jubilant.all_active, delay=5, timeout=timeout) juju.wait( - jubilant.all_active, delay=5, timeout=60 * 10, error=jubilant.any_error + jubilant.all_active, delay=5, timeout=60 * 5, error=jubilant.any_error ) juju.wait( jubilant.all_agents_idle, delay=5, - timeout=60 * 10, + timeout=60 * 5, error=jubilant.any_error, ) From 9aa62dc2407fc2fadb45cd4d49404c3bd0ffe2c6 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 11:59:47 -0400 Subject: [PATCH 047/108] chore: callable workflow --- .../{upgrade.yaml => _integration.yaml} | 3 ++- .github/workflows/terraform.yml | 16 +--------------- 2 files changed, 3 insertions(+), 16 deletions(-) rename .github/workflows/{upgrade.yaml => _integration.yaml} (93%) diff --git a/.github/workflows/upgrade.yaml b/.github/workflows/_integration.yaml similarity index 93% rename from .github/workflows/upgrade.yaml rename to .github/workflows/_integration.yaml index 57f47d32..49556fd5 100644 --- a/.github/workflows/upgrade.yaml +++ b/.github/workflows/_integration.yaml @@ -2,6 +2,7 @@ name: Test the Terraform product module on: workflow_dispatch: + workflow_call: jobs: terraform-test: @@ -10,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - product: [ "cos-lite" ] + product: [ "cos_lite" ] scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index a8000a8a..e290ca47 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -47,18 +47,4 @@ jobs: run: just validate-terraform test-integration: name: Terraform integration - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - product: [ "cos_lite" ] - scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install dependencies - run: | - sudo snap install concierge --classic - sudo concierge prepare -p microk8s --extra-snaps just,astral-uv,terraform - - name: Test Terraform product module upgrade scenarios - run: just integration ${{ matrix.product }}/${{ matrix.scenario }}/test_upgrade_${{ matrix.scenario }}.py \ No newline at end of file + uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-lite-upgrade \ No newline at end of file From ca409ba16f33895aaa83a5c738d2ce2dfc3622c6 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 13:35:48 -0400 Subject: [PATCH 048/108] chore: Fix branch in CI workflow --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 3edf5c0a..0b43b001 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -47,4 +47,4 @@ jobs: run: just validate-terraform test-integration: name: Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-lite-upgrade + uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch From 30f13132d0f0758538e5000f14703c3ab13f0bee Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 15:55:50 -0400 Subject: [PATCH 049/108] feat: bundle test for role-all=true --- .github/workflows/_integration.yaml | 6 +- pyproject.toml | 1 + .../cos/tls_full/test_upgrade_cos_tls_full.py | 34 +- .../integration/cos/tls_full/track-2.yaml.j2 | 305 ++++++++++++++++++ tests/integration/helpers.py | 22 +- uv.lock | 99 ++++++ 6 files changed, 461 insertions(+), 6 deletions(-) create mode 100644 tests/integration/cos/tls_full/track-2.yaml.j2 diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index c5126d00..bf9e6cdb 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -5,9 +5,9 @@ on: workflow_call: jobs: - setup-microceph: - name: Install and setup Microceph - uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch + # setup-microceph: + # name: Install and setup Microceph + # uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch terraform-test: name: Test product module runs-on: ubuntu-latest diff --git a/pyproject.toml b/pyproject.toml index 5d68be1e..26bb1691 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,4 +8,5 @@ version = "0.0.0" dependencies = [ "jubilant", "pytest", + "jinja2", ] diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index b0074fb0..6ac5cceb 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -9,10 +9,11 @@ import jubilant import pytest -from helpers import wait_for_active_idle_without_error +from helpers import wait_for_active_idle_without_error, render_bundle TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -TRACK_2_BUNDLE_FILE = Path(__file__).parent.resolve() / "track-2.yaml" +TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" +TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" S3_ENDPOINT = { "s3_endpoint": os.getenv("S3_ENDPOINT"), "s3_secret_key": os.getenv("S3_SECRET_KEY"), @@ -24,6 +25,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) @@ -46,3 +48,31 @@ def test_deploy_from_track( **S3_ENDPOINT, ) wait_for_active_idle_without_error([cos_model], timeout=7200) + + +def test_deploy_bundle_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + # TODO: We can avoid using TF here and use juju-deploy, but then we need to also juju.offer and whatever else the TF mod does for us + tf_manager.apply( + "ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT + ) + render_bundle( + TRACK_2_BUNDLE_TEMPLATE, + TRACK_2_RENDERED_BUNDLE, + variables={"s3_endpoint": os.getenv("S3_ENDPOINT"), "ca_model": ca_model.model}, + ) + breakpoint() + cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) + s3_creds = cos_model.add_secret( + "s3creds", {"access-key": "access-key", "secret-key": "secret-key"} + ) + for coordinator in ["loki", "mimir", "tempo"]: + cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") + cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) + + wait_for_active_idle_without_error([cos_model], timeout=7200) + # TODO: Place this in a cleanup test? + os.remove(TRACK_2_RENDERED_BUNDLE) diff --git a/tests/integration/cos/tls_full/track-2.yaml.j2 b/tests/integration/cos/tls_full/track-2.yaml.j2 new file mode 100644 index 00000000..8f3011c0 --- /dev/null +++ b/tests/integration/cos/tls_full/track-2.yaml.j2 @@ -0,0 +1,305 @@ +bundle: kubernetes +saas: + certificates: + url: admin/{{ ca_model }}.certificates +applications: + alertmanager: + charm: alertmanager-k8s + channel: 2/edge + revision: 188 + resources: + alertmanager-image: 101 + scale: 1 + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + trust: true + ca: + charm: self-signed-certificates + channel: 1/stable + revision: 317 + scale: 1 + constraints: arch=amd64 + catalogue: + charm: catalogue-k8s + channel: 2/edge + revision: 108 + resources: + catalogue-image: 37 + scale: 1 + constraints: arch=amd64 + trust: true + grafana: + charm: grafana-k8s + channel: 2/edge + revision: 169 + resources: + grafana-image: 77 + litestream-image: 46 + scale: 1 + constraints: arch=amd64 + storage: + database: kubernetes,1,1024M + trust: true + loki: + charm: loki-coordinator-k8s + channel: 2/edge + revision: 49 + resources: + nginx-image: 7 + nginx-prometheus-exporter-image: 3 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname + trust: true + loki-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: loki + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + loki-worker: + charm: loki-worker-k8s + channel: 2/edge + revision: 50 + resources: + loki-image: 3 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + loki-persisted: kubernetes,1,1024M + trust: true + mimir: + charm: mimir-coordinator-k8s + channel: 2/edge + revision: 68 + resources: + nginx-image: 15 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname + trust: true + mimir-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: mimir + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + mimir-worker: + charm: mimir-worker-k8s + channel: 2/edge + revision: 58 + resources: + mimir-image: 16 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + recovery-data: kubernetes,1,1024M + trust: true + otelcol: + charm: opentelemetry-collector-k8s + channel: 2/edge + revision: 99 + resources: + opentelemetry-collector-image: 9 + scale: 1 + constraints: arch=amd64 + storage: + persisted: kubernetes,1,1024M + trust: true + tempo: + charm: tempo-coordinator-k8s + channel: 2/edge + revision: 128 + resources: + nginx-image: 8 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname + trust: true + tempo-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: tempo + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + tempo-worker: + charm: tempo-worker-k8s + channel: 2/edge + revision: 86 + resources: + tempo-image: 12 + scale: 1 + constraints: arch=amd64 + storage: + wal: kubernetes,1,1024M + trust: true + traefik: + charm: traefik-k8s + channel: latest/stable + revision: 254 + base: ubuntu@20.04/stable + resources: + traefik-image: 162 + scale: 1 + constraints: arch=amd64 + storage: + configurations: kubernetes,1,1024M + trust: true +relations: +- - mimir:s3 + - mimir-s3-integrator:s3-credentials +- - loki:s3 + - loki-s3-integrator:s3-credentials +- - tempo:s3 + - tempo-s3-integrator:s3-credentials +- - traefik:certificates + - certificates:certificates +- - traefik:receive-ca-cert + - ca:send-ca-cert +- - mimir:receive-remote-write + - otelcol:send-remote-write +- - mimir:receive-remote-write + - tempo:send-remote-write +- - otelcol:send-traces + - tempo:tracing +- - catalogue:catalogue + - tempo:catalogue +- - catalogue:catalogue + - mimir:catalogue +- - alertmanager:catalogue + - catalogue:catalogue +- - catalogue:catalogue + - grafana:catalogue +- - tempo:ingress + - traefik:traefik-route +- - grafana:ingress + - traefik:traefik-route +- - catalogue:ingress + - traefik:ingress +- - grafana:grafana-source + - loki:grafana-source +- - alertmanager:ingress + - traefik:ingress +- - otelcol:metrics-endpoint + - alertmanager:self-metrics-endpoint +- - grafana:grafana-source + - mimir:grafana-source +- - grafana:grafana-source + - tempo:grafana-source +- - alertmanager:grafana-source + - grafana:grafana-source +- - otelcol:metrics-endpoint + - tempo:metrics-endpoint +- - otelcol:metrics-endpoint + - loki:self-metrics-endpoint +- - otelcol:metrics-endpoint + - mimir:self-metrics-endpoint +- - loki:ingress + - traefik:ingress +- - mimir:ingress + - traefik:ingress +- - mimir:charm-tracing + - otelcol:receive-traces +- - loki:logging + - otelcol:send-loki-logs +- - loki:charm-tracing + - otelcol:receive-traces +- - ca:certificates + - mimir:certificates +- - grafana:charm-tracing + - otelcol:receive-traces +- - alertmanager:alerting + - loki:alertmanager +- - ca:certificates + - grafana:certificates +- - ca:certificates + - tempo:certificates +- - ca:certificates + - catalogue:certificates +- - alertmanager:certificates + - ca:certificates +- - ca:certificates + - otelcol:receive-server-cert +- - ca:certificates + - loki:certificates +- - alertmanager:alerting + - mimir:alertmanager +- - loki:logging-consumer + - otelcol:receive-loki-logs +- - grafana:grafana-dashboard + - mimir:grafana-dashboards-provider +- - grafana:grafana-dashboard + - loki:grafana-dashboards-provider +- - tempo:logging + - otelcol:receive-loki-logs +- - alertmanager:grafana-dashboard + - grafana:grafana-dashboard +- - grafana:grafana-dashboard + - tempo:grafana-dashboard +- - mimir:logging-consumer + - otelcol:receive-loki-logs +- - tempo-worker:tempo-cluster + - tempo:tempo-cluster +- - mimir-worker:mimir-cluster + - mimir:mimir-cluster +- - loki-worker:loki-cluster + - loki:loki-cluster +--- # overlay.yaml +applications: + alertmanager: + offers: + alertmanager-karma-dashboard: + endpoints: + - karma-dashboard + acl: + admin: admin + ca: + offers: + certificates: + endpoints: + - certificates + acl: + admin: admin + send-ca-cert: + endpoints: + - send-ca-cert + acl: + admin: admin + grafana: + offers: + grafana-dashboards: + endpoints: + - grafana-dashboard + acl: + admin: admin + loki: + offers: + loki-logging: + endpoints: + - logging + acl: + admin: admin + mimir: + offers: + mimir-receive-remote-write: + endpoints: + - receive-remote-write + acl: + admin: admin diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 26dcc827..5bd0b55b 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -2,9 +2,11 @@ import shlex import shutil import subprocess -from typing import List, Optional +from pathlib import Path +from typing import Dict, List, Optional import jubilant +from jinja2 import Template class TfDirManager: @@ -53,3 +55,21 @@ def wait_for_active_idle_without_error( timeout=60 * 5, error=jubilant.any_error, ) + + +def render_bundle( + template: Path, output: Path, variables: Optional[Dict[str, str]] = None +): + """The main function for rendering the bundle template.""" + if variables is None: + variables = {} + breakpoint() + with open(template) as t: + jinja_template = Template(t.read(), autoescape=True) + + # print(jinja_template.render(**variables)) + with open(output, "wt") as o: + # Type-ignore because pyright complains: + # Argument 1 to "dump" of "TemplateStream" has + # incompatible type "TextIOWrapper"; expected "Union[str, IO[bytes]]" + jinja_template.stream(**variables).dump(o) # type: ignore[arg-type] diff --git a/uv.lock b/uv.lock index aff80395..4c73b574 100644 --- a/uv.lock +++ b/uv.lock @@ -32,6 +32,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + [[package]] name = "jubilant" version = "1.4.0" @@ -44,17 +56,104 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/06/4965ed70d4b9d405c8bdefc4926d94cae202014b4488a25aa8c1fe9fb462/jubilant-1.4.0-py3-none-any.whl", hash = "sha256:1df7eaf125fad8d0d3d35e6d83eca43bfbb7884debcd6c7f4b0822600e2a485c", size = 27185, upload-time = "2025-08-27T00:11:44.851Z" }, ] +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631, upload-time = "2025-09-27T18:36:05.558Z" }, + { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057, upload-time = "2025-09-27T18:36:07.165Z" }, + { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050, upload-time = "2025-09-27T18:36:08.005Z" }, + { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681, upload-time = "2025-09-27T18:36:08.881Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705, upload-time = "2025-09-27T18:36:10.131Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524, upload-time = "2025-09-27T18:36:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282, upload-time = "2025-09-27T18:36:12.573Z" }, + { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745, upload-time = "2025-09-27T18:36:13.504Z" }, + { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571, upload-time = "2025-09-27T18:36:14.779Z" }, + { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056, upload-time = "2025-09-27T18:36:16.125Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932, upload-time = "2025-09-27T18:36:17.311Z" }, + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + [[package]] name = "observability-stack" version = "0.0.0" source = { virtual = "." } dependencies = [ + { name = "jinja2" }, { name = "jubilant" }, { name = "pytest" }, ] [package.metadata] requires-dist = [ + { name = "jinja2" }, { name = "jubilant" }, { name = "pytest" }, ] From 43a0bba96549e22ef7d2f0d03adc0d842d25775d Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 16:16:59 -0400 Subject: [PATCH 050/108] chore: test bundle in CI --- .github/workflows/_integration.yaml | 2 +- .../cos/tls_external/test_upgrade_cos_tls_external.py | 1 + .../cos/tls_internal/test_upgrade_cos_tls_internal.py | 1 + tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index bf9e6cdb..b76b9cf9 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - product: [ "cos_lite" ] + product: [ "cos", "cos_lite" ] scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index d068b4ca..7868bb17 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -23,6 +23,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 7de831bf..cf0f6fc3 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -23,6 +23,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index 7ac3239d..ea12c6a8 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -23,6 +23,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) +@pytest.mark.skip() @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) From 0d3aab0f4c602ab0b1fcbf904505376d1152f6b2 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 16:29:44 -0400 Subject: [PATCH 051/108] chore: remove breakpoint in render_bundle --- tests/integration/helpers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 5bd0b55b..a6c5c16b 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -60,10 +60,8 @@ def wait_for_active_idle_without_error( def render_bundle( template: Path, output: Path, variables: Optional[Dict[str, str]] = None ): - """The main function for rendering the bundle template.""" if variables is None: variables = {} - breakpoint() with open(template) as t: jinja_template = Template(t.read(), autoescape=True) From 3cd65fb37156a05f2953d3af6a5e645bd27919da Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 16:38:14 -0400 Subject: [PATCH 052/108] chore: remove breakpoint in render_bundle --- tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py | 1 - tests/integration/helpers.py | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 6ac5cceb..4f4fe5c6 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -64,7 +64,6 @@ def test_deploy_bundle_from_track( TRACK_2_RENDERED_BUNDLE, variables={"s3_endpoint": os.getenv("S3_ENDPOINT"), "ca_model": ca_model.model}, ) - breakpoint() cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) s3_creds = cos_model.add_secret( "s3creds", {"access-key": "access-key", "secret-key": "secret-key"} diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index a6c5c16b..6077338c 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -65,7 +65,6 @@ def render_bundle( with open(template) as t: jinja_template = Template(t.read(), autoescape=True) - # print(jinja_template.render(**variables)) with open(output, "wt") as o: # Type-ignore because pyright complains: # Argument 1 to "dump" of "TemplateStream" has From 7ad26c36513af6a0bda26af7c43008455df9fe7b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 22 Oct 2025 17:08:39 -0400 Subject: [PATCH 053/108] feat: bundles --- .github/workflows/_integration.yaml | 4 +- .../test_upgrade_cos_tls_full_bundle.py | 56 ++++ .../cos/tls_external/track-2.yaml.j2 | 271 ++++++++++++++++ .../cos/tls_full/test_upgrade_cos_tls_full.py | 33 +- .../test_upgrade_cos_tls_full_bundle.py | 56 ++++ .../test_upgrade_cos_tls_internal_bundle.py | 52 +++ .../cos/tls_internal/track-2.yaml.j2 | 300 ++++++++++++++++++ .../test_upgrade_cos_tls_none_bundle.py | 52 +++ .../integration/cos/tls_none/track-2.yaml.j2 | 266 ++++++++++++++++ 9 files changed, 1057 insertions(+), 33 deletions(-) create mode 100644 tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py create mode 100644 tests/integration/cos/tls_external/track-2.yaml.j2 create mode 100644 tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py create mode 100644 tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py create mode 100644 tests/integration/cos/tls_internal/track-2.yaml.j2 create mode 100644 tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py create mode 100644 tests/integration/cos/tls_none/track-2.yaml.j2 diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index b76b9cf9..0502f4c4 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - product: [ "cos", "cos_lite" ] + product: [ "cos" ] # TODO: enable "cos_lite" tests scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] steps: - name: Checkout @@ -28,4 +28,4 @@ jobs: export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key - just integration ${{ matrix.product }}/${{ matrix.scenario }}/test_upgrade_${{ matrix.product }}_${{ matrix.scenario }}.py + just integration ${{ matrix.product }}/${{ matrix.scenario }} diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py new file mode 100644 index 00000000..5b7b7c90 --- /dev/null +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py @@ -0,0 +1,56 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with external TLS, and without internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +import os +from pathlib import Path + +import jubilant +from helpers import wait_for_active_idle_without_error, render_bundle + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" +TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" +S3_ENDPOINT = { + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), +} + + +def test_envvars(): + assert all(S3_ENDPOINT.values()) + + +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + tf_manager.apply( + "ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT + ) + render_bundle( + TRACK_2_BUNDLE_TEMPLATE, + TRACK_2_RENDERED_BUNDLE, + variables={ + "s3_endpoint": S3_ENDPOINT["s3_endpoint"], + "ca_model": ca_model.model, + }, + ) + cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) + os.remove(TRACK_2_RENDERED_BUNDLE) + s3_creds = cos_model.add_secret( + "s3creds", + { + "access-key": S3_ENDPOINT["s3_access_key"], + "secret-key": S3_ENDPOINT["s3_secret_key"], + }, + ) + for coordinator in ["loki", "mimir", "tempo"]: + cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") + cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) + + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_external/track-2.yaml.j2 b/tests/integration/cos/tls_external/track-2.yaml.j2 new file mode 100644 index 00000000..eb280b76 --- /dev/null +++ b/tests/integration/cos/tls_external/track-2.yaml.j2 @@ -0,0 +1,271 @@ +bundle: kubernetes +saas: + certificates: + url: admin/{{ ca_model }}.certificates +applications: + alertmanager: + charm: alertmanager-k8s + channel: 2/edge + revision: 188 + resources: + alertmanager-image: 101 + scale: 1 + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + trust: true + catalogue: + charm: catalogue-k8s + channel: 2/edge + revision: 108 + resources: + catalogue-image: 37 + scale: 1 + constraints: arch=amd64 + trust: true + grafana: + charm: grafana-k8s + channel: 2/edge + revision: 169 + resources: + grafana-image: 77 + litestream-image: 46 + scale: 1 + constraints: arch=amd64 + storage: + database: kubernetes,1,1024M + trust: true + loki: + charm: loki-coordinator-k8s + channel: 2/edge + revision: 49 + resources: + nginx-image: 7 + nginx-prometheus-exporter-image: 3 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname + trust: true + loki-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: loki + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + loki-worker: + charm: loki-worker-k8s + channel: 2/edge + revision: 50 + resources: + loki-image: 3 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + loki-persisted: kubernetes,1,1024M + trust: true + mimir: + charm: mimir-coordinator-k8s + channel: 2/edge + revision: 68 + resources: + nginx-image: 15 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname + trust: true + mimir-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: mimir + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + mimir-worker: + charm: mimir-worker-k8s + channel: 2/edge + revision: 58 + resources: + mimir-image: 16 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + recovery-data: kubernetes,1,1024M + trust: true + otelcol: + charm: opentelemetry-collector-k8s + channel: 2/edge + revision: 99 + resources: + opentelemetry-collector-image: 9 + scale: 1 + constraints: arch=amd64 + storage: + persisted: kubernetes,1,1024M + trust: true + tempo: + charm: tempo-coordinator-k8s + channel: 2/edge + revision: 128 + resources: + nginx-image: 8 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname + trust: true + tempo-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: tempo + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + tempo-worker: + charm: tempo-worker-k8s + channel: 2/edge + revision: 86 + resources: + tempo-image: 12 + scale: 1 + constraints: arch=amd64 + storage: + wal: kubernetes,1,1024M + trust: true + traefik: + charm: traefik-k8s + channel: latest/stable + revision: 254 + base: ubuntu@20.04/stable + resources: + traefik-image: 162 + scale: 1 + constraints: arch=amd64 + storage: + configurations: kubernetes,1,1024M + trust: true +relations: +- - mimir:s3 + - mimir-s3-integrator:s3-credentials +- - loki:s3 + - loki-s3-integrator:s3-credentials +- - tempo:s3 + - tempo-s3-integrator:s3-credentials +- - traefik:certificates + - certificates:certificates +- - mimir:receive-remote-write + - otelcol:send-remote-write +- - mimir:receive-remote-write + - tempo:send-remote-write +- - otelcol:send-traces + - tempo:tracing +- - catalogue:catalogue + - tempo:catalogue +- - catalogue:catalogue + - mimir:catalogue +- - alertmanager:catalogue + - catalogue:catalogue +- - catalogue:catalogue + - grafana:catalogue +- - tempo:ingress + - traefik:traefik-route +- - grafana:ingress + - traefik:traefik-route +- - catalogue:ingress + - traefik:ingress +- - grafana:grafana-source + - loki:grafana-source +- - alertmanager:ingress + - traefik:ingress +- - otelcol:metrics-endpoint + - alertmanager:self-metrics-endpoint +- - grafana:grafana-source + - mimir:grafana-source +- - grafana:grafana-source + - tempo:grafana-source +- - alertmanager:grafana-source + - grafana:grafana-source +- - otelcol:metrics-endpoint + - tempo:metrics-endpoint +- - otelcol:metrics-endpoint + - loki:self-metrics-endpoint +- - otelcol:metrics-endpoint + - mimir:self-metrics-endpoint +- - loki:ingress + - traefik:ingress +- - mimir:ingress + - traefik:ingress +- - mimir:charm-tracing + - otelcol:receive-traces +- - loki:logging + - otelcol:send-loki-logs +- - loki:charm-tracing + - otelcol:receive-traces +- - grafana:charm-tracing + - otelcol:receive-traces +- - alertmanager:alerting + - loki:alertmanager +- - alertmanager:alerting + - mimir:alertmanager +- - loki:logging-consumer + - otelcol:receive-loki-logs +- - grafana:grafana-dashboard + - mimir:grafana-dashboards-provider +- - grafana:grafana-dashboard + - loki:grafana-dashboards-provider +- - tempo:logging + - otelcol:receive-loki-logs +- - alertmanager:grafana-dashboard + - grafana:grafana-dashboard +- - grafana:grafana-dashboard + - tempo:grafana-dashboard +- - mimir:logging-consumer + - otelcol:receive-loki-logs +- - tempo-worker:tempo-cluster + - tempo:tempo-cluster +- - mimir-worker:mimir-cluster + - mimir:mimir-cluster +- - loki-worker:loki-cluster + - loki:loki-cluster +--- # overlay.yaml +applications: + alertmanager: + offers: + alertmanager-karma-dashboard: + endpoints: + - karma-dashboard + acl: + admin: admin + grafana: + offers: + grafana-dashboards: + endpoints: + - grafana-dashboard + acl: + admin: admin + loki: + offers: + loki-logging: + endpoints: + - logging + acl: + admin: admin + mimir: + offers: + mimir-receive-remote-write: + endpoints: + - receive-remote-write + acl: + admin: admin diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 4f4fe5c6..0eb7d3b5 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -9,11 +9,9 @@ import jubilant import pytest -from helpers import wait_for_active_idle_without_error, render_bundle +from helpers import wait_for_active_idle_without_error TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" -TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" S3_ENDPOINT = { "s3_endpoint": os.getenv("S3_ENDPOINT"), "s3_secret_key": os.getenv("S3_SECRET_KEY"), @@ -25,7 +23,7 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) -@pytest.mark.skip() +@pytest.mark.skip() # TODO: Remove this @pytest.mark.xfail( reason="When host is resource-constrained, model can take too long to settle" ) @@ -48,30 +46,3 @@ def test_deploy_from_track( **S3_ENDPOINT, ) wait_for_active_idle_without_error([cos_model], timeout=7200) - - -def test_deploy_bundle_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n - tf_manager.init(TRACK_2_TF_FILE) - # TODO: We can avoid using TF here and use juju-deploy, but then we need to also juju.offer and whatever else the TF mod does for us - tf_manager.apply( - "ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT - ) - render_bundle( - TRACK_2_BUNDLE_TEMPLATE, - TRACK_2_RENDERED_BUNDLE, - variables={"s3_endpoint": os.getenv("S3_ENDPOINT"), "ca_model": ca_model.model}, - ) - cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) - s3_creds = cos_model.add_secret( - "s3creds", {"access-key": "access-key", "secret-key": "secret-key"} - ) - for coordinator in ["loki", "mimir", "tempo"]: - cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") - cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - - wait_for_active_idle_without_error([cos_model], timeout=7200) - # TODO: Place this in a cleanup test? - os.remove(TRACK_2_RENDERED_BUNDLE) diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py new file mode 100644 index 00000000..b54c3b94 --- /dev/null +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py @@ -0,0 +1,56 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with external and internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +import os +from pathlib import Path + +import jubilant +from helpers import wait_for_active_idle_without_error, render_bundle + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" +TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" +S3_ENDPOINT = { + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), +} + + +def test_envvars(): + assert all(S3_ENDPOINT.values()) + + +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + tf_manager.init(TRACK_2_TF_FILE) + tf_manager.apply( + "ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT + ) + render_bundle( + TRACK_2_BUNDLE_TEMPLATE, + TRACK_2_RENDERED_BUNDLE, + variables={ + "s3_endpoint": S3_ENDPOINT["s3_endpoint"], + "ca_model": ca_model.model, + }, + ) + cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) + os.remove(TRACK_2_RENDERED_BUNDLE) + s3_creds = cos_model.add_secret( + "s3creds", + { + "access-key": S3_ENDPOINT["s3_access_key"], + "secret-key": S3_ENDPOINT["s3_secret_key"], + }, + ) + for coordinator in ["loki", "mimir", "tempo"]: + cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") + cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) + + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py new file mode 100644 index 00000000..edfeaebe --- /dev/null +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py @@ -0,0 +1,52 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS with internal TLS, and without external TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +import os +from pathlib import Path + +import jubilant +from helpers import wait_for_active_idle_without_error, render_bundle + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" +TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" +S3_ENDPOINT = { + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), +} + + +def test_envvars(): + assert all(S3_ENDPOINT.values()) + + +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + render_bundle( + TRACK_2_BUNDLE_TEMPLATE, + TRACK_2_RENDERED_BUNDLE, + variables={ + "s3_endpoint": S3_ENDPOINT["s3_endpoint"], + "ca_model": ca_model.model, + }, + ) + cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) + os.remove(TRACK_2_RENDERED_BUNDLE) + s3_creds = cos_model.add_secret( + "s3creds", + { + "access-key": S3_ENDPOINT["s3_access_key"], + "secret-key": S3_ENDPOINT["s3_secret_key"], + }, + ) + for coordinator in ["loki", "mimir", "tempo"]: + cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") + cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) + + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_internal/track-2.yaml.j2 b/tests/integration/cos/tls_internal/track-2.yaml.j2 new file mode 100644 index 00000000..9a95930b --- /dev/null +++ b/tests/integration/cos/tls_internal/track-2.yaml.j2 @@ -0,0 +1,300 @@ +bundle: kubernetes +applications: + alertmanager: + charm: alertmanager-k8s + channel: 2/edge + revision: 188 + resources: + alertmanager-image: 101 + scale: 1 + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + trust: true + ca: + charm: self-signed-certificates + channel: 1/stable + revision: 317 + scale: 1 + constraints: arch=amd64 + catalogue: + charm: catalogue-k8s + channel: 2/edge + revision: 108 + resources: + catalogue-image: 37 + scale: 1 + constraints: arch=amd64 + trust: true + grafana: + charm: grafana-k8s + channel: 2/edge + revision: 169 + resources: + grafana-image: 77 + litestream-image: 46 + scale: 1 + constraints: arch=amd64 + storage: + database: kubernetes,1,1024M + trust: true + loki: + charm: loki-coordinator-k8s + channel: 2/edge + revision: 49 + resources: + nginx-image: 7 + nginx-prometheus-exporter-image: 3 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname + trust: true + loki-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: loki + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + loki-worker: + charm: loki-worker-k8s + channel: 2/edge + revision: 50 + resources: + loki-image: 3 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + loki-persisted: kubernetes,1,1024M + trust: true + mimir: + charm: mimir-coordinator-k8s + channel: 2/edge + revision: 68 + resources: + nginx-image: 15 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname + trust: true + mimir-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: mimir + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + mimir-worker: + charm: mimir-worker-k8s + channel: 2/edge + revision: 58 + resources: + mimir-image: 16 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + recovery-data: kubernetes,1,1024M + trust: true + otelcol: + charm: opentelemetry-collector-k8s + channel: 2/edge + revision: 99 + resources: + opentelemetry-collector-image: 9 + scale: 1 + constraints: arch=amd64 + storage: + persisted: kubernetes,1,1024M + trust: true + tempo: + charm: tempo-coordinator-k8s + channel: 2/edge + revision: 128 + resources: + nginx-image: 8 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname + trust: true + tempo-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: tempo + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + tempo-worker: + charm: tempo-worker-k8s + channel: 2/edge + revision: 86 + resources: + tempo-image: 12 + scale: 1 + constraints: arch=amd64 + storage: + wal: kubernetes,1,1024M + trust: true + traefik: + charm: traefik-k8s + channel: latest/stable + revision: 254 + base: ubuntu@20.04/stable + resources: + traefik-image: 162 + scale: 1 + constraints: arch=amd64 + storage: + configurations: kubernetes,1,1024M + trust: true +relations: +- - mimir:s3 + - mimir-s3-integrator:s3-credentials +- - loki:s3 + - loki-s3-integrator:s3-credentials +- - tempo:s3 + - tempo-s3-integrator:s3-credentials +- - traefik:receive-ca-cert + - ca:send-ca-cert +- - mimir:receive-remote-write + - otelcol:send-remote-write +- - mimir:receive-remote-write + - tempo:send-remote-write +- - otelcol:send-traces + - tempo:tracing +- - catalogue:catalogue + - tempo:catalogue +- - catalogue:catalogue + - mimir:catalogue +- - alertmanager:catalogue + - catalogue:catalogue +- - catalogue:catalogue + - grafana:catalogue +- - tempo:ingress + - traefik:traefik-route +- - grafana:ingress + - traefik:traefik-route +- - catalogue:ingress + - traefik:ingress +- - grafana:grafana-source + - loki:grafana-source +- - alertmanager:ingress + - traefik:ingress +- - otelcol:metrics-endpoint + - alertmanager:self-metrics-endpoint +- - grafana:grafana-source + - mimir:grafana-source +- - grafana:grafana-source + - tempo:grafana-source +- - alertmanager:grafana-source + - grafana:grafana-source +- - otelcol:metrics-endpoint + - tempo:metrics-endpoint +- - otelcol:metrics-endpoint + - loki:self-metrics-endpoint +- - otelcol:metrics-endpoint + - mimir:self-metrics-endpoint +- - loki:ingress + - traefik:ingress +- - mimir:ingress + - traefik:ingress +- - mimir:charm-tracing + - otelcol:receive-traces +- - loki:logging + - otelcol:send-loki-logs +- - loki:charm-tracing + - otelcol:receive-traces +- - ca:certificates + - mimir:certificates +- - grafana:charm-tracing + - otelcol:receive-traces +- - alertmanager:alerting + - loki:alertmanager +- - ca:certificates + - grafana:certificates +- - ca:certificates + - tempo:certificates +- - ca:certificates + - catalogue:certificates +- - alertmanager:certificates + - ca:certificates +- - ca:certificates + - otelcol:receive-server-cert +- - ca:certificates + - loki:certificates +- - alertmanager:alerting + - mimir:alertmanager +- - loki:logging-consumer + - otelcol:receive-loki-logs +- - grafana:grafana-dashboard + - mimir:grafana-dashboards-provider +- - grafana:grafana-dashboard + - loki:grafana-dashboards-provider +- - tempo:logging + - otelcol:receive-loki-logs +- - alertmanager:grafana-dashboard + - grafana:grafana-dashboard +- - grafana:grafana-dashboard + - tempo:grafana-dashboard +- - mimir:logging-consumer + - otelcol:receive-loki-logs +- - tempo-worker:tempo-cluster + - tempo:tempo-cluster +- - mimir-worker:mimir-cluster + - mimir:mimir-cluster +- - loki-worker:loki-cluster + - loki:loki-cluster +--- # overlay.yaml +applications: + alertmanager: + offers: + alertmanager-karma-dashboard: + endpoints: + - karma-dashboard + acl: + admin: admin + ca: + offers: + certificates: + endpoints: + - certificates + acl: + admin: admin + send-ca-cert: + endpoints: + - send-ca-cert + acl: + admin: admin + grafana: + offers: + grafana-dashboards: + endpoints: + - grafana-dashboard + acl: + admin: admin + loki: + offers: + loki-logging: + endpoints: + - logging + acl: + admin: admin + mimir: + offers: + mimir-receive-remote-write: + endpoints: + - receive-remote-write + acl: + admin: admin diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py new file mode 100644 index 00000000..038f197f --- /dev/null +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py @@ -0,0 +1,52 @@ +"""There are 2 sections of the COS deployment (internal and external) which can implement TLS +communication. This python test file deploys COS without external and internal TLS. + +For more further TLS configuration details, refer to our documentation: +https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" + +import os +from pathlib import Path + +import jubilant +from helpers import wait_for_active_idle_without_error, render_bundle + +TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" +TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" +TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" +S3_ENDPOINT = { + "s3_endpoint": os.getenv("S3_ENDPOINT"), + "s3_secret_key": os.getenv("S3_SECRET_KEY"), + "s3_access_key": os.getenv("S3_ACCESS_KEY"), +} + + +def test_envvars(): + assert all(S3_ENDPOINT.values()) + + +def test_deploy_from_track( + tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju +): + # GIVEN a module deployed from track n + render_bundle( + TRACK_2_BUNDLE_TEMPLATE, + TRACK_2_RENDERED_BUNDLE, + variables={ + "s3_endpoint": S3_ENDPOINT["s3_endpoint"], + "ca_model": ca_model.model, + }, + ) + cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) + os.remove(TRACK_2_RENDERED_BUNDLE) + s3_creds = cos_model.add_secret( + "s3creds", + { + "access-key": S3_ENDPOINT["s3_access_key"], + "secret-key": S3_ENDPOINT["s3_secret_key"], + }, + ) + for coordinator in ["loki", "mimir", "tempo"]: + cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") + cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) + + wait_for_active_idle_without_error([cos_model], timeout=7200) diff --git a/tests/integration/cos/tls_none/track-2.yaml.j2 b/tests/integration/cos/tls_none/track-2.yaml.j2 new file mode 100644 index 00000000..20cee093 --- /dev/null +++ b/tests/integration/cos/tls_none/track-2.yaml.j2 @@ -0,0 +1,266 @@ +bundle: kubernetes +applications: + alertmanager: + charm: alertmanager-k8s + channel: 2/edge + revision: 188 + resources: + alertmanager-image: 101 + scale: 1 + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + trust: true + catalogue: + charm: catalogue-k8s + channel: 2/edge + revision: 108 + resources: + catalogue-image: 37 + scale: 1 + constraints: arch=amd64 + trust: true + grafana: + charm: grafana-k8s + channel: 2/edge + revision: 169 + resources: + grafana-image: 77 + litestream-image: 46 + scale: 1 + constraints: arch=amd64 + storage: + database: kubernetes,1,1024M + trust: true + loki: + charm: loki-coordinator-k8s + channel: 2/edge + revision: 49 + resources: + nginx-image: 7 + nginx-prometheus-exporter-image: 3 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname + trust: true + loki-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: loki + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + loki-worker: + charm: loki-worker-k8s + channel: 2/edge + revision: 50 + resources: + loki-image: 3 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + loki-persisted: kubernetes,1,1024M + trust: true + mimir: + charm: mimir-coordinator-k8s + channel: 2/edge + revision: 68 + resources: + nginx-image: 15 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname + trust: true + mimir-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: mimir + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + mimir-worker: + charm: mimir-worker-k8s + channel: 2/edge + revision: 58 + resources: + mimir-image: 16 + scale: 1 + options: + role-all: true + constraints: arch=amd64 + storage: + data: kubernetes,1,1024M + recovery-data: kubernetes,1,1024M + trust: true + otelcol: + charm: opentelemetry-collector-k8s + channel: 2/edge + revision: 99 + resources: + opentelemetry-collector-image: 9 + scale: 1 + constraints: arch=amd64 + storage: + persisted: kubernetes,1,1024M + trust: true + tempo: + charm: tempo-coordinator-k8s + channel: 2/edge + revision: 128 + resources: + nginx-image: 8 + nginx-prometheus-exporter-image: 4 + scale: 1 + constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname + trust: true + tempo-s3-integrator: + charm: s3-integrator + channel: 2/edge + revision: 243 + scale: 1 + options: + bucket: tempo + endpoint: {{ s3_endpoint }} + constraints: arch=amd64 + trust: true + tempo-worker: + charm: tempo-worker-k8s + channel: 2/edge + revision: 86 + resources: + tempo-image: 12 + scale: 1 + constraints: arch=amd64 + storage: + wal: kubernetes,1,1024M + trust: true + traefik: + charm: traefik-k8s + channel: latest/stable + revision: 254 + base: ubuntu@20.04/stable + resources: + traefik-image: 162 + scale: 1 + constraints: arch=amd64 + storage: + configurations: kubernetes,1,1024M + trust: true +relations: +- - mimir:s3 + - mimir-s3-integrator:s3-credentials +- - loki:s3 + - loki-s3-integrator:s3-credentials +- - tempo:s3 + - tempo-s3-integrator:s3-credentials +- - mimir:receive-remote-write + - otelcol:send-remote-write +- - mimir:receive-remote-write + - tempo:send-remote-write +- - otelcol:send-traces + - tempo:tracing +- - catalogue:catalogue + - tempo:catalogue +- - catalogue:catalogue + - mimir:catalogue +- - alertmanager:catalogue + - catalogue:catalogue +- - catalogue:catalogue + - grafana:catalogue +- - tempo:ingress + - traefik:traefik-route +- - grafana:ingress + - traefik:traefik-route +- - catalogue:ingress + - traefik:ingress +- - grafana:grafana-source + - loki:grafana-source +- - alertmanager:ingress + - traefik:ingress +- - otelcol:metrics-endpoint + - alertmanager:self-metrics-endpoint +- - grafana:grafana-source + - mimir:grafana-source +- - grafana:grafana-source + - tempo:grafana-source +- - alertmanager:grafana-source + - grafana:grafana-source +- - otelcol:metrics-endpoint + - tempo:metrics-endpoint +- - otelcol:metrics-endpoint + - loki:self-metrics-endpoint +- - otelcol:metrics-endpoint + - mimir:self-metrics-endpoint +- - loki:ingress + - traefik:ingress +- - mimir:ingress + - traefik:ingress +- - mimir:charm-tracing + - otelcol:receive-traces +- - loki:logging + - otelcol:send-loki-logs +- - loki:charm-tracing + - otelcol:receive-traces +- - grafana:charm-tracing + - otelcol:receive-traces +- - alertmanager:alerting + - loki:alertmanager +- - alertmanager:alerting + - mimir:alertmanager +- - loki:logging-consumer + - otelcol:receive-loki-logs +- - grafana:grafana-dashboard + - mimir:grafana-dashboards-provider +- - grafana:grafana-dashboard + - loki:grafana-dashboards-provider +- - tempo:logging + - otelcol:receive-loki-logs +- - alertmanager:grafana-dashboard + - grafana:grafana-dashboard +- - grafana:grafana-dashboard + - tempo:grafana-dashboard +- - mimir:logging-consumer + - otelcol:receive-loki-logs +- - tempo-worker:tempo-cluster + - tempo:tempo-cluster +- - mimir-worker:mimir-cluster + - mimir:mimir-cluster +- - loki-worker:loki-cluster + - loki:loki-cluster +--- # overlay.yaml +applications: + alertmanager: + offers: + alertmanager-karma-dashboard: + endpoints: + - karma-dashboard + acl: + admin: admin + grafana: + offers: + grafana-dashboards: + endpoints: + - grafana-dashboard + acl: + admin: admin + loki: + offers: + loki-logging: + endpoints: + - logging + acl: + admin: admin + mimir: + offers: + mimir-receive-remote-write: + endpoints: + - receive-remote-write + acl: + admin: admin From afda5010bc3006eed040d94908a5667172efcf8b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 08:42:42 -0400 Subject: [PATCH 054/108] chore: bump timeout --- ...s_full_bundle.py => test_upgrade_cos_tls_external_bundle.py} | 2 +- .../cos/tls_full/test_upgrade_cos_tls_full_bundle.py | 2 +- .../cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py | 2 +- .../cos/tls_none/test_upgrade_cos_tls_none_bundle.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename tests/integration/cos/tls_external/{test_upgrade_cos_tls_full_bundle.py => test_upgrade_cos_tls_external_bundle.py} (96%) diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py similarity index 96% rename from tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py rename to tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py index 5b7b7c90..14649ba6 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_full_bundle.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py @@ -53,4 +53,4 @@ def test_deploy_from_track( cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py index b54c3b94..b91716e3 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py @@ -53,4 +53,4 @@ def test_deploy_from_track( cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py index edfeaebe..6225533a 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py @@ -49,4 +49,4 @@ def test_deploy_from_track( cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py index 038f197f..9fb0077b 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py @@ -49,4 +49,4 @@ def test_deploy_from_track( cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=21600) From d7f6899d31affd2d5b97ba13050811880079c99b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 12:01:27 -0400 Subject: [PATCH 055/108] chore: use self-hosted runners --- .github/workflows/_integration.yaml | 21 +- .github/workflows/terraform.yml | 13 +- .../test_upgrade_cos_tls_external.py | 7 +- .../test_upgrade_cos_tls_external_bundle.py | 56 ---- .../cos/tls_external/track-2.yaml.j2 | 271 ---------------- .../cos/tls_full/test_upgrade_cos_tls_full.py | 5 - .../test_upgrade_cos_tls_full_bundle.py | 56 ---- .../integration/cos/tls_full/track-2.yaml.j2 | 305 ------------------ .../test_upgrade_cos_tls_internal.py | 5 - .../test_upgrade_cos_tls_internal_bundle.py | 52 --- .../cos/tls_internal/track-2.yaml.j2 | 300 ----------------- .../cos/tls_none/test_upgrade_cos_tls_none.py | 5 - .../test_upgrade_cos_tls_none_bundle.py | 52 --- .../integration/cos/tls_none/track-2.yaml.j2 | 266 --------------- tests/integration/helpers.py | 19 +- 15 files changed, 27 insertions(+), 1406 deletions(-) delete mode 100644 tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py delete mode 100644 tests/integration/cos/tls_external/track-2.yaml.j2 delete mode 100644 tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py delete mode 100644 tests/integration/cos/tls_full/track-2.yaml.j2 delete mode 100644 tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py delete mode 100644 tests/integration/cos/tls_internal/track-2.yaml.j2 delete mode 100644 tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py delete mode 100644 tests/integration/cos/tls_none/track-2.yaml.j2 diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index 0502f4c4..014be54a 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -3,19 +3,25 @@ name: Test the Terraform product module on: workflow_dispatch: workflow_call: + inputs: + product: + required: true + type: string + runner-labels: + type: string + default: '["ubuntu-latest"]' jobs: - # setup-microceph: - # name: Install and setup Microceph - # uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch + setup-microceph: + name: Install and setup Microceph + uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch terraform-test: name: Test product module - runs-on: ubuntu-latest + runs-on: ${{ fromJson(inputs.runner-labels) }} strategy: fail-fast: false matrix: - product: [ "cos" ] # TODO: enable "cos_lite" tests - scenario: [ "tls_full", "tls_external", "tls_internal", "tls_none" ] + scenario: ["tls_full", "tls_external", "tls_internal", "tls_none"] steps: - name: Checkout uses: actions/checkout@v4 @@ -25,7 +31,8 @@ jobs: sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform - name: Test deployment run: | + # TODO make these env vars in workflow or from repo secrets export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key - just integration ${{ matrix.product }}/${{ matrix.scenario }} + just integration ${{ inputs.product }}/${{ matrix.scenario }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 0b43b001..b2760824 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -45,6 +45,15 @@ jobs: sudo snap install just --classic - name: Validate the Terraform modules run: just validate-terraform - test-integration: - name: Terraform integration + test-integration-cos-lite: + name: COS Lite Terraform integration uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch + with: + product: cos_lite + runner-labels: '["ubuntu-latest"]' + test-integration-cos: + name: COS Terraform integration + uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch + with: + product: cos + runner-labels: '["self-hosted","linux","amd64","noble","xlarge"]' diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 7868bb17..3311a313 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -8,7 +8,6 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" @@ -23,10 +22,6 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) -@pytest.mark.skip() -@pytest.mark.xfail( - reason="When host is resource-constrained, model can take too long to settle" -) def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): @@ -45,4 +40,4 @@ def test_deploy_from_track( cos_model=cos_model.model, **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=7200) # TODO: Reduce if not needed diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py deleted file mode 100644 index 14649ba6..00000000 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external_bundle.py +++ /dev/null @@ -1,56 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS with external TLS, and without internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -import os -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error, render_bundle - -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" -TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" -S3_ENDPOINT = { - "s3_endpoint": os.getenv("S3_ENDPOINT"), - "s3_secret_key": os.getenv("S3_SECRET_KEY"), - "s3_access_key": os.getenv("S3_ACCESS_KEY"), -} - - -def test_envvars(): - assert all(S3_ENDPOINT.values()) - - -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply( - "ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT - ) - render_bundle( - TRACK_2_BUNDLE_TEMPLATE, - TRACK_2_RENDERED_BUNDLE, - variables={ - "s3_endpoint": S3_ENDPOINT["s3_endpoint"], - "ca_model": ca_model.model, - }, - ) - cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) - os.remove(TRACK_2_RENDERED_BUNDLE) - s3_creds = cos_model.add_secret( - "s3creds", - { - "access-key": S3_ENDPOINT["s3_access_key"], - "secret-key": S3_ENDPOINT["s3_secret_key"], - }, - ) - for coordinator in ["loki", "mimir", "tempo"]: - cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") - cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - - wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_external/track-2.yaml.j2 b/tests/integration/cos/tls_external/track-2.yaml.j2 deleted file mode 100644 index eb280b76..00000000 --- a/tests/integration/cos/tls_external/track-2.yaml.j2 +++ /dev/null @@ -1,271 +0,0 @@ -bundle: kubernetes -saas: - certificates: - url: admin/{{ ca_model }}.certificates -applications: - alertmanager: - charm: alertmanager-k8s - channel: 2/edge - revision: 188 - resources: - alertmanager-image: 101 - scale: 1 - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - trust: true - catalogue: - charm: catalogue-k8s - channel: 2/edge - revision: 108 - resources: - catalogue-image: 37 - scale: 1 - constraints: arch=amd64 - trust: true - grafana: - charm: grafana-k8s - channel: 2/edge - revision: 169 - resources: - grafana-image: 77 - litestream-image: 46 - scale: 1 - constraints: arch=amd64 - storage: - database: kubernetes,1,1024M - trust: true - loki: - charm: loki-coordinator-k8s - channel: 2/edge - revision: 49 - resources: - nginx-image: 7 - nginx-prometheus-exporter-image: 3 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname - trust: true - loki-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: loki - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - loki-worker: - charm: loki-worker-k8s - channel: 2/edge - revision: 50 - resources: - loki-image: 3 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - loki-persisted: kubernetes,1,1024M - trust: true - mimir: - charm: mimir-coordinator-k8s - channel: 2/edge - revision: 68 - resources: - nginx-image: 15 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname - trust: true - mimir-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: mimir - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - mimir-worker: - charm: mimir-worker-k8s - channel: 2/edge - revision: 58 - resources: - mimir-image: 16 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - recovery-data: kubernetes,1,1024M - trust: true - otelcol: - charm: opentelemetry-collector-k8s - channel: 2/edge - revision: 99 - resources: - opentelemetry-collector-image: 9 - scale: 1 - constraints: arch=amd64 - storage: - persisted: kubernetes,1,1024M - trust: true - tempo: - charm: tempo-coordinator-k8s - channel: 2/edge - revision: 128 - resources: - nginx-image: 8 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname - trust: true - tempo-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: tempo - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - tempo-worker: - charm: tempo-worker-k8s - channel: 2/edge - revision: 86 - resources: - tempo-image: 12 - scale: 1 - constraints: arch=amd64 - storage: - wal: kubernetes,1,1024M - trust: true - traefik: - charm: traefik-k8s - channel: latest/stable - revision: 254 - base: ubuntu@20.04/stable - resources: - traefik-image: 162 - scale: 1 - constraints: arch=amd64 - storage: - configurations: kubernetes,1,1024M - trust: true -relations: -- - mimir:s3 - - mimir-s3-integrator:s3-credentials -- - loki:s3 - - loki-s3-integrator:s3-credentials -- - tempo:s3 - - tempo-s3-integrator:s3-credentials -- - traefik:certificates - - certificates:certificates -- - mimir:receive-remote-write - - otelcol:send-remote-write -- - mimir:receive-remote-write - - tempo:send-remote-write -- - otelcol:send-traces - - tempo:tracing -- - catalogue:catalogue - - tempo:catalogue -- - catalogue:catalogue - - mimir:catalogue -- - alertmanager:catalogue - - catalogue:catalogue -- - catalogue:catalogue - - grafana:catalogue -- - tempo:ingress - - traefik:traefik-route -- - grafana:ingress - - traefik:traefik-route -- - catalogue:ingress - - traefik:ingress -- - grafana:grafana-source - - loki:grafana-source -- - alertmanager:ingress - - traefik:ingress -- - otelcol:metrics-endpoint - - alertmanager:self-metrics-endpoint -- - grafana:grafana-source - - mimir:grafana-source -- - grafana:grafana-source - - tempo:grafana-source -- - alertmanager:grafana-source - - grafana:grafana-source -- - otelcol:metrics-endpoint - - tempo:metrics-endpoint -- - otelcol:metrics-endpoint - - loki:self-metrics-endpoint -- - otelcol:metrics-endpoint - - mimir:self-metrics-endpoint -- - loki:ingress - - traefik:ingress -- - mimir:ingress - - traefik:ingress -- - mimir:charm-tracing - - otelcol:receive-traces -- - loki:logging - - otelcol:send-loki-logs -- - loki:charm-tracing - - otelcol:receive-traces -- - grafana:charm-tracing - - otelcol:receive-traces -- - alertmanager:alerting - - loki:alertmanager -- - alertmanager:alerting - - mimir:alertmanager -- - loki:logging-consumer - - otelcol:receive-loki-logs -- - grafana:grafana-dashboard - - mimir:grafana-dashboards-provider -- - grafana:grafana-dashboard - - loki:grafana-dashboards-provider -- - tempo:logging - - otelcol:receive-loki-logs -- - alertmanager:grafana-dashboard - - grafana:grafana-dashboard -- - grafana:grafana-dashboard - - tempo:grafana-dashboard -- - mimir:logging-consumer - - otelcol:receive-loki-logs -- - tempo-worker:tempo-cluster - - tempo:tempo-cluster -- - mimir-worker:mimir-cluster - - mimir:mimir-cluster -- - loki-worker:loki-cluster - - loki:loki-cluster ---- # overlay.yaml -applications: - alertmanager: - offers: - alertmanager-karma-dashboard: - endpoints: - - karma-dashboard - acl: - admin: admin - grafana: - offers: - grafana-dashboards: - endpoints: - - grafana-dashboard - acl: - admin: admin - loki: - offers: - loki-logging: - endpoints: - - logging - acl: - admin: admin - mimir: - offers: - mimir-receive-remote-write: - endpoints: - - receive-remote-write - acl: - admin: admin diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 0eb7d3b5..9a3a9653 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -8,7 +8,6 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" @@ -23,10 +22,6 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) -@pytest.mark.skip() # TODO: Remove this -@pytest.mark.xfail( - reason="When host is resource-constrained, model can take too long to settle" -) def test_deploy_from_track( tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju ): diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py deleted file mode 100644 index b91716e3..00000000 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full_bundle.py +++ /dev/null @@ -1,56 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS with external and internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -import os -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error, render_bundle - -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" -TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" -S3_ENDPOINT = { - "s3_endpoint": os.getenv("S3_ENDPOINT"), - "s3_secret_key": os.getenv("S3_SECRET_KEY"), - "s3_access_key": os.getenv("S3_ACCESS_KEY"), -} - - -def test_envvars(): - assert all(S3_ENDPOINT.values()) - - -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply( - "ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT - ) - render_bundle( - TRACK_2_BUNDLE_TEMPLATE, - TRACK_2_RENDERED_BUNDLE, - variables={ - "s3_endpoint": S3_ENDPOINT["s3_endpoint"], - "ca_model": ca_model.model, - }, - ) - cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) - os.remove(TRACK_2_RENDERED_BUNDLE) - s3_creds = cos_model.add_secret( - "s3creds", - { - "access-key": S3_ENDPOINT["s3_access_key"], - "secret-key": S3_ENDPOINT["s3_secret_key"], - }, - ) - for coordinator in ["loki", "mimir", "tempo"]: - cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") - cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - - wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_full/track-2.yaml.j2 b/tests/integration/cos/tls_full/track-2.yaml.j2 deleted file mode 100644 index 8f3011c0..00000000 --- a/tests/integration/cos/tls_full/track-2.yaml.j2 +++ /dev/null @@ -1,305 +0,0 @@ -bundle: kubernetes -saas: - certificates: - url: admin/{{ ca_model }}.certificates -applications: - alertmanager: - charm: alertmanager-k8s - channel: 2/edge - revision: 188 - resources: - alertmanager-image: 101 - scale: 1 - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - trust: true - ca: - charm: self-signed-certificates - channel: 1/stable - revision: 317 - scale: 1 - constraints: arch=amd64 - catalogue: - charm: catalogue-k8s - channel: 2/edge - revision: 108 - resources: - catalogue-image: 37 - scale: 1 - constraints: arch=amd64 - trust: true - grafana: - charm: grafana-k8s - channel: 2/edge - revision: 169 - resources: - grafana-image: 77 - litestream-image: 46 - scale: 1 - constraints: arch=amd64 - storage: - database: kubernetes,1,1024M - trust: true - loki: - charm: loki-coordinator-k8s - channel: 2/edge - revision: 49 - resources: - nginx-image: 7 - nginx-prometheus-exporter-image: 3 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname - trust: true - loki-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: loki - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - loki-worker: - charm: loki-worker-k8s - channel: 2/edge - revision: 50 - resources: - loki-image: 3 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - loki-persisted: kubernetes,1,1024M - trust: true - mimir: - charm: mimir-coordinator-k8s - channel: 2/edge - revision: 68 - resources: - nginx-image: 15 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname - trust: true - mimir-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: mimir - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - mimir-worker: - charm: mimir-worker-k8s - channel: 2/edge - revision: 58 - resources: - mimir-image: 16 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - recovery-data: kubernetes,1,1024M - trust: true - otelcol: - charm: opentelemetry-collector-k8s - channel: 2/edge - revision: 99 - resources: - opentelemetry-collector-image: 9 - scale: 1 - constraints: arch=amd64 - storage: - persisted: kubernetes,1,1024M - trust: true - tempo: - charm: tempo-coordinator-k8s - channel: 2/edge - revision: 128 - resources: - nginx-image: 8 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname - trust: true - tempo-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: tempo - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - tempo-worker: - charm: tempo-worker-k8s - channel: 2/edge - revision: 86 - resources: - tempo-image: 12 - scale: 1 - constraints: arch=amd64 - storage: - wal: kubernetes,1,1024M - trust: true - traefik: - charm: traefik-k8s - channel: latest/stable - revision: 254 - base: ubuntu@20.04/stable - resources: - traefik-image: 162 - scale: 1 - constraints: arch=amd64 - storage: - configurations: kubernetes,1,1024M - trust: true -relations: -- - mimir:s3 - - mimir-s3-integrator:s3-credentials -- - loki:s3 - - loki-s3-integrator:s3-credentials -- - tempo:s3 - - tempo-s3-integrator:s3-credentials -- - traefik:certificates - - certificates:certificates -- - traefik:receive-ca-cert - - ca:send-ca-cert -- - mimir:receive-remote-write - - otelcol:send-remote-write -- - mimir:receive-remote-write - - tempo:send-remote-write -- - otelcol:send-traces - - tempo:tracing -- - catalogue:catalogue - - tempo:catalogue -- - catalogue:catalogue - - mimir:catalogue -- - alertmanager:catalogue - - catalogue:catalogue -- - catalogue:catalogue - - grafana:catalogue -- - tempo:ingress - - traefik:traefik-route -- - grafana:ingress - - traefik:traefik-route -- - catalogue:ingress - - traefik:ingress -- - grafana:grafana-source - - loki:grafana-source -- - alertmanager:ingress - - traefik:ingress -- - otelcol:metrics-endpoint - - alertmanager:self-metrics-endpoint -- - grafana:grafana-source - - mimir:grafana-source -- - grafana:grafana-source - - tempo:grafana-source -- - alertmanager:grafana-source - - grafana:grafana-source -- - otelcol:metrics-endpoint - - tempo:metrics-endpoint -- - otelcol:metrics-endpoint - - loki:self-metrics-endpoint -- - otelcol:metrics-endpoint - - mimir:self-metrics-endpoint -- - loki:ingress - - traefik:ingress -- - mimir:ingress - - traefik:ingress -- - mimir:charm-tracing - - otelcol:receive-traces -- - loki:logging - - otelcol:send-loki-logs -- - loki:charm-tracing - - otelcol:receive-traces -- - ca:certificates - - mimir:certificates -- - grafana:charm-tracing - - otelcol:receive-traces -- - alertmanager:alerting - - loki:alertmanager -- - ca:certificates - - grafana:certificates -- - ca:certificates - - tempo:certificates -- - ca:certificates - - catalogue:certificates -- - alertmanager:certificates - - ca:certificates -- - ca:certificates - - otelcol:receive-server-cert -- - ca:certificates - - loki:certificates -- - alertmanager:alerting - - mimir:alertmanager -- - loki:logging-consumer - - otelcol:receive-loki-logs -- - grafana:grafana-dashboard - - mimir:grafana-dashboards-provider -- - grafana:grafana-dashboard - - loki:grafana-dashboards-provider -- - tempo:logging - - otelcol:receive-loki-logs -- - alertmanager:grafana-dashboard - - grafana:grafana-dashboard -- - grafana:grafana-dashboard - - tempo:grafana-dashboard -- - mimir:logging-consumer - - otelcol:receive-loki-logs -- - tempo-worker:tempo-cluster - - tempo:tempo-cluster -- - mimir-worker:mimir-cluster - - mimir:mimir-cluster -- - loki-worker:loki-cluster - - loki:loki-cluster ---- # overlay.yaml -applications: - alertmanager: - offers: - alertmanager-karma-dashboard: - endpoints: - - karma-dashboard - acl: - admin: admin - ca: - offers: - certificates: - endpoints: - - certificates - acl: - admin: admin - send-ca-cert: - endpoints: - - send-ca-cert - acl: - admin: admin - grafana: - offers: - grafana-dashboards: - endpoints: - - grafana-dashboard - acl: - admin: admin - loki: - offers: - loki-logging: - endpoints: - - logging - acl: - admin: admin - mimir: - offers: - mimir-receive-remote-write: - endpoints: - - receive-remote-write - acl: - admin: admin diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index cf0f6fc3..6e73fdd1 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -8,7 +8,6 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" @@ -23,10 +22,6 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) -@pytest.mark.skip() -@pytest.mark.xfail( - reason="When host is resource-constrained, model can take too long to settle" -) def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py deleted file mode 100644 index 6225533a..00000000 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal_bundle.py +++ /dev/null @@ -1,52 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS with internal TLS, and without external TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -import os -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error, render_bundle - -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" -TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" -S3_ENDPOINT = { - "s3_endpoint": os.getenv("S3_ENDPOINT"), - "s3_secret_key": os.getenv("S3_SECRET_KEY"), - "s3_access_key": os.getenv("S3_ACCESS_KEY"), -} - - -def test_envvars(): - assert all(S3_ENDPOINT.values()) - - -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n - render_bundle( - TRACK_2_BUNDLE_TEMPLATE, - TRACK_2_RENDERED_BUNDLE, - variables={ - "s3_endpoint": S3_ENDPOINT["s3_endpoint"], - "ca_model": ca_model.model, - }, - ) - cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) - os.remove(TRACK_2_RENDERED_BUNDLE) - s3_creds = cos_model.add_secret( - "s3creds", - { - "access-key": S3_ENDPOINT["s3_access_key"], - "secret-key": S3_ENDPOINT["s3_secret_key"], - }, - ) - for coordinator in ["loki", "mimir", "tempo"]: - cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") - cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - - wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_internal/track-2.yaml.j2 b/tests/integration/cos/tls_internal/track-2.yaml.j2 deleted file mode 100644 index 9a95930b..00000000 --- a/tests/integration/cos/tls_internal/track-2.yaml.j2 +++ /dev/null @@ -1,300 +0,0 @@ -bundle: kubernetes -applications: - alertmanager: - charm: alertmanager-k8s - channel: 2/edge - revision: 188 - resources: - alertmanager-image: 101 - scale: 1 - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - trust: true - ca: - charm: self-signed-certificates - channel: 1/stable - revision: 317 - scale: 1 - constraints: arch=amd64 - catalogue: - charm: catalogue-k8s - channel: 2/edge - revision: 108 - resources: - catalogue-image: 37 - scale: 1 - constraints: arch=amd64 - trust: true - grafana: - charm: grafana-k8s - channel: 2/edge - revision: 169 - resources: - grafana-image: 77 - litestream-image: 46 - scale: 1 - constraints: arch=amd64 - storage: - database: kubernetes,1,1024M - trust: true - loki: - charm: loki-coordinator-k8s - channel: 2/edge - revision: 49 - resources: - nginx-image: 7 - nginx-prometheus-exporter-image: 3 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname - trust: true - loki-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: loki - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - loki-worker: - charm: loki-worker-k8s - channel: 2/edge - revision: 50 - resources: - loki-image: 3 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - loki-persisted: kubernetes,1,1024M - trust: true - mimir: - charm: mimir-coordinator-k8s - channel: 2/edge - revision: 68 - resources: - nginx-image: 15 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname - trust: true - mimir-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: mimir - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - mimir-worker: - charm: mimir-worker-k8s - channel: 2/edge - revision: 58 - resources: - mimir-image: 16 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - recovery-data: kubernetes,1,1024M - trust: true - otelcol: - charm: opentelemetry-collector-k8s - channel: 2/edge - revision: 99 - resources: - opentelemetry-collector-image: 9 - scale: 1 - constraints: arch=amd64 - storage: - persisted: kubernetes,1,1024M - trust: true - tempo: - charm: tempo-coordinator-k8s - channel: 2/edge - revision: 128 - resources: - nginx-image: 8 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname - trust: true - tempo-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: tempo - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - tempo-worker: - charm: tempo-worker-k8s - channel: 2/edge - revision: 86 - resources: - tempo-image: 12 - scale: 1 - constraints: arch=amd64 - storage: - wal: kubernetes,1,1024M - trust: true - traefik: - charm: traefik-k8s - channel: latest/stable - revision: 254 - base: ubuntu@20.04/stable - resources: - traefik-image: 162 - scale: 1 - constraints: arch=amd64 - storage: - configurations: kubernetes,1,1024M - trust: true -relations: -- - mimir:s3 - - mimir-s3-integrator:s3-credentials -- - loki:s3 - - loki-s3-integrator:s3-credentials -- - tempo:s3 - - tempo-s3-integrator:s3-credentials -- - traefik:receive-ca-cert - - ca:send-ca-cert -- - mimir:receive-remote-write - - otelcol:send-remote-write -- - mimir:receive-remote-write - - tempo:send-remote-write -- - otelcol:send-traces - - tempo:tracing -- - catalogue:catalogue - - tempo:catalogue -- - catalogue:catalogue - - mimir:catalogue -- - alertmanager:catalogue - - catalogue:catalogue -- - catalogue:catalogue - - grafana:catalogue -- - tempo:ingress - - traefik:traefik-route -- - grafana:ingress - - traefik:traefik-route -- - catalogue:ingress - - traefik:ingress -- - grafana:grafana-source - - loki:grafana-source -- - alertmanager:ingress - - traefik:ingress -- - otelcol:metrics-endpoint - - alertmanager:self-metrics-endpoint -- - grafana:grafana-source - - mimir:grafana-source -- - grafana:grafana-source - - tempo:grafana-source -- - alertmanager:grafana-source - - grafana:grafana-source -- - otelcol:metrics-endpoint - - tempo:metrics-endpoint -- - otelcol:metrics-endpoint - - loki:self-metrics-endpoint -- - otelcol:metrics-endpoint - - mimir:self-metrics-endpoint -- - loki:ingress - - traefik:ingress -- - mimir:ingress - - traefik:ingress -- - mimir:charm-tracing - - otelcol:receive-traces -- - loki:logging - - otelcol:send-loki-logs -- - loki:charm-tracing - - otelcol:receive-traces -- - ca:certificates - - mimir:certificates -- - grafana:charm-tracing - - otelcol:receive-traces -- - alertmanager:alerting - - loki:alertmanager -- - ca:certificates - - grafana:certificates -- - ca:certificates - - tempo:certificates -- - ca:certificates - - catalogue:certificates -- - alertmanager:certificates - - ca:certificates -- - ca:certificates - - otelcol:receive-server-cert -- - ca:certificates - - loki:certificates -- - alertmanager:alerting - - mimir:alertmanager -- - loki:logging-consumer - - otelcol:receive-loki-logs -- - grafana:grafana-dashboard - - mimir:grafana-dashboards-provider -- - grafana:grafana-dashboard - - loki:grafana-dashboards-provider -- - tempo:logging - - otelcol:receive-loki-logs -- - alertmanager:grafana-dashboard - - grafana:grafana-dashboard -- - grafana:grafana-dashboard - - tempo:grafana-dashboard -- - mimir:logging-consumer - - otelcol:receive-loki-logs -- - tempo-worker:tempo-cluster - - tempo:tempo-cluster -- - mimir-worker:mimir-cluster - - mimir:mimir-cluster -- - loki-worker:loki-cluster - - loki:loki-cluster ---- # overlay.yaml -applications: - alertmanager: - offers: - alertmanager-karma-dashboard: - endpoints: - - karma-dashboard - acl: - admin: admin - ca: - offers: - certificates: - endpoints: - - certificates - acl: - admin: admin - send-ca-cert: - endpoints: - - send-ca-cert - acl: - admin: admin - grafana: - offers: - grafana-dashboards: - endpoints: - - grafana-dashboard - acl: - admin: admin - loki: - offers: - loki-logging: - endpoints: - - logging - acl: - admin: admin - mimir: - offers: - mimir-receive-remote-write: - endpoints: - - receive-remote-write - acl: - admin: admin diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index ea12c6a8..82f7133a 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -8,7 +8,6 @@ from pathlib import Path import jubilant -import pytest from helpers import wait_for_active_idle_without_error TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" @@ -23,10 +22,6 @@ def test_envvars(): assert all(S3_ENDPOINT.values()) -@pytest.mark.skip() -@pytest.mark.xfail( - reason="When host is resource-constrained, model can take too long to settle" -) def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py deleted file mode 100644 index 9fb0077b..00000000 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none_bundle.py +++ /dev/null @@ -1,52 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS without external and internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -import os -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error, render_bundle - -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" -TRACK_2_BUNDLE_TEMPLATE = Path(__file__).parent.resolve() / "track-2.yaml.j2" -TRACK_2_RENDERED_BUNDLE = Path(__file__).parent.resolve() / "rendered-track-2.yaml" -S3_ENDPOINT = { - "s3_endpoint": os.getenv("S3_ENDPOINT"), - "s3_secret_key": os.getenv("S3_SECRET_KEY"), - "s3_access_key": os.getenv("S3_ACCESS_KEY"), -} - - -def test_envvars(): - assert all(S3_ENDPOINT.values()) - - -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n - render_bundle( - TRACK_2_BUNDLE_TEMPLATE, - TRACK_2_RENDERED_BUNDLE, - variables={ - "s3_endpoint": S3_ENDPOINT["s3_endpoint"], - "ca_model": ca_model.model, - }, - ) - cos_model.deploy(TRACK_2_RENDERED_BUNDLE, trust=True) - os.remove(TRACK_2_RENDERED_BUNDLE) - s3_creds = cos_model.add_secret( - "s3creds", - { - "access-key": S3_ENDPOINT["s3_access_key"], - "secret-key": S3_ENDPOINT["s3_secret_key"], - }, - ) - for coordinator in ["loki", "mimir", "tempo"]: - cos_model.grant_secret(s3_creds, f"{coordinator}-s3-integrator") - cos_model.config(f"{coordinator}-s3-integrator", {"credentials": s3_creds}) - - wait_for_active_idle_without_error([cos_model], timeout=21600) diff --git a/tests/integration/cos/tls_none/track-2.yaml.j2 b/tests/integration/cos/tls_none/track-2.yaml.j2 deleted file mode 100644 index 20cee093..00000000 --- a/tests/integration/cos/tls_none/track-2.yaml.j2 +++ /dev/null @@ -1,266 +0,0 @@ -bundle: kubernetes -applications: - alertmanager: - charm: alertmanager-k8s - channel: 2/edge - revision: 188 - resources: - alertmanager-image: 101 - scale: 1 - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - trust: true - catalogue: - charm: catalogue-k8s - channel: 2/edge - revision: 108 - resources: - catalogue-image: 37 - scale: 1 - constraints: arch=amd64 - trust: true - grafana: - charm: grafana-k8s - channel: 2/edge - revision: 169 - resources: - grafana-image: 77 - litestream-image: 46 - scale: 1 - constraints: arch=amd64 - storage: - database: kubernetes,1,1024M - trust: true - loki: - charm: loki-coordinator-k8s - channel: 2/edge - revision: 49 - resources: - nginx-image: 7 - nginx-prometheus-exporter-image: 3 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=loki,anti-pod.topology-key=kubernetes.io/hostname - trust: true - loki-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: loki - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - loki-worker: - charm: loki-worker-k8s - channel: 2/edge - revision: 50 - resources: - loki-image: 3 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - loki-persisted: kubernetes,1,1024M - trust: true - mimir: - charm: mimir-coordinator-k8s - channel: 2/edge - revision: 68 - resources: - nginx-image: 15 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=mimir,anti-pod.topology-key=kubernetes.io/hostname - trust: true - mimir-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: mimir - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - mimir-worker: - charm: mimir-worker-k8s - channel: 2/edge - revision: 58 - resources: - mimir-image: 16 - scale: 1 - options: - role-all: true - constraints: arch=amd64 - storage: - data: kubernetes,1,1024M - recovery-data: kubernetes,1,1024M - trust: true - otelcol: - charm: opentelemetry-collector-k8s - channel: 2/edge - revision: 99 - resources: - opentelemetry-collector-image: 9 - scale: 1 - constraints: arch=amd64 - storage: - persisted: kubernetes,1,1024M - trust: true - tempo: - charm: tempo-coordinator-k8s - channel: 2/edge - revision: 128 - resources: - nginx-image: 8 - nginx-prometheus-exporter-image: 4 - scale: 1 - constraints: arch=amd64 tags=anti-pod.app.kubernetes.io/name=tempo,anti-pod.topology-key=kubernetes.io/hostname - trust: true - tempo-s3-integrator: - charm: s3-integrator - channel: 2/edge - revision: 243 - scale: 1 - options: - bucket: tempo - endpoint: {{ s3_endpoint }} - constraints: arch=amd64 - trust: true - tempo-worker: - charm: tempo-worker-k8s - channel: 2/edge - revision: 86 - resources: - tempo-image: 12 - scale: 1 - constraints: arch=amd64 - storage: - wal: kubernetes,1,1024M - trust: true - traefik: - charm: traefik-k8s - channel: latest/stable - revision: 254 - base: ubuntu@20.04/stable - resources: - traefik-image: 162 - scale: 1 - constraints: arch=amd64 - storage: - configurations: kubernetes,1,1024M - trust: true -relations: -- - mimir:s3 - - mimir-s3-integrator:s3-credentials -- - loki:s3 - - loki-s3-integrator:s3-credentials -- - tempo:s3 - - tempo-s3-integrator:s3-credentials -- - mimir:receive-remote-write - - otelcol:send-remote-write -- - mimir:receive-remote-write - - tempo:send-remote-write -- - otelcol:send-traces - - tempo:tracing -- - catalogue:catalogue - - tempo:catalogue -- - catalogue:catalogue - - mimir:catalogue -- - alertmanager:catalogue - - catalogue:catalogue -- - catalogue:catalogue - - grafana:catalogue -- - tempo:ingress - - traefik:traefik-route -- - grafana:ingress - - traefik:traefik-route -- - catalogue:ingress - - traefik:ingress -- - grafana:grafana-source - - loki:grafana-source -- - alertmanager:ingress - - traefik:ingress -- - otelcol:metrics-endpoint - - alertmanager:self-metrics-endpoint -- - grafana:grafana-source - - mimir:grafana-source -- - grafana:grafana-source - - tempo:grafana-source -- - alertmanager:grafana-source - - grafana:grafana-source -- - otelcol:metrics-endpoint - - tempo:metrics-endpoint -- - otelcol:metrics-endpoint - - loki:self-metrics-endpoint -- - otelcol:metrics-endpoint - - mimir:self-metrics-endpoint -- - loki:ingress - - traefik:ingress -- - mimir:ingress - - traefik:ingress -- - mimir:charm-tracing - - otelcol:receive-traces -- - loki:logging - - otelcol:send-loki-logs -- - loki:charm-tracing - - otelcol:receive-traces -- - grafana:charm-tracing - - otelcol:receive-traces -- - alertmanager:alerting - - loki:alertmanager -- - alertmanager:alerting - - mimir:alertmanager -- - loki:logging-consumer - - otelcol:receive-loki-logs -- - grafana:grafana-dashboard - - mimir:grafana-dashboards-provider -- - grafana:grafana-dashboard - - loki:grafana-dashboards-provider -- - tempo:logging - - otelcol:receive-loki-logs -- - alertmanager:grafana-dashboard - - grafana:grafana-dashboard -- - grafana:grafana-dashboard - - tempo:grafana-dashboard -- - mimir:logging-consumer - - otelcol:receive-loki-logs -- - tempo-worker:tempo-cluster - - tempo:tempo-cluster -- - mimir-worker:mimir-cluster - - mimir:mimir-cluster -- - loki-worker:loki-cluster - - loki:loki-cluster ---- # overlay.yaml -applications: - alertmanager: - offers: - alertmanager-karma-dashboard: - endpoints: - - karma-dashboard - acl: - admin: admin - grafana: - offers: - grafana-dashboards: - endpoints: - - grafana-dashboard - acl: - admin: admin - loki: - offers: - loki-logging: - endpoints: - - logging - acl: - admin: admin - mimir: - offers: - mimir-receive-remote-write: - endpoints: - - receive-remote-write - acl: - admin: admin diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 6077338c..26dcc827 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -2,11 +2,9 @@ import shlex import shutil import subprocess -from pathlib import Path -from typing import Dict, List, Optional +from typing import List, Optional import jubilant -from jinja2 import Template class TfDirManager: @@ -55,18 +53,3 @@ def wait_for_active_idle_without_error( timeout=60 * 5, error=jubilant.any_error, ) - - -def render_bundle( - template: Path, output: Path, variables: Optional[Dict[str, str]] = None -): - if variables is None: - variables = {} - with open(template) as t: - jinja_template = Template(t.read(), autoescape=True) - - with open(output, "wt") as o: - # Type-ignore because pyright complains: - # Argument 1 to "dump" of "TemplateStream" has - # incompatible type "TextIOWrapper"; expected "Union[str, IO[bytes]]" - jinja_template.stream(**variables).dump(o) # type: ignore[arg-type] From 6c111ad77e6b028c018a527cf26148bf93b01fa7 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 12:04:26 -0400 Subject: [PATCH 056/108] chore: make microceph required for COS --- .github/workflows/_integration.yaml | 3 --- .github/workflows/terraform.yml | 8 ++++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index 014be54a..ce5efac1 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -12,9 +12,6 @@ on: default: '["ubuntu-latest"]' jobs: - setup-microceph: - name: Install and setup Microceph - uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch terraform-test: name: Test product module runs-on: ${{ fromJson(inputs.runner-labels) }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index b2760824..e4f6d790 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -47,13 +47,17 @@ jobs: run: just validate-terraform test-integration-cos-lite: name: COS Lite Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch with: product: cos_lite runner-labels: '["ubuntu-latest"]' + setup-microceph: + name: Install and setup Microceph + uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch test-integration-cos: name: COS Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch + needs: setup-microceph + uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch with: product: cos runner-labels: '["self-hosted","linux","amd64","noble","xlarge"]' From f9f0d0ebeafc926632b1f4caa71401675ca5c240 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 12:21:49 -0400 Subject: [PATCH 057/108] chore: make microceph required for COS --- .github/workflows/_integration.yaml | 35 ++++++++++++++++++++-- .github/workflows/_setup_microceph.yml | 41 -------------------------- .github/workflows/terraform.yml | 3 -- 3 files changed, 33 insertions(+), 46 deletions(-) delete mode 100644 .github/workflows/_setup_microceph.yml diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index ce5efac1..ec33d4cd 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -26,10 +26,41 @@ jobs: run: | sudo snap install concierge --classic sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform - - name: Test deployment + - name: Install and configure microceph + if: ${{ inputs.product == 'cos' }} run: | - # TODO make these env vars in workflow or from repo secrets + # https://github.com/canonical/microceph-action/blob/main/microceph.sh + function check_ceph_ok_or_exit () { + i=0 + for i in {1..5}; do + if sudo microceph.ceph status | grep HEALTH_OK; then + break + else + sudo microceph.ceph status + sleep 30 + sudo microceph.ceph health detail + fi + done + if [ "$i" -eq 5 ]; then + exit 1 + fi + } + + sudo snap install microceph + sudo microceph cluster bootstrap + sleep 30s + sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 + sudo microceph disk add loop,2G,3 + check_ceph_ok_or_exit + + sudo microceph enable rgw --port 8080 --ssl-port 8443 + sudo microceph.radosgw-admin user create --uid=user --display-name=User + sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key + + # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key + - name: Test deployment + run: | just integration ${{ inputs.product }}/${{ matrix.scenario }} diff --git a/.github/workflows/_setup_microceph.yml b/.github/workflows/_setup_microceph.yml deleted file mode 100644 index 6fb34ea8..00000000 --- a/.github/workflows/_setup_microceph.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Terraform - -on: - workflow_call: - -jobs: - microceph: - name: microceph - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install and configure microceph - run: | - # https://github.com/canonical/microceph-action/blob/main/microceph.sh - function check_ceph_ok_or_exit () { - i=0 - for i in {1..5}; do - if sudo microceph.ceph status | grep HEALTH_OK; then - break - else - sudo microceph.ceph status - sleep 30 - sudo microceph.ceph health detail - fi - done - if [ "$i" -eq 5 ]; then - exit 1 - fi - } - - sudo snap install microceph - sudo microceph cluster bootstrap - sleep 30s - sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 - sudo microceph disk add loop,2G,3 - check_ceph_ok_or_exit - - sudo microceph enable rgw --port 8080 --ssl-port 8443 - sudo microceph.radosgw-admin user create --uid=user --display-name=User - sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index e4f6d790..231fc2ad 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -51,9 +51,6 @@ jobs: with: product: cos_lite runner-labels: '["ubuntu-latest"]' - setup-microceph: - name: Install and setup Microceph - uses: canonical/observability-stack/.github/workflows/_setup_microceph.yml@feat/cos-upgrade # TODO: Fix branch test-integration-cos: name: COS Terraform integration needs: setup-microceph From 7710b2c99a0fccea98f531a4df7d4a5ecb6ee192 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 12:22:36 -0400 Subject: [PATCH 058/108] chore --- .github/workflows/terraform.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 231fc2ad..47af0c68 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -53,7 +53,6 @@ jobs: runner-labels: '["ubuntu-latest"]' test-integration-cos: name: COS Terraform integration - needs: setup-microceph uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch with: product: cos From 76888a22d53da3104c8ad1b96348708fe1484db7 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 12:56:48 -0400 Subject: [PATCH 059/108] test: self-hosted-linux-amd64-noble-xlarge --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 47af0c68..a2aa9e84 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -56,4 +56,4 @@ jobs: uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch with: product: cos - runner-labels: '["self-hosted","linux","amd64","noble","xlarge"]' + runner-labels: '["self-hosted-linux-amd64-noble-xlarge"]' From ea6222eea398d2f12821d1dde22c4490e2730f15 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 13:49:47 -0400 Subject: [PATCH 060/108] chore: try more resources --- .github/workflows/_integration.yaml | 4 ++-- .github/workflows/terraform.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index ec33d4cd..dcf7858d 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -9,12 +9,12 @@ on: type: string runner-labels: type: string - default: '["ubuntu-latest"]' + default: ubuntu-latest jobs: terraform-test: name: Test product module - runs-on: ${{ fromJson(inputs.runner-labels) }} + runs-on: ${{ inputs.runner-labels }} strategy: fail-fast: false matrix: diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index a2aa9e84..61ea58c4 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -50,10 +50,10 @@ jobs: uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch with: product: cos_lite - runner-labels: '["ubuntu-latest"]' + runner-labels: ubuntu-latest test-integration-cos: name: COS Terraform integration uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch with: product: cos - runner-labels: '["self-hosted-linux-amd64-noble-xlarge"]' + runner-labels: self-hosted-linux-amd64-noble-2xlarge From e10850b0a9ff04dfb4b5d07d5b31503a39a9164d Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 23 Oct 2025 13:55:20 -0400 Subject: [PATCH 061/108] chore: remove duplicate tests --- .../tls_external/test_upgrade_tls_external.py | 37 ------------------- .../tls_full/test_upgrade_tls_full.py | 37 ------------------- .../tls_internal/test_upgrade_tls_internal.py | 28 -------------- .../tls_none/test_upgrade_tls_none.py | 28 -------------- 4 files changed, 130 deletions(-) delete mode 100644 tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py delete mode 100644 tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py delete mode 100644 tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py delete mode 100644 tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py diff --git a/tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py deleted file mode 100644 index c616c52c..00000000 --- a/tests/integration/cos_lite/tls_external/test_upgrade_tls_external.py +++ /dev/null @@ -1,37 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS with external TLS, and without internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error - -TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" - - -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n-1 - tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply( - # NOTE: "Terraform cannot predict how many instances will be created. To work around this, - # use the -target argument to first apply only the resources that the count depends on." - target="ssc", - ca_model=ca_model.model, - cos_model=cos_model.model, - ) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - wait_for_active_idle_without_error([ca_model, cos_model]) - - -def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - # WHEN upgraded to track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py deleted file mode 100644 index 8f103bb7..00000000 --- a/tests/integration/cos_lite/tls_full/test_upgrade_tls_full.py +++ /dev/null @@ -1,37 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS with external and internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error - -TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" - - -def test_deploy_from_track( - tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju -): - # GIVEN a module deployed from track n-1 - tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply( - # NOTE: "Terraform cannot predict how many instances will be created. To work around this, - # use the -target argument to first apply only the resources that the count depends on." - target="ssc", - ca_model=ca_model.model, - cos_model=cos_model.model, - ) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - wait_for_active_idle_without_error([ca_model, cos_model]) - - -def test_deploy_to_track(tf_manager, ca_model: jubilant.Juju, cos_model: jubilant.Juju): - # WHEN upgraded to track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) - # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py b/tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py deleted file mode 100644 index 5575cba1..00000000 --- a/tests/integration/cos_lite/tls_internal/test_upgrade_tls_internal.py +++ /dev/null @@ -1,28 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS with internal TLS, and without external TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error - -TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" - - -def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): - # GIVEN a module deployed from track n-1 - tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply(model=cos_model.model) - wait_for_active_idle_without_error([cos_model]) - - -def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): - # WHEN upgraded to track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(model=cos_model.model) - # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([cos_model]) diff --git a/tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py b/tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py deleted file mode 100644 index fef51262..00000000 --- a/tests/integration/cos_lite/tls_none/test_upgrade_tls_none.py +++ /dev/null @@ -1,28 +0,0 @@ -"""There are 2 sections of the COS deployment (internal and external) which can implement TLS -communication. This python test file deploys COS without external and internal TLS. - -For more further TLS configuration details, refer to our documentation: -https://documentation.ubuntu.com/observability/latest/how-to/configure-tls-encryption/""" - -from pathlib import Path - -import jubilant -from helpers import wait_for_active_idle_without_error - -TRACK_1_TF_FILE = Path(__file__).parent.resolve() / "track-1.tf" -TRACK_2_TF_FILE = Path(__file__).parent.resolve() / "track-2.tf" - - -def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): - # GIVEN a module deployed from track n-1 - tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply(model=cos_model.model) - wait_for_active_idle_without_error([cos_model]) - - -def test_deploy_to_track(tf_manager, cos_model: jubilant.Juju): - # WHEN upgraded to track n - tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply(model=cos_model.model) - # THEN the model is upgraded and is active/idle - wait_for_active_idle_without_error([cos_model], ) From 62c8c9f1a7b19b7b3f7bf048ddc61ff80d0cef00 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 24 Oct 2025 12:02:16 -0400 Subject: [PATCH 062/108] chore: remove self-hosted runner logic --- .github/workflows/_integration.yaml | 37 +------------------ .github/workflows/terraform.yml | 10 +---- .../test_upgrade_cos_tls_external.py | 3 +- .../cos/tls_full/test_upgrade_cos_tls_full.py | 2 +- .../test_upgrade_cos_tls_internal.py | 2 +- .../cos/tls_none/test_upgrade_cos_tls_none.py | 2 +- 6 files changed, 8 insertions(+), 48 deletions(-) diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index dcf7858d..818ed350 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -7,7 +7,7 @@ on: product: required: true type: string - runner-labels: + runner: type: string default: ubuntu-latest @@ -26,41 +26,6 @@ jobs: run: | sudo snap install concierge --classic sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform - - name: Install and configure microceph - if: ${{ inputs.product == 'cos' }} - run: | - # https://github.com/canonical/microceph-action/blob/main/microceph.sh - function check_ceph_ok_or_exit () { - i=0 - for i in {1..5}; do - if sudo microceph.ceph status | grep HEALTH_OK; then - break - else - sudo microceph.ceph status - sleep 30 - sudo microceph.ceph health detail - fi - done - if [ "$i" -eq 5 ]; then - exit 1 - fi - } - - sudo snap install microceph - sudo microceph cluster bootstrap - sleep 30s - sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 - sudo microceph disk add loop,2G,3 - check_ceph_ok_or_exit - - sudo microceph enable rgw --port 8080 --ssl-port 8443 - sudo microceph.radosgw-admin user create --uid=user --display-name=User - sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key - - # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} - export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 - export S3_ACCESS_KEY=access-key - export S3_SECRET_KEY=secret-key - name: Test deployment run: | just integration ${{ inputs.product }}/${{ matrix.scenario }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 61ea58c4..db5fe889 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -47,13 +47,7 @@ jobs: run: just validate-terraform test-integration-cos-lite: name: COS Lite Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yaml@main with: product: cos_lite - runner-labels: ubuntu-latest - test-integration-cos: - name: COS Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/cos-upgrade # TODO: Fix branch - with: - product: cos - runner-labels: self-hosted-linux-amd64-noble-2xlarge + runner: ubuntu-latest diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 3311a313..0b1c8859 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -40,4 +40,5 @@ def test_deploy_from_track( cos_model=cos_model.model, **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=7200) # TODO: Reduce if not needed + wait_for_active_idle_without_error([cos_model], timeout=3600) + diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index 9a3a9653..a76e0f3e 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -40,4 +40,4 @@ def test_deploy_from_track( cos_model=cos_model.model, **S3_ENDPOINT, ) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=3600) diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 6e73fdd1..d61da226 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -26,4 +26,4 @@ def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) tf_manager.apply(model=cos_model.model, **S3_ENDPOINT) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=3600) diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index 82f7133a..ea48fcb9 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -26,4 +26,4 @@ def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) tf_manager.apply(model=cos_model.model, **S3_ENDPOINT) - wait_for_active_idle_without_error([cos_model], timeout=7200) + wait_for_active_idle_without_error([cos_model], timeout=3600) From 003f92aca0174b47daa795f1348c8a82522248ac Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 24 Oct 2025 12:11:49 -0400 Subject: [PATCH 063/108] first attempts --- .github/workflows/_integration.yaml | 35 +++++++++++++++++++++++++++++ .github/workflows/terraform.yml | 6 +++++ 2 files changed, 41 insertions(+) diff --git a/.github/workflows/_integration.yaml b/.github/workflows/_integration.yaml index 818ed350..c804cb49 100644 --- a/.github/workflows/_integration.yaml +++ b/.github/workflows/_integration.yaml @@ -26,6 +26,41 @@ jobs: run: | sudo snap install concierge --classic sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform + - name: Install and configure microceph + if: ${{ inputs.product == 'cos' }} + run: | + # https://github.com/canonical/microceph-action/blob/main/microceph.sh + function check_ceph_ok_or_exit () { + i=0 + for i in {1..5}; do + if sudo microceph.ceph status | grep HEALTH_OK; then + break + else + sudo microceph.ceph status + sleep 30 + sudo microceph.ceph health detail + fi + done + if [ "$i" -eq 5 ]; then + exit 1 + fi + } + + sudo snap install microceph + sudo microceph cluster bootstrap + sleep 30s + sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 + sudo microceph disk add loop,2G,3 + check_ceph_ok_or_exit + + sudo microceph enable rgw --port 8080 --ssl-port 8443 + sudo microceph.radosgw-admin user create --uid=user --display-name=User + sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key + + # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key - name: Test deployment run: | just integration ${{ inputs.product }}/${{ matrix.scenario }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index db5fe889..27854184 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -51,3 +51,9 @@ jobs: with: product: cos_lite runner: ubuntu-latest + test-integration-cos: + name: COS Terraform integration + uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/self-hosted-runner-ci # TODO: Fix branch + with: + product: cos + runner: self-hosted-linux-amd64-noble-large From 92c709fc25e0106db7a52a64916f13f976758340 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 6 Nov 2025 12:21:42 +0100 Subject: [PATCH 064/108] test: canonical k8s --- .github/workflows/_integration.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index c804cb49..af3724e3 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -25,7 +25,8 @@ jobs: - name: Install dependencies run: | sudo snap install concierge --classic - sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform + # TODO: Find out what the snaps deploy from? + sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform - name: Install and configure microceph if: ${{ inputs.product == 'cos' }} run: | From 485bfb5214da0ad22a243180eb0037b385b12c81 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 6 Nov 2025 12:33:57 +0100 Subject: [PATCH 065/108] chore --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index af3724e3..185d6521 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -14,7 +14,7 @@ on: jobs: terraform-test: name: Test product module - runs-on: ${{ inputs.runner-labels }} + runs-on: ${{ inputs.runner }} strategy: fail-fast: false matrix: From 3166274bcae0aa700e13385747baf89cbf9d2a46 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 6 Nov 2025 12:34:44 +0100 Subject: [PATCH 066/108] chore --- terraform/cos-lite/applications.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index dd1bd5ab..632ef925 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -21,6 +21,7 @@ module "catalogue" { storage_directives = var.catalogue.storage_directives units = var.catalogue.units } +# TODO: Remove this after testing module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform" From 1aa3ba98fd0ea5a6f424da4fac58c90668887235 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 6 Nov 2025 14:25:45 +0100 Subject: [PATCH 067/108] chore --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index e658d746..7f3996b1 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -53,7 +53,7 @@ jobs: runner: ubuntu-latest test-integration-cos: name: COS Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yaml@feat/self-hosted-runner-ci # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/self-hosted-runner-ci # TODO: Fix branch with: product: cos runner: self-hosted-linux-amd64-noble-large From efd34283f3b4c0428530c34e0e8b903b4ed8979b Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 15:18:00 +0100 Subject: [PATCH 068/108] test --- .github/workflows/_integration.yml | 99 ++++++++++++++++++------------ 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 185d6521..9925b016 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,46 +22,69 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install dependencies + - name: Set up microk8s + timeout-minutes: 5 + if: ${{ inputs.runner != 'ubuntu-latest' }} run: | - sudo snap install concierge --classic - # TODO: Find out what the snaps deploy from? - sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform - - name: Install and configure microceph - if: ${{ inputs.product == 'cos' }} + sudo apt-get update + sudo apt-get install retry -y + sudo snap install microk8s --channel='1.30-strict/stable' + sudo adduser "$USER" snap_microk8s + - name: (IS hosted) Configure microk8s Docker Hub mirror + timeout-minutes: 5 + if: ${{ inputs.runner != 'ubuntu-latest' }} run: | - # https://github.com/canonical/microceph-action/blob/main/microceph.sh - function check_ceph_ok_or_exit () { - i=0 - for i in {1..5}; do - if sudo microceph.ceph status | grep HEALTH_OK; then - break - else - sudo microceph.ceph status - sleep 30 - sudo microceph.ceph health detail - fi - done - if [ "$i" -eq 5 ]; then - exit 1 - fi - } + # Wait for microk8s to populate iptables + # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo snap install microceph - sudo microceph cluster bootstrap - sleep 30s - sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 - sudo microceph disk add loop,2G,3 - check_ceph_ok_or_exit + sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml << EOF + server = "$DOCKERHUB_MIRROR" + [host."${DOCKERHUB_MIRROR#'https://'}"] + capabilities = ["pull", "resolve"] + EOF + sudo microk8s stop + sudo microk8s start + # - name: Install dependencies + # run: | + # sudo snap install concierge --classic + # # TODO: Find out what the snaps deploy from? + # sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform + # - name: Install and configure microceph + # if: ${{ inputs.product == 'cos' }} + # run: | + # # https://github.com/canonical/microceph-action/blob/main/microceph.sh + # function check_ceph_ok_or_exit () { + # i=0 + # for i in {1..5}; do + # if sudo microceph.ceph status | grep HEALTH_OK; then + # break + # else + # sudo microceph.ceph status + # sleep 30 + # sudo microceph.ceph health detail + # fi + # done + # if [ "$i" -eq 5 ]; then + # exit 1 + # fi + # } - sudo microceph enable rgw --port 8080 --ssl-port 8443 - sudo microceph.radosgw-admin user create --uid=user --display-name=User - sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key + # sudo snap install microceph + # sudo microceph cluster bootstrap + # sleep 30s + # sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 + # sudo microceph disk add loop,2G,3 + # check_ceph_ok_or_exit - # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} - export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 - export S3_ACCESS_KEY=access-key - export S3_SECRET_KEY=secret-key - - name: Test deployment - run: | - just integration ${{ inputs.product }}/${{ matrix.scenario }} + # sudo microceph enable rgw --port 8080 --ssl-port 8443 + # sudo microceph.radosgw-admin user create --uid=user --display-name=User + # sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key + + # # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} + # export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + # export S3_ACCESS_KEY=access-key + # export S3_SECRET_KEY=secret-key + # - name: Test deployment + # run: | + # just integration ${{ inputs.product }}/${{ matrix.scenario }} From 782565ee32510705ebd4ef3b8cf274da9cce6854 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 15:26:47 +0100 Subject: [PATCH 069/108] test --- .github/workflows/_integration.yml | 94 +++++++++++++++++------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 9925b016..6a8aa51d 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,7 +22,22 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up microk8s + # Setup for GitHub runners + - name: Install dependencies + if: ${{ inputs.runner == 'ubuntu-latest' }} + run: | + sudo snap install concierge --classic + # TODO: Find out what the snaps deploy from? + sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform + + # Setup for Self-hosted (PS7) runners + - name: Install snaps + if: ${{ inputs.runner != 'ubuntu-latest' }} + run: | + sudo snap install just --classic + sudo snap install astral-uv --classic + sudo snap install terraform --classic + - name: Install microk8s timeout-minutes: 5 if: ${{ inputs.runner != 'ubuntu-latest' }} run: | @@ -45,46 +60,43 @@ jobs: EOF sudo microk8s stop sudo microk8s start - # - name: Install dependencies - # run: | - # sudo snap install concierge --classic - # # TODO: Find out what the snaps deploy from? - # sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform - # - name: Install and configure microceph - # if: ${{ inputs.product == 'cos' }} - # run: | - # # https://github.com/canonical/microceph-action/blob/main/microceph.sh - # function check_ceph_ok_or_exit () { - # i=0 - # for i in {1..5}; do - # if sudo microceph.ceph status | grep HEALTH_OK; then - # break - # else - # sudo microceph.ceph status - # sleep 30 - # sudo microceph.ceph health detail - # fi - # done - # if [ "$i" -eq 5 ]; then - # exit 1 - # fi - # } + + # Runner-independent setup + - name: Install and configure microceph + if: ${{ inputs.product == 'cos' }} + run: | + # https://github.com/canonical/microceph-action/blob/main/microceph.sh + function check_ceph_ok_or_exit () { + i=0 + for i in {1..5}; do + if sudo microceph.ceph status | grep HEALTH_OK; then + break + else + sudo microceph.ceph status + sleep 30 + sudo microceph.ceph health detail + fi + done + if [ "$i" -eq 5 ]; then + exit 1 + fi + } - # sudo snap install microceph - # sudo microceph cluster bootstrap - # sleep 30s - # sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 - # sudo microceph disk add loop,2G,3 - # check_ceph_ok_or_exit + sudo snap install microceph + sudo microceph cluster bootstrap + sleep 30s + sudo microceph.ceph config set "mon.$(hostname)" mon_data_avail_warn 6 + sudo microceph disk add loop,2G,3 + check_ceph_ok_or_exit - # sudo microceph enable rgw --port 8080 --ssl-port 8443 - # sudo microceph.radosgw-admin user create --uid=user --display-name=User - # sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key + sudo microceph enable rgw --port 8080 --ssl-port 8443 + sudo microceph.radosgw-admin user create --uid=user --display-name=User + sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key - # # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} - # export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 - # export S3_ACCESS_KEY=access-key - # export S3_SECRET_KEY=secret-key - # - name: Test deployment - # run: | - # just integration ${{ inputs.product }}/${{ matrix.scenario }} + # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} + export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ACCESS_KEY=access-key + export S3_SECRET_KEY=secret-key + - name: Test deployment + run: | + just integration ${{ inputs.product }}/${{ matrix.scenario }} From 0253c3de39875f697a111e98d395841f77a52f29 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 15:33:24 +0100 Subject: [PATCH 070/108] test --- .github/workflows/_integration.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 6a8aa51d..9548efe8 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -93,10 +93,9 @@ jobs: sudo microceph.radosgw-admin user create --uid=user --display-name=User sudo microceph.radosgw-admin key create --uid=user --key-type=s3 --access-key=access-key --secret-key=secret-key - # TODO make these env vars in workflow ${{ secrets.S3_SECRET_KEY }} + - name: Test deployment + run: | export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key - - name: Test deployment - run: | just integration ${{ inputs.product }}/${{ matrix.scenario }} From 44e696354689ae70f7bb8b400f8ed4321553a015 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 16:19:59 +0100 Subject: [PATCH 071/108] test --- .github/workflows/_integration.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 9548efe8..d653b354 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -34,6 +34,7 @@ jobs: - name: Install snaps if: ${{ inputs.runner != 'ubuntu-latest' }} run: | + sudo snap install juju --classic --channel=3.6/stable sudo snap install just --classic sudo snap install astral-uv --classic sudo snap install terraform --classic @@ -95,6 +96,7 @@ jobs: - name: Test deployment run: | + # TODO: Add these as env-vars export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key From 30597ccc20de5a2b3179beb1fadefd59a95b2d22 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 17:43:38 +0100 Subject: [PATCH 072/108] initial tests for CI --- .github/workflows/_integration.yml | 28 ++++++++++++++++++++++++++-- .github/workflows/terraform.yml | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index d653b354..98291ec4 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,6 +22,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + # Setup for GitHub runners - name: Install dependencies if: ${{ inputs.runner == 'ubuntu-latest' }} @@ -29,7 +30,7 @@ jobs: sudo snap install concierge --classic # TODO: Find out what the snaps deploy from? sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform - + # Setup for Self-hosted (PS7) runners - name: Install snaps if: ${{ inputs.runner != 'ubuntu-latest' }} @@ -61,7 +62,30 @@ jobs: EOF sudo microk8s stop sudo microk8s start - + - name: Set up microk8s + timeout-minutes: 15 + if: ${{ inputs.runner != 'ubuntu-latest' }} + run: | + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/coredns + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner + + IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" + + mkdir ~/.kube/ + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config + - name: Set up environment + timeout-minutes: 15 + if: ${{ inputs.runner != 'ubuntu-latest' }} + run: | + mkdir -p ~/.local/share/juju # Workaround for juju 3 strict snap + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- juju bootstrap microk8s --config model-logs-size=10G microk8s + juju model-defaults logging-config='=INFO; unit=DEBUG' + # Runner-independent setup - name: Install and configure microceph if: ${{ inputs.product == 'cos' }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 7f3996b1..784a26c1 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -47,7 +47,7 @@ jobs: run: just validate-terraform test-integration-cos-lite: name: COS Lite Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yml@main + uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/self-hosted-runner-ci # TODO: Fix branch with: product: cos_lite runner: ubuntu-latest From 398d6c37bfce7ef7c13d2d93a0944104892404a3 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 17:51:35 +0100 Subject: [PATCH 073/108] chore --- .github/workflows/terraform.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 784a26c1..e8d4f197 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -47,13 +47,13 @@ jobs: run: just validate-terraform test-integration-cos-lite: name: COS Lite Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/self-hosted-runner-ci # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch with: product: cos_lite runner: ubuntu-latest test-integration-cos: name: COS Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yml@feat/self-hosted-runner-ci # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch with: product: cos runner: self-hosted-linux-amd64-noble-large From fe7d3f45acef2351c879b1213ffb8ee8ae449fce Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:09:32 +0100 Subject: [PATCH 074/108] test --- .github/workflows/_integration.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 98291ec4..3871b129 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -24,12 +24,12 @@ jobs: uses: actions/checkout@v4 # Setup for GitHub runners - - name: Install dependencies + - name: Concierge prepare if: ${{ inputs.runner == 'ubuntu-latest' }} run: | sudo snap install concierge --classic # TODO: Find out what the snaps deploy from? - sudo concierge prepare --juju-channel 3.6/stable -p k8s --extra-snaps just,astral-uv,terraform + sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform # Setup for Self-hosted (PS7) runners - name: Install snaps @@ -66,18 +66,19 @@ jobs: timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} run: | - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/coredns - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner + mkdir ~/.kube/ + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns && microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage && microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress && microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable rbac && microk8s status --wait-ready IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" && microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry && microk8s status --wait-ready + + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m - mkdir ~/.kube/ - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - name: Set up environment timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} From f2ef4b05a4dbd8b3159a7fb3a1b814512e376f90 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:13:01 +0100 Subject: [PATCH 075/108] test --- .github/workflows/_integration.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 3871b129..eb09492f 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -67,6 +67,9 @@ jobs: if: ${{ inputs.runner != 'ubuntu-latest' }} run: | mkdir ~/.kube/ + sudo usermod -aG snap_microk8s $USER + exec sg snap_microk8s "microk8s config | tee ~/.kube/config > /dev/null && sudo chown -f -R $USER ~/.kube" + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns && microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage && microk8s status --wait-ready From 2c6a6bb02f2b181c6a0f80dbed8457d3e4d783ac Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:25:03 +0100 Subject: [PATCH 076/108] test --- .github/workflows/_integration.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index eb09492f..1d0e8130 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -71,14 +71,20 @@ jobs: exec sg snap_microk8s "microk8s config | tee ~/.kube/config > /dev/null && sudo chown -f -R $USER ~/.kube" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns && microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage && microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress && microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable rbac && microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable rbac + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" && microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry && microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m From 8d7e51257fee96c839c4df1c85d2efd8a20db2d0 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:33:44 +0100 Subject: [PATCH 077/108] test --- .github/workflows/_integration.yml | 14 +++++++++++++- .github/workflows/terraform.yml | 12 ++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 1d0e8130..9d34a750 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -63,6 +63,7 @@ jobs: sudo microk8s stop sudo microk8s start - name: Set up microk8s + id: microk8s-setup timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} run: | @@ -87,7 +88,18 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m - + - name: Collect microk8s logs for debugging + timeout-minutes: 5 + if: ${{ failure() && steps.microk8s-setup.outcome == 'failure' }} + run: sudo microk8s inspect + - name: Upload microk8s logs for debugging + timeout-minutes: 5 + if: ${{ failure() && steps.microk8s-setup.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: debug-logs-microk8s-integration-test-charm-microk8s-juju-3-6-11-amd + path: /var/snap/microk8s/current/inspection-report-*.tar.gz + if-no-files-found: error - name: Set up environment timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index e8d4f197..668a5288 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -45,12 +45,12 @@ jobs: sudo snap install just --classic - name: Validate the Terraform modules run: just validate-terraform - test-integration-cos-lite: - name: COS Lite Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch - with: - product: cos_lite - runner: ubuntu-latest + # test-integration-cos-lite: + # name: COS Lite Terraform integration + # uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch + # with: + # product: cos_lite + # runner: ubuntu-latest test-integration-cos: name: COS Terraform integration uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch From 4b21881a24ae8b1bd4efa9c7025414e342b22e86 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:44:20 +0100 Subject: [PATCH 078/108] test --- .github/workflows/_integration.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 9d34a750..37323549 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -67,9 +67,7 @@ jobs: timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} run: | - mkdir ~/.kube/ sudo usermod -aG snap_microk8s $USER - exec sg snap_microk8s "microk8s config | tee ~/.kube/config > /dev/null && sudo chown -f -R $USER ~/.kube" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns @@ -88,13 +86,16 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m + + mkdir ~/.kube/ + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - name: Collect microk8s logs for debugging timeout-minutes: 5 - if: ${{ failure() && steps.microk8s-setup.outcome == 'failure' }} + if: ${{ steps.microk8s-setup.outcome == 'failure' }} run: sudo microk8s inspect - name: Upload microk8s logs for debugging timeout-minutes: 5 - if: ${{ failure() && steps.microk8s-setup.outcome == 'failure' }} + if: ${{ steps.microk8s-setup.outcome == 'failure' }} uses: actions/upload-artifact@v4 with: name: debug-logs-microk8s-integration-test-charm-microk8s-juju-3-6-11-amd From db569482c195969bdd13bd910b1b9618675bfdd3 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:51:01 +0100 Subject: [PATCH 079/108] test --- .github/workflows/_integration.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 37323549..b808a577 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -67,9 +67,10 @@ jobs: timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} run: | - sudo usermod -aG snap_microk8s $USER - + mkdir -p "$HOME"/.kube + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- usermod -aG snap_microk8s $USER sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- chown -f -R $USER ~/.kube sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage @@ -84,11 +85,7 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m - - mkdir ~/.kube/ - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - name: Collect microk8s logs for debugging timeout-minutes: 5 if: ${{ steps.microk8s-setup.outcome == 'failure' }} From 4ba7110609dd56282a0bc35aa64a95d70368977c Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 7 Nov 2025 18:56:12 +0100 Subject: [PATCH 080/108] test --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index b808a577..9c7180b5 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -68,7 +68,7 @@ jobs: if: ${{ inputs.runner != 'ubuntu-latest' }} run: | mkdir -p "$HOME"/.kube - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- usermod -aG snap_microk8s $USER + sudo usermod -aG snap_microk8s $USER sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- chown -f -R $USER ~/.kube sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns From 16797499222e5d046e0fa6f58307480612f8ebaa Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 11 Nov 2025 15:00:16 +0100 Subject: [PATCH 081/108] test --- .github/workflows/_integration.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 9c7180b5..bf633870 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -62,6 +62,10 @@ jobs: EOF sudo microk8s stop sudo microk8s start + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true - name: Set up microk8s id: microk8s-setup timeout-minutes: 15 @@ -79,12 +83,12 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable rbac sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m - name: Collect microk8s logs for debugging timeout-minutes: 5 From 88f1f506c0fc72db8c7418aaee94a07f465b2eee Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 11 Nov 2025 15:25:11 +0100 Subject: [PATCH 082/108] test --- .github/workflows/_integration.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index bf633870..f75667b0 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -64,8 +64,6 @@ jobs: sudo microk8s start - name: Setup tmate session uses: mxschmitt/action-tmate@v3 - with: - limit-access-to-actor: true - name: Set up microk8s id: microk8s-setup timeout-minutes: 15 From 03346bea6bf63fb50d277d7ba5b3586245a377b8 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 11 Nov 2025 15:46:31 +0100 Subject: [PATCH 083/108] test --- .github/workflows/_integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index f75667b0..6b56a298 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,8 +22,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - # Setup for GitHub runners + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 - name: Concierge prepare if: ${{ inputs.runner == 'ubuntu-latest' }} run: | From 07477510e21c5e423de27a8aa25157d9024ce6fa Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 13 Nov 2025 19:27:53 +0100 Subject: [PATCH 084/108] test --- .github/workflows/_integration.yml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 6b56a298..327a5491 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -28,7 +28,6 @@ jobs: if: ${{ inputs.runner == 'ubuntu-latest' }} run: | sudo snap install concierge --classic - # TODO: Find out what the snaps deploy from? sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform # Setup for Self-hosted (PS7) runners @@ -75,7 +74,9 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- chown -f -R $USER ~/.kube sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/coredns sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready @@ -88,18 +89,7 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m - - name: Collect microk8s logs for debugging - timeout-minutes: 5 - if: ${{ steps.microk8s-setup.outcome == 'failure' }} - run: sudo microk8s inspect - - name: Upload microk8s logs for debugging - timeout-minutes: 5 - if: ${{ steps.microk8s-setup.outcome == 'failure' }} - uses: actions/upload-artifact@v4 - with: - name: debug-logs-microk8s-integration-test-charm-microk8s-juju-3-6-11-amd - path: /var/snap/microk8s/current/inspection-report-*.tar.gz - if-no-files-found: error + # TODO: Move this to O11y GH workflows - name: Set up environment timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} From 13b8561bbd35e15b2083f903bce01dce531f20a4 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 18 Nov 2025 11:48:19 -0500 Subject: [PATCH 085/108] chore --- .github/workflows/_integration.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 327a5491..f464248b 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -44,7 +44,7 @@ jobs: run: | sudo apt-get update sudo apt-get install retry -y - sudo snap install microk8s --channel='1.30-strict/stable' + sudo snap install microk8s --channel='1.34-strict/stable' sudo adduser "$USER" snap_microk8s - name: (IS hosted) Configure microk8s Docker Hub mirror timeout-minutes: 5 @@ -68,15 +68,16 @@ jobs: timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} run: | - mkdir -p "$HOME"/.kube - sudo usermod -aG snap_microk8s $USER - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- chown -f -R $USER ~/.kube + # `newgrp` does not work in GitHub Actions; use `sudo --user` instead + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/coredns sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner + + IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready @@ -84,11 +85,9 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - - IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status deployment.apps/registry -n container-registry --watch --timeout=5m + + mkdir ~/.kube/ + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config # TODO: Move this to O11y GH workflows - name: Set up environment timeout-minutes: 15 From 8406a87c2a93ad11a145653a85c8140563d6bdc5 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 18 Nov 2025 11:48:37 -0500 Subject: [PATCH 086/108] chore --- .github/workflows/_integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index f464248b..303abc7d 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,8 +22,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 + # - name: Setup tmate session + # uses: mxschmitt/action-tmate@v3 - name: Concierge prepare if: ${{ inputs.runner == 'ubuntu-latest' }} run: | From 08fb05f49c7cd2b306af6abb9f0a1e11a8386817 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Tue, 18 Nov 2025 14:18:54 -0500 Subject: [PATCH 087/108] fix: TF test updates including external CA offer for receive-ca-cert --- .../test_upgrade_cos_tls_external.py | 7 +- tests/integration/cos/tls_external/track-2.tf | 3 +- .../cos/tls_full/test_upgrade_cos_tls_full.py | 7 +- tests/integration/cos/tls_full/track-2.tf | 3 +- .../test_upgrade_cos_tls_internal.py | 4 +- .../cos/tls_none/test_upgrade_cos_tls_none.py | 4 +- .../test_upgrade_cos_lite_tls_external.py | 1 - .../cos_lite/tls_external/track-1.tf | 3 +- .../cos_lite/tls_external/track-2.tf | 3 +- .../test_upgrade_cos_lite_tls_full.py | 1 - .../integration/cos_lite/tls_full/track-1.tf | 3 +- .../integration/cos_lite/tls_full/track-2.tf | 3 +- uv.lock | 167 +----------------- 13 files changed, 25 insertions(+), 184 deletions(-) diff --git a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py index 2e8941fb..4db63bad 100644 --- a/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py +++ b/tests/integration/cos/tls_external/test_upgrade_cos_tls_external.py @@ -24,7 +24,9 @@ def test_envvars(): - assert all(S3_ENDPOINT.values()) + assert all(S3_ENDPOINT.values()), ( + f"export the following env vars (upper case) before running this test: {S3_ENDPOINT.keys()}" + ) def test_deploy_from_track( @@ -32,9 +34,6 @@ def test_deploy_from_track( ): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply( - target="ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT - ) tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT) wait_for_active_idle_without_error([cos_model], timeout=5400) tls_ctx = get_tls_context(tmp_path, ca_model, "self-signed-certificates") diff --git a/tests/integration/cos/tls_external/track-2.tf b/tests/integration/cos/tls_external/track-2.tf index a43682ea..5c940b27 100644 --- a/tests/integration/cos/tls_external/track-2.tf +++ b/tests/integration/cos/tls_external/track-2.tf @@ -48,7 +48,8 @@ module "cos" { model_uuid = data.juju_model.cos-model.uuid channel = "2/edge" internal_tls = "false" - external_certificates_offer_url = module.ssc.offers.certificates.url + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" s3_endpoint = var.s3_endpoint s3_secret_key = var.s3_secret_key diff --git a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py index a0e1b8d2..8a5a651c 100644 --- a/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py +++ b/tests/integration/cos/tls_full/test_upgrade_cos_tls_full.py @@ -24,7 +24,9 @@ def test_envvars(): - assert all(S3_ENDPOINT.values()) + assert all(S3_ENDPOINT.values()), ( + f"export the following env vars (upper case) before running this test: {S3_ENDPOINT.keys()}" + ) def test_deploy_from_track( @@ -32,9 +34,6 @@ def test_deploy_from_track( ): # GIVEN a module deployed from track n tf_manager.init(TRACK_2_TF_FILE) - tf_manager.apply( - target="ssc", ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT - ) tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model, **S3_ENDPOINT) wait_for_active_idle_without_error([cos_model], timeout=5400) tls_ctx = get_tls_context(tmp_path, ca_model, "self-signed-certificates") diff --git a/tests/integration/cos/tls_full/track-2.tf b/tests/integration/cos/tls_full/track-2.tf index 4a7f67db..6151f22a 100644 --- a/tests/integration/cos/tls_full/track-2.tf +++ b/tests/integration/cos/tls_full/track-2.tf @@ -48,7 +48,8 @@ module "cos" { model_uuid = data.juju_model.cos-model.uuid channel = "2/edge" internal_tls = "true" - external_certificates_offer_url = module.ssc.offers.certificates.url + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" s3_endpoint = var.s3_endpoint s3_secret_key = var.s3_secret_key diff --git a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py index 422176c2..84bef0ea 100644 --- a/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py +++ b/tests/integration/cos/tls_internal/test_upgrade_cos_tls_internal.py @@ -23,7 +23,9 @@ def test_envvars(): - assert all(S3_ENDPOINT.values()) + assert all(S3_ENDPOINT.values()), ( + f"export the following env vars (upper case) before running this test: {S3_ENDPOINT.keys()}" + ) def test_deploy_from_track(tmp_path, tf_manager, cos_model: jubilant.Juju): diff --git a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py index 8b062533..bf4a3dff 100644 --- a/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py +++ b/tests/integration/cos/tls_none/test_upgrade_cos_tls_none.py @@ -23,7 +23,9 @@ def test_envvars(): - assert all(S3_ENDPOINT.values()) + assert all(S3_ENDPOINT.values()), ( + f"export the following env vars (upper case) before running this test: {S3_ENDPOINT.keys()}" + ) def test_deploy_from_track(tf_manager, cos_model: jubilant.Juju): diff --git a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py index 177ef86e..e8996217 100644 --- a/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py +++ b/tests/integration/cos_lite/tls_external/test_upgrade_cos_lite_tls_external.py @@ -24,7 +24,6 @@ def test_deploy_from_track( ): # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply(target="ssc", ca_model=ca_model.model, cos_model=cos_model.model) tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_external/track-1.tf b/tests/integration/cos_lite/tls_external/track-1.tf index 8ece2a32..2a2f183f 100644 --- a/tests/integration/cos_lite/tls_external/track-1.tf +++ b/tests/integration/cos_lite/tls_external/track-1.tf @@ -36,7 +36,8 @@ module "cos-lite" { model_uuid = data.juju_model.cos-model.uuid channel = "1/stable" internal_tls = "false" - external_certificates_offer_url = module.ssc.offers.certificates.url + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable } diff --git a/tests/integration/cos_lite/tls_external/track-2.tf b/tests/integration/cos_lite/tls_external/track-2.tf index 476299aa..6f819d90 100644 --- a/tests/integration/cos_lite/tls_external/track-2.tf +++ b/tests/integration/cos_lite/tls_external/track-2.tf @@ -36,7 +36,8 @@ module "cos-lite" { model_uuid = data.juju_model.cos-model.uuid channel = "2/edge" internal_tls = "false" - external_certificates_offer_url = module.ssc.offers.certificates.url + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable } diff --git a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py index 8a8abc82..41ccc176 100644 --- a/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py +++ b/tests/integration/cos_lite/tls_full/test_upgrade_cos_lite_tls_full.py @@ -24,7 +24,6 @@ def test_deploy_from_track( ): # GIVEN a module deployed from track n-1 tf_manager.init(TRACK_1_TF_FILE) - tf_manager.apply(target="ssc", ca_model=ca_model.model, cos_model=cos_model.model) tf_manager.apply(ca_model=ca_model.model, cos_model=cos_model.model) wait_for_active_idle_without_error([ca_model, cos_model]) diff --git a/tests/integration/cos_lite/tls_full/track-1.tf b/tests/integration/cos_lite/tls_full/track-1.tf index 3a2de76c..fa75e106 100644 --- a/tests/integration/cos_lite/tls_full/track-1.tf +++ b/tests/integration/cos_lite/tls_full/track-1.tf @@ -36,7 +36,8 @@ module "cos-lite" { model_uuid = data.juju_model.cos-model.uuid channel = "1/stable" internal_tls = "true" - external_certificates_offer_url = module.ssc.offers.certificates.url + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable } diff --git a/tests/integration/cos_lite/tls_full/track-2.tf b/tests/integration/cos_lite/tls_full/track-2.tf index 814f14dc..d6089644 100644 --- a/tests/integration/cos_lite/tls_full/track-2.tf +++ b/tests/integration/cos_lite/tls_full/track-2.tf @@ -36,7 +36,8 @@ module "cos-lite" { model_uuid = data.juju_model.cos-model.uuid channel = "2/edge" internal_tls = "true" - external_certificates_offer_url = module.ssc.offers.certificates.url + external_certificates_offer_url = "admin/${var.ca_model}.certificates" + external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable } diff --git a/uv.lock b/uv.lock index 4c73b574..417c1186 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.10" +requires-python = ">=3.14" [[package]] name = "colorama" @@ -11,18 +11,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "exceptiongroup" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, -] - [[package]] name = "iniconfig" version = "2.1.0" @@ -62,61 +50,6 @@ version = "3.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631, upload-time = "2025-09-27T18:36:05.558Z" }, - { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057, upload-time = "2025-09-27T18:36:07.165Z" }, - { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050, upload-time = "2025-09-27T18:36:08.005Z" }, - { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681, upload-time = "2025-09-27T18:36:08.881Z" }, - { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705, upload-time = "2025-09-27T18:36:10.131Z" }, - { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524, upload-time = "2025-09-27T18:36:11.324Z" }, - { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282, upload-time = "2025-09-27T18:36:12.573Z" }, - { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745, upload-time = "2025-09-27T18:36:13.504Z" }, - { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571, upload-time = "2025-09-27T18:36:14.779Z" }, - { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056, upload-time = "2025-09-27T18:36:16.125Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932, upload-time = "2025-09-27T18:36:17.311Z" }, - { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, - { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, - { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, - { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, - { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, - { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, - { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, - { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, - { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, - { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, - { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, - { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, - { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, - { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, - { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, - { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, - { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, - { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, - { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, - { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, - { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, - { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, @@ -191,12 +124,10 @@ version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ @@ -209,44 +140,6 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, - { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, - { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, - { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, - { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, - { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, - { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, - { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, - { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, - { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, - { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, - { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, - { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, - { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, @@ -266,61 +159,3 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] - -[[package]] -name = "tomli" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, - { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, - { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, - { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, - { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, - { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, - { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, - { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, - { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, - { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, - { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, - { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, - { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, - { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, - { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, - { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, - { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, - { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, - { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, - { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, - { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, - { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, - { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, - { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, - { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, - { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, - { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, - { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, - { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, - { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, - { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, - { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, - { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, - { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, - { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, - { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, - { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, - { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, - { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] From a20b2c94f386cfc77fa4ab176aa19fb149c80a4c Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 09:05:47 -0500 Subject: [PATCH 088/108] chore --- .github/workflows/_integration.yml | 8 ++------ .github/workflows/terraform.yml | 12 ++++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 303abc7d..2cb85f35 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,8 +22,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - # - name: Setup tmate session - # uses: mxschmitt/action-tmate@v3 + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 - name: Concierge prepare if: ${{ inputs.runner == 'ubuntu-latest' }} run: | @@ -61,8 +61,6 @@ jobs: EOF sudo microk8s stop sudo microk8s start - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - name: Set up microk8s id: microk8s-setup timeout-minutes: 15 @@ -88,7 +86,6 @@ jobs: mkdir ~/.kube/ sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - # TODO: Move this to O11y GH workflows - name: Set up environment timeout-minutes: 15 if: ${{ inputs.runner != 'ubuntu-latest' }} @@ -131,7 +128,6 @@ jobs: - name: Test deployment run: | - # TODO: Add these as env-vars export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 668a5288..e8d4f197 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -45,12 +45,12 @@ jobs: sudo snap install just --classic - name: Validate the Terraform modules run: just validate-terraform - # test-integration-cos-lite: - # name: COS Lite Terraform integration - # uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch - # with: - # product: cos_lite - # runner: ubuntu-latest + test-integration-cos-lite: + name: COS Lite Terraform integration + uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch + with: + product: cos_lite + runner: ubuntu-latest test-integration-cos: name: COS Terraform integration uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch From 0c241428cc43f94e2707ff986b713a7230adcc88 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 09:17:43 -0500 Subject: [PATCH 089/108] chore --- .github/workflows/_integration.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 2cb85f35..01d5895c 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,17 +22,15 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - name: Concierge prepare - if: ${{ inputs.runner == 'ubuntu-latest' }} + if: ${{ env.RUNNER_ENVIRONMENT == 'github-hosted' }} run: | sudo snap install concierge --classic sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform # Setup for Self-hosted (PS7) runners - name: Install snaps - if: ${{ inputs.runner != 'ubuntu-latest' }} + if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} run: | sudo snap install juju --classic --channel=3.6/stable sudo snap install just --classic @@ -40,7 +38,7 @@ jobs: sudo snap install terraform --classic - name: Install microk8s timeout-minutes: 5 - if: ${{ inputs.runner != 'ubuntu-latest' }} + if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} run: | sudo apt-get update sudo apt-get install retry -y @@ -48,13 +46,13 @@ jobs: sudo adduser "$USER" snap_microk8s - name: (IS hosted) Configure microk8s Docker Hub mirror timeout-minutes: 5 - if: ${{ inputs.runner != 'ubuntu-latest' }} + if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} run: | # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml << EOF + cat << EOF | sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml server = "$DOCKERHUB_MIRROR" [host."${DOCKERHUB_MIRROR#'https://'}"] capabilities = ["pull", "resolve"] @@ -64,7 +62,7 @@ jobs: - name: Set up microk8s id: microk8s-setup timeout-minutes: 15 - if: ${{ inputs.runner != 'ubuntu-latest' }} + if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} run: | # `newgrp` does not work in GitHub Actions; use `sudo --user` instead sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready @@ -73,7 +71,8 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/coredns sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner - + + IPADDR="" IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready @@ -83,12 +82,12 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable registry sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - + mkdir ~/.kube/ sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - name: Set up environment timeout-minutes: 15 - if: ${{ inputs.runner != 'ubuntu-latest' }} + if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} run: | mkdir -p ~/.local/share/juju # Workaround for juju 3 strict snap sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- juju bootstrap microk8s --config model-logs-size=10G microk8s From db53726b06c30d06114f5800d9a0f3b8374ef97a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 09:25:46 -0500 Subject: [PATCH 090/108] chore --- .github/workflows/_integration.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 01d5895c..82e75e16 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,6 +22,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 - name: Concierge prepare if: ${{ env.RUNNER_ENVIRONMENT == 'github-hosted' }} run: | From f62dac9c852a3599ccd985a81ca6ea28c1493119 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 09:35:05 -0500 Subject: [PATCH 091/108] chore --- .github/workflows/_integration.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 82e75e16..95748204 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -22,17 +22,15 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 - name: Concierge prepare - if: ${{ env.RUNNER_ENVIRONMENT == 'github-hosted' }} + if: ${{ runner.environment == 'github-hosted' }} run: | sudo snap install concierge --classic sudo concierge prepare --juju-channel 3.6/stable -p microk8s --extra-snaps just,astral-uv,terraform # Setup for Self-hosted (PS7) runners - name: Install snaps - if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} + if: ${{ runner.environment == 'self-hosted' }} run: | sudo snap install juju --classic --channel=3.6/stable sudo snap install just --classic @@ -40,7 +38,7 @@ jobs: sudo snap install terraform --classic - name: Install microk8s timeout-minutes: 5 - if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} + if: ${{ runner.environment == 'self-hosted' }} run: | sudo apt-get update sudo apt-get install retry -y @@ -48,7 +46,7 @@ jobs: sudo adduser "$USER" snap_microk8s - name: (IS hosted) Configure microk8s Docker Hub mirror timeout-minutes: 5 - if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} + if: ${{ runner.environment == 'self-hosted' }} run: | # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee @@ -64,7 +62,7 @@ jobs: - name: Set up microk8s id: microk8s-setup timeout-minutes: 15 - if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} + if: ${{ runner.environment == 'self-hosted' }} run: | # `newgrp` does not work in GitHub Actions; use `sudo --user` instead sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready @@ -89,7 +87,7 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config - name: Set up environment timeout-minutes: 15 - if: ${{ env.RUNNER_ENVIRONMENT == 'self-hosted' }} + if: ${{ runner.environment == 'self-hosted' }} run: | mkdir -p ~/.local/share/juju # Workaround for juju 3 strict snap sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- juju bootstrap microk8s --config model-logs-size=10G microk8s From a4a776f2ed391774b2660ce0a76522f59214f0f5 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 10:50:36 -0500 Subject: [PATCH 092/108] chore --- .github/workflows/_integration.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 95748204..e4ed3fdc 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -52,7 +52,7 @@ jobs: # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - cat << EOF | sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml + sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml > /dev/null << EOF server = "$DOCKERHUB_MIRROR" [host."${DOCKERHUB_MIRROR#'https://'}"] capabilities = ["pull", "resolve"] @@ -73,7 +73,8 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner IPADDR="" - IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') + IPADDR_TMP=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') + IPADDR="$IPADDR_TMP" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress From d7c180359691c30cc9cf5795818b518fa0aab544 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 11:26:36 -0500 Subject: [PATCH 093/108] shellcheck fixes --- .github/workflows/_integration.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index e4ed3fdc..9e546d24 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -52,7 +52,7 @@ jobs: # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml > /dev/null << EOF + cat << EOF | sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml server = "$DOCKERHUB_MIRROR" [host."${DOCKERHUB_MIRROR#'https://'}"] capabilities = ["pull", "resolve"] @@ -72,9 +72,7 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable hostpath-storage sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s.kubectl rollout status --namespace kube-system --watch --timeout=5m deployments/hostpath-provisioner - IPADDR="" - IPADDR_TMP=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') - IPADDR="$IPADDR_TMP" + IPADDR=$(ip -4 -j route get 2.2.2.2 | sed -n -e 's/^.*prefsrc\":"\([^ "]*\).*/\1/p') sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable "metallb:$IPADDR-$IPADDR" sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable ingress @@ -85,7 +83,7 @@ jobs: sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready mkdir ~/.kube/ - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config > ~/.kube/config + sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s config | sudo tee ~/.kube/config > /dev/null - name: Set up environment timeout-minutes: 15 if: ${{ runner.environment == 'self-hosted' }} @@ -128,7 +126,8 @@ jobs: - name: Test deployment run: | - export S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + S3_ENDPOINT=http://$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc'):8080 + export S3_ENDPOINT export S3_ACCESS_KEY=access-key export S3_SECRET_KEY=secret-key just integration ${{ inputs.product }}/${{ matrix.scenario }} From 0552a72a3201f1c40e5128d795ba3440a1eb5918 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 11:28:50 -0500 Subject: [PATCH 094/108] shellcheck fixes --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 9e546d24..9a278225 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -52,7 +52,7 @@ jobs: # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready - cat << EOF | sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml + sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml << EOF server = "$DOCKERHUB_MIRROR" [host."${DOCKERHUB_MIRROR#'https://'}"] capabilities = ["pull", "resolve"] From 67ab398834c8a84752e313d56f5cc34675c3edc2 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Wed, 19 Nov 2025 14:38:43 -0500 Subject: [PATCH 095/108] chore: bump DockerHub mirror step to 10 min timeout --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 9a278225..a3b2b847 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -45,7 +45,7 @@ jobs: sudo snap install microk8s --channel='1.34-strict/stable' sudo adduser "$USER" snap_microk8s - name: (IS hosted) Configure microk8s Docker Hub mirror - timeout-minutes: 5 + timeout-minutes: 10 if: ${{ runner.environment == 'self-hosted' }} run: | # Wait for microk8s to populate iptables From a58ecc0cd85dff80b4bf5c96b3136a066b03847a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 20 Nov 2025 09:11:47 -0500 Subject: [PATCH 096/108] chore: bump resources --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index e8d4f197..774e2d29 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -56,4 +56,4 @@ jobs: uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch with: product: cos - runner: self-hosted-linux-amd64-noble-large + runner: self-hosted-linux-amd64-noble-xlarge From 5c34a834ab6597139104a680e63293be45a0b571 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 21 Nov 2025 08:15:06 -0500 Subject: [PATCH 097/108] chore --- .github/workflows/_integration.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index a3b2b847..1d288fbf 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -36,21 +36,19 @@ jobs: sudo snap install just --classic sudo snap install astral-uv --classic sudo snap install terraform --classic - - name: Install microk8s - timeout-minutes: 5 - if: ${{ runner.environment == 'self-hosted' }} - run: | - sudo apt-get update - sudo apt-get install retry -y - sudo snap install microk8s --channel='1.34-strict/stable' - sudo adduser "$USER" snap_microk8s - name: (IS hosted) Configure microk8s Docker Hub mirror timeout-minutes: 10 if: ${{ runner.environment == 'self-hosted' }} run: | + snap install microk8s --channel "1.34-strict/stable" --classic + # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee - sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready + until [[ -n $(iptables --list | grep -i "microk8s") ]] + do + echo "MicroK8s has not yet configured iptables." + sleep 10 + done sudo tee /var/snap/microk8s/current/args/certs.d/docker.io/hosts.toml << EOF server = "$DOCKERHUB_MIRROR" From 1edecc40628500813e00bbe9737e3009eb6bd40a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 21 Nov 2025 09:10:31 -0500 Subject: [PATCH 098/108] chore --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 1d288fbf..5fc13bdd 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -40,7 +40,7 @@ jobs: timeout-minutes: 10 if: ${{ runner.environment == 'self-hosted' }} run: | - snap install microk8s --channel "1.34-strict/stable" --classic + sudo snap install microk8s --channel "1.34-strict/stable" --classic # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee From b8541061fe35ee3bba4851cf79761a8da6f7b516 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 21 Nov 2025 09:23:00 -0500 Subject: [PATCH 099/108] chore --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 5fc13bdd..56f9a9ff 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -44,7 +44,7 @@ jobs: # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee - until [[ -n $(iptables --list | grep -i "microk8s") ]] + until [[ -n $(sudo iptables --list | grep -i "microk8s") ]] do echo "MicroK8s has not yet configured iptables." sleep 10 From dea63cb10e701282df633ca2261b8481c7ed7451 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 21 Nov 2025 09:38:09 -0500 Subject: [PATCH 100/108] chore --- .github/workflows/_integration.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 56f9a9ff..e870ebd2 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -41,6 +41,7 @@ jobs: if: ${{ runner.environment == 'self-hosted' }} run: | sudo snap install microk8s --channel "1.34-strict/stable" --classic + sudo adduser "$USER" snap_microk8s # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee From afa6e3712f5de03801b2cb64320b34866d863b71 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 21 Nov 2025 09:59:47 -0500 Subject: [PATCH 101/108] chore --- .github/workflows/_integration.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index e870ebd2..536f6a4c 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -63,6 +63,9 @@ jobs: timeout-minutes: 15 if: ${{ runner.environment == 'self-hosted' }} run: | + sudo apt-get update + sudo apt-get install retry -y + # `newgrp` does not work in GitHub Actions; use `sudo --user` instead sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- microk8s status --wait-ready sudo --user "$USER" --preserve-env --preserve-env=PATH -- env -- retry --times 3 --delay 5 -- sudo microk8s enable dns From b5c5a672d8652bbde0282bff5cf04887733c9b1c Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 21 Nov 2025 09:57:43 -0500 Subject: [PATCH 102/108] fix: update Grafana's ingress integrations (#149) --- terraform/cos-lite/integrations.tf | 2 +- terraform/cos/integrations.tf | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/terraform/cos-lite/integrations.tf b/terraform/cos-lite/integrations.tf index 99a2bb0e..772b8eeb 100644 --- a/terraform/cos-lite/integrations.tf +++ b/terraform/cos-lite/integrations.tf @@ -239,7 +239,7 @@ resource "juju_integration" "grafana_ingress" { application { name = module.traefik.app_name - endpoint = module.traefik.endpoints.traefik_route + endpoint = module.traefik.endpoints.ingress } application { diff --git a/terraform/cos/integrations.tf b/terraform/cos/integrations.tf index 3cd93be5..c055d86e 100644 --- a/terraform/cos/integrations.tf +++ b/terraform/cos/integrations.tf @@ -291,6 +291,10 @@ resource "juju_integration" "ingress" { app_name = module.loki.app_names.loki_coordinator endpoint = module.loki.endpoints.ingress } + grafana = { + app_name = module.grafana.app_name + endpoint = module.grafana.endpoints.ingress + } } model_uuid = var.model_uuid @@ -308,10 +312,6 @@ resource "juju_integration" "ingress" { resource "juju_integration" "traefik_route" { for_each = { - grafana = { - app_name = module.grafana.app_name - endpoint = module.grafana.endpoints.ingress - } tempo = { app_name = module.tempo.app_names.tempo_coordinator endpoint = module.tempo.endpoints.ingress From f6e86cba8a08c2ae658dec6bc5edf0c74c8ddc6a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 27 Nov 2025 11:09:19 -0500 Subject: [PATCH 103/108] chore: Fix lock file --- uv.lock | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index d76f3ddc..79c8b71d 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.14" +requires-python = ">=3.10" [[package]] name = "colorama" @@ -92,10 +92,12 @@ version = "9.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", size = 1564125, upload-time = "2025-11-12T13:05:09.333Z" } wheels = [ @@ -108,6 +110,44 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, @@ -127,3 +167,61 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] + +[[package]] +name = "tomli" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, + { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, + { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, + { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, + { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, + { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, + { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, + { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] From b55685a71f9647c70ea78d7e1132fb9e15b53785 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 27 Nov 2025 12:01:30 -0500 Subject: [PATCH 104/108] COS Lite on self-hosted runners --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index eb3bed71..2ca25bd9 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -48,7 +48,7 @@ jobs: uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch with: product: cos_lite - runner: ubuntu-latest + runner: self-hosted-linux-amd64-noble-large test-integration-cos: name: COS Terraform integration uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch From ab13c3d1ac1a1ad6280a2aeabe4cbede5cfba5e6 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 27 Nov 2025 16:29:40 -0500 Subject: [PATCH 105/108] chore --- tests/integration/cos_lite/tls_external/track-2.tf | 2 +- tests/integration/cos_lite/tls_full/track-2.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/cos_lite/tls_external/track-2.tf b/tests/integration/cos_lite/tls_external/track-2.tf index fb11292a..19987272 100644 --- a/tests/integration/cos_lite/tls_external/track-2.tf +++ b/tests/integration/cos_lite/tls_external/track-2.tf @@ -34,7 +34,7 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/2" model_uuid = data.juju_model.cos-model.uuid - channel = "2/stable" + channel = "2/edge" # TODO: Switch to "2/stable" when Prometheus rev279 hits stable internal_tls = "false" external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" diff --git a/tests/integration/cos_lite/tls_full/track-2.tf b/tests/integration/cos_lite/tls_full/track-2.tf index 12dbff49..1d88acf2 100644 --- a/tests/integration/cos_lite/tls_full/track-2.tf +++ b/tests/integration/cos_lite/tls_full/track-2.tf @@ -34,7 +34,7 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/2" model_uuid = data.juju_model.cos-model.uuid - channel = "2/stable" + channel = "2/edge" # TODO: Switch to "2/stable" when Prometheus rev279 hits stable internal_tls = "true" external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" From d6d9a0d33cf79d57a420bf649768f1509e6de850 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 27 Nov 2025 16:31:18 -0500 Subject: [PATCH 106/108] chore --- tests/integration/cos_lite/tls_external/track-2.tf | 5 +++-- tests/integration/cos_lite/tls_full/track-2.tf | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/integration/cos_lite/tls_external/track-2.tf b/tests/integration/cos_lite/tls_external/track-2.tf index 19987272..a4920e07 100644 --- a/tests/integration/cos_lite/tls_external/track-2.tf +++ b/tests/integration/cos_lite/tls_external/track-2.tf @@ -34,10 +34,11 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/2" model_uuid = data.juju_model.cos-model.uuid - channel = "2/edge" # TODO: Switch to "2/stable" when Prometheus rev279 hits stable + channel = "2/stable" internal_tls = "false" external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" - traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable + traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable + prometheus = { revision = 279 } # TODO: Remove when rev279 hits stable } diff --git a/tests/integration/cos_lite/tls_full/track-2.tf b/tests/integration/cos_lite/tls_full/track-2.tf index 1d88acf2..2e5b67a5 100644 --- a/tests/integration/cos_lite/tls_full/track-2.tf +++ b/tests/integration/cos_lite/tls_full/track-2.tf @@ -34,11 +34,12 @@ module "ssc" { module "cos-lite" { source = "git::https://github.com/canonical/observability-stack//terraform/cos-lite?ref=track/2" model_uuid = data.juju_model.cos-model.uuid - channel = "2/edge" # TODO: Switch to "2/stable" when Prometheus rev279 hits stable + channel = "2/stable" internal_tls = "true" external_certificates_offer_url = "admin/${var.ca_model}.certificates" external_ca_cert_offer_url = "admin/${var.ca_model}.send-ca-cert" - traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable + traefik = { channel = "latest/edge" } # TODO: Switch to latest/stable when rev257 hits stable + prometheus = { revision = 279 } # TODO: Remove when rev279 hits stable } From c2a004115ac0269ae02849e120256b01718ee5b5 Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Thu, 27 Nov 2025 21:54:07 -0500 Subject: [PATCH 107/108] chore --- .github/workflows/_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/_integration.yml b/.github/workflows/_integration.yml index 536f6a4c..717b7e1a 100644 --- a/.github/workflows/_integration.yml +++ b/.github/workflows/_integration.yml @@ -45,7 +45,7 @@ jobs: # Wait for microk8s to populate iptables # https://chat.canonical.com/canonical/pl/jo5cg6wqjjrudqd5ybj6hhttee - until [[ -n $(sudo iptables --list | grep -i "microk8s") ]] + until sudo iptables --list | grep -q -i "microk8s" do echo "MicroK8s has not yet configured iptables." sleep 10 From 518a4ece9e53e9df5ab0b8d32283014fe014407a Mon Sep 17 00:00:00 2001 From: Michael Thamm Date: Fri, 28 Nov 2025 09:56:34 -0500 Subject: [PATCH 108/108] final cleanup --- .github/workflows/terraform.yml | 4 ++-- terraform/cos-lite/applications.tf | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 2ca25bd9..2a584588 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -45,13 +45,13 @@ jobs: run: just validate-terraform test-integration-cos-lite: name: COS Lite Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yml@main with: product: cos_lite runner: self-hosted-linux-amd64-noble-large test-integration-cos: name: COS Terraform integration - uses: canonical/observability-stack/.github/workflows/_integration.yml@cos-itests # TODO: Fix branch + uses: canonical/observability-stack/.github/workflows/_integration.yml@main with: product: cos runner: self-hosted-linux-amd64-noble-xlarge diff --git a/terraform/cos-lite/applications.tf b/terraform/cos-lite/applications.tf index 632ef925..dd1bd5ab 100644 --- a/terraform/cos-lite/applications.tf +++ b/terraform/cos-lite/applications.tf @@ -21,7 +21,6 @@ module "catalogue" { storage_directives = var.catalogue.storage_directives units = var.catalogue.units } -# TODO: Remove this after testing module "grafana" { source = "git::https://github.com/canonical/grafana-k8s-operator//terraform"