feat(facts, operations): add OpenWrt packages, move opkg underneath openwrt and add packages and update operations#1847
Conversation
- make same change as was done for same reason for operations
…OpenWrt specific modules - simplifies top-level name space when packages, procd and uci arrive - move opkg under openwrt (will be backfilled with deprecated version that can be removed)
- takes a OpenWrtFeature enum instance and tells if the feature is supported by the release - use to determine opkg vs. apk or DSA vs. switch or FW4 vs. FW3, etc
… choice - use OpenWrtHasFeature to decide which package manager to use
…cated forwarder - preserves backwards compatibility while allowing deprecation to be noted
… deprecated. - same approach as operations: is_deprecated and, optionally, deprecated_for - only emit one warning per distinct fact regardless of the number of invocations
…t.opkg - preserve backwards compability while giving notice of deprecation.
…entries for openwrt to pyinfra-metadata - required for them to show up in the documentation cards
…at use packages instead of single files - deferred imports broke "docs for packages" fix - change deferred import mechanism to allow equiv. of from .x import y - used updated mechanism for both freebsed operations and openwrt facts and operations - change deferred imports mechanism to dispose of module if only a single element imported - above needed as otherwise importer bypasses getattr - update fact and operation discovery to use table of deferred imports for packages - move remove_dups into discovery code
- i.e. <something> will come before <and.this.thing> even though and sorts before something
…t__.py - it is for local use only
wowi42
left a comment
There was a problem hiding this comment.
Verdict: NO-GO
Well-structured PR with good deprecation handling and broad test coverage. Three issues need fixing before merge.
Issues
1. Fixture bug: has_dsa_is_false_for_19_07.json tests the wrong feature
tests/facts/openwrt.features.OpenWrtHasFeature/has_dsa_is_false_for_19_07.json has "arg": ["has_dsa"] and "command": "echo has_dsa && ...", but the first line of output is "uses_apk" instead of "has_dsa". The test passes accidentally because both features return false for release 19.07, but the fixture is not testing what its name and args claim. First output line must match the echoed feature name: "has_dsa".
2. Missing fixture: openwrt.update (i.e. openwrt.packages.update) has no tests
The update function in src/pyinfra/operations/openwrt/packages.py is a @operation that calls host.get_fact(OpenWrtHasFeature, ...). There is no tests/operations/openwrt.packages.update/ directory. Create at least two fixtures covering the apk and opkg branches.
3. Drive-by refactor of freebsd/__init__.py — out of scope
src/pyinfra/operations/freebsd/__init__.py replaces the glob-based module auto-discovery with an explicit __ALL__ dict and a getattr that splits on dots for sub-module attribute access. This is unrelated to OpenWrt. The glob approach was more maintainable (drop a new .py under freebsd/ and it's auto-discovered); the explicit dict requires manual registration. If this change is intentional, split it into its own PR with a rationale.
Notes
- Copy-paste comment errors in
__getattr__docstrings:src/pyinfra/operations/freebsd/__init__.pyline 17,src/pyinfra/operations/openwrt/__init__.pyline 19, andsrc/pyinfra/facts/openwrt/__init__.pyline 19 all say "On-demand import of OpenWrt facts" but should reference the correct package (FreeBSD operations, OpenWrt operations, OpenWrt facts respectively). openwrt.packageshaspackages: str | list[str] = ""default. Per AGENTS.md new operations should useNone. The""default passes through toapk.packages._inner()which treats""as a package name rather than nooping. Minor since the operation is always called with explicit package lists, but worth aligning withNoneconvention.
- correct first line of output to be has_dsa (not copy paste is_apk)
- change back to previous approach.
- both apk an opkg cases
- operations not facts
- use | None = None for both openwrt.packages and opkg.packages - adjust tests accordingly
- rework opkg (older code) - parametrize FactBase - set output type to list[str] - set return types for process
- both openwrt and opkg
- src/pyinfra/facts/openwrt/opkg.py
- change from object to Any for __init__.py in openwrt
Fixed.
Indeed needed. Added.
Removed.
Fixed.
Fixed both Also I converted the fixtures to YAML while I was here and added typing to |
Add OpenWrt facts and operations packages, move the existing
opkgitems there and addpackagesandupdateoperations that selectapkvs.opkgbased on the running OpenWrt release.The rationale for the OpenWrt package is that there are three OpenWrt -specific items (
opkg,procd,uci) needed which don't need to be at the top-level.opkgexists today (even if it is being supplanted byapk),procdsupport will arrive soon and there are a couple of people working onucisupport.The expectation is that the top-level
opkgwill be removed after a suitable interval; the interval can probably be reasonably be short as the OpenWrt change fromopkgtoaskin their Release 25.12 means most users will switch to the release/package-management independentopenwrt.packagesonce it is available.Specifically changes here are:
operations/freebsdto allow for the equivalent ofimport .sub-package.something as somethingwhich is useful to avoiding unnecessarily levels in the namespace.operations/freebsdimplementation to be consistent with theopenwrtimplementationstest_facts.pyto allow for packages (vs. files) by making the same change as was made fortest_operations.pyopkgfacts and operations toopenwrtopkgfacts and operations with deprecated "forwarders"pyinfrarun per deprecated fact as some facts are called a large number of timesopkgfor both facts and operationsopenwrt.opkgOpenWrtHasFeaturefact, a general version of check needed for 6test_facts.pyandpyinfra_clisupport enum parameterspackagesandupdateoperations for OpenWrtOpenWrtHasFeatureto decide whether to useapkoropkgPackagesfact: is it is only consulted prior to doing something which is already covered for thepackagesandupdatecasespyinfra-metadata.tomlfor (1)operations/freebsd)lazy importmechanism inpython 3.15scripts/generation_operations_docs.pyto match sorting order used for imports; this affects not just the order on the page but also the order in the sidebarA couple of questions related to the deprecation at (3) above:
a) there is a warning in the documentation for the deprecations but is there a specific
admonitionfor deprecation that should have been used ?b) does the future release need to be specified now (the documentation currently doesn't specify one)
One note: at (5), i.e. the
OpenWrtHasFeaturefact, there is a core mechanism (ReleaseRange.contains) for which it wasn't clear where to put the (non-fixture) tests. I opted fortests/test_facts_other.pybut am happy to relocate them if there is a preferred location for such tests.3.xat this time)scripts/dev-test.sh)scripts/dev-lint.sh)conventional commits format