1
0

gitfs.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. # -*- coding: utf-8 -*-
  2. '''
  3. Base classes for gitfs/git_pillar integration tests
  4. '''
  5. # Import python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import copy
  8. import errno
  9. import logging
  10. import os
  11. import psutil
  12. import shutil
  13. import signal
  14. import tempfile
  15. import textwrap
  16. import time
  17. # Import Salt libs
  18. import salt.utils.files
  19. import salt.utils.path
  20. import salt.utils.yaml
  21. from salt.fileserver import gitfs
  22. from salt.pillar import git_pillar
  23. from salt.ext.six.moves import range # pylint: disable=redefined-builtin
  24. # Import Salt Testing libs
  25. from tests.support.case import ModuleCase
  26. from tests.support.mixins import LoaderModuleMockMixin, SaltReturnAssertsMixin
  27. from tests.support.runtests import RUNTIME_VARS
  28. from tests.support.helpers import (
  29. get_unused_localhost_port,
  30. requires_system_grains,
  31. patched_environ
  32. )
  33. from tests.support.mock import patch
  34. log = logging.getLogger(__name__)
  35. USERNAME = 'gitpillaruser'
  36. PASSWORD = 'saltrules'
  37. _OPTS = {
  38. '__role': 'minion',
  39. 'environment': None,
  40. 'pillarenv': None,
  41. 'hash_type': 'sha256',
  42. 'file_roots': {},
  43. 'state_top': 'top.sls',
  44. 'state_top_saltenv': None,
  45. 'renderer': 'yaml_jinja',
  46. 'renderer_whitelist': [],
  47. 'renderer_blacklist': [],
  48. 'pillar_merge_lists': False,
  49. 'git_pillar_base': 'master',
  50. 'git_pillar_fallback': '',
  51. 'git_pillar_branch': 'master',
  52. 'git_pillar_env': '',
  53. 'git_pillar_root': '',
  54. 'git_pillar_ssl_verify': True,
  55. 'git_pillar_global_lock': True,
  56. 'git_pillar_user': '',
  57. 'git_pillar_password': '',
  58. 'git_pillar_insecure_auth': False,
  59. 'git_pillar_privkey': '',
  60. 'git_pillar_pubkey': '',
  61. 'git_pillar_passphrase': '',
  62. 'git_pillar_refspecs': [
  63. '+refs/heads/*:refs/remotes/origin/*',
  64. '+refs/tags/*:refs/tags/*',
  65. ],
  66. 'git_pillar_includes': True,
  67. }
  68. PROC_TIMEOUT = 10
  69. class ProcessManager(object):
  70. '''
  71. Functions used both to set up self-contained SSH/HTTP servers for testing
  72. '''
  73. wait = 10
  74. def find_proc(self, name=None, search=None):
  75. def _search(proc):
  76. return any([search in x for x in proc.cmdline()])
  77. if name is None and search is None:
  78. raise ValueError('one of name or search is required')
  79. for proc in psutil.process_iter():
  80. if name is not None:
  81. try:
  82. if search is None:
  83. if name in proc.name():
  84. return proc
  85. elif name in proc.name() and _search(proc):
  86. return proc
  87. except psutil.NoSuchProcess:
  88. # Whichever process we are interrogating is no longer alive.
  89. # Skip it and keep searching.
  90. continue
  91. else:
  92. if _search(proc):
  93. return proc
  94. return None
  95. def wait_proc(self, name=None, search=None, timeout=PROC_TIMEOUT):
  96. for idx in range(1, self.wait + 1):
  97. proc = self.find_proc(name=name, search=search)
  98. if proc is not None:
  99. return proc
  100. else:
  101. if idx != self.wait:
  102. log.debug(
  103. 'Waiting for %s process (%d of %d)',
  104. name, idx, self.wait
  105. )
  106. time.sleep(1)
  107. else:
  108. log.debug(
  109. 'Failed fo find %s process after %d seconds',
  110. name, self.wait
  111. )
  112. raise Exception(
  113. 'Unable to find {0} process running from temp config file {1} '
  114. 'using psutil'.format(name, search)
  115. )
  116. class SSHDMixin(ModuleCase, ProcessManager, SaltReturnAssertsMixin):
  117. '''
  118. Functions to stand up an SSHD server to serve up git repos for tests.
  119. '''
  120. sshd_proc = None
  121. @classmethod
  122. def prep_server(cls):
  123. cls.sshd_config_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  124. cls.sshd_config = os.path.join(cls.sshd_config_dir, 'sshd_config')
  125. cls.sshd_port = get_unused_localhost_port()
  126. cls.url = 'ssh://{username}@127.0.0.1:{port}/~/repo.git'.format(
  127. username=cls.username,
  128. port=cls.sshd_port)
  129. cls.url_extra_repo = 'ssh://{username}@127.0.0.1:{port}/~/extra_repo.git'.format(
  130. username=cls.username,
  131. port=cls.sshd_port)
  132. home = '/root/.ssh'
  133. cls.ext_opts = {
  134. 'url': cls.url,
  135. 'url_extra_repo': cls.url_extra_repo,
  136. 'privkey_nopass': os.path.join(home, cls.id_rsa_nopass),
  137. 'pubkey_nopass': os.path.join(home, cls.id_rsa_nopass + '.pub'),
  138. 'privkey_withpass': os.path.join(home, cls.id_rsa_withpass),
  139. 'pubkey_withpass': os.path.join(home, cls.id_rsa_withpass + '.pub'),
  140. 'passphrase': cls.passphrase}
  141. def spawn_server(self):
  142. ret = self.run_function(
  143. 'state.apply',
  144. mods='git_pillar.ssh',
  145. pillar={'git_pillar': {'git_ssh': self.git_ssh,
  146. 'id_rsa_nopass': self.id_rsa_nopass,
  147. 'id_rsa_withpass': self.id_rsa_withpass,
  148. 'sshd_bin': self.sshd_bin,
  149. 'sshd_port': self.sshd_port,
  150. 'sshd_config_dir': self.sshd_config_dir,
  151. 'master_user': self.master_opts['user'],
  152. 'user': self.username}}
  153. )
  154. try:
  155. self.sshd_proc = self.wait_proc(name='sshd',
  156. search=self.sshd_config)
  157. finally:
  158. # Do the assert after we check for the PID so that we can track
  159. # it regardless of whether or not something else in the SLS
  160. # failed (but the SSH server still started).
  161. self.assertSaltTrueReturn(ret)
  162. class WebserverMixin(ModuleCase, ProcessManager, SaltReturnAssertsMixin):
  163. '''
  164. Functions to stand up an nginx + uWSGI + git-http-backend webserver to
  165. serve up git repos for tests.
  166. '''
  167. nginx_proc = uwsgi_proc = None
  168. @classmethod
  169. def prep_server(cls):
  170. '''
  171. Set up all the webserver paths. Designed to be run once in a
  172. setUpClass function.
  173. '''
  174. cls.root_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  175. cls.config_dir = os.path.join(cls.root_dir, 'config')
  176. cls.nginx_conf = os.path.join(cls.config_dir, 'nginx.conf')
  177. cls.uwsgi_conf = os.path.join(cls.config_dir, 'uwsgi.yml')
  178. cls.git_dir = os.path.join(cls.root_dir, 'git')
  179. cls.repo_dir = os.path.join(cls.git_dir, 'repos')
  180. cls.venv_dir = os.path.join(cls.root_dir, 'venv')
  181. cls.uwsgi_bin = os.path.join(cls.venv_dir, 'bin', 'uwsgi')
  182. cls.nginx_port = cls.uwsgi_port = get_unused_localhost_port()
  183. while cls.uwsgi_port == cls.nginx_port:
  184. # Ensure we don't hit a corner case in which two sucessive calls to
  185. # get_unused_localhost_port() return identical port numbers.
  186. cls.uwsgi_port = get_unused_localhost_port()
  187. cls.url = 'http://127.0.0.1:{port}/repo.git'.format(port=cls.nginx_port)
  188. cls.url_extra_repo = 'http://127.0.0.1:{port}/extra_repo.git'.format(port=cls.nginx_port)
  189. cls.ext_opts = {'url': cls.url, 'url_extra_repo': cls.url_extra_repo}
  190. # Add auth params if present (if so this will trigger the spawned
  191. # server to turn on HTTP basic auth).
  192. for credential_param in ('user', 'password'):
  193. if hasattr(cls, credential_param):
  194. cls.ext_opts[credential_param] = getattr(cls, credential_param)
  195. @requires_system_grains
  196. def spawn_server(self, grains):
  197. auth_enabled = hasattr(self, 'username') and hasattr(self, 'password')
  198. pillar = {'git_pillar': {'config_dir': self.config_dir,
  199. 'git_dir': self.git_dir,
  200. 'venv_dir': self.venv_dir,
  201. 'root_dir': self.root_dir,
  202. 'nginx_port': self.nginx_port,
  203. 'uwsgi_port': self.uwsgi_port,
  204. 'auth_enabled': auth_enabled}}
  205. # Different libexec dir for git backend on Debian-based systems
  206. git_core = '/usr/libexec/git-core' \
  207. if grains['os_family'] in ('RedHat') \
  208. else '/usr/lib/git-core'
  209. pillar['git_pillar']['git-http-backend'] = os.path.join(
  210. git_core,
  211. 'git-http-backend')
  212. ret = self.run_function(
  213. 'state.apply',
  214. mods='git_pillar.http',
  215. pillar=pillar)
  216. if not os.path.exists(pillar['git_pillar']['git-http-backend']):
  217. self.fail(
  218. '{0} not found. Either git is not installed, or the test '
  219. 'class needs to be updated.'.format(
  220. pillar['git_pillar']['git-http-backend']
  221. )
  222. )
  223. try:
  224. self.nginx_proc = self.wait_proc(name='nginx',
  225. search=self.nginx_conf)
  226. self.uwsgi_proc = self.wait_proc(name='uwsgi',
  227. search=self.uwsgi_conf)
  228. finally:
  229. # Do the assert after we check for the PID so that we can track
  230. # it regardless of whether or not something else in the SLS
  231. # failed (but the webserver still started).
  232. self.assertSaltTrueReturn(ret)
  233. class GitTestBase(ModuleCase):
  234. '''
  235. Base class for all gitfs/git_pillar tests. Must be subclassed and paired
  236. with either SSHDMixin or WebserverMixin to provide the server.
  237. '''
  238. case = port = bare_repo = base_extra_repo = admin_repo = admin_extra_repo = None
  239. maxDiff = None
  240. git_opts = '-c user.name="Foo Bar" -c user.email=foo@bar.com'
  241. ext_opts = {}
  242. # We need to temporarily skip pygit2 tests on EL7 until the EPEL packager
  243. # updates pygit2 to bring it up-to-date with libgit2.
  244. @requires_system_grains
  245. def is_el7(self, grains):
  246. return grains['os_family'] == 'RedHat' and grains['osmajorrelease'] == 7
  247. # Cent OS 6 has too old a version of git to handle the make_repo code, as
  248. # it lacks the -c option for git itself.
  249. @requires_system_grains
  250. def is_pre_el7(self, grains):
  251. return grains['os_family'] == 'RedHat' and grains['osmajorrelease'] < 7
  252. @classmethod
  253. def setUpClass(cls):
  254. cls.prep_server()
  255. def setUp(self):
  256. # Make the test class available to the tearDownClass so we can clean up
  257. # after ourselves. This (and the gated block below) prevent us from
  258. # needing to spend the extra time creating an ssh server and user and
  259. # then tear them down separately for each test.
  260. self.update_class(self)
  261. if self.is_pre_el7(): # pylint: disable=E1120
  262. self.skipTest(
  263. 'RHEL < 7 has too old a version of git to run these tests')
  264. @classmethod
  265. def update_class(cls, case):
  266. '''
  267. Make the test class available to the tearDownClass. Note that this
  268. cannot be defined in a parent class and inherited, as this will cause
  269. the parent class to be modified.
  270. '''
  271. if getattr(cls, 'case') is None:
  272. setattr(cls, 'case', case)
  273. def make_repo(self, root_dir, user='root'):
  274. raise NotImplementedError()
  275. class GitFSTestBase(GitTestBase, LoaderModuleMockMixin):
  276. '''
  277. Base class for all gitfs tests
  278. '''
  279. @requires_system_grains
  280. def setup_loader_modules(self, grains): # pylint: disable=W0221
  281. return {
  282. gitfs: {
  283. '__opts__': copy.copy(_OPTS),
  284. '__grains__': grains,
  285. }
  286. }
  287. def make_repo(self, root_dir, user='root'):
  288. raise NotImplementedError()
  289. class GitPillarTestBase(GitTestBase, LoaderModuleMockMixin):
  290. '''
  291. Base class for all git_pillar tests
  292. '''
  293. @requires_system_grains
  294. def setup_loader_modules(self, grains): # pylint: disable=W0221
  295. return {
  296. git_pillar: {
  297. '__opts__': copy.copy(_OPTS),
  298. '__grains__': grains,
  299. }
  300. }
  301. def get_pillar(self, ext_pillar_conf):
  302. '''
  303. Run git_pillar with the specified configuration
  304. '''
  305. cachedir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  306. self.addCleanup(shutil.rmtree, cachedir, ignore_errors=True)
  307. ext_pillar_opts = {'optimization_order': [0, 1, 2]}
  308. ext_pillar_opts.update(
  309. salt.utils.yaml.safe_load(
  310. ext_pillar_conf.format(
  311. cachedir=cachedir,
  312. extmods=os.path.join(cachedir, 'extmods'),
  313. **self.ext_opts
  314. )
  315. )
  316. )
  317. with patch.dict(git_pillar.__opts__, ext_pillar_opts):
  318. return git_pillar.ext_pillar(
  319. 'minion',
  320. {},
  321. *ext_pillar_opts['ext_pillar'][0]['git']
  322. )
  323. def make_repo(self, root_dir, user='root'):
  324. self.bare_repo = os.path.join(root_dir, 'repo.git')
  325. self.admin_repo = os.path.join(root_dir, 'admin')
  326. for dirname in (self.bare_repo, self.admin_repo):
  327. shutil.rmtree(dirname, ignore_errors=True)
  328. # Create bare repo
  329. self.run_function(
  330. 'git.init',
  331. [self.bare_repo],
  332. user=user,
  333. bare=True)
  334. # Clone bare repo
  335. self.run_function(
  336. 'git.clone',
  337. [self.admin_repo],
  338. url=self.bare_repo,
  339. user=user)
  340. def _push(branch, message):
  341. self.run_function(
  342. 'git.add',
  343. [self.admin_repo, '.'],
  344. user=user)
  345. self.run_function(
  346. 'git.commit',
  347. [self.admin_repo, message],
  348. user=user,
  349. git_opts=self.git_opts,
  350. )
  351. self.run_function(
  352. 'git.push',
  353. [self.admin_repo],
  354. remote='origin',
  355. ref=branch,
  356. user=user,
  357. )
  358. with salt.utils.files.fopen(
  359. os.path.join(self.admin_repo, 'top.sls'), 'w') as fp_:
  360. fp_.write(textwrap.dedent('''\
  361. base:
  362. '*':
  363. - foo
  364. '''))
  365. with salt.utils.files.fopen(
  366. os.path.join(self.admin_repo, 'foo.sls'), 'w') as fp_:
  367. fp_.write(textwrap.dedent('''\
  368. branch: master
  369. mylist:
  370. - master
  371. mydict:
  372. master: True
  373. nested_list:
  374. - master
  375. nested_dict:
  376. master: True
  377. '''))
  378. # Add another file to be referenced using git_pillar_includes
  379. with salt.utils.files.fopen(
  380. os.path.join(self.admin_repo, 'bar.sls'), 'w') as fp_:
  381. fp_.write('included_pillar: True\n')
  382. # Add another file in subdir
  383. os.mkdir(os.path.join(self.admin_repo, 'subdir'))
  384. with salt.utils.files.fopen(
  385. os.path.join(self.admin_repo, 'subdir', 'bar.sls'), 'w') as fp_:
  386. fp_.write('from_subdir: True\n')
  387. _push('master', 'initial commit')
  388. # Do the same with different values for "dev" branch
  389. self.run_function(
  390. 'git.checkout',
  391. [self.admin_repo],
  392. user=user,
  393. opts='-b dev')
  394. # The bar.sls shouldn't be in any branch but master
  395. self.run_function(
  396. 'git.rm',
  397. [self.admin_repo, 'bar.sls'],
  398. user=user)
  399. with salt.utils.files.fopen(
  400. os.path.join(self.admin_repo, 'top.sls'), 'w') as fp_:
  401. fp_.write(textwrap.dedent('''\
  402. dev:
  403. '*':
  404. - foo
  405. '''))
  406. with salt.utils.files.fopen(
  407. os.path.join(self.admin_repo, 'foo.sls'), 'w') as fp_:
  408. fp_.write(textwrap.dedent('''\
  409. branch: dev
  410. mylist:
  411. - dev
  412. mydict:
  413. dev: True
  414. nested_list:
  415. - dev
  416. nested_dict:
  417. dev: True
  418. '''))
  419. _push('dev', 'add dev branch')
  420. # Create just a top file in a separate repo, to be mapped to the base
  421. # env and referenced using git_pillar_includes
  422. self.run_function(
  423. 'git.checkout',
  424. [self.admin_repo],
  425. user=user,
  426. opts='-b top_only')
  427. # The top.sls should be the only file in this branch
  428. self.run_function(
  429. 'git.rm',
  430. [self.admin_repo, 'foo.sls', os.path.join('subdir', 'bar.sls')],
  431. user=user)
  432. with salt.utils.files.fopen(
  433. os.path.join(self.admin_repo, 'top.sls'), 'w') as fp_:
  434. fp_.write(textwrap.dedent('''\
  435. base:
  436. '*':
  437. - bar
  438. '''))
  439. _push('top_only', 'add top_only branch')
  440. # Create just another top file in a separate repo, to be mapped to the base
  441. # env and including mounted.bar
  442. self.run_function(
  443. 'git.checkout',
  444. [self.admin_repo],
  445. user=user,
  446. opts='-b top_mounted')
  447. # The top.sls should be the only file in this branch
  448. with salt.utils.files.fopen(
  449. os.path.join(self.admin_repo, 'top.sls'), 'w') as fp_:
  450. fp_.write(textwrap.dedent('''\
  451. base:
  452. '*':
  453. - mounted.bar
  454. '''))
  455. _push('top_mounted', 'add top_mounted branch')
  456. def make_extra_repo(self, root_dir, user='root'):
  457. self.bare_extra_repo = os.path.join(root_dir, 'extra_repo.git')
  458. self.admin_extra_repo = os.path.join(root_dir, 'admin_extra')
  459. for dirname in (self.bare_extra_repo, self.admin_extra_repo):
  460. shutil.rmtree(dirname, ignore_errors=True)
  461. # Create bare extra repo
  462. self.run_function(
  463. 'git.init',
  464. [self.bare_extra_repo],
  465. user=user,
  466. bare=True)
  467. # Clone bare repo
  468. self.run_function(
  469. 'git.clone',
  470. [self.admin_extra_repo],
  471. url=self.bare_extra_repo,
  472. user=user)
  473. def _push(branch, message):
  474. self.run_function(
  475. 'git.add',
  476. [self.admin_extra_repo, '.'],
  477. user=user)
  478. self.run_function(
  479. 'git.commit',
  480. [self.admin_extra_repo, message],
  481. user=user,
  482. git_opts=self.git_opts,
  483. )
  484. self.run_function(
  485. 'git.push',
  486. [self.admin_extra_repo],
  487. remote='origin',
  488. ref=branch,
  489. user=user,
  490. )
  491. with salt.utils.files.fopen(
  492. os.path.join(self.admin_extra_repo, 'top.sls'), 'w') as fp_:
  493. fp_.write(textwrap.dedent('''\
  494. "{{saltenv}}":
  495. '*':
  496. - motd
  497. - nowhere.foo
  498. '''))
  499. with salt.utils.files.fopen(
  500. os.path.join(self.admin_extra_repo, 'motd.sls'), 'w') as fp_:
  501. fp_.write(textwrap.dedent('''\
  502. motd: The force will be with you. Always.
  503. '''))
  504. _push('master', 'initial commit')
  505. class GitPillarSSHTestBase(GitPillarTestBase, SSHDMixin):
  506. '''
  507. Base class for GitPython and Pygit2 SSH tests
  508. '''
  509. id_rsa_nopass = id_rsa_withpass = None
  510. git_ssh = '/tmp/git_ssh'
  511. @classmethod
  512. def tearDownClass(cls):
  513. if cls.case is None:
  514. return
  515. if cls.case.sshd_proc is not None:
  516. cls.case.sshd_proc.send_signal(signal.SIGTERM)
  517. cls.case.run_state('user.absent', name=cls.username, purge=True)
  518. for dirname in (cls.sshd_config_dir, cls.case.admin_repo,
  519. cls.case.bare_repo):
  520. if dirname is not None:
  521. shutil.rmtree(dirname, ignore_errors=True)
  522. ssh_dir = os.path.expanduser('~/.ssh')
  523. for filename in (cls.id_rsa_nopass,
  524. cls.id_rsa_nopass + '.pub',
  525. cls.id_rsa_withpass,
  526. cls.id_rsa_withpass + '.pub',
  527. cls.git_ssh):
  528. try:
  529. os.remove(os.path.join(ssh_dir, filename))
  530. except OSError as exc:
  531. if exc.errno != errno.ENOENT:
  532. raise
  533. def setUp(self):
  534. '''
  535. Create the SSH server and user, and create the git repo
  536. '''
  537. super(GitPillarSSHTestBase, self).setUp()
  538. self.sshd_proc = self.find_proc(name='sshd',
  539. search=self.sshd_config)
  540. self.sshd_bin = salt.utils.path.which('sshd')
  541. if self.sshd_proc is None:
  542. self.spawn_server()
  543. known_hosts_ret = self.run_function(
  544. 'ssh.set_known_host',
  545. user=self.master_opts['user'],
  546. hostname='127.0.0.1',
  547. port=self.sshd_port,
  548. enc='ssh-rsa',
  549. fingerprint='fd:6f:7f:5d:06:6b:f2:06:0d:26:93:9e:5a:b5:19:46',
  550. hash_known_hosts=False,
  551. fingerprint_hash_type='md5',
  552. )
  553. if 'error' in known_hosts_ret:
  554. raise Exception(
  555. 'Failed to add key to {0} user\'s known_hosts '
  556. 'file: {1}'.format(
  557. self.master_opts['user'],
  558. known_hosts_ret['error']
  559. )
  560. )
  561. root_dir = os.path.expanduser('~{0}'.format(self.username))
  562. if root_dir.startswith('~'):
  563. self.fail(
  564. 'Unable to resolve homedir for user \'{0}\''.format(
  565. self.username
  566. )
  567. )
  568. self.make_repo(root_dir, user=self.username)
  569. self.make_extra_repo(root_dir, user=self.username)
  570. def get_pillar(self, ext_pillar_conf):
  571. '''
  572. Wrap the parent class' get_pillar() func in logic that temporarily
  573. changes the GIT_SSH to use our custom script, ensuring that the
  574. passphraselsess key is used to auth without needing to modify the root
  575. user's ssh config file.
  576. '''
  577. with patched_environ(GIT_SSH=self.git_ssh):
  578. return super(GitPillarSSHTestBase, self).get_pillar(ext_pillar_conf)
  579. class GitPillarHTTPTestBase(GitPillarTestBase, WebserverMixin):
  580. '''
  581. Base class for GitPython and Pygit2 HTTP tests
  582. '''
  583. @classmethod
  584. def tearDownClass(cls):
  585. for proc in (cls.case.nginx_proc, cls.case.uwsgi_proc):
  586. if proc is not None:
  587. try:
  588. proc.send_signal(signal.SIGQUIT)
  589. except psutil.NoSuchProcess:
  590. pass
  591. shutil.rmtree(cls.root_dir, ignore_errors=True)
  592. def setUp(self):
  593. '''
  594. Create and start the webserver, and create the git repo
  595. '''
  596. super(GitPillarHTTPTestBase, self).setUp()
  597. self.nginx_proc = self.find_proc(name='nginx',
  598. search=self.nginx_conf)
  599. self.uwsgi_proc = self.find_proc(name='uwsgi',
  600. search=self.uwsgi_conf)
  601. if self.nginx_proc is None and self.uwsgi_proc is None:
  602. self.spawn_server() # pylint: disable=E1120
  603. self.make_repo(self.repo_dir)
  604. self.make_extra_repo(self.repo_dir)