gitfs.rst 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184
  1. .. _tutorial-gitfs:
  2. ==================================
  3. Git Fileserver Backend Walkthrough
  4. ==================================
  5. .. note::
  6. This walkthrough assumes basic knowledge of Salt. To get up to speed, check
  7. out the :ref:`Salt Walkthrough <tutorial-salt-walk-through>`.
  8. The gitfs backend allows Salt to serve files from git repositories. It can be
  9. enabled by adding ``git`` to the :conf_master:`fileserver_backend` list, and
  10. configuring one or more repositories in :conf_master:`gitfs_remotes`.
  11. Branches and tags become Salt fileserver environments.
  12. .. note::
  13. Branching and tagging can result in a lot of potentially-conflicting
  14. :ref:`top files <states-top>`, for this reason it may be useful to set
  15. :conf_minion:`top_file_merging_strategy` to ``same`` in the minions' config
  16. files if the top files are being managed in a GitFS repo.
  17. .. _gitfs-dependencies:
  18. Installing Dependencies
  19. =======================
  20. Both pygit2_ and GitPython_ are supported Python interfaces to git. If
  21. compatible versions of both are installed, pygit2_ will be preferred. In these
  22. cases, GitPython_ can be forced using the :conf_master:`gitfs_provider`
  23. parameter in the master config file.
  24. .. note::
  25. It is recommended to always run the most recent version of any the below
  26. dependencies. Certain features of GitFS may not be available without
  27. the most recent version of the chosen library.
  28. .. _pygit2: https://github.com/libgit2/pygit2
  29. .. _GitPython: https://github.com/gitpython-developers/GitPython
  30. pygit2
  31. ------
  32. The minimum supported version of pygit2_ is 0.20.3. Availability for this
  33. version of pygit2_ is still limited, though the SaltStack team is working to
  34. get compatible versions available for as many platforms as possible.
  35. For the Fedora/EPEL versions which have a new enough version packaged, the
  36. following command would be used to install pygit2_:
  37. .. code-block:: bash
  38. # yum install python-pygit2
  39. Provided a valid version is packaged for Debian/Ubuntu (which is not currently
  40. the case), the package name would be the same, and the following command would
  41. be used to install it:
  42. .. code-block:: bash
  43. # apt-get install python-pygit2
  44. If pygit2_ is not packaged for the platform on which the Master is running, the
  45. pygit2_ website has installation instructions
  46. `here <pygit2-install-instructions>`_. Keep in mind however that
  47. following these instructions will install libgit2_ and pygit2_ without system
  48. packages. Additionally, keep in mind that :ref:`SSH authentication in pygit2
  49. <pygit2-authentication-ssh>` requires libssh2_ (*not* libssh) development
  50. libraries to be present before libgit2_ is built. On some Debian-based distros
  51. ``pkg-config`` is also required to link libgit2_ with libssh2.
  52. .. note::
  53. If you are receiving the error "Unsupported URL Protocol" in the Salt Master
  54. log when making a connection using SSH, review the libssh2 details listed
  55. above.
  56. Additionally, version 0.21.0 of pygit2 introduced a dependency on python-cffi_,
  57. which in turn depends on newer releases of libffi_. Upgrading libffi_ is not
  58. advisable as several other applications depend on it, so on older LTS linux
  59. releases pygit2_ 0.20.3 and libgit2_ 0.20.0 is the recommended combination.
  60. .. warning::
  61. pygit2_ is actively developed and `frequently makes
  62. non-backwards-compatible API changes <pygit2-version-policy>`_, even in
  63. minor releases. It is not uncommon for pygit2_ upgrades to result in errors
  64. in Salt. Please take care when upgrading pygit2_, and pay close attention
  65. to the changelog_, keeping an eye out for API changes. Errors can be
  66. reported on the `SaltStack issue tracker <saltstack-issue-tracker>`_.
  67. .. _pygit2-version-policy: http://www.pygit2.org/install.html#version-numbers
  68. .. _changelog: https://github.com/libgit2/pygit2#changelog
  69. .. _saltstack-issue-tracker: https://github.com/saltstack/salt/issues
  70. .. _pygit2-install-instructions: http://www.pygit2.org/install.html
  71. .. _libgit2: https://libgit2.github.com/
  72. .. _libssh2: http://www.libssh2.org/
  73. .. _python-cffi: https://pypi.python.org/pypi/cffi
  74. .. _libffi: http://sourceware.org/libffi/
  75. RedHat Pygit2 Issues
  76. ~~~~~~~~~~~~~~~~~~~~
  77. The release of RedHat/CentOS 7.3 upgraded both ``python-cffi`` and
  78. ``http-parser``, both of which are dependencies for pygit2_/libgit2_. Both
  79. ``pygit2`` and ``libgit2`` packages (which are from the EPEL repository) should
  80. be upgraded to the most recent versions, at least to ``0.24.2``.
  81. The below errors will show up in the master log if an incompatible
  82. ``python-pygit2`` package is installed:
  83. .. code-block:: text
  84. 2017-02-10 09:07:34,892 [salt.utils.gitfs ][ERROR ][11211] Import pygit2 failed: CompileError: command 'gcc' failed with exit status 1
  85. 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?
  86. 2017-02-10 09:07:34,907 [salt.utils.gitfs ][CRITICAL][11211] No suitable gitfs provider module is installed.
  87. 2017-02-10 09:07:34,912 [salt.master ][CRITICAL][11211] Master failed pre flight checks, exiting
  88. The below errors will show up in the master log if an incompatible ``libgit2``
  89. package is installed:
  90. .. code-block:: text
  91. 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
  92. A restart of the ``salt-master`` daemon and gitfs cache directory clean up may
  93. be required to allow http(s) repositories to continue to be fetched.
  94. GitPython
  95. ---------
  96. GitPython_ 0.3.0 or newer is required to use GitPython for gitfs. For
  97. RHEL-based Linux distros, a compatible version is available in EPEL, and can be
  98. easily installed on the master using yum:
  99. .. code-block:: bash
  100. # yum install GitPython
  101. Ubuntu 14.04 LTS and Debian Wheezy (7.x) also have a compatible version packaged:
  102. .. code-block:: bash
  103. # apt-get install python-git
  104. GitPython_ requires the ``git`` CLI utility to work. If installed from a system
  105. package, then git should already be installed, but if installed via pip_ then
  106. it may still be necessary to install git separately. For MacOS users,
  107. GitPython_ comes bundled in with the Salt installer, but git must still be
  108. installed for it to work properly. Git can be installed in several ways,
  109. including by installing XCode_.
  110. .. _pip: http://www.pip-installer.org/
  111. .. _XCode: https://developer.apple.com/xcode/
  112. .. warning::
  113. GitPython advises against the use of its library for long-running processes
  114. (such as a salt-master or salt-minion). Please see their warning on potential
  115. leaks of system resources:
  116. https://github.com/gitpython-developers/GitPython#leakage-of-system-resources.
  117. .. warning::
  118. Keep in mind that if GitPython has been previously installed on the master
  119. using pip (even if it was subsequently uninstalled), then it may still
  120. exist in the build cache (typically ``/tmp/pip-build-root/GitPython``) if
  121. the cache is not cleared after installation. The package in the build cache
  122. will override any requirement specifiers, so if you try upgrading to
  123. version 0.3.2.RC1 by running ``pip install 'GitPython==0.3.2.RC1'`` then it
  124. will ignore this and simply install the version from the cache directory.
  125. Therefore, it may be necessary to delete the GitPython directory from the
  126. build cache in order to ensure that the specified version is installed.
  127. .. warning::
  128. GitPython_ 2.0.9 and newer is not compatible with Python 2.6. If installing
  129. GitPython_ using pip on a machine running Python 2.6, make sure that a
  130. version earlier than 2.0.9 is installed. This can be done on the CLI by
  131. running ``pip install 'GitPython<2.0.9'``, or in a :py:func:`pip.installed
  132. <salt.states.pip_state.installed>` state using the following SLS:
  133. .. code-block:: yaml
  134. GitPython:
  135. pip.installed:
  136. - name: 'GitPython < 2.0.9'
  137. Simple Configuration
  138. ====================
  139. To use the gitfs backend, only two configuration changes are required on the
  140. master:
  141. 1. Include ``gitfs`` in the :conf_master:`fileserver_backend` list in the
  142. master config file:
  143. .. code-block:: yaml
  144. fileserver_backend:
  145. - gitfs
  146. .. note::
  147. ``git`` also works here. Prior to the 2018.3.0 release, *only* ``git``
  148. would work.
  149. 2. Specify one or more ``git://``, ``https://``, ``file://``, or ``ssh://``
  150. URLs in :conf_master:`gitfs_remotes` to configure which repositories to
  151. cache and search for requested files:
  152. .. code-block:: yaml
  153. gitfs_remotes:
  154. - https://github.com/saltstack-formulas/salt-formula.git
  155. SSH remotes can also be configured using scp-like syntax:
  156. .. code-block:: yaml
  157. gitfs_remotes:
  158. - git@github.com:user/repo.git
  159. - ssh://user@domain.tld/path/to/repo.git
  160. Information on how to authenticate to SSH remotes can be found :ref:`here
  161. <gitfs-authentication>`.
  162. 3. Restart the master to load the new configuration.
  163. .. note::
  164. In a master/minion setup, files from a gitfs remote are cached once by the
  165. master, so minions do not need direct access to the git repository.
  166. Multiple Remotes
  167. ================
  168. The ``gitfs_remotes`` option accepts an ordered list of git remotes to
  169. cache and search, in listed order, for requested files.
  170. A simple scenario illustrates this cascading lookup behavior:
  171. If the ``gitfs_remotes`` option specifies three remotes:
  172. .. code-block:: yaml
  173. gitfs_remotes:
  174. - git://github.com/example/first.git
  175. - https://github.com/example/second.git
  176. - file:///root/third
  177. And each repository contains some files:
  178. .. code-block:: yaml
  179. first.git:
  180. top.sls
  181. edit/vim.sls
  182. edit/vimrc
  183. nginx/init.sls
  184. second.git:
  185. edit/dev_vimrc
  186. haproxy/init.sls
  187. third:
  188. haproxy/haproxy.conf
  189. edit/dev_vimrc
  190. Salt will attempt to lookup the requested file from each gitfs remote
  191. repository in the order in which they are defined in the configuration. The
  192. :strong:`git://github.com/example/first.git` remote will be searched first.
  193. If the requested file is found, then it is served and no further searching
  194. is executed. For example:
  195. * A request for the file :strong:`salt://haproxy/init.sls` will be served from
  196. the :strong:`https://github.com/example/second.git` git repo.
  197. * A request for the file :strong:`salt://haproxy/haproxy.conf` will be served from the
  198. :strong:`file:///root/third` repo.
  199. .. note::
  200. This example is purposefully contrived to illustrate the behavior of the
  201. gitfs backend. This example should not be read as a recommended way to lay
  202. out files and git repos.
  203. The :strong:`file://` prefix denotes a git repository in a local directory.
  204. However, it will still use the given :strong:`file://` URL as a remote,
  205. rather than copying the git repo to the salt cache. This means that any
  206. refs you want accessible must exist as *local* refs in the specified repo.
  207. .. warning::
  208. Salt versions prior to 2014.1.0 are not tolerant of changing the
  209. order of remotes or modifying the URI of existing remotes. In those
  210. versions, when modifying remotes it is a good idea to remove the gitfs
  211. cache directory (``/var/cache/salt/master/gitfs``) before restarting the
  212. salt-master service.
  213. .. _gitfs-per-remote-config:
  214. Per-remote Configuration Parameters
  215. ===================================
  216. .. versionadded:: 2014.7.0
  217. The following master config parameters are global (that is, they apply to all
  218. configured gitfs remotes):
  219. * :conf_master:`gitfs_base`
  220. * :conf_master:`gitfs_root`
  221. * :conf_master:`gitfs_ssl_verify`
  222. * :conf_master:`gitfs_mountpoint` (new in 2014.7.0)
  223. * :conf_master:`gitfs_user` (**pygit2 only**, new in 2014.7.0)
  224. * :conf_master:`gitfs_password` (**pygit2 only**, new in 2014.7.0)
  225. * :conf_master:`gitfs_insecure_auth` (**pygit2 only**, new in 2014.7.0)
  226. * :conf_master:`gitfs_pubkey` (**pygit2 only**, new in 2014.7.0)
  227. * :conf_master:`gitfs_privkey` (**pygit2 only**, new in 2014.7.0)
  228. * :conf_master:`gitfs_passphrase` (**pygit2 only**, new in 2014.7.0)
  229. * :conf_master:`gitfs_refspecs` (new in 2017.7.0)
  230. * :conf_master:`gitfs_disable_saltenv_mapping` (new in 2018.3.0)
  231. * :conf_master:`gitfs_ref_types` (new in 2018.3.0)
  232. * :conf_master:`gitfs_update_interval` (new in 2018.3.0)
  233. .. note::
  234. pygit2 only supports disabling SSL verification in versions 0.23.2 and
  235. newer.
  236. These parameters can now be overridden on a per-remote basis. This allows for a
  237. tremendous amount of customization. Here's some example usage:
  238. .. code-block:: yaml
  239. gitfs_provider: pygit2
  240. gitfs_base: develop
  241. gitfs_remotes:
  242. - https://foo.com/foo.git
  243. - https://foo.com/bar.git:
  244. - root: salt
  245. - mountpoint: salt://bar
  246. - base: salt-base
  247. - ssl_verify: False
  248. - update_interval: 120
  249. - https://foo.com/bar.git:
  250. - name: second_bar_repo
  251. - root: other/salt
  252. - mountpoint: salt://other/bar
  253. - base: salt-base
  254. - ref_types:
  255. - branch
  256. - http://foo.com/baz.git:
  257. - root: salt/states
  258. - user: joe
  259. - password: mysupersecretpassword
  260. - insecure_auth: True
  261. - disable_saltenv_mapping: True
  262. - saltenv:
  263. - foo:
  264. - ref: foo
  265. - http://foo.com/quux.git:
  266. - all_saltenvs: master
  267. .. important::
  268. There are two important distinctions which should be noted for per-remote
  269. configuration:
  270. 1. The URL of a remote which has per-remote configuration must be suffixed
  271. with a colon.
  272. 2. Per-remote configuration parameters are named like the global versions,
  273. with the ``gitfs_`` removed from the beginning. The exception being the
  274. ``name``, ``saltenv``, and ``all_saltenvs`` parameters, which are only
  275. available to per-remote configurations.
  276. The ``all_saltenvs`` parameter is new in the 2018.3.0 release.
  277. In the example configuration above, the following is true:
  278. 1. The first and fourth gitfs remotes will use the ``develop`` branch/tag as the
  279. ``base`` environment, while the second and third will use the ``salt-base``
  280. branch/tag as the ``base`` environment.
  281. 2. The first remote will serve all files in the repository. The second
  282. remote will only serve files from the ``salt`` directory (and its
  283. subdirectories). The third remote will only server files from the
  284. ``other/salt`` directory (and its subdirectories), while the fourth remote
  285. will only serve files from the ``salt/states`` directory (and its
  286. subdirectories).
  287. 3. The third remote will only serve files from branches, and not from tags or
  288. SHAs.
  289. 4. The fourth remote will only have two saltenvs available: ``base`` (pointed
  290. at ``develop``), and ``foo`` (pointed at ``foo``).
  291. 5. The first and fourth remotes will have files located under the root of the
  292. Salt fileserver namespace (``salt://``). The files from the second remote
  293. will be located under ``salt://bar``, while the files from the third remote
  294. will be located under ``salt://other/bar``.
  295. 6. The second and third remotes reference the same repository and unique names
  296. need to be declared for duplicate gitfs remotes.
  297. 7. The fourth remote overrides the default behavior of :ref:`not authenticating
  298. to insecure (non-HTTPS) remotes <gitfs-insecure-auth>`.
  299. 8. Because ``all_saltenvs`` is configured for the fifth remote, files from the
  300. branch/tag ``master`` will appear in every fileserver environment.
  301. .. note::
  302. The use of ``http://`` (instead of ``https://``) is permitted here
  303. *only* because authentication is not being used. Otherwise, the
  304. ``insecure_auth`` parameter must be used (as in the fourth remote) to
  305. force Salt to authenticate to an ``http://`` remote.
  306. 9. The first remote will wait 120 seconds between updates instead of 60.
  307. .. _gitfs-per-saltenv-config:
  308. Per-Saltenv Configuration Parameters
  309. ====================================
  310. .. versionadded:: 2016.11.0
  311. For more granular control, Salt allows the following three things to be
  312. overridden for individual saltenvs within a given repo:
  313. - The :ref:`mountpoint <gitfs-walkthrough-mountpoint>`
  314. - The :ref:`root <gitfs-walkthrough-root>`
  315. - The branch/tag to be used for a given saltenv
  316. Here is an example:
  317. .. code-block:: yaml
  318. gitfs_root: salt
  319. gitfs_saltenv:
  320. - dev:
  321. - mountpoint: salt://gitfs-dev
  322. - ref: develop
  323. gitfs_remotes:
  324. - https://foo.com/bar.git:
  325. - saltenv:
  326. - staging:
  327. - ref: qa
  328. - mountpoint: salt://bar-staging
  329. - dev:
  330. - ref: development
  331. - https://foo.com/baz.git:
  332. - saltenv:
  333. - staging:
  334. - mountpoint: salt://baz-staging
  335. Given the above configuration, the following is true:
  336. 1. For all gitfs remotes, files for the ``dev`` saltenv will be located under
  337. ``salt://gitfs-dev``.
  338. 2. For the ``dev`` saltenv, files from the first remote will be sourced from
  339. the ``development`` branch, while files from the second remote will be
  340. sourced from the ``develop`` branch.
  341. 3. For the ``staging`` saltenv, files from the first remote will be located
  342. under ``salt://bar-staging``, while files from the second remote will be
  343. located under ``salt://baz-staging``.
  344. 4. For all gitfs remotes, and in all saltenvs, files will be served from the
  345. ``salt`` directory (and its subdirectories).
  346. .. _gitfs-custom-refspecs:
  347. Custom Refspecs
  348. ===============
  349. .. versionadded:: 2017.7.0
  350. GitFS will by default fetch remote branches and tags. However, sometimes it can
  351. be useful to fetch custom refs (such as those created for `GitHub pull
  352. requests`__). To change the refspecs GitFS fetches, use the
  353. :conf_master:`gitfs_refspecs` config option:
  354. .. __: https://help.github.com/articles/checking-out-pull-requests-locally/
  355. .. code-block:: yaml
  356. gitfs_refspecs:
  357. - '+refs/heads/*:refs/remotes/origin/*'
  358. - '+refs/tags/*:refs/tags/*'
  359. - '+refs/pull/*/head:refs/remotes/origin/pr/*'
  360. - '+refs/pull/*/merge:refs/remotes/origin/merge/*'
  361. In the above example, in addition to fetching remote branches and tags,
  362. GitHub's custom refs for pull requests and merged pull requests will also be
  363. fetched. These special ``head`` refs represent the head of the branch which is
  364. requesting to be merged, and the ``merge`` refs represent the result of the
  365. base branch after the merge.
  366. .. important::
  367. When using custom refspecs, the destination of the fetched refs *must* be
  368. under ``refs/remotes/origin/``, preferably in a subdirectory like in the
  369. example above. These custom refspecs will map as environment names using
  370. their relative path underneath ``refs/remotes/origin/``. For example,
  371. assuming the configuration above, the head branch for pull request 12345
  372. would map to fileserver environment ``pr/12345`` (slash included).
  373. Refspecs can be configured on a :ref:`per-remote basis
  374. <gitfs-per-remote-config>`. For example, the below configuration would only
  375. alter the default refspecs for the *second* GitFS remote. The first remote
  376. would only fetch branches and tags (the default).
  377. .. code-block:: yaml
  378. gitfs_remotes:
  379. - https://domain.tld/foo.git
  380. - https://domain.tld/bar.git:
  381. - refspecs:
  382. - '+refs/heads/*:refs/remotes/origin/*'
  383. - '+refs/tags/*:refs/tags/*'
  384. - '+refs/pull/*/head:refs/remotes/origin/pr/*'
  385. - '+refs/pull/*/merge:refs/remotes/origin/merge/*'
  386. .. _gitfs-global-remotes:
  387. Global Remotes
  388. ==============
  389. .. versionadded:: 2018.3.0 for all_saltenvs, sodium for fallback
  390. The ``all_saltenvs`` per-remote configuration parameter overrides the logic
  391. Salt uses to map branches/tags to fileserver environments (i.e. saltenvs). This
  392. allows a single branch/tag to appear in *all* GitFS saltenvs.
  393. .. note::
  394. ``all_saltenvs`` only works *within* GitFS. That is, files in a branch
  395. configured using ``all_saltenvs`` will *not* show up in a fileserver
  396. environment defined via some other fileserver backend (e.g.
  397. :conf_master:`file_roots`).
  398. The ``fallback`` global or per-remote configuration can also be used.
  399. This is very useful in particular when working with :ref:`salt formulas
  400. <conventions-formula>`. Prior to the addition of this feature, it was necessary
  401. to push a branch/tag to the remote repo for each saltenv in which that formula
  402. was to be used. If the formula needed to be updated, this update would need to
  403. be reflected in all of the other branches/tags. This is both inconvenient and
  404. not scalable.
  405. With ``all_saltenvs``, it is now possible to define your formula once, in a
  406. single branch.
  407. .. code-block:: yaml
  408. gitfs_remotes:
  409. - http://foo.com/quux.git:
  410. - all_saltenvs: anything
  411. If you want to also test working branches of the formula repository, use
  412. ``fallback``:
  413. .. code-block:: yaml
  414. gitfs_remotes:
  415. - http://foo.com/quux.git:
  416. - fallback: anything
  417. .. _gitfs-update-intervals:
  418. Update Intervals
  419. ================
  420. Prior to the 2018.3.0 release, GitFS would update its fileserver backends as part
  421. of a dedicated "maintenance" process, in which various routine maintenance
  422. tasks were performed. This tied the update interval to the
  423. :conf_master:`loop_interval` config option, and also forced all fileservers to
  424. update at the same interval.
  425. Now it is possible to make GitFS update at its own interval, using
  426. :conf_master:`gitfs_update_interval`:
  427. .. code-block:: yaml
  428. gitfs_update_interval: 180
  429. gitfs_remotes:
  430. - https://foo.com/foo.git
  431. - https://foo.com/bar.git:
  432. - update_interval: 120
  433. Using the above configuration, the first remote would update every three
  434. minutes, while the second remote would update every two minutes.
  435. Configuration Order of Precedence
  436. =================================
  437. The order of precedence for GitFS configuration is as follows (each level
  438. overrides all levels below it):
  439. 1. Per-saltenv configuration (defined under a per-remote ``saltenv``
  440. param)
  441. .. code-block:: yaml
  442. gitfs_remotes:
  443. - https://foo.com/bar.git:
  444. - saltenv:
  445. - dev:
  446. - mountpoint: salt://bar
  447. 2. Global per-saltenv configuration (defined in :conf_master:`gitfs_saltenv`)
  448. .. code-block:: yaml
  449. gitfs_saltenv:
  450. - dev:
  451. - mountpoint: salt://bar
  452. 3. Per-remote configuration parameter
  453. .. code-block:: yaml
  454. gitfs_remotes:
  455. - https://foo.com/bar.git:
  456. - mountpoint: salt://bar
  457. 4. Global configuration parameter
  458. .. code-block:: yaml
  459. gitfs_mountpoint: salt://bar
  460. .. note::
  461. The one exception to the above is when :ref:`all_saltenvs
  462. <gitfs-global-remotes>` is used. This value overrides all logic for mapping
  463. branches/tags to fileserver environments. So, even if
  464. :conf_master:`gitfs_saltenv` is used to globally override the mapping for a
  465. given saltenv, :ref:`all_saltenvs <gitfs-global-remotes>` would take
  466. precedence for any remote which uses it.
  467. It's important to note however that any ``root`` and ``mountpoint`` values
  468. configured in :conf_master:`gitfs_saltenv` (or :ref:`per-saltenv
  469. configuration <gitfs-per-saltenv-config>`) would be unaffected by this.
  470. .. _gitfs-walkthrough-root:
  471. Serving from a Subdirectory
  472. ===========================
  473. The :conf_master:`gitfs_root` parameter allows files to be served from a
  474. subdirectory within the repository. This allows for only part of a repository
  475. to be exposed to the Salt fileserver.
  476. Assume the below layout:
  477. .. code-block:: text
  478. .gitignore
  479. README.txt
  480. foo/
  481. foo/bar/
  482. foo/bar/one.txt
  483. foo/bar/two.txt
  484. foo/bar/three.txt
  485. foo/baz/
  486. foo/baz/top.sls
  487. foo/baz/edit/vim.sls
  488. foo/baz/edit/vimrc
  489. foo/baz/nginx/init.sls
  490. The below configuration would serve only the files under ``foo/baz``, ignoring
  491. the other files in the repository:
  492. .. code-block:: yaml
  493. gitfs_remotes:
  494. - git://mydomain.com/stuff.git
  495. gitfs_root: foo/baz
  496. The root can also be configured on a :ref:`per-remote basis
  497. <gitfs-per-remote-config>`.
  498. .. _gitfs-walkthrough-mountpoint:
  499. Mountpoints
  500. ===========
  501. .. versionadded:: 2014.7.0
  502. The :conf_master:`gitfs_mountpoint` parameter will prepend the specified path
  503. to the files served from gitfs. This allows an existing repository to be used,
  504. rather than needing to reorganize a repository or design it around the layout
  505. of the Salt fileserver.
  506. Before the addition of this feature, if a file being served up via gitfs was
  507. deeply nested within the root directory (for example,
  508. ``salt://webapps/foo/files/foo.conf``, it would be necessary to ensure that the
  509. file was properly located in the remote repository, and that all of the
  510. parent directories were present (for example, the directories
  511. ``webapps/foo/files/`` would need to exist at the root of the repository).
  512. The below example would allow for a file ``foo.conf`` at the root of the
  513. repository to be served up from the Salt fileserver path
  514. ``salt://webapps/foo/files/foo.conf``.
  515. .. code-block:: yaml
  516. gitfs_remotes:
  517. - https://mydomain.com/stuff.git
  518. gitfs_mountpoint: salt://webapps/foo/files
  519. Mountpoints can also be configured on a :ref:`per-remote basis
  520. <gitfs-per-remote-config>`.
  521. Using gitfs in Masterless Mode
  522. ==============================
  523. Since 2014.7.0, gitfs can be used in masterless mode. To do so, simply add the
  524. gitfs configuration parameters (and set :conf_master:`fileserver_backend`) in
  525. the _minion_ config file instead of the master config file.
  526. Using gitfs Alongside Other Backends
  527. ====================================
  528. Sometimes it may make sense to use multiple backends; for instance, if ``sls``
  529. files are stored in git but larger files are stored directly on the master.
  530. The cascading lookup logic used for multiple remotes is also used with multiple
  531. backends. If the :conf_master:`fileserver_backend` option contains multiple
  532. backends:
  533. .. code-block:: yaml
  534. fileserver_backend:
  535. - roots
  536. - git
  537. Then the ``roots`` backend (the default backend of files in ``/srv/salt``) will
  538. be searched first for the requested file; then, if it is not found on the
  539. master, each configured git remote will be searched.
  540. .. note::
  541. This can be used together with `file_roots` accepting `__env__` as a catch-all
  542. environment, since 2018.3.5 and 2019.2.1:
  543. .. code-block:: yaml
  544. file_roots:
  545. base:
  546. - /srv/salt
  547. __env__:
  548. - /srv/salt
  549. Branches, Environments, and Top Files
  550. =====================================
  551. When using the GitFS backend, branches, and tags will be mapped to environments
  552. using the branch/tag name as an identifier.
  553. There is one exception to this rule: the ``master`` branch is implicitly mapped
  554. to the ``base`` environment.
  555. So, for a typical ``base``, ``qa``, ``dev`` setup, the following branches could
  556. be used:
  557. .. code-block:: yaml
  558. master
  559. qa
  560. dev
  561. ``top.sls`` files from different branches will be merged into one at runtime.
  562. Since this can lead to overly complex configurations, the recommended setup is
  563. to have a separate repository, containing only the ``top.sls`` file with just
  564. one single ``master`` branch.
  565. To map a branch other than ``master`` as the ``base`` environment, use the
  566. :conf_master:`gitfs_base` parameter.
  567. .. code-block:: yaml
  568. gitfs_base: salt-base
  569. The base can also be configured on a :ref:`per-remote basis
  570. <gitfs-per-remote-config>`.
  571. .. _gitfs-whitelist-blacklist:
  572. Environment Whitelist/Blacklist
  573. ===============================
  574. .. versionadded:: 2014.7.0
  575. The :conf_master:`gitfs_saltenv_whitelist` and
  576. :conf_master:`gitfs_saltenv_blacklist` parameters allow for greater control
  577. over which branches/tags are exposed as fileserver environments. Exact matches,
  578. globs, and regular expressions are supported, and are evaluated in that order.
  579. If using a regular expression, ``^`` and ``$`` must be omitted, and the
  580. expression must match the entire branch/tag.
  581. .. code-block:: yaml
  582. gitfs_saltenv_whitelist:
  583. - base
  584. - v1.*
  585. - 'mybranch\d+'
  586. .. note::
  587. ``v1.*``, in this example, will match as both a glob and a regular
  588. expression (though it will have been matched as a glob, since globs are
  589. evaluated before regular expressions).
  590. The behavior of the blacklist/whitelist will differ depending on which
  591. combination of the two options is used:
  592. * If only :conf_master:`gitfs_saltenv_whitelist` is used, then **only**
  593. branches/tags which match the whitelist will be available as environments
  594. * If only :conf_master:`gitfs_saltenv_blacklist` is used, then the
  595. branches/tags which match the blacklist will **not** be available as
  596. environments
  597. * If both are used, then the branches/tags which match the whitelist, but do
  598. **not** match the blacklist, will be available as environments.
  599. .. _gitfs-authentication:
  600. Authentication
  601. ==============
  602. pygit2
  603. ------
  604. .. versionadded:: 2014.7.0
  605. Both HTTPS and SSH authentication are supported as of version 0.20.3, which is
  606. the earliest version of pygit2_ supported by Salt for gitfs.
  607. .. note::
  608. The examples below make use of per-remote configuration parameters, a
  609. feature new to Salt 2014.7.0. More information on these can be found
  610. :ref:`here <gitfs-per-remote-config>`.
  611. HTTPS
  612. ~~~~~
  613. For HTTPS repositories which require authentication, the username and password
  614. can be provided like so:
  615. .. code-block:: yaml
  616. gitfs_remotes:
  617. - https://domain.tld/myrepo.git:
  618. - user: git
  619. - password: mypassword
  620. .. _gitfs-insecure-auth:
  621. If the repository is served over HTTP instead of HTTPS, then Salt will by
  622. default refuse to authenticate to it. This behavior can be overridden by adding
  623. an ``insecure_auth`` parameter:
  624. .. code-block:: yaml
  625. gitfs_remotes:
  626. - http://domain.tld/insecure_repo.git:
  627. - user: git
  628. - password: mypassword
  629. - insecure_auth: True
  630. .. _pygit2-authentication-ssh:
  631. SSH
  632. ~~~
  633. SSH repositories can be configured using the ``ssh://`` protocol designation,
  634. or using scp-like syntax. So, the following two configurations are equivalent:
  635. * ``ssh://git@github.com/user/repo.git``
  636. * ``git@github.com:user/repo.git``
  637. Both :conf_master:`gitfs_pubkey` and :conf_master:`gitfs_privkey` (or their
  638. :ref:`per-remote counterparts <gitfs-per-remote-config>`) must be configured in
  639. order to authenticate to SSH-based repos. If the private key is protected with
  640. a passphrase, it can be configured using :conf_master:`gitfs_passphrase` (or
  641. simply ``passphrase`` if being configured :ref:`per-remote
  642. <gitfs-per-remote-config>`). For example:
  643. .. code-block:: yaml
  644. gitfs_remotes:
  645. - git@github.com:user/repo.git:
  646. - pubkey: /root/.ssh/id_rsa.pub
  647. - privkey: /root/.ssh/id_rsa
  648. - passphrase: myawesomepassphrase
  649. Finally, the SSH host key must be :ref:`added to the known_hosts file
  650. <gitfs-ssh-fingerprint>`.
  651. .. note::
  652. There is a known issue with public-key SSH authentication to Microsoft
  653. Visual Studio (VSTS) with pygit2. This is due to a bug or lack of support
  654. for VSTS in older libssh2 releases. Known working releases include libssh2
  655. 1.7.0 and later, and known incompatible releases include 1.5.0 and older.
  656. At the time of this writing, 1.6.0 has not been tested.
  657. Since upgrading libssh2 would require rebuilding many other packages (curl,
  658. etc.), followed by a rebuild of libgit2 and a reinstall of pygit2, an
  659. easier workaround for systems with older libssh2 is to use GitPython with a
  660. passphraseless key for authentication.
  661. GitPython
  662. ---------
  663. HTTPS
  664. ~~~~~
  665. For HTTPS repositories which require authentication, the username and password
  666. can be configured in one of two ways. The first way is to include them in the
  667. URL using the format ``https://<user>:<password>@<url>``, like so:
  668. .. code-block:: yaml
  669. gitfs_remotes:
  670. - https://git:mypassword@domain.tld/myrepo.git
  671. The other way would be to configure the authentication in ``~/.netrc``:
  672. .. code-block:: text
  673. machine domain.tld
  674. login git
  675. password mypassword
  676. If the repository is served over HTTP instead of HTTPS, then Salt will by
  677. default refuse to authenticate to it. This behavior can be overridden by adding
  678. an ``insecure_auth`` parameter:
  679. .. code-block:: yaml
  680. gitfs_remotes:
  681. - http://git:mypassword@domain.tld/insecure_repo.git:
  682. - insecure_auth: True
  683. SSH
  684. ~~~
  685. Only passphrase-less SSH public key authentication is supported using
  686. GitPython. **The auth parameters (pubkey, privkey, etc.) shown in the pygit2
  687. authentication examples above do not work with GitPython.**
  688. .. code-block:: yaml
  689. gitfs_remotes:
  690. - ssh://git@github.com/example/salt-states.git
  691. Since GitPython_ wraps the git CLI, the private key must be located in
  692. ``~/.ssh/id_rsa`` for the user under which the Master is running, and should
  693. have permissions of ``0600``. Also, in the absence of a user in the repo URL,
  694. GitPython_ will (just as SSH does) attempt to login as the current user (in
  695. other words, the user under which the Master is running, usually ``root``).
  696. If a key needs to be used, then ``~/.ssh/config`` can be configured to use
  697. the desired key. Information on how to do this can be found by viewing the
  698. manpage for ``ssh_config``. Here's an example entry which can be added to the
  699. ``~/.ssh/config`` to use an alternate key for gitfs:
  700. .. code-block:: text
  701. Host github.com
  702. IdentityFile /root/.ssh/id_rsa_gitfs
  703. The ``Host`` parameter should be a hostname (or hostname glob) that matches the
  704. domain name of the git repository.
  705. It is also necessary to :ref:`add the SSH host key to the known_hosts file
  706. <gitfs-ssh-fingerprint>`. The exception to this would be if strict host key
  707. checking is disabled, which can be done by adding ``StrictHostKeyChecking no``
  708. to the entry in ``~/.ssh/config``
  709. .. code-block:: text
  710. Host github.com
  711. IdentityFile /root/.ssh/id_rsa_gitfs
  712. StrictHostKeyChecking no
  713. However, this is generally regarded as insecure, and is not recommended.
  714. .. _gitfs-ssh-fingerprint:
  715. Adding the SSH Host Key to the known_hosts File
  716. -----------------------------------------------
  717. To use SSH authentication, it is necessary to have the remote repository's SSH
  718. host key in the ``~/.ssh/known_hosts`` file. If the master is also a minion,
  719. this can be done using the :mod:`ssh.set_known_host
  720. <salt.modules.ssh.set_known_host>` function:
  721. .. code-block:: bash
  722. # salt mymaster ssh.set_known_host user=root hostname=github.com
  723. mymaster:
  724. ----------
  725. new:
  726. ----------
  727. enc:
  728. ssh-rsa
  729. fingerprint:
  730. 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
  731. hostname:
  732. |1|OiefWWqOD4kwO3BhoIGa0loR5AA=|BIXVtmcTbPER+68HvXmceodDcfI=
  733. key:
  734. AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
  735. old:
  736. None
  737. status:
  738. updated
  739. If not, then the easiest way to add the key is to su to the user (usually
  740. ``root``) under which the salt-master runs and attempt to login to the
  741. server via SSH:
  742. .. code-block:: text
  743. $ su -
  744. Password:
  745. # ssh github.com
  746. The authenticity of host 'github.com (192.30.252.128)' can't be established.
  747. RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
  748. Are you sure you want to continue connecting (yes/no)? yes
  749. Warning: Permanently added 'github.com,192.30.252.128' (RSA) to the list of known hosts.
  750. Permission denied (publickey).
  751. It doesn't matter if the login was successful, as answering ``yes`` will write
  752. the fingerprint to the known_hosts file.
  753. Verifying the Fingerprint
  754. ~~~~~~~~~~~~~~~~~~~~~~~~~
  755. To verify that the correct fingerprint was added, it is a good idea to look it
  756. up. One way to do this is to use ``nmap``:
  757. .. code-block:: bash
  758. $ nmap -p 22 github.com --script ssh-hostkey
  759. Starting Nmap 5.51 ( http://nmap.org ) at 2014-08-18 17:47 CDT
  760. Nmap scan report for github.com (192.30.252.129)
  761. Host is up (0.17s latency).
  762. Not shown: 996 filtered ports
  763. PORT STATE SERVICE
  764. 22/tcp open ssh
  765. | ssh-hostkey: 1024 ad:1c:08:a4:40:e3:6f:9c:f5:66:26:5d:4b:33:5d:8c (DSA)
  766. |_2048 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 (RSA)
  767. 80/tcp open http
  768. 443/tcp open https
  769. 9418/tcp open git
  770. Nmap done: 1 IP address (1 host up) scanned in 28.78 seconds
  771. Another way is to check one's own ``known_hosts`` file, using this one-liner:
  772. .. code-block:: bash
  773. $ ssh-keygen -l -f /dev/stdin <<<`ssh-keyscan github.com 2>/dev/null` | awk '{print $2}'
  774. 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
  775. .. warning::
  776. AWS tracks usage of nmap and may flag it as abuse. On AWS hosts, the
  777. ``ssh-keygen`` method is recommended for host key verification.
  778. .. note::
  779. As of `OpenSSH 6.8`_ the SSH fingerprint is now shown as a base64-encoded
  780. SHA256 checksum of the host key. So, instead of the fingerprint looking
  781. like ``16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48``, it would look
  782. like ``SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8``.
  783. .. _`OpenSSH 6.8`: http://www.openssh.com/txt/release-6.8
  784. Refreshing gitfs Upon Push
  785. ==========================
  786. By default, Salt updates the remote fileserver backends every 60 seconds.
  787. However, if it is desirable to refresh quicker than that, the :ref:`Reactor
  788. System <reactor>` can be used to signal the master to update the fileserver on
  789. each push, provided that the git server is also a Salt minion. There are three
  790. steps to this process:
  791. 1. On the master, create a file **/srv/reactor/update_fileserver.sls**, with
  792. the following contents:
  793. .. code-block:: yaml
  794. update_fileserver:
  795. runner.fileserver.update
  796. 2. Add the following reactor configuration to the master config file:
  797. .. code-block:: yaml
  798. reactor:
  799. - 'salt/fileserver/gitfs/update':
  800. - /srv/reactor/update_fileserver.sls
  801. 3. On the git server, add a `post-receive hook`_
  802. a. If the user executing `git push` is the same as the minion user, use the following hook:
  803. .. code-block:: bash
  804. #!/usr/bin/env sh
  805. salt-call event.fire_master update salt/fileserver/gitfs/update
  806. b. To enable other git users to run the hook after a `push`, use sudo in the hook script:
  807. .. code-block:: bash
  808. #!/usr/bin/env sh
  809. sudo -u root salt-call event.fire_master update salt/fileserver/gitfs/update
  810. 4. If using sudo in the git hook (above), the policy must be changed to permit
  811. all users to fire the event. Add the following policy to the sudoers file
  812. on the git server.
  813. .. code-block:: bash
  814. Cmnd_Alias SALT_GIT_HOOK = /bin/salt-call event.fire_master update salt/fileserver/gitfs/update
  815. Defaults!SALT_GIT_HOOK !requiretty
  816. ALL ALL=(root) NOPASSWD: SALT_GIT_HOOK
  817. The ``update`` argument right after :mod:`event.fire_master
  818. <salt.modules.event.fire_master>` in this example can really be anything, as it
  819. represents the data being passed in the event, and the passed data is ignored
  820. by this reactor.
  821. Similarly, the tag name ``salt/fileserver/gitfs/update`` can be replaced by
  822. anything, so long as the usage is consistent.
  823. The ``root`` user name in the hook script and sudo policy should be changed to
  824. match the user under which the minion is running.
  825. .. _`post-receive hook`: http://www.git-scm.com/book/en/Customizing-Git-Git-Hooks#Server-Side-Hooks
  826. .. _git-as-ext_pillar:
  827. Using Git as an External Pillar Source
  828. ======================================
  829. The git external pillar (a.k.a. git_pillar) has been rewritten for the 2015.8.0
  830. release. This rewrite brings with it pygit2_ support (allowing for access to
  831. authenticated repositories), as well as more granular support for per-remote
  832. configuration. This configuration schema is detailed :ref:`here
  833. <git-pillar-configuration>`.
  834. .. _faq-gitfs-bug:
  835. Why aren't my custom modules/states/etc. syncing to my Minions?
  836. ===============================================================
  837. In versions 0.16.3 and older, when using the :mod:`git fileserver backend
  838. <salt.fileserver.gitfs>`, certain versions of GitPython may generate errors
  839. when fetching, which Salt fails to catch. While not fatal to the fetch process,
  840. these interrupt the fileserver update that takes place before custom types are
  841. synced, and thus interrupt the sync itself. Try disabling the git fileserver
  842. backend in the master config, restarting the master, and attempting the sync
  843. again.
  844. This issue is worked around in Salt 0.16.4 and newer.