commit 907cbc70cb9d07819115ec1d699f7b0b661632b2
Author: Nicolas Chauvet <kwizart(a)gmail.com>
Date: Wed Aug 18 22:58:41 2021 +0200
Add pagure role
roles/pagure/fedmsg/files/selinux/fedmsg.mod | Bin 0 -> 1158 bytes
roles/pagure/fedmsg/files/selinux/fedmsg.pp | Bin 0 -> 1174 bytes
roles/pagure/fedmsg/files/selinux/fedmsg.te | 21 +
roles/pagure/fedmsg/tasks/main.yml | 162 ++++++
roles/pagure/fedmsg/templates/base.py.j2 | 68 +++
roles/pagure/fedmsg/templates/logging.py.j2 | 162 ++++++
roles/pagure/fedmsg/templates/relay.py.j2 | 16 +
roles/pagure/fedmsg/templates/ssl.py.j2 | 16 +
roles/pagure/frontend/files/aliases | 93 +++
roles/pagure/frontend/files/backup-database | 10 +
roles/pagure/frontend/files/pagure_ev.service | 15 +
.../frontend/files/pagure_fast_worker.service | 15 +
.../frontend/files/pagure_medium_worker.service | 15 +
roles/pagure/frontend/files/pagure_mirror.service | 18 +
roles/pagure/frontend/files/pagure_sar.py | 161 ++++++
.../frontend/files/pagure_slow_worker.service | 15 +
roles/pagure/frontend/files/pg_hba.conf | 77 +++
roles/pagure/frontend/files/selinux/pagure.if | 1 +
roles/pagure/frontend/files/selinux/pagure.pp | Bin 0 -> 7261 bytes
roles/pagure/frontend/files/selinux/pagure.te | 11 +
roles/pagure/frontend/files/stunnel.service | 15 +
roles/pagure/frontend/files/syslog-logrotate | 20 +
roles/pagure/frontend/handlers/main.yml | 3 +
roles/pagure/frontend/tasks/main.yml | 598 ++++++++++++++++++++
roles/pagure/frontend/templates/0_pagure.conf | 236 ++++++++
roles/pagure/frontend/templates/alembic.ini | 50 ++
roles/pagure/frontend/templates/docs_pagure.wsgi | 22 +
.../frontend/templates/fedora-messaging.toml | 25 +
roles/pagure/frontend/templates/gitolite.rc | 196 +++++++
roles/pagure/frontend/templates/pagure.cfg | 380 +++++++++++++
roles/pagure/frontend/templates/pagure.wsgi | 29 +
roles/pagure/frontend/templates/robots.txt.j2 | 10 +
.../pagure/frontend/templates/securityheaders.conf | 8 +
roles/pagure/frontend/templates/stunnel-conf.j2 | 16 +
34 files changed, 2484 insertions(+), 0 deletions(-)
---
diff --git a/roles/pagure/fedmsg/files/selinux/fedmsg.mod
b/roles/pagure/fedmsg/files/selinux/fedmsg.mod
new file mode 100644
index 0000000..25e47ae
Binary files /dev/null and b/roles/pagure/fedmsg/files/selinux/fedmsg.mod differ
diff --git a/roles/pagure/fedmsg/files/selinux/fedmsg.pp
b/roles/pagure/fedmsg/files/selinux/fedmsg.pp
new file mode 100644
index 0000000..17a2594
Binary files /dev/null and b/roles/pagure/fedmsg/files/selinux/fedmsg.pp differ
diff --git a/roles/pagure/fedmsg/files/selinux/fedmsg.te
b/roles/pagure/fedmsg/files/selinux/fedmsg.te
new file mode 100644
index 0000000..6ce38d4
--- /dev/null
+++ b/roles/pagure/fedmsg/files/selinux/fedmsg.te
@@ -0,0 +1,21 @@
+
+module fedmsg 1.1;
+
+require {
+ type anon_inodefs_t;
+ type httpd_t;
+ class file write;
+}
+
+require {
+ type ptmx_t;
+ type httpd_t;
+ class chr_file getattr;
+}
+
+#============= httpd_t ==============
+# For basic port binding
+allow httpd_t anon_inodefs_t:file write;
+# So that psutil can work from /etc/fedmsg.d/logging.py
+allow httpd_t ptmx_t:chr_file getattr;
+
diff --git a/roles/pagure/fedmsg/tasks/main.yml b/roles/pagure/fedmsg/tasks/main.yml
new file mode 100644
index 0000000..0bff6d1
--- /dev/null
+++ b/roles/pagure/fedmsg/tasks/main.yml
@@ -0,0 +1,162 @@
+---
+# tasklist for setting up fedmsg
+# This is the base set of files needed for fedmsg
+
+- name: install needed packages
+ package: name={{ item }} state=present
+ with_items:
+ - fedmsg
+ - libsemanage-python
+ - python-psutil
+ tags:
+ - packages
+ - pagure
+ - pagure/fedmsg
+ when: ansible_distribution_major_version|int < 8
+
+- name: install needed packages
+ package: name={{ item }} state=present
+ with_items:
+ - fedmsg
+ - python3-libsemanage
+ - python3-psutil
+ tags:
+ - packages
+ - pagure
+ - pagure/fedmsg
+ when: ansible_distribution_major_version|int >= 8
+
+
+# We use setgid here so that the monitoring sockets created by fedmsg services
+# are accessible to the nrpe group.
+- name: create a /var/run/fedmsg dir with setgid for monitoring.
+ file: >
+ dest=/var/run/fedmsg
+ mode=2775
+ owner=fedmsg
+ group=nrpe
+ state=directory
+ tags:
+ - pagure
+ - pagure
+ - pagure/fedmsg
+
+- name: setup /etc/fedmsg.d directory
+ file: path=/etc/fedmsg.d owner=root group=root mode=0755 state=directory
+ tags:
+ - pagure
+ - pagure/fedmsg
+ - config
+
+# Any files that change need to restart any services that depend on them. A
+# trick here is that some hosts have an httpd that uses fedmsg, while others do
+# not. Some hosts have a fedmsg-hub that uses this config, while others do not.
+# Our handlers in handlers/restart_services.yml are smart enough to
+# *conditionally* restart these services, only if they are installed on the
+# system.
+- name: setup basic /etc/fedmsg.d/ contents
+ template: >
+ src="{{ item }}.j2"
+ dest="/etc/fedmsg.d/{{ item }}"
+ owner=root
+ group=root
+ mode=644
+ with_items:
+ - ssl.py
+ - relay.py
+ - logging.py
+ - base.py
+ tags:
+ - config
+ - fedmsgdconfig
+ - pagure
+ - pagure/fedmsg
+ notify:
+ - reload httpd
+ - restart fedmsg-relay
+
+- name: Remove unwanted files
+ file: dest=/etc/fedmsg.d/{{item}} state=absent
+ with_items:
+ - endpoints.py
+ tags:
+ - config
+ - fedmsgdconfig
+ - pagure
+ - pagure/fedmsg
+ notify:
+ - reload httpd
+ - restart fedmsg-relay
+
+- name: setup /etc/pki/fedmsg directory
+ file: path=/etc/pki/fedmsg owner=root group=root mode=0755 state=directory
+ tags:
+ - config
+ - pagure
+ - pagure/fedmsg
+
+- name: install fedmsg ca.cert
+ copy: >
+ src="{{ private }}/files/fedmsg-certs/keys/ca.crt"
+ dest=/etc/pki/fedmsg/ca.crt
+ owner=root
+ group=root
+ mode=0644
+ tags:
+ - config
+ - pagure
+ - pagure/fedmsg
+
+- name: fedmsg certs
+ copy: >
+ src="{{ private
}}/files/fedmsg-certs/keys/{{item['service']}}-{{fedmsg_fqdn |
default(inventory_hostname)}}.crt"
+ dest=/etc/pki/fedmsg/
+ mode=644
+ owner={{item['owner']}}
+ group={{item['group']}}
+ with_items:
+ - "{{ fedmsg_certs }}"
+ when: fedmsg_certs != []
+ tags:
+ - config
+ - pagure
+ - pagure/fedmsg
+
+- name: fedmsg keys
+ copy: >
+ src="{{ private
}}/files/fedmsg-certs/keys/{{item['service']}}-{{fedmsg_fqdn |
default(inventory_hostname)}}.key"
+ dest=/etc/pki/fedmsg/
+ mode=0640
+ owner={{item['owner']}}
+ group={{item['group']}}
+ with_items:
+ - "{{ fedmsg_certs }}"
+ when: fedmsg_certs != []
+ tags:
+ - config
+ - pagure
+ - pagure/fedmsg
+
+# Three tasks for handling our custom selinux module
+- name: ensure a directory exists for our custom selinux module
+ file: dest=/usr/local/share/fedmsg state=directory
+ tags:
+ - selinux
+ - pagure
+ - pagure/fedmsg
+
+- name: copy over our custom selinux module
+ copy: src=selinux/fedmsg.pp dest=/usr/local/share/fedmsg/fedmsg.pp
+ register: selinux_module
+ tags:
+ - selinux
+ - pagure
+ - pagure/fedmsg
+
+- name: install our custom selinux module
+ command: semodule -i /usr/local/share/fedmsg/fedmsg.pp
+ when: selinux_module is changed
+ tags:
+ - selinux
+ - pagure
+ - pagure/fedmsg
diff --git a/roles/pagure/fedmsg/templates/base.py.j2
b/roles/pagure/fedmsg/templates/base.py.j2
new file mode 100644
index 0000000..31a8e93
--- /dev/null
+++ b/roles/pagure/fedmsg/templates/base.py.j2
@@ -0,0 +1,68 @@
+config = dict(
+
+ # Tell every call to `fedmsg.publish` to use the relay
+ active=True,
+ cert_prefix="pagure",
+
+ topic_prefix="{{ fedmsg_prefix }}",
+ environment="{{ fedmsg_env }}",
+
+ # This used to be set to 1 for safety, but it turns out it was
+ # excessive. It is the number of seconds that fedmsg should sleep
+ # after it has initialized, but before it begins to try and send any
+ # messages. If set to a non-zero value, this will slow down one-off
+ # fedmsg scripts like the git post-receive hook and pkgdb2branch.
+ # If we are experiencing message-loss problems, one of the first things
+ # to try should be to turn this number up to a non-zero value. '1' should
+ # be more than sufficient.
+ post_init_sleep=0.4,
+
+ # This is the number of milliseconds to wait before timing out on
+ # connections.. notably to the fedmsg-relay in the event that it has
+ # crashed.
+ zmq_linger=2000,
+
+ # Default is 0
+ high_water_mark=0,
+ io_threads=1,
+
+ # We almost always want the fedmsg-hub to be sending messages with zmq as
+ # opposed to amqp or stomp. The only exception will be the bugzilla
+ # amqp<->zmq bridge service.
+ zmq_enabled=True,
+
+ # When subscribing to messages, we want to allow splats ('*') so we tell the
+ # hub to not be strict when comparing messages topics to subscription
+ # topics.
+ zmq_strict=False,
+
+ # See the following
+ # -
http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
+ # -
http://api.zeromq.org/3-2:zmq-setsockopt
+ zmq_tcp_keepalive=1,
+ zmq_tcp_keepalive_cnt=3,
+ zmq_tcp_keepalive_idle=60,
+ zmq_tcp_keepalive_intvl=5,
+)
+
+# This option adds an IPC socket by which we can monitor hub health.
+try:
+ import os
+ import psutil
+
+ pid = os.getpid()
+ proc = [p for p in psutil.process_iter() if p.pid == pid][0]
+
+ # proc.name is a method on modern versions of psutil.
+ name = proc.name
+ if callable(name):
+ name = name()
+
+ config['moksha.monitoring.socket'] = \
+ 'ipc:///var/run/fedmsg/monitoring-%s.socket' % name
+ config['moksha.monitoring.socket.mode'] = '770'
+except (OSError, ImportError):
+ # We run into issues when trying to import psutil from mod_wsgi on rhel7
+ # but this feature is of no concern in that context, so just fail quietly.
+ #
https://github.com/jmflinuxtx/kerneltest-harness/pull/17#issuecomment-480...
+ pass
diff --git a/roles/pagure/fedmsg/templates/logging.py.j2
b/roles/pagure/fedmsg/templates/logging.py.j2
new file mode 100644
index 0000000..154c100
--- /dev/null
+++ b/roles/pagure/fedmsg/templates/logging.py.j2
@@ -0,0 +1,162 @@
+# Setup fedmsg logging.
+
+# All of these modules are just used by the ContextInjector below.
+import inspect
+import logging
+import os
+import socket
+import traceback
+
+psutil = None
+try:
+ import psutil
+except (OSError, ImportError):
+ # We run into issues when trying to import psutil from inside mod_wsgi on
+ # rhel7. If we hit that here, then just fail quietly.
+ #
https://github.com/jmflinuxtx/kerneltest-harness/pull/17#issuecomment-480...
+ pass
+
+
+class ContextInjector(logging.Filter):
+ """ Logging filter that adds context to log records.
+
+ Filters are typically used to "filter" log records. They declare a filter
+ method that can return True or False. Only records with 'True' will
+ actually be logged.
+
+ Here, we somewhat abuse the concept of a filter. We always return true,
+ but we use the opportunity to hang important contextual information on the
+ log record to later be used by the logging Formatter. We don't normally
+ want to see all this stuff in normal log records, but we *do* want to see
+ it when we are emailed error messages. Seeing an error, but not knowing
+ which host it comes from, is not that useful.
+
+
http://docs.python.org/2/howto/logging-cookbook.html#filters-contextual
+ """
+
+ def filter(self, record):
+ current_process = ContextInjector.get_current_process()
+ current_hostname = socket.gethostname()
+
+ record.host = current_hostname
+ record.proc = current_process
+ record.pid = current_process.pid
+ record.proc_name = current_process.name
+ record.command_line = current_process.cmdline
+ # These are callabls on more modern versions of psutil.
+ if callable(record.proc_name):
+ record.proc_name = record.proc_name()
+ if callable(record.command_line):
+ record.command_line = record.command_line()
+ record.command_line = " ".join(record.command_line)
+ record.callstack = self.format_callstack()
+ return True
+
+ @staticmethod
+ def format_callstack():
+ for i, frame in enumerate(f[0] for f in inspect.stack()):
+ if not '__name__' in frame.f_globals:
+ continue
+ modname = frame.f_globals['__name__'].split('.')[0]
+ if modname != "logging":
+ break
+
+ def _format_frame(frame):
+ return ' File "%s", line %i in %s\n %s' % (frame)
+
+ stack = traceback.extract_stack()
+ stack = stack[:-i]
+ return "\n".join([_format_frame(frame) for frame in stack])
+
+ @staticmethod
+ def get_current_process():
+ mypid = os.getpid()
+
+ if not psutil:
+ raise OSError("Could not import psutil for %r" % mypid)
+
+ for proc in psutil.process_iter():
+ if proc.pid == mypid:
+ return proc
+
+ # This should be impossible.
+ raise ValueError("Could not find process %r" % mypid)
+
+ @classmethod
+ def __json__(cls):
+ """ We need to be jsonifiable for "fedmsg-config"
"""
+ return {'name': 'ContextInjector'}
+
+
+hefty_format = """Message
+-------
+[%(asctime)s][%(name)10s %(levelname)7s]
+%(message)s
+
+Process Details
+---------------
+host: %(host)s
+PID: %(pid)s
+name: %(proc_name)s
+command: %(command_line)s
+
+Callstack that lead to the logging statement
+--------------------------------------------
+%(callstack)s
+"""
+
+
+# See the following for constraints on this format
http://bit.ly/Xn1WDn
+config = dict(
+ logging=dict(
+ version=1,
+ formatters=dict(
+ bare={
+ "datefmt": "%Y-%m-%d %H:%M:%S",
+ "format": "[%(asctime)s][%(name)10s %(levelname)7s]
%(message)s"
+ },
+ hefty={
+ "datefmt": "%Y-%m-%d %H:%M:%S",
+ "format": hefty_format,
+ },
+ ),
+ filters=dict(
+ context={
+ # This "()" syntax in the stdlib doesn't seem to be
documented
+ # anywhere. I had to read
+ # /usr/lib64/python2.7/logging/config.py to figure it out.
+ "()": ContextInjector,
+ },
+ ),
+ handlers=dict(
+ console={
+ "class": "logging.StreamHandler",
+ "formatter": "bare",
+ "level": "INFO",
+ "stream": "ext://sys.stdout",
+ },
+ mailer={
+ "class": "logging.handlers.SMTPHandler",
+ "formatter": "hefty",
+ "filters": ["context"],
+ "level": "ERROR",
+ "mailhost": "hv01.online.rpmfusion.net",
+ "fromaddr": "noreply(a)rpmfusion.org",
+ "toaddrs":
["sysadmin-datanommer-members(a)rpmfusion.org"],
+ "subject": "fedmsg error log (pagure)",
+ },
+ ),
+ loggers=dict(
+ fedmsg={
+ "level": "INFO",
+ "propagate": False,
+ "handlers": ["console", "mailer"],
+ },
+ moksha={
+ "level": "INFO",
+ "propagate": False,
+ "handlers": ["console", "mailer"],
+ },
+ ),
+ ),
+)
diff --git a/roles/pagure/fedmsg/templates/relay.py.j2
b/roles/pagure/fedmsg/templates/relay.py.j2
new file mode 100644
index 0000000..cd620d9
--- /dev/null
+++ b/roles/pagure/fedmsg/templates/relay.py.j2
@@ -0,0 +1,16 @@
+config = dict(
+ endpoints={
+ # This is the output side of the relay to which all other
+ # services can listen.
+ "relay_outbound": [
+ # Messages emerge here
+ #"tcp://pagure.io:9940",
+ "tcp://{{inventory_hostname}}:9940",
+ ],
+ },
+
+ # wsgi scripts on the frontend talk back here
+ relay_inbound=[
+ "tcp://{{inventory_hostname}}:9941",
+ ],
+)
diff --git a/roles/pagure/fedmsg/templates/ssl.py.j2
b/roles/pagure/fedmsg/templates/ssl.py.j2
new file mode 100644
index 0000000..224b23a
--- /dev/null
+++ b/roles/pagure/fedmsg/templates/ssl.py.j2
@@ -0,0 +1,16 @@
+
+config = dict(
+ sign_messages=True,
+ validate_signatures=True,
+ ssldir="/etc/pki/fedmsg",
+
+
crl_location="https://rpmfusion.org/fedmsg/crl.pem",
+ crl_cache="/var/run/fedmsg/crl.pem",
+ crl_cache_expiry=86400, # Daily
+
+ certnames=dict([
+ ("shell.{{inventory_hostname_short}}",
"shell-{{inventory_hostname}}"),
+ ("pagure.{{inventory_hostname_short}}",
"pagure-{{inventory_hostname}}"),
+ ]),
+)
+
diff --git a/roles/pagure/frontend/files/aliases b/roles/pagure/frontend/files/aliases
new file mode 100644
index 0000000..aba690b
--- /dev/null
+++ b/roles/pagure/frontend/files/aliases
@@ -0,0 +1,93 @@
+#
+# Aliases in this file will NOT be expanded in the header from
+# Mail, but WILL be visible over networks or from /bin/mail.
+#
+# >>>>>>>>>> The program "newaliases" must be run
after
+# >> NOTE >> this file is updated for any changes to
+# >>>>>>>>>> show through to sendmail.
+#
+
+# Basic system aliases -- these MUST be present.
+mailer-daemon: postmaster
+admin: postmaster
+hostmaster: postmaster
+postmaster: sysadmin-main(a)rpmfusion.org
+
+# General redirections for pseudo accounts.
+bin: root
+daemon: root
+adm: root
+lp: root
+sync: root
+shutdown: root
+halt: root
+mail: root
+#news: root
+uucp: root
+operator: root
+games: root
+gopher: root
+ftp: root
+#nobody: root
+radiusd: root
+nut: root
+dbus: root
+vcsa: root
+canna: root
+wnn: root
+rpm: root
+nscd: root
+pcap: root
+apache: root
+webalizer: root
+dovecot: root
+fax: root
+quagga: root
+radvd: root
+pvm: root
+amanda: root
+privoxy: root
+ident: root
+named: root
+xfs: root
+gdm: root
+mailnull: root
+postgres: root
+sshd: root
+smmsp: root
+postfix: root
+netdump: root
+ldap: root
+squid: root
+ntp: root
+mysql: root
+desktop: root
+rpcuser: root
+rpc: root
+nfsnobody: root
+notifications: root
+
+ingres: root
+system: root
+toor: root
+manager: root
+dumper: root
+abuse: root
+nagios: root
+
+newsadm: news
+newsadmin: news
+usenet: news
+ftpadm: ftp
+ftpadmin: ftp
+ftp-adm: ftp
+ftp-admin: ftp
+
+# trap decode to catch security attacks
+decode: root
+
+# Person who should get root's mail
+root: sysadmin-main
+
+pagure: /dev/null
+reply: /dev/null
diff --git a/roles/pagure/frontend/files/backup-database
b/roles/pagure/frontend/files/backup-database
new file mode 100644
index 0000000..3f6e7d8
--- /dev/null
+++ b/roles/pagure/frontend/files/backup-database
@@ -0,0 +1,10 @@
+#!/bin/bash
+# Backup a database *locally* to /backups/.
+
+DB=$1
+
+# Make our latest backup
+/usr/bin/pg_dump -C $DB | /usr/bin/xz > /backups/$DB-$(date +%F).dump.xz
+
+# Also, delete the backup from a few days ago.
+rm -f /backups/$DB-$(date --date="3 days ago" +%F).dump.xz
diff --git a/roles/pagure/frontend/files/pagure_ev.service
b/roles/pagure/frontend/files/pagure_ev.service
new file mode 100644
index 0000000..f194b1b
--- /dev/null
+++ b/roles/pagure/frontend/files/pagure_ev.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Pagure EventSource server (Allowing live refresh of the pages supporting it)
+After=redis.target
+Documentation=https://pagure.io/pagure
+
+[Service]
+ExecStart=/usr/libexec/pagure-ev/pagure_stream_server.py
+Type=simple
+User=git
+Group=git
+Restart=on-failure
+LimitNOFILE=40960
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/pagure/frontend/files/pagure_fast_worker.service
b/roles/pagure/frontend/files/pagure_fast_worker.service
new file mode 100644
index 0000000..5b97b84
--- /dev/null
+++ b/roles/pagure/frontend/files/pagure_fast_worker.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Pagure worker for backend git interaction
+After=redis.target
+Documentation=https://pagure.io/pagure
+
+[Service]
+ExecStart=/usr/bin/celery worker -A pagure.lib.tasks --loglevel=info -Q fast_workers -c
5
+Environment="PAGURE_CONFIG=/etc/pagure/pagure.cfg"
+Type=simple
+User=git
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/roles/pagure/frontend/files/pagure_medium_worker.service
b/roles/pagure/frontend/files/pagure_medium_worker.service
new file mode 100644
index 0000000..799235a
--- /dev/null
+++ b/roles/pagure/frontend/files/pagure_medium_worker.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Pagure worker for backend git interaction
+After=redis.target
+Documentation=https://pagure.io/pagure
+
+[Service]
+ExecStart=/usr/bin/celery worker -A pagure.lib.tasks --loglevel=info -Q medium_workers -c
5
+Environment="PAGURE_CONFIG=/etc/pagure/pagure.cfg"
+Type=simple
+User=git
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/roles/pagure/frontend/files/pagure_mirror.service
b/roles/pagure/frontend/files/pagure_mirror.service
new file mode 100644
index 0000000..786eee8
--- /dev/null
+++ b/roles/pagure/frontend/files/pagure_mirror.service
@@ -0,0 +1,18 @@
+# This is a systemd's service file for the mirroring service, if you change
+# the default value of the CI_CELERY_QUEUE configuration key, do not
+# forget to edit it in the ExecStart line below
+
+[Unit]
+Description=Pagure service mirroring projects outside of pagure that asked for it
+After=redis.target
+Documentation=https://pagure.io/pagure
+
+[Service]
+ExecStart=/usr/bin/celery worker -A pagure.lib.tasks_mirror --loglevel=info -Q
pagure_mirror
+Environment="PAGURE_CONFIG=/etc/pagure/pagure.cfg"
+Type=simple
+User=paguremirroring
+Group=paguremirroring
+Restart=on-failure
+
+[Install]
diff --git a/roles/pagure/frontend/files/pagure_sar.py
b/roles/pagure/frontend/files/pagure_sar.py
new file mode 100644
index 0000000..dbe10cd
--- /dev/null
+++ b/roles/pagure/frontend/files/pagure_sar.py
@@ -0,0 +1,161 @@
+#!/usr/bin/python
+
+from __future__ import unicode_literals, print_function
+
+import json
+import os
+import sys
+
+import sqlalchemy
+
+import pagure.config
+import pagure.lib.query
+import pagure.lib.model_base
+from pagure.lib import model
+
+
+if 'PAGURE_CONFIG' not in os.environ \
+ and os.path.exists('/etc/pagure/pagure.cfg'):
+ os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
+
+
+_config = pagure.config.reload_config()
+session = pagure.lib.model_base.create_session(_config['DB_URL'])
+
+
+def get_issue_users(session, user_id):
+ ''' Return all pagure.lib.model.Issue related to the usernames provided
+ '''
+ query1 = session.query(
+ model.Issue.uid
+ ).filter(
+ sqlalchemy.or_(
+ model.Issue.assignee_id == user_id,
+ model.Issue.user_id == user_id
+ )
+ )
+ query2 = session.query(
+ model.Issue.uid
+ ).filter(
+ model.Issue.uid == model.IssueComment.issue_uid
+ ).filter(
+ model.IssueComment.user_id == user_id
+ )
+
+ query = session.query(
+ model.Issue
+ ).filter(
+ sqlalchemy.or_(
+ model.Issue.uid.in_(query1.subquery()),
+ model.Issue.uid.in_(query2.subquery())
+ )
+ ).order_by(
+ model.Issue.date_created
+ )
+
+ return query.all()
+
+
+def get_pr_users(session, user_id):
+ ''' Return all pagure.lib.model.PullRequest related to the usernames
provided
+ '''
+ query1 = session.query(
+ model.PullRequest.uid
+ ).filter(
+ sqlalchemy.or_(
+ model.PullRequest.assignee_id == user_id,
+ model.PullRequest.user_id == user_id
+ )
+ )
+ query2 = session.query(
+ model.PullRequest.uid
+ ).filter(
+ model.PullRequest.uid == model.PullRequestComment.pull_request_uid
+ ).filter(
+ model.PullRequestComment.user_id == user_id
+ )
+
+ query = session.query(
+ model.PullRequest
+ ).filter(
+ sqlalchemy.or_(
+ model.PullRequest.uid.in_(query1.subquery()),
+ model.PullRequest.uid.in_(query2.subquery())
+ )
+ ).order_by(
+ model.PullRequest.date_created
+ )
+
+ return query.all()
+
+
+def main():
+ ''' Prints out all the pagure project and comment related to the
username
+ specified in the SAR_USERNAME environment variable or the email
+ specified in the SAR_EMAIL environment variable..
+ '''
+
+ username = os.getenv('SAR_USERNAME')
+ email = os.getenv('SAR_EMAIL')
+
+ users = []
+ if username:
+ users.append(pagure.lib.query.search_user(session, username=username))
+ if email:
+ user_email = pagure.lib.query.search_user(session, email=email)
+ if user_email not in users:
+ users.append(user_email)
+
+ output = {}
+
+ for user in users:
+ if not user:
+ continue
+
+ temp = {}
+ temp['user_info'] = user.to_json(public=False)
+
+ projects = pagure.lib.query.search_projects(session, user.username)
+ projects = [
+ project.to_json()
+ for project in projects
+ ]
+ temp['projects'] = projects
+
+ issues = get_issue_users(session, user.id)
+ issues_json = []
+ for issue in issues:
+ tmp = issue.to_json()
+ comments = []
+ for comment in tmp['comments']:
+ if comment['user']['name'] != username:
+ continue
+ comments.append(comment)
+ tmp['comments'] = comments
+ issues_json.append(tmp)
+ temp['issues'] = issues_json
+
+ prs = get_pr_users(session, user.id)
+ prs_json = []
+ for pr in prs:
+ tmp = pr.to_json()
+ comments = []
+ for comment in tmp['comments']:
+ if comment['user']['name'] != username:
+ continue
+ comments.append(comment)
+ tmp['comments'] = comments
+ prs_json.append(tmp)
+ temp['pull_requests'] = prs_json
+
+ output[user.username] = temp
+
+ session.remove()
+
+ print(json.dumps(
+ output, sort_keys=True, indent=4, separators=(',', ': ')
+ ).encode('utf-8'))
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/roles/pagure/frontend/files/pagure_slow_worker.service
b/roles/pagure/frontend/files/pagure_slow_worker.service
new file mode 100644
index 0000000..17621ab
--- /dev/null
+++ b/roles/pagure/frontend/files/pagure_slow_worker.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Pagure worker for backend git interaction
+After=redis.target
+Documentation=https://pagure.io/pagure
+
+[Service]
+ExecStart=/usr/bin/celery worker -A pagure.lib.tasks --loglevel=info -Q slow_workers -c
5
+Environment="PAGURE_CONFIG=/etc/pagure/pagure.cfg"
+Type=simple
+User=git
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/roles/pagure/frontend/files/pg_hba.conf
b/roles/pagure/frontend/files/pg_hba.conf
new file mode 100644
index 0000000..20db085
--- /dev/null
+++ b/roles/pagure/frontend/files/pg_hba.conf
@@ -0,0 +1,77 @@
+# PostgreSQL Client Authentication Configuration File
+# ===================================================
+#
+# Refer to the PostgreSQL Administrator's Guide, chapter "Client
+# Authentication" for a complete description. A short synopsis
+# follows.
+#
+# This file controls: which hosts are allowed to connect, how clients
+# are authenticated, which PostgreSQL user names they can use, which
+# databases they can access. Records take one of these forms:
+#
+# local DATABASE USER METHOD [OPTION]
+# host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+# hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+#
+# (The uppercase items must be replaced by actual values.)
+#
+# The first field is the connection type: "local" is a Unix-domain socket,
+# "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl"
is an
+# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket.
+#
+# DATABASE can be "all", "sameuser", "samerole", a database
name, or
+# a comma-separated list thereof.
+#
+# USER can be "all", a user name, a group name prefixed with "+", or
+# a comma-separated list thereof. In both the DATABASE and USER fields
+# you can also write a file name prefixed with "@" to include names from
+# a separate file.
+#
+# CIDR-ADDRESS specifies the set of hosts the record matches.
+# It is made up of an IP address and a CIDR mask that is an integer
+# (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies
+# the number of significant bits in the mask. Alternatively, you can write
+# an IP address and netmask in separate columns to specify the set of hosts.
+#
+# METHOD can be "trust", "reject", "md5",
"crypt", "password",
+# "krb5", "ident", or "pam". Note that
"password" sends passwords
+# in clear text; "md5" is preferred since it sends encrypted passwords.
+#
+# OPTION is the ident map or the name of the PAM service, depending on METHOD.
+#
+# Database and user names containing spaces, commas, quotes and other special
+# characters must be quoted. Quoting one of the keywords "all",
"sameuser" or
+# "samerole" makes the name lose its special character, and just match a
+# database or username with that name.
+#
+# This file is read on server startup and when the postmaster receives
+# a SIGHUP signal. If you edit the file on a running system, you have
+# to SIGHUP the postmaster for the changes to take effect. You can use
+# "pg_ctl reload" to do that.
+
+# Put your actual configuration here
+# ----------------------------------
+#
+# If you want to allow non-local connections, you need to add more
+# "host" records. In that case you will also need to make PostgreSQL listen
+# on a non-local interface via the listen_addresses configuration parameter,
+# or via the -i or -h command line switches.
+#
+
+#@authcomment@
+
+# TYPE DATABASE USER CIDR-ADDRESS METHOD
+
+#@remove-line-for-nolocal@# "local" is for Unix domain socket connections only
+#@remove-line-for-nolocal@local all all
@authmethod@
+# IPv4 local connections:
+#host all all 127.0.0.1/32 @authmethod@
+# IPv6 local connections:
+#host all all ::1/128 @authmethod@
+
+local all all ident
+host all all 0.0.0.0 0.0.0.0 md5
+# Note, I can't think of a reason to make this more restrictive than ipv4 but
+# only fakefas needs it so far
+host all all ::1/128 md5
diff --git a/roles/pagure/frontend/files/selinux/pagure.fc
b/roles/pagure/frontend/files/selinux/pagure.fc
new file mode 100644
index 0000000..e69de29
diff --git a/roles/pagure/frontend/files/selinux/pagure.if
b/roles/pagure/frontend/files/selinux/pagure.if
new file mode 100644
index 0000000..3eb6a30
--- /dev/null
+++ b/roles/pagure/frontend/files/selinux/pagure.if
@@ -0,0 +1 @@
+## <summary></summary>
diff --git a/roles/pagure/frontend/files/selinux/pagure.pp
b/roles/pagure/frontend/files/selinux/pagure.pp
new file mode 100644
index 0000000..a6248e7
Binary files /dev/null and b/roles/pagure/frontend/files/selinux/pagure.pp differ
diff --git a/roles/pagure/frontend/files/selinux/pagure.te
b/roles/pagure/frontend/files/selinux/pagure.te
new file mode 100644
index 0000000..d661e61
--- /dev/null
+++ b/roles/pagure/frontend/files/selinux/pagure.te
@@ -0,0 +1,11 @@
+module pagure 1.0;
+
+require {
+ type httpd_t;
+ type gitosis_var_lib_t;
+ class dir { add_name remove_name write };
+ class file { create link setattr unlink write };
+}
+
+allow httpd_t gitosis_var_lib_t:dir { add_name remove_name write };
+allow httpd_t gitosis_var_lib_t:file { create link setattr unlink write };
diff --git a/roles/pagure/frontend/files/stunnel.service
b/roles/pagure/frontend/files/stunnel.service
new file mode 100644
index 0000000..1e9f492
--- /dev/null
+++ b/roles/pagure/frontend/files/stunnel.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=stunnel
+After=network.target
+Documentation=https://infrastructure.fedoraproject.org/infra/docs/fedmsg-websocket.txt
+
+[Service]
+ExecStart=/usr/bin/stunnel /etc/stunnel/stunnel.conf
+Type=forking
+User=root
+Group=root
+Restart=on-failure
+LimitNOFILE=40960
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/pagure/frontend/files/syslog-logrotate
b/roles/pagure/frontend/files/syslog-logrotate
new file mode 100644
index 0000000..7028290
--- /dev/null
+++ b/roles/pagure/frontend/files/syslog-logrotate
@@ -0,0 +1,20 @@
+/var/log/cron
+/var/log/maillog
+/var/log/messages
+/var/log/secure
+/var/log/spooler
+{
+ sharedscripts
+ postrotate
+ /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
+ endscript
+ daily
+ rotate 7
+ missingok
+ ifempty
+ compress
+ compresscmd /usr/bin/xz
+ uncompresscmd /usr/bin/xz
+ compressext .xz
+ dateext
+}
diff --git a/roles/pagure/frontend/handlers/main.yml
b/roles/pagure/frontend/handlers/main.yml
new file mode 100644
index 0000000..62b144e
--- /dev/null
+++ b/roles/pagure/frontend/handlers/main.yml
@@ -0,0 +1,3 @@
+---
+- name: restart pagure_milter
+ service: name=pagure_milter state=restarted
diff --git a/roles/pagure/frontend/tasks/main.yml b/roles/pagure/frontend/tasks/main.yml
new file mode 100644
index 0000000..ab2aa4b
--- /dev/null
+++ b/roles/pagure/frontend/tasks/main.yml
@@ -0,0 +1,598 @@
+---
+# Configuration for the pagure webapp
+
+- name: install needed packages
+ package: name={{ item }} state=present
+ with_items:
+ - pagure
+ - pagure-ci
+ - pagure-ev
+ - pagure-loadjson
+ - pagure-logcom
+ - pagure-milters
+ - pagure-webhook
+ - python-psycopg2
+ - python2-pygments2
+ - redis
+ - libsemanage-python
+ - mod_ssl
+ - stunnel
+ # Use haveged to ensure the server keeps some entropy
+ - haveged
+ when: env != 'pagure-staging'
+ tags:
+ - pagure
+ - packages
+
+- name: install needed packages
+ package: name={{ item }} state=present
+ with_items:
+ - pagure
+ - pagure-ci
+ - pagure-ev
+ - pagure-loadjson
+ - pagure-logcom
+ - pagure-milters
+ - pagure-webhook
+ - python3-psycopg2
+ - python3-pygments
+ - redis
+ - python3-libsemanage
+ - mod_ssl
+ - stunnel
+ # Use haveged to ensure the server keeps some entropy
+ - haveged
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+ - packages
+
+- name: install needed packages
+ package: name={{ item }} state=present
+ when: env == 'pagure-staging'
+ with_items:
+ - pagure-theme-pagureio
+ tags:
+ - pagure
+ - packages
+
+- name: Initialize postgres if necessary
+ command: /usr/bin/postgresql-setup initdb
+ creates=/var/lib/pgsql/data
+ notify:
+ - restart postgresql
+ tags:
+ - pagure
+
+- name: Put in robots.txt
+ template: src=robots.txt.j2 dest=/var/www/html/robots.txt
+ tags:
+ - pagure
+
+
+- name: Create the "git" user
+ command: useradd --move-home --login git --home /srv/git/
+ creates=/srv/git/
+ when: env != 'pagure-staging'
+ tags:
+ - pagure
+
+- name: Create the "git" user
+ command: useradd --create-home --home-dir=/srv/git/ git
+ creates=/srv/git/
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+
+- name: create the /attachments folder
+ file: state=directory
+ path=/srv/attachments
+ owner=git group=git mode=0775
+ tags:
+ - pagure
+
+# This now fails when there are broken symlinks. Lets figure out a better way to do this
- kevin
+#- name: Adjust owner of /srv/git
+# file: name=/srv/git state=directory recurse=yes owner=git group=git
+# tags:
+# - gitolite
+
+- name: create all the directories where we store the git repos
+ file: state=directory
+ path={{ item }}
+ owner=git group=git mode=0775
+ with_items:
+ - /srv/git/repositories/
+ - /srv/git/repositories/forks
+ - /srv/git/repositories/docs
+ - /srv/git/repositories/tickets
+ - /srv/git/repositories/requests
+ - /srv/git/remotes
+ tags:
+ - pagure
+
+- name: create the /srv/tmp folder where to clone repos
+ file: state=directory
+ path=/srv/tmp
+ owner=git group=git mode=0775
+ tags:
+ - pagure
+
+# Set things up for the mirroring feature
+
+- name: create the `paguremirroring` group
+ group:
+ name: paguremirroring
+ state: present
+ tags:
+ - pagure
+ - mirror
+
+- name: create the `paguremirroring` user
+ user:
+ name: paguremirroring
+ group: paguremirroring
+ groups: paguremirroring,git
+ shell: /bin/nologin
+ home: /srv/mirror
+ tags:
+ - pagure
+ - mirror
+
+# We need the SSL certs early on
+
+- name: Install the SSL cert so that we can use https
+ copy: >
+ src={{ private}}/files/httpd/{{ item }} dest=/etc/pki/tls/certs/{{ item }}
+ owner=root group=root mode=0600
+ notify: restart stunnel
+ with_items:
+ - pagure.io.cert
+ - pagure.io.key
+ - pagure.io.intermediate.cert
+ tags:
+ - config
+ - pagure
+ - httpd/certificate
+
+# Set-up postfix and the milter for postfix
+
+- name: Add the /etc/aliases file
+ copy: src=aliases dest=/etc/aliases owner=root mode=644
+ tags:
+ - config
+ - pagure
+ - postfix
+ notify:
+ - restart postfix
+ - restart pagure_milter
+
+# Override pagure_ev systemd service file
+
+- name: install pagure_ev service definition
+ copy: src=pagure_ev.service
+ dest=/usr/lib/systemd/system/pagure_ev.service
+ owner=root group=root mode=0644
+ notify:
+ - reload systemd
+ - restart pagure_ev
+ tags:
+ - pagure
+ - pagure_ev
+
+# Set-up stunnel for the event source server
+
+- name: install stunnel service definition
+ copy: src=stunnel.service
+ dest=/usr/lib/systemd/system/stunnel.service
+ owner=root group=root mode=0644
+ notify:
+ - reload systemd
+ - restart stunnel
+ tags:
+ - pagure
+ - stunnel
+
+- name: ensure old stunnel init file is gone
+ file: dest=/etc/init.d/stunnel/stunnel.init state=absent
+ tags:
+ - pagure
+ - stunnel
+ - config
+
+- name: make a bundle file of the cert and intermediate for stunnel
+ shell: cat /etc/pki/tls/certs/pagure.io.cert
/etc/pki/tls/certs/pagure.io.intermediate.cert >
/etc/pki/tls/certs/pagure.io.bundle.cert creates=/etc/pki/tls/certs/pagure.io.bundle.cert
+ tags:
+ - pagure
+ - stunnel
+ - config
+ when: env != 'pagure-staging'
+
+- name: make a bundle file of the cert and intermediate for stunnel (stg)
+ shell: cat /etc/pki/tls/certs/stg.pagure.io.cert
/etc/pki/tls/certs/stg.pagure.io.intermediate.cert >
/etc/pki/tls/certs/stg.pagure.io.bundle.cert
creates=/etc/pki/tls/certs/stg.pagure.io.bundle.cert
+ tags:
+ - pagure
+ - stunnel
+ - config
+ when: env == 'pagure-staging'
+
+- name: install stunnel.conf
+ template: src={{ item.file }}
+ dest={{ item.dest }}
+ owner=root group=root mode=0600
+ with_items:
+ - { file: stunnel-conf.j2, dest: /etc/stunnel/stunnel.conf }
+ notify: restart stunnel
+ tags:
+ - pagure
+ - stunnel
+ - config
+
+- name: Add the different service files for the different services
+ copy: src={{ item }}.service
+ dest=/etc/systemd/system/{{ item }}.service
+ owner=root group=root mode=0755
+ with_items:
+ - pagure_fast_worker
+ - pagure_medium_worker
+ - pagure_slow_worker
+ - pagure_mirror
+ notify:
+ - reload systemd
+ tags:
+ - pagure
+
+# setup fedora-messaging
+
+- name: install fedora-messaging as a dependency
+ package: name={{ item }} state=present
+ with_items:
+ - python2-fedora-messaging
+ when: env != 'pagure-staging'
+ tags:
+ - pagure
+ - fedora-messaging
+
+- name: install fedora-messaging as a dependency
+ package: name={{ item }} state=present
+ with_items:
+ - python3-fedora-messaging
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+ - fedora-messaging
+
+- name: create the config folder for fedora-messaging
+ file: path=/etc/fedora-messaging/ owner=root group=root mode=0755 state=directory
+ tags:
+ - pagure
+ - fedora-messaging
+
+- name: install the configuration file for fedora-messaging
+ template:
+ src=fedora-messaging.toml
+ dest=/etc/fedora-messaging/config.toml
+ tags:
+ - pagure
+ - fedora-messaging
+
+- name: create folder where we'll place the certs
+ file: path=/etc/pki/rabbitmq/pagurecert/ owner=root group=root mode=0755
state=directory
+ tags:
+ - pagure
+ - fedora-messaging
+
+- name: deploy pagure/rabbitmq certificate
+ copy: src={{ item.src }}
+ dest=/etc/pki/rabbitmq/pagurecert/{{ item.dest }}
+ owner={{ item.owner }} group={{ item.group}} mode={{ item.mode }}
+ when: env == 'pagure-staging'
+ with_items:
+ - src: "{{private}}/files/rabbitmq/staging/pki/issued/pagure.stg.crt"
+ dest: pagure.crt
+ owner: git
+ group: root
+ mode: "444"
+ - src: "{{private}}/files/rabbitmq/staging/pki/private/pagure.stg.key"
+ dest: pagure.key
+ owner: git
+ group: root
+ mode: "440"
+ - src: "{{private}}/files/rabbitmq/staging/pki/ca.crt"
+ dest: pagure.ca
+ owner: git
+ group: root
+ mode: "444"
+ tags:
+ - pagure
+ - fedora-messaging
+
+- name: deploy pagure/rabbitmq certificate
+ copy: src={{ item.src }}
+ dest=/etc/pki/rabbitmq/pagurecert/{{ item.dest }}
+ owner={{ item.owner }} group={{ item.group}} mode={{ item.mode }}
+ when: env != 'pagure-staging'
+ with_items:
+ - src: "{{private}}/files/rabbitmq/production/pki/issued/pagure.crt"
+ dest: pagure.crt
+ owner: git
+ group: root
+ mode: "444"
+ - src: "{{private}}/files/rabbitmq/production/pki/private/pagure.key"
+ dest: pagure.key
+ owner: git
+ group: root
+ mode: "440"
+ - src: "{{private}}/files/rabbitmq/production/pki/ca.crt"
+ dest: pagure.ca
+ owner: git
+ group: root
+ mode: "444"
+ tags:
+ - pagure
+ - fedora-messaging
+
+
+# Set-up Pagure
+
+- name: create the folders used for releases and archives
+ file: state=directory
+ path={{ item }}
+ owner=git group=git mode=0775
+ with_items:
+ - /var/www/releases
+ - /var/www/archives
+ tags:
+ - pagure
+ - web
+
+- name: copy sundry pagure configuration
+ template: src={{ item.file }}
+ dest={{ item.location }}/{{ item.file }}
+ owner=git group=postfix mode=0640
+ with_items:
+ - { file: pagure.cfg, location: /etc/pagure }
+ - { file: alembic.ini, location: /etc/pagure }
+ tags:
+ - config
+ - web
+ - pagure
+ notify:
+ - restart apache
+
+
+- name: create the database scheme
+ command: /usr/bin/python2 /usr/share/pagure/pagure_createdb.py
+ changed_when: "1 != 1"
+ environment:
+ PAGURE_CONFIG: /etc/pagure/pagure.cfg
+ when: env != 'pagure-staging'
+ tags:
+ - web
+ - pagure
+
+- name: create the database scheme
+ command: /usr/bin/python3 /usr/share/pagure/pagure_createdb.py
+ changed_when: "1 != 1"
+ environment:
+ PAGURE_CONFIG: /etc/pagure/pagure.cfg
+ when: env == 'pagure-staging'
+ tags:
+ - web
+ - pagure
+
+- name: Install the configuration file to activate https
+ template: src={{ item }} dest=/etc/httpd/conf.d/{{ item }}
+ owner=root group=root mode=0644
+ with_items:
+ - 0_pagure.conf
+ - securityheaders.conf
+ tags:
+ - files
+ - config
+ - pagure
+ - sslciphers
+ notify:
+ - restart apache
+
+- name: Install the wsgi file
+ template: src={{ item }}
+ dest=/var/www/{{ item }}
+ owner=git group=git mode=0644
+ with_items:
+ - pagure.wsgi
+ - docs_pagure.wsgi
+ tags:
+ - config
+ - web
+ - pagure
+ notify:
+ - restart apache
+
+- name: let paguremirroring read the pagure config
+ command: /usr/bin/setfacl -m user:paguremirroring:rx /etc/pagure/pagure.cfg
+ tags:
+ - pagure
+ - mirror
+
+- name: Add default facl so apache can read git repos
+ acl: default=yes etype=user entity=apache permissions="rx" name=/srv/git
state=present
+ register: acl_updates
+ tags:
+ - pagure
+
+- name: Manually fix current default ACLs since Ansible doesnt know recursive acls
+ when: acl_updates.changed
+ command: /usr/bin/setfacl -Rdm user:apache:rx /srv/git
+ tags:
+ - pagure
+
+- name: Manually fix current ACLs since Ansible doesnt know recursive acls
+ when: acl_updates.changed
+ command: /usr/bin/setfacl -Rm user:apache:rx /srv/git
+ tags:
+ - pagure
+
+- name: check the selinux context of the git repo directory
+ command: matchpathcon /srv/git
+ register: distgitcontext
+ check_mode: no
+ changed_when: false
+ tags:
+ - config
+ - pagure
+ - selinux
+
+- name: set the SELinux policy for the distgit root directory
+ command: semanage fcontext -a -t gitosis_var_lib_t "/srv/git(/.*)?"
+ when: distgitcontext.stdout.find('gitosis_var_lib_t') == -1
+ tags:
+ - config
+ - pagure
+ - selinux
+
+- name: check the selinux context of the releases directory
+ command: matchpathcon /var/www/releases
+ register: distgitcontext
+ check_mode: no
+ changed_when: false
+ tags:
+ - config
+ - pagure
+ - selinux
+
+# Note: On Fedora its httpd_sys_content_rw_t - Don't we love confusions?
+- name: set the SELinux policy for the releases directory
+ command: semanage fcontext -a -t httpd_sys_rw_content_t
"/var/www/releases(/.*)?"
+ when: distgitcontext.stdout.find('httpd_sys_rw_content_t') == -1
+ tags:
+ - config
+ - pagure
+ - selinux
+
+- name: copy over our custom selinux module
+ copy: src=selinux/pagure.pp dest=/usr/local/share/pagure.pp
+ register: selinux_module
+ tags:
+ - pagure
+
+- name: install our custom selinux module
+ command: semodule -i /usr/local/share/pagure.pp
+ when: selinux_module is changed
+ tags:
+ - pagure
+
+- name: set sebooleans so pagure can talk to the network (db + redis)
+ seboolean: name=httpd_can_network_connect
+ state=true
+ persistent=true
+ tags:
+ - selinux
+ - web
+ - pagure
+
+- name: set sebooleans so apache can send emails
+ seboolean: name=httpd_can_sendmail
+ state=true
+ persistent=true
+ tags:
+ - selinux
+ - web
+ - pagure
+
+
+# Ensure all the services are up and running
+
+- name: Start and enable httpd, postfix, pagure_milter
+ service: name={{ item }} enabled=yes state=started
+ with_items:
+ - httpd
+ - postfix
+ - stunnel
+ - redis
+ - pagure_ev
+ - pagure_ci
+ - pagure_loadjson
+ - pagure_logcom
+ - pagure_milter
+ - pagure_webhook
+ - pagure_worker
+ - pagure_gitolite_worker
+ - pagure_fast_worker
+ - pagure_medium_worker
+ - pagure_slow_worker
+# - pagure_api_key_expire_mail
+# - pagure_api_key_expire_mail.timer
+ - pagure_mirror_project_in
+ - pagure_mirror_project_in.timer
+# - fedmsg-relay
+ - haveged
+ ignore_errors: true
+ tags:
+ - pagure
+ - service
+ - postfix
+
+- name: setup logrotate to our needs
+ copy: src="{{ files }}/httpd/httpd.logrotate" dest=/etc/logrotate.d/httpd
+ tags:
+ - config
+ - apache
+
+- name: Add SAR script for pagure
+ copy: src=pagure_sar.py dest=/usr/local/bin/pagure_sar.py owner=git mode=0700
+ tags:
+ - SAR
+ - GDPR
+ - pagure
+
+- name: override the default syslog logrotate file
+ copy: src=syslog-logrotate dest=/etc/logrotate.d/syslog
+ tags:
+ - pagure
+ - logrotate
+
+- name: Letsencrypt for
releases.stg.pagure.org
+ include_role: name=letsencrypt
+ vars:
+ site_name:
releases.stg.pagure.org
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+ - letsencrypt
+
+- name: Letsencrypt for
docs.stg.pagure.org
+ include_role: name=letsencrypt
+ vars:
+ site_name:
docs.stg.pagure.org
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+ - letsencrypt
+
+- name: Letsencrypt for
stg.pagure.org
+ include_role: name=letsencrypt
+ vars:
+ site_name:
stg.pagure.org
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+ - letsencrypt
+
+- name: Letsencrypt for stg.pagure.io
+ include_role: name=letsencrypt
+ vars:
+ site_name: stg.pagure.io
+ when: env == 'pagure-staging'
+ tags:
+ - pagure
+ - letsencrypt
+
+- name: Letsencrypt for
pagure.org
+ include_role: name=letsencrypt
+ vars:
+ site_name:
pagure.org
+ when: env != 'pagure-staging'
+ tags:
+ - pagure
+ - letsencrypt
diff --git a/roles/pagure/frontend/templates/0_pagure.conf
b/roles/pagure/frontend/templates/0_pagure.conf
new file mode 100644
index 0000000..d14512f
--- /dev/null
+++ b/roles/pagure/frontend/templates/0_pagure.conf
@@ -0,0 +1,236 @@
+WSGISocketPrefix run/wsgi
+#WSGIRestrictStdout On
+WSGIRestrictSignal Off
+WSGIPythonOptimize 1
+WSGIPassAuthorization On
+WSGIDaemonProcess pagure user=git group=git maximum-requests=1000 display-name=pagure
processes=6 threads=6 inactivity-timeout=300
+WSGIDaemonProcess paguredocs user=git group=git maximum-requests=1000
display-name=paguredocs processes=4 threads=4 inactivity-timeout=300
+
+## Redirects http -> https
+
+<VirtualHost *:80>
+{% if env == 'pagure-staging' %}
+ ServerName stg.pagure.io
+ ProxyPass "/.well-known/acme-challenge"
"http://certgetter01/.well-known/acme-challenge"
+ Redirect permanent /
https://stg.pagure.io/
+{% else %}
+ ServerName pagure.io
+ Redirect permanent /
https://pagure.io/
+{% endif %}
+</VirtualHost>
+
+<VirtualHost *:80>
+{% if env == 'pagure-staging' %}
+ ServerName
docs.stg.pagure.org
+ ProxyPass "/.well-known/acme-challenge"
"http://certgetter01/.well-known/acme-challenge"
+ Redirect permanent /
https://docs.stg.pagure.org/
+{% else %}
+ ServerName
docs.pagure.org
+ Redirect permanent /
https://docs.pagure.org/
+{% endif %}
+</VirtualHost>
+
+<VirtualHost *:80>
+{% if env == 'pagure-staging' %}
+ ServerName
releases.stg.pagure.org
+ ProxyPass "/.well-known/acme-challenge"
"http://certgetter01/.well-known/acme-challenge"
+ Redirect permanent /
https://releases.stg.pagure.org/
+{% else %}
+ ServerName
releases.pagure.org
+ Redirect permanent /
https://releases.pagure.org/
+{% endif %}
+</VirtualHost>
+
+<VirtualHost *:80>
+{% if env == 'pagure-staging' %}
+ ServerName
stg.pagure.org
+ ProxyPass "/.well-known/acme-challenge"
"http://certgetter01/.well-known/acme-challenge"
+ Redirect permanent /
https://releases.stg.pagure.org/
+{% else %}
+ ServerName
pagure.org
+ #Redirect permanent /
https://releases.pagure.org/
+ ProxyPass "/.well-known/acme-challenge"
"http://certgetter01/.well-known/acme-challenge"
+{% endif %}
+
+# Added until we can get the cert out
+ DocumentRoot "/var/www/releases"
+
+ <Directory />
+ Options +Indexes
+ IndexOptions NameWidth=*
+ </Directory>
+
+</VirtualHost>
+
+
+
+## End of redirects http -> https
+
+
+<VirtualHost *:443>
+{% if env == 'pagure-staging' %}
+ ServerName stg.pagure.io
+{% else %}
+ ServerName pagure.io
+{% endif %}
+
+ Alias "/robots.txt" "/var/www/html/robots.txt"
+
+ WSGIScriptAlias / /var/www/pagure.wsgi
+
+ ServerAdmin admin(a)fedoraproject.org
+
+ SSLEngine on
+ SSLProtocol {{ ssl_protocols }}
+ SSLCipherSuite {{ ssl_ciphers }}
+ # Use secure TLSv1.1 and TLSv1.2 ciphers
+ Header always add Strict-Transport-Security "max-age=31536000; includeSubDomains;
preload"
+
+ SSLCertificateFile /etc/pki/tls/certs/pagure.io.cert
+ SSLCertificateChainFile /etc/pki/tls/certs/pagure.io.intermediate.cert
+ SSLCertificateKeyFile /etc/pki/tls/certs/pagure.io.key
+
+{% if env == 'pagure-staging' %}
+ Alias /static /usr/lib/python3.6/site-packages/pagure/static/
+{% else %}
+ Alias /static /usr/lib/python2.7/site-packages/pagure/static/
+{% endif %}
+
+ <Location "/static/vendor/emojione/emojione.sprites.png">
+ ExpiresActive On
+ ExpiresDefault "access plus 1 week"
+ Header append Cache-Control "public"
+ </Location>
+
+ SetEnv GIT_PROJECT_ROOT /srv/git/repositories
+
+ <Location />
+ WSGIProcessGroup pagure
+ <IfModule mod_authz_core.c>
+ # Apache 2.4
+ Require all granted
+ </IfModule>
+ <IfModule !mod_authz_core.c>
+ # Apache 2.2
+ Order deny,allow
+ Allow from all
+ </IfModule>
+ </Location>
+
+ <Location /releases>
+ Redirect "/releases"
https://releases.pagure.org
+ </Location>
+
+ <Location /apache-status>
+ SetHandler server-status
+ <RequireAny>
+ Require ip 127.0.0.1
+ Require ip ::1
+ Require host localhost
+ </RequireAny>
+ </Location>
+
+</VirtualHost>
+
+
+<VirtualHost *:443>
+{% if env == 'pagure-staging' %}
+ ServerName
stg.pagure.org
+{% else %}
+ ServerName
pagure.org
+{% endif %}
+
+ SSLEngine on
+ SSLProtocol {{ ssl_protocols }}
+ SSLCipherSuite {{ ssl_ciphers }}
+ # Use secure TLSv1.1 and TLSv1.2 ciphers
+ Header always add Strict-Transport-Security "max-age=31536000; includeSubDomains;
preload"
+
+{% if env == 'pagure-staging' %}
+ SSLCertificateFile /etc/pki/tls/certs/stg.pagure.org.cert
+ SSLCertificateChainFile /etc/pki/tls/certs/stg.pagure.org.intermediate.cert
+ SSLCertificateKeyFile /etc/pki/tls/private/stg.pagure.org.key
+{% else %}
+ SSLCertificateFile /etc/pki/tls/certs/pagure.org.cert
+ SSLCertificateChainFile /etc/pki/tls/certs/pagure.org.intermediate.cert
+ SSLCertificateKeyFile /etc/pki/tls/private/pagure.org.key
+{% endif %}
+{% if env == 'pagure-staging' %}
+ Redirect permanent /
https://stg.pagure.io/
+{% else %}
+ Redirect permanent /
https://pagure.io/
+{% endif %}
+</VirtualHost>
+
+
+<VirtualHost *:443>
+{% if env == 'pagure-staging' %}
+ ServerName
docs.stg.pagure.org
+{% else %}
+ ServerName
docs.pagure.org
+{% endif %}
+
+ WSGIScriptAlias / /var/www/docs_pagure.wsgi
+
+ SSLEngine on
+ SSLProtocol {{ ssl_protocols }}
+ SSLCipherSuite {{ ssl_ciphers }}
+ # Use secure TLSv1.1 and TLSv1.2 ciphers
+ Header always add Strict-Transport-Security "max-age=31536000; includeSubDomains;
preload"
+
+{% if env == 'pagure-staging' %}
+ SSLCertificateFile /etc/pki/tls/certs/docs.stg.pagure.org.cert
+ SSLCertificateChainFile /etc/pki/tls/certs/docs.stg.pagure.org.intermediate.cert
+ SSLCertificateKeyFile /etc/pki/tls/private/docs.stg.pagure.org.key
+{% else %}
+ SSLCertificateFile /etc/pki/tls/certs/pagure.io.cert
+ SSLCertificateChainFile /etc/pki/tls/certs/pagure.io.intermediate.cert
+ SSLCertificateKeyFile /etc/pki/tls/certs/pagure.io.key
+{% endif %}
+
+ Alias /static /usr/lib/python2.7/site-packages/pagure/static/
+
+ <Location "/static/vendor/emojione/emojione.sprites.png">
+ ExpiresActive On
+ ExpiresDefault "access plus 1 week"
+ Header append Cache-Control "public"
+ </Location>
+
+ <Location />
+ WSGIProcessGroup paguredocs
+ <IfModule mod_authz_core.c>
+ # Apache 2.4
+ Require all granted
+ </IfModule>
+ <IfModule !mod_authz_core.c>
+ # Apache 2.2
+ Order deny,allow
+ Allow from all
+ </IfModule>
+ </Location>
+</VirtualHost>
+
+<VirtualHost *:443>
+ DocumentRoot "/var/www/releases"
+{% if env == 'pagure-staging' %}
+ ServerName
releases.stg.pagure.org
+ SSLEngine on
+ SSLCertificateFile /etc/pki/tls/certs/releases.stg.pagure.org.cert
+ SSLCertificateKeyFile /etc/pki/tls/private/releases.stg.pagure.org.key
+ SSLCertificateChainFile /etc/pki/tls/certs/releases.stg.pagure.org.intermediate.cert
+ SSLHonorCipherOrder On
+ SSLProtocol {{ ssl_protocols }}
+ SSLCipherSuite {{ ssl_ciphers }}
+{% else %}
+ ServerName
releases.pagure.org
+{% endif %}
+
+ AddType application/octet-stream msi
+
+ <Directory />
+ Options +Indexes
+ IndexOptions NameWidth=*
+ </Directory>
+
+</VirtualHost>
+
diff --git a/roles/pagure/frontend/templates/alembic.ini
b/roles/pagure/frontend/templates/alembic.ini
new file mode 100644
index 0000000..7daf38c
--- /dev/null
+++ b/roles/pagure/frontend/templates/alembic.ini
@@ -0,0 +1,50 @@
+# A generic, single database configuration.
+
+[alembic]
+# path to migration scripts
+script_location = /usr/share/pagure/alembic
+
+# template used to generate migration files
+# file_template = %%(rev)s_%%(slug)s
+
+# set to 'true' to run the environment during
+# the 'revision' command, regardless of autogenerate
+# revision_environment = false
+
+#sqlalchemy.url = postgresql://<%= pkgdb_app %>:<%= pkgdb_appPassword
%>@db-pkgdb/pkgdb
+
+
+# Logging configuration
+[loggers]
+keys = root,sqlalchemy,alembic
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = WARN
+handlers = console
+qualname =
+
+[logger_sqlalchemy]
+level = WARN
+handlers =
+qualname = sqlalchemy.engine
+
+[logger_alembic]
+level = INFO
+handlers =
+qualname = alembic
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(levelname)-5.5s [%(name)s] %(message)s
+datefmt = %H:%M:%S
diff --git a/roles/pagure/frontend/templates/docs_pagure.wsgi
b/roles/pagure/frontend/templates/docs_pagure.wsgi
new file mode 100644
index 0000000..a9f8cea
--- /dev/null
+++ b/roles/pagure/frontend/templates/docs_pagure.wsgi
@@ -0,0 +1,22 @@
+#-*- coding: utf-8 -*-
+
+# The three lines below are required to run on EL6 as EL6 has
+# two possible version of python-sqlalchemy and python-jinja2
+# These lines make sure the application uses the correct version.
+import __main__
+__main__.__requires__ = ['SQLAlchemy >= 0.8', 'jinja2 >= 2.4']
+import pkg_resources
+
+import os
+## Set the environment variable pointing to the configuration file
+os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
+
+## The following is only needed if you did not install pagure
+## as a python module (for example if you run it from a git clone).
+#import sys
+#sys.path.insert(0, '/path/to/pagure/')
+
+
+## The most import line to make the wsgi working
+from pagure.docs_server import APP as application
+#application.debug = True
diff --git a/roles/pagure/frontend/templates/fedora-messaging.toml
b/roles/pagure/frontend/templates/fedora-messaging.toml
new file mode 100644
index 0000000..195a89d
--- /dev/null
+++ b/roles/pagure/frontend/templates/fedora-messaging.toml
@@ -0,0 +1,25 @@
+# A sample configuration for fedora-messaging. This file is in the TOML format.
+# For complete details on all configuration options, see the documentation.
+
+{% if env == "pagure-staging" %}
+amqp_url = "amqps://pagure.stg:@rabbitmq.stg.fedoraproject.org/%2Fpubsub"
+{% else %}
+amqp_url = "amqps://pagure:@rabbitmq.fedoraproject.org/%2Fpubsub"
+{% endif %}
+
+# The topic_prefix configuration value will add a prefix to the topics of every sent
message.
+# This is used for migrating from fedmsg, and should not be used afterwards.
+{% if env == "pagure-staging" %}
+topic_prefix = "io.pagure.stg"
+{% else %}
+topic_prefix = "io.pagure.prod"
+{% endif %}
+
+[tls]
+ca_cert = "/etc/pki/rabbitmq/pagurecert/pagure.ca"
+keyfile = "/etc/pki/rabbitmq/pagurecert/pagure.key"
+certfile = "/etc/pki/rabbitmq/pagurecert/pagure.crt"
+
+[client_properties]
+app = "pagure.io"
+
diff --git a/roles/pagure/frontend/templates/gitolite.rc
b/roles/pagure/frontend/templates/gitolite.rc
new file mode 100644
index 0000000..77eb32b
--- /dev/null
+++ b/roles/pagure/frontend/templates/gitolite.rc
@@ -0,0 +1,196 @@
+# configuration variables for gitolite
+
+# This file is in perl syntax. But you do NOT need to know perl to edit it --
+# just mind the commas, use single quotes unless you know what you're doing,
+# and make sure the brackets and braces stay matched up!
+
+# (Tip: perl allows a comma after the last item in a list also!)
+
+# HELP for commands can be had by running the command with "-h".
+
+# HELP for all the other FEATURES can be found in the documentation (look for
+# "list of non-core programs shipped with gitolite" in the master index) or
+# directly in the corresponding source file.
+
+%RC = (
+
+ # ------------------------------------------------------------------
+ HTTP_ANON_USER => 'ANONYMOUS_',
+
+ # default umask gives you perms of '0700'; see the rc file docs for
+ # how/why you might change this
+ UMASK => 0077,
+
+ # look for "git-config" in the documentation
+ GIT_CONFIG_KEYS => '',
+
+ # comment out if you don't need all the extra detail in the logfile
+ LOG_EXTRA => 1,
+ # syslog options
+ # 1. leave this section as is for normal gitolite logging
+ # 2. uncomment this line to log only to syslog:
+ # LOG_DEST => 'syslog',
+ # 3. uncomment this line to log to syslog and the normal gitolite log:
+ # LOG_DEST => 'syslog,normal',
+
+ # roles. add more roles (like MANAGER, TESTER, ...) here.
+ # WARNING: if you make changes to this hash, you MUST run 'gitolite
+ # compile' afterward, and possibly also 'gitolite trigger
POST_COMPILE'
+ ROLES => {
+ READERS => 1,
+ WRITERS => 1,
+ },
+
+ # enable caching (currently only Redis). PLEASE RTFM BEFORE USING!!!
+ # CACHE => 'Redis',
+
+ # ------------------------------------------------------------------
+
+ # rc variables used by various features
+
+ # the 'info' command prints this as additional info, if it is set
+ # SITE_INFO => 'Please see
http://blahblah/gitolite for
more help',
+
+ # the CpuTime feature uses these
+ # display user, system, and elapsed times to user after each git operation
+ # DISPLAY_CPU_TIME => 1,
+ # display a warning if total CPU times (u, s, cu, cs) crosses this limit
+ # CPU_TIME_WARN_LIMIT => 0.1,
+
+ # the Mirroring feature needs this
+ # HOSTNAME => "foo",
+
+ # TTL for redis cache; PLEASE SEE DOCUMENTATION BEFORE UNCOMMENTING!
+ # CACHE_TTL => 600,
+
+ # ------------------------------------------------------------------
+
+ # suggested locations for site-local gitolite code (see cust.html)
+
+ # this one is managed directly on the server
+ # LOCAL_CODE => "$ENV{HOME}/local",
+
+ # or you can use this, which lets you put everything in a subdirectory
+ # called "local" in your gitolite-admin repo. For a SECURITY WARNING
+ # on this, see
http://gitolite.com/gitolite/non-core.html#pushcode
+ # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
+
+ # ------------------------------------------------------------------
+
+ # List of commands and features to enable
+
+ ENABLE => [
+
+ # COMMANDS
+
+ # These are the commands enabled by default
+ 'help',
+ 'desc',
+ 'info',
+ 'perms',
+ 'writable',
+
+ # Uncomment or add new commands here.
+ # 'create',
+ # 'fork',
+ # 'mirror',
+ # 'readme',
+ # 'sskm',
+ # 'D',
+
+ # These FEATURES are enabled by default.
+
+ # essential (unless you're using smart-http mode)
+ 'ssh-authkeys',
+
+ # creates git-config enties from gitolite.conf file entries like 'config
foo.bar = baz'
+ 'git-config',
+
+ # creates git-daemon-export-ok files; if you don't use git-daemon,
comment this out
+ #'daemon',
+
+ # creates projects.list file; if you don't use gitweb, comment this out
+ #'gitweb',
+
+ # These FEATURES are disabled by default; uncomment to enable. If you
+ # need to add new ones, ask on the mailing list :-)
+
+ # user-visible behaviour
+
+ # prevent wild repos auto-create on fetch/clone
+ # 'no-create-on-read',
+ # no auto-create at all (don't forget to enable the 'create'
command!)
+ # 'no-auto-create',
+
+ # access a repo by another (possibly legacy) name
+ # 'Alias',
+
+ # give some users direct shell access. See documentation in
+ # sts.html for details on the following two choices.
+ # "Shell $ENV{HOME}/.gitolite.shell-users",
+ # 'Shell alice bob',
+
+ # set default roles from lines like 'option default.roles-1 = ...',
etc.
+ # 'set-default-roles',
+
+ # show more detailed messages on deny
+ # 'expand-deny-messages',
+
+ # show a message of the day
+ # 'Motd',
+
+ # system admin stuff
+
+ # enable mirroring (don't forget to set the HOSTNAME too!)
+ # 'Mirroring',
+
+ # allow people to submit pub files with more than one key in them
+ # 'ssh-authkeys-split',
+
+ # selective read control hack
+ # 'partial-copy',
+
+ # manage local, gitolite-controlled, copies of read-only upstream repos
+ # 'upstream',
+
+ # updates 'description' file instead of 'gitweb.description'
config item
+ # 'cgit',
+
+ # allow repo-specific hooks to be added
+ # 'repo-specific-hooks',
+
+ # performance, logging, monitoring...
+
+ # be nice
+ # 'renice 10',
+
+ # log CPU times (user, system, cumulative user, cumulative system)
+ # 'CpuTime',
+
+ # syntactic_sugar for gitolite.conf and included files
+
+ # allow backslash-escaped continuation lines in gitolite.conf
+ # 'continuation-lines',
+
+ # create implicit user groups from directory names in keydir/
+ # 'keysubdirs-as-groups',
+
+ # allow simple line-oriented macros
+ # 'macros',
+
+ # Kindergarten mode
+
+ # disallow various things that sensible people shouldn't be doing anyway
+ # 'Kindergarten',
+ ],
+
+);
+
+# ------------------------------------------------------------------------------
+# per perl rules, this should be the last line in such a file:
+1;
+
+# Local variables:
+# mode: perl
+# End:
+# vim: set syn=perl:
diff --git a/roles/pagure/frontend/templates/pagure.cfg
b/roles/pagure/frontend/templates/pagure.cfg
new file mode 100644
index 0000000..253d855
--- /dev/null
+++ b/roles/pagure/frontend/templates/pagure.cfg
@@ -0,0 +1,380 @@
+from datetime import timedelta
+
+### Set the time after which the admin session expires
+# There are two sessions on pagure, login that holds for 31 days and
+# the session defined here after which an user has to re-login.
+# This session is used when accessing all administrative parts of pagure
+# (ie: changing a project's or a user's settings)
+ADMIN_SESSION_LIFETIME = timedelta(minutes=20)
+
+# Make the CSRF token not-time limited, this way it is valid for the entire
+# duration of the session.
+WTF_CSRF_TIME_LIMIT=None
+
+### Secret key for the Flask application
+SECRET_KEY='{{ pagure_secret_key }}'
+SALT_EMAIL='{{ pagure_secret_salt_email }}'
+
+EMAIL_SEND = True
+
+# This is required so that login specifies https
+PREFERRED_URL_SCHEME='https'
+
+{% if env == 'pagure-staging' %}
+# OpenID server to use
+FAS_OPENID_ENDPOINT = 'https://id.stg.fedoraproject.org/openid/'
+{% endif %}
+
+### url to the database server:
+#DB_URL=mysql://user:pass@host/db_name
+#DB_URL=postgres://user:pass@host/db_name
+DB_URL = 'postgresql://{{ pagure_db_user }}:{{ pagure_db_pass }}@{{ pagure_db_host
}}/{{ pagure_db_name }}'
+
+### The FAS group in which the admin of pagure are
+ADMIN_GROUP = ['sysadmin-main']
+
+# The publicly visible admin email address
+ADMIN_EMAIL = 'admin(a)fedoraproject.org'
+
+### The email address to which the flask.log will send the errors (tracebacks)
+EMAIL_ERROR = 'pingou(a)pingoured.fr'
+
+### Default SMTP server to use for sending emails
+SMTP_SERVER = 'localhost'
+
+### Email used to sent emails
+{% if env == 'pagure-staging' %}
+FROM_EMAIL = 'pagure(a)stg.pagure.io'
+DOMAIN_EMAIL_NOTIFICATIONS = 'stg.pagure.io'
+{% else %}
+FROM_EMAIL = 'pagure(a)pagure.io'
+DOMAIN_EMAIL_NOTIFICATIONS = 'pagure.io'
+{% endif %}
+
+### The URL at which the project is available.
+{% if env == 'pagure-staging' %}
+APP_URL = 'https://stg.pagure.io/'
+DOC_APP_URL = 'https://docs.stg.pagure.org'
+{% else %}
+APP_URL = 'https://pagure.io/'
+DOC_APP_URL = 'https://docs.pagure.org'
+{% endif %}
+
+### Datagrepper info for the user profile
+{% if env == 'pagure-staging' %}
+DATAGREPPER_URL = 'https://apps.stg.fedoraproject.org/datagrepper'
+{% else %}
+DATAGREPPER_URL = 'https://apps.fedoraproject.org/datagrepper'
+{% endif %}
+DATAGREPPER_CATEGORY = 'pagure'
+
+### The URL to use to clone git repositories.
+{% if env == 'pagure-staging' %}
+GIT_URL_SSH = 'ssh://git@stg.pagure.io/'
+GIT_URL_GIT = 'https://stg.pagure.io/'
+{% else %}
+GIT_URL_SSH = 'ssh://git@pagure.io/'
+GIT_URL_GIT = 'https://pagure.io/'
+{% endif %}
+
+### The IP addresses allowed for the internal endpoints
+{% if eth0_ipv6 is defined %}
+IP_ALLOWED_INTERNAL = ['127.0.0.1', 'localhost', '::1', '{{
eth0_ip }}' , '{{ eth0_ipv6 }}']
+{% elif eth0_ip is defined %}
+IP_ALLOWED_INTERNAL = ['127.0.0.1', 'localhost', '::1', '{{
eth0_ip }}']
+{% else %}
+IP_ALLOWED_INTERNAL = ['127.0.0.1', 'localhost', '::1']
+{% endif %}
+
+# Redis configuration
+{% if env == 'pagure-staging' %}
+EVENTSOURCE_SOURCE = 'https://stg.pagure.io:8088'
+{% else %}
+EVENTSOURCE_SOURCE = 'https://pagure.io:8088'
+{% endif %}
+REDIS_HOST = '0.0.0.0'
+REDIS_PORT = 6379
+REDIS_DB = 0
+
+EV_STATS_PORT = '8888'
+
+WEBHOOK = True
+
+### Folder containing to the git repos
+GIT_FOLDER = '/srv/git/repositories'
+
+### Folder containing the forks repos
+FORK_FOLDER = '/srv/git/repositories/forks'
+
+### Folder containing the docs repos
+DOCS_FOLDER = '/srv/git/repositories/docs'
+
+### Folder containing the pull-requests repos
+REQUESTS_FOLDER = '/srv/git/repositories/requests'
+
+### Folder containing the tickets repos
+TICKETS_FOLDER = '/srv/git/repositories/tickets'
+
+### Folder containing the clones of the remotes git repo
+REMOTE_GIT_FOLDER = '/srv/git/remotes'
+
+### Folder containing out-of-git attachments cache
+ATTACHMENTS_FOLDER = '/srv/attachments'
+
+### Configuration file for gitolite
+GITOLITE_CONFIG = '/srv/git/.gitolite/conf/gitolite.conf'
+
+### Path of the release folder
+{% if env == 'pagure-staging' %}
+UPLOAD_FOLDER_URL = 'https://releases.stg.pagure.org/'
+{% else %}
+UPLOAD_FOLDER_URL = 'https://releases.pagure.org/'
+{% endif %}
+UPLOAD_FOLDER_PATH = '/var/www/releases/'
+
+### Folder where are cached the archives
+ARCHIVE_FOLDER = '/var/www/archives/'
+
+
+### Home folder of the gitolite user
+### Folder where to run gl-compile-conf from
+GITOLITE_HOME = '/srv/git/'
+
+### Folder containing all the public ssh keys for gitolite
+GITOLITE_KEYDIR = '/srv/git/.gitolite/keydir/'
+
+### Path to the gitolite.rc file
+GL_RC = '/srv/git/.gitolite.rc'
+
+### Path to the /bin directory where the gitolite tools can be found
+GL_BINDIR = '/usr/bin/'
+
+
+### Temp folder to be used to make the clones to work around bug in libgit2:
+## refs:
https://github.com/libgit2/libgit2/issues/2965
+## and
https://github.com/libgit2/libgit2/issues/2797
+TMP_FOLDER = '/srv/tmp'
+
+# Optional configuration
+
+### Number of items displayed per page
+# Used when listing items
+ITEM_PER_PAGE = 50
+
+### Maximum size of the uploaded content
+# Used to limit the size of file attached to a ticket for example
+MAX_CONTENT_LENGTH = 100 * 1024 * 1024 # 100 megabytes
+
+### Lenght for short commits ids or file hex
+SHORT_LENGTH = 7
+
+### List of blacklisted project names that can conflicts for pagure's URLs
+### or other
+BLACKLISTED_PROJECTS = [
+ 'static', 'pv', 'releases', 'new', 'api',
'settings', 'search', 'fork',
+ 'logout', 'login', 'user', 'users', 'groups',
'projects', 'ssh_info',
+ 'issues', 'pull-requests', 'commits', 'tree',
'forks', 'admin', 'c',
+ 'wait',
+]
+
+DISABLED_PLUGINS = ['IRC']
+
+
+# Authentication related configuration option
+
+### Switch the authentication method
+# Specify which authentication method to use, defaults to `fas` can be or
+# `local`
+# Default: ``fas``.
+PAGURE_AUTH = 'openid'
+
+# When this is set to True, the session cookie will only be returned to the
+# server via ssl (https). If you connect to the server via plain http, the
+# cookie will not be sent. This prevents sniffing of the cookie contents.
+# This may be set to False when testing your application but should always
+# be set to True in production.
+# Default: ``True``.
+SESSION_COOKIE_SECURE = True
+
+# The name of the cookie used to store the session id.
+# Default: ``.pagure``.
+SESSION_COOKIE_NAME = 'pagure'
+
+# Boolean specifying wether to check the user's IP address when retrieving
+# its session. This make things more secure (thus is on by default) but
+# under certain setup it might not work (for example is there are proxies
+# in front of the application).
+CHECK_SESSION_IP = True
+
+# Used by SESSION_COOKIE_PATH
+APPLICATION_ROOT = '/'
+
+# Set the SSH certs/keys
+{% if env == 'pagure-staging' %}
+SSH_KEYS = {
+ 'RSA': {
+ 'fingerprint': '2048 69:50:46:24:c7:94:44:f8:8d:83:05:5c:eb:73:fb:c4
(RSA)',
+ 'pubkey': 'stg.pagure.io,8.43.85.77,2620:52:3:1:dead:beef:cafe:fed3
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQDJNu490Rp305zGCJLvhVIrKjL7Xngew3NxgRYeopHBDvj+EFQUqULXtgrI5nUBMSB94RrsuHynFAXYy2m0snHjWzWjbIxM4ZVD2sX4GiKX6qu7WyxcGmGcL08MF919r+JSPL9oWWSq/CvvBF0M1eeqkIpjMZHpVKgR3uTMD5yW994NBLAQi9i1UdwGYNQc1KqWvlvW1XhFFtiIGscIFGRKsUOMvnJvWdU6T+djmzMy4hcahxnsPCZxCjbQpuH1JjihNNVWYOq7Ztjs1gxpTTV19ATp4Z2F95uyyQ3Y+Em9KeXcKXYxwVzYVho5SSB1ZYBL+xAH1osK23PvGD39UYp9',
+ 'SHA256': 'SHA256:x4xld/tPdeOhbyJcTOxd+IbSZ4OpnBzh/IskocyrOM',
+ }
+}
+{% else %}
+SSH_KEYS = {
+ 'RSA': {
+ 'fingerprint': '2048 90:8e:7f:a3:f7:f1:70:cb:56:77:96:17:44:c4:fc:82
(RSA)',
+ 'pubkey': 'pagure.io,8.43.85.75,2620:52:3:1:dead:beef:cafe:fed5
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQC198DWs0SQ3DX0ptu+8Wq6wnZMrXUCufN+wdSCtlyhHUeQ3q5B4Hgto1n2FMj752vToCfNTn9mWO7l2rNTrKeBsELpubl2jECHu4LqxkRVihu5UEzejfjiWNDN2jdXbYFY27GW9zymD7Gq3u+T/Mkp4lIcQKRoJaLobBmcVxrLPEEJMKI4AJY31jgxMTnxi7KcR+U5udQrZ3dzCn2BqUdiN5dMgckr4yNPjhl3emJeVJ/uhAJrEsgjzqxAb60smMO5/1By+yF85Wih4TnFtF4LwYYuxgqiNv72Xy4D/MGxCqkO/nH5eRNfcJ+AJFE7727F7Tnbo4xmAjilvRria/+l',
+ 'SHA256': 'SHA256:Gddkd5H7oQ1RaK8WgXSKl7JZP+FgLyidmxbLercJ/JY',
+ }
+}
+{% endif %}
+
+# Allow the backward compatiblity endpoints for the old URLs schema to
+# see the commits of a repo. This is only interesting if you pagure instance
+# was running since before version 1.3 and if you care about backward
+# compatibility in your URLs.
+OLD_VIEW_COMMIT_ENABLED = True
+
+PAGURE_CI_SERVICES=['jenkins']
+
+from pagure.mail_logging import ContextInjector, MSG_FORMAT
+LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'formatters': {
+ 'standard': {
+ 'format': '%(asctime)s [%(levelname)s] %(name)s:
%(message)s'
+ },
+ 'email_format': {
+ 'format': MSG_FORMAT
+ }
+ },
+ 'filters': {
+ 'myfilter': {
+ '()': ContextInjector,
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'formatter': 'standard',
+ 'class': 'logging.StreamHandler',
+ 'stream': 'ext://sys.stdout',
+ },
+ 'email': {
+ 'level': 'ERROR',
+ 'formatter': 'email_format',
+ 'class': 'logging.handlers.SMTPHandler',
+ 'mailhost': 'localhost',
+ 'fromaddr': 'pagure(a)pagure.io',
+ 'toaddrs': 'pingou(a)pingoured.fr',
+ 'subject': 'ERROR on pagure.io',
+ 'filters': ['myfilter'],
+ },
+ },
+ # The root logger configuration; this is a catch-all configuration
+ # that applies to all log messages not handled by a different logger
+ 'root': {
+ 'level': 'INFO',
+ 'handlers': ['console', 'email'],
+ },
+ 'loggers': {
+ 'pagure': {
+ 'handlers': ['console', 'email'],
+ 'level': 'DEBUG',
+ 'propagate': True
+ },
+ 'flask': {
+ 'handlers': ['console'],
+ 'level': 'INFO',
+ 'propagate': False
+ },
+ 'sqlalchemy': {
+ 'handlers': ['console'],
+ 'level': 'WARN',
+ 'propagate': False
+ },
+ 'binaryornot': {
+ 'handlers': ['console'],
+ 'level': 'WARN',
+ 'propagate': True
+ },
+ 'pagure.lib.encoding_utils': {
+ 'handlers': ['console'],
+ 'level': 'WARN',
+ 'propagate': False
+ },
+ }
+}
+
+CROSS_PROJECT_ACLS = [
+ 'create_project',
+ 'fork_project',
+ 'modify_project',
+ 'issue_create',
+ 'issue_comment',
+ 'pull_request_create',
+ 'pull_request_comment',
+ 'pull_request_merge',
+ 'pull_request_flag',
+]
+
+BLACKLISTED_GROUPS = ['forks', 'group', 'rpms',
'modules', 'container', 'tests']
+
+GITOLITE_CELERY_QUEUE = 'gitolite_queue'
+FAST_CELERY_QUEUE = 'fast_workers'
+MEDIUM_CELERY_QUEUE = 'medium_workers'
+SLOW_CELERY_QUEUE = 'slow_workers'
+PRIVATE_PROJECTS = False
+FEDMSG_NOTIFICATIONS = False
+FEDORA_MESSAGING_NOTIFICATIONS = True
+THEME = 'pagureio'
+
+MIRROR_SSHKEYS_FOLDER='/srv/mirror/ssh'
+
+SSH_KEYS_USERNAME_EXPECT = "git"
+SSH_KEYS_OPTIONS = 'restrict,command="/usr/libexec/pagure/aclchecker.py
%(username)s"'
+
+SSH_COMMAND_REPOSPANNER = ([
+ "/usr/libexec/repobridge",
+ "--extra", "username", "%(username)s",
+ "--extra", "repotype", "%(repotype)s",
+ "--extra", "project_name", "%(project_name)s",
+ "--extra", "project_user", "%(project_user)s",
+ "--extra", "project_namespace",
"%(project_namespace)s",
+ "%(cmd)s",
+ "'%(repotype)s/%(reponame)s'",
+], {"REPOBRIDGE_CONFIG": "/etc/pagure/repobridge_ansible.json"})
+SSH_COMMAND_NON_REPOSPANNER = ([
+ "/usr/bin/%(cmd)s",
+ "/srv/git/repositories/%(reponame)s",
+], {"GL_USER": "%(username)s"})
+
+
+
+GIT_AUTH_BACKEND = 'pagure'
+HTTP_REPO_ACCESS_GITOLITE = None
+
+{% if env == 'pagure-staging' %}
+CSP_HEADERS = (
+ "default-src 'self';"
+ "script-src 'self' '{nonce_script}'; "
+ "style-src 'self' '{nonce_style}'; "
+ "object-src 'none';"
+ "base-uri 'self';"
+ "img-src 'self' https:;"
+ "connect-src 'self'
https://stg.pagure.io:8088;"
+ "frame-src
https://docs.stg.pagure.org;"
+ "frame-ancestors
https://stg.pagure.io;"
+)
+{% else %}
+CSP_HEADERS = (
+ "default-src 'self';"
+ "script-src 'self' '{nonce_script}'; "
+ "style-src 'self' '{nonce_style}'; "
+ "object-src 'none';"
+ "base-uri 'self';"
+ "img-src 'self' https:;"
+ "connect-src 'self'
https://pagure.io:8088;"
+ "frame-src
https://docs.pagure.org;"
+ "frame-ancestors
https://pagure.io;"
+)
+{% endif %}
diff --git a/roles/pagure/frontend/templates/pagure.wsgi
b/roles/pagure/frontend/templates/pagure.wsgi
new file mode 100644
index 0000000..75c6ef3
--- /dev/null
+++ b/roles/pagure/frontend/templates/pagure.wsgi
@@ -0,0 +1,29 @@
+#-*- coding: utf-8 -*-
+
+# The three lines below are required to run on EL6 as EL6 has
+# two possible version of python-sqlalchemy and python-jinja2
+# These lines make sure the application uses the correct version.
+import __main__
+__main__.__requires__ = ['SQLAlchemy >= 0.8', 'jinja2 >= 2.4',
'Pygments>=2.1.0']
+import pkg_resources
+
+import os
+## Set the environment variable pointing to the configuration file
+os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
+
+## Set the environment variable if the tmp folder needs to be moved
+## Is necessary to work around bug in libgit2:
+## refs:
https://github.com/libgit2/libgit2/issues/2965
+## and
https://github.com/libgit2/libgit2/issues/2797
+os.environ['TEMP'] = '/srv/tmp/'
+
+## The following is only needed if you did not install pagure
+## as a python module (for example if you run it from a git clone).
+#import sys
+#sys.path.insert(0, '/path/to/pagure/')
+
+
+# The most import line to make the wsgi working
+from pagure.flask_app import create_app
+
+application = create_app()
diff --git a/roles/pagure/frontend/templates/robots.txt.j2
b/roles/pagure/frontend/templates/robots.txt.j2
new file mode 100644
index 0000000..9e911bd
--- /dev/null
+++ b/roles/pagure/frontend/templates/robots.txt.j2
@@ -0,0 +1,10 @@
+User-agent: *
+{% if env == 'pagure-staging' %}
+Disallow: /
+{% else %}
+Disallow: /api
+Disallow: /login
+Disallow: /*/raw
+Disallow: /*/blob
+Crawl-Delay: 2
+{% endif %}
diff --git a/roles/pagure/frontend/templates/securityheaders.conf
b/roles/pagure/frontend/templates/securityheaders.conf
new file mode 100644
index 0000000..42adcad
--- /dev/null
+++ b/roles/pagure/frontend/templates/securityheaders.conf
@@ -0,0 +1,8 @@
+Header always set X-Xss-Protection "1; mode=block"
+Header always set X-Content-Type-Options "nosniff"
+Header always set Referrer-Policy "same-origin"
+{% if env == 'pagure-staging' %}
+Header always set X-Frame-Options "ALLOW-FROM
https://stg.pagure.io/"
+{% else %}
+Header always set X-Frame-Options "ALLOW-FROM
https://pagure.io/"
+{% endif %}
diff --git a/roles/pagure/frontend/templates/stunnel-conf.j2
b/roles/pagure/frontend/templates/stunnel-conf.j2
new file mode 100644
index 0000000..3f97e5b
--- /dev/null
+++ b/roles/pagure/frontend/templates/stunnel-conf.j2
@@ -0,0 +1,16 @@
+{% if env == 'pagure-staging' %}
+cert = /etc/pki/tls/certs/stg.pagure.io.bundle.cert
+key = /etc/pki/tls/private/stg.pagure.io.key
+{% else %}
+cert = /etc/pki/tls/certs/pagure.io.bundle.cert
+key = /etc/pki/tls/certs/pagure.io.key
+{% endif %}
+pid = /var/run/stunnel.pid
+
+[{{ stunnel_service }}]
+sslVersion = all
+options = NO_SSLv2
+options = NO_SSLv3
+options = NO_TLSv1
+accept = {{ stunnel_source_port }}
+connect = {{ stunnel_destination_port }}