%PDF- %PDF-
Direktori : /proc/thread-self/root/usr/lib/python2.7/site-packages/salt/modules/ |
Current File : //proc/thread-self/root/usr/lib/python2.7/site-packages/salt/modules/mac_softwareupdate.py |
# -*- coding: utf-8 -*- ''' Support for the softwareupdate command on MacOS. ''' from __future__ import absolute_import, unicode_literals, print_function # Import python libs import re import os # import salt libs import salt.utils.data import salt.utils.files import salt.utils.path import salt.utils.mac_utils import salt.utils.platform from salt.exceptions import CommandExecutionError, SaltInvocationError __virtualname__ = 'softwareupdate' def __virtual__(): ''' Only for MacOS ''' if not salt.utils.platform.is_darwin(): return (False, 'The softwareupdate module could not be loaded: ' 'module only works on MacOS systems.') return __virtualname__ def _get_available(recommended=False, restart=False): ''' Utility function to get all available update packages. Sample return date: { 'updatename': '1.2.3-45', ... } ''' cmd = ['softwareupdate', '--list'] out = salt.utils.mac_utils.execute_return_result(cmd) # rexp parses lines that look like the following: # * Safari6.1.2MountainLion-6.1.2 # Safari (6.1.2), 51679K [recommended] # - iCal-1.0.2 # iCal, 1.0.2, 6520K rexp = re.compile('(?m)^ [*|-] ' r'([^ ].*)[\r\n].*\(([^\)]+)') if salt.utils.data.is_true(recommended): # rexp parses lines that look like the following: # * Safari6.1.2MountainLion-6.1.2 # Safari (6.1.2), 51679K [recommended] rexp = re.compile('(?m)^ [*] ' r'([^ ].*)[\r\n].*\(([^\)]+)') keys = ['name', 'version'] _get = lambda l, k: l[keys.index(k)] updates = rexp.findall(out) ret = {} for line in updates: name = _get(line, 'name') version_num = _get(line, 'version') ret[name] = version_num if not salt.utils.data.is_true(restart): return ret # rexp parses lines that look like the following: # * Safari6.1.2MountainLion-6.1.2 # Safari (6.1.2), 51679K [recommended] [restart] rexp1 = re.compile('(?m)^ [*|-] ' r'([^ ].*)[\r\n].*restart*') restart_updates = rexp1.findall(out) ret_restart = {} for update in ret: if update in restart_updates: ret_restart[update] = ret[update] return ret_restart def list_available(recommended=False, restart=False): ''' List all available updates. :param bool recommended: Show only recommended updates. :param bool restart: Show only updates that require a restart. :return: Returns a dictionary containing the updates :rtype: dict CLI Example: .. code-block:: bash salt '*' softwareupdate.list_available ''' return _get_available(recommended, restart) def ignore(name): ''' Ignore a specific program update. When an update is ignored the '-' and version number at the end will be omitted, so "SecUpd2014-001-1.0" becomes "SecUpd2014-001". It will be removed automatically if present. An update is successfully ignored when it no longer shows up after list_updates. :param name: The name of the update to add to the ignore list. :ptype: str :return: True if successful, False if not :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.ignore <update-name> ''' # remove everything after and including the '-' in the updates name. to_ignore = name.rsplit('-', 1)[0] cmd = ['softwareupdate', '--ignore', to_ignore] salt.utils.mac_utils.execute_return_success(cmd) return to_ignore in list_ignored() def list_ignored(): ''' List all updates that have been ignored. Ignored updates are shown without the '-' and version number at the end, this is how the softwareupdate command works. :return: The list of ignored updates :rtype: list CLI Example: .. code-block:: bash salt '*' softwareupdate.list_ignored ''' cmd = ['softwareupdate', '--list', '--ignore'] out = salt.utils.mac_utils.execute_return_result(cmd) # rep parses lines that look like the following: # "Safari6.1.2MountainLion-6.1.2", # or: # Safari6.1.2MountainLion-6.1.2 rexp = re.compile('(?m)^ ["]?' r'([^,|\s].*[^"|\n|,])[,|"]?') return rexp.findall(out) def reset_ignored(): ''' Make sure the ignored updates are not ignored anymore, returns a list of the updates that are no longer ignored. :return: True if the list was reset, Otherwise False :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.reset_ignored ''' cmd = ['softwareupdate', '--reset-ignored'] salt.utils.mac_utils.execute_return_success(cmd) return list_ignored() == [] def schedule_enabled(): ''' Check the status of automatic update scheduling. :return: True if scheduling is enabled, False if disabled :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.schedule_enabled ''' cmd = ['softwareupdate', '--schedule'] ret = salt.utils.mac_utils.execute_return_result(cmd) enabled = ret.split()[-1] return salt.utils.mac_utils.validate_enabled(enabled) == 'on' def schedule_enable(enable): ''' Enable/disable automatic update scheduling. :param enable: True/On/Yes/1 to turn on automatic updates. False/No/Off/0 to turn off automatic updates. If this value is empty, the current status will be returned. :type: bool str :return: True if scheduling is enabled, False if disabled :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.schedule_enable on|off ''' status = salt.utils.mac_utils.validate_enabled(enable) cmd = ['softwareupdate', '--schedule', salt.utils.mac_utils.validate_enabled(status)] salt.utils.mac_utils.execute_return_success(cmd) return salt.utils.mac_utils.validate_enabled(schedule_enabled()) == status def update_all(recommended=False, restart=True): ''' Install all available updates. Returns a dictionary containing the name of the update and the status of its installation. :param bool recommended: If set to True, only install the recommended updates. If set to False (default) all updates are installed. :param bool restart: Set this to False if you do not want to install updates that require a restart. Default is True :return: A dictionary containing the updates that were installed and the status of its installation. If no updates were installed an empty dictionary is returned. :rtype: dict CLI Example: .. code-block:: bash salt '*' softwareupdate.update_all ''' to_update = _get_available(recommended, restart) if not to_update: return {} for _update in to_update: cmd = ['softwareupdate', '--install', _update] salt.utils.mac_utils.execute_return_success(cmd) ret = {} updates_left = _get_available() for _update in to_update: ret[_update] = True if _update not in updates_left else False return ret def update(name): ''' Install a named update. :param str name: The name of the of the update to install. :return: True if successfully updated, otherwise False :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.update <update-name> ''' if not update_available(name): raise SaltInvocationError('Update not available: {0}'.format(name)) cmd = ['softwareupdate', '--install', name] salt.utils.mac_utils.execute_return_success(cmd) return not update_available(name) def update_available(name): ''' Check whether or not an update is available with a given name. :param str name: The name of the update to look for :return: True if available, False if not :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.update_available <update-name> salt '*' softwareupdate.update_available "<update with whitespace>" ''' return name in _get_available() def list_downloads(): ''' Return a list of all updates that have been downloaded locally. :return: A list of updates that have been downloaded :rtype: list CLI Example: .. code-block:: bash salt '*' softwareupdate.list_downloads ''' outfiles = [] for root, subFolder, files in salt.utils.path.os_walk('/Library/Updates'): for f in files: outfiles.append(os.path.join(root, f)) dist_files = [] for f in outfiles: if f.endswith('.dist'): dist_files.append(f) ret = [] for update in _get_available(): for f in dist_files: with salt.utils.files.fopen(f) as fhr: if update.rsplit('-', 1)[0] in salt.utils.stringutils.to_unicode(fhr.read()): ret.append(update) return ret def download(name): ''' Download a named update so that it can be installed later with the ``update`` or ``update_all`` functions :param str name: The update to download. :return: True if successful, otherwise False :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdate.download <update name> ''' if not update_available(name): raise SaltInvocationError('Update not available: {0}'.format(name)) if name in list_downloads(): return True cmd = ['softwareupdate', '--download', name] salt.utils.mac_utils.execute_return_success(cmd) return name in list_downloads() def download_all(recommended=False, restart=True): ''' Download all available updates so that they can be installed later with the ``update`` or ``update_all`` functions. It returns a list of updates that are now downloaded. :param bool recommended: If set to True, only install the recommended updates. If set to False (default) all updates are installed. :param bool restart: Set this to False if you do not want to install updates that require a restart. Default is True :return: A list containing all downloaded updates on the system. :rtype: list CLI Example: .. code-block:: bash salt '*' softwareupdate.download_all ''' to_download = _get_available(recommended, restart) for name in to_download: download(name) return list_downloads() def get_catalog(): ''' .. versionadded:: 2016.3.0 Get the current catalog being used for update lookups. Will return a url if a custom catalog has been specified. Otherwise the word 'Default' will be returned :return: The catalog being used for update lookups :rtype: str CLI Example: .. code-block:: bash salt '*' softwareupdates.get_catalog ''' cmd = ['defaults', 'read', '/Library/Preferences/com.apple.SoftwareUpdate.plist'] out = salt.utils.mac_utils.execute_return_result(cmd) if 'AppleCatalogURL' in out: cmd.append('AppleCatalogURL') out = salt.utils.mac_utils.execute_return_result(cmd) return out elif 'CatalogURL' in out: cmd.append('CatalogURL') out = salt.utils.mac_utils.execute_return_result(cmd) return out else: return 'Default' def set_catalog(url): ''' .. versionadded:: 2016.3.0 Set the Software Update Catalog to the URL specified :param str url: The url to the update catalog :return: True if successful, False if not :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdates.set_catalog http://swupd.local:8888/index.sucatalog ''' # This command always returns an error code, though it completes # successfully. Success will be determined by making sure get_catalog # returns the passed url cmd = ['softwareupdate', '--set-catalog', url] try: salt.utils.mac_utils.execute_return_success(cmd) except CommandExecutionError as exc: pass return get_catalog() == url def reset_catalog(): ''' .. versionadded:: 2016.3.0 Reset the Software Update Catalog to the default. :return: True if successful, False if not :rtype: bool CLI Example: .. code-block:: bash salt '*' softwareupdates.reset_catalog ''' # This command always returns an error code, though it completes # successfully. Success will be determined by making sure get_catalog # returns 'Default' cmd = ['softwareupdate', '--clear-catalog'] try: salt.utils.mac_utils.execute_return_success(cmd) except CommandExecutionError as exc: pass return get_catalog() == 'Default'