mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #26148 from terminalmage/winrepo
Refactor winrepo support
This commit is contained in:
commit
95a560ebf1
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
=============
|
||||
|
@ -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
|
||||
----------------------
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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):
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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(), {})
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user