Skip to content

Commit 05e5415

Browse files
Allow to set up load balancing when installing DOMjudge.
1 parent c1848cb commit 05e5415

File tree

8 files changed

+101
-9
lines changed

8 files changed

+101
-9
lines changed

provision-contest/ansible/domserver.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626
tags: ssh
2727
- role: mysql_server
2828
tags: mysql_server
29-
- role: domjudge_checkout
30-
tags: domjudge_checkout
31-
- role: domjudge_build
32-
tags: domjudge_build
33-
- role: domserver
34-
tags: domserver
3529
- role: mysql_replication
3630
tags: mysql_replication
3731
when: REPLICATION_PASSWORD is defined
3832
- role: keepalived
3933
tags: keepalived
4034
when: KEEPALIVED_PRIORITY is defined
35+
- role: domjudge_checkout
36+
tags: domjudge_checkout
37+
- role: domjudge_build
38+
tags: domjudge_build
39+
- role: domserver
40+
tags: domserver
4141
- role: prometheus_target_web
4242
tags: prometheus_target_web
4343
vars:

provision-contest/ansible/group_vars/all/all.yml

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ ICPC_IMAGE: false
2626
# server.
2727
WF_RESTRICTED_NETWORK: false
2828

29+
# Set this to true to enable load balancing instead of (automatic) failover
30+
# DBA_PASSWORD needs to be set for this in secret.yml
31+
DOMSERVER_LOADBALANCING: false
32+
2933
TIMEZONE: "Europe/Moscow"
3034

3135
PHP_FPM_MAX_CHILDREN: 400

provision-contest/ansible/group_vars/all/secret.yml.example

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
# Set this to enable master-master replication between two domservers.
33
#REPLICATION_PASSWORD: some-replication-password
44

5+
# Database administrator password. Needed when DOMSERVER_LOADBALANCING is true
6+
# Note: this user will have access from the whole SERVER_IP_PREFIX range
7+
#DBA_PASSWORD: some-dba-password
8+
59
# Database user password.
610
DB_PASSWORD: some-database-password
711

provision-contest/ansible/roles/domserver/tasks/main.yml

+13-3
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,26 @@
1919
owner: domjudge
2020
notify: fix permissions on domjudge inplace-install
2121

22+
- name: set the DBA credentials
23+
set_fact:
24+
dba_credentials: |
25+
{% if DBA_PASSWORD is defined %}
26+
-u domjudge_dba -p {{ DBA_PASSWORD }}
27+
{% else %}
28+
-u root
29+
{% endif %}
30+
2231
# When using replication, the DB will be dropped and recreated on the slave later.
2332
- name: check if the database is configured
24-
command: "{{ DJ_DIR }}/bin/dj_setup_database -u root status"
33+
command: "{{ DJ_DIR }}/bin/dj_setup_database {{ dba_credentials }} status"
2534
register: db_status
2635
ignore_errors: true
2736
changed_when: false
37+
when: not DOMSERVER_LOADBALANCING or groups['domserver'][0] == inventory_hostname
2838

2939
- name: make sure the database is configured
30-
command: "{{ DJ_DIR }}/bin/dj_setup_database -u root bare-install"
31-
when: "'failed' in db_status.stdout"
40+
command: "{{ DJ_DIR }}/bin/dj_setup_database {{ dba_credentials }} bare-install"
41+
when: "(not DOMSERVER_LOADBALANCING or groups['domserver'][0] == inventory_hostname) and 'failed' in db_status.stdout"
3242

3343
- name: install required packages
3444
apt:
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
# {{ansible_managed}}
22
# Format: 'unused:<db_host>:<db_name>:<user>:<password>:<db_port>'
3+
{% if DOMSERVER_LOADBALANCING %}
4+
unused:{{DOMSERVER_IP}}:domjudge:domjudge:{{DB_PASSWORD}}:3306
5+
{% else %}
36
unused:localhost:domjudge:domjudge:{{DB_PASSWORD}}:3306
7+
{% endif %}

provision-contest/ansible/roles/domserver/templates/nginx-domjudge-inner.j2

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ set $domjudgeRoot {{ DJ_DIR }}/webapp/public;
1111
set $prefix '';
1212

1313
location / {
14+
{% if DOMSERVER_LOADBALANCING %}
15+
if ($access_allowed = false) {
16+
return 403;
17+
}
18+
{% endif %}
1419
root $domjudgeRoot;
1520
try_files $uri @domjudgeFront;
1621
}

provision-contest/ansible/roles/domserver/templates/nginx-domjudge.conf.j2

+45
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,36 @@ upstream domjudge {
77
server unix:/var/run/php-fpm-domjudge.sock; # if using with etc/domjudge-fpm.conf
88
}
99

10+
{% if DOMSERVER_LOADBALANCING %}
11+
upstream domjudge-loadbalanced {
12+
least_conn;
13+
{% for host in groups['domserver'] %}
14+
server {{ hostvars[host].ansible_host }}:81;
15+
{% endfor %}
16+
}
17+
18+
server {
19+
listen 81;
20+
listen [::]:81;
21+
server_name _default_;
22+
23+
add_header Strict-Transport-Security max-age=31556952;
24+
include /etc/nginx/snippets/domjudge-inner;
25+
26+
set_real_ip_from {{ SERVER_IP_PREFIX }}.0/24;
27+
real_ip_header X-Forwarded-For;
28+
real_ip_recursive on;
29+
}
30+
31+
map $realip_remote_addr $access_allowed {
32+
default false;
33+
{% for host in groups['domserver'] %}
34+
{{ hostvars[host].ansible_host }} true;
35+
{% endfor %}
36+
}
37+
38+
{% endif %}
39+
1040
server {
1141
listen 80;
1242
listen [::]:80;
@@ -25,5 +55,20 @@ server {
2555

2656
add_header Strict-Transport-Security max-age=31556952;
2757

58+
{% if DOMSERVER_LOADBALANCING %}
59+
location / {
60+
proxy_pass http://domjudge-loadbalanced;
61+
proxy_http_version 1.1;
62+
proxy_set_header Upgrade $http_upgrade;
63+
proxy_set_header Connection "upgrade";
64+
proxy_set_header X-Forwarded-Proto $scheme;
65+
proxy_set_header Host $http_host;
66+
proxy_set_header X-Real-IP $remote_addr;
67+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
68+
proxy_request_buffering off;
69+
proxy_buffering off;
70+
}
71+
{% else %}
2872
include /etc/nginx/snippets/domjudge-inner;
73+
{% endif %}
2974
}

provision-contest/ansible/roles/mysql_server/tasks/main.yml

+20
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,23 @@
6767
loop:
6868
- load-db
6969
- dump-db
70+
71+
- name: create mysql user for for DOMjudge database administration
72+
mysql_user:
73+
name: domjudge_dba
74+
host: '{{ SERVER_IP_PREFIX }}.%'
75+
password: "{{ DBA_PASSWORD }}"
76+
append_privs: true
77+
priv: 'domjudge.*:ALL,GRANT/*.*:CREATE USER,RELOAD'
78+
state: present
79+
when: DBA_PASSWORD is defined
80+
81+
- name: create mysql user for for DOMjudge when we are doing loadbalancing
82+
mysql_user:
83+
name: domjudge
84+
host: '{{ SERVER_IP_PREFIX }}.%'
85+
password: "{{ DB_PASSWORD }}"
86+
append_privs: true
87+
priv: 'domjudge.*:SELECT,INSERT,UPDATE,DELETE'
88+
state: present
89+
when: DOMSERVER_LOADBALANCING

0 commit comments

Comments
 (0)