123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179 |
- .. _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.github.com/
- .. _libssh2: http://www.libssh2.org/
- .. _python-cffi: https://pypi.python.org/pypi/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::
- 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/articles/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, neon 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.
- Those are 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:: bash
- # 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:: bash
- $ 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:: bash
- 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`: http://www.git-scm.com/book/en/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.
|