SHA256
1
0
forked from pool/pagure

Accepting request 639243 from home:Pharaoh_Atem:SUSE_Pagure

Initial packaging of Pagure for openSUSE

OBS-URL: https://build.opensuse.org/request/show/639243
OBS-URL: https://build.opensuse.org/package/show/devel:tools:scm/pagure?expand=0&rev=1
This commit is contained in:
Martin Pluskal 2018-10-01 11:28:15 +00:00 committed by Git OBS Bridge
commit b12f70e978
8 changed files with 1357 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.osc

349
flask_fas_openid.py Normal file
View File

@ -0,0 +1,349 @@
# -*- coding: utf-8 -*-
# Flask-FAS-OpenID - A Flask extension for authorizing users with FAS-OpenID
#
# Primary maintainer: Patrick Uiterwijk <puiterwijk@fedoraproject.org>
#
# Copyright (c) 2013, Patrick Uiterwijk
# This file is part of python-fedora
#
# python-fedora is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# python-fedora is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with python-fedora; if not, see <http://www.gnu.org/licenses/>
'''
FAS-OpenID authentication plugin for the flask web framework
.. moduleauthor:: Patrick Uiterwijk <puiterwijk@fedoraproject.org>
..versionadded:: 0.3.33
'''
from functools import wraps
import logging
import time
from munch import Munch
import flask
try:
from flask import _app_ctx_stack as stack
except ImportError:
from flask import _request_ctx_stack as stack
from openid.consumer import consumer
from openid.fetchers import setDefaultFetcher, Urllib2Fetcher
from openid.extensions import pape, sreg, ax
from openid_cla import cla
from openid_teams import teams
import six
log = logging.getLogger(__name__)
# http://flask.pocoo.org/snippets/45/
def request_wants_json():
''' Return wether the user requested the data in JSON or not. '''
best = flask.request.accept_mimetypes \
.best_match(['application/json', 'text/html'])
return best == 'application/json' and \
flask.request.accept_mimetypes[best] > \
flask.request.accept_mimetypes['text/html']
class FASJSONEncoder(flask.json.JSONEncoder):
""" Dedicated JSON encoder for the FAS openid information. """
def default(self, o):
"""Implement this method in a subclass such that it returns a
serializable object for ``o``, or calls the base implementation (to
raise a ``TypeError``).
For example, to support arbitrary iterators, you could implement
default like this::
def default(self, o):
try:
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
return JSONEncoder.default(self, o)
"""
if isinstance(o, (set, frozenset)):
return list(o)
return flask.json.JSONEncoder.default(self, o)
class FAS(object):
""" The Flask plugin. """
def __init__(self, app=None):
self.postlogin_func = None
self.app = app
if self.app is not None:
self.init_app(app)
def init_app(self, app):
""" Constructor for the Flask application. """
self.app = app
app.config.setdefault('FAS_OPENID_ENDPOINT',
'https://id.fedoraproject.org/openid/')
app.config.setdefault('FAS_OPENID_CHECK_CERT', True)
if not self.app.config['FAS_OPENID_CHECK_CERT']:
setDefaultFetcher(Urllib2Fetcher())
# json_encoder is only available from flask 0.10
version = flask.__version__.split('.')
assume_recent = False
try:
major = int(version[0])
minor = int(version[1])
except ValueError:
# We'll assume we're using a recent enough flask as the packages
# of old versions used sane version numbers.
assume_recent = True
if assume_recent or (major > 0 or minor >= 10):
self.app.json_encoder = FASJSONEncoder
@app.route('/_flask_fas_openid_handler/', methods=['GET', 'POST'])
def flask_fas_openid_handler():
""" Endpoint for OpenID results. """
return self._handle_openid_request()
app.before_request(self._check_session)
def postlogin(self, f):
"""Marks a function as post login handler. This decorator calls your
function after the login has been performed.
"""
self.postlogin_func = f
return f
def _handle_openid_request(self):
return_url = flask.session.get('FLASK_FAS_OPENID_RETURN_URL', None)
cancel_url = flask.session.get('FLASK_FAS_OPENID_CANCEL_URL', None)
base_url = self.normalize_url(flask.request.base_url)
oidconsumer = consumer.Consumer(flask.session, None)
info = oidconsumer.complete(flask.request.values, base_url)
display_identifier = info.getDisplayIdentifier()
if info.status == consumer.FAILURE and display_identifier:
return 'FAILURE. display_identifier: %s' % display_identifier
elif info.status == consumer.CANCEL:
if cancel_url:
return flask.redirect(cancel_url)
return 'OpenID request was cancelled'
elif info.status == consumer.SUCCESS:
if info.endpoint.server_url != \
self.app.config['FAS_OPENID_ENDPOINT']:
log.warn('Claim received from invalid issuer: %s',
info.endpoint.server_url)
return 'Invalid provider issued claim!'
sreg_resp = sreg.SRegResponse.fromSuccessResponse(info)
teams_resp = teams.TeamsResponse.fromSuccessResponse(info)
cla_resp = cla.CLAResponse.fromSuccessResponse(info)
ax_resp = ax.FetchResponse.fromSuccessResponse(info)
user = {'fullname': '', 'username': '', 'email': '',
'timezone': '', 'cla_done': False, 'groups': []}
if not sreg_resp:
# If we have no basic info, be gone with them!
return flask.redirect(cancel_url)
user['username'] = sreg_resp.get('nickname')
user['fullname'] = sreg_resp.get('fullname')
user['email'] = sreg_resp.get('email')
user['timezone'] = sreg_resp.get('timezone')
user['login_time'] = time.time()
if cla_resp:
user['cla_done'] = cla.CLA_URI_FEDORA_DONE in cla_resp.clas
if teams_resp:
# The groups do not contain the cla_ groups
user['groups'] = frozenset(teams_resp.teams)
if ax_resp:
ssh_keys = ax_resp.get(
'http://fedoauth.org/openid/schema/SSH/key')
if isinstance(ssh_keys, (list, tuple)):
ssh_keys = '\n'.join(
ssh_key
for ssh_key in ssh_keys
if ssh_key.strip()
)
if ssh_keys:
user['ssh_key'] = ssh_keys
user['gpg_keyid'] = ax_resp.get(
'http://fedoauth.org/openid/schema/GPG/keyid')
flask.session['FLASK_FAS_OPENID_USER'] = user
flask.session.modified = True
if self.postlogin_func is not None:
self._check_session()
return self.postlogin_func(return_url)
else:
return flask.redirect(return_url)
else:
return 'Strange state: %s' % info.status
def _check_session(self):
if 'FLASK_FAS_OPENID_USER' not in flask.session \
or flask.session['FLASK_FAS_OPENID_USER'] is None:
flask.g.fas_user = None
else:
user = flask.session['FLASK_FAS_OPENID_USER']
# Add approved_memberships to provide backwards compatibility
# New applications should only use g.fas_user.groups
user['approved_memberships'] = []
for group in user['groups']:
membership = dict()
membership['name'] = group
user['approved_memberships'].append(Munch.fromDict(membership))
flask.g.fas_user = Munch.fromDict(user)
flask.g.fas_user.groups = frozenset(flask.g.fas_user.groups)
flask.g.fas_session_id = 0
def _check_safe_root(self, url):
if url is None:
return None
if url.startswith(flask.request.url_root) or url.startswith('/'):
# A URL inside the same app is deemed to always be safe
return url
return None
def login(self, username=None, password=None, return_url=None,
cancel_url=None, groups=['_FAS_ALL_GROUPS_']):
"""Tries to log in a user.
Sets the user information on :attr:`flask.g.fas_user`.
Will set 0 to :attr:`flask.g.fas_session_id, for compatibility
with flask_fas.
:kwarg username: Not used, but accepted for compatibility with the
flask_fas module
:kwarg password: Not used, but accepted for compatibility with the
flask_fas module
:kwarg return_url: The URL to forward the user to after login
:kwarg groups: A string or a list of group the user should belong
to to be authentified.
:returns: True if the user was succesfully authenticated.
:raises: Might raise an redirect to the OpenID endpoint
"""
if return_url is None:
if 'next' in flask.request.args.values():
return_url = flask.request.args.values['next']
else:
return_url = flask.request.url_root
# This makes sure that we only allow stuff where
# ?next= value is in a safe root (the application
# root)
return_url = (self._check_safe_root(return_url) or
flask.request.url_root)
session = {}
oidconsumer = consumer.Consumer(session, None)
try:
request = oidconsumer.begin(self.app.config['FAS_OPENID_ENDPOINT'])
except consumer.DiscoveryFailure as exc:
# VERY strange, as this means it could not discover an OpenID
# endpoint at FAS_OPENID_ENDPOINT
log.warn(exc)
return 'discoveryfailure'
if request is None:
# Also very strange, as this means the discovered OpenID
# endpoint is no OpenID endpoint
return 'no-request'
if isinstance(groups, six.string_types):
groups = [groups]
request.addExtension(sreg.SRegRequest(
required=['nickname', 'fullname', 'email', 'timezone']))
request.addExtension(pape.Request([]))
request.addExtension(teams.TeamsRequest(requested=groups))
request.addExtension(cla.CLARequest(
requested=[cla.CLA_URI_FEDORA_DONE]))
ax_req = ax.FetchRequest()
ax_req.add(ax.AttrInfo(
type_uri='http://fedoauth.org/openid/schema/GPG/keyid'))
ax_req.add(ax.AttrInfo(
type_uri='http://fedoauth.org/openid/schema/SSH/key',
count='unlimited'))
request.addExtension(ax_req)
trust_root = self.normalize_url(flask.request.url_root)
return_to = trust_root + '_flask_fas_openid_handler/'
flask.session['FLASK_FAS_OPENID_RETURN_URL'] = return_url
flask.session['FLASK_FAS_OPENID_CANCEL_URL'] = cancel_url
if request_wants_json():
output = request.getMessage(trust_root,
return_to=return_to).toPostArgs()
output['server_url'] = request.endpoint.server_url
return flask.jsonify(output)
elif request.shouldSendRedirect():
redirect_url = request.redirectURL(trust_root, return_to, False)
return flask.redirect(redirect_url)
else:
return request.htmlMarkup(
trust_root, return_to,
form_tag_attrs={'id': 'openid_message'}, immediate=False)
def logout(self):
'''Logout the user associated with this session
'''
flask.session['FLASK_FAS_OPENID_USER'] = None
flask.g.fas_session_id = None
flask.g.fas_user = None
flask.session.modified = True
def normalize_url(self, url):
''' Replace the scheme prefix of a url with our preferred scheme.
'''
scheme = self.app.config['PREFERRED_URL_SCHEME']
scheme_index = url.index('://')
return scheme + url[scheme_index:]
# This is a decorator we can use with any HTTP method (except login, obviously)
# to require a login.
# If the user is not logged in, it will redirect them to the login form.
# http://flask.pocoo.org/docs/patterns/viewdecorators/#login-required-decorator
def fas_login_required(function):
""" Flask decorator to ensure that the user is logged in against FAS.
To use this decorator you need to have a function named 'auth_login'.
Without that function the redirect if the user is not logged in will not
work.
"""
@wraps(function)
def decorated_function(*args, **kwargs):
if flask.g.fas_user is None:
return flask.redirect(flask.url_for('auth_login',
next=flask.request.url))
return function(*args, **kwargs)
return decorated_function
def cla_plus_one_required(function):
""" Flask decorator to retrict access to CLA+1.
To use this decorator you need to have a function named 'auth_login'.
Without that function the redirect if the user is not logged in will not
work.
"""
@wraps(function)
def decorated_function(*args, **kwargs):
if flask.g.fas_user is None or not flask.g.fas_user.cla_done \
or len(flask.g.fas_user.groups) < 1:
# FAS-OpenID does not return cla_ groups
return flask.redirect(flask.url_for('auth_login',
next=flask.request.url))
else:
return function(*args, **kwargs)
return decorated_function

View File

@ -0,0 +1,130 @@
diff -rup pagure-5.0/files/gitolite3.rc pagure-5.0.cfg-defs/files/gitolite3.rc
--- pagure-5.0/files/gitolite3.rc 2018-08-20 05:28:38.000000000 -0400
+++ pagure-5.0.cfg-defs/files/gitolite3.rc 2018-09-24 17:29:01.927780974 -0400
@@ -16,7 +16,7 @@
# ------------------------------------------------------------------
- GL_REPO_BASE => '/path/to/git/repositories',
+ GL_REPO_BASE => '/srv/gitolite/repositories',
# default umask gives you perms of '0700'; see the rc file docs for
# how/why you might change this
diff -rup pagure-5.0/files/pagure.cfg.sample pagure-5.0.cfg-defs/files/pagure.cfg.sample
--- pagure-5.0/files/pagure.cfg.sample 2018-09-24 15:57:50.000000000 -0400
+++ pagure-5.0.cfg-defs/files/pagure.cfg.sample 2018-09-24 17:29:01.928780964 -0400
@@ -68,21 +68,21 @@ GIT_URL_GIT = 'git://localhost.localdoma
### Folder containing to the git repos
GIT_FOLDER = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- '..',
- 'repos'
+ '/srv',
+ 'gitolite',
+ 'repositories'
)
REPOSPANNER_PSEUDO_FOLDER = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- '..',
+ '/srv',
+ 'gitolite',
'pseudo'
)
### Folder containing the clones for the remote pull-requests
REMOTE_GIT_FOLDER = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- '..',
+ '/srv',
+ 'gitolite',
'remotes'
)
@@ -92,21 +92,23 @@ VIRUS_SCAN_ATTACHMENTS = False
### Configuration file for gitolite
GITOLITE_CONFIG = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- '..',
+ '/srv',
+ 'gitolite',
+ '.gitolite',
+ 'conf',
'gitolite.conf'
)
### Home folder of the gitolite user
### Folder where to run gl-compile-conf from
-GITOLITE_HOME = None
+GITOLITE_HOME = '/srv/gitolite'
### Version of gitolite used: 2 or 3?
GITOLITE_VERSION = 3
### Folder containing all the public ssh keys for gitolite
-GITOLITE_KEYDIR = None
+GITOLITE_KEYDIR = os.path.join(GITOLITE_HOME, '.gitolite', 'keydir')
### Path to the gitolite.rc file
GL_RC = None
diff -rup pagure-5.0/files/pagure.conf pagure-5.0.cfg-defs/files/pagure.conf
--- pagure-5.0/files/pagure.conf 2018-08-23 15:08:03.000000000 -0400
+++ pagure-5.0.cfg-defs/files/pagure.conf 2018-09-24 17:29:01.928780964 -0400
@@ -29,9 +29,9 @@
## Use secure TLSv1.1 and TLSv1.2 ciphers
#Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
- #SSLCertificateFile /etc/pki/tls/....crt
- #SSLCertificateChainFile /etc/pki/tls/....intermediate.crt
- #SSLCertificateKeyFile /etc/pki/tls/....key
+ #SSLCertificateFile /etc/ssl/....crt
+ #SSLCertificateChainFile /etc/ssl/....intermediate.crt
+ #SSLCertificateKeyFile /etc/ssl/....key
#Alias /static /usr/lib/pythonX.Y/site-packages/pagure/static/
@@ -60,24 +60,24 @@
## Use secure TLSv1.1 and TLSv1.2 ciphers
#Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
- #SSLCertificateFile /etc/pki/tls/....crt
- #SSLCertificateChainFile /etc/pki/tls/....intermediate.crt
- #SSLCertificateKeyFile /etc/pki/tls/....key
+ #SSLCertificateFile /etc/ssl/....crt
+ #SSLCertificateChainFile /etc/ssl/....intermediate.crt
+ #SSLCertificateKeyFile /etc/ssl/....key
#Alias /static /usr/lib/pythonX.Y/site-packages/pagure/static/
- #Alias /releases /var/www/releases
+ #Alias /releases /srv/www/pagure-releases
## Section used to support cloning git repo over http (https in this case)
- #SetEnv GIT_PROJECT_ROOT /path/to/git/repositories
+ #SetEnv GIT_PROJECT_ROOT /srv/gitolite/repositories
- #AliasMatch ^/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /path/to/git/repositories/$1
- #AliasMatch ^/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /path/to/git/repositories/$1
+ #AliasMatch ^/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /srv/gitolite/repositories/$1
+ #AliasMatch ^/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /srv/gitolite/repositories/$1
#ScriptAliasMatch \
#"(?x)^/(.*/(HEAD | \
#info/refs | \
#objects/info/[^/]+ | \
#git-(upload|receive)-pack))$" \
- #/usr/libexec/git-core/git-http-backend/$1
+ #/usr/lib/git/git-http-backend/$1
#<Location />
#WSGIProcessGroup pagure
@@ -106,7 +106,7 @@
#</IfModule>
#</Location>
- #<Directory /var/www/releases>
+ #<Directory /srv/www/pagure-releases>
#Options +Indexes
#</Directory>

3
pagure-5.0.1.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f80add9dd706e5b59f0b1f9cf44fe2820b5b2573aea390602c17cbd3a742da58
size 21696775

107
pagure-README.SUSE Normal file
View File

@ -0,0 +1,107 @@
# Setting up pagure
0. Prepare the filesystem (this step is usually performed on package install)
mkdir -p /srv/www/pagure-releases
mkdir -p /srv/gitolite/repositories/{,docs,forks,requests,tickets}
mkdir -p /srv/gitolite/pseudo
mkdir -p /srv/gitolite/remotes
mkdir -p /srv/gitolite/.gitolite/{conf,keydir,logs}
touch /srv/gitolite/.gitolite/conf/gitolite.conf
cp /usr/share/doc/packages/pagure/gitolite3.rc /srv/gitolite/.gitolite.rc
chown git:git -R /srv/gitolite
chown git:git /srv/www/pagure-releases
mkdir -p /srv/www/run
setfacl -m user:wwwrun:rx --default /srv/gitolite
setfacl -Rdm user:wwwrun:rx /srv/gitolite
setfacl -Rm user:wwwrun:rx /srv/gitolite
1. Install and set up a database
Option A: PostgreSQL
Note: If your PostgreSQL server is not on the same machine, just install 'python3-psycopg2'
on the pagure host machine and follow the installation and database creation steps below
on the designated database server. This also requires the database port opened on the
database server's firewall.
zypper install postgresql-server
systemctl start postgresql
A1. Edit /var/lib/pgsql/data/pg_hba.conf and change auth method from `ident` to `md5` for localhost
A2. Create the pagure database
sudo -u postgres psql
CREATE DATABASE pagure;
CREATE USER pagure;
ALTER USER pagure WITH ENCRYPTED PASSWORD '--PagureDBUserPW--';
GRANT ALL PRIVILEGES ON DATABASE pagure to pagure;
GRANT ALL PRIVILEGES ON ALL tables IN SCHEMA public TO pagure;
GRANT ALL PRIVILEGES ON ALL sequences IN SCHEMA public TO pagure;
\q
A3. Enable and restart PostgreSQL
systemctl stop postgresql
systemctl enable --now postgresql
Option B: MariaDB
Note: If your MariaDB server is not on the same machine, just install 'python3-PyMySQL'
on the pagure host machine and follow the installation and database creation steps below
on the designated database server. This also requires the database port opened on the
database server's firewall.
zypper install mariadb mariadb-client
systemctl enable --now mariadb
mysql_secure_installation
B1. Create the pagure database
mysql -u root -p
mysql> create database pagure;
mysql> grant all privileges on pagure.* to pagure identified by '--PagureDBUserPW--';
mysql> flush privileges;
mysql> exit
2. Install Redis
zypper install redis
3. Configure redis
cp /etc/redis/default.conf.example /etc/redis/default.conf
chown root:redis /etc/redis/default.conf
systemctl enable --now redis@default.service
4. Edit /etc/pagure/pagure.cfg to set up pagure settings as appropriate.
For details on all the options in pagure.cfg, see https://docs.pagure.org/pagure/configuration.html
5. Populate the database
python3 /usr/share/pagure/pagure_createdb.py -c /etc/pagure/pagure.cfg -i /etc/pagure/alembic.ini
6. Edit /etc/apache2/vhosts.d/pagure.conf to set up web settings as appropriate.
7. Open ports in the firewall as appropriate
firewall-cmd --add-service=ssh
firewall-cmd --add-service=http
firewall-cmd --add-service=https
firewall-cmd --add-service=redis
firewall-cmd --runtime-to-permanent
8. Enable and start pagure_worker and pagure_gitolite_worker
9. Enable and start apache2, or restart if it's already running
For more details on setup, take a look at the official Pagure documentation: https://docs.pagure.org/pagure/

109
pagure.changes Normal file
View File

@ -0,0 +1,109 @@
-------------------------------------------------------------------
Sun Sep 30 15:06:24 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Add missing directory to directory structure
-------------------------------------------------------------------
Sat Sep 29 22:28:26 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Drop unnecessary systemd build dependency
-------------------------------------------------------------------
Sat Sep 29 21:15:49 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Add missing rcFOO symlinks to systemd services
-------------------------------------------------------------------
Sat Sep 29 20:29:04 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Update to 5.0.1
+ Multiple adjustments to the scripts keyhelper and aclchecker
+ Only enforce Signed-Off-By on the code repo of a project
+ Sign-off the merge commits when the project enforces it
+ Switch from GIT_SORT_TIME to GIT_SORT_NONE to preserve
'git log'-like commit ordering
+ Add reporter and assignee to notification emails headers
+ Fix various visual glitches
- Restore symlinks clobbered by setuptools' creation of archive
-------------------------------------------------------------------
Mon Sep 24 21:35:35 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Rebase to 5.0
+ Pagure now runs on Python 3
+ The UI has been completely redesigned
+ Theming has been redesigned, and new themes are included as subpackages
+ Many new API endpoints have been added
+ Rework how git hooks work to rely on a single file for efficiency
+ Expanded functionality included in the pagure-admin command
- Pagure defaults to the chameleon theme for openSUSE
- Drop all upstreamed patches
- Refresh example configuration patch
-------------------------------------------------------------------
Sun Jul 22 00:48:43 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Update to 4.0.4
- Refresh config fix patch for pagure-milters
-------------------------------------------------------------------
Wed Jul 11 04:05:20 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Add missing requirement on python-Pillow
-------------------------------------------------------------------
Wed Jul 11 01:21:18 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Drop python2-trollius-redis requirement since it's not actually used
-------------------------------------------------------------------
Sun Jun 10 00:04:18 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Backport patch to make syntax highlighting threshold configurable
-------------------------------------------------------------------
Sat Jun 9 21:56:34 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Bundle an internal pagure-celery binary to use stock celery
with Python 2
- Switch to a sed call instead of a patch to fix systemd units
to use correct libexecdir
-------------------------------------------------------------------
Sat Jun 9 13:20:33 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Fix syntax error in gitolite3.rc file
-------------------------------------------------------------------
Fri Jun 8 11:13:43 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Switch from /srv/pagure to /srv/gitolite to use the already
setup gitolite directory structure
-------------------------------------------------------------------
Mon Jun 4 04:45:53 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Fix pagure-ev to use correct libexecdir
- Fix pagure-milters to call correct function to load config
-------------------------------------------------------------------
Mon Jun 4 03:36:38 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Install gitolite configuration
-------------------------------------------------------------------
Mon Jun 4 01:15:19 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Prepare more of the filesystem tree as part of the packaging
- Refine README.SUSE to more closely match the required steps
-------------------------------------------------------------------
Sat Jun 2 17:44:49 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Refresh configuration patch to match SUSE sematics
- Add README.SUSE file for basic setup quick start guide
-------------------------------------------------------------------
Mon May 28 22:00:06 UTC 2018 - Neal Gompa <ngompa13@gmail.com>
- Initial packaging based on Mageia packaging

635
pagure.spec Normal file
View File

@ -0,0 +1,635 @@
#
# spec file for package pagure
#
# Copyright (c) 2018 Neal Gompa <ngompa13@gmail.com>.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
# Prevent dep generators from trying to process static stuff and stall out
# We only need to read the python metadata anyway
%global __provides_exclude_from ^%{python3_sitelib}/pagure/.*$
%global __requires_exclude_from ^%{python3_sitelib}/pagure/.*$
Name: pagure
Version: 5.0.1
Release: 0
Summary: A git-centered forge
Group: Development/Tools/Version Control
# Pagure itself is GPL-2.0-or-later; flask_fas_openid.py is LGPL-2.1-or-later
License: GPL-2.0-or-later AND LGPL-2.1-or-later
URL: https://pagure.io/pagure
Source0: https://pagure.io/releases/pagure/%{name}-%{version}.tar.gz
# Vendor in the single file from python-fedora that's needed
# This way, we avoid having to pull in all of python-fedora
# This file is licensed LGPL-2.1-or-later, per https://github.com/fedora-infra/python-fedora/blob/develop/README.rst#license
Source1: https://raw.githubusercontent.com/fedora-infra/python-fedora/4719f10b3af1cf068e969387eab7df7e935003cd/flask_fas_openid.py
# SUSE-specific README providing a quickstart guide
Source10: pagure-README.SUSE
# SUSE-specific fixes
# Change the defaults in the example config to match packaging
Patch1000: pagure-5.0-default-example-cfg.patch
BuildArch: noarch
BuildRequires: apache2
BuildRequires: fdupes
BuildRequires: systemd-rpm-macros
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-alembic
BuildRequires: python3-arrow
BuildRequires: python3-bcrypt
BuildRequires: python3-binaryornot
BuildRequires: python3-bleach
BuildRequires: python3-blinker
BuildRequires: python3-chardet
BuildRequires: python3-cryptography
BuildRequires: python3-docutils
BuildRequires: python3-Flask
BuildRequires: python3-Flask-WTF
# Pagure is currently not compatible with Markdown v3
BuildRequires: python3-Markdown < 3
BuildRequires: python3-nose
BuildRequires: python3-Pillow
BuildRequires: python3-psutil
BuildRequires: python3-pygit2 >= 0.24.0
BuildRequires: python3-Pygments
#BuildRequires: python3-fedora-flask
BuildRequires: python3-python3-openid
BuildRequires: python3-python-openid-cla
BuildRequires: python3-python-openid-teams
BuildRequires: python3-SQLAlchemy > 0.8
BuildRequires: python3-straight-plugin
BuildRequires: python3-WTForms
BuildRequires: python3-munch
BuildRequires: python3-redis
Requires: python3-alembic
Requires: python3-arrow
Requires: python3-bcrypt
Requires: python3-binaryornot
Requires: python3-bleach
Requires: python3-blinker
Requires: python3-celery
Requires: python3-chardet
Requires: python3-cryptography
Requires: python3-docutils
Requires: python3-Flask
Requires: python3-Flask-WTF
# Pagure is currently not compatible with Markdown v3
Requires: python3-Markdown < 3
Requires: python3-Pillow
Requires: python3-psutil
Requires: python3-pygit2 >= 0.24.0
Requires: python3-Pygments
#Requires: python3-fedora-flask
Requires: python3-python3-openid
Requires: python3-python-openid-cla
Requires: python3-python-openid-teams
Requires: python3-SQLAlchemy > 0.8
Requires: python3-straight-plugin
Requires: python3-WTForms
Requires: python3-munch
Requires: python3-redis
Requires: apache2-mod_wsgi-python3
# Required for celery
Requires: python3-pytz
# Required for database setup/migrations
Requires: python3-dbm
Requires: python3-kitchen
Requires: python3-requests
# If using PostgreSQL, the correct driver should be installed
Recommends: (python3-psycopg2 if postgresql-server)
# If using MariaDB/MySQL, the correct driver should be installed
Recommends: (python3-PyMySQL if mysql-server)
# The default theme is required
Requires: %{name}-theme-default
%{?systemd_requires}
# No dependency of the app per se, but required to make it working.
OrderWithRequires: gitolite >= 3.0
Requires(pre): gitolite >= 3.0
Requires: gitolite >= 3.0
Requires(post): user(wwwrun)
%description
Pagure is a light-weight git-centered forge based on pygit2.
Currently, Pagure offers a web-interface for git repositories, a ticket
system and possibilities to create new projects, fork existing ones and
create/merge pull-requests across or within projects.
For steps on how to set up the system after installing this package,
please read %{_docdir}/%{name}/README.SUSE.
%package theme-upstream
Summary: Base web interface theme
Requires: %{name} = %{version}-%{release}
%description theme-upstream
This package provides the web interface assets for styling
a Pagure server with the base upstream look and feel.
%package theme-pagureio
Summary: Web interface theme used for Pagure.io
Requires: %{name} = %{version}-%{release}
%description theme-pagureio
This package provides the web interface assets for styling
a Pagure server with the same look and feel as Pagure.io.
%package theme-srcfpo
Summary: Web interface theme used for src.fedoraproject.org
Requires: %{name} = %{version}-%{release}
%description theme-srcfpo
This package provides the web interface assets for styling
a Pagure server with the same look and feel as src.fedoraproject.org.
%package theme-chameleon
Summary: Web interface based on openSUSE's chameleon theme
Requires: %{name} = %{version}-%{release}
%description theme-chameleon
This package provides the web interface assets for styling
a Pagure server with the same look and feel as openSUSE Infrastructure.
%package theme-default-upstream
Summary: Default web interface theme from upstream
Conflicts: %{name}-theme-default
Provides: %{name}-theme-default
Requires: %{name}-theme-upstream = %{version}-%{release}
%description theme-default-upstream
This package sets the default web interface assets used for
a Pagure server running as shipped by upstream.
%package theme-default-openSUSE
Summary: Default web interface theme for openSUSE
Conflicts: %{name}-theme-default
Provides: %{name}-theme-default
Requires: %{name}-theme-chameleon = %{version}-%{release}
Enhances: (%{name} and branding-openSUSE)
RemovePathPostfixes: .openSUSE
%description theme-default-openSUSE
This package sets the default web interface assets used for
a Pagure server running on openSUSE.
%package milters
Summary: Milter to integrate pagure with emails
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
Requires: python3-pymilter
%{?systemd_requires}
# It would work with sendmail but we configure things (like the tempfile)
# to work with postfix
Requires: postfix
%description milters
Milters (Mail filters) allowing the integration of pagure and emails.
This is useful for example to allow commenting on a ticket by email.
%package ev
Summary: EventSource server for pagure
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
Requires: python3-Trololio
%{?systemd_requires}
%description ev
Pagure comes with an eventsource server allowing live update of the pages
supporting it. This package provides it.
%package webhook
Summary: Web-Hook server for pagure
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
%{?systemd_requires}
%description webhook
Pagure comes with an webhook server allowing http callbacks for any action
done on a project. This package provides it.
%package ci
Summary: A CI service for pagure
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
Requires: python3-python-jenkins
%{?systemd_requires}
%description ci
Pagure comes with a continuous integration service, currently supporting
only jenkins but extendable to others.
With this service, your CI server will be able to report the results of the
build on the pull-requests opened to your project.
%package logcom
Summary: The logcom service for pagure
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
%{?systemd_requires}
%description logcom
pagure-logcom contains the service that logs commits into the database so that
the activity calendar heatmap is filled.
%package loadjson
Summary: The loadjson service for pagure
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
%{?systemd_requires}
%description loadjson
pagure-loadjson is the service allowing to update the database with the
information provided in the JSON blobs that are stored in the tickets (and
in the future pull-requests) git repo.
%package mirror
Summary: The mirroring service for pagure
BuildRequires: systemd-rpm-macros
Requires: %{name} = %{version}-%{release}
%{?systemd_requires}
%description mirror
pagure-mirror is the service mirroring projects that asked for it outside
of this pagure instance.
%prep
%autosetup -p1
# Vendor in the file needed from python-fedora
install -pm 0644 %{SOURCE1} pagure/ui
sed -e "s/import flask_fas_openid/from pagure.ui import flask_fas_openid as flask_fas_openid/" -i pagure/ui/fas_login.py
# Install README.SUSE file
install -pm 0644 %{SOURCE10} README.SUSE
%build
%py3_build
%install
%py3_install
# Install apache configuration file
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/apache2/vhosts.d
install -p -m 644 files/pagure.conf $RPM_BUILD_ROOT/%{_sysconfdir}/apache2/vhosts.d/pagure.conf
# Install configuration file
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/pagure
install -p -m 644 files/pagure.cfg.sample $RPM_BUILD_ROOT/%{_sysconfdir}/pagure/pagure.cfg
# Install WSGI file
mkdir -p $RPM_BUILD_ROOT/%{_datadir}/pagure
install -p -m 644 files/pagure.wsgi $RPM_BUILD_ROOT/%{_datadir}/pagure/pagure.wsgi
install -p -m 644 files/doc_pagure.wsgi $RPM_BUILD_ROOT/%{_datadir}/pagure/doc_pagure.wsgi
# Install the createdb script
install -p -m 644 createdb.py $RPM_BUILD_ROOT/%{_datadir}/pagure/pagure_createdb.py
# Install the api_key_expire_mail.py script
install -p -m 644 files/api_key_expire_mail.py $RPM_BUILD_ROOT/%{_datadir}/pagure/api_key_expire_mail.py
# Install the keyhelper and aclcheck scripts
mkdir -p $RPM_BUILD_ROOT/%{_libexecdir}/pagure
install -p -m 755 files/aclchecker.py $RPM_BUILD_ROOT/%{_libexecdir}/pagure/aclchecker.py
install -p -m 755 files/keyhelper.py $RPM_BUILD_ROOT/%{_libexecdir}/pagure/keyhelper.py
# Install the alembic configuration file
install -p -m 644 files/alembic.ini $RPM_BUILD_ROOT/%{_sysconfdir}/pagure/alembic.ini
# Install the alembic revisions
cp -r alembic $RPM_BUILD_ROOT/%{_datadir}/pagure
# Install the systemd file for the worker
mkdir -p $RPM_BUILD_ROOT/%{_unitdir}
install -p -m 644 files/pagure_worker.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_worker.service
# Install the systemd file for the gitolite worker
install -p -m 644 files/pagure_gitolite_worker.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_gitolite_worker.service
# Install the systemd file for the web-hook
install -p -m 644 files/pagure_webhook.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_webhook.service
# Install the systemd file for the ci service
install -p -m 644 files/pagure_ci.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_ci.service
# Install the systemd file for the logcom service
install -p -m 644 files/pagure_logcom.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_logcom.service
# Install the systemd file for the loadjson service
install -p -m 644 files/pagure_loadjson.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_loadjson.service
# Install the systemd file for the mirror service
install -p -m 644 files/pagure_mirror.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_mirror.service
# Install the systemd file for the script sending reminder about API key
# expiration
install -p -m 644 files/pagure_api_key_expire_mail.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_api_key_expire_mail.service
install -p -m 644 files/pagure_api_key_expire_mail.timer \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_api_key_expire_mail.timer
# Install the milter files
mkdir -p $RPM_BUILD_ROOT/%{_tmpfilesdir}
install -p -m 0644 pagure-milters/milter_tempfile.conf \
$RPM_BUILD_ROOT/%{_tmpfilesdir}/%{name}-milter.conf
install -p -m 644 pagure-milters/pagure_milter.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_milter.service
install -p -m 644 pagure-milters/comment_email_milter.py \
$RPM_BUILD_ROOT/%{_datadir}/pagure/comment_email_milter.py
# Install the eventsource
mkdir -p $RPM_BUILD_ROOT/%{_libexecdir}/pagure-ev
install -p -m 755 pagure-ev/pagure_stream_server.py \
$RPM_BUILD_ROOT/%{_libexecdir}/pagure-ev/pagure_stream_server.py
install -p -m 644 pagure-ev/pagure_ev.service \
$RPM_BUILD_ROOT/%{_unitdir}/pagure_ev.service
# Switch all systemd units to use the correct libexecdir
sed -e "s|/usr/libexec|%{_libexecdir}|g" -i $RPM_BUILD_ROOT/%{_unitdir}/*.service
# Change default_config.py to use the correct libexecdir
sed -e "s|/usr/libexec|%{_libexecdir}|g" -i $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/default_config.py
# Fix the shebang for various scripts
sed -e "s|#!/usr/bin/env python|#!%{__python3}|" -i \
$RPM_BUILD_ROOT/%{_libexecdir}/pagure-ev/pagure_stream_server.py \
$RPM_BUILD_ROOT/%{_libexecdir}/pagure/aclchecker.py \
$RPM_BUILD_ROOT/%{_libexecdir}/pagure/keyhelper.py \
$RPM_BUILD_ROOT/%{_datadir}/pagure/comment_email_milter.py \
$RPM_BUILD_ROOT/%{_datadir}/pagure/pagure_createdb.py \
$RPM_BUILD_ROOT/%{_datadir}/pagure/api_key_expire_mail.py \
$RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/*.py \
$RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/hookrunner \
$RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/post-receive \
$RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/pre-receive \
$RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/repospannerhook
# Switch interpreter for systemd units to correct Python interpreter
sed -e "s|/usr/bin/python|%{__python3}|g" -i $RPM_BUILD_ROOT/%{_unitdir}/*.service
# Change to correct static file path for apache httpd
sed -e "s/pythonX.Y/python%{python3_version}/g" -i $RPM_BUILD_ROOT/%{_sysconfdir}/apache2/vhosts.d/pagure.conf
# Make symlinks for default theme packages
mv $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/themes/default $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/themes/upstream
ln -sr $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/themes/upstream $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/themes/default
ln -sr $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/themes/chameleon $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/themes/default.openSUSE
# Run fdupes
%fdupes $RPM_BUILD_ROOT/%{python3_sitelib}
%fdupes doc/
# Regenerate clobbered symlinks (Cf. https://pagure.io/pagure/issue/3782)
runnerhooks="post-receive pre-receive"
for runnerhook in $runnerhooks; do
rm -rf $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/$runnerhook
ln -sf hookrunner $RPM_BUILD_ROOT/%{python3_sitelib}/pagure/hooks/files/$runnerhook
done
# Make the rcFOO symlinks for systemd services
mkdir -p $RPM_BUILD_ROOT/%{_sbindir}
paguresvcs="api_key_expire_mail ci ev gitolite_worker loadjson logcom milter mirror webhook worker"
for paguresvc in $paguresvcs; do
ln -sf %{_sbindir}/service $RPM_BUILD_ROOT/%{_sbindir}/rcpagure_$paguresvc
done
# Install the basic directory structure
mkdir -p $RPM_BUILD_ROOT/srv/www/pagure-releases
mkdir -p $RPM_BUILD_ROOT/srv/gitolite/pseudo
mkdir -p $RPM_BUILD_ROOT/srv/gitolite/repositories/{,docs,forks,requests,tickets}
mkdir -p $RPM_BUILD_ROOT/srv/gitolite/remotes
mkdir -p $RPM_BUILD_ROOT/srv/gitolite/.gitolite/{conf,keydir,logs}
# Add empty gitolite config file
touch $RPM_BUILD_ROOT/srv/gitolite/.gitolite/conf/gitolite.conf
# Install gitolite rc file
install -p -m 644 files/gitolite3.rc $RPM_BUILD_ROOT/srv/gitolite/.gitolite.rc
%pre
# Do nothing, but ensure dependency is evaluated...
%post
echo "Create wsgi rundir if it doesn't exist..."
mkdir -p /srv/www/run || :
echo "Setting up facls..."
setfacl -m user:wwwrun:rx --default /srv/gitolite || :
setfacl -Rdm user:wwwrun:rx /srv/gitolite || :
setfacl -Rm user:wwwrun:rx /srv/gitolite || :
echo "See %{_docdir}/%{name}/README.SUSE to continue"
%systemd_post pagure_worker.service
%systemd_post pagure_gitolite_worker.service
%systemd_post pagure_api_key_expire_mail.timer
%post milters
%tmpfiles_create %{_tmpfilesdir}/%{name}-milter.conf
%systemd_post pagure_milter.service
%post ev
%systemd_post pagure_ev.service
%post webhook
%systemd_post pagure_webhook.service
%post ci
%systemd_post pagure_ci.service
%post logcom
%systemd_post pagure_logcom.service
%post loadjson
%systemd_post pagure_loadjson.service
%post mirror
%systemd_post pagure_mirror.service
%preun
%systemd_preun pagure_worker.service
%systemd_preun pagure_api_key_expire_mail.timer
%preun milters
%systemd_preun pagure_milter.service
%preun ev
%systemd_preun pagure_ev.service
%preun webhook
%systemd_preun pagure_webhook.service
%preun ci
%systemd_preun pagure_ci.service
%preun logcom
%systemd_preun pagure_logcom.service
%preun loadjson
%systemd_preun pagure_loadjson.service
%preun mirror
%systemd_preun pagure_mirror.service
%postun
%systemd_postun_with_restart pagure_worker.service
%systemd_postun_with_restart pagure_gitolite_worker.service
%systemd_postun pagure_api_key_expire_mail.timer
%postun milters
%systemd_postun_with_restart pagure_milter.service
%postun ev
%systemd_postun_with_restart pagure_ev.service
%postun webhook
%systemd_postun_with_restart pagure_webhook.service
%postun ci
%systemd_postun_with_restart pagure_ci.service
%postun logcom
%systemd_postun_with_restart pagure_logcom.service
%postun loadjson
%systemd_postun_with_restart pagure_loadjson.service
%postun mirror
%systemd_postun_with_restart pagure_mirror.service
%files
%doc README.SUSE README.rst UPGRADING.rst doc/ files/gitolite3.rc files/pagure.conf files/pagure.cfg.sample
%license LICENSE
%config(noreplace) %{_sysconfdir}/apache2/vhosts.d/pagure.conf
%config(noreplace) %{_sysconfdir}/pagure/pagure.cfg
%config(noreplace) %{_sysconfdir}/pagure/alembic.ini
%dir %{_sysconfdir}/pagure/
%dir %{_datadir}/pagure/
%config(noreplace) %{_datadir}/pagure/*.wsgi
%{_datadir}/pagure/*.py*
%exclude %{_datadir}/pagure/comment_email_milter.py*
%{_datadir}/pagure/alembic/
%{_libexecdir}/pagure/
%{python3_sitelib}/pagure/
%exclude %{python3_sitelib}/pagure/themes/default
%exclude %{python3_sitelib}/pagure/themes/default.openSUSE
%exclude %{python3_sitelib}/pagure/themes/upstream
%exclude %{python3_sitelib}/pagure/themes/pagureio
%exclude %{python3_sitelib}/pagure/themes/srcfpo
%exclude %{python3_sitelib}/pagure/themes/chameleon
%{python3_sitelib}/pagure*.egg-info
%{_bindir}/pagure-admin
%{_unitdir}/pagure_worker.service
%{_unitdir}/pagure_gitolite_worker.service
%{_unitdir}/pagure_api_key_expire_mail.service
%{_unitdir}/pagure_api_key_expire_mail.timer
%{_sbindir}/rcpagure_api_key_expire_mail
%{_sbindir}/rcpagure_worker
%{_sbindir}/rcpagure_gitolite_worker
# Pagure data content
%attr(-,git,git) %dir /srv/gitolite/pseudo
%attr(-,git,git) %dir /srv/gitolite/remotes
%attr(-,git,git) %dir /srv/gitolite/repositories/{,docs,forks,requests,tickets}
%attr(-,git,git) %dir /srv/gitolite/.gitolite/{,conf,keydir,logs}
%attr(-,git,git) %config(noreplace) /srv/gitolite/.gitolite/conf/gitolite.conf
%attr(-,git,git) %config(noreplace) /srv/gitolite/.gitolite.rc
%attr(-,git,git) %dir /srv/www/pagure-releases
%files theme-upstream
%license LICENSE
%{python3_sitelib}/pagure/themes/upstream/
%files theme-pagureio
%license LICENSE
%{python3_sitelib}/pagure/themes/pagureio/
%files theme-srcfpo
%license LICENSE
%{python3_sitelib}/pagure/themes/srcfpo/
%files theme-chameleon
%license LICENSE
%{python3_sitelib}/pagure/themes/chameleon/
%files theme-default-upstream
%license LICENSE
%{python3_sitelib}/pagure/themes/default
%files theme-default-openSUSE
%license LICENSE
%{python3_sitelib}/pagure/themes/default.openSUSE
%files milters
%license LICENSE
%dir %{_datadir}/pagure/
%{_tmpfilesdir}/%{name}-milter.conf
%{_unitdir}/pagure_milter.service
%{_datadir}/pagure/comment_email_milter.py*
%{_sbindir}/rcpagure_milter
%files ev
%license LICENSE
%{_libexecdir}/pagure-ev/
%{_unitdir}/pagure_ev.service
%{_sbindir}/rcpagure_ev
%files webhook
%license LICENSE
%{_unitdir}/pagure_webhook.service
%{_sbindir}/rcpagure_webhook
%files ci
%license LICENSE
%{_unitdir}/pagure_ci.service
%{_sbindir}/rcpagure_ci
%files logcom
%license LICENSE
%{_unitdir}/pagure_logcom.service
%{_sbindir}/rcpagure_logcom
%files loadjson
%license LICENSE
%{_unitdir}/pagure_loadjson.service
%{_sbindir}/rcpagure_loadjson
%files mirror
%license LICENSE
%{_unitdir}/pagure_mirror.service
%{_sbindir}/rcpagure_mirror
%changelog