mirror of
https://github.com/valitydev/salt.git
synced 2024-11-06 08:35:21 +00:00
Merge branch '2017.7' into '2018.3'
Conflicts: - doc/man/salt-api.1 - doc/man/salt-call.1 - doc/man/salt-cloud.1 - doc/man/salt-cp.1 - doc/man/salt-key.1 - doc/man/salt-master.1 - doc/man/salt-minion.1 - doc/man/salt-proxy.1 - doc/man/salt-run.1 - doc/man/salt-ssh.1 - doc/man/salt-syndic.1 - doc/man/salt-unity.1 - doc/man/salt.1 - doc/man/salt.7 - doc/man/spm.1 - salt/beacons/log.py - salt/client/ssh/__init__.py - salt/modules/cmdmod.py - salt/utils/win_functions.py - tests/integration/modules/test_cmdmod.py - tests/integration/netapi/rest_tornado/test_app.py - tests/integration/runners/test_state.py
This commit is contained in:
commit
3e6445a9d6
@ -46,6 +46,8 @@ pipeline {
|
||||
}
|
||||
}}
|
||||
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/minion'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/salt-runtests.log'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ pipeline {
|
||||
}
|
||||
}}
|
||||
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/minion'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/salt-runtests.log'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ pipeline {
|
||||
}
|
||||
}}
|
||||
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/minion'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/salt-runtests.log'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ pipeline {
|
||||
}
|
||||
}}
|
||||
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/minion'
|
||||
archiveArtifacts artifacts: 'artifacts/logs/salt-runtests.log'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
Gemfile
7
Gemfile
@ -11,16 +11,11 @@ group :docker do
|
||||
gem 'kitchen-docker', :git => 'https://github.com/test-kitchen/kitchen-docker.git'
|
||||
end
|
||||
|
||||
group :opennebula do
|
||||
gem 'kitchen-opennebula', '>=0.2.3'
|
||||
gem 'xmlrpc'
|
||||
end
|
||||
|
||||
group :windows do
|
||||
gem 'vagrant-wrapper'
|
||||
gem 'kitchen-vagrant'
|
||||
gem 'winrm', '~>2.0'
|
||||
gem 'winrm-fs', :git => 'https://github.com/WinRb/winrm-fs.git'
|
||||
gem 'winrm-fs', '~>1.2.1'
|
||||
end
|
||||
|
||||
group :ec2 do
|
||||
|
@ -103,9 +103,9 @@ Logfile logging log level. One of \fBall\fP, \fBgarbage\fP, \fBtrace\fP,
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt\-api(7)\fP
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fIsalt\-api(7)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -265,9 +265,9 @@ output. Set to True or False. Default: none.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -387,10 +387,10 @@ salt\-cloud \-m /path/to/cloud.map \-Q
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt\-cloud(7)\fP
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt\-cloud(7)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -201,9 +201,9 @@ New in version 2016.3.7,2016.11.6,2017.7.0.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -340,9 +340,9 @@ Auto\-create a signing key\-pair if it does not yet exist
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -108,9 +108,9 @@ Logfile logging log level. One of \fBall\fP, \fBgarbage\fP, \fBtrace\fP,
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -109,9 +109,9 @@ Logfile logging log level. One of \fBall\fP, \fBgarbage\fP, \fBtrace\fP,
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -116,10 +116,10 @@ Logfile logging log level. One of \fBall\fP, \fBgarbage\fP, \fBtrace\fP,
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -114,9 +114,9 @@ Logfile logging log level. One of \fBall\fP, \fBgarbage\fP, \fBtrace\fP,
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -348,9 +348,9 @@ output. Set to True or False. Default: none.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -110,9 +110,9 @@ Logfile logging log level. One of \fBall\fP, \fBgarbage\fP, \fBtrace\fP,
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -50,17 +50,17 @@ invokes that script.
|
||||
.SH OPTIONS
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt\-api(1)\fP
|
||||
\fBsalt\-call(1)\fP
|
||||
\fBsalt\-cloud(1)\fP
|
||||
\fBsalt\-cp(1)\fP
|
||||
\fBsalt\-key(1)\fP
|
||||
\fBsalt\-main(1)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fBsalt\-run(1)\fP
|
||||
\fBsalt\-ssh(1)\fP
|
||||
\fBsalt\-syndic(1)\fP
|
||||
\fIsalt\-api(1)\fP
|
||||
\fIsalt\-call(1)\fP
|
||||
\fIsalt\-cloud(1)\fP
|
||||
\fIsalt\-cp(1)\fP
|
||||
\fIsalt\-key(1)\fP
|
||||
\fIsalt\-main(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
\fIsalt\-run(1)\fP
|
||||
\fIsalt\-ssh(1)\fP
|
||||
\fIsalt\-syndic(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -95,16 +95,6 @@ the started execution and complete.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-state\-output=STATE_OUTPUT
|
||||
New in version 0.17.
|
||||
|
||||
.sp
|
||||
Override the configured \fBstate_output\fP value for minion output. One of
|
||||
\fBfull\fP, \fBterse\fP, \fBmixed\fP, \fBchanges\fP or \fBfilter\fP\&. Default:
|
||||
\fBfull\fP\&.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-subset=SUBSET
|
||||
Execute the routine on a random subset of the targeted minions. The
|
||||
minions will be verified that they have the named function before
|
||||
@ -344,9 +334,9 @@ output. Set to True or False. Default: none.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(7)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -132,9 +132,9 @@ in that directory which describes them.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBsalt(1)\fP
|
||||
\fBsalt\-master(1)\fP
|
||||
\fBsalt\-minion(1)\fP
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch45@gmail.com> and many others, please see the Authors file
|
||||
.\" Generated by docutils manpage writer.
|
||||
|
@ -21,7 +21,7 @@ management.
|
||||
|
||||
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 `keep_jobs` parameter in the
|
||||
time can be easily adjusted by changing the ``keep_jobs`` parameter in the
|
||||
Salt Master configuration file. The value passed in is measured via hours:
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ checking for and preventing JID collisions.
|
||||
The default location for the job cache is in the ``/var/cache/salt/master/jobs/``
|
||||
directory.
|
||||
|
||||
Setting the :conf_master:`job_cache`` to ``False`` in addition to setting
|
||||
Setting the :conf_master:`job_cache` to ``False`` in addition to setting
|
||||
the :conf_master:`keep_jobs` option to a smaller value, such as ``1``, in the Salt
|
||||
Master configuration file will reduce the size of the Default Job Cache, and thus
|
||||
the burden on the Salt Master.
|
||||
|
@ -79,6 +79,12 @@ def beacon(config):
|
||||
- tags:
|
||||
<tag>:
|
||||
regex: <pattern>
|
||||
|
||||
.. note::
|
||||
|
||||
regex matching is based on the `re`_ module
|
||||
|
||||
.. _re: https://docs.python.org/3.6/library/re.html#regular-expression-syntax
|
||||
'''
|
||||
_config = {}
|
||||
list(map(_config.update, config))
|
||||
|
@ -440,12 +440,12 @@ class SSH(object):
|
||||
'''
|
||||
Deploy the SSH key if the minions don't auth
|
||||
'''
|
||||
if not isinstance(ret[host], dict) or self.opts.get('ssh_key_deploy'):
|
||||
if not isinstance(ret[host], dict) or self.opts.get('ssh_key_deploy') is True:
|
||||
target = self.targets[host]
|
||||
if target.get('passwd', False) or self.opts['ssh_passwd']:
|
||||
self._key_deploy_run(host, target, False)
|
||||
return ret
|
||||
if (ret[host].get('stderr') or '').count('Permission denied'):
|
||||
if ret[host].get('stderr', '').count('Permission denied') and not self.opts.get('ssh_key_deploy') is False:
|
||||
target = self.targets[host]
|
||||
# permission denied, attempt to auto deploy ssh key
|
||||
print(('Permission denied for host {0}, do you want to deploy '
|
||||
|
@ -2269,9 +2269,12 @@ def script(source,
|
||||
os.chmod(path, 320)
|
||||
os.chown(path, __salt__['file.user_to_uid'](runas), -1)
|
||||
|
||||
path = _cmd_quote(path)
|
||||
if salt.utils.is_windows() and shell.lower() != 'powershell':
|
||||
cmd_path = _cmd_quote(path, escape=False)
|
||||
else:
|
||||
cmd_path = _cmd_quote(path)
|
||||
|
||||
ret = _run(path + ' ' + six.text_type(args) if args else path,
|
||||
ret = _run(cmd_path + ' ' + six.text_type(args) if args else cmd_path,
|
||||
cwd=cwd,
|
||||
stdin=stdin,
|
||||
output_encoding=output_encoding,
|
||||
|
@ -677,6 +677,7 @@ def install(name=None,
|
||||
reinstall_requires=False,
|
||||
regex=False,
|
||||
pcre=False,
|
||||
batch=False,
|
||||
**kwargs):
|
||||
'''
|
||||
Install package(s) from a repository
|
||||
@ -800,7 +801,16 @@ def install(name=None,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' pkg.install <extended regular expression> pcre=True
|
||||
|
||||
batch
|
||||
Use BATCH=true for pkg install, skipping all questions.
|
||||
Be careful when using in production.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' pkg.install <package name> batch=True
|
||||
'''
|
||||
try:
|
||||
pkg_params, pkg_type = __salt__['pkg_resource.parse_targets'](
|
||||
@ -812,6 +822,7 @@ def install(name=None,
|
||||
if pkg_params is None or len(pkg_params) == 0:
|
||||
return {}
|
||||
|
||||
env = {}
|
||||
opts = 'y'
|
||||
if salt.utils.data.is_true(orphan):
|
||||
opts += 'A'
|
||||
@ -831,6 +842,11 @@ def install(name=None,
|
||||
opts += 'x'
|
||||
if salt.utils.data.is_true(pcre):
|
||||
opts += 'X'
|
||||
if salt.utils.data.is_true(batch):
|
||||
env = {
|
||||
"BATCH": "true",
|
||||
"ASSUME_ALWAYS_YES": "YES"
|
||||
}
|
||||
|
||||
old = list_pkgs(jail=jail, chroot=chroot, root=root)
|
||||
|
||||
@ -867,7 +883,8 @@ def install(name=None,
|
||||
out = __salt__['cmd.run_all'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
python_shell=False,
|
||||
env=env
|
||||
)
|
||||
|
||||
if out['retcode'] != 0 and out['stderr']:
|
||||
|
@ -35,39 +35,24 @@ def __virtual__():
|
||||
'Ubuntu',
|
||||
'Debian',
|
||||
'Devuan',
|
||||
'Arch',
|
||||
'Arch ARM',
|
||||
'Manjaro',
|
||||
'ALT',
|
||||
'SUSE Enterprise Server',
|
||||
'SUSE',
|
||||
'OEL',
|
||||
'Linaro',
|
||||
'elementary OS',
|
||||
'McAfee OS Server',
|
||||
'Void',
|
||||
'Mint',
|
||||
'Raspbian',
|
||||
'XenServer',
|
||||
'Cumulus'
|
||||
))
|
||||
if __grains__.get('os', '') in disable:
|
||||
if __grains__.get('os') in disable:
|
||||
return (False, 'Your OS is on the disabled list')
|
||||
# Disable on all non-Linux OSes as well
|
||||
if __grains__['kernel'] != 'Linux':
|
||||
return (False, 'Non Linux OSes are not supported')
|
||||
# SUSE >=12.0 uses systemd
|
||||
if __grains__.get('os_family', '') == 'Suse':
|
||||
try:
|
||||
# osrelease might be in decimal format (e.g. "12.1"), or for
|
||||
# SLES might include service pack (e.g. "11 SP3"), so split on
|
||||
# non-digit characters, and the zeroth element is the major
|
||||
# number (it'd be so much simpler if it was always "X.Y"...)
|
||||
import re
|
||||
if int(re.split(r'\D+', __grains__.get('osrelease', ''))[0]) >= 12:
|
||||
return (False, 'SUSE version greater than or equal to 12 is not supported')
|
||||
except ValueError:
|
||||
return (False, 'You are missing the os_family grain')
|
||||
init_grain = __grains__.get('init')
|
||||
if init_grain not in (None, 'sysvinit', 'unknown'):
|
||||
return (False, 'Minion is running {0}'.format(init_grain))
|
||||
elif __utils__['systemd.booted'](__context__):
|
||||
# Should have been caught by init grain check, but check just in case
|
||||
return (False, 'Minion is running systemd')
|
||||
return 'service'
|
||||
|
||||
|
||||
|
@ -466,18 +466,13 @@ def _get_reg_software():
|
||||
'{0}\\{1}'.format(key, reg_key),
|
||||
'DisplayVersion',
|
||||
use_32bit)
|
||||
if (not d_vers_regdata['success'] or
|
||||
d_vers_regdata['vtype'] not in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_DWORD'] or
|
||||
d_vers_regdata['vdata'] in [None, False]):
|
||||
return
|
||||
|
||||
if isinstance(d_vers_regdata['vdata'], int):
|
||||
d_vers = six.text_type(d_vers_regdata['vdata'])
|
||||
else:
|
||||
d_vers = d_vers_regdata['vdata']
|
||||
|
||||
if not d_vers or d_vers == '(value not set)':
|
||||
d_vers = 'Not Found'
|
||||
d_vers = 'Not Found'
|
||||
if (d_vers_regdata['success'] and
|
||||
d_vers_regdata['vtype'] in ['REG_SZ', 'REG_EXPAND_SZ', 'REG_DWORD']):
|
||||
if isinstance(d_vers_regdata['vdata'], int):
|
||||
d_vers = six.text_type(d_vers_regdata['vdata'])
|
||||
elif d_vers_regdata['vdata'] and d_vers_regdata['vdata'] != '(value not set)': # Check for blank values
|
||||
d_vers = d_vers_regdata['vdata']
|
||||
|
||||
check_ok = False
|
||||
for check_reg in ['UninstallString', 'QuietUninstallString', 'ModifyPath']:
|
||||
|
@ -3064,12 +3064,21 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta,
|
||||
auth_group.add_option(
|
||||
'--key-deploy',
|
||||
dest='ssh_key_deploy',
|
||||
default=False,
|
||||
default=None,
|
||||
action='store_true',
|
||||
help='Set this flag to attempt to deploy the authorized ssh key '
|
||||
'with all minions. This combined with --passwd can make '
|
||||
'initial deployment of keys very fast and easy.'
|
||||
)
|
||||
auth_group.add_option(
|
||||
'--no-key-deploy',
|
||||
dest='ssh_key_deploy',
|
||||
default=None,
|
||||
action='store_false',
|
||||
help='Set this flag to stop salt-ssh from attempting to deploy an authorized ssh key '
|
||||
'with all minions. This is useful to skip the message about deploying to minions '
|
||||
'that cannot be logged into.'
|
||||
)
|
||||
auth_group.add_option(
|
||||
'--identities-only',
|
||||
dest='ssh_identities_only',
|
||||
|
@ -175,7 +175,7 @@ def enable_ctrl_logoff_handler():
|
||||
)
|
||||
|
||||
|
||||
def escape_argument(arg):
|
||||
def escape_argument(arg, escape=True):
|
||||
'''
|
||||
Escape the argument for the cmd.exe shell.
|
||||
See http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
|
||||
@ -186,12 +186,19 @@ def escape_argument(arg):
|
||||
Args:
|
||||
arg (str): a single command line argument to escape for the cmd.exe shell
|
||||
|
||||
Kwargs:
|
||||
escape (bool): True will call the escape_for_cmd_exe() function
|
||||
which escapes the characters '()%!^"<>&|'. False
|
||||
will not call the function and only quotes the cmd
|
||||
|
||||
Returns:
|
||||
str: an escaped string suitable to be passed as a program argument to the cmd.exe shell
|
||||
'''
|
||||
if not arg or re.search(r'(["\s])', arg):
|
||||
arg = '"' + arg.replace('"', r'\"') + '"'
|
||||
|
||||
if not escape:
|
||||
return arg
|
||||
return escape_for_cmd_exe(arg)
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@ import salt.utils.files
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.case import ShellCase, SSHCase
|
||||
from tests.support.helpers import flaky
|
||||
|
||||
|
||||
class GrainsTargetingTest(ShellCase):
|
||||
@ -52,6 +53,7 @@ class GrainsTargetingTest(ShellCase):
|
||||
sub_minion = self.run_salt('-G \'id:sub_minion\' test.ping')
|
||||
self.assertEqual(sorted(sub_minion), sorted(['sub_minion:', ' True']))
|
||||
|
||||
@flaky
|
||||
def test_grains_targeting_disconnected(self):
|
||||
'''
|
||||
Tests return of minion using grains targeting on a disconnected minion.
|
||||
@ -72,7 +74,7 @@ class GrainsTargetingTest(ShellCase):
|
||||
for item in self.run_salt('-t 1 -G \'id:disconnected\' test.ping', timeout=40):
|
||||
if item != 'disconnected:':
|
||||
ret = item.strip()
|
||||
self.assertEqual(ret, test_ret)
|
||||
assert ret == test_ret
|
||||
finally:
|
||||
os.unlink(key_file)
|
||||
|
||||
|
@ -9,6 +9,7 @@ import textwrap
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.helpers import (
|
||||
destructiveTest,
|
||||
skip_if_binaries_missing,
|
||||
@ -84,7 +85,7 @@ class CMDModuleTest(ModuleCase):
|
||||
'''
|
||||
self.assertEqual(self.run_function('cmd.run_stdout',
|
||||
['echo "cheese"']).rstrip(),
|
||||
'cheese')
|
||||
'cheese' if not salt.utils.is_windows() else '"cheese"')
|
||||
|
||||
def test_stderr(self):
|
||||
'''
|
||||
@ -99,7 +100,7 @@ class CMDModuleTest(ModuleCase):
|
||||
['echo "cheese" 1>&2',
|
||||
'shell={0}'.format(shell)], python_shell=True
|
||||
).rstrip(),
|
||||
'cheese')
|
||||
'cheese' if not salt.utils.is_windows() else '"cheese"')
|
||||
|
||||
def test_run_all(self):
|
||||
'''
|
||||
@ -120,7 +121,7 @@ class CMDModuleTest(ModuleCase):
|
||||
self.assertTrue(isinstance(ret.get('retcode'), int))
|
||||
self.assertTrue(isinstance(ret.get('stdout'), six.string_types))
|
||||
self.assertTrue(isinstance(ret.get('stderr'), six.string_types))
|
||||
self.assertEqual(ret.get('stderr').rstrip(), 'cheese')
|
||||
self.assertEqual(ret.get('stderr').rstrip(), 'cheese' if not salt.utils.is_windows() else '"cheese"')
|
||||
|
||||
def test_retcode(self):
|
||||
'''
|
||||
@ -258,10 +259,13 @@ class CMDModuleTest(ModuleCase):
|
||||
'''
|
||||
cmd = '''echo 'SELECT * FROM foo WHERE bar="baz"' '''
|
||||
expected_result = 'SELECT * FROM foo WHERE bar="baz"'
|
||||
if salt.utils.is_windows():
|
||||
expected_result = '\'SELECT * FROM foo WHERE bar="baz"\''
|
||||
result = self.run_function('cmd.run_stdout', [cmd]).strip()
|
||||
self.assertEqual(result, expected_result)
|
||||
|
||||
@skip_if_not_root
|
||||
@skipIf(salt.utils.is_windows, 'skip windows, requires password')
|
||||
def test_quotes_runas(self):
|
||||
'''
|
||||
cmd.run with quoted command
|
||||
@ -289,6 +293,7 @@ class CMDModuleTest(ModuleCase):
|
||||
out = self.run_function('cmd.run', ['env'], runas=self.runas_usr).splitlines()
|
||||
self.assertIn('USER={0}'.format(self.runas_usr), out)
|
||||
|
||||
@skipIf(not salt.utils.which_bin('sleep'), 'sleep cmd not installed')
|
||||
def test_timeout(self):
|
||||
'''
|
||||
cmd.run trigger timeout
|
||||
@ -299,6 +304,7 @@ class CMDModuleTest(ModuleCase):
|
||||
python_shell=True)
|
||||
self.assertTrue('Timed out' in out)
|
||||
|
||||
@skipIf(not salt.utils.which_bin('sleep'), 'sleep cmd not installed')
|
||||
def test_timeout_success(self):
|
||||
'''
|
||||
cmd.run sufficient timeout to succeed
|
||||
|
@ -126,6 +126,11 @@ class ServiceModuleTest(ModuleCase):
|
||||
if tuple(self.run_function('grains.item', ['osrelease_info'])['osrelease_info']) == (14, 0o4) and not systemd:
|
||||
# currently upstart does not have a mechanism to report if disabling a service fails if does not exist
|
||||
self.assertTrue(self.run_function('service.disable', [srv_name]))
|
||||
elif self.run_function('grains.item', ['osfullname'])['osfullname'] == 'Debian' and \
|
||||
self.run_function('grains.item', ['osmajorrelease'])['osmajorrelease'] < 9 and systemd:
|
||||
# currently disabling a service via systemd that does not exist
|
||||
# on Debian 8 results in a True return code
|
||||
self.assertTrue(self.run_function('service.disable', [srv_name]))
|
||||
else:
|
||||
try:
|
||||
disable = self.run_function('service.disable', [srv_name])
|
||||
|
@ -80,6 +80,7 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
|
||||
self.assertEqual(response.headers['Location'], '/login')
|
||||
|
||||
# Local client tests
|
||||
|
||||
@skipIf(True, 'to be re-enabled when #23623 is merged')
|
||||
def test_simple_local_post(self):
|
||||
'''
|
||||
@ -121,6 +122,7 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
|
||||
self.assertEqual(response_obj['return'], ["No minions matched the target. No command was sent, no jid was assigned."])
|
||||
|
||||
# local client request body test
|
||||
|
||||
@skipIf(True, 'Undetermined race condition in test. Temporarily disabled.')
|
||||
def test_simple_local_post_only_dictionary_request(self):
|
||||
'''
|
||||
|
@ -17,10 +17,10 @@ import threading
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.case import ShellCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.paths import TMP
|
||||
from tests.support.helpers import flaky, expensiveTest
|
||||
from tests.support.mock import MagicMock, patch
|
||||
from tests.support.paths import TMP
|
||||
from tests.support.unit import skipIf
|
||||
|
||||
# Import Salt Libs
|
||||
import salt.exceptions
|
||||
@ -73,11 +73,11 @@ class StateRunnerTest(ShellCase):
|
||||
|
||||
# First, check that we don't have the "bad" output that was displaying in
|
||||
# Issue #31330 where only the highstate outputter was listed
|
||||
self.assertIsNot(bad_out, ret_output)
|
||||
assert bad_out != ret_output
|
||||
|
||||
# Now test that some expected good sample output is present in the return.
|
||||
for item in good_out:
|
||||
self.assertIn(item, ret_output)
|
||||
assert item in ret_output
|
||||
|
||||
def test_orchestrate_nested(self):
|
||||
'''
|
||||
@ -90,8 +90,8 @@ class StateRunnerTest(ShellCase):
|
||||
'state.orchestrate nested-orch.outer',
|
||||
with_retcode=True)
|
||||
|
||||
self.assertFalse(os.path.exists('/tmp/ewu-2016-12-13'))
|
||||
self.assertNotEqual(code, 0)
|
||||
assert os.path.exists('/tmp/ewu-2016-12-13') is False
|
||||
assert code != 0
|
||||
|
||||
def test_orchestrate_state_and_function_failure(self):
|
||||
'''
|
||||
@ -168,7 +168,7 @@ class StateRunnerTest(ShellCase):
|
||||
|
||||
for out in ret_out:
|
||||
for item in out:
|
||||
self.assertIn(item, ret)
|
||||
assert item in ret
|
||||
|
||||
def test_orchestrate_retcode(self):
|
||||
'''
|
||||
@ -199,7 +199,7 @@ class StateRunnerTest(ShellCase):
|
||||
' Result: False'):
|
||||
self.assertIn(result, ret)
|
||||
|
||||
def test_orchestrate_target_doesnt_exists(self):
|
||||
def test_orchestrate_target_doesnt_exist(self):
|
||||
'''
|
||||
test orchestration when target doesn't exist
|
||||
while using multiple states
|
||||
@ -223,7 +223,7 @@ class StateRunnerTest(ShellCase):
|
||||
|
||||
for out in ret_out:
|
||||
for item in out:
|
||||
self.assertIn(item, ret)
|
||||
assert item in ret
|
||||
|
||||
def test_state_event(self):
|
||||
'''
|
||||
@ -241,7 +241,7 @@ class StateRunnerTest(ShellCase):
|
||||
while q.empty():
|
||||
self.run_salt('minion test.ping --static')
|
||||
out = q.get()
|
||||
self.assertIn(expect, six.text_type(out))
|
||||
assert expect in six.text_type(out)
|
||||
|
||||
server_thread.join()
|
||||
|
||||
@ -254,9 +254,9 @@ class StateRunnerTest(ShellCase):
|
||||
def count(thing, listobj):
|
||||
return sum([obj.strip() == thing for obj in listobj])
|
||||
|
||||
self.assertEqual(count('ID: test subset', ret), 1)
|
||||
self.assertEqual(count('Succeeded: 1', ret), 1)
|
||||
self.assertEqual(count('Failed: 0', ret), 1)
|
||||
assert count('ID: test subset', ret) == 1
|
||||
assert count('Succeeded: 1', ret) == 1
|
||||
assert count('Failed: 0', ret) == 1
|
||||
|
||||
def test_orchestrate_salt_function_return_false_failure(self):
|
||||
'''
|
||||
@ -275,10 +275,7 @@ class StateRunnerTest(ShellCase):
|
||||
state_result = ret['data']['master']['salt_|-deploy_check_|-test.false_|-function']['result']
|
||||
func_ret = ret['data']['master']['salt_|-deploy_check_|-test.false_|-function']['changes']
|
||||
|
||||
self.assertEqual(
|
||||
state_result,
|
||||
False,
|
||||
)
|
||||
assert state_result is False
|
||||
|
||||
self.assertEqual(
|
||||
func_ret,
|
||||
|
@ -22,7 +22,7 @@ from tests.support.case import ShellCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.paths import FILES, TMP
|
||||
from tests.support.mixins import ShellCaseCommonTestsMixin
|
||||
from tests.support.helpers import destructiveTest
|
||||
from tests.support.helpers import destructiveTest, flaky
|
||||
from tests.integration.utils import testprogram
|
||||
|
||||
# Import salt libs
|
||||
@ -103,12 +103,10 @@ class CallTest(ShellCase, testprogram.TestProgramCase, ShellCaseCommonTestsMixin
|
||||
log.debug('The pkg: {0} is already installed on the machine'.format(pkg))
|
||||
|
||||
@skipIf(sys.platform.startswith('win'), 'This test does not apply on Win')
|
||||
@flaky
|
||||
def test_user_delete_kw_output(self):
|
||||
ret = self.run_call('-l quiet -d user.delete')
|
||||
self.assertIn(
|
||||
'salt \'*\' user.delete name remove=True force=True',
|
||||
''.join(ret)
|
||||
)
|
||||
assert 'salt \'*\' user.delete name remove=True force=True' in ''.join(ret)
|
||||
|
||||
def test_salt_documentation_too_many_arguments(self):
|
||||
'''
|
||||
|
@ -8,8 +8,9 @@ import time
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ShellCase
|
||||
from tests.support.paths import TMP
|
||||
from tests.support.helpers import flaky
|
||||
from tests.support.mixins import ShellCaseCommonTestsMixin
|
||||
from tests.support.paths import TMP
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.files
|
||||
@ -91,11 +92,13 @@ class MatchTest(ShellCase, ShellCaseCommonTestsMixin):
|
||||
assert minion_in_returns('minion', data) is True
|
||||
assert minion_in_returns('sub_minion', data) is True
|
||||
|
||||
@flaky
|
||||
def test_compound_pillar(self):
|
||||
data = self.run_salt("-C 'I%@companions%three%sarah*' test.ping")
|
||||
assert minion_in_returns('minion', data) is True
|
||||
assert minion_in_returns('sub_minion', data) is True
|
||||
|
||||
@flaky
|
||||
def test_coumpound_pillar_pcre(self):
|
||||
data = self.run_salt("-C 'J%@knights%^(Lancelot|Galahad)$' test.ping")
|
||||
assert minion_in_returns('minion', data) is True
|
||||
@ -320,6 +323,7 @@ class MatchTest(ShellCase, ShellCaseCommonTestsMixin):
|
||||
data = self.run_salt('-d "*" user')
|
||||
self.assertIn('user.add:', data)
|
||||
|
||||
@flaky
|
||||
def test_salt_documentation_arguments_not_assumed(self):
|
||||
'''
|
||||
Test to see if we're not auto-adding '*' and 'sys.doc' to the call
|
||||
@ -331,16 +335,16 @@ class MatchTest(ShellCase, ShellCaseCommonTestsMixin):
|
||||
'see https://github.com/saltstack/salt-jenkins/issues/324.')
|
||||
data = self.run_salt('-d -t 20')
|
||||
if data:
|
||||
self.assertIn('user.add:', data)
|
||||
assert 'user.add:' in data
|
||||
data = self.run_salt('"*" -d -t 20')
|
||||
if data:
|
||||
self.assertIn('user.add:', data)
|
||||
assert 'user.add:' in data
|
||||
data = self.run_salt('"*" -d user -t 20')
|
||||
self.assertIn('user.add:', data)
|
||||
assert 'user.add:' in data
|
||||
data = self.run_salt('"*" sys.doc -d user -t 20')
|
||||
self.assertIn('user.add:', data)
|
||||
assert 'user.add:' in data
|
||||
data = self.run_salt('"*" sys.doc user -t 20')
|
||||
self.assertIn('user.add:', data)
|
||||
assert 'user.add:' in data
|
||||
|
||||
def test_salt_documentation_too_many_arguments(self):
|
||||
'''
|
||||
|
49
tests/integration/ssh/test_key_deploy.py
Normal file
49
tests/integration/ssh/test_key_deploy.py
Normal file
@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Daniel Wallace (daniel@saltstack.com)`
|
||||
|
||||
|
||||
====================================
|
||||
Test Case for --no-key-deploy
|
||||
====================================
|
||||
'''
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
# Import Python Libs
|
||||
import os
|
||||
import json
|
||||
|
||||
# Import Tests Libs
|
||||
from tests.support.case import SSHCase
|
||||
from tests.support.runtests import RUNTIME_VARS
|
||||
|
||||
|
||||
class SSHKeyDeployQuestionCase(SSHCase):
|
||||
|
||||
def _run_ssh(self, arg_str, with_retcode=False, timeout=25, catch_stderr=False):
|
||||
|
||||
arg_str = '-ldebug -c {0} -i --roster-file {1} --out=json localhost {2}'.format(
|
||||
self.get_config_dir(),
|
||||
os.path.join(RUNTIME_VARS.TMP_CONF_DIR, '_ssh', 'roster'),
|
||||
arg_str,
|
||||
)
|
||||
return self.run_script('salt-ssh',
|
||||
arg_str,
|
||||
with_retcode=with_retcode,
|
||||
catch_stderr=catch_stderr,
|
||||
timeout=timeout,
|
||||
raw=True)
|
||||
|
||||
def test_no_key_deploy(self):
|
||||
exp = {
|
||||
'localhost': {
|
||||
'stdout': '',
|
||||
'stderr': "Permission denied (publickey).\r\n",
|
||||
'retcode': 255,
|
||||
},
|
||||
}
|
||||
assert json.loads(self._run_ssh('--no-key-deploy localhost test.ping')) == exp
|
||||
|
||||
def test_key_deploy(self):
|
||||
exp = ['Process took more than 5 seconds to complete. Process Killed!']
|
||||
assert self._run_ssh('localhost test.ping', timeout=5) == exp
|
@ -2515,8 +2515,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
Test blockreplace when prepend_if_not_found=True and block doesn't
|
||||
exist in file.
|
||||
'''
|
||||
expected = self.marker_start + os.linesep + self.content + \
|
||||
self.marker_end + os.linesep + self.without_block
|
||||
expected = self.marker_start + '\n' + self.content + \
|
||||
self.marker_end + '\n' + self.without_block
|
||||
|
||||
# Pass 1: content ends in newline
|
||||
self._write(name, self.without_block)
|
||||
@ -2569,8 +2569,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
exist in file. Test with append_newline explicitly set to True.
|
||||
'''
|
||||
# Pass 1: content ends in newline
|
||||
expected = self.marker_start + os.linesep + self.content + \
|
||||
os.linesep + self.marker_end + os.linesep + self.without_block
|
||||
expected = self.marker_start + '\n' + self.content + \
|
||||
'\n' + self.marker_end + '\n' + self.without_block
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
@ -2595,8 +2595,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
self.assertEqual(self._read(name), expected)
|
||||
|
||||
# Pass 2: content does not end in newline
|
||||
expected = self.marker_start + os.linesep + self.content + \
|
||||
self.marker_end + os.linesep + self.without_block
|
||||
expected = self.marker_start + '\n' + self.content + \
|
||||
self.marker_end + '\n' + self.without_block
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
@ -2627,8 +2627,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
exist in file. Test with append_newline explicitly set to False.
|
||||
'''
|
||||
# Pass 1: content ends in newline
|
||||
expected = self.marker_start + os.linesep + self.content + \
|
||||
self.marker_end + os.linesep + self.without_block
|
||||
expected = self.marker_start + '\n' + self.content + \
|
||||
self.marker_end + '\n' + self.without_block
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
@ -2653,8 +2653,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
self.assertEqual(self._read(name), expected)
|
||||
|
||||
# Pass 2: content does not end in newline
|
||||
expected = self.marker_start + os.linesep + \
|
||||
self.content.rstrip('\r\n') + self.marker_end + os.linesep + \
|
||||
expected = self.marker_start + '\n' + \
|
||||
self.content.rstrip('\r\n') + self.marker_end + '\n' + \
|
||||
self.without_block
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
@ -2685,8 +2685,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
Test blockreplace when append_if_not_found=True and block doesn't
|
||||
exist in file.
|
||||
'''
|
||||
expected = self.without_block + self.marker_start + os.linesep + \
|
||||
self.content + self.marker_end + os.linesep
|
||||
expected = self.without_block + self.marker_start + '\n' + \
|
||||
self.content + self.marker_end + '\n'
|
||||
|
||||
# Pass 1: content ends in newline
|
||||
self._write(name, self.without_block)
|
||||
@ -2739,8 +2739,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
exist in file. Test with append_newline explicitly set to True.
|
||||
'''
|
||||
# Pass 1: content ends in newline
|
||||
expected = self.without_block + self.marker_start + os.linesep + \
|
||||
self.content + os.linesep + self.marker_end + os.linesep
|
||||
expected = self.without_block + self.marker_start + '\n' + \
|
||||
self.content + '\n' + self.marker_end + '\n'
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
@ -2765,8 +2765,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
self.assertEqual(self._read(name), expected)
|
||||
|
||||
# Pass 2: content does not end in newline
|
||||
expected = self.without_block + self.marker_start + os.linesep + \
|
||||
self.content + self.marker_end + os.linesep
|
||||
expected = self.without_block + self.marker_start + '\n' + \
|
||||
self.content + self.marker_end + '\n'
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
@ -2797,8 +2797,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
exist in file. Test with append_newline explicitly set to False.
|
||||
'''
|
||||
# Pass 1: content ends in newline
|
||||
expected = self.without_block + self.marker_start + os.linesep + \
|
||||
self.content + self.marker_end + os.linesep
|
||||
expected = self.without_block + self.marker_start + '\n' + \
|
||||
self.content + self.marker_end + '\n'
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
@ -2823,8 +2823,8 @@ class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
self.assertEqual(self._read(name), expected)
|
||||
|
||||
# Pass 2: content does not end in newline
|
||||
expected = self.without_block + self.marker_start + os.linesep + \
|
||||
self.content.rstrip('\r\n') + self.marker_end + os.linesep
|
||||
expected = self.without_block + self.marker_start + '\n' + \
|
||||
self.content.rstrip('\r\n') + self.marker_end + '\n'
|
||||
self._write(name, self.without_block)
|
||||
ret = self.run_state('file.blockreplace',
|
||||
name=name,
|
||||
|
@ -1065,6 +1065,16 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
|
||||
pkg_targets = _PKG_TARGETS.get(os_family, [])
|
||||
|
||||
if os_family.lower() == 'redhat':
|
||||
# If we're in the Red Hat family first we ensure that
|
||||
# the yum-plugin-versionlock package is installed
|
||||
ret = self.run_state(
|
||||
'pkg.installed',
|
||||
name='yum-plugin-versionlock',
|
||||
refresh=False,
|
||||
)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
||||
# Make sure that we have targets that match the os_family. If this
|
||||
# fails then the _PKG_TARGETS dict above needs to have an entry added,
|
||||
# with two packages that are not installed before these tests are run
|
||||
@ -1088,15 +1098,25 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
refresh=False,
|
||||
)
|
||||
|
||||
# changes from pkg.hold for Red Hat family are different
|
||||
if os_family.lower() == 'redhat':
|
||||
target_changes = {'new': 'hold', 'old': ''}
|
||||
elif os_family.lower() == 'debian':
|
||||
target_changes = {'new': 'hold', 'old': 'install'}
|
||||
|
||||
try:
|
||||
tag = 'pkg_|-{0}_|-{0}_|-installed'.format(target)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
self.assertIn(tag, ret)
|
||||
self.assertIn('changes', ret[tag])
|
||||
self.assertIn(target, ret[tag]['changes'])
|
||||
self.assertEqual(ret[tag]['changes'][target], {'new': 'hold', 'old': 'install'})
|
||||
self.assertEqual(ret[tag]['changes'][target], target_changes)
|
||||
finally:
|
||||
# Clean up, unhold package and remove
|
||||
self.run_function('pkg.unhold', name=target)
|
||||
ret = self.run_state('pkg.removed', name=target)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
if os_family.lower() == 'redhat':
|
||||
ret = self.run_state('pkg.removed',
|
||||
name='yum-plugin-versionlock')
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
@ -8,6 +8,7 @@ integration.modules.test_autoruns
|
||||
integration.modules.test_beacons
|
||||
integration.modules.test_config
|
||||
integration.modules.test_cp
|
||||
integration.modules.test_cmdmod
|
||||
integration.modules.test_data
|
||||
integration.modules.test_disk
|
||||
integration.modules.test_firewall
|
||||
|
Loading…
Reference in New Issue
Block a user