mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Merge branch 'develop' into virtualenv_mod
This commit is contained in:
commit
d9b5018700
11
conf/master
11
conf/master
@ -356,12 +356,12 @@
|
||||
# If this is set to True the first newline after a Jinja block is removed
|
||||
# (block, not variable tag!). Defaults to False, corresponds to the Jinja
|
||||
# environment init variable "trim_blocks".
|
||||
# jinja_trim_blocks: False
|
||||
#jinja_trim_blocks: False
|
||||
#
|
||||
# If this is set to True leading spaces and tabs are stripped from the start
|
||||
# of a line to a block. Defaults to False, corresponds to the Jinja
|
||||
# environment init variable "lstrip_blocks".
|
||||
# jinja_lstrip_blocks: False
|
||||
#jinja_lstrip_blocks: False
|
||||
|
||||
# The failhard option tells the minions to stop immediately after the first
|
||||
# failure detected in the state execution, defaults to False
|
||||
@ -381,7 +381,7 @@
|
||||
#state_output: full
|
||||
|
||||
# Automatically aggregate all states that have support for mod_aggregate by
|
||||
# setting to True. Or pass a list of state module names to automatically
|
||||
# setting to 'True'. Or pass a list of state module names to automatically
|
||||
# aggregate just those types.
|
||||
#
|
||||
# state_aggregate:
|
||||
@ -389,6 +389,11 @@
|
||||
#
|
||||
#state_aggregate: False
|
||||
|
||||
# Send progress events as each function in a state run completes execution
|
||||
# by setting to 'True'. Progress events are in the format
|
||||
# 'salt/job/<JID>/prog/<MID>/<RUN NUM>'.
|
||||
#state_events: False
|
||||
|
||||
##### File Server settings #####
|
||||
##########################################
|
||||
# Salt runs a lightweight file server written in zeromq to deliver files to
|
||||
|
@ -908,6 +908,41 @@ If set to 'changes', the output will be full unless the state didn't change.
|
||||
|
||||
state_output: full
|
||||
|
||||
.. conf_master:: state_aggregate
|
||||
|
||||
``state_aggregate``
|
||||
-------------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Automatically aggregate all states that have support for mod_aggregate by
|
||||
setting to ``True``. Or pass a list of state module names to automatically
|
||||
aggregate just those types.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
state_aggregate:
|
||||
- pkg
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
state_aggregate: True
|
||||
|
||||
.. conf_master:: state_events
|
||||
|
||||
``state_events``
|
||||
----------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Send progress events as each function in a state run completes execution
|
||||
by setting to ``True``. Progress events are in the format
|
||||
``salt/job/<JID>/prog/<MID>/<RUN NUM>``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
state_events: True
|
||||
|
||||
.. conf_master:: yaml_utf8
|
||||
|
||||
``yaml_utf8``
|
||||
@ -2308,10 +2343,21 @@ master, specify the higher level master with this configuration value.
|
||||
|
||||
syndic_master: masterofmasters
|
||||
|
||||
You can optionally connect a syndic to multiple higher level masters by
|
||||
setting the 'syndic_master' value to a list:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
syndic_master:
|
||||
- masterofmasters1
|
||||
- masterofmasters2
|
||||
|
||||
Each higher level master must be set up in a multimaster configuration.
|
||||
|
||||
.. conf_master:: syndic_master_port
|
||||
|
||||
``syndic_master_port``
|
||||
-----------------------
|
||||
----------------------
|
||||
|
||||
Default: ``4506``
|
||||
|
||||
|
@ -553,7 +553,7 @@ be able to execute a certain module. The sys module is built into the minion
|
||||
and cannot be disabled.
|
||||
|
||||
This setting can also tune the minion, as all modules are loaded into ram
|
||||
disabling modules will lover the minion's ram footprint.
|
||||
disabling modules will lower the minion's ram footprint.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -78,6 +78,11 @@ append a ``%`` to the ID:
|
||||
- '*':
|
||||
- 'pkg.*'
|
||||
|
||||
.. warning::
|
||||
All users that have external authentication privileges are allowed to run
|
||||
:mod:`saltutil.findjob <salt.modules.saltutil.find_job>`. Be aware
|
||||
that this could inadvertently expose some data such as minion IDs.
|
||||
|
||||
.. _salt-token-generation:
|
||||
|
||||
Tokens
|
||||
|
@ -86,6 +86,15 @@ Job events
|
||||
:var fun: The function the minion ran. E.g., ``test.ping``.
|
||||
:var return: The data returned from the execution module.
|
||||
|
||||
.. salt:event:: salt/job/<JID>/prog/<MID>/<RUN NUM>
|
||||
|
||||
Fired each time a each function in a state run completes execution. Must be
|
||||
enabled using the :conf_master:`state_events` option.
|
||||
|
||||
:var data: The data returned from the state module function.
|
||||
:var id: The minion ID.
|
||||
:var jid: The job ID.
|
||||
|
||||
.. _event-master_presence:
|
||||
|
||||
Presence events
|
||||
|
@ -63,3 +63,12 @@ of Masters" nodes can control multiple segments underneath them.
|
||||
|
||||
Syndics are covered in depth in :doc:`Salt Syndic </topics/topology/syndic>`.
|
||||
|
||||
Syndic with Multimaster
|
||||
=======================
|
||||
|
||||
.. versionadded:: 2015.5.0
|
||||
|
||||
Syndic with Multimaster lets you connect a syndic to multiple masters to provide
|
||||
an additional layer of redundancy in a syndic configuration.
|
||||
|
||||
Syndics are covered in depth in :doc:`Salt Syndic </topics/topology/syndic>`.
|
1313
doc/topics/releases/2015.8.0rc3.rst
Normal file
1313
doc/topics/releases/2015.8.0rc3.rst
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,14 @@ Salt Cloud Changes
|
||||
a page was changed from 20 (default) to 200 to reduce the number of API calls
|
||||
to Digital Ocean.
|
||||
|
||||
New Docker State/Module
|
||||
=======================
|
||||
|
||||
A new docker :mod:`state <salt.states.dockerng>` and :mod:`execution module
|
||||
<salt.modules.dockerng>` have been added. They will eventually take the place
|
||||
of the existing state and execution module, but for now will exist alongside
|
||||
them.
|
||||
|
||||
Git Pillar Rewritten
|
||||
====================
|
||||
|
||||
@ -31,6 +39,25 @@ with :mod:`gitfs <salt.fileserver.gitfs>`. See :mod:`here
|
||||
<salt.pillar.git_pillar>` for more information on the new git_pillar
|
||||
functionality.
|
||||
|
||||
Windows Software Repo Changes
|
||||
=============================
|
||||
|
||||
The :mod:`winrepo.update_git_repos <salt.runners.winrepo.update_git_repos>`
|
||||
runner has been updated to use either GitPython_ or pygit2_ to checkout the git
|
||||
repositories containing repo data. Existing winrepo git checkouts should be
|
||||
removed before starting up the salt-master after upgrading, if GitPython_ or
|
||||
pygit2_ is installed, to allow them to be checked out again.
|
||||
|
||||
This enhancement also brings new functionality, see the :mod:`winrepo runner
|
||||
<salt.runners.winrepo>` documentation for more information.
|
||||
|
||||
If neither GitPython_ nor pygit2_ are installed, then Salt will fall back to
|
||||
the pre-existing behavior for :mod:`winrepo.update_git_repos
|
||||
<salt.runners.winrepo.update_git_repos>`.
|
||||
|
||||
.. _GitPython: https://github.com/gitpython-developers/GitPython
|
||||
.. _pygit2: https://github.com/libgit2/pygit2
|
||||
|
||||
JBoss 7 State
|
||||
=============
|
||||
|
||||
|
@ -4,102 +4,207 @@
|
||||
Salt Syndic
|
||||
===========
|
||||
|
||||
The Salt Syndic interface is a powerful tool which allows for the construction
|
||||
of Salt command topologies. A basic Salt setup has a Salt Master commanding a
|
||||
group of Salt Minions. The Syndic interface is a special passthrough
|
||||
minion, it is run on a master and connects to another master, then the master
|
||||
that the Syndic minion is listening to can control the minions attached to
|
||||
the master running the syndic.
|
||||
The most basic or typical Salt topology consists of a single Master node
|
||||
controlling a group of Minion nodes. An intermediate node type, called Syndic,
|
||||
when used offers greater structural flexibility and scalability in the
|
||||
construction of Salt topologies than topologies constructed only out of Master
|
||||
and Minion node types.
|
||||
|
||||
The intent for supporting many layouts is not presented with the intent of
|
||||
supposing the use of any single topology, but to allow a more flexible method
|
||||
of controlling many systems.
|
||||
A Syndic node can be thought of as a special passthrough Minion node. A Syndic
|
||||
node consists of a ``salt-syndic`` daemon and a ``salt-master`` daemon running
|
||||
on the same system. The ``salt-master`` daemon running on the Syndic node
|
||||
controls a group of lower level Minion nodes and the ``salt-syndic`` daemon
|
||||
connects higher level Master node, sometimes called a Master of Masters.
|
||||
|
||||
The ``salt-syndic`` daemon relays publications and events between the Master
|
||||
node and the local ``salt-master`` daemon. This gives the Master node control
|
||||
over the Minion nodes attached to the ``salt-master`` daemon running on the
|
||||
Syndic node.
|
||||
|
||||
Configuring the Syndic
|
||||
======================
|
||||
|
||||
Since the Syndic only needs to be attached to a higher level master the
|
||||
configuration is very simple. On a master that is running a syndic to connect
|
||||
to a higher level master the :conf_master:`syndic_master` option needs to be
|
||||
set in the master config file. The ``syndic_master`` option contains the
|
||||
hostname or IP address of the master server that can control the master that
|
||||
the syndic is running on.
|
||||
To setup a Salt Syndic you need to tell the Syndic node and its Master node
|
||||
about each other. If your Master node is located at ``10.10.0.1``, then your
|
||||
configurations would be:
|
||||
|
||||
The master that the syndic connects to sees the syndic as an ordinary minion,
|
||||
and treats it as such. the higher level master will need to accept the syndic's
|
||||
minion key like any other minion. This master will also need to set the
|
||||
:conf_master:`order_masters` value in the configuration to ``True``. The
|
||||
``order_masters`` option in the config on the higher level master is very
|
||||
important, to control a syndic extra information needs to be sent with the
|
||||
publications, the ``order_masters`` option makes sure that the extra data is
|
||||
sent out.
|
||||
On the Syndic node:
|
||||
|
||||
To sum up, you have those configuration options available on the master side:
|
||||
.. code-block:: yaml
|
||||
|
||||
- :conf_master:`syndic_master`: MasterOfMaster ip/address
|
||||
- :conf_master:`syndic_master_port`: MasterOfMaster ret_port
|
||||
- :conf_master:`syndic_log_file`: path to the logfile (absolute or not)
|
||||
- :conf_master:`syndic_pidfile`: path to the pidfile (absolute or not)
|
||||
# /etc/salt/master
|
||||
syndic_master: 10.10.0.1 # may be either an IP address or a hostname
|
||||
|
||||
Each Syndic must provide its own ``file_roots`` directory. Files will not be
|
||||
automatically transferred from the master-master.
|
||||
.. code-block:: yaml
|
||||
|
||||
# /etc/salt/minion
|
||||
|
||||
# id is shared by the salt-syndic daemon and a possible salt-minion daemon
|
||||
# on the Syndic node
|
||||
id: my_syndic
|
||||
|
||||
On the Master node:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# /etc/salt/master
|
||||
order_masters: True
|
||||
|
||||
The :conf_master:`syndic_master` option tells the Syndic node where to find the
|
||||
Master node in the same way that the :conf_minion:`master` option tells a
|
||||
Minion node where to find a Master node.
|
||||
|
||||
The :conf_minion:`id` option is used by the ``salt-syndic`` daemon to identify
|
||||
with the Master node and if unset will default to the hostname or IP address of
|
||||
the Syndic just as with a Minion.
|
||||
|
||||
The :conf_master:`order_masters` option configures the Master node to send
|
||||
extra information with its publications that is needed by Syndic nodes
|
||||
connected directly to it.
|
||||
|
||||
.. note::
|
||||
|
||||
Each Syndic must provide its own ``file_roots`` directory. Files will not
|
||||
be automatically transferred from the Master node.
|
||||
|
||||
Configuring the Syndic with Multimaster
|
||||
=======================================
|
||||
|
||||
.. versionadded:: 2015.5.0
|
||||
|
||||
Syndic with Multimaster lets you connect a syndic to multiple masters to provide
|
||||
an additional layer of redundancy in a syndic configuration.
|
||||
|
||||
Higher level masters should first be configured in a multimaster configuration.
|
||||
See :doc:`Multimaster Tutorial </topics/tutorials/multimaster>`.
|
||||
|
||||
On the syndic, the :conf_master:`syndic_master` option is populated with
|
||||
a list of the higher level masters.
|
||||
|
||||
Since each syndic is connected to each master, jobs sent from any master are
|
||||
forwarded to minions that are connected to each syndic. If the ``master_id`` value
|
||||
is set in the master config on the higher level masters, job results are returned
|
||||
to the master that originated the request in a best effort fashion. Events/jobs
|
||||
without a ``master_id`` are returned to any available master.
|
||||
|
||||
Running the Syndic
|
||||
==================
|
||||
|
||||
The Syndic is a separate daemon that needs to be started on the master that is
|
||||
controlled by a higher master. Starting the Syndic daemon is the same as
|
||||
starting the other Salt daemons.
|
||||
The ``salt-syndic`` daemon is a separate process that needs to be started in
|
||||
addition to the ``salt-master`` daemon running on the Syndic node. Starting
|
||||
the ``salt-syndic`` daemon is the same as starting the other Salt daemons.
|
||||
|
||||
The Master node in many ways sees the Syndic as an ordinary Minion node. In
|
||||
particular, the Master will need to accept the Syndic's Minion key as it would
|
||||
for any other Minion.
|
||||
|
||||
On the Syndic node:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt-syndic
|
||||
or
|
||||
# service salt-syndic start
|
||||
|
||||
.. note::
|
||||
On the Master node:
|
||||
|
||||
If you have an exceptionally large infrastructure or many layers of
|
||||
syndics, you may find that the CLI doesn't wait long enough for the syndics
|
||||
to return their events. If you think this is the case, you can set the
|
||||
:conf_master:`syndic_wait` value in the upper master config. The default
|
||||
value is ``1``, and should work for the majority of deployments.
|
||||
.. code-block:: bash
|
||||
|
||||
# salt-key -a my_syndic
|
||||
|
||||
The Master node will now be able to control the Minion nodes connected to the
|
||||
Syndic. Only the Syndic key will be listed in the Master node's key registry
|
||||
but this also means that key activity between the Syndic's Minions and the
|
||||
Syndic does not encumber the Master node. In this way, the Syndic's key on the
|
||||
Master node can be thought of as a placeholder for the keys of all the Minion
|
||||
and Syndic nodes beneath it, giving the Master node a clear, high level
|
||||
structural view on the Salt cluster.
|
||||
|
||||
On the Master node:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt-key -L
|
||||
Accepted Keys:
|
||||
my_syndic
|
||||
Denied Keys:
|
||||
Unaccepted Keys:
|
||||
Rejected Keys:
|
||||
|
||||
# salt '*' test.ping
|
||||
minion_1:
|
||||
True
|
||||
minion_2:
|
||||
True
|
||||
minion_4:
|
||||
True
|
||||
minion_3:
|
||||
True
|
||||
|
||||
Topology
|
||||
========
|
||||
|
||||
The ``salt-syndic`` is little more than a command and event forwarder. When a
|
||||
command is issued from a higher-level master, it will be received by the
|
||||
configured syndics on lower-level masters, and propagated to to their minions,
|
||||
and other syndics that are bound to them further down in the hierarchy. When
|
||||
events and job return data are generated by minions, they aggregated back,
|
||||
through the same syndic(s), to the master which issued the command.
|
||||
A Master node (a node which is itself not a Syndic to another higher level
|
||||
Master node) must run a ``salt-master`` daemon and optionally a ``salt-minion``
|
||||
daemon.
|
||||
|
||||
The master sitting at the top of the hierarchy (the Master of Masters) will *not*
|
||||
be running the ``salt-syndic`` daemon. It will have the ``salt-master``
|
||||
daemon running, and optionally, the ``salt-minion`` daemon. Each syndic
|
||||
connected to an upper-level master will have both the ``salt-master`` and the
|
||||
``salt-syndic`` daemon running, and optionally, the ``salt-minion`` daemon.
|
||||
A Syndic node must run ``salt-syndic`` and ``salt-master`` daemons and
|
||||
optionally a ``salt-minion`` daemon.
|
||||
|
||||
Nodes on the lowest points of the hierarchy (minions which do not propagate
|
||||
data to another level) will only have the ``salt-minion`` daemon running. There
|
||||
is no need for either ``salt-master`` or ``salt-syndic`` to be running on a
|
||||
standard minion.
|
||||
A Minion node must run a ``salt-minion`` daemon.
|
||||
|
||||
Syndic and the CLI
|
||||
==================
|
||||
When a ``salt-master`` daemon issues a command, it will be received by the
|
||||
Syndic and Minion nodes directly connected to it. A Minion node will process
|
||||
the command in the way it ordinarily would. On a Syndic node, the
|
||||
``salt-syndic`` daemon will relay the command to the ``salt-master`` daemon
|
||||
running on the Syndic node, which then propagates the command to to the Minions
|
||||
and Syndics connected to it.
|
||||
|
||||
In order for the high-level master to return information from minions that are
|
||||
below the syndic(s), the CLI requires a short wait time in order to allow the
|
||||
syndic(s) to gather responses from their minions. This value is defined in the
|
||||
``syndic_wait`` and has a default of five seconds.
|
||||
When events and job return data are generated by ``salt-minion`` daemons, they
|
||||
are aggregated by the ``salt-master`` daemon they are connected to, which
|
||||
``salt-master`` daemon then relays the data back through its ``salt-syndic``
|
||||
daemon until the data reaches the Master or Syndic node that issued the command.
|
||||
|
||||
While it is possible to run a syndic without a minion installed on the same machine,
|
||||
it is recommended, for a faster CLI response time, to do so. Without a minion
|
||||
installed on the syndic, the timeout value of ``syndic_wait`` increases
|
||||
significantly - about three-fold. With a minion installed on the syndic, the CLI
|
||||
timeout resides at the value defined in ``syndic_wait``.
|
||||
Syndic wait
|
||||
===========
|
||||
|
||||
.. note::
|
||||
|
||||
To reduce the amount of time the CLI waits for minions to respond, install a minion
|
||||
on the syndic or tune the value of the ``syndic_wait`` configuration.
|
||||
To reduce the amount of time the CLI waits for Minions to respond, install
|
||||
a Minion on the Syndic or tune the value of the ``syndic_wait``
|
||||
configuration.
|
||||
|
||||
While it is possible to run a Syndic without a Minion installed on the same
|
||||
system, it is recommended, for a faster CLI response time, to do so. Without a
|
||||
Minion installed on the Syndic node, the timeout value of ``syndic_wait``
|
||||
increases significantly - about three-fold. With a Minion installed on the
|
||||
Syndic, the CLI timeout resides at the value defined in ``syndic_wait``.
|
||||
|
||||
.. note::
|
||||
|
||||
If you have a very large infrastructure or many layers of Syndics, you may
|
||||
find that the CLI doesn't wait long enough for the Syndics to return their
|
||||
events. If you think this is the case, you can set the
|
||||
:conf_master:`syndic_wait` value in the Master configs on the Master or
|
||||
Syndic nodes from which commands are executed. The default value is ``5``,
|
||||
and should work for the majority of deployments.
|
||||
|
||||
In order for a Master or Syndic node to return information from Minions that
|
||||
are below their Syndics, the CLI requires a short wait time in order to allow
|
||||
the Syndics to gather responses from their Minions. This value is defined in
|
||||
the :conf_master:`syndic_wait` config option and has a default of five seconds.
|
||||
|
||||
Syndic config options
|
||||
=====================
|
||||
|
||||
These are the options that can be used to configure a Syndic node. Note that
|
||||
other than ``id``, Syndic config options are placed in the Master config on the
|
||||
Syndic node.
|
||||
|
||||
- :conf_minion:`id`: Syndic id (shared by the ``salt-syndic`` daemon with a
|
||||
potential ``salt-minion`` daemon on the same system)
|
||||
- :conf_master:`syndic_master`: Master node IP address or hostname
|
||||
- :conf_master:`syndic_master_port`: Master node ret_port
|
||||
- :conf_master:`syndic_log_file`: path to the logfile (absolute or not)
|
||||
- :conf_master:`syndic_pidfile`: path to the pidfile (absolute or not)
|
||||
- :conf_master:`syndic_wait`: time in seconds to wait on returns from this syndic
|
||||
|
@ -170,6 +170,20 @@ Add ``cache_dir: True`` when the installer requires multiple source files. The
|
||||
directory containing the installer file will be recursively cached on the minion.
|
||||
Only applies to salt: installer URLs.
|
||||
|
||||
Alternatively the ``uninstaller`` can also simply repeat the URL of the msi file.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
7zip:
|
||||
9.20.00.0:
|
||||
installer: salt://win/repo/7zip/7z920-x64.msi
|
||||
full_name: 7-Zip 9.20 (x64 edition)
|
||||
reboot: False
|
||||
install_flags: '/qn /norestart'
|
||||
msiexec: True
|
||||
uninstaller: salt://win/repo/7zip/7z920-x64.msi
|
||||
uninstall_flags: '/qn /norestart'
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
sqlexpress:
|
||||
|
@ -57,7 +57,7 @@ class SPMClient(object):
|
||||
elif command == 'build':
|
||||
self._build(args)
|
||||
elif command == 'update_repo':
|
||||
self._download_repo_metadata()
|
||||
self._download_repo_metadata(args)
|
||||
elif command == 'create_repo':
|
||||
self._create_repo(args)
|
||||
elif command == 'files':
|
||||
@ -235,7 +235,7 @@ class SPMClient(object):
|
||||
formula_tar.close()
|
||||
conn.close()
|
||||
|
||||
def _traverse_repos(self, callback):
|
||||
def _traverse_repos(self, callback, repo_name=None):
|
||||
'''
|
||||
Traverse through all repo files and apply the functionality provided in
|
||||
the callback to them
|
||||
@ -260,9 +260,11 @@ class SPMClient(object):
|
||||
for repo in repo_data:
|
||||
if repo_data[repo].get('enabled', True) is False:
|
||||
continue
|
||||
if repo_name is not None and repo != repo_name:
|
||||
continue
|
||||
callback(repo, repo_data[repo])
|
||||
|
||||
def _download_repo_metadata(self):
|
||||
def _download_repo_metadata(self, args):
|
||||
'''
|
||||
Connect to all repos and download metadata
|
||||
'''
|
||||
@ -283,7 +285,8 @@ class SPMClient(object):
|
||||
with salt.utils.fopen(cache_path, 'w') as cph:
|
||||
msgpack.dump(metadata, cph)
|
||||
|
||||
self._traverse_repos(_update_metadata)
|
||||
repo_name = args[1] if len(args) > 1 else None
|
||||
self._traverse_repos(_update_metadata, repo_name)
|
||||
|
||||
def _get_repo_metadata(self):
|
||||
'''
|
||||
|
@ -1681,11 +1681,11 @@ class Map(Cloud):
|
||||
return {}
|
||||
|
||||
if not os.path.isfile(self.opts['map']):
|
||||
raise SaltCloudNotFound(
|
||||
'The specified map file does not exist: {0}\n'.format(
|
||||
self.opts['map']
|
||||
)
|
||||
log.error(
|
||||
'The specified map file does not exist: \'{0}\''.format(
|
||||
self.opts['map'])
|
||||
)
|
||||
raise SaltCloudNotFound()
|
||||
try:
|
||||
renderer = self.opts.get('renderer', 'yaml_jinja')
|
||||
rend = salt.loader.render(self.opts, {})
|
||||
|
@ -84,7 +84,11 @@ class SaltCloud(parsers.SaltCloudParser):
|
||||
self.exit(salt.defaults.exitcodes.EX_OK)
|
||||
|
||||
log.info('salt-cloud starting')
|
||||
mapper = salt.cloud.Map(self.config)
|
||||
try:
|
||||
mapper = salt.cloud.Map(self.config)
|
||||
except SaltCloudException as exc:
|
||||
msg = 'There was an error generating the mapper.'
|
||||
self.handle_exception(msg, exc)
|
||||
|
||||
names = self.config.get('names', None)
|
||||
if names is not None:
|
||||
@ -163,12 +167,21 @@ class SaltCloud(parsers.SaltCloudParser):
|
||||
|
||||
elif self.options.destroy and (self.config.get('names', None) or
|
||||
self.config.get('map', None)):
|
||||
if self.config.get('map', None):
|
||||
log.info('Applying map from {0!r}.'.format(self.config['map']))
|
||||
map_file = self.config.get('map', None)
|
||||
names = self.config.get('names', ())
|
||||
if map_file is not None:
|
||||
if names != ():
|
||||
msg = 'Supplying a mapfile, \'{0}\', in addition to instance names {1} ' \
|
||||
'with the \'--destroy\' or \'-d\' function is not supported. ' \
|
||||
'Please choose to delete either the entire map file or individual ' \
|
||||
'instances.'.format(map_file, names)
|
||||
self.handle_exception(msg, SaltCloudSystemExit)
|
||||
|
||||
log.info('Applying map from \'{0}\'.'.format(map_file))
|
||||
matching = mapper.delete_map(query='list_nodes')
|
||||
else:
|
||||
matching = mapper.get_running_by_names(
|
||||
self.config.get('names', ()),
|
||||
names,
|
||||
profile=self.options.profile
|
||||
)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1696,21 +1696,21 @@ class ClearFuncs(object):
|
||||
try:
|
||||
name = self.loadauth.load_name(clear_load)
|
||||
groups = self.loadauth.get_groups(clear_load)
|
||||
if not ((name in self.opts['external_auth'][clear_load['eauth']]) |
|
||||
('*' in self.opts['external_auth'][clear_load['eauth']])):
|
||||
eauth_config = self.opts['external_auth'][clear_load['eauth']]
|
||||
if '*' not in eauth_config and name not in eauth_config:
|
||||
found = False
|
||||
for group in groups:
|
||||
if "{0}%".format(group) in self.opts['external_auth'][clear_load['eauth']]:
|
||||
if "{0}%".format(group) in eauth_config:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
log.warning('Authentication failure of type "eauth" occurred.')
|
||||
return ''
|
||||
else:
|
||||
clear_load['groups'] = groups
|
||||
if not self.loadauth.time_auth(clear_load):
|
||||
log.warning('Authentication failure of type "eauth" occurred.')
|
||||
return ''
|
||||
|
||||
clear_load['groups'] = groups
|
||||
return self.loadauth.mk_token(clear_load)
|
||||
except Exception as exc:
|
||||
log.error(
|
||||
@ -1759,40 +1759,45 @@ class ClearFuncs(object):
|
||||
)
|
||||
)
|
||||
return ''
|
||||
|
||||
# Bail if the token is empty or if the eauth type specified is not allowed
|
||||
if not token or token['eauth'] not in self.opts['external_auth']:
|
||||
log.warning('Authentication failure of type "token" occurred.')
|
||||
return ''
|
||||
if not ((token['name'] in self.opts['external_auth'][token['eauth']]) |
|
||||
('*' in self.opts['external_auth'][token['eauth']])):
|
||||
found = False
|
||||
for group in token['groups']:
|
||||
if "{0}%".format(group) in self.opts['external_auth'][token['eauth']]:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
log.warning('Authentication failure of type "token" occurred.')
|
||||
return ''
|
||||
|
||||
group_perm_keys = [item for item in self.opts['external_auth'][token['eauth']] if item.endswith('%')] # The configured auth groups
|
||||
# Fetch eauth config and collect users and groups configured for access
|
||||
eauth_config = self.opts['external_auth'][token['eauth']]
|
||||
eauth_users = []
|
||||
eauth_groups = []
|
||||
for entry in eauth_config:
|
||||
if entry.endswith('%'):
|
||||
eauth_groups.append(entry.rstrip('%'))
|
||||
else:
|
||||
eauth_users.append(entry)
|
||||
|
||||
# First we need to know if the user is allowed to proceed via any of their group memberships.
|
||||
# If there are groups in the token, check if any of them are listed in the eauth config
|
||||
group_auth_match = False
|
||||
for group_config in group_perm_keys:
|
||||
group_config = group_config.rstrip('%')
|
||||
try:
|
||||
for group in token['groups']:
|
||||
if group == group_config:
|
||||
if group in eauth_groups:
|
||||
group_auth_match = True
|
||||
break
|
||||
except KeyError:
|
||||
pass
|
||||
if '*' not in eauth_users and token['name'] not in eauth_users and not group_auth_match:
|
||||
log.warning('Authentication failure of type "token" occurred.')
|
||||
return ''
|
||||
|
||||
# Compile list of authorized actions for the user
|
||||
auth_list = []
|
||||
|
||||
if '*' in self.opts['external_auth'][token['eauth']]:
|
||||
auth_list.extend(self.opts['external_auth'][token['eauth']]['*'])
|
||||
if token['name'] in self.opts['external_auth'][token['eauth']]:
|
||||
auth_list.extend(self.opts['external_auth'][token['eauth']][token['name']])
|
||||
# Add permissions for '*' or user-specific to the auth list
|
||||
for user_key in ('*', token['name']):
|
||||
auth_list.extend(eauth_config.get(user_key, []))
|
||||
# Add any add'l permissions allowed by group membership
|
||||
if group_auth_match:
|
||||
auth_list = self.ckminions.fill_auth_list_from_groups(self.opts['external_auth'][token['eauth']], token['groups'], auth_list)
|
||||
auth_list = self.ckminions.fill_auth_list_from_groups(eauth_config, token['groups'], auth_list)
|
||||
|
||||
log.trace("compiled auth_list: {0}".format(auth_list))
|
||||
log.trace("Compiled auth_list: {0}".format(auth_list))
|
||||
|
||||
good = self.ckminions.auth_check(
|
||||
auth_list,
|
||||
|
@ -1597,7 +1597,7 @@ def del_repo_key(name=None, **kwargs):
|
||||
owner_name, ppa_name = name[4:].split('/')
|
||||
ppa_info = _get_ppa_info_from_launchpad(
|
||||
owner_name, ppa_name)
|
||||
keyid = ppa_info['signing_key_fingerprint']
|
||||
keyid = ppa_info['signing_key_fingerprint'][-8:]
|
||||
else:
|
||||
raise SaltInvocationError(
|
||||
'keyid_ppa requires that a PPA be passed'
|
||||
|
@ -19,11 +19,10 @@ option. This will give users a couple release cycles to modify their scripts,
|
||||
SLS files, etc. to use the new functionality, rather than forcing users to
|
||||
change everything immediately.
|
||||
|
||||
In the **Carbon** release of Salt (slated for late summer/early fall 2015),
|
||||
this execution module will take the place of the default Docker execution
|
||||
module, and backwards-compatible naming will be maintained for a couple
|
||||
releases after that to allow users time to replace references to ``dockerng``
|
||||
with ``docker``.
|
||||
In the **Carbon** release of Salt (due early 2016), this execution module will
|
||||
take the place of the default Docker execution module, and backwards-compatible
|
||||
naming will be maintained for a couple releases after that to allow users time
|
||||
to replace references to ``dockerng`` with ``docker``.
|
||||
|
||||
|
||||
Installation Prerequisites
|
||||
|
@ -66,7 +66,7 @@ def system_info():
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt dell drac.getsysinfo
|
||||
salt dell drac.system_info
|
||||
'''
|
||||
cmd = __salt__['cmd.run_all']('racadm getsysinfo')
|
||||
|
||||
@ -84,7 +84,7 @@ def network_info():
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt dell drac.getniccfg
|
||||
salt dell drac.network_info
|
||||
'''
|
||||
|
||||
cmd = __salt__['cmd.run_all']('racadm getniccfg')
|
||||
|
@ -7,9 +7,9 @@ from __future__ import absolute_import
|
||||
# Import Python libs
|
||||
import collections
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import os
|
||||
|
||||
# Import salt libs
|
||||
import salt.crypt
|
||||
|
@ -725,7 +725,7 @@ def install(name=None,
|
||||
opts += 'U'
|
||||
if salt.utils.is_true(dryrun):
|
||||
opts += 'n'
|
||||
if not salt.utils.is_true(dryrun) and pkg_type != 'file':
|
||||
if not salt.utils.is_true(dryrun):
|
||||
opts += 'y'
|
||||
if salt.utils.is_true(quiet):
|
||||
opts += 'q'
|
||||
|
@ -40,7 +40,7 @@ def __virtual__():
|
||||
'''
|
||||
Provides imgadm only on SmartOS
|
||||
'''
|
||||
if __grains__['os'] == "SmartOS" and _check_imgadm():
|
||||
if salt.utils.is_smartos_globalzone() and _check_imgadm():
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
|
@ -41,7 +41,7 @@ def __virtual__():
|
||||
'''
|
||||
Provides virt on SmartOS
|
||||
'''
|
||||
if __grains__['os'] == "SmartOS" and _check_vmadm():
|
||||
if salt.utils.is_smartos_globalzone() and _check_vmadm():
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
|
@ -104,9 +104,9 @@ def _wait(jid):
|
||||
|
||||
def running(concurrent=False):
|
||||
'''
|
||||
Return a dict of state return data if a state function is already running.
|
||||
This function is used to prevent multiple state calls from being run at
|
||||
the same time.
|
||||
Return a list of strings that contain state return data if a state function is
|
||||
already running. This function is used to prevent multiple state calls from being
|
||||
run at the same time.
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
@ -437,12 +437,28 @@ def genrepo(saltenv='base'):
|
||||
|
||||
def install(name=None, refresh=False, pkgs=None, saltenv='base', **kwargs):
|
||||
'''
|
||||
Install the passed package
|
||||
Install the passed package from the winrepo
|
||||
|
||||
Return a dict containing the new package names and versions::
|
||||
:param name: The name of the package to install
|
||||
:type name: str or None
|
||||
|
||||
{'<package>': {'old': '<old-version>',
|
||||
'new': '<new-version>'}}
|
||||
:param bool refresh: Boolean value representing whether or not to refresh
|
||||
the winrepo db
|
||||
|
||||
:param pkgs: A list of packages to install from a software repository.
|
||||
All packages listed under ``pkgs`` will be installed via a single
|
||||
command.
|
||||
:type pkgs: list or None
|
||||
|
||||
:param str saltenv: The salt environment to use. Default is ``base``.
|
||||
|
||||
:param dict kwargs: Any additional argument that may be passed from the
|
||||
state module. If they don't apply, they are ignored.
|
||||
|
||||
:return: Return a dict containing the new package names and versions::
|
||||
|
||||
{'<package>': {'old': '<old-version>',
|
||||
'new': '<new-version>'}}
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -507,6 +523,9 @@ def install(name=None, refresh=False, pkgs=None, saltenv='base', **kwargs):
|
||||
if not cached_pkg:
|
||||
# It's not cached. Cache it, mate.
|
||||
cached_pkg = __salt__['cp.cache_file'](installer, saltenv)
|
||||
if not cached_pkg:
|
||||
return 'Unable to cache file {0} from saltenv: {1}'\
|
||||
.format(installer, saltenv)
|
||||
if __salt__['cp.hash_file'](installer, saltenv) != \
|
||||
__salt__['cp.hash_file'](cached_pkg):
|
||||
cached_pkg = __salt__['cp.cache_file'](installer, saltenv)
|
||||
@ -516,6 +535,9 @@ def install(name=None, refresh=False, pkgs=None, saltenv='base', **kwargs):
|
||||
cached_pkg = cached_pkg.replace('/', '\\')
|
||||
cache_path, _ = os.path.split(cached_pkg)
|
||||
msiexec = pkginfo[version_num].get('msiexec')
|
||||
allusers = pkginfo[version_num].get('allusers')
|
||||
if allusers is None:
|
||||
allusers = True
|
||||
install_flags = '{0} {1}'.format(pkginfo[version_num]['install_flags'], options and options.get('extra_install_flags') or "")
|
||||
|
||||
cmd = []
|
||||
@ -523,6 +545,8 @@ def install(name=None, refresh=False, pkgs=None, saltenv='base', **kwargs):
|
||||
cmd.extend(['msiexec', '/i'])
|
||||
cmd.append(cached_pkg)
|
||||
cmd.extend(install_flags.split())
|
||||
if msiexec and allusers:
|
||||
cmd.append('ALLUSERS="1"')
|
||||
|
||||
__salt__['cmd.run'](cmd, cache_path, output_loglevel='trace', python_shell=False)
|
||||
|
||||
|
@ -362,6 +362,8 @@ def salt_api_acl_tool(username, request):
|
||||
- 1.1.1.2
|
||||
foo:
|
||||
- 8.8.4.4
|
||||
bar:
|
||||
- '*'
|
||||
|
||||
:param username: Username to check against the API.
|
||||
:type username: str
|
||||
@ -390,14 +392,14 @@ def salt_api_acl_tool(username, request):
|
||||
users = acl.get('users', {})
|
||||
if users:
|
||||
if username in users:
|
||||
if ip in users[username]:
|
||||
if ip in users[username] or '*' in users[username]:
|
||||
logger.info(success_str.format(username, ip))
|
||||
return True
|
||||
else:
|
||||
logger.info(failure_str.format(username, ip))
|
||||
return False
|
||||
elif username not in users and '*' in users:
|
||||
if ip in users['*']:
|
||||
if ip in users['*'] or '*' in users['*']:
|
||||
logger.info(success_str.format(username, ip))
|
||||
return True
|
||||
else:
|
||||
@ -1521,19 +1523,18 @@ class Login(LowDataAdapter):
|
||||
try:
|
||||
eauth = self.opts.get('external_auth', {}).get(token['eauth'], {})
|
||||
|
||||
# Get sum of '*' perms, user-specific perms, and group-specific perms
|
||||
perms = eauth.get(token['name'], [])
|
||||
perms.extend(eauth.get('*', []))
|
||||
|
||||
if 'groups' in token:
|
||||
user_groups = set(token['groups'])
|
||||
eauth_groups = set([i.rstrip('%') for i in eauth.keys() if i.endswith('%')])
|
||||
|
||||
perms = []
|
||||
for group in user_groups & eauth_groups:
|
||||
perms.extend(eauth['{0}%'.format(group)])
|
||||
|
||||
perms = perms or None
|
||||
else:
|
||||
perms = eauth.get(token['name'], eauth.get('*'))
|
||||
|
||||
if perms is None:
|
||||
if not perms:
|
||||
raise ValueError("Eauth permission list not found.")
|
||||
except (AttributeError, IndexError, KeyError, ValueError):
|
||||
logger.debug("Configuration for external_auth malformed for "
|
||||
|
@ -23,6 +23,17 @@ the pickle protocol, set ``carbon.mode`` to ``pickle``:
|
||||
|
||||
carbon.mode: pickle
|
||||
|
||||
You can also specify the pattern used for the metric base path (except for virt modules metrics):
|
||||
carbon.metric_base_pattern: carbon.[minion_id].[module].[function]
|
||||
|
||||
These tokens can used :
|
||||
[module]: salt module
|
||||
[function]: salt function
|
||||
[minion_id]: minion id
|
||||
|
||||
Default is :
|
||||
carbon.metric_base_pattern: [module].[function].[minion_id]
|
||||
|
||||
Carbon settings may also be configured as:
|
||||
|
||||
.. code-block:: yaml
|
||||
@ -32,6 +43,7 @@ Carbon settings may also be configured as:
|
||||
port: <carbon port>
|
||||
skip_on_error: True
|
||||
mode: (pickle|text)
|
||||
metric_base_pattern: <pattern> | [module].[function].[minion_id]
|
||||
|
||||
Alternative configuration values can be used by prefacing the configuration.
|
||||
Any values not found in the alternative configuration will be pulled from
|
||||
@ -208,6 +220,7 @@ def _send(saltdata, metric_base, opts):
|
||||
host = opts.get('host')
|
||||
port = opts.get('port')
|
||||
skip = opts.get('skip')
|
||||
metric_base_pattern = opts.get('carbon.metric_base_pattern')
|
||||
if 'mode' in opts:
|
||||
mode = opts.get('mode').lower()
|
||||
|
||||
|
@ -217,8 +217,8 @@ def format_log(ret):
|
||||
new = chg[pkg]['new']
|
||||
if not new and new not in (False, None):
|
||||
new = 'absent'
|
||||
msg += '{0} changed from {1} to ' \
|
||||
'{2}\n'.format(pkg, old, new)
|
||||
msg += '{0!r} changed from {1!r} to ' \
|
||||
'{2!r}\n'.format(pkg, old, new)
|
||||
if not msg:
|
||||
msg = str(ret['changes'])
|
||||
if ret['result'] is True or ret['result'] is None:
|
||||
@ -257,9 +257,9 @@ class Compiler(object):
|
||||
'''
|
||||
Class used to compile and manage the High Data structure
|
||||
'''
|
||||
def __init__(self, opts):
|
||||
def __init__(self, opts, renderers):
|
||||
self.opts = opts
|
||||
self.rend = salt.loader.render(self.opts, {})
|
||||
self.rend = renderers
|
||||
|
||||
# We need __setstate__ and __getstate__ to avoid pickling errors since
|
||||
# 'self.rend' contains a function reference which is not picklable.
|
||||
|
@ -1505,7 +1505,8 @@ def managed(name,
|
||||
except Exception as exc:
|
||||
ret['changes'] = {}
|
||||
log.debug(traceback.format_exc())
|
||||
os.remove(tmp_filename)
|
||||
if os.path.isfile(tmp_filename):
|
||||
os.remove(tmp_filename)
|
||||
return _error(ret, 'Unable to check_cmd file: {0}'.format(exc))
|
||||
|
||||
# file being updated to verify using check_cmd
|
||||
@ -1523,7 +1524,8 @@ def managed(name,
|
||||
cret = mod_run_check_cmd(check_cmd, tmp_filename, **check_cmd_opts)
|
||||
if isinstance(cret, dict):
|
||||
ret.update(cret)
|
||||
os.remove(tmp_filename)
|
||||
if os.path.isfile(tmp_filename):
|
||||
os.remove(tmp_filename)
|
||||
return ret
|
||||
# Since we generated a new tempfile and we are not returning here
|
||||
# lets change the original sfn to the new tempfile or else we will
|
||||
@ -1561,7 +1563,7 @@ def managed(name,
|
||||
log.debug(traceback.format_exc())
|
||||
return _error(ret, 'Unable to manage file: {0}'.format(exc))
|
||||
finally:
|
||||
if tmp_filename:
|
||||
if tmp_filename and os.path.isfile(tmp_filename):
|
||||
os.remove(tmp_filename)
|
||||
|
||||
|
||||
|
@ -81,9 +81,6 @@ def user_exists(name, password=None, htpasswd_file=None, options='',
|
||||
ret['comment'] = useradd_ret['stderr']
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
else:
|
||||
ret['result'] = True
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'User already known'
|
||||
return ret
|
||||
|
@ -198,8 +198,6 @@ def _find_remove_targets(name=None,
|
||||
__salt__.get('pkg.normalize_name', lambda pkgname: pkgname)
|
||||
to_remove = {_normalize_name(name): version}
|
||||
|
||||
cver = cur_pkgs.get(name, [])
|
||||
|
||||
version_spec = False
|
||||
# Find out which packages will be targeted in the call to pkg.remove
|
||||
# Check current versions against specified versions
|
||||
@ -557,14 +555,61 @@ def installed(
|
||||
Ensure that the package is installed, and that it is the correct version
|
||||
(if specified).
|
||||
|
||||
name
|
||||
:param str name:
|
||||
The name of the package to be installed. This parameter is ignored if
|
||||
either "pkgs" or "sources" is used. Additionally, please note that this
|
||||
option can only be used to install packages from a software repository.
|
||||
To install a package file manually, use the "sources" option detailed
|
||||
below.
|
||||
|
||||
fromrepo
|
||||
:param str version:
|
||||
Install a specific version of a package. This option is ignored if
|
||||
either "pkgs" or "sources" is used. Currently, this option is supported
|
||||
for the following pkg providers: :mod:`apt <salt.modules.aptpkg>`,
|
||||
:mod:`ebuild <salt.modules.ebuild>`,
|
||||
:mod:`pacman <salt.modules.pacman>`,
|
||||
:mod:`yumpkg <salt.modules.yumpkg>`, and
|
||||
:mod:`zypper <salt.modules.zypper>`. The version number includes the
|
||||
release designation where applicable, to allow Salt to target a
|
||||
specific release of a given version. When in doubt, using the
|
||||
``pkg.latest_version`` function for an uninstalled package will tell
|
||||
you the version available.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt myminion pkg.latest_version httpd
|
||||
myminion:
|
||||
2.2.15-30.el6.centos
|
||||
|
||||
Also, while this function is not yet implemented for all pkg frontends,
|
||||
:mod:`pkg.list_repo_pkgs <salt.modules.yumpkg.list_repo_pkgs>` will
|
||||
show all versions available in the various repositories for a given
|
||||
package, irrespective of whether or not it is installed.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt myminion pkg.list_repo_pkgs httpd
|
||||
myminion:
|
||||
----------
|
||||
base:
|
||||
|_
|
||||
----------
|
||||
httpd:
|
||||
2.2.15-29.el6.centos
|
||||
updates:
|
||||
|_
|
||||
----------
|
||||
httpd:
|
||||
2.2.15-30.el6.centos
|
||||
|
||||
The version strings returned by either of these functions can be used
|
||||
as version specifiers in pkg states.
|
||||
|
||||
:param bool refresh:
|
||||
Update the repo database of available packages prior to installing the
|
||||
requested package.
|
||||
|
||||
:param str fromrepo:
|
||||
Specify a repository from which to install
|
||||
|
||||
.. note::
|
||||
@ -618,68 +663,101 @@ def installed(
|
||||
**4:0.8.10-0ubuntu0.12.04.1** either ``precise-updates`` or
|
||||
``precise-security`` could be used for the ``fromrepo`` value.
|
||||
|
||||
skip_verify
|
||||
:param bool skip_verify:
|
||||
Skip the GPG verification check for the package to be installed
|
||||
|
||||
skip_suggestions
|
||||
:param bool skip_suggestions:
|
||||
Force strict package naming. Disables lookup of package alternatives.
|
||||
|
||||
.. versionadded:: 2014.1.1
|
||||
|
||||
version
|
||||
Install a specific version of a package. This option is ignored if
|
||||
either "pkgs" or "sources" is used. Currently, this option is supported
|
||||
for the following pkg providers: :mod:`apt <salt.modules.aptpkg>`,
|
||||
:param list pkgs:
|
||||
A list of packages to install from a software repository. All packages
|
||||
listed under ``pkgs`` will be installed via a single command.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar
|
||||
- baz
|
||||
- hold: True
|
||||
|
||||
``NOTE:`` For :mod:`apt <salt.modules.aptpkg>`,
|
||||
:mod:`ebuild <salt.modules.ebuild>`,
|
||||
:mod:`pacman <salt.modules.pacman>`,
|
||||
:mod:`yumpkg <salt.modules.yumpkg>`, and
|
||||
:mod:`zypper <salt.modules.zypper>`. The version number includes the
|
||||
release designation where applicable, to allow Salt to target a
|
||||
specific release of a given version. When in doubt, using the
|
||||
``pkg.latest_version`` function for an uninstalled package will tell
|
||||
you the version available.
|
||||
:mod:`pacman <salt.modules.pacman>`, :mod:`yumpkg <salt.modules.yumpkg>`,
|
||||
and :mod:`zypper <salt.modules.zypper>`, version numbers can be specified
|
||||
in the ``pkgs`` argument. For example:
|
||||
|
||||
.. code-block:: bash
|
||||
.. code-block:: yaml
|
||||
|
||||
# salt myminion pkg.latest_version httpd
|
||||
myminion:
|
||||
2.2.15-30.el6.centos
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar: 1.2.3-4
|
||||
- baz
|
||||
|
||||
Also, while this function is not yet implemented for all pkg frontends,
|
||||
:mod:`pkg.list_repo_pkgs <salt.modules.yumpkg.list_repo_pkgs>` will
|
||||
show all versions available in the various repositories for a given
|
||||
package, irrespective of whether or not it is installed.
|
||||
Additionally, :mod:`ebuild <salt.modules.ebuild>`,
|
||||
:mod:`pacman <salt.modules.pacman>` and
|
||||
:mod:`zypper <salt.modules.zypper>` support the ``<``, ``<=``, ``>=``, and
|
||||
``>`` operators for more control over what versions will be installed. For
|
||||
|
||||
.. code-block:: bash
|
||||
Example:
|
||||
|
||||
# salt myminion pkg.list_repo_pkgs httpd
|
||||
myminion:
|
||||
----------
|
||||
base:
|
||||
|_
|
||||
----------
|
||||
httpd:
|
||||
2.2.15-29.el6.centos
|
||||
updates:
|
||||
|_
|
||||
----------
|
||||
httpd:
|
||||
2.2.15-30.el6.centos
|
||||
.. code-block:: yaml
|
||||
|
||||
The version strings returned by either of these functions can be used
|
||||
as version specifiers in pkg states.
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar: '>=1.2.3-4'
|
||||
- baz
|
||||
|
||||
refresh
|
||||
Update the repo database of available packages prior to installing the
|
||||
requested package.
|
||||
``NOTE:`` When using comparison operators, the expression must be enclosed
|
||||
in quotes to avoid a YAML render error.
|
||||
|
||||
hold
|
||||
Force the package to be held at the current installed version.
|
||||
Currently works with YUM & APT-based systems.
|
||||
With :mod:`ebuild <salt.modules.ebuild>` is also possible to specify a
|
||||
use flag list and/or if the given packages should be in
|
||||
package.accept_keywords file and/or the overlay from which you want the
|
||||
package to be installed.
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
For example:
|
||||
|
||||
allow_updates
|
||||
.. code-block:: yaml
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo: '~'
|
||||
- bar: '~>=1.2:slot::overlay[use,-otheruse]'
|
||||
- baz
|
||||
|
||||
**Multiple Package Installation Options: (not supported in Windows or
|
||||
pkgng)**
|
||||
|
||||
:param list sources:
|
||||
A list of packages to install, along with the source URI or local path
|
||||
from which to install each package. In the example below, ``foo``,
|
||||
``bar``, ``baz``, etc. refer to the name of the package, as it would
|
||||
appear in the output of the ``pkg.version`` or ``pkg.list_pkgs`` salt
|
||||
CLI commands.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- sources:
|
||||
- foo: salt://rpms/foo.rpm
|
||||
- bar: http://somesite.org/bar.rpm
|
||||
- baz: ftp://someothersite.org/baz.rpm
|
||||
- qux: /minion/path/to/qux.rpm
|
||||
|
||||
:param bool allow_updates:
|
||||
Allow the package to be updated outside Salt's control (e.g. auto
|
||||
updates on Windows). This means a package on the Minion can have a
|
||||
newer version than the latest available in the repository without
|
||||
@ -687,20 +765,22 @@ def installed(
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
Example:
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- fromrepo: mycustomrepo
|
||||
- skip_verify: True
|
||||
- skip_suggestions: True
|
||||
- version: 2.0.6~ubuntu3
|
||||
- refresh: True
|
||||
- hold: False
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- fromrepo: mycustomrepo
|
||||
- skip_verify: True
|
||||
- skip_suggestions: True
|
||||
- version: 2.0.6~ubuntu3
|
||||
- refresh: True
|
||||
- allow_updates: True
|
||||
- hold: False
|
||||
|
||||
:param bool pkg_verify:
|
||||
|
||||
pkg_verify
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
For requested packages that are already installed and would not be
|
||||
@ -711,27 +791,27 @@ def installed(
|
||||
below). Currently, this option is supported for the following pkg
|
||||
providers: :mod:`yumpkg <salt.modules.yumpkg>`.
|
||||
|
||||
Examples:
|
||||
Examples:
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- version: 2.2.15-30.el6.centos
|
||||
- pkg_verify: True
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- version: 2.2.15-30.el6.centos
|
||||
- pkg_verify: True
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar: 1.2.3-4
|
||||
- baz
|
||||
- pkg_verify:
|
||||
- ignore_types: [config,doc]
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar: 1.2.3-4
|
||||
- baz
|
||||
- pkg_verify:
|
||||
- ignore_types: [config,doc]
|
||||
|
||||
normalize : True
|
||||
:param bool normalize:
|
||||
Normalize the package name by removing the architecture, if the
|
||||
architecture of the package is different from the architecture of the
|
||||
operating system. The ability to disable this behavior is useful for
|
||||
@ -741,133 +821,64 @@ def installed(
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
Example:
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
gpfs.gplbin-2.6.32-279.31.1.el6.x86_64:
|
||||
pkg.installed:
|
||||
- normalize: False
|
||||
gpfs.gplbin-2.6.32-279.31.1.el6.x86_64:
|
||||
pkg.installed:
|
||||
- normalize: False
|
||||
|
||||
**Multiple Package Installation Options: (not supported in Windows or
|
||||
pkgng)**
|
||||
:param kwargs:
|
||||
These are specific to each OS. If it does not apply to the execution
|
||||
module for your OS, it is ignored.
|
||||
|
||||
pkgs
|
||||
A list of packages to install from a software repository. All packages
|
||||
listed under ``pkgs`` will be installed via a single command.
|
||||
:param bool hold:
|
||||
Force the package to be held at the current installed version.
|
||||
Currently works with YUM & APT based systems.
|
||||
|
||||
Example:
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
.. code-block:: yaml
|
||||
:param list names:
|
||||
A list of packages to install from a software repository. Each package
|
||||
will be installed individually by the package manager.
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar
|
||||
- baz
|
||||
- hold: True
|
||||
.. warning::
|
||||
|
||||
``NOTE:`` For :mod:`apt <salt.modules.aptpkg>`,
|
||||
:mod:`ebuild <salt.modules.ebuild>`,
|
||||
:mod:`pacman <salt.modules.pacman>`, :mod:`yumpkg <salt.modules.yumpkg>`,
|
||||
and :mod:`zypper <salt.modules.zypper>`, version numbers can be specified
|
||||
in the ``pkgs`` argument. For example:
|
||||
Unlike ``pkgs``, the ``names`` parameter cannot specify a version.
|
||||
In addition, it makes a separate call to the package management
|
||||
frontend to install each package, whereas ``pkgs`` makes just a
|
||||
single call. It is therefore recommended to use ``pkgs`` instead of
|
||||
``names`` to install multiple packages, both for the additional
|
||||
features and the performance improvement that it brings.
|
||||
|
||||
.. code-block:: yaml
|
||||
:param bool install_recommends:
|
||||
Whether to install the packages marked as recommended. Default is
|
||||
``True``. Currently only works with APT-based systems.
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar: 1.2.3-4
|
||||
- baz
|
||||
.. versionadded:: 2015.5.0
|
||||
|
||||
Additionally, :mod:`ebuild <salt.modules.ebuild>`,
|
||||
:mod:`pacman <salt.modules.pacman>` and
|
||||
:mod:`zypper <salt.modules.zypper>` support the ``<``, ``<=``, ``>=``, and
|
||||
``>`` operators for more control over what versions will be installed. For
|
||||
example:
|
||||
.. code-block:: yaml
|
||||
|
||||
.. code-block:: yaml
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- install_recommends: False
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo
|
||||
- bar: '>=1.2.3-4'
|
||||
- baz
|
||||
:param bool only_upgrade:
|
||||
Only upgrade the packages, if they are already installed. Default is
|
||||
``False``. Currently only works with APT-based systems.
|
||||
|
||||
``NOTE:`` When using comparison operators, the expression must be enclosed
|
||||
in quotes to avoid a YAML render error.
|
||||
.. versionadded:: 2015.5.0
|
||||
|
||||
With :mod:`ebuild <salt.modules.ebuild>` is also possible to specify a use
|
||||
flag list and/or if the given packages should be in package.accept_keywords
|
||||
file and/or the overlay from which you want the package to be installed.
|
||||
For example:
|
||||
.. code-block:: yaml
|
||||
|
||||
.. code-block:: yaml
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- only_upgrade: True
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- foo: '~'
|
||||
- bar: '~>=1.2:slot::overlay[use,-otheruse]'
|
||||
- baz
|
||||
|
||||
names
|
||||
A list of packages to install from a software repository. Each package
|
||||
will be installed individually by the package manager.
|
||||
|
||||
.. warning::
|
||||
|
||||
Unlike ``pkgs``, the ``names`` parameter cannot specify a version.
|
||||
In addition, it makes a separate call to the package management
|
||||
frontend to install each package, whereas ``pkgs`` makes just a
|
||||
single call. It is therefore recommended to use ``pkgs`` instead of
|
||||
``names`` to install multiple packages, both for the additional
|
||||
features and the performance improvement that it brings.
|
||||
|
||||
sources
|
||||
A list of packages to install, along with the source URI or local path
|
||||
from which to install each package. In the example below, ``foo``,
|
||||
``bar``, ``baz``, etc. refer to the name of the package, as it would
|
||||
appear in the output of the ``pkg.version`` or ``pkg.list_pkgs`` salt
|
||||
CLI commands.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
mypkgs:
|
||||
pkg.installed:
|
||||
- sources:
|
||||
- foo: salt://rpms/foo.rpm
|
||||
- bar: http://somesite.org/bar.rpm
|
||||
- baz: ftp://someothersite.org/baz.rpm
|
||||
- qux: /minion/path/to/qux.rpm
|
||||
|
||||
install_recommends
|
||||
Whether to install the packages marked as recommended. Default is
|
||||
``True``. Currently only works with APT-based systems.
|
||||
|
||||
.. versionadded:: 2015.5.0
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- install_recommends: False
|
||||
|
||||
only_upgrade
|
||||
Only upgrade the packages, if they are already installed. Default is
|
||||
``False``. Currently only works with APT-based systems.
|
||||
|
||||
.. versionadded:: 2015.5.0
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
httpd:
|
||||
pkg.installed:
|
||||
- only_upgrade: True
|
||||
:return:
|
||||
A dictionary containing the state of the software installation
|
||||
:rtype dict:
|
||||
|
||||
'''
|
||||
if isinstance(pkgs, list) and len(pkgs) == 0:
|
||||
|
@ -299,7 +299,7 @@ def running(name, enable=None, sig=None, init_delay=None, **kwargs):
|
||||
if before_toggle_status:
|
||||
ret['comment'] = 'The service {0} is already running'.format(name)
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['result'] = True
|
||||
return ret
|
||||
if enable is True and not before_toggle_enable_status:
|
||||
ret.update(_enable(name, None, **kwargs))
|
||||
@ -392,7 +392,7 @@ def dead(name, enable=None, sig=None, **kwargs):
|
||||
ret.update(_disable(name, None, **kwargs))
|
||||
return ret
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['result'] = True
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
|
@ -82,6 +82,8 @@ class AsyncTCPReqChannel(salt.transport.client.ReqChannel):
|
||||
|
||||
@classmethod
|
||||
def __key(cls, opts, **kwargs):
|
||||
if 'master_uri' in kwargs:
|
||||
opts['master_uri'] = kwargs['master_uri']
|
||||
return (opts['pki_dir'], # where the keys are stored
|
||||
opts['id'], # minion ID
|
||||
opts['master_uri'], # master ID
|
||||
|
@ -30,11 +30,10 @@ class Reactor(multiprocessing.Process, salt.state.Compiler):
|
||||
'''
|
||||
def __init__(self, opts):
|
||||
multiprocessing.Process.__init__(self)
|
||||
salt.state.Compiler.__init__(self, opts)
|
||||
|
||||
local_minion_opts = self.opts.copy()
|
||||
local_minion_opts = opts.copy()
|
||||
local_minion_opts['file_client'] = 'local'
|
||||
self.minion = salt.minion.MasterMinion(local_minion_opts)
|
||||
salt.state.Compiler.__init__(self, opts, self.minion.rend)
|
||||
|
||||
def render_reaction(self, glob_ref, tag, data):
|
||||
'''
|
||||
|
@ -359,6 +359,7 @@ class Schedule(object):
|
||||
if name in self.opts['pillar']['schedule']:
|
||||
del self.opts['pillar']['schedule'][name]
|
||||
schedule = self.opts['pillar']['schedule']
|
||||
log.warn('Pillar schedule deleted. Pillar refresh recommended. Run saltutil.refresh_pillar.')
|
||||
|
||||
# Fire the complete event back along with updated list of schedule
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts, listen=False)
|
||||
|
@ -552,6 +552,7 @@ def dependency_information(include_salt_cloud=False):
|
||||
('ZMQ', 'zmq', 'zmq_version'),
|
||||
('Mako', 'mako', '__version__'),
|
||||
('Tornado', 'tornado', 'version'),
|
||||
('timelib', 'timelib', 'version'),
|
||||
]
|
||||
|
||||
if include_salt_cloud:
|
||||
|
@ -387,6 +387,98 @@ class OpenNebulaTestCase(TestCase):
|
||||
self.assertEqual(opennebula.get_vn_id(mock_kwargs, 'foo'),
|
||||
mock_id)
|
||||
|
||||
# TODO: Write tests for create function
|
||||
|
||||
def test_destroy_function_error(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when --function or -f is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.destroy, 'my-vm', 'function')
|
||||
|
||||
def test_image_allocate_function_error(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when something other than
|
||||
--function or -f is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_allocate, 'foo')
|
||||
|
||||
def test_image_allocate_no_name_or_datastore_id(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when a neither a datastore_id
|
||||
nor a datastore_name is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_allocate, 'function')
|
||||
|
||||
def test_image_allocate_no_path_or_data(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when neither the path nor data args
|
||||
are provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit,
|
||||
opennebula.image_allocate,
|
||||
'function',
|
||||
kwargs={'datastore_id': '5'})
|
||||
|
||||
def test_image_clone_function_error(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when something other than
|
||||
--function or -f is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_clone, 'foo')
|
||||
|
||||
def test_image_clone_no_name(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when a name isn't provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_clone, 'function')
|
||||
|
||||
def test_image_clone_no_image_id_or_image_name(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when neither the image_id nor
|
||||
the image_name args are provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit,
|
||||
opennebula.image_clone,
|
||||
'function',
|
||||
kwargs={'name': 'test'})
|
||||
|
||||
def test_image_delete_function_error(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when something other than
|
||||
--function or -f is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_delete, 'foo')
|
||||
|
||||
def test_image_delete_no_name_or_image_id(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when a neither an image_id
|
||||
nor a name is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_delete, 'function')
|
||||
|
||||
def test_image_persist_function_error(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when something other than
|
||||
--function or -f is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_persistent, 'foo')
|
||||
|
||||
def test_image_persist_no_persist(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when the persist kwarg is missing.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit, opennebula.image_persistent, 'function')
|
||||
|
||||
def test_image_persist_no_name_or_image_id(self):
|
||||
'''
|
||||
Tests that a SaltCloudSystemExit is raised when a neither an image_id
|
||||
nor a name is provided.
|
||||
'''
|
||||
self.assertRaises(SaltCloudSystemExit,
|
||||
opennebula.image_delete,
|
||||
'function',
|
||||
kwargs={'persist': False})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
|
@ -58,7 +58,7 @@ class ServiceTestCase(TestCase):
|
||||
'result': True},
|
||||
{'changes': {},
|
||||
'comment': 'The service salt is already running',
|
||||
'name': 'salt', 'result': None}]
|
||||
'name': 'salt', 'result': True}]
|
||||
|
||||
tmock = MagicMock(return_value=True)
|
||||
fmock = MagicMock(return_value=False)
|
||||
@ -153,7 +153,7 @@ class ServiceTestCase(TestCase):
|
||||
'result': True},
|
||||
{'changes': {},
|
||||
'comment': 'The service salt is already dead', 'name': 'salt',
|
||||
'result': None}]
|
||||
'result': True}]
|
||||
|
||||
mock = MagicMock(return_value="salt")
|
||||
with patch.object(service, '_enabled_used_error', mock):
|
||||
|
Loading…
Reference in New Issue
Block a user