diff --git a/conf/minion b/conf/minion index fa5caf317b..7420713f96 100644 --- a/conf/minion +++ b/conf/minion @@ -235,13 +235,13 @@ # cause sub minion process to restart. #auth_safemode: False -# Ping Master to ensure connection is alive (seconds). +# Ping Master to ensure connection is alive (minutes). #ping_interval: 0 # To auto recover minions if master changes IP address (DDNS) # auth_tries: 10 # auth_safemode: False -# ping_interval: 90 +# ping_interval: 2 # # Minions won't know master is missing until a ping fails. After the ping fail, # the minion will attempt authentication and likely fails out and cause a restart. diff --git a/doc/ref/configuration/minion.rst b/doc/ref/configuration/minion.rst index 4c58ae2474..1545c28a55 100644 --- a/doc/ref/configuration/minion.rst +++ b/doc/ref/configuration/minion.rst @@ -883,7 +883,7 @@ restart. Default: ``0`` -Instructs the minion to ping its master(s) every n number of seconds. Used +Instructs the minion to ping its master(s) every n number of minutes. Used primarily as a mitigation technique against minion disconnects. .. code-block:: yaml diff --git a/salt/config/__init__.py b/salt/config/__init__.py index c558768d1d..13eb52a152 100644 --- a/salt/config/__init__.py +++ b/salt/config/__init__.py @@ -938,7 +938,7 @@ VALID_OPTS = { 'queue_dirs': list, - # Instructs the minion to ping its master(s) every n number of seconds. Used + # Instructs the minion to ping its master(s) every n number of minutes. Used # primarily as a mitigation technique against minion disconnects. 'ping_interval': int, diff --git a/salt/grains/core.py b/salt/grains/core.py index 48481fd3f8..a5b1c441a8 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -716,12 +716,14 @@ def _virtual(osdata): pass if os.path.isfile('/proc/1/cgroup'): try: - with salt.utils.fopen('/proc/1/cgroup', 'r') as fhr: - if ':/lxc/' in fhr.read(): - grains['virtual_subtype'] = 'LXC' with salt.utils.fopen('/proc/1/cgroup', 'r') as fhr: fhr_contents = fhr.read() - if ':/docker/' in fhr_contents or ':/system.slice/docker' in fhr_contents: + if ':/lxc/' in fhr_contents: + grains['virtual_subtype'] = 'LXC' + else: + if any(x in fhr_contents + for x in (':/system.slice/docker', ':/docker/', + ':/docker-ce/')): grains['virtual_subtype'] = 'Docker' except IOError: pass diff --git a/salt/states/http.py b/salt/states/http.py index 075ae194d7..58399293e9 100644 --- a/salt/states/http.py +++ b/salt/states/http.py @@ -132,8 +132,18 @@ def wait_for_successful_query(name, wait_for=300, **kwargs): Like query but, repeat and wait until match/match_type or status is fulfilled. State returns result from last query state in case of success or if no successful query was made within wait_for timeout. + name + The name of the query. + + wait_for + Total time to wait for requests that succeed. + request_interval Optional interval to delay requests by N seconds to reduce the number of requests sent. + + .. note:: + + All other arguements are passed to the http.query state. ''' starttime = time.time() @@ -141,7 +151,7 @@ def wait_for_successful_query(name, wait_for=300, **kwargs): caught_exception = None ret = None try: - ret = query(name, wait_for=wait_for, **kwargs) + ret = query(name, **kwargs) if ret['result']: return ret except Exception as exc: diff --git a/salt/utils/atomicfile.py b/salt/utils/atomicfile.py index f2b2781d18..98350d2035 100644 --- a/salt/utils/atomicfile.py +++ b/salt/utils/atomicfile.py @@ -15,6 +15,9 @@ import random import shutil import salt.ext.six as six +# Import salt libs +import salt.utils.win_dacl + CAN_RENAME_OPEN_FILE = False if os.name == 'nt': # pragma: no cover @@ -120,8 +123,12 @@ class _AtomicWFile(object): self._fh.close() if os.path.isfile(self._filename): shutil.copymode(self._filename, self._tmp_filename) - st = os.stat(self._filename) - os.chown(self._tmp_filename, st.st_uid, st.st_gid) + if salt.utils.win_dacl.HAS_WIN32: + owner = salt.utils.win_dacl.get_owner(self._filename) + salt.utils.win_dacl.set_owner(self._tmp_filename, owner) + else: + st = os.stat(self._filename) + os.chown(self._tmp_filename, st.st_uid, st.st_gid) atomic_rename(self._tmp_filename, self._filename) def __exit__(self, exc_type, exc_value, traceback): diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py index 33bcfedfd5..51790b28d9 100644 --- a/tests/unit/grains/test_core.py +++ b/tests/unit/grains/test_core.py @@ -5,6 +5,7 @@ # Import Python libs from __future__ import absolute_import +import logging import os # Import Salt Testing Libs @@ -25,6 +26,8 @@ import salt.grains.core as core # Import 3rd-party libs import salt.ext.six as six +log = logging.getLogger(__name__) + # Globals IPv4Address = salt.ext.ipaddress.IPv4Address IPv6Address = salt.ext.ipaddress.IPv6Address @@ -473,6 +476,26 @@ PATCHLEVEL = 3 self.assertListEqual(list(os_grains.get('osrelease_info')), os_release_map['osrelease_info']) self.assertEqual(os_grains.get('osmajorrelease'), os_release_map['osmajorrelease']) + def test_docker_virtual(self): + ''' + Test if OS grains are parsed correctly in Ubuntu Xenial Xerus + ''' + with patch.object(os.path, 'isdir', MagicMock(return_value=False)): + with patch.object(os.path, + 'isfile', + MagicMock(side_effect=lambda x: True if x == '/proc/1/cgroup' else False)): + for cgroup_substr in (':/system.slice/docker', ':/docker/', + ':/docker-ce/'): + cgroup_data = \ + '10:memory{0}a_long_sha256sum'.format(cgroup_substr) + log.debug( + 'Testing Docker cgroup substring \'%s\'', cgroup_substr) + with patch('salt.utils.fopen', mock_open(read_data=cgroup_data)): + self.assertEqual( + core._virtual({'kernel': 'Linux'}).get('virtual_subtype'), + 'Docker' + ) + def _check_ipaddress(self, value, ip_v): ''' check if ip address in a list is valid