Merge pull request #26148 from terminalmage/winrepo

Refactor winrepo support
This commit is contained in:
Mike Place 2015-08-10 08:31:25 -06:00
commit 95a560ebf1
14 changed files with 813 additions and 217 deletions

View File

@ -1140,14 +1140,12 @@ Walkthrough <gitfs-per-remote-config>`.
.. versionadded:: 2014.7.0
Specify the provider to be used for gitfs. More information can be found in the
:ref:`GitFS Walkthrough <gitfs-dependencies>`.
Optional parameter used to specify the provider to be used for gitfs. More
information can be found in the :ref:`GitFS Walkthrough <gitfs-dependencies>`.
Specify one value among valid values: ``gitpython``, ``pygit2``, ``dulwich``
.. _pygit2: https://github.com/libgit2/pygit2
.. _GitPython: https://github.com/gitpython-developers/GitPython
.. _dulwich: https://www.samba.org/~jelmer/dulwich/
Must be one of the following: ``pygit2``, ``gitpython``, or ``dulwich``. If
unset, then each will be tried in that same order, and the first one with a
compatible version installed will be the provider that is used.
.. code-block:: yaml
@ -1160,11 +1158,11 @@ Specify one value among valid values: ``gitpython``, ``pygit2``, ``dulwich``
Default: ``True``
The ``gitfs_ssl_verify`` option specifies whether to ignore SSL certificate
errors when contacting the gitfs backend. You might want to set this to
``False`` if you're using a git backend that uses a self-signed certificate but
keep in mind that setting this flag to anything other than the default of
``True`` is a security concern, you may want to try using the ssh transport.
Specifies whether or not to ignore SSL certificate errors when contacting the
remote repository. You might want to set this to ``False`` if you're using a
git repo that uses a self-signed certificate. However, keep in mind that
setting this to anything other ``True`` is a considered insecure, and using an
SSH-based transport (if available) may be a better option.
.. code-block:: yaml
@ -1942,11 +1940,27 @@ ext_pillar.
ext_pillar_first: False
.. _git-pillar-config-opts:
.. _git_pillar-config-opts:
Git External Pillar (git_pillar) Configuration Options
------------------------------------------------------
.. conf_master:: git_pillar_provider
``git_pillar_provider``
***********************
.. versionadded:: 2015.8.0
Specify the provider to be used for git_pillar. Must be either ``pygit2`` or
``gitpython``. If unset, then both will be tried in that same order, and the
first one with a compatible version installed will be the provider that is
used.
.. code-block:: yaml
git_pillar_provider: gitpython
.. conf_master:: git_pillar_base
``git_pillar_base``
@ -2030,7 +2044,7 @@ environment irrespective of the branch/tag being used.
.. conf_master:: git_pillar_root
``git_pillar_root``
********************
*******************
.. versionadded:: 2015.8.0
@ -2077,23 +2091,23 @@ files would be looked for in a subdirectory called ``pillar``.
Default: ``True``
Specifies whether or not to ignore SSL certificate errors when contacting the
git_pillar remote repository. You might want to set this to ``False`` if you're
using a git backend that uses a self-signed certificate but keep in mind that
setting this flag to anything other than the default of ``True`` is a security
concern, you may want to try using the ssh transport.
remote repository. You might want to set this to ``False`` if you're using a
git repo that uses a self-signed certificate. However, keep in mind that
setting this to anything other ``True`` is a considered insecure, and using an
SSH-based transport (if available) may be a better option.
.. code-block:: yaml
git_pillar_ssl_verify: True
git_pillar Authentication Options
*********************************
Git External Pillar Authentication Options
******************************************
These parameters only currently apply to the pygit2 gitfs provider.
Authentication works the same as it does in gitfs, as outlined in the
:ref:`GitFS Walkthrough <gitfs-authentication>`, though the global
configuration options are named differently to reflect that they are for
git_pillar instead of gitfs.
These parameters only currently apply to the ``pygit2``
:conf_master:`git_pillar_provider`. Authentication works the same as it does
in gitfs, as outlined in the :ref:`GitFS Walkthrough <gitfs-authentication>`,
though the global configuration options are named differently to reflect that
they are for git_pillar instead of gitfs.
.. conf_master:: git_pillar_user
@ -2700,57 +2714,238 @@ option then the master will log a warning message.
- master.d/*
- /etc/roles/webserver
.. _winrepo-config-opts:
Windows Software Repo Settings
==============================
.. conf_master:: winrepo_provider
``winrepo_provider``
--------------------
.. versionadded:: 2015.8.0
Specify the provider to be used for winrepo. Must be either ``pygit2`` or
``gitpython``. If unset, then both will be tried in that same order, and the
first one with a compatible version installed will be the provider that is
used.
.. code-block:: yaml
winrepo_provider: gitpython
.. conf_master:: winrepo_dir
.. conf_master:: win_repo
``win_repo``
------------
``winrepo_dir``
---------------
.. versionchanged:: 2015.8.0
Renamed from ``win_repo`` to ``winrepo_dir``
Default: ``/srv/salt/win/repo``
Location of the repo on the master
Location on the master where the :conf_master:`winrepo_remotes` are checked
out.
.. code-block:: yaml
win_repo: '/srv/salt/win/repo'
winrepo_dir: /srv/salt/win/repo
.. conf_master:: winrepo_cachefile
.. conf_master:: win_repo_mastercachefile
``win_repo_mastercachefile``
----------------------------
``winrepo_cachefile``
---------------------
Default: ``/srv/salt/win/repo/winrepo.p``
.. versionchanged:: 2015.8.0
Renamed from ``win_repo_mastercachefile`` to ``winrepo_cachefile``
Default: ``winrepo.p``
Path relative to :conf_master:`winrepo_dir` where the winrepo cache should be
created.
.. code-block:: yaml
win_repo_mastercachefile: '/srv/salt/win/repo/winrepo.p'
winrepo_cachefile: winrepo.p
.. conf_master:: winrepo_remotes
.. conf_master:: win_gitrepos
``win_gitrepos``
----------------
``winrepo_remotes``
-------------------
.. versionchanged:: 2015.8.0
Renamed from ``win_gitrepos`` to ``winrepo_remotes``
Default: ``['https://github.com/saltstack/salt-winrepo.git']``
List of git repositories to checkout and include in the winrepo
.. code-block:: yaml
winrepo_remotes:
- https://github.com/saltstack/salt-winrepo.git
To specify a specific revision of the repository, prepend a commit ID to the
URL of the the repository:
.. code-block:: yaml
winrepo_remotes:
- '<commit_id> https://github.com/saltstack/salt-winrepo.git'
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
ID is useful in that it allows one to revert back to a previous version in the
event that an error is introduced in the latest revision of the repo.
.. conf_master:: winrepo_branch
``winrepo_branch``
------------------
.. versionadded:: 2015.8.0
Default: ``master``
If the branch is omitted from a winrepo remote, then this branch will be
used instead. For example, in the configuration below, the first two remotes
would use the ``winrepo`` branch/tag, while the third would use the ``foo``
branch/tag.
.. code-block:: yaml
winrepo_branch: winrepo
ext_pillar:
- git:
- https://mygitserver/winrepo1.git
- https://mygitserver/winrepo2.git:
- foo https://mygitserver/winrepo3.git
.. conf_master:: winrepo_ssl_verify
``winrepo_ssl_verify``
----------------------
.. versionadded:: 2015.8.0
Default: ``True``
Specifies whether or not to ignore SSL certificate errors when contacting the
remote repository. You might want to set this to ``False`` if you're using a
git repo that uses a self-signed certificate. However, keep in mind that
setting this to anything other ``True`` is a considered insecure, and using an
SSH-based transport (if available) may be a better option.
.. code-block:: yaml
winrepo_ssl_verify: True
Winrepo Authentication Options
------------------------------
These parameters only currently apply to the ``pygit2``
:conf_master:`winrepo_provider`. Authentication works the same as it does in
gitfs, as outlined in the :ref:`GitFS Walkthrough <gitfs-authentication>`,
though the global configuration options are named differently to reflect that
they are for winrepo instead of gitfs.
.. conf_master:: winrepo_user
``winrepo_user``
****************
.. versionadded:: 2015.8.0
Default: ``''``
List of git repositories to include with the local repo.
Along with :conf_master:`winrepo_password`, is used to authenticate to HTTPS
remotes.
.. code-block:: yaml
win_gitrepos:
- 'https://github.com/saltstack/salt-winrepo.git'
winrepo_user: git
To specify a specific revision of the repository, preface the
repository location with a commit ID:
.. conf_master:: winrepo_password
``winrepo_password``
********************
.. versionadded:: 2015.8.0
Default: ``''``
Along with :conf_master:`winrepo_user`, is used to authenticate to HTTPS
remotes. This parameter is not required if the repository does not use
authentication.
.. code-block:: yaml
win_gitrepos:
- '<commit_id> https://github.com/saltstack/salt-winrepo.git'
winrepo_password: mypassword
Replacing ``<commit_id>`` with the ID from GitHub. Specifying a commit
ID is useful if you need to revert to a previous version if an error
is introduced in the latest version.
.. conf_master:: winrepo_insecure_auth
``winrepo_insecure_auth``
*************************
.. versionadded:: 2015.8.0
Default: ``False``
By default, Salt will not authenticate to an HTTP (non-HTTPS) remote. This
parameter enables authentication over HTTP. **Enable this at your own risk.**
.. code-block:: yaml
winrepo_insecure_auth: True
.. conf_master:: winrepo_pubkey
``winrepo_pubkey``
******************
.. versionadded:: 2015.8.0
Default: ``''``
Along with :conf_master:`winrepo_privkey` (and optionally
:conf_master:`winrepo_passphrase`), is used to authenticate to SSH remotes.
.. code-block:: yaml
winrepo_pubkey: /path/to/key.pub
.. conf_master:: winrepo_privkey
``winrepo_privkey``
*******************
.. versionadded:: 2015.8.0
Default: ``''``
Along with :conf_master:`winrepo_pubkey` (and optionally
:conf_master:`winrepo_passphrase`), is used to authenticate to SSH remotes.
.. code-block:: yaml
winrepo_privkey: /path/to/key
.. conf_master:: winrepo_passphrase
``winrepo_passphrase``
**********************
.. versionadded:: 2015.8.0
Default: ``''``
This parameter is optional, required only when the SSH key being used to
authenticate is protected by a passphrase.
.. code-block:: yaml
winrepo_passphrase: mypassphrase

View File

@ -1207,3 +1207,75 @@ have other services that need to go with it.
.. code-block:: yaml
update_restart_services: ['salt-minion']
Windows Software Repo Settings
==============================
.. important::
To use these config options, the minion must be running in masterless mode
(set :conf_minion:`file_client` to ``local``).
.. conf_minion:: winrepo_dir
.. conf_minion:: win_repo
``winrepo_dir``
---------------
.. versionchanged:: 2015.8.0
Renamed from ``win_repo`` to ``winrepo_dir``
Default: ``c:\\salt\\file_roots\\winrepo``
Location on the minion where the :conf_minion:`winrepo_remotes` are checked
out.
.. code-block:: yaml
winrepo_dir: /srv/salt/win/repo
.. conf_minion:: winrepo_cachefile
``winrepo_cachefile``
---------------------
.. versionchanged:: 2015.8.0
Renamed from ``win_repo_mastercachefile`` to ``winrepo_cachefile``
Default: ``winrepo.p``
Path relative to :conf_minion:`winrepo_dir` where the winrepo cache should be
created.
.. code-block:: yaml
winrepo_cachefile: winrepo.p
.. conf_minion:: winrepo_remotes
.. conf_minion:: win_gitrepos
``winrepo_remotes``
-------------------
.. versionadded:: 2015.8.0
Default: ``['https://github.com/saltstack/salt-winrepo.git']``
List of git repositories to checkout and include in the winrepo
.. code-block:: yaml
winrepo_remotes:
- https://github.com/saltstack/salt-winrepo.git
To specify a specific revision of the repository, prepend a commit ID to the
URL of the the repository:
.. code-block:: yaml
winrepo_remotes:
- '<commit_id> https://github.com/saltstack/salt-winrepo.git'
Replace ``<commit_id>`` with the SHA1 hash of a commit ID. Specifying a commit
ID is useful in that it allows one to revert back to a previous version in the
event that an error is introduced in the latest revision of the repo.

View File

@ -42,21 +42,27 @@ 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.
Several config options have been renamed to make the naming more consistent.
For a list of the winrepo config options, see :ref:`here
<winrepo-config-opts>`.
This enhancement also brings new functionality, see the :mod:`winrepo runner
<salt.runners.winrepo>` documentation for more information.
The :mod:`winrepo.update_git_repos <salt.runners.winrepo.update_git_repos>`
runner has been updated to use either pygit2_ or GitPython_ to checkout the git
repositories containing repo data. If pygit2_ or GitPython_ is installed,
existing winrepo git checkouts should be removed after upgrading to 2015.8.0,
to allow them to be checked out again by running
:py:func:`winrepo.update_git_repos <salt.runners.winrepo.update_git_repos>`.
This enhancement also brings new functionality, see the :ref:`Windows Software
Repository <2015-8-0-winrepo-changes>` 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>`.
<salt.runners.winrepo.update_git_repos>`, and a warning will be logged in the
master log.
.. _GitPython: https://github.com/gitpython-developers/GitPython
.. _pygit2: https://github.com/libgit2/pygit2
.. _GitPython: https://github.com/gitpython-developers/GitPython
JBoss 7 State
=============

View File

@ -1,7 +1,13 @@
.. _windows-package-manager:
===========================
Windows Software Repository
===========================
.. note::
Git repository management for the Windows Software Repository has changed
in version 2015.8.0. Please see :ref:`below <2015-8-0-winrepo-changes>` for
important details if upgrading from an earlier Salt release.
The Salt Windows Software Repository provides a package manager and software
repository similar to what is provided by yum and apt on Linux.
@ -48,12 +54,13 @@ between the pre and post ``pkg.list_pkgs`` results.
Usage
=====
By default, the Windows software repository is found at ``/srv/salt/win/repo``
This can be changed in the master config file (default location is
``/etc/salt/master``) by modifying the ``win_repo`` variable, but this must
reside somewhere inside the master's `file_roots`. Each piece of software
should have its own directory which contains the installers and a package
definition file. This package definition file is a YAML file named
By default, the Windows software repository is found at ``/srv/salt/win/repo``.
This can be changed in the master config file by setting the
:conf_master:`winrepo_dir` option (**NOTE:** this option was called
``win_repo`` in Salt versions prior to 2015.8.0). However, this path must
reside somewhere inside the master's :conf_master:`file_roots`. Each piece of
software should have its own directory which contains the installers and a
package definition file. This package definition file is a YAML file named
``init.sls``.
The package definition file should look similar to this example for Firefox:
@ -197,7 +204,8 @@ Alternatively the ``uninstaller`` can also simply repeat the URL of the msi file
Generate Repo Cache File
========================
Once the sls file has been created, generate the repository cache file with the winrepo runner:
Once the sls file has been created, generate the repository cache file with the
winrepo runner:
.. code-block:: bash
@ -247,9 +255,9 @@ The above line will install the latest version of Firefox.
The above line will install version 16.0.2 of Firefox.
If a different version of the package is already installed it will
be replaced with the version in winrepo (only if the package itself supports
live updating).
If a different version of the package is already installed it will be replaced
with the version in the winrepo (only if the package itself supports live
updating).
You can also specify the full name:
@ -274,33 +282,44 @@ future ``pkg.purge`` may direct the installer to remove all configs and
settings for software packages that support that option.
Standalone Minion Salt Windows Repo Module
==========================================
In order to facilitate managing a Salt Windows software repo with Salt on a
Standalone Minion on Windows, a new module named winrepo has been added to
Salt. winrepo matches what is available in the salt runner and allows you to
manage the Windows software repo contents. Example: ``salt '*'
winrepo.genrepo``
Standalone Minion on Windows, a :mod:`winrepo execution module
<salt.modules.win_repo>` is available. This execution module matches what is
available in the :mod:`winrepo runner <salt.runners.winrepo>` and allows for
Windows software repo contents to be managed on a standalone Windows minion.
For example, to generate the winrepo cache, ``salt-call winrepo.genrepo`` would
be run.
.. note::
The :mod:`winrepo execution module <salt.modules.win_repo>` does not
support the :ref:`new features <2015-8-0-winrepo-changes>` added in
version 2015.8.0.
Git Hosted Repo
===============
Windows software package definitions can also be hosted in one or more git
repositories. The default repo is one hosted on GitHub.com by SaltStack,Inc., which
includes package definitions for open source software. This repo points to the
HTTP or ftp locations of the installer files. Anyone is welcome to send a pull
request to this repo to add new package definitions. Browse the repo
here: `https://github.com/saltstack/salt-winrepo
<https://github.com/saltstack/salt-winrepo>`_ .
repositories. The default repo is one hosted on GitHub.com by SaltStack, Inc.,
which includes package definitions for open source software. This repo points
to the HTTP or ftp locations of the installer files. Anyone is welcome to send
a pull request to this repo to add new package definitions. Browse the repo
here: `https://github.com/saltstack/salt-winrepo.git
<https://github.com/saltstack/salt-winrepo.git>`_ .
Configure which git repos the master can search for package definitions by
modifying or extending the ``win_gitrepos`` configuration option list in the
master config.
Configure which git repositories the master can search for package definitions
by modifying or extending the :conf_master:`winrepo_remotes` option (**NOTE:**
this option was called ``win_gitrepos`` in Salt versions prior to 2015.8.0).
Checkout each git repo in ``win_gitrepos``, compile your package repository
cache and then refresh each minion's package cache:
Use the :py:func:`winrepo.update_git_repos
<salt.runners.winrepo.update_git_repos>` runner to clone/update the configured
reops, then use :py:func:`winrepo.genrepo <salt.runners.winrepo.genrepo>`
runner to compile the repository cache. Finally, use :py:func:`pkg.refresh_db
<salt.modules.win_pkg.refresh_db>` on each minion to have them update their
copy of the repository cache. Command examples are as follows:
.. code-block:: bash
@ -310,12 +329,82 @@ cache and then refresh each minion's package cache:
.. _wiki: http://wpkg.org/Category:Silent_Installers
.. _2015-8-0-winrepo-changes:
Changes in Version 2015.8.0
===========================
Many of the winrepo configuration parameters have changed in version 2015.8.0
to make the naming more consistent. The old parameter names will still work,
but a warning will be logged indicating that the old name is deprecated. For a
list of the winrepo config options, see :ref:`here <winrepo-config-opts>`.
Starting in version 2015.8.0, the :py:func:`winrepo.update_git_repos
<salt.runners.winrepo.update_git_repos>` runner now makes use of the same
underlying code used by the :ref:`Git Fileserver Backend <tutorial-gitfs>` and
:ref:`Git External Pillar <tutorial-git_pillar>` to maintain and update its
local clones of git repositories. If a compatible version of either pygit2_
(0.20.3 and later) or GitPython_ (0.3.0 or later) is installed, then Salt will
use it instead of the old method (which invokes the :py:func:`git.latest
<salt.states.git.latest>` state).
.. note::
If compatible versions of both pygit2_ and GitPython_ are installed, then
Salt will prefer pygit2_, to override this behavior use the
:conf_master:`winrepo_provider` configuration parameter:
.. code-block:: yaml
winrepo_provider: gitpython
.. _pygit2: https://github.com/libgit2/pygit2
.. _GitPython: https://github.com/gitpython-developers/GitPython
One important change this brings is the the fact that each repo configured
under the :conf_master:`winrepo_remotes` option (``win_gitrepos`` in Salt
versions prior to 2015.8.0) will have its URL hashed and and the files will be
checked out into a subdirectory containing that hashed name (for example,
``/srv/salt/win/repo/f42c3382aeeaa8733908e5c256dba1ca/myprogram.sls``). There
is no functional reason for the hashed name, it just comes from using the same
back-end code that gitfs and git_pillar are using.
To minimize potential issues, it is a good idea to remove any winrepo git
repositories that were checked out by the old (pre-2015.8.0) winrepo code when
upgrading the master to 2015.8.0 or later, and run
:py:func:`winrepo.update_git_repos <salt.runners.winrepo.update_git_repos>` to
clone them anew after the master is started.
Additional added features include the ability to access authenticated git
repositories (**NOTE:** pygit2_ only), and to set per-remote config settings. An
example of this would be the following:
.. code-block:: yaml
winrepo_remotes:
- https://github.com/saltstack/salt-winrepo.git
- git@github.com:myuser/myrepo.git:
- pubkey: /path/to/key.pub
- privkey: /path/to/key
- passphrase: myaw3s0m3pa$$phr4$3
- https://github.com/myuser/privaterepo.git:
- user: mygithubuser
- password: correcthorsebatterystaple
.. note::
Per-remote configuration settings work in the same fashion as they do in
gitfs, with global parameters being overridden by their per-remote
counterparts (for instance, setting :conf_master:`winrepo_passphrase` would
set a global passphrase for winrepo that would apply to all SSH-based
remotes, unless overridden by a ``passphrase`` per-remote parameter).
See :ref:`here <gitfs-per-remote-config>` for more a more in-depth
explanation of how per-remote configuration works in gitfs, the same
principles apply to winrepo.
Troubleshooting
===============
Incorrect name/version
----------------------

View File

@ -380,9 +380,6 @@ VALID_OPTS = {
# Events matching a tag in this list should never be sent to an event returner.
'event_return_blacklist': list,
# The source location for the winrepo sls files
'win_repo_source_dir': str,
# This pidfile to write out to when a deamon starts
'pidfile': str,
@ -569,9 +566,21 @@ VALID_OPTS = {
# The logfile location for salt-key
'key_logfile': str,
'win_repo': str,
'win_repo_mastercachefile': str,
'win_gitrepos': list,
# The source location for the winrepo sls files
# (used by win_pkg.py, minion only)
'winrepo_source_dir': str,
'winrepo_dir': str,
'winrepo_cachefile': str,
'winrepo_remotes': list,
'winrepo_branch': str,
'winrepo_ssl_verify': bool,
'winrepo_user': str,
'winrepo_password': str,
'winrepo_insecure_auth': bool,
'winrepo_privkey': str,
'winrepo_pubkey': str,
'winrepo_passphrase': str,
# Set a hard limit for the amount of memory modules can consume on a minion.
'modules_max_memory': int,
@ -842,7 +851,10 @@ DEFAULT_MINION_OPTS = {
'syndic_log_file': os.path.join(salt.syspaths.LOGS_DIR, 'syndic'),
'syndic_pidfile': os.path.join(salt.syspaths.PIDFILE_DIR, 'salt-syndic.pid'),
'random_reauth_delay': 10,
'win_repo_source_dir': 'salt://win/repo/',
'winrepo_source_dir': 'salt://win/repo/',
'winrepo_dir': 'c:\\salt\\file_roots\\winrepo',
'winrepo_cachefile': 'winrepo.p',
'winrepo_remotes': ['https://github.com/saltstack/salt-winrepo.git'],
'pidfile': os.path.join(salt.syspaths.PIDFILE_DIR, 'salt-minion.pid'),
'range_server': 'range:80',
'tcp_keepalive': True,
@ -1041,10 +1053,17 @@ DEFAULT_MASTER_OPTS = {
'verify_env': True,
'permissive_pki_access': False,
'default_include': 'master.d/*.conf',
'win_repo': os.path.join(salt.syspaths.BASE_FILE_ROOTS_DIR, 'win', 'repo'),
'win_repo_mastercachefile': os.path.join(salt.syspaths.BASE_FILE_ROOTS_DIR,
'win', 'repo', 'winrepo.p'),
'win_gitrepos': ['https://github.com/saltstack/salt-winrepo.git'],
'winrepo_dir': os.path.join(salt.syspaths.BASE_FILE_ROOTS_DIR, 'win', 'repo'),
'winrepo_cachefile': 'winrepo.p',
'winrepo_remotes': ['https://github.com/saltstack/salt-winrepo.git'],
'winrepo_branch': 'master',
'winrepo_ssl_verify': False,
'winrepo_user': '',
'winrepo_password': '',
'winrepo_insecure_auth': False,
'winrepo_privkey': '',
'winrepo_pubkey': '',
'winrepo_passphrase': '',
'syndic_wait': 5,
'jinja_lstrip_blocks': False,
'jinja_trim_blocks': False,

View File

@ -102,10 +102,10 @@ class Client(object):
# Backwards compatibility
saltenv = env
dest = os.path.join(self.opts['cachedir'],
'files',
saltenv,
path)
dest = salt.utils.path_join(self.opts['cachedir'],
'files',
saltenv,
path)
destdir = os.path.dirname(dest)
cumask = os.umask(63)
if not os.path.isdir(destdir):

View File

@ -93,9 +93,9 @@ def latest_version(*names, **kwargs):
latest_installed = sorted(installed_pkgs[name], cmp=_reverse_cmp_pkg_versions).pop()
log.debug('Latest installed version of package {0} is {1}'.format(name, latest_installed))
# get latest available (from win_repo) version of package
# get latest available (from winrepo_dir) version of package
pkg_info = _get_package_info(name)
log.trace('Raw win_repo pkg_info for {0} is {1}'.format(name, pkg_info))
log.trace('Raw winrepo pkg_info for {0} is {1}'.format(name, pkg_info))
latest_available = _get_latest_pkg_version(pkg_info)
if latest_available:
log.debug('Latest available version of package {0} is {1}'.format(name, latest_available))
@ -371,25 +371,47 @@ def refresh_db(saltenv='base'):
salt '*' pkg.refresh_db
'''
__context__.pop('winrepo.data', None)
repo = __opts__['win_repo_source_dir']
cached_files = __salt__['cp.cache_dir'](repo, saltenv, include_pat='*.sls')
if 'win_repo_source_dir' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo_source_dir\' config option is deprecated, please '
'use \'winrepo_source_dir\' instead.'
)
winrepo_source_dir = __opts__['win_repo_source_dir']
else:
winrepo_source_dir = __opts__['winrepo_source_dir']
cached_files = __salt__['cp.cache_dir'](
winrepo_source_dir,
saltenv,
include_pat='*.sls'
)
genrepo(saltenv=saltenv)
return cached_files
def _get_local_repo_dir(saltenv='base'):
master_repo_src = __opts__['win_repo_source_dir']
if 'win_repo_source_dir' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo_source_dir\' config option is deprecated, please '
'use \'winrepo_source_dir\' instead.'
)
winrepo_source_dir = __opts__['win_repo_source_dir']
else:
winrepo_source_dir = __opts__['winrepo_source_dir']
dirs = []
dirs.append(salt.syspaths.CACHE_DIR)
dirs.extend(['minion', 'files'])
dirs.append(saltenv)
dirs.extend(master_repo_src[7:].strip('/').split('/'))
dirs.extend(winrepo_source_dir[7:].strip('/').split('/'))
return os.sep.join(dirs)
def genrepo(saltenv='base'):
'''
Generate win_repo_cachefile based on sls files in the win_repo
Generate winrepo_cachefile based on sls files in the winrepo
CLI Example:

View File

@ -2,10 +2,11 @@
r'''
Module to manage Windows software repo on a Standalone Minion
The following options must be set in the Minion config:
file_client: local
win_repo_cachefile: c:\salt\file_roots\winrepo\winrepo.p
win_repo: c:\salt\file_roots\winrepo
``file_client: local`` must be set in the minion config file. Other config
options of interest include:
* :conf_minion:`winrepo_dir`
* :conf_minion:`winrepo_cachefile`
Place all Windows package files in the 'win_repo' directory.
'''
@ -46,7 +47,7 @@ def __virtual__():
def genrepo():
r'''
Generate win_repo_cachefile based on sls files in the win_repo
Generate winrepo_cachefile based on sls files in the win_repo
CLI Example:
@ -54,13 +55,31 @@ def genrepo():
salt-call winrepo.genrepo -c c:\salt\conf
'''
if 'win_repo' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo\' config option is deprecated, please use '
'\'winrepo_dir\' instead.'
)
winrepo_dir = __opts__['win_repo']
else:
winrepo_dir = __opts__['winrepo_dir']
if 'win_repo_cachefile' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo_cachefile\' config option is deprecated, please '
'use \'winrepo_cachefile\' instead.'
)
winrepo_cachefile = __opts__['win_repo_cachefile']
else:
winrepo_cachefile = __opts__['winrepo_cachefile']
ret = {}
repo = __opts__['win_repo']
if not os.path.exists(repo):
os.makedirs(repo)
winrepo = __opts__['win_repo_cachefile']
if not os.path.exists(winrepo_dir):
os.makedirs(winrepo_dir)
renderers = salt.loader.render(__opts__, __salt__)
for root, dirs, files in os.walk(repo):
for root, dirs, files in os.walk(winrepo_dir):
for name in files:
if name.endswith('.sls'):
config = salt.template.compile_template(
@ -77,7 +96,8 @@ def genrepo():
revmap[repodata['full_name']] = pkgname
ret.setdefault('repo', {}).update(config)
ret.setdefault('name_map', {}).update(revmap)
with salt.utils.fopen(os.path.join(repo, winrepo), 'w+b') as repo:
with salt.utils.fopen(
os.path.join(winrepo_dir, winrepo_cachefile), 'w+b') as repo:
repo.write(msgpack.dumps(ret))
salt.output.display_output(ret, 'pprint', __opts__)
return ret
@ -91,25 +111,43 @@ def update_git_repos():
This function will not work unless git is installed and the git module
is further updated to work on Windows. In the meantime just place all
Windows package files in the ``win_repo`` directory.
Windows package files in the :conf_minion:`winrepo_dir` directory.
'''
if 'win_repo' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo\' config option is deprecated, please use '
'\'winrepo_dir\' instead.'
)
winrepo_dir = __opts__['win_repo']
else:
winrepo_dir = __opts__['winrepo_dir']
if 'win_gitrepos' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_gitrepos\' config option is deprecated, please use '
'\'winrepo_remotes\' instead.'
)
winrepo_remotes = __opts__['win_gitrepos']
else:
winrepo_remotes = __opts__['winrepo_remotes']
ret = {}
#mminion = salt.minion.MasterMinion(__opts__)
repo = __opts__['win_repo']
gitrepos = __opts__['win_gitrepos']
for gitrepo in gitrepos:
#if '/' in gitrepo:
#targetname = gitrepo.split('/')[-1]
for remote in winrepo_remotes:
#if '/' in remote:
#targetname = remote.split('/')[-1]
#else:
#targetname = gitrepo
targetname = gitrepo
#targetname = remote
targetname = remote
rev = None
# If a revision is specified, use it.
if len(gitrepo.strip().split(' ')) > 1:
rev, gitrepo = gitrepo.strip().split(' ')
gittarget = os.path.join(repo, targetname)
#result = mminion.states['git.latest'](gitrepo,
result = __salt__['git.latest'](gitrepo,
if len(remote.strip().split(' ')) > 1:
rev, remote = remote.strip().split(' ')
gittarget = os.path.join(winrepo_dir, targetname)
#result = mminion.states['git.latest'](remote,
result = __salt__['git.latest'](remote,
rev=rev,
target=gittarget,
force=True)

View File

@ -135,7 +135,7 @@ authenication parameter names prefixed with ``git_pillar`` instead of ``gitfs``
:conf_master:`git_pillar_passphrase`, etc.).
A full list of the git_pillar configuration options can be found :ref:`here
<git-pillar-config-opts>`.
<git_pillar-config-opts>`.
.. _GitPython: https://github.com/gitpython-developers/GitPython
.. _pygit2: https://github.com/libgit2/pygit2

View File

@ -17,6 +17,7 @@ except ImportError:
# Import salt libs
from salt.exceptions import SaltRenderError
import salt.utils
import salt.utils.gitfs
import logging
import salt.minion
import salt.loader
@ -24,10 +25,12 @@ import salt.template
log = logging.getLogger(__name__)
PER_REMOTE_PARAMS = ('ssl_verify',)
def genrepo():
'''
Generate win_repo_cachefile based on sls files in the win_repo
Generate winrepo_cachefile based on sls files in the winrepo_dir
CLI Example:
@ -35,13 +38,31 @@ def genrepo():
salt-run winrepo.genrepo
'''
if 'win_repo' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo\' config option is deprecated, please use '
'\'winrepo_dir\' instead.'
)
winrepo_dir = __opts__['win_repo']
else:
winrepo_dir = __opts__['winrepo_dir']
if 'win_repo_mastercachefile' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo_mastercachefile\' config option is deprecated, '
'please use \'winrepo_cachefile\' instead.'
)
winrepo_cachefile = __opts__['win_repo_mastercachefile']
else:
winrepo_cachefile = __opts__['winrepo_cachefile']
ret = {}
repo = __opts__['win_repo']
if not os.path.exists(repo):
os.makedirs(repo)
winrepo = __opts__['win_repo_mastercachefile']
if not os.path.exists(winrepo_dir):
os.makedirs(winrepo_dir)
renderers = salt.loader.render(__opts__, __salt__)
for root, _, files in os.walk(repo):
for root, _, files in os.walk(winrepo_dir):
for name in files:
if name.endswith('.sls'):
try:
@ -50,25 +71,44 @@ def genrepo():
renderers,
__opts__['renderer'])
except SaltRenderError as exc:
log.debug('Failed to render {0}.'.format(os.path.join(root, name)))
log.debug(
'Failed to render {0}.'.format(
os.path.join(root, name)
)
)
log.debug('Error: {0}.'.format(exc))
continue
if config:
revmap = {}
for pkgname, versions in six.iteritems(config):
log.debug(
'Compiling winrepo data for package \'{0}\''
.format(pkgname)
)
for version, repodata in six.iteritems(versions):
log.debug(
'Compiling winrepo data for {0} version {1}'
.format(pkgname, version)
)
if not isinstance(version, six.string_types):
config[pkgname][str(version)] = \
config[pkgname].pop(version)
if not isinstance(repodata, dict):
log.debug('Failed to compile'
'{0}.'.format(os.path.join(root, name)))
__jid_event__.fire_event({'error': 'Failed to compile {0}.'.format(os.path.join(root, name))}, 'progress')
log.debug(
'Failed to compile {0}.'.format(
os.path.join(root, name)
)
)
__jid_event__.fire_event(
{'error': 'Failed to compile {0}.'.format(
os.path.join(root, name))},
'progress')
continue
revmap[repodata['full_name']] = pkgname
ret.setdefault('repo', {}).update(config)
ret.setdefault('name_map', {}).update(revmap)
with salt.utils.fopen(os.path.join(repo, winrepo), 'w+b') as repo:
with salt.utils.fopen(
os.path.join(winrepo_dir, winrepo_cachefile), 'w+b') as repo:
repo.write(msgpack.dumps(ret))
return ret
@ -83,23 +123,70 @@ def update_git_repos():
salt-run winrepo.update_git_repos
'''
ret = {}
mminion = salt.minion.MasterMinion(__opts__)
repo = __opts__['win_repo']
gitrepos = __opts__['win_gitrepos']
for gitrepo in gitrepos:
if '/' in gitrepo:
targetname = gitrepo.split('/')[-1]
else:
targetname = gitrepo
rev = None
# If a revision is specified, use it.
if len(gitrepo.strip().split(' ')) > 1:
rev, gitrepo = gitrepo.strip().split(' ')
gittarget = os.path.join(repo, targetname)
result = mminion.states['git.latest'](gitrepo,
rev=rev,
target=gittarget,
force=True)
ret[result['name']] = result['result']
return ret
if 'win_repo' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo\' config option is deprecated, please use '
'\'winrepo_dir\' instead.'
)
winrepo_dir = __opts__['win_repo']
else:
winrepo_dir = __opts__['winrepo_dir']
if 'win_gitrepos' in __opts__:
salt.utils.warn_until(
'Nitrogen',
'The \'win_gitrepos\' config option is deprecated, please use '
'\'winrepo_remotes\' instead.'
)
winrepo_remotes = __opts__['win_gitrepos']
else:
winrepo_remotes = __opts__['winrepo_remotes']
if not any((salt.utils.gitfs.HAS_GITPYTHON, salt.utils.gitfs.HAS_PYGIT2)):
# Use legacy code
if not salt.utils.is_windows():
# Don't warn on Windows, because Windows can't do cool things like
# use pygit2. It has to fall back to git.latest.
salt.utils.warn_until(
'Nitrogen',
'winrepo git support now requires either GitPython or pygit2. '
'Please install either GitPython >= {0} (or pygit2 >= {1} with '
'libgit2 >= {2}), clear out the winrepo_dir ({3}), and '
'restart the salt-master service.'.format(
salt.utils.gitfs.GITPYTHON_MINVER,
salt.utils.gitfs.PYGIT2_MINVER,
salt.utils.gitfs.LIBGIT2_MINVER,
winrepo_dir
)
)
ret = {}
mminion = salt.minion.MasterMinion(__opts__)
for remote in winrepo_remotes:
if '/' in remote:
targetname = remote.split('/')[-1]
else:
targetname = remote
rev = None
# If a revision is specified, use it.
if len(remote.strip().split(' ')) > 1:
rev, remote = remote.strip().split(' ')
gittarget = os.path.join(winrepo_dir, targetname)
result = mminion.states['git.latest'](remote,
rev=rev,
target=gittarget,
force=True)
ret[result['name']] = result['result']
return ret
else:
# New winrepo code utilizing salt.utils.gitfs
try:
winrepo = salt.utils.gitfs.WinRepo(__opts__)
winrepo.init_remotes(winrepo_remotes, PER_REMOTE_PARAMS)
winrepo.fetch_remotes()
winrepo.checkout()
except Exception as exc:
msg = 'Failed to update winrepo_remotes: {0}'.format(exc)
log.error(msg, exc_info_on_loglevel=logging.DEBUG)
return msg
return winrepo.winrepo_dirs

View File

@ -16,6 +16,7 @@ import itertools
# Salt Modules
import salt.runner
import salt.utils
import salt.config
@ -57,28 +58,52 @@ def genrepo(name, force=False, allow_empty=False):
'changes': {},
'comment': ''}
master_config = salt.config.master_config(os.path.join(salt.syspaths.CONFIG_DIR, 'master'))
win_repo = master_config['win_repo']
win_repo_mastercachefile = master_config['win_repo_mastercachefile']
master_config = salt.config.master_config(
os.path.join(salt.syspaths.CONFIG_DIR, 'master')
)
# Check if the win_repo directory exists
# if not search for a file with a newer mtime than the win_repo_mastercachefile file
if 'win_repo' in master_config:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo\' config option is deprecated, please use '
'\'winrepo_dir\' instead.'
)
winrepo_dir = master_config['win_repo']
else:
winrepo_dir = master_config['winrepo_dir']
if 'win_repo_mastercachefile' in master_config:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo_mastercachefile\' config option is deprecated, '
'please use \'winrepo_cachefile\' instead.'
)
winrepo_cachefile = master_config['win_repo_mastercachefile']
else:
winrepo_cachefile = master_config['winrepo_cachefile']
# We're actually looking for the full path to the cachefile here, so
# prepend the winrepo_dir
winrepo_cachefile = os.path.join(winrepo_dir, winrepo_cachefile)
# Check if the winrepo directory exists
# if not search for a file with a newer mtime than the winrepo_cachefile file
execute = False
if not force:
if not os.path.exists(win_repo):
if not os.path.exists(winrepo_dir):
ret['result'] = False
ret['comment'] = 'missing {0}'.format(win_repo)
ret['comment'] = '{0} is missing'.format(winrepo_dir)
return ret
elif not os.path.exists(win_repo_mastercachefile):
elif not os.path.exists(winrepo_cachefile):
execute = True
ret['comment'] = 'missing {0}'.format(win_repo_mastercachefile)
ret['comment'] = '{0} is missing'.format(winrepo_cachefile)
else:
win_repo_mastercachefile_mtime = os.stat(win_repo_mastercachefile)[stat.ST_MTIME]
for root, dirs, files in os.walk(win_repo):
winrepo_cachefile_mtime = os.stat(winrepo_cachefile)[stat.ST_MTIME]
for root, dirs, files in os.walk(winrepo_dir):
for name in itertools.chain(files, dirs):
full_path = os.path.join(root, name)
if os.stat(full_path)[stat.ST_MTIME] > win_repo_mastercachefile_mtime:
ret['comment'] = 'mtime({0}) < mtime({1})'.format(win_repo_mastercachefile, full_path)
if os.stat(full_path)[stat.ST_MTIME] > winrepo_cachefile_mtime:
ret['comment'] = 'mtime({0}) < mtime({1})'.format(winrepo_cachefile, full_path)
execute = True
break
@ -93,7 +118,7 @@ def genrepo(name, force=False, allow_empty=False):
runner_ret = runner.cmd('winrepo.genrepo', [])
ret['changes'] = {'winrepo': runner_ret}
if isinstance(runner_ret, dict) and runner_ret == {} and not allow_empty:
os.remove(win_repo_mastercachefile)
os.remove(winrepo_cachefile)
ret['result'] = False
ret['comment'] = 'winrepo.genrepo returned empty'
return ret

View File

@ -84,6 +84,14 @@ except ImportError:
log = logging.getLogger(__name__)
# Minimum versions for backend providers
GITPYTHON_MINVER = '0.3'
PYGIT2_MINVER = '0.20.3'
LIBGIT2_MINVER = '0.20.0'
# dulwich.__version__ is a versioninfotuple so we can compare tuples
# instead of using distutils.version.LooseVersion
DULWICH_MINVER = (0, 9, 4)
def failhard(role):
'''
@ -175,6 +183,12 @@ class GitProvider(object):
self.id = remote
self.get_url()
# Winrepo doesn't support the 'root' option, but it still must be part
# of the GitProvider object because other code depends on it. Add it as
# an empty string.
if 'root' not in repo_conf:
repo_conf['root'] = ''
# Set all repo config params as attributes
for key, val in six.iteritems(repo_conf):
setattr(self, key, val)
@ -212,15 +226,15 @@ class GitProvider(object):
log.critical(msg, exc_info_on_loglevel=logging.DEBUG)
failhard(self.role)
def check_pillar_root(self):
def check_root(self):
'''
Check if the relative root path exists in the checked-out copy of the
remote. Return the full path to that relative root if it does exist,
otherwise return None.
'''
pillar_root = os.path.join(self.cachedir, self.root)
if os.path.isdir(pillar_root):
return pillar_root
root_dir = os.path.join(self.cachedir, self.root).rstrip(os.sep)
if os.path.isdir(root_dir):
return root_dir
log.error(
'Root path \'{0}\' not present in {1} remote \'{2}\', '
'skipping.'.format(self.root, self.role, self.id)
@ -350,10 +364,10 @@ class GitProvider(object):
'''
Examine self.id and assign self.url (and self.branch, for git_pillar)
'''
if self.role == 'git_pillar':
# With git_pillar, the remote is specified in the format
# "<branch> <url>", so that we can get a unique identifier to
# hash for each remote.
if self.role in ('git_pillar', 'winrepo'):
# With winrepo and git_pillar, the remote is specified in the
# format '<branch> <url>', so that we can get a unique identifier
# to hash for each remote.
try:
self.branch, self.url = self.id.split(None, 1)
except ValueError:
@ -394,7 +408,7 @@ class GitPython(GitProvider):
self.repo.git.checkout(ref)
except Exception:
continue
return self.check_pillar_root()
return self.check_root()
log.error(
'Failed to checkout {0} from {1} remote \'{2}\': remote ref does '
'not exist'.format(self.branch, self.role, self.id)
@ -646,10 +660,10 @@ class Pygit2(GitProvider):
self.repo.checkout(local_ref)
# Reset HEAD to the commit id of the remote ref
self.repo.reset(oid, pygit2.GIT_RESET_HARD)
return self.check_pillar_root()
return self.check_root()
elif tag_ref in refs:
self.repo.checkout(tag_ref)
return self.check_pillar_root()
return self.check_root()
except Exception as exc:
log.error(
'Failed to checkout {0} from {1} remote \'{2}\': {3}'.format(
@ -1437,11 +1451,14 @@ class GitBase(object):
'''
Base class for gitfs/git_pillar
'''
def __init__(self, opts, valid_providers=VALID_PROVIDERS):
def __init__(self, opts, valid_providers=VALID_PROVIDERS, cache_root=None):
self.opts = opts
self.valid_providers = valid_providers
self.get_provider()
self.cache_root = os.path.join(self.opts['cachedir'], self.role)
if cache_root is not None:
self.cache_root = cache_root
else:
self.cache_root = os.path.join(self.opts['cachedir'], self.role)
self.env_cache = os.path.join(self.cache_root, 'envs.p')
self.hash_cachedir = os.path.join(
self.cache_root, self.role, 'hash')
@ -1782,15 +1799,14 @@ class GitBase(object):
# pylint: disable=no-member
gitver = distutils.version.LooseVersion(git.__version__)
minver_str = '0.3.0'
minver = distutils.version.LooseVersion(minver_str)
minver = distutils.version.LooseVersion(GITPYTHON_MINVER)
# pylint: enable=no-member
errors = []
if gitver < minver:
errors.append(
'Git fileserver backend is enabled in master config file, but '
'the GitPython version is earlier than {0}. Version {1} '
'detected.'.format(minver_str, git.__version__)
'detected.'.format(GITPYTHON_MINVER, git.__version__)
)
if not salt.utils.which('git'):
errors.append(
@ -1834,12 +1850,10 @@ class GitBase(object):
# pylint: disable=no-member
pygit2ver = distutils.version.LooseVersion(pygit2.__version__)
pygit2_minver_str = '0.20.3'
pygit2_minver = distutils.version.LooseVersion(pygit2_minver_str)
pygit2_minver = distutils.version.LooseVersion(PYGIT2_MINVER)
libgit2ver = distutils.version.LooseVersion(pygit2.LIBGIT2_VERSION)
libgit2_minver_str = '0.20.0'
libgit2_minver = distutils.version.LooseVersion(libgit2_minver_str)
libgit2_minver = distutils.version.LooseVersion(LIBGIT2_MINVER)
# pylint: enable=no-member
errors = []
@ -1847,13 +1861,13 @@ class GitBase(object):
errors.append(
'Git fileserver backend is enabled in master config file, but '
'pygit2 version is earlier than {0}. Version {1} detected.'
.format(pygit2_minver_str, pygit2.__version__)
.format(PYGIT2_MINVER, pygit2.__version__)
)
if libgit2ver < libgit2_minver:
errors.append(
'Git fileserver backend is enabled in master config file, but '
'libgit2 version is earlier than {0}. Version {1} detected.'
.format(libgit2_minver_str, pygit2.LIBGIT2_VERSION)
.format(LIBGIT2_MINVER, pygit2.LIBGIT2_VERSION)
)
if not salt.utils.which('git'):
errors.append(
@ -1893,16 +1907,13 @@ class GitBase(object):
elif 'dulwich' not in self.valid_providers:
return False
dulwich_version = dulwich.__version__
dulwich_min_version = (0, 9, 4)
errors = []
if dulwich_version < dulwich_min_version:
if dulwich.__version__ < DULWICH_MINVER:
errors.append(
'Git fileserver backend is enabled in the master config file, but '
'the installed version of Dulwich is earlier than {0}. Version {1} '
'detected.'.format(dulwich_min_version, dulwich_version)
'detected.'.format(DULWICH_MINVER, dulwich.__version__)
)
if errors:
@ -2218,7 +2229,6 @@ class GitPillar(GitBase):
else:
base_branch = self.opts['{0}_branch'.format(self.role)]
env = 'base' if repo.branch == base_branch else repo.branch
log.critical(env)
self.pillar_dirs[cachedir] = env
def update(self):
@ -2232,3 +2242,36 @@ class GitPillar(GitBase):
and just run pillar.fetch_remotes() there.
'''
return self.fetch_remotes()
class WinRepo(GitBase):
'''
Functionality specific to the winrepo runner
'''
def __init__(self, opts):
self.role = 'winrepo'
# Dulwich has no function to check out a branch/tag, so this will be
# limited to GitPython and Pygit2 for the forseeable future.
if 'win_repo' in opts:
salt.utils.warn_until(
'Nitrogen',
'The \'win_repo\' config option is deprecated, please use '
'\'winrepo_dir\' instead.'
)
winrepo_dir = opts['win_repo']
else:
winrepo_dir = opts['winrepo_dir']
GitBase.__init__(self,
opts,
valid_providers=('gitpython', 'pygit2'),
cache_root=winrepo_dir)
def checkout(self):
'''
Checkout the targeted branches/tags from the winrepo remotes
'''
self.winrepo_dirs = {}
for repo in self.remotes:
cachedir = repo.checkout()
if cachedir is not None:
self.winrepo_dirs[repo.url] = cachedir

View File

@ -36,14 +36,14 @@ class WinRepoTestCase(TestCase):
@patch('salt.loader.render', MagicMock(return_valu=''))
def test_genrepo(self):
'''
Test to generate win_repo_cachefile
based on sls files in the win_repo
Test to generate winrepo_cachefile based on sls files in the
winrepo_dir
'''
with patch.dict(win_repo.__opts__, {'win_repo': 'c:\\salt'}):
with patch.dict(win_repo.__opts__, {'winrepo_dir': 'c:\\salt'}):
mock_bool = MagicMock(return_value=True)
with patch.object(os.path, 'exists', mock_bool):
with patch.dict(win_repo.__opts__,
{'win_repo_cachefile': 'cache.c'}):
{'winrepo_cachefile': 'cache.c'}):
mock = MagicMock(return_value={})
with patch.object(os, 'walk', mock):
with patch('salt.utils.fopen', mock_open()):
@ -53,11 +53,11 @@ class WinRepoTestCase(TestCase):
def test_update_git_repos(self):
'''
Test to checkout git repos containing
Windows Software Package Definitions
Test to checkout git repos containing Windows software package
definitions
'''
with patch.dict(win_repo.__opts__, {'win_repo': 'c:\\salt'}):
with patch.dict(win_repo.__opts__, {'win_gitrepos': {}}):
with patch.dict(win_repo.__opts__, {'winrepo_dir': 'c:\\salt'}):
with patch.dict(win_repo.__opts__, {'winrepo_remotes': {}}):
mock = MagicMock(return_value=True)
with patch.object(salt.output, 'display_output', mock):
self.assertDictEqual(win_repo.update_git_repos(), {})

View File

@ -57,11 +57,11 @@ class MockRunnerClient(object):
@skipIf(NO_MOCK, NO_MOCK_REASON)
class WinrepoTestCase(TestCase):
'''
Validate the winrepo state
Validate the winrepo state
'''
def test_genrepo(self):
'''
Test to refresh the winrepo.p file of the repository
Test to refresh the winrepo.p file of the repository
'''
ret = {'name': 'salt',
'changes': {},
@ -70,21 +70,21 @@ class WinrepoTestCase(TestCase):
mock = MagicMock(side_effect=[False, True, True, True, True, True,
True])
with patch.object(os.path, 'exists', mock):
ret.update({'comment': 'missing /srv/salt/win/repo'})
ret.update({'comment': '/srv/salt/win/repo is missing'})
self.assertDictEqual(winrepo.genrepo('salt'), ret)
mock = MagicMock(return_value={'win_repo': 'salt',
'win_repo_mastercachefile': 'abc'})
mock = MagicMock(return_value={'winrepo_dir': 'salt',
'winrepo_cachefile': 'abc'})
with patch.object(salt.config, 'master_config', mock):
mock = MagicMock(return_value=[0, 1, 2, 3, 4, 5, 6, 7, 8])
with patch.object(os, 'stat', mock):
mock = MagicMock(return_value=[])
with patch.object(os, 'walk', mock):
with patch.dict(winrepo.__opts__, {"test": True}):
with patch.dict(winrepo.__opts__, {'test': True}):
ret.update({'comment': '', 'result': None})
self.assertDictEqual(winrepo.genrepo('salt'), ret)
with patch.dict(winrepo.__opts__, {"test": False}):
with patch.dict(winrepo.__opts__, {'test': False}):
ret.update({'result': True})
self.assertDictEqual(winrepo.genrepo('salt'), ret)