Skip to content

Commit 6af6a0a

Browse files
authored
Merge branch 'main' into feat/helm-ci-improvements
2 parents 3827d15 + 978e851 commit 6af6a0a

File tree

10 files changed

+74
-65
lines changed

10 files changed

+74
-65
lines changed

.github/workflows/tox.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ on:
1111
jobs:
1212
build:
1313
name: Tox unit tests and linting
14-
runs-on: ubuntu-latest
14+
runs-on: ubuntu-24.04
1515
strategy:
1616
matrix:
17-
python-version: ['3.10']
17+
python-version: ['3.12','3.13']
1818

1919
steps:
2020
- name: Check out the repository
@@ -41,5 +41,5 @@ jobs:
4141
- name: Archive code coverage results
4242
uses: actions/upload-artifact@v4
4343
with:
44-
name: code-coverage-report
44+
name: "code-coverage-report-${{ matrix.python-version }}"
4545
path: cover/

Dockerfile

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
FROM ubuntu:jammy AS python-builder
1+
FROM ubuntu:24.04 AS python-builder
22

33
RUN apt-get update && \
4-
apt-get install -y python3 python3-venv && \
5-
rm -rf /var/lib/apt/lists/*
4+
apt-get install -y python3 python3-venv
65

76
RUN python3 -m venv /venv && \
87
/venv/bin/pip install -U pip setuptools
@@ -14,16 +13,16 @@ COPY . /app
1413
RUN /venv/bin/pip install /app
1514

1615

17-
FROM ubuntu:jammy
16+
FROM ubuntu:24.04
1817

1918
# Don't buffer stdout and stderr as it breaks realtime logging
20-
ENV PYTHONUNBUFFERED 1
19+
ENV PYTHONUNBUFFERED=1
2120

2221
# Create the user that will be used to run the app
23-
ENV APP_UID 1001
24-
ENV APP_GID 1001
25-
ENV APP_USER app
26-
ENV APP_GROUP app
22+
ENV APP_UID=1001
23+
ENV APP_GID=1001
24+
ENV APP_USER=app
25+
ENV APP_GROUP=app
2726
RUN groupadd --gid $APP_GID $APP_GROUP && \
2827
useradd \
2928
--no-create-home \
@@ -40,5 +39,4 @@ RUN apt-get update && \
4039
COPY --from=python-builder /venv /venv
4140

4241
USER $APP_UID
43-
ENTRYPOINT ["tini", "-g", "--"]
44-
CMD ["/venv/bin/kopf", "run", "--module", "capi_janitor.openstack.operator", "--all-namespaces"]
42+
CMD ["/venv/bin/kopf", "run", "--module", "capi_janitor.openstack.operator", "--all-namespaces", "--verbose"]

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,26 @@ helm upgrade \
2424
--install
2525
```
2626

27+
## Tox for unittests and linting
28+
29+
We use tox to run unit tests and linters across the code.
30+
To run all the checks, including efforts to automatically
31+
fix linting issues, please run:
32+
33+
```sh
34+
tox
35+
```
36+
37+
You can run individual unit tests by running:
38+
39+
```sh
40+
tox -e py3 -- <name-of-unit-test>
41+
```
42+
43+
Note, failures on your initial tox run may be automatically
44+
fixed, where possible. So your second tox run may pass.
45+
This way we can run the default tox target in CI.
46+
2747
## Configuration
2848

2949
`cluster-api-janitor-openstack` will always clean up

capi_janitor/openstack/openstack.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import urllib.parse
55

66
import httpx
7-
87
from easykube import rest
98

109

capi_janitor/openstack/operator.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
import random
66
import string
77

8-
import kopf
9-
import yaml
10-
118
import easykube
129
import httpx
10+
import kopf
11+
import yaml
1312

1413
from . import openstack
1514

@@ -47,9 +46,7 @@ async def on_startup(**kwargs):
4746

4847
@kopf.on.cleanup()
4948
async def on_cleanup(**kwargs):
50-
"""
51-
Runs on operator shutdown.
52-
"""
49+
"""Runs on operator shutdown."""
5350
# Make sure that the easykube client is shut down properly
5451
await ekclient.aclose()
5552

@@ -105,7 +102,6 @@ async def secgroups_for_cluster(resource, cluster):
105102

106103
async def filtered_volumes_for_cluster(resource, cluster):
107104
"""Async iterator for volumes belonging to the specified cluster."""
108-
109105
async for vol in resource.list():
110106
# CSI Cinder sets metadata on the volumes that we can look for
111107
owner = vol.metadata.get("cinder.csi.openstack.org/cluster")
@@ -162,7 +158,6 @@ async def purge_openstack_resources(
162158
logger, clouds, cloud_name, cacert, name, include_volumes, include_appcred
163159
):
164160
"""Cleans up the OpenStack resources created by the OCCM and CSI for a cluster."""
165-
166161
# Use the credential to delete external resources as required
167162
async with openstack.Cloud.from_clouds(clouds, cloud_name, cacert) as cloud:
168163
if not cloud.is_authenticated:
@@ -360,7 +355,6 @@ async def _on_openstackcluster_event_impl(
360355
name, namespace, meta, labels, spec, logger, **kwargs
361356
):
362357
"""Executes whenever an event occurs for an OpenStack cluster."""
363-
364358
# Get the resource for manipulating OpenStackClusters at the preferred version
365359
openstackclusters = await _get_os_cluster_client()
366360

@@ -375,7 +369,10 @@ async def _on_openstackcluster_event_impl(
375369
if not meta.get("deletionTimestamp"):
376370
if FINALIZER not in finalizers:
377371
await patch_finalizers(
378-
openstackclusters, name, namespace, finalizers + [FINALIZER]
372+
openstackclusters,
373+
name,
374+
namespace,
375+
[*finalizers, FINALIZER],
379376
)
380377
logger.info("added janitor finalizer to cluster")
381378
return

capi_janitor/tests/openstack/test_operator.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import base64
22
import unittest
33
from unittest import mock
4-
import yaml
54

65
import easykube
76
import httpx
7+
import yaml
88

9-
from capi_janitor.openstack import openstack
10-
from capi_janitor.openstack import operator
9+
from capi_janitor.openstack import openstack, operator
1110
from capi_janitor.openstack.operator import OPENSTACK_USER_VOLUMES_RECLAIM_PROPERTY
1211

1312

pyproject.toml

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,40 @@
11
[tool.ruff]
2-
# Match Black's style
32
line-length = 88
4-
target-version = "py310" # adjust to your minimum supported Python version
3+
target-version = "py312"
54

6-
# Match Flake8/hacking exclude patterns
7-
exclude = [
8-
".venv",
9-
".git",
10-
".tox",
11-
"dist",
12-
"doc",
13-
"build",
14-
"*egg",
15-
"*lib/python*"
16-
]
17-
18-
# For OpenStack/_-based i18n
19-
builtins = ["_"]
20-
21-
# Optional: format with Ruff (in place of Black)
225
[tool.ruff.format]
23-
quote-style = "double"
24-
indent-style = "space"
25-
line-ending = "auto"
6+
line-ending = "lf"
267

278
[tool.ruff.lint]
289
select = [
2910
# pycodestyle
3011
"E",
3112
# Pyflakes
3213
"F",
14+
# flake8-builtins
15+
"A",
16+
# Ruff rules
17+
"RUF",
3318
# flake8-async
3419
"ASYNC",
3520
# pyupgrade
3621
"UP",
22+
# tidy imports
23+
"TID",
24+
# sorted imports
25+
"I",
26+
# check complexity
27+
"C90",
28+
# pep8 naming
29+
"N",
3730
]
3831

3932
[tool.mypy]
4033
follow_imports = "silent"
4134
warn_redundant_casts = true
4235
warn_unused_ignores = true
4336
check_untyped_defs = true
37+
38+
[tool.ruff.lint.mccabe]
39+
# Flag errors (`C901`) whenever the complexity level exceeds 5.
40+
max-complexity = 14

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ attrs==25.3.0
77
certifi==2025.4.26
88
click==8.1.8
99
easykube==0.6.0
10-
exceptiongroup==1.2.2
10+
exceptiongroup==1.3.0
1111
frozenlist==1.6.0
1212
h11==0.16.0
1313
httpcore==1.0.9
1414
httpx==0.28.1
1515
idna==3.10
1616
iso8601==2.1.0
17-
kopf==1.37.5
17+
kopf==1.38.0
1818
multidict==6.4.3
1919
propcache==0.3.1
2020
python-json-logger==3.3.0

test-requirements.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
hacking>=6.1.0,<7.1 # Apache-2.0
2-
3-
ruff~=0.11.8
1+
ruff~=0.11.9
42
coverage>=4.0,!=4.4 # Apache-2.0
53
stestr>=4.2.0 # Apache-2.0
64
codespell
75
types-PyYAML
86
types-setuptools
97
mypy
8+
black~=25.1.0

tox.ini

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[tox]
22
minversion = 4.0.0
3-
envlist = py3,ruff,codespell,pep8,mypy
3+
# We run autofix last, to ensure CI fails,
4+
# even though we do our best to autofix locally
5+
envlist = py3,ruff,black,codespell,mypy,autofix
46
skipsdist = True
57

68
[testenv]
@@ -15,11 +17,17 @@ deps = -r{toxinidir}/requirements.txt
1517
-r{toxinidir}/test-requirements.txt
1618
commands = stestr run {posargs}
1719

18-
[testenv:pep8]
20+
[testenv:autofix]
1921
commands =
22+
black {tox_root}
2023
ruff format {tox_root}
2124
codespell {tox_root} -w
22-
flake8 {postargs}
25+
ruff check {tox_root} --fix
26+
27+
[testenv:black]
28+
# TODO: understand why ruff doesn't fix
29+
# line lengths as well as black does
30+
commands = black {tox_root} --check
2331

2432
[testenv:codespell]
2533
commands = codespell {posargs}
@@ -46,11 +54,3 @@ commands =
4654

4755
[testenv:mypy]
4856
commands = mypy {tox_root} {posargs}
49-
50-
[flake8]
51-
# select only hacking errors
52-
select = H
53-
show-source = True
54-
ignore = H102
55-
builtins = _
56-
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build

0 commit comments

Comments
 (0)