Initial commit
All checks were successful
Ansible Playbook lint / ansible-lint (push) Successful in 35s
All checks were successful
Ansible Playbook lint / ansible-lint (push) Successful in 35s
This commit is contained in:
17
.gitea/workflows/lint.yml
Normal file
17
.gitea/workflows/lint.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
name: Ansible Playbook lint
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ansible-lint:
|
||||||
|
runs-on: imgbuilder
|
||||||
|
container:
|
||||||
|
image: gitea.konchin.com/system/ansible-image
|
||||||
|
credentials:
|
||||||
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Ansible Lint
|
||||||
|
run: |
|
||||||
|
ansible-lint roles/ playbooks/
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
group_vars/*/secret.yml
|
||||||
47
README.md
Normal file
47
README.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Ansible Playbook for CMS - Contest Management System
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
- Works on ArchLinux with systemd-boot.
|
||||||
|
- Just run `ansible-playbook playbooks/install.yml`.
|
||||||
|
|
||||||
|
## Configure CMS Contests
|
||||||
|
|
||||||
|
- Run `sudo -iu cmsuser` to login cmsuser.
|
||||||
|
- Run `cmsAddAdmin kcw` to create admin user.
|
||||||
|
- Run `cmsAdminWebServer` to open a temporary admin webserver.
|
||||||
|
- which opens on port 8889 or `<dns_prefix>-admin.<dns_suffix>` on port 80.
|
||||||
|
- You can start / enable `cms@<contest id>.service` after contest setup.
|
||||||
|
|
||||||
|
## Configure group vars secret
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# group_vars/cms/secret.yml
|
||||||
|
---
|
||||||
|
username: cmsuser
|
||||||
|
password: example_p4ssword
|
||||||
|
dns_prefix: cms-test
|
||||||
|
dns_suffix: example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Import Users
|
||||||
|
|
||||||
|
- Create a username / password mapping in `/srv/cms/passwd`.
|
||||||
|
e.g.
|
||||||
|
```
|
||||||
|
111550087 ThisIsARandomPassword
|
||||||
|
```
|
||||||
|
- Run `./users.bash` to generate `contest.yaml`.
|
||||||
|
- Run `cmsImportUser -A -c <contest id> .`.
|
||||||
|
|
||||||
|
### Delete all users from contest
|
||||||
|
|
||||||
|
Since you can't import users if they were already in the database. \
|
||||||
|
You'll need to delete them manually before import.
|
||||||
|
|
||||||
|
- Run `cut -d' ' -f1 passwd | xargs cmsRemoverUser`
|
||||||
|
|
||||||
|
## Import Tasks
|
||||||
|
|
||||||
|
- Put polygon zips in `/tmp/kcw*-.zip`.
|
||||||
|
- Run `./import.bash` and wait.
|
||||||
4
ansible.cfg
Normal file
4
ansible.cfg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[defaults]
|
||||||
|
roles_path=./roles/
|
||||||
|
inventory=./hosts
|
||||||
|
remote_user=root
|
||||||
2
group_vars/cms/main.yml
Normal file
2
group_vars/cms/main.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
setup_cgroupsv1_bootconf: /boot/loader/entries/arch.conf
|
||||||
8
hosts
Normal file
8
hosts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[control]
|
||||||
|
localhost ansible_connection=local
|
||||||
|
|
||||||
|
[cms]
|
||||||
|
test3.konchin.com
|
||||||
|
|
||||||
|
[all:vars]
|
||||||
|
ansible_python_interpreter=/usr/bin/python
|
||||||
9
playbooks/install.yml
Normal file
9
playbooks/install.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
- name: Install cms
|
||||||
|
hosts: cms
|
||||||
|
roles:
|
||||||
|
- role: setup_cgroupsv1
|
||||||
|
- role: install_packages
|
||||||
|
- role: cms_preparation
|
||||||
|
- role: setup_database
|
||||||
|
- role: configure_cms
|
||||||
12
roles/add_helper_scripts/files/import.bash
Normal file
12
roles/add_helper_scripts/files/import.bash
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env -S bash
|
||||||
|
|
||||||
|
mapfile -t files <<< "$(ls -1 /tmp/kcw-*.zip)"
|
||||||
|
|
||||||
|
for file in ${files[@]}; do
|
||||||
|
echo "target: $file"
|
||||||
|
dir=$(cut -d'$' -f1 <<< "$file")
|
||||||
|
if ! [[ -d "$dir" ]]; then
|
||||||
|
unzip -d "$dir" "$file"
|
||||||
|
fi
|
||||||
|
cmsImportTask "$dir"
|
||||||
|
done
|
||||||
10
roles/add_helper_scripts/files/users.bash
Normal file
10
roles/add_helper_scripts/files/users.bash
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env -S bash
|
||||||
|
cat > contest.yaml <<EOF
|
||||||
|
name: "con_test"
|
||||||
|
description: "Contest to test CMS"
|
||||||
|
users:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
awk '{printf "- username: \"%s\"\n password: \"%s\"\n", $1, $2}' passwd >> contest.yaml
|
||||||
|
|
||||||
|
less contest.yaml
|
||||||
15
roles/add_helper_scripts/tasks/main.yml
Normal file
15
roles/add_helper_scripts/tasks/main.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Copy users.bash
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: users.bash
|
||||||
|
dest: /srv/cms/users.bash
|
||||||
|
mode: '0755'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
- name: Copy import.bash
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: import.bash
|
||||||
|
dest: /srv/cms/import.bash
|
||||||
|
mode: '0755'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
1
roles/cms_preparation/files/bash_profile
Normal file
1
roles/cms_preparation/files/bash_profile
Normal file
@@ -0,0 +1 @@
|
|||||||
|
source "$HOME/.bashrc"
|
||||||
1
roles/cms_preparation/files/bashrc
Normal file
1
roles/cms_preparation/files/bashrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
source "$HOME/.profile"
|
||||||
4
roles/cms_preparation/files/profile
Normal file
4
roles/cms_preparation/files/profile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export PYENV_ROOT="$HOME/.pyenv"
|
||||||
|
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
|
||||||
|
eval "$(pyenv init -)"
|
||||||
|
source "$HOME/bin/activate"
|
||||||
104
roles/cms_preparation/tasks/main.yml
Normal file
104
roles/cms_preparation/tasks/main.yml
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
- name: Clone repository
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: 'https://github.com/cms-dev/cms.git'
|
||||||
|
dest: /srv/cms
|
||||||
|
version: b77c87b4d60fbe7df60dc5e03d2be632a25992fe
|
||||||
|
single_branch: true
|
||||||
|
track_submodules: true
|
||||||
|
update: false
|
||||||
|
- name: Run prerequisites
|
||||||
|
ansible.builtin.command: |
|
||||||
|
python prerequisites.py -y --as-root install
|
||||||
|
args:
|
||||||
|
chdir: /srv/cms
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
|
- name: Modify cmsuser
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: cmsuser
|
||||||
|
shell: /usr/bin/bash
|
||||||
|
home: /srv/cms
|
||||||
|
groups: wheel
|
||||||
|
append: true
|
||||||
|
- name: Allow wheel group to sudo
|
||||||
|
community.general.sudoers:
|
||||||
|
name: wheel
|
||||||
|
group: wheel
|
||||||
|
commands: ALL
|
||||||
|
runas: ALL
|
||||||
|
nopassword: true
|
||||||
|
- name: Chown cms directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /srv/cms/
|
||||||
|
state: directory
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
recurse: true
|
||||||
|
- name: Install pyenv
|
||||||
|
ansible.builtin.command: |
|
||||||
|
pyenv install 3.8.20 --skip-existing
|
||||||
|
args:
|
||||||
|
chdir: /srv/cms
|
||||||
|
become: true
|
||||||
|
become_user: cmsuser
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
|
- name: Setup pyenv
|
||||||
|
ansible.builtin.command: |
|
||||||
|
pyenv local 3.8.20
|
||||||
|
args:
|
||||||
|
chdir: /srv/cms
|
||||||
|
become: true
|
||||||
|
become_user: cmsuser
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
|
- name: Setup .profile
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: profile
|
||||||
|
dest: /srv/cms/.profile
|
||||||
|
mode: '0644'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
- name: Setup .bashrc
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: bashrc
|
||||||
|
dest: /srv/cms/.bashrc
|
||||||
|
mode: '0644'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
- name: Setup .bash_profile
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: bash_profile
|
||||||
|
dest: /srv/cms/.bash_profile
|
||||||
|
mode: '0644'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
- name: Check python version
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
sudo -iu cmsuser <<EOF
|
||||||
|
python --version
|
||||||
|
EOF
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
|
failed_when: ret.stdout != 'Python 3.8.20'
|
||||||
|
- name: Setup python venv
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
sudo -iu cmsuser <<EOF
|
||||||
|
python -m venv .
|
||||||
|
EOF
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
|
- name: Install requirements
|
||||||
|
ansible.builtin.pip:
|
||||||
|
virtualenv: /srv/cms
|
||||||
|
requirements: /srv/cms/requirements.txt
|
||||||
|
become: true
|
||||||
|
become_user: cmsuser
|
||||||
|
- name: Install cms
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
sudo -iu cmsuser <<EOF
|
||||||
|
python setup.py install
|
||||||
|
EOF
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
22
roles/configure_cms/files/cms-log.service
Normal file
22
roles/configure_cms/files/cms-log.service
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=CMS Log Server Daemon
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=cmsuser
|
||||||
|
Group=cmsuser
|
||||||
|
WorkingDirectory=/srv/cms
|
||||||
|
Environment=PYENV_SHELL=bash
|
||||||
|
Environment=PYENV_ROOT=/srv/cms/.pyenv
|
||||||
|
Environment=LOGNAME=cmsuser
|
||||||
|
Environment=VIRTUAL_ENV=/srv/cms
|
||||||
|
ExecStart=/srv/cms/bin/cmsLogService 0
|
||||||
|
ExecStop=/usr/bin/kill $MAINPID
|
||||||
|
Restart=on-failure
|
||||||
|
StandardInput=null
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
22
roles/configure_cms/files/cms-rank.service
Normal file
22
roles/configure_cms/files/cms-rank.service
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=CMS Ranking Server Daemon
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=cmsuser
|
||||||
|
Group=cmsuser
|
||||||
|
WorkingDirectory=/srv/cms
|
||||||
|
Environment=PYENV_SHELL=bash
|
||||||
|
Environment=PYENV_ROOT=/srv/cms/.pyenv
|
||||||
|
Environment=LOGNAME=cmsuser
|
||||||
|
Environment=VIRTUAL_ENV=/srv/cms
|
||||||
|
ExecStart=/srv/cms/bin/cmsRankingWebServer
|
||||||
|
ExecStop=/usr/bin/kill $MAINPID
|
||||||
|
Restart=on-failure
|
||||||
|
StandardInput=null
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
24
roles/configure_cms/files/cms@.service
Normal file
24
roles/configure_cms/files/cms@.service
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=CMS Resources Service Daemon for Contest ID %i
|
||||||
|
Requires=cms-log.service postgresql.service
|
||||||
|
After=network.target cms-log.service postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=cmsuser
|
||||||
|
Group=cmsuser
|
||||||
|
WorkingDirectory=/srv/cms
|
||||||
|
Environment=PYENV_SHELL=bash
|
||||||
|
Environment=PYENV_ROOT=/srv/cms/.pyenv
|
||||||
|
Environment=LOGNAME=cmsuser
|
||||||
|
Environment=VIRTUAL_ENV=/srv/cms
|
||||||
|
ExecStart=/srv/cms/bin/cmsResourceService -a %i
|
||||||
|
ExecStop=/usr/bin/kill $MAINPID
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=60s
|
||||||
|
StandardInput=null
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
46
roles/configure_cms/tasks/main.yml
Normal file
46
roles/configure_cms/tasks/main.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- name: Install cms.conf
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: cms.conf.jinja
|
||||||
|
dest: /usr/local/etc/cms.conf
|
||||||
|
mode: '0600'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
- name: Install cms.ranking.conf
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: cms.ranking.conf.jinja
|
||||||
|
dest: /usr/local/etc/cms.ranking.conf
|
||||||
|
mode: '0600'
|
||||||
|
owner: cmsuser
|
||||||
|
group: cmsuser
|
||||||
|
- name: Copy cms-log.service
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: cms-log.service
|
||||||
|
dest: /etc/systemd/system/cms-log.service
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
- name: Enable and start cms-log.service
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: cms-log.service
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
- name: Copy cms-rank.service
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: cms-rank.service
|
||||||
|
dest: /etc/systemd/system/cms-rank.service
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
- name: Enable and start cms-rank.service
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: cms-rank.service
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
- name: Copy cms@.service
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: cms@.service
|
||||||
|
dest: /etc/systemd/system/cms@.service
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
193
roles/configure_cms/templates/cms.conf.jinja
Normal file
193
roles/configure_cms/templates/cms.conf.jinja
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
{
|
||||||
|
"_help": "There is no way to put comments in a JSON file; the",
|
||||||
|
"_help": "fields starting with '_' are meant to be comments.",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "System-wide configuration",
|
||||||
|
|
||||||
|
"temp_dir": "/tmp",
|
||||||
|
|
||||||
|
"_help": "Whether to have a backdoor (see doc for the risks).",
|
||||||
|
"backdoor": false,
|
||||||
|
|
||||||
|
"_help": "The user/group that CMS will be run as.",
|
||||||
|
"cmsuser": "cmsuser",
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "AsyncLibrary",
|
||||||
|
|
||||||
|
"core_services":
|
||||||
|
{
|
||||||
|
"LogService": [["localhost", 29000]],
|
||||||
|
"ResourceService": [["localhost", 28000]],
|
||||||
|
"ScoringService": [["localhost", 28500]],
|
||||||
|
"Checker": [["localhost", 22000]],
|
||||||
|
"EvaluationService": [["localhost", 25000]],
|
||||||
|
"Worker": [["localhost", 26000],
|
||||||
|
["localhost", 26001],
|
||||||
|
["localhost", 26002],
|
||||||
|
["localhost", 26003],
|
||||||
|
["localhost", 26004],
|
||||||
|
["localhost", 26005],
|
||||||
|
["localhost", 26006],
|
||||||
|
["localhost", 26007],
|
||||||
|
["localhost", 26008],
|
||||||
|
["localhost", 26009],
|
||||||
|
["localhost", 26010],
|
||||||
|
["localhost", 26011],
|
||||||
|
["localhost", 26012],
|
||||||
|
["localhost", 26013],
|
||||||
|
["localhost", 26014],
|
||||||
|
["localhost", 26015]],
|
||||||
|
"ContestWebServer": [["localhost", 21000]],
|
||||||
|
"AdminWebServer": [["localhost", 21100]],
|
||||||
|
"ProxyService": [["localhost", 28600]],
|
||||||
|
"PrintingService": [["localhost", 25123]]
|
||||||
|
},
|
||||||
|
|
||||||
|
"other_services":
|
||||||
|
{
|
||||||
|
"TestFileCacher": [["localhost", 27501]]
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "Database",
|
||||||
|
|
||||||
|
"_help": "Connection string for the database.",
|
||||||
|
"database": "postgresql+psycopg2://cmsuser:{{ password }}@localhost:5432/cmsdb",
|
||||||
|
|
||||||
|
"_help": "Whether SQLAlchemy prints DB queries on stdout.",
|
||||||
|
"database_debug": false,
|
||||||
|
|
||||||
|
"_help": "Whether to use two-phase commit.",
|
||||||
|
"twophase_commit": false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "Worker",
|
||||||
|
|
||||||
|
"_help": "Don't delete the sandbox directory under /tmp/ when they",
|
||||||
|
"_help": "are not needed anymore. Warning: this can easily eat GB",
|
||||||
|
"_help": "of space very soon.",
|
||||||
|
"keep_sandbox": false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "Sandbox",
|
||||||
|
|
||||||
|
"_help": "Do not allow contestants' solutions to write files bigger",
|
||||||
|
"_help": "than this size (expressed in KB; defaults to 1 GB).",
|
||||||
|
"max_file_size": 1048576,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "WebServers",
|
||||||
|
|
||||||
|
"_help": "This key is used to encode information that can be seen",
|
||||||
|
"_help": "by the user, namely cookies and auto-incremented",
|
||||||
|
"_help": "numbers. It should be changed for each",
|
||||||
|
"_help": "contest. Particularly, you should not use this example",
|
||||||
|
"_help": "for other than testing. It must be a 16 bytes long",
|
||||||
|
"_help": "hexadecimal number. You can easily create a key calling:",
|
||||||
|
"_help": "python -c 'from cmscommon import crypto; print(crypto.get_hex_random_key())'",
|
||||||
|
"secret_key": "8e045a51e4b102ea803c06f92841a1fb",
|
||||||
|
|
||||||
|
"_help": "Whether Tornado prints debug information on stdout.",
|
||||||
|
"tornado_debug": false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "ContestWebServer",
|
||||||
|
|
||||||
|
"_help": "Listening HTTP addresses and ports for the CWSs listed above",
|
||||||
|
"_help": "in core_services. If you access them through a proxy (acting",
|
||||||
|
"_help": "as a load balancer) running on the same host you could put",
|
||||||
|
"_help": "127.0.0.1 here for additional security.",
|
||||||
|
"contest_listen_address": [""],
|
||||||
|
"contest_listen_port": [8888],
|
||||||
|
|
||||||
|
"_help": "Login cookie duration in seconds. The duration is refreshed",
|
||||||
|
"_help": "on every manual request.",
|
||||||
|
"cookie_duration": 10800,
|
||||||
|
|
||||||
|
"_help": "If CWSs write submissions to disk before storing them in",
|
||||||
|
"_help": "the DB, and where to save them. %s = DATA_DIR.",
|
||||||
|
"submit_local_copy": true,
|
||||||
|
"submit_local_copy_path": "%s/submissions/",
|
||||||
|
|
||||||
|
"_help": "The number of proxies that will be crossed before CWSs get",
|
||||||
|
"_help": "the request. This is used to decide whether to assume that",
|
||||||
|
"_help": "the real source IP address is the one listed in the request",
|
||||||
|
"_help": "headers or not. For example, if you're using nginx as a load",
|
||||||
|
"_help": "balancer, you will likely want to set this value to 1.",
|
||||||
|
"num_proxies_used": 0,
|
||||||
|
|
||||||
|
"_help": "Maximum size of a submission in bytes. If you use a proxy",
|
||||||
|
"_help": "and set these sizes to large values remember to change",
|
||||||
|
"_help": "client_max_body_size in nginx.conf too.",
|
||||||
|
"max_submission_length": 100000,
|
||||||
|
"max_input_length": 5000000,
|
||||||
|
|
||||||
|
"_help": "STL documentation path in the system (exposed in CWS).",
|
||||||
|
"stl_path": "/usr/share/cppreference/doc/html/",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "AdminWebServer",
|
||||||
|
|
||||||
|
"_help": "Listening HTTP address and port for the AWS. If you access",
|
||||||
|
"_help": "it through a proxy running on the same host you could put",
|
||||||
|
"_help": "127.0.0.1 here for additional security.",
|
||||||
|
"admin_listen_address": "",
|
||||||
|
"admin_listen_port": 8889,
|
||||||
|
|
||||||
|
"_help": "Login cookie duration for admins in seconds.",
|
||||||
|
"_help": "The duration is refreshed on every manual request.",
|
||||||
|
"admin_cookie_duration": 36000,
|
||||||
|
|
||||||
|
"_help": "The number of proxies that will be crossed before AWS gets",
|
||||||
|
"_help": "the request. This is used to determine the request's real",
|
||||||
|
"_help": "source IP address. For example, if you're using nginx as",
|
||||||
|
"_help": "a proxy, you will likely want to set this value to 1.",
|
||||||
|
"admin_num_proxies_used": 0,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "ScoringService",
|
||||||
|
|
||||||
|
"_help": "List of URLs (with embedded username and password) of the",
|
||||||
|
"_help": "RWSs where the scores are to be sent. Don't include the",
|
||||||
|
"_help": "load balancing proxy (if any), just the backends. If any",
|
||||||
|
"_help": "of them uses HTTPS specify a file with the certificates",
|
||||||
|
"_help": "you trust.",
|
||||||
|
"rankings": ["http://{{ username }}:{{ password }}@localhost:8890/"],
|
||||||
|
"https_certfile": null,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_section": "PrintingService",
|
||||||
|
|
||||||
|
"_help": "Maximum size of a print job in bytes.",
|
||||||
|
"max_print_length": 10000000,
|
||||||
|
|
||||||
|
"_help": "Printer name (can be found out using 'lpstat -p';",
|
||||||
|
"_help": "if null, printing is disabled)",
|
||||||
|
"printer": null,
|
||||||
|
|
||||||
|
"_help": "Output paper size (probably A4 or Letter)",
|
||||||
|
"paper_size": "A4",
|
||||||
|
|
||||||
|
"_help": "Maximum number of pages a user can print per print job",
|
||||||
|
"_help": "(excluding the title page). Text files are cropped to this",
|
||||||
|
"_help": "length. Too long pdf files are rejected.",
|
||||||
|
"max_pages_per_job": 10,
|
||||||
|
"max_jobs_per_user": 10,
|
||||||
|
"pdf_printing_allowed": false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"_help": "This is the end of this file."
|
||||||
|
}
|
||||||
|
|
||||||
16
roles/configure_cms/templates/cms.ranking.conf.jinja
Normal file
16
roles/configure_cms/templates/cms.ranking.conf.jinja
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"_help": "There is no way to put comments in a JSON file; the",
|
||||||
|
"_help": "fields starting with '_' are meant to be comments.",
|
||||||
|
|
||||||
|
"_help": "Listening address for RankingWebServer.",
|
||||||
|
"bind_address": "",
|
||||||
|
|
||||||
|
"_help": "Listening port for RankingWebServer.",
|
||||||
|
"http_port": 8890,
|
||||||
|
|
||||||
|
"_help": "Login information for adding and editing data.",
|
||||||
|
"username": "{{ username }}",
|
||||||
|
"password": "{{ password }}",
|
||||||
|
|
||||||
|
"_help": "This is the end of this file."
|
||||||
|
}
|
||||||
5
roles/configure_haproxy/handlers/main.yml
Normal file
5
roles/configure_haproxy/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Reload haproxy
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: haproxy
|
||||||
|
state: reloaded
|
||||||
14
roles/configure_haproxy/tasks/main.yml
Normal file
14
roles/configure_haproxy/tasks/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Copy haproxy.cfg
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: haproxy.cfg.jinja
|
||||||
|
dest: /etc/haproxy/haproxy.cfg
|
||||||
|
mode: '0600'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
notify: Reload haproxy
|
||||||
|
- name: Enable and start haproxy
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: haproxy.service
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
69
roles/configure_haproxy/templates/haproxy.cfg.jinja
Normal file
69
roles/configure_haproxy/templates/haproxy.cfg.jinja
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Example configuration. See the full configuration manual online.
|
||||||
|
#
|
||||||
|
# http://www.haproxy.org/download/2.5/doc/configuration.txt
|
||||||
|
#
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
global
|
||||||
|
maxconn 20000
|
||||||
|
log 127.0.0.1 local0
|
||||||
|
user haproxy
|
||||||
|
pidfile /run/haproxy.pid
|
||||||
|
daemon
|
||||||
|
|
||||||
|
userlist creds
|
||||||
|
user {{ username }} insecure-password {{ password }}
|
||||||
|
|
||||||
|
frontend secure
|
||||||
|
bind :8080
|
||||||
|
http-request auth unless { http_auth(creds) }
|
||||||
|
mode http
|
||||||
|
log global
|
||||||
|
option httplog
|
||||||
|
option dontlognull
|
||||||
|
option forwardfor except 127.0.0.0/8
|
||||||
|
maxconn 8000
|
||||||
|
timeout client 30s
|
||||||
|
|
||||||
|
use_backend rank if { hdr(host) -i {{ dns_prefix }}-ranking.{{ dns_suffix }} }
|
||||||
|
use_backend admin if { hdr(host) -i {{ dns_prefix }}-admin.{{ dns_suffix }} }
|
||||||
|
default_backend contest
|
||||||
|
|
||||||
|
frontend main
|
||||||
|
bind :80
|
||||||
|
mode http
|
||||||
|
log global
|
||||||
|
option httplog
|
||||||
|
option dontlognull
|
||||||
|
option forwardfor except 127.0.0.0/8
|
||||||
|
maxconn 8000
|
||||||
|
timeout client 30s
|
||||||
|
|
||||||
|
use_backend rank if { hdr(host) -i {{ dns_prefix }}-ranking.{{ dns_suffix }} }
|
||||||
|
use_backend admin if { hdr(host) -i {{ dns_prefix }}-admin.{{ dns_suffix }} }
|
||||||
|
default_backend contest
|
||||||
|
|
||||||
|
backend contest
|
||||||
|
mode http
|
||||||
|
balance roundrobin
|
||||||
|
timeout connect 5s
|
||||||
|
timeout server 30s
|
||||||
|
timeout queue 30s
|
||||||
|
server contest1 127.0.0.1:8888 check
|
||||||
|
|
||||||
|
backend admin
|
||||||
|
mode http
|
||||||
|
balance roundrobin
|
||||||
|
timeout connect 5s
|
||||||
|
timeout server 30s
|
||||||
|
timeout queue 30s
|
||||||
|
server admin1 127.0.0.1:8889 check
|
||||||
|
|
||||||
|
backend rank
|
||||||
|
mode http
|
||||||
|
balance roundrobin
|
||||||
|
timeout connect 5s
|
||||||
|
timeout server 30s
|
||||||
|
timeout queue 30s
|
||||||
|
server rank1 127.0.0.1:8890 check
|
||||||
4
roles/install_packages/handlers/main.yml
Normal file
4
roles/install_packages/handlers/main.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
- name: Upgrade packages
|
||||||
|
community.general.pacman:
|
||||||
|
upgrade: true
|
||||||
34
roles/install_packages/tasks/main.yml
Normal file
34
roles/install_packages/tasks/main.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
- name: Update package cache
|
||||||
|
community.general.pacman:
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Install cms dependencies
|
||||||
|
community.general.pacman:
|
||||||
|
pkg:
|
||||||
|
- base-devel
|
||||||
|
- jdk8-openjdk
|
||||||
|
- fpc
|
||||||
|
- postgresql
|
||||||
|
- python
|
||||||
|
- libcap
|
||||||
|
- git
|
||||||
|
notify: Upgrade packages
|
||||||
|
|
||||||
|
- name: Install cms optional dependencies
|
||||||
|
community.general.pacman:
|
||||||
|
pkg:
|
||||||
|
- postgresql-libs
|
||||||
|
- libcups
|
||||||
|
- libyaml
|
||||||
|
- python-virtualenv
|
||||||
|
- rust
|
||||||
|
notify: Upgrade packages
|
||||||
|
|
||||||
|
- name: Install additional packages
|
||||||
|
community.general.pacman:
|
||||||
|
pkg:
|
||||||
|
- pyenv
|
||||||
|
- haproxy
|
||||||
|
- python-psycopg2
|
||||||
|
notify: Upgrade packages
|
||||||
3
roles/setup_cgroupsv1/handlers/main.yml
Normal file
3
roles/setup_cgroupsv1/handlers/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
- name: Reboot
|
||||||
|
ansible.builtin.reboot:
|
||||||
13
roles/setup_cgroupsv1/tasks/main.yml
Normal file
13
roles/setup_cgroupsv1/tasks/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Setup boot entry facts
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
bootconf: "{{ setup_cgroupsv1_bootconf | default('/boot/loader/entries/arch.conf') }}"
|
||||||
|
- name: Append cgroupsv1 boot option
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: "{{ bootconf }}"
|
||||||
|
regexp: '^(options.*rw)'
|
||||||
|
line: '\1 SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 systemd.unified_cgroup_hierarchy=0'
|
||||||
|
backrefs: true
|
||||||
|
notify: Reboot
|
||||||
|
- name: Flush handlers
|
||||||
|
ansible.builtin.meta: flush_handlers
|
||||||
42
roles/setup_database/tasks/main.yml
Normal file
42
roles/setup_database/tasks/main.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
- name: Init PostgreSQL
|
||||||
|
ansible.builtin.command: |
|
||||||
|
initdb --locale=C.UTF-8 --encoding=UTF8 -D /var/lib/postgres/data
|
||||||
|
args:
|
||||||
|
creates: /var/lib/postgres/data/PG_VERSION
|
||||||
|
become: true
|
||||||
|
become_user: postgres
|
||||||
|
- name: Start and enable postgres
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: postgresql.service
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
- name: Setup postgres
|
||||||
|
become: true
|
||||||
|
become_user: postgres
|
||||||
|
block:
|
||||||
|
- name: Create cmsuser
|
||||||
|
community.postgresql.postgresql_user:
|
||||||
|
name: cmsuser
|
||||||
|
password: "{{ password }}"
|
||||||
|
environment:
|
||||||
|
PGOPTION: '-c password_encryption=scram-sha-256'
|
||||||
|
- name: Create cmsdb
|
||||||
|
community.postgresql.postgresql_db:
|
||||||
|
db: cmsdb
|
||||||
|
owner: cmsuser
|
||||||
|
- name: Configure privileges
|
||||||
|
community.postgresql.postgresql_privs:
|
||||||
|
db: cmsdb
|
||||||
|
role: cmsuser
|
||||||
|
privs: ALL
|
||||||
|
objs: ALL_IN_SCHEMA
|
||||||
|
- name: CMS init DB
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
sudo -iu cmsuser <<EOF
|
||||||
|
cmsInitDB
|
||||||
|
EOF
|
||||||
|
become: true
|
||||||
|
become_user: cmsuser
|
||||||
|
register: ret
|
||||||
|
changed_when: ret.rc != 0
|
||||||
Reference in New Issue
Block a user