Add a Fedora-hubs role based on the included Ansible role

This commit is contained in:
Aurélien Bompard 2017-06-27 16:27:40 +00:00
parent 364f0fd2fa
commit ea1c4cd45d
21 changed files with 706 additions and 83 deletions

View file

@ -11,6 +11,7 @@
tasks:
- include: "{{ tasks_path }}/persistent_cloud.yml"
- name: setup all the things
hosts: hubs-dev.fedorainfracloud.org
gather_facts: True
@ -20,107 +21,54 @@
- /srv/private/ansible/files/openstack/passwords.yml
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
roles:
- certbot
pre_tasks:
- include: "{{ tasks_path }}/cloud_setup_basic.yml"
- name: set hostname (required by some services, at least postfix need it)
hostname: name="{{inventory_hostname}}"
tasks:
- include: "{{ tasks_path }}/yumrepos.yml"
- dnf: name={{item}} state=present
with_items:
- git
- file: dest=/srv/git state=directory
- git: repo=https://pagure.io/fedora-hubs.git
dest=/srv/git/fedora-hubs
- name: create the code directory
file: dest=/srv/hubs state=directory owner=fedora group=fedora
- name: git clone the code
git: repo=https://pagure.io/fedora-hubs.git
dest=/srv/hubs/fedora-hubs
version=develop
ignore_errors: true
- file: dest=/etc/fedmsg.d/ state=directory
- name: copy around a number of files we want
command: cp {{item.src}} {{item.dest}}
with_items:
- src: /srv/git/fedora-hubs/fedmsg.d/testconfig.py
dest: /etc/fedmsg.d/testconfig.py
remote_src: True
- src: /srv/git/fedora-hubs/fedmsg.d/base.py
dest: /etc/fedmsg.d/base.py
remote_src: True
- src: /srv/git/fedora-hubs/fedmsg.d/logging.py
dest: /etc/fedmsg.d/logging.py
remote_src: True
- src: /srv/git/fedora-hubs/systemd/hubs-worker@.service
dest: /usr/lib/systemd/system/hubs-worker@.service
remote_src: True
- src: /srv/git/fedora-hubs/systemd/hubs-triage@.service
dest: /usr/lib/systemd/system/hubs-triage@.service
remote_src: True
- src: /srv/git/fedora-hubs/systemd/hubs-webapp.service
dest: /usr/lib/systemd/system/hubs-webapp.service
remote_src: True
become_user: fedora
#ignore_errors: true
roles:
- certbot
- role: hubs
main_user: fedora
hubs_url_hostname: hubs-dev.fedorainfracloud.org
hubs_secret_key: demotestinghubsmachine
hubs_db_type: sqlite
hubs_dev_mode: false
hubs_ssl_cert: /etc/letsencrypt/live/hubs-dev.fedorainfracloud.org/cert.pem
hubs_ssl_key: /etc/letsencrypt/live/hubs-dev.fedorainfracloud.org/privkey.pem
tasks:
- dnf: name={{item}} state=present
with_items:
- htop
- tmux
- vim
- redis
- python-pip
- gcc
- gcc-c++
- sqlite-devel
- libffi-devel
- openssl-devel
- python-datanommer-consumer
- datanommer-commands
- fedmsg-hub
- python-flask
- python-oauth2client
- python-bleach
- python-dogpile-cache
- python-psycopg2
- postgresql-devel
- postgresql-server
- command: pip install -r requirements.txt
chdir=/srv/git/fedora-hubs
creates=/usr/lib/python2.7/site-packages/fedmsg/
# The one in epel7 is too old... :(
- command: pip install --upgrade pygments
- command: pip install futures
creates=/usr/lib/python2.7/site-packages/concurrent/futures/
- command: python setup.py develop
chdir=/srv/git/fedora-hubs
creates=/usr/lib/python2.7/site-packages/fedora-hubs.egg-link
- command: systemctl daemon-reload
- service: name={{item}} enabled=yes state=started
- name: add more hubs workers
service: name={{item}} enabled=yes state=started
with_items:
- redis
- hubs-webapp
- hubs-worker@1
- hubs-worker@2
- hubs-worker@3
- hubs-worker@4
- hubs-worker@5
- hubs-worker@6
- hubs-worker@7
- hubs-worker@8
- hubs-triage@1
- hubs-triage@2
- hubs-triage@3
- hubs-triage@4
- hubs-triage@5
- hubs-triage@6
# Set up the db for datanommer
- command: postgresql-setup initdb creates=/var/lib/pgsql/data/pg_hba.conf
- service: name=postgresql enabled=yes state=started
# TODO -- createdb -E utf-8 datanommer
# TODO -- `datanommer-create-db`
- service: name=fedmsg-hub enabled=yes state=started
- hubs-worker@3
- hubs-worker@4

View file

@ -0,0 +1,14 @@
main_user: hubs
hubs_dev_mode: false
hubs_secret_key: changeme
hubs_base_dir: "/srv/hubs"
hubs_code_dir: "{{ hubs_base_dir }}/fedora-hubs"
hubs_conf_dir: "{{ hubs_base_dir }}/config"
hubs_venv_dir: "{{ hubs_base_dir }}/venv"
hubs_var_dir: "{{ hubs_base_dir }}/var"
hubs_db_type: sqlite
hubs_db_password: changeme
hubs_url_hostname: localhost
hubs_url: http{% if not hubs_dev_mode %}s{% endif %}://{{ hubs_url_hostname }}{% if hubs_dev_mode %}:5000{% endif %}
hubs_ssl_cert: /etc/pki/tls/certs/localhost.crt
hubs_ssl_key: /etc/pki/tls/private/localhost.key

View file

@ -0,0 +1,23 @@
# From https://docs.python.org/2/howto/logging.html
[loggers]
keys=root
[handlers]
keys=console
[formatters]
keys=simple
[logger_root]
level=DEBUG
handlers=console
[handler_console]
class=StreamHandler
level=DEBUG
formatter=simple
args=(sys.stdout,)
[formatter_simple]
format=[%(asctime)s][%(process)d][%(levelname)s] (%(name)s) %(message)s
datefmt=%H:%M:%S

View file

@ -0,0 +1,6 @@
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;

View file

@ -0,0 +1,14 @@
# PostgreSQL Client Authentication Configuration File
# ===================================================
#
# Refer to the "Client Authentication" section in the PostgreSQL
# documentation for a complete description of this file.
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5

View file

@ -0,0 +1,21 @@
- name: restart postgresql
service: name=postgresql state=restarted
- name: restart the hubs-specific fedmsg-hub
service: name=hubs-fedmsg-hub state=restarted
listen: "hubs configuration change"
- name: restart hubs triage
service: name=hubs-triage@* state=restarted
listen: "hubs configuration change"
- name: restart hubs workers
service: name=hubs-worker@* state=restarted
listen: "hubs configuration change"
- name: restart hubs SSE server
service: name=hubs-sse state=restarted
listen: "hubs configuration change"
# Webserver
- include: webserver.yml

View file

@ -0,0 +1,7 @@
- name: restart hubs webapp
service: name=hubs-webapp state=restarted
listen: "hubs configuration change"
when: not hubs_dev_mode
- name: restart nginx
service: name=nginx state=restarted

View file

@ -0,0 +1,56 @@
# Set up Postgres, create the database, and populate it.
- name: Install dependencies
dnf: name={{ item }} state=present
with_items:
- postgresql-server
- python-psycopg2
- name: Set up postgresql database
command: postgresql-setup --initdb
args:
creates: /var/lib/pgsql/data/base
- name: Set up postgresql access rules to allow local access
copy:
src: pg_hba.conf
dest: /var/lib/pgsql/data/pg_hba.conf
owner: postgres
group: postgres
mode: 0600
notify: restart postgresql
- name: Start and enable postgresql
service: name=postgresql state=started enabled=yes
- name: Set up the DB user
postgresql_user:
name: hubs
password: "{{ hubs_db_password }}"
role_attr_flags: NOSUPERUSER,NOCREATEROLE,NOCREATEDB
become_user: postgres
- name: Create the database
postgresql_db:
name: hubs
owner: hubs
register: db_creation
become_user: postgres
- name: Ease local access to the database
copy:
content: "*:*:hubs:hubs:{{ hubs_db_password }}"
dest: /home/{{ main_user }}/.pgpass
mode: 600
owner: "{{ main_user }}"
group: "{{ main_user }}"
- name: Populate the Fedora Hubs database
command: "{{ hubs_venv_dir }}/bin/python {{ hubs_code_dir }}/populate.py"
args:
chdir: "{{ hubs_code_dir }}"
environment:
HUBS_CONFIG: "{{ hubs_conf_dir }}/hubs_config.py"
become_user: "{{ main_user }}"
when: db_creation|succeeded

View file

@ -0,0 +1,8 @@
- name: Create and populate the Fedora Hubs database
command: "{{ hubs_venv_dir }}/bin/python {{ hubs_code_dir }}/populate.py"
args:
creates: "{{ hubs_var_dir }}/hubs.db"
chdir: "{{ hubs_code_dir }}"
environment:
HUBS_CONFIG: "{{ hubs_conf_dir }}/hubs_config.py"
become_user: "{{ main_user }}"

199
roles/hubs/tasks/main.yml Normal file
View file

@ -0,0 +1,199 @@
---
- name: Install helpful development packages
dnf: name={{ item }} state=present
with_items:
- git
- vim-enhanced
- name: Install external dependencies
dnf: name={{ item }} state=present
with_items:
- npm
- redis
- fedmsg-hub
- python-virtualenv
- python3-flask-oidc
- name: Install Fedora Hubs development packages
dnf: name={{ item }} state=present
with_items:
- gcc
- gcc-c++
- libffi-devel
- openssl-devel
- python-sphinx
- python2-devel
- python3-devel
- redhat-rpm-config
- sqlite-devel
when: hubs_dev_mode
- name: Install the distribution versions of requirements.txt
dnf: name={{ item }} state=present
with_items:
- python-alembic
- python-arrow
- python-bleach
- python-decorator
- python-dogpile-cache
- python-fedmsg-core
- python-fedmsg-meta-fedora-infrastructure
- python-flask
- python-flask-oidc
- python-fmn-lib
- python-fmn-rules
- python-futures
- python-html5lib
- python-munch
- pytz
- python-sqlalchemy
- python-markdown
- python2-pkgwat-api
- python-six
- python-pygments
- python-pygments-markdown-lexer
- python-retask
# Add various helpful configuration files
- name: Install a custom bashrc
template: src=bashrc dest=/home/{{ main_user }}/.bashrc
when: hubs_dev_mode
# Create directory structure
- name: Create the directory structure
file:
path: "{{ item.path }}"
state: directory
owner: "{{ main_user }}"
group: "{{ main_user }}"
mode: "{{ item.mode }}"
#setype: httpd_sys_content_rw_t
with_items:
- {path: "{{ hubs_base_dir }}", mode: 755}
- {path: "{{ hubs_conf_dir }}", mode: 750}
- {path: "{{ hubs_var_dir }}", mode: 750}
# Set up the Python development environment
- name: Install Fedora Hubs requirements.txt into hubs virtualenv
become_user: "{{ main_user }}"
pip:
requirements: "{{ hubs_code_dir }}/requirements.txt"
virtualenv: "{{ hubs_venv_dir}}"
virtualenv_site_packages: yes
- name: Install Fedora Hubs test-requirements.txt into hubs virtualenv
become_user: "{{ main_user }}"
pip:
requirements: "{{ hubs_code_dir }}/test-requirements.txt"
virtualenv: "{{ hubs_venv_dir}}"
virtualenv_site_packages: yes
- name: Install other packages into hubs virtualenv
become_user: "{{ main_user }}"
pip:
name: "{{ item }}"
virtualenv: "{{ hubs_venv_dir }}"
virtualenv_site_packages: yes
with_items:
- bleach
- name: Install Fedora Hubs into the virtualenv
become_user: "{{ main_user }}"
command: "{{ hubs_venv_dir }}/bin/pip install -e {{ hubs_code_dir }}"
args:
creates: "{{ hubs_venv_dir }}/lib/python2.7/site-packages/fedora-hubs.egg-link"
- name: Set bin file context in the virtualenv
file:
path: "{{ hubs_venv_dir }}/bin"
state: directory
recurse: true
setype: bin_t
- name: Add a basic Hubs configuration file
template:
src: "{{ item }}"
dest: "{{ hubs_conf_dir }}/hubs_config.py"
with_first_found:
- hubs_config.{{ ansible_hostname }}
- hubs_config
become_user: "{{ main_user }}"
notify: "hubs configuration change"
- name: Add a basic fedmsg configuration file
template:
src: "{{ item }}"
dest: "/etc/fedmsg.d/hubs_config.py"
with_first_found:
- fedmsg_config.{{ ansible_hostname }}
- fedmsg_config
notify: "hubs configuration change"
- name: Configure application to authenticate with iddev.fedorainfracloud.org
command:
oidc-register
--output-file {{ hubs_conf_dir }}/client_secrets.json
https://iddev.fedorainfracloud.org/ {{ hubs_url }}
become_user: "{{ main_user }}"
args:
creates: "{{ hubs_conf_dir }}/client_secrets.json"
# Set up, create, and populate the database.
- include: db-{{ hubs_db_type }}.yml
# Set up JavaScript requirements
- name: Install npm packages
command: npm install
become_user: "{{ main_user }}"
args:
creates: node_modules
chdir: "{{ hubs_code_dir }}/hubs/static/client"
- name: Build JavaScript assests
command: node_modules/.bin/webpack
become_user: "{{ main_user }}"
args:
chdir: "{{ hubs_code_dir }}/hubs/static/client"
creates: "{{ hubs_code_dir }}/hubs/static/js/build/common.js"
# Services
- name: Disable the system-wide fedmsg-hub
service: name=fedmsg-hub state=stopped enabled=no
- name: Install the service files
template:
src: "{{ item }}.service"
dest: /etc/systemd/system/{{ item }}.service
with_items:
- hubs-triage@
- hubs-worker@
- hubs-sse
- hubs-fedmsg-hub
register: service_installed
- name: reload systemd
command: systemctl daemon-reload
when: service_installed|changed
- name: Start and enable the services
service: name={{ item }} state=started enabled=yes
with_items:
- redis
- hubs-triage@1
- hubs-triage@2
- hubs-worker@1
- hubs-worker@2
- hubs-sse
- hubs-fedmsg-hub
# Webserver
- include: webserver.yml
when: not hubs_dev_mode

View file

@ -0,0 +1,87 @@
# Webserver config
- name: Install the webserver packages
dnf: name={{ item }} state=present
with_items:
- python-gunicorn
- nginx
- libsemanage-python
- name: Generate SSL certificate and key
shell:
echo -e "--\nSomeState\nSomeCity\nSomeOrganization\nSomeOrganizationalUnit\nlocalhost.localdomain\nroot@localhost.localdomain"
| openssl req -utf8 -newkey rsa:2048
-keyout /etc/pki/tls/private/localhost.key
-nodes -x509 -days 365
-out /etc/pki/tls/certs/localhost.crt
args:
creates: /etc/pki/tls/certs/localhost.crt
- name: Gunicorn logging configuration
copy:
src: logging.ini
dest: "{{ hubs_conf_dir }}/logging.ini"
owner: "{{ main_user }}"
group: "{{ main_user }}"
notify:
- restart hubs webapp
- name: Nginx configuration for hubs
template:
src: nginx.conf
dest: /etc/nginx/conf.d/hubs.conf
notify:
- restart nginx
- name: Nginx SSL configuration
template:
src: "{{ item }}"
dest: /etc/nginx/ssl_params
with_first_found:
- nginx_ssl_params.{{ ansible_hostname }}
- nginx_ssl_params
notify:
- restart nginx
- name: Nginx proxy configuration
copy:
src: "{{ item }}"
dest: /etc/nginx/proxy_params
with_first_found:
- nginx_proxy_params.{{ ansible_hostname }}
- nginx_proxy_params
notify:
- restart nginx
- name: Allow network connection for Nginx
seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
- name: Install the service files
template:
src: "{{ item }}.service"
dest: /etc/systemd/system/{{ item }}.service
with_items:
- hubs-webapp
register: service_installed
- name: reload systemd
command: systemctl daemon-reload
when: service_installed|changed
- name: Start and enable the services
service: name={{ item }} state=started enabled=yes
with_items:
- hubs-webapp
- nginx

View file

@ -0,0 +1,45 @@
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions
# If adding new functions to this file, note that you can add help text to the function
# by defining a variable with name _<function>_help containing the help text
export HUBS_CONFIG={{ hubs_conf_dir }}/hubs_config.py
export FLASK_APP={{ hubs_code_dir }}/hubs/app.py
workon() {
[ "$1" == "hubs" ] || ( echo "No such virtualenv."; exit 1 )
source {{ hubs_venv_dir }}/bin/activate
cd {{ hubs_code_dir }}
}
hup() {
source {{ hubs_venv_dir }}/bin/activate
pushd {{ hubs_code_dir }}
FLASK_DEBUG=1 flask run --host 0.0.0.0 --port 5000
}
hreset() {
source {{ hubs_venv_dir }}/bin/activate
{% if hubs_db_type == "postgresql" %}
sudo -u postgres dropdb hubs
sudo -u postgres createdb -O hubs hubs
{% else %}
rm {{ hubs_var_dir }}/hubs.db
{% endif %}
rm {{ hubs_var_dir }}/cache.db
pushd {{ hubs_code_dir }}
python populate.py
popd
deactivate
}

View file

@ -0,0 +1,23 @@
config = {
# Database
{% if hubs_db_type == "postgresql" %}
'hubs.sqlalchemy.uri': 'postgresql://hubs:{{ hubs_db_password }}@localhost/hubs',
{% else %}
'hubs.sqlalchemy.uri': 'sqlite:///{{ hubs_var_dir }}/hubs.db',
{% endif %}
# Some configuration for the general hubs cache.
"fedora-hubs.cache": {
"backend": "dogpile.cache.dbm",
#"expiration_time": 0,
"arguments": {
"filename": "{{ hubs_var_dir }}/cache.db",
},
},
# Fedmsg hub consumer
'hubs.consumer.enabled': True,
'hubs.redis.triage-queue-name': 'fedora-hubs-triage-queue',
}

View file

@ -0,0 +1,14 @@
[Unit]
Description=Hubs-specific fedmsg processing hub
After=network.target
Documentation=https://fedmsg.readthedocs.org/
[Service]
ExecStart={{ hubs_venv_dir }}/bin/python /usr/bin/fedmsg-hub
Type=simple
User=fedmsg
Group=fedmsg
Restart=on-failure
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,18 @@
[Unit]
Description=fedora-hubs SSE server
After=network.target
Documentation=https://pagure.io/fedora-hubs/
[Service]
ExecStart= \
{{ hubs_venv_dir }}/bin/python \
/usr/bin/twistd -l - --pidfile= \
-ny {{ hubs_code_dir }}/hubs/backend/sse_server.tac
Environment=HUBS_CONFIG={{ hubs_conf_dir }}/hubs_config.py
Type=simple
User={{ main_user }}
Group={{ main_user }}
Restart=on-failure
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,15 @@
[Unit]
Description=fedora-hubs triage worker #%i
After=network.target
Documentation=https://pagure.io/fedora-hubs/
[Service]
ExecStart={{ hubs_venv_dir }}/bin/fedora-hubs-triage
Environment=HUBS_CONFIG={{ hubs_conf_dir }}/hubs_config.py
Type=simple
User={{ main_user }}
Group={{ main_user }}
Restart=on-failure
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,20 @@
[Unit]
Description=fedora-hubs frontend webapp
After=network.target
Documentation=https://pagure.io/fedora-hubs/
[Service]
ExecStart= \
{{ hubs_venv_dir }}/bin/python \
/usr/bin/gunicorn -b 127.0.0.1:8000 --threads 12 \
--log-config {{ hubs_conf_dir }}/logging.ini \
{% if hubs_dev_mode %}--reload{% endif %} \
hubs.app:app
Environment=HUBS_CONFIG={{ hubs_conf_dir }}/hubs_config.py
Type=simple
User={{ main_user }}
Group={{ main_user }}
Restart=on-failure
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,15 @@
[Unit]
Description=fedora-hubs cache worker #%i
After=network.target
Documentation=https://pagure.io/fedora-hubs/
[Service]
ExecStart={{ hubs_venv_dir }}/bin/fedora-hubs-worker
Environment=HUBS_CONFIG={{ hubs_conf_dir }}/hubs_config.py
Type=simple
User={{ main_user }}
Group={{ main_user }}
Restart=on-failure
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,20 @@
# Enter any hubs configuration here
SECRET_KEY = "{{ hubs_secret_key }}"
{% if hubs_dev_mode %}
# Allow the cookie to be sent of http since we work on localhost
OIDC_ID_TOKEN_COOKIE_SECURE = False
{% endif %}
OIDC_CLIENT_SECRETS = "{{ hubs_conf_dir }}/client_secrets.json"
OIDC_OPENID_REALM = "{{ hubs_url }}/oidc_callback"
SSE_URL = {
# "host": "sse.example.com",
{% if hubs_dev_mode %}
"port": "8080",
{% else %}
"path": "/sse",
{% endif %}
}

View file

@ -0,0 +1,67 @@
upstream hubs {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
#server unix:/tmp/gunicorn.sock fail_timeout=0;
# for a TCP configuration
server 127.0.0.1:8000 fail_timeout=0;
}
upstream hubs-sse {
# SSE server (twisted-based)
server 127.0.0.1:8080 fail_timeout=0;
}
# Redirect cleartext traffic to HTTPS
server {
listen 80;
listen [::]:80;
server_name {{ hubs_url_hostname }};
return 301 https://$server_name$request_uri;
}
# Main server block
server {
listen 443 deferred;
listen [::]:443 deferred;
client_max_body_size 4G;
server_name {{ hubs_url_hostname }};
include ssl_params;
keepalive_timeout 5;
# path for static files
root {{ hubs_code_dir }}/hubs/static;
location / {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location /sse/ {
include proxy_params;
proxy_pass http://hubs-sse/;
# Allow long-running queries (SSE):
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache off;
chunked_transfer_encoding off;
keepalive_timeout 0;
proxy_read_timeout 30m;
}
location @proxy_to_app {
include proxy_params;
proxy_pass http://hubs;
}
#error_page 500 502 503 504 /500.html;
#location = /500.html {
# root /path/to/app/current/public;
#}
}

View file

@ -0,0 +1,3 @@
ssl on;
ssl_certificate {{ hubs_ssl_cert }};
ssl_certificate_key {{ hubs_ssl_key }};