diff --git a/pyinfra/facts/pkgin.py b/pyinfra/facts/pkgin.py new file mode 100644 index 000000000..6711bcb16 --- /dev/null +++ b/pyinfra/facts/pkgin.py @@ -0,0 +1,25 @@ +from pyinfra.api import FactBase + +from .util.packaging import parse_packages + +PKGIN_REGEX = r'^([a-zA-Z\-0-9]+)-([0-9\.]+\-?[a-z0-9]*)\s' + + +class PkginPackages(FactBase): + ''' + Returns a dict of installed pkgin packages: + + .. code:: python + + { + 'package_name': ['version'], + } + ''' + + command = 'pkgin list' + requires_command = 'pkgin' + + default = dict + + def process(self, output): + return parse_packages(PKGIN_REGEX, output, lower=False) diff --git a/pyinfra/operations/pkgin.py b/pyinfra/operations/pkgin.py new file mode 100644 index 000000000..324abc531 --- /dev/null +++ b/pyinfra/operations/pkgin.py @@ -0,0 +1,81 @@ +''' +Manage pkgin packages. +''' + +from pyinfra.api import operation +from pyinfra.facts.pkgin import PkginPackages + +from .util.packaging import ensure_packages + + +@operation +def upgrade(state=None, host=None): + ''' + Upgrades all pkgin packages. + ''' + + yield 'pkgin -y upgrade' + +_upgrade = upgrade # noqa: E305 + + +@operation +def update(state=None, host=None): + ''' + Updates pkgin repositories. + ''' + + yield 'pkgin -y update' + +_update = update # noqa: E305 + + +@operation +def packages( + packages=None, present=True, latest=False, + update=False, upgrade=False, + state=None, host=None, +): + ''' + Add/remove/update pkgin packages. + + + packages: list of packages to ensure + + present: whether the packages should be installed + + latest: whether to upgrade packages without a specified version + + update: run ``pkgin update`` before installing packages + + upgrade: run ``pkgin upgrade`` before installing packages + + Examples: + + .. code:: python + + # Update package list and install packages + pkgin.packages( + name='Install tmux and Vim', + packages=['tmux', 'vim'], + update=True, + ) + + # Install the latest versions of packages (always check) + pkgin.packages( + name='Install latest Vim', + packages=['vim'], + latest=True, + ) + ''' + + if update: + yield _update(state=state, host=host) + + if upgrade: + yield _upgrade(state=state, host=host) + + # TODO support glob for specific versions (it isn't as simple + # as apt's, as pkgin supports something like 'mysql-server>=5.6<5.7') + yield ensure_packages( + host, packages, host.get_fact(PkginPackages), present, + install_command='pkgin -y install', + uninstall_command='pkgin -y remove', + upgrade_command='pkgin -y upgrade', + latest=latest, + ) diff --git a/tests/facts/pkgin.PkginPackages/packages.json b/tests/facts/pkgin.PkginPackages/packages.json new file mode 100644 index 000000000..a316e083d --- /dev/null +++ b/tests/facts/pkgin.PkginPackages/packages.json @@ -0,0 +1,28 @@ +{ + "command": "pkgin list", + "requires_command": "pkgin", + "output": [ + "SDL2-2.0.14nb2 Simple DirectMedia Layer - cross-platform multimedia library", + "bash-5.1.4 The GNU Bourne Again Shell", + "ca-certificates-20200601nb1 Root CA certificates from the Mozilla Project", + "clang-10.0.1nb3 C language family frontend for LLVM", + "cmake-3.19.7 Cross platform make" + ], + "fact": { + "SDL2": [ + "2.0.14nb2" + ], + "bash": [ + "5.1.4" + ], + "ca-certificates": [ + "20200601nb1" + ], + "clang": [ + "10.0.1nb3" + ], + "cmake": [ + "3.19.7" + ] + } +} diff --git a/tests/operations/pkgin.packages/add_packages.json b/tests/operations/pkgin.packages/add_packages.json new file mode 100644 index 000000000..f57e4d07d --- /dev/null +++ b/tests/operations/pkgin.packages/add_packages.json @@ -0,0 +1,9 @@ +{ + "args": ["curl"], + "facts": { + "pkgin.PkginPackages": {} + }, + "commands": [ + "pkgin -y install curl" + ] +} diff --git a/tests/operations/pkgin.packages/remove_packages.json b/tests/operations/pkgin.packages/remove_packages.json new file mode 100644 index 000000000..a3c34ceaf --- /dev/null +++ b/tests/operations/pkgin.packages/remove_packages.json @@ -0,0 +1,14 @@ +{ + "args": [["curl", "i-dont-exist"]], + "kwargs": { + "present": false + }, + "facts": { + "pkgin.PkginPackages": { + "curl": "1" + } + }, + "commands": [ + "pkgin -y remove curl" + ] +} diff --git a/tests/operations/pkgin.packages/upgrade_packages.json b/tests/operations/pkgin.packages/upgrade_packages.json new file mode 100644 index 000000000..4e2c5aa16 --- /dev/null +++ b/tests/operations/pkgin.packages/upgrade_packages.json @@ -0,0 +1,14 @@ +{ + "args": ["curl"], + "kwargs": { + "latest": true + }, + "facts": { + "pkgin.PkginPackages": {} + }, + "commands": [ + "pkgin -y install curl" + ], + "idempotent": false, + "disable_itempotent_warning_reason": "package upgrades are always executed" +} diff --git a/tests/operations/pkgin.packages/upgrade_update.json b/tests/operations/pkgin.packages/upgrade_update.json new file mode 100644 index 000000000..58bb83a2c --- /dev/null +++ b/tests/operations/pkgin.packages/upgrade_update.json @@ -0,0 +1,18 @@ +{ + "args": ["curl"], + "kwargs": { + "update": true, + "upgrade": true + }, + "facts": { + "pkgin.PkginPackages": { + "curl": ["1"] + } + }, + "commands": [ + "pkgin -y update", + "pkgin -y upgrade" + ], + "idempotent": false, + "disable_itempotent_warning_reason": "package upgrades are always executed" +}