1
0

test_gitfs.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Erik Johnson <erik@saltstack.com>
  4. '''
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import errno
  8. import os
  9. import shutil
  10. import tempfile
  11. import textwrap
  12. import tornado.ioloop
  13. import logging
  14. import stat
  15. try:
  16. import pwd # pylint: disable=unused-import
  17. except ImportError:
  18. pass
  19. # Import Salt Testing Libs
  20. from tests.support.runtests import RUNTIME_VARS
  21. from tests.support.mixins import LoaderModuleMockMixin
  22. from tests.support.unit import TestCase, skipIf
  23. from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch
  24. # Import salt libs
  25. import salt.fileserver.gitfs as gitfs
  26. import salt.utils.files
  27. import salt.utils.platform
  28. import salt.utils.win_functions
  29. import salt.utils.yaml
  30. import salt.ext.six
  31. import salt.utils.gitfs
  32. from salt.utils.gitfs import (
  33. GITPYTHON_VERSION,
  34. GITPYTHON_MINVER,
  35. PYGIT2_VERSION,
  36. PYGIT2_MINVER,
  37. LIBGIT2_VERSION,
  38. LIBGIT2_MINVER
  39. )
  40. try:
  41. import git
  42. # We still need to use GitPython here for temp repo setup, so we do need to
  43. # actually import it. But we don't need import pygit2 in this module, we
  44. # can just use the LooseVersion instances imported along with
  45. # salt.utils.gitfs to check if we have a compatible version.
  46. HAS_GITPYTHON = GITPYTHON_VERSION >= GITPYTHON_MINVER
  47. except (ImportError, AttributeError):
  48. HAS_GITPYTHON = False
  49. try:
  50. HAS_PYGIT2 = PYGIT2_VERSION >= PYGIT2_MINVER \
  51. and LIBGIT2_VERSION >= LIBGIT2_MINVER
  52. except AttributeError:
  53. HAS_PYGIT2 = False
  54. log = logging.getLogger(__name__)
  55. UNICODE_FILENAME = 'питон.txt'
  56. UNICODE_DIRNAME = UNICODE_ENVNAME = 'соль'
  57. TAG_NAME = 'mytag'
  58. def _rmtree_error(func, path, excinfo):
  59. os.chmod(path, stat.S_IWRITE)
  60. func(path)
  61. def _clear_instance_map():
  62. try:
  63. del salt.utils.gitfs.GitFS.instance_map[tornado.ioloop.IOLoop.current()]
  64. except KeyError:
  65. pass
  66. @skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER))
  67. class GitfsConfigTestCase(TestCase, LoaderModuleMockMixin):
  68. def setup_loader_modules(self):
  69. opts = {
  70. 'sock_dir': self.tmp_sock_dir,
  71. 'gitfs_remotes': ['file://' + self.tmp_repo_dir],
  72. 'gitfs_root': '',
  73. 'fileserver_backend': ['gitfs'],
  74. 'gitfs_base': 'master',
  75. 'fileserver_events': True,
  76. 'transport': 'zeromq',
  77. 'gitfs_mountpoint': '',
  78. 'gitfs_saltenv': [],
  79. 'gitfs_env_whitelist': [],
  80. 'gitfs_env_blacklist': [],
  81. 'gitfs_saltenv_whitelist': [],
  82. 'gitfs_saltenv_blacklist': [],
  83. 'gitfs_user': '',
  84. 'gitfs_password': '',
  85. 'gitfs_insecure_auth': False,
  86. 'gitfs_privkey': '',
  87. 'gitfs_pubkey': '',
  88. 'gitfs_passphrase': '',
  89. 'gitfs_refspecs': [
  90. '+refs/heads/*:refs/remotes/origin/*',
  91. '+refs/tags/*:refs/tags/*'
  92. ],
  93. 'gitfs_ssl_verify': True,
  94. 'gitfs_disable_saltenv_mapping': False,
  95. 'gitfs_ref_types': ['branch', 'tag', 'sha'],
  96. 'gitfs_update_interval': 60,
  97. '__role': 'master',
  98. }
  99. opts['cachedir'] = self.tmp_cachedir
  100. opts['sock_dir'] = self.tmp_sock_dir
  101. return {
  102. gitfs: {
  103. '__opts__': opts,
  104. }
  105. }
  106. @classmethod
  107. def setUpClass(cls):
  108. # Clear the instance map so that we make sure to create a new instance
  109. # for this test class.
  110. _clear_instance_map()
  111. cls.tmp_repo_dir = os.path.join(RUNTIME_VARS.TMP, 'gitfs_root')
  112. if salt.utils.platform.is_windows():
  113. cls.tmp_repo_dir = cls.tmp_repo_dir.replace('\\', '/')
  114. cls.tmp_cachedir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  115. cls.tmp_sock_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  116. @classmethod
  117. def tearDownClass(cls):
  118. '''
  119. Remove the temporary git repository and gitfs cache directory to ensure
  120. a clean environment for the other test class(es).
  121. '''
  122. for path in (cls.tmp_cachedir, cls.tmp_sock_dir):
  123. try:
  124. shutil.rmtree(path, onerror=_rmtree_error)
  125. except OSError as exc:
  126. if exc.errno == errno.EACCES:
  127. log.error("Access error removeing file %s", path)
  128. continue
  129. if exc.errno != errno.EEXIST:
  130. raise
  131. def test_per_saltenv_config(self):
  132. opts_override = textwrap.dedent('''
  133. gitfs_root: salt
  134. gitfs_saltenv:
  135. - baz:
  136. # when loaded, the "salt://" prefix will be removed
  137. - mountpoint: salt://baz_mountpoint
  138. - ref: baz_branch
  139. - root: baz_root
  140. gitfs_remotes:
  141. - file://{0}tmp/repo1:
  142. - saltenv:
  143. - foo:
  144. - ref: foo_branch
  145. - root: foo_root
  146. - file://{0}tmp/repo2:
  147. - mountpoint: repo2
  148. - saltenv:
  149. - baz:
  150. - mountpoint: abc
  151. '''.format('/' if salt.utils.platform.is_windows() else ''))
  152. with patch.dict(gitfs.__opts__, salt.utils.yaml.safe_load(opts_override)):
  153. git_fs = salt.utils.gitfs.GitFS(
  154. gitfs.__opts__,
  155. gitfs.__opts__['gitfs_remotes'],
  156. per_remote_overrides=gitfs.PER_REMOTE_OVERRIDES,
  157. per_remote_only=gitfs.PER_REMOTE_ONLY)
  158. # repo1 (branch: foo)
  159. # The mountpoint should take the default (from gitfs_mountpoint), while
  160. # ref and root should take the per-saltenv params.
  161. self.assertEqual(git_fs.remotes[0].mountpoint('foo'), '')
  162. self.assertEqual(git_fs.remotes[0].ref('foo'), 'foo_branch')
  163. self.assertEqual(git_fs.remotes[0].root('foo'), 'foo_root')
  164. # repo1 (branch: bar)
  165. # The 'bar' branch does not have a per-saltenv configuration set, so
  166. # each of the below values should fall back to global values.
  167. self.assertEqual(git_fs.remotes[0].mountpoint('bar'), '')
  168. self.assertEqual(git_fs.remotes[0].ref('bar'), 'bar')
  169. self.assertEqual(git_fs.remotes[0].root('bar'), 'salt')
  170. # repo1 (branch: baz)
  171. # The 'baz' branch does not have a per-saltenv configuration set, but
  172. # it is defined in the gitfs_saltenv parameter, so the values
  173. # from that parameter should be returned.
  174. self.assertEqual(git_fs.remotes[0].mountpoint('baz'), 'baz_mountpoint')
  175. self.assertEqual(git_fs.remotes[0].ref('baz'), 'baz_branch')
  176. self.assertEqual(git_fs.remotes[0].root('baz'), 'baz_root')
  177. # repo2 (branch: foo)
  178. # The mountpoint should take the per-remote mountpoint value of
  179. # 'repo2', while ref and root should fall back to global values.
  180. self.assertEqual(git_fs.remotes[1].mountpoint('foo'), 'repo2')
  181. self.assertEqual(git_fs.remotes[1].ref('foo'), 'foo')
  182. self.assertEqual(git_fs.remotes[1].root('foo'), 'salt')
  183. # repo2 (branch: bar)
  184. # The 'bar' branch does not have a per-saltenv configuration set, so
  185. # the mountpoint should take the per-remote mountpoint value of
  186. # 'repo2', while ref and root should fall back to global values.
  187. self.assertEqual(git_fs.remotes[1].mountpoint('bar'), 'repo2')
  188. self.assertEqual(git_fs.remotes[1].ref('bar'), 'bar')
  189. self.assertEqual(git_fs.remotes[1].root('bar'), 'salt')
  190. # repo2 (branch: baz)
  191. # The 'baz' branch has the mountpoint configured as a per-saltenv
  192. # parameter. The other two should take the values defined in
  193. # gitfs_saltenv.
  194. self.assertEqual(git_fs.remotes[1].mountpoint('baz'), 'abc')
  195. self.assertEqual(git_fs.remotes[1].ref('baz'), 'baz_branch')
  196. self.assertEqual(git_fs.remotes[1].root('baz'), 'baz_root')
  197. LOAD = {'saltenv': 'base'}
  198. class GitFSTestFuncs(object):
  199. '''
  200. These are where the tests go, so that they can be run using both GitPython
  201. and pygit2.
  202. NOTE: The gitfs.update() has to happen AFTER the setUp is called. This is
  203. because running it inside the setUp will spawn a new singleton, which means
  204. that tests which need to mock the __opts__ will be too late; the setUp will
  205. have created a new singleton that will bypass our mocking. To ensure that
  206. our tests are reliable and correct, we want to make sure that each test
  207. uses a new gitfs object, allowing different manipulations of the opts to be
  208. tested.
  209. Therefore, keep the following in mind:
  210. 1. Each test needs to call gitfs.update() *after* any patching, and
  211. *before* calling the function being tested.
  212. 2. Do *NOT* move the gitfs.update() into the setUp.
  213. '''
  214. def test_file_list(self):
  215. gitfs.update()
  216. ret = gitfs.file_list(LOAD)
  217. self.assertIn('testfile', ret)
  218. self.assertIn(UNICODE_FILENAME, ret)
  219. # This function does not use os.sep, the Salt fileserver uses the
  220. # forward slash, hence it being explicitly used to join here.
  221. self.assertIn('/'.join((UNICODE_DIRNAME, 'foo.txt')), ret)
  222. def test_dir_list(self):
  223. gitfs.update()
  224. ret = gitfs.dir_list(LOAD)
  225. self.assertIn('grail', ret)
  226. self.assertIn(UNICODE_DIRNAME, ret)
  227. def test_envs(self):
  228. gitfs.update()
  229. ret = gitfs.envs(ignore_cache=True)
  230. self.assertIn('base', ret)
  231. self.assertIn(UNICODE_ENVNAME, ret)
  232. self.assertIn(TAG_NAME, ret)
  233. def test_ref_types_global(self):
  234. '''
  235. Test the global gitfs_ref_types config option
  236. '''
  237. with patch.dict(gitfs.__opts__, {'gitfs_ref_types': ['branch']}):
  238. gitfs.update()
  239. ret = gitfs.envs(ignore_cache=True)
  240. # Since we are restricting to branches only, the tag should not
  241. # appear in the envs list.
  242. self.assertIn('base', ret)
  243. self.assertIn(UNICODE_ENVNAME, ret)
  244. self.assertNotIn(TAG_NAME, ret)
  245. def test_ref_types_per_remote(self):
  246. '''
  247. Test the per_remote ref_types config option, using a different
  248. ref_types setting than the global test.
  249. '''
  250. remotes = [{'file://' + self.tmp_repo_dir: [{'ref_types': ['tag']}]}]
  251. with patch.dict(gitfs.__opts__, {'gitfs_remotes': remotes}):
  252. gitfs.update()
  253. ret = gitfs.envs(ignore_cache=True)
  254. # Since we are restricting to tags only, the tag should appear in
  255. # the envs list, but the branches should not.
  256. self.assertNotIn('base', ret)
  257. self.assertNotIn(UNICODE_ENVNAME, ret)
  258. self.assertIn(TAG_NAME, ret)
  259. def test_disable_saltenv_mapping_global_with_mapping_defined_globally(self):
  260. '''
  261. Test the global gitfs_disable_saltenv_mapping config option, combined
  262. with the per-saltenv mapping being defined in the global gitfs_saltenv
  263. option.
  264. '''
  265. opts = salt.utils.yaml.safe_load(textwrap.dedent('''\
  266. gitfs_disable_saltenv_mapping: True
  267. gitfs_saltenv:
  268. - foo:
  269. - ref: somebranch
  270. '''))
  271. with patch.dict(gitfs.__opts__, opts):
  272. gitfs.update()
  273. ret = gitfs.envs(ignore_cache=True)
  274. # Since we are restricting to tags only, the tag should appear in
  275. # the envs list, but the branches should not.
  276. self.assertEqual(ret, ['base', 'foo'])
  277. def test_disable_saltenv_mapping_global_with_mapping_defined_per_remote(self):
  278. '''
  279. Test the global gitfs_disable_saltenv_mapping config option, combined
  280. with the per-saltenv mapping being defined in the remote itself via the
  281. "saltenv" per-remote option.
  282. '''
  283. opts = salt.utils.yaml.safe_load(textwrap.dedent('''\
  284. gitfs_disable_saltenv_mapping: True
  285. gitfs_remotes:
  286. - {0}:
  287. - saltenv:
  288. - bar:
  289. - ref: somebranch
  290. '''.format(self.tmp_repo_dir)))
  291. with patch.dict(gitfs.__opts__, opts):
  292. gitfs.update()
  293. ret = gitfs.envs(ignore_cache=True)
  294. # Since we are restricting to tags only, the tag should appear in
  295. # the envs list, but the branches should not.
  296. self.assertEqual(ret, ['bar', 'base'])
  297. def test_disable_saltenv_mapping_per_remote_with_mapping_defined_globally(self):
  298. '''
  299. Test the per-remote disable_saltenv_mapping config option, combined
  300. with the per-saltenv mapping being defined in the global gitfs_saltenv
  301. option.
  302. '''
  303. opts = salt.utils.yaml.safe_load(textwrap.dedent('''\
  304. gitfs_remotes:
  305. - {0}:
  306. - disable_saltenv_mapping: True
  307. gitfs_saltenv:
  308. - hello:
  309. - ref: somebranch
  310. '''.format(self.tmp_repo_dir)))
  311. with patch.dict(gitfs.__opts__, opts):
  312. gitfs.update()
  313. ret = gitfs.envs(ignore_cache=True)
  314. # Since we are restricting to tags only, the tag should appear in
  315. # the envs list, but the branches should not.
  316. self.assertEqual(ret, ['base', 'hello'])
  317. def test_disable_saltenv_mapping_per_remote_with_mapping_defined_per_remote(self):
  318. '''
  319. Test the per-remote disable_saltenv_mapping config option, combined
  320. with the per-saltenv mapping being defined in the remote itself via the
  321. "saltenv" per-remote option.
  322. '''
  323. opts = salt.utils.yaml.safe_load(textwrap.dedent('''\
  324. gitfs_remotes:
  325. - {0}:
  326. - disable_saltenv_mapping: True
  327. - saltenv:
  328. - world:
  329. - ref: somebranch
  330. '''.format(self.tmp_repo_dir)))
  331. with patch.dict(gitfs.__opts__, opts):
  332. gitfs.update()
  333. ret = gitfs.envs(ignore_cache=True)
  334. # Since we are restricting to tags only, the tag should appear in
  335. # the envs list, but the branches should not.
  336. self.assertEqual(ret, ['base', 'world'])
  337. class GitFSTestBase(object):
  338. @classmethod
  339. def setUpClass(cls):
  340. cls.tmp_repo_dir = os.path.join(RUNTIME_VARS.TMP, 'gitfs_root')
  341. if salt.utils.platform.is_windows():
  342. cls.tmp_repo_dir = cls.tmp_repo_dir.replace('\\', '/')
  343. cls.tmp_cachedir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  344. cls.tmp_sock_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  345. try:
  346. shutil.rmtree(cls.tmp_repo_dir)
  347. except OSError as exc:
  348. if exc.errno == errno.EACCES:
  349. log.error("Access error removing file %s", cls.tmp_repo_dir)
  350. elif exc.errno != errno.ENOENT:
  351. raise
  352. shutil.copytree(
  353. salt.ext.six.text_type(RUNTIME_VARS.BASE_FILES),
  354. salt.ext.six.text_type(cls.tmp_repo_dir + '/')
  355. )
  356. repo = git.Repo.init(cls.tmp_repo_dir)
  357. username_key = str('USERNAME')
  358. orig_username = os.environ.get(username_key)
  359. environ_copy = os.environ.copy()
  360. try:
  361. if username_key not in os.environ:
  362. try:
  363. if salt.utils.platform.is_windows():
  364. os.environ[username_key] = \
  365. salt.utils.win_functions.get_current_user()
  366. else:
  367. os.environ[username_key] = \
  368. pwd.getpwuid(os.geteuid()).pw_name
  369. except AttributeError:
  370. log.error(
  371. 'Unable to get effective username, falling back to '
  372. '\'root\'.'
  373. )
  374. os.environ[username_key] = str('root')
  375. repo.index.add([x for x in os.listdir(cls.tmp_repo_dir)
  376. if x != '.git'])
  377. repo.index.commit('Test')
  378. # Add another branch with unicode characters in the name
  379. repo.create_head(UNICODE_ENVNAME, 'HEAD')
  380. # Add a tag
  381. repo.create_tag(TAG_NAME, 'HEAD')
  382. # Older GitPython versions do not have a close method.
  383. if hasattr(repo, 'close'):
  384. repo.close()
  385. finally:
  386. os.environ.clear()
  387. os.environ.update(environ_copy)
  388. @classmethod
  389. def tearDownClass(cls):
  390. '''
  391. Remove the temporary git repository and gitfs cache directory to ensure
  392. a clean environment for the other test class(es).
  393. '''
  394. for path in (cls.tmp_cachedir, cls.tmp_sock_dir, cls.tmp_repo_dir):
  395. try:
  396. salt.utils.files.rm_rf(path)
  397. except OSError as exc:
  398. if exc.errno == errno.EACCES:
  399. log.error("Access error removeing file %s", path)
  400. elif exc.errno != errno.EEXIST:
  401. raise
  402. def setUp(self):
  403. '''
  404. We don't want to check in another .git dir into GH because that just
  405. gets messy. Instead, we'll create a temporary repo on the fly for the
  406. tests to examine.
  407. Also ensure we A) don't re-use the singleton, and B) that the cachedirs
  408. are cleared. This keeps these performance enhancements from affecting
  409. the results of subsequent tests.
  410. '''
  411. if not gitfs.__virtual__():
  412. self.skipTest("GitFS could not be loaded. Skipping GitFS tests!")
  413. _clear_instance_map()
  414. for subdir in ('gitfs', 'file_lists'):
  415. try:
  416. salt.utils.files.rm_rf(os.path.join(self.tmp_cachedir, subdir))
  417. except OSError as exc:
  418. if exc.errno == errno.EACCES:
  419. log.warning("Access error removeing file %s", os.path.join(self.tmp_cachedir, subdir))
  420. continue
  421. if exc.errno != errno.ENOENT:
  422. raise
  423. if salt.ext.six.PY3 and salt.utils.platform.is_windows():
  424. self.setUpClass()
  425. self.setup_loader_modules()
  426. @skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER))
  427. @skipIf(NO_MOCK, NO_MOCK_REASON)
  428. class GitPythonTest(GitFSTestBase, GitFSTestFuncs, TestCase, LoaderModuleMockMixin):
  429. def setup_loader_modules(self):
  430. opts = {
  431. 'sock_dir': self.tmp_sock_dir,
  432. 'gitfs_remotes': ['file://' + self.tmp_repo_dir],
  433. 'gitfs_root': '',
  434. 'fileserver_backend': ['gitfs'],
  435. 'gitfs_base': 'master',
  436. 'fileserver_events': True,
  437. 'transport': 'zeromq',
  438. 'gitfs_mountpoint': '',
  439. 'gitfs_saltenv': [],
  440. 'gitfs_env_whitelist': [],
  441. 'gitfs_env_blacklist': [],
  442. 'gitfs_saltenv_whitelist': [],
  443. 'gitfs_saltenv_blacklist': [],
  444. 'gitfs_user': '',
  445. 'gitfs_password': '',
  446. 'gitfs_insecure_auth': False,
  447. 'gitfs_privkey': '',
  448. 'gitfs_pubkey': '',
  449. 'gitfs_passphrase': '',
  450. 'gitfs_refspecs': [
  451. '+refs/heads/*:refs/remotes/origin/*',
  452. '+refs/tags/*:refs/tags/*'
  453. ],
  454. 'gitfs_ssl_verify': True,
  455. 'gitfs_disable_saltenv_mapping': False,
  456. 'gitfs_ref_types': ['branch', 'tag', 'sha'],
  457. 'gitfs_update_interval': 60,
  458. '__role': 'master',
  459. }
  460. opts['cachedir'] = self.tmp_cachedir
  461. opts['sock_dir'] = self.tmp_sock_dir
  462. opts['gitfs_provider'] = 'gitpython'
  463. return {
  464. gitfs: {
  465. '__opts__': opts,
  466. }
  467. }
  468. @skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required for temp repo setup'.format(GITPYTHON_MINVER))
  469. @skipIf(not HAS_PYGIT2, 'pygit2 >= {0} and libgit2 >= {1} required'.format(PYGIT2_MINVER, LIBGIT2_MINVER))
  470. @skipIf(salt.utils.platform.is_windows(), 'Skip Pygit2 on windows, due to pygit2 access error on windows')
  471. @skipIf(NO_MOCK, NO_MOCK_REASON)
  472. class Pygit2Test(GitFSTestBase, GitFSTestFuncs, TestCase, LoaderModuleMockMixin):
  473. def setup_loader_modules(self):
  474. opts = {
  475. 'sock_dir': self.tmp_sock_dir,
  476. 'gitfs_remotes': ['file://' + self.tmp_repo_dir],
  477. 'gitfs_root': '',
  478. 'fileserver_backend': ['gitfs'],
  479. 'gitfs_base': 'master',
  480. 'fileserver_events': True,
  481. 'transport': 'zeromq',
  482. 'gitfs_mountpoint': '',
  483. 'gitfs_saltenv': [],
  484. 'gitfs_env_whitelist': [],
  485. 'gitfs_env_blacklist': [],
  486. 'gitfs_saltenv_whitelist': [],
  487. 'gitfs_saltenv_blacklist': [],
  488. 'gitfs_user': '',
  489. 'gitfs_password': '',
  490. 'gitfs_insecure_auth': False,
  491. 'gitfs_privkey': '',
  492. 'gitfs_pubkey': '',
  493. 'gitfs_passphrase': '',
  494. 'gitfs_refspecs': [
  495. '+refs/heads/*:refs/remotes/origin/*',
  496. '+refs/tags/*:refs/tags/*'
  497. ],
  498. 'gitfs_ssl_verify': True,
  499. 'gitfs_disable_saltenv_mapping': False,
  500. 'gitfs_ref_types': ['branch', 'tag', 'sha'],
  501. 'gitfs_update_interval': 60,
  502. '__role': 'master',
  503. }
  504. opts['cachedir'] = self.tmp_cachedir
  505. opts['sock_dir'] = self.tmp_sock_dir
  506. opts['gitfs_provider'] = 'pygit2'
  507. return {
  508. gitfs: {
  509. '__opts__': opts,
  510. }
  511. }