From f3d184c4780862543d13919ae0d7c7a9b4185196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Paw=C5=82owski?= Date: Wed, 17 Jun 2015 12:53:15 +0200 Subject: [PATCH 01/33] add get_route function to network module --- salt/modules/network.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/salt/modules/network.py b/salt/modules/network.py index 47c2cbcd0f..e2a222f798 100644 --- a/salt/modules/network.py +++ b/salt/modules/network.py @@ -1108,3 +1108,29 @@ def default_route(family=None): ret.append(route) return ret + + +def get_route(ip): + ''' + Return routing information for given destination ip + + CLI Example:: + + salt '*' network.get_route 10.10.10.10 + ''' + + if __grains__['kernel'] == 'Linux': + cmd = 'ip route get {0}'.format(ip) + out = __salt__['cmd.run'](cmd, python_shell=True) + regexp = re.compile(r'(via\s+(?P[\w\.:]+))?\s+dev\s+(?P[\w\W]+)\s+src\s+(?P[\w\.:]+)') + m = regexp.search(out.splitlines()[0]) + ret = { + 'destination': ip, + 'gateway': m.group('gateway'), + 'interface': m.group('interface'), + 'source': m.group('source')} + + return ret + else: + raise CommandExecutionError('Not yet supported on this platform') + From 0b6ef784b28d2449a4af2fde2ea14cf14a9866b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Paw=C5=82owski?= Date: Wed, 17 Jun 2015 13:14:56 +0200 Subject: [PATCH 02/33] network module: fix for ipv6 --- salt/modules/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/modules/network.py b/salt/modules/network.py index e2a222f798..64199a488b 100644 --- a/salt/modules/network.py +++ b/salt/modules/network.py @@ -1122,7 +1122,7 @@ def get_route(ip): if __grains__['kernel'] == 'Linux': cmd = 'ip route get {0}'.format(ip) out = __salt__['cmd.run'](cmd, python_shell=True) - regexp = re.compile(r'(via\s+(?P[\w\.:]+))?\s+dev\s+(?P[\w\W]+)\s+src\s+(?P[\w\.:]+)') + regexp = re.compile(r'(via\s+(?P[\w\.:]+))?\s+dev\s+(?P[\w\.\:]+)\s+.*src\s+(?P[\w\.:]+)') m = regexp.search(out.splitlines()[0]) ret = { 'destination': ip, From 79b4ec2da8f22990042a366ce75864ad48a53435 Mon Sep 17 00:00:00 2001 From: msciciel Date: Wed, 17 Jun 2015 22:04:30 +0200 Subject: [PATCH 03/33] network module lint fix Remove empty lines at the end of file --- salt/modules/network.py | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/modules/network.py b/salt/modules/network.py index 64199a488b..0df3aad038 100644 --- a/salt/modules/network.py +++ b/salt/modules/network.py @@ -1133,4 +1133,3 @@ def get_route(ip): return ret else: raise CommandExecutionError('Not yet supported on this platform') - From d7bfb0c7fd7023247c7c725ed9628d928d8d371b Mon Sep 17 00:00:00 2001 From: Bret Fisher Date: Tue, 23 Jun 2015 22:34:07 -0400 Subject: [PATCH 04/33] Smartos smf minion fix Per my own testing on dozens of SmartOS VM's and issue #473 "Problem 3", the salt-minion service manifest definition doesn't work. This change fixes that. I think it may have broke in 2014.7 so back porting to that ver. --- pkg/smartos/salt-minion.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/smartos/salt-minion.xml b/pkg/smartos/salt-minion.xml index 619276dc1e..269f23b165 100644 --- a/pkg/smartos/salt-minion.xml +++ b/pkg/smartos/salt-minion.xml @@ -14,7 +14,7 @@ grouping="require_all" restart_on="none" type="path"> - + - - - - - - + timeout_seconds="60"> + + + + + + Date: Tue, 23 Jun 2015 16:36:26 -0700 Subject: [PATCH 05/33] Don't refetch the template 100% of the time-- Performance optimization for templated files This module was actually re-fetching the template *every* run, even if we had the template cached locally (unless it was served from the master itself). With this change we check our local cache before fetching the template. This cuts ~1 RTT from the minion to the source of the file, which ranges from moderate to large savings. --- salt/fileclient.py | 34 ++++++++++-------- salt/modules/file.py | 83 +++++++++++++++++++++++++------------------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/salt/fileclient.py b/salt/fileclient.py index 4bbd75d053..c1e0ec2283 100644 --- a/salt/fileclient.py +++ b/salt/fileclient.py @@ -356,11 +356,14 @@ class Client(object): self.opts['cachedir'], 'localfiles', path.lstrip('/')) filesdest = os.path.join( self.opts['cachedir'], 'files', saltenv, path.lstrip('salt://')) + extrndest = self._extrn_path(path, saltenv) if os.path.exists(filesdest): return filesdest elif os.path.exists(localsfilesdest): return localsfilesdest + elif os.path.exists(extrndest): + return extrndest return '' @@ -537,13 +540,7 @@ class Client(object): netloc = salt.utils.sanitize_win_path_string(url_data.netloc) else: netloc = url_data.netloc - dest = salt.utils.path_join( - self.opts['cachedir'], - 'extrn_files', - saltenv, - netloc, - url_data.path - ) + dest = self._extrn_path(url, saltenv) destdir = os.path.dirname(dest) if not os.path.isdir(destdir): os.makedirs(destdir) @@ -670,13 +667,7 @@ class Client(object): return '' if not dest: # No destination passed, set the dest as an extrn_files cache - dest = salt.utils.path_join( - self.opts['cachedir'], - 'extrn_files', - saltenv, - url_data.netloc, - url_data.path - ) + dest = self._extrn_path(url, saltenv) # If Salt generated the dest name, create any required dirs makedirs = True @@ -690,6 +681,21 @@ class Client(object): shutil.move(data['data'], dest) return dest + def _extrn_path(self, url, saltenv): + ''' + Return the extn_filepath for a given url + ''' + url_data = urlparse(url) + + return salt.utils.path_join( + self.opts['cachedir'], + 'extrn_files', + saltenv, + url_data.netloc, + url_data.path + ) + + class LocalClient(Client): ''' diff --git a/salt/modules/file.py b/salt/modules/file.py index bec2edbeab..bcc669d7c3 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -2758,8 +2758,54 @@ def get_managed( # Copy the file to the minion and templatize it sfn = '' source_sum = {} - if template and source: - sfn = __salt__['cp.cache_file'](source, saltenv) + # if we have a source defined, lets figure out what the hash is + if source: + if _urlparse(source).scheme == 'salt': + source_sum = __salt__['cp.hash_file'](source, saltenv) + if not source_sum: + return '', {}, 'Source file {0} not found'.format(source) + elif source_hash: + protos = ['salt', 'http', 'https', 'ftp', 'swift'] + if _urlparse(source_hash).scheme in protos: + # The source_hash is a file on a server + hash_fn = __salt__['cp.cache_file'](source_hash, saltenv) + if not hash_fn: + return '', {}, 'Source hash file {0} not found'.format( + source_hash) + source_sum = extract_hash(hash_fn, '', name) + if source_sum is None: + return '', {}, ('Source hash file {0} contains an invalid ' + 'hash format, it must be in the format =.' + ).format(source_hash) + + else: + # The source_hash is a hash string + comps = source_hash.split('=') + if len(comps) < 2: + return '', {}, ('Source hash file {0} contains an ' + 'invalid hash format, it must be in ' + 'the format =' + ).format(source_hash) + source_sum['hsum'] = comps[1].strip() + source_sum['hash_type'] = comps[0].strip() + else: + return '', {}, ('Unable to determine upstream hash of' + ' source file {0}').format(source) + + # if the file is a template we need to actually template the file to get + # a checksum, but we can cache the template itselt + if template: + # check if we have the template cached + template_dest = __salt__['cp.is_cached'](source, saltenv) + if template_dest: + comps = source_hash.split('=') + cached_template_sum = get_hash(template_dest, form=source_sum['hash_type']) + if cached_template_sum == source_sum['hsum']: + sfn = template_dest + # if we didn't have the template file, lets get it + if not sfn: + sfn = __salt__['cp.cache_file'](source, saltenv) + # exists doesn't play nice with sfn as bool # but if cache failed, sfn == False if not sfn or not os.path.exists(sfn): @@ -2798,40 +2844,7 @@ def get_managed( else: __clean_tmp(sfn) return sfn, {}, data['data'] - else: - # Copy the file down if there is a source - if source: - if _urlparse(source).scheme == 'salt': - source_sum = __salt__['cp.hash_file'](source, saltenv) - if not source_sum: - return '', {}, 'Source file {0} not found'.format(source) - elif source_hash: - protos = ['salt', 'http', 'https', 'ftp', 'swift'] - if _urlparse(source_hash).scheme in protos: - # The source_hash is a file on a server - hash_fn = __salt__['cp.cache_file'](source_hash, saltenv) - if not hash_fn: - return '', {}, 'Source hash file {0} not found'.format( - source_hash) - source_sum = extract_hash(hash_fn, '', name) - if source_sum is None: - return '', {}, ('Source hash file {0} contains an invalid ' - 'hash format, it must be in the format =.' - ).format(source_hash) - else: - # The source_hash is a hash string - comps = source_hash.split('=') - if len(comps) < 2: - return '', {}, ('Source hash file {0} contains an ' - 'invalid hash format, it must be in ' - 'the format =' - ).format(source_hash) - source_sum['hsum'] = comps[1].strip() - source_sum['hash_type'] = comps[0].strip() - else: - return '', {}, ('Unable to determine upstream hash of' - ' source file {0}').format(source) return sfn, source_sum, '' From 0ecbf261ada82f1c35016b78cb8e1549725e77a3 Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Tue, 23 Jun 2015 09:05:30 +0200 Subject: [PATCH 06/33] Be more careful about stripping away root_dir from directory options Closes #24885 --- salt/config.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/salt/config.py b/salt/config.py index 0ecee4366a..d8bc77172d 100644 --- a/salt/config.py +++ b/salt/config.py @@ -911,14 +911,13 @@ def prepend_root_dir(opts, path_options): 'root_dir' option. ''' root_dir = os.path.abspath(opts['root_dir']) + root_opt = opts['root_dir'].rstrip(os.pathsep) for path_option in path_options: if path_option in opts: - if opts[path_option].startswith(opts['root_dir']): - opts[path_option] = opts[path_option][len(opts['root_dir']):] - opts[path_option] = salt.utils.path_join( - root_dir, - opts[path_option] - ) + path = opts[path_option] + if path == root_opt or path.startswith(root_opt + os.pathsep): + path = path[len(root_opt):] + opts[path_option] = salt.utils.path_join(root_dir, path) def insert_system_path(opts, paths): From bdb7a19c363389fa6ede42d170cdc7de6bf115ea Mon Sep 17 00:00:00 2001 From: justinta89 Date: Wed, 24 Jun 2015 11:31:07 -0600 Subject: [PATCH 07/33] Fixed ps module to not use depreciated psutil commands --- salt/modules/ps.py | 10 +++++----- tests/unit/modules/ps_test.py | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/salt/modules/ps.py b/salt/modules/ps.py index 67bc431d76..661b9c5ecd 100644 --- a/salt/modules/ps.py +++ b/salt/modules/ps.py @@ -125,7 +125,7 @@ def top(num_processes=5, interval=3): ''' result = [] start_usage = {} - for pid in psutil.get_pid_list(): + for pid in psutil.pids(): try: process = psutil.Process(pid) user, system = process.get_cpu_times() @@ -177,7 +177,7 @@ def get_pid_list(): salt '*' ps.get_pid_list ''' - return psutil.get_pid_list() + return psutil.pids() def kill_pid(pid, signal=15): @@ -535,9 +535,9 @@ def network_io_counters(interface=None): salt '*' ps.network_io_counters interface=eth0 ''' if not interface: - return dict(psutil.network_io_counters()._asdict()) + return dict(psutil.net_io_counters()._asdict()) else: - stats = psutil.network_io_counters(pernic=True) + stats = psutil.net_io_counters(pernic=True) if interface in stats: return dict(stats[interface]._asdict()) else: @@ -577,7 +577,7 @@ def get_users(): salt '*' ps.get_users ''' try: - recs = psutil.get_users() + recs = psutil.users() return [dict(x._asdict()) for x in recs] except AttributeError: # get_users is only present in psutil > v0.5.0 diff --git a/tests/unit/modules/ps_test.py b/tests/unit/modules/ps_test.py index a9e3cfa532..4d97892420 100644 --- a/tests/unit/modules/ps_test.py +++ b/tests/unit/modules/ps_test.py @@ -79,7 +79,7 @@ class PsTestCase(TestCase): MOCK_PROC.name = 'test_mock_proc' MOCK_PROC.pid = 9999999999 - @patch('psutil.get_pid_list', new=MagicMock(return_value=STUB_PID_LIST)) + @patch('psutil.pids', new=MagicMock(return_value=STUB_PID_LIST)) def test_get_pid_list(self): self.assertListEqual(STUB_PID_LIST, ps.get_pid_list()) @@ -149,7 +149,7 @@ class PsTestCase(TestCase): ## Should only be tested in integration # def test_boot_time(self): # pass - @patch('psutil.network_io_counters', new=MagicMock(return_value=STUB_NETWORK_IO)) + @patch('psutil.net_io_counters', new=MagicMock(return_value=STUB_NETWORK_IO)) def test_network_io_counters(self): self.assertDictEqual( {'packets_sent': 500, 'packets_recv': 600, 'bytes_recv': 2000, 'dropout': 4, 'bytes_sent': 1000, @@ -161,7 +161,7 @@ class PsTestCase(TestCase): {'read_time': 2000, 'write_bytes': 600, 'read_bytes': 500, 'write_time': 3000, 'read_count': 1000, 'write_count': 2000}, ps.disk_io_counters()) - @patch('psutil.get_users', new=MagicMock(return_value=[STUB_USER])) + @patch('psutil.users', new=MagicMock(return_value=[STUB_USER])) def test_get_users(self): self.assertDictEqual({'terminal': 'ttys000', 'started': 0.0, 'host': 'localhost', 'name': 'bdobbs'}, ps.get_users()[0]) From 4cf78a0a95259fa71a0e5906f1b333ff25e39425 Mon Sep 17 00:00:00 2001 From: Thomas Jackson Date: Wed, 24 Jun 2015 11:20:33 -0700 Subject: [PATCH 08/33] pylint --- salt/fileclient.py | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/fileclient.py b/salt/fileclient.py index c1e0ec2283..45f5399828 100644 --- a/salt/fileclient.py +++ b/salt/fileclient.py @@ -696,7 +696,6 @@ class Client(object): ) - class LocalClient(Client): ''' Use the local_roots option to parse a local file root From c03a6fa9d18c145419451cf899525d462a33fb4b Mon Sep 17 00:00:00 2001 From: Thomas Jackson Date: Wed, 24 Jun 2015 11:20:38 -0700 Subject: [PATCH 09/33] Add support for sources of managed files to be local --- salt/modules/file.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/salt/modules/file.py b/salt/modules/file.py index bcc669d7c3..5e9fc58cd4 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -2758,14 +2758,20 @@ def get_managed( # Copy the file to the minion and templatize it sfn = '' source_sum = {} + urlparsed_source = _urlparse(source) # if we have a source defined, lets figure out what the hash is if source: - if _urlparse(source).scheme == 'salt': + if urlparsed_source.scheme == 'salt': source_sum = __salt__['cp.hash_file'](source, saltenv) if not source_sum: return '', {}, 'Source file {0} not found'.format(source) + # if its a local file + elif urlparsed_source.scheme == 'file': + source_sum = get_hash(urlparsed_source.path) + elif source.startswith('/'): + source_sum = get_hash(source) elif source_hash: - protos = ['salt', 'http', 'https', 'ftp', 'swift'] + protos = ('salt', 'http', 'https', 'ftp', 'swift') if _urlparse(source_hash).scheme in protos: # The source_hash is a file on a server hash_fn = __salt__['cp.cache_file'](source_hash, saltenv) From 5fb75346efeedded2738a2c25a4914f94b364bff Mon Sep 17 00:00:00 2001 From: Thomas Jackson Date: Wed, 24 Jun 2015 12:31:51 -0700 Subject: [PATCH 10/33] Only parse the source if we have one --- salt/modules/file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/modules/file.py b/salt/modules/file.py index 5e9fc58cd4..01af8b8754 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -2758,9 +2758,9 @@ def get_managed( # Copy the file to the minion and templatize it sfn = '' source_sum = {} - urlparsed_source = _urlparse(source) # if we have a source defined, lets figure out what the hash is if source: + urlparsed_source = _urlparse(source) if urlparsed_source.scheme == 'salt': source_sum = __salt__['cp.hash_file'](source, saltenv) if not source_sum: From 52ccafded329f6bd1df6392da328aefae07b64eb Mon Sep 17 00:00:00 2001 From: Andreas Lutro Date: Wed, 24 Jun 2015 22:35:16 +0200 Subject: [PATCH 11/33] os.sep is the correct directory separator constant --- salt/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/config.py b/salt/config.py index d8bc77172d..c9aa491a07 100644 --- a/salt/config.py +++ b/salt/config.py @@ -911,11 +911,11 @@ def prepend_root_dir(opts, path_options): 'root_dir' option. ''' root_dir = os.path.abspath(opts['root_dir']) - root_opt = opts['root_dir'].rstrip(os.pathsep) + root_opt = opts['root_dir'].rstrip(os.sep) for path_option in path_options: if path_option in opts: path = opts[path_option] - if path == root_opt or path.startswith(root_opt + os.pathsep): + if path == root_opt or path.startswith(root_opt + os.sep): path = path[len(root_opt):] opts[path_option] = salt.utils.path_join(root_dir, path) From 59c3081e49a5ac9fafbf32210f1eebf1c51c6e4e Mon Sep 17 00:00:00 2001 From: Joseph Hall Date: Wed, 24 Jun 2015 14:42:37 -0600 Subject: [PATCH 12/33] Double-check main_cloud_config --- salt/cloud/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/salt/cloud/__init__.py b/salt/cloud/__init__.py index e376c6f6e3..291dd20cf7 100644 --- a/salt/cloud/__init__.py +++ b/salt/cloud/__init__.py @@ -1290,6 +1290,9 @@ class Cloud(object): except IOError: main_cloud_config = {} + if main_cloud_config is None: + main_cloud_config = {} + profile_details = self.opts['profiles'][profile] alias, driver = profile_details['provider'].split(':') mapped_providers = self.map_providers_parallel() From 152a9b2a12301aafde21e2dd6651d9221a041f0f Mon Sep 17 00:00:00 2001 From: Justin Findlay Date: Wed, 24 Jun 2015 16:56:52 -0600 Subject: [PATCH 13/33] fix some malformed doc links and anchors --- doc/topics/development/contributing.rst | 12 ++++++++---- doc/topics/development/hacking.rst | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/doc/topics/development/contributing.rst b/doc/topics/development/contributing.rst index cd7ed7530a..6ac1867e40 100644 --- a/doc/topics/development/contributing.rst +++ b/doc/topics/development/contributing.rst @@ -11,6 +11,8 @@ There are a number of ways to contribute to Salt development. For details on how to contribute documentation improvements please review :ref:`Writing Salt Documentation `. +.. _github-pull-request: + Sending a GitHub pull request ============================= @@ -41,7 +43,7 @@ Fork a Repo Guide_>`_ and is well worth reading. isolated into separate branches. If you're working on a fix, create your branch from the oldest release - branch having the bug. See :ref:`Which Salt Branch?`. + branch having the bug. See :ref:`Which Salt Branch? `. .. code-block:: bash @@ -155,13 +157,15 @@ Fork a Repo Guide_>`_ and is well worth reading. Test progress and results can be found at http://jenkins.saltstack.com/. +.. _which-salt-branch: + Which Salt branch? ================== GitHub will open pull requests against Salt's main branch, ``develop``, by default. Ideally features should go into ``develop`` and bug fixes should go into the oldest supported release branch affected by the bug. See -:ref:`Sending a GitHub pull request`. +:ref:`Sending a GitHub pull request `. If you have a bug fix and have already forked your working branch from ``develop`` and do not know how to rebase your commits against another branch, @@ -355,8 +359,8 @@ Issue and Pull Request Labeling System ====================================== SaltStack uses several labeling schemes to help facilitate code contributions -and bug resolution. See the :doc:`` documentation for -more information. +and bug resolution. See the :ref:`Labels and Milestones +` documentation for more information. .. _`saltstack/salt`: https://github.com/saltstack/salt .. _`GitHub Fork a Repo Guide`: https://help.github.com/articles/fork-a-repo diff --git a/doc/topics/development/hacking.rst b/doc/topics/development/hacking.rst index b8c5e85bd8..5402417bbf 100644 --- a/doc/topics/development/hacking.rst +++ b/doc/topics/development/hacking.rst @@ -288,5 +288,5 @@ Issue and Pull Request Labeling System -------------------------------------- SaltStack uses several labeling schemes to help facilitate code contributions -and bug resolution. See the :doc:`` documentation for -more information. +and bug resolution. See the :ref:`Labels and Milestones +` documentation for more information. From 87adca46e055256d70ede0734ea64e0536a67654 Mon Sep 17 00:00:00 2001 From: Thomas Jackson Date: Thu, 25 Jun 2015 09:06:33 -0700 Subject: [PATCH 14/33] Fix memory leak in saltnado Fixes #24846 If an event was checked after the request was closed out it was possible for requests to get into the event_listener's mapping and never be cleaned out. This fixes the leak by checking if the request is open or not before adding it to the mappings. --- salt/netapi/rest_tornado/saltnado.py | 18 +++++++++++++++++- .../netapi/rest_tornado/test_app.py | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/salt/netapi/rest_tornado/saltnado.py b/salt/netapi/rest_tornado/saltnado.py index 6c6a46fa5a..6f2347dbc5 100644 --- a/salt/netapi/rest_tornado/saltnado.py +++ b/salt/netapi/rest_tornado/saltnado.py @@ -267,7 +267,8 @@ class EventListener(object): # request_obj -> list of (tag, future) self.request_map = defaultdict(list) - self.timeout_map = {} # map of future -> timeout_callback + # map of future -> timeout_callback + self.timeout_map = {} self.stream = zmqstream.ZMQStream(self.event.sub, io_loop=tornado.ioloop.IOLoop.current()) @@ -280,7 +281,15 @@ class EventListener(object): if request not in self.request_map: return for tag, future in self.request_map[request]: + # timeout the future self._timeout_future(tag, future) + # remove the timeout + if future in self.timeout_map: + tornado.ioloop.IOLoop.current().remove_timeout(self.timeout_map[future]) + del self.timeout_map[future] + + del self.request_map[request] + def get_event(self, request, @@ -291,6 +300,13 @@ class EventListener(object): ''' Get an event (async of course) return a future that will get it later ''' + # if the request finished, no reason to allow event fetching, since we + # can't send back to the client + if request._finished: + future = Future() + future.set_exception(TimeoutException()) + return future + future = Future() if callback is not None: def handle_future(future): diff --git a/tests/integration/netapi/rest_tornado/test_app.py b/tests/integration/netapi/rest_tornado/test_app.py index a23d3e9c19..ff1f880fb1 100644 --- a/tests/integration/netapi/rest_tornado/test_app.py +++ b/tests/integration/netapi/rest_tornado/test_app.py @@ -581,6 +581,7 @@ class TestWebhookSaltAPIHandler(SaltnadoTestCase): self.assertIn('headers', event['data']) self.assertEqual(event['data']['post'], {'foo': 'bar'}) # get an event future + self._finished = False # TODO: remove after some cleanup of the event listener event = self.application.event_listener.get_event(self, tag='salt/netapi/hook', callback=verify_event, From 80c24be4fec66f368f7f52abbdc69050dc59bab5 Mon Sep 17 00:00:00 2001 From: "Gareth J. Greenaway" Date: Thu, 25 Jun 2015 09:15:52 -0700 Subject: [PATCH 15/33] Fixing an issue with the import_key method. Different results depending on which gnupg python module is installed. --- salt/modules/gpg.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/salt/modules/gpg.py b/salt/modules/gpg.py index 4301ec9dba..9b6e061f56 100644 --- a/salt/modules/gpg.py +++ b/salt/modules/gpg.py @@ -611,23 +611,29 @@ def import_key(user=None, raise SaltInvocationError('filename does not exist.') imported_data = gpg.import_keys(text) - log.debug('imported_data {0}'.format(imported_data.__dict__.keys())) - log.debug('imported_data {0}'.format(imported_data.counts)) - - if imported_data.counts: - if imported_data.counts['imported'] or imported_data.counts['imported_rsa']: + if GPG_1_3_1: + counts = imported_data.counts + if counts.get('imported') or counts.get('imported_rsa'): ret['message'] = 'Successfully imported key(s).' - elif imported_data.counts['unchanged']: + elif counts.get('unchanged'): ret['message'] = 'Key(s) already exist in keychain.' - elif imported_data.counts['not_imported']: + elif counts.get('not_imported'): ret['res'] = False ret['message'] = 'Unable to import key.' - elif not imported_data.counts['count']: + elif not counts.get('count'): ret['res'] = False ret['message'] = 'Unable to import key.' else: - ret['res'] = False - ret['message'] = 'Unable to import key.' + if imported_data.imported or imported_data.imported_rsa: + ret['message'] = 'Successfully imported key(s).' + elif imported_data.unchanged: + ret['message'] = 'Key(s) already exist in keychain.' + elif imported_data.not_imported: + ret['res'] = False + ret['message'] = 'Unable to import key.' + elif not imported_data.count: + ret['res'] = False + ret['message'] = 'Unable to import key.' return ret From 48b5e1653eb87f5d60eaf8b6837590dc9d23933f Mon Sep 17 00:00:00 2001 From: Thomas Jackson Date: Thu, 25 Jun 2015 10:13:08 -0700 Subject: [PATCH 16/33] pylint --- salt/netapi/rest_tornado/saltnado.py | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/netapi/rest_tornado/saltnado.py b/salt/netapi/rest_tornado/saltnado.py index 6f2347dbc5..94b5e23edf 100644 --- a/salt/netapi/rest_tornado/saltnado.py +++ b/salt/netapi/rest_tornado/saltnado.py @@ -290,7 +290,6 @@ class EventListener(object): del self.request_map[request] - def get_event(self, request, tag='', From 55eb73b0c9a2914e259ff4913a92b940b341782d Mon Sep 17 00:00:00 2001 From: "Gareth J. Greenaway" Date: Thu, 25 Jun 2015 11:33:36 -0700 Subject: [PATCH 17/33] fixing unit tests. --- salt/modules/gpg.py | 7 ++++++- tests/unit/modules/gpg_test.py | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/salt/modules/gpg.py b/salt/modules/gpg.py index 9b6e061f56..b3ef517d48 100644 --- a/salt/modules/gpg.py +++ b/salt/modules/gpg.py @@ -210,7 +210,6 @@ def list_keys(user=None): salt '*' gpg.list_keys ''' - log.debug('GPG_1_3_1 {0}'.format(GPG_1_3_1)) _keys = [] for _key in _list_keys(user): tmp = {} @@ -611,6 +610,12 @@ def import_key(user=None, raise SaltInvocationError('filename does not exist.') imported_data = gpg.import_keys(text) + + # include another check for Salt unit tests + gnupg_version = distutils.version.LooseVersion(gnupg.__version__) + if gnupg_version >= '1.3.1': + GPG_1_3_1 = True + if GPG_1_3_1: counts = imported_data.counts if counts.get('imported') or counts.get('imported_rsa'): diff --git a/tests/unit/modules/gpg_test.py b/tests/unit/modules/gpg_test.py index a787853f08..8bc6065212 100644 --- a/tests/unit/modules/gpg_test.py +++ b/tests/unit/modules/gpg_test.py @@ -37,7 +37,7 @@ RET = [{'created': '2014-07-25', class Mockgnupg(object): ''' - Mock smtplib class + Mock gnupg class ''' __version__ = '1.3.1' fingerprint = u'F321F' @@ -50,7 +50,7 @@ class Mockgnupg(object): class GPG(object): ''' - Mock smtplib class + Mock gnupg class ''' def __init__(self, gnupghome='/tmp/salt/.gnupg', homedir='/tmp/salt/.gnupg'): From c8514de3341d07ad7dfcd5b08fa9079477eec589 Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Thu, 25 Jun 2015 14:55:14 -0700 Subject: [PATCH 18/33] Fix update of undefined env var in npm module --- salt/modules/npm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/salt/modules/npm.py b/salt/modules/npm.py index 75a72cfd70..8ef0cc8ff2 100644 --- a/salt/modules/npm.py +++ b/salt/modules/npm.py @@ -119,6 +119,9 @@ def install(pkg=None, elif pkgs: cmd += ' "{0}"'.format('" "'.join(pkgs)) + if env is None: + env = {} + if runas: uid = salt.utils.get_uid(runas) if uid: @@ -188,6 +191,9 @@ def uninstall(pkg, ''' + if env is None: + env = {} + if runas: uid = salt.utils.get_uid(runas) if uid: @@ -245,6 +251,9 @@ def list_(pkg=None, ''' + if env is None: + env = {} + if runas: uid = salt.utils.get_uid(runas) if uid: From 6b544227ab0421537434b064c39c03bb4b7a7ec9 Mon Sep 17 00:00:00 2001 From: rallytime Date: Thu, 25 Jun 2015 16:00:33 -0600 Subject: [PATCH 19/33] Only warn about digital ocean deprecation if digital ocean is configured --- salt/cloud/clouds/digital_ocean.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/salt/cloud/clouds/digital_ocean.py b/salt/cloud/clouds/digital_ocean.py index 156b852307..8569dbf089 100644 --- a/salt/cloud/clouds/digital_ocean.py +++ b/salt/cloud/clouds/digital_ocean.py @@ -81,19 +81,22 @@ def get_configured_provider(): ''' Return the first configured instance. ''' - warn_until( - 'Beryllium', - 'The digital_ocean driver is deprecated and will be removed in Salt Beryllium. ' - 'Please convert your digital ocean provider configs to use the digital_ocean_v2 ' - 'driver.' - ) - - return config.is_provider_configured( + configuration = config.is_provider_configured( __opts__, __active_provider_name__ or 'digital_ocean', ('api_key',) ) + if configuration: + warn_until( + 'Beryllium', + 'The digital_ocean driver is deprecated and will be removed in Salt Beryllium. ' + 'Please convert your digital ocean provider configs to use the digital_ocean_v2 ' + 'driver.' + ) + + return configuration + def avail_locations(call=None): ''' From 6fde58182fbfa91318b613e572f102226f5d8e94 Mon Sep 17 00:00:00 2001 From: Ryan Lane Date: Thu, 25 Jun 2015 15:21:37 -0700 Subject: [PATCH 20/33] Try byte literals rather than unicode strings in the env --- salt/modules/npm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/salt/modules/npm.py b/salt/modules/npm.py index 8ef0cc8ff2..815ce49fc3 100644 --- a/salt/modules/npm.py +++ b/salt/modules/npm.py @@ -125,7 +125,7 @@ def install(pkg=None, if runas: uid = salt.utils.get_uid(runas) if uid: - env.update({'SUDO_UID': uid, 'SUDO_USER': ''}) + env.update({'SUDO_UID': b'{0}'.format(uid), 'SUDO_USER': b''}) result = __salt__['cmd.run_all'](cmd, python_shell=False, cwd=dir, runas=runas, env=env) @@ -197,7 +197,7 @@ def uninstall(pkg, if runas: uid = salt.utils.get_uid(runas) if uid: - env.update({'SUDO_UID': uid, 'SUDO_USER': ''}) + env.update({'SUDO_UID': b'{0}'.format(uid), 'SUDO_USER': b''}) cmd = 'npm uninstall' @@ -257,7 +257,7 @@ def list_(pkg=None, if runas: uid = salt.utils.get_uid(runas) if uid: - env.update({'SUDO_UID': uid, 'SUDO_USER': ''}) + env.update({'SUDO_UID': b'{0}'.format(uid), 'SUDO_USER': b''}) cmd = 'npm list --silent --json' From d47a448a801230a8ce9e71dd587c65c529a7690e Mon Sep 17 00:00:00 2001 From: Heewa Barfchin Date: Thu, 25 Jun 2015 22:11:15 -0400 Subject: [PATCH 21/33] Don't modify empty change --- salt/states/pkg.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/salt/states/pkg.py b/salt/states/pkg.py index 3c334c318a..6599a6447d 100644 --- a/salt/states/pkg.py +++ b/salt/states/pkg.py @@ -1038,14 +1038,15 @@ def installed( if modified_hold: for i in modified_hold: - comment.append(i['comment']) change_name = i['name'] - if len(changes[change_name]['new']) > 0: - changes[change_name]['new'] += '\n' - changes[change_name]['new'] += '{0}'.format(i['changes']['new']) - if len(changes[change_name]['old']) > 0: - changes[change_name]['old'] += '\n' - changes[change_name]['old'] += '{0}'.format(i['changes']['old']) + if change_name in changes: + comment.append(i['comment']) + if len(changes[change_name]['new']) > 0: + changes[change_name]['new'] += '\n' + changes[change_name]['new'] += '{0}'.format(i['changes']['new']) + if len(changes[change_name]['old']) > 0: + changes[change_name]['old'] += '\n' + changes[change_name]['old'] += '{0}'.format(i['changes']['old']) # Any requested packages that were not targeted for install or reinstall if not_modified: From 9ae0c78ffcb070b43d45e96b7ac0ca3c07c3cad3 Mon Sep 17 00:00:00 2001 From: Heewa Barfchin Date: Thu, 25 Jun 2015 23:28:01 -0400 Subject: [PATCH 22/33] Don't try to cache a template when it's not a file --- salt/modules/file.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/salt/modules/file.py b/salt/modules/file.py index 01af8b8754..3d6127bc2a 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -2799,8 +2799,9 @@ def get_managed( ' source file {0}').format(source) # if the file is a template we need to actually template the file to get - # a checksum, but we can cache the template itselt - if template: + # a checksum, but we can cache the template itself, but only if there is + # a template source (it could be a templated contents) + if template and source: # check if we have the template cached template_dest = __salt__['cp.is_cached'](source, saltenv) if template_dest: From bb0a6d56254f15e8b29c9055f46dce7b457e02dc Mon Sep 17 00:00:00 2001 From: Jayesh Kariya Date: Fri, 26 Jun 2015 13:06:53 +0530 Subject: [PATCH 23/33] adding states/supervisord unit test case. --- tests/unit/states/supervisord_test.py | 102 ++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/unit/states/supervisord_test.py diff --git a/tests/unit/states/supervisord_test.py b/tests/unit/states/supervisord_test.py new file mode 100644 index 0000000000..ff38a8862c --- /dev/null +++ b/tests/unit/states/supervisord_test.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +''' + :codeauthor: :email:`Jayesh Kariya ` +''' +# Import Python libs +from __future__ import absolute_import + +# Import Salt Testing Libs +from salttesting import skipIf, TestCase +from salttesting.mock import ( + NO_MOCK, + NO_MOCK_REASON, + MagicMock, + patch +) + +from salttesting.helpers import ensure_in_syspath + +ensure_in_syspath('../../') + +# Import Salt Libs +from salt.states import supervisord + +supervisord.__salt__ = {} +supervisord.__opts__ = {} + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +class SupervisordTestCase(TestCase): + ''' + Test cases for salt.states.supervisord + ''' + # 'running' function tests: 1 + + def test_running(self): + ''' + Test to ensure the named service is running. + ''' + name = 'wsgi_server' + + ret = {'name': name, + 'changes': {}, + 'result': True, + 'comment': ''} + + comt = ('Supervisord module not activated.' + ' Do you need to install supervisord?') + ret.update({'comment': comt, 'result': False}) + self.assertDictEqual(supervisord.running(name), ret) + + mock = MagicMock(return_value={name: {'state': 'running'}}) + with patch.dict(supervisord.__salt__, {'supervisord.status': mock}): + with patch.dict(supervisord.__opts__, {'test': True}): + comt = ('Service wsgi_server is already running') + ret.update({'comment': comt, 'result': True}) + self.assertDictEqual(supervisord.running(name), ret) + + with patch.dict(supervisord.__opts__, {'test': False}): + comt = ('Not starting already running service: wsgi_server') + ret.update({'comment': comt}) + self.assertDictEqual(supervisord.running(name), ret) + + # 'dead' function tests: 1 + + def test_dead(self): + ''' + Test to ensure the named service is dead (not running). + ''' + name = 'wsgi_server' + + ret = {'name': name, + 'changes': {}, + 'result': None, + 'comment': ''} + + with patch.dict(supervisord.__opts__, {'test': True}): + comt = ('Service {0} is set to be stopped'.format(name)) + ret.update({'comment': comt}) + self.assertDictEqual(supervisord.dead(name), ret) + + # 'mod_watch' function tests: 1 + + def test_mod_watch(self): + ''' + Test to always restart on watch. + ''' + name = 'wsgi_server' + + ret = {'name': name, + 'changes': {}, + 'result': None, + 'comment': ''} + + comt = ('Supervisord module not activated.' + ' Do you need to install supervisord?') + ret.update({'comment': comt, 'result': False}) + self.assertDictEqual(supervisord.mod_watch(name), ret) + + +if __name__ == '__main__': + from integration import run_tests + run_tests(SupervisordTestCase, needs_daemon=False) From d2f0d8fa96a0ec7648fee8005aabf91b0fdf2068 Mon Sep 17 00:00:00 2001 From: "Gareth J. Greenaway" Date: Fri, 26 Jun 2015 07:24:55 -0700 Subject: [PATCH 24/33] variable was referenced before assignment. Just removing the variable and checking the return from distutils.version.LooseVersion directly. --- salt/modules/gpg.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/salt/modules/gpg.py b/salt/modules/gpg.py index b3ef517d48..69cbd34e30 100644 --- a/salt/modules/gpg.py +++ b/salt/modules/gpg.py @@ -614,9 +614,6 @@ def import_key(user=None, # include another check for Salt unit tests gnupg_version = distutils.version.LooseVersion(gnupg.__version__) if gnupg_version >= '1.3.1': - GPG_1_3_1 = True - - if GPG_1_3_1: counts = imported_data.counts if counts.get('imported') or counts.get('imported_rsa'): ret['message'] = 'Successfully imported key(s).' From a3c1063a3773c1251e9c792bfddc53be169d6957 Mon Sep 17 00:00:00 2001 From: Trevor H Date: Wed, 27 May 2015 01:51:02 -0400 Subject: [PATCH 25/33] fix deprecated pymongo usage causing errors in latest pymongo --- salt/tops/mongo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/tops/mongo.py b/salt/tops/mongo.py index 83058e3443..fdaef38740 100644 --- a/salt/tops/mongo.py +++ b/salt/tops/mongo.py @@ -103,7 +103,7 @@ def top(**kwargs): environment_field = __opts__['master_tops']['mongo'].get('environment_field', 'environment') log.info('connecting to {0}:{1} for mongo ext_tops'.format(host, port)) - conn = pymongo.Connection(host, port) + conn = pymongo.MongoClient(host, port) log.debug('using database \'{0}\''.format(__opts__['mongo.db'])) mdb = conn[__opts__['mongo.db']] @@ -127,7 +127,7 @@ def top(**kwargs): ) ) - result = mdb[collection].find_one({id_field: minion_id}, fields=[states_field, environment_field]) + result = mdb[collection].find_one({id_field: minion_id}, projection=[states_field, environment_field]) if result and states_field in result: if environment_field in result: environment = result[environment_field] From be19a6730e64747def7d7a34f3879a0b1c6a0594 Mon Sep 17 00:00:00 2001 From: rallytime Date: Fri, 26 Jun 2015 11:05:04 -0600 Subject: [PATCH 26/33] Provide a less confusing error when cloud provider is misconfigured --- salt/cloud/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/salt/cloud/__init__.py b/salt/cloud/__init__.py index 1f4d19c8e5..0b1f33d5db 100644 --- a/salt/cloud/__init__.py +++ b/salt/cloud/__init__.py @@ -1514,8 +1514,12 @@ class Cloud(object): # Mis-configured provider that got removed? log.warn( 'The cloud driver, {0!r}, configured under the ' - '{1!r} cloud provider alias was not loaded since ' - '\'{2}()\' could not be found. Removing it from ' + '{1!r} cloud provider alias, could not be loaded. ' + 'Please check your provider configuration files and ' + 'ensure you have all required dependencies installed ' + 'for the {0!r} driver.\n' + 'In rare cases, this could indicate the \'{2}()\' ' + 'function could not be found.\nRemoving {0!r} from ' 'the available providers list'.format( driver, alias, fun ) From 1e81a88625aeaec9e6d5cf584c5d98670e8df851 Mon Sep 17 00:00:00 2001 From: rallytime Date: Fri, 26 Jun 2015 11:07:04 -0600 Subject: [PATCH 27/33] Clean up --- salt/cloud/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/cloud/__init__.py b/salt/cloud/__init__.py index 0b1f33d5db..f75e170e90 100644 --- a/salt/cloud/__init__.py +++ b/salt/cloud/__init__.py @@ -1516,7 +1516,7 @@ class Cloud(object): 'The cloud driver, {0!r}, configured under the ' '{1!r} cloud provider alias, could not be loaded. ' 'Please check your provider configuration files and ' - 'ensure you have all required dependencies installed ' + 'ensure all required dependencies are installed ' 'for the {0!r} driver.\n' 'In rare cases, this could indicate the \'{2}()\' ' 'function could not be found.\nRemoving {0!r} from ' From f88f344a281a60ec209082ee43503f6699e0907f Mon Sep 17 00:00:00 2001 From: Jacob Hammons Date: Fri, 26 Jun 2015 11:13:56 -0600 Subject: [PATCH 28/33] sphinx html theme updates --- doc/_themes/saltstack2/layout.html | 201 +++--- doc/_themes/saltstack2/static/css/basic.css | 605 ----------------- doc/_themes/saltstack2/static/css/main.css | 545 --------------- .../saltstack2/static/css/pygments.css | 63 -- .../static/css/webhelp.min_v1.1.css | 256 ------- .../static/css/webhelp.min_v1.4.1.css | 384 +++++++++++ .../saltstack2/static/images/email.png | Bin 1703 -> 17851 bytes .../saltstack2/static/images/epub_icon.png | Bin 392 -> 0 bytes .../saltstack2/static/images/epub_icon.svg | 25 + .../saltstack2/static/images/github.png | Bin 1968 -> 24382 bytes .../saltstack2/static/images/linkedin.png | Bin 1762 -> 15303 bytes .../saltstack2/static/images/meetup.png | Bin 1822 -> 22314 bytes .../static/images/messenger-generic.png | Bin 1759 -> 17557 bytes .../saltstack2/static/images/pdf_icon.png | Bin 979 -> 0 bytes .../saltstack2/static/images/pdf_icon.svg | 634 ++++++++++++++++++ .../saltstack2/static/images/reddit.png | Bin 1812 -> 26050 bytes .../images/saltStack_enterprise_350x125.jpg | Bin 0 -> 22331 bytes .../static/images/saltstack_logo.png | Bin 5034 -> 0 bytes .../saltstack2/static/images/sse-4-gui.png | Bin 20351 -> 0 bytes .../static/images/stackoverflow.png | Bin 1823 -> 20854 bytes .../saltstack2/static/images/twitter.png | Bin 1796 -> 20051 bytes .../static/images/youtube-variation.png | Bin 1620 -> 15325 bytes .../saltstack2/static/js/bootstrap.min.js | 12 - .../js/{webhelp.min_v1.1.js => core.min.js} | 181 +---- .../saltstack2/static/js/webhelp.min_v1.4.js | 191 ++++++ 25 files changed, 1347 insertions(+), 1750 deletions(-) delete mode 100644 doc/_themes/saltstack2/static/css/basic.css delete mode 100644 doc/_themes/saltstack2/static/css/main.css delete mode 100644 doc/_themes/saltstack2/static/css/pygments.css delete mode 100644 doc/_themes/saltstack2/static/css/webhelp.min_v1.1.css create mode 100644 doc/_themes/saltstack2/static/css/webhelp.min_v1.4.1.css mode change 100644 => 100755 doc/_themes/saltstack2/static/images/email.png delete mode 100644 doc/_themes/saltstack2/static/images/epub_icon.png create mode 100644 doc/_themes/saltstack2/static/images/epub_icon.svg delete mode 100644 doc/_themes/saltstack2/static/images/pdf_icon.png create mode 100644 doc/_themes/saltstack2/static/images/pdf_icon.svg create mode 100644 doc/_themes/saltstack2/static/images/saltStack_enterprise_350x125.jpg delete mode 100644 doc/_themes/saltstack2/static/images/saltstack_logo.png delete mode 100644 doc/_themes/saltstack2/static/images/sse-4-gui.png delete mode 100755 doc/_themes/saltstack2/static/js/bootstrap.min.js rename doc/_themes/saltstack2/static/js/{webhelp.min_v1.1.js => core.min.js} (71%) create mode 100644 doc/_themes/saltstack2/static/js/webhelp.min_v1.4.js diff --git a/doc/_themes/saltstack2/layout.html b/doc/_themes/saltstack2/layout.html index 57b32f93d8..bf8d487710 100644 --- a/doc/_themes/saltstack2/layout.html +++ b/doc/_themes/saltstack2/layout.html @@ -19,18 +19,14 @@ {%- set titlesuffix = "" %} {%- endif %} - {% set script_files = [ - '_static/js/webhelp.min_v1.1.js', - '_static/js/bootstrap.min.js', + '_static/js/core.min.js', + '_static/js/webhelp.min_v1.4.js', ] %} {% set css_files = [ -'_static/css/core.min.css', -'_static/css/webhelp.min_v1.1.css', -'_static/css/pygments.css', -'_static/css/basic.css', -'_static/css/main.css', + '_static/css/core.min.css', + '_static/css/webhelp.min_v1.4.1.css', ] %} {%- macro relbar() %} @@ -69,14 +65,10 @@ {%- macro css() %} {%- for cssfile in css_files %} - - - + {%- endfor %} - {%- endmacro %} - @@ -93,23 +85,14 @@ {{ css() }} + {%- if favicon %} + + {%- endif %} + - {%- if not embedded %} - {{ script() }} - {%- if use_opensearch %} - - {%- endif %} - - {%- if favicon %} - - {%- endif %} - {%- endif %} - {%- block linktags %} {%- if hasdoc('about') %} @@ -134,11 +117,6 @@ {%- endif %} {%- endblock %} - - {%- block extrahead %} {% endblock %} - - {%- block analytics %} - {% endblock %} @@ -146,88 +124,20 @@

You are using an outdated browser. Please upgrade your browser.

- - {%- block content %} - -
- - -
- + {% if build_type == "develop" and on_saltstack %} +
+ +
+ {% endif %} + {%- block document %} +
{% block body %} {% endblock %} +
{%- endblock %} {%- if prev %} {%- endif %} - {%- if next %} @@ -260,7 +177,6 @@
- {%- block footer %}
-

Get Started

-

New to SaltStack? Try our new Get Started Guide.

+ + + +

SaltStack Training

Now offering remote attendee training!

@@ -299,9 +217,82 @@
+ + + +
{%- endblock %} + + {%- if not embedded %} + {{ script() }} + {%- if use_opensearch %} + + {%- endif %} + {%- endif %} + {% if on_saltstack %} + diff --git a/doc/_themes/saltstack2/static/css/basic.css b/doc/_themes/saltstack2/static/css/basic.css deleted file mode 100644 index 267be39e1e..0000000000 --- a/doc/_themes/saltstack2/static/css/basic.css +++ /dev/null @@ -1,605 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text { -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -/*dt:target, .highlighted { - background-color: #fbe54e; -}*/ - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; - width:100%; -} - -td.code { - width: 100%; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -div.code-block-caption { - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; -} - -/*code.descname { - background-color: transparent; - font-weight: bold; - *//*font-size: 1.2em;*//* - font-size: 1.5em; -} - -code.descclassname { - background-color: transparent; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -}*/ - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/doc/_themes/saltstack2/static/css/main.css b/doc/_themes/saltstack2/static/css/main.css deleted file mode 100644 index 8989306855..0000000000 --- a/doc/_themes/saltstack2/static/css/main.css +++ /dev/null @@ -1,545 +0,0 @@ - - -/* ========================================================================== -Author's custom styles -========================================================================== */ -/*html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -ms-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - transition: all 0.2s ease; -} -body { - font-family: 'Open Sans', sans-serif; -} -.navbar .nav { - float:right; - margin: 0; - padding-top: 18px; -} -.navbar-inverse .brand, .navbar-inverse .nav > li > a { - color: #484c51; - font: 14px/24px 'Open Sans'; - font-weight: 200; -} -.navbar .nav li.currentNav { - background: url(../img/navCurrentArrow.png) center 32px no-repeat; -} -.hero-unit { - margin-bottom: 0; -} -.shaded { - background: #f7f9f8; -} -.shaded img { - margin: 8px 12px; -} -.articleCredits { - padding-left: 12px; - font: 12px/24px 'Open Sans'; - font-weight: 100; - white-space: pre; -} -.fullwidth { - padding: 30px; -} -body.contact .shaded img { - margin: 0; -} -.map img { - margin-top: 30px; - float: left; -} -body.index .success, body.index .clients { - margin-top: 0; -} -.success h2 { - margin-top: 25px; -} -.testimonialAuthor { - display: block; - margin-bottom: 30px; - font: 12px/24px 'Open Sans'; - color: #aa2b39; - font-weight: 800; - text-transform: uppercase; -} -.success hr, .events hr, .productnews hr { - margin-top: 0; -} -.clients { - background-color: #415a72; -} -.clients img { - margin: 15px 21px; -} -.news { - margin-bottom: 40px; -} -h2.homeSecTitles { - color: #8d9caa; - font-style: italic; - font-family: 'Open Sans'; - font-weight: 800; - text-transform: capitalize; - margin-bottom: 0; -} -.success h3 { - font-weight: 100; - font-style: italic; - font: 18px/30px 'Open Sans'; - color: #4f575b; margin: 25px 0; -} -.success img { - margin: 30px 10px 10px 80px; -} -.about img { - margin-bottom: 21px; -} -.carousel-inner { - max-height: 387px; -} -.carousel-control { - opacity: 1; - background: none; - border: none; - border-radius: 0; -} -.carousel-caption h1 { - text-transform:uppercase; - margin-top: 20px; - display:none; -} -.carousel-caption p { - margin-top: 25px; - font-weight: 100; - font: 16px/24px 'Open Sans'; - color: #000; - display: none; -} -.carousel-caption img { - margin-top: 10px; -} -#myCarousel img { - width: 100%; - height: auto; -} -#myCarousel .carousel-control img { - width: auto; -} - -h1, h2, h3, h4, h5, h6 { - font-weight: 100; - font-family: 'Open Sans'; - font-weight: normal; -} - -h2 { - font: 18px/28px 'Open Sans'; - text-transform: uppercase; - font-weight: 800; - color: #373e4b; - margin-bottom: 0; -} -h3 { - font-size: 16px; line-height:26px; -} -p { - font-size: 14px; line-height: 24px; color: #313131; -} -.lede { - text-align: center; - margin-bottom:20px; - max-width: 80%; - margin-left: 10%; -} -body.services .lede { - max-width: 95%; - margin-left: 2.5%; - margin-top: 30px; -} -body.products .lede { - margin-top: 30px; -} -.lede h3 { - font-weight: 100; - font: 24px/30px 'Open Sans'; - color: #aa2b39; -} -.lede h4 { - font-weight: 100; - font-style: italic; - font: 20px/30px 'Open Sans'; - color: #373e4b; -} -body.services .lede h4 { - font-size: 16px; - line-height: 150%; -} -body.services .lede { - margin-bottom: 30px; -} -body.about h1, body.services h1, body.contact h1 { - font: 20px/30px 'Open Sans'; - font-style: italic; - font-weight: 800; - color: #4f575b; - margin-top: 0; -} -.row-fluid { - margin-top: 50px; -} -body.about h6 { - margin: 0; - font-weight: 100; - font-style: italic; - font-family: 'Open Sans'; - text-transform: uppercase; - line-height: 80%; - margin-bottom: 10px; - color: #AA2B39; -} -body.services table { - margin: 0; - padding: 0; - table-layout: fixed; -} -body.services table th, body.services table td { - padding: 10px 0; - text-align: left; -} -body.services table td { - color: #373e4b; - font-style: italic; - font-weight: 100; - font-family: 'Open Sans'; - width: 206px; -} -body.services table tr:last-child th, body.services table tr:last-child td { - border-bottom: none; -} -body.services table tr:nth-child(even) { - background: #eff3f1; -} -body.services table td:first-child { - padding-left: 30px; -} -body.services table td.tableCenter { - text-align: center; -} -.singleProduct ul { - margin-left: 15px; -} -.singleProduct li { - padding: 5px 0; -} -.btn-red { - display:block; - padding: 5px 0; - background: #aa2b39; - color: #FFF; - font-style: italic; - font-weight: 100; - font-family: 'Open Sans'; - text-shadow: none; - border: none; - border-radius: 0; - box-shadow: none; - width: 100px; - margin-left: 75px; -} -.btn-red:hover, .bth-red:focus { - background-color: #9B1C2E; - color: white; -} -body.contact .btn-red { - margin-left: 0; margin-top: 5px; -} -#myCarousel .btn-red { - margin-left: 12px; margin-top:-7px; -} -.map { - border: 0; border-right: 1px solid #eee; -} -.map h2, .connect h2 { - margin: 0; -} -.map img { - padding-right: 30px; -} -.connect a { - margin: 0 8px 0 0; display: block; float: left; -} -.connect a img:hover { - margin-top: -5px; - -webkit-transition: margin 0.2s ease-out; - -moz-transition: margin 0.2s ease-out; - -o-transition: margin 0.2s ease-out; - transition: margin 0.2s ease-out; -} - -footer { - background: url(../images/footerBG.jpg) 50% 0 no-repeat; - min-height: 340px; - margin-top: 50px; - position:relative; - -webkit-background-size: cover; *//*for webKit*//* - -moz-background-size: cover; *//*Mozilla*//* - -o-background-size: cover; *//*opera*//* - background-size: cover; *//*generic*//* -} -footer p, footer a { - color: #FFF; - font-weight: 100; - font: 12px 'Open Sans'; -} -footer a { - display:block; - float: left; - margin: 0 0 6px 0; - clear: left; -} -footer .row-fluid { - margin-top: 30px; -} -.footerCol { - width: 20%; - float:left; -} -.footerCol h4 { - color: #FFF; - font-weight: 800; - font: 14px/24px 'Open Sans'; - text-transform: uppercase; - margin-bottom: 0; -} -footer .social a { - clear: none; - margin: 0 4px; -} -footer .social img:hover { - margin-top: -5px; - -webkit-transition: margin 0.2s ease-out; - -moz-transition: margin 0.2s ease-out; - -o-transition: margin 0.2s ease-out; - transition: margin 0.2s ease-out; -} -body.contact footer, body.index footer { - margin-top: 0; -} -.news img { - max-width: 275px; - height: auto; -} -.news h2, .news p, .events hr { - max-width: 275px; -} -.productnews hr { - max-width: 595px; -}*/ - -/* ========================================================================== -Sphinx custom styles -========================================================================== */ - -h1:hover > .headerlink, -h2:hover > .headerlink, -h3:hover > .headerlink, -h4:hover > .headerlink, -h5:hover > .headerlink, -h6:hover > .headerlink, -dt:hover > .headerlink { visibility: visible; } - -.sidebar .toctree-l1.current a { - border-right: 5px solid #fcaf3e; -} -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} -div.header div.rel a { - color: #fcaf3e; - letter-spacing: .1em; - text-transform: uppercase; -} -.descname { - font-weight: bold; -} -/*.literal { - background-color: #eeeeec; -}*/ -blockquote { - margin: 1em; -} -/*.footer, .footer a { - color: #888a85; -}*/ -div.admonition { - font-size: 0.9em; - margin: 1em 0 1em 0; - padding: 0.5em 1em 0.5em 1em; - border: 1px solid #ddd; -} -div.admonition p.admonition-title { - font-weight: bold; color: #3465a4; -} -div.warning { - border-color: #940000; -} -div.warning p.admonition-title { - color: #940000; -} -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} - -/* ========================================================================== -SaltStack custom styles -========================================================================== */ - -.lit-docs { - list-style-type: none; - margin: 0; -} - -.lit-item { - padding-bottom: 2em; -} - -.lit-annotation, -.lit-content { - display: inline-block; - vertical-align: top; -} - -.lit-annotation { - width: 40.42553191489362%; /* span-5 */ -} - -.lit-content { - width: 57.44680851063829%; /* span-7 */ -} - -/* Override a few Bootstrap-isms */ - -.lit-annotation pre, -.lit-content pre { - word-break: normal; - word-wrap: normal; - white-space: pre; - overflow-x: auto; -} - -.lit-content pre { - border: none; -} - -.lit-container { - position: relative; -} - -.lit-background { - position: absolute; - top: -1px; - bottom: 0; - right: 1.1em; - width: 57.44680851063829%; /* span-7 */ - - z-index: -1; - background-color: #f5f5f5; - - border: 1px solid #e5e5ee; - border: 1px solid rgba(0, 0, 0, 0.15); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -/* rST automatically puts the .container class on ``.. container`` directives -* which conflicts with the bootstrap class of the same name. >.< -*/ - -.scrollable.container { - width: auto; -} - -.scrollable { - overflow-x:auto; - position:relative; -} - -/* Code blocks */ - -/*pre { - position: relative; - border-top-width: 4px; - padding-top: 18px; *//* :before height *//* -}*/ - -.highlight-bash, -.highlight-jinja, -.highlight-python, -.highlight-yaml { - position: relative; -} -.highlight-bash:before, -.highlight-jinja:before, -.highlight-python:before, -.highlight-yaml:before { - z-index: 10; - font-size: 9px; - padding: 0.1em 0.8em; - text-align: center; - color: #999; - display: block; - position: absolute; - border-radius: 0 3px 0 3px; - border-top: none; - border-right: none; - background-color: #f1f1f1; - top: 0; - right: 0; - height: 18px; -} -.highlight-bash pre { - /* bit more subdued ... */ - border-color: #999; -} -.highlight-jinja pre { - border-color: #e00a1b; -} -.highlight-python pre { - border-color: #3377b0; -} -.highlight-yaml pre { - border-color: #ccc; -} -.highlight-bash:before { - content: 'BASH'; - background-color: #444; - color: white; -} -.highlight-jinja:before { - content: 'JINJA'; - background-color: #e00a1b; - color: white; -} -.highlight-python:before { - content: 'PYTHON'; - background-color: #3377b0; - color: #ffe243; -} -.highlight-yaml:before { - content: 'YAML'; - background-color: #ccc; - color: black; -} diff --git a/doc/_themes/saltstack2/static/css/pygments.css b/doc/_themes/saltstack2/static/css/pygments.css deleted file mode 100644 index 57eadc030e..0000000000 --- a/doc/_themes/saltstack2/static/css/pygments.css +++ /dev/null @@ -1,63 +0,0 @@ -.highlight .hll { background-color: #ffffcc } -.highlight { background: #eeffcc; } -.highlight .c { color: #408090; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ -.highlight .k { color: #007020; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ -.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #007020 } /* Comment.Preproc */ -.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ -.highlight .gd { color: #A00000 } /* Generic.Deleted */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #FF0000 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #333333 } /* Generic.Output */ -.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ -.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #007020 } /* Keyword.Pseudo */ -.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #902000 } /* Keyword.Type */ -.highlight .m { color: #208050 } /* Literal.Number */ -.highlight .s { color: #4070a0 } /* Literal.String */ -.highlight .na { color: #4070a0 } /* Name.Attribute */ -.highlight .nb { color: #007020 } /* Name.Builtin */ -.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ -.highlight .no { color: #60add5 } /* Name.Constant */ -.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ -.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ -.highlight .ne { color: #007020 } /* Name.Exception */ -.highlight .nf { color: #06287e } /* Name.Function */ -.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ -.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ -.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #bb60d5 } /* Name.Variable */ -.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #208050 } /* Literal.Number.Bin */ -.highlight .mf { color: #208050 } /* Literal.Number.Float */ -.highlight .mh { color: #208050 } /* Literal.Number.Hex */ -.highlight .mi { color: #208050 } /* Literal.Number.Integer */ -.highlight .mo { color: #208050 } /* Literal.Number.Oct */ -.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ -.highlight .sc { color: #4070a0 } /* Literal.String.Char */ -.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ -.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ -.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ -.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ -.highlight .sx { color: #c65d09 } /* Literal.String.Other */ -.highlight .sr { color: #235388 } /* Literal.String.Regex */ -.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ -.highlight .ss { color: #517918 } /* Literal.String.Symbol */ -.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ -.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ -.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ -.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/doc/_themes/saltstack2/static/css/webhelp.min_v1.1.css b/doc/_themes/saltstack2/static/css/webhelp.min_v1.1.css deleted file mode 100644 index d493475ad9..0000000000 --- a/doc/_themes/saltstack2/static/css/webhelp.min_v1.1.css +++ /dev/null @@ -1,256 +0,0 @@ -/*webhelp*/ - -body{font-family:"Lato",Helvetica,Arial,sans-serif;background-color:#fff;/*color:#1e2934;*/color:#676767} -.footer{padding-top:50px} -a{color:#428bca;text-decoration:none} -a:hover,a:focus{color:#2a6496;text-decoration:underline} -blockquote{font-size:15px} -button#dropdownMenu1{width:90%;padding:10px;margin:10px} -/*#menu-toggle{margin:10px 0}*/ -.panel-default>.panel-heading{background-color:#f8f8f2;border:1px solid #e3e3e3} -.well{background-color:#f5f5f5;border:1px solid #e3e3e3} -.nav>li>a{position:relative;display:block;padding:0} -#guide-links a,#guide-title{text-transform:uppercase;font-weight:300} -#guide-title,.well-title{text-transform:uppercase;font-weight:300} -img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic} -td img{max-width:none} -img.center{display:block;margin:auto} -.jumbotron h1{font-weight:300;text-transform:none} -.jumbotron{background-color:#171717;color:#fff;text-shadow:#000 .1em .1em .1em} -.jumbotron .glyphicon{color:#48b4fb;font-weight:100;;padding-right:10px;font-size:smaller} -.panel-title a{font-weight:300} -.panel-heading{padding:20px} -.panel-group a{text-decoration:none} -.list-group-item{border:none;padding-left:25px} -.list-group-item a{color:#333;display:list-item} -h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{text-transform:uppercase} -h1,.h1,h1 > code.docutils.literal{color:#48b4fb;font-size:40px;margin-top:10px;margin-bottom:30px} -h2,.h2,h2 > code.docutils.literal{color:#48b4fb;font-size:23px} -h3,.h3,h3 > code.docutils.literal{font-size:18px} -h4,.h4,h4 > code.docutils.literal{font-size:16px} -h5,.h5,h5 > code.docutils.literal{font-size:16px;font-style:italic} -.subhead{color:#C0392B;font-size:16px;text-transform:uppercase} -.reference h3{font-size:16pt;line-height:1.9;color:#D75400;;font-weight:300} -.head3 h2{font-size:21px;color:#C0392B} -.head4 h2{font-size:16px;color:#C0392B} -.btn-primary{color:#fff;background-color:#424242;border-color:#080808} -.btn-primary:hover{color:#fff;background-color:#424242;border-color:#080808} -.btn-secondary{color:#333;background-color:#f5f5f5;border-color:#ccc} -button#next-button{float:right;margin:15px 0 0 0} -button#prev-button{float:left;margin:15px 0 0 0} -.inner-addon{position:relative} -.inner-addon .glyphicon{position:absolute;padding:10px;pointer-events:none} -.glyphicon{color:#C0392B;;font-weight:100} -#next-button .glyphicon,#prev-button .glyphicon{color:#48b4fb} -.left-addon .glyphicon{padding:14px 0 0;left:10px} -.right-addon .glyphicon{padding:30px 0 0;right:5px} -.left-addon input{padding-left:30px} -.right-addon input{padding-right:30px} -#search-form{padding:5px 5px 10px} -#wrapper{padding-left:0;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease} -#wrapper.toggled{padding-left:250px} -#sidebar-wrapper{z-index:1000;position:fixed;right:250px;width:0;height:100%;margin-right:-240px;overflow-y:hidden;overflow-x:hidden;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease;background-color:#fff} -#sidebar-nav{position:absolute;top:0;width:250px;font-size:14px} -#wrapper.toggled #sidebar-wrapper{width:250px} -#page-content-wrapper{width:95%;padding:15px;font-size:15px;line-height:1.7} -#wrapper.toggled #page-content-wrapper{position:absolute;margin-left:-250px} -@media(min-width:768px) { - #wrapper{padding-right:250px} - #wrapper.toggled{padding-right:0} - #sidebar-wrapper{width:250px} - #wrapper.toggled #sidebar-wrapper{width:0} - #page-content-wrapper{padding:20px 0 0 0} - #wrapper.toggled #page-content-wrapper{position:relative;margin-right:0} - #menu-toggle{display:none!important} -} - -@media(min-width:992px) { - #wrapper{padding-right:300px} - #wrapper.toggled{padding-right:0} - #sidebar-wrapper{width:300px} - #sidebar-nav{width:300px} - #wrapper.toggled #sidebar-wrapper{width:0} - #page-content-wrapper{padding:20px 0 0 0} - #wrapper.toggled #page-content-wrapper{position:relative;margin-right:0} - #menu-toggle{display:none!important} -} - -@media(min-width:1200px) { - #wrapper{padding-right:350px} - #sidebar-wrapper{margin-right:-210px} - #wrapper.toggled{padding-right:0} - #sidebar-wrapper{width:350px} - #sidebar-nav{width:300px} - #wrapper.toggled #sidebar-wrapper{width:0} - #page-content-wrapper{padding:20px 0 0 0} - #wrapper.toggled #page-content-wrapper{position:relative;margin-right:0} - #menu-toggle{display:none!important} -} - -@media(min-width:1400px) { - #sidebar-wrapper{margin-right:-175px} - #menu-toggle{display:none!important} -} - -@media(max-width:768px) { - #sidebar-wrapper{border:1px solid #424242} -} -#header-nav{float:right;text-align:right} -#header-nav li {padding:0 0 15px 15px;font-weight:300} -#sidebar-nav ul{list-style:none;margin:0;padding:0} -#sidebar-nav .collapsed > ul{display:none} -#sidebar-nav .glyphicon{padding-left:5px;font-size:14px} -.nav>li>a:hover,.nav>li>a:focus{background-color:transparent} -#sidebar-nav li a{display:block;text-decoration:none;color:#424242;border-top:1px solid #e3e3e3;font-size:12px} -#sidebar-nav ul li:not(.tocify-item){padding-left:10px} -#sidebar-nav ul a{padding-top:5px;padding-bottom:5px} -#sidebar-nav > ul > .current{min-height:20px;padding:5px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)} -#sidebar-nav > ul > .current a{border:none} -#sidebar-nav .tocify li.current > a{font-weight:400;background:#48b4fb} -#sidebar-nav .tocify ul{list-style:circle} -#sidebar-nav .tocify li a{font-weight:400;font-size:14px;background-color:#34495E;padding-left:4px} -.tocify li a{display:block;text-decoration:none;color:#fff;border-bottom:none;font-size:14px;font-weight:300} -#tocify-header0 > li a{border-bottom:1px solid #2C3E50} -ul.tocify-subheader ul li{margin-left:20px} -#gen-links > li.current > .tocify > ul > li > a{font-weight:400;font-size:20px;background:transparent;border-bottom:none;border-top:none;color:#333} -#sidebar-nav li.current:not(.tocify-item) > a{font-weight:400;font-size:20px;border-bottom:none;border-top:none} -#gen-links{border-bottom:1px solid #e3e3e3} -#guide-links a{border-top:none;font-size:20px;color:#333} -#guide-links a:hover,a:focus{text-decoration:none} -li.current + li > a{border-top:none} -.reference.nested1{padding:5px;margin-bottom:40px;background-color:#FDFDFD;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)} -tr.sthead.prophead{color:#34495E;text-transform:uppercase} -aside{min-height:20px;padding:5px;border:1px solid #eee;background:rgba(255,255,255,0.5);border-radius:4px;width:95%;margin:0 auto;margin-bottom:20px;padding-left:50px;font-weight:300} -aside .glyphicon{font-size:20pt;float:left;margin-right:15px;height:100%;margin-left:-40px} -aside .title{text-transform:uppercase;color:#34495E} -aside .glyphicon{color:#F4C600} -.important .title{color:#D75400;font-weight:600} -.versionmodified{color:#009276} -#header-links{text-align: center;font-weight:300;padding-top:15px} -.versions{text-align: center;font-weight:300;border-top:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;padding:5px} -.permalink i{color:rgb(255, 255, 255);font-size:14pt;padding-left:5px} -.permalink i:hover{color:#000} -li.toctree-l3.current ul { - margin-left: 15px; -} -li.toctree-l2.current ul { - margin-left: 15px; -} -li.toctree-l1.current ul { - margin-left: 15px; -} - -.nav.nav-center { - margin:0; - float:none; -} - -ul.nav.collapsed{ - margin-left: 80px; - font-size: 14pt; - -} -#expanded-nav{ - font-size: 12pt; - font-weight:300; - ; -} - -#expanded-nav li{ - padding: 0 15px 0 0; -} - -ul.nav.collapsed li{ - padding: 0 0 15px 10px; - margin:0px; -} -#social-links{ - text-align: center; - padding-top: 10px; -} - -.navbar-default { - background-color: #fff; - border-color: #fff; -} -.navbar-header { - width: 100%; -} - -.open>.dropdown-menu { - width: 100%; -} -#lnav-title{ - font-weight:300; - ; - font-size:16pt; - text-align:center; -} - -pre { - border-top-width: 4px; - padding-top: 18px; :before height -} - -code { - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; - font-size: 12px; - color: #333333; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - white-space: nowrap; - background-color: rgba( 0, 0, 0, .1 ); -} - -code.xref { - color: #4070a0; -} - -code.descclassname { - background-color: transparent; - border: none; - -} - -code.descname { - background-color: transparent; - font-weight: bold; - /*font-size: 1.2em;*/ - font-size: 1.5em; -} - -dl.function { - margin-bottom:40px; - border-top: 1px solid #eee; - padding: 20px; -} - -#sidebar-nav li a.selected {font-weight:bold} - -#sidebar-nav a.current.reference.internal { - background-color: #424242; - color: #fff; - padding: 2px 4px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -#sidebar-nav a.current code { - color: #fff; - font-size: 14pt; - -} -.intro-text { - font-size: 18pt; - line-height: 1.3; - font-weight: 300; -} -img.logo { - margin-top: -10px; -} -img.nav-banner { - margin-top: 5px; -} - diff --git a/doc/_themes/saltstack2/static/css/webhelp.min_v1.4.1.css b/doc/_themes/saltstack2/static/css/webhelp.min_v1.4.1.css new file mode 100644 index 0000000000..67445d7a7e --- /dev/null +++ b/doc/_themes/saltstack2/static/css/webhelp.min_v1.4.1.css @@ -0,0 +1,384 @@ +body{font-family:"Lato",Helvetica,Arial,sans-serif;background-color:#fff;color:#676767} +.footer{padding-top:50px} +a{color:#428bca;text-decoration:none} +a:hover,a:focus{color:#2a6496;text-decoration:underline} +blockquote{font-size:15px} +button#dropdownMenu1{width:90%;padding:10px;margin:10px} +.panel-default>.panel-heading{background-color:#f8f8f2;border:1px solid #e3e3e3} +.well{background-color:#f5f5f5;border:1px solid #e3e3e3} +.nav>li>a{position:relative;display:block;padding:0} +#guide-links a,#guide-title{text-transform:uppercase;font-weight:300} +#guide-title,.well-title{text-transform:uppercase;font-weight:300} +.body-content img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic} +td img{max-width:none} +img.center{display:block;margin:auto} +.jumbotron h1{font-weight:300;text-transform:none} +.jumbotron{background-color:#171717;color:#fff;text-shadow:#000 .1em .1em .1em} +.jumbotron .glyphicon{color:#48b4fb;font-weight:100;padding-right:10px;font-size:smaller} +.panel-title a{font-weight:300} +.panel-heading{padding:20px} +.panel-group a{text-decoration:none} +.list-group-item{border:none;padding-left:25px} +.list-group-item a{color:#333;display:list-item} +h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{text-transform:uppercase} +h1,.h1,h1 > code.docutils.literal{color:#48b4fb;font-size:40px;margin-top:10px;margin-bottom:30px} +h2,.h2,h2 > code.docutils.literal{color:#48b4fb;font-size:23px} +h3,.h3,h3 > code.docutils.literal{font-size:18px} +h4,.h4,h4 > code.docutils.literal{font-size:16px} +h5,.h5,h5 > code.docutils.literal{font-size:16px;font-style:italic} +.subhead{color:#C0392B;font-size:16px;text-transform:uppercase} +.reference h3{font-size:16pt;line-height:1.9;color:#D75400;font-weight:300} +.head3 h2{font-size:21px;color:#C0392B} +.head4 h2{font-size:16px;color:#C0392B} +.btn-primary{color:#fff;background-color:#424242;border-color:#080808} +.btn-primary:hover{color:#fff;background-color:#424242;border-color:#080808} +.btn-secondary{color:#333;background-color:#f5f5f5;border-color:#ccc} +button#next-button{float:right;margin:15px 0 0} +button#prev-button{float:left;margin:15px 0 0} +.inner-addon{position:relative} +.inner-addon .glyphicon{position:absolute;padding:10px;pointer-events:none} +.glyphicon{color:#C0392B;font-weight:100} +#next-button .glyphicon,#prev-button .glyphicon{color:#48b4fb} +.left-addon .glyphicon{padding:14px 0 0;left:10px} +.right-addon .glyphicon{padding:30px 0 0;right:5px} +.left-addon input{padding-left:30px} +.right-addon input{padding-right:30px} +#search-form{padding:5px 5px 10px} +#wrapper{padding-left:0;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease} +#wrapper.toggled{padding-left:250px} +#sidebar-wrapper{z-index:1000;position:fixed;top:0;right:260px;width:0;height:100%;margin-right:-250px;overflow-y:hidden;overflow-x:hidden;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease;background-color:#fff} +#sidebar-nav{position:absolute;top:0;width:260px;font-size:14px} +#wrapper.toggled #sidebar-wrapper{width:260px} +#page-content-wrapper{width:95%;padding:15px;font-size:15px;line-height:1.7} +#wrapper.toggled #page-content-wrapper{position:absolute;margin-left:-250px} +#dev-notification{position:fixed;top:0;left:0;width:100%;background-color:#fff;text-align:center;z-index:20} +.alert.alert-warning.dev-notification-text{padding:0;margin-bottom:0;width:95%} +@media(min-width:768px) { + #wrapper{padding-right:260px} + #wrapper.toggled{padding-right:0} + #sidebar-wrapper{width:260px} + #wrapper.toggled #sidebar-wrapper{width:0} + #page-content-wrapper{padding:20px 0 0} + #wrapper.toggled #page-content-wrapper{position:relative;margin-right:0} + #menu-toggle{display:none!important} + .alert.alert-warning.dev-notification-text{width:65%} +} +@media(min-width:992px) { + #wrapper{padding-right:300px} + #wrapper.toggled{padding-right:0} + #sidebar-wrapper{width:300px} + #sidebar-nav{width:300px} + #wrapper.toggled #sidebar-wrapper{width:0} + #page-content-wrapper{padding:20px 0 0} + #wrapper.toggled #page-content-wrapper{position:relative;margin-right:0} + #menu-toggle{display:none!important} +} +@media(min-width:1200px) { + #wrapper{padding-right:350px} + #sidebar-wrapper{margin-right:-210px} + #wrapper.toggled{padding-right:0} + #sidebar-wrapper{width:350px} + #sidebar-nav{width:300px} + #wrapper.toggled #sidebar-wrapper{width:0} + #page-content-wrapper{padding:20px 0 0} + #wrapper.toggled #page-content-wrapper{position:relative;margin-right:0} + #menu-toggle{display:none!important} + .alert.alert-warning.dev-notification-text{width:68%} +} +@media(min-width:1400px) { + #sidebar-wrapper{margin-right:-175px} + #menu-toggle{display:none!important} + .alert.alert-warning.dev-notification-text{width:70%} +} +@media(max-width:768px) { + #sidebar-wrapper{border:1px solid #424242} +} +#header-nav{float:right;text-align:right} +#header-nav li{padding:0 0 15px 15px;font-weight:300} +#sidebar-wrapper{visibility:hidden} +#sidebar-nav ul{list-style:none;margin:0;padding:0} +#sidebar-nav .collapsed > ul{display:none} +#sidebar-nav .glyphicon{padding-left:5px;font-size:14px} +.nav>li>a:hover,.nav>li>a:focus{background-color:transparent} +#sidebar-nav li a{display:block;text-decoration:none;color:#424242;border-top:1px solid #e3e3e3;font-size:12px} +#sidebar-nav ul li:not(.tocify-item){padding-left:10px} +#sidebar-nav ul a{padding-top:5px;padding-bottom:5px} +#sidebar-nav > ul > .current{min-height:20px;padding:5px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)} +#sidebar-nav > ul > .current a{border:none} +#sidebar-nav .tocify li.current > a{font-weight:400;background:#48b4fb} +#sidebar-nav .tocify ul{list-style:circle} +#sidebar-nav .tocify li a{font-weight:400;font-size:14px;background-color:#34495E;padding-left:4px} +.tocify li a{display:block;text-decoration:none;color:#fff;border-bottom:none;font-size:14px;font-weight:300} +#tocify-header0 > li a{border-bottom:1px solid #2C3E50} +ul.tocify-subheader ul li{margin-left:20px} +#gen-links > li.current > .tocify > ul > li > a{font-weight:400;font-size:20px;background:transparent;border-bottom:none;border-top:none;color:#333} +#sidebar-nav li.current:not(.tocify-item) > a{font-weight:400;font-size:20px;border-bottom:none;border-top:none} +#gen-links{border-bottom:1px solid #e3e3e3} +#guide-links a{border-top:none;font-size:20px;color:#333} +#guide-links a:hover,a:focus{text-decoration:none} +li.current + li > a{border-top:none} +.reference.nested1{padding:5px;margin-bottom:40px;background-color:#FDFDFD;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)} +tr.sthead.prophead{color:#34495E;text-transform:uppercase} +aside{min-height:20px;padding:5px;border:1px solid #eee;background:rgba(255,255,255,0.5);border-radius:4px;width:95%;margin:0 auto;margin-bottom:20px;padding-left:50px;font-weight:300} +aside .glyphicon{font-size:20pt;float:left;margin-right:15px;height:100%;margin-left:-40px} +aside .title{text-transform:uppercase;color:#34495E} +aside .glyphicon{color:#F4C600} +.important .title{color:#D75400;font-weight:600} +.versionmodified{color:#009276} +#header-links{text-align:center;font-weight:300;padding-top:15px} +.versions{text-align:center;font-weight:300;border-top:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;padding:5px} +.versions a:hover,a:focus{text-decoration:none} +.permalink i{color:#fff;font-size:14pt;padding-left:5px} +.permalink i:hover{color:#000} +li.toctree-l3.current ul{margin-left:15px} +li.toctree-l2.current ul{margin-left:15px} +li.toctree-l1.current ul{margin-left:15px} +.nav.nav-center{margin:0;float:none} +ul.nav.collapsed{margin-left:80px;font-size:14pt} +#expanded-nav{font-size:12pt;font-weight:300} +#expanded-nav li{padding:0 15px 0 0} +ul.nav.collapsed li{padding:0 0 15px 10px;margin:0} +#social-links{text-align:center;padding:10px 0} +.navbar-default{background-color:#fff;border-color:#fff} +.navbar-header{width:100%} +.open>.dropdown-menu{width:100%} +#lnav-title{font-weight:300;font-size:16pt;text-align:center} +pre{border-top-width:4px;padding-top:18px} +code{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;white-space:nowrap;background-color:rgba(0,0,0,.1)} +code.xref{color:#4070a0} +code.descclassname{background-color:transparent;border:none} +code.descname{background-color:transparent;font-weight:700;font-size:1.5em} +dl.function{margin-bottom:30px;border-bottom:1px solid #eee} +#sidebar-nav li a.selected{font-weight:700} +#sidebar-nav a.current.reference.internal{background-color:#424242;color:#fff;padding:2px 4px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} +#sidebar-nav a.current code{color:#fff;font-size:14pt} +.intro-text{font-size:18pt;line-height:1.3;font-weight:300} +img.logo{margin-top:-10px} +.notifications{float:right;font-size:13pt} +div.logo{background-color:#000} +.modal-dialog{float:right;padding:125px 10px 0 0;width:375px} +.modal-backdrop.in{opacity:0} +.modal{direction:rtl;overflow-y:auto} +.modal .modal-dialog{direction:ltr} +.modal-open{overflow:auto} +.bootbox-body h3{color:#48b4fb} +.bootbox-body h3:first-child{margin-top:5px} +div.versions .btn{padding: 3px 6px} +div.versions p{margin: 3px 0 0} +div.versions a,div.versions a:hover,div.versions a:active{color: #428bca} + +/*pygments*/ + +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ + +/*basic*/ + +div.clearer{clear:both} +div.related{width:100%;font-size:90%} +div.related h3{display:none} +div.related ul{margin:0;padding:0 0 0 10px;list-style:none} +div.related li{display:inline} +div.related li.right{float:right;margin-right:5px} +div.sphinxsidebarwrapper{padding:10px 5px 0 10px} +div.sphinxsidebar{float:left;width:230px;margin-left:-100%;font-size:90%} +div.sphinxsidebar ul{list-style:none} +div.sphinxsidebar ul ul,div.sphinxsidebar ul.want-points{margin-left:20px;list-style:square} +div.sphinxsidebar ul ul{margin-top:0;margin-bottom:0} +div.sphinxsidebar form{margin-top:10px} +div.sphinxsidebar input{border:1px solid #98dbcc;font-family:sans-serif;font-size:1em} +div.sphinxsidebar #searchbox input[type="text"]{width:170px} +div.sphinxsidebar #searchbox input[type="submit"]{width:30px} +img{border:0;max-width:100%} +ul.search{margin:10px 0 0 20px;padding:0} +ul.search li{padding:5px 0 5px 20px;background-image:url(file.png);background-repeat:no-repeat;background-position:0 7px} +ul.search li a{font-weight:700} +ul.search li div.context{color:#888;margin:2px 0 0 30px;text-align:left} +ul.keywordmatches li.goodmatch a{font-weight:700} +table.contentstable{width:90%} +table.contentstable p.biglink{line-height:150%} +a.biglink{font-size:1.3em} +span.linkdescr{font-style:italic;padding-top:5px;font-size:90%} +table.indextable{width:100%} +table.indextable td{text-align:left;vertical-align:top} +table.indextable dl,table.indextable dd{margin-top:0;margin-bottom:0} +table.indextable tr.pcap{height:10px} +table.indextable tr.cap{margin-top:10px;background-color:#f2f2f2} +img.toggler{margin-right:3px;margin-top:3px;cursor:pointer} +div.modindex-jumpbox{border-top:1px solid #ddd;border-bottom:1px solid #ddd;margin:1em 0;padding:.4em} +div.genindex-jumpbox{border-top:1px solid #ddd;border-bottom:1px solid #ddd;margin:1em 0;padding:.4em} +a.headerlink{visibility:hidden} +h1:hover > a.headerlink,h2:hover > a.headerlink,h3:hover > a.headerlink,h4:hover > a.headerlink,h5:hover > a.headerlink,h6:hover > a.headerlink,dt:hover > a.headerlink,caption:hover > a.headerlink,p.caption:hover > a.headerlink,div.code-block-caption:hover > a.headerlink{visibility:visible} +div.body p.caption{text-align:inherit} +div.body td{text-align:left} +.field-list ul{padding-left:1em} +.first{margin-top:0!important} +p.rubric{margin-top:30px;font-weight:700} +img.align-left,.figure.align-left,object.align-left{clear:left;float:left;margin-right:1em} +img.align-right,.figure.align-right,object.align-right{clear:right;float:right;margin-left:1em} +img.align-center,.figure.align-center,object.align-center{display:block;margin-left:auto;margin-right:auto} +.align-left{text-align:left} +.align-center{text-align:center} +.align-right{text-align:right} +div.sidebar{margin:0 0 .5em 1em;border:1px solid #ddb;padding:7px 7px 0;background-color:#ffe;width:40%;float:right} +p.sidebar-title{font-weight:700} +div.topic{border:1px solid #ccc;padding:7px 7px 0;margin:10px 0} +p.topic-title{font-size:1.1em;font-weight:700;margin-top:10px} +div.admonition{margin-top:10px;margin-bottom:10px;padding:7px} +div.admonition dt{font-weight:700} +div.admonition dl{margin-bottom:0} +p.admonition-title{margin:0 10px 5px 0;font-weight:700} +div.body p.centered{text-align:center;margin-top:25px} +table.docutils{border:0;border-collapse:collapse} +table caption span.caption-number{font-style:italic} +table.docutils td,table.docutils th{padding:1px 8px 1px 5px;border-top:0;border-left:0;border-right:0;border-bottom:1px solid #aaa} +table.field-list td,table.field-list th{border:0!important} +table.footnote td,table.footnote th{border:0!important} +th{text-align:left;padding-right:5px} +table.citation{border-left:solid 1px gray;margin-left:1px} +table.citation td{border-bottom:none} +div.figure{margin:.5em;padding:.5em} +div.figure p.caption{padding:.3em} +div.figure p.caption span.caption-number{font-style:italic} +ol.arabic{list-style:decimal} +ol.loweralpha{list-style:lower-alpha} +ol.upperalpha{list-style:upper-alpha} +ol.lowerroman{list-style:lower-roman} +ol.upperroman{list-style:upper-roman} +dl{margin-bottom:15px} +dd p{margin-top:0} +dd ul,dd table{margin-bottom:10px} +dd{margin-top:3px;margin-bottom:10px;margin-left:30px} +dl.glossary dt{font-weight:700;font-size:1.1em} +.field-list ul{margin:0;padding-left:1em} +.field-list p{margin:0} +.optional{font-size:1.3em} +.sig-paren{font-size:larger} +.versionmodified{font-style:italic} +.system-message{background-color:#fda;padding:5px;border:3px solid red} +.footnote:target{background-color:#ffa} +.line-block{display:block;margin-top:1em;margin-bottom:1em} +.line-block .line-block{margin-top:0;margin-bottom:0;margin-left:1.5em} +.guilabel,.menuselection{font-family:sans-serif} +.accelerator{text-decoration:underline} +.classifier{font-style:oblique} +abbr,acronym{border-bottom:dotted 1px;cursor:help} +pre{overflow:auto;overflow-y:hidden} +td.linenos pre{padding:5px 0;border:0;background-color:transparent;color:#aaa} +table.highlighttable{margin-left:.5em;width:100%} +td.code{width:100%} +table.highlighttable td{padding:0 .5em} +div.code-block-caption{padding:2px 5px;font-size:small} +div.code-block-caption code{background-color:transparent} +div.code-block-caption + div > div.highlight > pre{margin-top:0} +div.code-block-caption span.caption-number{padding:.1em .3em;font-style:italic} +div.literal-block-wrapper{padding:1em 1em 0} +div.literal-block-wrapper div.highlight{margin:0} +h1 code,h2 code,h3 code,h4 code,h5 code,h6 code{background-color:transparent} +.viewcode-link{float:right} +.viewcode-back{float:right;font-family:sans-serif} +div.viewcode-block:target{margin:-1px -10px;padding:0 10px} +img.math{vertical-align:middle} +div.body div.math p{text-align:center} +span.eqno{float:right} +@media print { +div.document,div.documentwrapper,div.bodywrapper{margin:0!important;width:100%} +div.sphinxsidebar,div.related,div.footer,#top-link{display:none} +} + +/*main*/ + +h1:hover > .headerlink,h2:hover > .headerlink,h3:hover > .headerlink,h4:hover > .headerlink,h5:hover > .headerlink,h6:hover > .headerlink,dt:hover > .headerlink{visibility:visible} +.sidebar .toctree-l1.current a{border-right:5px solid #fcaf3e} +.line-block{display:block;margin-top:1em;margin-bottom:1em} +.line-block .line-block{margin-top:0;margin-bottom:0;margin-left:1.5em} +div.header div.rel a{color:#fcaf3e;letter-spacing:.1em;text-transform:uppercase} +.descname{font-weight:700} +blockquote{margin:1em} +div.admonition{font-size:.9em;margin:1em 0;padding:.5em 1em;border:1px solid #ddd} +div.admonition p.admonition-title{font-weight:700;color:#3465a4} +div.warning{border-color:#940000} +div.warning p.admonition-title{color:#940000} +div.viewcode-block:target{background-color:#f4debf;border-top:1px solid #ac9;border-bottom:1px solid #ac9} +.lit-docs{list-style-type:none;margin:0} +.lit-item{padding-bottom:2em} +.lit-annotation,.lit-content{display:inline-block;vertical-align:top} +.lit-annotation{width:40.425531914894%} +.lit-content{width:57.446808510638%} +.lit-annotation pre,.lit-content pre{word-break:normal;word-wrap:normal;white-space:pre;overflow-x:auto} +.lit-content pre{border:none} +.lit-container{position:relative} +.lit-background{position:absolute;top:-1px;bottom:0;right:1.1em;width:57.446808510638%;z-index:-1;background-color:#f5f5f5;border:1px solid #e5e5ee;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} +.scrollable.container{width:auto} +.scrollable{overflow-x:auto;position:relative} +.highlight-bash,.highlight-jinja,.highlight-python,.highlight-yaml{position:relative} +.highlight-bash:before,.highlight-jinja:before,.highlight-python:before,.highlight-yaml:before{z-index:10;font-size:9px;padding:.1em .8em;text-align:center;color:#999;display:block;position:absolute;border-radius:0 3px 0 3px;border-top:none;border-right:none;background-color:#f1f1f1;top:0;right:0;height:18px} +.highlight-bash pre{border-color:#999} +.highlight-jinja pre{border-color:#e00a1b} +.highlight-python pre{border-color:#3377b0} +.highlight-yaml pre{border-color:#ccc} +.highlight-bash:before{content:'BASH';background-color:#444;color:#fff} +.highlight-jinja:before{content:'JINJA';background-color:#e00a1b;color:#fff} +.highlight-python:before{content:'PYTHON';background-color:#3377b0;color:#ffe243} +.highlight-yaml:before{content:'YAML';background-color:#ccc;color:#000} diff --git a/doc/_themes/saltstack2/static/images/email.png b/doc/_themes/saltstack2/static/images/email.png old mode 100644 new mode 100755 index fed745e7286f4f41d538f4298883b4cb2375d3d0..4a71b7011fd35544e2c8c7239def2270e8aa09d1 GIT binary patch literal 17851 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 literal 1703 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU&_u!9QqR!T z%-qskN5Kfl*Eg`xH!{#Qu(UEYwlXkMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@w*YQzUNJP7fB~jokyxN_sAmB35=^15FMg%Dxp39RB|)hO_hL1;IHa;5 zRX-@TIKQ+g85nVC${?!>telHd6HD@oLh|!-V4)b0kzbNuoRMFk;OqX$Y%oHnAS2F_xR|9i5BS!;6Lst_gQzKUkV@GFK z6GIDAOLG&LUYGpj(%jU%5}4i;gkB4rdO-;yw*Y9fOKMSOS!#+~QGTuh*yC22xZPrk z(>$o&6x?nx!>Lyv=oo!a^ddz!ObD2UKumbz1#;lYKQ#}S=8J%dd#dmpC19Qr^>lFz zskpUfTBb)xpvdw6#-EQBo|L?Piq+6{BWqKag8htE7T1JHXo7FcnURUzZ-L0P^DW-K&`TfIH zuIcZ?uk6)vcFWQGv(<6)rZ|bfixC}shuzNqXf%c?ECy*u}so!&iNOzp#BKM z)+Gy@Y>uoybKvSSB@ugzmRsUWZwQym2sKwO{im_7WWV#DRVAyn#a}tCd9J>%EGRci z^=A*qnxKWh_P%;9*)Zp<_=eiEbs;8m9PYg}nep=2j?_*KpKHoF|0bQxJk`Lh{M1rG z!Q>}@+J7s|pJKV|;<*X2hn5zL?3*t0 z`}W)zPqE2S>MZwF7p?J5`yH-W=PZ=lKFNbeaP6ge&Gw$sl}=eFq}^xLa~d!#etQ3> T!8gTe~DWM4f&$yJX diff --git a/doc/_themes/saltstack2/static/images/epub_icon.png b/doc/_themes/saltstack2/static/images/epub_icon.png deleted file mode 100644 index 112fe4a94c9a17d1a77446478e0bd9daf79c75d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Z!3-q1ulFqjaY|exN`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%1qS$pxK3$rc>d(^=F55KPaa!+KE5zMth1`9HYa8Kx>bkn zbnU)T^ZC=q+t;sr`1a_*+oLBR%v`f@&XhyOOHKzYn9}#+)8*d1su!OwpL5LV`|l5} zJH`J0|G$BA)k>h@(j`HD!9Xq!z@TozZ3( z@2q|?IQYkccTb%fwzzzez$*5Z+^^hX|=n2#wKh1muJ!GBF{3gTe~DWM4fE7!lM diff --git a/doc/_themes/saltstack2/static/images/epub_icon.svg b/doc/_themes/saltstack2/static/images/epub_icon.svg new file mode 100644 index 0000000000..e50861b8d3 --- /dev/null +++ b/doc/_themes/saltstack2/static/images/epub_icon.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/doc/_themes/saltstack2/static/images/github.png b/doc/_themes/saltstack2/static/images/github.png index 3082c911c2b59dd00877b626f0d25e2793104a0c..c2bba844c4013fc85ed7e853cd33a9490816dd21 100644 GIT binary patch literal 24382 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 diff --git a/doc/_themes/saltstack2/static/images/linkedin.png b/doc/_themes/saltstack2/static/images/linkedin.png index aa4f56aaa975ab097ba28799ee8c4c8e5a6d856e..e68581cdd6a07086536daea0ab2bc2d89442099e 100644 GIT binary patch literal 15303 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 literal 1762 zcmaJ?X;2eq7>*@U14ETd4sBfm$YE{+A(4PU0wg6EA!>wz=2$`u$;MYzwbs-qPrP^KIs($*@XAV)zhRS;x^;$Sx@*dL`kv-^GTH}CVj*YnNp=f_6b z*|^)FP$)Z2G%F5ST`lhdYvkLlXO1I_8_X8M@lXn^7imCLm=qF&07og3fpMTnnz6MB z3`U`>eB}ZmEab&7B#@FIviJ}TN;QH;p@KsVYLP?%!hjf*$yH43(9PReKrUrsHw5rV zJaq(^Dv!?8fbp5J0!gMqLYHDgLx5ld10hg?um~_H(^Oi9fr*{wWgvUYF%b()yTA%2 z_I*-99v_H+G$0T_2*gWBWGXTCN>p@)eIt0uh$dwD+!QBMkLeebRvmDq)_mP2VR?@f<*?rO6xhpzyh@r zja&`OAr)X@6p0}n%)}y@zAr(ko~2c3KeP#H7||e76UhXUrKA~09`FBMmC9LfEgT1a z%=bTuwSo*aNQ?uukWM2(2AAS#38iL4Xh0DRX#^0IHq%9ZDg;B?R7ed(L`-)L@a2gl za+T%KZyLqpF*qtMEK*584vUFJcnEU2lo3D+BGc%BL6MX&3YpBNh6hmCK`X-|*i>>* z0G&pi!LlHUP6?{u8LadpmOdxeA_%1#iOd2u@^nxdsezQhbm0v7+_?nK$@c*(ojVuW zoLC}~4AC;)e~o+Q2+@#bJ1btqn3X@MLNu>I#ErWA0FB%kK8F=1FmxPWml*A|)^#c+ z{k|^gPDv*fQ`7bn!PRf=IN#m+)&h>c4e+b)%B}t)^O;}8Q-``7BM$StH_@pGJ>SF+ zF&+|Ef;D~}M;~;ac>eBgYisMp%F-Rf+?3D=?fTMPpqx; z3HRx-Hxaw$#VyUQF)EB(vh&Wq2g-yptV zOLS!E2s-c3#uXkdG3sNEmHDwISi9W4d88^U$=|(swCbF%ZAYWmRQ*v;w42dW+${gO zjTnkq-=IGHqubjamr>gz<#=w@sg|$EvShAa+Y*cQMRE z+_J(^)&=`L-Q1le1L*NiZbA!sGOq_lRpv=cQqGw}9a#;BV}ggq%*DN{`zx1z|A$q^ zy)h6itM~!?q%Rv1e|9M;!u79Zdsy2fkNsuY`FmT6=Urzu8PYRlua}>cN16A+)MW$* z$e>9NM{OESj<90m3YD{?F!%V~^*U?aE}S)I^~T?pINh)5YrmzE)OxLOR%keb_l}=+ zCY#&2TQ1Am3pPNXHVt`Q)n(PA`~Af)S==3s*gqFKZcoOTaiyenb_X3c>wN_-zZ9My zO*~MFNyh2UXB5;acZc=#=^x&UTzq};iR!M?y~h@L_k>(nVWXQKL=}j z7Q?;jlj60i4vbcKCkzazkKBs43k{-V<%XR1TzcC14Dk|yP0fAy5e}XSG8Y_zG+3jM7%wpra^6n?5qRwc_wm$xV_oiXt z(?NNy{KD5GN#P!*togr>lvM3+bD9j>f5o)v-Nb15Zeyo$th}}%KXvDDg3GUt1rw)G ZR;WQ6>LB|-jM?(n;jm*_mEoJS{{bYdu_*um diff --git a/doc/_themes/saltstack2/static/images/meetup.png b/doc/_themes/saltstack2/static/images/meetup.png index 05c2e6bfa12dc838d0cae660f8a4ee3ae73aaebd..7560726af75d81ee5a57ad8bc0a6496483398d96 100644 GIT binary patch literal 22314 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

v#~}-b!D}7tto-?#` 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 YDu<0POjgsb=zcjocOP!G+n&^a04z?qB>(^b diff --git a/doc/_themes/saltstack2/static/images/pdf_icon.png b/doc/_themes/saltstack2/static/images/pdf_icon.png deleted file mode 100644 index c24f66c04865f7a722168727effd9bac9b1ac0e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 979 zcmV;^11$WBP)H$b@4nT4- zz|hbTy1ToHb43l&N*g8v3Pb^VdU|+JkH>SSV1O`NEU%b3q0lp_QWSu$@pzn9jaBe; zUVzYC8_Z-`S(B|Th#WgIHV^h8_1TGVZ4I9fvofc?IH5d#l($!dP96@2d4N4 zCD?sqC4y|RnY71^(B^6+-#NzSzdQ)8Tmtp=%Rlo1`$V(=Zns{?sUnvz=IzxWStJrcG#W)L7UNJAWLf4g^>iMf zmn}AvVihpVSpeURCL1d$tW`65qZW=4sXgO6MndYqs%u zvip199y9cnEhbkKg#uLa04}z8GN5-}Ol}D9oh_aW=xbLpOG^uI1h#1CzUeEpK4+=Wi9$x8|#%EYeLh+nCP z?D__IceO!WOisUwgyjIDOl&Isv<-Iftqq1?O%wedcbd$<28CPqd^tOqcc)j+_9$ntqeymvskaSgHkHHhxm2>C)i zq_d|WpRdak6QiS})&rQ!s-eDkhG_L_#P)83`ur&}s=`mJHa>)O;y9E$w=l4Dfk94U zf`;V)Vo8aV-wWwrE#epI5MH$mX<0IqnV* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + rich + text + document + office + word + write + + + + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/_themes/saltstack2/static/images/reddit.png b/doc/_themes/saltstack2/static/images/reddit.png index 2ce9967d14d6ac3b95bcaf707f630bd8099549b6..49d536bfc8cfbdac88659918bd9e70beb3160f62 100644 GIT binary patch literal 26050 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 literal 1812 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%0DZ%+MU1bP%DX*Z|H9Q8LN34`^jb?L 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 literal 0 HcmV?d00001 diff --git a/doc/_themes/saltstack2/static/images/saltstack_logo.png b/doc/_themes/saltstack2/static/images/saltstack_logo.png deleted file mode 100644 index 35fe0cd68b37886505a9e2d8a9baf3de81eceedf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5034 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

~kSQ1EYeK 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 KMNUMnLSTabxT-Y( diff --git a/doc/_themes/saltstack2/static/images/stackoverflow.png b/doc/_themes/saltstack2/static/images/stackoverflow.png index c4bd350c9f46dad80ea3029bdecc204fefca119c..be8b8f52315e86529909593f4a2a25b4ddaf572d 100644 GIT binary patch literal 20854 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 literal 1823 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 WN#ERELEx?(kl(#_6Dzicr~VI%MuD9G literal 1796 zcmaJ?do)ye9G|up>lE!qD#dN|7|PsvnAb&2#$$GySroqtyPf_MUU^@Av(k@8|P6G+Y@4 z1&Vw=#v(0us)``A5C|qFCejnxbPSIMnF4_TWUxRM%bE0W)+K2OSnsUSIgB%i5S;>7 zYY8=`0gQ}rBoK8h4aP{@)cvKY8njK;(12 z|4FQqCutEd5Yb`rxPly9l!Gyp7V^Ron80v3hQ*C{(O-oTm`;Uh0WYtyt^qU&tWax= zhmK zajXba#G{CY7{@9T) z0gdDR*SN=zNDUdcpTtWVpX85dNX_GytZa5LQM$#Js|8@sQ!n^g+9(ma<2voOcZ6NZTV0X@7}O6ze| znqS)16M$~7o%OC5j=dVYW=JC`Q z8a91vQ#G==cir9TRWE%m_USeyRvB7Xb35IBvW(36wtRY@oCkde)ADgf}BoVtq4HTTO>f4KqEL6qi)$j^*84*%KfOO|cs_>Gouv z4!Y}^FRghcn`+^9jn~m0bF+k1a2CxGEj{BPXLlqxrPRU~@>`zyN!z0m7YHX;EJ)I! zeY+Pfmn-LvWPP_fsM!2|6g6*qm@mU;gP&Q*9QJO|_V5n-;uBU-YyZJZ9;S|IH*B}K zy|tcMy$BWFtEdT}&*P5HOmBJc{iLIfw_Lq>(vA+h{dio{{->iz*%E_Ubgj~AMKq0G zyF+3))xWn!mAX1JBy^v>+vtT^)XvJuNq=9rDN?U&@2lOszWc_CIiaJytJ*17=-PCM zxz(nlym4qy_6$6w6{{_rop4}@)z)(B@|M1On^o_tbEKzVWaS1}*O!7p6%WBOOZ46h zE!`K6fGf7e9DHa<%g!GC#TkSg+Tv3>_rx4FA1Df6*p%(@W%x@=!)CVJGQcL%UKEy7 zYJMc+x@GroZ>C?hhLGo_=LLmFYYO_-nvUK&c}}{trvBtmPg}{9w5sNMSk@J?(V??y z|3>zPxe@p460YD`jVW(VlsB3LwYSNy#N`<_Wc?6c>2qYudFlJbrowf{u;!VA|lB`JpZc$|4r-`pUd2$wOrdp8IjIx#5M!BooT%3Ss|VeM5lpza;jS KiprNqr2Yd)7s)FC diff --git a/doc/_themes/saltstack2/static/images/youtube-variation.png b/doc/_themes/saltstack2/static/images/youtube-variation.png index bf0084a8556a30d8f076e4fe1ced09b69c0d21b1..342d6504d8f04e19c32eda02c0b2eb234bf78a23 100644 GIT binary patch literal 15325 zcmXAwby!r-*T5H6atW1gktL;(E?pE@QkU*nVL_xDqy$6+L6&a!D~NP=Eg&F`AR)O( zt#pUfd;PtC?6c3EJ9ExGXXehFIrF*E&veu%$(hMPAP^;7{RsjDA~^c@BP9k(1|}EZ z1Ak<0>L#8bkTBQ3AAw)KvJVJEuIs3x^6Z&|tCy>%gR9#;xQfa>HxE~P$5(bBkl#$U z9!g*D553~)!VygKU1*Y~D}s*n9s(801FuQt$1WQVhqAu}VGL)ha z#(oDE-uta*X+`)^7&+7pbepvL1*hi~7Xj!jSV7^zeJn{Eh`?_gLJGoaXJSQJqi(1- zVCm)rp%DaFuLK!Q(okB^qkuTr7tkYBg3#fTOjKJr0p{3nGndDH)L%b6q_>=&;M`QQy3CKYnR5D`t{wc^<6hv#U`ArryEd&yU8`-OaD(XSl;oFcZ z5Ge&n^!d9;e$cHzko9*iEL7-0wbbz&oSAN4(Wy8Z#adlKyLL2SGH}`FA zm#7WC=QjM1UnKi@pX zd~E#nYjtI1TH_nc%%t z*v_rRt6kPZZZ6rz?|*~aHW~}iECE zVg3GUELS#BfItZJ1LC~=gd0-+xNy?aik3C zk!PG8>bLI3K=1XvqkVo~GeJ^a4Dnw7o`E{sfuaYYY?QfbQ-b_=kocR+w=HU7Nnusb z6@OCHsx*F;W{yz(4>J0~ODrRv{!`|tM-8)LtQ2N_wAg`qCSFOUR}_n9B$4>`N>sR~ z3sxy3NS25ksJvf7QQX5^VORogjy^_?RQle!8}<}SCUwgfcF%_WvAVIAvCg#m*L$qc zhj(Vkq{+Y$&pUbVCw|qe;c2>a{*BRATrA31U655_NR*I=Zls}L9O7qY=Lv|>f9;2N3FCZ_V*H)A}E)yCpqU(`LzD=@C>QY2P;}3<; z6RICnsbd{`%$K3d&OOdOpLvLRIC(U+H?(&$5ZaAj_`k?&$!qlv4G#S`G?^}$sVFuj zzMi?BIhDCsZ*A&lDp>cmuE7powPO0kWT&phCDK&ZB;VM;)S_CoG`p00vbnUm;7&oK zPNGh6&LpajE- zlr7k^#)DSQP;Mb(IBQ2asQW18j|j?mY9BL)ETxi6BK1j7p~}>hpbzPHlD>lund9a+j5s6{Hu$7fh@M zrLpzj>j!kZTyv}<7ga*IZeH93-24C)gmM$0z|mok!^{XT&H`R@w#O;U&Dxz*{n~yU z`>F9U-Q)N-rEgX{N;w_AZ+$G~JY7#4P8fEiihLG~pByEzS+j}h3Z~$VjEXdRs~qR{ z&Y1a!SgNG&k2w|3#V3ECq&!*3M2YFjmJ4Y}3Mdr`zf_o!ZhF|H+#_snGB{zJZ47^< z$to)>P$uQ_s%`Od`!MQv_HW2?AVZqScMCUv%y8#XWC4Al@LfTSP`doVjXG&wPx=#P+}KZb=~a}Q!m1vOw#96{jr3| zM2Nf&_64tR$~PrIQiZZJvTq-X?w3s|&UrAjJy_j8`%yY;H}_`yZs*-4bY1>iO(P*T z@ zWA=a67KC!ls8Whj*HWomD1Xh=P%awQY#*OIofSzP;+t&_uTyFK+^*2jVpq^NJS4BI zpQnGM|5smXXKcRKX6nr4#|}$i%gMv7iCMFj(<`OEwpjxL1MLa>3A+pUMfIt2S#;5# zvy=;Gi&7nD_w8Qr82E~Wi>hv_@#h5Fn4&%+e)7Sl8dWbx+jaJ?uMnjarNM`+p5I(< zPyAQ@oRTe`vQx^<_{0X5ERl?J_^_eaL|(!&4l-0T^)fEZY|WZ<2bF$IZY%^`s?Bmx zXFXIf@z*%i?{l2_^JY8|bubc}otzyMEPOs^J^No>;5u@6@g=qEZqseArLm_sG3)Xz z^26o_4PFOTv#T^l4MrK|a#qe8UKhrk>xAQYY89gR^!S0dly5h4WRzrOe=B=j{kbeq8F?|nlf!WR z-}OKl1HDM_*~I45@Q<_~nAC&R#CGS``Bxj*O{VhMp3WZjwmv@zG0P*vi|r2IIbXKj z&x_Q$E3fZ`@ZC6^S03w)7F;AUB_`h70;e5bA|-@ofq3&CQXQcU0tIk`K%wCv(D@DU z{|5x}76pMetU(~TG!Tfv6>Zh63Id6d!k;|W_nX<8_suf5!`$qTXi3dhk=-`E3k!Yp zkv;;1QP(RXecZ^f2|Xk5#{3 zNcZI|a*TilIqe1pvpnsUcBh;yn^{tZ)&hqW7X62_4zpnEambHJOil!w;7tN2uu~cC z2O$L^bLiTc_s!WNxka!c&1l2ih!ut4#(_8CAW;ga^byM_)nL5Uh(*V;khPR3*l$*w z$4({tjyl~B(pRJu@f>R3MxwwfzmXQ7+6dcw54e>ZsFlk3jSgIlFk>GB2m_=A+#A!n^+jwYHXb6b92W{mbh>k3qk)oZ3OmoqnIVhAvT~i1X zZ95i8<{&LLf>opW8&db_&n&Sy5i09NN+O_;nAKpBCB*BjH;}xl!vEY8|{mxpYJpK{Lx7 z`-EwXV2*y^N_8P*T@Dau#XRYupqenw~WoMj{>HL@&2l2ArTNlKDx zbvg!Xu)hS8sv0$**$7n$(<6=gdBGH2q|UpklFjTBc z&{DtIMvMj7fUORpPQ_q8`=)Ngt3!U=2-fAF@ySQ-I7{3v*6)<7aD+U9?k>l>k1*Z6gM3hQs6xnGkyAu@gH1@+tV-#6x5Pj?u z`lf)*WvogBUAfOgDt{;MsI}xQj z)QIbzJ+gh-%lWgcl*lq>1W6W!7IB-7ai9evSh9Ql;05ks%N=0MW>iS;kuKH6seDi= z5>N@V0>$^NHwk(fU?@qQRBwoM^Ad{Y9dPCQvh5gmV|)?SF?Nb{w=(E1L&3+FeY|AS zL9*1lwbqyiQzx8rM@#n=OjL^ugs_qBg44Y+f?lfwP1p%+HkNPsBW>@S=HJs5Ie?V@ zI>M!`8<#>HTl zBe*%a3!8o7k-e#VGu{x3!Wrf>`Mul*nb^DqN5VF0h19^y3Ax&B&yR4 zFHnfVmSVXdRlBPfh1%m#*c*bb*e;mS;s-Df0SR+t9xW?Kfh<;<9AeQrPI}4MKwvy8 z1I>4E#_3{pm#2YAX}*SNPZuX~cAcE}iVuVWQxlpoM@5!R$S1h9A5gPI=26VhpE1~^ zJDT84!|ZWJSUSJonR#3BMyb7G1N;3jBZkkU58AS=Y0(}lw>oFT7bbqd7~G&sd&yDL z+^awEGH=H%KlS+}K3F%RpDB@8NviwKh?#^Z`O9nH9!e410n;@CnTA-kRBc zgc+n&^%X?n))tBuT{NoX9((Bg1kzf>rXq9hocCP4$d-$&9;w*FCwTNy57Y*}q-V5d zMZd&`%B%&EESlDg7C+%~qukT>eF>M8Nk6w|1zU(u!bWO2v5MGARnEe+vY-X|vb zMv07ywaQcBR4Cy3Z$DIRFzbCv*efjQ=Z|^5AKoFC+x``GxMNEjjANmt-|yj4WDNUZ zBPHb^Bk-{*C;Wi{M{j>Qb7W+W3HK_v*BB6FuUu6u-ZD{HLzJCa=C;0pUh8B1AVy$k)#6(^z9bp$5h-%HanS@dXr)|Evyy;}{M5iOgbsve&-Zc{+HX;q z>wL%(F?bMp&1U`Pq7FKdrAx?QjGtI?z-{h~qxGwYKNHj6E_`&35(owqhkwrPw%AER!dXZ)ii2!F5Il)dPQ zs~Gjf@!`x*P2gi1SuD++u#t+PLW~m?H@p=A3TBe;f{lE#$H|#b8lY4bUWdQ*GvJ16%uiyeg^s*fiL;iJ_}~Hw<6&JwNBzti4R4>J^AJs}jP@8K zRe}aW#;sspxIkq`CDNn*kqJBGN)Y$xR2Gg%XT9CbV^uvr%+?D8(DST*6eBNFp~*%p z6^f$2m;(Mx5VY3~a>MCHS>+3cVIr;Ngvj|`D4b55UPeTu{gowEqbsEX;lqXyI9lK< z+cbgS3{$}3F;|wmL%Jqfpp?_+nKGnxw=Fbkh8zBeiKUruyejy65Tw&&`@@bdI*(R} zxDK4-`*tCQfd!kN(g@`TGlva)-+LorB7CG5syG(~g)>!>xOv#4I+zq!+SvC5g?9zu z{VB3QKqZL6&mV#Z%+X1Y!;xxsI`ohrE1b+J6C9z+MzV#%l$(OxqA%V<`Im!LdnVQT zOfezsjH|)-;r$KIE33u1GdJTQm$HKtS zd5&W|rGz7fS=rYg@0Y@EL`6HCMc_r^G`77HS{N(!y4`MJIKnmXxU=T^x5g}+%(SyGya++kTUPuR z*8bgD2wvpDU=)bqAl+K>Nr4(P&WD8;)s8~2zVkikJZAUDTWv)Tj>5y(=GuTuF=9p| z=SWM?u{H%d+D;}Hnd z{Yj;di#^q#{cALr0thlX5f=2t?2>Q&@kxSCG$@A7_n$NTl$AHqc61Db5fD>^!tR*< z?j;y{CI~wO;Tf#f>nLJH0%Mjg2>u>_9-U)V+O?woK)H1I_U)eJqoA8TZ=++%(PuZ; z%1#axi?aqunx8_aHLqOW245+ip}NIe*>|@h>grB!epT6VTvq36+U);#dSlXi*TL!% zXtNs{cd~k2qWD?_i;mlq#Qr|nll)jy8`;iaz0|oENKhmEu3e9}rd!!+ni$SoBTT`; zARGY=n>0N2w{uRhtfN`!_g6kD4K4VJdwSeoNdShCNj-c!=KPA(s=nqC63O?C0Q{*i z8m6McSF^UZx32v`^bDGuzgx0(T`sZfe#A36CtTaB%lq`Y}oD z>PD+dTijg zN@ra4E$g5hJk99GB_eTDEqItU^8&h60gl|R3m2-3pp>qu$k*Vb2ZVMZGo6+El0H?_ zSO!w&1g5M+^Wv;--lSTI*IyRKvz-qq431`o7GmXG>a!^B&pPYcO3uruUbkgz(i|MF7h4>9IP;k&|8`ENEnH_9ZZ z^4zZLZBFNhU`5`ii@FEfhc-Lr)!*atu{_wClA%%E%0Y=2gH*I-=cRVS{L?|FqCBy` zIs~ge3;UqH*yFvi#i0e7sE!1+=Vu2-Ey3nvB;G#g*EfNCQJX{eS-yZ-x_<@m*yEQ4 z4=MO)`LZtj$*rz3?1UY;KL;mt8nvq~&5cB{(D6HW*+!iNji=xleYkoK?JP$^b&LczHU~1_~uLTV199;o5$SG z8Wf(_cY4SY^8)K} z?WJkmjPSfM`IAJO*yqf|Juanw7+ukeB>VN;ixyx(N>;06>|xB$pPHYUHDsjl%hqRB zjel$5D@g)ht==rlxtE#)M)n$(jK&jg3@JwbI%itI7^0Edbj9&(W|gp0%DIQJ%tT0E zDWJZz&${RuA7!iD)p#FSHRIS(frG5V%)s(Wk| zvIP=sCRLC2g1y(wZ8BqzR%qdW7$pT_9~afgS)0p3uG}Pamgo)$NEqKhdq2&1K4~Nm z0#(GHf59Ppg!{z45^qCll0J`~f-?r|J5^uZ%6w%@g&wQ!HeNzMLkO^uCHtcsn+iC2O)h( zk!S&DqGrcM1I!#8L`mR(oE$=(>m{SSyfzPNcj%j@1oJ+L`jl|0_m8Hn*qkP9 z85O}eZZ*)2S6rRg-{Y6Bn;oVYtCXlvi?TXS@)iX7=WQ+Q_zSlYEnZ3;t@T(Q=-1GvGf)PmLc_G8(QEvmd`w4S(yo>SYY#D;iclkBbF`i=&-on6=HPIRvsb`-N`Si2)mf=+!$9Nu z8r0`b18+N_0~WKxkI3WzMHLRxR}M-_@TC8sVa+@DWltEj4qWB zs_*XEwyR3z%@*(I%u61RL4*-Y`PWgk49ywcIC_cE_d=$(j4a{eJGaj!=$4%Lorg!O ztrO|!{_=TNjwZW9=s%htNT9oVI$X;sCH(rt2AJeHUQ=5r$tIC_u6?}3wRd_{Nnih3 zeUThT03N*eIdX^77h>Trfh6uDTI7`d%hzxi=a$m4l4dX-xj_2LS{P`lr)R}2yXyqa z%^*EpbY=G#EMntI74a%pKJCN2+`Bx4=H9UO_3?Imj!%nXtu9&wSzAC9k>pCU`U1L2 zk3If6LUUzVa)Npk0IBm*m7~>PDt}Puo8DaV_U-5LoR2Xqt)>pC#FFaAb`K7f?c$^Y?C6J*xs{~M6 zGpe|fLv(eK8P@OGcemj>0KFfDzFg@Qbe`F+kfges|Z~gvx@NkU4BmK<&_rAT76)rJ_WOy0-g*Arjl|R zJ>kJeD(EiiaOLZc|4HE3wTx0?{3;z!;c(Q4p-7WVT=^ZN9w$fW(meFP3PHzMxu>Xg zCdB&E1H11|3U+7i@#u&L&a*6ByGWf>r&iv910P`-#l6Co zh1ZEdzeTOSaBT#JV*VJ5HAb^2Ys!lEeDWNcD?_|VE$jtMdPOCvR`&se;7V8g zXY0yCDjUsj?~ekj5MqBz0vK4CE3xC&V~J~=$CjFR9Dt>@Fks~lI#CCDez|V_?@c~7 z_q>C5r9z7@U0=ZCGSv@`4{^1HYn{ATD|I}O<@_|NLXXHcB{)+K7|VOEI*Lp{8A&prO?6u~g3a?bOO)Gl%_v|%2Gs$3;C$u2WC&#i}P zuQF&5X4tt;)J5T^>=Pi1ocG$qQ=6PO zn?j9!HK;D%lKwC3HHQVll$a_{bYCV-^iD>`pvp#ew|D5NM3TP$(2(1p7;T*L9aHl# z(~ZwQ|MSk@0GR_ma^5V`aFWa@{riB>e*6@5&xZoH1OAHZziXVyn9)?m@VqL1dYc?|zk2;(^I;YUc-Oc5LoK1S42Fx{Or;|MWsVAVz#4ih&QPMmOFI|wpiuZ&OY9*rp@%I zfA2=J?H#4y+mU)Y$H0@((f(yw`*>#{B|S{w^Rv+S;Mh(kR3}g7zd7w-_k)~uitLLg zW|_NYMVJ4aBfE}W;}C}&2Mr<&TTDm>3FJT`!rHS4UD4-E+Z8Itu2)?gQV>~tgH-Na zS~=`1Yp?|T*Y9roPh+$8EaU~bWX)T)^uScAQw>_+KVqT}Ag&P-2PY5PXGWfWKb@Hs z{5M(JdkJ|hs*Svfqmp>G=-gn#cW`wAcu_#4TxDd1A}HhEbXewFWxxS=Q&?HvD@$7E zxt-uE$?#WcleME(67dvnOizz{xdZF;?KQ@*gc&m6yXeq>XMno^jJdFd~C()<*s78R2((UL6t&U6|(Yuwj z{IV~mc&0=_^U!tZCiw4Z)c!JmmIrf5Yn?xz9x|m$TE&V&i{x#(=6gU*+23P`w2tid zL&gm~JrmaI7I9wimtLxZP5w#|Q#`Q95JVDgRf|N9>j3t7-2HFDe?MEdiT*FGHFY&S zVan^}={$dye+n=LkSTxl@giw4op7%}@|c80J73v`azAf0RMyZ0e*nMVSE)fC@FC-( zj!C`0!&q{PLfjIsOEc_c^iub()v-o@7sWhG*QC>9y;aBx(4Sh)FLWs61^4Ik>McrY zB^|UfzFLn4c z4paW8YL!CKF5ahLltY>qg-5R#Cp*Riu^EccH7&V3fZK5unXE>mcNDO-F+nefRUUf4 zeYnI=Z8a_Y$2PP zm_=kTf4X=#(9rGGLH2aZ@Mr;H;*cnj$XQ;(%5>f-n#6Kj69b;Ji%U*z!EN%vO;|Gp zkCNsZn_Tfam_?g7{=imYRDFQ%<&eAuXJSrdmx%D1`<3kq#NCUw zIgTwnf!_fQy()2V{>H|n$ZN)8V;3E}gCo5PH;k;h#$sorjTRzbn}nU;4#SHrT{E=- zw0v&|rq#df=L~{o_EgEfPXBgRa(>f_bbaAD@qB%iU*CE+2L>YWz63FYb)DBf#fCp~%=Z4dO(Z={RGHBDu8o~^llC6a27_pr2OMc8OD zIq5f}SG{Lr(j|s>ac&%TBT>d|02?iHkA!5g|By-Bw{5sRLYxcMIwV~DzIC6e*2f> zxv;2RKXrldxH!=sK1zsfy|Vx^msUvjijh$okVw#F4E83{3Yot*wqGz^N+;qK zYLyGQWb9Bqd7CT;B5ZvFg8 zu1HYkC7-vlnyN0`H2N>`;qfDK??4ksd_4GH;$!#nt}sz%ikS<~dH2Y_#L2)VgL0Ia zi`2U#FG8c!TVL!kqXgz*_qL6um9NOm zgVP_YZ#+-uRlbUr%`1npnd0Z%wfKW|*!BcO2e;8xpW`um-6D@G9q7@9;$U@HLZE6O zy%vcSVT!%o+csLafHb11tDKdrYU}IQ)gO-@Z*N1buF-ZmY^llr4QiU;L8+-5sR$0m zOVPdv`Y@RKo;64$@5=e4j1>A680SA-P$-iskO0 zl>W$i!_Sb{pOR_ooARV^K_#U38oTZCIo1TlM!x=I&Jqnu74FkJpEQlm`86IMj}He zf*h#(ApON{<%b&{BWfM$uRif&K>@vJ$?|?K5m~+UP~)|@zbtucv|HGvoJ)DE)5|xC zCwXqTu!@1Q(f0Oqb^qg|aj5j=9hYWGdJ(DkSAjH)1cLnm7_d3$b(eEWwa22PV5Egl z*mf`WOJ;zvWq%bkY(0nje74nX%3`nofjydIk*LjNgTu58_W!BZd5@xeqPn@eN;O20 z+R~ACxU848tw--wCya^u3b!2HS2z^x%i~>22*+eL%S zPT0LA(HDFaY#KJxqSFps({5dRsNs$L94DvnNg~k;?KDLe`ypt$BE)_$B3%O4%@CyA z5@1frY8A&}J`7uY@7B}I^|};D&<;u3e2}!+Gp(33UD`|uqa~)IsJ;gFx7@)C(~JN= z@mNLWjBm9vc6PR_mk82{v~fC{p3%6g{I;B-D(BJ$S&EiCkX# zDm5(xd7Cvo%wnDVafjR&emT8Bz-FP`)7u$Y;c%x;qWsXG%>DnTk|uOCU!UOaBM?`+Y2ZZ^gNQ|Yec4WHxfyZWjjz>p zd;6gTGjl+0FPav)hC+Ey(W1?=g)hk^^+x%RIWYtY_whOp zq!)T)r`dJ0*o15Cw5*W{Hov8r8gXDz^{u)k*?@!K+Omwp(rC@#qtdcstStbX(P`qxByb zvVPFn+@ZB1X=(ikEu8V{i7RfXA-^KSG1oUk3;WG!ju815+zNeDA^6Z2k);;$F5;7Yl6dU`w0enyX~Ry zbKl?$yPQZENduu@f6!xelAbO>yVgbOcNj*5NNMvLXjC}TBV2qABRPBEmVFTcItc%yyIfU)&g*aH^Le(my7civeuEU%8i=<*>yuFvaBza_RZG7x$%&2X z-q~^Cf+J*WyN69OQmq=&szZ6fRzAv!(BxmK$n_Ofu_#U}!nvI`9=Jf_EOKf^gB_yC zndL6i8>EBQxAnB`h5BD~$H-E?mb2+*hod$A{G1kR)EjiihujKYY6DJ@6Rf_u^yS+Q zcil+im`)$Vffay7p1c0Q67P%^^W)Ei7P?w^cr7&N856Pmb_9;afl(}yt*K)e4xF`< zG*C432O-cuRg8M6`dV%2oRg|U;X9cC+>miA%S7lV?WF(^WAa(IU3`T)O0MY#?e@=fj0czjx^FwwoP^^5h3tx9??LjcuMbe zzr2hxaKeayb&f}{Ijc{zi2Hn#-g?$q&kF1{|~{OB-DTzuSA#{`0qTn{gM*wKUd$ z=LW4WIUIuw)E1aL>$#!Ett*j0`A>t{dyg^$13kB>f7*p{t{LGWLOL+K`~g zHG&JU9>92rJ87^MTR;b4R{2a=wXoEGMeF%8sw1N0kXHFG1RUTmfPA~2pE6Q`x>S%> zHB0Z_guFrR8cRu_g0y9<{HWJIB1J16xgYb7Na=<|oH}I{Y9iz$4&!?&jp+k&wTVwU zRTRT=v`1~WpT&2Q=1#osEbR^(c+fZLl&s|u;(_1G zw7!RKkJyRiKgh;L_4V-?^*_kwT#ePt;$aW0{A+#KRp=~$uKeAKlljv24_jiUCtMEQ z1Z)TZ@(!aiU;1IX+9Z2$++Cm{dowf+vp_fj8;P*P{=)h{vSmfrn8H~lM&giP1&_2E z8D$oXGSD>|Z0;p3(*Um|cp>Q~T7l(*{sGf}6FZptA75mFRogo$M*o}u9I{{ssLatK z^dV*!Cx`#W$nfZhlS35a7feFePXDn>7EzEMW4wX&9XCNYf*b;o!aAt?*2NQ6h#khL zTjy#w!b!+N<}pIZm{jW>GB=S4(z9VF0}9{ta7ioiqUVlyhr_iGX@RhaXe`G9e!MYkhf|2hz%8p(dkn zob+71A5#!o={E(3Sb(&61RLD)fue-s-_yq}K!*eXL*%~O%S&@~m4an9aTd0$Jq)RG-wzteFJH*3#dCgJbE21%H+#p*g1XuZ+ajg`eNMGVYA`Gs7& zEAd-0QUDSua>+DJ-!RVy&BsyUy0DZ$`{La%V2=3mI7Nb|2=1CYad+8CTU=P_n>2Vi zTS6p>cPoVpTiD+tKdkQ?;{`silSwO{`F`q>fhIo#I$i0_REinC=v{t9AjK|70U+x% za5kOX)eN|UQu-!=9e!(R+ylS0!n_3&ir12H+=>6lx~A&mUGOZyDN9ryyB}zp{Vb>2 z1KC!YZ zRMXUHz=-*6T%jx~7Iz1LN4b0nWNkCyG43;Vyob}E7WLcnie|qNz)218?48^$D6m8<07+IadtP+yHwpvA zF8nqYXU`*4++$*&^w&P!Z&VOhs&D-=2Q&KM$ekrvO|*na(cwz)$WJ^KRykZTf>_uJ z07YV0p&riFPN98S`8$ie0L8khK)_14MKyK_9LDc-Pio3@uAo-r!vy;|u0ek0z@7C0kwB6FjupmF0{2(c(iidyz` z;l-(%`&t0~X1pa0Muvs&Df$$e@5GN(R_@E95(Z#Kzb-kJ6i?!1JU?ojygBFTBr6R3 zww?ySsJ7QSey*-8xR=(^3F?YfP$gegnqdQftol#0NPtmFd!u0o?yO2IAlzh(szJEk z*-^WezQQ{s-ia+W%vCGp``i3^FlpbuP+W&nZn+{X#D9 z;)E5}0VLMLMaGSM$?Z~f`59#zl{v9Fm6ik*0CGxsM<34(dz(xwS)l&9Ov& zdpCdwVj*dB%kA~+S1(!nD;dIye|NFue}@@u??gp7x$54EBQ%YDB0EZMPJQ{lVidjm zVE~reWlasClx?d6NeaICdO0mJ&_+9vQ%trxF?-h5^8Azi_ws{md}=eMNUbq|^z@ngq9u4U3r74RElu5aOOgU7i@P z#N&Sb0f_HGGw_*1R>v+$tT;O32$mJJNOnp0|1kLLS<>kTN+-9ZB+x||oVMecvA54r&wRp6l2mz+D^T#y>ozZ_=M7zP%8>$gR|KcW1wBD~(El z^io2Joq(P>2FTSGOWc|kR_giItKLcGCy;x~kIYXnV8e;8r zDbwi?U?;H0D#{=Hn%s{#&GjKrA>ZIAlSZeGg-O{(Ri-&u{R2uO+^z1MwlllWGB#JY zu7Mli^Amey!WVBd>c}hy%PcAW#b5*We<-7F%DAy5XMSKmwlr0l>er^JBMi+D_0?6T zR)n2kT=kE>;`6rJ=A?@mY{mn>8W4CnCgRKgJ|}2ut5c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU&_u!9QqR!T z%-qskN5Kfl*Eg`xH!{#Qu(UEYwlXkMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@w*YQzUNJP7fB~jokyxN_sAmB35=^15FMg%Dxp39RB|)hO_hL1;IHa;5 zRX-@TIKQ+g85nVC${?!>telHd6HD@oLh|!-V4)b0kzbNuoRMFk;OqX$Y%oHn2GYeA-V>2f=BS#}cLst_gQzKUkV@GFK z6GIDAOLG&LUYGpj(%jU%5}4i;gkEQydO-;yw*Y9fOKMSOS!#+~QGTuh*yC22xZPrj z(>$o&6x?oc#Hm*w=oo!a^ddz!ObD2UKumbz1#;lYKQ#}S=8J%d+is@!1O^7CL!K^< zAr-gQO!M^!2^2a0|NGgV#b>6-e`z$mz+St8TU=3BSt)8uCy#1(lUd-l6}>`hMVd}* zTiDHYO2K`_f?CImR!w25ty6nbTl;>jHU9i-{?7b$`OCh`9Jl&#c&G9Af9H38zf-(U z>+%+U?Hgr9O)@H_Da?US%q5ldPX>Rw=uhfq-gu1uFBMP@pD!J4uS2DWES zIlYeE@q0IE@uudpe?A;`F*9PidWR=wA5%zi^1}^f0vtPJ0u<(6@)O%}xl`rBb#7}r zh9gPuV&4d`%bwf$(&N;r1^4z`6`Y>&?Vp;$%qzREm&H0+C8hcJGJfT~_h|FxqqZg{ z8NI32DtzB&BwC$KnOg1seS>`2ZO>_!((BouK8-qjl~daE-jdOrY3iutW+_iFS`t5uQSFb#4X&iMXbNPuF-wY_1b->UhI@~TU=tk<(ryf_TtLi zH&ZQMm^<&>&l&b4RL=R)?0dd-m$=UL?$mGqzFF_uJm)Rx5*KgWX*uu9l05x0!P{ iN3H*)wSA*K6A#0U+?(G`6Idfa<-Dh>pUXO@geCx>fM_WI diff --git a/doc/_themes/saltstack2/static/js/bootstrap.min.js b/doc/_themes/saltstack2/static/js/bootstrap.min.js deleted file mode 100755 index 47fcb5b9e8..0000000000 --- a/doc/_themes/saltstack2/static/js/bootstrap.min.js +++ /dev/null @@ -1,12 +0,0 @@ -/*! - * Bootstrap v3.3.4 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -/*! - * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=3f6728c89fade52edc55) - * Config saved to config.json and https://gist.github.com/3f6728c89fade52edc55 - */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){"use strict";var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.alert");n||i.data("bs.alert",n=new o(this)),"string"==typeof e&&n[e].call(i)})}var i='[data-dismiss="alert"]',o=function(e){t(e).on("click",i,this.close)};o.VERSION="3.3.4",o.TRANSITION_DURATION=150,o.prototype.close=function(e){function i(){a.detach().trigger("closed.bs.alert").remove()}var n=t(this),s=n.attr("data-target");s||(s=n.attr("href"),s=s&&s.replace(/.*(?=#[^\s]*$)/,""));var a=t(s);e&&e.preventDefault(),a.length||(a=n.closest(".alert")),a.trigger(e=t.Event("close.bs.alert")),e.isDefaultPrevented()||(a.removeClass("in"),t.support.transition&&a.hasClass("fade")?a.one("bsTransitionEnd",i).emulateTransitionEnd(o.TRANSITION_DURATION):i())};var n=t.fn.alert;t.fn.alert=e,t.fn.alert.Constructor=o,t.fn.alert.noConflict=function(){return t.fn.alert=n,this},t(document).on("click.bs.alert.data-api",i,o.prototype.close)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.button"),s="object"==typeof e&&e;n||o.data("bs.button",n=new i(this,s)),"toggle"==e?n.toggle():e&&n.setState(e)})}var i=function(e,o){this.$element=t(e),this.options=t.extend({},i.DEFAULTS,o),this.isLoading=!1};i.VERSION="3.3.4",i.DEFAULTS={loadingText:"loading..."},i.prototype.setState=function(e){var i="disabled",o=this.$element,n=o.is("input")?"val":"html",s=o.data();e+="Text",null==s.resetText&&o.data("resetText",o[n]()),setTimeout(t.proxy(function(){o[n](null==s[e]?this.options[e]:s[e]),"loadingText"==e?(this.isLoading=!0,o.addClass(i).attr(i,i)):this.isLoading&&(this.isLoading=!1,o.removeClass(i).removeAttr(i))},this),0)},i.prototype.toggle=function(){var t=!0,e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var i=this.$element.find("input");"radio"==i.prop("type")&&(i.prop("checked")&&this.$element.hasClass("active")?t=!1:e.find(".active").removeClass("active")),t&&i.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));t&&this.$element.toggleClass("active")};var o=t.fn.button;t.fn.button=e,t.fn.button.Constructor=i,t.fn.button.noConflict=function(){return t.fn.button=o,this},t(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(i){var o=t(i.target);o.hasClass("btn")||(o=o.closest(".btn")),e.call(o,"toggle"),i.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){t(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))})}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.carousel"),s=t.extend({},i.DEFAULTS,o.data(),"object"==typeof e&&e),a="string"==typeof e?e:s.slide;n||o.data("bs.carousel",n=new i(this,s)),"number"==typeof e?n.to(e):a?n[a]():s.interval&&n.pause().cycle()})}var i=function(e,i){this.$element=t(e),this.$indicators=this.$element.find(".carousel-indicators"),this.options=i,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",t.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",t.proxy(this.pause,this)).on("mouseleave.bs.carousel",t.proxy(this.cycle,this))};i.VERSION="3.3.4",i.TRANSITION_DURATION=600,i.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},i.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},i.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(t.proxy(this.next,this),this.options.interval)),this},i.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},i.prototype.getItemForDirection=function(t,e){var i=this.getItemIndex(e),o="prev"==t&&0===i||"next"==t&&i==this.$items.length-1;if(o&&!this.options.wrap)return e;var n="prev"==t?-1:1,s=(i+n)%this.$items.length;return this.$items.eq(s)},i.prototype.to=function(t){var e=this,i=this.getItemIndex(this.$active=this.$element.find(".item.active"));return t>this.$items.length-1||0>t?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",this.$items.eq(t))},i.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&t.support.transition&&(this.$element.trigger(t.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},i.prototype.next=function(){return this.sliding?void 0:this.slide("next")},i.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},i.prototype.slide=function(e,o){var n=this.$element.find(".item.active"),s=o||this.getItemForDirection(e,n),a=this.interval,r="next"==e?"left":"right",l=this;if(s.hasClass("active"))return this.sliding=!1;var h=s[0],d=t.Event("slide.bs.carousel",{relatedTarget:h,direction:r});if(this.$element.trigger(d),!d.isDefaultPrevented()){if(this.sliding=!0,a&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var p=t(this.$indicators.children()[this.getItemIndex(s)]);p&&p.addClass("active")}var c=t.Event("slid.bs.carousel",{relatedTarget:h,direction:r});return t.support.transition&&this.$element.hasClass("slide")?(s.addClass(e),s[0].offsetWidth,n.addClass(r),s.addClass(r),n.one("bsTransitionEnd",function(){s.removeClass([e,r].join(" ")).addClass("active"),n.removeClass(["active",r].join(" ")),l.sliding=!1,setTimeout(function(){l.$element.trigger(c)},0)}).emulateTransitionEnd(i.TRANSITION_DURATION)):(n.removeClass("active"),s.addClass("active"),this.sliding=!1,this.$element.trigger(c)),a&&this.cycle(),this}};var o=t.fn.carousel;t.fn.carousel=e,t.fn.carousel.Constructor=i,t.fn.carousel.noConflict=function(){return t.fn.carousel=o,this};var n=function(i){var o,n=t(this),s=t(n.attr("data-target")||(o=n.attr("href"))&&o.replace(/.*(?=#[^\s]+$)/,""));if(s.hasClass("carousel")){var a=t.extend({},s.data(),n.data()),r=n.attr("data-slide-to");r&&(a.interval=!1),e.call(s,a),r&&s.data("bs.carousel").to(r),i.preventDefault()}};t(document).on("click.bs.carousel.data-api","[data-slide]",n).on("click.bs.carousel.data-api","[data-slide-to]",n),t(window).on("load",function(){t('[data-ride="carousel"]').each(function(){var i=t(this);e.call(i,i.data())})})}(jQuery),+function(t){"use strict";function e(e){e&&3===e.which||(t(n).remove(),t(s).each(function(){var o=t(this),n=i(o),s={relatedTarget:this};n.hasClass("open")&&(n.trigger(e=t.Event("hide.bs.dropdown",s)),e.isDefaultPrevented()||(o.attr("aria-expanded","false"),n.removeClass("open").trigger("hidden.bs.dropdown",s)))}))}function i(e){var i=e.attr("data-target");i||(i=e.attr("href"),i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,""));var o=i&&t(i);return o&&o.length?o:e.parent()}function o(e){return this.each(function(){var i=t(this),o=i.data("bs.dropdown");o||i.data("bs.dropdown",o=new a(this)),"string"==typeof e&&o[e].call(i)})}var n=".dropdown-backdrop",s='[data-toggle="dropdown"]',a=function(e){t(e).on("click.bs.dropdown",this.toggle)};a.VERSION="3.3.4",a.prototype.toggle=function(o){var n=t(this);if(!n.is(".disabled, :disabled")){var s=i(n),a=s.hasClass("open");if(e(),!a){"ontouchstart"in document.documentElement&&!s.closest(".navbar-nav").length&&t('

',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},i.prototype.init=function(e,i,o){if(this.enabled=!0,this.type=e,this.$element=t(i),this.options=this.getOptions(o),this.$viewport=this.options.viewport&&t(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var n=this.options.trigger.split(" "),s=n.length;s--;){var a=n[s];if("click"==a)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=a){var r="hover"==a?"mouseenter":"focusin",l="hover"==a?"mouseleave":"focusout";this.$element.on(r+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(l+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},i.prototype.getDelegateOptions=function(){var e={},i=this.getDefaults();return this._options&&t.each(this._options,function(t,o){i[t]!=o&&(e[t]=o)}),e},i.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i&&i.$tip&&i.$tip.is(":visible")?void(i.hoverState="in"):(i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())},i.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide()},i.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var o=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!o)return;var n=this,s=this.tip(),a=this.getUID(this.type);this.setContent(),s.attr("id",a),this.$element.attr("aria-describedby",a),this.options.animation&&s.addClass("fade");var r="function"==typeof this.options.placement?this.options.placement.call(this,s[0],this.$element[0]):this.options.placement,l=/\s?auto?\s?/i,h=l.test(r);h&&(r=r.replace(l,"")||"top"),s.detach().css({top:0,left:0,display:"block"}).addClass(r).data("bs."+this.type,this),this.options.container?s.appendTo(this.options.container):s.insertAfter(this.$element);var d=this.getPosition(),p=s[0].offsetWidth,c=s[0].offsetHeight;if(h){var f=r,u=this.options.container?t(this.options.container):this.$element.parent(),g=this.getPosition(u);r="bottom"==r&&d.bottom+c>g.bottom?"top":"top"==r&&d.top-cg.width?"left":"left"==r&&d.left-pa.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.width&&(n.left=a.left+a.width-d)}return n},i.prototype.getTitle=function(){var t,e=this.$element,i=this.options;return t=e.attr("data-original-title")||("function"==typeof i.title?i.title.call(e[0]):i.title)},i.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},i.prototype.tip=function(){return this.$tip=this.$tip||t(this.options.template)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},i.prototype.enable=function(){this.enabled=!0},i.prototype.disable=function(){this.enabled=!1},i.prototype.toggleEnabled=function(){this.enabled=!this.enabled},i.prototype.toggle=function(e){var i=this;e&&(i=t(e.currentTarget).data("bs."+this.type),i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i))),i.tip().hasClass("in")?i.leave(i):i.enter(i)},i.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type)})};var o=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=i,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.popover"),s="object"==typeof e&&e;(n||!/destroy|hide/.test(e))&&(n||o.data("bs.popover",n=new i(this,s)),"string"==typeof e&&n[e]())})}var i=function(t,e){this.init("popover",t,e)};if(!t.fn.tooltip)throw new Error("Popover requires tooltip.js");i.VERSION="3.3.4",i.DEFAULTS=t.extend({},t.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),i.prototype=t.extend({},t.fn.tooltip.Constructor.prototype),i.prototype.constructor=i,i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},i.prototype.hasContent=function(){return this.getTitle()||this.getContent()},i.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var o=t.fn.popover;t.fn.popover=e,t.fn.popover.Constructor=i,t.fn.popover.noConflict=function(){return t.fn.popover=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.tab");n||o.data("bs.tab",n=new i(this)),"string"==typeof e&&n[e]()})}var i=function(e){this.element=t(e)};i.VERSION="3.3.4",i.TRANSITION_DURATION=150,i.prototype.show=function(){var e=this.element,i=e.closest("ul:not(.dropdown-menu)"),o=e.data("target");if(o||(o=e.attr("href"),o=o&&o.replace(/.*(?=#[^\s]*$)/,"")),!e.parent("li").hasClass("active")){var n=i.find(".active:last a"),s=t.Event("hide.bs.tab",{relatedTarget:e[0]}),a=t.Event("show.bs.tab",{relatedTarget:n[0]});if(n.trigger(s),e.trigger(a),!a.isDefaultPrevented()&&!s.isDefaultPrevented()){var r=t(o);this.activate(e.closest("li"),i),this.activate(r,r.parent(),function(){n.trigger({type:"hidden.bs.tab",relatedTarget:e[0]}),e.trigger({type:"shown.bs.tab",relatedTarget:n[0]})})}}},i.prototype.activate=function(e,o,n){function s(){a.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),r?(e[0].offsetWidth,e.addClass("in")):e.removeClass("fade"),e.parent(".dropdown-menu").length&&e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),n&&n()}var a=o.find("> .active"),r=n&&t.support.transition&&(a.length&&a.hasClass("fade")||!!o.find("> .fade").length);a.length&&r?a.one("bsTransitionEnd",s).emulateTransitionEnd(i.TRANSITION_DURATION):s(),a.removeClass("in")};var o=t.fn.tab;t.fn.tab=e,t.fn.tab.Constructor=i,t.fn.tab.noConflict=function(){return t.fn.tab=o,this};var n=function(i){i.preventDefault(),e.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',n).on("click.bs.tab.data-api",'[data-toggle="pill"]',n)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.affix"),s="object"==typeof e&&e;n||o.data("bs.affix",n=new i(this,s)),"string"==typeof e&&n[e]()})}var i=function(e,o){this.options=t.extend({},i.DEFAULTS,o),this.$target=t(this.options.target).on("scroll.bs.affix.data-api",t.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",t.proxy(this.checkPositionWithEventLoop,this)),this.$element=t(e),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};i.VERSION="3.3.4",i.RESET="affix affix-top affix-bottom",i.DEFAULTS={offset:0,target:window},i.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return i>n?"top":!1;if("bottom"==this.affixed)return null!=i?n+this.unpin<=s.top?!1:"bottom":t-o>=n+a?!1:"bottom";var r=null==this.affixed,l=r?n:s.top,h=r?a:e;return null!=i&&i>=n?"top":null!=o&&l+h>=t-o?"bottom":!1},i.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(i.RESET).addClass("affix");var t=this.$target.scrollTop(),e=this.$element.offset();return this.pinnedOffset=e.top-t},i.prototype.checkPositionWithEventLoop=function(){setTimeout(t.proxy(this.checkPosition,this),1)},i.prototype.checkPosition=function(){if(this.$element.is(":visible")){var e=this.$element.height(),o=this.options.offset,n=o.top,s=o.bottom,a=t(document.body).height();"object"!=typeof o&&(s=n=o),"function"==typeof n&&(n=o.top(this.$element)),"function"==typeof s&&(s=o.bottom(this.$element));var r=this.getState(a,e,n,s);if(this.affixed!=r){null!=this.unpin&&this.$element.css("top","");var l="affix"+(r?"-"+r:""),h=t.Event(l+".bs.affix");if(this.$element.trigger(h),h.isDefaultPrevented())return;this.affixed=r,this.unpin="bottom"==r?this.getPinnedOffset():null,this.$element.removeClass(i.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==r&&this.$element.offset({top:a-e-s})}};var o=t.fn.affix;t.fn.affix=e,t.fn.affix.Constructor=i,t.fn.affix.noConflict=function(){return t.fn.affix=o,this},t(window).on("load",function(){t('[data-spy="affix"]').each(function(){var i=t(this),o=i.data();o.offset=o.offset||{},null!=o.offsetBottom&&(o.offset.bottom=o.offsetBottom),null!=o.offsetTop&&(o.offset.top=o.offsetTop),e.call(i,o)})})}(jQuery),+function(t){"use strict";function e(e){var i,o=e.attr("data-target")||(i=e.attr("href"))&&i.replace(/.*(?=#[^\s]+$)/,"");return t(o)}function i(e){return this.each(function(){var i=t(this),n=i.data("bs.collapse"),s=t.extend({},o.DEFAULTS,i.data(),"object"==typeof e&&e);!n&&s.toggle&&/show|hide/.test(e)&&(s.toggle=!1),n||i.data("bs.collapse",n=new o(this,s)),"string"==typeof e&&n[e]()})}var o=function(e,i){this.$element=t(e),this.options=t.extend({},o.DEFAULTS,i),this.$trigger=t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};o.VERSION="3.3.4",o.TRANSITION_DURATION=350,o.DEFAULTS={toggle:!0},o.prototype.dimension=function(){var t=this.$element.hasClass("width");return t?"width":"height"},o.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var e,n=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(n&&n.length&&(e=n.data("bs.collapse"),e&&e.transitioning))){var s=t.Event("show.bs.collapse");if(this.$element.trigger(s),!s.isDefaultPrevented()){n&&n.length&&(i.call(n,"hide"),e||n.data("bs.collapse",null));var a=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[a](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var r=function(){this.$element.removeClass("collapsing").addClass("collapse in")[a](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!t.support.transition)return r.call(this);var l=t.camelCase(["scroll",a].join("-"));this.$element.one("bsTransitionEnd",t.proxy(r,this)).emulateTransitionEnd(o.TRANSITION_DURATION)[a](this.$element[0][l])}}}},o.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var e=t.Event("hide.bs.collapse");if(this.$element.trigger(e),!e.isDefaultPrevented()){var i=this.dimension();this.$element[i](this.$element[i]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var n=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return t.support.transition?void this.$element[i](0).one("bsTransitionEnd",t.proxy(n,this)).emulateTransitionEnd(o.TRANSITION_DURATION):n.call(this)}}},o.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},o.prototype.getParent=function(){return t(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(t.proxy(function(i,o){var n=t(o); -this.addAriaAndCollapsedClass(e(n),n)},this)).end()},o.prototype.addAriaAndCollapsedClass=function(t,e){var i=t.hasClass("in");t.attr("aria-expanded",i),e.toggleClass("collapsed",!i).attr("aria-expanded",i)};var n=t.fn.collapse;t.fn.collapse=i,t.fn.collapse.Constructor=o,t.fn.collapse.noConflict=function(){return t.fn.collapse=n,this},t(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(o){var n=t(this);n.attr("data-target")||o.preventDefault();var s=e(n),a=s.data("bs.collapse"),r=a?"toggle":n.data();i.call(s,r)})}(jQuery),+function(t){"use strict";function e(i,o){this.$body=t(document.body),this.$scrollElement=t(t(i).is(document.body)?window:i),this.options=t.extend({},e.DEFAULTS,o),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",t.proxy(this.process,this)),this.refresh(),this.process()}function i(i){return this.each(function(){var o=t(this),n=o.data("bs.scrollspy"),s="object"==typeof i&&i;n||o.data("bs.scrollspy",n=new e(this,s)),"string"==typeof i&&n[i]()})}e.VERSION="3.3.4",e.DEFAULTS={offset:10},e.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},e.prototype.refresh=function(){var e=this,i="offset",o=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),t.isWindow(this.$scrollElement[0])||(i="position",o=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var e=t(this),n=e.data("target")||e.attr("href"),s=/^#./.test(n)&&t(n);return s&&s.length&&s.is(":visible")&&[[s[i]().top+o,n]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){e.offsets.push(this[0]),e.targets.push(this[1])})},e.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),e>=o)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(void 0===n[t+1]||e
").appendTo(a("body")),this.$lightbox=a("#lightbox"),this.$overlay=a("#lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".lb-outerContainer"),this.$container=this.$lightbox.find(".lb-container"),this.containerTopPadding=parseInt(this.$container.css("padding-top"),10),this.containerRightPadding=parseInt(this.$container.css("padding-right"),10),this.containerBottomPadding=parseInt(this.$container.css("padding-bottom"),10),this.containerLeftPadding=parseInt(this.$container.css("padding-left"),10),this.$overlay.hide().on("click",function(){return b.end(),!1}),this.$lightbox.hide().on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$outerContainer.on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$lightbox.find(".lb-prev").on("click",function(){return b.changeImage(0===b.currentImageIndex?b.album.length-1:b.currentImageIndex-1),!1}),this.$lightbox.find(".lb-next").on("click",function(){return b.changeImage(b.currentImageIndex===b.album.length-1?0:b.currentImageIndex+1),!1}),this.$lightbox.find(".lb-loader, .lb-close").on("click",function(){return b.end(),!1})},b.prototype.start=function(b){function c(a){d.album.push({link:a.attr("href"),title:a.attr("data-title")||a.attr("title")})}var d=this,e=a(window);e.on("resize",a.proxy(this.sizeOverlay,this)),a("select, object, embed").css({visibility:"hidden"}),this.sizeOverlay(),this.album=[];var f,g=0,h=b.attr("data-lightbox");if(h){f=a(b.prop("tagName")+'[data-lightbox="'+h+'"]');for(var i=0;ij||e.height>i)&&(e.width/j>e.height/i?(h=j,g=parseInt(e.height/(e.width/h),10),d.width(h),d.height(g)):(g=i,h=parseInt(e.width/(e.height/g),10),d.width(h),d.height(g)))),c.sizeContainer(d.width(),d.height())},e.src=this.album[b].link,this.currentImageIndex=b},b.prototype.sizeOverlay=function(){this.$overlay.width(a(window).width()).height(a(document).height())},b.prototype.sizeContainer=function(a,b){function c(){d.$lightbox.find(".lb-dataContainer").width(g),d.$lightbox.find(".lb-prevLink").height(h),d.$lightbox.find(".lb-nextLink").height(h),d.showImage()}var d=this,e=this.$outerContainer.outerWidth(),f=this.$outerContainer.outerHeight(),g=a+this.containerLeftPadding+this.containerRightPadding,h=b+this.containerTopPadding+this.containerBottomPadding;e!==g||f!==h?this.$outerContainer.animate({width:g,height:h},this.options.resizeDuration,"swing",function(){c()}):c()},b.prototype.showImage=function(){this.$lightbox.find(".lb-loader").hide(),this.$lightbox.find(".lb-image").fadeIn("slow"),this.updateNav(),this.updateDetails(),this.preloadNeighboringImages(),this.enableKeyboardNav()},b.prototype.updateNav=function(){var a=!1;try{document.createEvent("TouchEvent"),a=this.options.alwaysShowNavOnTouchDevices?!0:!1}catch(b){}this.$lightbox.find(".lb-nav").show(),this.album.length>1&&(this.options.wrapAround?(a&&this.$lightbox.find(".lb-prev, .lb-next").css("opacity","1"),this.$lightbox.find(".lb-prev, .lb-next").show()):(this.currentImageIndex>0&&(this.$lightbox.find(".lb-prev").show(),a&&this.$lightbox.find(".lb-prev").css("opacity","1")),this.currentImageIndex1&&this.options.showImageNumberLabel?this.$lightbox.find(".lb-number").text(this.options.albumLabel(this.currentImageIndex+1,this.album.length)).fadeIn("fast"):this.$lightbox.find(".lb-number").hide(),this.$outerContainer.removeClass("animating"),this.$lightbox.find(".lb-dataContainer").fadeIn(this.options.resizeDuration,function(){return b.sizeOverlay()})},b.prototype.preloadNeighboringImages=function(){if(this.album.length>this.currentImageIndex+1){var a=new Image;a.src=this.album[this.currentImageIndex+1].link}if(this.currentImageIndex>0){var b=new Image;b.src=this.album[this.currentImageIndex-1].link}},b.prototype.enableKeyboardNav=function(){a(document).on("keyup.keyboard",a.proxy(this.keyboardAction,this))},b.prototype.disableKeyboardNav=function(){a(document).off(".keyboard")},b.prototype.keyboardAction=function(a){var b=27,c=37,d=39,e=a.keyCode,f=String.fromCharCode(e).toLowerCase();e===b||f.match(/x|o|c/)?this.end():"p"===f||e===c?0!==this.currentImageIndex?this.changeImage(this.currentImageIndex-1):this.options.wrapAround&&this.album.length>1&&this.changeImage(this.album.length-1):("n"===f||e===d)&&(this.currentImageIndex!==this.album.length-1?this.changeImage(this.currentImageIndex+1):this.options.wrapAround&&this.album.length>1&&this.changeImage(0))},b.prototype.end=function(){this.disableKeyboardNav(),a(window).off("resize",this.sizeOverlay),this.$lightbox.fadeOut(this.options.fadeDuration),this.$overlay.fadeOut(this.options.fadeDuration),a("select, object, embed").css({visibility:"visible"})},b}();a(function(){{var a=new b;new c(a)}})}).call(this); -/*custom webhelp*/ -var windowheight = $( window ).height(); -$( document ).ready(function() { - /*lightbox around images*/ +/** + * bootbox.js v4.4.0 + * + * http://bootboxjs.com/license.txt + */ +!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"",header:"",footer:"",closeButton:"",form:"
",inputs:{text:"",textarea:"",email:"",select:"",checkbox:"
",date:"",time:"",number:"",password:""}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("").attr("label",d.group)),e=o[d.group]),e.append("")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("
"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".modal-dialog"),i=d.find(".modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+="",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("modal-lg"):"small"===a.size&&f.addClass("modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".modal-backdrop").length&&(a.currentTarget=d.children(".modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p}); - $( 'img' ).not( '.nolightbox' ).each(function() { - var source = $(this).attr( 'src' ); - var id = $(this).attr( 'id' ); - $(this).wrap('' ) - }); +/*! + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ - /*enable bootstrap tooltips*/ - $(function () { - $('[data-toggle="tooltip"]').tooltip() - }); - - - if ($( 'a.current' ).length) { - - var tgt = $( 'a.current' ); - - tgt.after('
    '); - $('dt .headerlink').each(function(idx, elem) { - - var i = [ - '
  • ', - last(elem.href.split('.')), - '
  • '] - .join(''); - - $( '#function-list' ).append(i); - }); - } - - /*scroll the right-hand navigation*/ - var wheight = $( window ).height() - $( '#sidebar-static' ).height(); - $(function(){ - $( '#sidebar-nav' ).slimScroll({ - width: 'inherit', - size: '14px', - height: wheight - }).promise().done(function() { - - if (window.location.hash) { - var hash = window.location.hash.substring(1); - var $link = $( '#sidebar-nav').find('a[href$="#' + hash + '"]').addClass("selected"); - if ($link.length) { - var scrollTo_val = $link.offset().top - 300 + 'px'; - $( '#sidebar-nav' ).slimScroll({ scrollTo : scrollTo_val }); - } - else if ($( 'a.current' ).length) { - var scrollTo_val = $( 'a.current' ).offset().top - 300 + 'px'; - $( '#sidebar-nav' ).slimScroll({ scrollTo : scrollTo_val }); - } - } - else if ($( 'a.current' ).length) { - var scrollTo_val = $( 'a.current' ).offset().top - 300 + 'px'; - $( '#sidebar-nav' ).slimScroll({ scrollTo : scrollTo_val }); - } - }); - }); - - /*permalink display*/ - $( 'a.headerlink').html( ''); - - $( 'h1,h2,h3,h4,h5,h6').mouseenter(function(){ - $(this).find( '.permalink' ).find( 'i' ).css({'color':'#000'}); - }).mouseleave(function(){ - $(this).find( '.permalink' ).find( 'i' ).css({'color':'#fff'}); - }); - - /*smooth on-page scrolling for long topic*/ - $( '#sidebar-nav' ).on('click','a[href^="#"]',function (e) { - e.preventDefault(); - $( '#sidebar-nav' ).find( 'a' ).removeClass('selected'); - $(this).addClass('selected'); - var target = this.hash; - var $target = $(target); - - $('html, body').stop().animate({ - 'scrollTop': $target.offset().top - }, 900, 'swing', function () { - window.location.hash = target; - }); - }); - - $( '#sidebar-nav' ).on('click','a.function-nav-link',function (e) { - e.preventDefault(); - $( 'a.function-nav-link' ).removeClass('selected'); - $(this).addClass('selected'); - var target = this.hash.substring(1); - var $target = $('dt[id="' + target + '"]'); - - $('html, body').stop().animate({ - 'scrollTop': $target.offset().top - }, 900, 'swing', function () { - window.location.hash = target; - }); - }); - - /*search form*/ - $( '#search-form' ).find( 'input' ).keypress(function(e) { - - if(e.which == 13) { - var cx = '004624818632696854117:yfmprrbw3pk&q='; - 'find which search instance to use' - if (DOCUMENTATION_OPTIONS.SEARCH_CX) { - cx = DOCUMENTATION_OPTIONS.SEARCH_CX; - } - var searchterm = encodeURIComponent($(this).val()); - $(this).val(""); - window.location.href = 'https://www.google.com/cse?cx=' + cx + '&q=' + searchterm; - } - }); - - /*menu collapse*/ - $( '#menu-toggle' ).click(function(e) { - e.preventDefault(); - $( '#wrapper' ).toggleClass( 'toggled' ); - }); - - $( 'div.versions' ).on('click', 'a', function (e) { - e.preventDefault(); - var clickedVer = $(this).attr("href"); - var $currentVer = $( 'a.selected-version' ); - if (window.location.href.indexOf(clickedVer) == -1) { - window.location.href = window.location.href.replace($currentVer.attr("href"), clickedVer); - } - else { - if ($currentVer.text().indexOf("develop") == -1) { - window.location.href = clickedVer + "topics/releases/" + $currentVer.text().trim() + ".html"; - } - else window.location.href = clickedVer + "topics/releases/"; - } - }); -}); // $.document.ready - -//refresh on window resize -var rtime = new Date(1, 1, 2000, 12,00,00); -var timeout = false; -var delta = 200; -$(window).resize(function() { - - if (!$( '#menu-toggle' ).is(":visible")) { - rtime = new Date(); - if (timeout === false) { - timeout = true; - setTimeout(resizeend, delta); - } - } -}); - -function resizeend() { - if (new Date() - rtime < delta) { - setTimeout(resizeend, delta); - } else { - timeout = false; - if ($( window ).height() > windowheight || $( window ).height() + 40 < windowheight) { - location.reload(false); - } - } -} - -function last(list) { - return list[list.length - 1]; -} +/*! + * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=3f6728c89fade52edc55) + * Config saved to config.json and https://gist.github.com/3f6728c89fade52edc55 + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){"use strict";var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.alert");n||i.data("bs.alert",n=new o(this)),"string"==typeof e&&n[e].call(i)})}var i='[data-dismiss="alert"]',o=function(e){t(e).on("click",i,this.close)};o.VERSION="3.3.4",o.TRANSITION_DURATION=150,o.prototype.close=function(e){function i(){a.detach().trigger("closed.bs.alert").remove()}var n=t(this),s=n.attr("data-target");s||(s=n.attr("href"),s=s&&s.replace(/.*(?=#[^\s]*$)/,""));var a=t(s);e&&e.preventDefault(),a.length||(a=n.closest(".alert")),a.trigger(e=t.Event("close.bs.alert")),e.isDefaultPrevented()||(a.removeClass("in"),t.support.transition&&a.hasClass("fade")?a.one("bsTransitionEnd",i).emulateTransitionEnd(o.TRANSITION_DURATION):i())};var n=t.fn.alert;t.fn.alert=e,t.fn.alert.Constructor=o,t.fn.alert.noConflict=function(){return t.fn.alert=n,this},t(document).on("click.bs.alert.data-api",i,o.prototype.close)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.button"),s="object"==typeof e&&e;n||o.data("bs.button",n=new i(this,s)),"toggle"==e?n.toggle():e&&n.setState(e)})}var i=function(e,o){this.$element=t(e),this.options=t.extend({},i.DEFAULTS,o),this.isLoading=!1};i.VERSION="3.3.4",i.DEFAULTS={loadingText:"loading..."},i.prototype.setState=function(e){var i="disabled",o=this.$element,n=o.is("input")?"val":"html",s=o.data();e+="Text",null==s.resetText&&o.data("resetText",o[n]()),setTimeout(t.proxy(function(){o[n](null==s[e]?this.options[e]:s[e]),"loadingText"==e?(this.isLoading=!0,o.addClass(i).attr(i,i)):this.isLoading&&(this.isLoading=!1,o.removeClass(i).removeAttr(i))},this),0)},i.prototype.toggle=function(){var t=!0,e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var i=this.$element.find("input");"radio"==i.prop("type")&&(i.prop("checked")&&this.$element.hasClass("active")?t=!1:e.find(".active").removeClass("active")),t&&i.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));t&&this.$element.toggleClass("active")};var o=t.fn.button;t.fn.button=e,t.fn.button.Constructor=i,t.fn.button.noConflict=function(){return t.fn.button=o,this},t(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(i){var o=t(i.target);o.hasClass("btn")||(o=o.closest(".btn")),e.call(o,"toggle"),i.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){t(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))})}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.carousel"),s=t.extend({},i.DEFAULTS,o.data(),"object"==typeof e&&e),a="string"==typeof e?e:s.slide;n||o.data("bs.carousel",n=new i(this,s)),"number"==typeof e?n.to(e):a?n[a]():s.interval&&n.pause().cycle()})}var i=function(e,i){this.$element=t(e),this.$indicators=this.$element.find(".carousel-indicators"),this.options=i,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",t.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",t.proxy(this.pause,this)).on("mouseleave.bs.carousel",t.proxy(this.cycle,this))};i.VERSION="3.3.4",i.TRANSITION_DURATION=600,i.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},i.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},i.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(t.proxy(this.next,this),this.options.interval)),this},i.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},i.prototype.getItemForDirection=function(t,e){var i=this.getItemIndex(e),o="prev"==t&&0===i||"next"==t&&i==this.$items.length-1;if(o&&!this.options.wrap)return e;var n="prev"==t?-1:1,s=(i+n)%this.$items.length;return this.$items.eq(s)},i.prototype.to=function(t){var e=this,i=this.getItemIndex(this.$active=this.$element.find(".item.active"));return t>this.$items.length-1||0>t?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",this.$items.eq(t))},i.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&t.support.transition&&(this.$element.trigger(t.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},i.prototype.next=function(){return this.sliding?void 0:this.slide("next")},i.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},i.prototype.slide=function(e,o){var n=this.$element.find(".item.active"),s=o||this.getItemForDirection(e,n),a=this.interval,r="next"==e?"left":"right",l=this;if(s.hasClass("active"))return this.sliding=!1;var h=s[0],d=t.Event("slide.bs.carousel",{relatedTarget:h,direction:r});if(this.$element.trigger(d),!d.isDefaultPrevented()){if(this.sliding=!0,a&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var p=t(this.$indicators.children()[this.getItemIndex(s)]);p&&p.addClass("active")}var c=t.Event("slid.bs.carousel",{relatedTarget:h,direction:r});return t.support.transition&&this.$element.hasClass("slide")?(s.addClass(e),s[0].offsetWidth,n.addClass(r),s.addClass(r),n.one("bsTransitionEnd",function(){s.removeClass([e,r].join(" ")).addClass("active"),n.removeClass(["active",r].join(" ")),l.sliding=!1,setTimeout(function(){l.$element.trigger(c)},0)}).emulateTransitionEnd(i.TRANSITION_DURATION)):(n.removeClass("active"),s.addClass("active"),this.sliding=!1,this.$element.trigger(c)),a&&this.cycle(),this}};var o=t.fn.carousel;t.fn.carousel=e,t.fn.carousel.Constructor=i,t.fn.carousel.noConflict=function(){return t.fn.carousel=o,this};var n=function(i){var o,n=t(this),s=t(n.attr("data-target")||(o=n.attr("href"))&&o.replace(/.*(?=#[^\s]+$)/,""));if(s.hasClass("carousel")){var a=t.extend({},s.data(),n.data()),r=n.attr("data-slide-to");r&&(a.interval=!1),e.call(s,a),r&&s.data("bs.carousel").to(r),i.preventDefault()}};t(document).on("click.bs.carousel.data-api","[data-slide]",n).on("click.bs.carousel.data-api","[data-slide-to]",n),t(window).on("load",function(){t('[data-ride="carousel"]').each(function(){var i=t(this);e.call(i,i.data())})})}(jQuery),+function(t){"use strict";function e(e){e&&3===e.which||(t(n).remove(),t(s).each(function(){var o=t(this),n=i(o),s={relatedTarget:this};n.hasClass("open")&&(n.trigger(e=t.Event("hide.bs.dropdown",s)),e.isDefaultPrevented()||(o.attr("aria-expanded","false"),n.removeClass("open").trigger("hidden.bs.dropdown",s)))}))}function i(e){var i=e.attr("data-target");i||(i=e.attr("href"),i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,""));var o=i&&t(i);return o&&o.length?o:e.parent()}function o(e){return this.each(function(){var i=t(this),o=i.data("bs.dropdown");o||i.data("bs.dropdown",o=new a(this)),"string"==typeof e&&o[e].call(i)})}var n=".dropdown-backdrop",s='[data-toggle="dropdown"]',a=function(e){t(e).on("click.bs.dropdown",this.toggle)};a.VERSION="3.3.4",a.prototype.toggle=function(o){var n=t(this);if(!n.is(".disabled, :disabled")){var s=i(n),a=s.hasClass("open");if(e(),!a){"ontouchstart"in document.documentElement&&!s.closest(".navbar-nav").length&&t('',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},i.prototype.init=function(e,i,o){if(this.enabled=!0,this.type=e,this.$element=t(i),this.options=this.getOptions(o),this.$viewport=this.options.viewport&&t(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var n=this.options.trigger.split(" "),s=n.length;s--;){var a=n[s];if("click"==a)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=a){var r="hover"==a?"mouseenter":"focusin",l="hover"==a?"mouseleave":"focusout";this.$element.on(r+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(l+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},i.prototype.getDelegateOptions=function(){var e={},i=this.getDefaults();return this._options&&t.each(this._options,function(t,o){i[t]!=o&&(e[t]=o)}),e},i.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i&&i.$tip&&i.$tip.is(":visible")?void(i.hoverState="in"):(i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())},i.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide()},i.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var o=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!o)return;var n=this,s=this.tip(),a=this.getUID(this.type);this.setContent(),s.attr("id",a),this.$element.attr("aria-describedby",a),this.options.animation&&s.addClass("fade");var r="function"==typeof this.options.placement?this.options.placement.call(this,s[0],this.$element[0]):this.options.placement,l=/\s?auto?\s?/i,h=l.test(r);h&&(r=r.replace(l,"")||"top"),s.detach().css({top:0,left:0,display:"block"}).addClass(r).data("bs."+this.type,this),this.options.container?s.appendTo(this.options.container):s.insertAfter(this.$element);var d=this.getPosition(),p=s[0].offsetWidth,c=s[0].offsetHeight;if(h){var f=r,u=this.options.container?t(this.options.container):this.$element.parent(),g=this.getPosition(u);r="bottom"==r&&d.bottom+c>g.bottom?"top":"top"==r&&d.top-cg.width?"left":"left"==r&&d.left-pa.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.width&&(n.left=a.left+a.width-d)}return n},i.prototype.getTitle=function(){var t,e=this.$element,i=this.options;return t=e.attr("data-original-title")||("function"==typeof i.title?i.title.call(e[0]):i.title)},i.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},i.prototype.tip=function(){return this.$tip=this.$tip||t(this.options.template)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},i.prototype.enable=function(){this.enabled=!0},i.prototype.disable=function(){this.enabled=!1},i.prototype.toggleEnabled=function(){this.enabled=!this.enabled},i.prototype.toggle=function(e){var i=this;e&&(i=t(e.currentTarget).data("bs."+this.type),i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i))),i.tip().hasClass("in")?i.leave(i):i.enter(i)},i.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type)})};var o=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=i,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.popover"),s="object"==typeof e&&e;(n||!/destroy|hide/.test(e))&&(n||o.data("bs.popover",n=new i(this,s)),"string"==typeof e&&n[e]())})}var i=function(t,e){this.init("popover",t,e)};if(!t.fn.tooltip)throw new Error("Popover requires tooltip.js");i.VERSION="3.3.4",i.DEFAULTS=t.extend({},t.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),i.prototype=t.extend({},t.fn.tooltip.Constructor.prototype),i.prototype.constructor=i,i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},i.prototype.hasContent=function(){return this.getTitle()||this.getContent()},i.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var o=t.fn.popover;t.fn.popover=e,t.fn.popover.Constructor=i,t.fn.popover.noConflict=function(){return t.fn.popover=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.tab");n||o.data("bs.tab",n=new i(this)),"string"==typeof e&&n[e]()})}var i=function(e){this.element=t(e)};i.VERSION="3.3.4",i.TRANSITION_DURATION=150,i.prototype.show=function(){var e=this.element,i=e.closest("ul:not(.dropdown-menu)"),o=e.data("target");if(o||(o=e.attr("href"),o=o&&o.replace(/.*(?=#[^\s]*$)/,"")),!e.parent("li").hasClass("active")){var n=i.find(".active:last a"),s=t.Event("hide.bs.tab",{relatedTarget:e[0]}),a=t.Event("show.bs.tab",{relatedTarget:n[0]});if(n.trigger(s),e.trigger(a),!a.isDefaultPrevented()&&!s.isDefaultPrevented()){var r=t(o);this.activate(e.closest("li"),i),this.activate(r,r.parent(),function(){n.trigger({type:"hidden.bs.tab",relatedTarget:e[0]}),e.trigger({type:"shown.bs.tab",relatedTarget:n[0]})})}}},i.prototype.activate=function(e,o,n){function s(){a.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),r?(e[0].offsetWidth,e.addClass("in")):e.removeClass("fade"),e.parent(".dropdown-menu").length&&e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),n&&n()}var a=o.find("> .active"),r=n&&t.support.transition&&(a.length&&a.hasClass("fade")||!!o.find("> .fade").length);a.length&&r?a.one("bsTransitionEnd",s).emulateTransitionEnd(i.TRANSITION_DURATION):s(),a.removeClass("in")};var o=t.fn.tab;t.fn.tab=e,t.fn.tab.Constructor=i,t.fn.tab.noConflict=function(){return t.fn.tab=o,this};var n=function(i){i.preventDefault(),e.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',n).on("click.bs.tab.data-api",'[data-toggle="pill"]',n)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.affix"),s="object"==typeof e&&e;n||o.data("bs.affix",n=new i(this,s)),"string"==typeof e&&n[e]()})}var i=function(e,o){this.options=t.extend({},i.DEFAULTS,o),this.$target=t(this.options.target).on("scroll.bs.affix.data-api",t.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",t.proxy(this.checkPositionWithEventLoop,this)),this.$element=t(e),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};i.VERSION="3.3.4",i.RESET="affix affix-top affix-bottom",i.DEFAULTS={offset:0,target:window},i.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return i>n?"top":!1;if("bottom"==this.affixed)return null!=i?n+this.unpin<=s.top?!1:"bottom":t-o>=n+a?!1:"bottom";var r=null==this.affixed,l=r?n:s.top,h=r?a:e;return null!=i&&i>=n?"top":null!=o&&l+h>=t-o?"bottom":!1},i.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(i.RESET).addClass("affix");var t=this.$target.scrollTop(),e=this.$element.offset();return this.pinnedOffset=e.top-t},i.prototype.checkPositionWithEventLoop=function(){setTimeout(t.proxy(this.checkPosition,this),1)},i.prototype.checkPosition=function(){if(this.$element.is(":visible")){var e=this.$element.height(),o=this.options.offset,n=o.top,s=o.bottom,a=t(document.body).height();"object"!=typeof o&&(s=n=o),"function"==typeof n&&(n=o.top(this.$element)),"function"==typeof s&&(s=o.bottom(this.$element));var r=this.getState(a,e,n,s);if(this.affixed!=r){null!=this.unpin&&this.$element.css("top","");var l="affix"+(r?"-"+r:""),h=t.Event(l+".bs.affix");if(this.$element.trigger(h),h.isDefaultPrevented())return;this.affixed=r,this.unpin="bottom"==r?this.getPinnedOffset():null,this.$element.removeClass(i.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==r&&this.$element.offset({top:a-e-s})}};var o=t.fn.affix;t.fn.affix=e,t.fn.affix.Constructor=i,t.fn.affix.noConflict=function(){return t.fn.affix=o,this},t(window).on("load",function(){t('[data-spy="affix"]').each(function(){var i=t(this),o=i.data();o.offset=o.offset||{},null!=o.offsetBottom&&(o.offset.bottom=o.offsetBottom),null!=o.offsetTop&&(o.offset.top=o.offsetTop),e.call(i,o)})})}(jQuery),+function(t){"use strict";function e(e){var i,o=e.attr("data-target")||(i=e.attr("href"))&&i.replace(/.*(?=#[^\s]+$)/,"");return t(o)}function i(e){return this.each(function(){var i=t(this),n=i.data("bs.collapse"),s=t.extend({},o.DEFAULTS,i.data(),"object"==typeof e&&e);!n&&s.toggle&&/show|hide/.test(e)&&(s.toggle=!1),n||i.data("bs.collapse",n=new o(this,s)),"string"==typeof e&&n[e]()})}var o=function(e,i){this.$element=t(e),this.options=t.extend({},o.DEFAULTS,i),this.$trigger=t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};o.VERSION="3.3.4",o.TRANSITION_DURATION=350,o.DEFAULTS={toggle:!0},o.prototype.dimension=function(){var t=this.$element.hasClass("width");return t?"width":"height"},o.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var e,n=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(n&&n.length&&(e=n.data("bs.collapse"),e&&e.transitioning))){var s=t.Event("show.bs.collapse");if(this.$element.trigger(s),!s.isDefaultPrevented()){n&&n.length&&(i.call(n,"hide"),e||n.data("bs.collapse",null));var a=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[a](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var r=function(){this.$element.removeClass("collapsing").addClass("collapse in")[a](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!t.support.transition)return r.call(this);var l=t.camelCase(["scroll",a].join("-"));this.$element.one("bsTransitionEnd",t.proxy(r,this)).emulateTransitionEnd(o.TRANSITION_DURATION)[a](this.$element[0][l])}}}},o.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var e=t.Event("hide.bs.collapse");if(this.$element.trigger(e),!e.isDefaultPrevented()){var i=this.dimension();this.$element[i](this.$element[i]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var n=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return t.support.transition?void this.$element[i](0).one("bsTransitionEnd",t.proxy(n,this)).emulateTransitionEnd(o.TRANSITION_DURATION):n.call(this)}}},o.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},o.prototype.getParent=function(){return t(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(t.proxy(function(i,o){var n=t(o); +this.addAriaAndCollapsedClass(e(n),n)},this)).end()},o.prototype.addAriaAndCollapsedClass=function(t,e){var i=t.hasClass("in");t.attr("aria-expanded",i),e.toggleClass("collapsed",!i).attr("aria-expanded",i)};var n=t.fn.collapse;t.fn.collapse=i,t.fn.collapse.Constructor=o,t.fn.collapse.noConflict=function(){return t.fn.collapse=n,this},t(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(o){var n=t(this);n.attr("data-target")||o.preventDefault();var s=e(n),a=s.data("bs.collapse"),r=a?"toggle":n.data();i.call(s,r)})}(jQuery),+function(t){"use strict";function e(i,o){this.$body=t(document.body),this.$scrollElement=t(t(i).is(document.body)?window:i),this.options=t.extend({},e.DEFAULTS,o),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",t.proxy(this.process,this)),this.refresh(),this.process()}function i(i){return this.each(function(){var o=t(this),n=o.data("bs.scrollspy"),s="object"==typeof i&&i;n||o.data("bs.scrollspy",n=new e(this,s)),"string"==typeof i&&n[i]()})}e.VERSION="3.3.4",e.DEFAULTS={offset:10},e.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},e.prototype.refresh=function(){var e=this,i="offset",o=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),t.isWindow(this.$scrollElement[0])||(i="position",o=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var e=t(this),n=e.data("target")||e.attr("href"),s=/^#./.test(n)&&t(n);return s&&s.length&&s.is(":visible")&&[[s[i]().top+o,n]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){e.offsets.push(this[0]),e.targets.push(this[1])})},e.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),e>=o)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(void 0===n[t+1]||e'); + $('dt .headerlink').each(function(idx, elem) { + var i = [ + '
  • ', + last(elem.href.split('.')), + '
  • '] + .join(''); + $( '#function-list' ).append(i); + }); + } + } + + /*scroll the right-hand navigation*/ + var wheight = $( window ).height() - $( '#sidebar-static' ).height() - $( '#sidebar-static-bottom' ).height(); + $(function(){ + $( '#sidebar-nav' ).slimScroll({ + width: 'inherit', + size: '14px', + height: wheight + }).promise().done(function() { + + if (window.location.hash) { + var hash = window.location.hash.substring(1); + var $link = $( '#sidebar-nav').find('a[href$="#' + hash + '"]').addClass("selected"); + if ($link.length) { + var scrollTo_val = $link.offset().top - 300 + 'px'; + $( '#sidebar-nav' ).slimScroll({ scrollTo : scrollTo_val }); + } + else if ($( 'a.current' ).length) { + var scrollTo_val = $( 'a.current' ).offset().top - 300 + 'px'; + $( '#sidebar-nav' ).slimScroll({ scrollTo : scrollTo_val }); + } + } + else if ($( 'a.current' ).length) { + var scrollTo_val = $( 'a.current' ).offset().top - 300 + 'px'; + $( '#sidebar-nav' ).slimScroll({ scrollTo : scrollTo_val }); + } + /*hidden by css - make visible after slimScroll plug-in loads*/ + $( '#sidebar-wrapper').css('visibility','visible'); + }); + }); + + /*permalink display*/ + $( 'a.headerlink').html( ''); + + $( 'h1,h2,h3,h4,h5,h6').mouseenter(function(){ + $(this).find( '.permalink' ).find( 'i' ).css({'color':'#000'}); + }).mouseleave(function(){ + $(this).find( '.permalink' ).find( 'i' ).css({'color':'#fff'}); + }); + + /*smooth on-page scrolling for long topic*/ + $( '#sidebar-nav' ).on('click','a[href^="#"]',function (e) { + e.preventDefault(); + $( '#sidebar-nav' ).find( 'a' ).removeClass('selected'); + $(this).addClass('selected'); + var target = this.hash; + var $target = $(target); + + $('html, body').stop().animate({ + 'scrollTop': $target.offset().top + }, 900, 'swing', function () { + window.location.hash = target; + }); + }); + + /*scroll to active topic*/ + $( '#sidebar-nav' ).on('click','a.function-nav-link',function (e) { + e.preventDefault(); + $( 'a.function-nav-link' ).removeClass('selected'); + $(this).addClass('selected'); + var target = this.hash.substring(1); + var $target = $('dt[id="' + target + '"]'); + + $('html, body').stop().animate({ + 'scrollTop': $target.offset().top + }, 900, 'swing', function () { + window.location.hash = target; + }); + }); + + /*search form*/ + $( '#search-form' ).find( 'input' ).keypress(function(e) { + if(e.which == 13) { + var cx = '004624818632696854117:yfmprrbw3pk&q='; + 'find which search instance to use' + if (DOCUMENTATION_OPTIONS.SEARCH_CX) { + cx = DOCUMENTATION_OPTIONS.SEARCH_CX; + } + var searchterm = encodeURIComponent($(this).val()); + $(this).val(""); + window.location.href = 'https://www.google.com/cse?cx=' + cx + '&q=' + searchterm; + } + }); + + /*menu collapse*/ + $( '#menu-toggle' ).click(function(e) { + e.preventDefault(); + $( '#wrapper' ).toggleClass( 'toggled' ); + }); + + /*version page selector*/ + $( 'div.versions' ).on('click', 'a', function (e) { + e.preventDefault(); + var clickedVer = $(this).attr("href"); + var $currentVer = $( 'div.versions' ).find( 'a.active' ).first(); + if (window.location.href.indexOf(clickedVer) == -1) { + window.location.href = window.location.href.replace($currentVer.attr("href"), clickedVer); + } + else { + if ($currentVer.text().indexOf("Develop") == -1) { + window.location.href = clickedVer + "topics/releases/" + $currentVer.text().trim() + ".html"; + } + else window.location.href = clickedVer + "topics/releases/"; + } + }); + + /*lightbox around images*/ + $( 'img' ).not( '.nolightbox' ).each(function() { + var source = $(this).attr( 'src' ); + var id = $(this).attr( 'id' ); + $(this).wrap('' ) + }); + + /*enable bootstrap tooltips*/ + $(function () { + $('[data-toggle="tooltip"]').tooltip(); + }); + + /*notification box*/ + var box; + $("#notifications").on('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + $.get('//docs.saltstack.com/en/announcements.html?id=1', function (data) { + box = bootbox.dialog({ + title: "Announcements", + message: data + }); + _gaq.push(['_trackEvent', 'docs', 'announcement-view']); + }); + }); + $(document).on('click', '.bootbox', function (event) { + box.modal('hide'); + }); +}); // $.document.ready + +//refresh on window resize +var rtime = new Date(1, 1, 2000, 12,00,00); +var timeout = false; +var delta = 200; +$(window).resize(function() { + + if (!$( '#menu-toggle' ).is(":visible")) { + rtime = new Date(); + if (timeout === false) { + timeout = true; + setTimeout(resizeend, delta); + } + } +}); + +function resizeend() { + if (new Date() - rtime < delta) { + setTimeout(resizeend, delta); + } else { + timeout = false; + if ($( window ).height() > windowheight || $( window ).height() + 40 < windowheight) { + location.reload(false); + } + } +} + +function last(list) { + return list[list.length - 1]; +} \ No newline at end of file From cf97a4ab17583a788cad6c646ae04a5d98c8eb42 Mon Sep 17 00:00:00 2001 From: Jacob Hammons Date: Fri, 26 Jun 2015 12:21:26 -0600 Subject: [PATCH 29/33] Updated man pages --- doc/man/salt-api.1 | 2 +- doc/man/salt-call.1 | 17 +- doc/man/salt-cloud.1 | 8 +- doc/man/salt-cp.1 | 2 +- doc/man/salt-key.1 | 2 +- doc/man/salt-master.1 | 2 +- doc/man/salt-minion.1 | 2 +- doc/man/salt-run.1 | 2 +- doc/man/salt-ssh.1 | 2 +- doc/man/salt-syndic.1 | 2 +- doc/man/salt-unity.1 | 2 +- doc/man/salt.1 | 2 +- doc/man/salt.7 | 19496 +++++++++++++++++++++++++++++++++++----- 13 files changed, 17370 insertions(+), 2171 deletions(-) diff --git a/doc/man/salt-api.1 b/doc/man/salt-api.1 index c383035d90..78d3dcfd4f 100644 --- a/doc/man/salt-api.1 +++ b/doc/man/salt-api.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-API" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-API" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-api \- salt-api Command . diff --git a/doc/man/salt-call.1 b/doc/man/salt-call.1 index f0423ff733..2083f53e0a 100644 --- a/doc/man/salt-call.1 +++ b/doc/man/salt-call.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-CALL" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-CALL" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-call \- salt-call Documentation . @@ -44,7 +44,20 @@ salt\-call [options] .SH DESCRIPTION .sp The salt\-call command is used to run module functions locally on a minion -instead of executing them from the master. +instead of executing them from the master. Salt\-call is used to run a +\fIStandalone Minion\fP, and was originally +created for \fItroubleshooting\fP\&. +.sp +The Salt Master is contacted to retrieve state files and other resources +during execution unless the \fB\-\-local\fP option is specified. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBsalt\-call\fP commands execute from the current user\(aqs shell +context, while \fBsalt\fP commands execute from the system\(aqs default context. +.UNINDENT +.UNINDENT .SH OPTIONS .INDENT 0.0 .TP diff --git a/doc/man/salt-cloud.1 b/doc/man/salt-cloud.1 index 4e5c70655b..28a287d725 100644 --- a/doc/man/salt-cloud.1 +++ b/doc/man/salt-cloud.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-CLOUD" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-CLOUD" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-cloud \- Salt Cloud Command . @@ -141,12 +141,6 @@ cloud provider carefully. .UNINDENT .INDENT 0.0 .TP -.B \-Q, \-\-query -Execute a query and print out information about all cloud VMs. Can be used -in conjunction with \-m to display only information about the specified map. -.UNINDENT -.INDENT 0.0 -.TP .B \-u, \-\-update\-bootstrap Update salt\-bootstrap to the latest develop version on GitHub. .UNINDENT diff --git a/doc/man/salt-cp.1 b/doc/man/salt-cp.1 index 8419e32755..420093db09 100644 --- a/doc/man/salt-cp.1 +++ b/doc/man/salt-cp.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-CP" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-CP" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-cp \- salt-cp Documentation . diff --git a/doc/man/salt-key.1 b/doc/man/salt-key.1 index ee493ccf3c..919b7280ce 100644 --- a/doc/man/salt-key.1 +++ b/doc/man/salt-key.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-KEY" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-KEY" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-key \- salt-key Documentation . diff --git a/doc/man/salt-master.1 b/doc/man/salt-master.1 index a93f3d82b8..439ded1192 100644 --- a/doc/man/salt-master.1 +++ b/doc/man/salt-master.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-MASTER" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-MASTER" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-master \- salt-master Documentation . diff --git a/doc/man/salt-minion.1 b/doc/man/salt-minion.1 index c24638e022..4aa0fa039a 100644 --- a/doc/man/salt-minion.1 +++ b/doc/man/salt-minion.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-MINION" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-MINION" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-minion \- salt-minion Documentation . diff --git a/doc/man/salt-run.1 b/doc/man/salt-run.1 index bd80a36d6a..994bfb518d 100644 --- a/doc/man/salt-run.1 +++ b/doc/man/salt-run.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-RUN" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-RUN" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-run \- salt-run Documentation . diff --git a/doc/man/salt-ssh.1 b/doc/man/salt-ssh.1 index f65cf9faac..59a88a43d8 100644 --- a/doc/man/salt-ssh.1 +++ b/doc/man/salt-ssh.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-SSH" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-SSH" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-ssh \- salt-ssh Documentation . diff --git a/doc/man/salt-syndic.1 b/doc/man/salt-syndic.1 index 13422d3f8c..dc2357539b 100644 --- a/doc/man/salt-syndic.1 +++ b/doc/man/salt-syndic.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-SYNDIC" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-SYNDIC" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-syndic \- salt-syndic Documentation . diff --git a/doc/man/salt-unity.1 b/doc/man/salt-unity.1 index f7e312a024..3db54dd91a 100644 --- a/doc/man/salt-unity.1 +++ b/doc/man/salt-unity.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT-UNITY" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT-UNITY" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt-unity \- salt-unity Command . diff --git a/doc/man/salt.1 b/doc/man/salt.1 index 56bc2966c7..d40efec417 100644 --- a/doc/man/salt.1 +++ b/doc/man/salt.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT" "1" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT" "1" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt \- salt . diff --git a/doc/man/salt.7 b/doc/man/salt.7 index 40a5409fa4..95e324f01b 100644 --- a/doc/man/salt.7 +++ b/doc/man/salt.7 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "SALT" "7" "May 06, 2015" "2015.5.0" "Salt" +.TH "SALT" "7" "June 26, 2015" "2015.5.2" "Salt" .SH NAME salt \- Salt Documentation . @@ -126,6 +126,11 @@ about Salt and see whats going on with Salt development! The Salt mailing list is hosted by Google Groups. It is open to new members. .sp \fI\%https://groups.google.com/forum/#!forum/salt\-users\fP +.sp +There is also a low\-traffic list used to announce new releases +called \fI\%salt\-announce\fP +.sp +\fI\%https://groups.google.com/forum/#!forum/salt\-announce\fP .SS IRC .sp The \fB#salt\fP IRC channel is hosted on the popular \fI\%Freenode\fP network. You @@ -845,7 +850,7 @@ If installing from pip (or from source using \fBsetup.py install\fP), be advised that the \fByum\-utils\fP package is needed for Salt to manage packages. Also, if the Python dependencies are not already installed, then you will need additional libraries/tools installed to build some of them. -More information on this can be found here\&. +More information on this can be found \fIhere\fP\&. .UNINDENT .UNINDENT .SS Installation from Repository @@ -1354,11 +1359,17 @@ minion exe>\fP should match the contents of the corresponding md5 file. .IP "Download here" .INDENT 0.0 .IP \(bu 2 -2014.7.5 +2015.5.0\-2 .IP \(bu 2 -\fI\%Salt\-Minion\-2014.7.5\-x86\-Setup.exe\fP | \fI\%md5\fP +\fI\%Salt\-Minion\-2015.5.0\-2\-x86\-Setup.exe\fP | \fI\%md5\fP .IP \(bu 2 -\fI\%Salt\-Minion\-2014.7.5\-AMD64\-Setup.exe\fP | \fI\%md5\fP +\fI\%Salt\-Minion\-2015.5.0\-2\-AMD64\-Setup.exe\fP | \fI\%md5\fP +.IP \(bu 2 +2014.7.5\-2 +.IP \(bu 2 +\fI\%Salt\-Minion\-2014.7.5\-2\-x86\-Setup.exe\fP | \fI\%md5\fP +.IP \(bu 2 +\fI\%Salt\-Minion\-2014.7.5\-2\-AMD64\-Setup.exe\fP | \fI\%md5\fP .IP \(bu 2 2014.7.4 .IP \(bu 2 @@ -1382,16 +1393,17 @@ minion exe>\fP should match the contents of the corresponding md5 file. .IP \(bu 2 Salt\-Minion\-2014.7.0\-1\-win32\-Setup.exe | md5 .IP \(bu 2 -Salt\-Minion\-2014.7.0\-AMD64\-Setup.exe | md5 -.UNINDENT -.sp +.INDENT 2.0 +.TP +.B Salt\-Minion\-2014.7.0\-AMD64\-Setup.exe | md5 +. \fBNOTE:\fP -.INDENT 0.0 +.INDENT 7.0 .INDENT 3.5 The 2014.7.0 installers have been removed because of a regression. Please use the 2014.7.1 release instead. .UNINDENT .UNINDENT -.INDENT 0.0 +.UNINDENT .IP \(bu 2 2014.1.13 .IP \(bu 2 @@ -1627,7 +1639,7 @@ Build the Salt Environment Right\-click on the file named \fBdev_env_salt.ps1\fP and select \fBRun with Powershell\fP .sp -This will clone salt into \fBC:\eSalt\-Dev\esalt\fP and set it to the 2015.2 +This will clone salt into \fBC:\eSalt\-Dev\esalt\fP and set it to the 2015.5 branch. You could optionally run the command from a powershell window with a \fB\-Version\fP switch to pull a different version. For example: .INDENT 3.0 @@ -2306,6 +2318,20 @@ zypper install salt salt\-minion salt\-master .UNINDENT .SS Suse Linux Enterprise .sp +For SLE 12 run the following as root: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +zypper addrepo http://download.opensuse.org/repositories/devel:languages:python/SLE_12/devel:languages:python.repo +zypper refresh +zypper install salt salt\-minion salt\-master +.ft P +.fi +.UNINDENT +.UNINDENT +.sp For SLE 11 SP3 run the following as root: .INDENT 0.0 .INDENT 3.5 @@ -2464,14 +2490,14 @@ wget \-O \- https://bootstrap.saltstack.com | sudo sh .UNINDENT .sp See the \fI\%salt\-bootstrap\fP documentation for other one liners. When using \fI\%Vagrant\fP -to test out salt, the \fI\%salty\-vagrant\fP tool will provision the VM for you. +to test out salt, the \fI\%Vagrant salt provisioner\fP will provision the VM for you. .SS Telling Salt to Run Masterless .sp -To instruct the minion to not look for a master when running -the \fBfile_client\fP configuration option needs to be set. +To instruct the minion to not look for a master, the \fBfile_client\fP +configuration option needs to be set in the minion configuration file. By default the \fBfile_client\fP is set to \fBremote\fP so that the -minion knows that file server and pillar data are to be gathered from the -master. When setting the \fBfile_client\fP option to \fBlocal\fP the +minion gathers file server and pillar data from the salt master. +When setting the \fBfile_client\fP option to \fBlocal\fP the minion is configured to not gather this data from the master. .INDENT 0.0 .INDENT 3.5 @@ -2703,6 +2729,9 @@ salt\-call state.highstate \-\-local .fi .UNINDENT .UNINDENT +.SS External Pillars +.sp +\fIExternal pillars\fP are supported when running in masterless mode. .SS Opening the Firewall up for Salt .sp The Salt master communicates with the minions using an AES\-encrypted ZeroMQ @@ -3008,14 +3037,14 @@ following the \fBinstallation\fP and the .INDENT 3.5 .IP "Stuck?" .sp -There are many ways to get help from the Salt community including our +There are many ways to \fIget help from the Salt community\fP including our \fI\%mailing list\fP and our \fI\%IRC channel\fP #salt. .UNINDENT .UNINDENT .SS Order your minions around .sp -Now that you have a master and at least one minion +Now that you have a \fImaster\fP and at least one \fIminion\fP communicating with each other you can perform commands on the minion via the \fBsalt\fP command. Salt calls are comprised of three main components: .INDENT 0.0 @@ -3224,9 +3253,9 @@ minions can be defined in pillar and then accessed inside sls formulas and template files. .TP .B Arbitrary Data: -Pillar can contain any basic data structure, so a list of values, or a -key/value store can be defined making it easy to iterate over a group -of values in sls formulas +Pillar can contain any basic data structure in dictionary format, +so a key/value store can be defined making it easy to iterate over a group +of values in sls formulas. .UNINDENT .sp Pillar is therefore one of the most important systems when using Salt. This @@ -3367,8 +3396,8 @@ users: .INDENT 0.0 .INDENT 3.5 The same directory lookups that exist in states exist in pillar, so the -file \fBusers/init.sls\fP can be referenced with \fBusers\fP in the top -file\&. +file \fBusers/init.sls\fP can be referenced with \fBusers\fP in the \fItop +file\fP\&. .UNINDENT .UNINDENT .sp @@ -3614,18 +3643,6 @@ salt \(aq*\(aq state.sls my_sls_file pillar=\(aq{"hello": "world"}\(aq .UNINDENT .UNINDENT .sp -Lists can be passed in pillar as well: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq state.highstate pillar=\(aq["foo", "bar", "baz"]\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 @@ -3928,7 +3945,7 @@ has an include statement it is literally extended to include the contents of the included SLS files. .sp Note that some of the SLS files are called init.sls, while others are not. More -info on what this means can be found in the States Tutorial\&. +info on what this means can be found in the \fIStates Tutorial\fP\&. .SS Extending Included SLS Data .sp Sometimes SLS data needs to be extended. Perhaps the apache service needs to @@ -4271,7 +4288,7 @@ following the \fBinstallation\fP and the .INDENT 3.5 .IP "Stuck?" .sp -There are many ways to get help from the Salt community including our +There are many ways to \fIget help from the Salt community\fP including our \fI\%mailing list\fP and our \fI\%IRC channel\fP #salt. .UNINDENT @@ -4336,7 +4353,7 @@ base: .UNINDENT .UNINDENT .sp -The top file is separated into environments (discussed +The \fItop file\fP is separated into environments (discussed later). The default environment is \fBbase\fP\&. Under the \fBbase\fP environment a collection of minion matches is defined; for now simply specify all hosts (\fB*\fP). @@ -4363,7 +4380,7 @@ base: .UNINDENT .SS Create an \fBsls\fP file .sp -In the same directory as the top file, create a file +In the same directory as the \fItop file\fP, create a file named \fBwebserver.sls\fP, containing the following: .INDENT 0.0 .INDENT 3.5 @@ -4378,7 +4395,7 @@ apache: # ID declaration .UNINDENT .UNINDENT .sp -The first line, called the id\-declaration, is an arbitrary identifier. +The first line, called the \fIid\-declaration\fP, is an arbitrary identifier. In this case it defines the name of the package to be installed. .sp \fBNOTE:\fP @@ -4390,10 +4407,10 @@ Debian/Ubuntu it is \fBapache2\fP\&. .UNINDENT .UNINDENT .sp -The second line, called the state\-declaration, defines which of the Salt +The second line, called the \fIstate\-declaration\fP, defines which of the Salt States we are using. In this example, we are using the \fBpkg state\fP to ensure that a given package is installed. .sp -The third line, called the function\-declaration, defines which function +The third line, called the \fIfunction\-declaration\fP, defines which function in the \fBpkg state\fP module to call. .INDENT 0.0 .INDENT 3.5 @@ -4426,7 +4443,7 @@ Next, let\(aqs run the state we created. Open a terminal on the master and run: .UNINDENT .sp Our master is instructing all targeted minions to run \fBstate.highstate\fP\&. When a minion executes a highstate call it -will download the top file and attempt to match the +will download the \fItop file\fP and attempt to match the expressions. When it does match an expression the modules listed for it will be downloaded, compiled, and executed. .sp @@ -4436,9 +4453,9 @@ and all changes made. \fBWARNING:\fP .INDENT 0.0 .INDENT 3.5 -If you have created custom grain modules, they will +If you have created \fIcustom grain modules\fP, they will not be available in the top file until after the first \fI\%highstate\fP\&. To make custom grains available on a minion\(aqs first -highstate, it is recommended to use this example to ensure that the custom grains are synced when +highstate, it is recommended to use \fIthis example\fP to ensure that the custom grains are synced when the minion starts. .UNINDENT .UNINDENT @@ -4498,7 +4515,8 @@ salt\-minion \-l debug .UNINDENT .TP .B Run the minion in the foreground -By not starting the minion in daemon mode (\fB\-d\fP) one can view any output from the minion as it works: +By not starting the minion in daemon mode (\fB\-d\fP) +one can view any output from the minion as it works: .INDENT 7.0 .INDENT 3.5 .sp @@ -4558,8 +4576,8 @@ basics of installing a package. We will now modify our \fBwebserver.sls\fP file to have requirements, and use even more Salt States. .SS Call multiple States .sp -You can specify multiple state\-declaration under an -id\-declaration\&. For example, a quick modification to our +You can specify multiple \fIstate\-declaration\fP under an +\fIid\-declaration\fP\&. For example, a quick modification to our \fBwebserver.sls\fP to also start Apache if it is not running: .INDENT 0.0 .INDENT 3.5 @@ -4607,23 +4625,23 @@ apache: .UNINDENT .UNINDENT .sp -\fBline 9\fP is the id\-declaration\&. In this example it is the location we +\fBline 9\fP is the \fIid\-declaration\fP\&. In this example it is the location we want to install our custom HTML file. (\fBNote:\fP the default location that Apache serves may differ from the above on your OS or distro. \fB/srv/www\fP could also be a likely place to look.) .sp -\fBLine 10\fP the state\-declaration\&. This example uses the Salt \fBfile +\fBLine 10\fP the \fIstate\-declaration\fP\&. This example uses the Salt \fBfile state\fP\&. .sp -\fBLine 11\fP is the function\-declaration\&. The \fBmanaged function\fP will download a file from the master and install it +\fBLine 11\fP is the \fIfunction\-declaration\fP\&. The \fBmanaged function\fP will download a file from the master and install it in the location specified. .sp -\fBLine 12\fP is a function\-arg\-declaration which, in this example, passes +\fBLine 12\fP is a \fIfunction\-arg\-declaration\fP which, in this example, passes the \fBsource\fP argument to the \fBmanaged function\fP\&. .sp -\fBLine 13\fP is a requisite\-declaration\&. +\fBLine 13\fP is a \fIrequisite\-declaration\fP\&. .sp -\fBLine 14\fP is a requisite\-reference which refers to a state and an ID. +\fBLine 14\fP is a \fIrequisite\-reference\fP which refers to a state and an ID. In this example, it is referring to the \fBID declaration\fP from our example in \fBpart 1\fP\&. This declaration tells Salt not to install the HTML file until Apache is installed. @@ -4665,7 +4683,7 @@ Verify that Apache is now serving your custom HTML. .INDENT 3.5 .IP "\fBrequire\fP vs. \fBwatch\fP" .sp -There are two requisite\-declaration, “require”, and “watch”. Not +There are two \fIrequisite\-declaration\fP, “require”, and “watch”. Not every state supports “watch”. The \fBservice state\fP does support “watch” and will restart a service based on the watch condition. .sp @@ -4694,7 +4712,7 @@ apache: .UNINDENT .sp If the pkg and service names differ on your OS or distro of choice you can -specify each one separately using a name\-declaration which explained +specify each one separately using a \fIname\-declaration\fP which explained in \fBPart 3\fP\&. .UNINDENT .UNINDENT @@ -4761,6 +4779,13 @@ Here\(aqs a more complex example: .sp .nf .ft C +# Comments in yaml start with a hash symbol. +# Since jinja rendering occurs before yaml parsing, if you want to include jinja +# in the comments you may need to escape them using \(aqjinja\(aq comments to prevent +# jinja from trying to render something which is not well\-defined jinja. +# e.g. +# {# iterate over the Three Stooges using a {% for %}..{% endfor %} loop +# with the iterator variable {{ usr }} becoming the state ID. #} {% for usr in \(aqmoe\(aq,\(aqlarry\(aq,\(aqcurly\(aq %} {{ usr }}: group: @@ -4841,7 +4866,7 @@ trees. .sp A previous example showed how to spread a Salt tree across several files. Similarly, \fBrequisites\fP span multiple files by -using an include\-declaration\&. For example: +using an \fIinclude\-declaration\fP\&. For example: .sp \fBpython/python\-libs.sls:\fP .INDENT 0.0 @@ -4875,7 +4900,7 @@ django: .UNINDENT .SS Extend declaration .sp -You can modify previous declarations by using an extend\-declaration\&. For +You can modify previous declarations by using an \fIextend\-declaration\fP\&. For example the following modifies the Apache tree to also restart Apache when the vhosts file is changed: .sp @@ -4925,7 +4950,7 @@ It appends to, rather than replacing the requisite component. .UNINDENT .SS Name declaration .sp -You can override the id\-declaration by using a name\-declaration\&. +You can override the \fIid\-declaration\fP by using a \fIname\-declaration\fP\&. For example, the previous example is a bit more maintainable if rewritten as follows: .sp @@ -4955,8 +4980,8 @@ mywebsite: .UNINDENT .SS Names declaration .sp -Even more powerful is using a names\-declaration to override the -id\-declaration for multiple states at once. This often can remove the +Even more powerful is using a \fInames\-declaration\fP to override the +\fIid\-declaration\fP for multiple states at once. This often can remove the need for looping in a template. For example, the first example in this tutorial can be rewritten without the loop: .INDENT 0.0 @@ -5030,7 +5055,7 @@ and \fBroots\fP appears before \fBgit\fP in the "win", and the file in gitfs will be ignored. .sp A more thorough explanation of how Salt\(aqs modular fileserver works can be -found here\&. We recommend reading this. +found \fIhere\fP\&. We recommend reading this. .UNINDENT .UNINDENT .SS Environment configuration @@ -5243,7 +5268,7 @@ of existing state trees. Many pre\-configured state trees can be found on Github in the \fI\%saltstack\-formulas\fP collection of repositories. .sp If you have any questions, suggestions, or just want to chat with other people -who are using Salt, we have a very active community +who are using Salt, we have a very \fIactive community\fP and we\(aqd love to hear from you. .sp In addition, by continuing to \fBpart 5\fP, you can learn about @@ -5471,7 +5496,7 @@ all: \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -The \fBmatch\fP argument uses compound matching +The \fBmatch\fP argument uses \fIcompound matching\fP .UNINDENT .UNINDENT .sp @@ -6157,9 +6182,9 @@ communication system, Salt provides an extremely fast, flexible, and easy\-to\-u configuration management system called \fBSalt States\fP\&. .SS Installing Salt .sp -SaltStack has been made to be very easy to install and get started. Setting up -Salt should be as easy as installing Salt via distribution packages on Linux or -via the Windows installer. The \fBinstallation documents\fP cover platform\-specific installation in depth. +SaltStack has been made to be very easy to install and get started. The +\fBinstallation documents\fP contain instructions +for all supported platforms. .SS Starting Salt .sp Salt functions on a master/minion topology. A master server acts as a @@ -6599,7 +6624,7 @@ root@saltmaster:~# salt myminion grains.item pythonpath \-\-out=pprint .UNINDENT .sp The full list of Salt outputters, as well as example output, can be found -here\&. +\fIhere\fP\&. .SS \fBsalt\-call\fP .sp The examples so far have described running commands from the Master using the @@ -6610,7 +6635,7 @@ Doing so allows you to see the minion log messages specific to the command you are running (which are \fInot\fP part of the return data you see when running the command from the Master using \fBsalt\fP), making it unnecessary to tail the minion log. More information on \fBsalt\-call\fP and how to use it can be found -here\&. +\fIhere\fP\&. .SS Grains .sp Salt uses a system called \fBGrains\fP to build up @@ -6918,9 +6943,8 @@ Two more in\-depth States tutorials exist, which delve much more deeply into Sta functionality. .INDENT 0.0 .IP 1. 3 -Thomas\(aq original states tutorial, \fBHow Do I Use Salt -States?\fP, covers much more to get off the -ground with States. +\fBHow Do I Use Salt States?\fP, covers much +more to get off the ground with States. .IP 2. 3 The \fBStates Tutorial\fP also provides a fantastic introduction. @@ -9291,8 +9315,8 @@ $ ssh\-keygen \-l \-f /dev/stdin <<<\(gassh\-keyscan \-t rsa github.com 2>/dev/n .SS Refreshing gitfs Upon Push .sp By default, Salt updates the remote fileserver backends every 60 seconds. -However, if it is desirable to refresh quicker than that, the Reactor -System can be used to signal the master to update the fileserver on +However, if it is desirable to refresh quicker than that, the \fIReactor +System\fP can be used to signal the master to update the fileserver on each push, provided that the git server is also a Salt minion. There are three steps to this process: .INDENT 0.0 @@ -10119,6 +10143,1525 @@ SaltStack maintains a Jenkins server which can be viewed at create fresh virtual machines for each test run, then execute the destructive tests on the new clean virtual machine. This allows for the execution of tests across supported platforms. +.SS HTTP Modules +.sp +This tutorial demonstrates using the various HTTP modules available in Salt. +These modules wrap the Python \fBurllib2\fP and \fBrequests\fP libraries, extending +them in a manner that is more consistent with Salt workflows. +.SS The \fBsalt.utils.http\fP Library +.sp +This library forms the core of the HTTP modules. Since it is designed to be used +from the minion as an execution module, in addition to the master as a runner, +it was abstracted into this multi\-use library. This library can also be imported +by 3rd\-party programs wishing to take advantage of its extended functionality. +.sp +Core functionality of the execution, state, and runner modules is derived from +this library, so common usages between them are described here. Documentation +specific to each module is described below. +.sp +This library can be imported with: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +import salt.utils.http +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Configuring Libraries +.sp +This library can make use of either \fBurllib2\fP, which ships with Python, or +\fBrequests\fP, which can be installed separately. By default, \fBurllib2\fP will +be used. In order to switch to \fBrequests\fP, set the following variable: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +requests_lib: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This can be set in the master or minion configuration file, or passed as an +option directly to any \fBhttp.query()\fP functions. +.SS \fBsalt.utils.http.query()\fP +.sp +This function forms a basic query, but with some add\-ons not present in the +\fBurllib2\fP and \fBrequests\fP libraries. Not all functionality currently +available in these libraries has been added, but can be in future iterations. +.sp +A basic query can be performed by calling this function with no more than a +single URL: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query(\(aqhttp://example.com\(aq) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +By default the query will be performed with a \fBGET\fP method. The method can +be overridden with the \fBmethod\fP argument: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query(\(aqhttp://example.com/delete/url\(aq, \(aqDELETE\(aq) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +When using the \fBPOST\fP method (and others, such \fBPUT\fP), extra data is usually +sent as well. This data can be either sent directly, in whatever format is +required by the remote server (XML, JSON, plain text, etc). +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com/delete/url\(aq, + method=\(aqPOST\(aq, + data=json.loads(mydict) +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Bear in mind that this data must be sent pre\-formatted; this function will not +format it for you. However, a templated file stored on the local system may be +passed through, along with variables to populate it with. To pass through only +the file (untemplated): +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com/post/url\(aq, + method=\(aqPOST\(aq, + data_file=\(aq/srv/salt/somefile.xml\(aq +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To pass through a file that contains jinja + yaml templating (the default): +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com/post/url\(aq, + method=\(aqPOST\(aq, + data_file=\(aq/srv/salt/somefile.jinja\(aq, + data_render=True, + template_data={\(aqkey1\(aq: \(aqvalue1\(aq, \(aqkey2\(aq: \(aqvalue2\(aq} +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To pass through a file that contains mako templating: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com/post/url\(aq, + method=\(aqPOST\(aq, + data_file=\(aq/srv/salt/somefile.mako\(aq, + data_render=True, + data_renderer=\(aqmako\(aq, + template_data={\(aqkey1\(aq: \(aqvalue1\(aq, \(aqkey2\(aq: \(aqvalue2\(aq} +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Because this function uses Salt\(aqs own rendering system, any Salt renderer can +be used. Because Salt\(aqs renderer requires \fB__opts__\fP to be set, an \fBopts\fP +dictionary should be passed in. If it is not, then the default \fB__opts__\fP +values for the node type (master or minion) will be used. Because this library +is intended primarily for use by minions, the default node type is \fBminion\fP\&. +However, this can be changed to \fBmaster\fP if necessary. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com/post/url\(aq, + method=\(aqPOST\(aq, + data_file=\(aq/srv/salt/somefile.jinja\(aq, + data_render=True, + template_data={\(aqkey1\(aq: \(aqvalue1\(aq, \(aqkey2\(aq: \(aqvalue2\(aq}, + opts=__opts__ +) + +salt.utils.http.query( + \(aqhttp://example.com/post/url\(aq, + method=\(aqPOST\(aq, + data_file=\(aq/srv/salt/somefile.jinja\(aq, + data_render=True, + template_data={\(aqkey1\(aq: \(aqvalue1\(aq, \(aqkey2\(aq: \(aqvalue2\(aq}, + node=\(aqmaster\(aq +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Headers may also be passed through, either as a \fBheader_list\fP, a +\fBheader_dict\fP or as a \fBheader_file\fP\&. As with the \fBdata_file\fP, the +\fBheader_file\fP may also be templated. Take note that because HTTP headers are +normally syntactically\-correct YAML, they will automatically be imported as an +a Python dict. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com/delete/url\(aq, + method=\(aqPOST\(aq, + header_file=\(aq/srv/salt/headers.jinja\(aq, + header_render=True, + header_renderer=\(aqjinja\(aq, + template_data={\(aqkey1\(aq: \(aqvalue1\(aq, \(aqkey2\(aq: \(aqvalue2\(aq} +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Because much of the data that would be templated between headers and data may be +the same, the \fBtemplate_data\fP is the same for both. Correcting possible +variable name collisions is up to the user. +.sp +The \fBquery()\fP function supports basic HTTP authentication. A username and +password may be passed in as \fBusername\fP and \fBpassword\fP, respectively. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + username=\(aqlarry\(aq, + password=\(ga5700g3543v4r\(ga, +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Cookies are also supported, using Python\(aqs built\-in \fBcookielib\fP\&. However, they +are turned off by default. To turn cookies on, set \fBcookies\fP to True. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + cookies=True +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +By default cookies are stored in Salt\(aqs cache directory, normally +\fB/var/cache/salt\fP, as a file called \fBcookies.txt\fP\&. However, this location +may be changed with the \fBcookie_jar\fP argument: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + cookies=True, + cookie_jar=\(aq/path/to/cookie_jar.txt\(aq +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +By default, the format of the cookie jar is LWP (aka, lib\-www\-perl). This +default was chosen because it is a human\-readable text file. If desired, the +format of the cookie jar can be set to Mozilla: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + cookies=True, + cookie_jar=\(aq/path/to/cookie_jar.txt\(aq, + cookie_format=\(aqmozilla\(aq +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Because Salt commands are normally one\-off commands that are piped together, +this library cannot normally behave as a normal browser, with session cookies +that persist across multiple HTTP requests. However, the session can be +persisted in a separate cookie jar. The default filename for this file, inside +Salt\(aqs cache directory, is \fBcookies.session.p\fP\&. This can also be changed. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + persist_session=True, + session_cookie_jar=\(aq/path/to/jar.p\(aq +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The format of this file is msgpack, which is consistent with much of the rest +of Salt\(aqs internal structure. Historically, the extension for this file is +\fB\&.p\fP\&. There are no current plans to make this configurable. +.SS Return Data +.sp +By default, \fBquery()\fP will attempt to decode the return data. Because it was +designed to be used with REST interfaces, it will attempt to decode the data +received from the remote server. First it will check the \fBContent\-type\fP header +to try and find references to XML. If it does not find any, it will look for +references to JSON. If it does not find any, it will fall back to plain text, +which will not be decoded. +.sp +JSON data is translated into a dict using Python\(aqs built\-in \fBjson\fP library. +XML is translated using \fBsalt.utils.xml_util\fP, which will use Python\(aqs +built\-in XML libraries to attempt to convert the XML into a dict. In order to +force either JSON or XML decoding, the \fBdecode_type\fP may be set: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + decode_type=\(aqxml\(aq +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Once translated, the return dict from \fBquery()\fP will include a dict called +\fBdict\fP\&. +.sp +If the data is not to be translated using one of these methods, decoding may be +turned off. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + decode=False +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If decoding is turned on, and references to JSON or XML cannot be found, then +this module will default to plain text, and return the undecoded data as +\fBtext\fP (even if text is set to \fBFalse\fP; see below). +.sp +The \fBquery()\fP function can return the HTTP status code, headers, and/or text +as required. However, each must individually be turned on. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + status=True, + headers=True, + text=True +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The return from these will be found in the return dict as \fBstatus\fP, +\fBheaders\fP and \fBtext\fP, respectively. +.SS Writing Return Data to Files +.sp +It is possible to write either the return data or headers to files, as soon as +the response is received from the server, but specifying file locations via the +\fBtext_out\fP or \fBheaders_out\fP arguments. \fBtext\fP and \fBheaders\fP do not need +to be returned to the user in order to do this. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttp://example.com\(aq, + text=False, + headers=False, + text_out=\(aq/path/to/url_download.txt\(aq, + headers_out=\(aq/path/to/headers_download.txt\(aq, +) +.ft P +.fi +.UNINDENT +.UNINDENT +.SS SSL Verification +.sp +By default, this function will verify SSL certificates. However, for testing or +debugging purposes, SSL verification can be turned off. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttps://example.com\(aq, + ssl_verify=False, +) +.ft P +.fi +.UNINDENT +.UNINDENT +.SS CA Bundles +.sp +The \fBrequests\fP library has its own method of detecting which CA (certficate +authority) bundle file to use. Usually this is implemented by the packager for +the specific operating system distribution that you are using. However, +\fBurllib2\fP requires a little more work under the hood. By default, Salt will +try to auto\-detect the location of this file. However, if it is not in an +expected location, or a different path needs to be specified, it may be done so +using the \fBca_bundle\fP variable. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.query( + \(aqhttps://example.com\(aq, + ca_bundle=\(aq/path/to/ca_bundle.pem\(aq, +) +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Updating CA Bundles +.sp +The \fBupdate_ca_bundle()\fP function can be used to update the bundle file at a +specified location. If the target location is not specified, then it will +attempt to auto\-detect the location of the bundle file. If the URL to download +the bundle from does not exist, a bundle will be downloaded from the cURL +website. +.sp +CAUTION: The \fBtarget\fP and the \fBsource\fP should always be specified! Failure +to specify the \fBtarget\fP may result in the file being written to the wrong +location on the local system. Failure to specify the \fBsource\fP may cause the +upstream URL to receive excess unnecessary traffic, and may cause a file to be +download which is hazardous or does not meet the needs of the user. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.update_ca_bundle( + target=\(aq/path/to/ca\-bundle.crt\(aq, + source=\(aqhttps://example.com/path/to/ca\-bundle.crt\(aq, + opts=__opts__, +) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The \fBopts\fP parameter should also always be specified. If it is, then the +\fBtarget\fP and the \fBsource\fP may be specified in the relevant configuration +file (master or minion) as \fBca_bundle\fP and \fBca_bundle_url\fP, respectively. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ca_bundle: /path/to/ca\-bundle.crt +ca_bundle_url: https://example.com/path/to/ca\-bundle.crt +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If Salt is unable to auto\-detect the location of the CA bundle, it will raise +an error. +.sp +The \fBupdate_ca_bundle()\fP function can also be passed a string or a list of +strings which represent files on the local system, which should be appended (in +the specified order) to the end of the CA bundle file. This is useful in +environments where private certs need to be made available, and are not +otherwise reasonable to add to the bundle file. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt.utils.http.update_ca_bundle( + opts=__opts__, + merge_files=[ + \(aq/etc/ssl/private_cert_1.pem\(aq, + \(aq/etc/ssl/private_cert_2.pem\(aq, + \(aq/etc/ssl/private_cert_3.pem\(aq, + ] +) +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Test Mode +.sp +This function may be run in test mode. This mode will perform all work up until +the actual HTTP request. By default, instead of performing the request, an empty +dict will be returned. Using this function with \fBTRACE\fP logging turned on will +reveal the contents of the headers and POST data to be sent. +.sp +Rather than returning an empty dict, an alternate \fBtest_url\fP may be passed in. +If this is detected, then test mode will replace the \fBurl\fP with the +\fBtest_url\fP, set \fBtest\fP to \fBTrue\fP in the return data, and perform the rest +of the requested operations as usual. This allows a custom, non\-destructive URL +to be used for testing when necessary. +.SS Execution Module +.sp +The \fBhttp\fP execution module is a very thin wrapper around the +\fBsalt.utils.http\fP library. The \fBopts\fP can be passed through as well, but if +they are not specified, the minion defaults will be used as necessary. +.sp +Because passing complete data structures from the command line can be tricky at +best and dangerous (in terms of execution injection attacks) at worse, the +\fBdata_file\fP, and \fBheader_file\fP are likely to see more use here. +.sp +All methods for the library are available in the execution module, as kwargs. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion http.query http://example.com/restapi method=POST \e + username=\(aqlarry\(aq password=\(aq5700g3543v4r\(aq headers=True text=True \e + status=True decode_type=xml data_render=True \e + header_file=/tmp/headers.txt data_file=/tmp/data.txt \e + header_render=True cookies=True persist_session=True +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Runner Module +.sp +Like the execution module, the \fBhttp\fP runner module is a very thin wrapper +around the \fBsalt.utils.http\fP library. The only significant difference is that +because runners execute on the master instead of a minion, a target is not +required, and default opts will be derived from the master config, rather than +the minion config. +.sp +All methods for the library are available in the runner module, as kwargs. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run http.query http://example.com/restapi method=POST \e + username=\(aqlarry\(aq password=\(aq5700g3543v4r\(aq headers=True text=True \e + status=True decode_type=xml data_render=True \e + header_file=/tmp/headers.txt data_file=/tmp/data.txt \e + header_render=True cookies=True persist_session=True +.ft P +.fi +.UNINDENT +.UNINDENT +.SS State Module +.sp +The state module is a wrapper around the runner module, which applies stateful +logic to a query. All kwargs as listed above are specified as usual in state +files, but two more kwargs are available to apply stateful logic. A required +parameter is \fBmatch\fP, which specifies a pattern to look for in the return +text. By default, this will perform a string comparison of looking for the +value of match in the return text. In Python terms this looks like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +if match in html_text: + return True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If more complex pattern matching is required, a regular expression can be used +by specifying a \fBmatch_type\fP\&. By default this is set to \fBstring\fP, but it +can be manually set to \fBpcre\fP instead. Please note that despite the name, this +will use Python\(aqs \fBre.search()\fP rather than \fBre.match()\fP\&. +.sp +Therefore, the following states are valid: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +http://example.com/restapi: + http.query: + \- match: \(aqSUCCESS\(aq + \- username: \(aqlarry\(aq + \- password: \(aq5700g3543v4r\(aq + \- data_render: True + \- header_file: /tmp/headers.txt + \- data_file: /tmp/data.txt + \- header_render: True + \- cookies: True + \- persist_session: True + +http://example.com/restapi: + http.query: + \- match_type: pcre + \- match: \(aq(?i)succe[ss|ed]\(aq + \- username: \(aqlarry\(aq + \- password: \(aq5700g3543v4r\(aq + \- data_render: True + \- header_file: /tmp/headers.txt + \- data_file: /tmp/data.txt + \- header_render: True + \- cookies: True + \- persist_session: True +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +In addition to, or instead of a match pattern, the status code for a URL can be +checked. This is done using the \fBstatus\fP argument: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +http://example.com/: + http.query: + \- status: \(aq200\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If both are specified, both will be checked, but if only one is \fBTrue\fP and the +other is \fBFalse\fP, then \fBFalse\fP will be returned. In this case, the comments +in the return data will contain information for troubleshooting. +.sp +Because this is a monitoring state, it will return extra data to code that +expects it. This data will always include \fBtext\fP and \fBstatus\fP\&. Optionally, +\fBheaders\fP and \fBdict\fP may also be requested by setting the \fBheaders\fP and +\fBdecode\fP arguments to True, respectively. +.SS LXC Management with Salt +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +This walkthrough assumes basic knowledge of Salt. To get up to speed, check +out the \fBSalt Walkthrough\fP\&. +.UNINDENT +.UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +Some features are only currently available in the \fBdevelop\fP branch, and +are new in the upcoming 2015.5.0 release. These new features will be +clearly labeled. +Even in 2015.5 release, you will need up to the last changeset of this +stable branch for the salt\-cloud stuff to work correctly. +.UNINDENT +.UNINDENT +.SS Dependencies +.sp +Manipulation of LXC containers in Salt requires the minion to have an LXC +version of at least 1.0 (an alpha or beta release of LXC 1.0 is acceptable). +The following distributions are known to have new enough versions of LXC +packaged: +.INDENT 0.0 +.IP \(bu 2 +RHEL/CentOS 6 and later (via \fI\%EPEL\fP) +.IP \(bu 2 +Fedora (All non\-EOL releases) +.IP \(bu 2 +Debian 8.0 (Jessie) +.IP \(bu 2 +Ubuntu 14.04 LTS and later (LXC templates are packaged separately as +\fBlxc\-templates\fP, it is recommended to also install this package) +.IP \(bu 2 +openSUSE 13.2 and later +.UNINDENT +.SS Profiles +.sp +Profiles allow for a sort of shorthand for commonly\-used +configurations to be defined in the minion config file, \fIgrains\fP, \fIpillar\fP, or the master config file. The +profile is retrieved by Salt using the \fBconfig.get\fP function, which looks in those locations, in that +order. This allows for profiles to be defined centrally in the master config +file, with several options for overriding them (if necessary) on groups of +minions or individual minions. +.sp +There are two types of profiles: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +One for defining the parameters used in container creation/clone. +.IP \(bu 2 +One for defining the container\(aqs network interface(s) settings. +.UNINDENT +.UNINDENT +.UNINDENT +.SS Container Profiles +.sp +LXC container profiles are defined defined underneath the +\fBlxc.container_profile\fP config option: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.container_profile: + centos: + template: centos + backing: lvm + vgname: vg1 + lvname: lxclv + size: 10G + centos_big: + template: centos + backing: lvm + vgname: vg1 + lvname: lxclv + size: 20G +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Profiles are retrieved using the \fBconfig.get\fP +function, with the \fBrecurse\fP merge strategy. This means that a profile can be +defined at a lower level (for example, the master config file) and then parts +of it can be overridden at a higher level (for example, in pillar data). +Consider the following container profile data: +.sp +\fBIn the Master config file:\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.container_profile: + centos: + template: centos + backing: lvm + vgname: vg1 + lvname: lxclv + size: 10G +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBIn the Pillar data\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.container_profile: + centos: + size: 20G +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Any minion with the above Pillar data would have the \fBsize\fP parameter in the +\fBcentos\fP profile overriden to 20G, while those minions without the above +Pillar data would have the 10G \fBsize\fP value. This is another way of achieving +the same result as the \fBcentos_big\fP profile above, without having to define +another whole profile that differs in just one value. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +In the 2014.7.x release cycle and earlier, container profiles are defined +under \fBlxc.profile\fP\&. This parameter will still work in version 2015.5.0, +but is deprecated and will be removed in a future release. Please note +however that the profile merging feature described above will only work +with profiles defined under \fBlxc.container_profile\fP, and only in versions +2015.5.0 and later. +.UNINDENT +.UNINDENT +.sp +Additionally, in version 2015.5.0 container profiles have been expanded to +support passing template\-specific CLI options to \fBlxc.create\fP\&. Below is a table describing the parameters which +can be configured in container profiles: +.TS +center; +|l|l|l|. +_ +T{ +Parameter +T} T{ +2015.5.0 and Newer +T} T{ +2014.7.x and Earlier +T} +_ +T{ +\fItemplate\fP\s-2\u1\d\s0 +T} T{ +Yes +T} T{ +Yes +T} +_ +T{ +\fIoptions\fP\s-2\u1\d\s0 +T} T{ +Yes +T} T{ +No +T} +_ +T{ +\fIimage\fP\s-2\u1\d\s0 +T} T{ +Yes +T} T{ +Yes +T} +_ +T{ +\fIbacking\fP +T} T{ +Yes +T} T{ +Yes +T} +_ +T{ +\fIsnapshot\fP\s-2\u2\d\s0 +T} T{ +Yes +T} T{ +Yes +T} +_ +T{ +\fIlvname\fP\s-2\u1\d\s0 +T} T{ +Yes +T} T{ +Yes +T} +_ +T{ +\fIfstype\fP\s-2\u1\d\s0 +T} T{ +Yes +T} T{ +Yes +T} +_ +T{ +\fIsize\fP +T} T{ +Yes +T} T{ +Yes +T} +_ +.TE +.INDENT 0.0 +.IP 1. 3 +Parameter is only supported for container creation, and will be ignored if +the profile is used when cloning a container. +.IP 2. 3 +Parameter is only supported for container cloning, and will be ignored if +the profile is used when not cloning a container. +.UNINDENT +.SS Network Profiles +.sp +LXC network profiles are defined defined underneath the \fBlxc.network_profile\fP +config option. +By default, the module uses a DHCP based configuration and try to guess a bridge to +get connectivity. +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +on pre \fB2015.5.2\fP, you need to specify explitly the network bridge +.UNINDENT +.UNINDENT +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile: + centos: + eth0: + link: br0 + type: veth + flags: up + ubuntu: + eth0: + link: lxcbr0 + type: veth + flags: up +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +As with container profiles, network profiles are retrieved using the +\fBconfig.get\fP function, with the \fBrecurse\fP +merge strategy. Consider the following network profile data: +.sp +\fBIn the Master config file:\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile: + centos: + eth0: + link: br0 + type: veth + flags: up +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBIn the Pillar data\fP +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile: + centos: + eth0: + link: lxcbr0 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Any minion with the above Pillar data would use the \fBlxcbr0\fP interface as the +bridge interface for any container configured using the \fBcentos\fP network +profile, while those minions without the above Pillar data would use the +\fBbr0\fP interface for the same. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +In the 2014.7.x release cycle and earlier, network profiles are defined +under \fBlxc.nic\fP\&. This parameter will still work in version 2015.5.0, but +is deprecated and will be removed in a future release. Please note however +that the profile merging feature described above will only work with +profiles defined under \fBlxc.network_profile\fP, and only in versions +2015.5.0 and later. +.UNINDENT +.UNINDENT +.sp +The following are parameters which can be configured in network profiles. These +will directly correspond to a parameter in an LXC configuration file (see \fBman +5 lxc.container.conf\fP). +.INDENT 0.0 +.IP \(bu 2 +\fBtype\fP \- Corresponds to \fBlxc.network.type\fP +.IP \(bu 2 +\fBlink\fP \- Corresponds to \fBlxc.network.link\fP +.IP \(bu 2 +\fBflags\fP \- Corresponds to \fBlxc.network.flags\fP +.UNINDENT +.sp +Interface\-specific options (MAC address, IPv4/IPv6, etc.) must be passed on a +container\-by\-container basis, for instance using the \fBnic_opts\fP argument to +\fBlxc.create\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.create container1 profile=centos network_profile=centos nic_opts=\(aq{eth0: {ipv4: 10.0.0.20/24, gateway: 10.0.0.1}}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +The \fBipv4\fP, \fBipv6\fP, \fBgateway\fP, and \fBlink\fP (bridge) settings in +network profiles / nic_opts will only work if the container doesnt redefine +the network configuration (for example in +\fB/etc/sysconfig/network\-scripts/ifcfg\-\fP on RHEL/CentOS, +or \fB/etc/network/interfaces\fP on Debian/Ubuntu/etc.). Use these with +caution. The container images installed using the \fBdownload\fP template, +for instance, typically are configured for eth0 to use DHCP, which will +conflict with static IP addresses set at the container level. +.UNINDENT +.UNINDENT +.SS Old lxc support (<1.0.7) +.sp +With saltstack \fB2015.5.2\fP and above, normally the setting is autoselected, but +before, you\(aqll need to teach your network profile to set +\fBlxc.network.ipv4.gateway\fP to \fBauto\fP when using a classic ipv4 configuration. +.sp +Thus you\(aqll need +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile.foo: + etho: + link: lxcbr0 + ipv4.gateway: auto +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Tricky network setups Examples +.sp +This example covers how to make a container with both an internal ip and a +public routable ip, wired on two veth pairs. +.sp +The another interface which receives directly a public routable ip can\(aqt be on +the first interface that we reserve for private inter LXC networking. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile.foo: + eth0: {gateway: null, bridge: lxcbr0} + eth1: + # replace that by your main interface + \(aqlink\(aq: \(aqbr0\(aq + \(aqmac\(aq: \(aq00:16:5b:01:24:e1\(aq + \(aqgateway\(aq: \(aq2.20.9.14\(aq + \(aqipv4\(aq: \(aq2.20.9.1\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Creating a Container on the CLI +.SS From a Template +.sp +LXC is commonly distributed with several template scripts in +/usr/share/lxc/templates. Some distros may package these separately in an +\fBlxc\-templates\fP package, so make sure to check if this is the case. +.sp +There are LXC template scripts for several different operating systems, but +some of them are designed to use tools specific to a given distribution. For +instance, the \fBubuntu\fP template uses deb_bootstrap, the \fBcentos\fP template +uses yum, etc., making these templates impractical when a container from a +different OS is desired. +.sp +The \fBlxc.create\fP function is used to create +containers using a template script. To create a CentOS container named +\fBcontainer1\fP on a CentOS minion named \fBmycentosminion\fP, using the +\fBcentos\fP LXC template, one can simply run the following command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt mycentosminion lxc.create container1 template=centos +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For these instances, there is a \fBdownload\fP template which retrieves minimal +container images for several different operating systems. To use this template, +it is necessary to provide an \fBoptions\fP parameter when creating the +container, with three values: +.INDENT 0.0 +.IP 1. 3 +\fBdist\fP \- the Linux distribution (i.e. \fBubuntu\fP or \fBcentos\fP) +.IP 2. 3 +\fBrelease\fP \- the release name/version (i.e. \fBtrusty\fP or \fB6\fP) +.IP 3. 3 +\fBarch\fP \- CPU architecture (i.e. \fBamd64\fP or \fBi386\fP) +.UNINDENT +.sp +The \fBlxc.images\fP function (new in version +2015.5.0) can be used to list the available images. Alternatively, the releases +can be viewed on \fI\%http://images.linuxcontainers.org/images/\fP\&. The images are +organized in such a way that the \fBdist\fP, \fBrelease\fP, and \fBarch\fP can be +determined using the following URL format: +\fBhttp://images.linuxcontainers.org/images/dist/release/arch\fP\&. For example, +\fBhttp://images.linuxcontainers.org/images/centos/6/amd64\fP would correspond to +a \fBdist\fP of \fBcentos\fP, a \fBrelease\fP of \fB6\fP, and an \fBarch\fP of \fBamd64\fP\&. +.sp +Therefore, to use the \fBdownload\fP template to create a new 64\-bit CentOS 6 +container, the following command can be used: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.create container1 template=download options=\(aq{dist: centos, release: 6, arch: amd64}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +These command\-line options can be placed into a \fI\%container profile\fP, like so: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.container_profile.cent6: + template: download + options: + dist: centos + release: 6 + arch: amd64 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The \fBoptions\fP parameter is not supported in profiles for the 2014.7.x +release cycle and earlier, so it would still need to be provided on the +command\-line. +.UNINDENT +.UNINDENT +.SS Cloning an Existing Container +.sp +To clone a container, use the \fBlxc.clone\fP +function: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.clone container2 orig=container1 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Using a Container Image +.sp +While cloning is a good way to create new containers from a common base +container, the source container that is being cloned needs to already exist on +the minion. This makes deploying a common container across minions difficult. +For this reason, Salt\(aqs \fBlxc.create\fP is capable +of installing a container from a tar archive of another container\(aqs rootfs. To +create an image of a container named \fBcent6\fP, run the following command as +root: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +tar czf cent6.tar.gz \-C /var/lib/lxc/cent6 rootfs +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Before doing this, it is recommended that the container is stopped. +.UNINDENT +.UNINDENT +.sp +The resulting tarball can then be placed alongside the files in the salt +fileserver and referenced using a \fBsalt://\fP URL. To create a container using +an image, use the \fBimage\fP parameter with \fBlxc.create\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.create new\-cent6 image=salt://path/to/cent6.tar.gz +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Making images of containers with LVM backing +.sp +For containers with LVM backing, the rootfs is not mounted, so it is +necessary to mount it first before creating the tar archive. When a +container is created using LVM backing, an empty \fBrootfs\fP dir is handily +created within \fB/var/lib/lxc/container_name\fP, so this can be used as the +mountpoint. The location of the logical volume for the container will be +\fB/dev/vgname/lvname\fP, where \fBvgname\fP is the name of the volume group, +and \fBlvname\fP is the name of the logical volume. Therefore, assuming a +volume group of \fBvg1\fP, a logical volume of \fBlxc\-cent6\fP, and a container +name of \fBcent6\fP, the following commands can be used to create a tar +archive of the rootfs: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +mount /dev/vg1/lxc\-cent6 /var/lib/lxc/cent6/rootfs +tar czf cent6.tar.gz \-C /var/lib/lxc/cent6 rootfs +umount /var/lib/lxc/cent6/rootfs +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +One caveat of using this method of container creation is that +\fB/etc/hosts\fP is left unmodified. This could cause confusion for some +distros if salt\-minion is later installed on the container, as the +functions that determine the hostname take \fB/etc/hosts\fP into account. +.sp +Additionally, when creating an rootfs image, be sure to remove +\fB/etc/salt/minion_id\fP and make sure that \fBid\fP is not defined in +\fB/etc/salt/minion\fP, as this will cause similar issues. +.UNINDENT +.UNINDENT +.SS Initializing a New Container as a Salt Minion +.sp +The above examples illustrate a few ways to create containers on the CLI, but +often it is desirable to also have the new container run as a Minion. To do +this, the \fBlxc.init\fP function can be used. This +function will do the following: +.INDENT 0.0 +.IP 1. 3 +Create a new container +.IP 2. 3 +Optionally set password and/or DNS +.IP 3. 3 +Bootstrap the minion (using either \fI\%salt\-bootstrap\fP or a custom command) +.UNINDENT +.sp +By default, the new container will be pointed at the same Salt Master as the +host machine on which the container was created. It will then request to +authenticate with the Master like any other bootstrapped Minion, at which point +it can be accepted. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.init test1 profile=centos +salt\-key \-a test1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For even greater convenience, the \fBLXC runner\fP contains +a runner function of the same name (\fBlxc.init\fP), +which creates a keypair, seeds the new minion with it, and pre\-accepts the key, +allowing for the new Minion to be created and authorized in a single step: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run lxc.init test1 host=myminion profile=centos +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Running Commands Within a Container +.sp +For containers which are not running their own Minion, commands can be run +within the container in a manner similar to using (\fBcmd.run +\fP on RHEL/CentOS, +or \fB/etc/network/interfaces\fP on Debian/Ubuntu/etc.). Use these with +caution. The container images installed using the \fBdownload\fP template, +for instance, typically are configured for eth0 to use DHCP, which will +conflict with static IP addresses set at the container level. +.UNINDENT +.UNINDENT +.SS Old lxc support (<1.0.7) +.sp +With saltstack \fB2015.5.2\fP and above, normally the setting is autoselected, but +before, you\(aqll need to teach your network profile to set +\fBlxc.network.ipv4.gateway\fP to \fBauto\fP when using a classic ipv4 configuration. +.sp +Thus you\(aqll need +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile.foo: + etho: + link: lxcbr0 + ipv4.gateway: auto +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Tricky network setups Examples +.sp +This example covers how to make a container with both an internal ip and a +public routable ip, wired on two veth pairs. +.sp +The another interface which receives directly a public routable ip can\(aqt be on +the first interface that we reserve for private inter LXC networking. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile.foo: + eth0: {gateway: null, bridge: lxcbr0} + eth1: + # replace that by your main interface + \(aqlink\(aq: \(aqbr0\(aq + \(aqmac\(aq: \(aq00:16:5b:01:24:e1\(aq + \(aqgateway\(aq: \(aq2.20.9.14\(aq + \(aqipv4\(aq: \(aq2.20.9.1\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Creating a Container on the CLI +.SS From a Template +.sp +LXC is commonly distributed with several template scripts in +/usr/share/lxc/templates. Some distros may package these separately in an +\fBlxc\-templates\fP package, so make sure to check if this is the case. +.sp +There are LXC template scripts for several different operating systems, but +some of them are designed to use tools specific to a given distribution. For +instance, the \fBubuntu\fP template uses deb_bootstrap, the \fBcentos\fP template +uses yum, etc., making these templates impractical when a container from a +different OS is desired. +.sp +The \fBlxc.create\fP function is used to create +containers using a template script. To create a CentOS container named +\fBcontainer1\fP on a CentOS minion named \fBmycentosminion\fP, using the +\fBcentos\fP LXC template, one can simply run the following command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt mycentosminion lxc.create container1 template=centos +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For these instances, there is a \fBdownload\fP template which retrieves minimal +container images for several different operating systems. To use this template, +it is necessary to provide an \fBoptions\fP parameter when creating the +container, with three values: +.INDENT 0.0 +.IP 1. 3 +\fBdist\fP \- the Linux distribution (i.e. \fBubuntu\fP or \fBcentos\fP) +.IP 2. 3 +\fBrelease\fP \- the release name/version (i.e. \fBtrusty\fP or \fB6\fP) +.IP 3. 3 +\fBarch\fP \- CPU architecture (i.e. \fBamd64\fP or \fBi386\fP) +.UNINDENT +.sp +The \fBlxc.images\fP function (new in version +2015.5.0) can be used to list the available images. Alternatively, the releases +can be viewed on \fI\%http://images.linuxcontainers.org/images/\fP\&. The images are +organized in such a way that the \fBdist\fP, \fBrelease\fP, and \fBarch\fP can be +determined using the following URL format: +\fBhttp://images.linuxcontainers.org/images/dist/release/arch\fP\&. For example, +\fBhttp://images.linuxcontainers.org/images/centos/6/amd64\fP would correspond to +a \fBdist\fP of \fBcentos\fP, a \fBrelease\fP of \fB6\fP, and an \fBarch\fP of \fBamd64\fP\&. +.sp +Therefore, to use the \fBdownload\fP template to create a new 64\-bit CentOS 6 +container, the following command can be used: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.create container1 template=download options=\(aq{dist: centos, release: 6, arch: amd64}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +These command\-line options can be placed into a \fI\%container profile\fP, like so: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.container_profile.cent6: + template: download + options: + dist: centos + release: 6 + arch: amd64 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The \fBoptions\fP parameter is not supported in profiles for the 2014.7.x +release cycle and earlier, so it would still need to be provided on the +command\-line. +.UNINDENT +.UNINDENT +.SS Cloning an Existing Container +.sp +To clone a container, use the \fBlxc.clone\fP +function: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.clone container2 orig=container1 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Using a Container Image +.sp +While cloning is a good way to create new containers from a common base +container, the source container that is being cloned needs to already exist on +the minion. This makes deploying a common container across minions difficult. +For this reason, Salt\(aqs \fBlxc.create\fP is capable +of installing a container from a tar archive of another container\(aqs rootfs. To +create an image of a container named \fBcent6\fP, run the following command as +root: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +tar czf cent6.tar.gz \-C /var/lib/lxc/cent6 rootfs +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Before doing this, it is recommended that the container is stopped. +.UNINDENT +.UNINDENT +.sp +The resulting tarball can then be placed alongside the files in the salt +fileserver and referenced using a \fBsalt://\fP URL. To create a container using +an image, use the \fBimage\fP parameter with \fBlxc.create\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.create new\-cent6 image=salt://path/to/cent6.tar.gz +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Making images of containers with LVM backing +.sp +For containers with LVM backing, the rootfs is not mounted, so it is +necessary to mount it first before creating the tar archive. When a +container is created using LVM backing, an empty \fBrootfs\fP dir is handily +created within \fB/var/lib/lxc/container_name\fP, so this can be used as the +mountpoint. The location of the logical volume for the container will be +\fB/dev/vgname/lvname\fP, where \fBvgname\fP is the name of the volume group, +and \fBlvname\fP is the name of the logical volume. Therefore, assuming a +volume group of \fBvg1\fP, a logical volume of \fBlxc\-cent6\fP, and a container +name of \fBcent6\fP, the following commands can be used to create a tar +archive of the rootfs: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +mount /dev/vg1/lxc\-cent6 /var/lib/lxc/cent6/rootfs +tar czf cent6.tar.gz \-C /var/lib/lxc/cent6 rootfs +umount /var/lib/lxc/cent6/rootfs +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +One caveat of using this method of container creation is that +\fB/etc/hosts\fP is left unmodified. This could cause confusion for some +distros if salt\-minion is later installed on the container, as the +functions that determine the hostname take \fB/etc/hosts\fP into account. +.sp +Additionally, when creating an rootfs image, be sure to remove +\fB/etc/salt/minion_id\fP and make sure that \fBid\fP is not defined in +\fB/etc/salt/minion\fP, as this will cause similar issues. +.UNINDENT +.UNINDENT +.SS Initializing a New Container as a Salt Minion +.sp +The above examples illustrate a few ways to create containers on the CLI, but +often it is desirable to also have the new container run as a Minion. To do +this, the \fBlxc.init\fP function can be used. This +function will do the following: +.INDENT 0.0 +.IP 1. 3 +Create a new container +.IP 2. 3 +Optionally set password and/or DNS +.IP 3. 3 +Bootstrap the minion (using either \fI\%salt\-bootstrap\fP or a custom command) +.UNINDENT +.sp +By default, the new container will be pointed at the same Salt Master as the +host machine on which the container was created. It will then request to +authenticate with the Master like any other bootstrapped Minion, at which point +it can be accepted. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.init test1 profile=centos +salt\-key \-a test1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For even greater convenience, the \fBLXC runner\fP contains +a runner function of the same name (\fBlxc.init\fP), +which creates a keypair, seeds the new minion with it, and pre\-accepts the key, +allowing for the new Minion to be created and authorized in a single step: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run lxc.init test1 host=myminion profile=centos +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Running Commands Within a Container +.sp +For containers which are not running their own Minion, commands can be run +within the container in a manner similar to using (\fBcmd.run + -{% for server, addrs in salt[\(aqmine.get\(aq](\(aqroles:web\(aq, \(aqnetwork.ip_addrs\(aq, expr_form=\(aqgrain\(aq).items() %} +{% for server, addrs in salt[\(aqmine.get\(aq](\(aqroles:web\(aq, \(aqnetwork.ip_addrs\(aq, expr_form=\(aqpillar\(aq).items() %} server {{ server }} {{ addrs[0] }}:80 check {% endfor %} @@ -13372,7 +15789,7 @@ command authorization to any external authentication system, such as PAM or LDAP .sp The external authentication system allows for specific users to be granted access to execute specific functions on specific minions. Access is configured -in the master configuration file and uses the access control system: +in the master configuration file and uses the \fIaccess control system\fP: .INDENT 0.0 .INDENT 3.5 .sp @@ -13402,8 +15819,8 @@ The PAM module does not allow authenticating as \fBroot\fP\&. .UNINDENT .UNINDENT .sp -To allow access to wheel modules or runner -modules the following \fB@\fP syntax must be used: +To allow access to \fIwheel modules\fP or \fIrunner +modules\fP the following \fB@\fP syntax must be used: .INDENT 0.0 .INDENT 3.5 .sp @@ -13653,7 +16070,7 @@ To configure an LDAP group, append a \fB%\fP to the ID: .nf .ft C external_auth: -ldap: + ldap: test_ldap_group%: \- \(aq*\(aq: \- test.echo @@ -13661,6 +16078,71 @@ ldap: .fi .UNINDENT .UNINDENT +.SH ACCESS CONTROL SYSTEM +.sp +New in version 0.10.4. + +.sp +Salt maintains a standard system used to open granular control to non +administrative users to execute Salt commands. The access control system +has been applied to all systems used to configure access to non administrative +control interfaces in Salt.These interfaces include, the \fBpeer\fP system, the +\fBexternal auth\fP system and the \fBclient acl\fP system. +.sp +The access control system mandated a standard configuration syntax used in +all of the three aforementioned systems. While this adds functionality to the +configuration in 0.10.4, it does not negate the old configuration. +.sp +Now specific functions can be opened up to specific minions from specific users +in the case of external auth and client ACLs, and for specific minions in the +case of the peer system. +.sp +The access controls are manifested using matchers in these configurations: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +client_acl: + fred: + \- web\e*: + \- pkg.list_pkgs + \- test.* + \- apache.* +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +In the above example, fred is able to send commands only to minions which match +the specified glob target. This can be expanded to include other functions for +other minions based on standard targets. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +external_auth: + pam: + dave: + \- test.ping + \- mongo\e*: + \- network.* + \- log\e*: + \- network.* + \- pkg.* + \- \(aqG@os:RedHat\(aq: + \- kmod.* + steve: + \- .* +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The above allows for all minions to be hit by test.ping by dave, and adds a +few functions that dave can execute on other minions. It also allows steve +unrestricted access to salt commands. .SH JOB MANAGEMENT .sp New in version 0.9.7. @@ -14317,6 +16799,198 @@ schedule: Since specifying the returner repeatedly can be tiresome, the \fBschedule_returner\fP option is available to specify one or a list of global returners to be used by the minions when scheduling. +.SH MANAGING THE JOB CACHE +.sp +The Salt Master maintains a job cache of all job executions which can be +queried via the jobs runner. The way this job cache is managed is very +pluggable via Salt\(aqs underlying returner interface. +.SS Default Job Cache +.sp +A number of options are available when configuring the job cache. The default +caching system uses local storage on the Salt Master and can be found in the +job cache directory (on Linux systems this is typically +/var/cache/salt/master/jobs). The default caching system is suitable for most +deployments as it does not typically require any further configuration or +management. +.sp +The default job cache is a temporary cache and jobs will be stored for 24 +hours. If the default cache needs to store jobs for a different period the +time can be easily adjusted by changing the \fIkeep_jobs\fP parameter in the +Salt Master configuration file. The value passed in is measured via hours: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +keep_jobs: 24 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS External Job Cache Options +.sp +Many deployments may wish to use an external database to maintain a long term +register of executed jobs. Salt comes with two main mechanisms to do this, the +master job cache and the external job cache. The difference is how the external +data store is accessed. +.SS Master Job Cache +.sp +New in version 2014.7. + +.sp +The master job cache setting makes the built in job cache on the master +modular. This system allows for the default cache to be swapped out by the Salt +returner system. To configure the master job cache, set up an external returner +database based on the instructions included with each returner and then simply +add the following configuration to the master configuration file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +master_job_cache: mysql +.ft P +.fi +.UNINDENT +.UNINDENT +.SS External Job Cache +.sp +The external job cache setting instructs the minions to directly contact the +data store. This scenario is helpful when the data store needs to be made +available to the minions. This can be an effective way to share historic data +across an infrastructure as data can be retrieved from the external job cache +via the \fBret\fP execution module. +.sp +To configure the external job cache, set up a returner database in the manner +described in the specific returner documentation. Ensure that the returner +database is accessible from the minions, and set the \fIext_job_cache\fP setting +in the master configuration file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_job_cache: redis +.ft P +.fi +.UNINDENT +.UNINDENT +.SH STORING DATA IN OTHER DATABASES +.sp +The SDB interface is designed to store and retrieve data that, unlike pillars +and grains, is not necessarily minion\-specific. The initial design goal was to +allow passwords to be stored in a secure database, such as one managed by the +keyring package, rather than as plain\-text files. However, as a generic database +interface, it could conceptually be used for a number of other purposes. +.sp +SDB was added to Salt in version 2014.7.0. SDB is currently experimental, and +should probably not be used in production. +.SS SDB Configuration +.sp +In order to use the SDB interface, a configuration profile must be set up in +either the master or minion configuration file. The configuration stanza +includes the name/ID that the profile will be referred to as, a \fBdriver\fP +setting, and any other arguments that are necessary for the SDB module that will +be used. For instance, a profile called \fBmykeyring\fP, which uses the +\fBsystem\fP service in the \fBkeyring\fP module would look like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +mykeyring: + driver: keyring + service: system +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +It is recommended to keep the name of the profile simple, as it is used in the +SDB URI as well. +.SS SDB URIs +.sp +SDB is designed to make small database queries (hence the name, SDB) using a +compact URL. This allows users to reference a database value quickly inside +a number of Salt configuration areas, without a lot of overhead. The basic +format of an SDB URI is: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +sdb:/// +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The profile refers to the configuration profile defined in either the master or +the minion configuration file. The args are specific to the module referred to +in the profile, but will typically only need to refer to the key of a +key/value pair inside the database. This is because the profile itself should +define as many other parameters as possible. +.sp +For example, a profile might be set up to reference credentials for a specific +OpenStack account. The profile might look like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +kevinopenstack: + driver: keyring + service: salt.cloud.openstack.kevin +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +And the URI used to reference the password might look like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +sdb://kevinopenstack/password +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Writing SDB Modules +.sp +There is currently one function that MUST exist in any SDB module (\fBget()\fP) +and one that MAY exist (\fBset_()\fP). If using a (\fBset_()\fP) function, a +\fB__func_alias__\fP dictionary MUST be declared in the module as well: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +__func_alias__ = { + \(aqset_\(aq: \(aqset\(aq, +} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This is because \fBset\fP is a Python built\-in, and therefore functions should not +be created which are called \fBset()\fP\&. The \fB__func_alias__\fP functionality is +provided via Salt\(aqs loader interfaces, and allows legally\-named functions to be +referred to using names that would otherwise be unwise to use. +.sp +The \fBget()\fP function is required, as it will be called via functions in other +areas of the code which make use of the \fBsdb://\fP URI. For example, the +\fBconfig.get\fP function in the \fBconfig\fP execution module uses this function. +.sp +The \fBset_()\fP function may be provided, but is not required, as some sources +may be read\-only, or may be otherwise unwise to access via a URI (for instance, +because of SQL injection attacks). +.sp +A simple example of an SDB module is \fBsalt/sdb/keyring_db.py\fP, as it provides +basic examples of most, if not all, of the types of functionality that are +available not only for SDB modules, but for Salt modules in general. .SH SALT EVENT SYSTEM .sp The Salt Event System is used to fire off events enabling third party @@ -14404,7 +17078,7 @@ Fired when accepting and rejecting minions keys on the Salt master. .INDENT 3.5 If a master is in \fBauto_accept mode\fP, \fBsalt/key\fP events will not be fired when the keys are accepted. In addition, pre\-seeding -keys (like happens through Salt\-Cloud) will not cause +keys (like happens through \fISalt\-Cloud\fP) will not cause firing of these events. .UNINDENT .UNINDENT @@ -14941,6 +17615,192 @@ caller.sminion.functions[\(aqevent.send\(aq]( .fi .UNINDENT .UNINDENT +.SH BEACONS +.sp +The beacon system allows the minion to hook into system processes and +continually translate external events into the salt event bus. The +primary example of this is the \fBinotify\fP beacon. This +beacon uses inotify to watch configured files or directories on the minion for +changes, creation, deletion etc. +.sp +This allows for the changes to be sent up to the master where the +reactor can respond to changes. +.SS Configuring The Beacons +.sp +The beacon system, like many others in Salt, can be configured via the +minion pillar, grains, or local config file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + inotify: + /etc/httpd/conf.d: {} + /opt: {} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Optionally, a beacon can be run on an interval other than the default +\fBloop_interval\fP, which is typically set to 1 second. +.sp +To run a beacon every 5 seconds, for example, provide an \fBinterval\fP argument +to a beacon. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +beacons: + inotify: + /etc/httpd/conf.d: {} + /opt: {} + interval: 5 + load: + \- 1m: + \- 0.0 + \- 2.0 + \- 5m: + \- 0.0 + \- 1.5 + \- 15m: + \- 0.1 + \- 1.0 + \- interval: 10 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Writing Beacon Plugins +.sp +Beacon plugins use the standard Salt loader system, meaning that many of the +constructs from other plugin systems holds true, such as the \fB__virtual__\fP +function. +.sp +The important function in the Beacon Plugin is the \fBbeacon\fP function. When +the beacon is configured to run, this function will be executed repeatedly +by the minion. The \fBbeacon\fP function therefore cannot block and should be +as lightweight as possible. The \fBbeacon\fP also must return a list of dicts, +each dict in the list will be translated into an event on the master. +.sp +Please see the \fBinotify\fP beacon as an example. +.SH RUNNING CUSTOM MASTER PROCESSES +.sp +In addition to the processes that the Salt Master automatically spawns, +it is possible to configure it to start additional custom processes. +.sp +This is useful if a dedicated process is needed that should run throughout +the life of the Salt Master. For periodic independent tasks, a +\fBscheduled runner\fP may be more appropriate. +.sp +Processes started in this way will be restarted if they die and will be +killed when the Salt Master is shut down. +.SS Example Configuration +.sp +Processes are declared in the master config file with the \fIext_processes\fP +option. Processes will be started in the order they are declared. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_processes: + \- mymodule.TestProcess + \- mymodule.AnotherProcess +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Example Process Class +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Import python libs +import time +import logging +from multiprocessing import Process + +# Import Salt libs +from salt.utils.event import SaltEvent + + +log = logging.getLogger(__name__) + + +class TestProcess(Process): + def __init__(self, opts): + Process.__init__(self) + self.opts = opts + + def run(self): + self.event = SaltEvent(\(aqmaster\(aq, self.opts[\(aqsock_dir\(aq]) + i = 0 + + while True: + self.event.fire_event({\(aqiteration\(aq: i}, \(aqext_processes/test{0}\(aq) + time.sleep(60) +.ft P +.fi +.UNINDENT +.UNINDENT +.SH HIGH AVAILABILITY FEATURES IN SALT +.sp +Salt supports several features for high availability and fault tolerance. +Brief documentation for these features is listed alongside their configuration +parameters in \fIConfiguration file examples\fP\&. +.SS Multimaster +.sp +Salt minions can connect to multiple masters at one time by configuring the +\fImaster\fP configuration paramter as a YAML list of all the available masters. By +default, all masters are "hot", meaning that any master can direct commands to +the Salt infrastructure. +.sp +In a multimaster configuration, each master must have the same cryptographic +keys, and minion keys must be accepted on all masters separately. The contents +of file_roots and pillar_roots need to be kept in sync with processes external +to Salt as well +.sp +A tutorial on setting up multimaster with "hot" masters is here: +.sp +\fBMultimaster Tutorial\fP +.SS Multimaster with Failover +.sp +Changing the \fBmaster_type\fP parameter from \fBstandard\fP to \fBfailover\fP will +cause minions to connect to the first responding master in the list of masters. +Every \fBmaster_alive_check\fP seconds the minions will check to make sure +the current master is still responding. If the master does not respond, +the minion will attempt to connect to the next master in the list. If the +minion runs out of masters, the list will be recycled in case dead masters +have been restored. Note that \fBmaster_alive_check\fP must be present in the +minion configuration, or else the recurring job to check master status +will not get scheduled. +.sp +Failover can be combined with PKI\-style encrypted keys, but PKI is NOT +REQUIRED to use failover. +.sp +Multimaster with PKI and Failover is discussed in +\fBthis tutorial\fP +.sp +\fBmaster_type: failover\fP can be combined with \fBmaster_shuffle: True\fP +to spread minion connections across all masters (one master per +minion, not each minion connecting to all masters). Adding Salt Syndics +into the mix makes it possible to create a load\-balanced Salt infrastructure. +If a master fails, minions will notice and select another master from the +available list. +.SS Syndic +.sp +Salt\(aqs Syndic feature is a way to create differing infrastructure +topologies. It is not strictly an HA feature, but can be treated as such. +.sp +With the syndic, a Salt infrastructure can be partitioned in such a way that +certain masters control certain segments of the infrastructure, and "Master +of Masters" nodes can control multiple segments underneath them. +.sp +Syndics are covered in depth in \fBSalt Syndic\fP\&. .SH SALT SYNDIC .sp The Salt Syndic interface is a powerful tool which allows for the construction @@ -15039,11 +17899,7 @@ standard minion. In order for the high\-level master to return information from minions that are below the syndic(s), the CLI requires a short wait time in order to allow the syndic(s) to gather responses from their minions. This value is defined in the - -.nf -\(ga\(ga -.fi -syndic_wait\(ga and has a default of five seconds. +\fBsyndic_wait\fP and has a default of five seconds. .sp While it is possible to run a syndic without a minion installed on the same machine, it is recommended, for a faster CLI response time, to do so. Without a minion @@ -15099,10 +17955,10 @@ The \fI\%proxytype connection class\fP (located in salt/proxy). .IP 2. 3 The \fI\%grains support code\fP (located in salt/grains). .IP 3. 3 -Salt modules specific to the controlled +\fISalt modules\fP specific to the controlled device. .IP 4. 3 -Salt states specific to the controlled device. +\fISalt states\fP specific to the controlled device. .UNINDENT .SS Configuration parameters on the master .sp @@ -15373,6 +18229,142 @@ def ping(self): The Junos API layer lacks the ability to do a traditional \(aqping\(aq, so the example simply checks the connection object field that indicates if the ssh connection was successfully made to the device. +.SH THE RAET TRANSPORT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +The RAET transport is in very early development, it is functional but no +promises are yet made as to its reliability or security. +As for reliability and security, the encryption used has been audited and +our tests show that raet is reliable. With this said we are still conducting +more security audits and pushing the reliability. +This document outlines the encryption used in RAET +.UNINDENT +.UNINDENT +.sp +New in version 2014.7.0. + +.sp +The Reliable Asynchronous Event Transport, or RAET, is an alternative transport +medium developed specifically with Salt in mind. It has been developed to +allow queuing to happen up on the application layer and comes with socket +layer encryption. It also abstracts a great deal of control over the socket +layer and makes it easy to bubble up errors and exceptions. +.sp +RAET also offers very powerful message routing capabilities, allowing for +messages to be routed between processes on a single machine all the way up to +processes on multiple machines. Messages can also be restricted, allowing +processes to be sent messages of specific types from specific sources +allowing for trust to be established. +.SS Using RAET in Salt +.sp +Using RAET in Salt is easy, the main difference is that the core dependencies +change, instead of needing pycrypto, M2Crypto, ZeroMQ, and PYZMQ, the packages +libsodium, libnacl, ioflo, and raet are required. Encryption is handled very cleanly +by libnacl, while the queueing and flow control is handled by +ioflo. Distribution packages are forthcoming, but libsodium can be easily +installed from source, or many distributions do ship packages for it. +The libnacl and ioflo packages can be easily installed from pypi, distribution +packages are in the works. +.sp +Once the new deps are installed the 2014.7 release or higher of Salt needs to +be installed. +.sp +Once installed, modify the configuration files for the minion and master to +set the transport to raet: +.sp +\fB/etc/salt/master\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +transport: raet +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +\fB/etc/salt/minion\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +transport: raet +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Now start salt as it would normally be started, the minion will connect to the +master and share long term keys, which can then in turn be managed via +salt\-key. Remote execution and salt states will function in the same way as +with Salt over ZeroMQ. +.SS Limitations +.sp +The 2014.7 release of RAET is not complete! The Syndic and Multi Master have +not been completed yet and these are slated for completion in the 2015.5.0 +release. +.sp +Also, Salt\-Raet allows for more control over the client but these hooks have +not been implemented yet, thereforre the client still uses the same system +as the ZeroMQ client. This means that the extra reliability that RAET exposes +has not yet been implemented in the CLI client. +.SS Why? +.SS Customer and User Request +.sp +Why make an alternative transport for Salt? There are many reasons, but the +primary motivation came from customer requests, many large companies came with +requests to run Salt over an alternative transport, the reasoning was varied, +from performance and scaling improvements to licensing concerns. These +customers have partnered with SaltStack to make RAET a reality. +.SS More Capabilities +.sp +RAET has been designed to allow salt to have greater communication +capabilities. It has been designed to allow for development into features +which out ZeroMQ topologies can\(aqt match. +.sp +Many of the proposed features are still under development and will be +announced as they enter proof of concept phases, but these features include +\fIsalt\-fuse\fP \- a filesystem over salt, \fIsalt\-vt\fP \- a parallel api driven shell +over the salt transport and many others. +.SS RAET Reliability +.sp +RAET is reliable, hence the name (Reliable Asynchronous Event Transport). +.sp +The concern posed by some over RAET reliability is based on the fact that +RAET uses UDP instead of TCP and UDP does not have built in reliability. +.sp +RAET itself implements the needed reliability layers that are not natively +present in UDP, this allows RAET to dynamically optimize packet delivery +in a way that keeps it both reliable and asynchronous. +.SS RAET and ZeroMQ +.sp +When using RAET, ZeroMQ is not required. RAET is a complete networking +replacement. It is noteworthy that RAET is not a ZeroMQ replacement in a +general sense, the ZeroMQ constructs are not reproduced in RAET, but they are +instead implemented in such a way that is specific to Salt\(aqs needs. +.sp +RAET is primarily an async communication layer over truly async connections, +defaulting to UDP. ZeroMQ is over TCP and abstracts async constructs within the +socket layer. +.sp +Salt is not dropping ZeroMQ support and has no immediate plans to do so. +.SS Encryption +.sp +RAET uses Dan Bernstein\(aqs NACL encryption libraries and CurveCP handshake. +The libnacl python binding binds to both libsodium and tweetnacl to execute +the underlying cryptography. This allows us to completely rely on an +externally developed cryptography system. +.sp +For more information on libsodium and CurveCP please see: +\fI\%http://doc.libsodium.org/\fP +\fI\%http://curvecp.org/\fP +.SS Programming Intro +.sp +\fIRaet Programming Introduction\fP .SH WINDOWS SOFTWARE REPOSITORY .sp The Salt Windows Software Repository provides a package manager and software @@ -15813,50 +18805,496 @@ There is no support in Salt for modifying ACLs, and therefore no support for changing file permissions, besides modifying the owner/user. .SH SALT CLOUD .SS Getting Started -.SS Install Salt Cloud .sp -Salt Cloud is now part of Salt proper. It was merged in as of -\fBSalt version 2014.1.0\fP\&. +Salt Cloud is built\-in to Salt and is configured on and executed from your Salt Master. +.SS Define a Profile .sp -On Ubuntu, install Salt Cloud by using following command: +The first step is to add the credentials for your cloud provider. Credentials +and provider settings are stored in provider configuration files. +Provider configurations contain the details needed to connect, and any global options that you want set on +your cloud minions (such as the location of your Salt Master). +.sp +On your Salt Master, browse to \fB/etc/salt/cloud.providers.d/\fP and create a file called \fB.provider.conf\fP, +replacing \fB\fP with \fBec2\fP, \fBsoftlayer\fP, and so on. The name helps you identify the contents, and is not +important as long as the file ends in \fB\&.conf\fP\&. +.sp +Next, browse to the \fI\%Provider specifics\fP and add any required settings for your +provider to this file. Here is an example for Amazon EC2: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -sudo add\-apt\-repository ppa:saltstack/salt -sudo apt\-get install salt\-cloud +my\-ec2: + provider: ec2 + # Set the EC2 access credentials (see below) + # + id: \(aqHJGRYCILJLKJYG\(aq + key: \(aqkdjgfsgm;woormgl/aserigjksjdhasdfgn\(aq + # Make sure this key is owned by root with permissions 0400. + # + private_key: /etc/salt/my_test_key.pem + keyname: my_test_key + securitygroup: default + # Optional: Set up the location of the Salt Master + # + minion: + master: saltmaster.example.com .ft P .fi .UNINDENT .UNINDENT .sp -If using Salt Cloud on OS X, \fBcurl\-ca\-bundle\fP must be installed. Presently, -this package is not available via \fBbrew\fP, but it is available using MacPorts: +The required configuration varies between providers so make sure you read the provider specifics. +.SS List Cloud Provider Options +.sp +You can now query the cloud provider you configured for available locations, +images, and sizes. This information is used when you set up VM profiles. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -sudo port install curl\-ca\-bundle +salt\-cloud \-\-list\-locations # my\-ec2 in the previous example +salt\-cloud \-\-list\-images +salt\-cloud \-\-list\-sizes .ft P .fi .UNINDENT .UNINDENT .sp -Salt Cloud depends on \fBapache\-libcloud\fP\&. Libcloud can be installed via pip -with \fBpip install apache\-libcloud\fP\&. -.SS Installing Salt Cloud for development +Replace \fB\fP with the name of the provider configuration you defined. +.SS Create VM Profiles .sp -Installing Salt for development enables Salt Cloud development as well, just -make sure \fBapache\-libcloud\fP is installed as per above paragraph. +On your Salt Master, browse to \fB/etc/salt/cloud.profiles.d/\fP and create a file called \fB.profiles.conf\fP, +replacing \fB\fP with \fBec2\fP, \fBsoftlayer\fP, and so on. The file must end in \fB\&.conf\fP\&. .sp -See these instructions: \fBInstalling Salt for development\fP\&. +You can now add any custom profiles you\(aqd like to define to this file. Here are a few examples: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +micro_ec2: + provider: my\-ec2 + image: ami\-d514f291 + size: t1.micro + +medium_ec2: + provider: my\-ec2 + image: ami\-d514f291 + size: m3.medium + +large_ec2: + provider: my\-ec2 + image: ami\-d514f291 + size: m3.large +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Notice that the \fBprovider\fP in our profile matches the provider name that we defined? That is how Salt Cloud +knows how to connect to create a VM with these attributes. +.SS Create VMs +.sp +VMs are created by calling \fBsalt\-cloud\fP with the following options: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p ... +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +For example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p micro_ec2 minion1 minion2 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Destroy VMs +.sp +Add a \fB\-d\fP and the minion name you provided to destroy: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-d minion1 minion2 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Query VMs +.sp +You can view details about the VMs you\(aqve created using \fB\-\-query\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-query +.ft P +.fi +.UNINDENT +.UNINDENT .SS Using Salt Cloud +.SS \fBsalt\-cloud\fP +.sp +Provision virtual machines in the cloud with Salt +.SS Synopsis +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-m /etc/salt/cloud.map + +salt\-cloud \-m /etc/salt/cloud.map NAME + +salt\-cloud \-m /etc/salt/cloud.map NAME1 NAME2 + +salt\-cloud \-p PROFILE NAME + +salt\-cloud \-p PROFILE NAME1 NAME2 NAME3 NAME4 NAME5 NAME6 +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Description +.sp +Salt Cloud is the system used to provision virtual machines on various public +clouds via a cleanly controlled profile and mapping system. +.SS Options +.INDENT 0.0 +.TP +.B \-\-version +Print the version of Salt that is running. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-versions\-report +Show program\(aqs dependencies and version number, and then exit +.UNINDENT +.INDENT 0.0 +.TP +.B \-h, \-\-help +Show the help message and exit +.UNINDENT +.INDENT 0.0 +.TP +.B \-c CONFIG_DIR, \-\-config\-dir=CONFIG_dir +The location of the Salt configuration directory. This directory contains +the configuration files for Salt master and minions. The default location +on most systems is \fB/etc/salt\fP\&. +.UNINDENT +.SS Execution Options +.INDENT 0.0 +.TP +.B \-L LOCATION, \-\-location=LOCATION +Specify which region to connect to. +.UNINDENT +.INDENT 0.0 +.TP +.B \-a ACTION, \-\-action=ACTION +Perform an action that may be specific to this cloud provider. This +argument requires one or more instance names to be specified. +.UNINDENT +.INDENT 0.0 +.TP +.B \-f , \-\-function= +Perform an function that may be specific to this cloud provider, that does +not apply to an instance. This argument requires a provider to be specified +(i.e.: nova). +.UNINDENT +.INDENT 0.0 +.TP +.B \-p PROFILE, \-\-profile=PROFILE +Select a single profile to build the named cloud VMs from. The profile must +be defined in the specified profiles file. +.UNINDENT +.INDENT 0.0 +.TP +.B \-m MAP, \-\-map=MAP +Specify a map file to use. If used without any other options, this option +will ensure that all of the mapped VMs are created. If the named VM already +exists then it will be skipped. +.UNINDENT +.INDENT 0.0 +.TP +.B \-H, \-\-hard +When specifying a map file, the default behavior is to ensure that all of +the VMs specified in the map file are created. If the \-\-hard option is +set, then any VMs that exist on configured cloud providers that are +not specified in the map file will be destroyed. Be advised that this can +be a destructive operation and should be used with care. +.UNINDENT +.INDENT 0.0 +.TP +.B \-d, \-\-destroy +Pass in the name(s) of VMs to destroy, salt\-cloud will search the +configured cloud providers for the specified names and destroy the +VMs. Be advised that this is a destructive operation and should be used +with care. Can be used in conjunction with the \-m option to specify a map +of VMs to be deleted. +.UNINDENT +.INDENT 0.0 +.TP +.B \-P, \-\-parallel +Normally when building many cloud VMs they are executed serially. The \-P +option will run each cloud vm build in a separate process allowing for +large groups of VMs to be build at once. +.sp +Be advised that some cloud provider\(aqs systems don\(aqt seem to be well suited +for this influx of vm creation. When creating large groups of VMs watch the +cloud provider carefully. +.UNINDENT +.INDENT 0.0 +.TP +.B \-u, \-\-update\-bootstrap +Update salt\-bootstrap to the latest develop version on GitHub. +.UNINDENT +.INDENT 0.0 +.TP +.B \-y, \-\-assume\-yes +Default yes in answer to all confirmation questions. +.UNINDENT +.INDENT 0.0 +.TP +.B \-k, \-\-keep\-tmp +Do not remove files from /tmp/ after deploy.sh finishes. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-show\-deploy\-args +Include the options used to deploy the minion in the data returned. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-script\-args=SCRIPT_ARGS +Script arguments to be fed to the bootstrap script when deploying the VM. +.UNINDENT +.SS Query Options +.INDENT 0.0 +.TP +.B \-Q, \-\-query +Execute a query and return some information about the nodes running on +configured cloud providers +.UNINDENT +.INDENT 0.0 +.TP +.B \-F, \-\-full\-query +Execute a query and print out all available information about all cloud VMs. +Can be used in conjunction with \-m to display only information about the +specified map. +.UNINDENT +.INDENT 0.0 +.TP +.B \-S, \-\-select\-query +Execute a query and print out selected information about all cloud VMs. +Can be used in conjunction with \-m to display only information about the +specified map. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-list\-providers +Display a list of configured providers. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-list\-profiles +New in version 2014.7.0. + +.sp +Display a list of configured profiles. Pass in a cloud provider to view +the provider\(aqs associated profiles, such as \fBdigital_ocean\fP, or pass in +\fBall\fP to list all the configured profiles. +.UNINDENT +.SS Cloud Providers Listings +.INDENT 0.0 +.TP +.B \-\-list\-locations=LIST_LOCATIONS +Display a list of locations available in configured cloud providers. Pass +the cloud provider that available locations are desired on, aka "linode", +or pass "all" to list locations for all configured cloud providers +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-list\-images=LIST_IMAGES +Display a list of images available in configured cloud providers. Pass the +cloud provider that available images are desired on, aka "linode", or pass +"all" to list images for all configured cloud providers +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-list\-sizes=LIST_SIZES +Display a list of sizes available in configured cloud providers. Pass the +cloud provider that available sizes are desired on, aka "AWS", or pass +"all" to list sizes for all configured cloud providers +.UNINDENT +.SS Cloud Credentials +.INDENT 0.0 +.TP +.B \-\-set\-password= +Configure password for a cloud provider and save it to the keyring. +PROVIDER can be specified with or without a driver, for example: +"\-\-set\-password bob rackspace" or more specific "\-\-set\-password bob +rackspace:openstack" DEPRECATED! +.UNINDENT +.SS Output Options +.INDENT 0.0 +.TP +.B \-\-out +Pass in an alternative outputter to display the return of data. This +outputter can be any of the available outputters: +.INDENT 7.0 +.INDENT 3.5 +\fBgrains\fP, \fBhighstate\fP, \fBjson\fP, \fBkey\fP, \fBoverstatestage\fP, \fBpprint\fP, \fBraw\fP, \fBtxt\fP, \fByaml\fP +.UNINDENT +.UNINDENT +.sp +Some outputters are formatted only for data returned from specific +functions; for instance, the \fBgrains\fP outputter will not work for non\-grains +data. +.sp +If an outputter is used that does not support the data passed into it, then +Salt will fall back on the \fBpprint\fP outputter and display the return data +using the Python \fBpprint\fP standard library module. +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +If using \fB\-\-out=json\fP, you will probably want \fB\-\-static\fP as well. +Without the static option, you will get a JSON string for each minion. +This is due to using an iterative outputter. So if you want to feed it +to a JSON parser, use \fB\-\-static\fP as well. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-out\-indent OUTPUT_INDENT, \-\-output\-indent OUTPUT_INDENT +Print the output indented by the provided value in spaces. Negative values +disable indentation. Only applicable in outputters that support +indentation. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-out\-file=OUTPUT_FILE, \-\-output\-file=OUTPUT_FILE +Write the output to the specified file. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-no\-color +Disable all colored output +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-force\-color +Force colored output +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +When using colored output the color codes are as follows: +.sp +\fBgreen\fP denotes success, \fBred\fP denotes failure, \fBblue\fP denotes +changes and success and \fByellow\fP denotes a expected future change in configuration. +.UNINDENT +.UNINDENT +.UNINDENT +.SS Examples +.sp +To create 4 VMs named web1, web2, db1, and db2 from specified profiles: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p fedora_rackspace web1 web2 db1 db2 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To read in a map file and create all VMs specified therein: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-m /path/to/cloud.map +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To read in a map file and create all VMs specified therein in parallel: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-m /path/to/cloud.map \-P +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To delete any VMs specified in the map file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-m /path/to/cloud.map \-d +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To delete any VMs NOT specified in the map file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-m /path/to/cloud.map \-H +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To display the status of all VMs specified in the map file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-m /path/to/cloud.map \-Q +.ft P +.fi +.UNINDENT +.UNINDENT +.SS See also +.sp +\fIsalt\-cloud(7)\fP +\fIsalt(7)\fP +\fIsalt\-master(1)\fP +\fIsalt\-minion(1)\fP .SS Salt Cloud basic usage .sp Salt Cloud needs, at least, one configured -Provider +\fIProvider\fP and \fBProfile\fP to be functional. .SS Creating a VM .sp @@ -16105,6 +19543,15 @@ $ salt\-cloud \-m /path/to/mapfile \-P .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Due to limitations in the GoGrid API, instances cannot be provisioned in parallel +with the GoGrid driver. Map files will work with GoGrid, but the \fB\-P\fP +argument should not be used on maps referencing GoGrid instances. +.UNINDENT +.UNINDENT +.sp A map file can also be enforced to represent the total state of a cloud deployment by using the \fB\-\-hard\fP option. When using the hard option any vms that exist but are not specified in the map file will be destroyed: @@ -16192,6 +19639,20 @@ Proceed? [N/y] .fi .UNINDENT .UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +Specifying Nodes with Maps on the Command Line +Specifying the name of a node or nodes with the maps options on the command +line is \fInot\fP supported. This is especially important to remember when +using \fB\-\-destroy\fP with maps; \fBsalt\-cloud\fP will ignore any arguments +passed in which are not directly relevant to the map file. \fIWhen using +\(ga\(ga\-\-destroy\(ga\(ga with a map, every node in the map file will be deleted!\fP +Maps don\(aqt provide any useful information for destroying individual nodes, +and should not be used to destroy a subset of a map. +.UNINDENT +.UNINDENT .SS Setting up New Salt Masters .sp Bootstrapping a new master in the map is as simple as: @@ -16327,22 +19788,14 @@ $ salt\-cloud \-f show_image ec2 image=ami\-fd20ad94 .sp There are three universal salt\-cloud functions that are extremely useful for gathering information about instances on a provider basis: -.sp - -.nf -* -.fi +.INDENT 0.0 +.IP \(bu 2 \fBlist_nodes\fP: Returns some general information about the instances for the given provider. - -.nf -* -.fi +.IP \(bu 2 \fBlist_nodes_full\fP: Returns all information about the instances for the given provider. - -.nf -* -.fi +.IP \(bu 2 \fBlist_nodes_select\fP: Returns select information about the instances for the given provider. +.UNINDENT .INDENT 0.0 .INDENT 3.5 .sp @@ -16359,6 +19812,45 @@ $ salt\-cloud \-f list_nodes_select linode Another useful reference for viewing salt\-cloud functions is the :ref:Salt Cloud Feature Matrix .SS Core Configuration +.SS Install Salt Cloud +.sp +Salt Cloud is now part of Salt proper. It was merged in as of +\fBSalt version 2014.1.0\fP\&. +.sp +On Ubuntu, install Salt Cloud by using following command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +sudo add\-apt\-repository ppa:saltstack/salt +sudo apt\-get install salt\-cloud +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If using Salt Cloud on OS X, \fBcurl\-ca\-bundle\fP must be installed. Presently, +this package is not available via \fBbrew\fP, but it is available using MacPorts: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +sudo port install curl\-ca\-bundle +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Salt Cloud depends on \fBapache\-libcloud\fP\&. Libcloud can be installed via pip +with \fBpip install apache\-libcloud\fP\&. +.SS Installing Salt Cloud for development +.sp +Installing Salt for development enables Salt Cloud development as well, just +make sure \fBapache\-libcloud\fP is installed as per above paragraph. +.sp +See these instructions: \fBInstalling Salt for development\fP\&. .SS Core Configuration .sp A number of core configuration options and some options that are global to the @@ -16386,7 +19878,7 @@ pool_size: 10 .sp The default minion configuration is set up in this file. Minions created by salt\-cloud derive their configuration from this file. Almost all parameters -found in Configuring the Salt Minion can +found in \fIConfiguring the Salt Minion\fP can be used here. .INDENT 0.0 .INDENT 3.5 @@ -16823,16 +20315,17 @@ my\-openstack\-config: Using Salt for DigitalOcean requires a \fBclient_key\fP and an \fBapi_key\fP\&. These can be found in the DigitalOcean web interface, in the "My Settings" section, under the API Access tab. -.. code\-block:: yaml .INDENT 0.0 .INDENT 3.5 -.INDENT 0.0 -.TP -.B my\-digitalocean\-config: -provider: digital_ocean -personal_access_token: xxx -location: New York 1 -.UNINDENT +.sp +.nf +.ft C +my\-digitalocean\-config: + provider: digital_ocean + personal_access_token: xxx + location: New York 1 +.ft P +.fi .UNINDENT .UNINDENT .sp @@ -16940,11 +20433,7 @@ devhost10\-lxc: .INDENT 0.0 .INDENT 3.5 In the cloud profile that uses this provider configuration, the syntax for the -\fBprovider\fP required field would be -.nf -\(ga\(ga -.fi -provdier: devhost10\-lxc\(ga. +\fBprovider\fP required field would be \fBprovider: devhost10\-lxc\fP\&. .UNINDENT .UNINDENT .SS Saltify @@ -17726,9 +21215,26 @@ salt\-cloud \-a show_instance myinstance DigitalOcean is a public cloud provider that specializes in Linux instances. .SS Configuration .sp -Using Salt for DigitalOcean requires a personal_access_token, an ssh_key_file, -and at least one SSH key name in ssh_key_names, more can be added by comma\-separating them. -The personal_access_token can be found in the Digital Ocean web interface, +Starting in Salt 2015.5.0, a new DigitalOcean driver was added to Salt Cloud to support +DigitalOcean\(aqs new API, APIv2. The original driver, referred to \fBdigital_ocean\fP will +be supported throughout the 2015.5.x releases of Salt, but will then be removed in Salt +Beryllium in favor of the APIv2 driver, \fBdigital_ocean_v2\fP\&. The following documentation +is relevant to the new driver, \fBdigital_ocean_v2\fP\&. To see documentation related to the +original \fBdigital_ocean\fP driver, please see the +\fBDigitalOcean Salt Cloud Driver\fP +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +When Salt Beryllium is released, the original \fBdigital_ocean\fP driver will no longer +be supported and the \fBdigital_ocean_v2\fP driver will become the \fBdigital_ocean\fP +driver. +.UNINDENT +.UNINDENT +.sp +Using Salt for DigitalOcean requires a \fBpersonal_access_token\fP, an \fBssh_key_file\fP, +and at least one SSH key name in \fBssh_key_names\fP\&. More can be added by separating each key +with a comma. The \fBpersonal_access_token\fP can be found in the DigitalOcean web interface in the "Apps & API" section. The SSH key name can be found under the "SSH Keys" section. .INDENT 0.0 .INDENT 3.5 @@ -17771,6 +21277,36 @@ digitalocean\-ubuntu: .UNINDENT .UNINDENT .sp +Locations can be obtained using the \fB\-\-list\-locations\fP option for the \fBsalt\-cloud\fP +command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# salt\-cloud \-\-list\-locations my\-digitalocean\-config +my\-digitalocean\-config: + \-\-\-\-\-\-\-\-\-\- + digital_ocean: + \-\-\-\-\-\-\-\-\-\- + Amsterdam 1: + \-\-\-\-\-\-\-\-\-\- + available: + False + features: + [u\(aqbackups\(aq] + name: + Amsterdam 1 + sizes: + [] + slug: + ams1 +\&...SNIP... +.ft P +.fi +.UNINDENT +.UNINDENT +.sp Sizes can be obtained using the \fB\-\-list\-sizes\fP option for the \fBsalt\-cloud\fP command: .INDENT 0.0 @@ -18357,7 +21893,7 @@ each cloud profile. Note that the number of instance stores varies by instance type. If more mappings are provided than are supported by the instance type, mappings will be created in the order provided and additional mappings will be ignored. Consult the \fI\%AWS documentation\fP for a listing of the available -instance stores, device names, and mount points. +instance stores, and device names. .INDENT 0.0 .INDENT 3.5 .sp @@ -18402,7 +21938,6 @@ existing volume use the \fBvolume_id\fP parameter. .nf .ft C device: /dev/xvdj -mount_point: /mnt/my_ebs volume_id: vol\-12345abcd .ft P .fi @@ -18416,7 +21951,6 @@ Or, to create a volume from an EBS snapshot, use the \fBsnapshot\fP parameter. .nf .ft C device: /dev/xvdj -mount_point: /mnt/my_ebs snapshot: snap\-abcd12345 .ft P .fi @@ -19081,6 +22615,17 @@ my\-gogrid\-config: .fi .UNINDENT .UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +A Note about using Map files with GoGrid: +.sp +Due to limitations in the GoGrid API, instances cannot be provisioned in parallel +with the GoGrid driver. Map files will work with GoGrid, but the \fB\-P\fP +argument should not be used on maps referencing GoGrid instances. +.UNINDENT +.UNINDENT .SS Profiles .SS Cloud Profiles .sp @@ -20213,7 +23758,19 @@ In other words, Salt will connect to a minion, then from that minion: .IP \(bu 2 Provision and configure a container for networking access .IP \(bu 2 -Use saltify to deploy salt and re\-attach to master +Use those modules to deploy salt and re\-attach to master. +.INDENT 2.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +\fBlxc runner\fP +.IP \(bu 2 +\fBlxc module\fP +.IP \(bu 2 +\fBseed\fP +.UNINDENT +.UNINDENT +.UNINDENT .UNINDENT .SS Limitations .INDENT 0.0 @@ -20223,16 +23780,26 @@ You can only act on one minion and one provider at a time. Listing images must be targeted to a particular LXC provider (nothing will be outputted with \fBall\fP) .UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +On pre \fB2015.5.2\fP, you need to specify explitly the network bridge +.UNINDENT +.UNINDENT .SS Operation .sp -Salt\(aqs LXC support does not use lxc.init. This enables it to tie minions -to a master in a more generic fashion (if any masters are defined) -and allows other custom association code. +Salt\(aqs LXC support does use \fBlxc.init\fP +via the \fBlxc.cloud_init_interface\fP +and seeds the minion via \fBseed.mkconfig\fP\&. +.sp +You can provide to those lxc VMs a profile and a network profile like if +you were directly using the minion module. .sp Order of operation: .INDENT 0.0 .IP \(bu 2 -Create the LXC container using \fBthe LXC execution module\fP on the desired minion (clone or template) +Create the LXC container on the desired minion (clone or template) .IP \(bu 2 Change LXC config options (if any need to be changed) .IP \(bu 2 @@ -20246,8 +23813,7 @@ Wait for LXC container to be up and ready for ssh .IP \(bu 2 Test SSH connection and bailout in error .IP \(bu 2 -Via SSH (with the help of saltify), upload deploy script and seeds, -then re\-attach the minion. +Upload deploy script and seeds, then re\-attach the minion. .UNINDENT .SS Provider configuration .sp @@ -20268,94 +23834,174 @@ devhost10\-lxc: .UNINDENT .SS Profile configuration .sp +Please read \fItutorial\-lxc\fP before anything else. +And specially \fItutorial\-lxc\-profiles\fP\&. +.sp Here are the options to configure your containers: .INDENT 0.0 .INDENT 3.5 +.INDENT 0.0 +.TP +.B target +Host minion id to install the lxc Container into +.TP +.B lxc_profile +Name of the profile or inline options for the LXC vm creation/cloning, +please see \fItutorial\-lxc\-profiles\-container\fP\&. +.TP +.B network_profile +Name of the profile or inline options for the LXC vm network settings, +please see \fItutorial\-lxc\-profiles\-network\fP\&. +.TP +.B nic_opts +Totally optionnal. +Per interface new\-style configuration options mappings which will +override any profile default option: +.INDENT 7.0 +.INDENT 3.5 .sp .nf .ft C -\(ga\(gatarget\(ga\(ga - Host minion id to install the lxc Container into -\(ga\(gaprofile\(ga\(ga - Name of the profile containing the LXC configuration - -Container creation/clone options: - Create a container by cloning: - \(ga\(gafrom_container\(ga\(ga - Name of an original container using clone - \(ga\(gasnapshot\(ga\(ga - Do we use snapshots on cloned filesystems - Create a container from scratch using an LXC template: - image - template to use - backing - Backing store type (None, lvm, brtfs) - lvname - LVM logical volume name, if any - fstype - Type of filesystem -size - Size of the containera (for brtfs, or lvm) -vgname - LVM Volume Group name, if any -users - Names of the users to be pre\-created inside the container -ssh_username - Username of the SSH systems administrator inside the container -sudo - Do we use sudo -ssh_gateway - if the minion is not in your \(aqtopmaster\(aq network, use - that gateway to connect to the lxc container. - This may be the public ip of the hosting minion -ssh_gateway_key - When using gateway, the ssh key of the gateway user (passed to saltify) -ssh_gateway_port - When using gateway, the ssh port of the gateway (passed to saltify) -ssh_gateway_user - When using gateway, user to login as via SSH (passed to saltify) -password - password for root and sysadmin (see "users" parameter above) -mac - mac address to assign to the container\(aqs network interface -ip - IP address to assign to the container\(aqs network interface -netmask - netmask for the network interface\(aqs IP -bridge - bridge under which the container\(aqs network interface will be enslaved -dnsservers - List of DNS servers to use\-\-this is optional. If present, DNS - servers will be restricted to that list if used -lxc_conf_unset - Configuration variables to unset in this container\(aqs LXC configuration -lxc_conf - LXC configuration variables to add in this container\(aqs LXC configuration -minion - minion configuration (see :doc:\(gaMinion Configuration in Salt Cloud \(ga) +eth0: {\(aqmac\(aq: \(aq00:16:3e:01:29:40\(aq, + \(aqgateway\(aq: None, (default) + \(aqlink\(aq: \(aqbr0\(aq, (default) + \(aqgateway\(aq: None, (default) + \(aqnetmask\(aq: \(aq\(aq, (default) + \(aqip\(aq: \(aq22.1.4.25\(aq}} .ft P .fi .UNINDENT .UNINDENT +.TP +.B password +password for root and sysadmin users +.TP +.B dnsservers +List of DNS servers to use. This is optional. +.TP +.B minion +minion configuration (see \fBMinion Configuration in Salt Cloud\fP) +.TP +.B bootstrap_shell +shell for bootstraping script (default: /bin/sh) +.TP +.B script +defaults to salt\-boostrap +.TP +.B script_args +arguments which are given to the bootstrap script. +the {0} placeholder will be replaced by the path which contains the +minion config and key files, eg: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +script_args="\-c {0}" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Using profiles: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -# Note: This example would go in /etc/salt/cloud.profile or any file in the -# /etc/salt/cloud.profile.d/ directory. +# Note: This example would go in /etc/salt/cloud.profiles or any file in the +# /etc/salt/cloud.profiles.d/ directory. +devhost10\-lxc: + provider: devhost10\-lxc + lxc_profile: foo + network_profile: bar + minion: + master: 10.5.0.1 + master_port: 4506 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Using inline profiles (eg to override the network bridge): +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +devhost11\-lxc: + provider: devhost10\-lxc + lxc_profile: + clone_from: foo + network_profile: + etho: + link: lxcbr0 + minion: + master: 10.5.0.1 + master_port: 4506 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Template instead of a clone: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +devhost11\-lxc: + provider: devhost10\-lxc + lxc_profile: + template: ubuntu + network_profile: + etho: + link: lxcbr0 + minion: + master: 10.5.0.1 + master_port: 4506 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Static ip: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Note: This example would go in /etc/salt/cloud.profiles or any file in the +# /etc/salt/cloud.profiles.d/ directory. +devhost10\-lxc: + provider: devhost10\-lxc + nic_opts: + eth0: + ipv4: 10.0.3.9 + minion: + master: 10.5.0.1 + master_port: 4506 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +DHCP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Note: This example would go in /etc/salt/cloud.profiles or any file in the +# /etc/salt/cloud.profiles.d/ directory. devhost10\-lxc: provider: devhost10\-lxc - from_container: ubuntu - backing: lvm - sudo: True - size: 3g - ip: 10.0.3.9 minion: master: 10.5.0.1 master_port: 4506 - lxc_conf: - \- lxc.utsname: superlxc .ft P .fi .UNINDENT @@ -20437,6 +24083,7 @@ linode_1024: provider: my\-linode\-config size: Linode 1024 image: Arch Linux 2013.06 + location: london .ft P .fi .UNINDENT @@ -20511,6 +24158,36 @@ my\-linode\-config: .fi .UNINDENT .UNINDENT +.sp +Locations can be obtained using the \fB\-\-list\-locations\fP option for the \fBsalt\-cloud\fP +command: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# salt\-cloud \-\-list\-locations my\-linode\-config +my\-linode\-config: + \-\-\-\-\-\-\-\-\-\- + linode: + \-\-\-\-\-\-\-\-\-\- + Atlanta, GA, USA: + \-\-\-\-\-\-\-\-\-\- + abbreviation: + atlanta + id: + 4 + Dallas, TX, USA: + \-\-\-\-\-\-\-\-\-\- + abbreviation: + dallas + id: + 2 +\&...SNIP... +.ft P +.fi +.UNINDENT +.UNINDENT .SS Cloning .sp When salt\-cloud accesses Linode via linode\-python it can clone machines. @@ -22104,6 +25781,147 @@ the following command: .sp You can now continue to provision new instances and they will all automatically be set up as minions of the master you\(aqve defined in the configuration file. +.SS Getting Started With vSphere +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Deprecated since version Carbon: The \fBvsphere\fP cloud driver has been +deprecated in favor of the \fBvmware\fP +cloud driver and will be removed in Salt Carbon. Please refer to +\fBGetting started with VMware\fP instead to get +started with the configuration. + +.UNINDENT +.UNINDENT +.sp +VMware vSphere is a management platform for virtual infrastructure and cloud +computing. +.SS Dependencies +.sp +The vSphere module for Salt Cloud requires the PySphere package, which is +available at PyPI: +.sp +\fI\%https://pypi.python.org/pypi/pysphere\fP +.sp +This package can be installed using \fIpip\fP or \fIeasy_install\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# pip install pysphere +# easy_install pysphere +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Configuration +.sp +Set up the cloud config at \fB/etc/salt/cloud.providers\fP or in the +\fB/etc/salt/cloud.providers.d/\fP directory: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-vsphere\-config: + provider: vsphere + # Set the vSphere access credentials + user: marco + password: polo + # Set the URL of your vSphere server + url: \(aqvsphere.example.com\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.SS Profiles +.SS Cloud Profiles +.sp +vSphere uses a Managed Object Reference to identify objects located in vCenter. +The MOR ID\(aqs are used when configuring a vSphere cloud profile. Use the +following reference when locating the MOR\(aqs for the cloud profile. +.sp +\fI\%http://kb.vmware.com/selfservice/microsites/search.do?cmd=displayKC&docType=kc&externalId=1017126&sliceId=1&docTypeID=DT_KB_1_1&dialogID=520386078&stateId=1%200%20520388386\fP +.sp +Set up an initial profile at \fB/etc/salt/cloud.profiles\fP or in the +\fB/etc/salt/cloud.profiles.d\fP directory: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +vsphere\-centos: + provider: my\-vsphere\-config + image: centos + # Optional + datastore: datastore\-15 + resourcepool: resgroup\-8 + folder: salt\-cloud + host: host\-9 + template: False +.ft P +.fi +.UNINDENT +.UNINDENT +.SS provider +.sp +Enter the name that was specified when the cloud provider profile was created. +.SS image +.sp +Images available to build an instance can be found using the \fI\-\-list\-images\fP +option: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +# salt\-cloud \-\-list\-images my\-vsphere\-config +.ft P +.fi +.UNINDENT +.UNINDENT +.SS datastore +.sp +The MOR of the datastore where the virtual machine should be located. If not +specified, the current datastore is used. +.SS resourcepool +.sp +The MOR of the resourcepool to be used for the new vm. If not set, it will use +the same resourcepool as the original vm. +.SS folder +.sp +Name of the folder that will contain the new VM. If not set, the VM will be +added to the folder the original VM belongs to. +.SS host +.sp +The MOR of the host where the vm should be registered. +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B If not specified: +.INDENT 7.0 +.IP \(bu 2 +if resourcepool is not specified, the current host is used. +.IP \(bu 2 +if resourcepool is specified, and the target pool represents a +stand\-alone host, the host is used. +.IP \(bu 2 +if resourcepool is specified, and the target pool represents a +DRS\-enabled cluster, a host selected by DRS is used. +.IP \(bu 2 +if resourcepool is specified, and the target pool represents a +cluster without DRS enabled, an InvalidArgument exception will be thrown. +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS template +.sp +Specifies whether or not the new virtual machine should be marked as a +template. Default is False. .SS Miscellaneous Options .SS Miscellaneous Salt Cloud Options .sp @@ -22142,16 +25960,18 @@ script_args: | head .fi .UNINDENT .UNINDENT -.SS Use SFTP to transfer files +.SS Selecting the File Transport .sp -Some distributions do not have scp distributed with the ssh package. The -solution is to use sftp with the \fIuse_sftp\fP flag +By default, Salt Cloud uses SFTP to transfer files to Linux hosts. However, if +SFTP is not available, or specific SCP functionality is needed, Salt Cloud can +be configured to use SCP instead. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -use_sftp: True +file_transport: sftp +file_transport: scp .ft P .fi .UNINDENT @@ -25646,13 +29466,13 @@ external interfaces to Salt, and even present multiple interfaces at once. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -The full list of netapi modules +\fIThe full list of netapi modules\fP .UNINDENT .UNINDENT .SS Configuration .sp -All \fBnetapi\fP configuration is done in the Salt master -config and takes a form similar to the following: +All \fBnetapi\fP configuration is done in the \fISalt master +config\fP and takes a form similar to the following: .INDENT 0.0 .INDENT 3.5 .sp @@ -25704,7 +29524,7 @@ file and then starting the \fBsalt\-api\fP daemon. Check the docs for each module to see external requirements and configuration settings. .sp Communication with Salt and Salt satellite projects is done using Salt\(aqs own -Python API\&. A list of available client interfaces is below. +\fIPython API\fP\&. A list of available client interfaces is below. .INDENT 0.0 .INDENT 3.5 .IP "salt\-api" @@ -25718,7 +29538,7 @@ project. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -The full list of netapi modules +\fIThe full list of netapi modules\fP .UNINDENT .UNINDENT .SS Client interfaces @@ -25743,7 +29563,7 @@ in the form of low\-data data structures. For example: .INDENT 7.0 .TP .B local(*args, **kwargs) -Run execution modules synchronously +Run \fIexecution modules\fP synchronously .sp See \fBsalt.client.LocalClient.cmd()\fP for all available parameters. @@ -25761,7 +29581,7 @@ Returns the result from the execution module .INDENT 7.0 .TP .B local_async(*args, **kwargs) -Run execution modules asynchronously +Run \fIexecution modules\fP asynchronously .sp Wraps \fBsalt.client.LocalClient.run_job()\fP\&. .INDENT 7.0 @@ -25773,7 +29593,7 @@ job ID .INDENT 7.0 .TP .B local_batch(*args, **kwargs) -Run execution modules against batches of minions +Run \fIexecution modules\fP against batches of minions .sp New in version 0.8.4. @@ -25804,7 +29624,7 @@ Returns the result from the runner module .INDENT 7.0 .TP .B wheel(fun, **kwargs) -Run wheel modules synchronously +Run \fIwheel modules\fP synchronously .sp Wraps \fBsalt.wheel.WheelClient.master_call()\fP\&. .sp @@ -26454,6 +30274,14 @@ Salt SSH takes its configuration from a master configuration file. Normally, thi file is in \fB/etc/salt/master\fP\&. If one wishes to use a customized configuration file, the \fB\-c\fP option to Salt SSH facilitates passing in a directory to look inside for a configuration file named \fBmaster\fP\&. +.SS Minion Config +.sp +New in version 2015.5.1. + +.sp +Minion config options can be defined globally using the master configuration +option \fBssh_minion_opts\fP\&. It can also be defined on a per\-minion basis with +the \fBminion_opts\fP entry in the roster. .SS Running Salt SSH as non\-root user .sp By default, Salt read all the configuration from /etc/salt/. If you are running @@ -26513,7 +30341,7 @@ identify which systems need to be targeted for execution. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -all\-salt.roster +\fIall\-salt.roster\fP .UNINDENT .UNINDENT .sp @@ -26544,21 +30372,189 @@ The information which can be stored in a roster \fItarget\fP is the following: .sp .nf .ft C -: # The id to reference the target system with - host: # The IP address or DNS name of the remote host - user: # The user to log in as - passwd: # The password to log in with +: # The id to reference the target system with + host: # The IP address or DNS name of the remote host + user: # The user to log in as + passwd: # The password to log in with # Optional parameters - port: # The target system\(aqs ssh port number - sudo: # Boolean to run command via sudo - priv: # File path to ssh private key, defaults to salt\-ssh.rsa - timeout: # Number of seconds to wait for response when establishing a - SSH connection + port: # The target system\(aqs ssh port number + sudo: # Boolean to run command via sudo + priv: # File path to ssh private key, defaults to salt\-ssh.rsa + timeout: # Number of seconds to wait for response when establishing + # an SSH connection + timeout: # Number of seconds to wait for response + minion_opts: # Dictionary of minion opts .ft P .fi .UNINDENT .UNINDENT +salt\-ssh server1 test.ping +.sp +salt\-ssh server1 test.ping \-i +.sp +salt\-ssh server1 test.ping \-\-askpass +.sp +salt\-ssh server1 test.ping +.INDENT 0.0 +.IP \(bu 2 +permission denied, do you want to deply the key? +.UNINDENT +.sp +salt\-ssh server1 disk.usage +salt\-ssh server1 network.interfaces +.INDENT 0.0 +.TP +.B server1: +host: 192.168.167.91 +user: root +.TP +.B server2: +host: 192.168.167.92 +user: vagrant +sudo: true +.UNINDENT +.sp +Install a package in minutes +.sp +vim /etc/salt/roster +.INDENT 0.0 +.TP +.B server3: +host: 192.168.167.93 +username: vagrant +sudo: true +.UNINDENT +.sp +salt\-ssh \-i server2 pkg.install cowsay +.sp +salt\-ssh \-i server2 cmd.run \(aq/usr/games/cowsay "Moo! This message brought to you by salt\-ssh"\(aq +.sp +Done +.sp +salt\-ssh \(aq*\(aq \-r \(aqifconfig\(aq +.sp +salt\-ssh \(aq*\(aq \-W pkg.install vim +.sp +salt\-ssh \(aq*\(aq cmd.run \(aqls \-a /tmp\(aq +salt\-ssh \(aq*\(aq cmd.run \(aqls \-a /tmp\(aq \-W +.sp +salt\-ssh can be ran from any system, it doesn\(aqt have to be a master. +Low overhead, run from your laptop. +.sp +Deployment handled by shim +the shim is a small script. +.sp +Target system needs python 2, 2.6 or higher (unless raw mode) +.sp +salt/client/init.py +.sp +Architecture differences +.sp +Salt is a push pull architecture \- Master can push jobs to the +minion, minion can pull files/data as needed +.sp +salt\-ssh is push only \- job has to be prepared beforehand +The master compiles the low state and gets everything ready. +.sp +Wrapper functions +.sp +salt/client/ssh/wrapper/* +.sp +cd /srv/salt +git clone \fI\%https://github.com/saltstack\-formulas/apache\-formula.git\fP base +rmd \-r base/.git +cp salt/pillar.example /srv/pillar/apache.sls +vim srv/pillar/top.sls +.INDENT 0.0 +.TP +.B base: +.INDENT 7.0 +.TP +.B \(aq*\(aq: +.INDENT 7.0 +.IP \(bu 2 +apache +.UNINDENT +.UNINDENT +.UNINDENT +.sp +salt\-ssh \(aq*\(aq pillar.item apache +.sp +vim /etc/salt/master +.INDENT 0.0 +.TP +.B extra_filerefs: +.INDENT 7.0 +.IP \(bu 2 +salt://apache/map.jinja (this file gets sent down with state runs \- can also be passed in on cli) +.UNINDENT +.UNINDENT +.sp +salt\-ssh \(aq*\(aq state.sls apache +Getting Started +.sp +Salt SSH is an agentless . +.sp +Salt SSH was developed over 18 months +.sp +Salt over SSH +Can leaves no trace (if desired) +Close to feature parity with Salt \- limitations are due to design (no event bus, no reactor, but +otherwise you can do all other actions) +No minion is installed +.sp +Installation +.sp +Salt Roster +.sp +The roster contains the connection information that the Salt Master uses to contact +a system over SSH. The roster is used only with SSH. +.sp +Open \fB/etc/salt/roster\fP in a text editor. +.sp +Add custom grains and other things here. By default ssh keys are used to authenticate. +.sp +The first time you connect to a system, use the \fB\-i\fP option. This accepts the host key +.sp +To auto accept run salt\-ssh \-i +.sp +Password authentication: +.sp +plain text password in roster file (not recommended) +.sp +\-\-askpass option +.sp +That worked! +.sp +Preferred way is to let salt ssh deploy its own key pair. All you need is the root password +for the target system. When you run commands, you won\(aqt be prompted. +.sp +salt\-ssh \(aq*\(aq test.ping +salt\-ssh \(aq*\(aq cmd.run \(aqls /\(aq +salt +.sp +Deployment process +.sp +The master complies Salt Thin, doesn\(aqt have certain dependencies that are required in a +typical environment. Creates a tarball, sends it over scp to a randomized secure temp directory +and then runs salt call from that temp directory. Gives you all of the power of salt, but introduces +some initial overhead. +.sp +The version of salt that is on the master is deployed to the ssh minion +.sp +Raw Commands +.sp +salt\-ssh \-r \- sends a raw command, this works on any system \- this doesn\(aqt go through a salt +module (not even cmd.run), +.sp +Remove Salt\-ssh when finished +.sp +salt\-ssh \-W +.sp +State system \- templated states with jinja calls to the salt dictionary \- each call makes a new ssh system, runs, gets the return, and then inserts it. +.sp +Publish and mine calls \- each minion .SH REFERENCE .SS Full list of builtin auth modules .TS @@ -26856,7 +30852,7 @@ Authenticate against an LDAP group Behavior is highly dependent on if Active Directory is in use. .sp AD handles group membership very differently than OpenLDAP. -See the External Authentication documentation for a thorough +See the \fIExternal Authentication\fP documentation for a thorough discussion of available parameters for customizing the search. .sp OpenLDAP allows you to search for all groups in the directory @@ -26874,63 +30870,44 @@ To get started, create a simple table that holds just a username and a password. The password field will hold a SHA256 checksum. .INDENT 0.0 .INDENT 3.5 -.INDENT 0.0 -.INDENT 3.5 .sp .nf .ft C - +CREATE TABLE \(gausers\(ga ( + \(gaid\(ga int(11) NOT NULL AUTO_INCREMENT, + \(gausername\(ga varchar(25) DEFAULT NULL, + \(gapassword\(ga varchar(70) DEFAULT NULL, + PRIMARY KEY (\(gaid\(ga) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; .ft P .fi .UNINDENT .UNINDENT -.INDENT 0.0 -.TP -.B CREATE TABLE \fIusers\fP ( -\fIid\fP int(11) NOT NULL AUTO_INCREMENT, -\fIusername\fP varchar(25) DEFAULT NULL, -\fIpassword\fP varchar(70) DEFAULT NULL, -PRIMARY KEY (\fIid\fP) -.UNINDENT -.sp -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; -.UNINDENT -.UNINDENT .sp To create a user within MySQL, execute the following statement. .INDENT 0.0 .INDENT 3.5 -.INDENT 0.0 -.INDENT 3.5 .sp .nf .ft C - -.ft P -.fi -.UNINDENT -.UNINDENT -.sp INSERT INTO users VALUES (NULL, \(aqdiana\(aq, SHA2(\(aqsecret\(aq, 256)) -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C - .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 -.TP -.B mysql_auth: -hostname: localhost -database: SaltStack -username: root -password: letmein -auth_sql: \(aqSELECT username FROM users WHERE username = "{0}" AND password = SHA2("{1}", 256)\(aq -.UNINDENT +.INDENT 3.5 +.sp +.nf +.ft C +mysql_auth: + hostname: localhost + database: SaltStack + username: root + password: letmein + auth_sql: \(aqSELECT username FROM users WHERE username = "{0}" AND password = SHA2("{1}", 256)\(aq +.ft P +.fi .UNINDENT .UNINDENT .sp @@ -26941,8 +30918,6 @@ authenticate users. Enable MySQL authentication. .INDENT 0.0 .INDENT 3.5 -.INDENT 0.0 -.INDENT 3.5 .sp .nf .ft C @@ -26954,8 +30929,6 @@ external_auth: .fi .UNINDENT .UNINDENT -.UNINDENT -.UNINDENT .INDENT 0.0 .TP .B depends @@ -27313,7 +31286,7 @@ salt \(aq*\(aq grains.items .UNINDENT .UNINDENT .sp -more info on using targeting with grains can be found here\&. +more info on using targeting with grains can be found \fIhere\fP\&. .SS Targeting with Executions .sp As of 0.8.8 targeting with executions is still under heavy development and this @@ -27353,7 +31326,7 @@ is used with \fBG@\fP as well as a regular expression with \fBE@\fP\&. The \fBwebser*\fP target does not need to be prefaced with a target type specifier because it is a glob. .sp -more info on using compound targeting can be found here\&. +more info on using compound targeting can be found \fIhere\fP\&. .SS Node Group Targeting .sp New in version 0.9.5. @@ -27361,7 +31334,7 @@ New in version 0.9.5. .sp For certain cases, it can be convenient to have a predefined group of minions on which to execute commands. This can be accomplished using what are called -nodegroups\&. Nodegroups allow for predefined +\fInodegroups\fP\&. Nodegroups allow for predefined compound targets to be declared in the master configuration file, as a sort of shorthand for having to type out complicated compound expressions. .INDENT 0.0 @@ -27528,7 +31501,20 @@ salt\-call [options] .SS Description .sp The salt\-call command is used to run module functions locally on a minion -instead of executing them from the master. +instead of executing them from the master. Salt\-call is used to run a +\fIStandalone Minion\fP, and was originally +created for \fItroubleshooting\fP\&. +.sp +The Salt Master is contacted to retrieve state files and other resources +during execution unless the \fB\-\-local\fP option is specified. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBsalt\-call\fP commands execute from the current user\(aqs shell +context, while \fBsalt\fP commands execute from the system\(aqs default context. +.UNINDENT +.UNINDENT .SS Options .INDENT 0.0 .TP @@ -28128,12 +32114,6 @@ cloud provider carefully. .UNINDENT .INDENT 0.0 .TP -.B \-Q, \-\-query -Execute a query and print out information about all cloud VMs. Can be used -in conjunction with \-m to display only information about the specified map. -.UNINDENT -.INDENT 0.0 -.TP .B \-u, \-\-update\-bootstrap Update salt\-bootstrap to the latest develop version on GitHub. .UNINDENT @@ -29496,7 +33476,7 @@ There are many ways to access Salt programmatically. .sp Salt can be used from CLI scripts as well as via a REST interface. .sp -See Salt\(aqs outputter system to retrieve structured +See Salt\(aqs \fIoutputter system\fP to retrieve structured data from Salt as JSON, or as shell\-friendly text, or many other formats. .sp See the \fBstate.event\fP runner to utilize @@ -29509,8 +33489,8 @@ Review the \fI\%netapi module\fP documentation for more information. .SS Salt\(aqs \fBopts\fP dictionary .sp Some clients require access to Salt\(aqs \fBopts\fP dictionary. (The dictionary -representation of the master or -minion config files.) +representation of the \fImaster\fP or +\fIminion\fP config files.) .sp A common pattern for fetching the \fBopts\fP dictionary is to defer to environment variables if they exist or otherwise fetch the config from the @@ -29671,7 +33651,7 @@ print __grains__[\(aqid\(aq] The interface used by the \fBsalt\fP CLI tool on the Salt Master .sp \fBLocalClient\fP is used to send a command to Salt minions to execute -execution modules and return the results to the +\fIexecution modules\fP and return the results to the Salt Master. .sp Importing and using \fBLocalClient\fP must be done on the same machine as the @@ -29878,8 +33858,8 @@ A generator of minion returns .nf .ft C >>> returns = local.cmd_batch(\(aq*\(aq, \(aqstate.highstate\(aq, bat=\(aq10%\(aq) ->>> for return in returns: -\&... print return +>>> for ret in returns: +\&... print(ret) {\(aqjerry\(aq: {...}} {\(aqdave\(aq: {...}} {\(aqstewart\(aq: {...}} @@ -29898,7 +33878,7 @@ following exceptions. .INDENT 7.0 .TP .B Returns -A generator +A generator yielding the individual minion returns .UNINDENT .INDENT 7.0 .INDENT 3.5 @@ -29907,7 +33887,7 @@ A generator .ft C >>> ret = local.cmd_iter(\(aq*\(aq, \(aqtest.ping\(aq) >>> for i in ret: -\&... print i +\&... print(i) {\(aqjerry\(aq: {\(aqret\(aq: True}} {\(aqdave\(aq: {\(aqret\(aq: True}} {\(aqstewart\(aq: {\(aqret\(aq: True}} @@ -29919,24 +33899,29 @@ A generator .INDENT 7.0 .TP .B cmd_iter_no_block(tgt, fun, arg=(), timeout=None, expr_form=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, **kwargs) -Blocks while waiting for individual minions to return. +.INDENT 7.0 +.TP +.B Yields the individual minion returns as they come in, or None +when no returns are available. +.UNINDENT .sp The function signature is the same as \fBcmd()\fP with the following exceptions. .INDENT 7.0 .TP .B Returns -None until the next minion returns. This allows for actions -to be injected in between minion returns. +A generator yielding the individual minion returns, or None +when no returns are available. This allows for actions to be +injected in between minion returns. .UNINDENT .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C ->>> ret = local.cmd_iter(\(aq*\(aq, \(aqtest.ping\(aq) +>>> ret = local.cmd_iter_no_block(\(aq*\(aq, \(aqtest.ping\(aq) >>> for i in ret: -\&... print i +\&... print(i) None {\(aqjerry\(aq: {\(aqret\(aq: True}} {\(aqdave\(aq: {\(aqret\(aq: True}} @@ -30093,7 +34078,7 @@ Call a single salt function .B class salt.runner.RunnerClient(opts) The interface used by the \fBsalt\-run\fP CLI tool on the Salt Master .sp -It executes runner modules which run on the Salt +It executes \fIrunner modules\fP which run on the Salt Master. .sp Importing and using \fBRunnerClient\fP must be done on the same machine as @@ -30197,13 +34182,28 @@ runner.eauth_sync({ .B class salt.wheel.WheelClient(opts=None) An interface to Salt\(aqs wheel modules .sp -Wheel modules interact with various parts of the +\fIWheel modules\fP interact with various parts of the Salt Master. .sp Importing and using \fBWheelClient\fP must be done on the same machine as the Salt Master and it must be done using the same user that the Salt Master is running as. Unless \fBexternal_auth\fP is configured and the user is authorized to execute wheel functions: (\fB@wheel\fP). +.sp +Usage: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +import salt.config +import salt.wheel +opts = salt.config.master_config(\(aq/etc/salt/master\(aq) +wheel = salt.wheel.WheelClient(opts) +.ft P +.fi +.UNINDENT +.UNINDENT .INDENT 7.0 .TP .B async(fun, low, user=\(aqUNKNOWN\(aq) @@ -30219,27 +34219,8 @@ Execute a function .sp .nf .ft C ->>> opts = salt.config.master_config(\(aq/etc/salt/master\(aq) ->>> runner = salt.runner.RunnerClient(opts) ->>> runner.cmd(\(aqjobs.list_jobs\(aq, []) -{ - \(aq20131219215650131543\(aq: { - \(aqArguments\(aq: [300], - \(aqFunction\(aq: \(aqtest.sleep\(aq, - \(aqStartTime\(aq: \(aq2013, Dec 19 21:56:50.131543\(aq, - \(aqTarget\(aq: \(aq*\(aq, - \(aqTarget\-type\(aq: \(aqglob\(aq, - \(aqUser\(aq: \(aqsaltdev\(aq - }, - \(aq20131219215921857715\(aq: { - \(aqArguments\(aq: [300], - \(aqFunction\(aq: \(aqtest.sleep\(aq, - \(aqStartTime\(aq: \(aq2013, Dec 19 21:59:21.857715\(aq, - \(aqTarget\(aq: \(aq*\(aq, - \(aqTarget\-type\(aq: \(aqglob\(aq, - \(aqUser\(aq: \(aqsaltdev\(aq - }, -} +>>> wheel.cmd(\(aqkey.finger\(aq, [\(aqjerry\(aq]) +{\(aqminions\(aq: {\(aqjerry\(aq: \(aq5d:f6:79:43:5e:d4:42:3f:57:b8:45:a8:7e:a4:6e:ca\(aq}} .ft P .fi .UNINDENT @@ -30282,14 +34263,6 @@ and the user is authorized to execute runner functions: (\fB@wheel\fP). .sp .nf .ft C - -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -.nf -.ft C >>> wheel.cmd_sync({ \(aqfun\(aq: \(aqkey.finger\(aq, \(aqmatch\(aq: \(aqjerry\(aq, @@ -30302,6 +34275,8 @@ and the user is authorized to execute runner functions: (\fB@wheel\fP). .fi .UNINDENT .UNINDENT +.UNINDENT +.UNINDENT .SS CloudClient .INDENT 0.0 .TP @@ -30465,17 +34440,26 @@ Query select instance information .TP .B class salt.client.ssh.client.SSHClient(c_path=\(aq/etc/salt/master\(aq, mopts=None) Create a client object for executing routines via the salt\-ssh backend +.sp +New in version 2015.5.0. + .INDENT 7.0 .TP .B cmd(tgt, fun, arg=(), timeout=None, expr_form=\(aqglob\(aq, kwarg=None, **kwargs) Execute a single command via the salt\-ssh subsystem and return all routines at once +.sp +New in version 2015.5.0. + .UNINDENT .INDENT 7.0 .TP .B cmd_iter(tgt, fun, arg=(), timeout=None, expr_form=\(aqglob\(aq, ret=\(aq\(aq, kwarg=None, **kwargs) Execute a single command via the salt\-ssh subsystem and return a generator +.sp +New in version 2015.5.0. + .UNINDENT .UNINDENT .SS Full list of Salt Cloud modules @@ -30534,6 +34518,7 @@ _ T{ \fBjoyent\fP T} T{ +Joyent Cloud Module T} _ T{ @@ -30549,11 +34534,6 @@ Linode Cloud Module using Apache Libcloud OR linode\-python bindings T} _ T{ -\fBlinodepy\fP -T} T{ -T} -_ -T{ \fBlxc\fP T} T{ Install Salt on an LXC Container @@ -31123,6 +35103,18 @@ Show the details from the provider concerning an instance The DigitalOcean cloud module is used to control access to the DigitalOcean VPS system. .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Due to Digital Ocean deprecating its original API, this salt\-cloud driver for +Digital Ocean will be deprecated in Salt Beryllium. The digital_ocean_v2 driver +that is currently available on all 2015.5.x releases will be used instead. +Starting in Beryllium, the digital_ocean_v2.py driver will be renamed to +digital_ocean.py and this driver will be removed. Please convert any original +digital_ocean provider configs to use the new digital_ocean_v2 provider configs. +.UNINDENT +.UNINDENT +.sp Use of this module only requires the \fBapi_key\fP parameter to be set. Set up the cloud configuration at \fB/etc/salt/cloud.providers\fP or \fB/etc/salt/cloud.providers.d/digital_ocean.conf\fP: @@ -32063,6 +36055,10 @@ Might be depreciated later. .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.ec2.sign(key, msg) +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.ec2.ssh_interface(vm_) Return the ssh_interface type to connect to. Either \(aqpublic_ips\(aq (default) or \(aqprivate_ips\(aq. @@ -32116,13 +36112,15 @@ Create or navigate to your desired Project. Make sure Google Compute Engine service is enabled under the Services section. .IP \(bu 2 -Go to "APIs and auth" and then the "Registered apps" section. +Go to "APIs and auth" section, and then the "Credentials" link. .IP \(bu 2 -Click the "REGISTER APP" button and give it a meaningful name. +Click the "CREATE NEW CLIENT ID" button. .IP \(bu 2 -Select "Web Application" and click "Register". +Select "Service Account" and click "Create Client ID" button. .IP \(bu 2 -Select Certificate, then "Generate Certificate" +This will automatically download a .json file; ignore it. +.IP \(bu 2 +Look for a new "Service Account" section in the page, click on the "Generate New P12 key" button .IP \(bu 2 Copy the Email Address for inclusion in your /etc/salt/cloud file in the \(aqservice_account_email_address\(aq setting. @@ -32148,7 +36146,7 @@ Consider using a more secure location for your private key. .ft C my\-gce\-config: # The Google Cloud Platform Project ID - project: google.com:erjohnso + project: "my\-project\-id" # The Service ACcount client ID service_account_email_address: 1234567890@developer.gserviceaccount.com # The location of the private key (PEM format) @@ -32739,6 +36737,17 @@ my\-gogrid\-config: .fi .UNINDENT .UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +A Note about using Map files with GoGrid: +.sp +Due to limitations in the GoGrid API, instances cannot be provisioned in parallel +with the GoGrid driver. Map files will work with GoGrid, but the \fB\-P\fP +argument should not be used on maps referencing GoGrid instances. +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B salt.cloud.clouds.gogrid.avail_images(conn=None, call=None) @@ -32747,6 +36756,12 @@ relevant data .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.gogrid.avail_locations(conn=None, call=None) +Return a dict of all available VM locations on the cloud provider with +relevant data +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.gogrid.avail_sizes(conn=None, call=None) Return a dict of all available VM images on the cloud provider with relevant data @@ -32778,6 +36793,17 @@ Return the image object to use .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.gogrid.get_node(conn, name) +Return a libcloud node for the named VM +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.gogrid.get_salt_interface(vm_) +Return the salt_interface type to connect to. Either \(aqpublic_ips\(aq (default) +or \(aqprivate_ips\(aq. +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.gogrid.get_size(conn, vm_) Return the VM\(aqs size object .UNINDENT @@ -32798,6 +36824,11 @@ Return a list of the VMs that are on the provider, with select fields .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.gogrid.reboot(name, conn=None) +Reboot a single VM +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.gogrid.script(vm_) Return the script deployment object .UNINDENT @@ -32806,6 +36837,463 @@ Return the script deployment object .B salt.cloud.clouds.gogrid.show_instance(name, call=None) Show the details from the provider concerning an instance .UNINDENT +.SS salt.cloud.clouds.joyent +.SS Joyent Cloud Module +.sp +The Joyent Cloud module is used to interact with the Joyent cloud system. +.sp +Set up the cloud configuration at \fB/etc/salt/cloud.providers\fP or +\fB/etc/salt/cloud.providers.d/joyent.conf\fP: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my\-joyent\-config: + provider: joyent + # The Joyent login user + user: fred + # The Joyent user\(aqs password + password: saltybacon + # The location of the ssh private key that can log into the new VM + private_key: /root/mykey.pem + # The name of the private key + private_key: mykey +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +When creating your profiles for the joyent cloud, add the location attribute to +the profile, this will automatically get picked up when performing tasks +associated with that vm. An example profile might look like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +joyent_512: + provider: my\-joyent\-config + size: Extra Small 512 MB + image: centos\-6 + location: us\-east\-1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This driver can also be used with the Joyent SmartDataCenter project. More +details can be found at: +.sp +Using SDC requires that an api_host_suffix is set. The default value for this is +\fI\&.api.joyentcloud.com\fP\&. All characters, including the leading \fI\&.\fP, should be +included: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +api_host_suffix: .api.myhostname.com +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B depends +PyCrypto +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.avail_images(call=None) +Get list of available images +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-images +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Can use a custom URL for images. Default is: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +image_url: images.joyent.com/image +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.avail_locations(call=None) +List all available locations +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.avail_sizes(call=None) +get list of available packages +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-\-list\-sizes +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.create(vm_) +Create a single VM from a data dict +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-p profile_name vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.create_node(**kwargs) +convenience function to make the rest api call for node creation. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.delete_key(kwargs=None, call=None) +List the keys available +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f delete_key joyent keyname=mykey +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.destroy(name, call=None) +destroy a machine by name +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP \-\- name given to the machine +.IP \(bu 2 +\fBcall\fP \-\- call value in this case is \(aqaction\(aq +.UNINDENT +.TP +.B Returns +array of booleans , true if successfully stopped and true if +successfully removed +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-d vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_configured_provider() +Return the first configured instance. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_image(vm_) +Return the image object to use +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_location(vm_=None) +.INDENT 7.0 +.TP +.B Return the joyent data center to use, in this order: +.INDENT 7.0 +.IP \(bu 2 +CLI parameter +.IP \(bu 2 +VM parameter +.IP \(bu 2 +Cloud profile setting +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_location_path(location=\(aqus\-east\-1\(aq, api_host_suffix=\(aq.api.joyentcloud.com\(aq) +create url from location variable +:param location: joyent data center location +:return: url +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_node(name) +gets the node from the full node list by name +:param name: name of the vm +:return: node object +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_salt_interface(vm_) +Return the salt_interface type to connect to. Either \(aqpublic_ips\(aq (default) +or \(aqprivate_ips\(aq. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.get_size(vm_) +Return the VM\(aqs size object +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.has_method(obj, method_name) +Find if the provided object has a specific method +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.import_key(kwargs=None, call=None) +List the keys available +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-f import_key joyent keyname=mykey keyfile=/tmp/mykey.pub +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.joyent_node_state(id_) +Convert joyent returned state to state common to other data center return +values for consistency +.INDENT 7.0 +.TP +.B Parameters +\fBid\fP \-\- joyent state value +.TP +.B Returns +libcloudfuncs state value +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.key_list(items=None) +convert list to dictionary using the key as the identifier +:param items: array to iterate over +:return: dictionary +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.list_keys(kwargs=None, call=None) +List the keys available +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.list_nodes(full=False, call=None) +list of nodes, keeping only a brief listing +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-Q +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.list_nodes_full(call=None) +list of nodes, maintaining all content provided from joyent listings +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-F +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.list_nodes_select(call=None) +Return a list of the VMs that are on the provider, with select fields +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.query(action=None, command=None, args=None, method=\(aqGET\(aq, location=None, data=None) +Make a web call to Joyent +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.query_instance(vm_=None, call=None) +Query an instance upon creation from the Joyent API +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.reboot(name, call=None) +reboot a machine by name +:param name: name given to the machine +:param call: call value in this case is \(aqaction\(aq +:return: true if successful +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a reboot vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.reformat_node(item=None, full=False) +Reformat the returned data from joyent, determine public/private IPs and +strip out fields if necessary to provide either full or brief content. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBitem\fP \-\- node dictionary +.IP \(bu 2 +\fBfull\fP \-\- full or brief output +.UNINDENT +.TP +.B Returns +dict +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.show_instance(name, call=None) +get details about a machine +:param name: name given to the machine +:param call: call value in this case is \(aqaction\(aq +:return: machine information +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a show_instance vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.show_key(kwargs=None, call=None) +List the keys available +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.ssh_interface(vm_) +Return the ssh_interface type to connect to. Either \(aqpublic_ips\(aq (default) +or \(aqprivate_ips\(aq. +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.start(name, call=None) +start a machine by name +:param name: name given to the machine +:param call: call value in this case is \(aqaction\(aq +:return: true if successful +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a start vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.stop(name, call=None) +stop a machine by name +:param name: name given to the machine +:param call: call value in this case is \(aqaction\(aq +:return: true if successful +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-cloud \-a stop vm_name +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.joyent.take_action(name=None, call=None, command=None, data=None, method=\(aqGET\(aq, location=\(aqus\-east\-1\(aq) +take action call used by start,stop, reboot +:param name: name given to the machine +:param call: call value in this case is \(aqaction\(aq +:command: api path +:data: any data to be passed to the api, must be in json format +:method: GET,POST,or DELETE +:location: data center to execute the command on +:return: true if successful +.UNINDENT .SS salt.cloud.clouds.libcloud_aws .SS The AWS Cloud Module .sp @@ -33015,7 +37503,11 @@ linode\-python >= 1.1.1 .UNINDENT .sp OR -:depends: apache\-libcloud >= 0.13.2 +.INDENT 0.0 +.TP +.B depends +apache\-libcloud >= 0.13.2 +.UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 @@ -33227,7 +37719,7 @@ Wait for a certain status New in version 2014.7.0. .sp -Please read core config documentation\&. +Please read \fIcore config documentation\fP\&. .INDENT 0.0 .TP .B salt.cloud.clouds.lxc.avail_images() @@ -33533,6 +38025,11 @@ Note: For rackconnect v3, rackconnectv3 needs to be specified with the rackconnect v3 cloud network as it\(aqs variable .INDENT 0.0 .TP +.B salt.cloud.clouds.nova.attach_volume(name, server_name, device=\(aq/dev/xvdb\(aq, **kwargs) +Attach block volume +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.nova.avail_images() Return a dict of all available VM images on the cloud provider. .UNINDENT @@ -33553,6 +38050,16 @@ Create a single VM from a data dict .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.nova.create_attach_volumes(name, call=None, **kwargs) +Create and attach volumes to created node +.UNINDENT +.INDENT 0.0 +.TP +.B salt.cloud.clouds.nova.create_volume(name, size=100, snapshot=None, voltype=None, **kwargs) +Create block storage device +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.nova.destroy(name, conn=None, call=None) Delete a single VM .UNINDENT @@ -33680,6 +38187,11 @@ Create block storage device .UNINDENT .INDENT 0.0 .TP +.B salt.cloud.clouds.nova.volume_create_attach(name, call=None, **kwargs) +Create and attach volumes to created node +.UNINDENT +.INDENT 0.0 +.TP .B salt.cloud.clouds.nova.volume_delete(name, **kwargs) Delete block storage device .UNINDENT @@ -34690,7 +39202,7 @@ are already installed, but not Salted. .sp Use of this module requires no configuration in the main cloud configuration file. However, profiles must still be configured, as described in the -core config documentation\&. +\fIcore config documentation\fP\&. .INDENT 0.0 .TP .B salt.cloud.clouds.saltify.create(vm_) @@ -34719,11 +39231,6 @@ no nodes to list. Because this module is not specific to any cloud providers, there will be no nodes to list. .UNINDENT -.INDENT 0.0 -.TP -.B salt.cloud.clouds.saltify.script(vm_) -Return the script deployment object -.UNINDENT .SS salt.cloud.clouds.softlayer .SS SoftLayer Cloud Module .sp @@ -34984,8 +39491,17 @@ Show the details from SoftLayer concerning a guest .SS salt.cloud.clouds.vsphere .SS vSphere Cloud Module .sp -New in version 2014.7.0. +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Deprecated since version Carbon: The \fI\%vsphere\fP cloud driver has been +deprecated in favor of the \fBvmware\fP +cloud driver and will be removed in Salt Carbon. Please refer to +\fBGetting started with VMware\fP to get started +and convert your vsphere provider configurations to use the vmware driver. +.UNINDENT +.UNINDENT .sp The vSphere cloud module is used to control access to VMWare vSphere. .INDENT 0.0 @@ -35025,6 +39541,8 @@ my\-vsphere\-config: provider: vsphere user: myuser password: verybadpass + template_user: root + template_password: mybadVMpassword url: \(aqhttps://10.1.1.1:443\(aq .ft P .fi @@ -35049,19 +39567,23 @@ https://10.1.1.1:443/sdk .UNINDENT .INDENT 0.0 .TP -.B folder: Name of the folder that will contain the new VM. If not set, the VM will -be added to the folder the original VM belongs to. +.B folder +Name of the folder that will contain the new VM. If not set, the VM will be added to +the folder the original VM belongs to. .TP -.B resourcepool: MOR of the resourcepool to be used for the new vm. If not set, it -uses the same resourcepool than the original vm. +.B resourcepool +MOR of the resourcepool to be used for the new vm. If not set, it uses the same +resourcepool than the original vm. .TP -.B datastore: MOR of the datastore where the virtual machine should be located. If -not specified, the current datastore is used. +.B datastore +MOR of the datastore where the virtual machine should be located. If not specified, +the current datastore is used. .TP -.B host: MOR of the host where the virtual machine should be registered. +.B host +MOR of the host where the virtual machine should be registered. .INDENT 7.0 .TP -.B IF not specified: +.B Id not specified: .INDENT 7.0 .IP \(bu 2 if resourcepool is not specified, current host is used. @@ -35077,8 +39599,27 @@ without DRS enabled, an InvalidArgument exception will be thrown. .UNINDENT .UNINDENT .TP -.B template: Specifies whether or not the new virtual machine should be marked as a -template. Default is False. +.B template +Specifies whether or not the new virtual machine should be marked as a template. +Default is False. +.TP +.B template_user +Specifies the user to access the VM. Should be +.TP +.B template_password +The password with which to access the VM. +.TP +.B sudo +The user to access the VM with sudo privileges. +.sp +New in version 2015.5.2. + +.TP +.B sudo_password +The password corresponding to the sudo user to access the VM with sudo privileges. +.sp +New in version 2015.5.2. + .UNINDENT .INDENT 0.0 .TP @@ -35250,7 +39791,8 @@ Show the details from vSphere concerning a guest # The number of worker threads to start. These threads are used to manage # return calls made from minions to the master. If the master seems to be -# running slowly, increase the number of threads. +# running slowly, increase the number of threads. This setting can not be +# set lower than 3. #worker_threads: 5 # The port used by the communication interface. The ret (return) port is the @@ -35499,6 +40041,17 @@ Show the details from vSphere concerning a guest # will cause minion to throw an exception and drop the message. # sign_pub_messages: False +##### Salt\-SSH Configuration ##### +########################################## + +# Pass in an alternative location for the salt\-ssh roster file +#roster_file: /etc/salt/roster + +# Pass in minion option overrides that will be inserted into the SHIM for +# salt\-ssh calls. The local minion config is not used for salt\-ssh. Can be +# overridden on a per\-minion basis in the roster (\(gaminion_opts\(ga) +#ssh_minion_opts: +# gpg_keydir: /root/gpg ##### Master Module Management ##### ########################################## @@ -35952,6 +40505,18 @@ Show the details from vSphere concerning a guest # If only one master is listed, this setting is ignored and a warning will be logged. #random_master: False +# Minions can connect to multiple masters simultaneously (all masters +# are "hot"), or can be configured to failover if a master becomes +# unavailable. Multiple hot masters are configured by setting this +# value to "standard". Failover masters can be requested by setting +# to "failover". MAKE SURE TO SET master_alive_interval if you are +# using failover. +# master_type: standard + +# Poll interval in seconds for checking if the master is still there. Only +# respected if master_type above is "failover". +# master_alive_interval: 30 + # Set whether the minion should connect to the master via IPv6: #ipv6: False @@ -36391,6 +40956,10 @@ Show the details from vSphere concerning a guest # states is cluttering the logs. Set it to True to ignore them. #state_output_diff: False +# The state_output_profile setting changes whether profile information +# will be shown for each state run. +#state_output_profile: True + # Fingerprint of the master public key to double verify the master is valid, # the master fingerprint can be found by running "salt\-key \-F master" on the # salt master. @@ -36547,8 +41116,8 @@ Show the details from vSphere concerning a guest .SS Configuring Salt .sp Salt configuration is very simple. The default configuration for the -master will work for most installations and the only requirement for -setting up a minion is to set the location of the master in the minion +\fImaster\fP will work for most installations and the only requirement for +setting up a \fIminion\fP is to set the location of the master in the minion configuration file. .sp The configuration files will be installed to \fB/etc/salt\fP and are named @@ -36790,7 +41359,7 @@ of the Salt system each have a respective configuration file. The \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -example master configuration file +\fIexample master configuration file\fP .UNINDENT .UNINDENT .sp @@ -37152,11 +41721,11 @@ sock_dir: /var/run/salt/master .UNINDENT .SS \fBenable_gpu_grains\fP .sp -Default: \fBFalse\fP +Default: \fBTrue\fP .sp -The master can take a while to start up when lspci and/or dmidecode is used -to populate the grains for the master. Enable if you want to see GPU hardware -data for your master. +Enable GPU hardware data for your master. Be aware that the master can +take a while to start up when lspci and/or dmidecode is used to populate the +grains for the master. .SS \fBjob_cache\fP .sp Default: \fBTrue\fP @@ -37309,7 +41878,7 @@ con_cache: True Default: False .sp Causes the master to periodically look for actively connected minions. -Presence events are fired on the event bus on a +\fIPresence events\fP are fired on the event bus on a regular interval with a list of connected minions, as well as events with lists of newly connected or disconnected minions. This is a master\-only operation that does not send executions to minions. Note, this does not detect minions @@ -37324,6 +41893,7 @@ presence_events: False .fi .UNINDENT .UNINDENT +.SS Salt\-SSH Configuration .SS \fBroster_file\fP .sp Default: \(aq/etc/salt/roster\(aq @@ -37339,6 +41909,24 @@ roster_file: /root/roster .fi .UNINDENT .UNINDENT +.SS \fBssh_minion_opts\fP +.sp +Default: None +.sp +Pass in minion option overrides that will be inserted into the SHIM for +salt\-ssh calls. The local minion config is not used for salt\-ssh. Can be +overridden on a per\-minion basis in the roster (\fBminion_opts\fP) +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +minion_opts: + gpg_keydir: /root/gpg +.ft P +.fi +.UNINDENT +.UNINDENT .SS Master Security Settings .SS \fBopen_mode\fP .sp @@ -37946,15 +42534,15 @@ fileserver environments. .UNINDENT .sp As of 2014.7.0, it is possible to have per\-repo versions of several of the -gitfs configuration parameters. For more information, see the GitFS -Walkthrough\&. +gitfs configuration parameters. For more information, see the \fIGitFS +Walkthrough\fP\&. .SS \fBgitfs_provider\fP .sp New in version 2014.7.0. .sp Specify the provider to be used for gitfs. More information can be found in the -GitFS Walkthrough\&. +\fIGitFS Walkthrough\fP\&. .sp Specify one value among valid values: \fBgitpython\fP, \fBpygit2\fP, \fBdulwich\fP .INDENT 0.0 @@ -37995,7 +42583,7 @@ Default: \fB\(aq\(aq\fP .sp Specifies a path on the salt fileserver from which gitfs remotes are served. Can be used in conjunction with \fI\%gitfs_root\fP\&. Can also be -configured on a per\-remote basis, see here for +configured on a per\-remote basis, see \fIhere\fP for more info. .INDENT 0.0 .INDENT 3.5 @@ -38035,7 +42623,7 @@ gitfs_root: somefolder/otherfolder .UNINDENT .sp Changed in version 2014.7.0: Ability to specify gitfs roots on a per\-remote basis was added. See -here for more info. +\fIhere\fP for more info. .SS \fBgitfs_base\fP .sp @@ -38053,7 +42641,7 @@ gitfs_base: salt .UNINDENT .UNINDENT .sp -Changed in version 2014.7.0: Ability to specify the base on a per\-remote basis was added. See here for more info. +Changed in version 2014.7.0: Ability to specify the base on a per\-remote basis was added. See \fIhere\fP for more info. .SS \fBgitfs_env_whitelist\fP .sp @@ -38064,7 +42652,7 @@ Default: \fB[]\fP .sp Used to restrict which environments are made available. Can speed up state runs if the repos in \fI\%gitfs_remotes\fP contain many branches/tags. More -information can be found in the GitFS Walkthrough\&. +information can be found in the \fIGitFS Walkthrough\fP\&. .INDENT 0.0 .INDENT 3.5 .sp @@ -38087,7 +42675,7 @@ Default: \fB[]\fP .sp Used to restrict which environments are made available. Can speed up state runs if the repos in \fI\%gitfs_remotes\fP contain many branches/tags. More -information can be found in the GitFS Walkthrough\&. +information can be found in the \fIGitFS Walkthrough\fP\&. .INDENT 0.0 .INDENT 3.5 .sp @@ -38104,7 +42692,7 @@ gitfs_env_blacklist: .SS GitFS Authentication Options .sp These parameters only currently apply to the pygit2 gitfs provider. Examples of -how to use these can be found in the GitFS Walkthrough\&. +how to use these can be found in the \fIGitFS Walkthrough\fP\&. .SS \fBgitfs_user\fP .sp New in version 2014.7.0. @@ -38171,7 +42759,7 @@ Default: \fB\(aq\(aq\fP .sp Along with \fI\%gitfs_privkey\fP (and optionally \fI\%gitfs_passphrase\fP), is used to authenticate to SSH remotes. This -parameter (or its per\-remote counterpart) is +parameter (or its \fIper\-remote counterpart\fP) is required for SSH remotes. .INDENT 0.0 .INDENT 3.5 @@ -38192,7 +42780,7 @@ Default: \fB\(aq\(aq\fP .sp Along with \fI\%gitfs_pubkey\fP (and optionally \fI\%gitfs_passphrase\fP), is used to authenticate to SSH remotes. This -parameter (or its per\-remote counterpart) is +parameter (or its \fIper\-remote counterpart\fP) is required for SSH remotes. .INDENT 0.0 .INDENT 3.5 @@ -38854,7 +43442,7 @@ ext_pillar: .UNINDENT .UNINDENT .sp -There are additional details at salt\-pillars +There are additional details at \fIsalt\-pillars\fP .SS \fBext_pillar_first\fP .sp New in version 2015.5.0. @@ -39370,7 +43958,7 @@ nodegroups: .UNINDENT .UNINDENT .sp -More information on using nodegroups can be found here\&. +More information on using nodegroups can be found \fIhere\fP\&. .SS Range Cluster Settings .SS \fBrange_server\fP .sp @@ -39473,6 +44061,24 @@ win_gitrepos: .fi .UNINDENT .UNINDENT +.sp +To specify a specific revision of the repository, preface the +repository location with a commit ID: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +win_gitrepos: + \- \(aq https://github.com/saltstack/salt\-winrepo.git\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Replacing \fB\fP with the ID from GitHub. Specifying a commit +ID is useful if you need to revert to a previous version if an error +is introduced in the latest version. .SS Configuring the Salt Minion .sp The Salt system is amazingly simple and easy to configure. The two components @@ -39483,7 +44089,7 @@ of the Salt system each have a respective configuration file. The \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -example minion configuration file +\fIexample minion configuration file\fP .UNINDENT .UNINDENT .sp @@ -39569,16 +44175,26 @@ master_type: failover New in version 2014.7.0. .sp -Default: \fBstr\fP +Default: \fBstandard\fP .sp -The type of the \fI\%master\fP variable. Can be either \fBfunc\fP or -\fBfailover\fP\&. +The type of the \fI\%master\fP variable. Can be \fBstandard\fP, \fBfailover\fP or +\fBfunc\fP\&. +.INDENT 0.0 +.INDENT 3.5 .sp -If the master needs to be dynamically assigned by executing a function instead -of reading in the static master value, set this to \fBfunc\fP\&. This can be used -to manage the minion\(aqs master setting from an execution module. By simply -changing the algorithm in the module to return a new master ip/fqdn, restart -the minion and it will connect to the new master. +.nf +.ft C +master_type: failover +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If this option is set to \fBfailover\fP, \fI\%master\fP must be a list of +master addresses. The minion will then try each master in the order specified +in the list until it successfully connects. \fBmaster_alive_interval\fP +must also be set, this determines how often the minion will verify the presence +of the master. .INDENT 0.0 .INDENT 3.5 .sp @@ -39590,19 +44206,26 @@ master_type: func .UNINDENT .UNINDENT .sp -If this option is set to \fBfailover\fP, \fI\%master\fP must be a list of -master addresses. The minion will then try each master in the order specified -in the list until it successfully connects. +If the master needs to be dynamically assigned by executing a function instead +of reading in the static master value, set this to \fBfunc\fP\&. This can be used +to manage the minion\(aqs master setting from an execution module. By simply +changing the algorithm in the module to return a new master ip/fqdn, restart +the minion and it will connect to the new master. +.SS \fBmaster_alive_interval\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -master_type: failover +master_alive_interval: 30 .ft P .fi .UNINDENT .UNINDENT +.sp +Configures how often, in seconds, the minion will verify that the current +master is alive and responding. The minion will try to establish a connection +to the next master in the list if it finds the existing one is dead. .SS \fBmaster_shuffle\fP .sp New in version 2014.7.0. @@ -39725,7 +44348,7 @@ Default: the system\(aqs hostname \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -Salt Walkthrough +\fISalt Walkthrough\fP .sp The \fBSetting up a Salt Minion\fP section contains detailed information on how the hostname is determined. @@ -39820,6 +44443,23 @@ cache_jobs: False .fi .UNINDENT .UNINDENT +.SS \fBgrains_cache\fP +.sp +Default: \fBFalse\fP +.sp +The minion can locally cache grain data instead of refreshing the data +each time the grain is referenced. By default this feature is disabled, +to enable set grains_cache to \fBTrue\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +cache_jobs: False +.ft P +.fi +.UNINDENT +.UNINDENT .SS \fBsock_dir\fP .sp Default: \fB/var/run/salt/minion\fP @@ -39972,23 +44612,6 @@ recon_randomize: True .fi .UNINDENT .UNINDENT -.SS \fBdns_check\fP -.sp -Default: \fBTrue\fP -.sp -When healing, a dns_check is run. This is to make sure that the originally -resolved dns has not changed. If this is something that does not happen in your -environment, set this value to \fBFalse\fP\&. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -dns_check: True -.ft P -.fi -.UNINDENT -.UNINDENT .SS \fBcache_sreqs\fP .sp Default: \fBTrue\fP @@ -41295,7 +45918,7 @@ ability for the Salt Master to integrate different file server backends. File server backends allow the Salt file server to act as a transparent bridge to external resources. A good example of this is the \fBgit\fP backend, which allows Salt to serve files sourced from one or more git repositories, but there are several others as well. Click -here for a full list of Salt\(aqs fileserver +\fIhere\fP for a full list of Salt\(aqs fileserver backends. .SS Enabling a Fileserver Backend .sp @@ -41313,7 +45936,7 @@ fileserver_backend: .UNINDENT .UNINDENT .sp -See the documentation for each backend to find the +See the \fIdocumentation\fP for each backend to find the correct value to add to \fBfileserver_backend\fP in order to enable them. .SS Using Multiple Backends @@ -41547,6 +46170,25 @@ option to local to make sure that the local file server interface is used. The cp module is the home of minion side file server operations. The cp module is used by the Salt state system, salt\-cp, and can be used to distribute files presented by the Salt file server. +.SS Escaping Special Characters +.sp +The \fBsalt://\fP url format can potentially contain a query string, for example +\fBsalt://dir/file.txt?saltenv=base\fP\&. You can prevent the fileclient/fileserver from +interpreting \fB?\fP as the initial token of a query string by referencing the file +with \fBsalt://|\fP rather than \fBsalt://\fP\&. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +/etc/marathon/conf/?checkpoint: + file.managed: + \- source: salt://|hw/config/?checkpoint + \- makedirs: True +.ft P +.fi +.UNINDENT +.UNINDENT .SS Environments .sp Since the file server is made to work with the Salt state system, it supports @@ -41780,8 +46422,8 @@ mind, this order is subject to change). An optional master config parameter (\fBgitfs_provider\fP) can be used to specify which provider should be used. .sp -More detailed information on how to use gitfs can be found in the Gitfs -Walkthrough\&. +More detailed information on how to use gitfs can be found in the \fIGitfs +Walkthrough\fP\&. .sp \fBNOTE:\fP .INDENT 0.0 @@ -41790,7 +46432,7 @@ Minimum requirements .sp To use \fI\%GitPython\fP for gitfs requires a minimum GitPython version of 0.3.0, as well as the git CLI utility. Instructions for installing GitPython can -be found here\&. +be found \fIhere\fP\&. .sp To use \fI\%pygit2\fP for gitfs requires a minimum \fI\%pygit2\fP version of 0.20.3. \fI\%pygit2\fP 0.20.3 requires \fI\%libgit2\fP 0.20.0. \fI\%pygit2\fP and \fI\%libgit2\fP are developed @@ -42020,7 +46662,7 @@ Other minionfs settings include: \fBminionfs_whitelist\fP, \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -tutorial\-minionfs +\fItutorial\-minionfs\fP .UNINDENT .UNINDENT .INDENT 0.0 @@ -43286,6 +47928,12 @@ Cassandra NoSQL Database Module T} _ T{ +\fBcassandra_cql\fP +T} T{ +Cassandra Database Module +T} +_ +T{ \fBchef\fP T} T{ Execute chef in server or solo mode @@ -43306,7 +47954,7 @@ _ T{ \fBcmdmod\fP T} T{ -A module for shelling out +A module for shelling out. T} _ T{ @@ -43352,6 +48000,11 @@ Manage cygwin packages. T} _ T{ +\fBcytest\fP +T} T{ +T} +_ +T{ \fBdaemontools\fP T} T{ daemontools service module. This module will create daemontools type @@ -43561,12 +48214,6 @@ The service module for FreeBSD T} _ T{ -\fBfsutils\fP -T} T{ -Run\-time utilities -T} -_ -T{ \fBgem\fP T} T{ Manage ruby gems. @@ -43671,6 +48318,7 @@ _ T{ \fBhipchat\fP T} T{ +Module for sending messages to hipchat. T} _ T{ @@ -43728,6 +48376,12 @@ Functions to perform introspection on a minion, and return data in a format T} _ T{ +\fBipmi\fP +T} T{ +Support IPMI commands over LAN. +T} +_ +T{ \fBipset\fP T} T{ Support for ipset @@ -43950,6 +48604,12 @@ Module to provide MySQL compatibility to salt. T} _ T{ +\fBnacl\fP +T} T{ +This module helps include encrypted passwords in pillars, grains and salt state files. +T} +_ +T{ \fBnagios\fP T} T{ Run nagios plugins/checks from salt and get the return as data. @@ -44161,7 +48821,6 @@ _ T{ \fBps\fP T} T{ -A salt interface to psutil, a system and process library. T} _ T{ @@ -44227,6 +48886,7 @@ _ T{ \fBrandom_org\fP T} T{ +Module for retrieving random information from Random.org T} _ T{ @@ -44394,6 +49054,7 @@ _ T{ \fBslack_notify\fP T} T{ +Module for sending messages to Slack T} _ T{ @@ -44483,7 +49144,7 @@ _ T{ \fBstate\fP T} T{ -Control the state system on the minion +Control the state system on the minion. T} _ T{ @@ -44547,6 +49208,12 @@ Support for reboot, shutdown, etc T} _ T{ +\fBsystem_profiler\fP +T} T{ +System Profiler Module +T} +_ +T{ \fBsystemd\fP T} T{ Provide the service module for systemd @@ -44747,7 +49414,7 @@ _ T{ \fBwin_useradd\fP T} T{ -Manage Windows users with ADSI +Manage Windows users with the net user command T} _ T{ @@ -46036,7 +50703,7 @@ salt \(aq*\(aq pkg.unhold pkgs=\(aq["foo", "bar"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.aptpkg.upgrade(refresh=True, dist_upgrade=True) +.B salt.modules.aptpkg.upgrade(refresh=True, dist_upgrade=False) Upgrades all packages via \fBapt\-get dist\-upgrade\fP .sp Returns a dict containing the changes. @@ -46053,7 +50720,7 @@ Returns a dict containing the changes. .TP .B dist_upgrade Whether to perform the upgrade using dist\-upgrade vs upgrade. Default -is to use dist\-upgrade. +is to use upgrade. .UNINDENT .sp New in version 2014.7.0. @@ -48111,7 +52778,7 @@ salt myminion boto_cloudwatch.get_all_alarms region=us\-east\-1 \-\-out=txt .sp Connection module for Amazon DynamoDB .sp -New in version 2015.5. +New in version 2015.5.0. .INDENT 0.0 .TP @@ -48163,13 +52830,15 @@ It\(aqs also possible to specify key, keyid and region via a profile, either as a passed in dict, or as a string to pull from pillars or minion config: .INDENT 7.0 .INDENT 3.5 -.INDENT 0.0 -.TP -.B myprofile: -keyid: GKTADJGHEIQSXMKKRBJ08H -key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs -region: us\-east\-1 -.UNINDENT +.sp +.nf +.ft C +myprofile: + keyid: GKTADJGHEIQSXMKKRBJ08H + key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs + region: us\-east\-1 +.ft P +.fi .UNINDENT .UNINDENT .TP @@ -51728,6 +56397,542 @@ salt \(aq*\(aq cassandra.version .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.cassandra_cql +.sp +Cassandra Database Module +.sp +New in version 2015.5.0. + +.INDENT 0.0 +.TP +.B depends +DataStax Python Driver for Apache Cassandra +\fI\%https://github.com/datastax/python\-driver\fP +pip install cassandra\-driver +.TP +.B referenced by +Salt\(aqs cassandra_cql returner +.TP +.B configuration +The Cassandra cluster members and connection port can either be specified +in the master or minion config, the minion\(aqs pillar or be passed to the module. +.sp +Example configuration in the config for a single node: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +cassandra: + cluster: 192.168.50.10 + port: 9000 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Example configuration in the config for a cluster: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +cassandra: + cluster: + \- 192.168.50.10 + \- 192.168.50.11 + \- 192.168.50.12 + port: 9000 + username: cas_admin +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.cql_query(query, contact_points=None, port=None, cql_user=None, cql_pass=None) +Run a query on a Cassandra cluster and return a dictionary. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBquery\fP (\fI\%str\fP) \-\- The query to execute. +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.IP \(bu 2 +\fBparams\fP (\fI\%str\fP) \-\- The parameters for the query, optional. +.UNINDENT +.TP +.B Returns +A dictionary from the return values of the query +.TP +.B Return type +list[dict] +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.create_keyspace(keyspace, replication_strategy=\(aqSimpleStrategy\(aq, replication_factor=1, replication_datacenters=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +Create a new keyspace in Cassandra. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBkeyspace\fP (\fI\%str\fP) \-\- The keyspace name +.IP \(bu 2 +\fBreplication_strategy\fP (\fI\%str\fP) \-\- either \fISimpleStrategy\fP or \fINetworkTopologyStrategy\fP +.IP \(bu 2 +\fBreplication_factor\fP (\fI\%int\fP) \-\- number of replicas of data on multiple nodes. not used if using NetworkTopologyStrategy +.IP \(bu 2 +\fBreplication_datacenters\fP (\fIstr | dict[str, int]\fP) \-\- string or dict of datacenter names to replication factors, required if using +NetworkTopologyStrategy (will be a dict if coming from state file). +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +The info for the keyspace or False if it does not exist. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.create_keyspace keyspace=newkeyspace + +salt \(aqminion1\(aq cassandra_cql.create_keyspace keyspace=newkeyspace replication_strategy=NetworkTopologyStrategy replication_datacenters=\(aq{"datacenter_1": 3, "datacenter_2": 2}\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.create_user(username, password, superuser=False, contact_points=None, port=None, cql_user=None, cql_pass=None) +Create a new cassandra user with credentials and superuser status. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBusername\fP (\fI\%str\fP) \-\- The name of the new user. +.IP \(bu 2 +\fBpassword\fP (\fI\%str\fP) \-\- The password of the new user. +.IP \(bu 2 +\fBsuperuser\fP (\fI\%bool\fP) \-\- Is the new user going to be a superuser? default: False +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns + +.TP +.B Return type + +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.create_user username=joe password=secret + +salt \(aqminion1\(aq cassandra_cql.create_user username=joe password=secret superuser=True + +salt \(aqminion1\(aq cassandra_cql.create_user username=joe password=secret superuser=True contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.drop_keyspace(keyspace, contact_points=None, port=None, cql_user=None, cql_pass=None) +Drop a keyspace if it exists in a Cassandra cluster. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBkeyspace\fP (\fI\%str\fP) \-\- The keyspace to drop. +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +The info for the keyspace or False if it does not exist. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.drop_keyspace keyspace=test + +salt \(aqminion1\(aq cassandra_cql.drop_keyspace keyspace=test contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.grant_permission(username, resource=None, resource_type=\(aqkeyspace\(aq, permission=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +Grant permissions to a user. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBusername\fP (\fI\%str\fP) \-\- The name of the user to grant permissions to. +.IP \(bu 2 +\fBresource\fP (\fI\%str\fP) \-\- The resource (keyspace or table), if None, permissions for all resources are granted. +.IP \(bu 2 +\fBresource_type\fP (\fI\%str\fP) \-\- The resource_type (keyspace or table), defaults to \(aqkeyspace\(aq. +.IP \(bu 2 +\fBpermission\fP (\fI\%str\fP) \-\- A permission name (e.g. select), if None, all permissions are granted. +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns + +.TP +.B Return type + +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.grant_permission + +salt \(aqminion1\(aq cassandra_cql.grant_permission username=joe resource=test_keyspace permission=select + +salt \(aqminion1\(aq cassandra_cql.grant_permission username=joe resource=test_table resource_type=table permission=select contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.info(contact_points=None, port=None, cql_user=None, cql_pass=None) +Show the Cassandra information for this cluster. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +The information for this Cassandra cluster. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.info + +salt \(aqminion1\(aq cassandra_cql.info contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.keyspace_exists(keyspace, contact_points=None, port=None, cql_user=None, cql_pass=None) +Check if a keyspace exists in a Cassandra cluster. +.sp +:param keyspace The keyspace name to check for. +:type keyspace: str +:param contact_points: The Cassandra cluster addresses, can either be a string or a list of IPs. +:type contact_points: str | list[str] +:param cql_user: The Cassandra user if authentication is turned on. +:type cql_user: str +:param cql_pass: The Cassandra user password if authentication is turned on. +:type cql_pass: str +:param port: The Cassandra cluster port, defaults to None. +:type port: int +:return: The info for the keyspace or False if it does not exist. +:rtype: dict +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.keyspace_exists keyspace=system + +salt \(aqminion1\(aq cassandra_cql.list_keyspaces keyspace=system contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.list_column_families(keyspace=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +List column families in a Cassandra cluster for all keyspaces or just the provided one. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBkeyspace\fP (\fI\%str\fP) \-\- The keyspace to provide the column families for, optional. +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +The column families in this Cassandra cluster. +.TP +.B Return type +list[dict] +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.list_column_families + +salt \(aqminion1\(aq cassandra_cql.list_column_families contact_points=minion1 + +salt \(aqminion1\(aq cassandra_cql.list_column_families keyspace=system +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.list_keyspaces(contact_points=None, port=None, cql_user=None, cql_pass=None) +List keyspaces in a Cassandra cluster. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +The keyspaces in this Cassandra cluster. +.TP +.B Return type +list[dict] +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.list_keyspaces + +salt \(aqminion1\(aq cassandra_cql.list_keyspaces contact_points=minion1 port=9000 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.list_permissions(username=None, resource=None, resource_type=\(aqkeyspace\(aq, permission=None, contact_points=None, port=None, cql_user=None, cql_pass=None) +List permissions. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBusername\fP (\fI\%str\fP) \-\- The name of the user to list permissions for. +.IP \(bu 2 +\fBresource\fP (\fI\%str\fP) \-\- The resource (keyspace or table), if None, permissions for all resources are listed. +.IP \(bu 2 +\fBresource_type\fP (\fI\%str\fP) \-\- The resource_type (keyspace or table), defaults to \(aqkeyspace\(aq. +.IP \(bu 2 +\fBpermission\fP (\fI\%str\fP) \-\- A permission name (e.g. select), if None, all permissions are listed. +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +Dictionary of permissions. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.list_permissions + +salt \(aqminion1\(aq cassandra_cql.list_permissions username=joe resource=test_keyspace permission=select + +salt \(aqminion1\(aq cassandra_cql.list_permissions username=joe resource=test_table resource_type=table permission=select contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.list_users(contact_points=None, port=None, cql_user=None, cql_pass=None) +List existing users in this Cassandra cluster. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.UNINDENT +.TP +.B Returns +The list of existing users. +.TP +.B Return type +\fI\%dict\fP +.UNINDENT +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.list_users + +salt \(aqminion1\(aq cassandra_cql.list_users contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.cassandra_cql.version(contact_points=None, port=None, cql_user=None, cql_pass=None) +Show the Cassandra version. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBcontact_points\fP (\fIstr | list[str]\fP) \-\- The Cassandra cluster addresses, can either be a string or a list of IPs. +.IP \(bu 2 +\fBcql_user\fP (\fI\%str\fP) \-\- The Cassandra user if authentication is turned on. +.IP \(bu 2 +\fBcql_pass\fP (\fI\%str\fP) \-\- The Cassandra user password if authentication is turned on. +.IP \(bu 2 +\fBport\fP (\fI\%int\fP) \-\- The Cassandra cluster port, defaults to None. +.UNINDENT +.TP +.B Returns +The version for this Cassandra cluster. +.TP +.B Return type +\fI\%str\fP +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion1\(aq cassandra_cql.version + +salt \(aqminion1\(aq cassandra_cql.version contact_points=minion1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.chef .sp Execute chef in server or solo mode @@ -52658,7 +57863,7 @@ salt minionname cloud.volume_list my\-nova .UNINDENT .SS salt.modules.cmdmod .sp -A module for shelling out +A module for shelling out. .sp Keep in mind that this module is insecure, in that it can give whomever has access to the master root execution access to all salt minions. @@ -52720,7 +57925,7 @@ salt \(aq*\(aq cmd.has_exec cat .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.retcode(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.retcode(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, clean_env=False, template=None, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Execute a shell command and return the command\(aqs return code. .sp Note that \fBenv\fP represents the environment variables for the command, and @@ -52779,13 +57984,16 @@ salt \(aq*\(aq cmd.retcode "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.run(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Execute the passed command and return the output as a string .sp Note that \fBenv\fP represents the environment variables for the command, and should be formatted as a dict, or a YAML string which resolves to a dict. .sp -WARNING: This function does not process commands through a shell +\fBWARNING:\fP +.INDENT 7.0 +.INDENT 3.5 +This function does not process commands through a shell unless the python_shell flag is set to True. This means that any shell\-specific functionality such as \(aqecho\(aq or the use of pipes, redirection or &&, should either be migrated to cmd.shell or @@ -52795,7 +58003,8 @@ The use of python_shell=True means that the shell will accept _any_ input including potentially malicious commands such as \(aqgood_command;rm \-rf /\(aq. Be absolutely certain that you have sanitized your input prior to using python_shell=True -\fB*********************************************************************\fP +.UNINDENT +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -52866,7 +58075,7 @@ salt \(aq*\(aq cmd.run cmd=\(aqsed \-e s/=/:/g\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_all(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.run_all(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Execute the passed command and return a dict of return data .sp Note that \fBenv\fP represents the environment variables for the command, and @@ -52914,7 +58123,7 @@ salt \(aq*\(aq cmd.run_all "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_chroot(root, cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=True, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqquiet\(aq, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.run_chroot(root, cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=True, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqquiet\(aq, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) New in version 2014.7.0. .sp @@ -52952,7 +58161,7 @@ salt \(aq*\(aq cmd.run_chroot /var/lib/lxc/container_name/rootfs \(aqsh /tmp/boo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_stderr(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.run_stderr(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Execute a command and only return the standard error .sp Note that \fBenv\fP represents the environment variables for the command, and @@ -53000,7 +58209,7 @@ salt \(aq*\(aq cmd.run_stderr "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.run_stdout(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.run_stdout(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Execute a command, and only return the standard out .sp Note that \fBenv\fP represents the environment variables for the command, and @@ -53048,7 +58257,7 @@ salt \(aq*\(aq cmd.run_stdout "grep f" stdin=\(aqone\entwo\enthree\enfour\enfive .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.script(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, template=None, umask=None, output_loglevel=\(aqdebug\(aq, quiet=False, timeout=None, reset_system_locale=True, __env__=None, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.script(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, template=None, umask=None, output_loglevel=\(aqdebug\(aq, quiet=False, timeout=None, reset_system_locale=True, __env__=None, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Download a script from a remote location and execute the script locally. The script can be located on the salt master file server or on an HTTP/FTP server. @@ -53089,7 +58298,7 @@ salt \(aq*\(aq cmd.script salt://scripts/runme.sh stdin=\(aqone\entwo\enthree\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.script_retcode(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, python_shell=None, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, __env__=None, saltenv=\(aqbase\(aq, output_loglevel=\(aqdebug\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.script_retcode(source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, python_shell=None, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, __env__=None, saltenv=\(aqbase\(aq, output_loglevel=\(aqdebug\(aq, use_vt=False, **kwargs) Download a script from a remote location and execute the script locally. The script can be located on the salt master file server or on an HTTP/FTP server. @@ -53131,17 +58340,21 @@ salt \(aq*\(aq cmd.script_retcode salt://scripts/runme.sh stdin=\(aqone\entwo\en .UNINDENT .INDENT 0.0 .TP -.B salt.modules.cmdmod.shell(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) +.B salt.modules.cmdmod.shell(cmd, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, env=None, clean_env=False, template=None, rstrip=True, umask=None, output_loglevel=\(aqdebug\(aq, quiet=False, timeout=None, reset_system_locale=True, ignore_retcode=False, saltenv=\(aqbase\(aq, use_vt=False, **kwargs) Execute the passed command and return the output as a string. .sp New in version 2015.5.0. .sp -WARNING: This passes the cmd argument directly to the shell +\fBWARNING:\fP +.INDENT 7.0 +.INDENT 3.5 +This passes the cmd argument directly to the shell without any further processing! Be absolutely sure that you have properly santized the command passed to this function and do not use untrusted inputs. -\fB********************************************************\fP +.UNINDENT +.UNINDENT .sp Note that \fBenv\fP represents the environment variables for the command, and should be formatted as a dict, or a YAML string which resolves to a dict. @@ -55014,6 +60227,26 @@ salt \(aq*\(aq data.load .UNINDENT .INDENT 0.0 .TP +.B salt.modules.data.pop(key, default=None) +Pop (return & delete) a value from the minion datastore +.sp +New in version 2015.5.2. + +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq data.pop "there was no val" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.data.update(key, value) Update a key with a value in the minion datastore .sp @@ -56879,7 +62112,7 @@ salt \(aq*\(aq docker.commit .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockerio.create_container(image, command=None, hostname=None, user=None, detach=True, stdin_open=False, tty=False, mem_limit=0, ports=None, environment=None, dns=None, volumes=None, volumes_from=None, name=None, cpu_shares=None, cpuset=None) +.B salt.modules.dockerio.create_container(image, command=None, hostname=None, user=None, detach=True, stdin_open=False, tty=False, mem_limit=0, ports=None, environment=None, dns=None, volumes=None, volumes_from=None, name=None, cpu_shares=None, cpuset=None, binds=None) Create a new container .INDENT 7.0 .TP @@ -56905,18 +62138,44 @@ environment variable mapping \fB({\(aqfoo\(aq:\(aqBAR\(aq})\fP port redirections \fB({\(aq222\(aq: {}})\fP .TP .B volumes -list of volume mappings: +list of volume mappings in either local volume, bound volume, or read\-only +bound volume form: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C -([\(aq/mountpoint/in/container:/guest/foo\(aq, \(aq/same/path/mounted/point\(aq]) +([\(aq/var/lib/mysql/\(aq, \(aq/usr/local/etc/ssl:/etc/ssl\(aq, \(aq/etc/passwd:/etc/passwd:ro\(aq]) .ft P .fi .UNINDENT .UNINDENT .TP +.B binds +complete dictionary of bound volume mappings: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{ \(aq/usr/local/etc/ssl/certs/internal.crt\(aq: { + \(aqbind\(aq: \(aq/etc/ssl/certs/com.example.internal.crt\(aq, + \(aqro\(aq: True + }, + \(aq/var/lib/mysql\(aq: { + \(aqbind\(aq: \(aq/var/lib/mysql/\(aq, + \(aqro\(aq: False + } +} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +This dictionary is suitable for feeding directly into the Docker API, and all +keys are required. +(see \fI\%http://docker\-py.readthedocs.org/en/latest/volumes/\fP) +.TP .B tty attach ttys, Default is \fBFalse\fP .TP @@ -57238,14 +62497,8 @@ salt \(aq*\(aq docker.kill .INDENT 0.0 .TP .B salt.modules.dockerio.load(imagepath) -.INDENT 7.0 -.INDENT 3.5 Load the specified file at imagepath into docker that was generated from -.UNINDENT -.UNINDENT -.INDENT 7.0 -.TP -.B a docker save command +a docker save command e.g. \fIdocker load < imagepath\fP .INDENT 7.0 .TP @@ -57265,7 +62518,6 @@ salt \(aq*\(aq docker.load /path/to/image .UNINDENT .UNINDENT .UNINDENT -.UNINDENT .INDENT 0.0 .TP .B salt.modules.dockerio.login(url=None, username=None, password=None, email=None) @@ -57727,7 +62979,7 @@ salt \(aq*\(aq docker.save arch_image /path/to/save/image .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockerio.script(container, source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, no_clean=False, saltenv=\(aqbase\(aq) +.B salt.modules.dockerio.script(container, source, args=None, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, no_clean=False, saltenv=\(aqbase\(aq) Wrapper for \fBcmdmod.script\fP inside a container context .INDENT 7.0 .TP @@ -57788,7 +63040,7 @@ salt \(aq*\(aq docker.script salt://scripts/runme.sh stdin=\(aqon .UNINDENT .INDENT 0.0 .TP -.B salt.modules.dockerio.script_retcode(container, source, cwd=None, stdin=None, runas=None, shell=\(aq/usr/bin/zsh\(aq, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, no_clean=False, saltenv=\(aqbase\(aq) +.B salt.modules.dockerio.script_retcode(container, source, cwd=None, stdin=None, runas=None, shell=\(aq/bin/bash\(aq, env=None, template=\(aqjinja\(aq, umask=None, timeout=None, reset_system_locale=True, no_clean=False, saltenv=\(aqbase\(aq) Wrapper for \fBcmdmod.script_retcode\fP inside a container context .INDENT 7.0 .TP @@ -60083,7 +65335,7 @@ salt \(aq*\(aq file.append /etc/motd args="[\(aqcheese=spam\(aq,\(aqspam=cheese\ .B salt.modules.file.basename(path) Returns the final component of a pathname .sp -New in version 2015.5. +New in version 2015.5.0. .sp This can be useful at the CLI but is frequently useful when scripting. @@ -60561,7 +65813,7 @@ salt \(aq*\(aq file.directory_exists /etc .B salt.modules.file.dirname(path) Returns the directory component of a pathname .sp -New in version 2015.5. +New in version 2015.5.0. .sp This can be useful at the CLI but is frequently useful when scripting. @@ -61532,6 +66784,9 @@ transfer the file to the minion again. This file is then grabbed and if it has template set, it renders the file to be placed into the correct place on the system using salt.files.utils.copyfile() .TP +.B ret +The initial state return data structure. Pass in \fBNone\fP to use the default structure. +.TP .B source file reference on the master .TP @@ -61700,7 +66955,7 @@ salt \(aq*\(aq file.move /path/to/src /path/to/dst .B salt.modules.file.normpath(path) Returns Normalize path, eliminating double slashes, etc. .sp -New in version 2015.5. +New in version 2015.5.0. .sp This can be useful at the CLI but is frequently useful when scripting. @@ -62728,8 +67983,28 @@ Support for firewalld Add a service for zone. If zone is omitted, default zone will be used. .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.add_service ssh +.ft P +.fi +.UNINDENT +.UNINDENT .sp To assign a service to a specific zone +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.add_service ssh my_zone +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62754,9 +68029,29 @@ salt \(aq*\(aq firewalld.default_zone Delete an existing service .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.delete_service my_service +.ft P +.fi +.UNINDENT +.UNINDENT .sp By default firewalld will be reloaded. However, to avoid reloading you need to specify the restart as False +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.delete_service my_service False +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62764,9 +68059,29 @@ you need to specify the restart as False Delete an existing zone .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.delete_zone my_zone +.ft P +.fi +.UNINDENT +.UNINDENT .sp By default firewalld will be reloaded. However, to avoid reloading you need to specify the restart as False +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.delete_zone my_zone False +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62825,8 +68140,28 @@ salt \(aq*\(aq firewalld.get_zones List everything added for or enabled in a zone .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.list_all +.ft P +.fi +.UNINDENT +.UNINDENT .sp List a specific zone +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.list_all my_zone +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62835,8 +68170,28 @@ List services added for zone as a space separated list. If zone is omitted, default zone will be used. .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.list_services +.ft P +.fi +.UNINDENT +.UNINDENT .sp List a specific zone +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.list_services my_zone +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62861,9 +68216,29 @@ salt \(aq*\(aq firewalld.list_zones Add a new service .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.new_service my_service +.ft P +.fi +.UNINDENT +.UNINDENT .sp By default firewalld will be reloaded. However, to avoid reloading you need to specify the restart as False +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.new_service my_service False +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62871,9 +68246,29 @@ you need to specify the restart as False Add a new zone .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.new_zone my_zone +.ft P +.fi +.UNINDENT +.UNINDENT .sp By default firewalld will be reloaded. However, to avoid reloading you need to specify the restart as False +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.new_zone my_zone False +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62882,8 +68277,28 @@ Remove a service from zone. This option can be specified multiple times. If zone is omitted, default zone will be used. .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.remove_service ssh +.ft P +.fi +.UNINDENT +.UNINDENT .sp To remove a service from a specific zone +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.remove_service ssh dmz +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -62891,6 +68306,16 @@ To remove a service from a specific zone Set default zone .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq firewalld.set_default_zone damian +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -64143,9 +69568,6 @@ salt \(aq*\(aq service.stop .UNINDENT .UNINDENT .UNINDENT -.SS salt.modules.fsutils -.sp -Run\-time utilities .SS salt.modules.gem .sp Manage ruby gems. @@ -65153,10 +70575,16 @@ A path to a private key to use over SSH .B https_user None HTTP Basic Auth username for HTTPS (only) clones +.sp +New in version 20515.5.0. + .TP .B https_pass None HTTP Basic Auth password for HTTPS (only) clones +.sp +New in version 2015.5.0. + .UNINDENT .sp CLI Example: @@ -65427,10 +70855,16 @@ a path to a private key to use over ssh .B https_user None HTTP Basic Auth username for HTTPS (only) clones +.sp +New in version 2015.5.0. + .TP .B https_pass None HTTP Basic Auth password for HTTPS (only) clones +.sp +New in version 2015.5.0. + .UNINDENT .sp CLI Example: @@ -65652,10 +71086,16 @@ Run git as a user other than what the minion runs as .B https_user None HTTP Basic Auth username for HTTPS (only) clones +.sp +New in version 2015.5.0. + .TP .B https_pass None HTTP Basic Auth password for HTTPS (only) clones +.sp +New in version 2015.5.0. + .UNINDENT .sp CLI Example: @@ -66793,14 +72233,12 @@ salt \(aq*\(aq gpg.import_key text=\(aq\-\-\-\-\-BEGIN PGP PUBLIC KEY BLOCK\-\-\ .UNINDENT .UNINDENT .UNINDENT -.sp -\&... \-\-\-\-\-END PGP PUBLIC KEY BLOCK\-\-\-\-\-\(aq .INDENT 7.0 -.INDENT 3.5 +.TP +.B \&... \-\-\-\-\-END PGP PUBLIC KEY BLOCK\-\-\-\-\-\(aq salt \(aq*\(aq gpg.import_key filename=\(aq/path/to/public\-key\-file\(aq .UNINDENT .UNINDENT -.UNINDENT .INDENT 0.0 .TP .B salt.modules.gpg.list_keys(user=None) @@ -67037,7 +72475,7 @@ salt \(aq*\(aq gpg.verify filename=\(aq/path/to/important.file\(aq use_pasphrase Return/control aspects of the grains data .INDENT 0.0 .TP -.B salt.modules.grains.append(key, val, convert=False) +.B salt.modules.grains.append(key, val, convert=False, delimiter=\(aq:\(aq) New in version 0.17.0. .sp @@ -67055,9 +72493,18 @@ The value to append to the grain key .INDENT 7.0 .TP .B Parameters +.INDENT 7.0 +.IP \(bu 2 \fBconvert\fP \-\- If convert is True, convert non\-list contents into a list. If convert is False and the grain contains non\-list contents, an error is given. Defaults to False. +.IP \(bu 2 +\fBdelimiter\fP \-\- The key can be a nested dict key. Use this parameter to +specify the delimiter you use. +You can now append values to a list in nested dictionnary grains. If the +list doesn\(aqt exist at this level, it will be created. +.. versionadded:: 2014.7.6 +.UNINDENT .UNINDENT .sp CLI Example: @@ -67310,6 +72757,16 @@ salt \(aq*\(aq grains.get_or_set_hash \(aqdjango:SECRET_KEY\(aq 50 .fi .UNINDENT .UNINDENT +.sp +\fBWARNING:\fP +.INDENT 7.0 +.INDENT 3.5 +This function could return strings which may contain characters which are reserved +as directives by the YAML parser, such as strings beginning with \fI%\fP\&. To avoid +issues when using the output of this function in an SLS file containing YAML+Jinja, +surround the call with single quotes. +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -68328,6 +73785,160 @@ salt devserver1 hg.update /path/to/repo somebranch .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.hipchat +.sp +Module for sending messages to hipchat. +.sp +New in version 2015.5.0. + +.INDENT 0.0 +.TP +.B configuration +This module can be used by either passing an api key and version +directly or by specifying both in a configuration profile in the salt +master/minion config. +.sp +For example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +hipchat: + api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15 + api_version: v1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.hipchat.find_room(name, api_key=None, api_version=None) +Find a room by name and return it. +:param name: The room name. +:param api_key: The HipChat admin api key. +:param api_version: The HipChat api version, if not specified in the configuration. +:return: The room object. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq hipchat.find_room name="Development Room" + +salt \(aq*\(aq hipchat.find_room name="Development Room" api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 api_version=v1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.hipchat.find_user(name, api_key=None, api_version=None) +Find a user by name and return it. +:param name: The user name. +:param api_key: The HipChat admin api key. +:param api_version: The HipChat api version, if not specified in the configuration. +:return: The user object. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq hipchat.find_user name="Thomas Hatch" + +salt \(aq*\(aq hipchat.find_user name="Thomas Hatch" api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 api_version=v1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.hipchat.list_rooms(api_key=None, api_version=None) +List all HipChat rooms. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The HipChat admin api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The HipChat api version, if not specified in the configuration. +.UNINDENT +.TP +.B Returns +The room list. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq hipchat.list_rooms + +salt \(aq*\(aq hipchat.list_rooms api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 api_version=v1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.hipchat.list_users(api_key=None, api_version=None) +List all HipChat users. +:param api_key: The HipChat admin api key. +:param api_version: The HipChat api version, if not specified in the configuration. +:return: The user list. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq hipchat.list_users + +salt \(aq*\(aq hipchat.list_users api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 api_version=v1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.hipchat.send_message(room_id, message, from_name, api_key=None, api_version=None, color=\(aqyellow\(aq, notify=False) +Send a message to a HipChat room. +:param room_id: The room id or room name, either will work. +:param message: The message to send to the HipChat room. +:param from_name: Specify who the message is from. +:param api_key: The HipChat api key, if not specified in the configuration. +:param api_version: The HipChat api version, if not specified in the configuration. +:param color: The color for the message, default: yellow. +:param notify: Whether to notify the room, default: False. +:return: Boolean if message was sent successfully. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq hipchat.send_message room_id="Development Room" message="Build is done" from_name="Build Server" + +salt \(aq*\(aq hipchat.send_message room_id="Development Room" message="Build failed" from_name="Build Server" color="red" notify=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.hosts .sp Manage the information in the hosts file @@ -68549,12 +74160,15 @@ salt \(aq*\(aq webutil.userdel /etc/httpd/htpasswd larry Module for making various web calls. Primarily designed for webhooks and the like, but also useful for basic http testing. .sp -New in version 2015.5. +New in version 2015.5.0. .INDENT 0.0 .TP .B salt.modules.http.query(url, **kwargs) Query a resource, and decode the return data +.sp +New in version 2015.5.0. + .sp CLI Example: .INDENT 7.0 @@ -68574,6 +74188,9 @@ salt \(aq*\(aq http.query http://somelink.com/ method=POST data=\(aq .TP .B salt.modules.http.update_ca_bundle(target=None, source=None, merge_files=None) Update the local CA bundle file from a URL +.sp +New in version 2015.5.0. + .sp CLI Example: .INDENT 7.0 @@ -68679,6 +74296,16 @@ salt \(aq*\(aq ilo.configure_network [IP ADDRESS] [NETMASK] [GATEWAY] Configure SNMP .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq ilo.configure_snmp [COMMUNITY STRING] [SNMP PORT] [SNMP TRAP PORT] +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -68911,6 +74538,16 @@ salt \(aq*\(aq ilo.network Configure the port HTTP should listen on .sp CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq ilo.set_http_port 8080 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -69868,6 +75505,1344 @@ salt myminion introspect.service_highstate requires=False .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.ipmi +.sp +Support IPMI commands over LAN. This module does not talk to the local +systems hardware through IPMI drivers. It uses a python module \fIpyghmi\fP\&. +.INDENT 0.0 +.TP +.B depends +Python module pyghmi. +You can install pyghmi using pip: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +pip install pyghmi +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B configuration +The following configuration defaults can be +define (pillar or config files): +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +ipmi.config: + api_host: 127.0.0.1 + api_user: admin + api_pass: apassword + api_port: 623 + api_kg: None +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Usage can override the config defaults: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_user api_host=myipmienabled.system + api_user=admin api_pass=pass + uid=1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.create_user(uid, name, password, channel=14, callback=False, link_auth=True, ipmi_msg=True, privilege_level=\(aqadministrator\(aq, **kwargs) +create/ensure a user is created with provided settings. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBprivilege_level\fP \-\- User Privilege Limit. (Determines the maximum privilege level that +the user is allowed to switch to on the specified channel.) +* callback +* user +* operator +* administrator +* proprietary +* no_access +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.create_user uid=2 name=steverweber api_host=172.168.0.7 api_pass=nevertell +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.fast_connect_test(**kwargs) +Returns True if connection success. +This uses an aggressive timeout value! +.INDENT 7.0 +.TP +.B Parameters +\fBkwargs\fP \-\- .INDENT 7.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.fast_connect_test api_host=172.168.0.9 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_bootdev(**kwargs) +Get current boot device override information. +.sp +Provides the current requested boot device. Be aware that not all IPMI +devices support this. Even in BMCs that claim to, occasionally the +BIOS or UEFI fail to honor it. This is usually only applicable to the +next reboot. +.INDENT 7.0 +.TP +.B Parameters +\fBkwargs\fP \-\- .INDENT 7.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_bootdev api_host=127.0.0.1 api_user=admin api_pass=pass +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_channel_access(channel=14, read_mode=\(aqnon_volatile\(aq, **kwargs) +:param kwargs:api_host=\(aq127.0.0.1\(aq api_user=\(aqadmin\(aq api_pass=\(aqexample\(aq api_port=623 +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBread_mode\fP \-\- .INDENT 2.0 +.IP \(bu 2 +non_volatile = get non\-volatile Channel Access +.IP \(bu 2 +volatile = get present volatile (active) setting of Channel Access +.UNINDENT + +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B return +A Python dict with the following keys/values: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +{ + alerting: + per_msg_auth: + user_level_auth: + access_mode:{ (ONE OF) + 0: \(aqdisabled\(aq, + 1: \(aqpre_boot\(aq, + 2: \(aqalways\(aq, + 3: \(aqshared\(aq + } + privilege_level: { (ONE OF) + 1: \(aqcallback\(aq, + 2: \(aquser\(aq, + 3: \(aqoperator\(aq, + 4: \(aqadministrator\(aq, + 5: \(aqproprietary\(aq, + } +} +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_channel_access channel=1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_channel_info(channel=14, **kwargs) +Get channel info +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B return +channel session supports: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- no_session: channel is session\-less +\- single: channel is single\-session +\- multi: channel is multi\-session +\- auto: channel is session\-based (channel could alternate between + single\- and multi\-session operation, as can occur with a + serial/modem channel that supports connection mode auto\-detect) +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_channel_info +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_channel_max_user_count(channel=14, **kwargs) +Get max users in channel +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.TP +.B Returns +int \-\- often 16 +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_channel_max_user_count +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_health(**kwargs) +Get Summarize health +.sp +This provides a summary of the health of the managed system. +It additionally provides an iterable list of reasons for +warning, critical, or failed assessments. +.sp +good health: {\(aqbadreadings\(aq: [], \(aqhealth\(aq: 0} +.INDENT 7.0 +.TP +.B Parameters +\fBkwargs\fP \-\- .INDENT 7.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_health api_host=127.0.0.1 api_user=admin api_pass=pass +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_power(**kwargs) +Get current power state +.sp +The response, if successful, should contain \(aqpowerstate\(aq key and +either \(aqon\(aq or \(aqoff\(aq to indicate current state. +.INDENT 7.0 +.TP +.B Parameters +\fBkwargs\fP \-\- .INDENT 7.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_power api_host=127.0.0.1 api_user=admin api_pass=pass +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_sensor_data(**kwargs) +Get sensor readings +.sp +Iterates sensor reading objects +.INDENT 7.0 +.TP +.B Parameters +\fBkwargs\fP \-\- .INDENT 7.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_sensor_data api_host=127.0.0.1 api_user=admin api_pass=pass +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_user(uid, channel=14, **kwargs) +Get user from uid and access on channel +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- user number [1:16] +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +return +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +name: (str) +uid: (int) +channel: (int) +access: + \- callback (bool) + \- link_auth (bool) + \- ipmi_msg (bool) + \- privilege_level: (str)[callback, user, operatorm administrator, + proprietary, no_access] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_user uid=2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_user_access(uid, channel=14, **kwargs) +Get user access +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- user number [1:16] +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +return +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +channel_info: + \- max_user_count = maximum number of user IDs on this channel + \- enabled_users = count of User ID slots presently in use + \- users_with_fixed_names = count of user IDs with fixed names +access: + \- callback + \- link_auth + \- ipmi_msg + \- privilege_level: [reserved, callback, user, operator + administrator, proprietary, no_access] +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_user_access uid=2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_user_name(uid, return_none_on_error=True, **kwargs) +Get user name +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- user number [1:16] +.IP \(bu 2 +\fBreturn_none_on_error\fP \-\- return None on error +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_user_name uid=2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.get_users(channel=14, **kwargs) +get list of users and access information +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.TP +.B Returns +name: (str) +uid: (int) +channel: (int) +access: +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +callback (bool) +.IP \(bu 2 +link_auth (bool) +.IP \(bu 2 +ipmi_msg (bool) +.IP \(bu 2 +.INDENT 2.0 +.TP +.B privilege_level: (str)[callback, user, operatorm administrator, +proprietary, no_access] +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT + +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.get_users api_host=172.168.0.7 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.raw_command(netfn, command, bridge_request=None, data=(), retry=True, delay_xmit=None, **kwargs) +Send raw ipmi command +.sp +This allows arbitrary IPMI bytes to be issued. This is commonly used +for certain vendor specific commands. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBnetfn\fP \-\- Net function number +.IP \(bu 2 +\fBcommand\fP \-\- Command value +.IP \(bu 2 +\fBbridge_request\fP \-\- The target slave address and channel number for +the bridge request. +.IP \(bu 2 +\fBdata\fP \-\- Command data as a tuple or list +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.TP +.B Returns +dict \-\- The response from IPMI device +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.raw_command netfn=0x06 command=0x46 data=[0x02] +# this will return the name of the user with id 2 in bytes +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_bootdev(bootdev=\(aqdefault\(aq, persist=False, uefiboot=False, **kwargs) +Set boot device to use on next reboot +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBbootdev\fP \-\- +.sp + +.nf +* +.fi +network \-\- Request network boot + +.nf +* +.fi +hd \-\- Boot from hard drive + +.nf +* +.fi +safe \-\- Boot from hard drive, requesting \(aqsafe mode\(aq + +.nf +* +.fi +optical \-\- boot from CD/DVD/BD drive + +.nf +* +.fi +setup \-\- Boot into setup utility + +.nf +* +.fi +default \-\- remove any IPMI directed boot device +.INDENT 2.0 +.INDENT 3.5 +request +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBpersist\fP \-\- If true, ask that system firmware use this device +beyond next boot. Be aware many systems do not honor +this +.IP \(bu 2 +\fBuefiboot\fP \-\- If true, request UEFI boot explicitly. Strictly +speaking, the spec sugests that if not set, the system +should BIOS boot and offers no "don\(aqt care" option. +In practice, this flag not being set does not preclude +UEFI boot on any system I\(aqve encountered. +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.TP +.B Returns +dict or True \-\- If callback is not provided, the response +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_bootdev bootdev=network persist=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_channel_access(channel=14, access_update_mode=\(aqnon_volatile\(aq, alerting=False, per_msg_auth=False, user_level_auth=False, access_mode=\(aqalways\(aq, privilege_update_mode=\(aqnon_volatile\(aq, privilege_level=\(aqadministrator\(aq, **kwargs) +Set channel access +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBaccess_update_mode\fP \-\- one of +\- \(aqdont_change\(aq = don\(aqt set or change Channel Access +\- \(aqnon_volatile\(aq = set non\-volatile Channel Access +\- \(aqvolatile\(aq = set volatile (active) setting of Channel Access +.IP \(bu 2 +\fBalerting\fP \-\- +.sp +PEF Alerting Enable/Disable +\- True = enable PEF Alerting +\- False = disable PEF Alerting on this channel +.INDENT 2.0 +.INDENT 3.5 +(Alert Immediate command can still be used to generate alerts) +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBper_msg_auth\fP \-\- +.sp +Per\-message Authentication +\- True = enable +\- False = disable Per\-message Authentication. [Authentication required to +.INDENT 2.0 +.INDENT 3.5 +activate any session on this channel, but authentication not +used on subsequent packets for the session.] +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBuser_level_auth\fP \-\- +.sp +User Level Authentication Enable/Disable. +\- True = enable User Level Authentication. All User Level commands are +.INDENT 2.0 +.INDENT 3.5 +to be authenticated per the Authentication Type that was +negotiated when the session was activated. +.UNINDENT +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +.INDENT 2.0 +.TP +.B False = disable User Level Authentication. Allow User Level commands to +be executed without being authenticated. +If the option to disable User Level Command authentication is +accepted, the BMC will accept packets with Authentication Type +set to None if they contain user level commands. +For outgoing packets, the BMC returns responses with the same +Authentication Type that was used for the request. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBaccess_mode\fP \-\- +.sp +Access Mode for IPMI messaging +(PEF Alerting is enabled/disabled separately from IPMI messaging) +* disabled = disabled for IPMI messaging +* pre_boot = pre\-boot only channel only available when system is in a +.INDENT 2.0 +.INDENT 3.5 +powered down state or in BIOS prior to start of boot. +.UNINDENT +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +.INDENT 2.0 +.TP +.B always = channel always available regardless of system mode. +BIOS typically dedicates the serial connection to the BMC. +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +.B shared = same as always available, but BIOS typically leaves the +serial port available for software use. +.UNINDENT +.UNINDENT + +.IP \(bu 2 +\fBprivilege_update_mode\fP \-\- Channel Privilege Level Limit. +This value sets the maximum privilege level +that can be accepted on the specified channel. +* dont_change = don\(aqt set or change channel Privilege Level Limit +* non_volatile = non\-volatile Privilege Level Limit according +* volatile = volatile setting of Privilege Level Limit +.IP \(bu 2 +\fBprivilege_level\fP \-\- Channel Privilege Level Limit +* reserved = unused +* callback +* user +* operator +* administrator +* proprietary = used by OEM +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_channel_access privilege_level=\(aqadministrator\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_identify(on=True, duration=600, **kwargs) +Request identify light +.sp +Request the identify light to turn off, on for a duration, +or on indefinitely. Other than error exceptions, +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBon\fP \-\- Set to True to force on or False to force off +.IP \(bu 2 +\fBduration\fP \-\- Set if wanting to request turn on for a duration +in seconds, None = indefinitely. +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_identify +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_power(state=\(aqpower_on\(aq, wait=True, **kwargs) +Request power state change +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBname\fP \-\- .INDENT 2.0 +.IP \(bu 2 +power_on \-\- system turn on +.IP \(bu 2 +power_off \-\- system turn off (without waiting for OS) +.IP \(bu 2 +shutdown \-\- request OS proper shutdown +.IP \(bu 2 +reset \-\- reset (without waiting for OS) +.IP \(bu 2 +boot \-\- If system is off, then \(aqon\(aq, else \(aqreset\(aq +.UNINDENT + +.IP \(bu 2 +\fBensure\fP \-\- If (bool True), do not return until system actually completes +requested state change for 300 seconds. +If a non\-zero (int), adjust the wait time to the +requested number of seconds +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.TP +.B Returns +dict \-\- A dict describing the response retrieved +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_power state=shutdown wait=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_user_access(uid, channel=14, callback=True, link_auth=True, ipmi_msg=True, privilege_level=\(aqadministrator\(aq, **kwargs) +Set user access +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- user number [1:16] +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.UNINDENT +.TP +.B Parm callback +User Restricted to Callback +.UNINDENT +.INDENT 7.0 +.TP +.B False = User Privilege Limit is determined by the User Privilege Limit +parameter, below, for both callback and non\-callback connections. +.TP +.B True = User Privilege Limit is determined by the User Privilege Limit +parameter for callback connections, but is restricted to Callback +level for non\-callback connections. Thus, a user can only initiate +a Callback when they \(aqcall in\(aq to the BMC, but once the callback +connection has been made, the user could potentially establish a +session as an Operator. +.UNINDENT +.INDENT 7.0 +.TP +.B Parameters +\fBlink_auth\fP \-\- User Link authentication +.UNINDENT +.sp +enable/disable (used to enable whether this +user\(aqs name and password information will be used for link +authentication, e.g. PPP CHAP) for the given channel. Link +authentication itself is a global setting for the channel and is +enabled/disabled via the serial/modem configuration parameters. +.INDENT 7.0 +.TP +.B Parameters +\fBipmi_msg\fP \-\- User IPMI Messaginge: +.UNINDENT +.sp +(used to enable/disable whether +this user\(aqs name and password information will be used for IPMI +Messaging. In this case, \(aqIPMI Messaging\(aq refers to the ability to +execute generic IPMI commands that are not associated with a +particular payload type. For example, if IPMI Messaging is disabled for +a user, but that user is enabled for activatallow_authing the SOL +payload type, then IPMI commands associated with SOL and session +management, such as Get SOL Configuration Parameters and Close Session +are available, but generic IPMI commands such as Get SEL Time are +unavailable.) +.INDENT 7.0 +.TP +.B Parameters +\fBprivilege_level\fP \-\- +.UNINDENT +.sp +User Privilege Limit. (Determines the maximum privilege level that the +user is allowed to switch to on the specified channel.) +.INDENT 7.0 +.INDENT 3.5 +.INDENT 0.0 +.IP \(bu 2 +callback +.IP \(bu 2 +user +.IP \(bu 2 +operator +.IP \(bu 2 +administrator +.IP \(bu 2 +proprietary +.IP \(bu 2 +no_access +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B Parameters +\fBkwargs\fP \-\- .INDENT 7.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_user_access uid=2 privilege_level=\(aqoperator\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_user_name(uid, name, **kwargs) +Set user name +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- user number [1:16] +.IP \(bu 2 +\fBname\fP \-\- username (limit of 16bytes) +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_user_name uid=2 name=\(aqsteverweber\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.set_user_password(uid, mode=\(aqset_password\(aq, password=None, **kwargs) +Set user password and (modes) +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- id number of user. see: get_names_uid()[\(aqname\(aq] +.IP \(bu 2 +\fBmode\fP \-\- .INDENT 2.0 +.IP \(bu 2 +disable = disable user connections +.IP \(bu 2 +enable = enable user connections +.IP \(bu 2 +set_password = set or ensure password +.IP \(bu 2 +test_password = test password is correct +.UNINDENT + +.IP \(bu 2 +\fBpassword\fP \-\- max 16 char string +(optional when mode is [disable or enable]) +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.TP +.B Returns +True on success +when mode = test_password, return False on bad password +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.set_user_password api_host=127.0.0.1 api_user=admin api_pass=pass + uid=1 password=newPass +salt\-call ipmi.set_user_password uid=1 mode=enable +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.ipmi.user_delete(uid, channel=14, **kwargs) +Delete user (helper) +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBuid\fP \-\- user number [1:16] +.IP \(bu 2 +\fBchannel\fP \-\- number [1:7] +.IP \(bu 2 +\fBkwargs\fP \-\- .INDENT 2.0 +.IP \(bu 2 +api_host=127.0.0.1 +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass=example +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT + +.UNINDENT +.UNINDENT +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call ipmi.user_delete uid=2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.ipset .sp Support for ipset @@ -70133,9 +77108,8 @@ salt \(aq*\(aq iptables.append filter INPUT \e .INDENT 0.0 .TP .B salt.modules.iptables.build_rule(table=None, chain=None, command=None, position=\(aq\(aq, full=None, family=\(aqipv4\(aq, **kwargs) -Build a well\-formatted iptables rule based on kwargs. Long options must be -used (\fI\-\-jump\fP instead of \fI\-j\fP) because they will have the \fI\-\-\fP added to -them. A \fItable\fP and \fIchain\fP are not required, unless \fIfull\fP is True. +Build a well\-formatted iptables rule based on kwargs. A \fItable\fP and \fIchain\fP +are not required, unless \fIfull\fP is True. .sp If \fIfull\fP is \fITrue\fP, then \fItable\fP, \fIchain\fP and \fIcommand\fP are required. \fIcommand\fP may be specified as either a short option (\(aqI\(aq) or a long option @@ -70147,6 +77121,9 @@ If a position is required (as with \fI\-I\fP or \fI\-D\fP), it may be specified .sp If \fIconnstate\fP is passed in, it will automatically be changed to \fIstate\fP\&. .sp +To pass in jump options that doesn\(aqt take arguments, pass in an empty +string. +.sp CLI Examples: .INDENT 7.0 .INDENT 3.5 @@ -70520,6 +77497,9 @@ salt \(aq*\(aq iptables.version family=ipv6 .SS salt.modules.jboss7 .sp Module for managing JBoss AS 7 through the CLI interface. +.sp +New in version 2015.5.0. + .INDENT 0.0 .TP .B In order to run each function, jboss_config dictionary with the following properties must be passed: @@ -71263,9 +78243,19 @@ salt \(aq*\(aq keystone.tenant_list profile=openstack1 .INDENT 0.0 .TP .B salt.modules.keystone.auth(profile=None, **connection_args) -Set up keystone credentials +Set up keystone credentials. Only intended to be used within Keystone\-enabled modules. .sp -Only intended to be used within Keystone\-enabled modules +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq keystone.auth +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -71413,7 +78403,9 @@ salt \(aq*\(aq keystone.endpoint_list .INDENT 0.0 .TP .B salt.modules.keystone.role_create(name, profile=None, **connection_args) -Create named role +Create a named role. +.sp +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp @@ -73402,6 +80394,19 @@ salt \(aqminion\(aq lxc.apply_network_profile web1 \e .fi .UNINDENT .UNINDENT +.sp +The special case to disable use of ethernet nics: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aqminion\(aq lxc.apply_network_profile web1 centos \e + "{eth0: {disable: true}}" +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -73487,7 +80492,7 @@ salt \(aqminion\(aq lxc.bootstrap container_name [config=config_data] \e .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.clone(name, orig, profile=None, **kwargs) +.B salt.modules.lxc.clone(name, orig, profile=None, network_profile=None, nic_opts=None, **kwargs) Create a new container as a clone of another container .INDENT 7.0 .TP @@ -73516,6 +80521,18 @@ Size of the volume to create. Only applicable if \fBbacking=lvm\fP\&. .B backing The type of storage to use. Set to \fBlvm\fP to use an LVM group. Defaults to filesystem within /var/lib/lxc. +.TP +.B network_profile +Network profile to use for container +.sp +New in version 2015.5.2. + +.TP +.B nic_opts +give extra opts overriding network profile values +.sp +New in version 2015.5.2. + .UNINDENT .sp CLI Examples: @@ -73586,6 +80603,68 @@ THE SALT CLOUD DRIVER (ask kiorky). .B name name of the lxc container to create .TP +.B pub_key +public key to preseed the minion with. +Can be the keycontent or a filepath +.TP +.B priv_key +private key to preseed the minion with. +Can be the keycontent or a filepath +.TP +.B profile +\fIprofile\fP selection +.TP +.B network_profile +\fInetwork profile\fP selection +.TP +.B nic_opts +per interface settings compatibles with +network profile (ipv4/ipv6/link/gateway/mac/netmask) +.sp +eg: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +\- {\(aqeth0\(aq: {\(aqmac\(aq: \(aq00:16:3e:01:29:40\(aq, + \(aqgateway\(aq: None, (default) + \(aqlink\(aq: \(aqbr0\(aq, (default) + \(aqgateway\(aq: None, (default) + \(aqnetmask\(aq: \(aq\(aq, (default) + \(aqip\(aq: \(aq22.1.4.25\(aq}} +.ft P +.fi +.UNINDENT +.UNINDENT +.TP +.B unconditional_install +given to lxc.bootstrap (see relative doc) +.TP +.B force_install +given to lxc.bootstrap (see relative doc) +.TP +.B config +any extra argument for the salt minion config +.TP +.B dnsservers +dns servers to set inside the container +.TP +.B autostart +autostart the container at boot time +.TP +.B password +administrative password for the container +.UNINDENT +.sp +\fBWARNING:\fP +.INDENT 7.0 +.INDENT 3.5 +Legacy but still supported options: +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP .B from_container which container we use as a template when running lxc.clone @@ -73613,17 +80692,9 @@ Use snapshot when cloning the container source .B vgname if using LVM: vgname .TP -.B lgname +.B lvname if using LVM: lvname .TP -.B pub_key -public key to preseed the minion with. -Can be the keycontent or a filepath -.TP -.B priv_key -private key to preseed the minion with. -Can be the keycontent or a filepath -.TP .B ip ip for the primary nic .TP @@ -73664,27 +80735,13 @@ eg: .UNINDENT .UNINDENT .TP -.B unconditional_install -given to lxc.bootstrap (see relative doc) -.TP -.B force_install -given to lxc.bootstrap (see relative doc) -.TP -.B config -any extra argument for the salt minion config -.TP -.B dnsservers -dns servers to set inside the container -.TP -.B autostart -autostart the container at boot time -.TP -.B password -administrative password for the container -.TP .B users administrative users for the container default: [root] and [root, ubuntu] on ubuntu +.TP +.B default_nic +name of the first interface, you should +really not override this .UNINDENT .sp CLI Example: @@ -74001,7 +81058,7 @@ Parameters set in a profile can be overridden by passing additional container creation arguments (such as the ones passed to \fI\%lxc.create\fP) to this function. .sp A profile can be defined either as the name of the profile, or a dictionary -of variable names and values. See the LXC Tutorial for more information on how to use LXC profiles. +of variable names and values. See the \fILXC Tutorial\fP for more information on how to use LXC profiles. .sp CLI Example: .INDENT 7.0 @@ -74023,7 +81080,7 @@ salt\-call lxc.get_container_profile ubuntu template=ubuntu backing=overlayfs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.get_network_profile(name=None) +.B salt.modules.lxc.get_network_profile(name=None, **kwargs) New in version 2015.5.0. .sp @@ -74059,11 +81116,25 @@ lxc.network_profile.centos: .UNINDENT .UNINDENT .sp +To disable networking entirely: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +lxc.network_profile.centos: + eth0: + disable: true +.ft P +.fi +.UNINDENT +.UNINDENT +.sp Parameters set in a profile can be overridden by passing additional arguments to this function. .sp A profile can be passed either as the name of the profile, or a -dictionary of variable names and values. See the LXC Tutorial for more information on how to use network +dictionary of variable names and values. See the \fILXC Tutorial\fP for more information on how to use network profiles. .sp \fBWARNING:\fP @@ -74157,7 +81228,7 @@ salt \(aq*\(aq lxc.info name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.init(name, config=None, cpuset=None, cpushare=None, memory=None, profile=None, network_profile=, nic=, nic_opts=None, cpu=None, autostart=True, password=None, password_encrypted=None, users=None, dnsservers=None, searchdomains=None, bridge=None, gateway=None, pub_key=None, priv_key=None, force_install=False, unconditional_install=False, bootstrap_delay=None, bootstrap_args=None, bootstrap_shell=None, bootstrap_url=None, **kwargs) +.B salt.modules.lxc.init(name, config=None, cpuset=None, cpushare=None, memory=None, profile=None, network_profile=None, nic=, nic_opts=None, cpu=None, autostart=True, password=None, password_encrypted=None, users=None, dnsservers=None, searchdomains=None, bridge=None, gateway=None, pub_key=None, priv_key=None, force_install=False, unconditional_install=False, bootstrap_delay=None, bootstrap_args=None, bootstrap_shell=None, bootstrap_url=None, **kwargs) Initialize a new container. .sp This is a partial idempotent function as if it is already provisioned, we @@ -74258,6 +81329,12 @@ If salt\-minion is not already installed, install it. Default: \fBTrue\fP Optional config parameters. By default, the id is set to the name of the container. .TP +.B master +salt master (default to minion\(aqs master) +.TP +.B master_port +salt master port (default to minion\(aqs master port) +.TP .B pub_key Explicit public key to preseed the minion with (optional). This can be either a filepath or a string representing the key @@ -74448,7 +81525,7 @@ salt myminion lxc.restart name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.retcode(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.retcode(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -74509,6 +81586,10 @@ Use SaltStack\(aqs utils.vt to stream output to console .B keep_env http_proxy,https_proxy,no_proxy A list of env vars to preserve. May be passed as commma\-delimited list. +.TP +.B chroot_fallback +if the container is not running, try to run the command using chroot +default: false .UNINDENT .sp CLI Example: @@ -74525,7 +81606,7 @@ salt myminion lxc.retcode mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -74583,6 +81664,10 @@ False Use SaltStack\(aqs utils.vt to stream output to console. Assumes \fBoutput=all\fP\&. .TP +.B chroot_fallback +if the container is not running, try to run the command using chroot +default: false +.TP .B keep_env http_proxy,https_proxy,no_proxy A list of env vars to preserve. May be passed as commma\-delimited list. @@ -74602,7 +81687,7 @@ salt myminion lxc.run mycontainer \(aqifconfig \-a\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_all(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_all(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -74661,6 +81746,10 @@ Use SaltStack\(aqs utils.vt to stream output to console .B keep_env http_proxy,https_proxy,no_proxy A list of env vars to preserve. May be passed as commma\-delimited list. +.TP +.B chroot_fallback +if the container is not running, try to run the command using chroot +default: false .UNINDENT .sp CLI Example: @@ -74677,13 +81766,13 @@ salt myminion lxc.run_all mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_cmd(name, cmd, no_start=False, preserve_state=True, stdin=None, stdout=True, stderr=False, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_cmd(name, cmd, no_start=False, preserve_state=True, stdin=None, stdout=True, stderr=False, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) Deprecated since version 2015.5.0: Use \fI\%lxc.run\fP instead .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_stderr(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_stderr(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -74742,6 +81831,10 @@ Use SaltStack\(aqs utils.vt to stream output to console .B keep_env http_proxy,https_proxy,no_proxy A list of env vars to preserve. May be passed as commma\-delimited list. +.TP +.B chroot_fallback +if the container is not running, try to run the command using chroot +default: false .UNINDENT .sp CLI Example: @@ -74758,7 +81851,7 @@ salt myminion lxc.run_stderr mycontainer \(aqip addr show\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.lxc.run_stdout(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) +.B salt.modules.lxc.run_stdout(name, cmd, no_start=False, preserve_state=True, stdin=None, python_shell=True, output_loglevel=\(aqdebug\(aq, use_vt=False, ignore_retcode=False, chroot_fallback=False, keep_env=\(aqhttp_proxy, https_proxy, no_proxy\(aq) New in version 2015.5.0. .sp @@ -74819,6 +81912,10 @@ Use SaltStack\(aqs utils.vt to stream output to console .B keep_env http_proxy,https_proxy,no_proxy A list of env vars to preserve. May be passed as commma\-delimited list. +.TP +.B chroot_fallback +if the container is not running, try to run the command using chroot +default: false .UNINDENT .sp CLI Example: @@ -74835,6 +81932,57 @@ salt myminion lxc.run_stdout mycontainer \(aqifconfig \-a\(aq .UNINDENT .INDENT 0.0 .TP +.B salt.modules.lxc.running_systemd(name, cache=True) +Determine if systemD is running +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq lxc.running_systemd ubuntu +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.lxc.search_lxc_bridge() +Search the first bridge which is potentially available as LXC bridge +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq lxc.search_lxc_bridge +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.lxc.search_lxc_bridges() +Search which bridges are potentially available as LXC bridges +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq lxc.search_lxc_bridges +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.lxc.set_dns(name, dnsservers=None, searchdomains=None) Changed in version 2015.5.0: The \fBdnsservers\fP and \fBsearchdomains\fP parameters can now be passed as a comma\-separated list. @@ -74983,6 +82131,23 @@ salt myminion lxc.stop name .UNINDENT .INDENT 0.0 .TP +.B salt.modules.lxc.systemd_running_state(name) +Get the operational state of a systemd based container +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.systemd_running_state ubuntu +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.lxc.templates() New in version 2015.5.0. @@ -75003,6 +82168,41 @@ salt myminion lxc.templates .UNINDENT .INDENT 0.0 .TP +.B salt.modules.lxc.test_bare_started_state(name) +Test if a non systemd container is fully started +For now, it consists only to test if the container is attachable +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.test_bare_started_state ubuntu +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.lxc.test_sd_started_state(name) +Test if a systemd container is fully started +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.test_sd_started_state ubuntu +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.lxc.unfreeze(name) Unfreeze the named container. .sp @@ -75039,6 +82239,50 @@ salt myminion lxc.update_lxc_conf ubuntu \e .UNINDENT .INDENT 0.0 .TP +.B salt.modules.lxc.version() +Return the actual lxc client version +.INDENT 7.0 +.INDENT 3.5 +New in version 2015.5.2. + +.UNINDENT +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq lxc.version +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.lxc.wait_started(name, timeout=300) +Check that the system has fully inited +.sp +This is actually very important for systemD based containers +.sp +see \fI\%https://github.com/saltstack/salt/issues/23847\fP +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt myminion lxc.wait_started ubuntu +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.lxc.write_conf(conf_file, conf) Write out an LXC configuration file .sp @@ -77712,6 +84956,33 @@ salt \(aq*\(aq random.hash \(aqI am a string\(aq md5 .UNINDENT .INDENT 0.0 .TP +.B salt.modules.mod_random.rand_int(start=1, end=10) +Returns a random integer number between the start and end number. +.INDENT 7.0 +.TP +.B start +1 +Any valid integer number +.TP +.B end +10 +Any valid integer number +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random.rand_int 1 10 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.mod_random.shadow_hash(crypt_salt=None, password=None, algorithm=\(aqsha512\(aq) Generates a salted hash suitable for /etc/shadow. .INDENT 7.0 @@ -77778,7 +85049,7 @@ Control Modjk via the Apache Tomcat "Status" worker Below is an example of the configuration needed for this module. This configuration data can be placed either in \fBgrains\fP or \fBpillar\fP\&. .sp -If using grains, this can be accomplished statically or via a grain module\&. +If using grains, this can be accomplished \fIstatically\fP or via a \fIgrain module\fP\&. .sp If using pillar, the yaml configuration can be placed directly into a pillar SLS file, making this both the easier and more dynamic method of configuring @@ -79742,6 +87013,188 @@ salt \(aq*\(aq mysql.version .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.nacl +.sp +This module helps include encrypted passwords in pillars, grains and salt state files. +.INDENT 0.0 +.TP +.B depends +libnacl, \fI\%https://github.com/saltstack/libnacl\fP +.UNINDENT +.sp +This is often useful if you wish to store your pillars in source control or +share your pillar data with others that you trust. I don\(aqt advise making your pillars public +regardless if they are encrypted or not. +.sp +When generating keys and encrypting passwords use \-\-local when using salt\-call for extra +security. Also consider using just the salt runner nacl when encrypting pillar passwords. +.sp +The nacl lib uses 32byte keys, these keys are base64 encoded to make your life more simple. +To generate your \fIkey\fP or \fIkeyfile\fP you can use: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.keygen keyfile=/root/.nacl +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Now with your key, you can encrypt some data: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.enc mypass keyfile=/root/.nacl +DRB7Q6/X5gGSRCTpZyxS6hXO5LnlJIIJ4ivbmUlbWj0llUA+uaVyvou3vJ4= +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To decrypt the data: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.dec data=\(aqDRB7Q6/X5gGSRCTpZyxS6hXO5LnlJIIJ4ivbmUlbWj0llUA+uaVyvou3vJ4=\(aq keyfile=/root/.nacl +mypass +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +The following optional configurations can be defined in the +minion or master config. Avoid storing the config in pillars! +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +cat /etc/salt/master.d/nacl.conf +nacl.config: + key: None + keyfile: /root/.nacl +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +When the key is defined in the master config you can use it from the nacl runner: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-run nacl.enc \(aqmyotherpass\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Now you can create a pillar with protected data like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +pillarexample: + user: root + password: {{ salt.nacl.dec(\(aqDRB7Q6/X5gGSRCTpZyxS6hXO5LnlJIIJ4ivbmUlbWj0llUA+uaVyvou3vJ4=\(aq) }} +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Or do something interesting with grains like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call nacl.enc minionname:dbrole +AL24Z2C5OlkReer3DuQTFdrNLchLuz3NGIhGjZkLtKRYry/b/CksWM8O9yskLwH2AGVLoEXI5jAa + +salt minionname grains.setval role \(aqAL24Z2C5OlkReer3DuQTFdrNLchLuz3NGIhGjZkLtKRYry/b/CksWM8O9yskLwH2AGVLoEXI5jAa\(aq + +{%\- set r = grains.get(\(aqrole\(aq) %} +{%\- set role = None %} +{%\- if r and \(aqnacl.dec\(aq in salt %} + {%\- set r = salt[\(aqnacl.dec\(aq](r,keyfile=\(aq/root/.nacl\(aq).split(\(aq:\(aq) %} + {%\- if opts[\(aqid\(aq] == r[0] %} + {%\- set role = r[1] %} + {%\- endif %} +{%\- endif %} +base: + {%\- if role %} + \(aq{{ opts[\(aqid\(aq] }}\(aq: + \- {{ role }} + {%\- endif %} +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.dec(data, **kwargs) +Takes a key generated from \fInacl.keygen\fP and decrypt some data. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.dec pEXHQM6cuaF7A= +salt\-call \-\-local nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq keyfile=/root/.nacl +salt\-call \-\-local nacl.dec data=\(aqpEXHQM6cuaF7A=\(aq key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.enc(data, **kwargs) +Takes a key generated from \fInacl.keygen\fP and encrypt some data. +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.enc datatoenc +salt\-call \-\-local nacl.enc datatoenc keyfile=/root/.nacl +salt\-call \-\-local nacl.enc datatoenc key=\(aqcKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k=\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.nacl.keygen(keyfile=None) +Use libnacl to generate a private key +.sp +CLI Examples: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt\-call \-\-local nacl.keygen +salt\-call \-\-local nacl.keygen keyfile=/root/.nacl +salt\-call \-\-local \-\-out=newline_values_only nacl.keygen > /root/.nacl +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.nagios .sp Run nagios plugins/checks from salt and get the return as data. @@ -81213,14 +88666,24 @@ New in version 2015.5.0. Return a True or False instead of ping output. .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt \(aq*\(aq network.ping archlinux.org return_boolean=True +.ft P +.fi .UNINDENT .UNINDENT .sp Set the time to wait for a response in seconds. .INDENT 7.0 .INDENT 3.5 +.sp +.nf +.ft C salt \(aq*\(aq network.ping archlinux.org timeout=3 +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT @@ -84705,7 +92168,7 @@ salt \(aq*\(aq npm.list .UNINDENT .INDENT 0.0 .TP -.B salt.modules.npm.uninstall(pkg, dir=None, runas=None) +.B salt.modules.npm.uninstall(pkg, dir=None, runas=None, env=None) Uninstall an NPM package. .sp If no directory is specified, the package will be uninstalled globally. @@ -84720,6 +92183,14 @@ global installation .TP .B runas The user to run NPM with +.TP +.B env +Environment variables to set when invoking npm. Uses the same \fBenv\fP +format as the \fBcmd.run\fP execution +function. +.sp +New in version 2015.5.3. + .UNINDENT .sp CLI Example: @@ -87285,7 +94756,8 @@ Salt now uses a portable python. As a result the entire pip module is now functional on the salt installation itself. You can pip install dependencies for your custom modules. You can even upgrade salt itself using pip. For this to work properly, you must specify the Current Working Directory (\fBcwd\fP) and -the Pip Binary (\fBbin_env\fP) salt should use. +the Pip Binary (\fBbin_env\fP) salt should use. The variable \fBpip_bin\fP can +be either a virtualenv path or the path to the pip binary itself. .sp For example, the following command will list all software installed using pip to your current salt environment: @@ -87331,7 +94803,7 @@ painful in windows. .sp To do this you just use pip with git to update to the version you want and then restart the service. Here is a sample state file that upgrades salt to the head -of the 2015.2 branch: +of the 2015.5 branch: .INDENT 0.0 .INDENT 3.5 .sp @@ -87341,7 +94813,7 @@ install_salt: pip.installed: \- cwd: \(aqC:\esalt\ebin\escripts\(aq \- bin_env: \(aqC:\esalt\ebin\escripts\epip.exe\(aq - \- editable: git+https://github.com/saltstack/salt@2015.2#egg=salt + \- editable: git+https://github.com/saltstack/salt@2015.5#egg=salt \- upgrade: True restart_service: @@ -87660,7 +95132,9 @@ The user under which to run pip .TP .B no_chown When user is given, do not attempt to copy and chown -a requirements file +a requirements file (needed if the requirements file refers to other +files via relative paths, as the copy\-and\-chown procedure does not +account for such files) .TP .B cwd Current working directory to run pip from @@ -91388,518 +98862,6 @@ returns a list of applied powerpath license keys .B salt.modules.powerpath.remove_license(key) Remove a license .UNINDENT -.SS salt.modules.ps -.sp -A salt interface to psutil, a system and process library. -See \fI\%http://code.google.com/p/psutil\fP\&. -.INDENT 0.0 -.TP -.B depends -.INDENT 7.0 -.IP \(bu 2 -psutil Python module, version 0.3.0 or later -.IP \(bu 2 -python\-utmp package (optional) -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.boot_time(time_format=None) -Return the boot time in number of seconds since the epoch began. -.sp -CLI Example: -.INDENT 7.0 -.TP -.B time_format -Optionally specify a \fI\%strftime\fP format string. Use -\fBtime_format=\(aq%c\(aq\fP to get a nicely\-formatted locale specific date and -time (i.e. \fBFri May 2 19:08:32 2014\fP). -.sp -New in version 2014.1.4. - -.UNINDENT -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.boot_time -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.cpu_percent(interval=0.1, per_cpu=False) -Return the percent of time the CPU is busy. -.INDENT 7.0 -.TP -.B interval -the number of seconds to sample CPU usage over -.TP -.B per_cpu -if True return an array of CPU percent busy for each CPU, otherwise -aggregate all percents into one number -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.cpu_percent -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.cpu_times(per_cpu=False) -Return the percent of time the CPU spends in each state, -e.g. user, system, idle, nice, iowait, irq, softirq. -.INDENT 7.0 -.TP -.B per_cpu -if True return an array of percents for each CPU, otherwise aggregate -all percents into one number -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.cpu_times -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.disk_io_counters(device=None) -Return disk I/O statistics. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.disk_io_counters - -salt \(aq*\(aq ps.disk_io_counters device=sda1 -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.disk_partition_usage(all=False) -Return a list of disk partitions plus the mount point, filesystem and usage -statistics. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.disk_partition_usage -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.disk_partitions(all=False) -Return a list of disk partitions and their device, mount point, and -filesystem type. -.INDENT 7.0 -.TP -.B all -if set to False, only return local, physical partitions (hard disk, -USB, CD/DVD partitions). If True, return all filesystems. -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.disk_partitions -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.disk_usage(path) -Given a path, return a dict listing the total available space as well as -the free space, and used space. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.disk_usage /home -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.get_pid_list() -Return a list of process ids (PIDs) for all running processes. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.get_pid_list -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.get_users() -Return logged\-in users. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.get_users -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.kill_pid(pid, signal=15) -Kill a process by PID. -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aqminion\(aq ps.kill_pid pid [signal=signal_number] -.ft P -.fi -.UNINDENT -.UNINDENT -.INDENT 7.0 -.TP -.B pid -PID of process to kill. -.TP -.B signal -Signal to send to the process. See manpage entry for kill -for possible values. Default: 15 (SIGTERM). -.UNINDENT -.sp -\fBExample:\fP -.sp -Send SIGKILL to process with PID 2000: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aqminion\(aq ps.kill_pid 2000 signal=9 -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.network_io_counters(interface=None) -Return network I/O statistics. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.network_io_counters - -salt \(aq*\(aq ps.network_io_counters interface=eth0 -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.num_cpus() -Return the number of CPUs. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.num_cpus -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.pgrep(pattern, user=None, full=False) -Return the pids for processes matching a pattern. -.sp -If full is true, the full command line is searched for a match, -otherwise only the name of the command is searched. -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.pgrep pattern [user=username] [full=(true|false)] -.ft P -.fi -.UNINDENT -.UNINDENT -.INDENT 7.0 -.TP -.B pattern -Pattern to search for in the process list. -.TP -.B user -Limit matches to the given username. Default: All users. -.TP -.B full -A boolean value indicating whether only the name of the command or -the full command line should be matched against the pattern. -.UNINDENT -.sp -\fBExamples:\fP -.sp -Find all httpd processes on all \(aqwww\(aq minions: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aqwww.*\(aq ps.pgrep httpd -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -Find all bash processes owned by user \(aqtom\(aq: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.pgrep bash user=tom -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.pkill(pattern, user=None, signal=15, full=False) -Kill processes matching a pattern. -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.pkill pattern [user=username] [signal=signal_number] \e - [full=(true|false)] -.ft P -.fi -.UNINDENT -.UNINDENT -.INDENT 7.0 -.TP -.B pattern -Pattern to search for in the process list. -.TP -.B user -Limit matches to the given username. Default: All users. -.TP -.B signal -Signal to send to the process(es). See manpage entry for kill -for possible values. Default: 15 (SIGTERM). -.TP -.B full -A boolean value indicating whether only the name of the command or -the full command line should be matched against the pattern. -.UNINDENT -.sp -\fBExamples:\fP -.sp -Send SIGHUP to all httpd processes on all \(aqwww\(aq minions: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aqwww.*\(aq ps.pkill httpd signal=1 -.ft P -.fi -.UNINDENT -.UNINDENT -.sp -Send SIGKILL to all bash processes owned by user \(aqtom\(aq: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.pkill bash signal=9 user=tom -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.proc_info(pid, attrs=None) -Return a dictionary of information for a process id (PID). -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.proc_info 2322 -salt \(aq*\(aq ps.proc_info 2322 attrs=\(aq["pid", "name"]\(aq -.ft P -.fi -.UNINDENT -.UNINDENT -.INDENT 7.0 -.TP -.B pid -PID of process to query. -.TP -.B attrs -Optional list of desired process attributes. The list of possible -attributes can be found here: -\fI\%http://pythonhosted.org/psutil/#psutil.Process\fP -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.swap_memory() -New in version 2014.7.0. - -.sp -Return a dict that describes swap memory statistics. -.sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -This function is only available in psutil version 0.6.0 and above. -.UNINDENT -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.swap_memory -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.top(num_processes=5, interval=3) -Return a list of top CPU consuming processes during the interval. -num_processes = return the top N CPU consuming processes -interval = the number of seconds to sample CPU usage over -.sp -CLI Examples: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.top - -salt \(aq*\(aq ps.top 5 10 -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.total_physical_memory() -Return the total number of bytes of physical memory. -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.total_physical_memory -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.ps.virtual_memory() -New in version 2014.7.0. - -.sp -Return a dict that describes statistics about system memory usage. -.sp -\fBNOTE:\fP -.INDENT 7.0 -.INDENT 3.5 -This function is only available in psutil version 0.6.0 and above. -.UNINDENT -.UNINDENT -.sp -CLI Example: -.INDENT 7.0 -.INDENT 3.5 -.sp -.nf -.ft C -salt \(aq*\(aq ps.virtual_memory -.ft P -.fi -.UNINDENT -.UNINDENT -.UNINDENT .SS salt.modules.publish .sp Publish a command from a minion to a target @@ -92058,11 +99020,19 @@ salt publish.runner manage.down Execute puppet routines .INDENT 0.0 .TP -.B salt.modules.puppet.disable() +.B salt.modules.puppet.disable(message=None) New in version 2014.7.0. .sp Disable the puppet agent +.INDENT 7.0 +.TP +.B message +New in version 2015.5.2. + +.sp +Disable message to send to puppet +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -92071,6 +99041,7 @@ CLI Example: .nf .ft C salt \(aq*\(aq puppet.disable +salt \(aq*\(aq puppet.disable \(aqdisabled for a good reason\(aq .ft P .fi .UNINDENT @@ -93691,6 +100662,326 @@ salt publish.runner manage.down .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.random_org +.sp +Module for retrieving random information from Random.org +.sp +New in version 2015.5.0. + +.INDENT 0.0 +.TP +.B configuration +This module can be used by either passing an api key and version +directly or by specifying both in a configuration profile in the salt +master/minion config. +.sp +For example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +random_org: + api_key: 7be1402d\-5719\-5bd3\-a306\-3def9f135da5 + api_version: 1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.generateBlobs(api_key=None, api_version=None, **kwargs) +List all Slack users. +:param api_key: The Random.org api key. +:param api_version: The Random.org api version. +:param format: Specifies the format in which the +.INDENT 7.0 +.INDENT 3.5 +blobs will be returned. Values +allowed are base64 and hex. +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B Returns +The user list. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq get_integers number=5 min=1 max=6 + +salt \(aq*\(aq get_integers number=5 min=1 max=6 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.generateDecimalFractions(api_key=None, api_version=None, **kwargs) +Generates true random decimal fractions +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The Random.org api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The Random.org api version. +.IP \(bu 2 +\fBnumber\fP \-\- How many random decimal fractions +you need. Must be within the [1,1e4] range. +.IP \(bu 2 +\fBdecimalPlaces\fP \-\- The number of decimal places +to use. Must be within the [1,20] range. +.IP \(bu 2 +\fBreplacement\fP \-\- Specifies whether the random numbers should +be picked with replacement. The default (true) +will cause the numbers to be picked with replacement, +i.e., the resulting numbers may contain duplicate +values (like a series of dice rolls). If you want the +numbers picked to be unique (like raffle tickets drawn +from a container), set this value to false. +.UNINDENT +.TP +.B Returns +A list of decimal fraction +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random_org.generateDecimalFractions number=10 decimalPlaces=4 + +salt \(aq*\(aq random_org.generateDecimalFractions number=10 decimalPlaces=4 replacement=True +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.generateGaussians(api_key=None, api_version=None, **kwargs) +This method generates true random numbers from a +Gaussian distribution (also known as a normal distribution). +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The Random.org api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The Random.org api version. +.IP \(bu 2 +\fBnumber\fP \-\- How many random numbers you need. +Must be within the [1,1e4] range. +.IP \(bu 2 +\fBmean\fP \-\- The distribution\(aqs mean. Must be +within the [\-1e6,1e6] range. +.IP \(bu 2 +\fBstandardDeviation\fP \-\- The distribution\(aqs standard +deviation. Must be within +the [\-1e6,1e6] range. +.IP \(bu 2 +\fBsignificantDigits\fP \-\- The number of significant digits +to use. Must be within the [2,20] range. +.UNINDENT +.TP +.B Returns +The user list. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random_org.generateGaussians number=10 mean=0.0 standardDeviation=1.0 significantDigits=8 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.generateIntegers(api_key=None, api_version=None, **kwargs) +Generate random integers +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The Random.org api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The Random.org api version. +.IP \(bu 2 +\fBnumber\fP \-\- The number of integers to generate +.IP \(bu 2 +\fBminimum\fP \-\- The lower boundary for the range from which the +random numbers will be picked. Must be within +the [\-1e9,1e9] range. +.IP \(bu 2 +\fBmaximum\fP \-\- The upper boundary for the range from which the +random numbers will be picked. Must be within +the [\-1e9,1e9] range. +.IP \(bu 2 +\fBreplacement\fP \-\- Specifies whether the random numbers should +be picked with replacement. The default (true) +will cause the numbers to be picked with replacement, +i.e., the resulting numbers may contain duplicate +values (like a series of dice rolls). If you want the +numbers picked to be unique (like raffle tickets drawn +from a container), set this value to false. +.IP \(bu 2 +\fBbase\fP \-\- Specifies the base that will be used to display the numbers. +Values allowed are 2, 8, 10 and 16. This affects the JSON +types and formatting of the resulting data as discussed below. +.UNINDENT +.TP +.B Returns +A list of integers. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random_org.generateIntegers number=5 minimum=1 maximum=6 + +salt \(aq*\(aq random_org.generateIntegers number=5 minimum=2 maximum=255 base=2 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.generateStrings(api_key=None, api_version=None, **kwargs) +Generate random strings. +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The Random.org api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The Random.org api version. +.IP \(bu 2 +\fBnumber\fP \-\- The number of strings to generate. +.IP \(bu 2 +\fBlength\fP \-\- The length of each string. Must be +within the [1,20] range. All strings +will be of the same length +.IP \(bu 2 +\fBcharacters\fP \-\- A string that contains the set of +characters that are allowed to occur +in the random strings. The maximum number +of characters is 80. +.IP \(bu 2 +\fBreplacement\fP \-\- Specifies whether the random strings should be picked +with replacement. The default (true) will cause the +strings to be picked with replacement, i.e., the +resulting list of strings may contain duplicates (like +a series of dice rolls). If you want the strings to be +unique (like raffle tickets drawn from a container), set +this value to false. +.UNINDENT +.TP +.B Returns +A list of strings. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random_org.generateStrings number=5 length=8 characters=\(aqabcdefghijklmnopqrstuvwxyz\(aq + +salt \(aq*\(aq random_org.generateStrings number=10 length=16 characters\(aqabcdefghijklmnopqrstuvwxyz\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.generateUUIDs(api_key=None, api_version=None, **kwargs) +Generate a list of random UUIDs +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The Random.org api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The Random.org api version. +.IP \(bu 2 +\fBnumber\fP \-\- How many random UUIDs you need. +Must be within the [1,1e3] range. +.UNINDENT +.TP +.B Returns +A list of UUIDs +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random_org.generateUUIDs number=5 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.random_org.getUsage(api_key=None, api_version=None) +Show current usages statistics +.INDENT 7.0 +.TP +.B Parameters +.INDENT 7.0 +.IP \(bu 2 +\fBapi_key\fP \-\- The Random.org api key. +.IP \(bu 2 +\fBapi_version\fP \-\- The Random.org api version. +.UNINDENT +.TP +.B Returns +The current usage statistics. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq random_org.getUsage + +salt \(aq*\(aq random_org.getUsage api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 api_version=1 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.rbenv .sp Manage ruby installations with rbenv. @@ -96653,6 +103944,23 @@ salt \(aq*\(aq saltutil.refresh_pillar .UNINDENT .INDENT 0.0 .TP +.B salt.modules.saltutil.refresh_beacons() +Signal the minion to refresh the beacons. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq saltutil.refresh_beacons +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.saltutil.refresh_modules() Signal the minion to refresh the module and grain data .sp @@ -96812,6 +104120,29 @@ salt \(aq*\(aq saltutil.sync_all .UNINDENT .INDENT 0.0 .TP +.B salt.modules.saltutil.sync_beacons(saltenv=None, refresh=True) +Sync the beacons from the _beacons directory on the salt master file +server. This function is environment aware, pass the desired environment +to grab the contents of the _beacons directory, base is the default +environment. +.sp +New in version 2015.5.1. + +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq saltutil.sync_beacons +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.saltutil.sync_grains(saltenv=None, refresh=True) Sync the grains from the _grains directory on the salt master file server. This function is environment aware, pass the desired environment @@ -96837,6 +104168,9 @@ Sync the modules from the _modules directory on the salt master file server. This function is environment aware, pass the desired environment to grab the contents of the _modules directory, base is the default environment. +.sp +New in version 2015.5.1. + .sp CLI Example: .INDENT 7.0 @@ -98124,6 +105458,146 @@ salt \(aq*\(aq shadow.set_warndays username 7 .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.slack_notify +.sp +Module for sending messages to Slack +.sp +New in version 2015.5.0. + +.INDENT 0.0 +.TP +.B configuration +This module can be used by either passing an api key and version +directly or by specifying both in a configuration profile in the salt +master/minion config. +.sp +For example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +slack: + api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.slack_notify.find_room(name, api_key=None) +Find a room by name and return it. +:param name: The room name. +:param api_key: The Slack admin api key. +:return: The room object. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq slack.find_room name="random" + +salt \(aq*\(aq slack.find_room name="random" api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.slack_notify.find_user(name, api_key=None) +Find a user by name and return it. +:param name: The user name. +:param api_key: The Slack admin api key. +:return: The user object. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq slack.find_user name="ThomasHatch" + +salt \(aq*\(aq slack.find_user name="ThomasHatch" api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.slack_notify.list_rooms(api_key=None) +List all Slack rooms. +.INDENT 7.0 +.TP +.B Parameters +\fBapi_key\fP \-\- The Slack admin api key. +.TP +.B Returns +The room list. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq slack.list_rooms + +salt \(aq*\(aq slack.list_rooms api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.slack_notify.list_users(api_key=None) +List all Slack users. +:param api_key: The Slack admin api key. +:return: The user list. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq slack.list_users + +salt \(aq*\(aq slack.list_users api_key=peWcBiMOS9HrZG15peWcBiMOS9HrZG15 +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.slack_notify.post_message(channel, message, from_name, api_key=None) +Send a message to a Slack channel. +:param channel: The channel name, either will work. +:param message: The message to send to the HipChat room. +:param from_name: Specify who the message is from. +:param api_key: The Slack api key, if not specified in the configuration. +:return: Boolean if message was sent successfully. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq slack.send_message channel="Development Room" message="Build is done" from_name="Build Server" +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.smartos_imgadm .sp Module for running imgadm command on SmartOS @@ -99540,44 +107014,42 @@ salt \(aq*\(aq user.rename name new_name IPS pkg support for Solaris .sp This module provides support for Solaris 11 new package management \- IPS (Image Packaging System). -In order to manage the IPS packages using salt, you need to override the \fBpkg\fP provider -by setting the \fBproviders\fP parameter in your Minion config file like this: +This is the default pkg module for Solaris 11 (and later). +.sp +If you want to use also other packaging module (e.g. pkgutil) together with IPS, you need to override the \fBpkg\fP provider +in sls for each package: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +mypackage: + pkg.installed: + \- provider: solarisips +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Or you can override it globally by setting the \fBproviders\fP parameter in your Minion config file like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C providers: - pkg: solarisips + pkg: pkgutil .ft P .fi .UNINDENT .UNINDENT -.sp -Or you can set the provider in sls for each pkg: -.. code\-block:: yaml -.INDENT 0.0 -.INDENT 3.5 -.INDENT 0.0 -.TP -.B mypackage: -.INDENT 7.0 -.TP -.B pkg.installed: -.INDENT 7.0 -.IP \(bu 2 -provider: solarisips -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT -.UNINDENT .INDENT 0.0 .TP .B salt.modules.solarisips.available_version(name, **kwargs) The available version of the package in the repository. In case of multiple match, it returns list of all matched packages. Accepts full or partial FMRI. +Please use pkg.latest_version as pkg.available_version is being deprecated. .sp CLI Example: .INDENT 7.0 @@ -99594,7 +107066,7 @@ salt \(aq*\(aq pkg.latest_version pkg://solaris/entire .INDENT 0.0 .TP .B salt.modules.solarisips.get_fmri(name, **kwargs) -Returns FMRI from partial name. Returns \(aq\(aq if not found. +Returns FMRI from partial name. Returns empty string (\(aq\(aq) if not found. In case of multiple match, the function returns list of all matched packages. .sp CLI Example: @@ -99644,6 +107116,7 @@ CLI Example: salt \(aq*\(aq pkg.install vim salt \(aq*\(aq pkg.install pkg://solaris/editor/vim salt \(aq*\(aq pkg.install pkg://solaris/editor/vim refresh=True +salt \(aq*\(aq pkg.install pkgs=\(aq["foo", "bar"]\(aq .ft P .fi .UNINDENT @@ -99674,6 +107147,7 @@ salt \(aq*\(aq pkg.is_installed bash The available version of the package in the repository. In case of multiple match, it returns list of all matched packages. Accepts full or partial FMRI. +Please use pkg.latest_version as pkg.available_version is being deprecated. .sp CLI Example: .INDENT 7.0 @@ -99738,7 +107212,7 @@ salt \(aq*\(aq pkg.list_upgrades refresh=True .INDENT 0.0 .TP .B salt.modules.solarisips.normalize_name(name, **kwargs) -Normalizes pkg name to full FMRI before running pkg.install. +Internal function. Normalizes pkg name to full FMRI before running pkg.install. In case of multiple match or no match, it returns the name without modifications and lets the "pkg install" to decide what to do. .sp CLI Example: @@ -99838,7 +107312,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq pkg.is_installed bash +salt \(aq*\(aq pkg.search bash .ft P .fi .UNINDENT @@ -101199,7 +108673,7 @@ salt \(aq*\(aq solr.version .sp Module for interop with the Splunk API .sp -New in version 2015.5. +New in version 2015.5.0. .INDENT 0.0 .TP @@ -101752,7 +109226,12 @@ others. .UNINDENT .SS salt.modules.state .sp -Control the state system on the minion +Control the state system on the minion. +.SS State Caching +.sp +When a highstate is called, the minion automatically caches a copy of the last high data. +If you then run a highstate with cache=True it will use that cached highdata and won\(aqt hit the fileserver +except for \fBsalt://\fP links in the states themselves. .INDENT 0.0 .TP .B salt.modules.state.apply_(mods=None, **kwargs) @@ -105188,6 +112667,62 @@ salt \(aq*\(aq system.shutdown .UNINDENT .UNINDENT .UNINDENT +.SS salt.modules.system_profiler +.sp +System Profiler Module +.sp +Interface with Mac OSX\(aqs command\-line System Profiler utility to get +information about package receipts and installed applications. +.sp +New in version 2015.5.0. + +.INDENT 0.0 +.TP +.B salt.modules.system_profiler.applications() +Return the results of a call to +\fBsystem_profiler \-xml \-detail full SPApplicationsDataType\fP +as a dictionary. Top\-level keys of the dictionary +are the names of each set of install receipts, since +there can be multiple receipts with the same name. +Contents of each key are a list of dictionaries. +.sp +Note that this can take a long time depending on how many +applications are installed on the target Mac. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq systemprofiler.applications +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.system_profiler.receipts() +Return the results of a call to +\fBsystem_profiler \-xml \-detail full SPInstallHistoryDataType\fP +as a dictionary. Top\-level keys of the dictionary +are the names of each set of install receipts, since +there can be multiple receipts with the same name. +Contents of each key are a list of dictionaries. +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq systemprofiler.receipts +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.modules.systemd .sp Provide the service module for systemd @@ -106228,11 +113763,11 @@ or use Self\-Signed certificates. .B depends .INDENT 7.0 .IP \(bu 2 -PyOpenSSL Python module +PyOpenSSL Python module (0.14 or later) .UNINDENT .TP .B configuration -Add the following values in \fB/etc/salt/minion\fP for the CA module +Add the following values in /etc/salt/minion for the CA module to function properly: .INDENT 7.0 .INDENT 3.5 @@ -106245,9 +113780,127 @@ ca.cert_base_path: \(aq/etc/pki\(aq .UNINDENT .UNINDENT .UNINDENT +.sp +CLI Example #1 +Creating a CA, a server request and its signed certificate: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C + +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +# salt\-call tls.create_ca my_little days=5 CN=\(aqMy Little CA\(aq C=US ST=Utah L=Salt Lake City O=Saltstack \fI\%emailAddress=pleasedontemail@thisisnot.coms\fP +.sp +Created Private Key: "/etc/pki/my_little/my_little_ca_cert.key" +Created CA "my_little_ca": "/etc/pki/my_little_ca/my_little_ca_cert.crt" +.sp +# salt\-call tls.create_csr my_little CN=www.thisisnot.coms +Created Private Key: "/etc/pki/my_little/certs/www.thisisnot.coms.key +Created CSR for "www.thisisnot.coms": "/etc/pki/my_little/certs/www.thisisnot.coms.csr" +.sp +# salt\-call tls.create_ca_signed_cert my_little CN=www.thisisnot.coms +Created Certificate for "www.thisisnot.coms": /etc/pki/my_little/certs/www.thisisnot.coms.crt" +.UNINDENT +.UNINDENT +.sp +CLI Example #2: +Creating a client request and its signed certificate +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C + +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +# salt\-call tls.create_csr my_little CN=DBReplica_No.1 cert_type=client +Created Private Key: "/etc/pki/my_little/certs//DBReplica_No.1.key." +Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1.csr." +.sp +# salt\-call tls.create_ca_signed_cert my_little CN=DBReplica_No.1 +Created Certificate for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1.crt" +.UNINDENT +.UNINDENT +.sp +CLI Example #3: +Creating both a server and client req + cert for the same CN +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C + +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +# salt\-call tls.create_csr my_little CN=MasterDBReplica_No.2 cert_type=client +Created Private Key: "/etc/pki/my_little/certs/MasterDBReplica_No.2.key." +Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/MasterDBReplica_No.2.csr." +.sp +# salt\-call tls.create_ca_signed_cert my_little CN=MasterDBReplica_No.2 +Created Certificate for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1.crt" +.sp +# salt\-call tls.create_csr my_little CN=MasterDBReplica_No.2 cert_type=server +Certificate "MasterDBReplica_No.2" already exists +.sp +(doh!) +.sp +# salt\-call tls.create_csr my_little CN=MasterDBReplica_No.2 cert_type=server type_ext=True +Created Private Key: "/etc/pki/my_little/certs/DBReplica_No.1_client.key." +Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1_client.csr." +.sp +# salt\-call tls.create_ca_signed_cert my_little CN=MasterDBReplica_No.2 +Certificate "MasterDBReplica_No.2" already exists +.sp +(DOH!) +.sp +# salt\-call tls.create_ca_signed_cert my_little CN=MasterDBReplica_No.2 cert_type=server type_ext=True +Created Certificate for "MasterDBReplica_No.2": "/etc/pki/my_little/certs/MasterDBReplica_No.2_server.crt" +.UNINDENT +.UNINDENT +.sp +CLI Example #4: +Create a server req + cert with non\-CN filename for the cert +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C + +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +# salt\-call tls.create_csr my_little CN=www.anothersometh.ing cert_type=server type_ext=True +Created Private Key: "/etc/pki/my_little/certs/www.anothersometh.ing_server.key." +Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/www.anothersometh.ing_server.csr." +.sp +# salt\-call tls_create_ca_signed_cert my_little CN=www.anothersometh.ing cert_type=server cert_filename="something_completely_different" +Created Certificate for "www.anothersometh.ing": /etc/pki/my_little/certs/something_completely_different.crt +.UNINDENT +.UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.ca_exists(ca_name, cacert_path=None) +.B salt.modules.tls.ca_exists(ca_name, cacert_path=None, ca_filename=None) Verify whether a Certificate Authority (CA) already exists .INDENT 7.0 .TP @@ -106256,6 +113909,12 @@ name of the CA .TP .B cacert_path absolute path to ca certificates root directory +.TP +.B ca_filename +alternative filename for the CA +.sp +New in version 2015.5.3. + .UNINDENT .sp CLI Example: @@ -106274,6 +113933,11 @@ salt \(aq*\(aq tls.ca_exists test_ca /etc/certs .TP .B salt.modules.tls.cert_base_path(cacert_path=None) Return the base path for certs from CLI or from options +.INDENT 7.0 +.TP +.B cacert_path +absolute path to ca certificates root directory +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -106314,7 +113978,7 @@ salt \(aq*\(aq tls.cert_info /dir/for/certs/cert.pem .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_ca(ca_name, bits=2048, days=365, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, fixmode=False, cacert_path=None, digest=\(aqsha256\(aq) +.B salt.modules.tls.create_ca(ca_name, bits=2048, days=365, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, fixmode=False, cacert_path=None, ca_filename=None, digest=\(aqsha256\(aq, onlyif=None, unless=None, replace=False) Create a Certificate Authority (CA) .INDENT 7.0 .TP @@ -106322,39 +113986,51 @@ Create a Certificate Authority (CA) name of the CA .TP .B bits -number of RSA key bits, Default is \fB2048\fP +number of RSA key bits, default is 2048 .TP .B days -number of days the CA will be valid, Default is \fB365\fP +number of days the CA will be valid, default is 365 .TP .B CN -common name in the request, Default is \fBlocalhost\fP +common name in the request, default is "localhost" .TP .B C -country, Default is \fBUS\fP +country, default is "US" .TP .B ST -state, Default is \fBUtah\fP +state, default is "Utah" .TP .B L -locality, Default is \fBSalt Lake City\fP +locality, default is "Centerville", the city where SaltStack originated .TP .B O -organization, Default is \fBSaltStack\fP +organization, default is "SaltStack" .TP .B OU -organizational unit, Default is \fBNone\fP +organizational unit, default is None .TP .B emailAddress -email address for the CA owner, Default is \fBxyz@pdq.net\fP +email address for the CA owner, default is \fI\%\(aqxyz@pdq.net\fP\(aq .TP .B cacert_path absolute path to ca certificates root directory +.TP +.B ca_filename +alternative filename for the CA +.sp +New in version 2015.5.3. + .TP .B digest The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: \(aqsha256\(aq +.TP +.B replace +Replace this certificate even if it exists +.sp +New in version 2015.5.1. + .UNINDENT .sp Writes out a CA certificate based upon defined config values. If the file @@ -106374,7 +114050,8 @@ ca_name=\(aqkoji\(aq .UNINDENT .UNINDENT .sp -the resulting CA, and corresponding key, would be written in the following location: +the resulting CA, and corresponding key, would be written in the following +location: .INDENT 7.0 .INDENT 3.5 .sp @@ -106401,7 +114078,7 @@ salt \(aq*\(aq tls.create_ca test_ca .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_ca_signed_cert(ca_name, CN, days=365, cacert_path=None, digest=\(aqsha256\(aq, **extensions) +.B salt.modules.tls.create_ca_signed_cert(ca_name, CN, days=365, cacert_path=None, ca_filename=None, cert_path=None, cert_filename=None, digest=\(aqsha256\(aq, cert_type=None, type_ext=False, replace=False) Create a Certificate (CERT) signed by a named Certificate Authority (CA) .sp If the certificate file already exists, the function just returns assuming @@ -106418,29 +114095,69 @@ name of the CA common name matching the certificate signing request .TP .B days -number of days certificate is valid, Default is \fB365\fP (1 year) +number of days certificate is valid, default is 365 (1 year) .TP .B cacert_path absolute path to ca certificates root directory +.TP +.B ca_filename +alternative filename for the CA +.sp +New in version 2015.5.3. + +.TP +.B cert_path +full path to the certificates directory +.TP +.B cert_filename +alternative filename for the certificate, useful when using special +characters in the CN. If this option is set it will override +the certificate filename output effects of \fBcert_type\fP\&. +\fBtype_ext\fP will be completely overridden. +.sp +New in version 2015.5.3. + .TP .B digest The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: \(aqsha256\(aq .TP -.B -.nf -** -.fi -extensions -X509 V3 certificate extension +.B replace +Replace this certificate even if it exists +.sp +New in version 2015.5.1. + +.TP +.B cert_type +string. Either \(aqserver\(aq or \(aqclient\(aq (see create_csr() for details). +.sp +If create_csr(type_ext=True) this function \fBmust\fP be called with the +same cert_type so it can find the CSR file. .UNINDENT .sp -Writes out a Certificate (CERT). If the file already -exists, the function just returns assuming the CERT already exists. +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +create_csr() defaults to cert_type=\(aqserver\(aq; therefore, if it was also +called with type_ext, cert_type becomes a required argument for +create_ca_signed_cert() +.UNINDENT +.UNINDENT +.INDENT 7.0 +.TP +.B type_ext +bool. If set True, use \fBcert_type\fP as an extension to the CN when +formatting the filename. .sp -The CN \fImust\fP match an existing CSR generated by create_csr. If it -does not, this method does nothing. +e.g.: some_subject_CN_server.crt or some_subject_CN_client.crt +.sp +This facilitates the context where both types are required for the same +subject +.sp +If \fBcert_filename\fP is \fInot None\fP, setting \fBtype_ext\fP has no +effect +.UNINDENT .sp If the following values were set: .INDENT 7.0 @@ -106456,8 +114173,8 @@ CN=\(aqtest.egavas.org\(aq .UNINDENT .UNINDENT .sp -the resulting signed certificate would be written in the -following location: +the resulting signed certificate would be written in the following +location: .INDENT 7.0 .INDENT 3.5 .sp @@ -106483,7 +114200,7 @@ salt \(aq*\(aq tls.create_ca_signed_cert test localhost .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_csr(ca_name, bits=2048, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, subjectAltName=None, cacert_path=None, digest=\(aqsha256\(aq) +.B salt.modules.tls.create_csr(ca_name, bits=2048, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, subjectAltName=None, cacert_path=None, ca_filename=None, csr_path=None, csr_filename=None, digest=\(aqsha256\(aq, type_ext=False, cert_type=\(aqserver\(aq, replace=False) Create a Certificate Signing Request (CSR) for a particular Certificate Authority (CA) .INDENT 7.0 @@ -106492,40 +114209,103 @@ particular Certificate Authority (CA) name of the CA .TP .B bits -number of RSA key bits, Default is \fB2048\fP +number of RSA key bits, default is 2048 .TP .B CN -common name in the request, Default is \fBlocalhost\fP +common name in the request, default is "localhost" .TP .B C -country, Default is \fBUS\fP +country, default is "US" .TP .B ST -state, Default is \fBUtah\fP +state, default is "Utah" .TP .B L -locality, Default is \fBSalt Lake City\fP +locality, default is "Centerville", the city where SaltStack originated .TP .B O -organization. Must the same as CA certificate or an error will be raised, Default is \fBSaltStack\fP +organization, default is "SaltStack" +NOTE: Must the same as CA certificate or an error will be raised .TP .B OU -organizational unit, Default is \fBNone\fP +organizational unit, default is None .TP .B emailAddress -email address for the request, Default is \fBxyz@pdq.net\fP +email address for the request, default is \fI\%\(aqxyz@pdq.net\fP\(aq .TP .B subjectAltName valid subjectAltNames in full form, e.g. to add DNS entry you would call -this function with this value: \fB[\(aqDNS:myapp.foo.comm\(aq]\fP +this function with this value: +.INDENT 7.0 .TP -.B cacert_path -absolute path to ca certificates root directory +.B examples: [\(aq\fI\%DNS:somednsname.com\fP\(aq, +\(aq\fI\%DNS:1.2.3.4\fP\(aq, +\(aqIP:1.2.3.4\(aq, +\(aqIP:2001:4801:7821:77:be76:4eff:fe11:e51\(aq, +\(aqemail:me@i.like.pie.com\(aq] +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 7.0 +.INDENT 3.5 +some libraries do not properly query IP: prefixes, instead looking +for the given req. source with a DNS: prefix. To be thorough, you +may want to include both DNS: and IP: entries if you are using +subjectAltNames for destinations for your TLS connections. +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 .TP -.B digest -The message digest algorithm. Must be a string describing a digest -algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). -For example, "md5" or "sha1". Default: \(aqsha256\(aq +.B e.g.: +requests to \fI\%https://1.2.3.4\fP will fail from python\(aqs +requests library w/out the second entry in the above list +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.sp +New in version Beryllium. + +.INDENT 7.0 +.TP +.B cert_type +Specify the general certificate type. Can be either \fIserver\fP or +\fIclient\fP\&. Indicates the set of common extensions added to the CSR. +.INDENT 7.0 +.TP +.B server: { +\(aqbasicConstraints\(aq: \(aqCA:FALSE\(aq, +\(aqextendedKeyUsage\(aq: \(aqserverAuth\(aq, +\(aqkeyUsage\(aq: \(aqdigitalSignature, keyEncipherment\(aq +.UNINDENT +.sp +} +.INDENT 7.0 +.TP +.B client: { +\(aqbasicConstraints\(aq: \(aqCA:FALSE\(aq, +\(aqextendedKeyUsage\(aq: \(aqclientAuth\(aq, +\(aqkeyUsage\(aq: \(aqnonRepudiation, digitalSignature, keyEncipherment\(aq +.UNINDENT +.sp +} +.TP +.B type_ext +boolean. Whether or not to extend the filename with CN_[cert_type] +This can be useful if a server and client certificate are needed for +the same CN. Defaults to False to avoid introducing an unexpected file +naming pattern +.sp +The files normally named some_subject_CN.csr and some_subject_CN.key +will then be saved +.TP +.B replace +Replace this signing request even if it exists +.sp +New in version 2015.5.1. + .UNINDENT .sp Writes out a Certificate Signing Request (CSR) If the file already @@ -106573,7 +114353,44 @@ salt \(aq*\(aq tls.create_csr test .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_pkcs12(ca_name, CN, passphrase=\(aq\(aq, cacert_path=None) +.B salt.modules.tls.create_empty_crl(ca_name, cacert_path=None, ca_filename=None, crl_file=None) +Create an empty Certificate Revocation List. +.sp +New in version Beryllium. + +.INDENT 7.0 +.TP +.B ca_name +name of the CA +.TP +.B cacert_path +absolute path to ca certificates root directory +.TP +.B ca_filename +alternative filename for the CA +.sp +New in version 2015.5.3. + +.TP +.B crl_file +full path to the CRL file +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq tls.create_empty_crl ca_name=\(aqkoji\(aq ca_filename=\(aqca\(aq crl_file=\(aq/etc/openvpn/team1/crl.pem\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.tls.create_pkcs12(ca_name, CN, passphrase=\(aq\(aq, cacert_path=None, replace=False) Create a PKCS#12 browser certificate for a particular Certificate (CN) .INDENT 7.0 .TP @@ -106588,6 +114405,12 @@ used to unlock the PKCS#12 certificate when loaded into the browser .TP .B cacert_path absolute path to ca certificates root directory +.TP +.B replace +Replace this certificate even if it exists +.sp +New in version 2015.5.1. + .UNINDENT .sp If the following values were set: @@ -106631,39 +114454,37 @@ salt \(aq*\(aq tls.create_pkcs12 test localhost .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.create_self_signed_cert(tls_dir=\(aqtls\(aq, bits=2048, days=365, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, cacert_path=None, digest=\(aqsha256\(aq) +.B salt.modules.tls.create_self_signed_cert(tls_dir=\(aqtls\(aq, bits=2048, days=365, CN=\(aqlocalhost\(aq, C=\(aqUS\(aq, ST=\(aqUtah\(aq, L=\(aqSalt Lake City\(aq, O=\(aqSaltStack\(aq, OU=None, emailAddress=\(aqxyz@pdq.net\(aq, cacert_path=None, cert_filename=None, digest=\(aqsha256\(aq, replace=False) Create a Self\-Signed Certificate (CERT) .INDENT 7.0 .TP .B tls_dir -location appended to the ca.cert_base_path, Default is \fBtls\fP +location appended to the ca.cert_base_path, default is \(aqtls\(aq .TP .B bits -number of RSA key bits, Default is \fB2048\fP -.TP -.B days -validity of certificate, Default is \fB365\fP +number of RSA key bits, default is 2048 .TP .B CN -common name in the request, Default is \fBlocalhost\fP +common name in the request, default is "localhost" .TP .B C -country, Default is \fBUS\fP +country, default is "US" .TP .B ST -state, Default is \fBUtah\fP +state, default is "Utah" .TP .B L -locality, Default is \fBSalt Lake City\fP +locality, default is "Centerville", the city where SaltStack originated .TP .B O -organization. Must the same as CA certificate or an error will be raised, Default is \fBSaltStack\fP +organization, default is "SaltStack" +NOTE: Must the same as CA certificate or an error will be raised .TP .B OU -organizational unit, Default is \fBNone\fP +organizational unit, default is None .TP .B emailAddress -email address for the request, Default is \fBxyz@pdq.net\fP +email address for the request, default is \fI\%\(aqxyz@pdq.net\fP\(aq .TP .B cacert_path absolute path to ca certificates root directory @@ -106672,6 +114493,12 @@ absolute path to ca certificates root directory The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: \(aqsha256\(aq +.TP +.B replace +Replace this certificate even if it exists +.sp +New in version 2015.5.1. + .UNINDENT .sp Writes out a Self\-Signed Certificate (CERT). If the file already @@ -106705,13 +114532,24 @@ following location: .UNINDENT .UNINDENT .sp -CLI Examples: +CLI Example: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C salt \(aq*\(aq tls.create_self_signed_cert +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Passing options from the command line: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C salt \(aqminion\(aq tls.create_self_signed_cert CN=\(aqtest.mysite.org\(aq .ft P .fi @@ -106748,7 +114586,109 @@ salt \(aq*\(aq tls.get_ca test_ca as_text=False cacert_path=/etc/certs .UNINDENT .INDENT 0.0 .TP -.B salt.modules.tls.maybe_fix_ssl_version(ca_name, cacert_path=None) +.B salt.modules.tls.get_ca_signed_cert(ca_name, CN=\(aqlocalhost\(aq, as_text=False, cacert_path=None, cert_filename=None) +Get the certificate path or content +.INDENT 7.0 +.TP +.B ca_name +name of the CA +.TP +.B CN +common name of the certificate +.TP +.B as_text +if true, return the certificate content instead of the path +.TP +.B cacert_path +absolute path to certificates root directory +.TP +.B cert_filename +alternative filename for the certificate, useful when using special characters in the CN +.sp +New in version 2015.5.3. + +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq tls.get_ca_signed_cert test_ca CN=localhost as_text=False cacert_path=/etc/certs +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.tls.get_ca_signed_key(ca_name, CN=\(aqlocalhost\(aq, as_text=False, cacert_path=None, key_filename=None) +Get the certificate path or content +.INDENT 7.0 +.TP +.B ca_name +name of the CA +.TP +.B CN +common name of the certificate +.TP +.B as_text +if true, return the certificate content instead of the path +.TP +.B cacert_path +absolute path to certificates root directory +.TP +.B key_filename +alternative filename for the key, useful when using special characters +.sp +New in version 2015.5.3. + +.sp +in the CN +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq tls.get_ca_signed_key test_ca CN=localhost as_text=False cacert_path=/etc/certs +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.tls.get_extensions(cert_type) +Fetch X509 and CSR extension definitions from tls:extensions: +(common|server|client) or set them to standard defaults. +.sp +New in version Beryllium. + +.INDENT 7.0 +.TP +.B cert_type: +The type of certificate such as \fBserver\fP or \fBclient\fP\&. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq tls.get_extensions client +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.modules.tls.maybe_fix_ssl_version(ca_name, cacert_path=None, ca_filename=None) Check that the X509 version is correct (was incorrectly set in previous salt versions). This will fix the version if needed. @@ -106759,6 +114699,12 @@ ca authority name .TP .B cacert_path absolute path to ca certificates root directory +.TP +.B ca_filename +alternative filename for the CA +.sp +New in version 2015.5.3. + .UNINDENT .sp CLI Example: @@ -106775,6 +114721,50 @@ salt \(aq*\(aq tls.maybe_fix_ssl_version test_ca /etc/certs .UNINDENT .INDENT 0.0 .TP +.B salt.modules.tls.revoke_cert(ca_name, CN, cacert_path=None, ca_filename=None, cert_path=None, cert_filename=None, crl_file=None) +Revoke a certificate. +.sp +New in version Beryllium. + +.INDENT 7.0 +.TP +.B ca_name +Name of the CA. +.TP +.B CN +Common name matching the certificate signing request. +.TP +.B cacert_path +Absolute path to ca certificates root directory. +.TP +.B ca_filename +Alternative filename for the CA. +.TP +.B cert_path +Path to the cert file. +.TP +.B cert_filename +Alternative filename for the certificate, useful when using special +characters in the CN. +.TP +.B crl_file +Full path to the CRL file. +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq tls.revoke_cert ca_name=\(aqkoji\(aq ca_filename=\(aqca\(aq crl_file=\(aq/etc/openvpn/team1/crl.pem\(aq +.ft P +.fi +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP .B salt.modules.tls.set_ca_path(cacert_path) If wanted, store the aforementioned cacert_path in context to be used as the basepath for further operations @@ -110355,13 +118345,6 @@ salt \(aq*\(aq group.info foo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_groupadd.list_groups(useldap=False) -Return a list of groups on Windows -.sp -set \(aquseldap\(aq to True to connect to the local LDAP server -.UNINDENT -.INDENT 0.0 -.TP .B salt.modules.win_groupadd.members(name, members_list) remove a user from a group .sp @@ -110372,10 +118355,6 @@ CLI Example: .nf .ft C salt \(aq*\(aq group.members foo \(aquser1,user2,user3\(aq - -if using LDAP DNs, usernames must be seperated with a ", " - -salt \(aq*\(aq group.members name=\(aqcn=foo,dc=domain,dc=com\(aq members_list=\(aqcn=user1,cn=Users,dc=domain,dc=com, cn=user2,ou=Test,dc=domain,dc=com\(aq .ft P .fi .UNINDENT @@ -110963,6 +118942,11 @@ Only the ones that listen to the WM_SETTINGCHANGE message .TP .B salt.modules.win_path.add(path, index=0) Add the directory to the SYSTEM path in the index location +.INDENT 7.0 +.TP +.B Returns: +boolean True if successful, False if unsuccessful +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -110985,6 +118969,11 @@ salt \(aq*\(aq win_path.add \(aqc:\epython27\(aq index=\(aq\-1\(aq .B salt.modules.win_path.exists(path) Check if the directory is configured in the SYSTEM path Case\-insensitive and ignores trailing backslash +.INDENT 7.0 +.TP +.B Returns: +boolean True if path exists, False if not +.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -111003,17 +118992,56 @@ salt \(aq*\(aq win_path.exists \(aqC:\epyThon27\(aq .INDENT 0.0 .TP .B salt.modules.win_path.get_path() -Returns the system path +Returns a list of items in the SYSTEM path +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq win_path.get_path +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.modules.win_path.rehash() -Send a WM_SETTINGCHANGE Broadcast to Windows to rehash the Environment variables +Send a WM_SETTINGCHANGE Broadcast to Windows to refresh the Environment variables +.sp +CLI Example: +.sp +\&... code\-block:: bash +.INDENT 7.0 +.INDENT 3.5 +salt \(aq*\(aq win_path.rehash +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP .B salt.modules.win_path.remove(path) Remove the directory from the SYSTEM path +.INDENT 7.0 +.TP +.B Returns: +boolean True if successful, False if unsuccessful +.UNINDENT +.sp +CLI Example: +.INDENT 7.0 +.INDENT 3.5 +.sp +.nf +.ft C +# Will remove C:\ePython27 from the path +salt \(aq*\(aq win_path.remove \(aqc:\e\epython27\(aq +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .SS salt.modules.win_pkg .sp @@ -112623,13 +120651,12 @@ salt \(aq*\(aq win_update.list_updates categories=[\(aqCritical Updates\(aq] ver .UNINDENT .SS salt.modules.win_useradd .sp -Manage Windows users with ADSI +Manage Windows users with the net user command .sp -Can manage local user accounts or domain accounts (if salt\-minion is running as a user w/access -to AD (or localsystem on a DC), AD accounts should be managed as LDAP objects... +NOTE: This currently only works with local user accounts, not domain accounts .INDENT 0.0 .TP -.B salt.modules.win_useradd.add(name, password=None, fullname=False, description=False, firstname=False, lastname=False, middleinitial=False, disabled=False, requirepwchange=True, pwneverexpires=False, uid=None, gid=None, groups=None, home=False, shell=None, unique=False, system=False, roomnumber=False, workphone=False, homephone=False, loginclass=False, createhome=False) +.B salt.modules.win_useradd.add(name, password=None, uid=None, gid=None, groups=None, home=False, shell=None, unique=False, system=False, fullname=False, roomnumber=False, workphone=False, homephone=False, loginclass=False, createhome=False) Add a user to the minion .sp CLI Example: @@ -112639,13 +120666,6 @@ CLI Example: .nf .ft C salt \(aq*\(aq user.add name password - -if you want to create on a domain controller, you should use the LDAP DN of the object to create -short name will work, but UPN will not get set - -you must use name=\(aqcn=user,....\(aq since the DN contains \(aq=\(aq - -salt \(aqdomainController\(aq user.add name=\(aqcn=user,cn=Users,dc=domain,dc=dom\(aq password=\(aqpa$$word\(aq .ft P .fi .UNINDENT @@ -112698,8 +120718,6 @@ CLI Example: .nf .ft C salt \(aq*\(aq user.chgroups foo wheel,root True - -if using DNs, group names must be separated with \(aq, \(aq .ft P .fi .UNINDENT @@ -112707,8 +120725,9 @@ if using DNs, group names must be separated with \(aq, \(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_useradd.chhome(name, home) -Change the home directory of the user +.B salt.modules.win_useradd.chhome(name, home, persist=False) +Change the home directory of the user, pass True for persist to move files +to the new home directory if the old home directory exist. .sp CLI Example: .INDENT 7.0 @@ -112716,7 +120735,7 @@ CLI Example: .sp .nf .ft C -salt \(aq*\(aq user.chhome foo \e\efileserver\ehome\efoo +salt \(aq*\(aq user.chhome foo \e\efileserver\ehome\efoo True .ft P .fi .UNINDENT @@ -112759,24 +120778,6 @@ salt \(aq*\(aq user.delete name .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_useradd.disable(name, disabled=True) -disable a user account -.sp -salt \(aq*\(aq disableuser foo -.sp -to enable a user: -.sp -salt \(aq*\(aq disableuser foot False -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.win_useradd.enable(name) -enable a user account -.sp -salt \(aq*\(aq user.enable foo -.UNINDENT -.INDENT 0.0 -.TP .B salt.modules.win_useradd.getent(refresh=False) Return the list of all info for all users .sp @@ -112828,22 +120829,11 @@ salt \(aq*\(aq user.list_groups foo .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_useradd.list_users(useldap=False) +.B salt.modules.win_useradd.list_users() Return a list of users on Windows .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_useradd.passwordneverexpires(name, clear=False) -set a user\(aqs password to never expire -.sp -salt \(aq*\(aq user.passwordneverexpires foo -.sp -to clear the password never expires setting (i.e. set it to expire), use clear=True -.sp -salt \(aq*\(aq user.passwordneverexpires foo True -.UNINDENT -.INDENT 0.0 -.TP .B salt.modules.win_useradd.removegroup(name, group) Remove user from a group .sp @@ -112871,9 +120861,6 @@ CLI Example: .nf .ft C salt \(aq*\(aq user.rename name new_name - -domain users should use LDAP, to rename the cn, sAMAccountName, and UPN -salt \(aqdomainController\(aq user.rename name=\(aqcn=user,cn=Users,dc=domain,dc=dom\(aq new_name=\(aqnewUserName\(aq .ft P .fi .UNINDENT @@ -112881,25 +120868,8 @@ salt \(aqdomainController\(aq user.rename name=\(aqcn=user,cn=Users,dc=domain,dc .UNINDENT .INDENT 0.0 .TP -.B salt.modules.win_useradd.requirepasswordchange(name, clear=False) -expire a user\(aqs password (i.e. require it to change on next logon) -if the password is set to "never expire" this has no effect -.sp -salt \(aq*\(aq user.requirepasswordchange foo -.sp -to clear the require password change flag, use clear=True -.sp -salt \(aq*\(aq user.requirepasswordchange foo True -.UNINDENT -.INDENT 0.0 -.TP -.B salt.modules.win_useradd.setpassword(name, password, mustchange=None, neverexpires=None) +.B salt.modules.win_useradd.setpassword(name, password) Set a user\(aqs password -.INDENT 7.0 -.TP -.B use \(aqmustchange\(aq and \(aqneverexpires\(aq to set those user account attributes, by default they will be left alone (None) -setting to \(aqFalse\(aq will clear them, setting to \(aqTrue\(aq will set them -.UNINDENT .sp CLI Example: .INDENT 7.0 @@ -114162,7 +122132,7 @@ Hold packages with \fByum \-q versionlock\fP\&. .INDENT 7.0 .TP .B name -The name of the package to be deleted. +The name of the package to be held. .UNINDENT .sp Multiple Package Options: @@ -114695,7 +122665,7 @@ salt \(aq*\(aq pkg.purge pkgs=\(aq["foo", "bar"]\(aq .UNINDENT .INDENT 0.0 .TP -.B salt.modules.yumpkg.refresh_db(branch_arg, repo_arg, exclude_arg) +.B salt.modules.yumpkg.refresh_db(branch_arg=None, repo_arg=None, exclude_arg=None, branch=None, repo=None, exclude=None) Check the yum repos for updated packages .sp Returns: @@ -116298,7 +124268,7 @@ be created, so long as the following values are specified: .B repo or alias alias by which the zypper refers to the repo .TP -.B url or mirrorlist +.B url, mirrorlist or baseurl the URL for zypper to reference .TP .B enabled @@ -116651,11 +124621,10 @@ New in version 2014.7.0. .INDENT 7.0 .IP \(bu 2 CherryPy Python module. Versions 3.2.{2,3,4} are strongly -.UNINDENT -.sp recommended due to a known \fI\%SSL error\fP introduced in version 3.2.5. The issue was reportedly resolved with CherryPy milestone 3.3, but the patch was committed for version 3.6.1. +.UNINDENT .TP .B optdepends .INDENT 7.0 @@ -116663,8 +124632,16 @@ CherryPy milestone 3.3, but the patch was committed for version 3.6.1. ws4py Python module for websockets support. .UNINDENT .TP +.B client_libraries +.INDENT 7.0 +.IP \(bu 2 +Java: \fI\%https://github.com/SUSE/saltstack\-netapi\-client\-java\fP +.IP \(bu 2 +Python: \fI\%https://github.com/saltstack/pepper\fP +.UNINDENT +.TP .B configuration -All authentication is done through Salt\(aqs external auth system which requires additional configuration not described +All authentication is done through Salt\(aqs \fIexternal auth\fP system which requires additional configuration not described here. .sp Example production\-ready configuration; add to the Salt master config file @@ -116881,7 +124858,7 @@ corresponds to the return for each command in the response. .sp Lowstate, broadly, is a dictionary of values that are mapped to a function call. This pattern is used pervasively throughout Salt. The functions called -from netapi modules are described in Client Interfaces\&. +from netapi modules are described in \fIClient Interfaces\fP\&. .sp The following example (in JSON format) causes Salt to execute two commands, a command sent to minions as well as a runner function on the master: @@ -117376,7 +125353,7 @@ Start an execution command and immediately return the job id .UNINDENT .UNINDENT .sp -lowstate data describing Salt commands must be sent in the +\fIlowstate\fP data describing Salt commands must be sent in the request body. The \fBclient\fP option will be set to \fBlocal_async()\fP\&. .UNINDENT @@ -117582,7 +125559,7 @@ This entry point is primarily for "one\-off" commands. Each request must pass full Salt authentication credentials. Otherwise this URL is identical to the \fI\%root URL (/)\fP\&. .sp -lowstate data describing Salt commands must be sent in the +\fIlowstate\fP data describing Salt commands must be sent in the request body. .INDENT 7.0 .TP @@ -117730,7 +125707,7 @@ Salt infrastructure. \fBSEE ALSO:\fP .INDENT 7.0 .INDENT 3.5 -events +\fIevents\fP .UNINDENT .UNINDENT .INDENT 7.0 @@ -117954,7 +125931,7 @@ after_success: \fBSEE ALSO:\fP .INDENT 7.0 .INDENT 3.5 -events, reactor +\fIevents\fP, \fIreactor\fP .UNINDENT .UNINDENT .INDENT 7.0 @@ -118325,7 +126302,7 @@ Salt infrastructure. Uses websocket as the transport mechanism. \fBSEE ALSO:\fP .INDENT 7.0 .INDENT 3.5 -events +\fIevents\fP .UNINDENT .UNINDENT .INDENT 7.0 @@ -118537,7 +126514,7 @@ tornado Python module .UNINDENT .TP .B configuration -All authentication is done through Salt\(aqs external auth system which requires additional configuration not described +All authentication is done through Salt\(aqs \fIexternal auth\fP system which requires additional configuration not described here. .UNINDENT .sp @@ -118618,7 +126595,7 @@ authentication credentials, what returner to use, etc. .sp Salt uses the lowstate data format internally in many places to pass command data between functions. Salt also uses lowstate for the -LocalClient() Python API interface. +\fILocalClient()\fP Python API interface. .UNINDENT .sp The following example (in JSON format) causes Salt to execute two commands: @@ -119087,43 +127064,43 @@ data: { .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.SaltAPIHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS \fB/login\fP .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.SaltAuthHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS \fB/minions\fP .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.MinionSaltAPIHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS \fB/jobs\fP .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.JobsSaltAPIHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS \fB/run\fP .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.RunSaltAPIHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS \fB/events\fP .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.EventsSaltAPIHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS \fB/hook\fP .INDENT 0.0 .TP .B salt.netapi.rest_tornado.saltnado.WebhookSaltAPIHandler -alias of \fB\fP +alias of \fB\fP .UNINDENT .SS rest_wsgi .SS A minimalist REST API for Salt @@ -119134,7 +127111,7 @@ commands to the Salt master. There are no dependencies. Extra care must be taken when deploying this module into production. Please read this documentation in entirety. .sp -All authentication is done through Salt\(aqs external auth +All authentication is done through Salt\(aqs \fIexternal auth\fP system. .SS Usage .INDENT 0.0 @@ -119290,8 +127267,8 @@ Content\-Type: application/json .INDENT 0.0 .TP .B form lowstate -A list of lowstate data appropriate for the -client interface you are calling. +A list of \fIlowstate\fP data appropriate for the +\fIclient\fP interface you are calling. .TP .B status 200 success @@ -119401,12 +127378,7 @@ _ .SS Display compact output data structure .sp Example output:: -\(aqsaltdev\(aq: {\(aqtest_|\-always\-passes_|\-foo_|\-succeed_without_changes\(aq: {\(aqcomment\(aq: \(aqSuccess!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.111814\(aq, \(aqresult\(aq: True, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 0, \(aqchanges\(aq: {}}, \(aqtest_|\-my\-custom\-combo_|\-foo_|\-configurable_test_state\(aq: {\(aqcomment\(aq: \(aqbar.baz\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.117177\(aq, \(aqresult\(aq: False, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 4, \(aqchanges\(aq: {\(aqtesting\(aq: {\(aqnew\(aq: \(aqSomething pretended to change\(aq, \(aqold\(aq: \(aqUnchanged\(aq}}}, \(aqtest_|\-always\-fails_|\-foo_|\-fail_without_changes\(aq: {\(aqcomment\(aq: \(aqFailure!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.113124\(aq, \(aqresult\(aq: False, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 1, \(aqchanges\(aq: {}}, \(aqtest_|\-always\-changes\-and\-succeeds_|\-foo_|\-succeed_with_changes\(aq: {\(aqcomment\(aq: \(aqSuccess!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.114570\(aq, \(aqresult\(aq: True, \(aqduration\(aq: 0, \(aq__run_num__\(aq: 2, \(aqchanges\(aq: {\(aqtesting\(aq: {\(aqnew\(aq: \(aqSomething pretended to change\(aq, \(aqold\(aq: \(aqUnchanged\(aq}}}, \(aqtest_|\-always\-changes\-and\-fails_|\-foo_|\-fail_with_changes\(aq: {\(aqcomment\(aq: \(aqFailure!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.115561\(aq, \(aqresult\(aq: False, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 3, \(aqchanges\(aq: {\(aqtesting\(aq: {\(aqnew\(aq: \(aqSomething pretended to change\(aq, \(aqold\(aq: \(aqUnchanged\(aq}}}}} -.INDENT 0.0 -.INDENT 3.5 -{\(aqmyminion\(aq: {\(aqfoo\(aq: {\(aqlist\(aq: [\(aqHello\(aq, \(aqWorld\(aq], \(aqbar\(aq: \(aqbaz\(aq, \(aqdictionary\(aq: {\(aqabc\(aq: 123, \(aqdef\(aq: 456}}}} -.UNINDENT -.UNINDENT +\(aqsaltdev\(aq: {\(aqtest_|\-always\-passes_|\-foo_|\-succeed_without_changes\(aq: {\(aqcomment\(aq: \(aqSuccess!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.111814\(aq, \(aqresult\(aq: True, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 0, \(aqchanges\(aq: {}}, \(aqtest_|\-my\-custom\-combo_|\-foo_|\-configurable_test_state\(aq: {\(aqcomment\(aq: \(aqbar.baz\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.117177\(aq, \(aqresult\(aq: False, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 4, \(aqchanges\(aq: {\(aqtesting\(aq: {\(aqnew\(aq: \(aqSomething pretended to change\(aq, \(aqold\(aq: \(aqUnchanged\(aq}}}, \(aqtest_|\-always\-fails_|\-foo_|\-fail_without_changes\(aq: {\(aqcomment\(aq: \(aqFailure!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.113124\(aq, \(aqresult\(aq: False, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 1, \(aqchanges\(aq: {}}, \(aqtest_|\-always\-changes\-and\-succeeds_|\-foo_|\-succeed_with_changes\(aq: {\(aqcomment\(aq: \(aqSuccess!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.114570\(aq, \(aqresult\(aq: True, \(aqduration\(aq: 0, \(aq__run_num__\(aq: 2, \(aqchanges\(aq: {\(aqtesting\(aq: {\(aqnew\(aq: \(aqSomething pretended to change\(aq, \(aqold\(aq: \(aqUnchanged\(aq}}}, \(aqtest_|\-always\-changes\-and\-fails_|\-foo_|\-fail_with_changes\(aq: {\(aqcomment\(aq: \(aqFailure!\(aq, \(aqname\(aq: \(aqfoo\(aq, \(aqstart_time\(aq: \(aq05:16:26.115561\(aq, \(aqresult\(aq: False, \(aqduration\(aq: 1, \(aq__run_num__\(aq: 3, \(aqchanges\(aq: {\(aqtesting\(aq: {\(aqnew\(aq: \(aqSomething pretended to change\(aq, \(aqold\(aq: \(aqUnchanged\(aq}}}}}{\(aqmyminion\(aq: {\(aqfoo\(aq: {\(aqlist\(aq: [\(aqHello\(aq, \(aqWorld\(aq], \(aqbar\(aq: \(aqbaz\(aq, \(aqdictionary\(aq: {\(aqabc\(aq: 123, \(aqdef\(aq: 456}}}} .INDENT 0.0 .TP .B salt.output.compact.output(data) @@ -119738,7 +127710,7 @@ Display ret data .SS salt.output.overstatestage .SS Display clean output of an overstate stage .sp -This outputter is used to display OverState stages, +This outputter is used to display \fIOverState\fP stages, and should not be called directly. .INDENT 0.0 .TP @@ -120018,10 +127990,10 @@ To match minions using other matchers, use \fBexpr_form\fP: .SS Pillars .sp Salt includes a number of built\-in external pillars, listed at -all\-salt.pillars\&. +\fIall\-salt.pillars\fP\&. .sp You may also wish to look at the standard pillar documentation, at -pillar\-configuration +\fIpillar\-configuration\fP .sp The source for the built\-in Salt pillars can be found here: \fI\%https://github.com/saltstack/salt/blob/develop/salt/pillar\fP @@ -120073,11 +128045,6 @@ Use etcd data as a Pillar source T} _ T{ -\fBfile_encode\fP -T} T{ -T} -_ -T{ \fBfile_tree\fP T} T{ Recursively iterate over directories and add all files as Pillar data. @@ -120164,7 +128131,7 @@ _ T{ \fBvarstack_pillar\fP T} T{ -Use varstack data as a Pillar source +Use \fI\%Varstack\fP data as a Pillar source T} _ T{ @@ -120797,13 +128764,13 @@ the \fBext_pillar:\fP configuration would be like: .nf .ft C ext_pillar: - \- git: _ git://gitserver/git\-pillar.git root=pillar + \- git: __env__ git://gitserver/git\-pillar.git root=pillar .ft P .fi .UNINDENT .UNINDENT .sp -The (optinal) root=pillar defines the directory that contains the pillar data. +The (optional) root=pillar defines the directory that contains the pillar data. The corresponding \fBtop.sls\fP would be like: .INDENT 0.0 .INDENT 3.5 @@ -121972,7 +129939,27 @@ Execute a command and read the output as YAML .UNINDENT .SS salt.pillar.varstack_pillar .sp -Use varstack data as a Pillar source +Use \fI\%Varstack\fP data as a Pillar source +.SS Configuring Varstack +.sp +Using varstack in Salt is fairly simple. Just put the following into the +config file of your master: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ext_pillar: + \- varstack: /etc/varstack.yaml +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Varstack will then use /etc/varstack.yaml to determine which configuration +data to return as pillar information. From there you can take a look at the +\fI\%README\fP of +varstack on how this file is evaluated. .INDENT 0.0 .TP .B salt.pillar.varstack_pillar.ext_pillar(minion_id, pillar, conf) @@ -122696,7 +130683,7 @@ following tags: \fImacro\fP, \fIset\fP, \fIload_yaml\fP, \fIload_json\fP, \fIimp .SS Calling Salt Functions .sp The Jinja renderer provides a shorthand lookup syntax for the \fBsalt\fP -dictionary of execution function\&. +dictionary of \fIexecution function\fP\&. .sp New in version 2014.7.0. @@ -122994,12 +130981,12 @@ In this module, a few objects are defined for you, giving access to Salt\(aqs execution functions, grains, pillar, etc. They are: .INDENT 0.0 .IP \(bu 2 -\fB__salt__\fP \- Execution functions (i.e. +\fB__salt__\fP \- \fIExecution functions\fP (i.e. \fB__salt__[\(aqtest.echo\(aq](\(aqfoo\(aq)\fP) .IP \(bu 2 -\fB__grains__\fP \- Grains (i.e. \fB__grains__[\(aqos\(aq]\fP) +\fB__grains__\fP \- \fIGrains\fP (i.e. \fB__grains__[\(aqos\(aq]\fP) .IP \(bu 2 -\fB__pillar__\fP \- Pillar data (i.e. \fB__pillar__[\(aqfoo\(aq]\fP) +\fB__pillar__\fP \- \fIPillar data\fP (i.e. \fB__pillar__[\(aqfoo\(aq]\fP) .IP \(bu 2 \fB__opts__\fP \- Minion configuration options .IP \(bu 2 @@ -123137,27 +131124,27 @@ Salt PyDSL object, useful for configuring DSL behavior per sls rendering. \fBinclude\fP .INDENT 0.0 .INDENT 3.5 -Salt PyDSL function for creating include\-declaration\(aqs. +Salt PyDSL function for creating \fIinclude\-declaration\fP\(aqs. .UNINDENT .UNINDENT .sp \fBextend\fP .INDENT 0.0 .INDENT 3.5 -Salt PyDSL function for creating extend\-declaration\(aqs. +Salt PyDSL function for creating \fIextend\-declaration\fP\(aqs. .UNINDENT .UNINDENT .sp \fBstate\fP .INDENT 0.0 .INDENT 3.5 -Salt PyDSL function for creating ID\-declaration\(aqs. +Salt PyDSL function for creating \fIID\-declaration\fP\(aqs. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp -A state ID\-declaration is created with a \fBstate(id)\fP function call. +A state \fIID\-declaration\fP is created with a \fBstate(id)\fP function call. Subsequent \fBstate(id)\fP call with the same id returns the same object. This singleton access pattern applies to all declaration objects created with the DSL. @@ -123179,7 +131166,7 @@ The \fIid\fP argument is optional. If omitted, an UUID will be generated and use the \fIid\fP\&. .sp \fBstate(id)\fP returns an object under which you can create a -state\-declaration object by accessing an attribute named after \fIany\fP +\fIstate\-declaration\fP object by accessing an attribute named after \fIany\fP state module available in Salt. .INDENT 0.0 .INDENT 3.5 @@ -123195,11 +131182,11 @@ state(\(aqexample\(aq).pkg .UNINDENT .UNINDENT .sp -Then, a function\-declaration object can be created from a -state\-declaration object by one of the following two ways: +Then, a \fIfunction\-declaration\fP object can be created from a +\fIstate\-declaration\fP object by one of the following two ways: .INDENT 0.0 .IP 1. 3 -by calling a method named after the state function on the state\-declaration object. +by calling a method named after the state function on the \fIstate\-declaration\fP object. .UNINDENT .INDENT 0.0 .INDENT 3.5 @@ -123213,7 +131200,7 @@ state(\(aqexample\(aq).file.managed(...) .UNINDENT .INDENT 0.0 .IP 2. 3 -by directly calling the attribute named for the state\-declaration, and +by directly calling the attribute named for the \fIstate\-declaration\fP, and supplying the state function name as the first argument. .UNINDENT .INDENT 0.0 @@ -123227,9 +131214,9 @@ state(\(aqexample\(aq).file(\(aqmanaged\(aq, ...) .UNINDENT .UNINDENT .sp -With either way of creating a function\-declaration object, any -function\-arg\-declaration\(aqs can be passed as keyword arguments to the -call. Subsequent calls of a function\-declaration will update the arg +With either way of creating a \fIfunction\-declaration\fP object, any +\fIfunction\-arg\-declaration\fP\(aqs can be passed as keyword arguments to the +call. Subsequent calls of a \fIfunction\-declaration\fP will update the arg declarations. .INDENT 0.0 .INDENT 3.5 @@ -123245,7 +131232,7 @@ state(\(aqexample\(aq).file.managed(source=\(aqsalt://webserver/index.html\(aq) .sp As a shortcut, the special \fIname\fP argument can also be passed as the first or second positional argument depending on the first or second -way of calling the state\-declaration object. In the following +way of calling the \fIstate\-declaration\fP object. In the following two examples \fIls \-la\fP is the \fIname\fP argument. .INDENT 0.0 .INDENT 3.5 @@ -123259,16 +131246,16 @@ state(\(aqexample\(aq).cmd(\(aqrun\(aq, \(aqls \-la\(aq, cwd=\(aq/\(aq) .UNINDENT .UNINDENT .sp -Finally, a requisite\-declaration object with its -requisite\-reference\(aqs can be created by invoking one of the -requisite methods (see \fBState Requisites\fP) on either a function\-declaration -object or a state\-declaration object. The return value of a -requisite call is also a function\-declaration object, so you +Finally, a \fIrequisite\-declaration\fP object with its +\fIrequisite\-reference\fP\(aqs can be created by invoking one of the +requisite methods (see \fBState Requisites\fP) on either a \fIfunction\-declaration\fP +object or a \fIstate\-declaration\fP object. The return value of a +requisite call is also a \fIfunction\-declaration\fP object, so you can chain several requisite calls together. .sp -Arguments to a requisite call can be a list of state\-declaration objects +Arguments to a requisite call can be a list of \fIstate\-declaration\fP objects and/or a set of keyword arguments whose names are state modules and values are -IDs of ID\-declaration\(aqs or names of name\-declaration\(aqs. +IDs of \fIID\-declaration\fP\(aqs or names of \fIname\-declaration\fP\(aqs. .INDENT 0.0 .INDENT 3.5 .sp @@ -123298,9 +131285,9 @@ apache2.service.running() .UNINDENT .UNINDENT .sp -include\-declaration objects can be created with the \fBinclude\fP function, -while extend\-declaration objects can be created with the \fBextend\fP function, -whose arguments are just function\-declaration objects. +\fIinclude\-declaration\fP objects can be created with the \fBinclude\fP function, +while \fIextend\-declaration\fP objects can be created with the \fBextend\fP function, +whose arguments are just \fIfunction\-declaration\fP objects. .INDENT 0.0 .INDENT 3.5 .sp @@ -123316,7 +131303,7 @@ extend(state(\(aqapache2\(aq).service.watch(file=\(aq/etc/httpd/httpd.conf\(aq) The \fBinclude\fP function, by default, causes the included sls file to be rendered as soon as the \fBinclude\fP function is called. It returns a list of rendered module objects; sls files not rendered with the pydsl renderer return \fBNone\fP\(aqs. -This behavior creates no include\-declaration\(aqs in the resulting high state +This behavior creates no \fIinclude\-declaration\fP\(aqs in the resulting high state data structure. .INDENT 0.0 .INDENT 3.5 @@ -123357,7 +131344,7 @@ include(\(aqedit.vim\(aq, \(aqhttp.server\(aq, delayed=True) .UNINDENT .UNINDENT .sp -Above will just create a include\-declaration in the rendered result, and +Above will just create a \fIinclude\-declaration\fP in the rendered result, and such call always returns \fBNone\fP\&. .SS Special integration with the \fIcmd\fP state .sp @@ -123385,9 +131372,9 @@ of our function into a structure expected by the state system. See \fBsalt.states.cmd.call()\fP for more information. .SS Implicit ordering of states .sp -Salt states are explicitly ordered via requisite\-declaration\(aqs. +Salt states are explicitly ordered via \fIrequisite\-declaration\fP\(aqs. However, with \fIpydsl\fP it\(aqs possible to let the renderer track the order -of creation for function\-declaration objects, and implicitly add +of creation for \fIfunction\-declaration\fP objects, and implicitly add \fBrequire\fP requisites for your states to enforce the ordering. This feature is enabled by setting the \fBordered\fP option on \fB__pydsl__\fP\&. .sp @@ -123427,11 +131414,11 @@ Above example should create states from \fB0\fP to \fB9\fP that will output \fB0 \fBone\fP, \fBtwo\fP, \fB3\fP, ... \fB9\fP, in that order. .sp It\(aqs important to know that \fIpydsl\fP tracks the \fIcreations\fP of -function\-declaration objects, and automatically adds a \fBrequire\fP requisite -to a function\-declaration object that requires the last -function\-declaration object created before it in the sls file. +\fIfunction\-declaration\fP objects, and automatically adds a \fBrequire\fP requisite +to a \fIfunction\-declaration\fP object that requires the last +\fIfunction\-declaration\fP object created before it in the sls file. .sp -This means later calls (perhaps to update the function\(aqs function\-arg\-declaration) to a previously created function declaration will not change the +This means later calls (perhaps to update the function\(aqs \fIfunction\-arg\-declaration\fP) to a previously created function declaration will not change the order. .SS Render time state execution .sp @@ -123440,7 +131427,7 @@ high state data representation by a renderer before the states can be executed. In the case of the \fIpydsl\fP renderer, the .sls file is executed as a python module as it is being rendered which makes it easy to execute a state at render time. In \fIpydsl\fP, executing one or more states at render time can be done by calling a -configured ID\-declaration object. +configured \fIID\-declaration\fP object. .INDENT 0.0 .INDENT 3.5 .sp @@ -123460,15 +131447,15 @@ s() # execute the two states now .UNINDENT .UNINDENT .sp -Once an ID\-declaration is called at render time it is detached from the +Once an \fIID\-declaration\fP is called at render time it is detached from the sls module as if it was never defined. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 If \fIimplicit ordering\fP is enabled (i.e., via \fB__pydsl__.set(ordered=True)\fP) then -the \fIfirst\fP invocation of a ID\-declaration object must be done before a -new function\-declaration is created. +the \fIfirst\fP invocation of a \fIID\-declaration\fP object must be done before a +new \fIfunction\-declaration\fP is created. .UNINDENT .UNINDENT .SS Integration with the stateconf renderer @@ -124420,7 +132407,7 @@ a MongoDB server, a MySQL server, or any system. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -Full list of builtin returners +\fIFull list of builtin returners\fP .UNINDENT .UNINDENT .SS Using Returners @@ -124461,7 +132448,7 @@ test.ping command will be sent out to the three named returners. .sp A returner is a Python module containing at minimum a \fBreturner\fP function. Other optional functions can be included to add support for -master_job_cache, external_job_cache, and \fI\%Event Returners\fP\&. +\fImaster_job_cache\fP, \fIexternal_job_cache\fP, and \fI\%Event Returners\fP\&. .INDENT 0.0 .TP .B \fBreturner\fP @@ -124511,9 +132498,9 @@ The above example of a returner set to send the data to a Redis server serializes the data as JSON and sets it in redis. .SS Master Job Cache Support .sp -master_job_cache, external_job_cache, and \fI\%Event Returners\fP\&. -Salt\(aqs master_job_cache allows returners to be used as a pluggable -replacement for the default_job_cache\&. In order to do so, a returner +\fImaster_job_cache\fP, \fIexternal_job_cache\fP, and \fI\%Event Returners\fP\&. +Salt\(aqs \fImaster_job_cache\fP allows returners to be used as a pluggable +replacement for the \fIdefault_job_cache\fP\&. In order to do so, a returner must implement the following functions: .sp \fBNOTE:\fP @@ -124625,7 +132612,7 @@ def get_load(jid): .UNINDENT .SS External Job Cache Support .sp -Salt\(aqs external_job_cache extends the master_job_cache\&. External +Salt\(aqs \fIexternal_job_cache\fP extends the \fImaster_job_cache\fP\&. External Job Cache support requires the following functions in addition to what is required for Master Job Cache support: .INDENT 0.0 @@ -124786,7 +132773,7 @@ default returner with the same name. .sp Note that a returner\(aqs default name is its filename (i.e. \fBfoo.py\fP becomes returner \fBfoo\fP), but that its name can be overridden by using a -__virtual__ function\&. A good example of this can be +\fI__virtual__ function\fP\&. A good example of this can be found in the \fI\%redis\fP returner, which is named \fBredis_return.py\fP but is loaded as simply \fBredis\fP: .INDENT 0.0 @@ -124814,7 +132801,7 @@ def __virtual__(): .sp The \fBreturner\fP, \fBprep_jid\fP, \fBsave_load\fP, \fBget_load\fP, and \fBevent_return\fP functions can be tested by configuring the -master_job_cache and \fI\%Event Returners\fP in the master config +\fImaster_job_cache\fP and \fI\%Event Returners\fP in the master config file and submitting a job to \fBtest.ping\fP each minion from the master. .sp Once you have successfully exercised the Master Job Cache functions, test the @@ -124909,6 +132896,7 @@ _ T{ \fBhipchat_return\fP T} T{ +Return salt data via hipchat. T} _ T{ @@ -124992,6 +132980,7 @@ _ T{ \fBslack_returner\fP T} T{ +Return salt data via slack T} _ T{ @@ -125393,27 +133382,17 @@ An example Django module that registers a function called \(aqreturner_callback\(aq with this module\(aqs \(aqreturner\(aq function: .INDENT 0.0 .INDENT 3.5 -.INDENT 0.0 -.INDENT 3.5 .sp .nf .ft C - -.ft P -.fi -.UNINDENT -.UNINDENT -.sp import salt.returners.django_return from django.dispatch import receiver -.sp + @receiver(salt.returners.django_return, sender=returner) def returner_callback(sender, ret): -.INDENT 0.0 -.INDENT 3.5 -print(\(aqI received {0} from {1}\(aq.format(ret, sender)) -.UNINDENT -.UNINDENT + print(\(aqI received {0} from {1}\(aq.format(ret, sender)) +.ft P +.fi .UNINDENT .UNINDENT .INDENT 0.0 @@ -125631,6 +133610,114 @@ Return data to an etcd server or cluster .B salt.returners.etcd_return.save_load(jid, load) Save the load to the specified jid .UNINDENT +.SS salt.returners.hipchat_return +.sp +Return salt data via hipchat. +.sp +New in version 2015.5.0. + +.sp +The following fields can be set in the minion conf file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +hipchat.room_id (required) +hipchat.api_key (required) +hipchat.api_version (required) +hipchat.from_name (required) +hipchat.color (optional) +hipchat.notify (optional) +hipchat.profile (optional) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Alternative configuration values can be used by prefacing the configuration. +Any values not found in the alternative configuration will be pulled from +the default location: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +hipchat.room_id +hipchat.api_key +hipchat.api_version +hipchat.from_name +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Hipchat settings may also be configured as: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +hipchat: + room_id: RoomName + api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + api_version: v1 + from_name: user@email.com + +alternative.hipchat: + room_id: RoomName + api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + api_version: v1 + from_name: user@email.com + +hipchat_profile: + api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + api_version: v1 + from_name: user@email.com + +hipchat: + profile: hipchat_profile + room_id: RoomName + +alternative.hipchat: + profile: hipchat_profile + room_id: RoomName +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To use the HipChat returner, append \(aq\-\-return hipchat\(aq to the salt command. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq test.ping \-\-return hipchat +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To use the alternative configuration, append \(aq\-\-return_config alternative\(aq to the salt command. +.sp +New in version 2015.5.0. + +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq test.ping \-\-return hipchat \-\-return_config alternative +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.returners.hipchat_return.returner(ret) +Send an hipchat message with the data +.UNINDENT .SS salt.returners.kafka_return .sp Return data to a Kafka topic @@ -125856,6 +133943,20 @@ Required python modules: pymongo This returner will send data from the minions to a MongoDB server. To configure the settings for your MongoDB server, add the following lines to the minion config files: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +mongo.db: +mongo.host: +mongo.user: +mongo.password: +mongo.port: 27017 +.ft P +.fi +.UNINDENT +.UNINDENT .sp You can also ask for indexes creation on the most common used fields, which should greatly improve performance. Indexes are not created by default. @@ -126960,6 +135061,104 @@ Do any work necessary to prepare a JID, including sending a custom id Log outcome to sentry. The returner tries to identify errors and report them as such. All other messages will be reported at info level. .UNINDENT +.SS salt.returners.slack_returner +.sp +Return salt data via slack +.sp +New in version 2015.5.0. + +.sp +The following fields can be set in the minion conf file: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +slack.channel (required) +slack.api_key (required) +slack.from_name (required) +slack.profile (optional) +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Alternative configuration values can be used by prefacing the configuration. +Any values not found in the alternative configuration will be pulled from +the default location: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +slack.channel +slack.api_key +slack.from_name +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Hipchat settings may also be configured as: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +slack: + channel: RoomName + api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + from_name: user@email.com + +alternative.slack: + room_id: RoomName + api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + from_name: user@email.com + +slack_profile: + api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + from_name: user@email.com + +slack: + profile: slack_profile + channel: RoomName + +alternative.slack: + profile: slack_profile + channel: RoomName +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To use the HipChat returner, append \(aq\-\-return slack\(aq to the salt command. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq test.ping \-\-return slack +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To use the alternative configuration, append \(aq\-\-return_config alternative\(aq to the salt command. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +salt \(aq*\(aq test.ping \-\-return slack \-\-return_config alternative +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.returners.slack_returner.returner(ret) +Send an slack message with the data +.UNINDENT .SS salt.returners.sms_return .sp Return data by SMS. @@ -127448,11 +135647,7 @@ _ T{ \fBclustershell\fP T} T{ -.INDENT 0.0 -.TP -.B requires -clustershell -.UNINDENT +This roster resolves hostname in a pdsh/clustershell style. T} _ T{ @@ -127570,6 +135765,18 @@ echo \(aq{ .UNINDENT .sp This is the format that an inventory script needs to output to work with ansible, and thus here. +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[~]# salt\-ssh \-\-roster\-file /etc/salt/hosts salt.gtmanfred.com test.ping +salt.gtmanfred.com: + True +.ft P +.fi +.UNINDENT +.UNINDENT .sp Any of the [groups] or direct hostnames will return. The \(aqall\(aq is special, and returns everything. .INDENT 0.0 @@ -127658,21 +135865,24 @@ Return the targets from the flat yaml file, checks opts for location but defaults to /etc/salt/roster .UNINDENT .SS salt.roster.clustershell -.INDENT 0.0 -.TP -.B requires -clustershell -.UNINDENT -.sp -\fI\%https://github.com/cea\-hpc/clustershell\fP .sp This roster resolves hostname in a pdsh/clustershell style. -.sp -When you want to use host globs for target matching, use \-\-roster clustershell. .INDENT 0.0 .TP -.B Example: +.B depends +clustershell, \fI\%https://github.com/cea\-hpc/clustershell\fP +.UNINDENT +.sp +When you want to use host globs for target matching, use \fB\-\-roster clustershell\fP\&. For example: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C salt\-ssh \-\-roster clustershell \(aqserver_[1\-10,21\-30],test_server[5,7,9]\(aq test.ping +.ft P +.fi +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -127750,7 +135960,7 @@ A Salt runner can be a simple client call or a complex application. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -The full list of runners +\fIThe full list of runners\fP .UNINDENT .UNINDENT .SS Full list of runner modules @@ -127845,11 +136055,7 @@ _ T{ \fBnacl\fP T} T{ -.INDENT 0.0 -.TP -.B requires -libnacl -.UNINDENT +This runner helps create encrypted passwords that can be included in pillars. T} _ T{ @@ -128071,7 +136277,7 @@ This runner wraps the functionality of salt cloud making salt cloud routines available to all internal apis via the runner system .INDENT 0.0 .TP -.B salt.runners.cloud.action(fun=None, cloudmap=None, instances=None, provider=None, instance=None, **kwargs) +.B salt.runners.cloud.action(func=None, cloudmap=None, instances=None, provider=None, instance=None, **kwargs) Execute a single action on the given map/provider/instance .UNINDENT .INDENT 0.0 @@ -128664,7 +136870,7 @@ then the environments for all configured backends will be returned. .B backend Narrow fileserver backends to a subset of the enabled ones. .sp -Changed in version 2015.5.0::: If all passed backends start with a minus sign (\fB\-\fP), then these +Changed in version 2015.5.0: If all passed backends start with a minus sign (\fB\-\fP), then these backends will be excluded from the enabled backends. However, if there is a mix of backends with and without a minus sign (ex: \fBbackend=\-roots,git\fP) then the ones starting with a minus @@ -128740,11 +136946,7 @@ Set a fileserver update lock for VCS fileserver backends (\fBgit\fP, \fBhg\fP, \ .INDENT 7.0 .INDENT 3.5 This will only operate on enabled backends (those configured in - -.nf -:master_conf:\(gafileserver_backend\(ga -.fi -). +\fBfileserver_backend\fP). .UNINDENT .UNINDENT .INDENT 7.0 @@ -128871,12 +137073,15 @@ salt\-run git_pillar.update branch=\(aqbranch\(aq repo=\(aqlocation\(aq Module for making various web calls. Primarily designed for webhooks and the like, but also useful for basic http testing. .sp -New in version 2015.5. +New in version 2015.5.0. .INDENT 0.0 .TP .B salt.runners.http.query(url, output=True, **kwargs) Query a resource, and decode the return data +.sp +New in version 2015.5.0. + .sp CLI Example: .INDENT 7.0 @@ -128896,6 +137101,9 @@ salt\-run http.query http://somelink.com/ method=POST data=\(aq .TP .B salt.runners.http.update_ca_bundle(target=None, source=None, merge_files=None) Update the local CA bundle file from a URL +.sp +New in version 2015.5.0. + .sp CLI Example: .INDENT 7.0 @@ -129586,38 +137794,43 @@ salt\-run mine.get \(aq*\(aq network.interfaces .UNINDENT .UNINDENT .SS salt.runners.nacl -.INDENT 0.0 -.TP -.B requires -libnacl -.UNINDENT -.sp -\fI\%https://github.com/saltstack/libnacl\fP .sp This runner helps create encrypted passwords that can be included in pillars. -This is often usefull if you wish to store your pillars in source control or +.INDENT 0.0 +.TP +.B depends +libnacl, \fI\%https://github.com/saltstack/libnacl\fP +.UNINDENT +.sp +This is often useful if you wish to store your pillars in source control or share your pillar data with others that you trust. I dont advise making your pillars public regardless if they are encrypted or not. .sp The following configurations can be defined in the master config -so your users can create encrypted passwords using the runner nacl. +so your users can create encrypted passwords using the runner nacl: .INDENT 0.0 .INDENT 3.5 +.sp +.nf +.ft C cat /etc/salt/master.d/nacl.conf nacl.config: -.INDENT 0.0 -.INDENT 3.5 -key: None -keyfile: /root/.nacl -.UNINDENT -.UNINDENT + key: None + keyfile: /root/.nacl +.ft P +.fi .UNINDENT .UNINDENT .sp Now with the config in the master you can use the runner nacl like: .INDENT 0.0 .INDENT 3.5 +.sp +.nf +.ft C salt\-run nacl.enc \(aqdata\(aq +.ft P +.fi .UNINDENT .UNINDENT .INDENT 0.0 @@ -130355,7 +138568,7 @@ system. More Orchestrate documentation .INDENT 0.0 .IP \(bu 2 -Full Orchestrate Tutorial +\fIFull Orchestrate Tutorial\fP .IP \(bu 2 \fBDocs for the master\-side state module\fP .UNINDENT @@ -131012,7 +139225,7 @@ def mod_aggregate(low, chunks, running): \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -This documentation has been moved here\&. +This documentation has been moved \fIhere\fP\&. .UNINDENT .UNINDENT .SS File State Backups @@ -131755,7 +139968,7 @@ file. \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -This documentation has been moved here\&. +This documentation has been moved \fIhere\fP\&. .UNINDENT .UNINDENT .SS Highstate data structure definitions @@ -131867,7 +140080,7 @@ mywebsite: .INDENT 3.5 watch_in and require_in .sp -Sometimes it is more convenient to use the watch_in or require_in syntax +Sometimes it is more convenient to use the \fIwatch_in\fP or \fIrequire_in\fP syntax instead of extending another \fBSLS\fP file. .sp \fBState Requisites\fP @@ -132417,7 +140630,7 @@ requisite logic. \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -This documentation has been moved here\&. +This documentation has been moved \fIhere\fP\&. .UNINDENT .UNINDENT .SS Ordering States @@ -132570,12 +140783,12 @@ In this example, the httpd service is only going to be started if the package, user, group, and file are executed successfully. .SS Requisite Documentation .sp -For detailed information on each of the individual requisites, please -look here. +For detailed information on each of the individual requisites, \fIplease +look here.\fP .SS The Order Option .sp Before using the \fIorder\fP option, remember that the majority of state ordering -should be done with a requisite\-declaration, and that a requisite +should be done with a \fIrequisite\-declaration\fP, and that a requisite declaration will override an \fIorder\fP option, so a state with order option should not require or required by other states. .sp @@ -132620,7 +140833,7 @@ vim: \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -This documentation has been moved here\&. +This documentation has been moved \fIhere\fP\&. .UNINDENT .UNINDENT .SS State Providers @@ -133556,7 +141769,7 @@ restart\-apache2: configure\-apache2: file.managed: - \- path: /etc/apache2/apache2.conf + \- name: /etc/apache2/apache2.conf \- source: salt://apache2/apache2.conf .ft P .fi @@ -133576,7 +141789,7 @@ restart\-apache2: configure\-apache2: file.managed: - \- path: /etc/apache2/apache2.conf + \- name: /etc/apache2/apache2.conf \- source: salt://apache2/apache2.conf \- listen_in: \- service: apache2 @@ -133606,7 +141819,7 @@ same privileges as the salt\-minion. .ft C comment\-repo: file.replace: - \- path: /etc/yum.repos.d/fedora.repo + \- name: /etc/yum.repos.d/fedora.repo \- pattern: ^enabled=0 \- repl: enabled=1 \- check_cmd: @@ -134380,7 +142593,7 @@ Any custom states which have been synced to a minion, that are named the same as one of Salt\(aqs default set of states, will take the place of the default state with the same name. Note that a state\(aqs default name is its filename (i.e. \fBfoo.py\fP becomes state \fBfoo\fP), but that its name can be overridden -by using a __virtual__ function\&. +by using a \fI__virtual__ function\fP\&. .SS Cross Calling Modules .sp As with Execution Modules, State Modules can also make use of the \fB__salt__\fP @@ -135289,6 +143502,12 @@ Manage ini files T} _ T{ +\fBipmi\fP +T} T{ +Manage IPMI devices over LAN +T} +_ +T{ \fBipset\fP T} T{ Management of ipsets @@ -135762,6 +143981,12 @@ Management of timezones T} _ T{ +\fBtls\fP +T} T{ +Enforce state for SSL/TLS +T} +_ +T{ \fBtomcat\fP T} T{ This state uses the manager webapp to manage Apache tomcat webapps @@ -136216,7 +144441,7 @@ and bz2 in Python 2. Keep the archive in the minion\(aqs cache .UNINDENT .UNINDENT -.SS salt.states.jboss7 +.SS salt.states.artifactory .sp This state downloads artifacts from artifactory. .INDENT 0.0 @@ -136460,8 +144685,15 @@ specific lens. State name .TP .B context -The context to use. Set this to a file path, prefixed by \fB/files\fP, to -avoid redundancy, e.g.: +A file path, prefixed by \fB/files\fP\&. Should resolve to an actual file +(not an arbitrary augeas path). This is used to avoid duplicating the +file name for each item in the changes list (for example, \fBset bind 0.0.0.0\fP +in the example below operates on the file specified by \fBcontext\fP). If +\fBcontext\fP is not specified, a file path prefixed by \fB/files\fP should be +included with the \fBset\fP command. +.sp +The file path is examined to determine if the +specified changes are already present. .INDENT 7.0 .INDENT 3.5 .sp @@ -137233,7 +145465,7 @@ that contains a dict with region, key and keyid. .SS salt.states.boto_dynamodb .SS Manage DynamoDB Tables .sp -New in version 2015.5. +New in version 2015.5.0. .sp Create and destroy DynamoDB tables. Be aware that this interacts with Amazon\(aqs @@ -137927,18 +146159,16 @@ Name of the IAM role. A list of availability zones for this ELB. .TP .B listeners +A list of listener lists; example: +[ .INDENT 7.0 -.TP -.B A list of listener lists; example: -.INDENT 7.0 -.TP -.B [ +.INDENT 3.5 [\(aq443\(aq, \(aqHTTPS\(aq, \(aqarn:aws:iam::1111111:server\-certificate/mycert\(aq], [\(aq8443\(aq, \(aq80\(aq, \(aqHTTPS\(aq, \(aqHTTP\(aq, \(aqarn:aws:iam::1111111:server\-certificate/mycert\(aq] .UNINDENT +.UNINDENT .sp ] -.UNINDENT .TP .B subnets A list of subnet IDs in your VPC to attach to your LoadBalancer. @@ -139330,9 +147560,7 @@ my\-project: .fi .UNINDENT .UNINDENT -.sp -Should I use \fI\%cmd.run\fP or \fI\%cmd.wait\fP? -\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- +.SS Should I use \fI\%cmd.run\fP or \fI\%cmd.wait\fP? .sp These two states are often confused. The important thing to remember about them is that \fI\%cmd.run\fP states are run each time the SLS @@ -140640,7 +148868,7 @@ Set debconf selections from a file or a template : debconf.set_file: \- source: salt://pathto/pkg.selections.jinja2 - \- template: jinja2 + \- template: jinja \- context: some_value: "false" .ft P @@ -140784,6 +149012,7 @@ running my_service: docker.running: \- container: mysuperdocker + \- image: corp/mysuperdocker_img \- port_bindings: "5000/tcp": HostIp: "" @@ -140799,7 +149028,7 @@ my_service: The \fBport_bindings\fP argument above is a dictionary. The double indentation is required for PyYAML to load the data structure properly as a python dictionary. More information can be found -here +\fIhere\fP .UNINDENT .UNINDENT .IP \(bu 2 @@ -140904,7 +149133,7 @@ a mapping of mapping portInHost : PortInContainer .UNINDENT .TP .B volumes -List of volumes +List of volumes (see notes for the running function) .UNINDENT .sp For other parameters, see absolutely first the salt.modules.dockerio @@ -141145,20 +149374,23 @@ only meaningful if port does not contain portinhost:portincontainer mapping) .B volumes List of volumes to mount or create in the container (like \fB\-v\fP of \fBdocker run\fP command), mapping host directory to container directory. -To create a volume in the container: +.sp +To specify a volume in the container in terse list format: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C \- volumes: - \- "/var/log/service" + \- "/var/log/service" # container\-only volume + \- "/srv/timezone:/etc/timezone" # bound volume + \- "/usr/local/etc/passwd:/etc/passwd:ro" # read\-only bound volume .ft P .fi .UNINDENT .UNINDENT .sp -For read\-write mounting, use the short form (note that the notion of +You can also use the short dictionary form (note that the notion of source:target from docker is preserved): .INDENT 7.0 .INDENT 3.5 @@ -141166,13 +149398,13 @@ source:target from docker is preserved): .nf .ft C \- volumes: - \- /var/log/service: /var/log/service + \- /var/log/service: /var/log/service # mandatory read\-write implied .ft P .fi .UNINDENT .UNINDENT .sp -Or, to specify read\-only mounting, use the extended form: +Or, alternatively, to specify read\-only mounting, use the extended form: .INDENT 7.0 .INDENT 3.5 .sp @@ -141180,29 +149412,29 @@ Or, to specify read\-only mounting, use the extended form: .ft C \- volumes: \- /home/user1: - bind: /mnt/vol2 - ro: true + bind: /mnt/vol2 + ro: True \- /var/www: - bind: /mnt/vol1 - ro: false + bind: /mnt/vol1 + ro: False .ft P .fi .UNINDENT .UNINDENT .sp -Or (mostly for backwards compatibility) a dict style +Or (for backwards compatibility) another dict style: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C \- volumes: - /home/user1: - bind: /mnt/vol2 - ro: true - /var/www: - bind: /mnt/vol1 - ro: false + /home/user1: + bind: /mnt/vol2 + ro: True + /var/www: + bind: /mnt/vol1 + ro: False .ft P .fi .UNINDENT @@ -141374,6 +149606,20 @@ damian: Ensure DRAC network is in a consistent state .INDENT 0.0 .INDENT 3.5 +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +my_network: + drac.network: + \- ip: 10.225.108.29 + \- netmask: 255.255.255.224 + \- gateway: 10.225.108.1 +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 @@ -141632,7 +149878,7 @@ def run(): .INDENT 3.5 The \fBdefaults\fP and \fBcontext\fP arguments require extra indentation (four spaces instead of the normal two) in order to create a nested dictionary. -More information\&. +\fIMore information\fP\&. .UNINDENT .UNINDENT .sp @@ -143258,11 +151504,7 @@ New in version 0.17.0. Filesystem path to the file to be edited. .TP .B pattern -Python\(aqs -.nf -\(garegular expression search\(ga_ -.fi -\&. +Python\(aqs \fI\%regular expression search\fP\&. .TP .B repl The replacement text. @@ -143819,9 +152061,15 @@ A path on the minion server to a private key to use over SSH .TP .B https_user HTTP Basic Auth username for HTTPS (only) clones +.sp +New in version 2015.5.0. + .TP .B https_pass HTTP Basic Auth password for HTTPS (only) clones +.sp +New in version 2015.5.0. + .TP .B onlyif A command to run as a check, run the named command only if the command @@ -144288,11 +152536,7 @@ Ensure myservice dashboard is managed: The behavior of this module is to create dashboards if they do not exist, to add rows if they do not exist in existing dashboards, and to update rows if they exist in dashboards. The module will not manage rows that are not defined, -.INDENT 0.0 -.INDENT 3.5 allowing users to manage their own custom rows. -.UNINDENT -.UNINDENT .INDENT 0.0 .TP .B salt.states.grafana.dashboard_absent(name, hosts=None, profile=\(aqgrafana\(aq) @@ -144734,14 +152978,11 @@ The message that is to be sent to the Hipchat room. .UNINDENT .sp The following parameters are optional: -api_key .INDENT 7.0 -.INDENT 3.5 +.TP +.B api_key The api key for Hipchat to use for authentication, if not specified in the configuration options of master or minion. -.UNINDENT -.UNINDENT -.INDENT 7.0 .TP .B api_version The api version for Hipchat to use, @@ -145223,6 +153464,245 @@ changes dict will contain the sections that changed options present in file and not specified in sections will be deleted changes dict will contain the sections that changed .UNINDENT +.SS salt.states.ipmi +.SS Manage IPMI devices over LAN +.sp +The following configuration defaults can be defined in the +minion, master config or pillar: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ipmi.config: + api_host: 127.0.0.1 + api_user: admin + api_pass: apassword + api_port: 623 + api_kg: None +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Every call can override the config defaults: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +ensure myipmi system is set to network boot: + ipmi.boot_device: + \- name: network + \- api_host: myipmi.hostname.com + \- api_user: root + \- api_pass: apassword + \- api_kg: None + +ensure myipmi system is powered on: + ipmi.power: + \- name: boot + \- api_host: myipmi.hostname.com + \- api_user: root + \- api_pass: apassword +.ft P +.fi +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.ipmi.boot_device(name=\(aqdefault\(aq, **kwargs) +Request power state change +.INDENT 7.0 +.TP +.B name = \fBdefault\fP +.INDENT 7.0 +.IP \(bu 2 +network \-\- Request network boot +.IP \(bu 2 +hd \-\- Boot from hard drive +.IP \(bu 2 +safe \-\- Boot from hard drive, requesting \(aqsafe mode\(aq +.IP \(bu 2 +optical \-\- boot from CD/DVD/BD drive +.IP \(bu 2 +setup \-\- Boot into setup utility +.IP \(bu 2 +default \-\- remove any IPMI directed boot device request +.UNINDENT +.TP +.B kwargs +.INDENT 7.0 +.IP \(bu 2 +api_host=localhost +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass= +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.ipmi.power(name=\(aqpower_on\(aq, wait=300, **kwargs) +Request power state change +.INDENT 7.0 +.TP +.B name +.INDENT 7.0 +.TP +.B Ensure power state one of: +.INDENT 7.0 +.IP \(bu 2 +power_on \-\- system turn on +.IP \(bu 2 +power_off \-\- system turn off (without waiting for OS) +.IP \(bu 2 +shutdown \-\- request OS proper shutdown +.IP \(bu 2 +reset \-\- reset (without waiting for OS) +.IP \(bu 2 +boot \-\- If system is off, then \(aqon\(aq, else \(aqreset\(aq +.UNINDENT +.UNINDENT +.TP +.B wait +wait X seconds for the job to complete before forcing. +(defaults to 300 seconds) +.TP +.B kwargs +.INDENT 7.0 +.IP \(bu 2 +api_host=localhost +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass= +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.ipmi.user_absent(name, channel=14, **kwargs) +Remove user +Delete all user (uid) records having the matching name. +.INDENT 7.0 +.TP +.B name +string name of user to delete +.TP +.B channel +channel to remove user access from defaults to 14 for auto. +.TP +.B kwargs +.INDENT 7.0 +.IP \(bu 2 +api_host=localhost +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass= +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B salt.states.ipmi.user_present(name, uid, password, channel=14, callback=False, link_auth=True, ipmi_msg=True, privilege_level=\(aqadministrator\(aq, **kwargs) +Ensure IPMI user and user privileges. +.INDENT 7.0 +.TP +.B name +name of user (limit 16 bytes) +.TP +.B uid +user id number (1 to 7) +.TP +.B password +user password (limit 16 bytes) +.TP +.B channel +ipmi channel defaults to 14 for auto +.TP +.B callback +User Restricted to Callback +.INDENT 7.0 +.TP +.B False = User Privilege Limit is determined by the User Privilege Limit +parameter privilege_level, for both callback and non\-callback connections. +.TP +.B True = User Privilege Limit is determined by the privilege_level +parameter for callback connections, but is restricted to Callback +level for non\-callback connections. Thus, a user can only initiate +a Callback when they \(aqcall in\(aq to the BMC, but once the callback +connection has been made, the user could potentially establish a +session as an Operator. +.UNINDENT +.TP +.B link_auth +User Link authentication +True/False +user name and password information will be used for link +authentication, e.g. PPP CHAP) for the given channel. Link +authentication itself is a global setting for the channel and is +enabled/disabled via the serial/modem configuration parameters. +.TP +.B ipmi_msg +User IPMI Messaginge +True/False +user name and password information will be used for IPMI +Messaging. In this case, \(aqIPMI Messaging\(aq refers to the ability to +execute generic IPMI commands that are not associated with a +particular payload type. For example, if IPMI Messaging is disabled for +a user, but that user is enabled for activatallow_authing the SOL +payload type, then IPMI commands associated with SOL and session +management, such as Get SOL Configuration Parameters and Close Session +are available, but generic IPMI commands such as Get SEL Time are +unavailable.) +ipmi_msg +.TP +.B privilege_level +.INDENT 7.0 +.IP \(bu 2 +callback +.IP \(bu 2 +user +.IP \(bu 2 +operator +.IP \(bu 2 +administrator +.IP \(bu 2 +proprietary +.IP \(bu 2 +no_access +.UNINDENT +.TP +.B kwargs +.INDENT 7.0 +.IP \(bu 2 +api_host=localhost +.IP \(bu 2 +api_user=admin +.IP \(bu 2 +api_pass= +.IP \(bu 2 +api_port=623 +.IP \(bu 2 +api_kg=None +.UNINDENT +.UNINDENT +.UNINDENT .SS salt.states.ipset .SS Management of ipsets .sp @@ -145581,6 +154061,9 @@ All other arguments are passed in with the same name as the long option that would normally be used for iptables, with one exception: \fB\-\-state\fP is specified as \fIconnstate\fP instead of \fIstate\fP (not to be confused with \fIctstate\fP). +.sp +Jump options that doesn\(aqt take arguments should be passed in with an empty +string. .UNINDENT .INDENT 0.0 .TP @@ -145635,6 +154118,9 @@ All other arguments are passed in with the same name as the long option that would normally be used for iptables, with one exception: \fB\-\-state\fP is specified as \fIconnstate\fP instead of \fIstate\fP (not to be confused with \fIctstate\fP). +.sp +Jump options that doesn\(aqt take arguments should be passed in with an empty +string. .UNINDENT .INDENT 0.0 .TP @@ -145670,6 +154156,9 @@ All other arguments are passed in with the same name as the long option that would normally be used for iptables, with one exception: \fB\-\-state\fP is specified as \fIconnstate\fP instead of \fIstate\fP (not to be confused with \fIctstate\fP). +.sp +Jump options that doesn\(aqt take arguments should be passed in with an empty +string. .UNINDENT .INDENT 0.0 .TP @@ -145696,6 +154185,9 @@ The requested table policy .SS salt.states.jboss7 .sp Manage JBoss 7 Application Server via CLI interface +.sp +New in version 2015.5.0. + .sp This state uses jboss\-cli.sh script from JBoss installation and parses its output to determine execution result. .sp @@ -146532,12 +155024,34 @@ Linux File Access Control Lists Ensure a Linux ACL is present .INDENT 0.0 .INDENT 3.5 +.sp +.nf +.ft C +root: + acl.present: + \- name: /root + \- acl_type: users + \- acl_name: damian + \- perms: rwx +.ft P +.fi .UNINDENT .UNINDENT .sp Ensure a Linux ACL does not exist .INDENT 0.0 .INDENT 3.5 +.sp +.nf +.ft C +root: + acl.absent: + \- name: /root + \- acl_type: user + \- acl_name: damian + \- perms: rwx +.ft P +.fi .UNINDENT .UNINDENT .INDENT 0.0 @@ -146824,12 +155338,19 @@ lvstest: .SS Manage Linux Containers .INDENT 0.0 .TP -.B salt.states.lxc.absent(name) +.B salt.states.lxc.absent(name, stop=False) Ensure a container is not present, destroying it if present .INDENT 7.0 .TP .B name Name of the container to destroy +.TP +.B stop +stop before destroying +default: false +.sp +New in version 2015.5.2. + .UNINDENT .INDENT 7.0 .INDENT 3.5 @@ -146932,7 +155453,7 @@ web02: .UNINDENT .INDENT 0.0 .TP -.B salt.states.lxc.present(name, running=None, clone_from=None, snapshot=False, profile=None, template=None, options=None, image=None, config=None, fstype=None, size=None, backing=None, vgname=None, lvname=None) +.B salt.states.lxc.present(name, running=None, clone_from=None, snapshot=False, profile=None, network_profile=None, template=None, options=None, image=None, config=None, fstype=None, size=None, backing=None, vgname=None, lvname=None) Changed in version 2015.5.0: The \fI\%lxc.created\fP state has been renamed to \fBlxc.present\fP, and the \fI\%lxc.cloned\fP state has been merged into this state. @@ -146966,8 +155487,17 @@ False Use Copy On Write snapshots (LVM). Only supported with \fBclone_from\fP\&. .TP .B profile -Profile to use in container creation (see the LXC Tutorial for more information). Values in a +Profile to use in container creation (see the \fILXC Tutorial\fP for more information). Values in a profile will be overridden by the parameters listed below. +.TP +.B network_profile +Network Profile to use in container creation +(see the \fILXC Tutorial\fP +for more information). Values in a profile will be overridden by +the parameters listed below. +.sp +New in version 2015.5.2. + .UNINDENT .sp \fBContainer Creation Arguments\fP @@ -147019,7 +155549,7 @@ web01: .UNINDENT .UNINDENT .sp -Remember to double\-indent the options, due to how PyYAML works\&. +Remember to double\-indent the options, due to \fIhow PyYAML works\fP\&. .TP .B image A tar archive to use as the rootfs for the container. Conflicts with @@ -149934,6 +158464,10 @@ Specify a repository from which to install .TP .B skip_verify Skip the GPG verification check for the package to be installed +.TP +.B refresh +Update the repo database of available packages prior to installing the +requested package. .UNINDENT .sp Multiple Package Installation Options: @@ -150082,7 +158616,7 @@ refresh the package database before checking for new upgrades .B kwargs Any keyword arguments to pass through to \fBpkg.upgrade\fP\&. .sp -New in version 2015.5. +New in version 2015.5.0. .UNINDENT .UNINDENT @@ -151037,7 +159571,7 @@ on the host. .INDENT 7.0 .TP .B name -The licnese key to ensure is absent +The license key to ensure is absent .UNINDENT .UNINDENT .INDENT 0.0 @@ -151048,7 +159582,7 @@ on the host. .INDENT 7.0 .TP .B name -The licnese key to ensure is present +The license key to ensure is present .UNINDENT .UNINDENT .SS salt.states.process @@ -151570,17 +160104,29 @@ Deprecated since version Beryllium. .TP .B owner Initial owner permission to set on the VHost, if present +.sp +Deprecated since version Beryllium. + .TP .B conf Initial conf string to apply to the VHost and user. Defaults to .* +.sp +Deprecated since version Beryllium. + .TP .B write Initial write permissions to apply to the VHost and user. Defaults to .* +.sp +Deprecated since version Beryllium. + .TP .B read Initial read permissions to apply to the VHost and user. Defaults to .* +.sp +Deprecated since version Beryllium. + .TP .B runas Name of the user to run the command @@ -151999,7 +160545,7 @@ New in version 0.17.0. .sp This state is intended for use from the Salt Master. It provides access to sending commands down to minions as well as access to executing master\-side -modules. These state functions wrap Salt\(aqs Python API\&. +modules. These state functions wrap Salt\(aqs \fIPython API\fP\&. .sp \fBSEE ALSO:\fP .INDENT 0.0 @@ -152007,7 +160553,7 @@ modules. These state functions wrap Salt\(aqs Python API\&. More Orchestrate documentation .INDENT 0.0 .IP \(bu 2 -Full Orchestrate Tutorial +\fIFull Orchestrate Tutorial\fP .IP \(bu 2 \fBThe Orchestrate runner\fP .UNINDENT @@ -152410,6 +160956,26 @@ This will schedule the command within the range specified. The range parameter must be a dictionary with the date strings using the dateutil format. Requires python\-dateutil. .TP +.B once +This will schedule a job to run once on the specified date. +.TP +.B once_fmt +The default date format is ISO 8601 but can be overridden by +also specifying the \fBonce_fmt\fP option. +.TP +.B enabled +Whether the job should be enabled or disabled. Value should be a boolean. +.TP +.B return_job +Whether to return information to the Salt master upon job completion. +.TP +.B metadata +Using the metadata parameter special values can be associated with +a scheduled job. These values are not used in the execution of the job, +but can be used to search for specific jobs later if combined with the +return_job parameter. The metadata parameter must be specified as a +dictionary, othewise it will be ignored. +.TP .B returner The returner to use to return the results of the scheduled job. .TP @@ -152758,14 +161324,15 @@ slack\-message: .UNINDENT .sp The api key can be specified in the master or minion configuration like below: -.. code\-block:: yaml .INDENT 0.0 .INDENT 3.5 -.INDENT 0.0 -.TP -.B slack: -api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15 -.UNINDENT +.sp +.nf +.ft C +slack: + api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15 +.ft P +.fi .UNINDENT .UNINDENT .INDENT 0.0 @@ -152806,14 +161373,13 @@ The message that is to be sent to the Hipchat room. .UNINDENT .sp The following parameters are optional: -api_key .INDENT 7.0 -.INDENT 3.5 +.TP +.B api_key The api key for Slack to use for authentication, if not specified in the configuration options of master or minion. .UNINDENT .UNINDENT -.UNINDENT .SS salt.states.smtp .SS Sending Messages via SMTP .sp @@ -152867,7 +161433,7 @@ The message to send via SMTP .sp Splunk Search State Module .sp -New in version 2015.5. +New in version 2015.5.0. .sp This state is used to ensure presence of splunk searches. @@ -153732,6 +162298,14 @@ The name of the timezone to use (e.g.: America/Denver) Whether or not to set the hardware clock to UTC (default is True) .UNINDENT .UNINDENT +.SS salt.states.tls +.SS Enforce state for SSL/TLS +.INDENT 0.0 +.TP +.B salt.states.tls.valid_certificate(name, weeks=0, days=0, hours=0, minutes=0, seconds=0) +Verify that a TLS certificate is valid now and (optionally) will be valid +for the time specified through weeks, days, hours, minutes, and seconds. +.UNINDENT .SS salt.states.tomcat .sp This state uses the manager webapp to manage Apache tomcat webapps @@ -154204,6 +162778,15 @@ the file will be transferred from the master file server. .B cwd Path to the working directory where "pip install" is executed. .TP +.B user +The user under which to run virtualenv and pip +.TP +.B no_chown: False +When user is given, do not attempt to copy and chown +a requirements file (needed if the requirements file refers to other +files via relative paths, as the copy\-and\-chown procedure does not +account for such files) +.TP .B use_wheel False Prefer wheel archives (requires pip>=1.4) @@ -154532,35 +163115,35 @@ ISWebserverRole: .TP .B salt.states.win_servermanager.removed(name) Remove the windows feature -name: +.INDENT 7.0 +.TP +.B name: +short name of the feature (the right column in win_servermanager.list_available) +.UNINDENT +.sp +\fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 -short name of the feature (the right column in win_servermanager.list_available) +Some features require a reboot after uninstallation. If so the feature will not be completly uninstalled until +the server is restarted. .UNINDENT .UNINDENT .sp -Note: -Some features require a reboot after uninstallation. If so the feature will not be completly uninstalled until -the server is restarted. Example: +.sp Run \fBsalt MinionName win_servermanager.list_installed\fP to get a list of all features installed. Use the top name listed for each feature, not the indented one. Do not use the role or feature names mentioned in the PKGMGR documentation. -.. code\-block:: yaml .INDENT 7.0 .INDENT 3.5 -.INDENT 0.0 -.TP -.B ISWebserverRole: -.INDENT 7.0 -.TP -.B win_servermanager.removed: -.INDENT 7.0 -.IP \(bu 2 -name: Web\-Server -.UNINDENT -.UNINDENT -.UNINDENT +.sp +.nf +.ft C +ISWebserverRole: + win_servermanager.removed: + \- name: Web\-Server +.ft P +.fi .UNINDENT .UNINDENT .UNINDENT @@ -154959,7 +163542,7 @@ installed2 .UNINDENT .INDENT 0.0 .TP -.B salt.states.zcbuildout.installed(name, config=\(aqbuildout.cfg\(aq, quiet=False, parts=None, user=None, env=(), buildout_ver=None, test_release=False, distribute=None, new_st=None, offline=False, newest=False, python=\(aq/home/erik/virtualenv/docs/bin/python2\(aq, debug=False, verbose=False, unless=None, onlyif=None, use_vt=False, loglevel=\(aqdebug\(aq) +.B salt.states.zcbuildout.installed(name, config=\(aqbuildout.cfg\(aq, quiet=False, parts=None, user=None, env=(), buildout_ver=None, test_release=False, distribute=None, new_st=None, offline=False, newest=False, python=\(aq/usr/bin/python2.7\(aq, debug=False, verbose=False, unless=None, onlyif=None, use_vt=False, loglevel=\(aqdebug\(aq) Install buildout in a specific directory .sp It is a thin wrapper to modules.buildout.buildout @@ -155104,7 +163687,7 @@ state module to call execution modules within state runs. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -Full list of builtin modules +\fIFull list of builtin modules\fP .UNINDENT .UNINDENT .sp @@ -155492,7 +164075,7 @@ def foo(): .sp Salt includes a number of built\-in subsystems to generate top file data, they are listed listed at -all\-salt.tops\&. +\fIall\-salt.tops\fP\&. .sp The source for the built\-in Salt master tops can be found here: \fI\%https://github.com/saltstack/salt/blob/develop/salt/tops\fP @@ -155832,24 +164415,28 @@ Writes \fByaml_contents\fP to a file named specified by \fBdefault_include\fP\&. This folder is named \fBmaster.d\fP by default. Please look at -\fI\%http://docs.saltstack.com/en/latest/ref/configuration/master.html#include\-configuration\fP +\fBinclude\-configuration\fP for more information. .sp -Example low data -data = { +Example low data: .INDENT 7.0 .INDENT 3.5 -\(aqusername\(aq: \(aqsalt\(aq, -\(aqpassword\(aq: \(aqsalt\(aq, -\(aqfun\(aq: \(aqconfig.update_config\(aq, -\(aqfile_name\(aq: \(aqgui\(aq, -\(aqyaml_contents\(aq: {\(aqid\(aq: 1}, -\(aqclient\(aq: \(aqwheel\(aq, -\(aqeauth\(aq: \(aqpam\(aq, -.UNINDENT -.UNINDENT .sp +.nf +.ft C +data = { + \(aqusername\(aq: \(aqsalt\(aq, + \(aqpassword\(aq: \(aqsalt\(aq, + \(aqfun\(aq: \(aqconfig.update_config\(aq, + \(aqfile_name\(aq: \(aqgui\(aq, + \(aqyaml_contents\(aq: {\(aqid\(aq: 1}, + \(aqclient\(aq: \(aqwheel\(aq, + \(aqeauth\(aq: \(aqpam\(aq, } +.ft P +.fi +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP @@ -156118,8 +164705,7 @@ New in version 2015.5.0. .B salt.beacons.diskusage.beacon(config) Monitor the disk usage of the minion .sp -Specify thresholds for for each load average -and only emit a beacon if any of them are +Specify thresholds for each disk and only emit a beacon if any of them are exceeded. .sp code_block:: yaml @@ -156129,10 +164715,14 @@ code_block:: yaml .TP .B beacons: .INDENT 7.0 +.TP +.B diskusage: +.INDENT 7.0 .IP \(bu 2 -diskusage: -\- /: 63% -\- /mnt/nfs: 50% +/: 63% +.IP \(bu 2 +/mnt/nfs: 50% +.UNINDENT .UNINDENT .UNINDENT .UNINDENT @@ -156143,6 +164733,19 @@ diskusage: Watch files and translate the changes into salt events .INDENT 0.0 .TP +.B depends +.INDENT 7.0 +.IP \(bu 2 +pyinotify Python module >= 0.9.5 +.UNINDENT +.TP +.B Caution +Using generic mask options like open, access, ignored, and +closed_nowrite with reactors can easily cause the reactor +to loop on itself. +.UNINDENT +.INDENT 0.0 +.TP .B salt.beacons.inotify.beacon(config) Watch the configured files .sp @@ -156165,32 +164768,54 @@ beacons: .fi .UNINDENT .UNINDENT +.sp +The mask list can contain the following events (the default mask is create, +delete, and modify): +.INDENT 7.0 +.IP \(bu 2 +access File accessed +.IP \(bu 2 +attrib File metadata changed +.IP \(bu 2 +close_nowrite Unwritable file closed +.IP \(bu 2 +close_write Writable file closed +.IP \(bu 2 +create File created in watched directory +.IP \(bu 2 +delete File deleted from watched directory +.IP \(bu 2 +delete_self Watched file or directory deleted +.IP \(bu 2 +modify File modified +.IP \(bu 2 +moved_from File moved out of watched directory +.IP \(bu 2 +moved_to File moved into watched directory +.IP \(bu 2 +move_self Watched file moved +.IP \(bu 2 +open File opened +.UNINDENT +.sp +The mask can also contain the following options: +.INDENT 7.0 +.IP \(bu 2 +dont_follow Don\(aqt dereference symbolic links +.IP \(bu 2 +excl_unlink Omit events for children after they have been unlinked +.IP \(bu 2 +oneshot Remove watch after one event +.IP \(bu 2 +onlydir Operate only if name is directory +.UNINDENT .INDENT 7.0 .TP -.B The mask can be a single option from: -access -attrib -close_nowrite -close_write -create -delete -delete_self -excl_unlink -ignored -modify -moved_from -moved_to -move_self -oneshot -onlydir -open -unmount -.TP .B recurse: -Tell the beacon to recursively watch files in the directory +Recursively watch files in the directory .TP .B auto_add: -Automatically start adding files that are created in the watched directory +Automatically start watching files that are created in the watched directory .UNINDENT .UNINDENT .SS salt.beacons.journald @@ -156209,10 +164834,10 @@ This beacons config will return all sshd jornal entries .nf .ft C beacons: - journald: - sshd: - SYSLOG_IDENTIFIER: sshd - PRIORITY: 6 + journald: + sshd: + SYSLOG_IDENTIFIER: sshd + PRIORITY: 6 .ft P .fi .UNINDENT @@ -156226,7 +164851,7 @@ Beacon to emit system load averages .B salt.beacons.load.beacon(config) Emit the load averages of this host. .sp -Specify thresholds for for each load average +Specify thresholds for each load average and only emit a beacon if any of them are exceeded. .INDENT 7.0 @@ -156261,7 +164886,7 @@ New in version 2015.5.0. .B salt.beacons.network_info.beacon(config) Emit the network statistics of this host. .sp -Specify thresholds for for each network stat +Specify thresholds for each network stat and only emit a beacon if any of them are exceeded. .sp @@ -156440,13 +165065,11 @@ beacons: account_sid: "" auth_token: "" twilio_number: "+15555555555" - poll_interval: 10 + interval: 10 .ft P .fi .UNINDENT .UNINDENT -.sp -poll_interval defaults to 10 seconds .UNINDENT .SS salt.beacons.wtmp .sp @@ -156872,7 +165495,7 @@ The usage of a clear top\-level directory as well as properly named states reduces the overall complexity and leads a user to both understand what will be included at a glance and where it is located. .sp -In addition Formulas should +In addition \fIFormulas\fP should be used as often as possible. .sp \fBNOTE:\fP @@ -156887,7 +165510,7 @@ changes will not take place. .UNINDENT .SS Structuring Pillar Files .sp -Pillars are used to store +\fIPillars\fP are used to store secure and insecure data pertaining to minions. When designing the structure of the \fB/srv/pillar\fP directory, the pillars contained within should once again be focused on clear and concise data which users can easily @@ -157138,7 +165761,7 @@ in the same state as the service and package. .sp In the next example steps will be taken to begin addressing these issues. Starting with the addition of a map.jinja file (as noted in the -Formula documentation), and +\fIFormula documentation\fP), and modification of static values: .sp \fB/srv/salt/apache/map.jinja\fP: @@ -158819,99 +167442,203 @@ has come from, and most importantly, to give credit where credit is due! There are a number of ways to contribute to Salt development. .sp For details on how to contribute documentation improvements please review -Writing Salt Documentation\&. +\fIWriting Salt Documentation\fP\&. .SS Sending a GitHub pull request .sp Sending pull requests on GitHub is the preferred method for receiving contributions. The workflow advice below mirrors \fI\%GitHub\(aqs own guide\fP and is well worth reading. .INDENT 0.0 .IP 1. 3 -Fork the \fI\%saltstack/salt\fP repository on GitHub. +\fI\%Fork saltstack/salt\fP on GitHub. .IP 2. 3 Make a local clone of your fork. -.IP 3. 3 -Create a new branch in your clone. -.sp -A branch should have one purpose. For example, "Fix bug X," or "Add feature -Y." Multiple pull requests should be opened for unrelated changes. -.sp -Choose a name for your branch that describes its purpose. .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C -git checkout \-b fixed\-broken\-thing +git clone git@github.com:my\-account/salt.git +cd salt +.ft P +.fi +.UNINDENT +.UNINDENT +.IP 3. 3 +Add \fI\%saltstack/salt\fP as a git remote. +.INDENT 3.0 +.INDENT 3.5 +.sp +.nf +.ft C +git remote add upstream https://github.com/saltstack/salt.git .ft P .fi .UNINDENT .UNINDENT .IP 4. 3 -Make edits and changes locally. -.IP 5. 3 -Commit changes to this new branch. +Create a new branch in your clone. .sp -Edit the necessary files in your Salt clone and remember to add them to -your commit. Write a descriptive commit message. +\fBNOTE:\fP +.INDENT 3.0 +.INDENT 3.5 +A branch should have one purpose. For example, "Fix bug X," or "Add +feature Y". Multiple unrelated fixes and/or features should be +isolated into separate branches. +.UNINDENT +.UNINDENT +.sp +If you\(aqre working on a fix, create your branch from the oldest release +branch having the bug. See \fI\%Which Salt Branch?\fP\&. .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C -git add path/to/file1 -git add path/to/file2 -git commit \-m "Fixed X in file1 and file2" +git fetch upstream +git checkout \-b fix\-broken\-thing upstream/2015.5 .ft P .fi .UNINDENT .UNINDENT .sp -If you get stuck \fI\%there are many introductory Git resources on -help.github.com\fP\&. -.IP 6. 3 -Push your locally\-committed changes to your GitHub fork. +If you\(aqre working on a feature, create your branch from the develop branch. .INDENT 3.0 .INDENT 3.5 .sp .nf .ft C -git push \-\-set\-upstream origin fixed\-broken\-thing +git fetch upstream +git checkout \-b add\-cool\-feature upstream/develop +.ft P +.fi +.UNINDENT +.UNINDENT +.IP 5. 3 +Edit and commit changes to your branch. +.INDENT 3.0 +.INDENT 3.5 +.sp +.nf +.ft C +vim path/to/file1 path/to/file2 +git diff +git add path/to/file1 path/to/file2 +git commit +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Write a short, descriptive commit title and a longer commit message if +necessary. +.sp +\fBNOTE:\fP +.INDENT 3.0 +.INDENT 3.5 +If your change fixes a bug or implements a feature already filed in the +\fI\%issue tracker\fP, be sure to reference the issue +number in the commit message body. +.UNINDENT +.UNINDENT +.INDENT 3.0 +.INDENT 3.5 +.sp +.nf +.ft C +fix broken things in file1 and file2 + +Fixes #31337. The issue is now eradicated from file1 and file2. + +# Please enter the commit message for your changes. Lines starting +# with \(aq#\(aq will be ignored, and an empty message aborts the commit. +# On branch fix\-broken\-thing +# Changes to be committed: +# modified: path/to/file1 +# modified: path/to/file2 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +If you get stuck, there are many introductory Git resources on +\fI\%http://help.github.com\fP\&. +.IP 6. 3 +Push your locally\-committed changes to your GitHub fork, +.sp +\fBNOTE:\fP +.INDENT 3.0 +.INDENT 3.5 +You may want to rebase before pushing to work out any potential +conflicts. +.UNINDENT +.UNINDENT +.INDENT 3.0 +.INDENT 3.5 +.sp +.nf +.ft C +git fetch upstream +git rebase upstream/2015.5 fix\-broken\-thing +git push \-\-set\-upstream origin fix\-broken\-thing +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +or, +.INDENT 3.0 +.INDENT 3.5 +.sp +.nf +.ft C +git fetch upstream +git rebase upstream/develop add\-cool\-feature +git push \-\-set\-upstream origin add\-cool\-feature .ft P .fi .UNINDENT .UNINDENT .IP 7. 3 -Go to your fork on the GitHub website & find your branch. +Find the branch on your GitHub salt fork. .sp -GitHub automatically displays a button with the text "Compare & pull -request" for recently pushed branches. -.sp -Otherwise click on the "Branches" tab at the top of your fork. A button -with the text "New pull request" will be beside each branch. +\fI\%https://github.com/my\-account/salt/branches/fix\-broken\-thing\fP .IP 8. 3 Open a new pull request. +.sp +Click on \fBPull Request\fP on the right near the top of the page, +.sp +\fI\%https://github.com/my\-account/salt/pull/new/fix\-broken\-thing\fP .INDENT 3.0 .IP 1. 3 -Click one of the pull request buttons from the previous step. GitHub -will present a form and show a comparison of the changes in your pull -request. +If your branch is a fix for a release branch, choose that as the base +branch (e.g. \fB2015.5\fP), +.sp +\fI\%https://github.com/my\-account/salt/compare/saltstack:2015.5...fix\-broken\-thing\fP +.sp +If your branch is a feature, choose \fBdevelop\fP as the base branch, +.sp +\fI\%https://github.com/my\-account/salt/compare/saltstack:develop...add\-cool\-feature\fP .IP 2. 3 -Write a descriptive comment, include links to any project issues -related to the pull request. +Review that the proposed changes are what you expect. .IP 3. 3 -Click "Create pull request". +Write a descriptive comment. Include links to related issues (e.g. +\(aqFixes #31337.\(aq) in the comment field. +.IP 4. 3 +Click \fBCreate pull request\fP\&. .UNINDENT .IP 9. 3 -The Salt repo managers will be notified of your pull request. +Salt project members will review your pull request and automated tests will +run on it. .sp -If a reviewer asks for changes: +If you recognize any test failures as being related to your proposed +changes or if a reviewer asks for modifications: .INDENT 3.0 .IP 1. 3 -Make the changes in your local clone on the same local branch. +Make the new changes in your local clone on the same local branch. .IP 2. 3 -Push the branch to GitHub using the same command as before. +Push the branch to GitHub again using the same commands as before. .IP 3. 3 -The new commits will be reflected in the pull request automatically. +New and updated commits will be added to the pull request automatically. .IP 4. 3 Feel free to add a comment to the discussion. .UNINDENT @@ -158922,33 +167649,31 @@ Feel free to add a comment to the discussion. .INDENT 3.5 Jenkins .sp -Whenever you make a pull request against the main Salt repository your -changes will be tested on a variety of operating systems and -configurations. On average these tests take 30 minutes to run and once -they are complete a PASS/FAIL message will be added to your pull -request. This message contains a link to \fI\%http://jenkins.saltstack.com\fP -where you can review the test results. This message will also generate an -email which will be sent to the email address associated with your GitHub -account informing you of these results. It should be noted that a test -failure does not necessarily mean there is an issue in the associated pull -request as the entire development branch is tested. +Pull request against \fI\%saltstack/salt\fP are automatically tested on a +variety of operating systems and configurations. On average these tests +take 30 minutes. Depending on your GitHub notification settings you may +also receive an email message about the test results. +.sp +Test progress and results can be found at \fI\%http://jenkins.saltstack.com/\fP\&. .UNINDENT .UNINDENT .SS Which Salt branch? .sp -GitHub will open pull requests against Salt\(aqs main branch named \fBdevelop\fP by -default. Most contributors can keep the default options. This section is for -advanced contributors. +GitHub will open pull requests against Salt\(aqs main branch, \fBdevelop\fP, by +default. Ideally features should go into \fBdevelop\fP and bug fixes should go +into the oldest supported release branch affected by the bug. See +\fI\%Sending a GitHub pull request\fP\&. .sp -Each pull request should address a single concern, as mentioned in the section -above. For example, "Fix bug X," or "Add feature Y." And a pull request should -be opened against the branch that corresponds to that concern. +If you have a bug fix and have already forked your working branch from +\fBdevelop\fP and do not know how to rebase your commits against another branch, +then submit it to \fBdevelop\fP anyway and we\(aqll be sure to backport it to the +correct place. .SS The current release branch .sp The current release branch is the most recent stable release. Pull requests containing bug fixes should be made against the release branch. .sp -The branch name will be a date\-based name such as \fB2014.7\fP\&. +The branch name will be a date\-based name such as \fB2015.5\fP\&. .sp Bug fixes are made on this branch so that minor releases can be cut from this branch without introducing surprises and new features. This approach maximizes @@ -159170,7 +167895,7 @@ git rebase \-\-onto bp\-1234 .UNINDENT .UNINDENT .sp -Note, release branches prior to \fB2014.7\fP will not be able to make use of +Note, release branches prior to \fB2015.5\fP will not be able to make use of rebase and must use cherry\-picking instead. .IP 5. 3 Push the back\-port branch to GitHub and open a new pull request. @@ -159188,6 +167913,10 @@ git push \-u origin bp\-1234 .UNINDENT .UNINDENT .UNINDENT +.SS Issue and Pull Request Labeling System +.sp +SaltStack uses several labeling schemes to help facilitate code contributions +and bug resolution. See the \fILabels and Milestones\fP documentation for more information. .SS Deprecating Code .sp Salt should remain backwards compatible, though sometimes, this backwards @@ -160063,6 +168792,332 @@ Run the test suite with following command: .UNINDENT .sp See \fBhere\fP for more information regarding the test suite. +.SS Issue and Pull Request Labeling System +.sp +SaltStack uses several labeling schemes to help facilitate code contributions +and bug resolution. See the \fILabels and Milestones\fP documentation for more information. +.SS GitHub Labels and Milestones +.sp +SaltStack uses several labeling schemes, as well as applying milestones, to triage incoming issues and pull requests in +the GitHub Issue Tracker. Most of the labels and milestones are used for internal tracking, but the following +definitions might prove useful for the community to discover the best issues to help resolve. +.SS Milestones +.sp +Milestones are most often applied to issues, as a milestone is assigned to every issue that has been triaged. However, +milestones can also be applied to pull requests. SaltStack uses milestones to track bugs or features that should be +included in the next major feature release, or even the next bug\-fix release, as well as what issues are ready to be +worked on or what might be blocked. All incoming issues must have a milestone associated with them. +.INDENT 0.0 +.TP +.B Approved +Used to indicate that this issue has all of the needed information and is ready to be worked on. +.TP +.B Blocked +Used to indicate that the issue is not ready to be worked on yet. This typically applies to issues that have been +labeled with “Info Needed”, “Question”, “Expected Behavior”, “Won’t Fix for Now”, etc. +.TP +.B Dot or Bug\-fix Release +Used to help filter/identify what issues must be fixed before the release such as 2014.7.4 or 2015.2.3. This +milestone is often used in conjunction with the \fBBlocker\fP label, but not always. +.TP +.B Feature Release +Similar to the Dot or Bug\-fix Release milestone, but for upcoming feature releases such as Boron, Carbon, etc. +This milestone is often used in conjunction with the \fBBlocker\fP label, but not always. +.UNINDENT +.SS Labels +.sp +Labels are used to facilitate the resolution of new pull requests and open issues. Most labels are confined to being +applied to either issues or pull requests, though some labels may be applied to both. +.SS Issue Labels +.sp +All incoming issues should be triaged with at least one label and a milestone. When a new issue comes in, it should be +determined if the issue is a bug or a feature request, and either of those labels should be applied accordingly. Bugs +and Feature Requests have differing labeling schemes, detailed below, where other labels are applied to them to further +help contributors find issues to fix or implement. +.sp +There are some labels, such as \fBQuestion\fP or some of the "Status" labels that may be applied as "stand alone" labels +in which more information may be needed or a decision must be reached on how to proceed. (See the "Bug Status Labels" +section below.) +.SS Features +.sp +The \fBFeature\fP label should be applied when a user is requesting entirely new functionality. This can include new +functions, modules, states, modular systems, flags for existing functions, etc. Features \fIdo not\fP receive severity +or priority labels, as those labels are only used for bugs. However, they may receive "Functional Area" labels or "ZD". +.sp +Feature request issues will be prioritized on an "as\-needed" basis using milestones during SaltStack\(aqs feature release +and sprint planning processes. +.SS Bugs +.sp +All bugs should have the \fBBug\fP label as well as a severity, priority, functional area, and a status, as applicable. +.SS Severity +.sp +How severe is the bug? SaltStack uses four labels to determine the severity of a bug: \fBBlocker\fP, \fBCritical\fP, +\fBHigh\fP, and \fBMedium\fP\&. This scale is intended to make the bug\-triage process as objective as possible. +.INDENT 0.0 +.TP +.B Blocker +Should be used sparingly to indicate must\-have fixes for the impending release. +.TP +.B Critical +Applied to bugs that have data loss, crashes, hanging, unresponsive system, etc. +.TP +.B High Severity +Any bug report that contains incorrect functionality, bad functionality, a confusing user experience, etc. +.TP +.B Medium Severity +Applied to bugs that are about cosmetic items, spelling, spacing, colors, etc. +.UNINDENT +.SS Priority +.sp +In addition to using a bug severity to classify issues, a priority is also assigned to each bug to give further +granularity in searching for bugs to fix. In this way, a bug\(aqs priority is defined as follows: +.INDENT 0.0 +.TP +.B P1 +Very likely. Everyone will see the bug. +.TP +.B P2 +Somewhat likely. Most will see the bug, but a few will not. +.TP +.B P3 +Half will see the bug, about half will not. +.TP +.B P4 +Most will not see the bug. Usually a very specific use case or corner case. +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +A bug\(aqs priority is relative to its functional area. If a bug report, for example, about \fBgitfs\fP includes details +indicating that everyone who \fBgitfs\fP will run into this bug, then a \fBP1\fP label will be applied, even though +Salt users who are not enabling \fBgitfs\fP will see the bug. +.UNINDENT +.UNINDENT +.SS Functional Areas +.sp +All bugs should receive a "Functional Area" label to indicate what region of Salt the bug is mainly seen in. This will +help internal developers as well as community members identify areas of expertise to find issues that can be fixed more +easily. Functional Area labels can also be applied to Feature Requests. +.sp +Functional Area Labels, in alphabetical order, include: +.INDENT 0.0 +.IP \(bu 2 +Core +.IP \(bu 2 +Documentation +.IP \(bu 2 +Execution Module +.IP \(bu 2 +File Servers +.IP \(bu 2 +Multi\-Master +.IP \(bu 2 +Packaging +.IP \(bu 2 +Pillar +.IP \(bu 2 +Platform Mgmt. +.IP \(bu 2 +RAET +.IP \(bu 2 +Returners +.IP \(bu 2 +Salt\-API +.IP \(bu 2 +Salt\-Cloud +.IP \(bu 2 +Salt\-SSH +.IP \(bu 2 +Salt\-Syndic +.IP \(bu 2 +State Module +.IP \(bu 2 +Windows +.IP \(bu 2 +ZMQ +.UNINDENT +.SS Bug Status Labels +.sp +Status lables are used to define and track the state a bug is in at any given time. Not all bugs will have a status +label, but if a SaltStack employee is able to apply a status label, he or she will. Status labels are somewhat unique +in the fact that they might be the only label on an issue, such as \fBPending Discussion\fP, \fBInfo Needed\fP, or +\fBExpected Behavior\fP until further action can be taken. +.INDENT 0.0 +.TP +.B Cannot Reproduce +Someone from the SaltStack team has tried to reproduce the bug with the given information but they are unable to +replicate the problem. More information will need to be provided from the original issue\-filer before proceeding. +.TP +.B Confirmed +A SaltStack engineer has confirmed the reported bug and provided a simple way to reproduce the failure. +.TP +.B Duplicate +The issue has been reported already in another report. A link to the other bug report must be provided. At that +point the new issue can be closed. Usually, the earliest bug on file is kept as that typically has the most +discussion revolving around the issue, though not always. (This can be a "stand\-alone" label.) +.TP +.B Expected Behavior +The issue reported is expected behavior and nothing needs to be fixed. (This can be a "stand\-alone" label.) +.TP +.B Fixed Pending Verification +The bug has been fixed and a link to the applicable pull request(s) has been provided, but confirmation is being +sought from the community member(s) involved in the bug to test and confirm the fix. +.TP +.B Info Needed +More information about the issue is needed before proceeding such as a versions report, a sample state, the command +the user was running, or the operating system the error was occurring on, etc. (This can be a "stand\-alone" label.) +.TP +.B Upstream Bug +The reported bug is something that cannot be fixed in the Salt code base but is instead a bug in another library +such a bug in ZMQ or Python. When an issue is labeled with \fBUpstream Bug\fP then a bug report in the upstream +project must be filed (or found if a report already exists) and a link to the report must be provided to the issue +in Salt for tracking purposes. (This can be a stand\-alone label.) +.TP +.B Won\(aqt Fix for Now +The SaltStack team has acknowledged the issue at hand is legitimate, but made the call that it’s not something +they’re able or willing to fix at this time. These issues may be revisited in the future. +.UNINDENT +.SS Other +.sp +There are a couple of other labels that are helpful in categorizing bugs that are not included in the categories above. +These labels can either stand on their own such as \fBQuestion\fP or can be applied to bugs or feature requests as +applicable. +.INDENT 0.0 +.TP +.B Low Hanging Fruit +Applied to bugs that should be easy to fix. This is useful for new contributors to know where some simple things +are to get involved in contributing to salt. +.TP +.B Question +Used when the issue isn’t a bug nor a feature, but the user has a question about expected behavior, how something +works, is misunderstanding a concept, etc. This label is typically applied on its own with \fBBlocked\fP milestone. +.TP +.B Regression +Helps with additional filtering for bug fixing. If something previously worked and now does not work, as opposed to +something that never worked in the first place, the issue should be treated with greater urgency. +.TP +.B ZD +Stands for “Zendesk” and is used to help track bugs that customers are seeing as well as community members. Bugs +with this label should be treated with greater urgency. +.UNINDENT +.SS Pull Request Labels +.sp +SaltStack also applies various labels to incoming pull requests. These are mainly used to help SaltStack engineers +easily identify the nature the changes presented in a pull request and whether or not that pull request is ready to be +reviewed and merged into the Salt codebase. +.SS Type of Change +.sp +A "* Change" label is applied to each incoming pull request. The type of change label that is applied to a pull request +is based on a scale that encompasses the number of lines affected by the change in conjunction with the area of code +the change touches (i.e. core code areas vs. execution or state modules). +.sp +The conditions given for these labels are recommendations, as the pull request reviewer will also consult their +intuition and experience regarding the magnitude of the impact of the proposed changes in the pull request. +.sp +Core code areas include: state compiler, crypto engine, master and minion, transport, pillar rendering, loader, +transport layer, event system, salt.utils, client, cli, logging, netapi, runner engine, templating engine, top file +compilation, file client, file server, mine, salt\-ssh, test runner, etc. +.INDENT 0.0 +.IP \(bu 2 +.INDENT 2.0 +.TP +.B Minor Change +.INDENT 7.0 +.IP \(bu 2 +Less than 64 lines changed, or +.IP \(bu 2 +Less than 8 core lines changed +.UNINDENT +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +.B Medium Change +.INDENT 7.0 +.IP \(bu 2 +Less than 256 lines changed, or +.IP \(bu 2 +Less than 64 core lines changed +.UNINDENT +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +.B Master Change +.INDENT 7.0 +.IP \(bu 2 +More than 256 lines changed, or +.IP \(bu 2 +More than 64 core lines changed +.UNINDENT +.UNINDENT +.IP \(bu 2 +.INDENT 2.0 +.TP +.B Expert Change +.INDENT 7.0 +.IP \(bu 2 +Needs specialized, in\-depth review +.UNINDENT +.UNINDENT +.UNINDENT +.SS Back\-port Labels +.sp +There are two labels that are used to keep track of what pull requests need to be back\-ported to an older release branch +and which pull requests have already been back\-ported. +.INDENT 0.0 +.TP +.B Bugfix \- back\-port +Indicates a pull request that needs to be back\-ported. Once the back\-port is completed, the back\-porting pull request +is linked to the original pull request and this label is removed. +.TP +.B Bugfix \- [Done] back\-ported +Indicates a pull request that has been back\-ported to another branch. The pull request that is responsible for the +backport should be linked to this original pull request. +.UNINDENT +.SS Testing Labels +.sp +There are a couple of labels that the QA team uses to indicate the mergability of a pull request. If the pull request is +legitimately passing or failing tests, then one or more of these labels may be applied. +.INDENT 0.0 +.TP +.B Lint +If a pull request fails the test run, but the only failures are related pylint errors, this label will be applied to +indicate that pylint needs to be fixed before proceeding. +.TP +.B Pending Changes +Indicates that additional commits should be added to the original pull request before the pull request is merged +into the codebase. These changes are unrelated to fixing tests and are generally needed to round out any unfinished +pull requests. +.TP +.B Tests Passed +Sometimes the Jenkins test run encounters problems, either tests that are known to have reliability issues or a +test VM failed to build, but the problems are not related to the code changed in the pull request. This label is +used to indicate that someone has reviewed the test failures and has deemed the failures to be non\-pertinent. +.UNINDENT +.SS Other Pull Request Labels +.INDENT 0.0 +.TP +.B Awesome +Applied to pull requests that implemented a cool new feature or fixed a bug in an excellent way. +.UNINDENT +.SS Labels that Bridge Issues and Pull Requests +.INDENT 0.0 +.TP +.B Needs Testcase +Used by SaltStack\(aqs QA team to realize where pain points are and to bring special attention to where some test +coverage needs to occur, especially in areas that have regressed. This label can apply to issues or pull requests, +which can also be open or closed. Once tests are written, the pull request containing the tests should be linked to +the issue or pull request that originally had the \fBNeeds Testcase\fP label. At this point, the \fBNeeds Testcase\fP +label must be removed to indicate that tests no longer need to be written. +.TP +.B Pending Discussion +If this label is applied to an issue, the issue may or may not be a bug. Enough information was provided about the +issue, but some other opinions on the issue are desirable before proceeding. (This can be a "stand\-alone" label.) +If the label is applied to a pull request, this is used to signal that further discussion must occur before a +decision is made to either merge the pull request into the code base or to close it all together. +.UNINDENT .SS Logging Internals .sp TODO @@ -160921,7 +169976,7 @@ To run tests marked as destructive, set the \fB\-\-run\-destructive\fP flag: .SS Running Cloud Provider Tests .sp Salt\(aqs testing suite also includes integration tests to assess the successful -creation and deletion of cloud instances using Salt\-Cloud for +creation and deletion of cloud instances using \fISalt\-Cloud\fP for providers supported by Salt\-Cloud. .sp The cloud provider tests are off by default and run on sample configuration files @@ -161050,7 +170105,7 @@ including past and current release branches. For a full list of currently running test environments, go to \fI\%http://jenkins.saltstack.com\fP\&. .SS Using Salt\-Cloud on Jenkins .sp -For testing Salt on Jenkins, SaltStack uses Salt\-Cloud to +For testing Salt on Jenkins, SaltStack uses \fISalt\-Cloud\fP to spin up virtual machines. The script using Salt\-Cloud to accomplish this is open source and can be found here: \fI\%https://github.com/saltstack/salt/blob/develop/tests/jenkins.py\fP .SS Writing Tests @@ -161390,7 +170445,7 @@ class DestructiveExampleModuleTest(integration.ModuleCase): .UNINDENT .SS Cloud Provider Tests .sp -Cloud provider integration tests are used to assess Salt\-Cloud\(aqs +Cloud provider integration tests are used to assess \fISalt\-Cloud\fP\(aqs ability to create and destroy cloud instances for various supported cloud providers. Cloud provider tests inherit from the ShellCase Integration Class. .sp @@ -162052,6 +171107,13 @@ if __name__ == \(aq__main__\(aq: .sp # RAET # Reliable Asynchronous Event Transport Protocol +.sp +\fBSEE ALSO:\fP +.INDENT 0.0 +.INDENT 3.5 +\fIRAET Overview\fP +.UNINDENT +.UNINDENT .SS Protocol .sp Layering: @@ -162602,7 +171664,7 @@ def myfunction(value, strip=False): .SS Adding module documentation to the index .sp Each module type has an index listing all modules of that type. For example: -all\-salt.modules, all\-salt.states, all\-salt.renderers\&. +\fIall\-salt.modules\fP, \fIall\-salt.states\fP, \fIall\-salt.renderers\fP\&. New modules must be added to the index manually. .INDENT 0.0 .IP 1. 3 @@ -162840,7 +171902,7 @@ One design goal of Salt\(aqs GitFS fileserver backend was to facilitate reusable States. GitFS is a quick and natural way to use Formulas. .INDENT 0.0 .IP 1. 3 -Install and configure GitFS\&. +\fIInstall and configure GitFS\fP\&. .IP 2. 3 Add one or more Formula repository URLs as remotes in the \fBgitfs_remotes\fP list in the Salt Master configuration file: @@ -162989,15 +172051,15 @@ base: .sp Salt Formulas are designed to work out of the box with no additional configuration. However, many Formula support additional configuration and -customization through Pillar\&. Examples of available options can +customization through \fIPillar\fP\&. Examples of available options can be found in a file named \fBpillar.example\fP in the root directory of each Formula repository. .SS Using Formula with your own states .sp Remember that Formula are regular Salt States and can be used with all Salt\(aqs normal state mechanisms. Formula can be required from other States with -requisites\-require declarations, they can be modified using \fBextend\fP, -they can made to watch other states with requisites\-watch\-in\&. +\fIrequisites\-require\fP declarations, they can be modified using \fBextend\fP, +they can made to watch other states with \fIrequisites\-watch\-in\fP\&. .sp The following example uses the stock \fI\%apache\-formula\fP alongside a custom state to create a vhost on a Debian/Ubuntu system and to reload the @@ -163075,8 +172137,8 @@ deploy_myapp: .SS Use a descriptive State ID .sp The ID of a state is used as a unique identifier that may be referenced via -other states in requisites\&. It must be unique across the -whole state tree (it is a key in a dictionary, after +other states in \fIrequisites\fP\&. It must be unique across the +whole state tree (\fIit is a key in a dictionary\fP, after all). .sp In addition a state ID should be descriptive and serve as a high\-level hint of @@ -163109,14 +172171,14 @@ apache: .UNINDENT .sp Salt\(aqs state compiler will transform "short\-decs" into the longer format -when compiling the human\-friendly highstate structure into the -machine\-friendly lowstate structure\&. +\fIwhen compiling the human\-friendly highstate structure into the +machine\-friendly lowstate structure\fP\&. .SS Specify the \fBname\fP parameter .sp Use a unique and permanent identifier for the state ID and reserve \fBname\fP for data with variability. .sp -The name declaration is a required parameter for all +The \fIname declaration\fP is a required parameter for all state functions. The state ID will implicitly be used as \fBname\fP if it is not explicitly set in the state. .sp @@ -163208,9 +172270,9 @@ variables or interact. .IP \(bu 2 Whatever the Jinja step produces must be valid YAML. .IP \(bu 2 -Whatever the YAML step produces must be a valid highstate data -structure\&. (This is also true of the final step -for any of the alternate renderers in Salt.) +Whatever the YAML step produces must be a valid \fIhighstate data +structure\fP\&. (This is also true of the final step +for \fIany of the alternate renderers\fP in Salt.) .IP \(bu 2 Highstate can be thought of as a human\-friendly data structure; easy to write and easy to read. @@ -163456,7 +172518,7 @@ read it will be hard to maintain \-\- switch to a format that is easier to read. .sp Using alternate renderers is very simple to do using Salt\(aqs "she\-bang" syntax at the top of the file. The Python renderer must simply return the correct -highstate data structure\&. The following +\fIhighstate data structure\fP\&. The following example is a state tree of two sls files, one simple and one complicated. .sp \fB/srv/salt/top.sls\fP: @@ -163590,10 +172652,11 @@ php_ini: .sp .nf .ft C -PHP: - engine: \(aqOn\(aq - short_open_tag: \(aqOff\(aq - error_reporting: \(aqE_ALL & ~E_DEPRECATED & ~E_STRICT\(aq +php_ini: + PHP: + engine: \(aqOn\(aq + short_open_tag: \(aqOff\(aq + error_reporting: \(aqE_ALL & ~E_DEPRECATED & ~E_STRICT\(aq .ft P .fi .UNINDENT @@ -163607,8 +172670,8 @@ PHP: .ft C {% macro php_ini_serializer(data) %} {% for section_name, name_val_pairs in data.items() %} -[{{ section }}] -{% for name, val in name_val_pairs.items() %} +[{{ section_name }}] +{% for name, val in name_val_pairs.items() \-%} {{ name }} = "{{ val }}" {% endfor %} {% endfor %} @@ -163912,7 +172975,7 @@ appX: .sp .nf .ft C -{% load_yaml \(aqtomcat/defaults.yaml\(aq as server_xml_defaults %} +{% import_yaml \(aqtomcat/defaults.yaml\(aq as server_xml_defaults %} {% set server_xml_final_values = salt.pillar.get( \(aqappX:server_xml_overrides\(aq, default=server_xml_defaults, @@ -163960,7 +173023,7 @@ example: .nf .ft C {# Load the map file. #} -{% load_yaml \(aqapp/defaults.yaml\(aq as app_defaults %} +{% import_yaml \(aqapp/defaults.yaml\(aq as app_defaults %} {# Extract the relevant subset for the app configured on the current machine (configured via a grain in this example). #} @@ -164017,7 +173080,7 @@ installing Apache. It should not perform additional changes such as set the Apache configuration file or create vhosts. .sp If a formula is single\-purpose as in the example above, other formulas, and -also other states can \fBinclude\fP and use that formula with requisites +also other states can \fBinclude\fP and use that formula with \fIrequisites\fP without also including undesirable or unintended side\-effects. .sp The following is a best\-practice example for a reusable Apache formula. (This @@ -164162,7 +173225,7 @@ Pillar to make any desired changes. .SS Scripting .sp Remember that both State files and Pillar files can easily call out to Salt -execution modules and have access to all the system +\fIexecution modules\fP and have access to all the system grains as well. .INDENT 0.0 .INDENT 3.5 @@ -164181,7 +173244,7 @@ grains as well. .UNINDENT .sp Jinja macros to encapsulate logic or conditionals are discouraged in favor of -writing custom execution modules in Python. +\fIwriting custom execution modules\fP in Python. .SS Repository structure .sp A basic Formula repository should have the following layout: @@ -165067,507 +174130,4433 @@ double check before committing fixes. See the \fBversion numbers\fP page for more information about the version numbering scheme. .SS Latest Stable Release -.SS Salt 2014.7.0 Release Notes \- Codename Helium .sp -This release is the largest Salt release ever, with more features and commits -then any previous release of Salt. Everything from the new RAET transport to -major updates in Salt Cloud and the merging of Salt API into the main project. -.sp -\fBIMPORTANT:\fP -.INDENT 0.0 -.INDENT 3.5 -The Fedora/RHEL/CentOS \fBsalt\-master\fP package has been modified for this -release. The following components of Salt have been broken out and placed -into their own packages: -.INDENT 0.0 -.IP \(bu 2 -salt\-syndic -.IP \(bu 2 -salt\-cloud -.IP \(bu 2 -salt\-ssh -.UNINDENT -.sp -When the \fBsalt\-master\fP package is upgraded, these components will be -removed, and they will need to be manually installed. -.UNINDENT -.UNINDENT -.sp -\fBIMPORTANT:\fP -.INDENT 0.0 -.INDENT 3.5 -Compound/pillar matching have been temporarily disabled for the \fBmine\fP -and \fBpublish\fP modules for this release due to the possibility of -inferring pillar data using pillar glob matching. A proper fix is now in -the 2014.7 branch and scheduled for the 2014.7.1 release, and compound -matching and non\-globbing pillar matching will be re\-enabled at that point. -.sp -Compound and pillar matching for normal salt commands are unaffected. -.UNINDENT -.UNINDENT -.SS New Transport! -.SS RAET Transport Option -.sp -This has been a HUGE amount of work, but the beta release of Salt with RAET is -ready to go. RAET is a reliable queuing transport system that has been -developed in partnership with a number of large enterprises to give Salt an -alternative to ZeroMQ and a way to get Salt to scale well beyond tens of -thousands of servers. Unlike ZeroMQ, RAET is completely asynchronous in every -aspect of its operation and has been developed using the flow programming -paradigm. This allows for many new capabilities to be added to Salt in the -upcoming releases. -.sp -Please keep in mind that this is a beta release of RAET and we hope for bugs to -be worked out, performance to be better realized and more in the 2015.5.0 -release. -.sp -Simply stated, users running Salt with RAET should expect some hiccups as we -hammer out the update. This is a BETA release of Salt RAET. -.sp -For information about how to use Salt with RAET please see the -\fBtutorial\fP\&. -.SS Salt SSH Enhancements -.sp -Salt SSH has just entered a new league, with substantial updates and -improvements to make salt\-ssh more reliable and easier then ever! From new -features like the ansible roster and fileserver backends to the new pypi -salt\-ssh installer to lowered deps and a swath of bugfixes, salt\-ssh is -basically reborn! -.SS Install salt\-ssh Using pip -.sp -Salt\-ssh is now pip\-installable! -.sp -\fI\%https://pypi.python.org/pypi/salt\-ssh/\fP -.sp -Pip will bring in all of the required deps, and while some deps are compiled, -they all include pure python implementations, meaning that any compile errors -which may be seen can be safely ignored. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -pip install salt\-ssh -.ft P -.fi -.UNINDENT -.UNINDENT -.SS Fileserver Backends -.sp -Salt\-ssh can now use the salt fileserver backend system. This allows for -the gitfs, hgfs, s3, and many more ways to centrally store states to be easily -used with salt\-ssh. This also allows for a distributed team to easily use -a centralized source. -.SS Saltfile Support -.sp -The new saltfile system makes it easy to have a user specific custom extended -configuration. -.SS Ext Pillar -.sp -Salt\-ssh can now use the external pillar system. Making it easier then ever -to use salt\-ssh with teams. -.SS No More sshpass -.sp -Thanks to the enhancements in the salt vt system, salt\-ssh no longer requires -sshpass to send passwords to ssh. This also makes the manipulation of ssh -calls substantially more flexible, allowing for intercepting ssh calls in -a much more fluid way. -.SS Pure Python Shim -.sp -The salt\-ssh call originally used a shell script to discover what version of -python to execute with and determine the state of the ssh code deployment. -This shell script has been replaced with a pure python version making it easy -to increase the capability of the code deployment without causing platform -inconsistency issues with different shell interpreters. -.SS Custom Module Delivery -.sp -Custom modules are now seamlessly delivered. This makes the deployment of -custom grains, states, execution modules and returners a seamless process. -.SS CP Module Support -.sp -Salt\-ssh now makes simple file transfers easier then ever! The \fIcp\fP -module allows for files to be conveniently sent from the salt fileserver -system down to systems. -.SS More Thin Directory Options -.sp -Salt ssh functions by copying a subset of the salt code, or \fIsalt thin\fP down -to the target system. In the past this was always transferred to /tmp/.salt -and cached there for subsequent commands. -.sp -Now, salt thin can be sent to a random directory and removed when the call -is complete with the \fI\-W\fP option. The new \fI\-W\fP option still uses a static -location but will clean up that location when finished. -.sp -The default \fIsalt thin\fP location is now user defined, allowing multiple users -to cleanly access the same systems. -.SS State System Enhancements -.SS New Imperative State Keyword "Listen" -.sp -The new \fBlisten\fP and \fBlisten_in\fP keywords allow for completely imperative -states by calling the \fBmod_watch()\fP routine after all states have run instead -of re\-ordering the states. -.SS Mod Aggregate Runtime Manipulator -.sp -The new \fBmod_aggregate\fP system allows for the state system to rewrite the -state data during execution. This allows for state definitions to be aggregated -dynamically at runtime. -.sp -The best example is found in the \fBpkg\fP state. If -\fBmod_aggregate\fP is turned on, then when the first pkg state is reached, the -state system will scan all of the other running states for pkg states and take -all other packages set for install and install them all at once in the first -pkg state. -.sp -These runtime modifications make it easy to run groups of states together. In -future versions, we hope to fill out the \fBmod_aggregate\fP system to build in -more and more optimizations. -.sp -For more documentation on \fBmod_aggregate\fP, see \fBthe documentation\fP\&. -.SS New Requisites: onchanges and onfail -.sp -The new \fBonchanges\fP and \fBonchanges_in\fP requisites make a state apply only if -there are changes in the required state. This is useful to execute post hooks -after changes occur on a system. -.sp -The other new requisites, \fBonfail\fP, and \fBonfail_in\fP, allow for a state to run -in reaction to the failure of another state. -.sp -For more information about these new requisites, see the -\fBrequisites documentation\fP\&. -.SS Global onlyif and unless -.sp -The \fBonlyif\fP and \fBunless\fP options can now be used for any state declaration. -.SS Use \fBnames\fP to expand and override values -.sp -The names declaration in Salt\(aqs state system can now -override or add values to the expanded data structure. For example: -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -my_users: - user.present: - \- names: - \- larry - \- curly - \- moe: - \- shell: /bin/zsh - \- groups: - \- wheel - \- shell: /bin/bash -.ft P -.fi -.UNINDENT -.UNINDENT -.SS Major Features -.SS Scheduler Additions -.sp -The Salt scheduler system has received MAJOR enhancements, allowing for -cron\-like scheduling and much more granular timing routines. See \fBhere\fP for more info. -.SS Red Hat 7 Family Support -.sp -All the needed additions have been made to run Salt on RHEL 7 and derived OSes -like CentOS and Scientific. -.SS Fileserver Backends in salt\-call -.sp -Fileserver backends like gitfs can now be used without a salt master! Just add -the fileserver backend configuration to the minion config and execute -salt\-call. This has been a much\-requested feature and we are happy to finally -bring it to our users. -.SS Amazon Execution Modules -.sp -An entire family of execution modules further enhancing Salt\(aqs Amazon Cloud -support. They include the following: -.INDENT 0.0 -.IP \(bu 2 -\fBAutoscale Groups\fP (includes \fBstate support\fP) \-\- related: \fBLaunch Control\fP states -.IP \(bu 2 -\fBCloud Watch\fP (includes \fBstate support\fP) -.IP \(bu 2 -\fBElastic Cache\fP (includes \fBstate support\fP) -.IP \(bu 2 -\fBElastic Load Balancer\fP (includes \fBstate support\fP) -.IP \(bu 2 -\fBIAM Identity and Access Management\fP (includes \fBstate support\fP) -.IP \(bu 2 -\fBRoute53 DNS\fP (includes \fBstate support\fP) -.IP \(bu 2 -\fBSecurity Groups\fP (includes \fBstate support\fP) -.IP \(bu 2 -\fBSimple Queue Service\fP (includes \fBstate support\fP) -.UNINDENT -.SS LXC Runner Enhancements -.sp -BETA -The Salt LXC management system has received a number of enhancements which make -running an LXC cloud entirely from Salt an easy proposition. -.SS Next Gen Docker Management -.sp -The Docker support in Salt has been increased at least ten fold. The Docker API -is now completely exposed and Salt ships with Docker data tracking systems -which make automating Docker deployments very easy. -.SS Peer System Performance Improvements -.sp -The peer system communication routines have been refined to make the peer -system substantially faster. -.SS SDB -.sp -Encryption at rest for configs -.SS GPG Renderer -.sp -Encrypted pillar at rest -.SS OpenStack Expansion -.sp -Lots of new OpenStack stuff -.SS Queues System -.sp -Ran change external queue systems into Salt events -.SS Multi Master Failover Additions -.sp -Connecting to multiple masters is more dynamic then ever -.SS Chef Execution Module -.sp -Managing Chef with Salt just got even easier! -.SS salt\-api Project Merge -.sp -The \fBsalt\-api\fP project has been merged into Salt core and is now available as -part of the regular \fBsalt\-master\fP package install. No API changes were made, -the \fBsalt\-api\fP script and init scripts remain intact. -.sp -\fBsalt\-api\fP has always provided Yet Another Pluggable Interface to Salt (TM) -in the form of "netapi" modules. These are modules that bind to a port and -start a service. Like many of Salt\(aqs other module types, netapi modules often -have library and configuration dependencies. See the documentation for each -module for instructions. -.sp -\fBSEE ALSO:\fP -.INDENT 0.0 -.INDENT 3.5 -The full list of netapi modules. -.UNINDENT -.UNINDENT -.SS Synchronous and Asynchronous Execution of Runner and Wheel Modules -.sp -\fBsalt.runner.RunnerClient\fP and \fBsalt.wheel.WheelClient\fP -have both gained complimentary \fBcmd_sync\fP and \fBcmd_async\fP methods allowing -for synchronous and asynchronous execution of any Runner or Wheel module -function, all protected using Salt\(aqs external authentication -system. \fBsalt\-api\fP benefits from this addition as well. -.SS \fBrest_cherrypy\fP Additions -.sp -The \fBrest_cherrypy\fP netapi module -provides the main REST API for Salt. -.SS Web Hooks -.sp -This release of course includes the Web Hook additions from the most recent -\fBsalt\-api\fP release, which allows external services to signal actions within a -Salt infrastructure. External services such as Amazon SNS, Travis\-CI, or -GitHub, as well as internal services that cannot or should not run a Salt -minion daemon can be used as first\-class components in Salt\(aqs rich -orchestration capabilities. -.sp -The raw HTTP request body is now available in the event data. This is sometimes -required information for checking an HMAC signature in order to verify a HTTP -request. As an example, Amazon or GitHub requests are signed this way. -.SS Generating and Accepting Minion Keys -.sp -The \fB/key\fP convenience URL -generates a public and private key for a minion, automatically pre\-accepts the -public key on the Salt Master, and returns both keys as a tarball for download. -.sp -This allows for easily bootstrapping the key on a new minion with a single HTTP -call, such as with a Kickstart script, all using regular shell tools. -.INDENT 0.0 -.INDENT 3.5 -.sp -.nf -.ft C -curl \-sS http://salt\-api.example.com:8000/keys \e - \-d mid=jerry \e - \-d username=kickstart \e - \-d password=kickstart \e - \-d eauth=pam \e - \-o jerry\-salt\-keys.tar -.ft P -.fi -.UNINDENT -.UNINDENT -.SS Fileserver Backend Enhancements -.sp -All of the fileserver backends have been overhauled to be faster, lighter, and -more reliable. The VCS backends (\fBgitfs\fP, -\fBhgfs\fP, and \fBsvnfs\fP) -have also received a \fBlot\fP of new features. -.sp -Additionally, most config parameters for the VCS backends can now be configured -on a per\-remote basis, allowing for global config parameters to be overridden -for a specific gitfs/hgfs/svnfs remote. -.SS New \fBgitfs\fP Features -.SS Pygit2 and Dulwich -.sp -In addition to supporting GitPython, support for \fI\%pygit2\fP (0.20.3 and newer) and -\fI\%dulwich\fP have been added. Provided a compatible version of \fI\%pygit2\fP is -installed, it will now be the default provider. The config parameter -\fBgitfs_provider\fP has been added to allow one to choose a specific -provider for gitfs. -.SS Mountpoints -.sp -Prior to this release, to serve a file from gitfs at a salt fileserver URL of -\fBsalt://foo/bar/baz.txt\fP, it was necessary to ensure that the parent -directories existed in the repository. A new config parameter -\fBgitfs_mountpoint\fP allows gitfs remotes to be exposed starting at -a user\-defined \fBsalt://\fP URL. -.SS Environment Whitelisting/Blacklisting -.sp -By default, gitfs will expose all branches and tags as Salt fileserver -environments. Two new config parameters, \fBgitfs_env_whitelist\fP, and -\fBgitfs_env_blacklist\fP, allow more control over which branches and -tags are exposed. More detailed information on how these two options work can -be found in the Gitfs Walkthrough\&. -.SS Expanded Authentication Support -.sp -As of \fI\%pygit2\fP 0.20.3, both http(s) and SSH key authentication are supported, -and Salt now also supports both authentication methods when using \fI\%pygit2\fP\&. Keep -in mind that \fI\%pygit2\fP 0.20.3 is not yet available on many platforms, so those -who had been using authenticated git repositories with a passphraseless key -should stick to GitPython if a new enough \fI\%pygit2\fP is not yet available for the -platform on which the master is running. -.sp -A full explanation of how to use authentication can be found in the Gitfs -Walkthrough\&. -.SS New \fBhgfs\fP Features -.SS Mountpoints -.sp -This feature works exactly like its \fI\%gitfs counterpart\fP\&. The new config parameter is called -\fBhgfs_mountpoint\fP\&. -.SS Environment Whitelisting/Blacklisting -.sp -This feature works exactly like its \fI\%gitfs counterpart\fP\&. The new config parameters are called -\fBhgfs_env_whitelist\fP and \fBhgfs_env_blacklist\fP\&. -.SS New \fBsvnfs\fP Features -.SS Mountpoints -.sp -This feature works exactly like its \fI\%gitfs counterpart\fP\&. The new config parameter is called -\fBsvnfs_mountpoint\fP\&. -.SS Environment Whitelisting/Blacklisting -.sp -This feature works exactly like its \fI\%gitfs counterpart\fP\&. The new config parameters are called -\fBsvnfs_env_whitelist\fP and \fBsvnfs_env_blacklist\fP\&. -.SS Configurable Trunk/Branches/Tags Paths -.sp -Prior to this release, the paths where trunk, branches, and tags were located -could only be in directores named "trunk", "branches", and "tags" directly -under the root of the repository. Three new config parameters -(\fBsvnfs_trunk\fP, \fBsvnfs_branches\fP, and -\fBsvnfs_tags\fP) allow SVN repositories which are laid out -differently to be used with svnfs. -.SS New \fBminionfs\fP Features -.SS Mountpoint -.sp -This feature works exactly like its \fI\%gitfs counterpart\fP\&. The new config parameter is called -\fBminionfs_mountpoint\fP\&. The one major difference is that, as -minionfs doesn\(aqt use multiple remotes (it just serves up files pushed to the -master using \fBcp.push\fP) there is no such thing as a -per\-remote configuration for \fBminionfs_mountpoint\fP\&. -.SS Changing the Saltenv from Which Files are Served -.sp -A new config parameter (\fBminionfs_env\fP) allows minionfs files to -be served from a Salt fileserver environment other than \fBbase\fP\&. -.SS Minion Whitelisting/Blacklisting -.sp -By default, minionfs will expose the pushed files from all minions. Two new -config parameters, \fBminionfs_whitelist\fP, and -\fBminionfs_blacklist\fP, allow minionfs to be restricted to serve -files from only the desired minions. -.SS Pyobjects Renderer -.sp -Salt now ships with with the \fBPyobjects Renderer\fP that allows for construction of States using pure -Python with an idiomatic object interface. -.SS New Modules -.sp -In addition to the Amazon modules mentioned above, there are also several other -new execution modules: -.INDENT 0.0 -.IP \(bu 2 -\fBOracle\fP -.IP \(bu 2 -\fBRandom\fP -.IP \(bu 2 -\fBRedis\fP -.IP \(bu 2 -\fBAmazon Simple Queue Service\fP -.IP \(bu 2 -\fBBlock Device Management\fP -.IP \(bu 2 -\fBCoreOS etcd\fP -.IP \(bu 2 -\fBGenesis\fP -.IP \(bu 2 -\fBInfluxDB\fP -.IP \(bu 2 -\fBServer Density\fP -.IP \(bu 2 -\fBTwilio Notifications\fP -.IP \(bu 2 -\fBVarnish\fP -.IP \(bu 2 -\fBZNC IRC Bouncer\fP -.IP \(bu 2 -\fBSMTP\fP -.UNINDENT -.SS New Runners -.INDENT 0.0 -.IP \(bu 2 -\fBMap/Reduce Style\fP -.IP \(bu 2 -\fBQueue\fP -.UNINDENT -.SS New External Pillars -.INDENT 0.0 -.IP \(bu 2 -\fBCoreOS etcd\fP -.UNINDENT -.SS New Salt\-Cloud Providers -.INDENT 0.0 -.IP \(bu 2 -\fBAliyun ECS Cloud\fP -.IP \(bu 2 -\fBLXC Containers\fP -.IP \(bu 2 -\fBProxmox (OpenVZ containers & KVM)\fP -.UNINDENT -.SS Salt Call Change -.sp -When used with a returner, salt\-call now contacts a master if \fB\-\-local\fP -is not specicified. -.SS Deprecations -.SS \fBsalt.modules.virtualenv_mod\fP -.INDENT 0.0 -.IP \(bu 2 -Removed deprecated \fBmemoize\fP function from \fBsalt/utils/__init__.py\fP (deprecated) -.IP \(bu 2 -Removed deprecated \fBno_site_packages\fP argument from \fBcreate\fP function (deprecated) -.IP \(bu 2 -Removed deprecated \fBcheck_dns\fP argument from \fBminion_config\fP and \fBapply_minion_config\fP functions (deprecated) -.IP \(bu 2 -Removed deprecated \fBOutputOptionsWithTextMixIn\fP class from \fBsalt/utils/parsers.py\fP (deprecated) -.IP \(bu 2 -Removed the following deprecated functions from \fBsalt/modules/ps.py\fP: -\- \fBphysical_memory_usage\fP (deprecated) -\- \fBvirtual_memory_usage\fP (deprecated) -\- \fBcached_physical_memory\fP (deprecated) -\- \fBphysical_memory_buffers\fP (deprecated) -.IP \(bu 2 -Removed deprecated cloud arguments from \fBcloud_config\fP function in \fBsalt/config.py\fP: -\- \fBvm_config\fP (deprecated) -\- \fBvm_config_path\fP (deprecated) -.IP \(bu 2 -Removed deprecated \fBlibcloud_version\fP function from \fBsalt/cloud/libcloudfuncs.py\fP (deprecated) -.IP \(bu 2 -Removed deprecated \fBCloudConfigMixIn\fP class from \fBsalt/utils/parsers.py\fP (deprecated) -.UNINDENT +\fB/topics/releases/2015.5.2\fP .SS Previous Releases +.SS Salt 2015.5.0 Release Notes \- Codename Lithium +.sp +The 2015.5.0 feature release of Salt is focused on hardening Salt and mostly +on improving existing systems. A few major additions are present, primarily +the new Beacon system. Most enhancements have been focused around improving +existing features and interfaces. +.sp +As usual the release notes are not exhaustive and primarily include the most +notable additions and improvements. Hundreds of bugs have been fixed and many +modules have been substantially updated and added. +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +In order to fix potential shell injection vulnerabilities in salt modules, +a change has been made to the various \fBcmd\fP module functions. These +functions now default to \fBpython_shell=False\fP, which means that the +commands will not be sent to an actual shell. +.sp +The largest side effect of this change is that "shellisms", such as pipes, +will not work by default. The modules shipped with salt have been audited +to fix any issues that might have arisen from this change. Additionally, +the \fBcmd\fP state module has been unaffected, and use of \fBcmd.run\fP in +jinja is also unaffected. \fBcmd.run\fP calls on the CLI will also allow +shellisms. +.sp +However, custom execution modules which use shellisms in \fBcmd\fP calls +will break, unless you pass \fBpython_shell=True\fP to these calls. +.sp +As a temporary workaround, you can set \fBcmd_safe: False\fP in your minion +and master configs. This will revert the default, but is also less secure, +as it will allow shell injection vulnerabilities to be written in custom +code. We recommend you only set this setting for as long as it takes to +resolve these issues in your custom code, then remove the override. +.UNINDENT +.UNINDENT +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +Starting in this version of salt, \fBpillar_opts\fP defaults to False instead +of True. This means that master opts will not be present in minion pillar, +and as a result, \fBconfig.get\fP calls will not include master opts. +.sp +We recommend pillar is used for configuration options which need to make it +to the minion. +.UNINDENT +.UNINDENT +.SS Beacons +.sp +The beacon system allows the minion to hook into system processes and +continually translate external events into the salt event bus. The primary +example of this is the \fBinotify\fP beacon. This beacon uses +inotify to watch configured files or directories on the minion for changes, +creation, deletion etc. +.sp +This allows for the changes to be sent up to the master where the reactor can +respond to changes. +.SS Sudo Minion Settings +.sp +It is now possible to run the minion as a non\-root user and for the minion to +execute commands via sudo. Simply add \fIsudo_user: root\fP to the minion config, +run the minion as a non\-root user and grant that user sudo rights to execute +salt\-call. +.SS Lazy Loader +.sp +The Lazy Loader is a significant overhaul of Salt\(aqs module loader system. The +Lazy Loader will lazily load modules on access instead of all on start. In +addition to a major performance improvement, this "sandboxes" modules so a +bad/broken import of a single module will only affect jobs that require +accessing the broken module. (:issue: \fI20274\fP) +.SS Enhanced Active Directory Support +.sp +The eauth system for LDAP has been extended to support Microsoft Active +Directory out of the box. This includes Active Directory and LDAP group support +for eauth. +.SS Salt LXC Enhancements +.sp +The LXC systems have been overhauled to be more consistent and to fix many +bugs. +.sp +This overhaul makes using LXC with Salt much easier and substantially improves +the underlying capabilities of Salt\(aqs LXC integration. +.SS Salt SSH +.INDENT 0.0 +.IP \(bu 2 +Additional configuration options and command line flags have been added to +configure the scan roster on the fly +.IP \(bu 2 +Added support for \fBstate.single\fP in \fBsalt\-ssh\fP +.IP \(bu 2 +Added support for \fBpublish.publish\fP, \fBpublish.full_data\fP, and +\fBpublish.runner\fP in \fBsalt\-ssh\fP +.IP \(bu 2 +Added support for \fBmine.get\fP in \fBsalt\-ssh\fP +.UNINDENT +.SS New Windows Installer +.sp +The new Windows installer changes how Salt is installed on Windows. +The old installer used bbfreeze to create an isolated python environment to +execute in. This made adding modules and python libraries difficult. The new +installer sets up a more flexible python environment making it easy to manage +the python install and add python modules. +.sp +Instead of frozen packages, a full python implementation resides in the bin +directory (\fBC:\esalt\ebin\fP). By executing pip or easy_install from within the +Scripts directory (\fBC:\esalt\ebin\eScripts\fP) you can install any additional +python modules you may need for your custom environment. +.sp +The .exe\(aqs that once resided at the root of the salt directory (\fBC:\esalt\fP) +have been replaced by .bat files and should function the same way as the .exe\(aqs +in previous versions. +.sp +The new Windows Installer will not replace the minion config file and key if +they already exist on the target system. Only the salt program files will be +replaced. \fBC:\esalt\econf\fP and \fBC:\esalt\evar\fP will remain unchanged. +.SS Removed Requests Dependency +.sp +The hard dependency on the requests library has been removed. Requests is still +required by a number of cloud modules but is no longer required for normal Salt +operations. +.sp +This removal fixes issues that were introduced with requests and salt\-ssh, as +well as issues users experienced from the many different packaging methods used +by requests package maintainers. +.SS Python 3 Updates +.sp +While Salt does not YET run on Python 3 it has been updated to INSTALL on +Python 3, taking us one step closer. What remains is getting the test suite to +the point where it can run on Python 3 so that we can verify compatibility. +.SS RAET Additions +.sp +The RAET support continues to improve. RAET now supports multi\-master and many +bugs and performance issues have been fixed. RAET is much closer to being a +first class citizen. +.SS Modified File Detection +.sp +A number of functions have been added to the RPM\-based package managers to +detect and diff files that are modified from the original package installs. +This can be found in the new pkg.modified functions. +.SS Reactor Update +.sp +Fix an infinite recursion problem for runner/wheel reactor jobs by passing a +"user" (Reactor) to all jobs that the reactor starts. The reactor skips all +events created by that username \-\- thereby only reacting to events not caused +by itself. Because of this, runner and wheel executions from the runner will +have user "Reactor" in the job cache. +.SS Misc Fixes/Additions +.INDENT 0.0 +.IP \(bu 2 +SDB driver for etcd. (:issue: \fI22043\fP) +.IP \(bu 2 +Add \fBonly_upgrade\fP argument to apt\-based \fBpkg.install\fP to only install a +package version if the package is already installed. (Great for security +updates!) +.IP \(bu 2 +Joyent now requires a \fBkeyname\fP to be specified in the provider +configuration. This change was necessitated upstream by the 7.0+ API. +.IP \(bu 2 +Add \fBargs\fP argument to \fBcmd.script_retcode\fP to match \fBcmd.script\fP in +the \fBcmd module\fP\&. (:issue: \fI21122\fP) +.IP \(bu 2 +Fixed bug where TCP keepalive was not being sent on the defined interval on +the return port (4506) from minion to master. (:issue: \fI21465\fP) +.IP \(bu 2 +LocalClient may now optionally raise SaltClientError exceptions. If using +this class directly, checking for and handling this exception is recommended. +(:issue: \fI21501\fP) +.IP \(bu 2 +The SAuth object is now a singleton, meaning authentication state is global +(per master) on each minion. This reduces sign\-ins of minions from 3\->1 per +startup. +.IP \(bu 2 +Nested outputter has been optimized, it is now much faster. +.IP \(bu 2 +Extensive fileserver backend updates. +.UNINDENT +.SS Deprecations +.INDENT 0.0 +.IP \(bu 2 +Removed \fBparameter\fP keyword argument from \fBeselect.exec_action\fP execution +module. +.IP \(bu 2 +Removed \fBrunas\fP parameter from the following \fBpip\(ga\fP execution module +functions: \fBinstall\fP, \fBuninstall\fP, \fBfreeze\fP, \fBlist_\fP, +\fBlist_upgrades\fP, \fBupgrade_available\fP, \fBupgrade\fP\&. Please migrate to +\fBuser\fP\&. +.IP \(bu 2 +Removed \fBrunas\fP parameter from the following \fBpip\fP state module +functions: \fBinstalled\fP, \fBremoved\fP, \fBuptodate\fP . Please migrate to +\fBuser\fP\&. +.IP \(bu 2 +Removed \fBquiet\fP option from all functions in \fBcmdmod\fP execution module. +Please use \fBoutput_loglevel=quiet\fP instead. +.IP \(bu 2 +Removed \fBparameter\fP argument from \fBeselect.set_\fP state. Please migrate to +\fBmodule_parameter\fP or \fBaction_parameter\fP\&. +.IP \(bu 2 +The \fBsalt_events\fP table schema has changed to include an additional field +called \fBmaster_id\fP to distinguish between events flowing into a database +from multiple masters. If \fBevent_return\fP is enabled in the master config, +the database schema must first be updated to add the \fBmaster_id\fP field. +This alteration can be accomplished as follows: +.INDENT 2.0 +.INDENT 3.5 +\fBALTER TABLE salt_events ADD master_id VARCHAR(255) NOT NULL;\fP +.UNINDENT +.UNINDENT +.UNINDENT +.SS Known Issues +.INDENT 0.0 +.IP \(bu 2 +In multi\-master mode, a minion may become temporarily unresponsive if modules +or pillars are refreshed at the same time that one or more masters are down. +This can be worked around by setting \(aqauth_timeout\(aq and \(aqauth_tries\(aq down to +shorter periods. +.UNINDENT +.SS Salt 2015.5.1 Release Notes +.INDENT 0.0 +.TP +.B release +2015\-05\-20 +.UNINDENT +.sp +Version 2015.5.1 is a bugfix release for \fB2015.5.0\fP\&. +.sp +Changes: +.INDENT 0.0 +.IP \(bu 2 +salt.runners.cloud.action() has changed the \fIfun\fP keyword argument to \fIfunc\fP\&. +Please update any calls to this function in the cloud runner. +.UNINDENT +.sp +Extended Changelog Courtesy of Todd Stansell (\fI\%https://github.com/tjstansell/salt\-changelogs\fP): +.INDENT 0.0 +.TP +.B \fBPR\fP \fI\%#23989\fP: (\fIrallytime\fP) Backport \fI\%#23980\fP to 2015.5 +@ \fI2015\-05\-20T19:33:41Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23980\fP: (\fIiggy\fP) template: jinja2 \-> jinja | refs: \fI\%#23989\fP +.IP \(bu 2 +117ecb1 Merge pull request \fI\%#23989\fP from rallytime/\fI\%bp\-23980\fP +.IP \(bu 2 +8f8557c template: jinja2 \-> jinja +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23988\fP: (\fIrallytime\fP) Backport \fI\%#23977\fP to 2015.5 +@ \fI2015\-05\-20T19:13:36Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23977\fP: (\fIionutbalutoiu\fP) Fixed glance image_create | refs: \fI\%#23988\fP +.IP \(bu 2 +d4f1ba0 Merge pull request \fI\%#23988\fP from rallytime/\fI\%bp\-23977\fP +.IP \(bu 2 +46fc7c6 Fixed glance image_create +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23986\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-20T18:41:33Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23965\fP: (\fIhvnsweeting\fP) handle all exceptions gitpython can raise +.IP \(bu 2 +9566e7d Merge pull request \fI\%#23986\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +0b78156 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.IP \(bu 2 +314e4db Merge pull request \fI\%#23965\fP from hvnsweeting/20147\-fix\-gitfs\-gitpython\-exception +.IP \(bu 2 +2576301 handle all exception gitpython can raise +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23985\fP: (\fIUtahDave\fP) Add 2014.7.5\-2 and 2015.5.0\-2 Windows installer download links +@ \fI2015\-05\-20T18:32:44Z\fP +.INDENT 7.0 +.IP \(bu 2 +9d1130e Merge pull request \fI\%#23985\fP from UtahDave/2015.5local +.IP \(bu 2 +10338d0 Add links to Windows 2015.5.0\-2 install downloads +.IP \(bu 2 +b84f975 updated Windows 2014.7.5\-2 installer download link +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23983\fP: (\fIrallytime\fP) Versionadded tags for https_user and https_pass args new in 2015.5.0 +@ \fI2015\-05\-20T18:05:27Z\fP +.INDENT 7.0 +.IP \(bu 2 +ca7729d Merge pull request \fI\%#23983\fP from rallytime/versionadded_git_options +.IP \(bu 2 +14eae22 Versionadded tags for https_user and https_pass args new in 2015.5.0 +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23970\fP: (\fIjayeshka\fP) adding system unit test case +@ \fI2015\-05\-20T17:12:57Z\fP +.INDENT 7.0 +.IP \(bu 2 +b06df57 Merge pull request \fI\%#23970\fP from jayeshka/system\-unit\-test +.IP \(bu 2 +89eb008 adding system unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23967\fP: (\fIjayeshka\fP) adding states/memcached unit test case +@ \fI2015\-05\-20T17:12:26Z\fP +.INDENT 7.0 +.IP \(bu 2 +38d5f75 Merge pull request \fI\%#23967\fP from jayeshka/memcached\-states\-unit\-test +.IP \(bu 2 +8ef9240 adding states/memcached unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23966\fP: (\fIjayeshka\fP) adding states/modjk unit test case +@ \fI2015\-05\-20T17:11:48Z\fP +.INDENT 7.0 +.IP \(bu 2 +868e807 Merge pull request \fI\%#23966\fP from jayeshka/modjk\-states\-unit\-test +.IP \(bu 2 +422a964 adding states/modjk unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23942\fP: (\fIjacobhammons\fP) Updates to sphinx saltstack2 doc theme +@ \fI2015\-05\-20T15:43:54Z\fP +.INDENT 7.0 +.IP \(bu 2 +6316490 Merge pull request \fI\%#23942\fP from jacobhammons/2015.5 +.IP \(bu 2 +31023c8 Updates to sphinx saltstack2 doc theme +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23874\fP: (\fIjoejulian\fP) Validate keyword arguments to be valid +@ \fI2015\-05\-20T04:53:40Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23872\fP: (\fIjoejulian\fP) create_ca_signed_cert can error if dereferenced dict is used for args | refs: \fI\%#23874\fP +.IP \(bu 2 +587957b Merge pull request \fI\%#23874\fP from joejulian/2015.5_tls_validate_kwargs +.IP \(bu 2 +30102ac Fix py3 and ordering inconsistency problems. +.IP \(bu 2 +493f7ad Validate keyword arguments to be valid +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23960\fP: (\fIrallytime\fP) Backport \fI\%#22114\fP to 2015.5 +@ \fI2015\-05\-20T04:37:09Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBPR\fP \fI\%#22114\fP: (\fIdmyerscough\fP) Fixing KeyError when there are no additional pages | refs: \fI\%#23960\fP +.IP \(bu 2 +00c5c22 Merge pull request \fI\%#23960\fP from rallytime/\fI\%bp\-22114\fP +.IP \(bu 2 +f3e1d63 Catch KeyError +.IP \(bu 2 +306b1ea Fixing KeyError +.IP \(bu 2 +6b2cda2 Fix PEP8 complaint +.IP \(bu 2 +239e50f Fixing KeyError when there are no additional pages +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23961\fP: (\fIrallytime\fP) Backport \fI\%#23944\fP to 2015.5 +@ \fI2015\-05\-20T04:35:41Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23944\fP: (\fIryan\-lane\fP) Add missing loginclass argument to _changes call | refs: \fI\%#23961\fP +.IP \(bu 2 +4648b46 Merge pull request \fI\%#23961\fP from rallytime/\fI\%bp\-23944\fP +.IP \(bu 2 +970d19a Add missing loginclass argument to _changes call +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23948\fP: (\fIjfindlay\fP) augeas.change state now returns changes as a dict +@ \fI2015\-05\-20T04:00:10Z\fP +.INDENT 7.0 +.IP \(bu 2 +0cb5cd3 Merge pull request \fI\%#23948\fP from jfindlay/augeas_changes +.IP \(bu 2 +f09b80a augeas.change state now returns changes as a dict +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23957\fP: (\fIrallytime\fP) Backport \fI\%#23951\fP to 2015.5 +@ \fI2015\-05\-20T03:04:24Z\fP +.INDENT 7.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23951\fP: (\fIryan\-lane\fP) Do not check perms in file.copy if preserve | refs: \fI\%#23957\fP +.IP \(bu 2 +2d185f7 Merge pull request \fI\%#23957\fP from rallytime/\fI\%bp\-23951\fP +.IP \(bu 2 +996b431 Update file.py +.IP \(bu 2 +85d461f Do not check perms in file.copy if preserve +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23956\fP: (\fIrallytime\fP) Backport \fI\%#23906\fP to 2015.5 +@ \fI2015\-05\-20T03:04:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23839\fP: (\fIgladiatr72\fP) wonky loader syndrome +| refs: \fI\%#23906\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23373\fP: (\fItnypex\fP) reactor/orchestrate race condition on salt[\(aqpillar.get\(aq] +| refs: \fI\%#23906\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23906\fP: (\fIgladiatr72\fP) Added exception handler to trap the RuntimeError raised when +| refs: \fI\%#23956\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ebff1ff Merge pull request \fI\%#23956\fP from rallytime/\fI\%bp\-23906\fP +.IP \(bu 2 +9d87fd3 add proper marker for format argument +.IP \(bu 2 +197688e Added exception handler to trap the RuntimeError raised when Depends.enforce_dependency() class method fires unsuccessfully. There appears to be no synchronization within the Depends decorator class wrt the class global dependency_dict which results in incomplete population of any loader instantiation occuring at the time of one of these exceptions. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23955\fP: (\fIrallytime\fP) Backport \fI\%#19305\fP to 2015.5 +@ \fI2015\-05\-20T03:03:55Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#19852\fP: (\fITaiSHiNet\fP) DigitalOcean APIv2 can\(aqt delete machines when there is only 1 page +| refs: \fI\%#23955\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#19304\fP: (\fITaiSHiNet\fP) DigitalOcean API v2 cannot delete VMs on 2nd page +| refs: \fI\%#19305\fP +.IP \(bu 2 +\fBPR\fP \fI\%#19305\fP: (\fITaiSHiNet\fP) Fixes droplet listing past page 1 +| refs: \fI\%#23955\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +da3f919 Merge pull request \fI\%#23955\fP from rallytime/\fI\%bp\-19305\fP +.IP \(bu 2 +bbf2429 Fixes droplet listing past page 1 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23940\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-19T22:37:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23820\fP: (\fIUtahDave\fP) 2014.7.5 schedule error +| refs: \fI\%#23881\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#22131\fP: (\fIquixoten\fP) "unexpected keyword argument \(aqmerge\(aq" on 2014.7.2 (salt\-ssh) +| refs: \fI\%#23887\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23939\fP: (\fIbasepi\fP) Add extended changelog to 2014.7.6 release notes +.IP \(bu 2 +\fBPR\fP \fI\%#23887\fP: (\fIbasepi\fP) [2014.7] Bring salt\-ssh pillar.get in line with mainline pillar.get +.IP \(bu 2 +\fBPR\fP \fI\%#23881\fP: (\fIgarethgreenaway\fP) Fixes to schedule module in 2014.7 +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +02a78fc Merge pull request \fI\%#23940\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +36f0065 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.INDENT 2.0 +.IP \(bu 2 +9133912 Merge pull request \fI\%#23939\fP from basepi/v2014.7.6release +.INDENT 2.0 +.IP \(bu 2 +32b65dc Add extended changelog to 2014.7.6 release notes +.UNINDENT +.IP \(bu 2 +0031ca2 Merge pull request \fI\%#23881\fP from garethgreenaway/23820_2014_7_schedule_list_issue +.INDENT 2.0 +.IP \(bu 2 +b207f2a Missing continue in the list function when deleting unused attributes. +.UNINDENT +.IP \(bu 2 +63bd21e Merge pull request \fI\%#23887\fP from basepi/salt\-ssh.pillar.get.22131 +.INDENT 2.0 +.IP \(bu 2 +bc84502 Bring salt\-ssh pillar.get in line with mainline pillar.get +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23932\fP: (\fIrallytime\fP) Backport \fI\%#23908\fP to 2015.5 +@ \fI2015\-05\-19T21:41:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23908\fP: (\fInleib\fP) fix connection function to mongo +| refs: \fI\%#23932\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ee4c01b Merge pull request \fI\%#23932\fP from rallytime/\fI\%bp\-23908\fP +.IP \(bu 2 +5d520c9 fix connection function to mongo +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23931\fP: (\fIrallytime\fP) Backport \fI\%#23880\fP to 2015.5 +@ \fI2015\-05\-19T21:41:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23880\fP: (\fIbastiaanb\fP) if setting client_config_dir to \(aq~\(aq, expand path +| refs: \fI\%#23931\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +70bd407 Merge pull request \fI\%#23931\fP from rallytime/\fI\%bp\-23880\fP +.IP \(bu 2 +8ce59a2 if setting client_config_dir to \(aq~\(aq, expand path +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23898\fP: (\fIkiorky\fP) Lxc profiles +| refs: \fI\%#23897\fP +@ \fI2015\-05\-19T21:08:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23847\fP: (\fIkiorky\fP) lxc: systemd containers cant be seeded +| refs: \fI\%#23806\fP \fI\%#23898\fP \fI\%#23897\fP \fI\%#23808\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23833\fP: (\fIkiorky\fP) lxc.set_dns fails intermittently +| refs: \fI\%#23898\fP \fI\%#23807\fP \fI\%#23897\fP \fI\%#23808\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23772\fP: (\fIcheuschober\fP) lxc.init fails to bootstrap container +| refs: \fI\%#23806\fP \fI\%#23898\fP \fI\%#23807\fP \fI\%#23897\fP \fI\%#23808\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23658\fP: (\fIarthurlogilab\fP) [salt\-cloud lxc] too verbose, shows host: True multiple times when starting +| refs: \fI\%#23898\fP \fI\%#23897\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23657\fP: (\fIarthurlogilab\fP) [salt\-cloud lxc] NameError: global name \(aq__salt__\(aq is not defined +| refs: \fI\%#23727\fP \fI\%#23898\fP \fI\%#23897\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23897\fP: (\fIkiorky\fP) Lxc seed and prof ports +| refs: \fI\%#23898\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23808\fP: (\fIkiorky\fP) Lxc seed and prof ports +| refs: \fI\%#23807\fP \fI\%#23897\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23807\fP: (\fIkiorky\fP) Lxc profiles +| refs: \fI\%#23898\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23806\fP: (\fIkiorky\fP) Lxc seeding +| refs: \fI\%#23807\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5bdbf0a Merge pull request \fI\%#23898\fP from makinacorpus/lxc_profiles +.IP \(bu 2 +d9051a0 lxc: systemd support +.IP \(bu 2 +e8d674f lxc: chroot fallback toggle +.IP \(bu 2 +e2887a0 lxc: sync func name with develop +.IP \(bu 2 +e96e345 lxc more fixes (lxc.set_dns) +.IP \(bu 2 +fdb6424 lxc: Fix salt config (no more a kwarg) +.IP \(bu 2 +63e63fa repair salt cloud lxc api on develop +.IP \(bu 2 +80eabe2 lxc salt cloud doc +.IP \(bu 2 +73f229d lxc: unificate saltconfig/master/master_port +.IP \(bu 2 +0bc1f08 lxc: refactor a bit saltcloud/lxc interface +.IP \(bu 2 +7a80370 lxc: get networkprofile from saltcloud +.IP \(bu 2 +47acb2e lxc: default net profile has now correct options +.IP \(bu 2 +7eadf48 lxc: select the appropriate default bridge +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23922\fP: (\fIgarethgreenaway\fP) Fixes to debian_ip.py +@ \fI2015\-05\-19T18:50:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23900\fP: (\fIhashi825\fP) salt ubuntu network building issue 2015.5.0 +| refs: \fI\%#23922\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b818f72 Merge pull request \fI\%#23922\fP from garethgreenaway/23900_2015_5_bonding_interface_fixes +.IP \(bu 2 +0bba536 Fixing issue reported when using bonded interfaces on Ubuntu. Attributes should be bond\-, but the code was attempting to split just on +.nf +bond_ +.fi +\&. Fix accounts for both, but the debian_ip.py module will write out bond attributes with bond\- +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23925\fP: (\fIjpic\fP) Fixed wrong path in LXC cloud documentation +@ \fI2015\-05\-19T18:23:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23924\fP: (\fIjpic\fP) Fixed wrong path in LXC cloud documentation +| refs: \fI\%#23925\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b1c98a3 Merge pull request \fI\%#23925\fP from jpic/fix/wrong_lxc_path +.IP \(bu 2 +a4bcd75 Fixed wrong path in LXC cloud documentation +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23894\fP: (\fIwhiteinge\fP) Add __all__ attribute to Mock class for docs +@ \fI2015\-05\-19T17:17:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +7f6a716 Merge pull request \fI\%#23894\fP from whiteinge/doc\-mock__all__ +.IP \(bu 2 +6eeca46 Add __all__ attribute to Mock class for docs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23884\fP: (\fIjfindlay\fP) Fix locale.set_locale on debian +@ \fI2015\-05\-19T15:51:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23767\fP: (\fIchrimi\fP) Salt system.locale fails on non existent default locale +| refs: \fI\%#23884\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8108a9b Merge pull request \fI\%#23884\fP from jfindlay/fix_locale +.IP \(bu 2 +91c2d51 use append_if_not_found in locale.set_locale +.IP \(bu 2 +e632603 (re)generate /etc/default/locale +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23866\fP: (\fIjfindlay\fP) backport \fI\%#23834\fP, change portage.dep.strip_empty to list comprehension +@ \fI2015\-05\-19T15:50:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23834\fP: (\fIArabus\fP) Avoid deprecation warning from portage.dep.strip_empty() +| refs: \fI\%#23866\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6bae12f Merge pull request \fI\%#23866\fP from jfindlay/flag_strip +.IP \(bu 2 +aa032cc replace portage.dep.strip_empty() with list comprehension +.IP \(bu 2 +7576872 Proper replacement for portage.dep.strip_empty() with list comprehension, pep8fix +.IP \(bu 2 +2851a5c Switch portage.dep.strip_empty(...) to filter(None,...) to avoid deprecation warning and do essentially the same +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23917\fP: (\fIcorywright\fP) Split debian bonding options on dash instead of underscore +@ \fI2015\-05\-19T15:44:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23904\fP: (\fImbrgm\fP) Network config bonding section cannot be parsed when attribute names use dashes +| refs: \fI\%#23917\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a67a008 Merge pull request \fI\%#23917\fP from corywright/issue23904 +.IP \(bu 2 +c06f8cf Split debian bonding options on dash instead of underscore +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23909\fP: (\fIjayeshka\fP) \(aqstr\(aq object has no attribute \(aqcapitalized\(aq +@ \fI2015\-05\-19T15:41:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +e8fcd09 Merge pull request \fI\%#23909\fP from jayeshka/file\-exe\-module +.IP \(bu 2 +e422d9d \(aqstr\(aq object has no attribute \(aqcapitalized\(aq +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23903\fP: (\fIgarethgreenaway\fP) Adding docs for missing schedule state module parameters. +@ \fI2015\-05\-19T06:29:34Z\fP +.INDENT 2.0 +.IP \(bu 2 +c73bf38 Merge pull request \fI\%#23903\fP from garethgreenaway/missing_docs_schedule_state +.IP \(bu 2 +acd8ab9 Adding docs for missing schedule state module parameters. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +f7eb70c changed previous release to 2014.7.6 +.IP \(bu 2 +608059f Merge branch \(aq2015.5\(aq of \fI\%https://github.com/jacobhammons/salt\fP into 2015.5 +.INDENT 2.0 +.IP \(bu 2 +a56697b Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5 +.IP \(bu 2 +1c2af5c Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5 +.IP \(bu 2 +ef58128 Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5 +.IP \(bu 2 +8664e8b Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5\-2 +.IP \(bu 2 +46eb265 saltstack2 sphinx theme updates +.IP \(bu 2 +e7442d3 Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5 +.IP \(bu 2 +ee3c1bd missed one +.IP \(bu 2 +3872921 More updates to sphinx2 theme +.IP \(bu 2 +fcd4865 Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5 +.IP \(bu 2 +8c32152 removed TOC numbering, additional tweaks to layout.html +.IP \(bu 2 +73dfaef Merge branch \(aq2015.5\(aq of \fI\%https://github.com/saltstack/salt\fP into 2015.5 +.IP \(bu 2 +16d8a75 saltstack2 sphinx theme and build settings +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23806\fP: (\fIkiorky\fP) Lxc seeding +| refs: \fI\%#23807\fP +@ \fI2015\-05\-18T23:18:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23847\fP: (\fIkiorky\fP) lxc: systemd containers cant be seeded +| refs: \fI\%#23806\fP \fI\%#23898\fP \fI\%#23897\fP \fI\%#23808\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23772\fP: (\fIcheuschober\fP) lxc.init fails to bootstrap container +| refs: \fI\%#23806\fP \fI\%#23898\fP \fI\%#23807\fP \fI\%#23897\fP \fI\%#23808\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ff3cc7d Merge pull request \fI\%#23806\fP from makinacorpus/lxc_seeding +.IP \(bu 2 +61b7aad runners/lxc: optim +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23892\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-18T23:07:57Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23891\fP: (\fIbasepi\fP) Update the release notes index page +.IP \(bu 2 +\fBPR\fP \fI\%#23888\fP: (\fIbasepi\fP) Update the 2014.7.6 release notes with CVE details +.IP \(bu 2 +\fBPR\fP \fI\%#23871\fP: (\fIrallytime\fP) Backport \fI\%#23848\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23848\fP: (\fIdumol\fP) Updated installation docs for SLES 12. +| refs: \fI\%#23871\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5f1a93d Merge pull request \fI\%#23892\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +c2eed77 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.IP \(bu 2 +17c5810 Merge pull request \fI\%#23891\fP from basepi/releasenotes +.INDENT 2.0 +.IP \(bu 2 +dec153b Update the release notes index page +.UNINDENT +.IP \(bu 2 +a93e58f Merge pull request \fI\%#23888\fP from basepi/v2014.7.6release +.INDENT 2.0 +.IP \(bu 2 +49921b6 Update the 2014.7.6 release notes with CVE details +.UNINDENT +.IP \(bu 2 +5073028 Merge pull request \fI\%#23871\fP from rallytime/\fI\%bp\-23848\fP +.INDENT 2.0 +.IP \(bu 2 +379c09c Updated for SLES 12. +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23875\fP: (\fIrallytime\fP) Backport \fI\%#23838\fP to 2015.5 +@ \fI2015\-05\-18T22:28:55Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23838\fP: (\fIgtmanfred\fP) add refresh_beacons and sync_beacons +| refs: \fI\%#23875\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +66d1335 Merge pull request \fI\%#23875\fP from rallytime/\fI\%bp\-23838\fP +.IP \(bu 2 +3174227 Add versionadded directives to new beacon saltutil functions +.IP \(bu 2 +4a94b2c add refresh_beacons and sync_beacons +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23876\fP: (\fIrallytime\fP) Switch digital ocean tests to v2 driver +@ \fI2015\-05\-18T22:17:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +d294cf2 Merge pull request \fI\%#23876\fP from rallytime/switch_digital_ocean_tests_v2 +.IP \(bu 2 +dce9b54 Remove extra line +.IP \(bu 2 +4acf58e Switch digital ocean tests to v2 driver +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23882\fP: (\fIgarethgreenaway\fP) Fixes to scheduler in 2015.5 +@ \fI2015\-05\-18T22:09:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23792\fP: (\fIneogenix\fP) Salt Scheduler Incorrect Response (True, should be False) +| refs: \fI\%#23882\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b97a48c Merge pull request \fI\%#23882\fP from garethgreenaway/23792_2015_5_wrong_return_code +.IP \(bu 2 +37dbde6 Job already exists in schedule, should return False. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23868\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-18T18:35:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#20198\fP: (\fIjcftang\fP) virt.get_graphics, virt.get_nics are broken, in turn breaking other things +| refs: \fI\%#23809\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23823\fP: (\fIgtmanfred\fP) add link local for ipv6 +.IP \(bu 2 +\fBPR\fP \fI\%#23810\fP: (\fIrallytime\fP) Backport \fI\%#23757\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23809\fP: (\fIrallytime\fP) Fix virtualport section of virt.get_nics loop +.IP \(bu 2 +\fBPR\fP \fI\%#23802\fP: (\fIgtmanfred\fP) if it is ipv6 ip_to_int will fail +.IP \(bu 2 +\fBPR\fP \fI\%#23757\fP: (\fIclan\fP) use abspath, do not eliminating symlinks +| refs: \fI\%#23810\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23573\fP: (\fItechhat\fP) Scan all available networks for public and private IPs +| refs: \fI\%#23802\fP +.IP \(bu 2 +\fBPR\fP \fI\%#21487\fP: (\fIrallytime\fP) Backport \fI\%#21469\fP to 2014.7 +| refs: \fI\%#23809\fP +.IP \(bu 2 +\fBPR\fP \fI\%#21469\fP: (\fIvdesjardins\fP) fixes \fI\%#20198\fP: virt.get_graphics and virt.get_nics calls in module virt +| refs: \fI\%#21487\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +61c922e Merge pull request \fI\%#23868\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +c9ed233 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.IP \(bu 2 +aee00c8 Merge pull request \fI\%#23810\fP from rallytime/\fI\%bp\-23757\fP +.INDENT 2.0 +.IP \(bu 2 +fb32c32 use abspath, do not eliminating symlinks +.UNINDENT +.IP \(bu 2 +6b3352b Merge pull request \fI\%#23809\fP from rallytime/virt_get_nics_fix +.INDENT 2.0 +.IP \(bu 2 +0616fb7 Fix virtualport section of virt.get_nics loop +.UNINDENT +.IP \(bu 2 +188f03f Merge pull request \fI\%#23823\fP from gtmanfred/2014.7 +.INDENT 2.0 +.IP \(bu 2 +5ef006d add link local for ipv6 +.UNINDENT +.IP \(bu 2 +f3ca682 Merge pull request \fI\%#23802\fP from gtmanfred/2014.7 +.INDENT 2.0 +.IP \(bu 2 +2da98b5 if it is ipv6 ip_to_int will fail +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23863\fP: (\fIrahulhan\fP) Adding states/timezone.py unit test +@ \fI2015\-05\-18T17:02:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +433f873 Merge pull request \fI\%#23863\fP from rahulhan/states_timezone_unit_test +.IP \(bu 2 +72fcabc Adding states/timezone.py unit test +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23862\fP: (\fIrahulhan\fP) Adding states/tomcat.py unit tests +@ \fI2015\-05\-18T17:02:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +37b3ee5 Merge pull request \fI\%#23862\fP from rahulhan/states_tomcat_unit_test +.IP \(bu 2 +65d7752 Adding states/tomcat.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23860\fP: (\fIrahulhan\fP) Adding states/test.py unit tests +@ \fI2015\-05\-18T17:01:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +dde7207 Merge pull request \fI\%#23860\fP from rahulhan/states_test_unit_test +.IP \(bu 2 +1f4cf86 Adding states/test.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23859\fP: (\fIrahulhan\fP) Adding states/sysrc.py unit tests +@ \fI2015\-05\-18T17:01:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +3c9b813 Merge pull request \fI\%#23859\fP from rahulhan/states_sysrc_unit_test +.IP \(bu 2 +6a903b0 Adding states/sysrc.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23812\fP: (\fIrallytime\fP) Backport \fI\%#23790\fP to 2015.5 +@ \fI2015\-05\-18T15:30:34Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23790\fP: (\fIaboe76\fP) updated suse spec file to version 2015.5.0 +| refs: \fI\%#23812\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4cf30a7 Merge pull request \fI\%#23812\fP from rallytime/\fI\%bp\-23790\fP +.IP \(bu 2 +3f65631 updated suse spec file to version 2015.5.0 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23811\fP: (\fIrallytime\fP) Backport \fI\%#23786\fP to 2015.5 +@ \fI2015\-05\-18T15:30:27Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23786\fP: (\fIkaithar\fP) Log the error generated that causes returns.mysql.returner to except. +| refs: \fI\%#23811\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c6f939a Merge pull request \fI\%#23811\fP from rallytime/\fI\%bp\-23786\fP +.IP \(bu 2 +346f30b Log the error generated that causes returns.mysql.returner to except. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23850\fP: (\fIjayeshka\fP) adding sysbench unit test case +@ \fI2015\-05\-18T15:28:04Z\fP +.INDENT 2.0 +.IP \(bu 2 +ce60582 Merge pull request \fI\%#23850\fP from jayeshka/sysbench\-unit\-test +.IP \(bu 2 +280abde adding sysbench unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23843\fP: (\fIThe\-Loeki\fP) Fix erroneous virtual:physical core grain detection +@ \fI2015\-05\-18T15:24:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +060902f Merge pull request \fI\%#23843\fP from The\-Loeki/patch\-1 +.IP \(bu 2 +9e2cf60 Fix erroneous virtual:physical core grain detection +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23816\fP: (\fISnergster\fP) Doc for \fI\%#23685\fP Added prereq, caution, and additional mask information +@ \fI2015\-05\-18T15:18:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23815\fP: (\fISnergster\fP) [beacons] inotify errors on subdir creation +| refs: \fI\%#23816\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3257a9b Merge pull request \fI\%#23816\fP from Snergster/23685\-doc\-fix +.IP \(bu 2 +0fca49d Added prereq, caution, and additional mask information +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23832\fP: (\fIahus1\fP) make saltify provider use standard boostrap procedure +@ \fI2015\-05\-18T02:18:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23829\fP: (\fIahus1\fP) make saltify provider use standard boostrap procedure +| refs: \fI\%#23832\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3df3b85 Merge pull request \fI\%#23832\fP from ahus1/ahus1_saltify_bootstrap_2015.5 +.IP \(bu 2 +f5b1734 fixing problem in unit test +.IP \(bu 2 +cba47f6 make saltify to use standard boostrap procedure, therefore providing all options like master_sign_pub_file +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23791\fP: (\fIoptix2000\fP) Psutil compat +@ \fI2015\-05\-16T04:05:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +8ec4fb2 Merge pull request \fI\%#23791\fP from optix2000/psutil_compat +.IP \(bu 2 +5470cf5 Fix pylint errors and sloppy inline comments +.IP \(bu 2 +64634b6 Update psutil.pid_list to use psutil.pids +.IP \(bu 2 +5dd6d69 Fix imports that aren\(aqt in __all__ +.IP \(bu 2 +8a1da33 Fix test cases by mocking psutil_compat +.IP \(bu 2 +558798d Fix net_io_counters deprecation issue +.IP \(bu 2 +8140f92 Override unecessary pylint errors +.IP \(bu 2 +7d02ad4 Fix some of the mock names for the new API +.IP \(bu 2 +9b3023e Fix overloaded getters/setters. Fix line lengths +.IP \(bu 2 +180eb87 Fix whitespace +.IP \(bu 2 +f8edf72 Use new psutil API in ps module +.IP \(bu 2 +e48982f Fix version checking in psutil_compat +.IP \(bu 2 +93ee411 Create compatability psutil. psutil 3.0 drops 1.0 API, but we still support old psutil versions. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23782\fP: (\fIterminalmage\fP) Replace "command \-v" with "which" and get rid of spurious log messages +@ \fI2015\-05\-16T04:03:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +405517b Merge pull request \fI\%#23782\fP from terminalmage/issue23772 +.IP \(bu 2 +0f6f239 More ignore_retcode to suppress spurious log msgs +.IP \(bu 2 +b4c48e6 Ignore return code in lxc.attachable +.IP \(bu 2 +08658c0 Replace "command \-v" with "which" +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23783\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-15T21:38:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22959\fP: (\fIhighlyunavailable\fP) Windows Salt hangs if file.directory is trying to write to a drive that doesn\(aqt exist +.IP \(bu 2 +\fBISSUE\fP \fI\%#22332\fP: (\fIrallytime\fP) [salt\-ssh] Add a check for host in /etc/salt/roster +| refs: \fI\%#23748\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#16424\fP: (\fIstanvit\fP) salt\-run cloud.create fails with saltify +.IP \(bu 2 +\fBPR\fP \fI\%#23748\fP: (\fIbasepi\fP) [2014.7] Log salt\-ssh roster render errors more assertively and verbosely +.IP \(bu 2 +\fBPR\fP \fI\%#23731\fP: (\fItwangboy\fP) Fixes \fI\%#22959\fP: Trying to add a directory to an unmapped drive in windows +.IP \(bu 2 +\fBPR\fP \fI\%#23730\fP: (\fIrallytime\fP) Backport \fI\%#23729\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23729\fP: (\fIrallytime\fP) Partially merge \fI\%#23437\fP (grains fix) +| refs: \fI\%#23730\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23688\fP: (\fItwangboy\fP) Added inet_pton to utils/validate/net.py for ip.set_static_ip in windows +.IP \(bu 2 +\fBPR\fP \fI\%#23488\fP: (\fIcellscape\fP) LXC cloud fixes +.IP \(bu 2 +\fBPR\fP \fI\%#23437\fP: (\fIcedwards\fP) Grains item patch +| refs: \fI\%#23729\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cb2eb40 Merge pull request \fI\%#23783\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +9df51ca __opts__.get +.IP \(bu 2 +51d23ed Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.INDENT 2.0 +.IP \(bu 2 +d9af0c3 Merge pull request \fI\%#23488\fP from cellscape/lxc\-cloud\-fixes +.INDENT 2.0 +.IP \(bu 2 +64250a6 Remove profile from opts after creating LXC container +.IP \(bu 2 +c4047d2 Set destroy=True in opts when destroying cloud instance +.IP \(bu 2 +9e1311a Store instance names in opts when performing cloud action +.IP \(bu 2 +934bc57 Correctly pass custom env to lxc\-attach +.IP \(bu 2 +7fb85f7 Preserve test=True option in cloud states +.IP \(bu 2 +9771b5a Fix detection of absent LXC container in cloud state +.IP \(bu 2 +fb24f0c Report failure when failed to create/clone LXC container +.IP \(bu 2 +2d9aa2b Avoid shadowing variables in lxc module +.IP \(bu 2 +792e102 Allow to override profile options in lxc.cloud_init_interface +.IP \(bu 2 +42bd64b Return changes on successful lxc.create from salt\-cloud +.IP \(bu 2 +4409eab Return correct result when creating cloud LXC container +.IP \(bu 2 +377015c Issue \fI\%#16424\fP: List all providers when creating salt\-cloud instance without profile +.UNINDENT +.IP \(bu 2 +808bbe1 Merge pull request \fI\%#23748\fP from basepi/salt\-ssh.roster.host.check +.INDENT 2.0 +.IP \(bu 2 +bc53e04 Log entire exception for render errors in roster +.IP \(bu 2 +753de6a Log render errors in roster to error level +.IP \(bu 2 +e01a7a9 Always let the real YAML error through +.UNINDENT +.IP \(bu 2 +72cf360 Merge pull request \fI\%#23731\fP from twangboy/fix_22959 +.INDENT 2.0 +.IP \(bu 2 +88e5495 Fixes \fI\%#22959\fP: Trying to add a directory to an unmapped drive in windows +.UNINDENT +.IP \(bu 2 +2610195 Merge pull request \fI\%#23730\fP from rallytime/\fI\%bp\-23729\fP +.INDENT 2.0 +.IP \(bu 2 +1877cae adding support for nested grains to grains.item +.UNINDENT +.IP \(bu 2 +3e9df88 Merge pull request \fI\%#23688\fP from twangboy/fix_23415 +.INDENT 2.0 +.IP \(bu 2 +6a91169 Fixed unused\-import pylint error +.IP \(bu 2 +5e25b3f fixed pylint errors +.IP \(bu 2 +1a96766 Added inet_pton to utils/validate/net.py for ip.set_static_ip in windows +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23781\fP: (\fIjfindlay\fP) fix unit test mock errors on arch +@ \fI2015\-05\-15T19:40:07Z\fP +.INDENT 2.0 +.IP \(bu 2 +982f873 Merge pull request \fI\%#23781\fP from jfindlay/fix_locale_tests +.IP \(bu 2 +14c711e fix unit test mock errors on arch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23740\fP: (\fIjfindlay\fP) Binary write +@ \fI2015\-05\-15T18:10:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23566\fP: (\fIrks2286\fP) Salt\-cp corrupting the file after transfer to minion +| refs: \fI\%#23740\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +916b1c4 Merge pull request \fI\%#23740\fP from jfindlay/binary_write +.IP \(bu 2 +626930a update incorrect comment wording +.IP \(bu 2 +a978f5c always use binary file write mode on windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23736\fP: (\fIjfindlay\fP) always load pip execution module +@ \fI2015\-05\-15T18:10:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23682\fP: (\fIchrish42\fP) Pip module requires system pip, even when not used (with env_bin) +| refs: \fI\%#23736\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +348645e Merge pull request \fI\%#23736\fP from jfindlay/fix_pip +.IP \(bu 2 +b8867a8 update pip tests +.IP \(bu 2 +040bbc4 only check pip version in one place +.IP \(bu 2 +6c453a5 check for executable status of bin_env +.IP \(bu 2 +3337257 always load the pip module as pip could be anywhere +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23770\fP: (\fIcellscape\fP) Fix cloud LXC container destruction +@ \fI2015\-05\-15T17:38:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +10cedfb Merge pull request \fI\%#23770\fP from cellscape/fix\-cloud\-lxc\-destruction +.IP \(bu 2 +4f6021c Fix cloud LXC container destruction +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23759\fP: (\fIlisa2lisa\fP) fixed the problem for not beable to revoke \fI\&.\fP, for more detail https… +@ \fI2015\-05\-15T17:38:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +ddea822 Merge pull request \fI\%#23759\fP from lisa2lisa/iss23664 +.IP \(bu 2 +a29f161 fixed the problem for not beable to revoke \fI\&.\fP, for more detail \fI\%https://github.com/saltstack/salt/issues/23201\fP, fixed mysql cannot create user with pure digit password, for more info \fI\%https://github.com/saltstack/salt/issues/23664\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23769\fP: (\fIcellscape\fP) Fix file_roots CA lookup in salt.utils.http.get_ca_bundle +@ \fI2015\-05\-15T16:21:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +10615ff Merge pull request \fI\%#23769\fP from cellscape/utils\-http\-ca\-file\-roots +.IP \(bu 2 +8e90f32 Fix file_roots CA lookup in salt.utils.http.get_ca_bundle +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23765\fP: (\fIjayeshka\fP) adding states/makeconf unit test case +@ \fI2015\-05\-15T14:29:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +fd8a1b7 Merge pull request \fI\%#23765\fP from jayeshka/makeconf_states\-unit\-test +.IP \(bu 2 +26e31af adding states/makeconf unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23760\fP: (\fIticosax\fP) [doc] document refresh argument +@ \fI2015\-05\-15T14:23:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +ee13b08 Merge pull request \fI\%#23760\fP from ticosax/2015.5 +.IP \(bu 2 +e3ca859 document refresh argument +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23766\fP: (\fIjayeshka\fP) adding svn unit test case +@ \fI2015\-05\-15T14:23:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +a017f72 Merge pull request \fI\%#23766\fP from jayeshka/svn\-unit\-test +.IP \(bu 2 +19939cf adding svn unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23751\fP: (\fIrallytime\fP) Backport \fI\%#23737\fP to 2015.5 +@ \fI2015\-05\-15T03:58:37Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23734\fP: (\fIbradthurber\fP) 2015.5.0 modules/archive.py ZipFile instance has no attribute \(aq__exit__\(aq \- only python 2.6? +| refs: \fI\%#23737\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23737\fP: (\fIbradthurber\fP) fix for 2015.5.0 modules/archive.py ZipFile instance has no attribute… +| refs: \fI\%#23751\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0ed9d45 Merge pull request \fI\%#23751\fP from rallytime/\fI\%bp\-23737\fP +.IP \(bu 2 +8d1eb32 fix for 2015.5.0 modules/archive.py ZipFile instance has no attribute \(aq__exit__\(aq \- only python 2.6? \fI\%#23734\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23710\fP: (\fIkiorky\fP) Get more useful output from stateful commands +@ \fI2015\-05\-14T21:58:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23709\fP: (\fIkiorky\fP) cmdmod: enhancement is really needed for stateful commands +| refs: \fI\%#23710\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +d73984e Merge pull request \fI\%#23710\fP from makinacorpus/i23709 +.IP \(bu 2 +c706909 Get more useful output from stateful commands +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23724\fP: (\fIrallytime\fP) Backport \fI\%#23609\fP to 2015.5 +@ \fI2015\-05\-14T19:34:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23609\fP: (\fIkaidokert\fP) file_map: chown created directories if not root \fI\%#23608\fP +| refs: \fI\%#23724\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cdf421b Merge pull request \fI\%#23724\fP from rallytime/\fI\%bp\-23609\fP +.IP \(bu 2 +fe3a762 file_map: chmod created directories if not root +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23723\fP: (\fIrallytime\fP) Backport \fI\%#23568\fP to 2015.5 +@ \fI2015\-05\-14T19:34:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23568\fP: (\fItechhat\fP) Allow Salt Cloud to use either SCP or SFTP, as configured +| refs: \fI\%#23723\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +94f9099 Merge pull request \fI\%#23723\fP from rallytime/\fI\%bp\-23568\fP +.IP \(bu 2 +bbec34a Allow Salt Cloud to use either SCP or SFTP, as configured +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23725\fP: (\fIrallytime\fP) Backport \fI\%#23691\fP to 2015.5 +@ \fI2015\-05\-14T19:32:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23691\fP: (\fIdennisjac\fP) add initial configuration documentation for varstack pillar +| refs: \fI\%#23725\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +137e5ee Merge pull request \fI\%#23725\fP from rallytime/\fI\%bp\-23691\fP +.IP \(bu 2 +28a846e add initial configuration documentation for varstack pillar +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23722\fP: (\fIrallytime\fP) Backport \fI\%#23472\fP to 2015.5 +@ \fI2015\-05\-14T19:31:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23472\fP: (\fItechhat\fP) Allow neutron network list to be used as pillar data +| refs: \fI\%#23722\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0c00995 Merge pull request \fI\%#23722\fP from rallytime/\fI\%bp\-23472\fP +.IP \(bu 2 +c3d0f39 Change versionadded tag for backport +.IP \(bu 2 +023e88f Allow neutron network list to be used as pillar data +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23727\fP: (\fIjfindlay\fP) fix npm execution module stacktrace +@ \fI2015\-05\-14T18:14:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23657\fP: (\fIarthurlogilab\fP) [salt\-cloud lxc] NameError: global name \(aq__salt__\(aq is not defined +| refs: \fI\%#23727\fP \fI\%#23898\fP \fI\%#23897\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cbf4ca8 Merge pull request \fI\%#23727\fP from jfindlay/npm_salt +.IP \(bu 2 +05392f2 fix npm execution module stacktrace +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23718\fP: (\fIrahulhan\fP) Adding states/user.py unit tests +@ \fI2015\-05\-14T17:15:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +ef536d5 Merge pull request \fI\%#23718\fP from rahulhan/states_user_unit_tests +.IP \(bu 2 +aad27db Adding states/user.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23720\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-14T17:13:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23604\fP: (\fIAzidburn\fP) service.dead on systemd Minion create an Error Message +| refs: \fI\%#23607\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23548\fP: (\fIkkaig\fP) grains.list_present produces incorrect (?) output +| refs: \fI\%#23674\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23403\fP: (\fIiamfil\fP) salt.runners.cloud.action fun parameter is replaced +| refs: \fI\%#23680\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23680\fP: (\fIcachedout\fP) Rename kwarg in cloud runner +.IP \(bu 2 +\fBPR\fP \fI\%#23674\fP: (\fIcachedout\fP) Handle lists correctly in grains.list_prsesent +.IP \(bu 2 +\fBPR\fP \fI\%#23672\fP: (\fItwangboy\fP) Fix user present +.IP \(bu 2 +\fBPR\fP \fI\%#23670\fP: (\fIrallytime\fP) Backport \fI\%#23607\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23607\fP: (\fIAzidburn\fP) Fix for \fI\%#23604\fP\&. No error reporting. Exitcode !=0 are ok +| refs: \fI\%#23670\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a529d74 Merge pull request \fI\%#23720\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +06a3ebd Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.IP \(bu 2 +1b86460 Merge pull request \fI\%#23680\fP from cachedout/issue_23403 +.INDENT 2.0 +.IP \(bu 2 +d5986c2 Rename kwarg in cloud runner +.UNINDENT +.IP \(bu 2 +cd64af0 Merge pull request \fI\%#23674\fP from cachedout/issue_23548 +.INDENT 2.0 +.IP \(bu 2 +da8a2f5 Handle lists correctly in grains.list_prsesent +.UNINDENT +.IP \(bu 2 +d322a19 Merge pull request \fI\%#23672\fP from twangboy/fix_user_present +.INDENT 2.0 +.IP \(bu 2 +731e7af Merge branch \(aq2014.7\(aq of \fI\%https://github.com/saltstack/salt\fP into fix_user_present +.IP \(bu 2 +d6f70a4 Fixed user.present to create password in windows +.UNINDENT +.IP \(bu 2 +43f7025 Merge pull request \fI\%#23670\fP from rallytime/\fI\%bp\-23607\fP +.INDENT 2.0 +.IP \(bu 2 +ed30dc4 Fix for \fI\%#23604\fP\&. No error reporting. Exitcode !=0 are ok +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23704\fP: (\fIjayeshka\fP) adding states/lvs_server unit test case +@ \fI2015\-05\-14T14:22:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +13facbf Merge pull request \fI\%#23704\fP from jayeshka/lvs_server_states\-unit\-test +.IP \(bu 2 +da323da adding states/lvs_server unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23703\fP: (\fIjayeshka\fP) adding states/lvs_service unit test case +@ \fI2015\-05\-14T14:21:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +f95ca31 Merge pull request \fI\%#23703\fP from jayeshka/lvs_service_states\-unit\-test +.IP \(bu 2 +66717c8 adding states/lvs_service unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23702\fP: (\fIjayeshka\fP) Remove superfluous return statement. +@ \fI2015\-05\-14T14:20:42Z\fP +.INDENT 2.0 +.IP \(bu 2 +07e987e Merge pull request \fI\%#23702\fP from jayeshka/fix_lvs_service +.IP \(bu 2 +ecff218 fix lvs_service +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23686\fP: (\fIjfindlay\fP) remove superflous return statement +@ \fI2015\-05\-14T14:20:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +39973d4 Merge pull request \fI\%#23686\fP from jfindlay/fix_lvs_server +.IP \(bu 2 +5aaeb73 remove superflous return statement +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23690\fP: (\fIrallytime\fP) Backport \fI\%#23424\fP to 2015.5 +@ \fI2015\-05\-13T23:04:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23424\fP: (\fIjtand\fP) Added python_shell=True for refresh_db in pacman.py +| refs: \fI\%#23690\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +be7c7ef Merge pull request \fI\%#23690\fP from rallytime/\fI\%bp\-23424\fP +.IP \(bu 2 +94574b7 Added python_shell=True for refresh_db in pacman.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23681\fP: (\fIcachedout\fP) Start on 2015.5.1 release notes +@ \fI2015\-05\-13T19:44:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +1a0db43 Merge pull request \fI\%#23681\fP from cachedout/2015_5_1_release_notes +.IP \(bu 2 +bdbbfa6 Start on 2015.5.1 release notes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23679\fP: (\fIjfindlay\fP) Merge \fI\%#23616\fP +@ \fI2015\-05\-13T19:03:53Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23616\fP: (\fISnergster\fP) virtual returning none warning fixed in dev but missed in 2015.5 +| refs: \fI\%#23679\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b54075a Merge pull request \fI\%#23679\fP from jfindlay/merge_23616 +.IP \(bu 2 +6e15e19 appease pylint\(aqs blank line strictures +.IP \(bu 2 +8750680 virtual returning none warning fixed in dev but missed in 2015.5 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23675\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-13T18:35:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23611\fP: (\fIhubez\fP) master_type set to \(aqfailover\(aq but \(aqmaster\(aq is not of type list but of type +| refs: \fI\%#23637\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23479\fP: (\fIdanielmorlock\fP) Typo in pkg.removed for Gentoo? +| refs: \fI\%#23558\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23452\fP: (\fImichaelforge\fP) minion crashed with empty grain +| refs: \fI\%#23639\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23411\fP: (\fIdr4Ke\fP) grains.append should work at any level of a grain +| refs: \fI\%#23440\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23355\fP: (\fIdr4Ke\fP) salt\-ssh: \(aqsources: salt://\(aq files from \(aqpkg\(aq state are not included in salt_state.tgz +| refs: \fI\%#23530\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23110\fP: (\fImartinhoefling\fP) Copying files from gitfs in file.recurse state fails +.IP \(bu 2 +\fBISSUE\fP \fI\%#23004\fP: (\fIb18\fP) 2014.7.5 \- Windows \- pkg.list_pkgs \- "nxlog" never shows up in output. +| refs: \fI\%#23433\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#22908\fP: (\fIkaranjad\fP) Add failhard option to salt orchestration +| refs: \fI\%#23389\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#22141\fP: (\fIDeshke\fP) grains.get_or_set_hash render error if hash begins with "%" +| refs: \fI\%#23640\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23661\fP: (\fIrallytime\fP) Merge \fI\%#23640\fP with whitespace fix +.IP \(bu 2 +\fBPR\fP \fI\%#23640\fP: (\fIcachedout\fP) Add warning to get_or_set_hash about reserved chars +| refs: \fI\%#23661\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23639\fP: (\fIcachedout\fP) Handle exceptions raised by __virtual__ +.IP \(bu 2 +\fBPR\fP \fI\%#23637\fP: (\fIcachedout\fP) Convert str master to list +.IP \(bu 2 +\fBPR\fP \fI\%#23606\fP: (\fItwangboy\fP) Fixed checkbox for starting service and actually starting it +.IP \(bu 2 +\fBPR\fP \fI\%#23595\fP: (\fIrallytime\fP) Backport \fI\%#23549\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23594\fP: (\fIrallytime\fP) Backport \fI\%#23496\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23593\fP: (\fIrallytime\fP) Backport \fI\%#23442\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23592\fP: (\fIrallytime\fP) Backport \fI\%#23389\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23573\fP: (\fItechhat\fP) Scan all available networks for public and private IPs +| refs: \fI\%#23802\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23558\fP: (\fIjfindlay\fP) reorder emerge command line +.IP \(bu 2 +\fBPR\fP \fI\%#23554\fP: (\fIjleroy\fP) Debian: Hostname always updated +.IP \(bu 2 +\fBPR\fP \fI\%#23551\fP: (\fIdr4Ke\fP) grains.append unit tests, related to \fI\%#23474\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23549\fP: (\fIvr\-jack\fP) Update __init__.py +| refs: \fI\%#23595\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23537\fP: (\fIt0rrant\fP) Update changelog +.IP \(bu 2 +\fBPR\fP \fI\%#23530\fP: (\fIdr4Ke\fP) salt\-ssh state: fix including all salt:// references +.IP \(bu 2 +\fBPR\fP \fI\%#23496\fP: (\fImartinhoefling\fP) Fix for issue \fI\%#23110\fP +| refs: \fI\%#23594\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23474\fP: (\fIdr4Ke\fP) Fix grains.append in nested dictionnary grains \fI\%#23411\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23442\fP: (\fIclan\fP) add directory itself to keep list +| refs: \fI\%#23593\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23440\fP: (\fIdr4Ke\fP) fix grains.append in nested dictionnary grains \fI\%#23411\fP +| refs: \fI\%#23474\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23433\fP: (\fItwangboy\fP) Obtain all software from the registry +.IP \(bu 2 +\fBPR\fP \fI\%#23389\fP: (\fIcachedout\fP) Correct fail_hard typo +| refs: \fI\%#23592\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e480f13 Merge pull request \fI\%#23675\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +bd63548 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.INDENT 2.0 +.IP \(bu 2 +0f006ac Merge pull request \fI\%#23661\fP from rallytime/merge\-23640 +.INDENT 2.0 +.IP \(bu 2 +4427f42 Whitespace fix +.IP \(bu 2 +dd91154 Add warning to get_or_set_hash about reserved chars +.UNINDENT +.IP \(bu 2 +84e2ef8 Merge pull request \fI\%#23639\fP from cachedout/issue_23452 +.INDENT 2.0 +.IP \(bu 2 +d418b49 Syntax error! +.IP \(bu 2 +45b4015 Handle exceptions raised by __virtual__ +.UNINDENT +.IP \(bu 2 +bd9b94b Merge pull request \fI\%#23637\fP from cachedout/issue_23611 +.INDENT 2.0 +.IP \(bu 2 +56cb1f5 Fix typo +.IP \(bu 2 +f6fcf19 Convert str master to list +.UNINDENT +.IP \(bu 2 +f20c0e4 Merge pull request \fI\%#23595\fP from rallytime/\fI\%bp\-23549\fP +.INDENT 2.0 +.IP \(bu 2 +6efcac0 Update __init__.py +.UNINDENT +.IP \(bu 2 +1acaf86 Merge pull request \fI\%#23594\fP from rallytime/\fI\%bp\-23496\fP +.INDENT 2.0 +.IP \(bu 2 +d5ae1d2 Fix for issue \fI\%#23110\fP This resolves issues when the freshly created directory is removed by fileserver.update. +.UNINDENT +.IP \(bu 2 +2c221c7 Merge pull request \fI\%#23593\fP from rallytime/\fI\%bp\-23442\fP +.INDENT 2.0 +.IP \(bu 2 +39869a1 check w/ low[\(aqname\(aq] only +.IP \(bu 2 +304cc49 another fix for file defined w/ id, but require name +.IP \(bu 2 +8814d41 add directory itself to keep list +.UNINDENT +.IP \(bu 2 +fadd1ef Merge pull request \fI\%#23606\fP from twangboy/fix_installer +.INDENT 2.0 +.IP \(bu 2 +038331e Fixed checkbox for starting service and actually starting it +.UNINDENT +.UNINDENT +.IP \(bu 2 +acdd3fc Fix lint +.IP \(bu 2 +680e88f Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.INDENT 2.0 +.IP \(bu 2 +10b3f0f Merge pull request \fI\%#23592\fP from rallytime/\fI\%bp\-23389\fP +.INDENT 2.0 +.IP \(bu 2 +734cc43 Correct fail_hard typo +.UNINDENT +.IP \(bu 2 +cd34b9b Merge pull request \fI\%#23573\fP from techhat/novaquery +.INDENT 2.0 +.IP \(bu 2 +f92db5e Linting +.IP \(bu 2 +26e00d3 Scan all available networks for public and private IPs +.UNINDENT +.IP \(bu 2 +2a72cd7 Merge pull request \fI\%#23558\fP from jfindlay/fix_ebuild +.INDENT 2.0 +.IP \(bu 2 +45404fb reorder emerge command line +.UNINDENT +.IP \(bu 2 +a664a3c Merge pull request \fI\%#23530\fP from dr4Ke/fix_salt\-ssh_to_include_pkg_sources +.INDENT 2.0 +.IP \(bu 2 +5df6a80 fix pylint warning +.IP \(bu 2 +d0549e5 salt\-ssh state: fix including all salt:// references +.UNINDENT +.IP \(bu 2 +55c3869 Merge pull request \fI\%#23433\fP from twangboy/list_pkgs_fix +.INDENT 2.0 +.IP \(bu 2 +8ab5b1b Fix pylint error +.IP \(bu 2 +2d11d65 Obtain all software from the registry +.UNINDENT +.IP \(bu 2 +755bed0 Merge pull request \fI\%#23554\fP from jleroy/debian\-hostname\-fix +.INDENT 2.0 +.IP \(bu 2 +5ff749e Debian: Hostname always updated +.UNINDENT +.IP \(bu 2 +6ec87ce Merge pull request \fI\%#23551\fP from dr4Ke/grains.append_unit_tests +.INDENT 2.0 +.IP \(bu 2 +ebff9df fix pylint errors +.IP \(bu 2 +c495404 unit tests for grains.append module function +.IP \(bu 2 +0c9a323 use MagickMock +.IP \(bu 2 +c838a22 unit tests for grains.append module function +.UNINDENT +.IP \(bu 2 +e96c5c5 Merge pull request \fI\%#23474\fP from dr4Ke/fix_grains.append_nested +.INDENT 2.0 +.IP \(bu 2 +a01a5bb grains.get, parameter delimititer, versionadded: 2014.7.6 +.IP \(bu 2 +b39f504 remove debugging output +.IP \(bu 2 +b6e15e2 fix grains.append in nested dictionnary grains \fI\%#23411\fP +.UNINDENT +.IP \(bu 2 +ab7e1ae Merge pull request \fI\%#23537\fP from t0rrant/patch\-1 +.INDENT 2.0 +.IP \(bu 2 +8e03cc9 Update changelog +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23669\fP: (\fIrallytime\fP) Backport \fI\%#23586\fP to 2015.5 +@ \fI2015\-05\-13T18:27:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23586\fP: (\fILothiraldan\fP) Fix salt.state.file._unify_sources_and_hashes when sources is used without sources_hashes +| refs: \fI\%#23669\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0dad6be Merge pull request \fI\%#23669\fP from rallytime/\fI\%bp\-23586\fP +.IP \(bu 2 +ef4c6ad Remove another unused import +.IP \(bu 2 +73cfda7 Remove unused import +.IP \(bu 2 +52b68d6 Use the zip_longest from six module for python 3 compatiblity +.IP \(bu 2 +18d5ff9 Fix salt.state.file._unify_sources_and_hashes when sources is used without sources_hashes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23662\fP: (\fIrallytime\fP) Merge \fI\%#23642\fP with pylint fix +@ \fI2015\-05\-13T15:46:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23642\fP: (\fIcachedout\fP) Let saltmod handle lower\-level exceptions gracefully +| refs: \fI\%#23662\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fabef75 Merge pull request \fI\%#23662\fP from rallytime/merge\-23642 +.IP \(bu 2 +aa7bbd8 Remove unused import +.IP \(bu 2 +9e66d4c Let saltmod handle lower\-level exceptions gracefully +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23622\fP: (\fIjfindlay\fP) merge \fI\%#23508\fP +@ \fI2015\-05\-13T15:36:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23508\fP: (\fIcro\fP) Port mysql returner to postgres using jsonb datatype +| refs: \fI\%#23622\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +072b927 Merge pull request \fI\%#23622\fP from jfindlay/pgjsonb +.IP \(bu 2 +454322c appease pylint\(aqs proscription on blank line excess +.IP \(bu 2 +57c6171 Get time with timezone correct also in job return. +.IP \(bu 2 +e109d0f Get time with timezone correct. +.IP \(bu 2 +21e06b9 Fix SQL, remove unneeded imports. +.IP \(bu 2 +653f360 Stop making changes in 2 places. +.IP \(bu 2 +d6daaa0 Typo. +.IP \(bu 2 +7d748bf SSL is handled differently by Pg, so don\(aqt set it here. +.IP \(bu 2 +cc7c377 Fill alter_time field in salt_events with current time with timezone. +.IP \(bu 2 +43defe9 Port mysql module to Postgres using jsonb datatypes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23651\fP: (\fIjayeshka\fP) adding solr unit test case +@ \fI2015\-05\-13T15:26:15Z\fP +.INDENT 2.0 +.IP \(bu 2 +c1bdd4d Merge pull request \fI\%#23651\fP from jayeshka/solr\-unit\-test +.IP \(bu 2 +6e05148 adding solr unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23649\fP: (\fIjayeshka\fP) adding states/libvirt unit test case +@ \fI2015\-05\-13T15:24:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +ee43411 Merge pull request \fI\%#23649\fP from jayeshka/libvirt_states\-unit\-test +.IP \(bu 2 +0fb923a adding states/libvirt unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23648\fP: (\fIjayeshka\fP) adding states/linux_acl unit test case +@ \fI2015\-05\-13T15:24:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +c7fc466 Merge pull request \fI\%#23648\fP from jayeshka/linux_acl_states\-unit\-test +.IP \(bu 2 +3f0ab29 removed error. +.IP \(bu 2 +11081c1 adding states/linux_acl unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23650\fP: (\fIjayeshka\fP) adding states/kmod unit test case +@ \fI2015\-05\-13T15:09:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +4cba7ba Merge pull request \fI\%#23650\fP from jayeshka/kmod_states\-unit\-test +.IP \(bu 2 +1987015 adding states/kmod unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23633\fP: (\fIjayeshka\fP) made changes to test_interfaces function. +@ \fI2015\-05\-13T06:51:07Z\fP +.INDENT 2.0 +.IP \(bu 2 +bc8faf1 Merge pull request \fI\%#23633\fP from jayeshka/win_network\-2015.5\-unit\-test +.IP \(bu 2 +0936e1d made changes to test_interfaces function. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23619\fP: (\fIjfindlay\fP) fix kmod.present processing of module loading +@ \fI2015\-05\-13T01:16:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +7df3579 Merge pull request \fI\%#23619\fP from jfindlay/fix_kmod_state +.IP \(bu 2 +73facbf fix kmod.present processing of module loading +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23598\fP: (\fIrahulhan\fP) Adding states/win_dns_client.py unit tests +@ \fI2015\-05\-12T21:47:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +d4f3095 Merge pull request \fI\%#23598\fP from rahulhan/states_win_dns_client_unit_test +.IP \(bu 2 +d08d885 Adding states/win_dns_client.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23597\fP: (\fIrahulhan\fP) Adding states/vbox_guest.py unit tests +@ \fI2015\-05\-12T21:46:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +811c6a1 Merge pull request \fI\%#23597\fP from rahulhan/states_vbox_guest_unit_test +.IP \(bu 2 +6a2909e Removed errors +.IP \(bu 2 +4cde78a Adding states/vbox_guest.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23615\fP: (\fIrallytime\fP) Backport \fI\%#23577\fP to 2015.5 +@ \fI2015\-05\-12T21:19:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23577\fP: (\fImsciciel\fP) Fix find and remove functions to pass database param +| refs: \fI\%#23615\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +029ff11 Merge pull request \fI\%#23615\fP from rallytime/\fI\%bp\-23577\fP +.IP \(bu 2 +6f74477 Fix find and remove functions to pass database param +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23603\fP: (\fIrahulhan\fP) Adding states/winrepo.py unit tests +@ \fI2015\-05\-12T18:40:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +b858953 Merge pull request \fI\%#23603\fP from rahulhan/states_winrepo_unit_test +.IP \(bu 2 +a66e7e7 Adding states/winrepo.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23602\fP: (\fIrahulhan\fP) Adding states/win_path.py unit tests +@ \fI2015\-05\-12T18:39:37Z\fP +.INDENT 2.0 +.IP \(bu 2 +3cbbd6d Merge pull request \fI\%#23602\fP from rahulhan/states_win_path_unit_test +.IP \(bu 2 +122c29f Adding states/win_path.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23600\fP: (\fIrahulhan\fP) Adding states/win_network.py unit tests +@ \fI2015\-05\-12T18:39:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +3c904e8 Merge pull request \fI\%#23600\fP from rahulhan/states_win_network_unit_test +.IP \(bu 2 +b418404 removed lint error +.IP \(bu 2 +1be8023 Adding states/win_network.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23599\fP: (\fIrahulhan\fP) Adding win_firewall.py unit tests +@ \fI2015\-05\-12T18:37:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +10243a7 Merge pull request \fI\%#23599\fP from rahulhan/states_win_firewall_unit_test +.IP \(bu 2 +6cda890 Adding win_firewall.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23601\fP: (\fIbasepi\fP) Add versionadded for jboss module/state +@ \fI2015\-05\-12T17:22:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +e73071d Merge pull request \fI\%#23601\fP from basepi/jboss.version.added +.IP \(bu 2 +0174c8f Add versionadded for jboss module/state +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23469\fP: (\fIs0undt3ch\fP) Call the windows specific function not the general one +@ \fI2015\-05\-12T16:47:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +9beb7bc Merge pull request \fI\%#23469\fP from s0undt3ch/hotfix/call\-the\-win\-func +.IP \(bu 2 +83e88a3 Call the windows specific function not the general one +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23583\fP: (\fIjayeshka\fP) adding states/ipset unit test case +@ \fI2015\-05\-12T16:31:55Z\fP +.INDENT 2.0 +.IP \(bu 2 +d2f0975 Merge pull request \fI\%#23583\fP from jayeshka/ipset_states\-unit\-test +.IP \(bu 2 +4330cf4 adding states/ipset unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23582\fP: (\fIjayeshka\fP) adding states/keyboard unit test case +@ \fI2015\-05\-12T16:31:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +82a47e8 Merge pull request \fI\%#23582\fP from jayeshka/keyboard_states\-unit\-test +.IP \(bu 2 +fa94d7a adding states/keyboard unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23581\fP: (\fIjayeshka\fP) adding states/layman unit test case +@ \fI2015\-05\-12T16:30:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +77e5b28 Merge pull request \fI\%#23581\fP from jayeshka/layman_states\-unit\-test +.IP \(bu 2 +297b055 adding states/layman unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23580\fP: (\fIjayeshka\fP) adding smf unit test case +@ \fI2015\-05\-12T16:29:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +cbe3282 Merge pull request \fI\%#23580\fP from jayeshka/smf\-unit\-test +.IP \(bu 2 +4f97191 adding smf unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23572\fP: (\fIThe\-Loeki\fP) Fix regression of \fI\%#21355\fP introduced by \fI\%#21603\fP +@ \fI2015\-05\-12T16:28:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#21603\fP: (\fIipmb\fP) ssh_auth.present fails on key without comment +| refs: \fI\%#23572\fP \fI\%#23572\fP +.IP \(bu 2 +\fBPR\fP \fI\%#21355\fP: (\fIThe\-Loeki\fP) Fix for comments containing whitespaces +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +16a3338 Merge pull request \fI\%#23572\fP from The\-Loeki/ssh_auth_fix +.IP \(bu 2 +d8248dd Fix regression of \fI\%#21355\fP introduced by \fI\%#21603\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23565\fP: (\fIgarethgreenaway\fP) fix to aptpkg module +@ \fI2015\-05\-12T16:25:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23490\fP: (\fIlichtamberg\fP) salt.modules.aptpkg.upgrade should have default "dist_upgrade=False" +| refs: \fI\%#23565\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f843f89 Merge pull request \fI\%#23565\fP from garethgreenaway/2015_2_aptpkg_upgrade_default_to_upgrade +.IP \(bu 2 +97ae514 aptpkg.upgrade should default to upgrade instead of dist_upgrade. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23550\fP: (\fIjfindlay\fP) additional mock for rh_ip_test test_build_bond +@ \fI2015\-05\-12T15:17:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23473\fP: (\fIterminalmage\fP) unit.modules.rh_ip_test.RhipTestCase.test_build_bond is not properly mocked +| refs: \fI\%#23550\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c1157cd Merge pull request \fI\%#23550\fP from jfindlay/fix_rh_ip_test +.IP \(bu 2 +e9b94d3 additional mock for rh_ip_test test_build_bond +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23552\fP: (\fIgarethgreenaway\fP) Fix for an issue caused by a previous pull request +@ \fI2015\-05\-11T21:54:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +b593328 Merge pull request \fI\%#23552\fP from garethgreenaway/2015_5_returner_fix_broken_previous_pr +.IP \(bu 2 +7d70e2b Passed argumentes in the call _fetch_profile_opts to were in the wrong order +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23547\fP: (\fIslinu3d\fP) Added AWS v4 signature support for 2015.5 +@ \fI2015\-05\-11T21:52:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +d0f9682 Merge pull request \fI\%#23547\fP from slinu3d/2015.5 +.IP \(bu 2 +f3bfdb5 Fixed urlparse and urlencode calls +.IP \(bu 2 +802dbdb Added AWS v4 signature support for 2015.5 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23544\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-11T18:02:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23159\fP: (\fIaneeshusa\fP) Unused validator +.IP \(bu 2 +\fBISSUE\fP \fI\%#20518\fP: (\fIekle\fP) module s3.get does not support eu\-central\-1 +| refs: \fI\%#23467\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#563\fP: (\fIchutz\fP) pidfile support for minion and master daemons +| refs: \fI\%#23460\fP \fI\%#23461\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23538\fP: (\fIcro\fP) Update date in LICENSE file +.IP \(bu 2 +\fBPR\fP \fI\%#23505\fP: (\fIaneeshusa\fP) Remove unused ssh config validator. Fixes \fI\%#23159\fP\&. +.IP \(bu 2 +\fBPR\fP \fI\%#23467\fP: (\fIslinu3d\fP) Added AWS v4 signature support +.IP \(bu 2 +\fBPR\fP \fI\%#23460\fP: (\fIs0undt3ch\fP) [2014.7] Update to latest stable bootstrap script v2015.05.07 +.IP \(bu 2 +\fBPR\fP \fI\%#23444\fP: (\fItechhat\fP) Add create_attach_volume to nova driver +.IP \(bu 2 +\fBPR\fP \fI\%#23439\fP: (\fItechhat\fP) Add wait_for_passwd_maxtries variable +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +06c6a1f Merge pull request \fI\%#23544\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +f8a36bc Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.INDENT 2.0 +.IP \(bu 2 +b79fed3 Merge pull request \fI\%#23538\fP from cro/licupdate +.INDENT 2.0 +.IP \(bu 2 +345efe2 Update date in LICENSE file +.UNINDENT +.IP \(bu 2 +a123a36 Merge pull request \fI\%#23505\fP from aneeshusa/remove\-unused\-ssh\-config\-validator +.INDENT 2.0 +.IP \(bu 2 +90af167 Remove unused ssh config validator. Fixes \fI\%#23159\fP\&. +.UNINDENT +.IP \(bu 2 +ca2c21a Merge pull request \fI\%#23467\fP from slinu3d/2014.7 +.INDENT 2.0 +.IP \(bu 2 +0b4081d Fixed pylint error at line 363 +.IP \(bu 2 +5be5eb5 Fixed pylink errors +.IP \(bu 2 +e64f374 Fixed lint errors +.IP \(bu 2 +b9d1ac4 Added AWS v4 signature support +.UNINDENT +.IP \(bu 2 +e6f9eec Merge pull request \fI\%#23444\fP from techhat/novacreateattach +.INDENT 2.0 +.IP \(bu 2 +ebdb7ea Add create_attach_volume to nova driver +.UNINDENT +.IP \(bu 2 +e331463 Merge pull request \fI\%#23460\fP from s0undt3ch/hotfix/bootstrap\-script\-2014.7 +.INDENT 2.0 +.IP \(bu 2 +edcd0c4 Update to latest stable bootstrap script v2015.05.07 +.UNINDENT +.IP \(bu 2 +7a8ce1a Merge pull request \fI\%#23439\fP from techhat/maxtries +.INDENT 2.0 +.IP \(bu 2 +0ad3ff2 Add wait_for_passwd_maxtries variable +.UNINDENT +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23470\fP: (\fItwangboy\fP) Fixed service.restart for salt\-minion +@ \fI2015\-05\-11T17:54:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23426\fP: (\fItwangboy\fP) Can\(aqt restart salt\-minion on 64 bit windows (2015.5.0) +| refs: \fI\%#23470\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +aa5b896 Merge pull request \fI\%#23470\fP from twangboy/fix_svc_restart +.IP \(bu 2 +b3f284c Fixed tests +.IP \(bu 2 +ad44d79 Fixed service.restart for salt\-minion +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23539\fP: (\fIrahulhan\fP) Adding states/virtualenv_mod.py unit tests +@ \fI2015\-05\-11T17:02:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +67988b2 Merge pull request \fI\%#23539\fP from rahulhan/states_virtualenv_mod_unit_test +.IP \(bu 2 +750bb07 Adding states/virtualenv_mod.py unit tests +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +6f0cf2e Merge remote\-tracking branch \(aqupstream/2015.2\(aq into 2015.5 +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23244\fP: (\fIfreimer\fP) Caller not available in reactors +| refs: \fI\%#23245\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23509\fP: (\fIkeesbos\fP) Catch the unset (empty/None) environment case +.IP \(bu 2 +\fBPR\fP \fI\%#23423\fP: (\fIcachedout\fP) Remove jid_event from state.orch +.IP \(bu 2 +\fBPR\fP \fI\%#23245\fP: (\fIfreimer\fP) Add Caller functionality to reactors. +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c966196 Merge pull request \fI\%#23423\fP from cachedout/remove_jid_event_from_orch +.INDENT 2.0 +.IP \(bu 2 +f81aab7 Remove jid_event from state.orch +.UNINDENT +.IP \(bu 2 +2bb09b7 Merge pull request \fI\%#23509\fP from keesbos/Catch_empty_environment +.INDENT 2.0 +.IP \(bu 2 +6dedeac Catch the unset (empty/None) environment case +.UNINDENT +.IP \(bu 2 +6d42f30 Merge pull request \fI\%#23245\fP from freimer/issue_23244 +.INDENT 2.0 +.IP \(bu 2 +24cf6eb Add Caller functionality to reactors. +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23513\fP: (\fIgladiatr72\fP) short\-circuit auto\-failure of iptables.delete state +@ \fI2015\-05\-11T15:18:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +c3f03d8 Merge pull request \fI\%#23513\fP from gladiatr72/RFC_stop_iptables.check_from_short\-circuiting_position\-only_delete_rule +.IP \(bu 2 +c71714c short\-circuit auto\-failure of iptables.delete state if position argument is set without the other accoutrements that check_rule requires. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23534\fP: (\fIjayeshka\fP) adding states/ini_manage unit test case +@ \fI2015\-05\-11T14:32:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +4e77f6f Merge pull request \fI\%#23534\fP from jayeshka/ini_manage_states\-unit\-test +.IP \(bu 2 +831223c adding states/ini_manage unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23533\fP: (\fIjayeshka\fP) adding states/hipchat unit test case +@ \fI2015\-05\-11T14:30:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +11ba9ed Merge pull request \fI\%#23533\fP from jayeshka/hipchat\-states\-unit\-test +.IP \(bu 2 +41d14b3 adding states/hipchat unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23532\fP: (\fIjayeshka\fP) adding states/ipmi unit test case +@ \fI2015\-05\-11T14:28:15Z\fP +.INDENT 2.0 +.IP \(bu 2 +e542113 Merge pull request \fI\%#23532\fP from jayeshka/ipmi\-states\-unit\-test +.IP \(bu 2 +fc3e64a adding states/ipmi unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23531\fP: (\fIjayeshka\fP) adding service unit test case +@ \fI2015\-05\-11T14:27:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +9ba85fd Merge pull request \fI\%#23531\fP from jayeshka/service\-unit\-test +.IP \(bu 2 +3ad5314 adding service unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23517\fP: (\fIgarethgreenaway\fP) fix to returners +@ \fI2015\-05\-11T14:20:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23512\fP: (\fICode\-Vortex\fP) hipchat_returner / slack_returner not work correctly +| refs: \fI\%#23517\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +32838cd Merge pull request \fI\%#23517\fP from garethgreenaway/23512_2015_5_returners_with_profiles +.IP \(bu 2 +81e31e2 fix for returners that utilize profile attributes. code in the if else statement was backwards. \fI\%#23512\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23502\fP: (\fIrahulhan\fP) Adding states/win_servermanager.py unit tests +@ \fI2015\-05\-08T19:47:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +6be7d8d Merge pull request \fI\%#23502\fP from rahulhan/states_win_servermanager_unit_test +.IP \(bu 2 +2490074 Adding states/win_servermanager.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23495\fP: (\fIjayeshka\fP) adding seed unit test case +@ \fI2015\-05\-08T17:30:38Z\fP +.INDENT 2.0 +.IP \(bu 2 +6048578 Merge pull request \fI\%#23495\fP from jayeshka/seed\-unit\-test +.IP \(bu 2 +3f134bc adding seed unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23494\fP: (\fIjayeshka\fP) adding sensors unit test case +@ \fI2015\-05\-08T17:30:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +70bc3c1 Merge pull request \fI\%#23494\fP from jayeshka/sensors\-unit\-test +.IP \(bu 2 +1fb48a3 adding sensors unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23493\fP: (\fIjayeshka\fP) adding states/incron unit test case +@ \fI2015\-05\-08T17:29:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +b981b20 Merge pull request \fI\%#23493\fP from jayeshka/incron\-states\-unit\-test +.IP \(bu 2 +cc7bc17 adding states/incron unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23492\fP: (\fIjayeshka\fP) adding states/influxdb_database unit test case +@ \fI2015\-05\-08T17:29:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +4019c49 Merge pull request \fI\%#23492\fP from jayeshka/influxdb_database\-states\-unit\-test +.IP \(bu 2 +e1fcac8 adding states/influxdb_database unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23491\fP: (\fIjayeshka\fP) adding states/influxdb_user unit test case +@ \fI2015\-05\-08T16:24:07Z\fP +.INDENT 2.0 +.IP \(bu 2 +d317a77 Merge pull request \fI\%#23491\fP from jayeshka/influxdb_user\-states\-unit\-test +.IP \(bu 2 +9d4043f adding states/influxdb_user unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23477\fP: (\fIgalet\fP) LDAP auth: Escape filter value for group membership search +@ \fI2015\-05\-07T22:04:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +e0b2a73 Merge pull request \fI\%#23477\fP from galet/ldap\-filter\-escaping +.IP \(bu 2 +33038b9 LDAP auth: Escape filter value for group membership search +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23476\fP: (\fIcachedout\fP) Lint becaon +@ \fI2015\-05\-07T19:55:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23431\fP: (\fIUtahDave\fP) Beacon fixes +| refs: \fI\%#23476\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e1719fe Merge pull request \fI\%#23476\fP from cachedout/lint_23431 +.IP \(bu 2 +8d1ff20 Lint becaon +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23431\fP: (\fIUtahDave\fP) Beacon fixes +| refs: \fI\%#23476\fP +@ \fI2015\-05\-07T19:53:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +1e299ed Merge pull request \fI\%#23431\fP from UtahDave/beacon_fixes +.IP \(bu 2 +152f223 remove unused import +.IP \(bu 2 +81198f9 fix interval logic and example +.IP \(bu 2 +5504778 update to proper examples +.IP \(bu 2 +6890439 fix list for mask +.IP \(bu 2 +ee7b579 remove custom interval code. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23468\fP: (\fIrahulhan\fP) Adding states/win_system.py unit tests +@ \fI2015\-05\-07T19:20:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +ea55c44 Merge pull request \fI\%#23468\fP from rahulhan/states_win_system_unit_test +.IP \(bu 2 +33f8c12 Adding states/win_system.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23466\fP: (\fIUtahDave\fP) minor spelling fix +@ \fI2015\-05\-07T19:19:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +e6e1114 Merge pull request \fI\%#23466\fP from UtahDave/2015.5local +.IP \(bu 2 +b2c399a minor spelling fix +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23461\fP: (\fIs0undt3ch\fP) [2015.5] Update to latest stable bootstrap script v2015.05.07 +@ \fI2015\-05\-07T19:16:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#563\fP: (\fIchutz\fP) pidfile support for minion and master daemons +| refs: \fI\%#23460\fP \fI\%#23461\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4eeb1e6 Merge pull request \fI\%#23461\fP from s0undt3ch/hotfix/bootstrap\-script +.IP \(bu 2 +638c63d Update to latest stable bootstrap script v2015.05.07 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23450\fP: (\fIjayeshka\fP) adding scsi unit test case +@ \fI2015\-05\-07T19:00:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +8651278 Merge pull request \fI\%#23450\fP from jayeshka/scsi\-unit\-test +.IP \(bu 2 +e7269ff adding scsi unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23449\fP: (\fIjayeshka\fP) adding s3 unit test case +@ \fI2015\-05\-07T18:59:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +8b374ae Merge pull request \fI\%#23449\fP from jayeshka/s3\-unit\-test +.IP \(bu 2 +85786bf adding s3 unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23448\fP: (\fIjayeshka\fP) adding states/keystone unit test case +@ \fI2015\-05\-07T18:58:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +49b431c Merge pull request \fI\%#23448\fP from jayeshka/keystone\-states\-unit\-test +.IP \(bu 2 +a3050eb adding states/keystone unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23447\fP: (\fIjayeshka\fP) adding states/grafana unit test case +@ \fI2015\-05\-07T18:58:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +23d7e7e Merge pull request \fI\%#23447\fP from jayeshka/grafana\-states\-unit\-test +.IP \(bu 2 +7e90a4a adding states/grafana unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23438\fP: (\fItechhat\fP) Gate requests import +@ \fI2015\-05\-07T07:22:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +1fd0bc2 Merge pull request \fI\%#23438\fP from techhat/gaterequests +.IP \(bu 2 +d5b15fc Gate requests import +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23429\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-07T05:35:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#17245\fP: (\fItomashavlas\fP) localemod does not generate locale for Arch +| refs: \fI\%#23307\fP \fI\%#23397\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23425\fP: (\fIbasepi\fP) [2014.7] Fix typo in FunctionWrapper +.IP \(bu 2 +\fBPR\fP \fI\%#23422\fP: (\fIcro\fP) $HOME should not be used, some shells don\(aqt set it. +.IP \(bu 2 +\fBPR\fP \fI\%#23414\fP: (\fIjfindlay\fP) 2015.2 \-> 2015.5 +.IP \(bu 2 +\fBPR\fP \fI\%#23409\fP: (\fIterminalmage\fP) Update Lithium docstrings in 2014.7 branch +| refs: \fI\%#23410\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23404\fP: (\fIhvnsweeting\fP) saltapi cherrypy: initialize var when POST body is empty +.IP \(bu 2 +\fBPR\fP \fI\%#23397\fP: (\fIjfindlay\fP) add more flexible whitespace to locale_gen search +.IP \(bu 2 +\fBPR\fP \fI\%#23385\fP: (\fIrallytime\fP) Backport \fI\%#23346\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23346\fP: (\fIericfode\fP) Allow file_map in salt\-cloud to handle folders. +| refs: \fI\%#23385\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3c4f734 Merge pull request \fI\%#23429\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +7729834 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.IP \(bu 2 +644eb75 Merge pull request \fI\%#23422\fP from cro/gce_sh_home +.INDENT 2.0 +.IP \(bu 2 +4ef9e6b Don\(aqt use $HOME to find user\(aqs directory, some shells don\(aqt set it +.UNINDENT +.IP \(bu 2 +ef17ab4 Merge pull request \fI\%#23425\fP from basepi/functionwrapper_typo +.INDENT 2.0 +.IP \(bu 2 +c390737 Fix typo in FunctionWrapper +.UNINDENT +.IP \(bu 2 +1b13ec0 Merge pull request \fI\%#23385\fP from rallytime/\fI\%bp\-23346\fP +.INDENT 2.0 +.IP \(bu 2 +9efc13c more linting fixes +.IP \(bu 2 +cf131c9 cleaned up some pylint errors +.IP \(bu 2 +f981699 added logic to sftp_file and file_map to allow folder uploads using file_map +.UNINDENT +.IP \(bu 2 +f8c7a62 Merge pull request \fI\%#23414\fP from jfindlay/update_branch +.INDENT 2.0 +.IP \(bu 2 +8074d16 2015.2 \-> 2015.5 +.UNINDENT +.IP \(bu 2 +54b3bd4 Merge pull request \fI\%#23404\fP from hvnsweeting/cherrypy\-post\-emptybody\-fix +.INDENT 2.0 +.IP \(bu 2 +f85f8f9 initialize var when POST body is empty +.UNINDENT +.IP \(bu 2 +160f703 Merge pull request \fI\%#23409\fP from terminalmage/update\-lithium\-docstrings\-2014.7 +.INDENT 2.0 +.IP \(bu 2 +bc97d01 Fix sphinx typo +.IP \(bu 2 +20006b0 Update Lithium docstrings in 2014.7 branch +.UNINDENT +.IP \(bu 2 +aa5fb0a Merge pull request \fI\%#23397\fP from jfindlay/fix_locale_gen +.INDENT 2.0 +.IP \(bu 2 +0941fef add more flexible whitespace to locale_gen search +.UNINDENT +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23396\fP: (\fIbasepi\fP) [2015.2] Merge forward from 2014.7 to 2015.2 +@ \fI2015\-05\-06T21:42:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23294\fP: (\fIvariia\fP) file.replace fails to append if repl string partially available +| refs: \fI\%#23350\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#23026\fP: (\fIadelcast\fP) Incorrect salt\-syndic logfile and pidfile locations +| refs: \fI\%#23341\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#22742\fP: (\fIhvnsweeting\fP) salt\-master says: "This master address: \(aqsalt\(aq was previously resolvable but now fails to resolve!" +| refs: \fI\%#23344\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#19114\fP: (\fIpykler\fP) salt\-ssh and gpg pillar renderer +| refs: \fI\%#23272\fP \fI\%#23347\fP \fI\%#23188\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#17245\fP: (\fItomashavlas\fP) localemod does not generate locale for Arch +| refs: \fI\%#23307\fP \fI\%#23397\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#580\fP: (\fIthatch45\fP) recursive watch not being caught +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#552\fP: (\fIjhutchins\fP) Support require and watch under the same state dec +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23368\fP: (\fIkaithar\fP) Backport \fI\%#23367\fP to 2014.7 +.IP \(bu 2 +\fBPR\fP \fI\%#23367\fP: (\fIkaithar\fP) Put the sed insert statement back in to the output. +| refs: \fI\%#23368\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23350\fP: (\fIlorengordon\fP) Append/prepend: search for full line +.IP \(bu 2 +\fBPR\fP \fI\%#23347\fP: (\fIbasepi\fP) [2014.7] Salt\-SSH Backport FunctionWrapper.__contains__ +.IP \(bu 2 +\fBPR\fP \fI\%#23344\fP: (\fIcachedout\fP) Explicitely set file_client on master +.IP \(bu 2 +\fBPR\fP \fI\%#23341\fP: (\fIcachedout\fP) Fix syndic pid and logfile path +.IP \(bu 2 +\fBPR\fP \fI\%#23324\fP: (\fIs0undt3ch\fP) [2014.7] Update to the latest stable release of the bootstrap script v2015.05.04 +.IP \(bu 2 +\fBPR\fP \fI\%#23318\fP: (\fIcellscape\fP) Honor seed argument in LXC container initializaton +.IP \(bu 2 +\fBPR\fP \fI\%#23311\fP: (\fIcellscape\fP) Fix new container initialization in LXC runner +| refs: \fI\%#23318\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23307\fP: (\fIjfindlay\fP) check for /etc/locale.gen +.IP \(bu 2 +\fBPR\fP \fI\%#23272\fP: (\fIbasepi\fP) [2014.7] Allow salt\-ssh minion config overrides via master config and roster +| refs: \fI\%#23347\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23188\fP: (\fIbasepi\fP) [2014.7] Work around bug in salt\-ssh in config.get for gpg renderer +| refs: \fI\%#23272\fP +.IP \(bu 2 +\fBPR\fP \fI\%#18368\fP: (\fIbasepi\fP) Merge forward from 2014.7 to develop +| refs: \fI\%#23367\fP \fI\%#23368\fP +.IP \(bu 2 +\fBPR\fP \fI\%#589\fP: (\fIepoelke\fP) add \-\-quiet and \-\-outfile options to saltkey +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#567\fP: (\fIbastichelaar\fP) Added upstart module +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#560\fP: (\fIUtahDave\fP) The runas feature that was added in 93423aa2e5e4b7de6452090b0039560d2b13... +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#504\fP: (\fISEJeff\fP) File state goodies +| refs: \fI\%#23324\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1fb8445 Merge pull request \fI\%#23396\fP from basepi/merge\-forward\-2015.2 +.IP \(bu 2 +2766c8c Fix typo in FunctionWrapper +.IP \(bu 2 +fd09cda Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.2 +.INDENT 2.0 +.IP \(bu 2 +0c76dd4 Merge pull request \fI\%#23368\fP from kaithar/\fI\%bp\-23367\fP +.INDENT 2.0 +.IP \(bu 2 +577f419 Pylint fix +.IP \(bu 2 +8d9acd1 Put the sed insert statement back in to the output. +.UNINDENT +.IP \(bu 2 +3493cc1 Merge pull request \fI\%#23350\fP from lorengordon/file.replace_assume_line +.INDENT 2.0 +.IP \(bu 2 +b60e224 Append/prepend: search for full line +.UNINDENT +.IP \(bu 2 +7be5c48 Merge pull request \fI\%#23341\fP from cachedout/issue_23026 +.INDENT 2.0 +.IP \(bu 2 +e98e65e Fix tests +.IP \(bu 2 +6011b43 Fix syndic pid and logfile path +.UNINDENT +.IP \(bu 2 +ea61abf Merge pull request \fI\%#23272\fP from basepi/salt\-ssh.minion.config.19114 +.INDENT 2.0 +.IP \(bu 2 +c223309 Add versionadded +.IP \(bu 2 +be7407f Lint +.IP \(bu 2 +c2c3375 Missing comma +.IP \(bu 2 +8e3e8e0 Pass the minion_opts through the FunctionWrapper +.IP \(bu 2 +cb69cd0 Match the master config template in the master config reference +.IP \(bu 2 +87fc316 Add Salt\-SSH section to master config template +.IP \(bu 2 +91dd9dc Add ssh_minion_opts to master config ref +.IP \(bu 2 +c273ea1 Add minion config to salt\-ssh doc +.IP \(bu 2 +a0b6b76 Add minion_opts to roster docs +.IP \(bu 2 +5212c35 Accept minion_opts from the target information +.IP \(bu 2 +e2099b6 Process \fIssh_minion_opts\fP from master config +.IP \(bu 2 +3b64214 Revert "Work around bug in salt\-ssh in config.get for gpg renderer" +.IP \(bu 2 +494953a Remove the strip (embracing multi\-line YAML dump) +.IP \(bu 2 +fe87f0f Dump multi\-line yaml into the SHIM +.IP \(bu 2 +b751a72 Inject local minion config into shim if available +.UNINDENT +.IP \(bu 2 +4f760dd Merge pull request \fI\%#23347\fP from basepi/salt\-ssh.functionwrapper.contains.19114 +.INDENT 2.0 +.IP \(bu 2 +30595e3 Backport FunctionWrapper.__contains__ +.UNINDENT +.IP \(bu 2 +02658b1 Merge pull request \fI\%#23344\fP from cachedout/issue_22742 +.INDENT 2.0 +.IP \(bu 2 +5adc96c Explicitely set file_client on master +.UNINDENT +.IP \(bu 2 +ba7605d Merge pull request \fI\%#23318\fP from cellscape/honor\-seed\-argument +.INDENT 2.0 +.IP \(bu 2 +228b1be Honor seed argument in LXC container initializaton +.UNINDENT +.IP \(bu 2 +4ac4509 Merge pull request \fI\%#23307\fP from jfindlay/fix_locale_gen +.INDENT 2.0 +.IP \(bu 2 +101199a check for /etc/locale.gen +.UNINDENT +.IP \(bu 2 +f790f42 Merge pull request \fI\%#23324\fP from s0undt3ch/hotfix/bootstrap\-script\-2014.7 +.IP \(bu 2 +6643e47 Update to the latest stable release of the bootstrap script v2015.05.04 +.UNINDENT +.UNINDENT +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +23d4feb Merge remote\-tracking branch \(aqupstream/2015.2\(aq into 2015.5 +.UNINDENT +.INDENT 0.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23412\fP: (\fIrahulhan\fP) Adding states/win_update.py unit tests +@ \fI2015\-05\-06T18:31:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +b3c1672 Merge pull request \fI\%#23412\fP from rahulhan/states_win_update_unit_test +.IP \(bu 2 +9bc1519 Removed unwanted imports +.IP \(bu 2 +f12bfcf Adding states/win_update.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23413\fP: (\fIterminalmage\fP) Update manpages for 2015.2 \-> 2015.5 +@ \fI2015\-05\-06T17:12:57Z\fP +.INDENT 2.0 +.IP \(bu 2 +f2d7646 Merge pull request \fI\%#23413\fP from terminalmage/update\-manpages +.IP \(bu 2 +23fa440 Update manpages to reflect 2015.2 rename to 2015.5 +.IP \(bu 2 +0fdaa73 Fix missed docstring updates from 2015.2 \-> 2015.5 +.IP \(bu 2 +4fea5ba Add missing RST file +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23410\fP: (\fIterminalmage\fP) Update Lithium docstrings in 2015.2 branch +@ \fI2015\-05\-06T15:53:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23409\fP: (\fIterminalmage\fP) Update Lithium docstrings in 2014.7 branch +| refs: \fI\%#23410\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +bafbea7 Merge pull request \fI\%#23410\fP from terminalmage/update\-lithium\-docstrings\-2015.2 +.IP \(bu 2 +d395565 Update Lithium docstrings in 2015.2 branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23407\fP: (\fIjayeshka\fP) adding rsync unit test case +@ \fI2015\-05\-06T15:52:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +02ef41a Merge pull request \fI\%#23407\fP from jayeshka/rsync\-unit\-test +.IP \(bu 2 +a4dd836 adding rsync unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23406\fP: (\fIjayeshka\fP) adding states/lxc unit test case +@ \fI2015\-05\-06T15:51:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +58ec2a2 Merge pull request \fI\%#23406\fP from jayeshka/lxc\-states\-unit\-test +.IP \(bu 2 +32a0d03 adding states/lxc unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23395\fP: (\fIbasepi\fP) [2015.2] Add note to 2015.2.0 release notes about master opts in pillar +@ \fI2015\-05\-05T22:15:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +8837d00 Merge pull request \fI\%#23395\fP from basepi/2015.2.0masteropts +.IP \(bu 2 +b261c95 Add note to 2015.2.0 release notes about master opts in pillar +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23393\fP: (\fIbasepi\fP) [2015.2] Add warning about python_shell changes to 2015.2.0 release notes +@ \fI2015\-05\-05T22:12:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +f79aed5 Merge pull request \fI\%#23393\fP from basepi/2015.2.0python_shell +.IP \(bu 2 +b2f033f Add CLI note +.IP \(bu 2 +48e7b3e Add warning about python_shell changes to 2015.2.0 release notes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23380\fP: (\fIgladiatr72\fP) Fix for double output with static salt cli/v2015.2 +@ \fI2015\-05\-05T21:44:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +a977776 Merge pull request \fI\%#23380\fP from gladiatr72/fix_for_double_output_with_static__salt_CLI/v2015.2 +.IP \(bu 2 +c47fdd7 Actually removed the \fBstatic\fP bits from below the else: fold this time. +.IP \(bu 2 +4ee3679 Fix for incorrect output with salt CLI \-\-static option +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23379\fP: (\fIrahulhan\fP) Adding states/rabbitmq_cluster.py +@ \fI2015\-05\-05T21:44:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +5c9543c Merge pull request \fI\%#23379\fP from rahulhan/states_rabbitmq_cluster_test +.IP \(bu 2 +04c22d1 Adding states/rabbitmq_cluster.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23377\fP: (\fIrahulhan\fP) Adding states/xmpp.py unit tests +@ \fI2015\-05\-05T21:43:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +430f080 Merge pull request \fI\%#23377\fP from rahulhan/states_xmpp_test +.IP \(bu 2 +32923b5 Adding states/xmpp.py unit tests +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23335\fP: (\fIsteverweber\fP) 2015.2: include doc in master config for module_dirs +@ \fI2015\-05\-05T21:28:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +8c057e6 Merge pull request \fI\%#23335\fP from steverweber/2015.2 +.IP \(bu 2 +5e3bae9 help installing python pysphere lib +.IP \(bu 2 +97513b0 include module_dirs +.IP \(bu 2 +36b1c87 include module_dirs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23362\fP: (\fIjayeshka\fP) adding states/zk_concurrency unit test case +@ \fI2015\-05\-05T15:50:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +1648253 Merge pull request \fI\%#23362\fP from jayeshka/zk_concurrency\-states\-unit\-test +.IP \(bu 2 +f60dda4 adding states/zk_concurrency unit test case +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23363\fP: (\fIjayeshka\fP) adding riak unit test case +@ \fI2015\-05\-05T14:23:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +1cdaeed Merge pull request \fI\%#23363\fP from jayeshka/riak\-unit\-test +.IP \(bu 2 +f9da6db adding riak unit test case +.UNINDENT +.UNINDENT +.SS Salt 2015.5.2 Release Notes +.INDENT 0.0 +.TP +.B release +2015\-06\-10 +.UNINDENT +.sp +Version 2015.5.2 is a bugfix release for \fB2015.5.0\fP\&. +.sp +Extended Changelog Courtesy of Todd Stansell (\fI\%https://github.com/tjstansell/salt\-changelogs\fP): +.INDENT 0.0 +.TP +.B \fBPR\fP \fI\%#24346\fP: (\fIrallytime\fP) Backport \fI\%#24271\fP to 2015.5 +@ \fI2015\-06\-03T18:44:31Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24271\fP: (\fIrandybias\fP) Fixed the setup instructions +.nf +refs: \fI\%#24346\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +76927c9 Merge pull request \fI\%#24346\fP from rallytime/\fI\%bp\-24271\fP +.IP \(bu 2 +04067b6 Fixed the setup instructions +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24345\fP: (\fIrallytime\fP) Backport \fI\%#24013\fP to 2015.5 +@ \fI2015\-06\-03T18:39:41Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24012\fP: (\fIjbq\fP) Enabling a service does not create the appropriate rc.d symlinks on Ubuntu +.nf +refs: \fI\%#24013\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24013\fP: (\fIjbq\fP) Fix enabling a service on Ubuntu \fI\%#24012\fP +.nf +refs: \fI\%#24345\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +4afa03d Merge pull request \fI\%#24345\fP from rallytime/\fI\%bp\-24013\fP +.IP \(bu 2 +16e0732 Fix enabling a service on Ubuntu \fI\%#24012\fP +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24365\fP: (\fIjacobhammons\fP) Fixes for PDF build errors +@ \fI2015\-06\-03T17:50:02Z\fP +.INDENT 7.0 +.IP \(bu 2 +c3392c2 Merge pull request \fI\%#24365\fP from jacobhammons/DocFixes +.IP \(bu 2 +0fc1902 Fixes for PDF build errors +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24313\fP: (\fInicholascapo\fP) Fix \fI\%#22991\fP Correctly set result when test=True +@ \fI2015\-06\-03T14:49:18Z\fP +.sp +\fBISSUE\fP \fI\%#22991\fP: (\fInicholascapo\fP) npm.installed ignores test=True +* ae681a4 Merge pull request \fI\%#24313\fP from nicholascapo/\fI\%fix\-22991\fP\-npm.installed\-test\-true +* ac9644c Fix \fI\%#22991\fP npm.installed correctly set result on test=True +.TP +.B \fBPR\fP \fI\%#24312\fP: (\fInicholascapo\fP) Fix \fI\%#18966\fP: file.serialize supports test=True +@ \fI2015\-06\-03T14:49:06Z\fP +.sp +\fBISSUE\fP \fI\%#18966\fP: (\fIbechtoldt\fP) file.serialize ignores test=True +* d57a9a2 Merge pull request \fI\%#24312\fP from nicholascapo/\fI\%fix\-18966\fP\-file.serialize\-test\-true +* e7328e7 Fix \fI\%#18966\fP file.serialize correctly set result on test=True +.TP +.B \fBPR\fP \fI\%#24302\fP: (\fIjfindlay\fP) fix pkg hold/unhold integration test +@ \fI2015\-06\-03T03:27:43Z\fP +.INDENT 7.0 +.IP \(bu 2 +6b694e3 Merge pull request \fI\%#24302\fP from jfindlay/pkg_tests +.IP \(bu 2 +c2db0b1 fix pkg hold/unhold integration test +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24349\fP: (\fIrallytime\fP) Remove references to mount_points in ec2 docs +@ \fI2015\-06\-03T01:54:09Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#14021\fP: (\fImathrawka\fP) EC2 doc mentions mount_point, but unable to use properly +.nf +refs: \fI\%#24349\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +aca8447 Merge pull request \fI\%#24349\fP from rallytime/\fI\%fix\-14021\fP +.IP \(bu 2 +a235b11 Remove references to mount_points in ec2 docs +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24328\fP: (\fIdr4Ke\fP) Fix state grains silently fails 2015.5 +@ \fI2015\-06\-02T15:18:46Z\fP +.sp +\fBISSUE\fP \fI\%#24319\fP: (\fIdr4Ke\fP) grains state shouldn\(aqt fail silently +* 88a997e Merge pull request \fI\%#24328\fP from dr4Ke/fix_state_grains_silently_fails_2015.5 +* 8a63d1e fix state grains silently fails \fI\%#24319\fP +.INDENT 7.0 +.IP \(bu 2 +ca1af20 grains state: add some tests +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24310\fP: (\fItechhat\fP) Add warning about destroying maps +@ \fI2015\-06\-02T03:01:28Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24036\fP: (\fIarthurlogilab\fP) [salt\-cloud] Protect against passing command line arguments as names for the \-\-destroy command in map files +.nf +refs: \fI\%#24310\fP +.fi +.sp +.TP +.B \fBISSUE\fP \fI\%#9772\fP: (\fIs0undt3ch\fP) Delete VM\(aqs in a map does not delete them all +.nf +refs: \fI\%#24310\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +7dcd9bb Merge pull request \fI\%#24310\fP from techhat/mapwarning +.IP \(bu 2 +ca535a6 Add warning about destroying maps +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24281\fP: (\fIsteverweber\fP) Ipmi docfix +@ \fI2015\-06\-01T17:45:36Z\fP +.INDENT 7.0 +.IP \(bu 2 +02bfb25 Merge pull request \fI\%#24281\fP from steverweber/ipmi_docfix +.IP \(bu 2 +dd36f2c yaml formating +.IP \(bu 2 +f6deef3 include api_kg kwarg in ipmi state +.IP \(bu 2 +a7d4e97 doc cleanup +.IP \(bu 2 +0ded2fd save more cleanup to doc +.IP \(bu 2 +08872f2 fix name api_key to api_kg +.IP \(bu 2 +165a387 doc fix add api_kg kwargs +.IP \(bu 2 +1ec7888 cleanup docs +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24287\fP: (\fIjfindlay\fP) fix pkg test on ubuntu 12.04 for realz +@ \fI2015\-06\-01T14:16:37Z\fP +.INDENT 7.0 +.IP \(bu 2 +73cd2cb Merge pull request \fI\%#24287\fP from jfindlay/pkg_test +.IP \(bu 2 +98944d8 fix pkg test on ubuntu 12.04 for realz +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24279\fP: (\fIrallytime\fP) Backport \fI\%#24263\fP to 2015.5 +@ \fI2015\-06\-01T04:29:34Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24263\fP: (\fIcdarwin\fP) Correct usage of import_yaml in formula documentation +.nf +refs: \fI\%#24279\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +02017a0 Merge pull request \fI\%#24279\fP from rallytime/\fI\%bp\-24263\fP +.IP \(bu 2 +beff7c7 Correct usage of import_yaml in formula documentation +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24277\fP: (\fIrallytime\fP) Put a space between after_jump commands +@ \fI2015\-06\-01T04:28:26Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24226\fP: (\fIc4urself\fP) iptables state needs to keep ordering of flags +.nf +refs: \fI\%#24277\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +2ba696d Merge pull request \fI\%#24277\fP from rallytime/fix_iptables_jump +.IP \(bu 2 +e2d1606 Move after_jump split out of loop +.IP \(bu 2 +d14f130 Remove extra loop +.IP \(bu 2 +42ed532 Put a space between after_jump commands +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24262\fP: (\fIbasepi\fP) More dictupdate after \fI\%#24142\fP +@ \fI2015\-05\-31T04:09:37Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24142\fP: (\fIbasepi\fP) Optimize dictupdate.update and add \fI\%#24097\fP functionality +.nf +refs: \fI\%#24262\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24097\fP: (\fIkiorky\fP) Optimize dictupdate +.nf +refs: \fI\%#24142\fP \fI\%#24142\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +113eba3 Merge pull request \fI\%#24262\fP from basepi/dictupdatefix +.IP \(bu 2 +0c4832c Raise a typeerror if non\-dict types +.IP \(bu 2 +be21aaa Pylint +.IP \(bu 2 +bb8a6c6 More optimization +.IP \(bu 2 +c933249 py3 compat +.IP \(bu 2 +ff6b2a7 Further optimize dictupdate.update() +.IP \(bu 2 +c73f5ba Remove unused valtype +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24269\fP: (\fIkiorky\fP) zfs: Fix spurious retcode hijacking in virtual +@ \fI2015\-05\-30T17:47:49Z\fP +.INDENT 7.0 +.IP \(bu 2 +785d5a1 Merge pull request \fI\%#24269\fP from makinacorpus/zfs +.IP \(bu 2 +0bf23ce zfs: Fix spurious retcode hijacking in virtual +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24257\fP: (\fIjfindlay\fP) fix pkg mod integration test on ubuntu 12.04 +@ \fI2015\-05\-29T23:09:00Z\fP +.INDENT 7.0 +.IP \(bu 2 +3d885c0 Merge pull request \fI\%#24257\fP from jfindlay/pkg_tests +.IP \(bu 2 +9508924 fix pkg mod integration test on ubuntu 12.04 +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24260\fP: (\fIbasepi\fP) Fix some typos from \fI\%#24080\fP +@ \fI2015\-05\-29T22:54:58Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23657\fP: (\fIarthurlogilab\fP) [salt\-cloud lxc] NameError: global name \(aq__salt__\(aq is not defined +.nf +refs: \fI\%#24080\fP \fI\%#23982\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24080\fP: (\fIkiorky\fP) Lxc consistency2 +.nf +refs: \fI\%#24260\fP \fI\%#23982\fP \fI\%#24066\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24066\fP: (\fIkiorky\fP) Merge forward 2015.5 \-> develop +.nf +refs: \fI\%#23982\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24065\fP: (\fIkiorky\fP) continue to fix \fI\%#23883\fP +.nf +refs: \fI\%#24080\fP \fI\%#24066\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#23982\fP: (\fIkiorky\fP) lxc: path support +.nf +refs: \fI\%#24080\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +08a1075 Merge pull request \fI\%#24260\fP from basepi/lxctypos24080 +.IP \(bu 2 +0fa1ad3 Fix another lxc typo +.IP \(bu 2 +669938f s/you ll/you\(aqll/ +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24080\fP: (\fIkiorky\fP) Lxc consistency2 +.nf +refs: \fI\%#24260\fP \fI\%#23982\fP \fI\%#24066\fP +.fi +.sp +.sp +@ \fI2015\-05\-29T22:51:54Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23657\fP: (\fIarthurlogilab\fP) [salt\-cloud lxc] NameError: global name \(aq__salt__\(aq is not defined +.nf +refs: \fI\%#24080\fP \fI\%#23982\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24066\fP: (\fIkiorky\fP) Merge forward 2015.5 \-> develop +.nf +refs: \fI\%#23982\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24065\fP: (\fIkiorky\fP) continue to fix \fI\%#23883\fP +.nf +refs: \fI\%#24080\fP \fI\%#24066\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#23982\fP: (\fIkiorky\fP) lxc: path support +.nf +refs: \fI\%#24080\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +75590cf Merge pull request \fI\%#24080\fP from makinacorpus/lxc_consistency2 +.IP \(bu 2 +81f8067 lxc: fix old lxc test +.IP \(bu 2 +458f506 seed: lint +.IP \(bu 2 +96b8d55 Fix seed.mkconfig yamldump +.IP \(bu 2 +76ddb68 lxc/applynet: conservative +.IP \(bu 2 +ce7096f variable collision +.IP \(bu 2 +8a8b28d lxc: lint +.IP \(bu 2 +458b18b more lxc docs +.IP \(bu 2 +ef1f952 lxc docs: typos +.IP \(bu 2 +d67a43d more lxc docs +.IP \(bu 2 +608da5e modules/lxc: merge resolution +.IP \(bu 2 +27c4689 modules/lxc: more consistent comparsion +.IP \(bu 2 +07c365a lxc: merge conflict spotted +.IP \(bu 2 +9993915 modules/lxc: rework settings for consistency +.IP \(bu 2 +ce11d83 lxc: Global doc refresh +.IP \(bu 2 +61ed2f5 clouds/lxc: profile key is conflicting +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24247\fP: (\fIrallytime\fP) Backport \fI\%#24220\fP to 2015.5 +@ \fI2015\-05\-29T21:40:01Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24210\fP: (\fIdamonnk\fP) salt\-cloud vsphere.py should allow key_filename param +.nf +refs: \fI\%#24220\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24220\fP: (\fIdjcrabhat\fP) adding key_filename param to vsphere provider +.nf +refs: \fI\%#24247\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +da14f3b Merge pull request \fI\%#24247\fP from rallytime/\fI\%bp\-24220\fP +.IP \(bu 2 +0b1041d adding key_filename param to vsphere provider +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24254\fP: (\fIrallytime\fP) Add deprecation warning to Digital Ocean v1 Driver +@ \fI2015\-05\-29T21:39:25Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#22731\fP: (\fIdmyerscough\fP) Decommission DigitalOcean APIv1 and have users use the new DigitalOcean APIv2 +.nf +refs: \fI\%#24254\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +21d6126 Merge pull request \fI\%#24254\fP from rallytime/add_deprecation_warning_digitalocean +.IP \(bu 2 +cafe37b Add note to docs about deprecation +.IP \(bu 2 +ea0f1e0 Add deprecation warning to digital ocean driver to move to digital_ocean_v2 +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24252\fP: (\fIaboe76\fP) Updated suse spec to 2015.5.1 +@ \fI2015\-05\-29T21:38:45Z\fP +.INDENT 7.0 +.IP \(bu 2 +dac055d Merge pull request \fI\%#24252\fP from aboe76/opensuse_package +.IP \(bu 2 +0ad617d Updated suse spec to 2015.5.1 +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24251\fP: (\fIgarethgreenaway\fP) Returners broken in 2015.5 +@ \fI2015\-05\-29T21:37:52Z\fP +.INDENT 7.0 +.IP \(bu 2 +49e7fe8 Merge pull request \fI\%#24251\fP from garethgreenaway/2015_5_returner_brokenness +.IP \(bu 2 +5df6b52 The code calling cfg as a function vs treating it as a dictionary and using get is currently backwards causing returners to fail when used from the CLI and in scheduled jobs. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24255\fP: (\fIrallytime\fP) Clarify digital ocean documentation and mention v1 driver deprecation +@ \fI2015\-05\-29T21:37:07Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#21498\fP: (\fIrallytime\fP) Clarify Digital Ocean Documentation +.nf +refs: \fI\%#24255\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +bfb9461 Merge pull request \fI\%#24255\fP from rallytime/clarify_digital_ocean_driver_docs +.IP \(bu 2 +8d51f75 Clarify digital ocean documentation and mention v1 driver deprecation +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24232\fP: (\fIrallytime\fP) Backport \fI\%#23308\fP to 2015.5 +@ \fI2015\-05\-29T21:36:46Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#23308\fP: (\fIthusoy\fP) Don\(aqt merge: Add missing jump arguments to iptables module +.nf +refs: \fI\%#24232\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +41f5756 Merge pull request \fI\%#24232\fP from rallytime/\fI\%bp\-23308\fP +.IP \(bu 2 +2733f66 Import string +.IP \(bu 2 +9097cca Add missing jump arguments to iptables module +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24245\fP: (\fISacro\fP) Unset PYTHONHOME when starting the service +@ \fI2015\-05\-29T20:00:31Z\fP +.INDENT 7.0 +.IP \(bu 2 +a95982c Merge pull request \fI\%#24245\fP from Sacro/patch\-2 +.IP \(bu 2 +6632d06 Unset PYTHONHOME when starting the service +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24121\fP: (\fIhvnsweeting\fP) deprecate setting user permission in rabbitmq_vhost.present +@ \fI2015\-05\-29T15:55:40Z\fP +.INDENT 7.0 +.IP \(bu 2 +1504c76 Merge pull request \fI\%#24121\fP from hvnsweeting/rabbitmq\-host\-deprecate\-set\-permission +.IP \(bu 2 +2223158 deprecate setting user permission in rabbitmq_host.present +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24179\fP: (\fImerll\fP) Changing user and group only possible for existing ids. +@ \fI2015\-05\-29T15:52:43Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24169\fP: (\fImerll\fP) Changing user and group only possible for existing ids. +.nf +refs: \fI\%#24179\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +ba02f65 Merge pull request \fI\%#24179\fP from Precis/fix\-file\-uid\-gid\-2015.0 +.IP \(bu 2 +ee4c9d5 Use ids if user or group is not present. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24229\fP: (\fImsteed\fP) Fix auth failure on syndic with external_auth +@ \fI2015\-05\-29T15:04:06Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24147\fP: (\fIpaclat\fP) Syndication issues when using authentication on master of masters. +.nf +refs: \fI\%#24229\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +9bfb066 Merge pull request \fI\%#24229\fP from msteed/issue\-24147 +.IP \(bu 2 +482d1cf Fix auth failure on syndic with external_auth +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24234\fP: (\fIjayeshka\fP) adding states/quota unit test case. +@ \fI2015\-05\-29T14:14:27Z\fP +.INDENT 7.0 +.IP \(bu 2 +19fa43c Merge pull request \fI\%#24234\fP from jayeshka/quota\-states\-unit\-test +.IP \(bu 2 +c233565 adding states/quota unit test case. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24217\fP: (\fIjfindlay\fP) disable intermittently failing tests +@ \fI2015\-05\-29T03:08:39Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#40\fP: (\fIthatch45\fP) Clean up timeouts +.nf +refs: \fI\%#22857\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#23623\fP: (\fIjfindlay\fP) Fix /jobs endpoint\(aqs return +.nf +refs: \fI\%#24217\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#22857\fP: (\fIjacksontj\fP) Fix /jobs endpoint\(aqs return +.nf +refs: \fI\%#23623\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +e15142c Merge pull request \fI\%#24217\fP from jfindlay/disable_bad_tests +.IP \(bu 2 +6b62804 disable intermittently failing tests +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24199\fP: (\fIryan\-lane\fP) Various fixes for boto_route53 and boto_elb +@ \fI2015\-05\-29T03:02:41Z\fP +.INDENT 7.0 +.IP \(bu 2 +ce8e43b Merge pull request \fI\%#24199\fP from lyft/route53\-fix\-elb +.IP \(bu 2 +d8dc9a7 Better unit tests for boto_elb state +.IP \(bu 2 +62f214b Remove cnames_present test +.IP \(bu 2 +7b9ae82 Lint fix +.IP \(bu 2 +b74b0d1 Various fixes for boto_route53 and boto_elb +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24142\fP: (\fIbasepi\fP) Optimize dictupdate.update and add \fI\%#24097\fP functionality +.nf +refs: \fI\%#24262\fP +.fi +.sp +.sp +@ \fI2015\-05\-29T03:00:56Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24097\fP: (\fIkiorky\fP) Optimize dictupdate +.nf +refs: \fI\%#24142\fP \fI\%#24142\fP +.fi +.sp +.UNINDENT +.sp +\fBPR\fP \fI\%#21968\fP: (\fIryanwohara\fP) Verifying the key has a value before using it. +* a43465d Merge pull request \fI\%#24142\fP from basepi/dictupdate24097 +* 5c6e210 Deepcopy on merge_recurse +.INDENT 7.0 +.IP \(bu 2 +a13c84a Fix None check from \fI\%#21968\fP +.IP \(bu 2 +9ef2c64 Add docstring +.IP \(bu 2 +8579429 Add in recursive_update from \fI\%#24097\fP +.IP \(bu 2 +8599143 if key not in dest, don\(aqt recurse +.IP \(bu 2 +d8a84b3 Rename klass to valtype +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24208\fP: (\fIjayeshka\fP) adding states/ports unit test case. +@ \fI2015\-05\-28T23:06:33Z\fP +.INDENT 7.0 +.IP \(bu 2 +526698b Merge pull request \fI\%#24208\fP from jayeshka/ports\-states\-unit\-test +.IP \(bu 2 +657b709 adding states/ports unit test case. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24219\fP: (\fIjfindlay\fP) find zfs without modinfo +@ \fI2015\-05\-28T21:07:26Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#20635\fP: (\fIdennisjac\fP) 2015.2.0rc1: zfs errors in log after update +.nf +refs: \fI\%#24219\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +d00945f Merge pull request \fI\%#24219\fP from jfindlay/zfs_check +.IP \(bu 2 +15d4019 use the salt loader in the zfs mod +.IP \(bu 2 +5599b67 try to search for zfs if modinfo is unavailable +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24190\fP: (\fImsteed\fP) Fix issue 23815 +@ \fI2015\-05\-28T20:10:34Z\fP +.sp +\fBISSUE\fP \fI\%#23815\fP: (\fISnergster\fP) [beacons] inotify errors on subdir creation +* 3dc4b85 Merge pull request \fI\%#24190\fP from msteed/issue\-23815 +* 086a1a9 lint +.INDENT 7.0 +.IP \(bu 2 +65de62f fix \fI\%#23815\fP +.IP \(bu 2 +d04e916 spelling +.IP \(bu 2 +db9f682 add inotify beacon unit tests +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24211\fP: (\fIrallytime\fP) Backport \fI\%#24205\fP to 2015.5 +@ \fI2015\-05\-28T18:28:15Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24205\fP: (\fIhazelesque\fP) Docstring fix in salt.modules.yumpkg.hold +.nf +refs: \fI\%#24211\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +436634b Merge pull request \fI\%#24211\fP from rallytime/\fI\%bp\-24205\fP +.IP \(bu 2 +23284b5 Docstring fix in salt.modules.yumpkg.hold +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24212\fP: (\fIterminalmage\fP) Clarify error in rendering template for top file +@ \fI2015\-05\-28T18:26:20Z\fP +.INDENT 7.0 +.IP \(bu 2 +cc58624 Merge pull request \fI\%#24212\fP from terminalmage/clarify\-error\-msg +.IP \(bu 2 +ca807fb Clarify error in rendering template for top file +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24213\fP: (\fIThe\-Loeki\fP) ShouldFix _\- troubles in debian_ip +@ \fI2015\-05\-28T18:24:39Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23904\fP: (\fImbrgm\fP) Network config bonding section cannot be parsed when attribute names use dashes +.nf +refs: \fI\%#23917\fP +.fi +.sp +.TP +.B \fBISSUE\fP \fI\%#23900\fP: (\fIhashi825\fP) salt ubuntu network building issue 2015.5.0 +.nf +refs: \fI\%#23922\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#23922\fP: (\fIgarethgreenaway\fP) Fixes to debian_ip.py +.nf +refs: \fI\%#24213\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#23917\fP: (\fIcorywright\fP) Split debian bonding options on dash instead of underscore +.nf +refs: \fI\%#24213\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +9825160 Merge pull request \fI\%#24213\fP from The\-Loeki/patch\-3 +.IP \(bu 2 +a68d515 ShouldFix _\- troubles in debian_ip +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24214\fP: (\fIbasepi\fP) 2015.5.1release +@ \fI2015\-05\-28T16:23:57Z\fP +.INDENT 7.0 +.IP \(bu 2 +071751d Merge pull request \fI\%#24214\fP from basepi/2015.5.1release +.IP \(bu 2 +e5ba31b 2015.5.1 release date +.IP \(bu 2 +768494c Update latest release in docs +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24202\fP: (\fIrallytime\fP) Backport \fI\%#24186\fP to 2015.5 +@ \fI2015\-05\-28T05:16:48Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24186\fP: (\fIthcipriani\fP) Update salt vagrant provisioner info +.nf +refs: \fI\%#24202\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +c2f1fdb Merge pull request \fI\%#24202\fP from rallytime/\fI\%bp\-24186\fP +.IP \(bu 2 +db793dd Update salt vagrant provisioner info +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24192\fP: (\fIrallytime\fP) Backport \fI\%#20474\fP to 2015.5 +@ \fI2015\-05\-28T05:16:18Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#20474\fP: (\fIdjcrabhat\fP) add sudo, sudo_password params to vsphere deploy to allow for non\-root deploys +.nf +refs: \fI\%#24192\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +8a085a2 Merge pull request \fI\%#24192\fP from rallytime/\fI\%bp\-20474\fP +.IP \(bu 2 +fd3c783 add sudo, sudo_password params to deploy to allow for non\-root deploys +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24184\fP: (\fIrallytime\fP) Backport \fI\%#24129\fP to 2015.5 +@ \fI2015\-05\-28T05:15:08Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24129\fP: (\fIpengyao\fP) Wheel client doc +.nf +refs: \fI\%#24184\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +7cc535b Merge pull request \fI\%#24184\fP from rallytime/\fI\%bp\-24129\fP +.IP \(bu 2 +722a662 fixed a typo +.IP \(bu 2 +565eb46 Add cmd doc for WheelClient +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24183\fP: (\fIrallytime\fP) Backport \fI\%#19320\fP to 2015.5 +@ \fI2015\-05\-28T05:14:36Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#19320\fP: (\fIclan\fP) add \(aqstate_output_profile\(aq option for profile output +.nf +refs: \fI\%#24183\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +eb0af70 Merge pull request \fI\%#24183\fP from rallytime/\fI\%bp\-19320\fP +.IP \(bu 2 +55db1bf sate_output_profile default to True +.IP \(bu 2 +9919227 fix type: statei \-> state +.IP \(bu 2 +0549ca6 add \(aqstate_output_profile\(aq option for profile output +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24201\fP: (\fIwhiteinge\fP) Add list of client libraries for the rest_cherrypy module to the top\-level documentation +@ \fI2015\-05\-28T02:12:09Z\fP +.INDENT 7.0 +.IP \(bu 2 +1b5bf23 Merge pull request \fI\%#24201\fP from whiteinge/rest_cherrypy\-client\-libs +.IP \(bu 2 +5f71802 Add list of client libraries for the rest_cherrypy module +.IP \(bu 2 +28fc77f Fix rest_cherrypy config example indentation +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24195\fP: (\fIrallytime\fP) Merge \fI\%#24185\fP with a couple of fixes +@ \fI2015\-05\-27T22:18:37Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24185\fP: (\fIjacobhammons\fP) Fixes for doc build errors +.nf +refs: \fI\%#24195\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +3307ec2 Merge pull request \fI\%#24195\fP from rallytime/merge\-24185 +.IP \(bu 2 +d8daa9d Merge \fI\%#24185\fP with a couple of fixes +.IP \(bu 2 +634d56b Fixed pylon error +.IP \(bu 2 +0689815 Fixes for doc build errors +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24166\fP: (\fIjayeshka\fP) adding states/pkgng unit test case. +@ \fI2015\-05\-27T20:27:49Z\fP +.INDENT 7.0 +.IP \(bu 2 +7e400bc Merge pull request \fI\%#24166\fP from jayeshka/pkgng\-states\-unit\-test +.IP \(bu 2 +2234bb0 adding states/pkgng unit test case. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24189\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-27T20:26:31Z\fP +.sp +\fBPR\fP \fI\%#24178\fP: (\fIrallytime\fP) Backport \fI\%#24118\fP to 2014.7, too. +\fBPR\fP \fI\%#24159\fP: (\fIrallytime\fP) Fill out modules/keystone.py CLI Examples +\fBPR\fP \fI\%#24158\fP: (\fIrallytime\fP) Fix test_valid_docs test for tls module +\fBPR\fP \fI\%#24118\fP: (\fItrevor\-h\fP) removed deprecated pymongo usage +.INDENT 7.0 +.INDENT 3.5 +.nf +refs: \fI\%#24139\fP \fI\%#24178\fP +.fi +.sp +.UNINDENT +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +9fcda79 Merge pull request \fI\%#24189\fP from basepi/merge\-forward\-2015.5 +.IP \(bu 2 +8839e9c Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.IP \(bu 2 +9d7331c Merge pull request \fI\%#24178\fP from rallytime/\fI\%bp\-24118\fP +.INDENT 2.0 +.IP \(bu 2 +e2217a0 removed deprecated pymongo usage as no longer functional with pymongo > 3.x +.UNINDENT +.IP \(bu 2 +4e8c503 Merge pull request \fI\%#24159\fP from rallytime/keystone_doc_examples +.INDENT 2.0 +.IP \(bu 2 +dadac8d Fill out modules/keystone.py CLI Examples +.UNINDENT +.IP \(bu 2 +fc10ee8 Merge pull request \fI\%#24158\fP from rallytime/fix_doc_error +.INDENT 2.0 +.IP \(bu 2 +49a517e Fix test_valid_docs test for tls module +.UNINDENT +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24181\fP: (\fIjtand\fP) Fixed error where file was evaluated as a symlink in test_absent +@ \fI2015\-05\-27T18:26:28Z\fP +.INDENT 7.0 +.IP \(bu 2 +2303dec Merge pull request \fI\%#24181\fP from jtand/file_test +.IP \(bu 2 +5f0e601 Fixed error where file was evaluated as a symlink in test_absent +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24180\fP: (\fIterminalmage\fP) Skip libvirt tests if not running as root +@ \fI2015\-05\-27T18:18:47Z\fP +.INDENT 7.0 +.IP \(bu 2 +a162768 Merge pull request \fI\%#24180\fP from terminalmage/fix\-libvirt\-test +.IP \(bu 2 +72e7416 Skip libvirt tests if not running as root +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24165\fP: (\fIjayeshka\fP) adding states/portage_config unit test case. +@ \fI2015\-05\-27T17:15:08Z\fP +.INDENT 7.0 +.IP \(bu 2 +1fbc5b2 Merge pull request \fI\%#24165\fP from jayeshka/portage_config\-states\-unit\-test +.IP \(bu 2 +8cf1505 adding states/portage_config unit test case. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24164\fP: (\fIjayeshka\fP) adding states/pecl unit test case. +@ \fI2015\-05\-27T17:14:26Z\fP +.INDENT 7.0 +.IP \(bu 2 +4747856 Merge pull request \fI\%#24164\fP from jayeshka/pecl\-states\-unit\-test +.IP \(bu 2 +563a5b3 adding states/pecl unit test case. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24160\fP: (\fIThe\-Loeki\fP) small enhancement to data module; pop() +@ \fI2015\-05\-27T17:03:10Z\fP +.INDENT 7.0 +.IP \(bu 2 +cdaaa19 Merge pull request \fI\%#24160\fP from The\-Loeki/patch\-1 +.IP \(bu 2 +2175ff3 doc & merge fix +.IP \(bu 2 +eba382c small enhancement to data module; pop() +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24153\fP: (\fItechhat\fP) Batch mode sometimes improperly builds lists of minions to process +@ \fI2015\-05\-27T16:21:53Z\fP +.INDENT 7.0 +.IP \(bu 2 +4a8dbc7 Merge pull request \fI\%#24153\fP from techhat/batchlist +.IP \(bu 2 +467ba64 Make sure that minion IDs are strings +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24167\fP: (\fIjayeshka\fP) adding states/pagerduty unit test case. +@ \fI2015\-05\-27T16:14:01Z\fP +.INDENT 7.0 +.IP \(bu 2 +ed8ccf5 Merge pull request \fI\%#24167\fP from jayeshka/pagerduty\-states\-unit\-test +.IP \(bu 2 +1af8c83 adding states/pagerduty unit test case. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24156\fP: (\fIbasepi\fP) [2015.5] Merge forward from 2014.7 to 2015.5 +@ \fI2015\-05\-27T15:05:01Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23464\fP: (\fItibold\fP) cmd_iter_no_block() blocks +.nf +refs: \fI\%#24093\fP +.fi +.sp +.UNINDENT +.sp +\fBPR\fP \fI\%#24125\fP: (\fIhvnsweeting\fP) Fix rabbitmq test mode +\fBPR\fP \fI\%#24093\fP: (\fImsteed\fP) Make LocalClient.cmd_iter_no_block() not block +\fBPR\fP \fI\%#24008\fP: (\fIdavidjb\fP) Correct reST formatting for states.cmd documentation +\fBPR\fP \fI\%#23933\fP: (\fIjacobhammons\fP) sphinx saltstack2 doc theme +* b9507d1 Merge pull request \fI\%#24156\fP from basepi/merge\-forward\-2015.5 +* e52b5ab Remove stray >>>>> +.INDENT 7.0 +.IP \(bu 2 +7dfbd92 Merge remote\-tracking branch \(aqupstream/2014.7\(aq into merge\-forward\-2015.5 +.INDENT 2.0 +.IP \(bu 2 +c0d32e0 Merge pull request \fI\%#24125\fP from hvnsweeting/fix\-rabbitmq\-test\-mode +.INDENT 2.0 +.IP \(bu 2 +71862c6 enhance log +.IP \(bu 2 +28e2594 change according to new output of rabbitmq module functions +.IP \(bu 2 +cd0212e processes and returns better output for rabbitmq module +.UNINDENT +.IP \(bu 2 +39a8f30 Merge pull request \fI\%#24093\fP from msteed/issue\-23464 +.INDENT 2.0 +.IP \(bu 2 +fd35903 Fix failing test +.IP \(bu 2 +41b344c Make LocalClient.cmd_iter_no_block() not block +.UNINDENT +.IP \(bu 2 +5bffd30 Merge pull request \fI\%#24008\fP from davidjb/2014.7 +.INDENT 2.0 +.IP \(bu 2 +8b8d029 Correct reST formatting for documentation +.UNINDENT +.IP \(bu 2 +1aa0420 Merge pull request \fI\%#23933\fP from jacobhammons/2014.7 +.IP \(bu 2 +a3613e6 removed numbering from doc TOC +.IP \(bu 2 +78b737c removed 2015.* release from release notes, updated index page to remove PDF/epub links +.IP \(bu 2 +e867f7d Changed build settings to use saltstack2 theme and update release versions. +.IP \(bu 2 +81ed9c9 sphinx saltstack2 doc theme +.UNINDENT +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24145\fP: (\fIjfindlay\fP) attempt to decode win update package +@ \fI2015\-05\-26T23:20:20Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24102\fP: (\fIbormotov\fP) win_update encondig problems +.nf +refs: \fI\%#24145\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +05745fa Merge pull request \fI\%#24145\fP from jfindlay/win_update_encoding +.IP \(bu 2 +cc5e17e attempt to decode win update package +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24123\fP: (\fIkiorky\fP) fix service enable/disable change +@ \fI2015\-05\-26T21:24:19Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24122\fP: (\fIkiorky\fP) service.dead is no more stateful: services does not handle correctly enable/disable change state +.nf +refs: \fI\%#24123\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +7024789 Merge pull request \fI\%#24123\fP from makinacorpus/ss +.IP \(bu 2 +2e2e1d2 fix service enable/disable change +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24146\fP: (\fIrallytime\fP) Fixes the boto_vpc_test failure on CentOS 5 tests +@ \fI2015\-05\-26T20:15:19Z\fP +.INDENT 7.0 +.IP \(bu 2 +51c3cec Merge pull request \fI\%#24146\fP from rallytime/fix_centos_boto_failure +.IP \(bu 2 +ac0f97d Fixes the boto_vpc_test failure on CentOS 5 tests +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24144\fP: (\fItwangboy\fP) Compare Keys ignores all newlines and carriage returns +@ \fI2015\-05\-26T19:25:48Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24052\fP: (\fItwangboy\fP) v2015.5.1 Changes the way it interprets the minion_master.pub file +.nf +refs: \fI\%#24089\fP \fI\%#24144\fP +.fi +.sp +.TP +.B \fBISSUE\fP \fI\%#23566\fP: (\fIrks2286\fP) Salt\-cp corrupting the file after transfer to minion +.nf +refs: \fI\%#24144\fP \fI\%#23740\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#23740\fP: (\fIjfindlay\fP) Binary write +.nf +refs: \fI\%#24144\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +1c91a21 Merge pull request \fI\%#24144\fP from twangboy/fix_24052 +.IP \(bu 2 +c197b41 Compare Keys removing all newlines and carriage returns +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24139\fP: (\fIrallytime\fP) Backport \fI\%#24118\fP to 2015.5 +@ \fI2015\-05\-26T18:24:27Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24118\fP: (\fItrevor\-h\fP) removed deprecated pymongo usage +.nf +refs: \fI\%#24139\fP \fI\%#24178\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +0841667 Merge pull request \fI\%#24139\fP from rallytime/\fI\%bp\-24118\fP +.IP \(bu 2 +4bb519b removed deprecated pymongo usage as no longer functional with pymongo > 3.x +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24138\fP: (\fIrallytime\fP) Backport \fI\%#24116\fP to 2015.5 +@ \fI2015\-05\-26T18:23:51Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24116\fP: (\fIawdrius\fP) Fixed typo in chown username (ending dot) that fails the command. +.nf +refs: \fI\%#24138\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +742eca2 Merge pull request \fI\%#24138\fP from rallytime/\fI\%bp\-24116\fP +.IP \(bu 2 +7f08641 Fixed typo in chown username (ending dot) that fails the command. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24137\fP: (\fIrallytime\fP) Backport \fI\%#24105\fP to 2015.5 +@ \fI2015\-05\-26T18:23:40Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24105\fP: (\fIcedwards\fP) Updated some beacon\-specific documentation formatting +.nf +refs: \fI\%#24137\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +e01536d Merge pull request \fI\%#24137\fP from rallytime/\fI\%bp\-24105\fP +.IP \(bu 2 +f0778a0 Updated some beacon\-specific documentation formatting +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24136\fP: (\fIrallytime\fP) Backport \fI\%#24104\fP to 2015.5 +@ \fI2015\-05\-26T15:58:47Z\fP +.sp +\fBISSUE\fP \fI\%#23364\fP: (\fIpruiz\fP) Unable to destroy host using proxmox cloud: There was an error destroying machines: 501 Server Error: Method \(aqDELETE /nodes/pmx1/openvz/openvz/100\(aq not implemented +\fBPR\fP \fI\%#24104\fP: (\fIpruiz\fP) Only try to stop a VM if it\(aqs not already stopped. (fixes \fI\%#23364\fP) +.INDENT 7.0 +.INDENT 3.5 +.nf +refs: \fI\%#24136\fP +.fi +.sp +.UNINDENT +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +89cdf97 Merge pull request \fI\%#24136\fP from rallytime/\fI\%bp\-24104\fP +.IP \(bu 2 +c538884 Only try to stop a VM if it\(aqs not already stopped. (fixes \fI\%#23364\fP) +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24135\fP: (\fIrallytime\fP) Backport \fI\%#24083\fP to 2015.5 +@ \fI2015\-05\-26T15:58:27Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24083\fP: (\fIswdream\fP) fix code block syntax +.nf +refs: \fI\%#24135\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +67c4373 Merge pull request \fI\%#24135\fP from rallytime/\fI\%bp\-24083\fP +.IP \(bu 2 +e1d06f9 fix code block syntax +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24131\fP: (\fIjayeshka\fP) adding states/mysql_user unit test case +@ \fI2015\-05\-26T15:58:10Z\fP +.INDENT 7.0 +.IP \(bu 2 +a83371e Merge pull request \fI\%#24131\fP from jayeshka/mysql_user\-states\-unit\-test +.IP \(bu 2 +ed1ef69 adding states/mysql_user unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24130\fP: (\fIjayeshka\fP) adding states/ntp unit test case +@ \fI2015\-05\-26T15:57:29Z\fP +.INDENT 7.0 +.IP \(bu 2 +1dc1d2a Merge pull request \fI\%#24130\fP from jayeshka/ntp\-states\-unit\-test +.IP \(bu 2 +ede4a9f adding states/ntp unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24128\fP: (\fIjayeshka\fP) adding states/openstack_config unit test case +@ \fI2015\-05\-26T15:56:08Z\fP +.INDENT 7.0 +.IP \(bu 2 +3943417 Merge pull request \fI\%#24128\fP from jayeshka/openstack_config\-states\-unit\-test +.IP \(bu 2 +ca09e0f adding states/openstack_config unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24127\fP: (\fIjayeshka\fP) adding states/npm unit test case +@ \fI2015\-05\-26T15:55:18Z\fP +.INDENT 7.0 +.IP \(bu 2 +23f25c4 Merge pull request \fI\%#24127\fP from jayeshka/npm\-states\-unit\-test +.IP \(bu 2 +c3ecabb adding states/npm unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24077\fP: (\fIanlutro\fP) Change how state_verbose output is filtered +@ \fI2015\-05\-26T15:41:11Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24009\fP: (\fIhvnsweeting\fP) state_verbose False summary is wrong +.nf +refs: \fI\%#24077\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +07488a4 Merge pull request \fI\%#24077\fP from alprs/fix\-outputter_highstate_nonverbose_count +.IP \(bu 2 +7790408 Change how state_verbose output is filtered +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24119\fP: (\fIjfindlay\fP) Update contrib docs +@ \fI2015\-05\-26T15:37:01Z\fP +.INDENT 7.0 +.IP \(bu 2 +224820f Merge pull request \fI\%#24119\fP from jfindlay/update_contrib_docs +.IP \(bu 2 +fa2d411 update example release branch in contrib docs +.IP \(bu 2 +a0b76b5 clarify git rebase instructions +.IP \(bu 2 +3517e00 fix contribution docs link typos +.IP \(bu 2 +651629c backport dev contrib doc updates to 2015.5 +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23928\fP: (\fIjoejulian\fP) Add the ability to replace existing certificates +@ \fI2015\-05\-25T19:47:26Z\fP +.INDENT 7.0 +.IP \(bu 2 +5488c4a Merge pull request \fI\%#23928\fP from joejulian/2015.5_tls_module_replace_existing +.IP \(bu 2 +4a4cbdd Add the ability to replace existing certificates +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24078\fP: (\fIjfindlay\fP) if a charmap is not supplied, set it to the codeset +@ \fI2015\-05\-25T19:39:19Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23221\fP: (\fIReiner030\fP) Debian Jessie: locale.present not working again +.nf +refs: \fI\%#24078\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +dd90ef0 Merge pull request \fI\%#24078\fP from jfindlay/locale_charmap +.IP \(bu 2 +5eb97f0 if a charmap is not supplied, set it to the codeset +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24088\fP: (\fIjfindlay\fP) pkg module integration tests +@ \fI2015\-05\-25T19:39:02Z\fP +.INDENT 7.0 +.IP \(bu 2 +9cec5d3 Merge pull request \fI\%#24088\fP from jfindlay/pkg_tests +.IP \(bu 2 +f1bd5ec adding pkg module integration tests +.IP \(bu 2 +739b2ef rework yumpkg refresh_db so args are not mandatory +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24089\fP: (\fIjfindlay\fP) allow override of binary file mode on windows +@ \fI2015\-05\-25T19:38:44Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24052\fP: (\fItwangboy\fP) v2015.5.1 Changes the way it interprets the minion_master.pub file +.nf +refs: \fI\%#24089\fP \fI\%#24144\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +517552c Merge pull request \fI\%#24089\fP from jfindlay/binary_write +.IP \(bu 2 +b2259a6 allow override of binary file mode on windows +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24092\fP: (\fIjfindlay\fP) collect scattered contents edits, ensure it\(aqs a str +@ \fI2015\-05\-25T19:38:10Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23973\fP: (\fImschiff\fP) state file.managed: setting contents_pillar to a pillar which is a list throws exception instead giving descriptive error message +.nf +refs: \fI\%#24092\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +121ab9f Merge pull request \fI\%#24092\fP from jfindlay/file_state +.IP \(bu 2 +cfa0f13 collect scattered contents edits, ensure it\(aqs a str +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24112\fP: (\fIThe\-Loeki\fP) thin_gen breaks when thinver doesn\(aqt exist +@ \fI2015\-05\-25T19:37:47Z\fP +.INDENT 7.0 +.IP \(bu 2 +84e65de Merge pull request \fI\%#24112\fP from The\-Loeki/patch\-1 +.IP \(bu 2 +34646ea thin_gen breaks when thinver doesn\(aqt exist +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24108\fP: (\fIjayeshka\fP) adding states/mysql_query unit test case +@ \fI2015\-05\-25T12:30:48Z\fP +.INDENT 7.0 +.IP \(bu 2 +ec509ed Merge pull request \fI\%#24108\fP from jayeshka/mysql_query\-states\-unit\-test +.IP \(bu 2 +ec50450 adding states/mysql_query unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24110\fP: (\fIjayeshka\fP) adding varnish unit test case +@ \fI2015\-05\-25T12:30:21Z\fP +.INDENT 7.0 +.IP \(bu 2 +f2e5d6c Merge pull request \fI\%#24110\fP from jayeshka/varnish\-unit\-test +.IP \(bu 2 +e119889 adding varnish unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24109\fP: (\fIjayeshka\fP) adding states/mysql_grants unit test case +@ \fI2015\-05\-25T12:29:53Z\fP +.INDENT 7.0 +.IP \(bu 2 +4fca2b4 Merge pull request \fI\%#24109\fP from jayeshka/mysql_grants\-states\-unit\-test +.IP \(bu 2 +11a93cb adding states/mysql_grants unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24028\fP: (\fInleib\fP) send a disable message to disable puppet +@ \fI2015\-05\-25T04:02:11Z\fP +.INDENT 7.0 +.IP \(bu 2 +6b43c9a Merge pull request \fI\%#24028\fP from nleib/2015.5 +.IP \(bu 2 +15f24b4 update format of string in disabled msg +.IP \(bu 2 +7690e5b remove trailing whitespaces +.IP \(bu 2 +56a9720 Update puppet.py +.IP \(bu 2 +9686391 Update puppet.py +.IP \(bu 2 +33f3d68 send a disable message to disable puppet +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24100\fP: (\fIjfindlay\fP) adding states/file unit test case +@ \fI2015\-05\-24T05:17:54Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#23963\fP: (\fIjayeshka\fP) adding states/file unit test case +.nf +refs: \fI\%#24100\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +52c9aca Merge pull request \fI\%#24100\fP from jfindlay/merge_23963 +.IP \(bu 2 +7d59deb adding states/file unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24098\fP: (\fIgalet\fP) Systemd not recognized properly on Oracle Linux 7 +@ \fI2015\-05\-24T04:07:31Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#21446\fP: (\fIdpheasant\fP) check for systemd on Oracle Linux +.nf +refs: \fI\%#24098\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +0eb9f15 Merge pull request \fI\%#24098\fP from galet/2015.5 +.IP \(bu 2 +4d6ab21 Systemd not recognized properly on Oracle Linux 7 +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24090\fP: (\fIjfindlay\fP) adding states/mount unit test case +@ \fI2015\-05\-22T23:02:57Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24062\fP: (\fIjayeshka\fP) adding states/mount unit test case +.nf +refs: \fI\%#24090\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +8e04db7 Merge pull request \fI\%#24090\fP from jfindlay/merge_24062 +.IP \(bu 2 +a81a922 adding states/mount unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24086\fP: (\fIrallytime\fP) Backport \fI\%#22806\fP to 2015.5 +@ \fI2015\-05\-22T21:18:20Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#22574\fP: (\fIunicolet\fP) error when which is not available +.nf +refs: \fI\%#22806\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#22806\fP: (\fIjfindlay\fP) use cmd.run_all instead of cmd.run_stdout +.nf +refs: \fI\%#24086\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +c0079f5 Merge pull request \fI\%#24086\fP from rallytime/\fI\%bp\-22806\fP +.IP \(bu 2 +f728f55 use cmd.run_all instead of cmd.run_stdout +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24024\fP: (\fIjayeshka\fP) adding states/mongodb_user unit test case +@ \fI2015\-05\-22T20:53:19Z\fP +.INDENT 7.0 +.IP \(bu 2 +09de253 Merge pull request \fI\%#24024\fP from jayeshka/mongodb_user\-states\-unit\-test +.IP \(bu 2 +f31dc92 resolved errors +.IP \(bu 2 +d038b1f adding states/mongodb_user unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24065\fP: (\fIkiorky\fP) continue to fix \fI\%#23883\fP +.nf +refs: \fI\%#24080\fP \fI\%#24066\fP +.fi +.sp +.sp +@ \fI2015\-05\-22T18:59:21Z\fP +.sp +\fBISSUE\fP \fI\%#23883\fP: (\fIkaithar\fP) max_event_size seems broken +* bfd812c Merge pull request \fI\%#24065\fP from makinacorpus/real23883 +* 028282e continue to fix \fI\%#23883\fP +.TP +.B \fBPR\fP \fI\%#24029\fP: (\fIkiorky\fP) Fix providers handling +@ \fI2015\-05\-22T16:56:06Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#24017\fP: (\fIarthurlogilab\fP) [salt\-cloud openstack] TypeError: unhashable type: \(aqdict\(aq on map creation +.nf +refs: \fI\%#24029\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +429adfe Merge pull request \fI\%#24029\fP from makinacorpus/fixproviders +.IP \(bu 2 +412b39b Fix providers handling +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23936\fP: (\fIjfindlay\fP) remove unreachable returns in file state +@ \fI2015\-05\-22T16:26:49Z\fP +.INDENT 7.0 +.IP \(bu 2 +a42cccc Merge pull request \fI\%#23936\fP from jfindlay/file_state +.IP \(bu 2 +ac29c0c also validate file.recurse source parameter +.IP \(bu 2 +57f7388 remove unreachable returns in file state +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24063\fP: (\fIjayeshka\fP) removed tuple index error +@ \fI2015\-05\-22T14:58:20Z\fP +.INDENT 7.0 +.IP \(bu 2 +8b69b41 Merge pull request \fI\%#24063\fP from jayeshka/mount\-states\-module +.IP \(bu 2 +b9745d5 removed tuple index error +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24057\fP: (\fIrallytime\fP) Backport \fI\%#22572\fP to 2015.5 +@ \fI2015\-05\-22T05:36:25Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#22572\fP: (\fIThe\-Loeki\fP) Small docfix for GitPillar +.nf +refs: \fI\%#24057\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +02ac4aa Merge pull request \fI\%#24057\fP from rallytime/\fI\%bp\-22572\fP +.IP \(bu 2 +49aad84 Small docfix for GitPillar +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24040\fP: (\fIrallytime\fP) Backport \fI\%#24027\fP to 2015.5 +@ \fI2015\-05\-21T23:43:54Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23088\fP: (\fIwfhg\fP) Segfault when adding a Zypper repo on SLES 11.3 +.nf +refs: \fI\%#24027\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#24027\fP: (\fIwfhg\fP) Add baseurl to salt.modules.zypper.mod_repo +.nf +refs: \fI\%#24040\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +82de059 Merge pull request \fI\%#24040\fP from rallytime/\fI\%bp\-24027\fP +.IP \(bu 2 +37d25d8 Added baseurl as alias for url and mirrorlist in salt.modules.zypper.mod_repo. +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24039\fP: (\fIrallytime\fP) Backport \fI\%#24015\fP to 2015.5 +@ \fI2015\-05\-21T23:43:25Z\fP +.INDENT 7.0 +.TP +.B \fBPR\fP \fI\%#24015\fP: (\fIYanChii\fP) minor improvement of solarisips docs & fix typos +.nf +refs: \fI\%#24039\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +d909781 Merge pull request \fI\%#24039\fP from rallytime/\fI\%bp\-24015\fP +.IP \(bu 2 +6bfaa94 minor improovement of solarisips docs & fix typos +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24038\fP: (\fIrallytime\fP) Backport \fI\%#19599\fP to 2015.5 +@ \fI2015\-05\-21T23:43:10Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#19598\fP: (\fIfayetted\fP) ssh_auth.present test=true incorectly reports changes will be made +.nf +refs: \fI\%#19599\fP +.fi +.sp +.TP +.B \fBPR\fP \fI\%#19599\fP: (\fIfayetted\fP) Fix ssh_auth test mode, compare lines not just key +.nf +refs: \fI\%#24038\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +4a0f254 Merge pull request \fI\%#24038\fP from rallytime/\fI\%bp\-19599\fP +.IP \(bu 2 +ea00d3e Fix ssh_auth test mode, compare lines not just key +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24046\fP: (\fIrallytime\fP) Remove key management test from digital ocean cloud tests +@ \fI2015\-05\-21T22:32:04Z\fP +.INDENT 7.0 +.IP \(bu 2 +42b87f1 Merge pull request \fI\%#24046\fP from rallytime/remove_key_test +.IP \(bu 2 +1d031ca Remove key management test from digital ocean cloud tests +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24044\fP: (\fIcro\fP) Remove spurious log message, fix typo in doc +@ \fI2015\-05\-21T22:31:49Z\fP +.INDENT 7.0 +.IP \(bu 2 +eff54b1 Merge pull request \fI\%#24044\fP from cro/pgjsonb +.IP \(bu 2 +de06633 Remove spurious log message, fix typo in doc +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24001\fP: (\fImsteed\fP) issue \fI\%#23883\fP +@ \fI2015\-05\-21T20:32:30Z\fP +.sp +\fBISSUE\fP \fI\%#23883\fP: (\fIkaithar\fP) max_event_size seems broken +* ac32000 Merge pull request \fI\%#24001\fP from msteed/issue\-23883 +* bea97a8 issue \fI\%#23883\fP +.TP +.B \fBPR\fP \fI\%#23995\fP: (\fIkiorky\fP) Lxc path pre +@ \fI2015\-05\-21T17:26:03Z\fP +.INDENT 7.0 +.IP \(bu 2 +f7fae26 Merge pull request \fI\%#23995\fP from makinacorpus/lxc_path_pre +.IP \(bu 2 +319282a lint +.IP \(bu 2 +1dc67e5 lxc: versionadded +.IP \(bu 2 +fcad7cb lxc: states improvments +.IP \(bu 2 +644bd72 lxc: more consistence for profiles +.IP \(bu 2 +139372c lxc: remove merge cruft +.IP \(bu 2 +725b046 lxc: Repair merge +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24032\fP: (\fIkartiksubbarao\fP) Update augeas_cfg.py +@ \fI2015\-05\-21T17:03:42Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#16383\fP: (\fIinterjection\fP) salt.states.augeas.change example from docs fails with exception +.nf +refs: \fI\%#24032\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +26d6851 Merge pull request \fI\%#24032\fP from kartiksubbarao/augeas_insert_16383 +.IP \(bu 2 +3686dcd Update augeas_cfg.py +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24025\fP: (\fIjayeshka\fP) adding timezone unit test case +@ \fI2015\-05\-21T16:50:53Z\fP +.INDENT 7.0 +.IP \(bu 2 +55c9245 Merge pull request \fI\%#24025\fP from jayeshka/timezone\-unit\-test +.IP \(bu 2 +1ec33e2 removed assertion error +.IP \(bu 2 +16ecb28 adding timezone unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24023\fP: (\fIjayeshka\fP) adding states/mongodb_database unit test case +@ \fI2015\-05\-21T16:49:17Z\fP +.INDENT 7.0 +.IP \(bu 2 +e243617 Merge pull request \fI\%#24023\fP from jayeshka/mongodb_database\-states\-unit\-test +.IP \(bu 2 +5a9ac7e adding states/mongodb_database unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24022\fP: (\fIjayeshka\fP) adding states/modjk_worker unit test case +@ \fI2015\-05\-21T16:48:29Z\fP +.INDENT 7.0 +.IP \(bu 2 +b377bd9 Merge pull request \fI\%#24022\fP from jayeshka/modjk_worker\-states\-unit\-test +.IP \(bu 2 +05c0a98 adding states/modjk_worker unit test case +.UNINDENT +.TP +.B \fBPR\fP \fI\%#24005\fP: (\fImsteed\fP) issue \fI\%#23776\fP +@ \fI2015\-05\-21T01:55:34Z\fP +.sp +\fBISSUE\fP \fI\%#23776\fP: (\fIenblde\fP) Presence change events constantly reporting all minions as new in 2015.5 +* 701c51b Merge pull request \fI\%#24005\fP from msteed/issue\-23776 +* 62e67d8 issue \fI\%#23776\fP +.TP +.B \fBPR\fP \fI\%#23996\fP: (\fIneogenix\fP) iptables state generates a 0 position which is invalid in iptables cli \fI\%#23950\fP +@ \fI2015\-05\-20T22:44:27Z\fP +.INDENT 7.0 +.TP +.B \fBISSUE\fP \fI\%#23950\fP: (\fIneogenix\fP) iptables state generates a 0 position which is invalid in iptables cli +.nf +refs: \fI\%#23996\fP +.fi +.sp +.UNINDENT +.INDENT 7.0 +.IP \(bu 2 +17b7c0b Merge pull request \fI\%#23996\fP from neogenix/2015.5\-23950 +.IP \(bu 2 +ad417a5 fix for \fI\%#23950\fP +.UNINDENT +.TP +.B \fBPR\fP \fI\%#23994\fP: (\fIrallytime\fP) Skip the gpodder pkgrepo test for Ubuntu 15 \- they don\(aqt have vivid ppa up yet +@ \fI2015\-05\-20T21:18:21Z\fP +.INDENT 7.0 +.IP \(bu 2 +4cb8773 Merge pull request \fI\%#23994\fP from rallytime/skip_test_ubuntu_15 +.IP \(bu 2 +9e0ec07 Skip the gpodder pkgrepo test \- they don\(aqt have vivid ppa up yet +.UNINDENT +.UNINDENT .SS Salt 2014.7.0 Release Notes \- Codename Helium .sp This release is the largest Salt release ever, with more features and commits @@ -165740,7 +178729,7 @@ For more information about these new requisites, see the The \fBonlyif\fP and \fBunless\fP options can now be used for any state declaration. .SS Use \fBnames\fP to expand and override values .sp -The names declaration in Salt\(aqs state system can now +The \fInames declaration\fP in Salt\(aqs state system can now override or add values to the expanded data structure. For example: .INDENT 0.0 .INDENT 3.5 @@ -165845,7 +178834,7 @@ module for instructions. \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 -The full list of netapi modules. +\fIThe full list of netapi modules.\fP .UNINDENT .UNINDENT .SS Synchronous and Asynchronous Execution of Runner and Wheel Modules @@ -165853,7 +178842,7 @@ The full list of netapi modules. \fBsalt.runner.RunnerClient\fP and \fBsalt.wheel.WheelClient\fP have both gained complimentary \fBcmd_sync\fP and \fBcmd_async\fP methods allowing for synchronous and asynchronous execution of any Runner or Wheel module -function, all protected using Salt\(aqs external authentication +function, all protected using Salt\(aqs \fIexternal authentication\fP system. \fBsalt\-api\fP benefits from this addition as well. .SS \fBrest_cherrypy\fP Additions .sp @@ -165925,7 +178914,7 @@ By default, gitfs will expose all branches and tags as Salt fileserver environments. Two new config parameters, \fBgitfs_env_whitelist\fP, and \fBgitfs_env_blacklist\fP, allow more control over which branches and tags are exposed. More detailed information on how these two options work can -be found in the Gitfs Walkthrough\&. +be found in the \fIGitfs Walkthrough\fP\&. .SS Expanded Authentication Support .sp As of \fI\%pygit2\fP 0.20.3, both http(s) and SSH key authentication are supported, @@ -165935,8 +178924,8 @@ who had been using authenticated git repositories with a passphraseless key should stick to GitPython if a new enough \fI\%pygit2\fP is not yet available for the platform on which the master is running. .sp -A full explanation of how to use authentication can be found in the Gitfs -Walkthrough\&. +A full explanation of how to use authentication can be found in the \fIGitfs +Walkthrough\fP\&. .SS New \fBhgfs\fP Features .SS Mountpoints .sp @@ -166068,6 +179057,2209 @@ Removed deprecated \fBlibcloud_version\fP function from \fBsalt/cloud/libcloudfu .IP \(bu 2 Removed deprecated \fBCloudConfigMixIn\fP class from \fBsalt/utils/parsers.py\fP (deprecated) .UNINDENT +.SS Salt 2014.7.1 Release Notes +.INDENT 0.0 +.TP +.B release +2015\-01\-12 +.UNINDENT +.sp +Version 2014.7.1 is a bugfix release for \fB2014.7.0\fP\&. The changes include: +.INDENT 0.0 +.IP \(bu 2 +Fixed gitfs serving symlinks in \fBfile.recurse\fP states (\fI\%issue 17700\fP) +.IP \(bu 2 +Fixed holding of multiple packages (YUM) when combined with version pinning +(\fI\%issue 18468\fP) +.IP \(bu 2 +Fixed use of Jinja templates in masterless mode with non\-roots fileserver +backend (\fI\%issue 17963\fP) +.IP \(bu 2 +Re\-enabled pillar and compound matching for mine and publish calls. Note that +pillar globbing is still disabled for those modes, for security reasons. +(\fI\%issue 17194\fP) +.IP \(bu 2 +Fix for \fBtty: True\fP in salt\-ssh (\fI\%issue 16847\fP) +.IP \(bu 2 +Fix for supervisord states when supervisor not installed to system python +(\fI\%issue 18044\fP) +.IP \(bu 2 +Fix for logging when \fBlog_level=\(aqquiet\(aq\fP for \fBcmd.run\fP (\fI\%issue 19479\fP) +.UNINDENT +.SS Salt 2014.7.2 Release Notes +.INDENT 0.0 +.TP +.B release +TBA +.UNINDENT +.sp +Version 2014.7.2 is a bugfix release for \fB2014.7.0\fP\&. The changes include: +.INDENT 0.0 +.IP \(bu 2 +Fix erroneous warnings for systemd service enabled check (\fI\%issue 19606\fP) +.IP \(bu 2 +Fix FreeBSD kernel module loading, listing, and persistence +\fBkmod\fP (\fI\%issue 197151\fP, \fI\%issue 19682\fP) +.IP \(bu 2 +Allow case\-sensitive npm package names in the \fBnpm state\fP\&. This may break behavior for people expecting the state +to lowercase their npm package names for them. The \fBnpm module\fP was never affected by mandatory lowercasing. +(\fI\%issue 20329\fP) +.IP \(bu 2 +Deprecate the \fBactivate\fP parameter for pip.install for both the +\fBmodule\fP and the \fBstate\fP\&. +If \fBbin_env\fP is given and points to a virtualenv, there is no need to +activate that virtualenv in a shell for pip to install to the virtualenv. +.IP \(bu 2 +Fix a file\-locking bug in gitfs (\fI\%issue 18839\fP) +.UNINDENT +.SS Salt 2014.7.3 Release Notes +.INDENT 0.0 +.TP +.B release +TBA +.UNINDENT +.sp +Version 2014.7.3 is a bugfix release for \fB2014.7.0\fP\&. +.sp +Changes: +.INDENT 0.0 +.IP \(bu 2 +Multi\-master minions mode no longer route fileclient operations asymetrically. +This fixes the source of many multi\-master bugs where the minion would +become unrepsonsive from one or more masters. +.IP \(bu 2 +Fix bug wherein network.iface could produce stack traces. +.IP \(bu 2 +net.arp will no longer be made available unless arp is installed on the +system. +.IP \(bu 2 +Major performance improvements to Saltnado +.IP \(bu 2 +Allow KVM module to operate under KVM itself or VMWare Fusion +.IP \(bu 2 +Various fixes to the Windows installation scripts +.IP \(bu 2 +Fix issue where the syndic would not correctly propogate loads to the master +job cache. +.IP \(bu 2 +Improve error handling on invalid /etc/network/interfaces file in salt +networking modules +.IP \(bu 2 +Fix bug where a reponse status was not checked for in fileclient.get_url +.IP \(bu 2 +Enable eauth when running salt in batch mode +.IP \(bu 2 +Increase timeout in Boto Route53 module +.IP \(bu 2 +Fix bugs with Salt\(aqs \(aqtar\(aq module option parsing +.IP \(bu 2 +Fix parsing of NTP servers on Windows +.IP \(bu 2 +Fix issue with blockdev tuning not reporting changes correctly +.IP \(bu 2 +Update to the latest Salt bootstrap script +.IP \(bu 2 +Update Linode salt\-cloud driver to use either linode\-python or +apache\-libcloud +.IP \(bu 2 +Fix for s3.query function to return correct headers +.IP \(bu 2 +Fix for s3.head returning None for files that exist +.IP \(bu 2 +Fix the disable function in win_service module so that the service is +disabled correctly +.IP \(bu 2 +Fix race condition between master and minion when making a directory when +both daemons are on the same host +.IP \(bu 2 +Fix an issue where file.recurse would fail at the root of an svn repo +when the repo has a mountpoint +.IP \(bu 2 +Fix an issue where file.recurse would fail at the root of an hgfs repo +when the repo has a mountpoint +.IP \(bu 2 +Fix an issue where file.recurse would fail at the root of an gitfs repo +when the repo has a mountpoint +.IP \(bu 2 +Add status.master capability for Windows. +.IP \(bu 2 +Various fixes to ssh_known_hosts +.IP \(bu 2 +Various fixes to states.network bonding for Debian +.IP \(bu 2 +The debian_ip.get_interfaces module no longer removes nameservers. +.IP \(bu 2 +Better integration between grains.virtual and systemd\-detect\-virt and +virt\-what +.IP \(bu 2 +Fix traceback in sysctl.present state output +.IP \(bu 2 +Fix for issue where mount.mounted would fail when superopts were not a part +of mount.active (extended=True). Also mount.mounted various fixes for Solaris +and FreeBSD. +.IP \(bu 2 +Fix error where datetimes were not correctly safeguarded before being passed +into msgpack. +.IP \(bu 2 +Fix file.replace regressions. If the pattern is not found, and if dry run is False, +and if \fIbackup\fP is False, and if a pre\-existing file exists with extension \fI\&.bak\fP, +then that backup file will be overwritten. This backup behavior is a result of how \fIfileinput\fP +works. Fixing it requires either passing through the file twice (the +first time only to search for content and set a flag), or rewriting +\fIfile.replace\fP so it doesn\(aqt use \fIfileinput\fP +.IP \(bu 2 +VCS filreserver fixes/optimizations +.IP \(bu 2 +Catch fileserver configuration errors on master start +.IP \(bu 2 +Raise errors on invalid gitfs configurations +.IP \(bu 2 +set_locale when locale file does not exist (Redhat family) +.IP \(bu 2 +Fix to correctly count active devices when created mdadm array with spares +.IP \(bu 2 +Fix to correctly target minions in batch mode +.IP \(bu 2 +Support \fI\%ssh://\fP urls using the gitfs dulwhich backend +.IP \(bu 2 +New fileserver runner +.IP \(bu 2 +Fix various bugs with argument parsing to the publish module. +.IP \(bu 2 +Fix disk.usage for Synology OS +.IP \(bu 2 +Fix issue with tags occurring twice with docker.pulled +.IP \(bu 2 +Fix incorrect key error in SMTP returner +.IP \(bu 2 +Fix condition which would remount loopback filesystems on every state run +.IP \(bu 2 +Remove requsites from listens after they are called in the state system +.IP \(bu 2 +Make system implementation of service.running aware of legacy service calls +.IP \(bu 2 +Fix issue where publish.publish would not handle duplicate responses gracefully. +.IP \(bu 2 +Accept Kali Linux for aptpkg salt execution module +.IP \(bu 2 +Fix bug where cmd.which could not handle a dirname as an argument +.IP \(bu 2 +Fix issue in ps.pgrep where exceptions were thrown on Windows. +.UNINDENT +.sp +Known issues: +.INDENT 0.0 +.IP \(bu 2 +In multimaster mode, a minion may become temporarily unresponsive +if modules or pillars are refreshed at the same time that one +or more masters are down. This can be worked around by setting +\(aqauth_timeout\(aq and \(aqauth_tries\(aq down to shorter periods. +.UNINDENT +.SS Salt 2014.7.4 Release Notes +.INDENT 0.0 +.TP +.B release +TBA +.UNINDENT +.sp +Version 2014.7.4 is a bugfix release for \fB2014.7.0\fP\&. +.sp +Changes: +.INDENT 0.0 +.IP \(bu 2 +Multi\-master minions mode no longer route fileclient operations asymetrically. +This fixes the source of many multi\-master bugs where the minion would +become unrepsonsive from one or more masters. +.IP \(bu 2 +Fix bug wherein network.iface could produce stack traces. +.IP \(bu 2 +net.arp will no longer be made available unless arp is installed on the +system. +.IP \(bu 2 +Major performance improvements to Saltnado +.IP \(bu 2 +Allow KVM module to operate under KVM itself or VMWare Fusion +.IP \(bu 2 +Various fixes to the Windows installation scripts +.IP \(bu 2 +Fix issue where the syndic would not correctly propogate loads to the master +job cache. +.IP \(bu 2 +Improve error handling on invalid /etc/network/interfaces file in salt +networking modules +.IP \(bu 2 +Fix bug where a reponse status was not checked for in fileclient.get_url +.IP \(bu 2 +Enable eauth when running salt in batch mode +.IP \(bu 2 +Increase timeout in Boto Route53 module +.IP \(bu 2 +Fix bugs with Salt\(aqs \(aqtar\(aq module option parsing +.IP \(bu 2 +Fix parsing of NTP servers on Windows +.IP \(bu 2 +Fix issue with blockdev tuning not reporting changes correctly +.IP \(bu 2 +Update to the latest Salt bootstrap script +.IP \(bu 2 +Update Linode salt\-cloud driver to use either linode\-python or +apache\-libcloud +.IP \(bu 2 +Fix for s3.query function to return correct headers +.IP \(bu 2 +Fix for s3.head returning None for files that exist +.IP \(bu 2 +Fix the disable function in win_service module so that the service is +disabled correctly +.IP \(bu 2 +Fix race condition between master and minion when making a directory when +both daemons are on the same host +.IP \(bu 2 +Fix an issue where file.recurse would fail at the root of an svn repo +when the repo has a mountpoint +.IP \(bu 2 +Fix an issue where file.recurse would fail at the root of an hgfs repo +when the repo has a mountpoint +.IP \(bu 2 +Fix an issue where file.recurse would fail at the root of an gitfs repo +when the repo has a mountpoint +.IP \(bu 2 +Add status.master capability for Windows. +.IP \(bu 2 +Various fixes to ssh_known_hosts +.IP \(bu 2 +Various fixes to states.network bonding for Debian +.IP \(bu 2 +The debian_ip.get_interfaces module no longer removes nameservers. +.IP \(bu 2 +Better integration between grains.virtual and systemd\-detect\-virt and +virt\-what +.IP \(bu 2 +Fix traceback in sysctl.present state output +.IP \(bu 2 +Fix for issue where mount.mounted would fail when superopts were not a part +of mount.active (extended=True). Also mount.mounted various fixes for Solaris +and FreeBSD. +.IP \(bu 2 +Fix error where datetimes were not correctly safeguarded before being passed +into msgpack. +.IP \(bu 2 +Fix file.replace regressions. If the pattern is not found, and if dry run is False, +and if \fIbackup\fP is False, and if a pre\-existing file exists with extension \fI\&.bak\fP, +then that backup file will be overwritten. This backup behavior is a result of how \fIfileinput\fP +works. Fixing it requires either passing through the file twice (the +first time only to search for content and set a flag), or rewriting +\fIfile.replace\fP so it doesn\(aqt use \fIfileinput\fP +.IP \(bu 2 +VCS filreserver fixes/optimizations +.IP \(bu 2 +Catch fileserver configuration errors on master start +.IP \(bu 2 +Raise errors on invalid gitfs configurations +.IP \(bu 2 +set_locale when locale file does not exist (Redhat family) +.IP \(bu 2 +Fix to correctly count active devices when created mdadm array with spares +.IP \(bu 2 +Fix to correctly target minions in batch mode +.IP \(bu 2 +Support \fI\%ssh://\fP urls using the gitfs dulwhich backend +.IP \(bu 2 +New fileserver runner +.IP \(bu 2 +Fix various bugs with argument parsing to the publish module. +.IP \(bu 2 +Fix disk.usage for Synology OS +.IP \(bu 2 +Fix issue with tags occurring twice with docker.pulled +.IP \(bu 2 +Fix incorrect key error in SMTP returner +.IP \(bu 2 +Fix condition which would remount loopback filesystems on every state run +.IP \(bu 2 +Remove requsites from listens after they are called in the state system +.IP \(bu 2 +Make system implementation of service.running aware of legacy service calls +.IP \(bu 2 +Fix issue where publish.publish would not handle duplicate responses gracefully. +.IP \(bu 2 +Accept Kali Linux for aptpkg salt execution module +.IP \(bu 2 +Fix bug where cmd.which could not handle a dirname as an argument +.IP \(bu 2 +Fix issue in ps.pgrep where exceptions were thrown on Windows. +.UNINDENT +.sp +Known issues: +.INDENT 0.0 +.IP \(bu 2 +In multimaster mode, a minion may become temporarily unresponsive +if modules or pillars are refreshed at the same time that one +or more masters are down. This can be worked around by setting +\(aqauth_timeout\(aq and \(aqauth_tries\(aq down to shorter periods. +.IP \(bu 2 +There are known issues with batch mode operating on the incorrect number of minions. +This bug can be patched with the change in \fI\%Pull Request #22464\fP\&. +.IP \(bu 2 +The \fIfun\fP, \fIstate\fP, and \fIunless\fP keywords are missing from the state internals, which +can cause problems running some states. This bug can be patched with the change in +\fI\%Pull Request #22365\fP\&. +.UNINDENT +.SS Salt 2014.7.5 Release Notes +.INDENT 0.0 +.TP +.B release +2015\-04\-16 +.UNINDENT +.sp +Version 2014.7.5 is a bugfix release for \fB2014.7.0\fP\&. +.sp +Changes: +.INDENT 0.0 +.IP \(bu 2 +Fixed a key error bug in salt\-cloud +.IP \(bu 2 +Updated man pages to better match documentation +.IP \(bu 2 +Fixed bug concerning high CPU usage with salt\-ssh +.IP \(bu 2 +Fixed bugs with remounting cvfs and fuse filesystems +.IP \(bu 2 +Fixed bug with alowing requisite tracking of entire sls files +.IP \(bu 2 +Fixed bug with aptpkg.mod_repo returning OK even if apt\-add\-repository fails +.IP \(bu 2 +Increased frequency of ssh terminal output checking +.IP \(bu 2 +Fixed malformed locale string in localmod module +.IP \(bu 2 +Fixed checking of available version of package when accept_keywords were changed +.IP \(bu 2 +Fixed bug to make git.latest work with empty repositories +.IP \(bu 2 +Added **kwargs to service.mod_watch which removes warnings about \fIenable\fP and \fI__reqs__\fP not being supported by the function +.IP \(bu 2 +Improved state comments to not grow so quickly on failed requisites +.IP \(bu 2 +Added force argument to service to trigger force_reload +.IP \(bu 2 +Fixed bug to andle pkgrepo keyids that have been converted to int +.IP \(bu 2 +Fixed module.portage_config bug with appending accept_keywords +.IP \(bu 2 +Fixed bug to correctly report disk usage on windows minion +.IP \(bu 2 +Added the ability to specify key prefix for S3 ext_pillar +.IP \(bu 2 +Fixed issues with batch mode operating on the incorrect number of minions +.IP \(bu 2 +Fixed a bug with the proxmox cloud provider stacktracing on disk definition +.IP \(bu 2 +Fixed a bug with the changes dictionary in the file state +.IP \(bu 2 +Fixed the TCP keep alive settings to work better with SREQ caching +.IP \(bu 2 +Fixed many bugs within the iptables state and module +.IP \(bu 2 +Fixed bug with states by adding \fIfun\fP, \fIstate\fP, and \fIunless\fP to the state runtime internal keywords listing +.IP \(bu 2 +Added ability to eAuth against Active Directory +.IP \(bu 2 +Fixed some salt\-ssh issues when running on Fedora 21 +.IP \(bu 2 +Fixed grains.get_or_set_hash to work with multiple entries under same key +.IP \(bu 2 +Added better explanations and more examples of how the Reactor calls functions to docs +.IP \(bu 2 +Fixed bug to not pass \fIex_config_drive\fP to libcloud unless it\(aqs explicitly enabled +.IP \(bu 2 +Fixed bug with pip.install on windows +.IP \(bu 2 +Fixed bug where puppet.run always returns a 0 retcode +.IP \(bu 2 +Fixed race condition bug with minion scheduling via pillar +.IP \(bu 2 +Made efficiency improvements and bug fixes to the windows installer +.IP \(bu 2 +Updated environment variables to fix bug with pygit2 when running salt as non\-root user +.IP \(bu 2 +Fixed cas behavior on data module \-\- data.cas was not saving changes +.IP \(bu 2 +Fixed GPG rendering error +.IP \(bu 2 +Fixed strace error in virt.query +.IP \(bu 2 +Fixed stacktrace when running chef\-solo command +.IP \(bu 2 +Fixed possible bug wherein uncaught exceptions seem to make zmq3 tip over when threading is involved +.IP \(bu 2 +Fixed argument passing to the reactor +.IP \(bu 2 +Fixed glibc caching to prevent bug where salt\-minion getaddrinfo in dns_check() never got updated nameservers +.UNINDENT +.sp +Known issues: +.INDENT 0.0 +.IP \(bu 2 +In multimaster mode, a minion may become temporarily unresponsive +if modules or pillars are refreshed at the same time that one +or more masters are down. This can be worked around by setting +\(aqauth_timeout\(aq and \(aqauth_tries\(aq down to shorter periods. +.UNINDENT +.SS Salt 2014.7.6 Release Notes +.INDENT 0.0 +.TP +.B release +2015\-05\-18 +.UNINDENT +.sp +Version 2014.7.6 is a bugfix release for \fB2014.7.0\fP\&. +.sp +This release is a security release. A minor issue was found, as cited below: +.INDENT 0.0 +.IP \(bu 2 +CVE\-2015\-4017 \-\- Certificates are not verified when connecting to server in +the Aliyun and Proxmox modules +.UNINDENT +.sp +Only users of the Aliyun or Proxmox cloud modules are at risk. The +vulnerability does not exist in the latest 2015.5.0 release of Salt. +.sp +Changes: +.INDENT 0.0 +.IP \(bu 2 +salt.runners.cloud.action() has changed the \fIfun\fP keyword argument to \fIfunc\fP\&. +Please update any calls to this function in the cloud runner. +.UNINDENT +.sp +Extended Changelog Courtesy of Todd Stansell (\fI\%https://github.com/tjstansell/salt\-changelogs\fP): +.INDENT 0.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23810\fP: (\fIrallytime\fP) Backport \fI\%#23757\fP to 2014.7 +@ \fI2015\-05\-18T15:30:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23757\fP: (\fIclan\fP) use abspath, do not eliminating symlinks +| refs: \fI\%#23810\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +aee00c8 Merge pull request \fI\%#23810\fP from rallytime/\fI\%bp\-23757\fP +.IP \(bu 2 +fb32c32 use abspath, do not eliminating symlinks +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23809\fP: (\fIrallytime\fP) Fix virtualport section of virt.get_nics loop +@ \fI2015\-05\-18T15:30:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#20198\fP: (\fIjcftang\fP) virt.get_graphics, virt.get_nics are broken, in turn breaking other things +| refs: \fI\%#23809\fP +.IP \(bu 2 +\fBPR\fP \fI\%#21487\fP: (\fIrallytime\fP) Backport \fI\%#21469\fP to 2014.7 +| refs: \fI\%#23809\fP +.IP \(bu 2 +\fBPR\fP \fI\%#21469\fP: (\fIvdesjardins\fP) fixes \fI\%#20198\fP: virt.get_graphics and virt.get_nics calls in module virt +| refs: \fI\%#21487\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6b3352b Merge pull request \fI\%#23809\fP from rallytime/virt_get_nics_fix +.IP \(bu 2 +0616fb7 Fix virtualport section of virt.get_nics loop +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23823\fP: (\fIgtmanfred\fP) add link local for ipv6 +@ \fI2015\-05\-17T12:48:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +188f03f Merge pull request \fI\%#23823\fP from gtmanfred/2014.7 +.IP \(bu 2 +5ef006d add link local for ipv6 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23802\fP: (\fIgtmanfred\fP) if it is ipv6 ip_to_int will fail +@ \fI2015\-05\-16T04:06:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23573\fP: (\fItechhat\fP) Scan all available networks for public and private IPs +| refs: \fI\%#23802\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f3ca682 Merge pull request \fI\%#23802\fP from gtmanfred/2014.7 +.IP \(bu 2 +2da98b5 if it is ipv6 ip_to_int will fail +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23488\fP: (\fIcellscape\fP) LXC cloud fixes +@ \fI2015\-05\-15T18:09:35Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#16424\fP: (\fIstanvit\fP) salt\-run cloud.create fails with saltify +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +d9af0c3 Merge pull request \fI\%#23488\fP from cellscape/lxc\-cloud\-fixes +.IP \(bu 2 +64250a6 Remove profile from opts after creating LXC container +.IP \(bu 2 +c4047d2 Set destroy=True in opts when destroying cloud instance +.IP \(bu 2 +9e1311a Store instance names in opts when performing cloud action +.IP \(bu 2 +934bc57 Correctly pass custom env to lxc\-attach +.IP \(bu 2 +7fb85f7 Preserve test=True option in cloud states +.IP \(bu 2 +9771b5a Fix detection of absent LXC container in cloud state +.IP \(bu 2 +fb24f0c Report failure when failed to create/clone LXC container +.IP \(bu 2 +2d9aa2b Avoid shadowing variables in lxc module +.IP \(bu 2 +792e102 Allow to override profile options in lxc.cloud_init_interface +.IP \(bu 2 +42bd64b Return changes on successful lxc.create from salt\-cloud +.IP \(bu 2 +4409eab Return correct result when creating cloud LXC container +.IP \(bu 2 +377015c Issue \fI\%#16424\fP: List all providers when creating salt\-cloud instance without profile +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23748\fP: (\fIbasepi\fP) [2014.7] Log salt\-ssh roster render errors more assertively and verbosely +@ \fI2015\-05\-14T22:38:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22332\fP: (\fIrallytime\fP) [salt\-ssh] Add a check for host in /etc/salt/roster +| refs: \fI\%#23748\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +808bbe1 Merge pull request \fI\%#23748\fP from basepi/salt\-ssh.roster.host.check +.IP \(bu 2 +bc53e04 Log entire exception for render errors in roster +.IP \(bu 2 +753de6a Log render errors in roster to error level +.IP \(bu 2 +e01a7a9 Always let the real YAML error through +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23731\fP: (\fItwangboy\fP) Fixes \fI\%#22959\fP: Trying to add a directory to an unmapped drive in windows +@ \fI2015\-05\-14T21:59:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22959\fP: (\fIhighlyunavailable\fP) Windows Salt hangs if file.directory is trying to write to a drive that doesn\(aqt exist +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +72cf360 Merge pull request \fI\%#23731\fP from twangboy/fix_22959 +.IP \(bu 2 +88e5495 Fixes \fI\%#22959\fP: Trying to add a directory to an unmapped drive in windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23730\fP: (\fIrallytime\fP) Backport \fI\%#23729\fP to 2014.7 +@ \fI2015\-05\-14T21:58:34Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23729\fP: (\fIrallytime\fP) Partially merge \fI\%#23437\fP (grains fix) +| refs: \fI\%#23730\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23437\fP: (\fIcedwards\fP) Grains item patch +| refs: \fI\%#23729\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2610195 Merge pull request \fI\%#23730\fP from rallytime/\fI\%bp\-23729\fP +.IP \(bu 2 +1877cae adding support for nested grains to grains.item +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23688\fP: (\fItwangboy\fP) Added inet_pton to utils/validate/net.py for ip.set_static_ip in windows +@ \fI2015\-05\-14T16:15:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +3e9df88 Merge pull request \fI\%#23688\fP from twangboy/fix_23415 +.IP \(bu 2 +6a91169 Fixed unused\-import pylint error +.IP \(bu 2 +5e25b3f fixed pylint errors +.IP \(bu 2 +1a96766 Added inet_pton to utils/validate/net.py for ip.set_static_ip in windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23680\fP: (\fIcachedout\fP) Rename kwarg in cloud runner +@ \fI2015\-05\-13T19:44:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23403\fP: (\fIiamfil\fP) salt.runners.cloud.action fun parameter is replaced +| refs: \fI\%#23680\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1b86460 Merge pull request \fI\%#23680\fP from cachedout/issue_23403 +.IP \(bu 2 +d5986c2 Rename kwarg in cloud runner +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23674\fP: (\fIcachedout\fP) Handle lists correctly in grains.list_prsesent +@ \fI2015\-05\-13T18:34:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23548\fP: (\fIkkaig\fP) grains.list_present produces incorrect (?) output +| refs: \fI\%#23674\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +cd64af0 Merge pull request \fI\%#23674\fP from cachedout/issue_23548 +.IP \(bu 2 +da8a2f5 Handle lists correctly in grains.list_prsesent +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23672\fP: (\fItwangboy\fP) Fix user present +@ \fI2015\-05\-13T18:30:09Z\fP +.INDENT 2.0 +.IP \(bu 2 +d322a19 Merge pull request \fI\%#23672\fP from twangboy/fix_user_present +.IP \(bu 2 +731e7af Merge branch \(aq2014.7\(aq of \fI\%https://github.com/saltstack/salt\fP into fix_user_present +.IP \(bu 2 +d6f70a4 Fixed user.present to create password in windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23670\fP: (\fIrallytime\fP) Backport \fI\%#23607\fP to 2014.7 +@ \fI2015\-05\-13T18:27:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23604\fP: (\fIAzidburn\fP) service.dead on systemd Minion create an Error Message +| refs: \fI\%#23607\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23607\fP: (\fIAzidburn\fP) Fix for \fI\%#23604\fP\&. No error reporting. Exitcode !=0 are ok +| refs: \fI\%#23670\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +43f7025 Merge pull request \fI\%#23670\fP from rallytime/\fI\%bp\-23607\fP +.IP \(bu 2 +ed30dc4 Fix for \fI\%#23604\fP\&. No error reporting. Exitcode !=0 are ok +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23661\fP: (\fIrallytime\fP) Merge \fI\%#23640\fP with whitespace fix +@ \fI2015\-05\-13T15:47:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22141\fP: (\fIDeshke\fP) grains.get_or_set_hash render error if hash begins with "%" +| refs: \fI\%#23640\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23640\fP: (\fIcachedout\fP) Add warning to get_or_set_hash about reserved chars +| refs: \fI\%#23661\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0f006ac Merge pull request \fI\%#23661\fP from rallytime/merge\-23640 +.IP \(bu 2 +4427f42 Whitespace fix +.IP \(bu 2 +dd91154 Add warning to get_or_set_hash about reserved chars +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23639\fP: (\fIcachedout\fP) Handle exceptions raised by __virtual__ +@ \fI2015\-05\-13T15:11:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23452\fP: (\fImichaelforge\fP) minion crashed with empty grain +| refs: \fI\%#23639\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +84e2ef8 Merge pull request \fI\%#23639\fP from cachedout/issue_23452 +.IP \(bu 2 +d418b49 Syntax error! +.IP \(bu 2 +45b4015 Handle exceptions raised by __virtual__ +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23637\fP: (\fIcachedout\fP) Convert str master to list +@ \fI2015\-05\-13T15:08:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23611\fP: (\fIhubez\fP) master_type set to \(aqfailover\(aq but \(aqmaster\(aq is not of type list but of type +| refs: \fI\%#23637\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +bd9b94b Merge pull request \fI\%#23637\fP from cachedout/issue_23611 +.IP \(bu 2 +56cb1f5 Fix typo +.IP \(bu 2 +f6fcf19 Convert str master to list +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23595\fP: (\fIrallytime\fP) Backport \fI\%#23549\fP to 2014.7 +@ \fI2015\-05\-12T21:19:40Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23549\fP: (\fIvr\-jack\fP) Update __init__.py +| refs: \fI\%#23595\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f20c0e4 Merge pull request \fI\%#23595\fP from rallytime/\fI\%bp\-23549\fP +.IP \(bu 2 +6efcac0 Update __init__.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23594\fP: (\fIrallytime\fP) Backport \fI\%#23496\fP to 2014.7 +@ \fI2015\-05\-12T21:19:34Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23110\fP: (\fImartinhoefling\fP) Copying files from gitfs in file.recurse state fails +.IP \(bu 2 +\fBPR\fP \fI\%#23496\fP: (\fImartinhoefling\fP) Fix for issue \fI\%#23110\fP +| refs: \fI\%#23594\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1acaf86 Merge pull request \fI\%#23594\fP from rallytime/\fI\%bp\-23496\fP +.IP \(bu 2 +d5ae1d2 Fix for issue \fI\%#23110\fP This resolves issues when the freshly created directory is removed by fileserver.update. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23593\fP: (\fIrallytime\fP) Backport \fI\%#23442\fP to 2014.7 +@ \fI2015\-05\-12T21:19:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23442\fP: (\fIclan\fP) add directory itself to keep list +| refs: \fI\%#23593\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2c221c7 Merge pull request \fI\%#23593\fP from rallytime/\fI\%bp\-23442\fP +.IP \(bu 2 +39869a1 check w/ low[\(aqname\(aq] only +.IP \(bu 2 +304cc49 another fix for file defined w/ id, but require name +.IP \(bu 2 +8814d41 add directory itself to keep list +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23606\fP: (\fItwangboy\fP) Fixed checkbox for starting service and actually starting it +@ \fI2015\-05\-12T21:18:50Z\fP +.INDENT 2.0 +.IP \(bu 2 +fadd1ef Merge pull request \fI\%#23606\fP from twangboy/fix_installer +.IP \(bu 2 +038331e Fixed checkbox for starting service and actually starting it +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23592\fP: (\fIrallytime\fP) Backport \fI\%#23389\fP to 2014.7 +@ \fI2015\-05\-12T16:44:42Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22908\fP: (\fIkaranjad\fP) Add failhard option to salt orchestration +| refs: \fI\%#23389\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23389\fP: (\fIcachedout\fP) Correct fail_hard typo +| refs: \fI\%#23592\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +10b3f0f Merge pull request \fI\%#23592\fP from rallytime/\fI\%bp\-23389\fP +.IP \(bu 2 +734cc43 Correct fail_hard typo +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23573\fP: (\fItechhat\fP) Scan all available networks for public and private IPs +| refs: \fI\%#23802\fP +@ \fI2015\-05\-12T15:22:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +cd34b9b Merge pull request \fI\%#23573\fP from techhat/novaquery +.IP \(bu 2 +f92db5e Linting +.IP \(bu 2 +26e00d3 Scan all available networks for public and private IPs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23558\fP: (\fIjfindlay\fP) reorder emerge command line +@ \fI2015\-05\-12T15:17:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23479\fP: (\fIdanielmorlock\fP) Typo in pkg.removed for Gentoo? +| refs: \fI\%#23558\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2a72cd7 Merge pull request \fI\%#23558\fP from jfindlay/fix_ebuild +.IP \(bu 2 +45404fb reorder emerge command line +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23530\fP: (\fIdr4Ke\fP) salt\-ssh state: fix including all salt:// references +@ \fI2015\-05\-12T15:13:43Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23355\fP: (\fIdr4Ke\fP) salt\-ssh: \(aqsources: salt://\(aq files from \(aqpkg\(aq state are not included in salt_state.tgz +| refs: \fI\%#23530\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a664a3c Merge pull request \fI\%#23530\fP from dr4Ke/fix_salt\-ssh_to_include_pkg_sources +.IP \(bu 2 +5df6a80 fix pylint warning +.IP \(bu 2 +d0549e5 salt\-ssh state: fix including all salt:// references +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23433\fP: (\fItwangboy\fP) Obtain all software from the registry +@ \fI2015\-05\-11T22:47:52Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23004\fP: (\fIb18\fP) 2014.7.5 \- Windows \- pkg.list_pkgs \- "nxlog" never shows up in output. +| refs: \fI\%#23433\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +55c3869 Merge pull request \fI\%#23433\fP from twangboy/list_pkgs_fix +.IP \(bu 2 +8ab5b1b Fix pylint error +.IP \(bu 2 +2d11d65 Obtain all software from the registry +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23554\fP: (\fIjleroy\fP) Debian: Hostname always updated +@ \fI2015\-05\-11T21:57:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +755bed0 Merge pull request \fI\%#23554\fP from jleroy/debian\-hostname\-fix +.IP \(bu 2 +5ff749e Debian: Hostname always updated +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23551\fP: (\fIdr4Ke\fP) grains.append unit tests, related to \fI\%#23474\fP +@ \fI2015\-05\-11T21:54:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +6ec87ce Merge pull request \fI\%#23551\fP from dr4Ke/grains.append_unit_tests +.IP \(bu 2 +ebff9df fix pylint errors +.IP \(bu 2 +c495404 unit tests for grains.append module function +.IP \(bu 2 +0c9a323 use MagickMock +.IP \(bu 2 +c838a22 unit tests for grains.append module function +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23474\fP: (\fIdr4Ke\fP) Fix grains.append in nested dictionnary grains \fI\%#23411\fP +@ \fI2015\-05\-11T18:00:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23411\fP: (\fIdr4Ke\fP) grains.append should work at any level of a grain +| refs: \fI\%#23440\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23440\fP: (\fIdr4Ke\fP) fix grains.append in nested dictionnary grains \fI\%#23411\fP +| refs: \fI\%#23474\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e96c5c5 Merge pull request \fI\%#23474\fP from dr4Ke/fix_grains.append_nested +.IP \(bu 2 +a01a5bb grains.get, parameter delimititer, versionadded: 2014.7.6 +.IP \(bu 2 +b39f504 remove debugging output +.IP \(bu 2 +b6e15e2 fix grains.append in nested dictionnary grains \fI\%#23411\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23537\fP: (\fIt0rrant\fP) Update changelog +@ \fI2015\-05\-11T17:02:16Z\fP +.INDENT 2.0 +.IP \(bu 2 +ab7e1ae Merge pull request \fI\%#23537\fP from t0rrant/patch\-1 +.IP \(bu 2 +8e03cc9 Update changelog +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23538\fP: (\fIcro\fP) Update date in LICENSE file +@ \fI2015\-05\-11T15:19:25Z\fP +.INDENT 2.0 +.IP \(bu 2 +b79fed3 Merge pull request \fI\%#23538\fP from cro/licupdate +.IP \(bu 2 +345efe2 Update date in LICENSE file +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23505\fP: (\fIaneeshusa\fP) Remove unused ssh config validator. Fixes \fI\%#23159\fP\&. +@ \fI2015\-05\-09T13:24:15Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23159\fP: (\fIaneeshusa\fP) Unused validator +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +a123a36 Merge pull request \fI\%#23505\fP from aneeshusa/remove\-unused\-ssh\-config\-validator +.IP \(bu 2 +90af167 Remove unused ssh config validator. Fixes \fI\%#23159\fP\&. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23467\fP: (\fIslinu3d\fP) Added AWS v4 signature support +@ \fI2015\-05\-08T14:36:19Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#20518\fP: (\fIekle\fP) module s3.get does not support eu\-central\-1 +| refs: \fI\%#23467\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ca2c21a Merge pull request \fI\%#23467\fP from slinu3d/2014.7 +.IP \(bu 2 +0b4081d Fixed pylint error at line 363 +.IP \(bu 2 +5be5eb5 Fixed pylink errors +.IP \(bu 2 +e64f374 Fixed lint errors +.IP \(bu 2 +b9d1ac4 Added AWS v4 signature support +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23444\fP: (\fItechhat\fP) Add create_attach_volume to nova driver +@ \fI2015\-05\-07T19:51:32Z\fP +.INDENT 2.0 +.IP \(bu 2 +e6f9eec Merge pull request \fI\%#23444\fP from techhat/novacreateattach +.IP \(bu 2 +ebdb7ea Add create_attach_volume to nova driver +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23460\fP: (\fIs0undt3ch\fP) [2014.7] Update to latest stable bootstrap script v2015.05.07 +@ \fI2015\-05\-07T19:10:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#563\fP: (\fIchutz\fP) pidfile support for minion and master daemons +| refs: \fI\%#23460\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e331463 Merge pull request \fI\%#23460\fP from s0undt3ch/hotfix/bootstrap\-script\-2014.7 +.IP \(bu 2 +edcd0c4 Update to latest stable bootstrap script v2015.05.07 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23439\fP: (\fItechhat\fP) Add wait_for_passwd_maxtries variable +@ \fI2015\-05\-07T07:28:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +7a8ce1a Merge pull request \fI\%#23439\fP from techhat/maxtries +.IP \(bu 2 +0ad3ff2 Add wait_for_passwd_maxtries variable +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23422\fP: (\fIcro\fP) $HOME should not be used, some shells don\(aqt set it. +@ \fI2015\-05\-06T21:02:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +644eb75 Merge pull request \fI\%#23422\fP from cro/gce_sh_home +.IP \(bu 2 +4ef9e6b Don\(aqt use $HOME to find user\(aqs directory, some shells don\(aqt set it +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23425\fP: (\fIbasepi\fP) [2014.7] Fix typo in FunctionWrapper +@ \fI2015\-05\-06T20:38:03Z\fP +.INDENT 2.0 +.IP \(bu 2 +ef17ab4 Merge pull request \fI\%#23425\fP from basepi/functionwrapper_typo +.IP \(bu 2 +c390737 Fix typo in FunctionWrapper +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23385\fP: (\fIrallytime\fP) Backport \fI\%#23346\fP to 2014.7 +@ \fI2015\-05\-06T20:12:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23346\fP: (\fIericfode\fP) Allow file_map in salt\-cloud to handle folders. +| refs: \fI\%#23385\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +1b13ec0 Merge pull request \fI\%#23385\fP from rallytime/\fI\%bp\-23346\fP +.IP \(bu 2 +9efc13c more linting fixes +.IP \(bu 2 +cf131c9 cleaned up some pylint errors +.IP \(bu 2 +f981699 added logic to sftp_file and file_map to allow folder uploads using file_map +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23414\fP: (\fIjfindlay\fP) 2015.2 \-> 2015.5 +@ \fI2015\-05\-06T20:04:02Z\fP +.INDENT 2.0 +.IP \(bu 2 +f8c7a62 Merge pull request \fI\%#23414\fP from jfindlay/update_branch +.IP \(bu 2 +8074d16 2015.2 \-> 2015.5 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23404\fP: (\fIhvnsweeting\fP) saltapi cherrypy: initialize var when POST body is empty +@ \fI2015\-05\-06T17:35:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +54b3bd4 Merge pull request \fI\%#23404\fP from hvnsweeting/cherrypy\-post\-emptybody\-fix +.IP \(bu 2 +f85f8f9 initialize var when POST body is empty +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23409\fP: (\fIterminalmage\fP) Update Lithium docstrings in 2014.7 branch +@ \fI2015\-05\-06T16:20:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +160f703 Merge pull request \fI\%#23409\fP from terminalmage/update\-lithium\-docstrings\-2014.7 +.IP \(bu 2 +bc97d01 Fix sphinx typo +.IP \(bu 2 +20006b0 Update Lithium docstrings in 2014.7 branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23397\fP: (\fIjfindlay\fP) add more flexible whitespace to locale_gen search +@ \fI2015\-05\-06T03:44:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#17245\fP: (\fItomashavlas\fP) localemod does not generate locale for Arch +| refs: \fI\%#23307\fP \fI\%#23397\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +aa5fb0a Merge pull request \fI\%#23397\fP from jfindlay/fix_locale_gen +.IP \(bu 2 +0941fef add more flexible whitespace to locale_gen search +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23368\fP: (\fIkaithar\fP) Backport \fI\%#23367\fP to 2014.7 +@ \fI2015\-05\-05T21:42:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23367\fP: (\fIkaithar\fP) Put the sed insert statement back in to the output. +| refs: \fI\%#23368\fP +.IP \(bu 2 +\fBPR\fP \fI\%#18368\fP: (\fIbasepi\fP) Merge forward from 2014.7 to develop +| refs: \fI\%#23367\fP \fI\%#23368\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +0c76dd4 Merge pull request \fI\%#23368\fP from kaithar/\fI\%bp\-23367\fP +.IP \(bu 2 +577f419 Pylint fix +.IP \(bu 2 +8d9acd1 Put the sed insert statement back in to the output. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23350\fP: (\fIlorengordon\fP) Append/prepend: search for full line +@ \fI2015\-05\-05T21:42:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23294\fP: (\fIvariia\fP) file.replace fails to append if repl string partially available +| refs: \fI\%#23350\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3493cc1 Merge pull request \fI\%#23350\fP from lorengordon/file.replace_assume_line +.IP \(bu 2 +b60e224 Append/prepend: search for full line +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23341\fP: (\fIcachedout\fP) Fix syndic pid and logfile path +@ \fI2015\-05\-05T21:29:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23026\fP: (\fIadelcast\fP) Incorrect salt\-syndic logfile and pidfile locations +| refs: \fI\%#23341\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7be5c48 Merge pull request \fI\%#23341\fP from cachedout/issue_23026 +.IP \(bu 2 +e98e65e Fix tests +.IP \(bu 2 +6011b43 Fix syndic pid and logfile path +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23272\fP: (\fIbasepi\fP) [2014.7] Allow salt\-ssh minion config overrides via master config and roster +| refs: \fI\%#23347\fP +@ ** +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#19114\fP: (\fIpykler\fP) salt\-ssh and gpg pillar renderer +| refs: \fI\%#23188\fP \fI\%#23272\fP \fI\%#23347\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23188\fP: (\fIbasepi\fP) [2014.7] Work around bug in salt\-ssh in config.get for gpg renderer +| refs: \fI\%#23272\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ea61abf Merge pull request \fI\%#23272\fP from basepi/salt\-ssh.minion.config.19114 +.IP \(bu 2 +c223309 Add versionadded +.IP \(bu 2 +be7407f Lint +.IP \(bu 2 +c2c3375 Missing comma +.IP \(bu 2 +8e3e8e0 Pass the minion_opts through the FunctionWrapper +.IP \(bu 2 +cb69cd0 Match the master config template in the master config reference +.IP \(bu 2 +87fc316 Add Salt\-SSH section to master config template +.IP \(bu 2 +91dd9dc Add ssh_minion_opts to master config ref +.IP \(bu 2 +c273ea1 Add minion config to salt\-ssh doc +.IP \(bu 2 +a0b6b76 Add minion_opts to roster docs +.IP \(bu 2 +5212c35 Accept minion_opts from the target information +.IP \(bu 2 +e2099b6 Process \fIssh_minion_opts\fP from master config +.IP \(bu 2 +3b64214 Revert "Work around bug in salt\-ssh in config.get for gpg renderer" +.IP \(bu 2 +494953a Remove the strip (embracing multi\-line YAML dump) +.IP \(bu 2 +fe87f0f Dump multi\-line yaml into the SHIM +.IP \(bu 2 +b751a72 Inject local minion config into shim if available +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23347\fP: (\fIbasepi\fP) [2014.7] Salt\-SSH Backport FunctionWrapper.__contains__ +@ \fI2015\-05\-05T14:13:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#19114\fP: (\fIpykler\fP) salt\-ssh and gpg pillar renderer +| refs: \fI\%#23188\fP \fI\%#23272\fP \fI\%#23347\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23272\fP: (\fIbasepi\fP) [2014.7] Allow salt\-ssh minion config overrides via master config and roster +| refs: \fI\%#23347\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23188\fP: (\fIbasepi\fP) [2014.7] Work around bug in salt\-ssh in config.get for gpg renderer +| refs: \fI\%#23272\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4f760dd Merge pull request \fI\%#23347\fP from basepi/salt\-ssh.functionwrapper.contains.19114 +.IP \(bu 2 +30595e3 Backport FunctionWrapper.__contains__ +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23344\fP: (\fIcachedout\fP) Explicitely set file_client on master +@ \fI2015\-05\-04T23:21:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22742\fP: (\fIhvnsweeting\fP) salt\-master says: "This master address: \(aqsalt\(aq was previously resolvable but now fails to resolve!" +| refs: \fI\%#23344\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +02658b1 Merge pull request \fI\%#23344\fP from cachedout/issue_22742 +.IP \(bu 2 +5adc96c Explicitely set file_client on master +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23318\fP: (\fIcellscape\fP) Honor seed argument in LXC container initializaton +@ \fI2015\-05\-04T20:58:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23311\fP: (\fIcellscape\fP) Fix new container initialization in LXC runner +| refs: \fI\%#23318\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +ba7605d Merge pull request \fI\%#23318\fP from cellscape/honor\-seed\-argument +.IP \(bu 2 +228b1be Honor seed argument in LXC container initializaton +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23307\fP: (\fIjfindlay\fP) check for /etc/locale.gen +@ \fI2015\-05\-04T20:56:32Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#17245\fP: (\fItomashavlas\fP) localemod does not generate locale for Arch +| refs: \fI\%#23307\fP \fI\%#23397\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +4ac4509 Merge pull request \fI\%#23307\fP from jfindlay/fix_locale_gen +.IP \(bu 2 +101199a check for /etc/locale.gen +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23324\fP: (\fIs0undt3ch\fP) [2014.7] Update to the latest stable release of the bootstrap script v2015.05.04 +@ \fI2015\-05\-04T16:28:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#580\fP: (\fIthatch45\fP) recursive watch not being caught +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#552\fP: (\fIjhutchins\fP) Support require and watch under the same state dec +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#589\fP: (\fIepoelke\fP) add \-\-quiet and \-\-outfile options to saltkey +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#567\fP: (\fIbastichelaar\fP) Added upstart module +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#560\fP: (\fIUtahDave\fP) The runas feature that was added in 93423aa2e5e4b7de6452090b0039560d2b13... +| refs: \fI\%#23324\fP +.IP \(bu 2 +\fBPR\fP \fI\%#504\fP: (\fISEJeff\fP) File state goodies +| refs: \fI\%#23324\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f790f42 Merge pull request \fI\%#23324\fP from s0undt3ch/hotfix/bootstrap\-script\-2014.7 +.IP \(bu 2 +6643e47 Update to the latest stable release of the bootstrap script v2015.05.04 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23329\fP: (\fIcro\fP) Require requests to verify cert when talking to aliyun and proxmox cloud providers +@ \fI2015\-05\-04T16:18:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +5487367 Merge pull request \fI\%#23329\fP from cro/cloud_verify_cert +.IP \(bu 2 +860d4b7 Turn on ssl verify for requests. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23311\fP: (\fIcellscape\fP) Fix new container initialization in LXC runner +| refs: \fI\%#23318\fP +@ \fI2015\-05\-04T09:55:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +ea20176 Merge pull request \fI\%#23311\fP from cellscape/fix\-salt\-cloud\-lxc\-init +.IP \(bu 2 +76fbb34 Fix new container initialization in LXC runner +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23298\fP: (\fIchris\-prince\fP) Fixed issue \fI\%#18880\fP in 2014.7 branch +@ \fI2015\-05\-03T15:49:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#18880\fP: (\fIjohtso\fP) npm installed breaks when a module is missing +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c399b8f Merge pull request \fI\%#23298\fP from chris\-prince/2014.7 +.IP \(bu 2 +0fa25db Fixed issue \fI\%#18880\fP in 2014.7 branch +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23292\fP: (\fIrallytime\fP) Merge \fI\%#23151\fP with pylint fixes +@ \fI2015\-05\-02T03:54:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23148\fP: (\fIcr1st1p\fP) virt \- error handling bogus if machine image location is wrong +.IP \(bu 2 +\fBPR\fP \fI\%#23151\fP: (\fIcr1st1p\fP) Fixes \fI\%#23148\fP +| refs: \fI\%#23292\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +16ecefd Merge pull request \fI\%#23292\fP from rallytime/merge\-23151 +.IP \(bu 2 +8ff852a Merge \fI\%#23151\fP with pylint fixes +.IP \(bu 2 +8ffa12e Fixes \fI\%#23148\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23274\fP: (\fIbasepi\fP) [2014.7] Reduce salt\-ssh debug log verbosity +@ \fI2015\-05\-01T20:19:23Z\fP +.INDENT 2.0 +.IP \(bu 2 +ce24315 Merge pull request \fI\%#23274\fP from basepi/salt\-ssh.debug.verbosity +.IP \(bu 2 +ecee6c6 Log stdout and stderr to trace +.IP \(bu 2 +08f54d7 Log stdout and stderr to trace as well +.IP \(bu 2 +9b9c30f Reduce salt\-ssh debug log verbosity +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23261\fP: (\fIrallytime\fP) Fix tornado websocket event handler registration +@ \fI2015\-05\-01T18:20:31Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22605\fP: (\fImavenAtHouzz\fP) Tornado websockets event Handlers registration are incorrect +| refs: \fI\%#23261\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +7b55e43 Merge pull request \fI\%#23261\fP from rallytime/\fI\%fix\-22605\fP +.IP \(bu 2 +4950fbf Fix tornado websocket event handler registration +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23258\fP: (\fIteizz\fP) TCP keepalives on the ret side, Revisited. +@ \fI2015\-05\-01T16:13:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +83ef7cb Merge pull request \fI\%#23258\fP from teizz/ret_keepalive_2014_7_5 +.IP \(bu 2 +0b9fb6f The fixes by cachedout which were backported into 2015_2 were missing a single parameter thus not setting up the TCP keepalive for the ZeroMQ Channel by default. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23241\fP: (\fItechhat\fP) Move iptables log options after the jump +@ \fI2015\-05\-01T01:31:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23224\fP: (\fItwellspring\fP) iptables.append \-\-log parameters must be after \-\-jump LOG +| refs: \fI\%#23241\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8de3c83 Merge pull request \fI\%#23241\fP from techhat/issue23224 +.IP \(bu 2 +87f7948 Move iptables log options after the jump +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23228\fP: (\fIrallytime\fP) Backport \fI\%#23171\fP to 2014.7 +@ \fI2015\-04\-30T21:09:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23171\fP: (\fIskizunov\fP) Bugfix: \(aqclean_proc_dir\(aq is broken +| refs: \fI\%#23228\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f20210e Merge pull request \fI\%#23228\fP from rallytime/\fI\%bp\-23171\fP +.IP \(bu 2 +e670e99 Bugfix: \(aqclean_proc_dir\(aq is broken +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23227\fP: (\fIrallytime\fP) Backport \fI\%#22808\fP to 2014.7 +@ \fI2015\-04\-30T21:09:14Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22703\fP: (\fIXiol\fP) salt\-ssh does not work with list matcher +| refs: \fI\%#22808\fP +.IP \(bu 2 +\fBPR\fP \fI\%#22808\fP: (\fIbasepi\fP) [2015.2] Add list targeting to salt\-ssh flat roster +| refs: \fI\%#23227\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +721cc28 Merge pull request \fI\%#23227\fP from rallytime/\fI\%bp\-22808\fP +.IP \(bu 2 +d208a00 Dict, not list +.IP \(bu 2 +a3f529e It\(aqs already been converted to a list +.IP \(bu 2 +dd57f2d Add list targeting to salt\-ssh flat roster +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22823\fP: (\fIhvnsweeting\fP) 22822 file directory clean +@ \fI2015\-04\-30T15:25:51Z\fP +.INDENT 2.0 +.IP \(bu 2 +82c22af Merge pull request \fI\%#22823\fP from hvnsweeting/22822\-file\-directory\-clean +.IP \(bu 2 +c749c27 fix lint \- remove unnecessary parenthesis +.IP \(bu 2 +cb3dfee refactor +.IP \(bu 2 +8924b5a refactor: use relpath instead of do it manually +.IP \(bu 2 +d3060a5 refactor +.IP \(bu 2 +5759a0e bugfix: fix file.directory clean=True when it require parent dir +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22977\fP: (\fIbersace\fP) Fix fileserver backends __opts__ overwritten by _pillar +@ \fI2015\-04\-30T15:24:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22941\fP: (\fIbersace\fP) \fI_pillar\fP func breaks fileserver globals +| refs: \fI\%#22977\fP \fI\%#22942\fP +.IP \(bu 2 +\fBPR\fP \fI\%#22942\fP: (\fIbersace\fP) Fix fileserver backends global overwritten by _pillar +| refs: \fI\%#22977\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +f6c0728 Merge pull request \fI\%#22977\fP from bersace/fix\-fileserver\-backends\-pillar\-side\-effect +.IP \(bu 2 +5f451f6 Fix fileserver backends __opts__ overwritten by _pillar +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23180\fP: (\fIjfindlay\fP) fix typos from 36841bdd in masterapi.py +@ \fI2015\-04\-30T15:22:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23166\fP: (\fIclaudiupopescu\fP) "Error in function _minion_event" resulting in modules not loaded +| refs: \fI\%#23180\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +34206f7 Merge pull request \fI\%#23180\fP from jfindlay/remote_event +.IP \(bu 2 +72066e1 fix typos from 36841bdd in masterapi.py +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23176\fP: (\fIjfindlay\fP) copy standard cmd.run* kwargs into cmd.run_chroot +@ \fI2015\-04\-30T15:22:12Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23153\fP: (\fIcr1st1p\fP) cmdmod : run_chroot \- broken in 2014.7.5 \- missing kwargs +| refs: \fI\%#23176\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b6b8216 Merge pull request \fI\%#23176\fP from jfindlay/run_chroot +.IP \(bu 2 +7dc3417 copy standard cmd.run* kwargs into cmd.run_chroot +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23193\fP: (\fIjoejulian\fP) supervisord.mod_watch should accept sfun +@ \fI2015\-04\-30T04:34:21Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23192\fP: (\fIjoejulian\fP) supervisord mod_watch does not accept sfun +| refs: \fI\%#23193\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +effacbe Merge pull request \fI\%#23193\fP from joejulian/2014.7_supervisord_accept_sfun +.IP \(bu 2 +efb59f9 supervisord.mod_watch should accept sfun +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23188\fP: (\fIbasepi\fP) [2014.7] Work around bug in salt\-ssh in config.get for gpg renderer +| refs: \fI\%#23272\fP +@ \fI2015\-04\-30T04:34:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#19114\fP: (\fIpykler\fP) salt\-ssh and gpg pillar renderer +| refs: \fI\%#23188\fP \fI\%#23272\fP \fI\%#23347\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +72fe88e Merge pull request \fI\%#23188\fP from basepi/salt\-ssh.function.wrapper.gpg.19114 +.IP \(bu 2 +d73979e Work around bug in salt\-ssh in config.get for gpg renderer +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23154\fP: (\fIcachedout\fP) Re\-establish channel on interruption in fileclient +@ \fI2015\-04\-29T16:18:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#21480\fP: (\fImsciciel\fP) TypeError: string indices must be integers, not str +| refs: \fI\%#23154\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +168508e Merge pull request \fI\%#23154\fP from cachedout/refresh_channel +.IP \(bu 2 +9f8dd80 Re\-establish channel on interruption in fileclient +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23146\fP: (\fIrallytime\fP) Backport \fI\%#20779\fP to 2014.7 +@ \fI2015\-04\-28T20:45:06Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#20647\fP: (\fIryan\-lane\fP) file.serialize fails to serialize due to ordered dicts +| refs: \fI\%#20779\fP +.IP \(bu 2 +\fBPR\fP \fI\%#20779\fP: (\fIcachedout\fP) Use declared yaml options +| refs: \fI\%#23146\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3b53e04 Merge pull request \fI\%#23146\fP from rallytime/\fI\%bp\-20779\fP +.IP \(bu 2 +ffd1849 compare OrderedDicts in serializer unit test +.IP \(bu 2 +a221706 Just change serialize +.IP \(bu 2 +a111798 Use declared yaml options +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23145\fP: (\fIrallytime\fP) Backport \fI\%#23089\fP to 2014.7 +@ \fI2015\-04\-28T20:44:56Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#23089\fP: (\fIcachedout\fP) Stringify version number before lstrip +| refs: \fI\%#23145\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +8bb4664 Merge pull request \fI\%#23145\fP from rallytime/\fI\%bp\-23089\fP +.IP \(bu 2 +93c41af Stringify version number before lstrip +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23144\fP: (\fIrallytime\fP) Backport \fI\%#23124\fP to 2014.7 +@ \fI2015\-04\-28T20:44:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#16188\fP: (\fIdrawks\fP) salt.modules.parted has various functions with bogus input validation. +| refs: \fI\%#23124\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23124\fP: (\fIether42\fP) fix parsing the output of parted in parted.list_() +| refs: \fI\%#23144\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c85d36f Merge pull request \fI\%#23144\fP from rallytime/\fI\%bp\-23124\fP\-2014\-7 +.IP \(bu 2 +6b64da7 fix parsing the output of parted +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23120\fP: (\fIterminalmage\fP) Don\(aqt run os.path.relpath() if repo doesn\(aqt have a "root" param set +@ \fI2015\-04\-28T15:46:54Z\fP +.INDENT 2.0 +.IP \(bu 2 +a27b158 Merge pull request \fI\%#23120\fP from terminalmage/fix\-gitfs\-relpath +.IP \(bu 2 +1860fff Don\(aqt run os.path.relpath() if repo doesn\(aqt have a "root" param set +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23132\fP: (\fIclinta\fP) Backport b27c176 +@ \fI2015\-04\-28T15:00:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +fcba607 Merge pull request \fI\%#23132\fP from clinta/patch\-2 +.IP \(bu 2 +a824d72 Backport b27c176 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23114\fP: (\fIrallytime\fP) Adjust ZeroMQ 4 docs to reflect changes to Ubuntu 12 packages +@ \fI2015\-04\-28T03:59:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#18476\fP: (\fIAuha\fP) Upgrading salt on my master caused dependency issues +| refs: \fI\%#23114\fP \fI\%#18610\fP +.IP \(bu 2 +\fBPR\fP \fI\%#18610\fP: (\fIrallytime\fP) Make ZMQ 4 installation docs for ubuntu more clear +| refs: \fI\%#23114\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b0f4b28 Merge pull request \fI\%#23114\fP from rallytime/remove_ubuntu_zmq4_docs +.IP \(bu 2 +f6cc7c8 Adjust ZeroMQ 4 docs to reflect changes to Ubuntu 12 packages +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23108\fP: (\fIrallytime\fP) Backport \fI\%#23097\fP to 2014.7 +@ \fI2015\-04\-28T03:58:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23085\fP: (\fIxenophonf\fP) Use "s3fs" (not "s3") in fileserver_roots +| refs: \fI\%#23097\fP +.IP \(bu 2 +\fBPR\fP \fI\%#23097\fP: (\fIrallytime\fP) Change s3 to s3fs in fileserver_roots docs example +| refs: \fI\%#23108\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +399857f Merge pull request \fI\%#23108\fP from rallytime/\fI\%bp\-23097\fP +.IP \(bu 2 +fa88984 Change s3 to s3fs in fileserver_roots docs example +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23112\fP: (\fIbasepi\fP) [2014.7] Backport \fI\%#22199\fP to fix mysql returner save_load errors +@ \fI2015\-04\-28T03:55:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22171\fP: (\fIbasepi\fP) We should only call returner.save_load once per jid +| refs: \fI\%#22199\fP +.IP \(bu 2 +\fBPR\fP \fI\%#22199\fP: (\fIbasepi\fP) [2015.2] Put a bandaid on the save_load duplicate issue (mysql returner) +| refs: \fI\%#23112\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +5541537 Merge pull request \fI\%#23112\fP from basepi/mysql_returner_save_load +.IP \(bu 2 +0127012 Put a bandaid on the save_load duplicate issue +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23113\fP: (\fIrallytime\fP) Revert "Backport \fI\%#22895\fP to 2014.7" +@ \fI2015\-04\-28T03:27:29Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#22925\fP: (\fIrallytime\fP) Backport \fI\%#22895\fP to 2014.7 +| refs: \fI\%#23113\fP +.IP \(bu 2 +\fBPR\fP \fI\%#22895\fP: (\fIaletourneau\fP) pam_tally counter was not reset to 0 after a succesfull login +| refs: \fI\%#22925\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +dfe2066 Merge pull request \fI\%#23113\fP from saltstack/revert\-22925\-\fI\%bp\-22895\fP +.IP \(bu 2 +b957ea8 Revert "Backport \fI\%#22895\fP to 2014.7" +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23094\fP: (\fIterminalmage\fP) pygit2: disable cleaning of stale refs for authenticated remotes +@ \fI2015\-04\-27T20:51:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23013\fP: (\fImarkusr815\fP) gitfs regression with authenticated repos +| refs: \fI\%#23094\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +21515f3 Merge pull request \fI\%#23094\fP from terminalmage/issue23013 +.IP \(bu 2 +aaf7b04 pygit2: disable cleaning of stale refs for authenticated remotes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23048\fP: (\fIjfindlay\fP) py\-2.6 compat for utils/boto.py ElementTree exception +@ \fI2015\-04\-25T16:56:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +d45aa21 Merge pull request \fI\%#23048\fP from jfindlay/ET_error +.IP \(bu 2 +64c42cc py\-2.6 compat for utils/boto.py ElementTree exception +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23025\fP: (\fIjfindlay\fP) catch exceptions on bad system locales/encodings +@ \fI2015\-04\-25T16:56:30Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22981\fP: (\fIsyphernl\fP) Locale state throwing traceback when generating not (yet) existing locale +| refs: \fI\%#23025\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +d25a5c1 Merge pull request \fI\%#23025\fP from jfindlay/fix_sys_locale +.IP \(bu 2 +9c4d62b catch exceptions on bad system locales/encodings +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22932\fP: (\fIhvnsweeting\fP) bugfix: also manipulate dir_mode when source not defined +@ \fI2015\-04\-25T16:54:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +5e44b59 Merge pull request \fI\%#22932\fP from hvnsweeting/file\-append\-bugfix +.IP \(bu 2 +3f368de do not use assert in execution module +.IP \(bu 2 +9d4fd4a bugfix: also manipulate dir_mode when source not defined +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23055\fP: (\fIjfindlay\fP) prevent ps module errors on accessing dead procs +@ \fI2015\-04\-24T22:39:49Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#23021\fP: (\fIether42\fP) ps.pgrep raises NoSuchProcess +| refs: \fI\%#23055\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c2416a4 Merge pull request \fI\%#23055\fP from jfindlay/fix_ps +.IP \(bu 2 +c2dc7ad prevent ps module errors on accessing dead procs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23031\fP: (\fIjfindlay\fP) convert exception e.message to just e +@ \fI2015\-04\-24T18:38:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +bfd9158 Merge pull request \fI\%#23031\fP from jfindlay/exception +.IP \(bu 2 +856bad1 convert exception e.message to just e +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23015\fP: (\fIhvnsweeting\fP) if status of service is stop, there is not an error with it +@ \fI2015\-04\-24T14:35:10Z\fP +.INDENT 2.0 +.IP \(bu 2 +7747f33 Merge pull request \fI\%#23015\fP from hvnsweeting/set\-non\-error\-lvl\-for\-service\-status\-log +.IP \(bu 2 +92ea163 if status of service is stop, there is not an error with it +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#23000\fP: (\fIjfindlay\fP) set systemd service killMode to process for minion +@ \fI2015\-04\-24T03:42:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22993\fP: (\fIjetpak\fP) salt\-minion restart causes all spawned daemons to die on centos7 (systemd) +| refs: \fI\%#23000\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2e09789 Merge pull request \fI\%#23000\fP from jfindlay/systemd_kill +.IP \(bu 2 +3d575e2 set systemd service killMode to process for minion +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22999\fP: (\fIjtand\fP) Added retry_dns to minion doc. +@ \fI2015\-04\-24T03:30:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22707\fP: (\fIarthurlogilab\fP) retry_dns of master configuration is missing from the documentation +| refs: \fI\%#22999\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b5c059a Merge pull request \fI\%#22999\fP from jtand/fix_22707 +.IP \(bu 2 +8486e17 Added retry_dns to minion doc. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22990\fP: (\fItechhat\fP) Use the proper cloud conf variable +@ \fI2015\-04\-23T17:48:07Z\fP +.INDENT 2.0 +.IP \(bu 2 +27dc877 Merge pull request \fI\%#22990\fP from techhat/2014.7 +.IP \(bu 2 +d33bcbc Use the proper cloud conf variable +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22976\fP: (\fImultani\fP) Improve state_output documentation +@ \fI2015\-04\-23T12:24:22Z\fP +.INDENT 2.0 +.IP \(bu 2 +13dff65 Merge pull request \fI\%#22976\fP from multani/fix/state\-output\-doc +.IP \(bu 2 +19efd41 Improve state_output documentation +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22955\fP: (\fIterminalmage\fP) Fix regression introduced yesterday in dockerio module +@ \fI2015\-04\-22T18:56:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +89fa185 Merge pull request \fI\%#22955\fP from terminalmage/dockerio\-run\-fix +.IP \(bu 2 +b4472ad Fix regression introduced yesterday in dockerio module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22954\fP: (\fIrallytime\fP) Backport \fI\%#22909\fP to 2014.7 +@ \fI2015\-04\-22T18:56:20Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#22909\fP: (\fImguegan\fP) Fix compatibility with pkgin > 0.7 +| refs: \fI\%#22954\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +46ef227 Merge pull request \fI\%#22954\fP from rallytime/\fI\%bp\-22909\fP +.IP \(bu 2 +70c1cd3 Fix compatibility with pkgin > 0.7 +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22856\fP: (\fIjfindlay\fP) increase timeout and decrease tries for route53 records +@ \fI2015\-04\-22T16:47:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#18720\fP: (\fIReiner030\fP) timeouts when setting Route53 records +| refs: \fI\%#22856\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c9ae593 Merge pull request \fI\%#22856\fP from jfindlay/route53_timeout +.IP \(bu 2 +ba4a786 add route53 record sync wait, default=False +.IP \(bu 2 +ea2fd50 increase timeout and tries for route53 records +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22946\fP: (\fIs0undt3ch\fP) Test with a more recent pip version to avoid a traceback +@ \fI2015\-04\-22T16:25:17Z\fP +.INDENT 2.0 +.IP \(bu 2 +a178d44 Merge pull request \fI\%#22946\fP from s0undt3ch/2014.7 +.IP \(bu 2 +bc87749 Test with a more recent pip version to avoid a traceback +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22945\fP: (\fIgarethgreenaway\fP) Fixes to scheduler +@ \fI2015\-04\-22T16:25:00Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22571\fP: (\fIBoomerB\fP) same error message as on issue \fI\%#18504\fP +| refs: \fI\%#22945\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +de339be Merge pull request \fI\%#22945\fP from garethgreenaway/22571_2014_7_schedule_pillar_refresh_seconds_exceptions +.IP \(bu 2 +bfa6d25 Fixing a reported issue when using a scheduled job from pillar with splay. _seconds element that acted as a backup of the actual seconds was being removed when pillar was refreshed and causing exceptions. This fix moves some splay related code out of the if else condition so it\(aqs checked whether the job is in the job queue or not. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22887\fP: (\fIhvnsweeting\fP) fix \fI\%#18843\fP +@ \fI2015\-04\-22T15:47:05Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#18843\fP: (\fIcalvinhp\fP) State user.present will fail to create home if user exists and homedir doesn\(aqt +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +12d2b91 Merge pull request \fI\%#22887\fP from hvnsweeting/18843\-fix\-user\-present\-home +.IP \(bu 2 +7fe7b08 run user.chhome once to avoid any side\-effect when run it twice +.IP \(bu 2 +19de995 clarify the usage of home arg +.IP \(bu 2 +d6dc09a enhance doc, as usermod on ubuntu 12.04 will not CREATE home +.IP \(bu 2 +0ce4d7f refactor: force to use boolean +.IP \(bu 2 +849d19e log debug the creating dir process +.IP \(bu 2 +c4e95b9 fix \fI\%#18843\fP: usermod won\(aqt create a dir if old home does not exist +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22930\fP: (\fIjfindlay\fP) localemod.gen_locale now always returns a boolean +@ \fI2015\-04\-22T15:37:39Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#21140\fP: (\fIholms\fP) locale.present state executed successfully, although originally fails +| refs: \fI\%#22930\fP \fI\%#22829\fP +.IP \(bu 2 +\fBISSUE\fP \fI\%#2417\fP: (\fIffa\fP) Module standards +| refs: \fI\%#22829\fP +.IP \(bu 2 +\fBPR\fP \fI\%#22829\fP: (\fIF30\fP) Always return a boolean in gen_locale() +| refs: \fI\%#22930\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +b7de7bd Merge pull request \fI\%#22930\fP from jfindlay/localegen_bool +.IP \(bu 2 +399399f localemod.gen_locale now always returns a boolean +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22933\fP: (\fIhvnsweeting\fP) add test for \fI\%#18843\fP +@ \fI2015\-04\-22T15:27:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#18843\fP: (\fIcalvinhp\fP) State user.present will fail to create home if user exists and homedir doesn\(aqt +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +11bcf14 Merge pull request \fI\%#22933\fP from hvnsweeting/18843\-test +.IP \(bu 2 +b13db32 add test for \fI\%#18843\fP +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22925\fP: (\fIrallytime\fP) Backport \fI\%#22895\fP to 2014.7 +| refs: \fI\%#23113\fP +@ \fI2015\-04\-22T02:30:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#22895\fP: (\fIaletourneau\fP) pam_tally counter was not reset to 0 after a succesfull login +| refs: \fI\%#22925\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +6890752 Merge pull request \fI\%#22925\fP from rallytime/\fI\%bp\-22895\fP +.IP \(bu 2 +3852d96 Pylint fix +.IP \(bu 2 +90f7829 Fixed pylint issues +.IP \(bu 2 +5ebf159 Cleaned up pull request +.IP \(bu 2 +a08ac47 pam_tally counter was not reset to 0 after a succesfull login +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22914\fP: (\fIcachedout\fP) Call proper returner function in jobs.list_jobs +@ \fI2015\-04\-22T00:49:01Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22790\fP: (\fIwhiteinge\fP) jobs.list_jobs runner tracebacks on \(aqmissing\(aq argument +| refs: \fI\%#22914\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +eca37eb Merge pull request \fI\%#22914\fP from cachedout/issue_22790 +.IP \(bu 2 +d828d6f Call proper returner function in jobs.list_jobs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22918\fP: (\fIJaseFace\fP) Add a note to the git_pillar docs stating that GitPython is the only currently supported provider +@ \fI2015\-04\-22T00:48:26Z\fP +.INDENT 2.0 +.IP \(bu 2 +44f3409 Merge pull request \fI\%#22918\fP from JaseFace/git\-pillar\-provider\-doc\-note +.IP \(bu 2 +0aee5c2 Add a note to the git_pillar docs stating that GitPython is the only currently supported provider +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22907\fP: (\fItechhat\fP) Properly merge cloud configs to create profiles +@ \fI2015\-04\-21T22:02:44Z\fP +.INDENT 2.0 +.IP \(bu 2 +31c461f Merge pull request \fI\%#22907\fP from techhat/cloudconfig +.IP \(bu 2 +3bf4e66 Properly merge cloud configs to create profiles +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22894\fP: (\fI0xf10e\fP) Fix issue \fI\%#22782\fP +@ \fI2015\-04\-21T18:55:18Z\fP +.INDENT 2.0 +.IP \(bu 2 +f093975 Merge pull request \fI\%#22894\fP from 0xf10e/2014.7 +.IP \(bu 2 +58fa24c Clarify doc on kwarg \(aqroles\(aq for user_present(). +.IP \(bu 2 +f0ae2eb Improve readability by renaming tenant_role +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22902\fP: (\fIrallytime\fP) Change state example to use proper kwarg +@ \fI2015\-04\-21T18:50:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#12003\fP: (\fIMarkusMuellerAU\fP) [state.dockerio] docker.run TypeError: run() argument after ** must be a mapping, not str +| refs: \fI\%#22902\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +c802ba7 Merge pull request \fI\%#22902\fP from rallytime/docker_doc_fix +.IP \(bu 2 +8f70346 Change state example to use proper kwarg +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22898\fP: (\fIterminalmage\fP) dockerio: better error message for native exec driver +@ \fI2015\-04\-21T18:02:58Z\fP +.INDENT 2.0 +.IP \(bu 2 +81771a7 Merge pull request \fI\%#22898\fP from terminalmage/issue12003 +.IP \(bu 2 +c375309 dockerio: better error message for native exec driver +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22897\fP: (\fIrallytime\fP) Add param documentation for file.replace state +@ \fI2015\-04\-21T17:31:04Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22825\fP: (\fIpaolodina\fP) Issue using file.replace in state file +| refs: \fI\%#22897\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +e2ec4ec Merge pull request \fI\%#22897\fP from rallytime/\fI\%fix\-22825\fP +.IP \(bu 2 +9c51630 Add param documentation for file.replace state +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22850\fP: (\fIbersace\fP) Fix pillar and salt fileserver mixed +@ \fI2015\-04\-21T17:04:33Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22844\fP: (\fIbersace\fP) LocalClient file cache confuse pillar and state files +| refs: \fI\%#22850\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fd53889 Merge pull request \fI\%#22850\fP from bersace/fix\-pillar\-salt\-mixed +.IP \(bu 2 +31b98e7 Initialize state file client after pillar loading +.IP \(bu 2 +f6bebb7 Use saltenv +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22818\fP: (\fItwangboy\fP) Added documentation regarding pip in windows +@ \fI2015\-04\-21T03:58:59Z\fP +.INDENT 2.0 +.IP \(bu 2 +1380fec Merge pull request \fI\%#22818\fP from twangboy/upd_pip_docs +.IP \(bu 2 +cb999c7 Update pip.py +.IP \(bu 2 +3cc5c97 Added documentation regarding pip in windows +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22872\fP: (\fIrallytime\fP) Prevent stacktrace on os.path.exists in hosts module +@ \fI2015\-04\-21T02:54:40Z\fP +.INDENT 2.0 +.IP \(bu 2 +b2bf17f Merge pull request \fI\%#22872\fP from rallytime/fix_hosts_stacktrace +.IP \(bu 2 +c88a1ea Prevent stacktrace on os.path.exists in hosts module +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22853\fP: (\fIs0undt3ch\fP) Don\(aqt assume package installation order. +@ \fI2015\-04\-21T02:42:41Z\fP +.INDENT 2.0 +.IP \(bu 2 +03af523 Merge pull request \fI\%#22853\fP from s0undt3ch/2014.7 +.IP \(bu 2 +b62df62 Don\(aqt assume package installation order. +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22877\fP: (\fIs0undt3ch\fP) Don\(aqt fail on \fImake clean\fP just because the directory does not exist +@ \fI2015\-04\-21T02:40:47Z\fP +.INDENT 2.0 +.IP \(bu 2 +9211e36 Merge pull request \fI\%#22877\fP from s0undt3ch/hotfix/clean\-docs\-fix +.IP \(bu 2 +95d6887 Don\(aqt fail on \fImake clean\fP just because the directory does not exist +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22873\fP: (\fIthatch45\fP) Type check the version since it will often be numeric +@ \fI2015\-04\-21T02:38:11Z\fP +.INDENT 2.0 +.IP \(bu 2 +5bdbd08 Merge pull request \fI\%#22873\fP from thatch45/type_check +.IP \(bu 2 +53b8376 Type check the version since it will often be numeric +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22870\fP: (\fItwangboy\fP) Added ability to send a version with a space in it +@ \fI2015\-04\-20T23:18:28Z\fP +.INDENT 2.0 +.IP \(bu 2 +c965b0a Merge pull request \fI\%#22870\fP from twangboy/fix_installer_again +.IP \(bu 2 +3f180cf Added ability to send a version with a space in it +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22863\fP: (\fIrallytime\fP) Backport \fI\%#20974\fP to 2014.7 +@ \fI2015\-04\-20T19:29:37Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBPR\fP \fI\%#20974\fP: (\fIJohannesEbke\fP) Fix expr_match usage in salt.utils.check_whitelist_blacklist +| refs: \fI\%#22863\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +2973eb1 Merge pull request \fI\%#22863\fP from rallytime/\fI\%bp\-20974\fP +.IP \(bu 2 +14913a4 Fix expr_match usage in salt.utils.check_whitelist_blacklist +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22578\fP: (\fIhvnsweeting\fP) gracefully handle when salt\-minion cannot decrypt key +@ \fI2015\-04\-20T15:24:45Z\fP +.INDENT 2.0 +.IP \(bu 2 +c45b92b Merge pull request \fI\%#22578\fP from hvnsweeting/2014\-7\-fix\-compile\-pillar +.IP \(bu 2 +f75b24a gracefully handle when salt\-minion cannot decrypt key +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22800\fP: (\fIterminalmage\fP) Improve error logging for pygit2 SSH\-based remotes +@ \fI2015\-04\-18T17:18:55Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#21979\fP: (\fIyrdevops\fP) gitfs: error message not descriptive enough when libgit2 was compiled without libssh2 +| refs: \fI\%#22800\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +900c7a5 Merge pull request \fI\%#22800\fP from terminalmage/issue21979 +.IP \(bu 2 +8f1c008 Clarify that for pygit2, receiving 0 objects means repo is up\-to\-date +.IP \(bu 2 +98885f7 Add information about libssh2 requirement for pygit2 ssh auth +.IP \(bu 2 +09468d2 Fix incorrect log message +.IP \(bu 2 +2093bf8 Adjust loglevels for gitfs errors +.IP \(bu 2 +9d394df Improve error logging for pygit2 SSH\-based remotes +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22813\fP: (\fItwangboy\fP) Updated instructions for building salt +@ \fI2015\-04\-18T04:10:07Z\fP +.INDENT 2.0 +.IP \(bu 2 +e99f2fd Merge pull request \fI\%#22813\fP from twangboy/win_doc_fix +.IP \(bu 2 +adc421a Fixed some formatting issues +.IP \(bu 2 +8901b3b Updated instructions for building salt +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22810\fP: (\fIbasepi\fP) [2014.7] More msgpack gating for salt\-ssh +@ \fI2015\-04\-17T22:28:24Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22708\fP: (\fIBilge\fP) salt\-ssh file.accumulated error: NameError: global name \(aqmsgpack\(aq is not defined +| refs: \fI\%#22810\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +fe1de89 Merge pull request \fI\%#22810\fP from basepi/salt\-ssh.more.msgpack.gating +.IP \(bu 2 +d4da8e6 Gate msgpack in salt/modules/saltutil.py +.IP \(bu 2 +02303b2 Gate msgpack in salt/modules/data.py +.IP \(bu 2 +d7e8741 Gate salt.states.file.py msgpack +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22803\fP: (\fIrallytime\fP) Allow map file to work with softlayer +@ \fI2015\-04\-17T20:34:42Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#17144\fP: (\fIxpender\fP) salt\-cloud \-m fails with softlayer +| refs: \fI\%#22803\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +11df71e Merge pull request \fI\%#22803\fP from rallytime/\fI\%fix\-17144\fP +.IP \(bu 2 +ce88b6a Allow map file to work with softlayer +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22807\fP: (\fIrallytime\fP) Add 2014.7.5 links to windows installation docs +@ \fI2015\-04\-17T20:32:13Z\fP +.INDENT 2.0 +.IP \(bu 2 +cd43a95 Merge pull request \fI\%#22807\fP from rallytime/windows_docs_update +.IP \(bu 2 +5931a58 Replace all 4s with 5s +.IP \(bu 2 +eadaead Add 2014.7.5 links to windows installation docs +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22795\fP: (\fIrallytime\fP) Added release note for 2014.7.5 release +@ \fI2015\-04\-17T18:05:36Z\fP +.INDENT 2.0 +.IP \(bu 2 +0b295e2 Merge pull request \fI\%#22795\fP from rallytime/release_notes +.IP \(bu 2 +fde1fee Remove extra line +.IP \(bu 2 +b19b95d Added release note for 2014.7.5 release +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22759\fP: (\fItwangboy\fP) Final edits to the batch files for running salt +@ \fI2015\-04\-17T04:31:15Z\fP +.INDENT 2.0 +.IP \(bu 2 +\fBISSUE\fP \fI\%#22740\fP: (\fIlorengordon\fP) New Windows installer assumes salt is installed to the current directory +| refs: \fI\%#22759\fP +.IP \(bu 2 +\fBPR\fP \fI\%#22754\fP: (\fItwangboy\fP) Removed redundant \e and " +| refs: \fI\%#22759\fP +.UNINDENT +.INDENT 2.0 +.IP \(bu 2 +3c91459 Merge pull request \fI\%#22759\fP from twangboy/fix_bat_one_last_time +.IP \(bu 2 +075f82e Final edits to the batch files for running salt +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22760\fP: (\fIthatch45\fP) Fix issues with the syndic +@ \fI2015\-04\-17T04:30:48Z\fP +.INDENT 2.0 +.IP \(bu 2 +20d3f2b Merge pull request \fI\%#22760\fP from thatch45/syndic_fix +.IP \(bu 2 +e2db624 Fix issues with the syndic not resolving the master when the interface is set +.UNINDENT +.IP \(bu 2 +\fBPR\fP \fI\%#22762\fP: (\fItwangboy\fP) Fixed version not showing in Add/Remove Programs +@ \fI2015\-04\-17T04:29:46Z\fP +.INDENT 2.0 +.IP \(bu 2 +54c4584 Merge pull request \fI\%#22762\fP from twangboy/fix_installer +.IP \(bu 2 +4d25af8 Fixed version not showing in Add/Remove Programs +.UNINDENT +.UNINDENT .SS Salt 2014.1.0 Release Notes \- Codename Hydrogen .sp \fBNOTE:\fP @@ -170012,7 +185204,7 @@ Here s the md5sum: .sp 7d5aca4633bc22f59045f59e82f43b56 .sp -For instructions on how to set up Salt please see the installation +For instructions on how to set up Salt please see the \fIinstallation\fP instructions. .SS New Features .SS Salt Run @@ -170120,12 +185312,12 @@ Here is the md5sum: .sp 9a925da04981e65a0f237f2e77ddab37 .sp -For instructions on how to set up Salt please see the installation +For instructions on how to set up Salt please see the \fIinstallation\fP instructions. .SS New Features .SS Salt Syndic .sp -The new Syndic interface allows a master to be +The new \fISyndic interface\fP allows a master to be commanded via another higher level salt master. This is a powerful solution allowing a master control structure to exist, allowing salt to scale to much larger levels then before. @@ -170223,7 +185415,7 @@ Or from PyPI: .sp \fI\%https://pypi.python.org/packages/source/s/salt/salt\-0.9.2.tar.gz\fP .sp -For instructions on how to set up Salt please see the installation +For instructions on how to set up Salt please see the \fIinstallation\fP instructions. .SS New Features .SS Salt\-Call Additions @@ -170295,7 +185487,7 @@ Or from PyPI: .sp \fI\%https://pypi.python.org/packages/source/s/salt/salt\-0.9.3.tar.gz\fP .sp -For instructions on how to set up Salt please see the installation +For instructions on how to set up Salt please see the \fIinstallation\fP instructions. .SS New Features .SS WAN Support @@ -170630,7 +185822,7 @@ Or from PyPI: .sp \fI\%https://pypi.python.org/packages/source/s/salt/salt\-0.9.4.tar.gz\fP .sp -For instructions on how to set up Salt please see the installation +For instructions on how to set up Salt please see the \fIinstallation\fP instructions. .SS New Features .SS Failhard State Option @@ -172410,7 +187602,7 @@ salt \-t 60 \(aq*\(aq test.ping If the Minion id is not configured explicitly (using the \fBid\fP parameter), Salt will determine the id based on the hostname. Exactly how this is determined varies a little between operating systems and is described in -detail here\&. +detail \fIhere\fP\&. .SS I\(aqm trying to manage packages/services but I get an error saying that the state is not available. Why? .sp Salt detects the Minion\(aqs operating system and assigns the correct package or @@ -172629,7 +187821,7 @@ for salt itself: .TP .B Auto\-Order The evaluation of states in the order that they are defined in a SLS -file. \fISee also\fP: ordering\&. +file. \fISee also\fP: \fIordering\fP\&. .TP .B Bootstrap A stand\-alone Salt project which can download and install a Salt master @@ -172637,34 +187829,34 @@ and/or a Salt minion onto a host. \fISee also\fP: \fI\%salt\-bootstrap\fP\&. .TP .B Compound Matcher A combination of many target definitions that can be combined with -boolean operators. \fISee also\fP: targeting\&. +boolean operators. \fISee also\fP: \fItargeting\fP\&. .TP .B EAuth Shorthand for \(aqexternal authentication\(aq. A system for calling to a system outside of Salt in order to authenticate users and determine if they are allowed to issue particular commands to Salt. \fISee also\fP: -external auth\&. +\fIexternal auth\fP\&. .TP .B Environment A directory tree containing state files which can be applied to -minions. \fISee also\fP: top file\&. +minions. \fISee also\fP: \fItop file\fP\&. .TP .B Execution Module A Python module that contains execution functions which directly perform various system\-management tasks on a server. Salt ships with a number of execution modules but users can also write their own -execution modules to perform specialized tasks. \fISee also\fP: the -list of execution modules\&. +execution modules to perform specialized tasks. \fISee also\fP: \fIthe +list of execution modules\fP\&. .TP .B Execution Function A Python function inside an Execution Module that may take arguments -and performs specific system\-management tasks. \fISee also\fP: the -list of execution modules\&. +and performs specific system\-management tasks. \fISee also\fP: \fIthe +list of execution modules\fP\&. .TP .B External Job Cache An external data\-store that can archive information about jobs that have been run. A default returner. \fISee also\fP: -\fBext_job_cache\fP, the list of returners\&. +\fBext_job_cache\fP, \fIthe list of returners\fP\&. .TP .B External Pillar A module that accepts arbitrary arguments and returns a dictionary. @@ -172673,17 +187865,17 @@ The dictionary is automatically added to a pillar for a minion. .B Event A notice emitted onto an event bus. Events are often driven by requests for actions to occur on a minion or master and the results of those -actions. \fISee also\fP: Salt Reactor\&. +actions. \fISee also\fP: \fISalt Reactor\fP\&. .TP .B File Server A local or remote location for storing both Salt\-specific files such as top files or SLS files as well as files that can be distributed to -minions, such as system configuration files. \fISee also\fP: Salt\(aqs -file server\&. +minions, such as system configuration files. \fISee also\fP: \fISalt\(aqs +file server\fP\&. .TP .B Grain A key\-value pair which contains a fact about a system, such as its -hostname, network addresses. \fISee also\fP: targeting with grains\&. +hostname, network addresses. \fISee also\fP: \fItargeting with grains\fP\&. .TP .B Halite The Salt GUI. \fISee also\fP: \fI\%Halite\fP\&. @@ -172702,15 +187894,15 @@ A unique identifier to represent a given \fI\%job\fP\&. .TP .B Highdata The data structure in a SLS file the represents a set of state -declarations. \fISee also\fP: state layers\&. +declarations. \fISee also\fP: \fIstate layers\fP\&. .TP .B Highstate The collection of states to be applied to a system. \fISee also\fP: -state layers\&. +\fIstate layers\fP\&. .TP .B Low State The collection of processed states after requisites and order are -evaluated. \fISee also\fP: state layers\&. +evaluated. \fISee also\fP: \fIstate layers\fP\&. .TP .B Master A central Salt daemon which from which commands can be issued to @@ -172727,7 +187919,7 @@ generate top file data. .B Mine A facility to collect arbitrary data from minions and store that data on the master. This data is then available to all other minions. -[Sometimes referred to as Salt Mine.] \fISee also\fP: Salt Mine\&. +[Sometimes referred to as Salt Mine.] \fISee also\fP: \fISalt Mine\fP\&. .TP .B Minion A server running a Salt minion daemon which can listen to commands from @@ -172744,26 +187936,26 @@ masters at the same time in high\-availability environments. .TP .B Node Group A pre\-defined group of minions declared in the master configuration -file. \fISee also\fP: targeting\&. +file. \fISee also\fP: \fItargeting\fP\&. .TP .B Outputter A formatter for defining the characteristics of output data from a Salt -command. \fISee also\fP: list of outputters\&. +command. \fISee also\fP: \fIlist of outputters\fP\&. .TP .B Overstate A system by which a Master can issue function calls to minions in a -deterministic order. \fISee also\fP: overstate\&. +deterministic order. \fISee also\fP: \fIoverstate\fP\&. .TP .B Peer Communication The ability for minions to communicate directly with other minions instead of brokering commands through the Salt master. \fISee also\fP: -peer communication\&. +\fIpeer communication\fP\&. .TP .B Pillar A simple key\-value store for user\-defined data to be made available to a minion. Often used to store and distribute sensitive data to minions. -\fISee also\fP: Pillar, list of Pillar -modules\&. +\fISee also\fP: \fIPillar\fP, \fIlist of Pillar +modules\fP\&. .TP .B Proxy Minion A minion which can control devices that are unable to run a Salt minion @@ -172776,29 +187968,29 @@ be used in cases where adding pure Python into SLS files is beneficial. .TP .B Reactor An interface for listening to events and defining actions that Salt -should taken upon receipt of given events. \fISee also\fP: Reactor\&. +should taken upon receipt of given events. \fISee also\fP: \fIReactor\fP\&. .TP .B Render Pipe Allows SLS files to be rendered by multiple renderers, with each renderer receiving the output of the previous. \fISee also\fP: -composing renderers\&. +\fIcomposing renderers\fP\&. .TP .B Renderer Responsible for translating a given data serialization format such as YAML or JSON into a Python data structure that can be consumed by Salt. -\fISee also\fP: list of renderers\&. +\fISee also\fP: \fIlist of renderers\fP\&. .TP .B Returner Allows for the results of a Salt command to be sent to a given data\-store such as a database or log file for archival. \fISee also\fP: -list of returners\&. +\fIlist of returners\fP\&. .TP .B Roster A flat\-file list of target hosts. (Currently only used by salt\-ssh.) .TP .B Runner Module -A module containing a set of runner functions. \fISee also\fP: list -of runner modules\&. +A module containing a set of runner functions. \fISee also\fP: \fIlist +of runner modules\fP\&. .TP .B Runner Function A function which is is called by the \fBsalt\-run\fP command and @@ -172807,7 +187999,7 @@ executes on the master instead of on a minion. \fISee also\fP: .TP .B Salt Cloud A suite of tools used to create and deploy systems on many hosted cloud -providers. \fISee also\fP: salt\-cloud\&. +providers. \fISee also\fP: \fIsalt\-cloud\fP\&. .TP .B Salt SSH A configuration management and remote orchestration system that does @@ -172831,11 +188023,11 @@ Contains a set of \fI\%state declarations\fP\&. .B State Declaration A data structure which contains a unique ID and describes one or more states of a system such as ensuring that a package is installed or a -user is defined. \fISee also\fP: highstate structure\&. +user is defined. \fISee also\fP: \fIhighstate structure\fP\&. .TP .B State Module A module which contains a set of state functions. \fISee also\fP: -list of state modules\&. +\fIlist of state modules\fP\&. .TP .B State Function A function contained inside a \fI\%state module\fP which @@ -172850,16 +188042,16 @@ Translates \fI\%highdata\fP into lowdata. .TP .B Syndic A forwarder which can relay messages between tiered masters. \fBSee -also\fP: Syndic\&. +also\fP: \fISyndic\fP\&. .TP .B Target Minion(s) to which a given salt command will apply. \fISee also\fP: -targeting\&. +\fItargeting\fP\&. .TP .B Top File Determines which SLS files should be applied to various systems and organizes those groups of systems into environments. \fISee also\fP: -top file, list of master top modules\&. +\fItop file\fP, \fIlist of master top modules\fP\&. .TP .B Worker A master process which can send notices and receive replies from From 8575192cc435cfffdc2c4e30008bc54201b62241 Mon Sep 17 00:00:00 2001 From: Justin Findlay Date: Sat, 27 Jun 2015 00:56:48 -0600 Subject: [PATCH 30/33] revise label and milestone documentation --- doc/topics/development/contributing.rst | 2 + doc/topics/development/labels.rst | 412 ++++++++++++------------ 2 files changed, 212 insertions(+), 202 deletions(-) diff --git a/doc/topics/development/contributing.rst b/doc/topics/development/contributing.rst index 6ac1867e40..ab5b642742 100644 --- a/doc/topics/development/contributing.rst +++ b/doc/topics/development/contributing.rst @@ -285,6 +285,8 @@ format-patch`_ and send them to the `salt-users`_ mailing list. The contributor will then get credit for the patch, and the Salt community will have an archive of the patch and a place for discussion. +.. _backporting-pull-requests: + Backporting Pull Requests ========================= diff --git a/doc/topics/development/labels.rst b/doc/topics/development/labels.rst index 1bca21ab86..42d634d4db 100644 --- a/doc/topics/development/labels.rst +++ b/doc/topics/development/labels.rst @@ -4,284 +4,292 @@ GitHub Labels and Milestones ============================ -SaltStack uses several labeling schemes, as well as applying milestones, to triage incoming issues and pull requests in -the GitHub Issue Tracker. Most of the labels and milestones are used for internal tracking, but the following -definitions might prove useful for the community to discover the best issues to help resolve. +SaltStack uses several label categories, as well as milestones, to triage incoming issues and pull requests in the +GitHub issue tracker. Labels are used to sort issues by type, priority, severity, status, functional area, functional +group, and targeted release and pull requests by status, functional area, functional group, type of change, and test +status. Milestones are used to indicate whether an issue is fully triaged or is scheduled to be fixed by SaltStack in +an upcoming sprint. Milestones ========== -Milestones are most often applied to issues, as a milestone is assigned to every issue that has been triaged. However, -milestones can also be applied to pull requests. SaltStack uses milestones to track bugs or features that should be -included in the next major feature release, or even the next bug-fix release, as well as what issues are ready to be -worked on or what might be blocked. All incoming issues must have a milestone associated with them. +All issues are assigned to a milestone, whereas pull requests are almost never assigned to a milestone as the mean +lifetime of pull requests is short enough that there is no need to track them temporally. -Approved - Used to indicate that this issue has all of the needed information and is ready to be worked on. +SaltStack uses milestones to indicate which issues are blocked on submitter or upstream actions, are approved, or are +scheduled to be fixed or implemented in an upcoming sprint. If an issue is not attached to a sprint milestone, you are +welcome to work on it at your own desire and convenience. If it is attached to a sprint milestone and you have already +begun working on it or have a solution in mind or have other ideas related to the issue, you are encouraged to +coordinate with the assignee via the GitHub issue tracker to create the best possible solution or implementation. -Blocked - Used to indicate that the issue is not ready to be worked on yet. This typically applies to issues that have been - labeled with “Info Needed”, “Question”, “Expected Behavior”, “Won’t Fix for Now”, etc. +``Approved`` + The issue has been validated and has all necessary information. -Dot or Bug-fix Release - Used to help filter/identify what issues must be fixed before the release such as 2014.7.4 or 2015.2.3. This - milestone is often used in conjunction with the ``Blocker`` label, but not always. +``Blocked`` + The issue is waiting on actions by parties outside of SaltStack, such as receiving more information from the + submitter or resolution of an upstream issue. This milestone is usually applied in conjunction with the labels + ``Info Needed``, ``Question``, ``Expected Behavior``, ``Won't Fix For Now``, or ``Upstream Bug``. -Feature Release - Similar to the Dot or Bug-fix Release milestone, but for upcoming feature releases such as Boron, Carbon, etc. - This milestone is often used in conjunction with the ``Blocker`` label, but not always. +``Under Review`` + The issue is having further validation done by a SaltStack engineer. + +```` + The issue is being actively worked on by a SaltStack engineer. Sprint milestones names are constructed from the + chemical symbol of the next release's codename and the number of sprints until that release is made. For example, + if the next release codename is ``Neon`` and there are five sprints until that release, the corresponding sprint + milestone will be called ``Ne 5``. See :doc:`` for a discussion of Salt's release + codenames. Labels ====== -Labels are used to facilitate the resolution of new pull requests and open issues. Most labels are confined to being -applied to either issues or pull requests, though some labels may be applied to both. +Labels are used to sort and describe issues and pull requests. Some labels are usually reserved for one or the other, +though most labels may be applied to both. -Issue Labels ------------- +New issues will receive at least one label and a milestone, and new pull requests will receive at least one label. +Except for the :ref:`functional area ` and :ref:`functional group ` +label categories, issues will generally receive only up to one label per category. -All incoming issues should be triaged with at least one label and a milestone. When a new issue comes in, it should be -determined if the issue is a bug or a feature request, and either of those labels should be applied accordingly. Bugs -and Feature Requests have differing labeling schemes, detailed below, where other labels are applied to them to further -help contributors find issues to fix or implement. +Type +---- -There are some labels, such as ``Question`` or some of the "Status" labels that may be applied as "stand alone" labels -in which more information may be needed or a decision must be reached on how to proceed. (See the "Bug Status Labels" -section below.) +Issues are categorized into one of several types. Type labels are almost never used for pull requests. GitHub treats +pull requests like issues in many ways, so a pull request could be considered an issue with an implicit ``Pull Request`` +type label applied. -Features -~~~~~~~~ +``Feature`` + The issue is a request for new functionality including changes, enhancements, refactors, etc. -The ``Feature`` label should be applied when a user is requesting entirely new functionality. This can include new -functions, modules, states, modular systems, flags for existing functions, etc. Features *do not* receive severity -or priority labels, as those labels are only used for bugs. However, they may receive "Functional Area" labels or "ZD". +``Bug`` + The issue documents broken, incorrect, or confusing behavior. This label is always accompanied by a :ref:`severity + label `. -Feature request issues will be prioritized on an "as-needed" basis using milestones during SaltStack's feature release -and sprint planning processes. +``Duplicate`` + The issue is a duplicate of another feature request or bug report. -Bugs -~~~~ +``Upstream Bug`` + The issue is a result of an upstream issue. -All bugs should have the ``Bug`` label as well as a severity, priority, functional area, and a status, as applicable. +``Question`` + The issue is more of a question than a request for new features or a report of broken features, but can sometimes + lead to further discussion or changes of confusing or incongruous behavior or documentation. -Severity -^^^^^^^^ - -How severe is the bug? SaltStack uses four labels to determine the severity of a bug: ``Blocker``, ``Critical``, -``High``, and ``Medium``. This scale is intended to make the bug-triage process as objective as possible. - -Blocker - Should be used sparingly to indicate must-have fixes for the impending release. - -Critical - Applied to bugs that have data loss, crashes, hanging, unresponsive system, etc. - -High Severity - Any bug report that contains incorrect functionality, bad functionality, a confusing user experience, etc. - -Medium Severity - Applied to bugs that are about cosmetic items, spelling, spacing, colors, etc. +``Expected Behavior`` + The issue is a bug report of intended functionality. Priority -^^^^^^^^ +-------- -In addition to using a bug severity to classify issues, a priority is also assigned to each bug to give further -granularity in searching for bugs to fix. In this way, a bug's priority is defined as follows: +An issue's priority is relative to its :ref:`functional area `. If a bug report, for example, +about ``gitfs`` indicates that all users of ``gitfs`` will encounter this bug, then a ``P1`` label will be applied, even +though users who are not using ``gitfs`` will not encounter the bug. If a feature is requested by many users, it may be +given a high priority. -P1 - Very likely. Everyone will see the bug. +``P1`` + The issue will be seen by all users. -P2 - Somewhat likely. Most will see the bug, but a few will not. +``P2`` + The issue will be seen by most users. -P3 - Half will see the bug, about half will not. +``P3`` + The issue will be seen by about half of users. -P4 - Most will not see the bug. Usually a very specific use case or corner case. +``P4`` + The issue will not be seen by most users. Usually the issue is a very specific use case or corner case. -.. note:: +.. _bug-severity-labels: - A bug's priority is relative to its functional area. If a bug report, for example, about ``gitfs`` includes details - indicating that everyone who ``gitfs`` will run into this bug, then a ``P1`` label will be applied, even though - Salt users who are not enabling ``gitfs`` will see the bug. +Severity +-------- -Functional Areas -^^^^^^^^^^^^^^^^ +Severity labels are almost always only applied to issues labeled ``Bug``. -All bugs should receive a "Functional Area" label to indicate what region of Salt the bug is mainly seen in. This will -help internal developers as well as community members identify areas of expertise to find issues that can be fixed more -easily. Functional Area labels can also be applied to Feature Requests. +``Blocker`` + The issue is blocking an impending release. -Functional Area Labels, in alphabetical order, include: +``Critical`` + The issue causes data loss, crashes or hangs salt processes, makes the system unresponsive, etc. -* Core -* Documentation -* Execution Module -* File Servers -* Multi-Master -* Packaging -* Pillar -* Platform Mgmt. -* RAET -* Returners -* Salt-API -* Salt-Cloud -* Salt-SSH -* Salt-Syndic -* State Module -* Windows -* ZMQ +``High Severity`` + The issue reports incorrect functionality, bad functionality, a confusing user experience, etc. -Bug Status Labels -^^^^^^^^^^^^^^^^^ +``Medium Severity`` + The issue reports cosmetic items, formatting, spelling, colors, etc. -Status lables are used to define and track the state a bug is in at any given time. Not all bugs will have a status -label, but if a SaltStack employee is able to apply a status label, he or she will. Status labels are somewhat unique -in the fact that they might be the only label on an issue, such as ``Pending Discussion``, ``Info Needed``, or -``Expected Behavior`` until further action can be taken. +.. _functional-area-labels: -Cannot Reproduce - Someone from the SaltStack team has tried to reproduce the bug with the given information but they are unable to - replicate the problem. More information will need to be provided from the original issue-filer before proceeding. +Functional Area +--------------- -Confirmed - A SaltStack engineer has confirmed the reported bug and provided a simple way to reproduce the failure. +Many major components of Salt have corresponding GitHub labels. These labels are applied to all issues and pull +requests as is reasonably appropriate. They are useful in organizing issues and pull requests according to the source +code relevant to issues or the source code changed by pull requests. -Duplicate - The issue has been reported already in another report. A link to the other bug report must be provided. At that - point the new issue can be closed. Usually, the earliest bug on file is kept as that typically has the most - discussion revolving around the issue, though not always. (This can be a "stand-alone" label.) +* ``Execution Module`` +* ``File Servers`` +* ``Grains`` +* ``Multi-Master`` +* ``Packaging`` Related to packaging of Salt, not Salt's support for package management. +* ``Pillar`` +* ``RAET`` +* ``Returners`` +* ``Runners`` +* ``Salt-API`` +* ``Salt-Cloud`` +* ``Salt-SSH`` +* ``Salt-Syndic`` +* ``State Module`` +* ``Tests`` +* ``Transport`` +* ``Windows`` +* ``ZMQ`` -Expected Behavior - The issue reported is expected behavior and nothing needs to be fixed. (This can be a "stand-alone" label.) +.. _functional-group-labels: -Fixed Pending Verification - The bug has been fixed and a link to the applicable pull request(s) has been provided, but confirmation is being - sought from the community member(s) involved in the bug to test and confirm the fix. +Functional Group +---------------- -Info Needed - More information about the issue is needed before proceeding such as a versions report, a sample state, the command - the user was running, or the operating system the error was occurring on, etc. (This can be a "stand-alone" label.) +These labels sort issues and pull requests according to the internal SaltStack engineering teams. -Upstream Bug - The reported bug is something that cannot be fixed in the Salt code base but is instead a bug in another library - such a bug in ZMQ or Python. When an issue is labeled with ``Upstream Bug`` then a bug report in the upstream - project must be filed (or found if a report already exists) and a link to the report must be provided to the issue - in Salt for tracking purposes. (This can be a stand-alone label.) +``Core`` + The issue or pull request relates to code that is central or existential to Salt itself. -Won't Fix for Now - The SaltStack team has acknowledged the issue at hand is legitimate, but made the call that it’s not something - they’re able or willing to fix at this time. These issues may be revisited in the future. +``Platform`` + The issue or pull request relates to support and integration with various platforms like traditional operating + systems as well as containers, platform-based utilities like filesystems, command schedulers, etc., and + system-based applications like webservers, databases, etc. -Other -~~~~~ +``RIoT`` + The issue or pull request relates to support and integration with various abstract systems like cloud providers, + hypervisors, API-based services, etc. -There are a couple of other labels that are helpful in categorizing bugs that are not included in the categories above. -These labels can either stand on their own such as ``Question`` or can be applied to bugs or feature requests as -applicable. +``Console`` + The issue or pull request relates to the SaltStack enterprise console. -Low Hanging Fruit - Applied to bugs that should be easy to fix. This is useful for new contributors to know where some simple things - are to get involved in contributing to salt. +``Documentation`` + The issue or pull request relates to documentation. -Question - Used when the issue isn’t a bug nor a feature, but the user has a question about expected behavior, how something - works, is misunderstanding a concept, etc. This label is typically applied on its own with ``Blocked`` milestone. +Status +------ -Regression - Helps with additional filtering for bug fixing. If something previously worked and now does not work, as opposed to - something that never worked in the first place, the issue should be treated with greater urgency. +Status labels are used to define and track the state of issues and pull requests. Not all potential statuses correspond +to a label, but some statuses are common enough that labels have been created for them. If an issue has not been moved +beyond the ``Blocked`` milestone, it is very likely that it will only have a status label. -ZD - Stands for “Zendesk” and is used to help track bugs that customers are seeing as well as community members. Bugs - with this label should be treated with greater urgency. +``Bugfix - back-port`` + The pull request needs to be back-ported to an older release branch. This is done by :ref:`recreating the pull + request ` against that branch. Once the back-port is completed, this label is replaced + with a ``Bugfix - [Done] back-ported`` label. Normally, new features should go into the develop and bug fixes into + the oldest supported release branch, see :ref:``. -Pull Request Labels -------------------- +``Bugfix - [Done] back-ported`` + The pull request has been back-ported to an older branch. -SaltStack also applies various labels to incoming pull requests. These are mainly used to help SaltStack engineers -easily identify the nature the changes presented in a pull request and whether or not that pull request is ready to be -reviewed and merged into the Salt codebase. +``Cannot Reproduce`` + The issue is a bug and has been reviewed by a SaltStack engineer, but it cannot be replicated with the provided + information and context. Those involved with the bug will need to work through additional ideas until the bug can + be isolated and verified. + +``Confirmed`` + The issue is a bug and has been confirmed by a SaltStack engineer, who often documents a minimal working example + that reproduces the bug. + +``Fixed Pending Verification`` + The issue is a bug and has been fixed by one or more pull requests, which should link to the issue. Closure of the + issue is contingent upon confirmation of resolution from the submitter. If the submitter reports a negative + confirmation, this label is removed. If no response is given after a few weeks, then the issue will be assumed + fixed and closed. + +``Info Needed`` + The issue needs more information before it can be verified and resolved. For a feature request this may include a + description of the use cases. Almost all bug reports need to include at least the versions of salt and its + dependencies, the system type and version, commands used, debug logs, error messages, and relevant configs. + +``Pending Changes`` + The pull request needs additional changes before it can be merged. + +``Pending Discussion`` + The issue or pull request needs more discussion before it can be closed or merged. The status of the issue or pull + request is not clear or apparent enough for definite action to be taken, or additional input from SaltStack, the + submitter, or another party has been requested. + + If the issue is not a pull request, once the discussion has arrived at a cogent conclusion, this label will be + removed and the issue will be accepted. If it is a pull request, the results of the discussion may require + additional changes and thus, a ``Pending Changes`` label. + +``Won't Fix for Now`` + The issue is legitimate, but it is not something the SaltStack team is currently able or willing to fix or + implement. Issues having this label may be revisited in the future. Type of Change ~~~~~~~~~~~~~~ -A "* Change" label is applied to each incoming pull request. The type of change label that is applied to a pull request -is based on a scale that encompasses the number of lines affected by the change in conjunction with the area of code -the change touches (i.e. core code areas vs. execution or state modules). +Every pull request should receive a change label. These labels measure the quantity of change as well as the +significance of the change. The amount of change and the importance of the code area changed are considered, but often +the depth of secondary code review required and the potential repercussions of the change may also advise the label +choice. -The conditions given for these labels are recommendations, as the pull request reviewer will also consult their -intuition and experience regarding the magnitude of the impact of the proposed changes in the pull request. +Core code areas include: state compiler, crypto engine, master and minion and syndic daemons, transport, pillar +rendering, loader, transport layer, event system, salt.utils, client, cli, logging, netapi, runner engine, templating +engine, top file compilation, file client, file server, mine, salt-ssh, test runner, etc. -Core code areas include: state compiler, crypto engine, master and minion, transport, pillar rendering, loader, -transport layer, event system, salt.utils, client, cli, logging, netapi, runner engine, templating engine, top file -compilation, file client, file server, mine, salt-ssh, test runner, etc. +Non-core code usually constitutes the specific set of plugins for each of the several plugin layers of Salt: execution +modules, states, runners, returners, clouds, etc. -* Minor Change +``Minor Change`` * Less than 64 lines changed, or * Less than 8 core lines changed -* Medium Change +``Medium Change`` * Less than 256 lines changed, or * Less than 64 core lines changed -* Master Change +``Master Change`` * More than 256 lines changed, or * More than 64 core lines changed -* Expert Change +``Expert Change`` * Needs specialized, in-depth review -Back-port Labels -~~~~~~~~~~~~~~~~ +Test Status +----------- -There are two labels that are used to keep track of what pull requests need to be back-ported to an older release branch -and which pull requests have already been back-ported. +These labels relate to the status of the automated tests that run on pull requests. If the tests on a pull request fail +and are not overridden by one of these labels, the pull request submitter needs to update the code and/or tests so that +the tests pass and the pull request can be merged. -Bugfix - back-port - Indicates a pull request that needs to be back-ported. Once the back-port is completed, the back-porting pull request - is linked to the original pull request and this label is removed. +``Lint`` + The pull request has passed all tests except for the code lint checker. -Bugfix - [Done] back-ported - Indicates a pull request that has been back-ported to another branch. The pull request that is responsible for the - backport should be linked to this original pull request. +``Tests Passed`` + The pull request has passed all tests even though some test results are negative. Sometimes the automated testing + infrastructure will encounter internal errors unrelated to the code change in the pull request that cause test runs + to fail. These errors can be caused by cloud provider and network issues and also Jenkins issues like erroneously + accumulating workspace artifacts, resource exhaustion, and bugs that arise from long running Jenkins processes. -Testing Labels -~~~~~~~~~~~~~~ +Other +----- -There are a couple of labels that the QA team uses to indicate the mergability of a pull request. If the pull request is -legitimately passing or failing tests, then one or more of these labels may be applied. +These labels indicate miscellaneous issue types or statuses that are common or important enough to be tracked and sorted +with labels. -Lint - If a pull request fails the test run, but the only failures are related pylint errors, this label will be applied to - indicate that pylint needs to be fixed before proceeding. +``Awesome`` + The pull request implements an especially well crafted solution, or a very difficult but necessary change. -Pending Changes - Indicates that additional commits should be added to the original pull request before the pull request is merged - into the codebase. These changes are unrelated to fixing tests and are generally needed to round out any unfinished - pull requests. +``Low Hanging Fruit`` + The issue is trivial or almost trivial to implement or fix. Issues having this label should be a good starting + place for new contributors to Salt. -Tests Passed - Sometimes the Jenkins test run encounters problems, either tests that are known to have reliability issues or a - test VM failed to build, but the problems are not related to the code changed in the pull request. This label is - used to indicate that someone has reviewed the test failures and has deemed the failures to be non-pertinent. +``Needs Testcase`` + The issue or pull request relates to a feature that needs test coverage. The pull request containing the tests + should reference the issue or pull request having this label, whereupon the label should be removed. -Other Pull Request Labels -~~~~~~~~~~~~~~~~~~~~~~~~~ +``Regression`` + The issue is a bug that breaks functionality known to work in previous releases. -Awesome - Applied to pull requests that implemented a cool new feature or fixed a bug in an excellent way. +``Story`` + The issue is used by a SaltStack engineer to track progress on multiple related issues in a single place. -Labels that Bridge Issues and Pull Requests -=========================================== +``ZD`` + The issue is related to a Zendesk customer support ticket. -Needs Testcase - Used by SaltStack's QA team to realize where pain points are and to bring special attention to where some test - coverage needs to occur, especially in areas that have regressed. This label can apply to issues or pull requests, - which can also be open or closed. Once tests are written, the pull request containing the tests should be linked to - the issue or pull request that originally had the ``Needs Testcase`` label. At this point, the ``Needs Testcase`` - label must be removed to indicate that tests no longer need to be written. - -Pending Discussion - If this label is applied to an issue, the issue may or may not be a bug. Enough information was provided about the - issue, but some other opinions on the issue are desirable before proceeding. (This can be a "stand-alone" label.) - If the label is applied to a pull request, this is used to signal that further discussion must occur before a - decision is made to either merge the pull request into the code base or to close it all together. +```` + The issue is scheduled to be implemented by ````. See :doc:`` for a + discussion of Salt's release codenames. From e3045be5a9c0117d6c36a3a2ea6e2d25000b634c Mon Sep 17 00:00:00 2001 From: Jayesh Kariya Date: Mon, 29 Jun 2015 14:13:45 +0530 Subject: [PATCH 31/33] adding redismod unit test case. --- tests/unit/modules/redismod_test.py | 474 ++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 tests/unit/modules/redismod_test.py diff --git a/tests/unit/modules/redismod_test.py b/tests/unit/modules/redismod_test.py new file mode 100644 index 0000000000..c0e0363880 --- /dev/null +++ b/tests/unit/modules/redismod_test.py @@ -0,0 +1,474 @@ +# -*- coding: utf-8 -*- +''' + :codeauthor: :email:`Jayesh Kariya ` +''' +# Import Python libs +from __future__ import absolute_import + +# Import Salt Testing Libs +from salttesting import skipIf, TestCase +from salttesting.mock import ( + NO_MOCK, + NO_MOCK_REASON, + MagicMock, + patch) + +from salttesting.helpers import ensure_in_syspath + +ensure_in_syspath('../../') + +# Import Salt Libs +from salt.modules import redismod +from datetime import datetime + + +# Globals +redismod.__grains__ = {} +redismod.__salt__ = {} +redismod.__context__ = {} +redismod.__opts__ = {} + + +class Mockredis(object): + ''' + Mock redis class + ''' + class ConnectionError(Exception): + ''' + Mock ConnectionError class + ''' + pass + +redismod.redis = Mockredis + + +class MockConnect(object): + ''' + Mock Connect class + ''' + counter = 0 + + def __init__(self): + self.name = None + self.pattern = None + self.value = None + self.key = None + self.seconds = None + self.timestamp = None + self.field = None + self.start = None + self.stop = None + self.master_host = None + self.master_port = None + + @staticmethod + def bgrewriteaof(): + ''' + Mock bgrewriteaof method + ''' + return 'A' + + @staticmethod + def bgsave(): + ''' + Mock bgsave method + ''' + return 'A' + + def config_get(self, pattern): + ''' + Mock config_get method + ''' + self.pattern = pattern + return 'A' + + def config_set(self, name, value): + ''' + Mock config_set method + ''' + self.name = name + self.value = value + return 'A' + + @staticmethod + def dbsize(): + ''' + Mock dbsize method + ''' + return 'A' + + @staticmethod + def delete(): + ''' + Mock delete method + ''' + return 'A' + + def exists(self, key): + ''' + Mock exists method + ''' + self.key = key + return 'A' + + def expire(self, key, seconds): + ''' + Mock expire method + ''' + self.key = key + self.seconds = seconds + return 'A' + + def expireat(self, key, timestamp): + ''' + Mock expireat method + ''' + self.key = key + self.timestamp = timestamp + return 'A' + + @staticmethod + def flushall(): + ''' + Mock flushall method + ''' + return 'A' + + @staticmethod + def flushdb(): + ''' + Mock flushdb method + ''' + return 'A' + + def get(self, key): + ''' + Mock get method + ''' + self.key = key + return 'A' + + def hget(self, key, field): + ''' + Mock hget method + ''' + self.key = key + self.field = field + return 'A' + + def hgetall(self, key): + ''' + Mock hgetall method + ''' + self.key = key + return 'A' + + @staticmethod + def info(): + ''' + Mock info method + ''' + return 'A' + + def keys(self, pattern): + ''' + Mock keys method + ''' + self.pattern = pattern + return 'A' + + def type(self, key): + ''' + Mock type method + ''' + self.key = key + return 'A' + + @staticmethod + def lastsave(): + ''' + Mock lastsave method + ''' + return datetime.now() + + def llen(self, key): + ''' + Mock llen method + ''' + self.key = key + return 'A' + + def lrange(self, key, start, stop): + ''' + Mock lrange method + ''' + self.key = key + self.start = start + self.stop = stop + return 'A' + + @staticmethod + def ping(): + ''' + Mock ping method + ''' + MockConnect.counter = MockConnect.counter + 1 + if MockConnect.counter == 1: + return 'A' + elif MockConnect.counter in (2, 3, 5): + raise Mockredis.ConnectionError('foo') + + @staticmethod + def save(): + ''' + Mock save method + ''' + return 'A' + + def set(self, key, value): + ''' + Mock set method + ''' + self.key = key + self.value = value + return 'A' + + @staticmethod + def shutdown(): + ''' + Mock shutdown method + ''' + return 'A' + + def slaveof(self, master_host, master_port): + ''' + Mock slaveof method + ''' + self.master_host = master_host + self.master_port = master_port + return 'A' + + def smembers(self, key): + ''' + Mock smembers method + ''' + self.key = key + return 'A' + + @staticmethod + def time(): + ''' + Mock time method + ''' + return 'A' + + def zcard(self, key): + ''' + Mock zcard method + ''' + self.key = key + return 'A' + + def zrange(self, key, start, stop): + ''' + Mock zrange method + ''' + self.key = key + self.start = start + self.stop = stop + return 'A' + + +@skipIf(NO_MOCK, NO_MOCK_REASON) +@patch('salt.modules.redismod._connect', MagicMock(return_value=MockConnect())) +class RedismodTestCase(TestCase): + ''' + Test cases for salt.modules.redismod + ''' + def test_bgrewriteaof(self): + ''' + Test to asynchronously rewrite the append-only file + ''' + self.assertEqual(redismod.bgrewriteaof(), 'A') + + def test_bgsave(self): + ''' + Test to asynchronously save the dataset to disk + ''' + self.assertEqual(redismod.bgsave(), 'A') + + def test_config_get(self): + ''' + Test to get redis server configuration values + ''' + self.assertEqual(redismod.config_get('*'), 'A') + + def test_config_set(self): + ''' + Test to set redis server configuration values + ''' + self.assertEqual(redismod.config_set('name', 'value'), 'A') + + def test_dbsize(self): + ''' + Test to return the number of keys in the selected database + ''' + self.assertEqual(redismod.dbsize(), 'A') + + def test_delete(self): + ''' + Test to deletes the keys from redis, returns number of keys deleted + ''' + self.assertEqual(redismod.delete(), 'A') + + def test_exists(self): + ''' + Test to return true if the key exists in redis + ''' + self.assertEqual(redismod.exists('key'), 'A') + + def test_expire(self): + ''' + Test to set a keys time to live in seconds + ''' + self.assertEqual(redismod.expire('key', 'seconds'), 'A') + + def test_expireat(self): + ''' + Test to set a keys expire at given UNIX time + ''' + self.assertEqual(redismod.expireat('key', 'timestamp'), 'A') + + def test_flushall(self): + ''' + Test to remove all keys from all databases + ''' + self.assertEqual(redismod.flushall(), 'A') + + def test_flushdb(self): + ''' + Test to remove all keys from the selected database + ''' + self.assertEqual(redismod.flushdb(), 'A') + + def test_get_key(self): + ''' + Test to get redis key value + ''' + self.assertEqual(redismod.get_key('key'), 'A') + + def test_hget(self): + ''' + Test to get specific field value from a redis hash, returns dict + ''' + self.assertEqual(redismod.hget('key', 'field'), 'A') + + def test_hgetall(self): + ''' + Test to get all fields and values from a redis hash, returns dict + ''' + self.assertEqual(redismod.hgetall('key'), 'A') + + def test_info(self): + ''' + Test to get information and statistics about the server + ''' + self.assertEqual(redismod.info(), 'A') + + def test_keys(self): + ''' + Test to get redis keys, supports glob style patterns + ''' + self.assertEqual(redismod.keys('pattern'), 'A') + + def test_key_type(self): + ''' + Test to get redis key type + ''' + self.assertEqual(redismod.key_type('key'), 'A') + + def test_lastsave(self): + ''' + Test to get the UNIX time in seconds of the last successful + save to disk + ''' + self.assertTrue(redismod.lastsave()) + + def test_llen(self): + ''' + Test to get the length of a list in Redis + ''' + self.assertEqual(redismod.llen('key'), 'A') + + def test_lrange(self): + ''' + Test to get a range of values from a list in Redis + ''' + self.assertEqual(redismod.lrange('key', 'start', 'stop'), 'A') + + def test_ping(self): + ''' + Test to ping the server, returns False on connection errors + ''' + self.assertEqual(redismod.ping(), 'A') + + self.assertFalse(redismod.ping()) + + def test_save(self): + ''' + Test to synchronously save the dataset to disk + ''' + self.assertEqual(redismod.save(), 'A') + + def test_set_key(self): + ''' + Test to set redis key value + ''' + self.assertEqual(redismod.set_key('key', 'value'), 'A') + + def test_shutdown(self): + ''' + Test to synchronously save the dataset to disk and then + shut down the server + ''' + self.assertFalse(redismod.shutdown()) + + self.assertTrue(redismod.shutdown()) + + self.assertFalse(redismod.shutdown()) + + def test_slaveof(self): + ''' + Test to make the server a slave of another instance, or + promote it as master + ''' + self.assertEqual(redismod.slaveof('master_host', 'master_port'), 'A') + + def test_smembers(self): + ''' + Test to get members in a Redis set + ''' + self.assertListEqual(redismod.smembers('key'), ['A']) + + def test_time(self): + ''' + Test to return the current server UNIX time in seconds + ''' + self.assertEqual(redismod.time(), 'A') + + def test_zcard(self): + ''' + Test to get the length of a sorted set in Redis + ''' + self.assertEqual(redismod.zcard('key'), 'A') + + def test_zrange(self): + ''' + Test to get a range of values from a sorted set in Redis by index + ''' + self.assertEqual(redismod.zrange('key', 'start', 'stop'), 'A') + + +if __name__ == '__main__': + from integration import run_tests + run_tests(RedismodTestCase, needs_daemon=False) From d6dc6f97b544c3534dd8bd2ee728c05287cc664f Mon Sep 17 00:00:00 2001 From: Justin Findlay Date: Mon, 29 Jun 2015 10:53:17 -0600 Subject: [PATCH 32/33] versionadded Fixes #24747. --- salt/modules/network.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/salt/modules/network.py b/salt/modules/network.py index b3d5dea7a6..a2015744b0 100644 --- a/salt/modules/network.py +++ b/salt/modules/network.py @@ -1130,6 +1130,8 @@ def get_route(ip): ''' Return routing information for given destination ip + .. versionadded:: 2015.5.3 + CLI Example:: salt '*' network.get_route 10.10.10.10 From 3c6f4a4842d5799ffe3bf37892a0acd215e8c792 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Wed, 1 Jul 2015 16:02:25 -0600 Subject: [PATCH 33/33] Strip leading / for local file paths --- salt/fileclient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/fileclient.py b/salt/fileclient.py index ce42e4bf34..fa6027ce32 100644 --- a/salt/fileclient.py +++ b/salt/fileclient.py @@ -365,7 +365,7 @@ class Client(object): localsfilesdest = os.path.join( self.opts['cachedir'], 'localfiles', path.lstrip('|/')) filesdest = os.path.join( - self.opts['cachedir'], 'files', saltenv, path.lstrip('|')) + self.opts['cachedir'], 'files', saltenv, path.lstrip('|/')) extrndest = self._extrn_path(path, saltenv) if os.path.exists(filesdest):