12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184 |
- .. _tutorial-gitfs:
- ==================================
- Git Fileserver Backend Walkthrough
- ==================================
- .. note::
- This walkthrough assumes basic knowledge of Salt. To get up to speed, check
- out the :ref:`Salt Walkthrough <tutorial-salt-walk-through>`.
- The gitfs backend allows Salt to serve files from git repositories. It can be
- enabled by adding ``git`` to the :conf_master:`fileserver_backend` list, and
- configuring one or more repositories in :conf_master:`gitfs_remotes`.
- Branches and tags become Salt fileserver environments.
- .. note::
- Branching and tagging can result in a lot of potentially-conflicting
- :ref:`top files <states-top>`, for this reason it may be useful to set
- :conf_minion:`top_file_merging_strategy` to ``same`` in the minions' config
- files if the top files are being managed in a GitFS repo.
- .. _gitfs-dependencies:
- Installing Dependencies
- =======================
- Both pygit2_ and GitPython_ are supported Python interfaces to git. If
- compatible versions of both are installed, pygit2_ will be preferred. In these
- cases, GitPython_ can be forced using the :conf_master:`gitfs_provider`
- parameter in the master config file.
- .. note::
- It is recommended to always run the most recent version of any the below
- dependencies. Certain features of GitFS may not be available without
- the most recent version of the chosen library.
- .. _pygit2: https://github.com/libgit2/pygit2
- .. _GitPython: https://github.com/gitpython-developers/GitPython
- pygit2
- ------
- The minimum supported version of pygit2_ is 0.20.3. Availability for this
- version of pygit2_ is still limited, though the SaltStack team is working to
- get compatible versions available for as many platforms as possible.
- For the Fedora/EPEL versions which have a new enough version packaged, the
- following command would be used to install pygit2_:
- .. code-block:: bash
- # yum install python-pygit2
- Provided a valid version is packaged for Debian/Ubuntu (which is not currently
- the case), the package name would be the same, and the following command would
- be used to install it:
- .. code-block:: bash
- # apt-get install python-pygit2
- If pygit2_ is not packaged for the platform on which the Master is running, the
- pygit2_ website has installation instructions
- `here <pygit2-install-instructions>`_. Keep in mind however that
- following these instructions will install libgit2_ and pygit2_ without system
- packages. Additionally, keep in mind that :ref:`SSH authentication in pygit2
- <pygit2-authentication-ssh>` requires libssh2_ (*not* libssh) development
- libraries to be present before libgit2_ is built. On some Debian-based distros
- ``pkg-config`` is also required to link libgit2_ with libssh2.
- .. note::
- If you are receiving the error "Unsupported URL Protocol" in the Salt Master
- log when making a connection using SSH, review the libssh2 details listed
- above.
- Additionally, version 0.21.0 of pygit2 introduced a dependency on python-cffi_,
- which in turn depends on newer releases of libffi_. Upgrading libffi_ is not
- advisable as several other applications depend on it, so on older LTS linux
- releases pygit2_ 0.20.3 and libgit2_ 0.20.0 is the recommended combination.
- .. warning::
- pygit2_ is actively developed and `frequently makes
- non-backwards-compatible API changes <pygit2-version-policy>`_, even in
- minor releases. It is not uncommon for pygit2_ upgrades to result in errors
- in Salt. Please take care when upgrading pygit2_, and pay close attention
- to the changelog_, keeping an eye out for API changes. Errors can be
- reported on the `SaltStack issue tracker <saltstack-issue-tracker>`_.
- .. _pygit2-version-policy: http://www.pygit2.org/install.html#version-numbers
- .. _changelog: https://github.com/libgit2/pygit2#changelog
- .. _saltstack-issue-tracker: https://github.com/saltstack/salt/issues
- .. _pygit2-install-instructions: http://www.pygit2.org/install.html
- .. _libgit2: https://libgit2.org/
- .. _libssh2: https://www.libssh2.org/
- .. _python-cffi: https://pypi.org/project/cffi
- .. _libffi: http://sourceware.org/libffi/
- RedHat Pygit2 Issues
- ~~~~~~~~~~~~~~~~~~~~
- The release of RedHat/CentOS 7.3 upgraded both ``python-cffi`` and
- ``http-parser``, both of which are dependencies for pygit2_/libgit2_. Both
- ``pygit2`` and ``libgit2`` packages (which are from the EPEL repository) should
- be upgraded to the most recent versions, at least to ``0.24.2``.
- The below errors will show up in the master log if an incompatible
- ``python-pygit2`` package is installed:
- .. code-block:: text
- 2017-02-10 09:07:34,892 [salt.utils.gitfs ][ERROR ][11211] Import pygit2 failed: CompileError: command 'gcc' failed with exit status 1
- 2017-02-10 09:07:34,907 [salt.utils.gitfs ][ERROR ][11211] gitfs is configured but could not be loaded, are pygit2 and libgit2 installed?
- 2017-02-10 09:07:34,907 [salt.utils.gitfs ][CRITICAL][11211] No suitable gitfs provider module is installed.
- 2017-02-10 09:07:34,912 [salt.master ][CRITICAL][11211] Master failed pre flight checks, exiting
- The below errors will show up in the master log if an incompatible ``libgit2``
- package is installed:
- .. code-block:: text
- 2017-02-15 18:04:45,211 [salt.utils.gitfs ][ERROR ][6211] Error occurred fetching gitfs remote 'https://foo.com/bar.git': No Content-Type header in response
- A restart of the ``salt-master`` daemon and gitfs cache directory clean up may
- be required to allow http(s) repositories to continue to be fetched.
- GitPython
- ---------
- GitPython_ 0.3.0 or newer is required to use GitPython for gitfs. For
- RHEL-based Linux distros, a compatible version is available in EPEL, and can be
- easily installed on the master using yum:
- .. code-block:: bash
- # yum install GitPython
- Ubuntu 14.04 LTS and Debian Wheezy (7.x) also have a compatible version packaged:
- .. code-block:: bash
- # apt-get install python-git
- GitPython_ requires the ``git`` CLI utility to work. If installed from a system
- package, then git should already be installed, but if installed via pip_ then
- it may still be necessary to install git separately. For MacOS users,
- GitPython_ comes bundled in with the Salt installer, but git must still be
- installed for it to work properly. Git can be installed in several ways,
- including by installing XCode_.
- .. _pip: http://www.pip-installer.org/
- .. _XCode: https://developer.apple.com/xcode/
- .. warning::
- GitPython advises against the use of its library for long-running processes
- (such as a salt-master or salt-minion). Please see their warning on potential
- leaks of system resources:
- https://github.com/gitpython-developers/GitPython#leakage-of-system-resources.
- .. warning::
- Keep in mind that if GitPython has been previously installed on the master
- using pip (even if it was subsequently uninstalled), then it may still
- exist in the build cache (typically ``/tmp/pip-build-root/GitPython``) if
- the cache is not cleared after installation. The package in the build cache
- will override any requirement specifiers, so if you try upgrading to
- version 0.3.2.RC1 by running ``pip install 'GitPython==0.3.2.RC1'`` then it
- will ignore this and simply install the version from the cache directory.
- Therefore, it may be necessary to delete the GitPython directory from the
- build cache in order to ensure that the specified version is installed.
- .. warning::
- GitPython_ 2.0.9 and newer is not compatible with Python 2.6. If installing
- GitPython_ using pip on a machine running Python 2.6, make sure that a
- version earlier than 2.0.9 is installed. This can be done on the CLI by
- running ``pip install 'GitPython<2.0.9'``, or in a :py:func:`pip.installed
- <salt.states.pip_state.installed>` state using the following SLS:
- .. code-block:: yaml
- GitPython:
- pip.installed:
- - name: 'GitPython < 2.0.9'
- Simple Configuration
- ====================
- To use the gitfs backend, only two configuration changes are required on the
- master:
- 1. Include ``gitfs`` in the :conf_master:`fileserver_backend` list in the
- master config file:
- .. code-block:: yaml
- fileserver_backend:
- - gitfs
- .. note::
- ``git`` also works here. Prior to the 2018.3.0 release, *only* ``git``
- would work.
- 2. Specify one or more ``git://``, ``https://``, ``file://``, or ``ssh://``
- URLs in :conf_master:`gitfs_remotes` to configure which repositories to
- cache and search for requested files:
- .. code-block:: yaml
- gitfs_remotes:
- - https://github.com/saltstack-formulas/salt-formula.git
- SSH remotes can also be configured using scp-like syntax:
- .. code-block:: yaml
- gitfs_remotes:
- - git@github.com:user/repo.git
- - ssh://user@domain.tld/path/to/repo.git
- Information on how to authenticate to SSH remotes can be found :ref:`here
- <gitfs-authentication>`.
- 3. Restart the master to load the new configuration.
- .. note::
- In a master/minion setup, files from a gitfs remote are cached once by the
- master, so minions do not need direct access to the git repository.
- Multiple Remotes
- ================
- The ``gitfs_remotes`` option accepts an ordered list of git remotes to
- cache and search, in listed order, for requested files.
- A simple scenario illustrates this cascading lookup behavior:
- If the ``gitfs_remotes`` option specifies three remotes:
- .. code-block:: yaml
- gitfs_remotes:
- - git://github.com/example/first.git
- - https://github.com/example/second.git
- - file:///root/third
- And each repository contains some files:
- .. code-block:: yaml
- first.git:
- top.sls
- edit/vim.sls
- edit/vimrc
- nginx/init.sls
- second.git:
- edit/dev_vimrc
- haproxy/init.sls
- third:
- haproxy/haproxy.conf
- edit/dev_vimrc
- Salt will attempt to lookup the requested file from each gitfs remote
- repository in the order in which they are defined in the configuration. The
- :strong:`git://github.com/example/first.git` remote will be searched first.
- If the requested file is found, then it is served and no further searching
- is executed. For example:
- * A request for the file :strong:`salt://haproxy/init.sls` will be served from
- the :strong:`https://github.com/example/second.git` git repo.
- * A request for the file :strong:`salt://haproxy/haproxy.conf` will be served from the
- :strong:`file:///root/third` repo.
- .. note::
- This example is purposefully contrived to illustrate the behavior of the
- gitfs backend. This example should not be read as a recommended way to lay
- out files and git repos.
- The :strong:`file://` prefix denotes a git repository in a local directory.
- However, it will still use the given :strong:`file://` URL as a remote,
- rather than copying the git repo to the salt cache. This means that any
- refs you want accessible must exist as *local* refs in the specified repo.
- .. warning::
- Salt versions prior to 2014.1.0 are not tolerant of changing the
- order of remotes or modifying the URI of existing remotes. In those
- versions, when modifying remotes it is a good idea to remove the gitfs
- cache directory (``/var/cache/salt/master/gitfs``) before restarting the
- salt-master service.
- .. _gitfs-per-remote-config:
- Per-remote Configuration Parameters
- ===================================
- .. versionadded:: 2014.7.0
- The following master config parameters are global (that is, they apply to all
- configured gitfs remotes):
- * :conf_master:`gitfs_base`
- * :conf_master:`gitfs_root`
- * :conf_master:`gitfs_ssl_verify`
- * :conf_master:`gitfs_mountpoint` (new in 2014.7.0)
- * :conf_master:`gitfs_user` (**pygit2 only**, new in 2014.7.0)
- * :conf_master:`gitfs_password` (**pygit2 only**, new in 2014.7.0)
- * :conf_master:`gitfs_insecure_auth` (**pygit2 only**, new in 2014.7.0)
- * :conf_master:`gitfs_pubkey` (**pygit2 only**, new in 2014.7.0)
- * :conf_master:`gitfs_privkey` (**pygit2 only**, new in 2014.7.0)
- * :conf_master:`gitfs_passphrase` (**pygit2 only**, new in 2014.7.0)
- * :conf_master:`gitfs_refspecs` (new in 2017.7.0)
- * :conf_master:`gitfs_disable_saltenv_mapping` (new in 2018.3.0)
- * :conf_master:`gitfs_ref_types` (new in 2018.3.0)
- * :conf_master:`gitfs_update_interval` (new in 2018.3.0)
- .. note::
- pygit2 only supports disabling SSL verification in versions 0.23.2 and
- newer.
- These parameters can now be overridden on a per-remote basis. This allows for a
- tremendous amount of customization. Here's some example usage:
- .. code-block:: yaml
- gitfs_provider: pygit2
- gitfs_base: develop
- gitfs_remotes:
- - https://foo.com/foo.git
- - https://foo.com/bar.git:
- - root: salt
- - mountpoint: salt://bar
- - base: salt-base
- - ssl_verify: False
- - update_interval: 120
- - https://foo.com/bar.git:
- - name: second_bar_repo
- - root: other/salt
- - mountpoint: salt://other/bar
- - base: salt-base
- - ref_types:
- - branch
- - http://foo.com/baz.git:
- - root: salt/states
- - user: joe
- - password: mysupersecretpassword
- - insecure_auth: True
- - disable_saltenv_mapping: True
- - saltenv:
- - foo:
- - ref: foo
- - http://foo.com/quux.git:
- - all_saltenvs: master
- .. important::
- There are two important distinctions which should be noted for per-remote
- configuration:
- 1. The URL of a remote which has per-remote configuration must be suffixed
- with a colon.
- 2. Per-remote configuration parameters are named like the global versions,
- with the ``gitfs_`` removed from the beginning. The exception being the
- ``name``, ``saltenv``, and ``all_saltenvs`` parameters, which are only
- available to per-remote configurations.
- The ``all_saltenvs`` parameter is new in the 2018.3.0 release.
- In the example configuration above, the following is true:
- 1. The first and fourth gitfs remotes will use the ``develop`` branch/tag as the
- ``base`` environment, while the second and third will use the ``salt-base``
- branch/tag as the ``base`` environment.
- 2. The first remote will serve all files in the repository. The second
- remote will only serve files from the ``salt`` directory (and its
- subdirectories). The third remote will only server files from the
- ``other/salt`` directory (and its subdirectories), while the fourth remote
- will only serve files from the ``salt/states`` directory (and its
- subdirectories).
- 3. The third remote will only serve files from branches, and not from tags or
- SHAs.
- 4. The fourth remote will only have two saltenvs available: ``base`` (pointed
- at ``develop``), and ``foo`` (pointed at ``foo``).
- 5. The first and fourth remotes will have files located under the root of the
- Salt fileserver namespace (``salt://``). The files from the second remote
- will be located under ``salt://bar``, while the files from the third remote
- will be located under ``salt://other/bar``.
- 6. The second and third remotes reference the same repository and unique names
- need to be declared for duplicate gitfs remotes.
- 7. The fourth remote overrides the default behavior of :ref:`not authenticating
- to insecure (non-HTTPS) remotes <gitfs-insecure-auth>`.
- 8. Because ``all_saltenvs`` is configured for the fifth remote, files from the
- branch/tag ``master`` will appear in every fileserver environment.
- .. note::
- The use of ``http://`` (instead of ``https://``) is permitted here
- *only* because authentication is not being used. Otherwise, the
- ``insecure_auth`` parameter must be used (as in the fourth remote) to
- force Salt to authenticate to an ``http://`` remote.
- 9. The first remote will wait 120 seconds between updates instead of 60.
- .. _gitfs-per-saltenv-config:
- Per-Saltenv Configuration Parameters
- ====================================
- .. versionadded:: 2016.11.0
- For more granular control, Salt allows the following three things to be
- overridden for individual saltenvs within a given repo:
- - The :ref:`mountpoint <gitfs-walkthrough-mountpoint>`
- - The :ref:`root <gitfs-walkthrough-root>`
- - The branch/tag to be used for a given saltenv
- Here is an example:
- .. code-block:: yaml
- gitfs_root: salt
- gitfs_saltenv:
- - dev:
- - mountpoint: salt://gitfs-dev
- - ref: develop
- gitfs_remotes:
- - https://foo.com/bar.git:
- - saltenv:
- - staging:
- - ref: qa
- - mountpoint: salt://bar-staging
- - dev:
- - ref: development
- - https://foo.com/baz.git:
- - saltenv:
- - staging:
- - mountpoint: salt://baz-staging
- Given the above configuration, the following is true:
- 1. For all gitfs remotes, files for the ``dev`` saltenv will be located under
- ``salt://gitfs-dev``.
- 2. For the ``dev`` saltenv, files from the first remote will be sourced from
- the ``development`` branch, while files from the second remote will be
- sourced from the ``develop`` branch.
- 3. For the ``staging`` saltenv, files from the first remote will be located
- under ``salt://bar-staging``, while files from the second remote will be
- located under ``salt://baz-staging``.
- 4. For all gitfs remotes, and in all saltenvs, files will be served from the
- ``salt`` directory (and its subdirectories).
- .. _gitfs-custom-refspecs:
- Custom Refspecs
- ===============
- .. versionadded:: 2017.7.0
- GitFS will by default fetch remote branches and tags. However, sometimes it can
- be useful to fetch custom refs (such as those created for `GitHub pull
- requests`__). To change the refspecs GitFS fetches, use the
- :conf_master:`gitfs_refspecs` config option:
- .. __: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally
- .. code-block:: yaml
- gitfs_refspecs:
- - '+refs/heads/*:refs/remotes/origin/*'
- - '+refs/tags/*:refs/tags/*'
- - '+refs/pull/*/head:refs/remotes/origin/pr/*'
- - '+refs/pull/*/merge:refs/remotes/origin/merge/*'
- In the above example, in addition to fetching remote branches and tags,
- GitHub's custom refs for pull requests and merged pull requests will also be
- fetched. These special ``head`` refs represent the head of the branch which is
- requesting to be merged, and the ``merge`` refs represent the result of the
- base branch after the merge.
- .. important::
- When using custom refspecs, the destination of the fetched refs *must* be
- under ``refs/remotes/origin/``, preferably in a subdirectory like in the
- example above. These custom refspecs will map as environment names using
- their relative path underneath ``refs/remotes/origin/``. For example,
- assuming the configuration above, the head branch for pull request 12345
- would map to fileserver environment ``pr/12345`` (slash included).
- Refspecs can be configured on a :ref:`per-remote basis
- <gitfs-per-remote-config>`. For example, the below configuration would only
- alter the default refspecs for the *second* GitFS remote. The first remote
- would only fetch branches and tags (the default).
- .. code-block:: yaml
- gitfs_remotes:
- - https://domain.tld/foo.git
- - https://domain.tld/bar.git:
- - refspecs:
- - '+refs/heads/*:refs/remotes/origin/*'
- - '+refs/tags/*:refs/tags/*'
- - '+refs/pull/*/head:refs/remotes/origin/pr/*'
- - '+refs/pull/*/merge:refs/remotes/origin/merge/*'
- .. _gitfs-global-remotes:
- Global Remotes
- ==============
- .. versionadded:: 2018.3.0 for all_saltenvs, 3001 for fallback
- The ``all_saltenvs`` per-remote configuration parameter overrides the logic
- Salt uses to map branches/tags to fileserver environments (i.e. saltenvs). This
- allows a single branch/tag to appear in *all* GitFS saltenvs.
- .. note::
- ``all_saltenvs`` only works *within* GitFS. That is, files in a branch
- configured using ``all_saltenvs`` will *not* show up in a fileserver
- environment defined via some other fileserver backend (e.g.
- :conf_master:`file_roots`).
- The ``fallback`` global or per-remote configuration can also be used.
- This is very useful in particular when working with :ref:`salt formulas
- <conventions-formula>`. Prior to the addition of this feature, it was necessary
- to push a branch/tag to the remote repo for each saltenv in which that formula
- was to be used. If the formula needed to be updated, this update would need to
- be reflected in all of the other branches/tags. This is both inconvenient and
- not scalable.
- With ``all_saltenvs``, it is now possible to define your formula once, in a
- single branch.
- .. code-block:: yaml
- gitfs_remotes:
- - http://foo.com/quux.git:
- - all_saltenvs: anything
- If you want to also test working branches of the formula repository, use
- ``fallback``:
- .. code-block:: yaml
- gitfs_remotes:
- - http://foo.com/quux.git:
- - fallback: anything
- .. _gitfs-update-intervals:
- Update Intervals
- ================
- Prior to the 2018.3.0 release, GitFS would update its fileserver backends as part
- of a dedicated "maintenance" process, in which various routine maintenance
- tasks were performed. This tied the update interval to the
- :conf_master:`loop_interval` config option, and also forced all fileservers to
- update at the same interval.
- Now it is possible to make GitFS update at its own interval, using
- :conf_master:`gitfs_update_interval`:
- .. code-block:: yaml
- gitfs_update_interval: 180
- gitfs_remotes:
- - https://foo.com/foo.git
- - https://foo.com/bar.git:
- - update_interval: 120
- Using the above configuration, the first remote would update every three
- minutes, while the second remote would update every two minutes.
- Configuration Order of Precedence
- =================================
- The order of precedence for GitFS configuration is as follows (each level
- overrides all levels below it):
- 1. Per-saltenv configuration (defined under a per-remote ``saltenv``
- param)
- .. code-block:: yaml
- gitfs_remotes:
- - https://foo.com/bar.git:
- - saltenv:
- - dev:
- - mountpoint: salt://bar
- 2. Global per-saltenv configuration (defined in :conf_master:`gitfs_saltenv`)
- .. code-block:: yaml
- gitfs_saltenv:
- - dev:
- - mountpoint: salt://bar
- 3. Per-remote configuration parameter
- .. code-block:: yaml
- gitfs_remotes:
- - https://foo.com/bar.git:
- - mountpoint: salt://bar
- 4. Global configuration parameter
- .. code-block:: yaml
- gitfs_mountpoint: salt://bar
- .. note::
- The one exception to the above is when :ref:`all_saltenvs
- <gitfs-global-remotes>` is used. This value overrides all logic for mapping
- branches/tags to fileserver environments. So, even if
- :conf_master:`gitfs_saltenv` is used to globally override the mapping for a
- given saltenv, :ref:`all_saltenvs <gitfs-global-remotes>` would take
- precedence for any remote which uses it.
- It's important to note however that any ``root`` and ``mountpoint`` values
- configured in :conf_master:`gitfs_saltenv` (or :ref:`per-saltenv
- configuration <gitfs-per-saltenv-config>`) would be unaffected by this.
- .. _gitfs-walkthrough-root:
- Serving from a Subdirectory
- ===========================
- The :conf_master:`gitfs_root` parameter allows files to be served from a
- subdirectory within the repository. This allows for only part of a repository
- to be exposed to the Salt fileserver.
- Assume the below layout:
- .. code-block:: text
- .gitignore
- README.txt
- foo/
- foo/bar/
- foo/bar/one.txt
- foo/bar/two.txt
- foo/bar/three.txt
- foo/baz/
- foo/baz/top.sls
- foo/baz/edit/vim.sls
- foo/baz/edit/vimrc
- foo/baz/nginx/init.sls
- The below configuration would serve only the files under ``foo/baz``, ignoring
- the other files in the repository:
- .. code-block:: yaml
- gitfs_remotes:
- - git://mydomain.com/stuff.git
- gitfs_root: foo/baz
- The root can also be configured on a :ref:`per-remote basis
- <gitfs-per-remote-config>`.
- .. _gitfs-walkthrough-mountpoint:
- Mountpoints
- ===========
- .. versionadded:: 2014.7.0
- The :conf_master:`gitfs_mountpoint` parameter will prepend the specified path
- to the files served from gitfs. This allows an existing repository to be used,
- rather than needing to reorganize a repository or design it around the layout
- of the Salt fileserver.
- Before the addition of this feature, if a file being served up via gitfs was
- deeply nested within the root directory (for example,
- ``salt://webapps/foo/files/foo.conf``, it would be necessary to ensure that the
- file was properly located in the remote repository, and that all of the
- parent directories were present (for example, the directories
- ``webapps/foo/files/`` would need to exist at the root of the repository).
- The below example would allow for a file ``foo.conf`` at the root of the
- repository to be served up from the Salt fileserver path
- ``salt://webapps/foo/files/foo.conf``.
- .. code-block:: yaml
- gitfs_remotes:
- - https://mydomain.com/stuff.git
- gitfs_mountpoint: salt://webapps/foo/files
- Mountpoints can also be configured on a :ref:`per-remote basis
- <gitfs-per-remote-config>`.
- Using gitfs in Masterless Mode
- ==============================
- Since 2014.7.0, gitfs can be used in masterless mode. To do so, simply add the
- gitfs configuration parameters (and set :conf_master:`fileserver_backend`) in
- the _minion_ config file instead of the master config file.
- Using gitfs Alongside Other Backends
- ====================================
- Sometimes it may make sense to use multiple backends; for instance, if ``sls``
- files are stored in git but larger files are stored directly on the master.
- The cascading lookup logic used for multiple remotes is also used with multiple
- backends. If the :conf_master:`fileserver_backend` option contains multiple
- backends:
- .. code-block:: yaml
- fileserver_backend:
- - roots
- - git
- Then the ``roots`` backend (the default backend of files in ``/srv/salt``) will
- be searched first for the requested file; then, if it is not found on the
- master, each configured git remote will be searched.
- .. note::
- This can be used together with `file_roots` accepting `__env__` as a catch-all
- environment, since 2018.3.5 and 2019.2.1:
- .. code-block:: yaml
- file_roots:
- base:
- - /srv/salt
- __env__:
- - /srv/salt
- Branches, Environments, and Top Files
- =====================================
- When using the GitFS backend, branches, and tags will be mapped to environments
- using the branch/tag name as an identifier.
- There is one exception to this rule: the ``master`` branch is implicitly mapped
- to the ``base`` environment.
- So, for a typical ``base``, ``qa``, ``dev`` setup, the following branches could
- be used:
- .. code-block:: yaml
- master
- qa
- dev
- ``top.sls`` files from different branches will be merged into one at runtime.
- Since this can lead to overly complex configurations, the recommended setup is
- to have a separate repository, containing only the ``top.sls`` file with just
- one single ``master`` branch.
- To map a branch other than ``master`` as the ``base`` environment, use the
- :conf_master:`gitfs_base` parameter.
- .. code-block:: yaml
- gitfs_base: salt-base
- The base can also be configured on a :ref:`per-remote basis
- <gitfs-per-remote-config>`.
- .. _gitfs-whitelist-blacklist:
- Environment Whitelist/Blacklist
- ===============================
- .. versionadded:: 2014.7.0
- The :conf_master:`gitfs_saltenv_whitelist` and
- :conf_master:`gitfs_saltenv_blacklist` parameters allow for greater control
- over which branches/tags are exposed as fileserver environments. Exact matches,
- globs, and regular expressions are supported, and are evaluated in that order.
- If using a regular expression, ``^`` and ``$`` must be omitted, and the
- expression must match the entire branch/tag.
- .. code-block:: yaml
- gitfs_saltenv_whitelist:
- - base
- - v1.*
- - 'mybranch\d+'
- .. note::
- ``v1.*``, in this example, will match as both a glob and a regular
- expression (though it will have been matched as a glob, since globs are
- evaluated before regular expressions).
- The behavior of the blacklist/whitelist will differ depending on which
- combination of the two options is used:
- * If only :conf_master:`gitfs_saltenv_whitelist` is used, then **only**
- branches/tags which match the whitelist will be available as environments
- * If only :conf_master:`gitfs_saltenv_blacklist` is used, then the
- branches/tags which match the blacklist will **not** be available as
- environments
- * If both are used, then the branches/tags which match the whitelist, but do
- **not** match the blacklist, will be available as environments.
- .. _gitfs-authentication:
- Authentication
- ==============
- pygit2
- ------
- .. versionadded:: 2014.7.0
- Both HTTPS and SSH authentication are supported as of version 0.20.3, which is
- the earliest version of pygit2_ supported by Salt for gitfs.
- .. note::
- The examples below make use of per-remote configuration parameters, a
- feature new to Salt 2014.7.0. More information on these can be found
- :ref:`here <gitfs-per-remote-config>`.
- HTTPS
- ~~~~~
- For HTTPS repositories which require authentication, the username and password
- can be provided like so:
- .. code-block:: yaml
- gitfs_remotes:
- - https://domain.tld/myrepo.git:
- - user: git
- - password: mypassword
- .. _gitfs-insecure-auth:
- If the repository is served over HTTP instead of HTTPS, then Salt will by
- default refuse to authenticate to it. This behavior can be overridden by adding
- an ``insecure_auth`` parameter:
- .. code-block:: yaml
- gitfs_remotes:
- - http://domain.tld/insecure_repo.git:
- - user: git
- - password: mypassword
- - insecure_auth: True
- .. _pygit2-authentication-ssh:
- SSH
- ~~~
- SSH repositories can be configured using the ``ssh://`` protocol designation,
- or using scp-like syntax. So, the following two configurations are equivalent:
- * ``ssh://git@github.com/user/repo.git``
- * ``git@github.com:user/repo.git``
- Both :conf_master:`gitfs_pubkey` and :conf_master:`gitfs_privkey` (or their
- :ref:`per-remote counterparts <gitfs-per-remote-config>`) must be configured in
- order to authenticate to SSH-based repos. If the private key is protected with
- a passphrase, it can be configured using :conf_master:`gitfs_passphrase` (or
- simply ``passphrase`` if being configured :ref:`per-remote
- <gitfs-per-remote-config>`). For example:
- .. code-block:: yaml
- gitfs_remotes:
- - git@github.com:user/repo.git:
- - pubkey: /root/.ssh/id_rsa.pub
- - privkey: /root/.ssh/id_rsa
- - passphrase: myawesomepassphrase
- Finally, the SSH host key must be :ref:`added to the known_hosts file
- <gitfs-ssh-fingerprint>`.
- .. note::
- There is a known issue with public-key SSH authentication to Microsoft
- Visual Studio (VSTS) with pygit2. This is due to a bug or lack of support
- for VSTS in older libssh2 releases. Known working releases include libssh2
- 1.7.0 and later, and known incompatible releases include 1.5.0 and older.
- At the time of this writing, 1.6.0 has not been tested.
- Since upgrading libssh2 would require rebuilding many other packages (curl,
- etc.), followed by a rebuild of libgit2 and a reinstall of pygit2, an
- easier workaround for systems with older libssh2 is to use GitPython with a
- passphraseless key for authentication.
- GitPython
- ---------
- HTTPS
- ~~~~~
- For HTTPS repositories which require authentication, the username and password
- can be configured in one of two ways. The first way is to include them in the
- URL using the format ``https://<user>:<password>@<url>``, like so:
- .. code-block:: yaml
- gitfs_remotes:
- - https://git:mypassword@domain.tld/myrepo.git
- The other way would be to configure the authentication in ``~/.netrc``:
- .. code-block:: text
- machine domain.tld
- login git
- password mypassword
- If the repository is served over HTTP instead of HTTPS, then Salt will by
- default refuse to authenticate to it. This behavior can be overridden by adding
- an ``insecure_auth`` parameter:
- .. code-block:: yaml
- gitfs_remotes:
- - http://git:mypassword@domain.tld/insecure_repo.git:
- - insecure_auth: True
- SSH
- ~~~
- Only passphrase-less SSH public key authentication is supported using
- GitPython. **The auth parameters (pubkey, privkey, etc.) shown in the pygit2
- authentication examples above do not work with GitPython.**
- .. code-block:: yaml
- gitfs_remotes:
- - ssh://git@github.com/example/salt-states.git
- Since GitPython_ wraps the git CLI, the private key must be located in
- ``~/.ssh/id_rsa`` for the user under which the Master is running, and should
- have permissions of ``0600``. Also, in the absence of a user in the repo URL,
- GitPython_ will (just as SSH does) attempt to login as the current user (in
- other words, the user under which the Master is running, usually ``root``).
- If a key needs to be used, then ``~/.ssh/config`` can be configured to use
- the desired key. Information on how to do this can be found by viewing the
- manpage for ``ssh_config``. Here's an example entry which can be added to the
- ``~/.ssh/config`` to use an alternate key for gitfs:
- .. code-block:: text
- Host github.com
- IdentityFile /root/.ssh/id_rsa_gitfs
- The ``Host`` parameter should be a hostname (or hostname glob) that matches the
- domain name of the git repository.
- It is also necessary to :ref:`add the SSH host key to the known_hosts file
- <gitfs-ssh-fingerprint>`. The exception to this would be if strict host key
- checking is disabled, which can be done by adding ``StrictHostKeyChecking no``
- to the entry in ``~/.ssh/config``
- .. code-block:: text
- Host github.com
- IdentityFile /root/.ssh/id_rsa_gitfs
- StrictHostKeyChecking no
- However, this is generally regarded as insecure, and is not recommended.
- .. _gitfs-ssh-fingerprint:
- Adding the SSH Host Key to the known_hosts File
- -----------------------------------------------
- To use SSH authentication, it is necessary to have the remote repository's SSH
- host key in the ``~/.ssh/known_hosts`` file. If the master is also a minion,
- this can be done using the :mod:`ssh.set_known_host
- <salt.modules.ssh.set_known_host>` function:
- .. code-block:: console
- # salt mymaster ssh.set_known_host user=root hostname=github.com
- mymaster:
- ----------
- new:
- ----------
- enc:
- ssh-rsa
- fingerprint:
- 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
- hostname:
- |1|OiefWWqOD4kwO3BhoIGa0loR5AA=|BIXVtmcTbPER+68HvXmceodDcfI=
- key:
- AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
- old:
- None
- status:
- updated
- If not, then the easiest way to add the key is to su to the user (usually
- ``root``) under which the salt-master runs and attempt to login to the
- server via SSH:
- .. code-block:: text
- $ su -
- Password:
- # ssh github.com
- The authenticity of host 'github.com (192.30.252.128)' can't be established.
- RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
- Are you sure you want to continue connecting (yes/no)? yes
- Warning: Permanently added 'github.com,192.30.252.128' (RSA) to the list of known hosts.
- Permission denied (publickey).
- It doesn't matter if the login was successful, as answering ``yes`` will write
- the fingerprint to the known_hosts file.
- Verifying the Fingerprint
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- To verify that the correct fingerprint was added, it is a good idea to look it
- up. One way to do this is to use ``nmap``:
- .. code-block:: console
- $ nmap -p 22 github.com --script ssh-hostkey
- Starting Nmap 5.51 ( http://nmap.org ) at 2014-08-18 17:47 CDT
- Nmap scan report for github.com (192.30.252.129)
- Host is up (0.17s latency).
- Not shown: 996 filtered ports
- PORT STATE SERVICE
- 22/tcp open ssh
- | ssh-hostkey: 1024 ad:1c:08:a4:40:e3:6f:9c:f5:66:26:5d:4b:33:5d:8c (DSA)
- |_2048 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 (RSA)
- 80/tcp open http
- 443/tcp open https
- 9418/tcp open git
- Nmap done: 1 IP address (1 host up) scanned in 28.78 seconds
- Another way is to check one's own ``known_hosts`` file, using this one-liner:
- .. code-block:: bash
- $ ssh-keygen -l -f /dev/stdin <<<`ssh-keyscan github.com 2>/dev/null` | awk '{print $2}'
- 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
- .. warning::
- AWS tracks usage of nmap and may flag it as abuse. On AWS hosts, the
- ``ssh-keygen`` method is recommended for host key verification.
- .. note::
- As of `OpenSSH 6.8`_ the SSH fingerprint is now shown as a base64-encoded
- SHA256 checksum of the host key. So, instead of the fingerprint looking
- like ``16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48``, it would look
- like ``SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8``.
- .. _`OpenSSH 6.8`: http://www.openssh.com/txt/release-6.8
- Refreshing gitfs Upon Push
- ==========================
- By default, Salt updates the remote fileserver backends every 60 seconds.
- However, if it is desirable to refresh quicker than that, the :ref:`Reactor
- System <reactor>` can be used to signal the master to update the fileserver on
- each push, provided that the git server is also a Salt minion. There are three
- steps to this process:
- 1. On the master, create a file **/srv/reactor/update_fileserver.sls**, with
- the following contents:
- .. code-block:: yaml
- update_fileserver:
- runner.fileserver.update
- 2. Add the following reactor configuration to the master config file:
- .. code-block:: yaml
- reactor:
- - 'salt/fileserver/gitfs/update':
- - /srv/reactor/update_fileserver.sls
- 3. On the git server, add a `post-receive hook`_
- a. If the user executing `git push` is the same as the minion user, use the following hook:
- .. code-block:: bash
- #!/usr/bin/env sh
- salt-call event.fire_master update salt/fileserver/gitfs/update
- b. To enable other git users to run the hook after a `push`, use sudo in the hook script:
- .. code-block:: bash
- #!/usr/bin/env sh
- sudo -u root salt-call event.fire_master update salt/fileserver/gitfs/update
- 4. If using sudo in the git hook (above), the policy must be changed to permit
- all users to fire the event. Add the following policy to the sudoers file
- on the git server.
- .. code-block:: console
- Cmnd_Alias SALT_GIT_HOOK = /bin/salt-call event.fire_master update salt/fileserver/gitfs/update
- Defaults!SALT_GIT_HOOK !requiretty
- ALL ALL=(root) NOPASSWD: SALT_GIT_HOOK
- The ``update`` argument right after :mod:`event.fire_master
- <salt.modules.event.fire_master>` in this example can really be anything, as it
- represents the data being passed in the event, and the passed data is ignored
- by this reactor.
- Similarly, the tag name ``salt/fileserver/gitfs/update`` can be replaced by
- anything, so long as the usage is consistent.
- The ``root`` user name in the hook script and sudo policy should be changed to
- match the user under which the minion is running.
- .. _`post-receive hook`: https://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#Server-Side-Hooks
- .. _git-as-ext_pillar:
- Using Git as an External Pillar Source
- ======================================
- The git external pillar (a.k.a. git_pillar) has been rewritten for the 2015.8.0
- release. This rewrite brings with it pygit2_ support (allowing for access to
- authenticated repositories), as well as more granular support for per-remote
- configuration. This configuration schema is detailed :ref:`here
- <git-pillar-configuration>`.
- .. _faq-gitfs-bug:
- Why aren't my custom modules/states/etc. syncing to my Minions?
- ===============================================================
- In versions 0.16.3 and older, when using the :mod:`git fileserver backend
- <salt.fileserver.gitfs>`, certain versions of GitPython may generate errors
- when fetching, which Salt fails to catch. While not fatal to the fetch process,
- these interrupt the fileserver update that takes place before custom types are
- synced, and thus interrupt the sync itself. Try disabling the git fileserver
- backend in the master config, restarting the master, and attempting the sync
- again.
- This issue is worked around in Salt 0.16.4 and newer.
|