D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
proc
/
self
/
root
/
opt
/
saltstack
/
salt
/
lib
/
python3.10
/
site-packages
/
salt
/
states
/
Filename :
ports.py
back
Copy
""" Manage software from FreeBSD ports .. versionadded:: 2014.1.0 .. note:: It may be helpful to use a higher timeout when running a :mod:`ports.installed <salt.states.ports>` state, since compiling the port may exceed Salt's timeout. .. code-block:: bash salt -t 1200 '*' state.highstate """ import copy import logging # Needed by imported function _options_file_exists import os # pylint: disable=W0611 import sys import salt.utils.data from salt.exceptions import CommandExecutionError, SaltInvocationError from salt.modules.freebsdports import _normalize, _options_file_exists log = logging.getLogger(__name__) def __virtual__(): if __grains__.get("os", "") == "FreeBSD" and "ports.install" in __salt__: return "ports" return (False, "ports module could not be loaded") def _repack_options(options): """ Repack the options data """ return { str(x): _normalize(y) for x, y in salt.utils.data.repack_dictlist(options).items() } def _get_option_list(options): """ Returns the key/value pairs in the passed dict in a commaspace-delimited list in the format "key=value". """ return ", ".join(["{}={}".format(x, y) for x, y in options.items()]) def _build_option_string(options): """ Common function to get a string to append to the end of the state comment """ if options: return "with the following build options: {}".format(_get_option_list(options)) else: return "with the default build options" def installed(name, options=None): """ Verify that the desired port is installed, and that it was compiled with the desired options. options Make sure that the desired non-default options are set .. warning:: Any build options not passed here assume the default values for the port, and are not just differences from the existing cached options from a previous ``make config``. Example usage: .. code-block:: yaml security/nmap: ports.installed: - options: - IPV6: off """ ret = { "name": name, "changes": {}, "result": True, "comment": "{} is already installed".format(name), } try: current_options = __salt__["ports.showconfig"]( name, default=False, dict_return=True ) default_options = __salt__["ports.showconfig"]( name, default=True, dict_return=True ) # unpack the options from the top-level return dict if current_options: current_options = current_options[next(iter(current_options))] if default_options: default_options = default_options[next(iter(default_options))] except (SaltInvocationError, CommandExecutionError) as exc: ret["result"] = False ret["comment"] = ( "Unable to get configuration for {}. Port name may " "be invalid, or ports tree may need to be updated. " "Error message: {}".format(name, exc) ) return ret options = _repack_options(options) if options is not None else {} desired_options = copy.deepcopy(default_options) desired_options.update(options) ports_pre = [ x["origin"] for x in __salt__["pkg.list_pkgs"](with_origin=True).values() ] if current_options == desired_options and name in ports_pre: # Port is installed as desired if options: ret["comment"] += " " + _build_option_string(options) return ret if not default_options: if options: ret["result"] = False ret[ "comment" ] = "{} does not have any build options, yet options were specified".format( name ) return ret else: if __opts__["test"]: ret["result"] = None ret["comment"] = "{} will be installed".format(name) return ret else: bad_opts = [x for x in options if x not in default_options] if bad_opts: ret["result"] = False ret[ "comment" ] = "The following options are not available for {}: {}".format( name, ", ".join(bad_opts) ) return ret if __opts__["test"]: ret["result"] = None ret["comment"] = "{} will be installed ".format(name) ret["comment"] += _build_option_string(options) return ret if options: if not __salt__["ports.config"](name, reset=True, **options): ret["result"] = False ret["comment"] = "Unable to set options for {}".format(name) return ret else: __salt__["ports.rmconfig"](name) if _options_file_exists(name): ret["result"] = False ret["comment"] = "Unable to clear options for {}".format(name) return ret ret["changes"] = __salt__["ports.install"](name) ports_post = [ x["origin"] for x in __salt__["pkg.list_pkgs"](with_origin=True).values() ] err = sys.modules[__salt__["test.ping"].__module__].__context__.pop( "ports.install_error", None ) if err or name not in ports_post: ret["result"] = False if ret["result"]: ret["comment"] = "Successfully installed {}".format(name) if default_options: ret["comment"] += " " + _build_option_string(options) else: ret["comment"] = "Failed to install {}".format(name) if err: ret["comment"] += ". Error message:\n{}".format(err) return ret