-
Notifications
You must be signed in to change notification settings - Fork 1
feat: scaffold garm-configurator charm (ISD-5732) #209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
florentianayuwono
wants to merge
8
commits into
main
Choose a base branch
from
feat/gram-configurator-scaffold-isd-5732
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
6c6b039
chore: scaffold garm-configurator charm config files
florentianayuwono 5e3df05
feat: implement garm-configurator charm scaffold
florentianayuwono 3a5f519
test: add garm-configurator integration test
florentianayuwono 6d1a8ac
chore: add garm-configurator to tox and CI lint/unit matrix
florentianayuwono 05b2295
fix: add parts section, switch pyright to mypy
florentianayuwono fda474d
chore: remove unnecessary --only-binary=pluggy from requirements.txt
florentianayuwono d44e7bf
chore: align pyproject.toml with platform-engineering-charm-template
florentianayuwono 0eebbcd
Apply suggestions from code review
florentianayuwono File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # This file configures Charmcraft. | ||
| # See https://juju.is/docs/sdk/charmcraft-config for guidance. | ||
|
|
||
| name: garm-configurator | ||
|
|
||
| type: charm | ||
|
|
||
| base: ubuntu@24.04 | ||
| platforms: | ||
| amd64: | ||
|
|
||
| summary: Configuration broker charm for GARM scalesets. | ||
|
|
||
| description: | | ||
| Holds configuration for a single GARM scaleset and provider combination, | ||
| sharing it with the GARM charm via Juju integrations. | ||
|
|
||
| parts: | ||
| charm: | ||
| source: . | ||
| plugin: charm | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Copyright 2026 Canonical Ltd. | ||
| # See LICENSE file for licensing details. | ||
|
|
||
| # Testing tools configuration | ||
| [tool.coverage.run] | ||
| branch = true | ||
|
|
||
| [tool.coverage.report] | ||
| show_missing = true | ||
|
|
||
| [tool.pytest.ini_options] | ||
| minversion = "6.0" | ||
| log_cli_level = "INFO" | ||
| pythonpath = ["lib", "src"] | ||
|
|
||
| # Linting tools configuration | ||
| [tool.ruff] | ||
| target-version = "py310" | ||
| line-length = 99 | ||
|
|
||
| # enable ruff linters: | ||
| # S flake8-bandit | ||
| # B flake8-bugbear | ||
| # A flake8-builtins | ||
| # CPY flake8-copyright | ||
| # SIM flake8-simplify | ||
| # TC flake8-type-checking | ||
| # I isort | ||
| # N pep8-naming | ||
| # D pydocstyle | ||
| # F Pyflakes | ||
| # UP pyupgrade | ||
| # RUF Ruff-specific rules | ||
| # E/W pycodestyle | ||
| lint.select = ["A", "B", "C", "CPY", "D", "E", "F", "I", "N", "RUF", "S", "SIM", "TC", "UP", "W"] | ||
| lint.ignore = [ | ||
| "B904", | ||
| "D107", | ||
| "D203", | ||
| "D204", | ||
| "D205", | ||
| "D213", | ||
| "D215", | ||
| "D400", | ||
| "D404", | ||
| "D406", | ||
| "D407", | ||
| "D408", | ||
| "D409", | ||
| "D413", | ||
| "E501", | ||
| "S105", | ||
| "S603", | ||
| "TC002", | ||
| "TC006", | ||
| "UP006", | ||
| "UP007", | ||
| "UP035", | ||
| "UP045", | ||
| ] | ||
| lint.per-file-ignores."tests/*" = ["B011", "D100", "D101", "D102", "D103", "D104", "D212", "D415", "D417", "S"] | ||
| lint.flake8-copyright.author = "Canonical Ltd." | ||
| lint.flake8-copyright.min-file-size = 1 | ||
| lint.flake8-copyright.notice-rgx = "Copyright\\s\\d{4}([-,]\\d{4})*\\s+" | ||
| lint.mccabe.max-complexity = 10 | ||
| lint.pydocstyle.convention = "google" | ||
|
|
||
| [tool.codespell] | ||
| skip = "build,lib,venv,icon.svg,.tox,.git,.mypy_cache,.ruff_cache,.coverage,htmlcov,uv.lock,grafana_dashboards" | ||
|
|
||
| [tool.mypy] | ||
| check_untyped_defs = true | ||
| disallow_untyped_defs = true | ||
| explicit_package_bases = true | ||
| ignore_missing_imports = true | ||
| namespace_packages = true | ||
|
|
||
| [[tool.mypy.overrides]] | ||
| disallow_untyped_defs = false | ||
| module = "tests.*" | ||
|
|
||
| [tool.bandit] | ||
| exclude_dirs = ["/venv/"] | ||
|
|
||
| [tool.bandit.assert_used] | ||
| skips = ["*/*test.py", "*/test_*.py", "*tests/*.py"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ops==3.7.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #!/usr/bin/env python3 | ||
| # Copyright 2026 Canonical Ltd. | ||
| # See LICENSE file for licensing details. | ||
|
|
||
| """Charm entrypoint for the GARM configurator charm.""" | ||
|
|
||
| import typing | ||
|
|
||
| import ops | ||
|
|
||
|
|
||
| class GarmConfiguratorCharm(ops.CharmBase): | ||
| """GARM configurator charm.""" | ||
|
|
||
| def __init__(self, *args: typing.Any) -> None: | ||
| """Initialize the instance. | ||
|
|
||
| Args: | ||
| args: passthrough to CharmBase. | ||
| """ | ||
| super().__init__(*args) | ||
| self.framework.observe(self.on.collect_unit_status, self._on_collect_unit_status) | ||
|
|
||
| def _on_collect_unit_status(self, event: ops.CollectStatusEvent) -> None: | ||
| """Handle collect-unit-status event. | ||
|
|
||
| Args: | ||
| event: The collect status event. | ||
| """ | ||
| event.add_status(ops.ActiveStatus("Ready")) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| ops.main(GarmConfiguratorCharm) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # Copyright 2026 Canonical Ltd. | ||
| # See LICENSE file for licensing details. | ||
|
|
||
| """Unit tests for GarmConfiguratorCharm.""" | ||
|
|
||
| import ops | ||
| from scenario import Context, State | ||
|
|
||
| from charm import GarmConfiguratorCharm | ||
|
|
||
|
|
||
| def test_charm_reaches_active_on_install(): | ||
| """ | ||
| arrange: A fresh charm context. | ||
| act: Run the install event. | ||
| assert: Unit status is Active. | ||
| """ | ||
| ctx = Context(GarmConfiguratorCharm) | ||
| out = ctx.run(ctx.on.install(), State()) | ||
| assert out.unit_status == ops.ActiveStatus("Ready") | ||
|
|
||
|
|
||
| def test_charm_reaches_active_on_config_changed(): | ||
| """ | ||
| arrange: A fresh charm context. | ||
| act: Run the config-changed event. | ||
| assert: Unit status is Active. | ||
| """ | ||
| ctx = Context(GarmConfiguratorCharm) | ||
| out = ctx.run(ctx.on.config_changed(), State()) | ||
| assert out.unit_status == ops.ActiveStatus("Ready") | ||
|
|
||
|
|
||
| def test_charm_collect_unit_status_emits_active(): | ||
| """ | ||
| arrange: A fresh charm context. | ||
| act: Run the collect-unit-status event directly. | ||
| assert: Unit status is Active. | ||
| """ | ||
| ctx = Context(GarmConfiguratorCharm) | ||
| out = ctx.run(ctx.on.collect_unit_status(), State()) | ||
| assert out.unit_status == ops.ActiveStatus("Ready") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| env_list = ["lint", "complexity", "static", "unit", "coverage-report"] | ||
|
|
||
| [env_run_base] | ||
| package = "skip" | ||
| set_env = { PYTHONPATH = "{tox_root}/lib:{tox_root}/src:{tox_root}/tests", PYTHONBREAKPOINT = "pdb.set_trace", PY_COLORS = "1" } | ||
| pass_env = ["PYTHONPATH", "CHARM_BUILD_DIR", "MODEL_SETTINGS"] | ||
|
|
||
| [env.lint] | ||
| description = "Check code against coding style standards" | ||
| deps = ["ruff", "codespell"] | ||
| commands = [ | ||
| ["codespell", "{tox_root}"], | ||
| ["ruff", "check", "src"], | ||
| ["ruff", "format", "--check", "--diff", "src"], | ||
| ] | ||
|
|
||
| [env.complexity] | ||
| description = "Check cyclomatic complexity" | ||
| deps = ["ruff"] | ||
| commands = [["ruff", "check", "--select", "C90", "src"]] | ||
|
|
||
| [env.static] | ||
| description = "Run static type checks" | ||
| deps = ["mypy", "bandit[toml]", "-r requirements.txt"] | ||
| commands = [ | ||
| ["mypy", "src"], | ||
|
florentianayuwono marked this conversation as resolved.
|
||
| ["bandit", "-c", "pyproject.toml", "-r", "src"], | ||
| ] | ||
|
|
||
| [env.unit] | ||
| description = "Run unit tests" | ||
| deps = ["pytest", "coverage[toml]", "ops-scenario==8.7.0", "-r requirements.txt"] | ||
| commands = [ | ||
| [ | ||
| "coverage", | ||
| "run", | ||
| "--source=src", | ||
| "-m", | ||
| "pytest", | ||
| "--tb", | ||
| "native", | ||
| "-v", | ||
| "-s", | ||
| { replace = "posargs", default = ["tests/unit"], extend = true }, | ||
| ], | ||
| ] | ||
|
|
||
| [env.coverage-report] | ||
| description = "Report coverage results" | ||
| deps = ["coverage[toml]"] | ||
| commands = [["coverage", "report"]] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # Copyright 2026 Canonical Ltd. | ||
| # See LICENSE file for licensing details. | ||
|
|
||
| """Integration tests for the garm-configurator charm.""" | ||
|
|
||
| import logging | ||
|
|
||
| import jubilant | ||
| import pytest | ||
|
|
||
| from tests.conftest import CHARM_FILE_PARAM | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| @pytest.fixture(name="garm_configurator_charm_file", scope="module") | ||
| def garm_configurator_charm_file_fixture(pytestconfig: pytest.Config) -> str: | ||
| """Return the path to the built garm-configurator charm file.""" | ||
| charm = pytestconfig.getoption(CHARM_FILE_PARAM) | ||
| if not charm: | ||
| pytest.skip( | ||
| f"missing required {CHARM_FILE_PARAM} option for garm-configurator integration tests" | ||
| ) | ||
| if len(charm) > 1: | ||
| configurator_charms = [f for f in charm if "configurator" in f] | ||
|
|
||
| if not configurator_charms: | ||
| pytest.skip( | ||
| f"no garm-configurator charm file found in {CHARM_FILE_PARAM} option" | ||
| ) | ||
| return configurator_charms[0] | ||
| return charm[0] | ||
|
|
||
|
|
||
| @pytest.fixture(name="garm_configurator_app", scope="module") | ||
| def deploy_garm_configurator_app_fixture( | ||
| juju: jubilant.Juju, | ||
| garm_configurator_charm_file: str, | ||
| ) -> str: | ||
| """Deploy the garm-configurator application standalone with no relations. | ||
|
|
||
| Returns the application name once the app reaches Active. | ||
| """ | ||
| app_name = "garm-configurator" | ||
| juju.deploy(charm=garm_configurator_charm_file, app=app_name) | ||
| juju.wait( | ||
| lambda status: jubilant.all_active(status, app_name), | ||
| timeout=5 * 60, | ||
| delay=10, | ||
| ) | ||
| return app_name | ||
|
|
||
|
|
||
| def test_garm_configurator_deploys_active( | ||
| juju: jubilant.Juju, | ||
| garm_configurator_app: str, | ||
| ) -> None: | ||
| """ | ||
| arrange: garm-configurator charm deployed with no relations wired. | ||
| act: Check the application status. | ||
| assert: Application is in Active state. | ||
| """ | ||
| status = juju.status() | ||
| assert jubilant.all_active(status, garm_configurator_app) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.