PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/mac_portspkg.py |
""" Support for MacPorts under macOS. This module has some caveats. 1. Updating the database of available ports is quite resource-intensive. However, `refresh=True` is the default for all operations that need an up-to-date copy of available ports. Consider `refresh=False` when you are sure no db update is needed. 2. In some cases MacPorts doesn't always realize when another copy of itself is running and will gleefully tromp all over the available ports database. This makes MacPorts behave in undefined ways until a fresh complete copy is retrieved. Because of 1 and 2 it is possible to get the salt-minion into a state where `salt mac-machine pkg./something/` won't want to return. Use `salt-run jobs.active` on the master to check for potentially long-running calls to `port`. Finally, ports database updates are always handled with `port selfupdate` as opposed to `port sync`. This makes sense in the MacPorts user community but may confuse experienced Linux admins as Linux package managers don't upgrade the packaging software when doing a package database update. In other words `salt mac-machine pkg.refresh_db` is more like `apt-get update; apt-get upgrade dpkg apt-get` than simply `apt-get update`. """ import copy import logging import re import salt.utils.data import salt.utils.functools import salt.utils.mac_utils import salt.utils.path import salt.utils.pkg import salt.utils.platform import salt.utils.versions from salt.exceptions import CommandExecutionError log = logging.getLogger(__name__) LIST_ACTIVE_ONLY = True __virtualname__ = "pkg" def __virtual__(): """ Confine this module to Mac OS with MacPorts. """ if not salt.utils.platform.is_darwin(): return False, "mac_ports only available on MacOS" if not salt.utils.path.which("port"): return False, 'mac_ports requires the "port" binary' return __virtualname__ def _list(query=""): cmd = f"port list {query}" out = salt.utils.mac_utils.execute_return_result(cmd) ret = {} for line in out.splitlines(): try: name, version_num, category = re.split(r"\s+", line.lstrip())[0:3] version_num = version_num[1:] except ValueError: continue ret[name] = version_num return ret def _list_pkgs_from_context(versions_as_list): """ Use pkg list from __context__ """ if versions_as_list: return __context__["pkg.list_pkgs"] else: ret = copy.deepcopy(__context__["pkg.list_pkgs"]) __salt__["pkg_resource.stringify"](ret) return ret def list_pkgs(versions_as_list=False, **kwargs): """ List the packages currently installed in a dict:: {'<package_name>': '<version>'} CLI Example: .. code-block:: bash salt '*' pkg.list_pkgs """ versions_as_list = salt.utils.data.is_true(versions_as_list) # 'removed', 'purge_desired' not yet implemented or not applicable if any( [salt.utils.data.is_true(kwargs.get(x)) for x in ("removed", "purge_desired")] ): return {} if "pkg.list_pkgs" in __context__ and kwargs.get("use_context", True): return _list_pkgs_from_context(versions_as_list) ret = {} cmd = ["port", "installed"] out = salt.utils.mac_utils.execute_return_result(cmd) for line in out.splitlines(): try: name, version_num, active = re.split(r"\s+", line.lstrip())[0:3] version_num = version_num[1:] except ValueError: continue if not LIST_ACTIVE_ONLY or active == "(active)": __salt__["pkg_resource.add_pkg"](ret, name, version_num) __salt__["pkg_resource.sort_pkglist"](ret) __context__["pkg.list_pkgs"] = copy.deepcopy(ret) if not versions_as_list: __salt__["pkg_resource.stringify"](ret) return ret def version(*names, **kwargs): """ Returns a string representing the package version or an empty string if not installed. If more than one package name is specified, a dict of name/version pairs is returned. CLI Example: .. code-block:: bash salt '*' pkg.version <package name> salt '*' pkg.version <package1> <package2> <package3> """ return __salt__["pkg_resource.version"](*names, **kwargs) def latest_version(*names, **kwargs): """ Return the latest version of the named package available for upgrade or installation Options: refresh Update ports with ``port selfupdate`` CLI Example: .. code-block:: bash salt '*' pkg.latest_version <package name> salt '*' pkg.latest_version <package1> <package2> <package3> """ if salt.utils.data.is_true(kwargs.get("refresh", True)): refresh_db() available = _list(" ".join(names)) or {} installed = __salt__["pkg.list_pkgs"]() or {} ret = {} for key, val in available.items(): if key not in installed or salt.utils.versions.compare( ver1=installed[key], oper="<", ver2=val ): ret[key] = val else: ret[key] = f"{version(key)} (installed)" return ret # available_version is being deprecated available_version = salt.utils.functools.alias_function( latest_version, "available_version" ) def remove(name=None, pkgs=None, **kwargs): """ Removes packages with ``port uninstall``. name The name of the package to be deleted. Multiple Package Options: pkgs A list of packages to delete. Must be passed as a python list. The ``name`` parameter will be ignored if this option is passed. .. versionadded:: 0.16.0 Returns a dict containing the changes. CLI Example: .. code-block:: bash salt '*' pkg.remove <package name> salt '*' pkg.remove <package1>,<package2>,<package3> salt '*' pkg.remove pkgs='["foo", "bar"]' """ pkg_params = __salt__["pkg_resource.parse_targets"](name, pkgs, **kwargs)[0] old = list_pkgs() targets = [x for x in pkg_params if x in old] if not targets: return {} cmd = ["port", "uninstall"] cmd.extend(targets) err_message = "" try: salt.utils.mac_utils.execute_return_success(cmd) except CommandExecutionError as exc: err_message = exc.strerror __context__.pop("pkg.list_pkgs", None) new = list_pkgs() ret = salt.utils.data.compare_dicts(old, new) if err_message: raise CommandExecutionError( "Problem encountered removing package(s)", info={"errors": err_message, "changes": ret}, ) return ret def install(name=None, refresh=False, pkgs=None, **kwargs): """ Install the passed package(s) with ``port install`` name The name of the formula to be installed. Note that this parameter is ignored if "pkgs" is passed. CLI Example: .. code-block:: bash salt '*' pkg.install <package name> version Specify a version to pkg to install. Ignored if pkgs is specified. CLI Example: .. code-block:: bash salt '*' pkg.install <package name> salt '*' pkg.install git-core version='1.8.5.5' variant Specify a variant to pkg to install. Ignored if pkgs is specified. CLI Example: .. code-block:: bash salt '*' pkg.install <package name> salt '*' pkg.install git-core version='1.8.5.5' variant='+credential_osxkeychain+doc+pcre' Multiple Package Installation Options: pkgs A list of formulas to install. Must be passed as a python list. CLI Example: .. code-block:: bash salt '*' pkg.install pkgs='["foo","bar"]' salt '*' pkg.install pkgs='["foo@1.2","bar"]' salt '*' pkg.install pkgs='["foo@1.2+ssl","bar@2.3"]' Returns a dict containing the new package names and versions:: {'<package>': {'old': '<old-version>', 'new': '<new-version>'}} CLI Example: .. code-block:: bash salt '*' pkg.install 'package package package' """ pkg_params, pkg_type = __salt__["pkg_resource.parse_targets"](name, pkgs, {}) if salt.utils.data.is_true(refresh): refresh_db() # Handle version kwarg for a single package target if pkgs is None: version_num = kwargs.get("version") variant_spec = kwargs.get("variant") spec = {} if version_num: spec["version"] = version_num if variant_spec: spec["variant"] = variant_spec pkg_params = {name: spec} if not pkg_params: return {} formulas_array = [] for pname, pparams in pkg_params.items(): formulas_array.append(pname) if pparams: if "version" in pparams: formulas_array.append("@" + pparams["version"]) if "variant" in pparams: formulas_array.append(pparams["variant"]) old = list_pkgs() cmd = ["port", "install"] cmd.extend(formulas_array) err_message = "" try: salt.utils.mac_utils.execute_return_success(cmd) except CommandExecutionError as exc: err_message = exc.strerror __context__.pop("pkg.list_pkgs", None) new = list_pkgs() ret = salt.utils.data.compare_dicts(old, new) if err_message: raise CommandExecutionError( "Problem encountered installing package(s)", info={"errors": err_message, "changes": ret}, ) return ret def list_upgrades(refresh=True, **kwargs): # pylint: disable=W0613 """ Check whether or not an upgrade is available for all packages Options: refresh Update ports with ``port selfupdate`` CLI Example: .. code-block:: bash salt '*' pkg.list_upgrades """ if refresh: refresh_db() return _list("outdated") def upgrade_available(pkg, refresh=True, **kwargs): """ Check whether or not an upgrade is available for a given package CLI Example: .. code-block:: bash salt '*' pkg.upgrade_available <package name> """ return pkg in list_upgrades(refresh=refresh) def refresh_db(**kwargs): """ Update ports with ``port selfupdate`` CLI Example: .. code-block:: bash salt mac pkg.refresh_db """ # Remove rtag file to keep multiple refreshes from happening in pkg states salt.utils.pkg.clear_rtag(__opts__) cmd = ["port", "selfupdate"] return salt.utils.mac_utils.execute_return_success(cmd) def upgrade(refresh=True, **kwargs): # pylint: disable=W0613 """ Run a full upgrade using MacPorts 'port upgrade outdated' Options: refresh Update ports with ``port selfupdate`` Returns a dictionary containing the changes: .. code-block:: python {'<package>': {'old': '<old-version>', 'new': '<new-version>'}} CLI Example: .. code-block:: bash salt '*' pkg.upgrade """ if refresh: refresh_db() old = list_pkgs() cmd = ["port", "upgrade", "outdated"] result = __salt__["cmd.run_all"](cmd, output_loglevel="trace", python_shell=False) __context__.pop("pkg.list_pkgs", None) new = list_pkgs() ret = salt.utils.data.compare_dicts(old, new) if result["retcode"] != 0: raise CommandExecutionError( "Problem encountered upgrading packages", info={"changes": ret, "result": result}, ) return ret