mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
Merge pull request #46494 from rallytime/merge-develop
[develop] Merge forward from 2018.3 to develop
This commit is contained in:
commit
889293cf37
@ -1438,7 +1438,7 @@ This should still be considered a less than secure option, due to the fact
|
||||
that trust is based on just the requesting minion.
|
||||
|
||||
Please see the :ref:`Autoaccept Minions from Grains <tutorial-autoaccept-grains>`
|
||||
documentation for more infomation.
|
||||
documentation for more information.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
@ -2212,7 +2212,7 @@ This allows the following more convenient syntax to be used:
|
||||
# (this comment remains in the rendered template)
|
||||
## ensure all the formula services are running
|
||||
% for service in formula_services:
|
||||
enable_service_{{ serivce }}:
|
||||
enable_service_{{ service }}:
|
||||
service.running:
|
||||
name: {{ service }}
|
||||
% endfor
|
||||
|
@ -2519,7 +2519,7 @@ The grains that should be sent to the master on authentication to decide if
|
||||
the minion's key should be accepted automatically.
|
||||
|
||||
Please see the :ref:`Autoaccept Minions from Grains <tutorial-autoaccept-grains>`
|
||||
documentation for more infomation.
|
||||
documentation for more information.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -71,7 +71,7 @@ The generated grain information will appear similar to:
|
||||
provider: my_ec2:ec2
|
||||
profile: ec2-web
|
||||
|
||||
The generation of the salt-cloud grain can be surpressed by the
|
||||
The generation of the salt-cloud grain can be suppressed by the
|
||||
option ``enable_cloud_grains: 'False'`` in the cloud configuration file.
|
||||
|
||||
Cloud Configuration Syntax
|
||||
|
@ -125,7 +125,7 @@ to start that machine running.
|
||||
The "magic packet" must be sent by an existing salt minion which is on
|
||||
the same network segment as the target machine. (Or your router
|
||||
must be set up especially to route WoL packets.) Your target machine
|
||||
must be set up to listen for WoL and to respond appropriatly.
|
||||
must be set up to listen for WoL and to respond appropriately.
|
||||
|
||||
You must provide the Salt node id of the machine which will send
|
||||
the WoL packet \(parameter ``wol_sender_node``\), and
|
||||
|
@ -153,7 +153,7 @@ starts at the root of the state tree or pillar.
|
||||
Errors
|
||||
======
|
||||
|
||||
Saltstack allows to raise custom errors using the ``raise`` jinja function.
|
||||
Saltstack allows raising custom errors using the ``raise`` jinja function.
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
@ -1122,7 +1122,7 @@ Returns:
|
||||
'body': '{
|
||||
"userId": 1,
|
||||
"id": 1,
|
||||
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
|
||||
"title": "sunt aut facere repellat provident occaecati excepturi option reprehenderit",
|
||||
"body": "quia et suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto"
|
||||
}'
|
||||
}
|
||||
|
@ -338,8 +338,8 @@ Given the above setup, the orchestration will be carried out as follows:
|
||||
|
||||
.. _orchestrate-runner-parsing-results-programatically:
|
||||
|
||||
Parsing Results Programatically
|
||||
-------------------------------
|
||||
Parsing Results Programmatically
|
||||
--------------------------------
|
||||
|
||||
Orchestration jobs return output in a specific data structure. That data
|
||||
structure is represented differently depending on the outputter used. With the
|
||||
|
@ -146,7 +146,7 @@ Changes:
|
||||
- **PR** `#36690`_: (*rallytime*) [2016.3] Merge forward from 2015.8 to 2016.3
|
||||
- **PR** `#36680`_: (*rallytime*) [2016.3] Merge forward from 2015.8 to 2016.3
|
||||
- **PR** `#36659`_: (*terminalmage*) Support dynamic env in new-style git_pillar
|
||||
- **PR** `#36538`_: (*clinta*) daemon-reload on call to service.avaliable
|
||||
- **PR** `#36538`_: (*clinta*) daemon-reload on call to service.available
|
||||
- **PR** `#36616`_: (*cro*) Zypper fix test
|
||||
- **PR** `#36621`_: (*terminalmage*) Fix shadowed builtins
|
||||
- **PR** `#36636`_: (*rallytime*) Back-port `#36618`_ to 2016.3
|
||||
|
@ -503,7 +503,7 @@ setting a ``port`` option under the Master's ``discovery`` configuration:
|
||||
|
||||
.. note::
|
||||
When using a port number other than the default, the Minion's ``discovery``
|
||||
configuraton must *also* have a port specified, otherwise the Minion will
|
||||
configuration must *also* have a port specified, otherwise the Minion will
|
||||
still attempt to contact the Master on port ``4520``.
|
||||
|
||||
**Minion configuration**
|
||||
@ -528,7 +528,7 @@ Connection to a type instead of DNS
|
||||
By now each Minion was connecting to a Master by DNS or IP address. From now on it is possible
|
||||
also to connect to a _type_ of a Master. For example, in a network there are three different
|
||||
Masters, each corresponds for a particular niche or environment or specific role etc. The Minion
|
||||
is supposed to connect only to one of those Masters that is described approriately.
|
||||
is supposed to connect only to one of those Masters that is described appropriately.
|
||||
|
||||
To achieve such an effect, each `/etc/salt/master` configuration should have a `discovery` option,
|
||||
which should have a `mapping` element with arbitrary key/value pairs. The same configuration should
|
||||
@ -701,7 +701,7 @@ The generated grain information will appear similar to:
|
||||
provider: my_ec2:ec2
|
||||
profile: ec2-web
|
||||
|
||||
The generation of salt-cloud grains can be surpressed by the
|
||||
The generation of salt-cloud grains can be suppressed by the
|
||||
option ``enable_cloud_grains: 'False'`` in the cloud configuration file.
|
||||
|
||||
Upgraded Saltify Driver
|
||||
@ -766,7 +766,7 @@ Terms usable in yaml files Description
|
||||
========================== ===========
|
||||
classes A list of classes that will be processed in order
|
||||
states A list of states that will be returned by master_tops function
|
||||
pillars A yaml dictionnary that will be returned by the ext_pillar function
|
||||
pillars A yaml dictionary that will be returned by the ext_pillar function
|
||||
environment Node saltenv that will be used by master_tops
|
||||
========================== ===========
|
||||
|
||||
|
@ -10,7 +10,7 @@ Slots
|
||||
future releases
|
||||
|
||||
Many times it is useful to store the results of a command during the course of
|
||||
an execution. Salt Slots are designed to allow to store this information and
|
||||
an execution. Salt Slots are designed to allow you to store this information and
|
||||
use it later during the :ref:`highstate <running-highstate>` or other job
|
||||
execution.
|
||||
|
||||
|
@ -327,14 +327,14 @@ Here's a summary of the command line options:
|
||||
-U If set, fully upgrade the system prior to bootstrapping Salt
|
||||
-I If set, allow insecure connections while downloading any files. For
|
||||
example, pass '--no-check-certificate' to 'wget' or '--insecure' to
|
||||
'curl'. On Debian and Ubuntu, using this option with -U allows to obtain
|
||||
'curl'. On Debian and Ubuntu, using this option with -U allows one to obtain
|
||||
GnuPG archive keys insecurely if distro has changed release signatures.
|
||||
-F Allow copied files to overwrite existing (config, init.d, etc)
|
||||
-K If set, keep the temporary files in the temporary directories specified
|
||||
with -c and -k
|
||||
-C Only run the configuration function. Implies -F (forced overwrite).
|
||||
To overwrite Master or Syndic configs, -M or -S, respectively, must
|
||||
also be specified. Salt installation will be ommitted, but some of the
|
||||
also be specified. Salt installation will be omitted, but some of the
|
||||
dependencies could be installed to write configuration with -j or -J.
|
||||
-A Pass the salt-master DNS name or IP. This will be stored under
|
||||
${BS_SALT_ETC_DIR}/minion.d/99-master-address.conf
|
||||
|
@ -70,7 +70,7 @@ Mon Oct 12 08:48:25 UTC 2015 - dmacvicar@suse.de
|
||||
-------------------------------------------------------------------
|
||||
Mon Oct 12 08:19:45 UTC 2015 - dmacvicar@suse.de
|
||||
|
||||
- allow to disable docs in preparation for building
|
||||
- allow one to disable docs in preparation for building
|
||||
on other platforms without all dependencies.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
@ -103,8 +103,8 @@ import time
|
||||
import salt.cache
|
||||
import salt.config as config
|
||||
import salt.loader
|
||||
import salt.utils
|
||||
import salt.utils.cloud
|
||||
import salt.utils.files
|
||||
import salt.utils.yaml
|
||||
import salt.ext.six as six
|
||||
import salt.version
|
||||
@ -1003,7 +1003,7 @@ def request_instance(vm_):
|
||||
)
|
||||
if ssh_publickeyfile is not None:
|
||||
try:
|
||||
with salt.utils.fopen(ssh_publickeyfile, 'r') as spkc_:
|
||||
with salt.utils.files.fopen(ssh_publickeyfile, 'r') as spkc_:
|
||||
ssh_publickeyfile_contents = spkc_.read()
|
||||
except Exception as exc:
|
||||
raise SaltCloudConfigError(
|
||||
@ -1219,7 +1219,7 @@ def request_instance(vm_):
|
||||
|
||||
if userdata_file:
|
||||
if os.path.exists(userdata_file):
|
||||
with salt.utils.fopen(userdata_file, 'r') as fh_:
|
||||
with salt.utils.files.fopen(userdata_file, 'r') as fh_:
|
||||
userdata = fh_.read()
|
||||
|
||||
if userdata and userdata_template:
|
||||
|
@ -648,7 +648,7 @@ def _get_properties(path="", method="GET", forced_params=None):
|
||||
# Browse all path elements but last
|
||||
for elem in path_levels[:-1]:
|
||||
search_path += '/' + elem
|
||||
# Lookup for a dictionnary with path = "requested path" in list" and return its children
|
||||
# Lookup for a dictionary with path = "requested path" in list" and return its children
|
||||
sub = (item for item in sub if item["path"] == search_path).next()['children']
|
||||
# Get leaf element in path
|
||||
search_path += '/' + path_levels[-1]
|
||||
|
@ -345,7 +345,7 @@ __usage() {
|
||||
with -c and -k
|
||||
-C Only run the configuration function. Implies -F (forced overwrite).
|
||||
To overwrite Master or Syndic configs, -M or -S, respectively, must
|
||||
also be specified. Salt installation will be ommitted, but some of the
|
||||
also be specified. Salt installation will be omitted, but some of the
|
||||
dependencies could be installed to write configuration with -j or -J.
|
||||
-A Pass the salt-master DNS name or IP. This will be stored under
|
||||
\${BS_SALT_ETC_DIR}/minion.d/99-master-address.conf
|
||||
|
@ -252,7 +252,7 @@ VALID_OPTS = {
|
||||
# Force the minion into a single environment when it fetches files from the master
|
||||
'saltenv': (type(None), six.string_types),
|
||||
|
||||
# Prevent saltenv from being overriden on the command line
|
||||
# Prevent saltenv from being overridden on the command line
|
||||
'lock_saltenv': bool,
|
||||
|
||||
# Force the minion into a single pillar root when it fetches pillar data from the master
|
||||
@ -2320,7 +2320,7 @@ def prepend_root_dir(opts, path_options):
|
||||
# drive is not prefixed on a config option
|
||||
pass
|
||||
elif os.path.isabs(path):
|
||||
# Absolute path (not default or overriden root_dir)
|
||||
# Absolute path (not default or overridden root_dir)
|
||||
# No prepending required
|
||||
continue
|
||||
# Prepending the root dir
|
||||
|
@ -46,7 +46,7 @@ Example of usage
|
||||
08:33:57 gtmanbot > gtmanfred: pong
|
||||
08:34:02 @gtmanfred > !echo ping
|
||||
08:34:02 gtmanbot > ping
|
||||
08:34:17 @gtmanfred > !event test/tag/ircbot irc is usefull
|
||||
08:34:17 @gtmanfred > !event test/tag/ircbot irc is useful
|
||||
08:34:17 gtmanbot > gtmanfred: TaDa!
|
||||
|
||||
.. code-block:: text
|
||||
|
@ -267,7 +267,7 @@ class SlackClient(object):
|
||||
|
||||
def can_user_run(self, user, command, groups):
|
||||
'''
|
||||
Break out the permissions into the folowing:
|
||||
Break out the permissions into the following:
|
||||
|
||||
Check whether a user is in any group, including whether a group has the '*' membership
|
||||
|
||||
@ -282,7 +282,7 @@ class SlackClient(object):
|
||||
|
||||
:rtype: tuple
|
||||
:returns: On a successful permitting match, returns 2-element tuple that contains
|
||||
the name of the group that successfuly matched, and a dictionary containing
|
||||
the name of the group that successfully matched, and a dictionary containing
|
||||
the configuration of the group so it can be referenced.
|
||||
|
||||
On failure it returns an empty tuple
|
||||
@ -400,7 +400,7 @@ class SlackClient(object):
|
||||
When encountering an error (e.g. invalid message), yields {}, the caller can proceed to the next message
|
||||
|
||||
When the websocket being read from has given up all its messages, yields {'done': True} to
|
||||
indicate that the caller has read all of the relevent data for now, and should continue
|
||||
indicate that the caller has read all of the relevant data for now, and should continue
|
||||
its own processing and check back for more data later.
|
||||
|
||||
This relies on the caller sleeping between checks, otherwise this could flood
|
||||
|
@ -1084,7 +1084,7 @@ def upgrade(refresh=True, dist_upgrade=False, **kwargs):
|
||||
<value> seconds
|
||||
|
||||
download_only
|
||||
Only donwload the packages, don't unpack or install them
|
||||
Only download the packages, don't unpack or install them
|
||||
|
||||
.. versionadded:: 2018.3.0
|
||||
|
||||
|
@ -3425,10 +3425,10 @@ def powershell_all(cmd,
|
||||
empty Powershell output (which would result in an exception). Instead we
|
||||
treat this as a special case and one of two things will happen:
|
||||
|
||||
- If the value of the ``force_list`` paramater is ``True``, then the
|
||||
- If the value of the ``force_list`` parameter is ``True``, then the
|
||||
``result`` field of the return dictionary will be an empty list.
|
||||
|
||||
- If the value of the ``force_list`` paramater is ``False``, then the
|
||||
- If the value of the ``force_list`` parameter is ``False``, then the
|
||||
return dictionary **will not have a result key added to it**. We aren't
|
||||
setting ``result`` to ``None`` in this case, because ``None`` is the
|
||||
Python representation of "null" in JSON. (We likewise can't use ``False``
|
||||
@ -3441,20 +3441,20 @@ def powershell_all(cmd,
|
||||
content, and the type of the resulting Python object is other than ``list``
|
||||
then one of two things will happen:
|
||||
|
||||
- If the value of the ``force_list`` paramater is ``True``, then the
|
||||
- If the value of the ``force_list`` parameter is ``True``, then the
|
||||
``result`` field will be a singleton list with the Python object as its
|
||||
sole member.
|
||||
|
||||
- If the value of the ``force_list`` paramater is ``False``, then the value
|
||||
- If the value of the ``force_list`` parameter is ``False``, then the value
|
||||
of ``result`` will be the unmodified Python object.
|
||||
|
||||
If Powershell's output is not an empty string, Python is able to parse its
|
||||
content, and the type of the resulting Python object is ``list``, then the
|
||||
value of ``result`` will be the unmodified Python object. The
|
||||
``force_list`` paramater has no effect in this case.
|
||||
``force_list`` parameter has no effect in this case.
|
||||
|
||||
.. note::
|
||||
An example of why the ``force_list`` paramater is useful is as
|
||||
An example of why the ``force_list`` parameter is useful is as
|
||||
follows: The Powershell command ``dir x | Convert-ToJson`` results in
|
||||
|
||||
- no output when x is an empty directory.
|
||||
@ -3602,7 +3602,7 @@ def powershell_all(cmd,
|
||||
where characters may be dropped or incorrectly converted when executed.
|
||||
Default is False.
|
||||
|
||||
:param bool force_list: The purpose of this paramater is described in the
|
||||
:param bool force_list: The purpose of this parameter is described in the
|
||||
preamble of this function's documentation. Default value is False.
|
||||
|
||||
:param list success_retcodes: This parameter will be allow a list of
|
||||
|
@ -2433,8 +2433,7 @@ def blockreplace(path,
|
||||
backup='.bak',
|
||||
dry_run=False,
|
||||
show_changes=True,
|
||||
append_newline=False,
|
||||
):
|
||||
append_newline=False):
|
||||
'''
|
||||
.. versionadded:: 2014.1.0
|
||||
|
||||
@ -2481,18 +2480,30 @@ def blockreplace(path,
|
||||
The file extension to use for a backup of the file if any edit is made.
|
||||
Set to ``False`` to skip making a backup.
|
||||
|
||||
dry_run
|
||||
Don't make any edits to the file.
|
||||
dry_run : False
|
||||
If ``True``, do not make any edits to the file and simply return the
|
||||
changes that *would* be made.
|
||||
|
||||
show_changes
|
||||
Output a unified diff of the old file and the new file. If ``False``,
|
||||
return a boolean if any changes were made.
|
||||
show_changes : True
|
||||
Controls how changes are presented. If ``True``, this function will
|
||||
return a unified diff of the changes made. If False, then it will
|
||||
return a boolean (``True`` if any changes were made, otherwise
|
||||
``False``).
|
||||
|
||||
append_newline:
|
||||
Append a newline to the content block. For more information see:
|
||||
https://github.com/saltstack/salt/issues/33686
|
||||
append_newline : False
|
||||
Controls whether or not a newline is appended to the content block. If
|
||||
the value of this argument is ``True`` then a newline will be added to
|
||||
the content block. If it is ``False``, then a newline will *not* be
|
||||
added to the content block. If it is ``None`` then a newline will only
|
||||
be added to the content block if it does not already end in a newline.
|
||||
|
||||
.. versionadded:: 2016.3.4
|
||||
.. versionchanged:: 2017.7.5,2018.3.1
|
||||
New behavior added when value is ``None``.
|
||||
.. versionchanged:: Fluorine
|
||||
The default value of this argument will change to ``None`` to match
|
||||
the behavior of the :py:func:`file.blockreplace state
|
||||
<salt.states.file.blockreplace>`
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -2502,87 +2513,137 @@ def blockreplace(path,
|
||||
'#-- end managed zone foobar --' $'10.0.1.1 foo.foobar\\n10.0.1.2 bar.foobar' True
|
||||
|
||||
'''
|
||||
path = os.path.expanduser(path)
|
||||
|
||||
if not os.path.exists(path):
|
||||
raise SaltInvocationError('File not found: {0}'.format(path))
|
||||
|
||||
if append_if_not_found and prepend_if_not_found:
|
||||
raise SaltInvocationError(
|
||||
'Only one of append and prepend_if_not_found is permitted'
|
||||
)
|
||||
|
||||
path = os.path.expanduser(path)
|
||||
|
||||
if not os.path.exists(path):
|
||||
raise SaltInvocationError('File not found: {0}'.format(path))
|
||||
|
||||
if not __utils__['files.is_text'](path):
|
||||
raise SaltInvocationError(
|
||||
'Cannot perform string replacements on a binary file: {0}'
|
||||
.format(path)
|
||||
)
|
||||
|
||||
# Search the file; track if any changes have been made for the return val
|
||||
if append_newline is None and not content.endswith((os.linesep, '\n')):
|
||||
append_newline = True
|
||||
|
||||
# Split the content into a list of lines, removing newline characters. To
|
||||
# ensure that we handle both Windows and POSIX newlines, first split on
|
||||
# Windows newlines, and then split on POSIX newlines.
|
||||
split_content = []
|
||||
for win_line in content.split('\r\n'):
|
||||
for content_line in win_line.split('\n'):
|
||||
split_content.append(content_line)
|
||||
|
||||
line_count = len(split_content)
|
||||
|
||||
has_changes = False
|
||||
orig_file = []
|
||||
new_file = []
|
||||
in_block = False
|
||||
old_content = ''
|
||||
done = False
|
||||
# we do not use in_place editing to avoid file attrs modifications when
|
||||
block_found = False
|
||||
linesep = None
|
||||
|
||||
def _add_content(linesep, lines=None, include_marker_start=True,
|
||||
end_line=None):
|
||||
if lines is None:
|
||||
lines = []
|
||||
include_marker_start = True
|
||||
|
||||
if end_line is None:
|
||||
end_line = marker_end
|
||||
end_line = end_line.rstrip('\r\n') + linesep
|
||||
|
||||
if include_marker_start:
|
||||
lines.append(marker_start + linesep)
|
||||
|
||||
if split_content:
|
||||
for index, content_line in enumerate(split_content, 1):
|
||||
if index != line_count:
|
||||
lines.append(content_line + linesep)
|
||||
else:
|
||||
# We're on the last line of the content block
|
||||
if append_newline:
|
||||
lines.append(content_line + linesep)
|
||||
lines.append(end_line)
|
||||
else:
|
||||
lines.append(content_line + end_line)
|
||||
else:
|
||||
lines.append(end_line)
|
||||
|
||||
return lines
|
||||
|
||||
# We do not use in-place editing to avoid file attrs modifications when
|
||||
# no changes are required and to avoid any file access on a partially
|
||||
# written file.
|
||||
# we could also use salt.utils.filebuffer.BufferedReader
|
||||
#
|
||||
# We could also use salt.utils.filebuffer.BufferedReader
|
||||
try:
|
||||
fi_file = fileinput.input(path,
|
||||
inplace=False, backup=False,
|
||||
bufsize=1, mode='rb')
|
||||
for line in fi_file:
|
||||
fi_file = fileinput.input(
|
||||
path,
|
||||
inplace=False,
|
||||
backup=False,
|
||||
bufsize=1,
|
||||
mode='rb')
|
||||
|
||||
for line in fi_file:
|
||||
line = salt.utils.stringutils.to_unicode(line)
|
||||
result = line
|
||||
write_line_to_new_file = True
|
||||
|
||||
if linesep is None:
|
||||
# Auto-detect line separator
|
||||
if line.endswith('\r\n'):
|
||||
linesep = '\r\n'
|
||||
elif line.endswith('\n'):
|
||||
linesep = '\n'
|
||||
else:
|
||||
# No newline(s) in file, fall back to system's linesep
|
||||
linesep = os.linesep
|
||||
|
||||
if marker_start in line:
|
||||
# managed block start found, start recording
|
||||
# We've entered the content block
|
||||
in_block = True
|
||||
|
||||
else:
|
||||
if in_block:
|
||||
if marker_end in line:
|
||||
# end of block detected
|
||||
# We're not going to write the lines from the old file to
|
||||
# the new file until we have exited the block.
|
||||
write_line_to_new_file = False
|
||||
|
||||
marker_end_pos = line.find(marker_end)
|
||||
if marker_end_pos != -1:
|
||||
# End of block detected
|
||||
in_block = False
|
||||
# We've found and exited the block
|
||||
block_found = True
|
||||
|
||||
# Handle situations where there may be multiple types
|
||||
# of line endings in the same file. Separate the content
|
||||
# into lines. Account for Windows-style line endings
|
||||
# using os.linesep, then by linux-style line endings
|
||||
# using '\n'
|
||||
split_content = []
|
||||
for linesep_line in content.split(os.linesep):
|
||||
for content_line in linesep_line.split('\n'):
|
||||
split_content.append(content_line)
|
||||
|
||||
# Trim any trailing new lines to avoid unwanted
|
||||
# additional new lines
|
||||
while not split_content[-1]:
|
||||
split_content.pop()
|
||||
|
||||
# push new block content in file
|
||||
for content_line in split_content:
|
||||
new_file.append(content_line + os.linesep)
|
||||
|
||||
done = True
|
||||
|
||||
else:
|
||||
# remove old content, but keep a trace
|
||||
old_content += line
|
||||
result = None
|
||||
# else: we are not in the marked block, keep saving things
|
||||
_add_content(linesep, lines=new_file,
|
||||
include_marker_start=False,
|
||||
end_line=line[marker_end_pos:])
|
||||
|
||||
# Save the line from the original file
|
||||
orig_file.append(line)
|
||||
if result is not None:
|
||||
new_file.append(result)
|
||||
# end for. If we are here without block management we maybe have some problems,
|
||||
# or we need to initialise the marked block
|
||||
if write_line_to_new_file:
|
||||
new_file.append(line)
|
||||
|
||||
except (IOError, OSError) as exc:
|
||||
raise CommandExecutionError(
|
||||
'Failed to read from {0}: {1}'.format(path, exc)
|
||||
)
|
||||
finally:
|
||||
if linesep is None:
|
||||
# If the file was empty, we will not have set linesep yet. Assume
|
||||
# the system's line separator. This is needed for when we
|
||||
# prepend/append later on.
|
||||
linesep = os.linesep
|
||||
try:
|
||||
fi_file.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if in_block:
|
||||
# unterminated block => bad, always fail
|
||||
@ -2590,35 +2651,27 @@ def blockreplace(path,
|
||||
'Unterminated marked block. End of file reached before marker_end.'
|
||||
)
|
||||
|
||||
if not done:
|
||||
if not block_found:
|
||||
if prepend_if_not_found:
|
||||
# add the markers and content at the beginning of file
|
||||
new_file.insert(0, marker_end + os.linesep)
|
||||
if append_newline is True:
|
||||
new_file.insert(0, content + os.linesep)
|
||||
else:
|
||||
new_file.insert(0, content)
|
||||
new_file.insert(0, marker_start + os.linesep)
|
||||
done = True
|
||||
prepended_content = _add_content(linesep)
|
||||
prepended_content.extend(new_file)
|
||||
new_file = prepended_content
|
||||
block_found = True
|
||||
elif append_if_not_found:
|
||||
# Make sure we have a newline at the end of the file
|
||||
if 0 != len(new_file):
|
||||
if not new_file[-1].endswith(os.linesep):
|
||||
new_file[-1] += os.linesep
|
||||
if not new_file[-1].endswith(linesep):
|
||||
new_file[-1] += linesep
|
||||
# add the markers and content at the end of file
|
||||
new_file.append(marker_start + os.linesep)
|
||||
if append_newline is True:
|
||||
new_file.append(content + os.linesep)
|
||||
else:
|
||||
new_file.append(content)
|
||||
new_file.append(marker_end + os.linesep)
|
||||
done = True
|
||||
_add_content(linesep, lines=new_file)
|
||||
block_found = True
|
||||
else:
|
||||
raise CommandExecutionError(
|
||||
'Cannot edit marked block. Markers were not found in file.'
|
||||
)
|
||||
|
||||
if done:
|
||||
if block_found:
|
||||
diff = ''.join(difflib.unified_diff(orig_file, new_file))
|
||||
has_changes = diff is not ''
|
||||
if has_changes and not dry_run:
|
||||
|
1290
salt/modules/git.py
1290
salt/modules/git.py
File diff suppressed because it is too large
Load Diff
@ -178,7 +178,7 @@ If you wish to customize the document format:
|
||||
- mode: '0640'
|
||||
|
||||
|
||||
Some `replace_text_regex` values that might be helpfull.
|
||||
Some `replace_text_regex` values that might be helpful.
|
||||
|
||||
## CERTS
|
||||
'-----BEGIN RSA PRIVATE KEY-----[\r\n\t\f\S]{0,2200}': 'XXXXXXX'
|
||||
|
@ -367,7 +367,7 @@ def get_host_mac(name=None, allow_array=False, **api_opts):
|
||||
'''
|
||||
Get mac address from host record.
|
||||
|
||||
Use `allow_array` to return possible mutiple values.
|
||||
Use `allow_array` to return possible multiple values.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -390,7 +390,7 @@ def get_host_ipv4(name=None, mac=None, allow_array=False, **api_opts):
|
||||
'''
|
||||
Get ipv4 address from host record.
|
||||
|
||||
Use `allow_array` to return possible mutiple values.
|
||||
Use `allow_array` to return possible multiple values.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -446,7 +446,7 @@ def get_host_ipv6addr_info(ipv6addr=None, mac=None,
|
||||
def get_network(ipv4addr=None, network=None, return_fields=None, **api_opts):
|
||||
'''
|
||||
Get list of all networks.
|
||||
This is helpfull when looking up subnets to
|
||||
This is helpful when looking up subnets to
|
||||
use with func:nextavailableip
|
||||
|
||||
This call is offen slow and not cached!
|
||||
|
@ -189,7 +189,7 @@ def upgrade(reboot=False, at_time=None):
|
||||
def upgrade_available():
|
||||
'''
|
||||
Detect if a new kernel version is available in the repositories.
|
||||
Returns True if a new kernel is avaliable, False otherwise.
|
||||
Returns True if a new kernel is available, False otherwise.
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
@ -182,7 +182,7 @@ def upgrade(reboot=False, at_time=None):
|
||||
def upgrade_available():
|
||||
'''
|
||||
Detect if a new kernel version is available in the repositories.
|
||||
Returns True if a new kernel is avaliable, False otherwise.
|
||||
Returns True if a new kernel is available, False otherwise.
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
@ -206,7 +206,7 @@ def destroy_node(node_id, profile, **libcloud_kwargs):
|
||||
'''
|
||||
Destroy a node in the cloud
|
||||
|
||||
:param node_id: Unique ID of the node to destory
|
||||
:param node_id: Unique ID of the node to destroy
|
||||
:type node_id: ``str``
|
||||
|
||||
:param profile: The profile key
|
||||
|
@ -256,7 +256,7 @@ def rotate(name, pattern=None, conf_file=default_conf, **kwargs):
|
||||
``name`` and ``pattern`` were kept for backwards compatibility reasons.
|
||||
|
||||
``name`` is an alias for the ``entryname`` argument, ``pattern`` is an alias
|
||||
for ``log_file``. These aliasses wil only be used if the ``entryname`` and
|
||||
for ``log_file``. These aliases will only be used if the ``entryname`` and
|
||||
``log_file`` arguments are not passed.
|
||||
|
||||
For a full list of arguments see ```logadm.show_args```.
|
||||
|
@ -153,7 +153,8 @@ def latest_version(*names, **kwargs):
|
||||
continue
|
||||
|
||||
cur = pkgs.get(pkgname, '')
|
||||
if not cur or salt.utils.compare_versions(ver1=cur,
|
||||
if not cur or salt.utils.versions.compare(
|
||||
ver1=cur,
|
||||
oper='<',
|
||||
ver2=pkgver):
|
||||
ret[pkgname] = pkgver
|
||||
|
@ -13,7 +13,6 @@ from subprocess import Popen, PIPE
|
||||
|
||||
# Import Salt libs
|
||||
from salt.ext import six
|
||||
from salt.client import Caller
|
||||
|
||||
|
||||
ArgumentParser = object
|
||||
@ -105,8 +104,7 @@ def xccdf(params):
|
||||
success = _OSCAP_EXIT_CODES_MAP[proc.returncode]
|
||||
returncode = proc.returncode
|
||||
if success:
|
||||
caller = Caller()
|
||||
caller.cmd('cp.push_dir', tempdir)
|
||||
__salt__['cp.push_dir'](tempdir)
|
||||
shutil.rmtree(tempdir, ignore_errors=True)
|
||||
upload_dir = tempdir
|
||||
|
||||
|
@ -728,7 +728,7 @@ def import_file(source, use_32bit_registry=False):
|
||||
can be either a local file path or a URL type supported by salt
|
||||
(e.g. ``salt://salt_master_path``).
|
||||
|
||||
:param bool use_32bit_registry: If the value of this paramater is ``True``
|
||||
:param bool use_32bit_registry: If the value of this parameter is ``True``
|
||||
then the ``REG`` file will be imported into the Windows 32 bit registry.
|
||||
Otherwise the Windows 64 bit registry will be used.
|
||||
|
||||
|
@ -231,7 +231,7 @@ def soft_kill(jid, state_id=None):
|
||||
this instructs a running state to safely exit at a given
|
||||
state id. This needs to pass in the jid of the running state.
|
||||
If a state_id is not passed then the jid referenced will be safely exited
|
||||
at the begining of the next state run.
|
||||
at the beginning of the next state run.
|
||||
|
||||
The given state id is the id got a given state execution, so given a state
|
||||
that looks like this:
|
||||
@ -264,7 +264,7 @@ def pause(jid, state_id=None, duration=None):
|
||||
Set up a state id pause, this instructs a running state to pause at a given
|
||||
state id. This needs to pass in the jid of the running state and can
|
||||
optionally pass in a duration in seconds. If a state_id is not passed then
|
||||
the jid referenced will be paused at the begining of the next state run.
|
||||
the jid referenced will be paused at the beginning of the next state run.
|
||||
|
||||
The given state id is the id got a given state execution, so given a state
|
||||
that looks like this:
|
||||
|
@ -3944,7 +3944,7 @@ def create_dvs(dvs_dict, dvs_name, service_instance=None):
|
||||
Note: The ``dvs_name`` param will override any name set in ``dvs_dict``.
|
||||
|
||||
dvs_dict
|
||||
Dict representation of the new DVS (exmaple in salt.states.dvs)
|
||||
Dict representation of the new DVS (example in salt.states.dvs)
|
||||
|
||||
dvs_name
|
||||
Name of the DVS to be created.
|
||||
@ -4019,7 +4019,7 @@ def update_dvs(dvs_dict, dvs, service_instance=None):
|
||||
|
||||
dvs_dict
|
||||
Dictionary with the values the DVS should be update with
|
||||
(exmaple in salt.states.dvs)
|
||||
(example in salt.states.dvs)
|
||||
|
||||
dvs
|
||||
Name of the DVS to be updated.
|
||||
@ -4479,7 +4479,7 @@ def create_dvportgroup(portgroup_dict, portgroup_name, dvs,
|
||||
|
||||
portgroup_dict
|
||||
Dictionary with the config values the portgroup should be created with
|
||||
(exmaple in salt.states.dvs).
|
||||
(example in salt.states.dvs).
|
||||
|
||||
portgroup_name
|
||||
Name of the portgroup to be created.
|
||||
@ -4526,7 +4526,7 @@ def update_dvportgroup(portgroup_dict, portgroup, dvs, service_instance=True):
|
||||
|
||||
portgroup_dict
|
||||
Dictionary with the values the portgroup should be update with
|
||||
(exmaple in salt.states.dvs).
|
||||
(example in salt.states.dvs).
|
||||
|
||||
portgroup
|
||||
Name of the portgroup to be updated.
|
||||
@ -4813,7 +4813,7 @@ def create_storage_policy(policy_name, policy_dict, service_instance=None):
|
||||
|
||||
policy_dict
|
||||
Dictionary containing the changes to apply to the policy.
|
||||
(exmaple in salt.states.pbm)
|
||||
(example in salt.states.pbm)
|
||||
|
||||
service_instance
|
||||
Service instance (vim.ServiceInstance) of the vCenter.
|
||||
@ -4853,7 +4853,7 @@ def update_storage_policy(policy, policy_dict, service_instance=None):
|
||||
|
||||
policy_dict
|
||||
Dictionary containing the changes to apply to the policy.
|
||||
(exmaple in salt.states.pbm)
|
||||
(example in salt.states.pbm)
|
||||
|
||||
service_instance
|
||||
Service instance (vim.ServiceInstance) of the vCenter.
|
||||
@ -6472,7 +6472,7 @@ def configure_host_cache(enabled, datastore=None, swap_size_MiB=None,
|
||||
|
||||
swap_size_MiB
|
||||
Swap size in Mibibytes. Needs to be set if enabled is ``true``. Must be
|
||||
smaller thant the datastore size.
|
||||
smaller than the datastore size.
|
||||
|
||||
service_instance
|
||||
Service instance (vim.ServiceInstance) of the vCenter/ESXi host.
|
||||
@ -7595,7 +7595,7 @@ def _apply_hard_disk(unit_number, key, operation, disk_label=None, size=None,
|
||||
Action which should be done on the device add or edit
|
||||
|
||||
disk_label
|
||||
Label of the new disk, can be overriden
|
||||
Label of the new disk, can be overridden
|
||||
|
||||
size
|
||||
Size of the disk
|
||||
|
@ -1605,7 +1605,7 @@ def check_perms(path,
|
||||
``True``.
|
||||
|
||||
reset (bool):
|
||||
``True`` wil show what permisisons will be removed by resetting the
|
||||
``True`` will show what permisisons will be removed by resetting the
|
||||
DACL. ``False`` will do nothing. Default is ``False``.
|
||||
|
||||
Returns:
|
||||
|
@ -1058,7 +1058,7 @@ def install(name=None,
|
||||
This parameter is ignored if ``pkgs`` or ``sources`` is passed.
|
||||
|
||||
resolve_capabilities
|
||||
If this option is set to True zypper will take capabilites into
|
||||
If this option is set to True zypper will take capabilities into
|
||||
account. In this case names which are just provided by a package
|
||||
will get installed. Default is False.
|
||||
|
||||
|
@ -29,7 +29,7 @@ in <> brackets) in the url in order to populate pillar data based on the grain v
|
||||
|
||||
.. versionchanged:: 2018.3.0
|
||||
|
||||
If %s is present in the url, it will be automaticaly replaced by the minion_id:
|
||||
If %s is present in the url, it will be automatically replaced by the minion_id:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -29,7 +29,7 @@ in <> brackets) in the url in order to populate pillar data based on the grain v
|
||||
|
||||
.. versionchanged:: 2018.3.0
|
||||
|
||||
If %s is present in the url, it will be automaticaly replaced by the minion_id:
|
||||
If %s is present in the url, it will be automatically replaced by the minion_id:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -81,13 +81,13 @@ parameters are sensitive, it's recommended to pass them to the states via pillar
|
||||
|
||||
'''
|
||||
|
||||
# Python libs
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import json
|
||||
import logging
|
||||
|
||||
# Salt libs
|
||||
import salt.utils
|
||||
# Import Salt libs
|
||||
import salt.utils.files
|
||||
|
||||
__virtualname__ = 'azurearm_resource'
|
||||
|
||||
@ -424,7 +424,7 @@ def policy_definition_present(name, policy_rule=None, policy_type=None, mode=Non
|
||||
return ret
|
||||
|
||||
try:
|
||||
with salt.utils.fopen(sfn, 'r') as prf:
|
||||
with salt.utils.files.fopen(sfn, 'r') as prf:
|
||||
temp_rule = json.load(prf)
|
||||
except Exception as exc:
|
||||
ret['comment'] = 'Unable to load policy rule file "{0}"! ({1})'.format(policy_rule_file, exc)
|
||||
|
@ -1061,7 +1061,7 @@ def diskgroups_configured(name, diskgroups, erase_disks=False):
|
||||
|
||||
erase_disks
|
||||
Specifies whether to erase all partitions on all disks member of the
|
||||
disk group before the disk group is created. Default vaule is False.
|
||||
disk group before the disk group is created. Default value is False.
|
||||
'''
|
||||
proxy_details = __salt__['esxi.get_details']()
|
||||
hostname = proxy_details['host'] if not proxy_details.get('vcenter') \
|
||||
@ -1371,7 +1371,7 @@ def host_cache_configured(name, enabled, datastore, swap_size='100%',
|
||||
|
||||
erase_backing_disk
|
||||
Specifies whether to erase all partitions on the backing disk before
|
||||
the datastore is created. Default vaule is False.
|
||||
the datastore is created. Default value is False.
|
||||
'''
|
||||
log.trace('enabled = %s', enabled)
|
||||
log.trace('datastore = %s', datastore)
|
||||
|
@ -41,7 +41,7 @@ or clusters are available.
|
||||
as this makes all master configuration settings available in all minion's
|
||||
pillars.
|
||||
|
||||
Etcd profile configuration can be overriden using following arguments: ``host``,
|
||||
Etcd profile configuration can be overridden using following arguments: ``host``,
|
||||
``port``, ``username``, ``password``, ``ca``, ``client_key`` and ``client_cert``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
@ -4160,11 +4160,20 @@ def blockreplace(
|
||||
append_if_not_found=False,
|
||||
prepend_if_not_found=False,
|
||||
backup='.bak',
|
||||
show_changes=True):
|
||||
show_changes=True,
|
||||
append_newline=None):
|
||||
'''
|
||||
Maintain an edit in a file in a zone delimited by two line markers
|
||||
|
||||
.. versionadded:: 2014.1.0
|
||||
.. versionchanged:: 2017.7.5,2018.3.1
|
||||
``append_newline`` argument added. Additionally, to improve
|
||||
idempotence, if the string represented by ``marker_end`` is found in
|
||||
the middle of the line, the content preceding the marker will be
|
||||
removed when the block is replaced. This allows one to remove
|
||||
``append_newline: False`` from the SLS and have the block properly
|
||||
replaced if the end of the content block is immediately followed by the
|
||||
``marker_end`` (i.e. no newline before the marker).
|
||||
|
||||
A block of content delimited by comments can help you manage several lines
|
||||
entries without worrying about old entries removal. This can help you
|
||||
@ -4249,9 +4258,9 @@ def blockreplace(
|
||||
See the ``source_hash`` parameter description for :mod:`file.managed
|
||||
<salt.states.file.managed>` function for more details and examples.
|
||||
|
||||
template
|
||||
The named templating engine will be used to render the downloaded file.
|
||||
Defaults to ``jinja``. The following templates are supported:
|
||||
template : jinja
|
||||
Templating engine to be used to render the downloaded file. The
|
||||
following engines are supported:
|
||||
|
||||
- :mod:`cheetah <salt.renderers.cheetah>`
|
||||
- :mod:`genshi <salt.renderers.genshi>`
|
||||
@ -4261,29 +4270,42 @@ def blockreplace(
|
||||
- :mod:`wempy <salt.renderers.wempy>`
|
||||
|
||||
context
|
||||
Overrides default context variables passed to the template.
|
||||
Overrides default context variables passed to the template
|
||||
|
||||
defaults
|
||||
Default context passed to the template.
|
||||
Default context passed to the template
|
||||
|
||||
append_if_not_found
|
||||
If markers are not found and set to True then the markers and content
|
||||
will be appended to the file. Default is ``False``
|
||||
append_if_not_found : False
|
||||
If markers are not found and this option is set to ``True``, the
|
||||
content block will be appended to the file.
|
||||
|
||||
prepend_if_not_found
|
||||
If markers are not found and set to True then the markers and content
|
||||
will be prepended to the file. Default is ``False``
|
||||
prepend_if_not_found : False
|
||||
If markers are not found and this option is set to ``True``, the
|
||||
content block will be prepended to the file.
|
||||
|
||||
backup
|
||||
The file extension to use for a backup of the file if any edit is made.
|
||||
Set this to ``False`` to skip making a backup.
|
||||
|
||||
dry_run
|
||||
Don't make any edits to the file
|
||||
dry_run : False
|
||||
If ``True``, do not make any edits to the file and simply return the
|
||||
changes that *would* be made.
|
||||
|
||||
show_changes
|
||||
Output a unified diff of the old file and the new file. If ``False``
|
||||
return a boolean if any changes were made
|
||||
show_changes : True
|
||||
Controls how changes are presented. If ``True``, the ``Changes``
|
||||
section of the state return will contain a unified diff of the changes
|
||||
made. If False, then it will contain a boolean (``True`` if any changes
|
||||
were made, otherwise ``False``).
|
||||
|
||||
append_newline
|
||||
Controls whether or not a newline is appended to the content block. If
|
||||
the value of this argument is ``True`` then a newline will be added to
|
||||
the content block. If it is ``False``, then a newline will *not* be
|
||||
added to the content block. If it is unspecified, then a newline will
|
||||
only be added to the content block if it does not already end in a
|
||||
newline.
|
||||
|
||||
.. versionadded:: 2017.7.5,2018.3.1
|
||||
|
||||
Example of usage with an accumulator and with a variable:
|
||||
|
||||
@ -4385,6 +4407,7 @@ def blockreplace(
|
||||
for index, item in enumerate(text):
|
||||
content += six.text_type(item)
|
||||
|
||||
try:
|
||||
changes = __salt__['file.blockreplace'](
|
||||
name,
|
||||
marker_start,
|
||||
@ -4394,8 +4417,15 @@ def blockreplace(
|
||||
prepend_if_not_found=prepend_if_not_found,
|
||||
backup=backup,
|
||||
dry_run=__opts__['test'],
|
||||
show_changes=show_changes
|
||||
show_changes=show_changes,
|
||||
append_newline=append_newline)
|
||||
except Exception as exc:
|
||||
log.exception('Encountered error managing block')
|
||||
ret['comment'] = (
|
||||
'Encountered error managing block: {0}. '
|
||||
'See the log for details.'.format(exc)
|
||||
)
|
||||
return ret
|
||||
|
||||
if changes:
|
||||
ret['pchanges'] = {'diff': changes}
|
||||
|
@ -110,26 +110,30 @@ def _get_branch_opts(branch, local_branch, all_local_branches,
|
||||
return ret
|
||||
|
||||
|
||||
def _get_local_rev_and_branch(target, user, password):
|
||||
def _get_local_rev_and_branch(target, user, password, output_encoding=None):
|
||||
'''
|
||||
Return the local revision for before/after comparisons
|
||||
'''
|
||||
log.info('Checking local revision for %s', target)
|
||||
try:
|
||||
local_rev = __salt__['git.revision'](target,
|
||||
local_rev = __salt__['git.revision'](
|
||||
target,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
log.info('No local revision for %s', target)
|
||||
local_rev = None
|
||||
|
||||
log.info('Checking local branch for %s', target)
|
||||
try:
|
||||
local_branch = __salt__['git.current_branch'](target,
|
||||
local_branch = __salt__['git.current_branch'](
|
||||
target,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
log.info('No local branch for %s', target)
|
||||
local_branch = None
|
||||
@ -260,6 +264,7 @@ def latest(name,
|
||||
unless=False,
|
||||
refspec_branch='*',
|
||||
refspec_tag='*',
|
||||
output_encoding=None,
|
||||
**kwargs):
|
||||
'''
|
||||
Make sure the repository is cloned to the given directory and is
|
||||
@ -521,6 +526,30 @@ def latest(name,
|
||||
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
output_encoding
|
||||
Use this option to specify which encoding to use to decode the output
|
||||
from any git commands which are run. This should not be needed in most
|
||||
cases.
|
||||
|
||||
.. note::
|
||||
|
||||
On Windows, this option works slightly differently in the git state
|
||||
and execution module than it does in the :mod:`"cmd" execution
|
||||
module <salt.modules.cmdmod>`. The filenames in most git
|
||||
repositories are created using a UTF-8 locale, and the system
|
||||
encoding on Windows (CP1252) will successfully (but incorrectly)
|
||||
decode many UTF-8 characters. This makes interacting with
|
||||
repositories containing UTF-8 filenames on Windows unreliable.
|
||||
Therefore, Windows will default to decoding the output from git
|
||||
commands using UTF-8 unless this option is explicitly used to
|
||||
specify the encoding.
|
||||
|
||||
On non-Windows platforms, the default output decoding behavior will
|
||||
be observed (i.e. the encoding specified by the locale will be
|
||||
tried first, and if that fails, UTF-8 will be used as a fallback).
|
||||
|
||||
.. versionadded:: 2018.3.1
|
||||
|
||||
.. _`git-fetch(1)`: http://git-scm.com/docs/git-fetch
|
||||
|
||||
.. note::
|
||||
@ -698,7 +727,8 @@ def latest(name,
|
||||
https_user=https_user,
|
||||
https_pass=https_pass,
|
||||
ignore_retcode=False,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _fail(
|
||||
ret,
|
||||
@ -808,18 +838,29 @@ def latest(name,
|
||||
check = 'refs' if bare else '.git'
|
||||
gitdir = os.path.join(target, check)
|
||||
comments = []
|
||||
if os.path.isdir(gitdir) or __salt__['git.is_worktree'](target,
|
||||
if os.path.isdir(gitdir) \
|
||||
or __salt__['git.is_worktree'](
|
||||
target,
|
||||
user=user,
|
||||
password=password):
|
||||
password=password,
|
||||
output_encoding=output_encoding):
|
||||
# Target directory is a git repository or git worktree
|
||||
try:
|
||||
all_local_branches = __salt__['git.list_branches'](
|
||||
target, user=user, password=password)
|
||||
all_local_tags = __salt__['git.list_tags'](target,
|
||||
target,
|
||||
user=user,
|
||||
password=password)
|
||||
local_rev, local_branch = \
|
||||
_get_local_rev_and_branch(target, user, password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
all_local_tags = __salt__['git.list_tags'](
|
||||
target,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
local_rev, local_branch = _get_local_rev_and_branch(
|
||||
target,
|
||||
user,
|
||||
password,
|
||||
output_encoding)
|
||||
|
||||
if not bare and remote_rev is None and local_rev is not None:
|
||||
return _fail(
|
||||
@ -855,7 +896,8 @@ def latest(name,
|
||||
branch + '^{commit}',
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _fail(
|
||||
ret,
|
||||
@ -867,7 +909,8 @@ def latest(name,
|
||||
remotes = __salt__['git.remotes'](target,
|
||||
user=user,
|
||||
password=password,
|
||||
redact_auth=False)
|
||||
redact_auth=False,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
revs_match = _revs_equal(local_rev, remote_rev, remote_rev_type)
|
||||
try:
|
||||
@ -879,7 +922,8 @@ def latest(name,
|
||||
__salt__['git.diff'](target,
|
||||
'HEAD',
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
)
|
||||
except CommandExecutionError:
|
||||
# No need to capture the error and log it, the _git_run()
|
||||
@ -933,7 +977,8 @@ def latest(name,
|
||||
remote_rev + '^{commit}',
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
# Local checkout doesn't have the remote_rev
|
||||
pass
|
||||
@ -954,7 +999,8 @@ def latest(name,
|
||||
desired_upstream,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
pass
|
||||
else:
|
||||
@ -974,7 +1020,8 @@ def latest(name,
|
||||
rev + '^{commit}',
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
# Shouldn't happen if the tag exists
|
||||
# locally but account for this just in
|
||||
@ -1044,7 +1091,8 @@ def latest(name,
|
||||
is_ancestor=True,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
if fast_forward is False:
|
||||
if not force_reset:
|
||||
@ -1075,7 +1123,8 @@ def latest(name,
|
||||
opts=['--abbrev-ref'],
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
# There is a local branch but the rev-parse command
|
||||
# failed, so that means there is no upstream tracking
|
||||
@ -1144,7 +1193,8 @@ def latest(name,
|
||||
user=user,
|
||||
password=password,
|
||||
https_user=https_user,
|
||||
https_pass=https_pass)
|
||||
https_pass=https_pass,
|
||||
output_encoding=output_encoding)
|
||||
if fetch_url is None:
|
||||
comments.append(
|
||||
'Remote \'{0}\' set to {1}'.format(
|
||||
@ -1318,7 +1368,7 @@ def latest(name,
|
||||
identity=identity,
|
||||
saltenv=__env__,
|
||||
ignore_retcode=True,
|
||||
).keys() if '^{}' not in x
|
||||
output_encoding=output_encoding) if '^{}' not in x
|
||||
])
|
||||
if set(all_local_tags) != remote_tags:
|
||||
has_remote_rev = False
|
||||
@ -1336,7 +1386,8 @@ def latest(name,
|
||||
user=user,
|
||||
password=password,
|
||||
identity=identity,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _failed_fetch(ret, exc, comments)
|
||||
else:
|
||||
@ -1352,7 +1403,8 @@ def latest(name,
|
||||
remote_rev + '^{commit}',
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _fail(
|
||||
ret,
|
||||
@ -1384,7 +1436,8 @@ def latest(name,
|
||||
refs=[base_rev, remote_rev],
|
||||
is_ancestor=True,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
if fast_forward is False and not force_reset:
|
||||
return _not_fast_forward(
|
||||
@ -1427,7 +1480,8 @@ def latest(name,
|
||||
force=force_checkout,
|
||||
opts=checkout_opts,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
if '-b' in checkout_opts:
|
||||
comments.append(
|
||||
'New branch \'{0}\' was checked out, with {1} '
|
||||
@ -1450,7 +1504,7 @@ def latest(name,
|
||||
opts=['--hard', remote_rev],
|
||||
user=user,
|
||||
password=password,
|
||||
)
|
||||
output_encoding=output_encoding)
|
||||
ret['changes']['forced update'] = True
|
||||
comments.append(
|
||||
'Repository was hard-reset to {0}'.format(remote_loc)
|
||||
@ -1461,7 +1515,8 @@ def latest(name,
|
||||
target,
|
||||
opts=branch_opts,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(upstream_action)
|
||||
|
||||
# Fast-forward to the desired revision
|
||||
@ -1474,12 +1529,14 @@ def latest(name,
|
||||
# trying to merge changes. (The call to
|
||||
# git.symbolic_ref will only return output if HEAD
|
||||
# points to a branch.)
|
||||
if __salt__['git.symbolic_ref'](target,
|
||||
if __salt__['git.symbolic_ref'](
|
||||
target,
|
||||
'HEAD',
|
||||
opts=['--quiet'],
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True):
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding):
|
||||
|
||||
if git_ver >= _LooseVersion('1.8.1.6'):
|
||||
# --ff-only added in version 1.8.1.6. It's not
|
||||
@ -1499,7 +1556,8 @@ def latest(name,
|
||||
rev=remote_rev,
|
||||
opts=merge_opts,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Repository was fast-forwarded to {0}'
|
||||
.format(remote_loc)
|
||||
@ -1518,7 +1576,8 @@ def latest(name,
|
||||
opts=['--hard',
|
||||
remote_rev if rev == 'HEAD' else rev],
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Repository was reset to {0} (fast-forward)'
|
||||
.format(rev)
|
||||
@ -1535,7 +1594,8 @@ def latest(name,
|
||||
user=user,
|
||||
password=password,
|
||||
identity=identity,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _failed_submodule_update(ret, exc, comments)
|
||||
elif bare:
|
||||
@ -1557,7 +1617,8 @@ def latest(name,
|
||||
user=user,
|
||||
password=password,
|
||||
identity=identity,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _failed_fetch(ret, exc, comments)
|
||||
else:
|
||||
@ -1574,7 +1635,8 @@ def latest(name,
|
||||
cwd=target,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
new_rev = None
|
||||
|
||||
@ -1682,7 +1744,8 @@ def latest(name,
|
||||
identity=identity,
|
||||
https_user=https_user,
|
||||
https_pass=https_pass,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
msg = 'Clone failed: {0}'.format(_strip_exc(exc))
|
||||
return _fail(ret, msg, comments)
|
||||
@ -1715,7 +1778,10 @@ def latest(name,
|
||||
else:
|
||||
if remote_rev_type == 'tag' \
|
||||
and rev not in __salt__['git.list_tags'](
|
||||
target, user=user, password=password):
|
||||
target,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding):
|
||||
return _fail(
|
||||
ret,
|
||||
'Revision \'{0}\' does not exist in clone'
|
||||
@ -1728,18 +1794,21 @@ def latest(name,
|
||||
__salt__['git.list_branches'](
|
||||
target,
|
||||
user=user,
|
||||
password=password):
|
||||
password=password,
|
||||
output_encoding=output_encoding):
|
||||
if rev == 'HEAD':
|
||||
checkout_rev = remote_rev
|
||||
else:
|
||||
checkout_rev = desired_upstream \
|
||||
if desired_upstream \
|
||||
else rev
|
||||
__salt__['git.checkout'](target,
|
||||
__salt__['git.checkout'](
|
||||
target,
|
||||
checkout_rev,
|
||||
opts=['-b', branch],
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Branch \'{0}\' checked out, with {1} '
|
||||
'as a starting point'.format(
|
||||
@ -1748,8 +1817,11 @@ def latest(name,
|
||||
)
|
||||
)
|
||||
|
||||
local_rev, local_branch = \
|
||||
_get_local_rev_and_branch(target, user, password)
|
||||
local_rev, local_branch = _get_local_rev_and_branch(
|
||||
target,
|
||||
user,
|
||||
password,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
if local_branch is None \
|
||||
and remote_rev is not None \
|
||||
@ -1771,7 +1843,8 @@ def latest(name,
|
||||
target,
|
||||
opts=['--hard', remote_rev],
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Repository was reset to {0}'.format(remote_loc)
|
||||
)
|
||||
@ -1783,7 +1856,8 @@ def latest(name,
|
||||
opts=['--abbrev-ref'],
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
upstream = False
|
||||
|
||||
@ -1796,9 +1870,11 @@ def latest(name,
|
||||
branch_opts = _get_branch_opts(
|
||||
branch,
|
||||
local_branch,
|
||||
__salt__['git.list_branches'](target,
|
||||
__salt__['git.list_branches'](
|
||||
target,
|
||||
user=user,
|
||||
password=password),
|
||||
password=password,
|
||||
output_encoding=output_encoding),
|
||||
desired_upstream,
|
||||
git_ver)
|
||||
elif upstream and desired_upstream is False:
|
||||
@ -1821,9 +1897,11 @@ def latest(name,
|
||||
branch_opts = _get_branch_opts(
|
||||
branch,
|
||||
local_branch,
|
||||
__salt__['git.list_branches'](target,
|
||||
__salt__['git.list_branches'](
|
||||
target,
|
||||
user=user,
|
||||
password=password),
|
||||
password=password,
|
||||
output_encoding=output_encoding),
|
||||
desired_upstream,
|
||||
git_ver)
|
||||
else:
|
||||
@ -1834,17 +1912,20 @@ def latest(name,
|
||||
target,
|
||||
opts=branch_opts,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(upstream_action)
|
||||
|
||||
if submodules and remote_rev:
|
||||
try:
|
||||
__salt__['git.submodule'](target,
|
||||
__salt__['git.submodule'](
|
||||
target,
|
||||
'update',
|
||||
opts=['--init', '--recursive'],
|
||||
user=user,
|
||||
password=password,
|
||||
identity=identity)
|
||||
identity=identity,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
return _failed_submodule_update(ret, exc, comments)
|
||||
|
||||
@ -1853,7 +1934,8 @@ def latest(name,
|
||||
cwd=target,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
new_rev = None
|
||||
|
||||
@ -1883,7 +1965,8 @@ def present(name,
|
||||
separate_git_dir=None,
|
||||
shared=None,
|
||||
user=None,
|
||||
password=None):
|
||||
password=None,
|
||||
output_encoding=None):
|
||||
'''
|
||||
Ensure that a repository exists in the given directory
|
||||
|
||||
@ -1943,6 +2026,30 @@ def present(name,
|
||||
|
||||
.. versionadded:: 2016.3.4
|
||||
|
||||
output_encoding
|
||||
Use this option to specify which encoding to use to decode the output
|
||||
from any git commands which are run. This should not be needed in most
|
||||
cases.
|
||||
|
||||
.. note::
|
||||
|
||||
On Windows, this option works slightly differently in the git state
|
||||
and execution module than it does in the :mod:`"cmd" execution
|
||||
module <salt.modules.cmdmod>`. The filenames in most git
|
||||
repositories are created using a UTF-8 locale, and the system
|
||||
encoding on Windows (CP1252) will successfully (but incorrectly)
|
||||
decode many UTF-8 characters. This makes interacting with
|
||||
repositories containing UTF-8 filenames on Windows unreliable.
|
||||
Therefore, Windows will default to decoding the output from git
|
||||
commands using UTF-8 unless this option is explicitly used to
|
||||
specify the encoding.
|
||||
|
||||
On non-Windows platforms, the default output decoding behavior will
|
||||
be observed (i.e. the encoding specified by the locale will be
|
||||
tried first, and if that fails, UTF-8 will be used as a fallback).
|
||||
|
||||
.. versionadded:: 2018.3.1
|
||||
|
||||
.. _`git-init(1)`: http://git-scm.com/docs/git-init
|
||||
.. _`worktree`: http://git-scm.com/docs/git-worktree
|
||||
'''
|
||||
@ -1954,7 +2061,10 @@ def present(name,
|
||||
return ret
|
||||
elif not bare and \
|
||||
(os.path.isdir(os.path.join(name, '.git')) or
|
||||
__salt__['git.is_worktree'](name, user=user, password=password)):
|
||||
__salt__['git.is_worktree'](name,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding)):
|
||||
return ret
|
||||
# Directory exists and is not a git repo, if force is set destroy the
|
||||
# directory and recreate, otherwise throw an error
|
||||
@ -2013,7 +2123,8 @@ def present(name,
|
||||
separate_git_dir=separate_git_dir,
|
||||
shared=shared,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
actions = [
|
||||
'Initialized {0}repository in {1}'.format(
|
||||
@ -2050,6 +2161,7 @@ def detached(name,
|
||||
https_pass=None,
|
||||
onlyif=False,
|
||||
unless=False,
|
||||
output_encoding=None,
|
||||
**kwargs):
|
||||
'''
|
||||
.. versionadded:: 2016.3.0
|
||||
@ -2132,6 +2244,29 @@ def detached(name,
|
||||
A command to run as a check, only run the named command if the command
|
||||
passed to the ``unless`` option returns false
|
||||
|
||||
output_encoding
|
||||
Use this option to specify which encoding to use to decode the output
|
||||
from any git commands which are run. This should not be needed in most
|
||||
cases.
|
||||
|
||||
.. note::
|
||||
|
||||
On Windows, this option works slightly differently in the git state
|
||||
and execution module than it does in the :mod:`"cmd" execution
|
||||
module <salt.modules.cmdmod>`. The filenames in most git
|
||||
repositories are created using a UTF-8 locale, and the system
|
||||
encoding on Windows (CP1252) will successfully (but incorrectly)
|
||||
decode many UTF-8 characters. This makes interacting with
|
||||
repositories containing UTF-8 filenames on Windows unreliable.
|
||||
Therefore, Windows will default to decoding the output from git
|
||||
commands using UTF-8 unless this option is explicitly used to
|
||||
specify the encoding.
|
||||
|
||||
On non-Windows platforms, the default output decoding behavior will
|
||||
be observed (i.e. the encoding specified by the locale will be
|
||||
tried first, and if that fails, UTF-8 will be used as a fallback).
|
||||
|
||||
.. versionadded:: 2018.3.1
|
||||
'''
|
||||
|
||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||
@ -2252,10 +2387,17 @@ def detached(name,
|
||||
|
||||
gitdir = os.path.join(target, '.git')
|
||||
if os.path.isdir(gitdir) \
|
||||
or __salt__['git.is_worktree'](target, user=user, password=password):
|
||||
or __salt__['git.is_worktree'](target,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding):
|
||||
# Target directory is a git repository or git worktree
|
||||
|
||||
local_commit_id = _get_local_rev_and_branch(target, user, password)[0]
|
||||
local_commit_id = _get_local_rev_and_branch(
|
||||
target,
|
||||
user,
|
||||
password,
|
||||
output_encoding=output_encoding)[0]
|
||||
|
||||
if remote_rev_type is 'hash':
|
||||
try:
|
||||
@ -2263,7 +2405,8 @@ def detached(name,
|
||||
rev,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
hash_exists_locally = False
|
||||
else:
|
||||
@ -2274,7 +2417,8 @@ def detached(name,
|
||||
remotes = __salt__['git.remotes'](target,
|
||||
user=user,
|
||||
password=password,
|
||||
redact_auth=False)
|
||||
redact_auth=False,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
if remote in remotes and name in remotes[remote]['fetch']:
|
||||
pass
|
||||
@ -2300,7 +2444,8 @@ def detached(name,
|
||||
user=user,
|
||||
password=password,
|
||||
https_user=https_user,
|
||||
https_pass=https_pass)
|
||||
https_pass=https_pass,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Remote {0} updated from \'{1}\' to \'{2}\''.format(
|
||||
remote,
|
||||
@ -2380,7 +2525,8 @@ def detached(name,
|
||||
identity=identity,
|
||||
https_user=https_user,
|
||||
https_pass=https_pass,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
comments.append('{0} cloned to {1}'.format(name, target))
|
||||
|
||||
except Exception as exc:
|
||||
@ -2417,7 +2563,8 @@ def detached(name,
|
||||
user=user,
|
||||
password=password,
|
||||
identity=identity,
|
||||
saltenv=__env__)
|
||||
saltenv=__env__,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError as exc:
|
||||
msg = 'Fetch failed'
|
||||
msg += ':\n\n' + six.text_type(exc)
|
||||
@ -2432,7 +2579,12 @@ def detached(name,
|
||||
#get refs and checkout
|
||||
checkout_commit_id = ''
|
||||
if remote_rev_type is 'hash':
|
||||
if __salt__['git.describe'](target, rev, user=user, password=password):
|
||||
if __salt__['git.describe'](
|
||||
target,
|
||||
rev,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding):
|
||||
checkout_commit_id = rev
|
||||
else:
|
||||
return _fail(
|
||||
@ -2448,7 +2600,8 @@ def detached(name,
|
||||
identity=identity,
|
||||
https_user=https_user,
|
||||
https_pass=https_pass,
|
||||
ignore_retcode=False)
|
||||
ignore_retcode=False,
|
||||
output_encoding=output_encoding)
|
||||
|
||||
if 'refs/remotes/'+remote+'/'+rev in all_remote_refs:
|
||||
checkout_commit_id = all_remote_refs['refs/remotes/' + remote + '/' + rev]
|
||||
@ -2476,7 +2629,8 @@ def detached(name,
|
||||
target,
|
||||
opts=['--hard', 'HEAD'],
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Repository was reset to HEAD before checking out revision'
|
||||
)
|
||||
@ -2499,7 +2653,8 @@ def detached(name,
|
||||
checkout_commit_id,
|
||||
force=force_checkout,
|
||||
user=user,
|
||||
password=password)
|
||||
password=password,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Commit ID {0} was checked out at {1}'.format(
|
||||
checkout_commit_id,
|
||||
@ -2512,7 +2667,8 @@ def detached(name,
|
||||
cwd=target,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding)
|
||||
except CommandExecutionError:
|
||||
new_rev = None
|
||||
|
||||
@ -2522,7 +2678,8 @@ def detached(name,
|
||||
opts=['--init', '--recursive'],
|
||||
user=user,
|
||||
password=password,
|
||||
identity=identity)
|
||||
identity=identity,
|
||||
output_encoding=output_encoding)
|
||||
comments.append(
|
||||
'Submodules were updated'
|
||||
)
|
||||
@ -2544,6 +2701,7 @@ def config_unset(name,
|
||||
repo=None,
|
||||
user=None,
|
||||
password=None,
|
||||
output_encoding=None,
|
||||
**kwargs):
|
||||
r'''
|
||||
.. versionadded:: 2015.8.0
|
||||
@ -2586,6 +2744,30 @@ def config_unset(name,
|
||||
global : False
|
||||
If ``True``, this will set a global git config option
|
||||
|
||||
output_encoding
|
||||
Use this option to specify which encoding to use to decode the output
|
||||
from any git commands which are run. This should not be needed in most
|
||||
cases.
|
||||
|
||||
.. note::
|
||||
|
||||
On Windows, this option works slightly differently in the git state
|
||||
and execution module than it does in the :mod:`"cmd" execution
|
||||
module <salt.modules.cmdmod>`. The filenames in most git
|
||||
repositories are created using a UTF-8 locale, and the system
|
||||
encoding on Windows (CP1252) will successfully (but incorrectly)
|
||||
decode many UTF-8 characters. This makes interacting with
|
||||
repositories containing UTF-8 filenames on Windows unreliable.
|
||||
Therefore, Windows will default to decoding the output from git
|
||||
commands using UTF-8 unless this option is explicitly used to
|
||||
specify the encoding.
|
||||
|
||||
On non-Windows platforms, the default output decoding behavior will
|
||||
be observed (i.e. the encoding specified by the locale will be
|
||||
tried first, and if that fails, UTF-8 will be used as a fallback).
|
||||
|
||||
.. versionadded:: 2018.3.1
|
||||
|
||||
|
||||
**Examples:**
|
||||
|
||||
@ -2658,6 +2840,7 @@ def config_unset(name,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding,
|
||||
**{'global': global_}
|
||||
)
|
||||
|
||||
@ -2707,6 +2890,7 @@ def config_unset(name,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding,
|
||||
**{'global': global_}
|
||||
)
|
||||
|
||||
@ -2722,6 +2906,7 @@ def config_unset(name,
|
||||
all=all_,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding,
|
||||
**{'global': global_}
|
||||
)
|
||||
except CommandExecutionError as exc:
|
||||
@ -2746,6 +2931,7 @@ def config_unset(name,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding,
|
||||
**{'global': global_}
|
||||
)
|
||||
|
||||
@ -2766,6 +2952,7 @@ def config_unset(name,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding,
|
||||
**{'global': global_}
|
||||
)
|
||||
|
||||
@ -2787,6 +2974,7 @@ def config_set(name,
|
||||
repo=None,
|
||||
user=None,
|
||||
password=None,
|
||||
output_encoding=None,
|
||||
**kwargs):
|
||||
'''
|
||||
.. versionadded:: 2014.7.0
|
||||
@ -2829,6 +3017,30 @@ def config_set(name,
|
||||
global : False
|
||||
If ``True``, this will set a global git config option
|
||||
|
||||
output_encoding
|
||||
Use this option to specify which encoding to use to decode the output
|
||||
from any git commands which are run. This should not be needed in most
|
||||
cases.
|
||||
|
||||
.. note::
|
||||
|
||||
On Windows, this option works slightly differently in the git state
|
||||
and execution module than it does in the :mod:`"cmd" execution
|
||||
module <salt.modules.cmdmod>`. The filenames in most git
|
||||
repositories are created using a UTF-8 locale, and the system
|
||||
encoding on Windows (CP1252) will successfully (but incorrectly)
|
||||
decode many UTF-8 characters. This makes interacting with
|
||||
repositories containing UTF-8 filenames on Windows unreliable.
|
||||
Therefore, Windows will default to decoding the output from git
|
||||
commands using UTF-8 unless this option is explicitly used to
|
||||
specify the encoding.
|
||||
|
||||
On non-Windows platforms, the default output decoding behavior will
|
||||
be observed (i.e. the encoding specified by the locale will be
|
||||
tried first, and if that fails, UTF-8 will be used as a fallback).
|
||||
|
||||
.. versionadded:: 2018.3.1
|
||||
|
||||
**Local Config Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
@ -2922,6 +3134,7 @@ def config_set(name,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True,
|
||||
output_encoding=output_encoding,
|
||||
**{'all': True, 'global': global_}
|
||||
)
|
||||
|
||||
@ -2952,6 +3165,7 @@ def config_set(name,
|
||||
multivar=multivar,
|
||||
user=user,
|
||||
password=password,
|
||||
output_encoding=output_encoding,
|
||||
**{'global': global_}
|
||||
)
|
||||
except CommandExecutionError as exc:
|
||||
|
@ -104,7 +104,7 @@ def present(name=None, data=None, ensure_data=True, **api_opts):
|
||||
addr['ipv4addr'] = ip
|
||||
found_matches += 1
|
||||
if found_matches > 1:
|
||||
ret['comment'] = 'infoblox record cant updated because ipaddress {0} matches mutiple func:nextavailableip'.format(ip)
|
||||
ret['comment'] = 'infoblox record cant updated because ipaddress {0} matches multiple func:nextavailableip'.format(ip)
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
|
@ -31,7 +31,7 @@ Example state chaining the install and reboot operations:
|
||||
- onchanges:
|
||||
- kernel: install-latest-kernel
|
||||
|
||||
Chaining can also be acheived using wait/listen requisites:
|
||||
Chaining can also be achieved using wait/listen requisites:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ def installed(
|
||||
.. versionadded:: 2014.1.1
|
||||
|
||||
:param bool resolve_capabilities:
|
||||
Turn on resolving capabilities. This allow to name "provides" or alias names for packages.
|
||||
Turn on resolving capabilities. This allow one to name "provides" or alias names for packages.
|
||||
|
||||
.. versionadded:: 2018.3.0
|
||||
|
||||
@ -1967,7 +1967,7 @@ def downloaded(name,
|
||||
- salt-minion: 2015.8.5-1.el6
|
||||
|
||||
:param bool resolve_capabilities:
|
||||
Turn on resolving capabilities. This allow to name "provides" or alias names for packages.
|
||||
Turn on resolving capabilities. This allow one to name "provides" or alias names for packages.
|
||||
|
||||
.. versionadded:: 2018.3.0
|
||||
|
||||
@ -2259,7 +2259,7 @@ def latest(
|
||||
has no effect on the rest.
|
||||
|
||||
:param bool resolve_capabilities:
|
||||
Turn on resolving capabilities. This allow to name "provides" or alias names for packages.
|
||||
Turn on resolving capabilities. This allow one to name "provides" or alias names for packages.
|
||||
|
||||
.. versionadded:: 2018.3.0
|
||||
|
||||
@ -2886,7 +2886,7 @@ def uptodate(name, refresh=False, pkgs=None, **kwargs):
|
||||
have no effect on the rest.
|
||||
|
||||
:param bool resolve_capabilities:
|
||||
Turn on resolving capabilities. This allow to name "provides" or alias names for packages.
|
||||
Turn on resolving capabilities. This allow one to name "provides" or alias names for packages.
|
||||
|
||||
.. versionadded:: 2018.3.0
|
||||
|
||||
|
@ -54,7 +54,7 @@ def present(name,
|
||||
priority
|
||||
Priority (defaults to 0)
|
||||
apply_to
|
||||
Apply policy to 'queues', 'exchanges' or 'all' (defailt to 'all')
|
||||
Apply policy to 'queues', 'exchanges' or 'all' (default to 'all')
|
||||
vhost
|
||||
Virtual host to apply to (defaults to '/')
|
||||
runas
|
||||
|
@ -319,7 +319,7 @@ def powered_off(name):
|
||||
|
||||
def destroyed(name):
|
||||
'''
|
||||
Stops a VM (or VMs) and removes all refences to it (them). (Runs ``vagrant destroy``.)
|
||||
Stops a VM (or VMs) and removes all references to it (them). (Runs ``vagrant destroy``.)
|
||||
|
||||
Subsequent re-use of the same machine will requere another operation of ``vagrant.running``
|
||||
or a call to the ``vagrant.init`` execution module.
|
||||
|
@ -373,7 +373,7 @@ def len_gte(name, value):
|
||||
|
||||
def len_lt(name, value):
|
||||
'''
|
||||
Only succeed if the lenght of the given register location is less than
|
||||
Only succeed if the length of the given register location is less than
|
||||
the given value.
|
||||
|
||||
USAGE:
|
||||
|
@ -184,7 +184,7 @@ def translate_input(translator,
|
||||
of that tuple will have their translation skipped. Optionally,
|
||||
skip_translate can be set to True to skip *all* translation.
|
||||
'''
|
||||
kwargs = copy.deepcopy(salt.utils.clean_kwargs(**kwargs))
|
||||
kwargs = copy.deepcopy(salt.utils.args.clean_kwargs(**kwargs))
|
||||
invalid = {}
|
||||
collisions = []
|
||||
|
||||
|
@ -492,7 +492,7 @@ class GitProvider(object):
|
||||
@classmethod
|
||||
def add_conf_overlay(cls, name):
|
||||
'''
|
||||
Programatically determine config value based on the desired saltenv
|
||||
Programmatically determine config value based on the desired saltenv
|
||||
'''
|
||||
def _getconf(self, tgt_env='base'):
|
||||
strip_sep = lambda x: x.rstrip(os.sep) \
|
||||
|
@ -259,7 +259,7 @@ def get_device_opts(opts, salt_obj=None):
|
||||
if opts.get('proxy') or opts.get('napalm'):
|
||||
opts['multiprocessing'] = device_dict.get('multiprocessing', False)
|
||||
# Most NAPALM drivers are SSH-based, so multiprocessing should default to False.
|
||||
# But the user can be allows to have a different value for the multiprocessing, which will
|
||||
# But the user can be allows one to have a different value for the multiprocessing, which will
|
||||
# override the opts.
|
||||
if salt_obj and not device_dict:
|
||||
# get the connection details from the opts
|
||||
|
@ -17,5 +17,5 @@ pillars:
|
||||
- app-backend
|
||||
# Safe minion_id matching
|
||||
{% if minion_id == 'zrh.node3' %}
|
||||
safe_pillar: '_only_ zrh.node3 will see this pillar and this cannot be overriden like grains'
|
||||
safe_pillar: '_only_ zrh.node3 will see this pillar and this cannot be overridden like grains'
|
||||
{% endif %}
|
||||
|
@ -147,7 +147,8 @@ class GitModuleTest(ModuleCase):
|
||||
TODO: maybe move this behavior to ModuleCase itself?
|
||||
'''
|
||||
return salt.utils.data.decode(
|
||||
super(GitModuleTest, self).run_function(*args, **kwargs)
|
||||
super(GitModuleTest, self).run_function(*args, **kwargs),
|
||||
encoding='utf-8'
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
@ -206,7 +207,8 @@ class GitModuleTest(ModuleCase):
|
||||
self.run_function('cmd.run', ['cp ' + tar_archive + ' /root/'])
|
||||
with closing(tarfile.open(tar_archive, 'r')) as tar_obj:
|
||||
self.assertEqual(
|
||||
sorted(salt.utils.data.decode(tar_obj.getnames())),
|
||||
sorted(salt.utils.data.decode(tar_obj.getnames(),
|
||||
encoding='utf-8')),
|
||||
sorted([
|
||||
'foo', 'foo/bar', 'foo/baz', 'foo/foo', 'foo/питон',
|
||||
'foo/qux', 'foo/qux/bar', 'foo/qux/baz', 'foo/qux/foo',
|
||||
@ -236,7 +238,8 @@ class GitModuleTest(ModuleCase):
|
||||
self.assertTrue(tarfile.is_tarfile(tar_archive))
|
||||
with closing(tarfile.open(tar_archive, 'r')) as tar_obj:
|
||||
self.assertEqual(
|
||||
sorted(salt.utils.data.decode(tar_obj.getnames())),
|
||||
sorted(salt.utils.data.decode(tar_obj.getnames(),
|
||||
encoding='utf-8')),
|
||||
sorted(['foo', 'foo/bar', 'foo/baz', 'foo/foo', 'foo/питон'])
|
||||
)
|
||||
finally:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,7 @@ import signal
|
||||
import socket
|
||||
import string
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import tornado.ioloop
|
||||
@ -50,7 +51,7 @@ except ImportError:
|
||||
# Import Salt Tests Support libs
|
||||
from tests.support.unit import skip, _id
|
||||
from tests.support.mock import patch
|
||||
from tests.support.paths import FILES
|
||||
from tests.support.paths import FILES, TMP
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -954,6 +955,24 @@ def with_system_user_and_group(username, group,
|
||||
return decorator
|
||||
|
||||
|
||||
def with_tempfile(func):
|
||||
'''
|
||||
Generates a tempfile and cleans it up when test completes.
|
||||
'''
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
fd_, name = tempfile.mkstemp(prefix='__salt.test.', dir=TMP)
|
||||
os.close(fd_)
|
||||
del fd_
|
||||
ret = func(self, name, *args, **kwargs)
|
||||
try:
|
||||
os.remove(name)
|
||||
except Exception:
|
||||
pass
|
||||
return ret
|
||||
return wrapper
|
||||
|
||||
|
||||
def requires_system_grains(func):
|
||||
'''
|
||||
Function decorator which loads and passes the system's grains to the test
|
||||
|
@ -285,10 +285,11 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
"We shall say 'Ni' again to you, if you do not appease us."
|
||||
])
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'#-- START BLOCK 1',
|
||||
'#-- END BLOCK 1',
|
||||
new_multiline_content,
|
||||
backup=False)
|
||||
marker_start='#-- START BLOCK 1',
|
||||
marker_end='#-- END BLOCK 1',
|
||||
content=new_multiline_content,
|
||||
backup=False,
|
||||
append_newline=None)
|
||||
|
||||
with salt.utils.files.fopen(self.tfile.name, 'rb') as fp:
|
||||
filecontent = fp.read()
|
||||
@ -306,9 +307,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
CommandExecutionError,
|
||||
filemod.blockreplace,
|
||||
self.tfile.name,
|
||||
'#-- START BLOCK 2',
|
||||
'#-- END BLOCK 2',
|
||||
new_content,
|
||||
marker_start='#-- START BLOCK 2',
|
||||
marker_end='#-- END BLOCK 2',
|
||||
content=new_content,
|
||||
append_if_not_found=False,
|
||||
backup=False
|
||||
)
|
||||
@ -319,9 +320,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
)
|
||||
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'#-- START BLOCK 2',
|
||||
'#-- END BLOCK 2',
|
||||
new_content,
|
||||
marker_start='#-- START BLOCK 2',
|
||||
marker_end='#-- END BLOCK 2',
|
||||
content=new_content,
|
||||
backup=False,
|
||||
append_if_not_found=True)
|
||||
|
||||
@ -382,9 +383,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
CommandExecutionError,
|
||||
filemod.blockreplace,
|
||||
self.tfile.name,
|
||||
'#-- START BLOCK 2',
|
||||
'#-- END BLOCK 2',
|
||||
new_content,
|
||||
marker_start='#-- START BLOCK 2',
|
||||
marker_end='#-- END BLOCK 2',
|
||||
content=new_content,
|
||||
prepend_if_not_found=False,
|
||||
backup=False
|
||||
)
|
||||
@ -396,8 +397,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
fp.read())
|
||||
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'#-- START BLOCK 2', '#-- END BLOCK 2',
|
||||
new_content,
|
||||
marker_start='#-- START BLOCK 2',
|
||||
marker_end='#-- END BLOCK 2',
|
||||
content=new_content,
|
||||
backup=False,
|
||||
prepend_if_not_found=True)
|
||||
|
||||
@ -410,9 +412,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
|
||||
def test_replace_partial_marked_lines(self):
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK',
|
||||
'// END BLOCK',
|
||||
'new content 1',
|
||||
marker_start='// START BLOCK',
|
||||
marker_end='// END BLOCK',
|
||||
content='new content 1',
|
||||
backup=False)
|
||||
|
||||
with salt.utils.files.fopen(self.tfile.name, 'r') as fp:
|
||||
@ -420,7 +422,7 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
self.assertIn('new content 1', filecontent)
|
||||
self.assertNotIn('to be removed', filecontent)
|
||||
self.assertIn('first part of start line', filecontent)
|
||||
self.assertIn('first part of end line', filecontent)
|
||||
self.assertNotIn('first part of end line', filecontent)
|
||||
self.assertIn('part of start line not removed', filecontent)
|
||||
self.assertIn('part of end line not removed', filecontent)
|
||||
|
||||
@ -430,7 +432,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
|
||||
filemod.blockreplace(
|
||||
self.tfile.name,
|
||||
'// START BLOCK', '// END BLOCK', 'new content 2',
|
||||
marker_start='// START BLOCK',
|
||||
marker_end='// END BLOCK',
|
||||
content='new content 2',
|
||||
backup=fext)
|
||||
|
||||
self.assertTrue(os.path.exists(bak_file))
|
||||
@ -441,22 +445,27 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
bak_file = '{0}{1}'.format(self.tfile.name, fext)
|
||||
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK', '// END BLOCK', 'new content 3',
|
||||
marker_start='// START BLOCK',
|
||||
marker_end='// END BLOCK',
|
||||
content='new content 3',
|
||||
backup=False)
|
||||
|
||||
self.assertFalse(os.path.exists(bak_file))
|
||||
|
||||
def test_no_modifications(self):
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK', '// END BLOCK',
|
||||
'new content 4',
|
||||
backup=False)
|
||||
marker_start='#-- START BLOCK 1',
|
||||
marker_end='#-- END BLOCK 1',
|
||||
content='new content 4',
|
||||
backup=False,
|
||||
append_newline=None)
|
||||
before_ctime = os.stat(self.tfile.name).st_mtime
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK',
|
||||
'// END BLOCK',
|
||||
'new content 4',
|
||||
backup=False)
|
||||
marker_start='#-- START BLOCK 1',
|
||||
marker_end='#-- END BLOCK 1',
|
||||
content='new content 4',
|
||||
backup=False,
|
||||
append_newline=None)
|
||||
after_ctime = os.stat(self.tfile.name).st_mtime
|
||||
|
||||
self.assertEqual(before_ctime, after_ctime)
|
||||
@ -464,9 +473,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
def test_dry_run(self):
|
||||
before_ctime = os.stat(self.tfile.name).st_mtime
|
||||
filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK',
|
||||
'// END BLOCK',
|
||||
'new content 5',
|
||||
marker_start='// START BLOCK',
|
||||
marker_end='// END BLOCK',
|
||||
content='new content 5',
|
||||
dry_run=True)
|
||||
after_ctime = os.stat(self.tfile.name).st_mtime
|
||||
|
||||
@ -474,18 +483,18 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
|
||||
def test_show_changes(self):
|
||||
ret = filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK',
|
||||
'// END BLOCK',
|
||||
'new content 6',
|
||||
marker_start='// START BLOCK',
|
||||
marker_end='// END BLOCK',
|
||||
content='new content 6',
|
||||
backup=False,
|
||||
show_changes=True)
|
||||
|
||||
self.assertTrue(ret.startswith('---')) # looks like a diff
|
||||
|
||||
ret = filemod.blockreplace(self.tfile.name,
|
||||
'// START BLOCK',
|
||||
'// END BLOCK',
|
||||
'new content 7',
|
||||
marker_start='// START BLOCK',
|
||||
marker_end='// END BLOCK',
|
||||
content='new content 7',
|
||||
backup=False,
|
||||
show_changes=False)
|
||||
|
||||
@ -496,9 +505,9 @@ class FileBlockReplaceTestCase(TestCase, LoaderModuleMockMixin):
|
||||
CommandExecutionError,
|
||||
filemod.blockreplace,
|
||||
self.tfile.name,
|
||||
'#-- START BLOCK UNFINISHED',
|
||||
'#-- END BLOCK UNFINISHED',
|
||||
'foobar',
|
||||
marker_start='#-- START BLOCK UNFINISHED',
|
||||
marker_end='#-- END BLOCK UNFINISHED',
|
||||
content='foobar',
|
||||
backup=False
|
||||
)
|
||||
|
||||
|
@ -28,8 +28,10 @@ class OpenscapTestCase(TestCase):
|
||||
policy_file = '/usr/share/openscap/policy-file-xccdf.xml'
|
||||
|
||||
def setUp(self):
|
||||
import salt.modules.openscap
|
||||
salt.modules.openscap.__salt__ = MagicMock()
|
||||
patchers = [
|
||||
patch('salt.modules.openscap.Caller', MagicMock()),
|
||||
patch('salt.modules.openscap.__salt__', MagicMock()),
|
||||
patch('salt.modules.openscap.shutil.rmtree', Mock()),
|
||||
patch(
|
||||
'salt.modules.openscap.tempfile.mkdtemp',
|
||||
@ -68,8 +70,7 @@ class OpenscapTestCase(TestCase):
|
||||
cwd=openscap.tempfile.mkdtemp.return_value,
|
||||
stderr=PIPE,
|
||||
stdout=PIPE)
|
||||
openscap.Caller().cmd.assert_called_once_with(
|
||||
'cp.push_dir', self.random_temp_dir)
|
||||
openscap.__salt__['cp.push_dir'].assert_called_once_with(self.random_temp_dir)
|
||||
self.assertEqual(openscap.shutil.rmtree.call_count, 1)
|
||||
self.assertEqual(
|
||||
response,
|
||||
@ -106,8 +107,7 @@ class OpenscapTestCase(TestCase):
|
||||
cwd=openscap.tempfile.mkdtemp.return_value,
|
||||
stderr=PIPE,
|
||||
stdout=PIPE)
|
||||
openscap.Caller().cmd.assert_called_once_with(
|
||||
'cp.push_dir', self.random_temp_dir)
|
||||
openscap.__salt__['cp.push_dir'].assert_called_once_with(self.random_temp_dir)
|
||||
self.assertEqual(openscap.shutil.rmtree.call_count, 1)
|
||||
self.assertEqual(
|
||||
response,
|
||||
|
@ -14,10 +14,12 @@ from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch, MagicMock
|
||||
|
||||
# Import Salt libs
|
||||
import salt.config
|
||||
import salt.utils.path
|
||||
from salt.client import ssh
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
@skipIf(not salt.utils.path.which('ssh'), "No ssh binary found in path")
|
||||
class SSHPasswordTests(ShellCase):
|
||||
def test_password_failure(self):
|
||||
'''
|
||||
|
@ -84,7 +84,7 @@ class DockerImageTestCase(TestCase, LoaderModuleMockMixin):
|
||||
- force: true
|
||||
|
||||
if ``image:latest`` is not downloaded and force is true
|
||||
should pull a new image successfuly.
|
||||
should pull a new image successfully.
|
||||
'''
|
||||
docker_inspect_image = MagicMock(return_value={'Id': '1234567890ab'})
|
||||
docker_pull = MagicMock(
|
||||
|
@ -482,7 +482,7 @@ class UtilStateMergeSubreturnTestcase(TestCase):
|
||||
res = salt.utils.state.merge_subreturn(m, s)
|
||||
self.assertFalse(res['result'])
|
||||
|
||||
# False result cannot be overriden
|
||||
# False result cannot be overridden
|
||||
for any_result in [True, None, False]:
|
||||
m = copy.deepcopy(self.main_ret)
|
||||
m['result'] = False
|
||||
|
Loading…
Reference in New Issue
Block a user