Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set up load balancing when installing DOMjudge. #59

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions provision-contest/ansible/domserver.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@
tags: ssh
- role: mysql_server
tags: mysql_server
- role: domjudge_checkout
tags: domjudge_checkout
- role: domjudge_build
tags: domjudge_build
- role: domserver
tags: domserver
- role: mysql_replication
tags: mysql_replication
when: REPLICATION_PASSWORD is defined
- role: keepalived
tags: keepalived
when: KEEPALIVED_PRIORITY is defined
- role: domjudge_checkout
tags: domjudge_checkout
- role: domjudge_build
tags: domjudge_build
- role: domserver
tags: domserver
- role: prometheus_target_web
tags: prometheus_target_web
vars:
Expand Down
4 changes: 4 additions & 0 deletions provision-contest/ansible/group_vars/all/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ GRAPHICAL: false
# server.
WF_RESTRICTED_NETWORK: false

# Set this to true to enable load balancing instead of (automatic) failover
# DBA_PASSWORD needs to be set for this in secret.yml
DOMSERVER_LOADBALANCING: false

TIMEZONE: "Europe/Moscow"

PHP_FPM_MAX_CHILDREN: 400
Expand Down
4 changes: 4 additions & 0 deletions provision-contest/ansible/group_vars/all/secret.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# Set this to enable master-master replication between two domservers.
#REPLICATION_PASSWORD: some-replication-password

# Database administrator password. Needed when DOMSERVER_LOADBALANCING is true
# Note: this user will have access from the whole SERVER_IP_PREFIX range
#DBA_PASSWORD: some-dba-password

# Database user password.
DB_PASSWORD: some-database-password

Expand Down
20 changes: 15 additions & 5 deletions provision-contest/ansible/roles/domserver/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,26 @@
owner: domjudge
notify: Fix permissions on domjudge inplace-install

- name: set the DBA credentials
set_fact:
dba_credentials: |
{% if host_type == 'domserver' and DBA_PASSWORD is defined %}
-u domjudge_dba -p {{ DBA_PASSWORD }}
{% else %}
-s -u root
{% endif %}

# When using replication, the DB will be dropped and recreated on the slave later.
- name: Check if the database is configured
command: "{{ DJ_DIR }}/bin/dj_setup_database -s -u root status"
- name: check if the database is configured
command: "{{ DJ_DIR }}/bin/dj_setup_database {{ dba_credentials }} status"
register: db_status
ignore_errors: true
changed_when: false
when: not DOMSERVER_LOADBALANCING or groups['domserver'][0] == inventory_hostname or host_type != 'domserver'

- name: Make sure the database is configured
command: "{{ DJ_DIR }}/bin/dj_setup_database -s -u root bare-install"
when: "'failed' in db_status.stdout"
- name: make sure the database is configured
command: "{{ DJ_DIR }}/bin/dj_setup_database {{ dba_credentials }} bare-install"
when: "(not DOMSERVER_LOADBALANCING or groups['domserver'][0] == inventory_hostname or host_type != 'domserver') and 'failed' in db_status.stdout"

- name: Install required packages
apt:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# {{ansible_managed}}
# Format: 'unused:<db_host>:<db_name>:<user>:<password>:<db_port>'
{% if host_type == 'domserver' and DOMSERVER_LOADBALANCING %}
unused:{{DOMSERVER_IP}}:domjudge:domjudge:{{DB_PASSWORD}}:3306
{% else %}
unused:localhost:domjudge:domjudge:{{DB_PASSWORD}}:3306
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ set $domjudgeRoot {{ DJ_DIR }}/webapp/public;
set $prefix '';

location / {
{% if host_type == 'domserver' and DOMSERVER_LOADBALANCING %}
if ($access_allowed = false) {
return 403;
}
{% endif %}
root $domjudgeRoot;
try_files $uri @domjudgeFront;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,43 @@ upstream domjudge {
server unix:/var/run/php-fpm-domjudge.sock; # if using with etc/domjudge-fpm.conf
}

{% if host_type == 'domserver' and DOMSERVER_LOADBALANCING %}
upstream domjudge-loadbalanced {
least_conn;
keepalive 100;
{% for host in groups['domserver'] %}
server {{ hostvars[host].ansible_host }}:444;
{% endfor %}
}

server {
listen 444 ssl http2;
listen [::]:444 ssl http2;
server_name _default_;

ssl_certificate {{DOMSERVER_SSL_CERT}};
ssl_certificate_key {{DOMSERVER_SSL_KEY}};
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;

add_header Strict-Transport-Security max-age=31556952;
include /etc/nginx/snippets/domjudge-inner;

set_real_ip_from {{ SERVER_IP_PREFIX }}.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}

map $realip_remote_addr $access_allowed {
default false;
{{ DOMSERVER_IP }} true;
{% for host in groups['domserver'] %}
{{ hostvars[host].ansible_host }} true;
{% endfor %}
}

{% endif %}

server {
listen 80;
listen [::]:80;
Expand All @@ -26,5 +63,19 @@ server {
add_header Strict-Transport-Security max-age=31556952;

send_timeout 36000s;
{% if host_type == 'domserver' and DOMSERVER_LOADBALANCING %}
location / {
proxy_pass https://domjudge-loadbalanced;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_request_buffering off;
proxy_buffering off;
}
{% else %}
include /etc/nginx/snippets/domjudge-inner;
{% endif %}
}
22 changes: 22 additions & 0 deletions provision-contest/ansible/roles/mysql_server/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,25 @@
loop:
- load-db
- dump-db

- name: create mysql user for for DOMjudge database administration
mysql_user:
name: domjudge_dba
host: '{{ item }}'
password: "{{ DBA_PASSWORD }}"
append_privs: true
priv: 'domjudge.*:ALL,GRANT/*.*:CREATE USER,RELOAD'
state: present
when: host_type == 'domserver' and DBA_PASSWORD is defined
loop: "{{ groups['domserver'] | map('extract', hostvars, 'ansible_host') + [DOMSERVER_IP] }}"

- name: create mysql user for for DOMjudge when we are doing loadbalancing
mysql_user:
name: domjudge
host: '{{ item }}'
password: "{{ DB_PASSWORD }}"
append_privs: true
priv: 'domjudge.*:SELECT,INSERT,UPDATE,DELETE'
state: present
when: host_type == 'domserver' and DOMSERVER_LOADBALANCING
loop: "{{ groups['domserver'] | map('extract', hostvars, 'ansible_host') + [DOMSERVER_IP] }}"