diff --git a/.typos.toml b/.typos.toml index 186698e11..15e19eaa8 100644 --- a/.typos.toml +++ b/.typos.toml @@ -1,6 +1,7 @@ [files] extend-exclude = [ "tests/facts/apt.SimulateOperationWillChange/upgrade.json", + "tests/facts/opkg.OpkgPackages/opkg_packages.json", "tests/words.txt", ] diff --git a/pyinfra/facts/opkg.py b/pyinfra/facts/opkg.py new file mode 100644 index 000000000..b16927062 --- /dev/null +++ b/pyinfra/facts/opkg.py @@ -0,0 +1,233 @@ +""" +Gather the information provided by ``opkg`` on OpenWrt systems: + + ``opkg`` configuration + + feeds configuration + + list of installed packages + + list of packages with available upgrades + + + see https://openwrt.org/docs/guide-user/additional-software/opkg +""" + +import re +from typing import Dict, NamedTuple, Union + +from pyinfra import logger +from pyinfra.api import FactBase +from pyinfra.facts.util.packaging import parse_packages + +# TODO - change NamedTuple to dataclass Opkgbut need to figure out how to get json serialization +# to work without changing core code + + +class OpkgPkgUpgradeInfo(NamedTuple): + installed: str + available: str + + +class OpkgConfInfo(NamedTuple): + paths: Dict[str, str] # list of paths, e.g. {'root':'/', 'ram':'/tmp} + list_dir: str # where package lists are stored, e.g. /var/opkg-lists + options: Dict[ + str, Union[str, bool] + ] # mapping from option to value, e.g. {'check_signature': True} + arch_cfg: Dict[str, int] # priorities for architectures + + +class OpkgFeedInfo(NamedTuple): + url: str # url for the feed + fmt: str # format of the feed, e.g. "src/gz" + kind: str # whether it comes from the 'distribution' or is 'custom' + + +class OpkgConf(FactBase): + """ + Returns a NamedTuple with the current configuration: + + .. code:: python + + ConfInfo( + paths = { + "root": "/", + "ram": "/tmp", + }, + list_dir = "/opt/opkg-lists", + options = { + "overlay_root": "/overlay" + }, + arch_cfg = { + "all": 1, + "noarch": 1, + "i386_pentium": 10 + } + ) + + """ + + regex = re.compile( + r""" + ^(?:\s*) + (?: + (?:arch\s+(?P\w+)\s+(?P\d+))| + (?:dest\s+(?P\w+)\s+(?P[\w/\-]+))| + (?:lists_dir\s+(?Pext)\s+(?P[\w/\-]+))| + (?:option\s+(?P