From 5ab53dc751919691415631e5381dcd6b317ff611 Mon Sep 17 00:00:00 2001 From: Slavek Kabrda Date: Aug 23 2018 15:30:05 +0000 Subject: Make it possible to only run gitolite post compilation stage when necessary --- diff --git a/pagure/flask_app.py b/pagure/flask_app.py index d619baf..58e6ea6 100644 --- a/pagure/flask_app.py +++ b/pagure/flask_app.py @@ -142,7 +142,9 @@ def generate_user_key_files(): for user in users: pagure.lib.update_user_ssh( flask.g.session, user, user.public_ssh_key, - pagure_config.get('GITOLITE_KEYDIR', None)) + pagure_config.get('GITOLITE_KEYDIR', None), + update_only=True, + ) pagure.lib.git.generate_gitolite_acls(project=None) diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 3b90f9c..2e2905e 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -3492,7 +3492,7 @@ def add_email_to_user(session, user, user_email): update_log_email_user(session, user_email, user) -def update_user_ssh(session, user, ssh_key, keydir): +def update_user_ssh(session, user, ssh_key, keydir, update_only=False): ''' Set up a new user into the database or update its information. ''' if isinstance(user, six.string_types): user = get_user(session, user) @@ -3500,7 +3500,10 @@ def update_user_ssh(session, user, ssh_key, keydir): user.public_ssh_key = ssh_key if keydir and user.public_ssh_key: create_user_ssh_keys_on_disk(user, keydir) - pagure.lib.git.generate_gitolite_acls(project=None) + if update_only: + pagure.lib.tasks.gitolite_post_compile_only.delay() + else: + pagure.lib.git.generate_gitolite_acls(project=None) session.add(user) session.flush() diff --git a/pagure/lib/git_auth.py b/pagure/lib/git_auth.py index 64a520f..6b8d8a8 100644 --- a/pagure/lib/git_auth.py +++ b/pagure/lib/git_auth.py @@ -724,6 +724,19 @@ class Gitolite3Auth(Gitolite2Auth): _log.debug('Command: %s', cmd) return cmd + @classmethod + def post_compile_only(cls): + """ This method runs `gitolite trigger POST_COMPILE` without touching + any other gitolite configuration. Most importantly, this will process + SSH keys used by gitolite. + """ + _log.info('Triggering gitolite POST_COMPILE') + gitolite_folder = pagure_config.get('GITOLITE_HOME', None) + if gitolite_folder: + cmd = 'HOME=%s gitolite trigger POST_COMPILE' % gitolite_folder + _log.debug('Command: %s', cmd) + cls._run_gitolite_cmd(cmd) + class GitAuthTestHelper(GitAuthHelper): """ Simple test auth module to check the auth customization system. """ diff --git a/pagure/lib/tasks.py b/pagure/lib/tasks.py index c3cea08..e4f0c44 100644 --- a/pagure/lib/tasks.py +++ b/pagure/lib/tasks.py @@ -162,6 +162,23 @@ def generate_gitolite_acls( @conn.task(queue=pagure_config.get('GITOLITE_CELERY_QUEUE', None), bind=True) @pagure_task +def gitolite_post_compile_only(self, session): + """ Do gitolite post-processing only. Most importantly, this processes SSH + keys used by gitolite. This is an optimization task that's supposed to be + used if you only need to run `gitolite trigger POST_COMPILE` without + touching any other gitolite configuration + """ + helper = pagure.lib.git_auth.get_git_auth_helper( + pagure_config['GITOLITE_BACKEND']) + _log.debug('Got helper: %s', helper) + if hasattr(helper, 'post_compile_only'): + helper.post_compile_only() + else: + helper.generate_acls(project=None) + + +@conn.task(queue=pagure_config.get('GITOLITE_CELERY_QUEUE', None), bind=True) +@pagure_task def delete_project( self, session, namespace=None, name=None, user=None, action_user=None): """ Delete a project in pagure. diff --git a/pagure/ui/app.py b/pagure/ui/app.py index a03a31d..1065027 100644 --- a/pagure/ui/app.py +++ b/pagure/ui/app.py @@ -1077,6 +1077,7 @@ def user_settings(): user=user, ssh_key=ssh_key, keydir=pagure_config.get('GITOLITE_KEYDIR', None), + update_only=True, ) flask.g.session.commit() message = 'Public ssh key updated' diff --git a/tests/test_pagure_lib.py b/tests/test_pagure_lib.py index 14f1ed5..1b4af4b 100644 --- a/tests/test_pagure_lib.py +++ b/tests/test_pagure_lib.py @@ -2205,6 +2205,16 @@ class PagureLibtests(tests.Modeltests): user = pagure.lib.search_user(self.session, username='foo') self.assertEqual(user.public_ssh_key, None) + @patch('pagure.lib.tasks.gitolite_post_compile_only.delay') + def test_update_user_ssh_update_only(self, gitolite_post_compile_only): + """ Test that update_user_ssh method called with update_only=True + calls the gitolite_post_compile_only method of helper. """ + user = pagure.lib.search_user(self.session, username='foo') + msg = pagure.lib.update_user_ssh( + self.session, user, 'blah', keydir='/tmp', update_only=True + ) + gitolite_post_compile_only.assert_called_once() + def avatar_url_from_email(self): """ Test the avatar_url_from_openid of pagure.lib. """ output = pagure.lib.avatar_url_from_email('pingou@fedoraproject.org') diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 7aa5a64..ae8e375 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -1,4 +1,4 @@ -from mock import patch, Mock +from mock import patch, MagicMock, Mock from collections import namedtuple import os import unittest @@ -114,3 +114,22 @@ class TestCommitsAuthorStats(unittest.TestCase): self.assertEqual(last_time, '2018-01-01 00:00') self.assertEqual(authors, [(2, [('Alice', None)]), (1, [('Bob', '')])]) + + +class TestGitolitePostCompileOnly(object): + @patch('pagure.lib.git_auth.get_git_auth_helper') + def test_backend_has_post_compile_only(self, get_helper): + helper = MagicMock() + get_helper.return_value = helper + helper.post_compile_only = MagicMock() + tasks.gitolite_post_compile_only() + helper.post_compile_only.assert_called_once() + + @patch('pagure.lib.git_auth.get_git_auth_helper') + def test_backend_doesnt_have_post_compile_only(self, get_helper): + helper = MagicMock() + get_helper.return_value = helper + helper.generate_acls = MagicMock() + del helper.post_compile_only + tasks.gitolite_post_compile_only() + helper.generate_acls.assert_called_once_with(project=None)