
This should now be a largely functional deployment of mailman 3. There are still some bits that need testing but we'll use followup changes to force failure and hold nodes. This deployment of mailman3 uses upstream docker container images. We currently hack up uids and gids to accomodate that. We also hack up the settings file and bind mount it over the upstream file in order to use host networking. We override the hyperkitty index type to xapian. All list domains are hosted in a single installation and we use native vhosting to handle that. We'll deploy this to a new server and migrate one mailing list domain at a time. This will allow us to start with lists.opendev.org and test things like dmarc settings before expanding to the remaining lists. A migration script is also included, which has seen extensive testing on held nodes for importing copies of the production data sets. Change-Id: Ic9bf5cfaf0b87c100a6ce003a6645010a7b50358
279 lines
7.4 KiB
YAML
279 lines
7.4 KiB
YAML
# The old mailman2 exim config refers to this file. Write it out
|
|
# to make basic testing happy, but we may need to clean it up or
|
|
# modify it for mailman3.
|
|
- name: Write /etc/aliases.domain
|
|
template:
|
|
src: "domain_aliases.j2"
|
|
dest: "/etc/aliases.domain"
|
|
mode: '0444'
|
|
|
|
- name: Create Mailman Group
|
|
group:
|
|
name: mailman
|
|
gid: 10010
|
|
system: yes
|
|
|
|
- name: Create Mailman User
|
|
user:
|
|
name: mailman
|
|
uid: 10010
|
|
comment: Mailman User
|
|
shell: /bin/bash
|
|
home: /var/lib/mailman
|
|
group: mailman
|
|
create_home: yes
|
|
system: yes
|
|
|
|
#### Install Mailman ####
|
|
|
|
- name: Ensure Mailman core volume directory exists
|
|
file:
|
|
state: directory
|
|
path: "/var/lib/mailman/core"
|
|
# TODO: undo for https://github.com/maxking/docker-mailman/issues/550
|
|
owner: 100
|
|
group: 65533
|
|
mode: '0755'
|
|
|
|
- name: Ensure Mailman database volume directory exists
|
|
file:
|
|
state: directory
|
|
path: "/var/lib/mailman/database"
|
|
# TODO: undo for https://github.com/maxking/docker-mailman/issues/550
|
|
owner: 999
|
|
group: 999
|
|
mode: '0755'
|
|
|
|
- name: Ensure Mailman web volume directories exist
|
|
file:
|
|
state: directory
|
|
path: "/var/lib/mailman/{{ item }}"
|
|
# TODO: undo for https://github.com/maxking/docker-mailman/issues/550
|
|
owner: 100
|
|
group: 101
|
|
mode: '0755'
|
|
loop:
|
|
- import
|
|
- web
|
|
- web-data
|
|
- web-data/fulltext_index
|
|
- web-data/mm2archives
|
|
|
|
- name: Copy our overridden settings.py for mailman-web
|
|
copy:
|
|
src: web-settings.py
|
|
dest: /var/lib/mailman/web/settings.py
|
|
# TODO: undo for https://github.com/maxking/docker-mailman/issues/550
|
|
owner: 100
|
|
group: 101
|
|
mode: '0644'
|
|
|
|
- name: Copy our settings_local.py for mailman-web
|
|
copy:
|
|
src: web-settings_local.py
|
|
dest: /var/lib/mailman/web-data/settings_local.py
|
|
# TODO: undo for https://github.com/maxking/docker-mailman/issues/550
|
|
owner: 100
|
|
group: 101
|
|
mode: '0644'
|
|
|
|
- name: Copy our max_allowed_packet override config
|
|
copy:
|
|
src: 99-max_allowed_packet.cnf
|
|
dest: /var/lib/mailman/99-max_allowed_packet.cnf
|
|
owner: 999
|
|
group: 999
|
|
mode: '0644'
|
|
|
|
- name: Ensure /etc/mailman-compose directory
|
|
file:
|
|
state: directory
|
|
path: /etc/mailman-compose
|
|
mode: '0755'
|
|
|
|
- name: Put docker-compose file in place
|
|
template:
|
|
src: docker-compose.yaml.j2
|
|
dest: /etc/mailman-compose/docker-compose.yaml
|
|
mode: '0600'
|
|
|
|
- name: Run docker-compose pull
|
|
shell:
|
|
cmd: docker-compose pull
|
|
chdir: /etc/mailman-compose/
|
|
|
|
- name: Run docker-compose up
|
|
shell:
|
|
cmd: docker-compose up -d
|
|
chdir: /etc/mailman-compose/
|
|
|
|
- name: Run docker prune to cleanup unneeded images
|
|
shell:
|
|
cmd: docker image prune -f
|
|
|
|
- name: Install apache2
|
|
package:
|
|
name:
|
|
- apache2
|
|
- apache2-utils
|
|
state: present
|
|
|
|
- name: Apache modules
|
|
apache2_module:
|
|
state: present
|
|
name: "{{ a2_mod }}"
|
|
loop:
|
|
- authz_host
|
|
- proxy
|
|
- proxy_uwsgi
|
|
- ssl
|
|
- rewrite
|
|
loop_control:
|
|
loop_var: a2_mod
|
|
notify: mailman restart apache2
|
|
|
|
- name: Make sure packaged default site disabled
|
|
command: a2dissite 000-default.conf
|
|
args:
|
|
removes: /etc/apache2/sites-enabled/000-default.conf
|
|
|
|
- name: Create mailman vhost config
|
|
template:
|
|
src: mailman.vhost.j2
|
|
dest: "/etc/apache2/sites-enabled/50-{{ mailman_sites.0.listdomain }}.conf"
|
|
owner: root
|
|
group: root
|
|
mode: '0644'
|
|
notify: mailman reload apache2
|
|
|
|
- name: Enable apache2 server
|
|
service:
|
|
name: "apache2"
|
|
enabled: yes
|
|
|
|
#### Configure Mailman Services ####
|
|
|
|
- name: Wait for mm3 REST API to be up and running
|
|
uri:
|
|
url: 'http://localhost:8001/3.1/domains'
|
|
url_username: restadmin
|
|
url_password: "{{ mailman3_rest_password }}"
|
|
force_basic_auth: yes
|
|
method: GET
|
|
register: mm_rest_api_up
|
|
delay: 1
|
|
retries: 300
|
|
until: mm_rest_api_up and mm_rest_api_up.status == 200
|
|
no_log: true
|
|
|
|
# It has been difficult to nail down a reliable mathod for determining
|
|
# when the database is sufficiently populated that we can create the django
|
|
# admin user. We apply a number of approaches in response to this. If we
|
|
# can identify a single method that is reliable this list can be trimmed.
|
|
- name: Wait for DB to be populated
|
|
command: >
|
|
docker exec mailman-compose_database_1 bash -c
|
|
'mysql -u mailman -p"$MYSQL_PASSWORD" -D mailmandb -e
|
|
"SHOW TABLES LIKE \"auth_user\";"'
|
|
register: django_db_exists
|
|
delay: 1
|
|
retries: 300
|
|
until: django_db_exists.stdout_lines | length > 1 and django_db_exists.stdout_lines[1] == "auth_user"
|
|
|
|
- name: Wait for DB to be populated second approach
|
|
command: >
|
|
docker exec mailman-core alembic -c /usr/lib/python3.9/site-packages/mailman/config/alembic.cfg current
|
|
register: alembic_version
|
|
delay: 1
|
|
retries: 300
|
|
until: alembic_version.stdout_lines | length > 0 and "(head)" in alembic_version.stdout_lines[0]
|
|
|
|
- name: Wait for DB to be populated third approach
|
|
shell: >
|
|
docker exec mailman-web bash -c
|
|
'python3 manage.py showmigrations' |
|
|
grep -q '^ \[ \] [0-9]\+_.*'
|
|
register: django_db_migrations
|
|
delay: 1
|
|
retries: 300
|
|
failed_when: false
|
|
# When grep stops matching the empty '[ ]' that indicates all migrations
|
|
# are marked with '[X]' and are complete. Grep returns non zero when we
|
|
# reach this point.
|
|
until: django_db_migrations.rc != 0
|
|
|
|
- name: Check if django admin user exists
|
|
command: >
|
|
docker exec mailman-compose_database_1 bash -c
|
|
'mysql -u mailman -p"$MYSQL_PASSWORD" -D mailmandb -e
|
|
"SELECT COUNT(id) FROM auth_user WHERE id = 1 AND is_superuser = 1;"'
|
|
register: django_admin_exists
|
|
|
|
- name: Create django admin user
|
|
when: django_admin_exists.stdout_lines[1] == "0"
|
|
command: >
|
|
docker exec mailman-web bash -c
|
|
"DJANGO_SUPERUSER_PASSWORD={{ mailman3_admin_password }}
|
|
python3 manage.py createsuperuser --no-input
|
|
--username {{ mailman3_admin_user }}
|
|
--email '{{ mailman3_admin_email }}'"
|
|
no_log: true
|
|
|
|
- name: Create lists in mm3
|
|
include_tasks: create_lists.yaml
|
|
loop: "{{ mailman_sites }}"
|
|
loop_control:
|
|
loop_var: mm_site
|
|
|
|
#### Logrotate for service logs ####
|
|
|
|
- name: Rotate mailman logs
|
|
include_role:
|
|
name: logrotate
|
|
vars:
|
|
logrotate_rotate: 90
|
|
logrotate_file_name: '/var/lib/mailman/web-data/logs/*.log'
|
|
|
|
#### Database Backups ####
|
|
|
|
- name: Create db backup dest
|
|
file:
|
|
state: directory
|
|
path: /var/backups/mailman-mariadb
|
|
mode: 0700
|
|
owner: root
|
|
group: root
|
|
|
|
- name: Set up cron job to backup the database
|
|
cron:
|
|
name: mailman-db-backup
|
|
state: present
|
|
user: root
|
|
job: >
|
|
/usr/local/bin/docker-compose -f /etc/mailman-compose/docker-compose.yaml exec -T database
|
|
bash -c '/usr/bin/mysqldump --opt --databases mailmandb --single-transaction -uroot -p"$MYSQL_ROOT_PASSWORD"' |
|
|
gzip -9 > /var/backups/mailman-mariadb/mailman-mariadb.sql.gz
|
|
minute: 14
|
|
hour: 5
|
|
|
|
- name: Rotate db backups
|
|
include_role:
|
|
name: logrotate
|
|
vars:
|
|
logrotate_file_name: /var/backups/mailman-mariadb/mailman-mariadb.sql.gz
|
|
logrotate_compress: false
|
|
|
|
- name: Setup db backup streaming job
|
|
block:
|
|
- name: Create backup streaming config dir
|
|
file:
|
|
path: /etc/borg-streams
|
|
state: directory
|
|
|
|
- name: Create db streaming file
|
|
copy:
|
|
content: >-
|
|
/usr/local/bin/docker-compose -f /etc/mailman-compose/docker-compose.yaml exec -T mariadb
|
|
bash -c '/usr/bin/mysqldump --skip-extended-insert --databases mailmandb --single-transaction -uroot -p"$MYSQL_ROOT_PASSWORD"'
|
|
dest: /etc/borg-streams/mysql
|