%PDF- %PDF-
Direktori : /lib/python2.7/site-packages/salt/states/ |
Current File : //lib/python2.7/site-packages/salt/states/ports.py |
# -*- coding: utf-8 -*- ''' 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 ''' from __future__ import absolute_import, print_function, unicode_literals # Import python libs import copy import logging import sys # Import salt libs import salt.utils.data from salt.exceptions import SaltInvocationError, CommandExecutionError from salt.modules.freebsdports import _normalize, _options_file_exists # Needed by imported function _options_file_exists import os # pylint: disable=W0611 from salt.ext import six log = logging.getLogger(__name__) def __virtual__(): if __grains__.get('os', '') == 'FreeBSD' and 'ports.install' in __salt__: return 'ports' return False def _repack_options(options): ''' Repack the options data ''' return dict( [ (six.text_type(x), _normalize(y)) for x, y in six.iteritems(salt.utils.data.repack_dictlist(options)) ] ) 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(['{0}={1}'.format(x, y) for x, y in six.iteritems(options)]) 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: {0}' .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': '{0} 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 {0}. Port name may ' 'be invalid, or ports tree may need to be updated. ' 'Error message: {1}'.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 six.itervalues(__salt__['pkg.list_pkgs'](with_origin=True)) ] 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'] = ('{0} does not have any build options, yet ' 'options were specified'.format(name)) return ret else: if __opts__['test']: ret['result'] = None ret['comment'] = '{0} 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 ' '{0}: {1}'.format(name, ', '.join(bad_opts))) return ret if __opts__['test']: ret['result'] = None ret['comment'] = '{0} 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 {0}'.format(name) return ret else: __salt__['ports.rmconfig'](name) if _options_file_exists(name): ret['result'] = False ret['comment'] = 'Unable to clear options for {0}'.format(name) return ret ret['changes'] = __salt__['ports.install'](name) ports_post = [ x['origin'] for x in six.itervalues(__salt__['pkg.list_pkgs'](with_origin=True)) ] 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 {0}'.format(name) if default_options: ret['comment'] += ' ' + _build_option_string(options) else: ret['comment'] = 'Failed to install {0}'.format(name) if err: ret['comment'] += '. Error message:\n{0}'.format(err) return ret