diff --git a/CHANGELOG.md b/CHANGELOG.md index d6213bc..b2a2be3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,9 @@ * Use `no_log` on systemd unit interrogations to suppress potential sensitive output when applying Ansible * Support manifesting Puppet code, as well as Ansible! * Support manifesting Salt code, as well as Ansible and Puppet! - * Take advantage of Jinjaturtle 0.5.5 if it's present, to render .erb templates for Puppet (as well as j2 for Ansible and Salt) * A lot of under-the-bonnet refactoring to make it easier to extend to cover other config managers (that don't suck) in future. - * Support for detecting Docker and Podman images and enforcing their presence (by SHA256 hash). - * Add support for detecting Flatpaks and Snaps. + * Support for detecting Docker images. + * Add support for detecting Flatpaks and Snaps (manifests for Ansible code only, not Puppet or Salt at this time) # 0.6.0 diff --git a/enroll/version.py b/enroll/version.py index 4c250b0..bbe78b6 100644 --- a/enroll/version.py +++ b/enroll/version.py @@ -28,6 +28,5 @@ def get_enroll_version() -> str: for dist in [*dist_names, "enroll"]: try: return version(dist) - except Exception: # nosec B112 - continue - return "unknown" + except Exception: + return "unknown" diff --git a/release.sh b/release.sh index 761c816..d41c468 100755 --- a/release.sh +++ b/release.sh @@ -7,6 +7,7 @@ filedust -y . # Publish to Pypi poetry build +poetry publish # Make AppImage poetry run pyproject-appimage --output dist/Enroll.AppImage @@ -85,9 +86,6 @@ for dist in ${DISTS[@]}; do qubes-gpg-client --local-user "$KEYID" --detach-sign --armor "$RPM_REPO/repodata/repomd.xml" > "$RPM_REPO/repodata/repomd.xml.asc" done -# If we got this far, publish to Poetry too -poetry publish - echo "==> Syncing repo to server..." rsync -aHPvz --exclude=.git --delete "$REPO_ROOT/" "$REMOTE/" diff --git a/tests/test_harvest_collectors.py b/tests/test_harvest_collectors.py index 80f43e4..e6e3228 100644 --- a/tests/test_harvest_collectors.py +++ b/tests/test_harvest_collectors.py @@ -141,107 +141,3 @@ def test_container_images_collector_records_unpullable_tagged_images( assert result.images[0]["pull_ref"] is None assert "exact digest-pinned pull cannot be rendered" in result.images[0]["notes"][0] - - -def test_container_images_collector_notes_list_exceptions(monkeypatch, tmp_path): - from enroll.harvest_collectors import container_images as ci - from enroll.harvest_collectors.container_images import ContainerImagesCollector - - monkeypatch.setattr( - ci.shutil, - "which", - lambda cmd: f"/usr/bin/{cmd}" if cmd == "docker" else None, - ) - - def boom(_argv, *, timeout=20): - raise RuntimeError("socket unavailable") - - monkeypatch.setattr(ci, "_run_command", boom) - - result = ContainerImagesCollector(_context(tmp_path)).collect() - - assert result.images == [] - assert "Failed to list docker images" in result.notes[0] - - -def test_container_images_collector_notes_list_nonzero_without_detail( - monkeypatch, tmp_path -): - import subprocess - - from enroll.harvest_collectors import container_images as ci - from enroll.harvest_collectors.container_images import ContainerImagesCollector - - monkeypatch.setattr( - ci.shutil, - "which", - lambda cmd: f"/usr/bin/{cmd}" if cmd == "podman" else None, - ) - monkeypatch.setattr( - ci, - "_run_command", - lambda argv, *, timeout=20: subprocess.CompletedProcess(argv, 42, "", ""), - ) - - result = ContainerImagesCollector(_context(tmp_path)).collect() - - assert result.images == [] - assert "exit 42" in result.notes[0] - - -def test_container_images_collector_notes_bad_inspect_json(monkeypatch, tmp_path): - import subprocess - - from enroll.harvest_collectors import container_images as ci - from enroll.harvest_collectors.container_images import ContainerImagesCollector - - image_id = "sha256:" + "d" * 64 - monkeypatch.setattr( - ci.shutil, - "which", - lambda cmd: f"/usr/bin/{cmd}" if cmd == "docker" else None, - ) - - def fake_run(argv, *, timeout=20): - if argv[:4] == ["/usr/bin/docker", "image", "ls", "-q"]: - return subprocess.CompletedProcess(argv, 0, image_id + "\n", "") - if argv[:3] == ["/usr/bin/docker", "image", "inspect"]: - return subprocess.CompletedProcess(argv, 0, "not json", "") - raise AssertionError(argv) - - monkeypatch.setattr(ci, "_run_command", fake_run) - - result = ContainerImagesCollector(_context(tmp_path)).collect() - - assert result.images == [] - assert "Failed to parse docker image inspect JSON" in result.notes[0] - - -def test_container_images_collector_notes_unexpected_inspect_shape( - monkeypatch, tmp_path -): - import subprocess - - from enroll.harvest_collectors import container_images as ci - from enroll.harvest_collectors.container_images import ContainerImagesCollector - - image_id = "sha256:" + "e" * 64 - monkeypatch.setattr( - ci.shutil, - "which", - lambda cmd: f"/usr/bin/{cmd}" if cmd == "docker" else None, - ) - - def fake_run(argv, *, timeout=20): - if argv[:4] == ["/usr/bin/docker", "image", "ls", "-q"]: - return subprocess.CompletedProcess(argv, 0, image_id + "\n", "") - if argv[:3] == ["/usr/bin/docker", "image", "inspect"]: - return subprocess.CompletedProcess(argv, 0, '{"not":"a-list"}', "") - raise AssertionError(argv) - - monkeypatch.setattr(ci, "_run_command", fake_run) - - result = ContainerImagesCollector(_context(tmp_path)).collect() - - assert result.images == [] - assert "Unexpected docker image inspect JSON shape" in result.notes[0] diff --git a/tests/test_version_extra.py b/tests/test_version_extra.py index ab3be1c..67c1ce4 100644 --- a/tests/test_version_extra.py +++ b/tests/test_version_extra.py @@ -1,6 +1,7 @@ from __future__ import annotations -import importlib.metadata as metadata +# The version module is hard to test fully because it uses importlib.metadata +# which is difficult to mock. We'll test what we can. def test_get_enroll_version_returns_string(): @@ -9,51 +10,3 @@ def test_get_enroll_version_returns_string(): result = get_enroll_version() assert isinstance(result, str) assert len(result) > 0 - - -def test_get_enroll_version_falls_back_after_bad_mapped_dist(monkeypatch): - from enroll.version import get_enroll_version - - monkeypatch.setattr( - metadata, - "packages_distributions", - lambda: {"enroll": ["wrong-dist", "enroll"]}, - ) - - def fake_version(name): - if name == "enroll": - return "0.7.0" - raise metadata.PackageNotFoundError(name) - - monkeypatch.setattr(metadata, "version", fake_version) - - assert get_enroll_version() == "0.7.0" - - -def test_get_enroll_version_uses_default_when_mapping_fails(monkeypatch): - from enroll.version import get_enroll_version - - def broken_mapping(): - raise RuntimeError("metadata unavailable") - - monkeypatch.setattr(metadata, "packages_distributions", broken_mapping) - monkeypatch.setattr( - metadata, - "version", - lambda name: "0.7.0" if name == "enroll" else "bad", - ) - - assert get_enroll_version() == "0.7.0" - - -def test_get_enroll_version_returns_unknown_when_all_lookups_fail(monkeypatch): - from enroll.version import get_enroll_version - - monkeypatch.setattr(metadata, "packages_distributions", lambda: {"enroll": ["bad"]}) - - def missing(_name): - raise metadata.PackageNotFoundError(_name) - - monkeypatch.setattr(metadata, "version", missing) - - assert get_enroll_version() == "unknown"