Initial commit
Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
commit
0a0341e6f9
92 changed files with 3529 additions and 0 deletions
64
.forgejo/workflows/ansible-ci.yml
Normal file
64
.forgejo/workflows/ansible-ci.yml
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ansible-docsmith:
|
||||||
|
runs-on: node-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install ansible-docsmith
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y python3-pip
|
||||||
|
pip install ansible-docsmith --break-system-packages
|
||||||
|
|
||||||
|
- name: Run ansible-docsmith
|
||||||
|
run: |
|
||||||
|
for role_dir in $(ls --color=none roles); do
|
||||||
|
ansible-docsmith generate "roles/${role_dir}"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Verify changes
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
git diff > diff.txt
|
||||||
|
CHANGES=$(wc -l diff.txt | awk '{ print $1 }')
|
||||||
|
echo "Number of changes: ${CHANGES}"
|
||||||
|
if [ ${CHANGES} -gt 0 ] ; then
|
||||||
|
echo ""
|
||||||
|
cat diff.txt
|
||||||
|
echo ""
|
||||||
|
echo "Fix with the following command:"
|
||||||
|
echo ""
|
||||||
|
echo "run ansible-docsmith generate ${role_dir}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
molecule:
|
||||||
|
runs-on: node-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
role:
|
||||||
|
- certbot
|
||||||
|
- galene
|
||||||
|
- golang
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install requirements for Python
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y python3-pip
|
||||||
|
pip install -r test-requirements.txt --break-system-packages
|
||||||
|
|
||||||
|
- name: Install requirements for Ansible Galaxy
|
||||||
|
run: |
|
||||||
|
ansible-galaxy collection install -r test-requirements.yml
|
||||||
|
|
||||||
|
- name: Run molecule
|
||||||
|
run: molecule test --all
|
||||||
|
chdir: "roles/${{ matrix.role }}"
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
venv
|
||||||
9
LICENSE
Normal file
9
LICENSE
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 jriou
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Ansible
|
||||||
|
|
||||||
|
My Ansible collection.
|
||||||
29
galaxy.yml
Normal file
29
galaxy.yml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
namespace: jriou
|
||||||
|
name: general
|
||||||
|
version: 1.0.0
|
||||||
|
readme: README.md
|
||||||
|
authors:
|
||||||
|
- "Julien Riou (https://git.riou.xyz/jriou)"
|
||||||
|
description: "My Ansible Collection"
|
||||||
|
license_file: LICENSE
|
||||||
|
tags:
|
||||||
|
- infrastructure
|
||||||
|
- certbot
|
||||||
|
- coller
|
||||||
|
- firefly
|
||||||
|
- forgejo
|
||||||
|
- forgejo_runners
|
||||||
|
- galene
|
||||||
|
- golang
|
||||||
|
- navidrome
|
||||||
|
repository: "https://git.riou.xyz/jriou/ansible"
|
||||||
|
issues: "https://git.riou.xyz/jriou/ansible/issues"
|
||||||
|
build_ignore:
|
||||||
|
- .github
|
||||||
|
- .gitignore
|
||||||
|
- changelogs
|
||||||
|
- roles/*/molecule
|
||||||
|
- '*.tar.gz'
|
||||||
|
- test-requirements.txt
|
||||||
|
- test-requirements.yml
|
||||||
61
roles/certbot/README.md
Normal file
61
roles/certbot/README.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Ansible Role Certbot
|
||||||
|
|
||||||
|
## Table of content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`certbot_email`](#variable-certbot_email)
|
||||||
|
* [`certbot_domain`](#variable-certbot_domain)
|
||||||
|
* [`certbot_molecule`](#variable-certbot_molecule)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `certbot_email` | `str` | Yes | N/A | E-mail to register the certificate. |
|
||||||
|
| `certbot_domain` | `str` | Yes | N/A | Domain name to register the certificate. |
|
||||||
|
| `certbot_molecule` | `bool` | No | `false` | Run the role with Ansible Molecule.<br><br>Disable cert generation in the CI. |
|
||||||
|
|
||||||
|
### `certbot_email`<a id="variable-certbot_email"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
E-mail to register the certificate.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `certbot_domain`<a id="variable-certbot_domain"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Domain name to register the certificate.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `certbot_molecule`<a id="variable-certbot_molecule"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Run the role with Ansible Molecule.
|
||||||
|
|
||||||
|
Disable cert generation in the CI.
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `false`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
10
roles/certbot/defaults/main.yml
Normal file
10
roles/certbot/defaults/main.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Run the role with Ansible Molecule.
|
||||||
|
#
|
||||||
|
# Disable cert generation in the CI.
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: false
|
||||||
|
certbot_molecule: false
|
||||||
25
roles/certbot/meta/argument_specs.yml
Normal file
25
roles/certbot/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install and configure a certbot
|
||||||
|
description:
|
||||||
|
- Install and configure a [certbot](https://certbot.eff.org/).
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
certbot_email:
|
||||||
|
description:
|
||||||
|
- E-mail to register the certificate.
|
||||||
|
required: true
|
||||||
|
|
||||||
|
certbot_domain:
|
||||||
|
description:
|
||||||
|
- Domain name to register the certificate.
|
||||||
|
required: true
|
||||||
|
|
||||||
|
certbot_molecule:
|
||||||
|
description:
|
||||||
|
- Run the role with Ansible Molecule.
|
||||||
|
- Disable cert generation in the CI.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
9
roles/certbot/molecule/default/converge.yml
Normal file
9
roles/certbot/molecule/default/converge.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
- name: Converge
|
||||||
|
hosts: molecule
|
||||||
|
roles:
|
||||||
|
- certbot
|
||||||
|
vars:
|
||||||
|
certbot_domain: test.org
|
||||||
|
certbot_email: test@test.org
|
||||||
|
certbot_molecule: true
|
||||||
18
roles/certbot/molecule/default/create.yml
Normal file
18
roles/certbot/molecule/default/create.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
- name: Create containers
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Create containers
|
||||||
|
containers.podman.podman_container:
|
||||||
|
hostname: "{{ item }}"
|
||||||
|
name: "{{ item }}"
|
||||||
|
image: "{{ hostvars[item]['container_image'] }}"
|
||||||
|
state: started
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
|
|
||||||
|
- name: Wait for containers to be ready
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
delegate_to: "{{ item }}"
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
11
roles/certbot/molecule/default/destroy.yml
Normal file
11
roles/certbot/molecule/default/destroy.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: Destroy container instances
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Remove containers
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
|
failed_when: false
|
||||||
12
roles/certbot/molecule/default/inventory/hosts.yml
Normal file
12
roles/certbot/molecule/default/inventory/hosts.yml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
molecule:
|
||||||
|
hosts:
|
||||||
|
debian11:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian11-ansible:latest
|
||||||
|
debian12:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian12-ansible:latest
|
||||||
|
debian13:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian13-ansible:latest
|
||||||
24
roles/certbot/molecule/default/molecule.yml
Normal file
24
roles/certbot/molecule/default/molecule.yml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
ansible:
|
||||||
|
executor:
|
||||||
|
args:
|
||||||
|
ansible_playbook:
|
||||||
|
- --inventory=inventory/
|
||||||
|
env:
|
||||||
|
ANSIBLE_ROLES_PATH: ../../../../roles
|
||||||
|
playbooks:
|
||||||
|
create: create.yml
|
||||||
|
destroy: destroy.yml
|
||||||
|
converge: converge.yml
|
||||||
|
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
options:
|
||||||
|
requirements-file: ${MOLECULE_SCENARIO_DIRECTORY}/requirements.yml
|
||||||
|
|
||||||
|
scenario:
|
||||||
|
test_sequence:
|
||||||
|
- create
|
||||||
|
- converge
|
||||||
|
- idempotence
|
||||||
|
- destroy
|
||||||
3
roles/certbot/molecule/default/requirements.yml
Normal file
3
roles/certbot/molecule/default/requirements.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: containers.podman
|
||||||
13
roles/certbot/tasks/main.yml
Normal file
13
roles/certbot/tasks/main.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
- name: Install packages
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: certbot
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Request certificate
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >-
|
||||||
|
certbot certonly --standalone -n --agree-tos
|
||||||
|
--email {{ certbot_email }} -d {{ certbot_domain }}
|
||||||
|
creates: /etc/letsencrypt/live/{{ certbot_domain }}/fullchain.pem
|
||||||
|
when: not certbot_molecule
|
||||||
159
roles/coller/README.md
Normal file
159
roles/coller/README.md
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
# Ansible Role Coller
|
||||||
|
|
||||||
|
Ansible role to manage a [coller](https://git.riou.xyz/jriou/coller) instance.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
See [Variable
|
||||||
|
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
|
||||||
|
to find where you should put your own variables.
|
||||||
|
|
||||||
|
Then define at least `coller_db_password` with a strong and secure password,
|
||||||
|
encrypted using
|
||||||
|
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
|
||||||
|
|
||||||
|
## Table of content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`coller_version`](#variable-coller_version)
|
||||||
|
* [`coller_config_dir`](#variable-coller_config_dir)
|
||||||
|
* [`coller_port`](#variable-coller_port)
|
||||||
|
* [`coller_manage_iptables`](#variable-coller_manage_iptables)
|
||||||
|
* [`coller_allowed_sources`](#variable-coller_allowed_sources)
|
||||||
|
* [`coller_db_name`](#variable-coller_db_name)
|
||||||
|
* [`coller_db_user`](#variable-coller_db_user)
|
||||||
|
* [`coller_db_password`](#variable-coller_db_password)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `coller_version` | `str` | No | `"1.3.1"` | Version of the binary. |
|
||||||
|
| `coller_config_dir` | `path` | No | `"/etc/coller"` | Directory of the configuration files. |
|
||||||
|
| `coller_port` | `int` | No | `8080` | Port to listen. |
|
||||||
|
| `coller_manage_iptables` | `bool` | No | `false` | Create iptables rule to allow the service. |
|
||||||
|
| `coller_allowed_sources` | `list` | No | N/A | List of allowed networks to allow.<br><br>Enabled when `coller_manage_iptables` is enabled. |
|
||||||
|
| `coller_db_name` | `str` | No | `"coller"` | Name of the database to connect. |
|
||||||
|
| `coller_db_user` | `str` | No | `"coller"` | User to connect to the database. |
|
||||||
|
| `coller_db_password` | `str` | Yes | N/A | Password to connect to the database. |
|
||||||
|
|
||||||
|
### `coller_version`<a id="variable-coller_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Version of the binary.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"1.3.1"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_config_dir`<a id="variable-coller_config_dir"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Directory of the configuration files.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/etc/coller"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_port`<a id="variable-coller_port"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Port to listen.
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `8080`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_manage_iptables`<a id="variable-coller_manage_iptables"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Create iptables rule to allow the service.
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `false`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_allowed_sources`<a id="variable-coller_allowed_sources"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
List of allowed networks to allow.
|
||||||
|
|
||||||
|
Enabled when `coller_manage_iptables` is enabled.
|
||||||
|
|
||||||
|
- **Type**: `list`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_db_name`<a id="variable-coller_db_name"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Name of the database to connect.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"coller"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_db_user`<a id="variable-coller_db_user"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
User to connect to the database.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"coller"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `coller_db_password`<a id="variable-coller_db_password"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Password to connect to the database.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Example of a basic coller.yml playbook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- hosts: coller
|
||||||
|
roles:
|
||||||
|
- coller
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the playbook:
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook coller.yml
|
||||||
|
```
|
||||||
51
roles/coller/defaults/main.yml
Normal file
51
roles/coller/defaults/main.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Version of the binary.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 1.3.1
|
||||||
|
coller_version: 1.3.1
|
||||||
|
|
||||||
|
# Directory of the configuration files.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /etc/coller
|
||||||
|
coller_config_dir: /etc/coller
|
||||||
|
|
||||||
|
# Port to listen.
|
||||||
|
#
|
||||||
|
# - Type: int
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 8080
|
||||||
|
coller_port: 8080
|
||||||
|
|
||||||
|
# Create iptables rule to allow the service.
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: false
|
||||||
|
coller_manage_iptables: false
|
||||||
|
|
||||||
|
# List of allowed networks to allow.
|
||||||
|
#
|
||||||
|
# Enabled when `coller_manage_iptables` is enabled.
|
||||||
|
#
|
||||||
|
# - Type: list
|
||||||
|
# - Required: No
|
||||||
|
coller_allowed_sources: []
|
||||||
|
|
||||||
|
# Name of the database to connect.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: coller
|
||||||
|
coller_db_name: coller
|
||||||
|
|
||||||
|
# User to connect to the database.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: coller
|
||||||
|
coller_db_user: coller
|
||||||
4
roles/coller/handlers/main.yml
Normal file
4
roles/coller/handlers/main.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
- name: save iptables
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: netfilter-persistent save
|
||||||
52
roles/coller/meta/argument_specs.yml
Normal file
52
roles/coller/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install and configure a coller instance
|
||||||
|
description:
|
||||||
|
- Install and configure a [coller](https://git.riou.xyz/jriou/coller) instance.
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
coller_version:
|
||||||
|
description:
|
||||||
|
- Version of the binary.
|
||||||
|
default: "1.3.1"
|
||||||
|
|
||||||
|
coller_config_dir:
|
||||||
|
description:
|
||||||
|
- Directory of the configuration files.
|
||||||
|
type: path
|
||||||
|
default: /etc/coller
|
||||||
|
|
||||||
|
coller_port:
|
||||||
|
description:
|
||||||
|
- Port to listen.
|
||||||
|
type: int
|
||||||
|
default: 8080
|
||||||
|
|
||||||
|
coller_manage_iptables:
|
||||||
|
description:
|
||||||
|
- Create iptables rule to allow the service.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
|
||||||
|
coller_allowed_sources:
|
||||||
|
description:
|
||||||
|
- List of allowed networks to allow.
|
||||||
|
- Enabled when `coller_manage_iptables` is enabled.
|
||||||
|
type: list
|
||||||
|
|
||||||
|
coller_db_name:
|
||||||
|
description:
|
||||||
|
- Name of the database to connect.
|
||||||
|
default: coller
|
||||||
|
|
||||||
|
coller_db_user:
|
||||||
|
description:
|
||||||
|
- User to connect to the database.
|
||||||
|
default: coller
|
||||||
|
|
||||||
|
coller_db_password:
|
||||||
|
description:
|
||||||
|
- Password to connect to the database.
|
||||||
|
required: true
|
||||||
3
roles/coller/meta/main.yml
Normal file
3
roles/coller/meta/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- role: geerlingguy.docker
|
||||||
55
roles/coller/tasks/main.yml
Normal file
55
roles/coller/tasks/main.yml
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
---
|
||||||
|
- name: check password
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- coller_db_password is defined
|
||||||
|
|
||||||
|
- name: download source code
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://git.riou.xyz/jriou/coller.git
|
||||||
|
dest: /opt/coller
|
||||||
|
version: "{{ coller_version }}"
|
||||||
|
|
||||||
|
- name: create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
loop:
|
||||||
|
- "{{ coller_config_dir }}"
|
||||||
|
|
||||||
|
- name: create docker-compose files
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.src }}.j2"
|
||||||
|
dest: "{{ coller_config_dir }}/{{ item.src }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
loop:
|
||||||
|
- src: docker-compose.yml
|
||||||
|
mode: "0644"
|
||||||
|
- src: db.env
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: create configuration file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content:
|
||||||
|
database_type: postgres
|
||||||
|
database_dsn: "host=db dbname={{ coller_db_name }} user={{ coller_db_user }} password={{ coller_db_password }}"
|
||||||
|
dest: "{{ coller_config_dir }}/collerd.json"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0640"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: start service
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ coller_config_dir }}"
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
|
|
||||||
|
- name: manage iptables
|
||||||
|
when: coller_manage_iptables
|
||||||
|
ansible.builtin.include_tasks: manage-iptables.yml
|
||||||
16
roles/coller/tasks/manage-iptables.yml
Normal file
16
roles/coller/tasks/manage-iptables.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
- name: install packages
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: netfilter-persistent
|
||||||
|
|
||||||
|
- name: allow with iptables
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}"
|
||||||
|
destination_ports:
|
||||||
|
- "{{ coller_port }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: coller
|
||||||
|
loop: "{{ coller_allowed_sources }}"
|
||||||
|
notify: save iptables
|
||||||
6
roles/coller/templates/db.env.j2
Normal file
6
roles/coller/templates/db.env.j2
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
POSTGRES_USER={{ coller_db_user }}
|
||||||
|
POSTGRES_PASSWORD={{ coller_db_password }}
|
||||||
|
POSTGRES_DB={{ coller_db_name }}
|
||||||
|
POSTGRES_INITDB_ARGS="--data-checksums"
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
32
roles/coller/templates/docker-compose.yml.j2
Normal file
32
roles/coller/templates/docker-compose.yml.j2
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
image: coller:{{ coller_version }}
|
||||||
|
build: /opt/coller
|
||||||
|
container_name: collerd
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- coller
|
||||||
|
ports:
|
||||||
|
- "{{ coller_port }}:8080"
|
||||||
|
volumes:
|
||||||
|
- "{{ coller_config_dir }}/collerd.json:/etc/collerd.json:ro"
|
||||||
|
command: collerd -config /etc/collerd.json
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:17
|
||||||
|
hostname: db
|
||||||
|
container_name: collerd_db
|
||||||
|
restart: always
|
||||||
|
env_file: {{ coller_config_dir }}/db.env
|
||||||
|
networks:
|
||||||
|
- coller
|
||||||
|
volumes:
|
||||||
|
- coller:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
coller:
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
coller:
|
||||||
234
roles/firefly/README.md
Normal file
234
roles/firefly/README.md
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
# Ansible Role Firefly
|
||||||
|
|
||||||
|
Ansible role to manage a [Firefly III](https://firefly-iii.org/) instance.
|
||||||
|
|
||||||
|
## Table of content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`firefly_version`](#variable-firefly_version)
|
||||||
|
* [`firefly_port`](#variable-firefly_port)
|
||||||
|
* [`firefly_static_cron_token`](#variable-firefly_static_cron_token)
|
||||||
|
* [`firefly_home`](#variable-firefly_home)
|
||||||
|
* [`firefly_site_owner`](#variable-firefly_site_owner)
|
||||||
|
* [`firefly_app_key`](#variable-firefly_app_key)
|
||||||
|
* [`firefly_language`](#variable-firefly_language)
|
||||||
|
* [`firefly_tz`](#variable-firefly_tz)
|
||||||
|
* [`firefly_db_database`](#variable-firefly_db_database)
|
||||||
|
* [`firefly_db_username`](#variable-firefly_db_username)
|
||||||
|
* [`firefly_db_password`](#variable-firefly_db_password)
|
||||||
|
* [`firefly_manage_iptables`](#variable-firefly_manage_iptables)
|
||||||
|
* [`firefly_allowed_sources`](#variable-firefly_allowed_sources)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `firefly_version` | `str` | No | `"latest"` | Version of the docker image. |
|
||||||
|
| `firefly_port` | `int` | No | `8080` | |
|
||||||
|
| `firefly_static_cron_token` | `str` | Yes | N/A | Token used by the cron job (sensitive). |
|
||||||
|
| `firefly_home` | `path` | No | `"/var/lib/firefly"` | Directory where to store data files. |
|
||||||
|
| `firefly_site_owner` | `str` | No | `"root@localhost"` | E-mail address of the site owner. |
|
||||||
|
| `firefly_app_key` | `str` | Yes | N/A | Application key (sensitive). |
|
||||||
|
| `firefly_language` | `str` | No | `"en_US"` | Language of the web interface. |
|
||||||
|
| `firefly_tz` | `str` | No | `"Etc/UTC"` | Time zone of the web interface. |
|
||||||
|
| `firefly_db_database` | `str` | No | `"firefly"` | Name of the database. |
|
||||||
|
| `firefly_db_username` | `str` | No | `"firefly"` | Name of the user to connect to the database. |
|
||||||
|
| `firefly_db_password` | `str` | Yes | N/A | Password to connect to the database (sensitive). |
|
||||||
|
| `firefly_manage_iptables` | `bool` | No | `false` | Configure iptables rules. |
|
||||||
|
| `firefly_allowed_sources` | `list` | No | N/A | List of IP ranges to allow when `firefly_manage_iptables` is enabled. |
|
||||||
|
|
||||||
|
### `firefly_version`<a id="variable-firefly_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Version of the docker image.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"latest"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_port`<a id="variable-firefly_port"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `8080`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_static_cron_token`<a id="variable-firefly_static_cron_token"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Token used by the cron job (sensitive).
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_home`<a id="variable-firefly_home"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Directory where to store data files.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/var/lib/firefly"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_site_owner`<a id="variable-firefly_site_owner"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
E-mail address of the site owner.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"root@localhost"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_app_key`<a id="variable-firefly_app_key"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Application key (sensitive).
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_language`<a id="variable-firefly_language"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Language of the web interface.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"en_US"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_tz`<a id="variable-firefly_tz"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Time zone of the web interface.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"Etc/UTC"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_db_database`<a id="variable-firefly_db_database"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Name of the database.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"firefly"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_db_username`<a id="variable-firefly_db_username"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Name of the user to connect to the database.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"firefly"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_db_password`<a id="variable-firefly_db_password"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Password to connect to the database (sensitive).
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_manage_iptables`<a id="variable-firefly_manage_iptables"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Configure iptables rules.
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `false`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `firefly_allowed_sources`<a id="variable-firefly_allowed_sources"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
List of IP ranges to allow when `firefly_manage_iptables` is enabled.
|
||||||
|
|
||||||
|
- **Type**: `list`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
See [Variable
|
||||||
|
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
|
||||||
|
to find where you should put your own variables.
|
||||||
|
|
||||||
|
Then define at least `firefly_static_cron_token`, `firefly_db_password` and
|
||||||
|
`firefly_app_key` variables with a strong and secure password, encrypted using
|
||||||
|
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
|
||||||
|
|
||||||
|
See list of [default variables](defaults/main.yml).
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Example of a basic firefly.yml playbook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
hosts:
|
||||||
|
- firefly
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- firefly
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the playbook:
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook firefly.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
As we all love FOSS projects, you should consider [sponsoring and/or
|
||||||
|
contribute](https://github.com/firefly-iii/firefly-iii).
|
||||||
66
roles/firefly/defaults/main.yml
Normal file
66
roles/firefly/defaults/main.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
firefly_port: 8000
|
||||||
|
|
||||||
|
# Version of the docker image.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: latest
|
||||||
|
firefly_version: latest
|
||||||
|
|
||||||
|
# Directory where to store data files.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /var/lib/firefly
|
||||||
|
firefly_home: /var/lib/firefly
|
||||||
|
|
||||||
|
# E-mail address of the site owner.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: root@localhost
|
||||||
|
firefly_site_owner: root@localhost
|
||||||
|
|
||||||
|
|
||||||
|
# Language of the web interface.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: en_US
|
||||||
|
firefly_language: en_US
|
||||||
|
|
||||||
|
# Time zone of the web interface.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: Etc/UTC
|
||||||
|
firefly_tz: Etc/UTC
|
||||||
|
|
||||||
|
# Name of the database.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: firefly
|
||||||
|
firefly_db_database: firefly
|
||||||
|
|
||||||
|
# Name of the user to connect to the database.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: firefly
|
||||||
|
firefly_db_username: firefly
|
||||||
|
|
||||||
|
|
||||||
|
# Configure iptables rules.
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: false
|
||||||
|
firefly_manage_iptables: false
|
||||||
|
|
||||||
|
# List of IP ranges to allow when `firefly_manage_iptables` is enabled.
|
||||||
|
#
|
||||||
|
# - Type: list
|
||||||
|
# - Required: No
|
||||||
|
firefly_allowed_sources: []
|
||||||
4
roles/firefly/handlers/main.yml
Normal file
4
roles/firefly/handlers/main.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
- name: save iptables
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: netfilter-persistent save
|
||||||
76
roles/firefly/meta/argument_specs.yml
Normal file
76
roles/firefly/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install and configure Firefly III
|
||||||
|
description:
|
||||||
|
- Install and configure [Firefly III](https://www.firefly-iii.org/).
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
firefly_version:
|
||||||
|
description:
|
||||||
|
- Version of the docker image.
|
||||||
|
default: latest
|
||||||
|
|
||||||
|
firefly_port:
|
||||||
|
descritpion:
|
||||||
|
- Port to listen.
|
||||||
|
type: int
|
||||||
|
default: 8080
|
||||||
|
|
||||||
|
firefly_static_cron_token:
|
||||||
|
description:
|
||||||
|
- Token used by the cron job (sensitive).
|
||||||
|
required: true
|
||||||
|
|
||||||
|
firefly_home:
|
||||||
|
description:
|
||||||
|
- Directory where to store data files.
|
||||||
|
type: path
|
||||||
|
default: /var/lib/firefly
|
||||||
|
|
||||||
|
firefly_site_owner:
|
||||||
|
description:
|
||||||
|
- E-mail address of the site owner.
|
||||||
|
default: root@localhost
|
||||||
|
|
||||||
|
firefly_app_key:
|
||||||
|
description:
|
||||||
|
- Application key (sensitive).
|
||||||
|
required: true
|
||||||
|
|
||||||
|
firefly_language:
|
||||||
|
description:
|
||||||
|
- Language of the web interface.
|
||||||
|
default: en_US
|
||||||
|
|
||||||
|
firefly_tz:
|
||||||
|
description:
|
||||||
|
- Time zone of the web interface.
|
||||||
|
default: Etc/UTC
|
||||||
|
|
||||||
|
firefly_db_database:
|
||||||
|
description:
|
||||||
|
- Name of the database.
|
||||||
|
default: firefly
|
||||||
|
|
||||||
|
firefly_db_username:
|
||||||
|
description:
|
||||||
|
- Name of the user to connect to the database.
|
||||||
|
default: firefly
|
||||||
|
|
||||||
|
firefly_db_password:
|
||||||
|
description:
|
||||||
|
- Password to connect to the database (sensitive).
|
||||||
|
required: true
|
||||||
|
|
||||||
|
firefly_manage_iptables:
|
||||||
|
description:
|
||||||
|
- Configure iptables rules.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
|
||||||
|
firefly_allowed_sources:
|
||||||
|
description:
|
||||||
|
- List of IP ranges to allow when `firefly_manage_iptables` is enabled.
|
||||||
|
type: list
|
||||||
3
roles/firefly/meta/main.yml
Normal file
3
roles/firefly/meta/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- role: geerlingguy.docker
|
||||||
47
roles/firefly/tasks/main.yml
Normal file
47
roles/firefly/tasks/main.yml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
- name: check requirements
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- firefly_static_cron_token is defined
|
||||||
|
- firefly_db_password is defined
|
||||||
|
- firefly_app_key is defined
|
||||||
|
|
||||||
|
- name: install dependencies
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- python3-docker
|
||||||
|
- python3-compose
|
||||||
|
|
||||||
|
- name: create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/firefly
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: create configuration files
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item }}.j2"
|
||||||
|
dest: "/etc/firefly/{{ item }}"
|
||||||
|
mode: "0600"
|
||||||
|
loop:
|
||||||
|
- docker-compose.yml
|
||||||
|
- db.env
|
||||||
|
- app.env
|
||||||
|
|
||||||
|
- name: start service
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: /etc/firefly
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
|
|
||||||
|
- name: allow with iptables
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}"
|
||||||
|
destination_ports:
|
||||||
|
- "{{ firefly_port }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: firefly
|
||||||
|
loop: "{{ firefly_allowed_sources }}"
|
||||||
|
notify: save iptables
|
||||||
|
when: firefly_manage_iptables
|
||||||
132
roles/firefly/templates/app.env.j2
Normal file
132
roles/firefly/templates/app.env.j2
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
APP_ENV=local
|
||||||
|
APP_DEBUG=false
|
||||||
|
|
||||||
|
SITE_OWNER={{ firefly_site_owner }}
|
||||||
|
|
||||||
|
APP_KEY={{ firefly_app_key }}
|
||||||
|
|
||||||
|
DEFAULT_LANGUAGE={{ firefly_language }}
|
||||||
|
DEFAULT_LOCALE=equal
|
||||||
|
|
||||||
|
TZ={{ firefly_tz }}
|
||||||
|
|
||||||
|
TRUSTED_PROXIES=*
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
|
||||||
|
APP_LOG_LEVEL=notice
|
||||||
|
|
||||||
|
AUDIT_LOG_LEVEL=emergency
|
||||||
|
AUDIT_LOG_CHANNEL=
|
||||||
|
PAPERTRAIL_HOST=
|
||||||
|
PAPERTRAIL_PORT=
|
||||||
|
|
||||||
|
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||||
|
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
|
||||||
|
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||||
|
# Use "pgsql" for PostgreSQL
|
||||||
|
# Use "mysql" for MySQL and MariaDB.
|
||||||
|
# Use "sqlite" for SQLite.
|
||||||
|
DB_CONNECTION=pgsql
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_DATABASE={{ firefly_db_database }}
|
||||||
|
DB_USERNAME={{ firefly_db_username }}
|
||||||
|
DB_PASSWORD={{ firefly_db_password }}
|
||||||
|
DB_SOCKET=
|
||||||
|
|
||||||
|
PGSQL_SSL_MODE=prefer
|
||||||
|
PGSQL_SCHEMA=public
|
||||||
|
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
|
||||||
|
REDIS_SCHEME=tcp
|
||||||
|
REDIS_PATH=
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PORT=6379
|
||||||
|
REDIS_USERNAME=firefly
|
||||||
|
REDIS_PASSWORD=
|
||||||
|
REDIS_DB="0"
|
||||||
|
REDIS_CACHE_DB="1"
|
||||||
|
|
||||||
|
COOKIE_PATH="/"
|
||||||
|
COOKIE_DOMAIN=
|
||||||
|
COOKIE_SECURE=false
|
||||||
|
COOKIE_SAMESITE=lax
|
||||||
|
|
||||||
|
MAIL_MAILER=log
|
||||||
|
MAIL_HOST=null
|
||||||
|
MAIL_PORT=2525
|
||||||
|
MAIL_FROM=changeme@example.com
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_SENDMAIL_COMMAND=
|
||||||
|
MAILGUN_DOMAIN=
|
||||||
|
MAILGUN_SECRET=
|
||||||
|
MAILGUN_ENDPOINT=api.mailgun.net
|
||||||
|
MANDRILL_SECRET=
|
||||||
|
SPARKPOST_SECRET=
|
||||||
|
SEND_ERROR_MESSAGE=true
|
||||||
|
SEND_REPORT_JOURNALS=true
|
||||||
|
|
||||||
|
ENABLE_EXTERNAL_MAP=false
|
||||||
|
ENABLE_EXTERNAL_RATES=false
|
||||||
|
MAP_DEFAULT_LAT=51.983333
|
||||||
|
MAP_DEFAULT_LONG=5.916667
|
||||||
|
MAP_DEFAULT_ZOOM=6
|
||||||
|
|
||||||
|
VALID_URL_PROTOCOLS=
|
||||||
|
|
||||||
|
AUTHENTICATION_GUARD=web
|
||||||
|
AUTHENTICATION_GUARD_HEADER=REMOTE_USER
|
||||||
|
AUTHENTICATION_GUARD_EMAIL=
|
||||||
|
|
||||||
|
PASSPORT_PRIVATE_KEY=
|
||||||
|
PASSPORT_PUBLIC_KEY=
|
||||||
|
|
||||||
|
CUSTOM_LOGOUT_URL=
|
||||||
|
|
||||||
|
DISABLE_FRAME_HEADER=false
|
||||||
|
DISABLE_CSP_HEADER=false
|
||||||
|
TRACKER_SITE_ID=
|
||||||
|
TRACKER_URL=
|
||||||
|
|
||||||
|
ALLOW_WEBHOOKS=false
|
||||||
|
|
||||||
|
STATIC_CRON_TOKEN={{ firefly_static_cron_token }}
|
||||||
|
|
||||||
|
DKR_BUILD_LOCALE=false
|
||||||
|
DKR_CHECK_SQLITE=true
|
||||||
|
DKR_RUN_MIGRATION=true
|
||||||
|
DKR_RUN_UPGRADE=true
|
||||||
|
DKR_RUN_VERIFY=true
|
||||||
|
DKR_RUN_REPORT=true
|
||||||
|
DKR_RUN_PASSPORT_INSTALL=true
|
||||||
|
|
||||||
|
APP_NAME=FireflyIII
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
QUEUE_DRIVER=sync
|
||||||
|
CACHE_PREFIX=firefly
|
||||||
|
PUSHER_KEY=
|
||||||
|
IPINFO_TOKEN=
|
||||||
|
PUSHER_SECRET=
|
||||||
|
PUSHER_ID=
|
||||||
|
DEMO_USERNAME=
|
||||||
|
DEMO_PASSWORD=
|
||||||
|
FIREFLY_III_LAYOUT=v1
|
||||||
|
|
||||||
|
#
|
||||||
|
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
|
||||||
|
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
|
||||||
|
# This configuration value WILL NOT HELP.
|
||||||
|
#
|
||||||
|
# Notable exception to this rule is Synology, which, according to some users, will use APP_URL to rewrite stuff.
|
||||||
|
#
|
||||||
|
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
|
||||||
|
# So when configuring anything WEB related this variable doesn't do anything. Nothing
|
||||||
|
#
|
||||||
|
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
|
||||||
|
#
|
||||||
|
APP_URL=http://localhost
|
||||||
5
roles/firefly/templates/db.env.j2
Normal file
5
roles/firefly/templates/db.env.j2
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
POSTGRES_USER={{ firefly_db_username }}
|
||||||
|
POSTGRES_PASSWORD={{ firefly_db_password }}
|
||||||
|
POSTGRES_DB={{ firefly_db_database }}
|
||||||
|
POSTGRES_INITDB_ARGS="--data-checksums"
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
40
roles/firefly/templates/docker-compose.yml.j2
Normal file
40
roles/firefly/templates/docker-compose.yml.j2
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: fireflyiii/core:{{ firefly_version }}
|
||||||
|
hostname: app
|
||||||
|
container_name: firefly_iii_core
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- {{ firefly_home }}/app/upload:/var/www/html/storage/upload
|
||||||
|
env_file: /etc/firefly/app.env
|
||||||
|
networks:
|
||||||
|
- firefly_iii
|
||||||
|
ports:
|
||||||
|
- {{ firefly_port }}:8080
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
db:
|
||||||
|
image: postgres:17
|
||||||
|
hostname: db
|
||||||
|
container_name: firefly_iii_db
|
||||||
|
restart: always
|
||||||
|
env_file: /etc/firefly/db.env
|
||||||
|
networks:
|
||||||
|
- firefly_iii
|
||||||
|
volumes:
|
||||||
|
- {{ firefly_home }}/db/data:/var/lib/postgresql/data
|
||||||
|
- {{ firefly_home }}/db/backup:/var/lib/postgresql/backup
|
||||||
|
|
||||||
|
cron:
|
||||||
|
image: alpine
|
||||||
|
restart: always
|
||||||
|
container_name: firefly_iii_cron
|
||||||
|
command: sh -c "echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/{{ firefly_static_cron_token }}\" | crontab - && crond -f -L /dev/stdout"
|
||||||
|
networks:
|
||||||
|
- firefly_iii
|
||||||
|
|
||||||
|
networks:
|
||||||
|
firefly_iii:
|
||||||
|
driver: bridge
|
||||||
239
roles/forgejo/README.md
Normal file
239
roles/forgejo/README.md
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
# Ansible Role Forgejo
|
||||||
|
|
||||||
|
Ansible role to manage a [Forgejo](https://forgejo.org/) instance.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
See [Variable
|
||||||
|
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
|
||||||
|
to find where you should put your own variables.
|
||||||
|
|
||||||
|
Then define at least `forgejo_db_password` with a strong and secure password,
|
||||||
|
encrypted using
|
||||||
|
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
|
||||||
|
|
||||||
|
|
||||||
|
## Table of Content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`forgejo_server`](#variable-forgejo_server)
|
||||||
|
* [`forgejo_version`](#variable-forgejo_version)
|
||||||
|
* [`forgejo_home_dir`](#variable-forgejo_home_dir)
|
||||||
|
* [`forgejo_config_dir`](#variable-forgejo_config_dir)
|
||||||
|
* [`forgejo_web_port`](#variable-forgejo_web_port)
|
||||||
|
* [`forgejo_ssh_port`](#variable-forgejo_ssh_port)
|
||||||
|
* [`forgejo_db_username`](#variable-forgejo_db_username)
|
||||||
|
* [`forgejo_db_password`](#variable-forgejo_db_password)
|
||||||
|
* [`forgejo_db_database`](#variable-forgejo_db_database)
|
||||||
|
* [`forgejo_mailer`](#variable-forgejo_mailer)
|
||||||
|
* [`forgejo_service`](#variable-forgejo_service)
|
||||||
|
* [`forgejo_manage_iptables`](#variable-forgejo_manage_iptables)
|
||||||
|
* [`forgejo_allowed_sources`](#variable-forgejo_allowed_sources)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `forgejo_server` | `bool` | No | `true` | Enable the server mode |
|
||||||
|
| `forgejo_version` | `int` | No | `14` | Version of the Forgejo binaries |
|
||||||
|
| `forgejo_home_dir` | `path` | No | `"/var/lib/forgejo"` | Path to the home directory |
|
||||||
|
| `forgejo_config_dir` | `path` | No | `"/etc/forgejo"` | Path to the configuration directory |
|
||||||
|
| `forgejo_web_port` | `int` | No | `3000` | Port to listen for the web UI |
|
||||||
|
| `forgejo_ssh_port` | `int` | No | `222` | Port to listen for SSH |
|
||||||
|
| `forgejo_db_username` | `str` | No | `"forgejo"` | Name of the user in the database |
|
||||||
|
| `forgejo_db_password` | `str` | Yes | N/A | Password of the user in the database |
|
||||||
|
| `forgejo_db_database` | `str` | No | `"forgejo"` | Name of the database |
|
||||||
|
| `forgejo_mailer` | `dict` | No | N/A | Configure the mailer to send e-mail notifications<br><br>Define a `enabled` key with a boolean to enable the mailer<br><br>Define a `from` key with the source e-mail address<br><br>See [Email setup](https://forgejo.org/docs/latest/admin/setup/email/) |
|
||||||
|
| `forgejo_service` | `dict` | No | N/A | Configure service settings<br><br>See [Service](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#service-service) |
|
||||||
|
| `forgejo_manage_iptables` | `bool` | No | `false` | Configure iptables rules |
|
||||||
|
| `forgejo_allowed_sources` | `list` | No | N/A | List of IP ranges to allow when `forgejo_manage_iptables` is enabled |
|
||||||
|
|
||||||
|
### `forgejo_server`<a id="variable-forgejo_server"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Enable the server mode
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `true`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_version`<a id="variable-forgejo_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Version of the Forgejo binaries
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `14`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_home_dir`<a id="variable-forgejo_home_dir"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the home directory
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/var/lib/forgejo"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_config_dir`<a id="variable-forgejo_config_dir"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the configuration directory
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/etc/forgejo"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_web_port`<a id="variable-forgejo_web_port"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Port to listen for the web UI
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `3000`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_ssh_port`<a id="variable-forgejo_ssh_port"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Port to listen for SSH
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `222`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_db_username`<a id="variable-forgejo_db_username"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Name of the user in the database
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"forgejo"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_db_password`<a id="variable-forgejo_db_password"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Password of the user in the database
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: Yes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_db_database`<a id="variable-forgejo_db_database"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Name of the database
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"forgejo"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_mailer`<a id="variable-forgejo_mailer"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Configure the mailer to send e-mail notifications
|
||||||
|
|
||||||
|
Define a `enabled` key with a boolean to enable the mailer
|
||||||
|
|
||||||
|
Define a `from` key with the source e-mail address
|
||||||
|
|
||||||
|
See [Email setup](https://forgejo.org/docs/latest/admin/setup/email/)
|
||||||
|
|
||||||
|
- **Type**: `dict`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_service`<a id="variable-forgejo_service"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Configure service settings
|
||||||
|
|
||||||
|
See [Service](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#service-service)
|
||||||
|
|
||||||
|
- **Type**: `dict`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_manage_iptables`<a id="variable-forgejo_manage_iptables"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Configure iptables rules
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `false`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_allowed_sources`<a id="variable-forgejo_allowed_sources"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
List of IP ranges to allow when `forgejo_manage_iptables` is enabled
|
||||||
|
|
||||||
|
- **Type**: `list`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Example of a basic forgejo.yml playbook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- hosts: forgejo
|
||||||
|
roles:
|
||||||
|
- forgejo
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the playbook:
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook forgejo.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
As we all love FOSS projects, you should consider [donating to
|
||||||
|
Codeberg](https://donate.codeberg.org/), the non-profit organization behind
|
||||||
|
Forgejo.
|
||||||
90
roles/forgejo/defaults/main.yml
Normal file
90
roles/forgejo/defaults/main.yml
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Enable the server mode
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: true
|
||||||
|
forgejo_server: true
|
||||||
|
|
||||||
|
# Version of the Forgejo binaries
|
||||||
|
#
|
||||||
|
# - Type: int
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 14
|
||||||
|
forgejo_version: 14
|
||||||
|
|
||||||
|
# Path to the home directory
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /var/lib/forgejo
|
||||||
|
forgejo_home_dir: /var/lib/forgejo
|
||||||
|
|
||||||
|
# Path to the configuration directory
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /etc/forgejo
|
||||||
|
forgejo_config_dir: /etc/forgejo
|
||||||
|
|
||||||
|
# Port to listen for the web UI
|
||||||
|
#
|
||||||
|
# - Type: int
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 3000
|
||||||
|
forgejo_web_port: 3000
|
||||||
|
|
||||||
|
# Port to listen for SSH
|
||||||
|
#
|
||||||
|
# - Type: int
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 222
|
||||||
|
forgejo_ssh_port: 222
|
||||||
|
|
||||||
|
# Name of the user in the database
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: forgejo
|
||||||
|
forgejo_db_username: forgejo
|
||||||
|
|
||||||
|
# Name of the database
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: forgejo
|
||||||
|
forgejo_db_database: forgejo
|
||||||
|
|
||||||
|
# Configure the mailer to send e-mail notifications
|
||||||
|
#
|
||||||
|
# Define a `enabled` key with a boolean to enable the mailer
|
||||||
|
#
|
||||||
|
# Define a `from` key with the source e-mail address
|
||||||
|
#
|
||||||
|
# See
|
||||||
|
#
|
||||||
|
# - Type: dict
|
||||||
|
# - Required: No
|
||||||
|
forgejo_mailer: {}
|
||||||
|
|
||||||
|
# Configure service settings
|
||||||
|
#
|
||||||
|
# See
|
||||||
|
#
|
||||||
|
# - Type: dict
|
||||||
|
# - Required: No
|
||||||
|
forgejo_service: {}
|
||||||
|
|
||||||
|
# Configure iptables rules
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: false
|
||||||
|
forgejo_manage_iptables: false
|
||||||
|
|
||||||
|
# List of IP ranges to allow when `forgejo_manage_iptables` is enabled
|
||||||
|
#
|
||||||
|
# - Type: list
|
||||||
|
# - Required: No
|
||||||
|
forgejo_allowed_sources: []
|
||||||
4
roles/forgejo/handlers/main.yml
Normal file
4
roles/forgejo/handlers/main.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
- name: Save iptables
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: netfilter-persistent save
|
||||||
84
roles/forgejo/meta/argument_specs.yml
Normal file
84
roles/forgejo/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install and configure a Forgejo instance
|
||||||
|
description:
|
||||||
|
- Install and configure a [Forgejo](https://forgejo.org/) instance.
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
forgejo_server:
|
||||||
|
description:
|
||||||
|
- Enable the server mode
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
|
||||||
|
forgejo_version:
|
||||||
|
description:
|
||||||
|
- Version of the Forgejo binaries
|
||||||
|
type: int
|
||||||
|
default: 14
|
||||||
|
|
||||||
|
forgejo_home_dir:
|
||||||
|
description:
|
||||||
|
- Path to the home directory
|
||||||
|
type: path
|
||||||
|
default: /var/lib/forgejo
|
||||||
|
|
||||||
|
forgejo_config_dir:
|
||||||
|
description:
|
||||||
|
- Path to the configuration directory
|
||||||
|
type: path
|
||||||
|
default: /etc/forgejo
|
||||||
|
|
||||||
|
forgejo_web_port:
|
||||||
|
description:
|
||||||
|
- Port to listen for the web UI
|
||||||
|
type: int
|
||||||
|
default: 3000
|
||||||
|
|
||||||
|
forgejo_ssh_port:
|
||||||
|
description:
|
||||||
|
- Port to listen for SSH
|
||||||
|
type: int
|
||||||
|
default: 222
|
||||||
|
|
||||||
|
forgejo_db_username:
|
||||||
|
description:
|
||||||
|
- Name of the user in the database
|
||||||
|
default: forgejo
|
||||||
|
|
||||||
|
forgejo_db_password:
|
||||||
|
description:
|
||||||
|
- Password of the user in the database
|
||||||
|
required: true
|
||||||
|
|
||||||
|
forgejo_db_database:
|
||||||
|
description:
|
||||||
|
- Name of the database
|
||||||
|
default: forgejo
|
||||||
|
|
||||||
|
forgejo_mailer:
|
||||||
|
description:
|
||||||
|
- Configure the mailer to send e-mail notifications
|
||||||
|
- Define a `enabled` key with a boolean to enable the mailer
|
||||||
|
- Define a `from` key with the source e-mail address
|
||||||
|
- See [Email setup](https://forgejo.org/docs/latest/admin/setup/email/)
|
||||||
|
type: dict
|
||||||
|
|
||||||
|
forgejo_service:
|
||||||
|
description:
|
||||||
|
- Configure service settings
|
||||||
|
- See [Service](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#service-service)
|
||||||
|
type: dict
|
||||||
|
|
||||||
|
forgejo_manage_iptables:
|
||||||
|
description:
|
||||||
|
- Configure iptables rules
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
|
||||||
|
forgejo_allowed_sources:
|
||||||
|
description:
|
||||||
|
- List of IP ranges to allow when `forgejo_manage_iptables` is enabled
|
||||||
|
type: list
|
||||||
3
roles/forgejo/meta/main.yml
Normal file
3
roles/forgejo/meta/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- role: geerlingguy.docker
|
||||||
64
roles/forgejo/tasks/main.yml
Normal file
64
roles/forgejo/tasks/main.yml
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
- name: Check database password
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that: forgejo_db_password is defined
|
||||||
|
|
||||||
|
- name: Add forgejo user
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: forgejo
|
||||||
|
system: yes
|
||||||
|
password: '!'
|
||||||
|
home: "{{ forgejo_home_dir }}"
|
||||||
|
create_home: false
|
||||||
|
|
||||||
|
- name: Read forgejo attributes
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: forgejo
|
||||||
|
|
||||||
|
- name: Create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ item }}"
|
||||||
|
owner: forgejo
|
||||||
|
group: forgejo
|
||||||
|
mode: "0755"
|
||||||
|
loop: &forgejo_directories
|
||||||
|
- "{{ forgejo_config_dir }}"
|
||||||
|
- "{{ forgejo_home_dir }}"
|
||||||
|
- "{{ forgejo_home_dir }}/server"
|
||||||
|
- "{{ forgejo_home_dir }}/db"
|
||||||
|
|
||||||
|
- name: Ensure permissions on those directories
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "chown -R forgejo:forgejo {{ item }}"
|
||||||
|
loop: *forgejo_directories
|
||||||
|
|
||||||
|
- name: Create docker-compose configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.name }}.j2"
|
||||||
|
dest: "{{ forgejo_config_dir }}/{{ item.name }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
loop:
|
||||||
|
- name: docker-compose.yml
|
||||||
|
mode: "0644"
|
||||||
|
- name: server.env
|
||||||
|
mode: "0600"
|
||||||
|
- name: db.env
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: Start service
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ forgejo_config_dir }}"
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
|
|
||||||
|
- name: Allow with iptables
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}"
|
||||||
|
destination_ports:
|
||||||
|
- "{{ forgejo_web_port }}"
|
||||||
6
roles/forgejo/templates/db.env.j2
Normal file
6
roles/forgejo/templates/db.env.j2
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
POSTGRES_USER="{{ forgejo_db_username }}"
|
||||||
|
POSTGRES_PASSWORD="{{ forgejo_db_password }}"
|
||||||
|
POSTGRES_DB="{{ forgejo_db_database }}"
|
||||||
|
POSTGRES_INITDB_ARGS="--data-checksums"
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
35
roles/forgejo/templates/docker-compose.yml.j2
Normal file
35
roles/forgejo/templates/docker-compose.yml.j2
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
image: codeberg.org/forgejo/forgejo:{{ forgejo_version }}
|
||||||
|
container_name: forgejo-server
|
||||||
|
env_file: {{ forgejo_config_dir }}/server.env
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- forgejo
|
||||||
|
volumes:
|
||||||
|
- "{{ forgejo_home_dir }}/server:/data"
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "{{ forgejo_web_port }}:3000"
|
||||||
|
- "{{ forgejo_ssh_port }}:22"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:17
|
||||||
|
hostname: db
|
||||||
|
container_name: forgejo-db
|
||||||
|
restart: always
|
||||||
|
env_file: {{ forgejo_config_dir }}/db.env
|
||||||
|
user: "{{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}"
|
||||||
|
networks:
|
||||||
|
- forgejo
|
||||||
|
volumes:
|
||||||
|
- "{{ forgejo_home_dir }}/db:/var/lib/postgresql/data"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
forgejo:
|
||||||
|
external: false
|
||||||
19
roles/forgejo/templates/server.env.j2
Normal file
19
roles/forgejo/templates/server.env.j2
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
USER_UID={{ ansible_facts.getent_passwd.forgejo[1] }}
|
||||||
|
USER_GID={{ ansible_facts.getent_passwd.forgejo[2] }}
|
||||||
|
FORGEJO__server__SSH_PORT={{ forgejo_ssh_port }}
|
||||||
|
FORGEJO__database__DB_TYPE=postgres
|
||||||
|
FORGEJO__database__HOST=db:5432
|
||||||
|
FORGEJO__database__NAME="{{ forgejo_db_database }}"
|
||||||
|
FORGEJO__database__USER="{{ forgejo_db_username }}"
|
||||||
|
FORGEJO__database__PASSWD="{{ forgejo_db_password }}"
|
||||||
|
{% if forgejo_mailer %}
|
||||||
|
{% for k, v in forgejo_mailer.items() %}
|
||||||
|
FORGEJO__mailer__{{ k | upper }}="{{ v }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if forgejo_service %}
|
||||||
|
{% for k, v in forgejo_service.items() %}
|
||||||
|
FORGEJO__service__{{ k | upper }}="{{ v }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
118
roles/forgejo_runners/README.md
Normal file
118
roles/forgejo_runners/README.md
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
# Ansible Role Forgejo Runners
|
||||||
|
|
||||||
|
Ansible role to manage [Forgejo](https://forgejo.org/) runners.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
See [Variable
|
||||||
|
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
|
||||||
|
to find where you should put your own variables.
|
||||||
|
|
||||||
|
Then define at least `forgejo_db_password` with a strong and secure password,
|
||||||
|
encrypted using
|
||||||
|
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
|
||||||
|
|
||||||
|
|
||||||
|
## Table of Content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`forgejo_runners_version`](#variable-forgejo_runners_version)
|
||||||
|
* [`forgejo_runners_config_dir`](#variable-forgejo_runners_config_dir)
|
||||||
|
* [`forgejo_runners_instance`](#variable-forgejo_runners_instance)
|
||||||
|
* [`forgejo_runners_settings`](#variable-forgejo_runners_settings)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `forgejo_runners_version` | `str` | No | `"9.1.1"` | Version of the runners |
|
||||||
|
| `forgejo_runners_config_dir` | `path` | No | `"/etc/forgejo-runners"` | Path to the configuration directory of the runners |
|
||||||
|
| `forgejo_runners_instance` | `str` | No | N/A | URL of the Forgejo instance to register the runners |
|
||||||
|
| `forgejo_runners_settings` | `dict` | No | N/A | Dict of runners to configure<br><br>The key is the name of the repository on the instance<br><br>The value is a dict with a `token` key and optionally a dict of `labels` |
|
||||||
|
|
||||||
|
### `forgejo_runners_version`<a id="variable-forgejo_runners_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Version of the runners
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"9.1.1"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_runners_config_dir`<a id="variable-forgejo_runners_config_dir"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the configuration directory of the runners
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/etc/forgejo-runners"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_runners_instance`<a id="variable-forgejo_runners_instance"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
URL of the Forgejo instance to register the runners
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `forgejo_runners_settings`<a id="variable-forgejo_runners_settings"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Dict of runners to configure
|
||||||
|
|
||||||
|
The key is the name of the repository on the instance
|
||||||
|
|
||||||
|
The value is a dict with a `token` key and optionally a dict of `labels`
|
||||||
|
|
||||||
|
- **Type**: `dict`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Example of a basic playbook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- hosts: forgejo_runners
|
||||||
|
roles:
|
||||||
|
- forgejo_runners
|
||||||
|
vars:
|
||||||
|
forgejo_runners_instance: https://codeberg.org # FIXME
|
||||||
|
forgejo_runners:
|
||||||
|
my_runner:
|
||||||
|
token: **redacted**
|
||||||
|
labels:
|
||||||
|
node-latest: docker://data.forgejo.org/oci/node:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the playbook:
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook forgejo_runners.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
As we all love FOSS projects, you should consider [donating to
|
||||||
|
Codeberg](https://donate.codeberg.org/), the non-profit organization behind
|
||||||
|
Forgejo.
|
||||||
1
roles/forgejo_runners/TODO.txt
Normal file
1
roles/forgejo_runners/TODO.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Focus on runners only
|
||||||
25
roles/forgejo_runners/defaults/main.yml
Normal file
25
roles/forgejo_runners/defaults/main.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Version of the runners
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 9.1.1
|
||||||
|
forgejo_runners_version: 9.1.1
|
||||||
|
|
||||||
|
# Path to the configuration directory of the runners
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /etc/forgejo-runners
|
||||||
|
forgejo_runners_config_dir: /etc/forgejo-runners
|
||||||
|
|
||||||
|
# Dict of runners to configure
|
||||||
|
#
|
||||||
|
# The key is the name of the repository on the instance
|
||||||
|
#
|
||||||
|
# The value is a dict with a `token` key and optionally a dict of `labels`
|
||||||
|
#
|
||||||
|
# - Type: dict
|
||||||
|
# - Required: No
|
||||||
|
forgejo_runners_settings: {}
|
||||||
17
roles/forgejo_runners/handlers/main.yml
Normal file
17
roles/forgejo_runners/handlers/main.yml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
- name: save iptables
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: netfilter-persistent save
|
||||||
|
|
||||||
|
- name: start runners
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ forgejo_runners_config_dir }}"
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
|
|
||||||
|
- name: restart runners
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ forgejo_runners_config_dir }}"
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
|
state: restarted
|
||||||
30
roles/forgejo_runners/meta/argument_specs.yml
Normal file
30
roles/forgejo_runners/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install and configure Forgejo runners
|
||||||
|
description:
|
||||||
|
- Install and configure [Forgejo](https://forgejo.org/) runners.
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
forgejo_runners_version:
|
||||||
|
description:
|
||||||
|
- Version of the runners
|
||||||
|
default: 9.1.1
|
||||||
|
|
||||||
|
forgejo_runners_config_dir:
|
||||||
|
description:
|
||||||
|
- Path to the configuration directory of the runners
|
||||||
|
type: path
|
||||||
|
default: /etc/forgejo-runners
|
||||||
|
|
||||||
|
forgejo_runners_instance:
|
||||||
|
description:
|
||||||
|
- URL of the Forgejo instance to register the runners
|
||||||
|
|
||||||
|
forgejo_runners_settings:
|
||||||
|
description:
|
||||||
|
- Dict of runners to configure
|
||||||
|
- The key is the name of the repository on the instance
|
||||||
|
- The value is a dict with a `token` key and optionally a dict of `labels`
|
||||||
|
type: dict
|
||||||
3
roles/forgejo_runners/meta/main.yml
Normal file
3
roles/forgejo_runners/meta/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- role: geerlingguy.docker
|
||||||
20
roles/forgejo_runners/tasks/deploy-runners.yml
Normal file
20
roles/forgejo_runners/tasks/deploy-runners.yml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
- name: register runners
|
||||||
|
ansible.builtin.include_tasks: register-runner.yml
|
||||||
|
loop: "{{ forgejo_runners | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.key }}"
|
||||||
|
|
||||||
|
- name: create runners configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "runners/docker-compose.yml.j2"
|
||||||
|
dest: "{{ forgejo_runners_config_dir }}/docker-compose.yml"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: start runners service
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ forgejo_runners_config_dir }}"
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
61
roles/forgejo_runners/tasks/deploy-server.yml
Normal file
61
roles/forgejo_runners/tasks/deploy-server.yml
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
- name: check database password
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that: forgejo_db_password is defined
|
||||||
|
|
||||||
|
- name: create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ item }}"
|
||||||
|
owner: forgejo
|
||||||
|
group: forgejo
|
||||||
|
mode: "0755"
|
||||||
|
loop: &forgejo_directories
|
||||||
|
- "{{ forgejo_config_dir }}"
|
||||||
|
- "{{ forgejo_home_dir }}"
|
||||||
|
- "{{ forgejo_home_dir }}/server"
|
||||||
|
- "{{ forgejo_home_dir }}/db"
|
||||||
|
|
||||||
|
- name: ensure permissions on those directories
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "chown -R forgejo:forgejo {{ item }}"
|
||||||
|
loop: *forgejo_directories
|
||||||
|
|
||||||
|
- name: create docker-compose configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.name }}.j2"
|
||||||
|
dest: "{{ forgejo_config_dir }}/{{ item.name }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "{{ item.mode }}"
|
||||||
|
loop:
|
||||||
|
- name: docker-compose.yml
|
||||||
|
mode: "0644"
|
||||||
|
- name: server.env
|
||||||
|
mode: "0600"
|
||||||
|
- name: db.env
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: start service
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ forgejo_config_dir }}"
|
||||||
|
files:
|
||||||
|
- docker-compose.yml
|
||||||
|
|
||||||
|
- name: allow with iptables
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}"
|
||||||
|
destination_ports:
|
||||||
|
- "{{ forgejo_web_port }}"
|
||||||
|
- "{{ forgejo_ssh_port }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: forgejo
|
||||||
|
loop: "{{ forgejo_allowed_sources }}"
|
||||||
|
notify: save iptables
|
||||||
|
when: forgejo_manage_iptables
|
||||||
|
|
||||||
|
- name: deploy runners
|
||||||
|
ansible.builtin.include_tasks: deploy-runners.yml
|
||||||
|
when: forgejo_runners
|
||||||
21
roles/forgejo_runners/tasks/main.yml
Normal file
21
roles/forgejo_runners/tasks/main.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
- name: add forgejo user
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: forgejo
|
||||||
|
system: yes
|
||||||
|
password: '!'
|
||||||
|
home: "{{ forgejo_home_dir }}"
|
||||||
|
create_home: no
|
||||||
|
|
||||||
|
- name: read forgejo attributes
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: forgejo
|
||||||
|
|
||||||
|
- name: deploy server
|
||||||
|
ansible.builtin.include_tasks: deploy-server.yml
|
||||||
|
when: forgejo_server
|
||||||
|
|
||||||
|
- name: deploy runners
|
||||||
|
ansible.builtin.include_tasks: deploy-runners.yml
|
||||||
|
when: forgejo_runners is defined
|
||||||
39
roles/forgejo_runners/tasks/register-runner.yml
Normal file
39
roles/forgejo_runners/tasks/register-runner.yml
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
- name: check variables
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- forgejo_runners_instance is defined
|
||||||
|
- forgejo_runners_version is defined
|
||||||
|
- forgejo_runners_config_dir is defined
|
||||||
|
- "'key' in item"
|
||||||
|
- "'value' in item"
|
||||||
|
|
||||||
|
- name: create runner subdirectory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ forgejo_runners_config_dir }}/{{ item.key }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
owner: forgejo
|
||||||
|
group: forgejo
|
||||||
|
|
||||||
|
- name: register runner
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >-
|
||||||
|
docker run
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
-v {{ forgejo_runners_config_dir }}/{{ item.key }}:/data
|
||||||
|
--rm
|
||||||
|
--user {{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}
|
||||||
|
code.forgejo.org/forgejo/runner:{{ forgejo_runners_version }}
|
||||||
|
forgejo-runner register --no-interactive
|
||||||
|
--token {{ item.value.token }}
|
||||||
|
--name {{ item.key }}
|
||||||
|
--instance {{ forgejo_runners_instance }}
|
||||||
|
creates: "{{ forgejo_runners_config_dir }}/{{ item.key }}/.runner"
|
||||||
|
notify: start runners
|
||||||
|
|
||||||
|
- name: create runner configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: runners/config.yml.j2
|
||||||
|
dest: "{{ forgejo_runners_config_dir }}/{{ item.key }}/config.yml"
|
||||||
|
notify: restart runners
|
||||||
6
roles/forgejo_runners/templates/db.env.j2
Normal file
6
roles/forgejo_runners/templates/db.env.j2
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
POSTGRES_USER="{{ forgejo_db_username }}"
|
||||||
|
POSTGRES_PASSWORD="{{ forgejo_db_password }}"
|
||||||
|
POSTGRES_DB="{{ forgejo_db_database }}"
|
||||||
|
POSTGRES_INITDB_ARGS="--data-checksums"
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
35
roles/forgejo_runners/templates/docker-compose.yml.j2
Normal file
35
roles/forgejo_runners/templates/docker-compose.yml.j2
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
image: codeberg.org/forgejo/forgejo:{{ forgejo_version }}
|
||||||
|
container_name: forgejo-server
|
||||||
|
env_file: {{ forgejo_config_dir }}/server.env
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- forgejo
|
||||||
|
volumes:
|
||||||
|
- "{{ forgejo_home_dir }}/server:/data"
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "{{ forgejo_web_port }}:3000"
|
||||||
|
- "{{ forgejo_ssh_port }}:22"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:17
|
||||||
|
hostname: db
|
||||||
|
container_name: forgejo-db
|
||||||
|
restart: always
|
||||||
|
env_file: {{ forgejo_config_dir }}/db.env
|
||||||
|
user: "{{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}"
|
||||||
|
networks:
|
||||||
|
- forgejo
|
||||||
|
volumes:
|
||||||
|
- "{{ forgejo_home_dir }}/db:/var/lib/postgresql/data"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
forgejo:
|
||||||
|
external: false
|
||||||
44
roles/forgejo_runners/templates/runners/config.yml.j2
Normal file
44
roles/forgejo_runners/templates/runners/config.yml.j2
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
job_level: info
|
||||||
|
|
||||||
|
runner:
|
||||||
|
file: .runner
|
||||||
|
capacity: 1
|
||||||
|
timeout: 3h
|
||||||
|
shutdown_timeout: 3h
|
||||||
|
insecure: false
|
||||||
|
fetch_timeout: 5s
|
||||||
|
fetch_interval: 2s
|
||||||
|
report_interval: 1s
|
||||||
|
{% if item.value.labels | default({}) %}
|
||||||
|
labels:
|
||||||
|
{% for label_name, label_value in item.value.labels.items() %}
|
||||||
|
- "{{ label_name }}:{{ label_value }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
port: 0
|
||||||
|
dir: ""
|
||||||
|
external_server: ""
|
||||||
|
secret: ""
|
||||||
|
host: ""
|
||||||
|
proxy_port: 0
|
||||||
|
actions_cache_url_override: ""
|
||||||
|
|
||||||
|
container:
|
||||||
|
network: ""
|
||||||
|
enable_ipv6: false
|
||||||
|
privileged: false
|
||||||
|
options:
|
||||||
|
workdir_parent:
|
||||||
|
valid_volumes: []
|
||||||
|
docker_host: "-"
|
||||||
|
force_pull: false
|
||||||
|
force_rebuild: false
|
||||||
|
|
||||||
|
host:
|
||||||
|
workdir_parent:
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
services:
|
||||||
|
docker:
|
||||||
|
image: docker:dind
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- certs:/certs
|
||||||
|
|
||||||
|
{% for runner in forgejo_runners %}
|
||||||
|
runner-{{ runner }}:
|
||||||
|
image: code.forgejo.org/forgejo/runner:{{ forgejo_runners_version }}
|
||||||
|
user: {{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: tcp://docker:2376
|
||||||
|
DOCKER_TLS_VERIFY: 1
|
||||||
|
DOCKER_CERT_PATH: /certs/client
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- {{ forgejo_runners_config_dir }}/{{ runner }}:/data
|
||||||
|
- certs:/certs
|
||||||
|
command: 'forgejo-runner --config config.yml daemon'
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
certs:
|
||||||
19
roles/forgejo_runners/templates/server.env.j2
Normal file
19
roles/forgejo_runners/templates/server.env.j2
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
USER_UID={{ ansible_facts.getent_passwd.forgejo[1] }}
|
||||||
|
USER_GID={{ ansible_facts.getent_passwd.forgejo[2] }}
|
||||||
|
FORGEJO__server__SSH_PORT={{ forgejo_ssh_port }}
|
||||||
|
FORGEJO__database__DB_TYPE=postgres
|
||||||
|
FORGEJO__database__HOST=db:5432
|
||||||
|
FORGEJO__database__NAME="{{ forgejo_db_database }}"
|
||||||
|
FORGEJO__database__USER="{{ forgejo_db_username }}"
|
||||||
|
FORGEJO__database__PASSWD="{{ forgejo_db_password }}"
|
||||||
|
{% if forgejo_mailer %}
|
||||||
|
{% for k, v in forgejo_mailer.items() %}
|
||||||
|
FORGEJO__mailer__{{ k | upper }}="{{ v }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if forgejo_service %}
|
||||||
|
{% for k, v in forgejo_service.items() %}
|
||||||
|
FORGEJO__service__{{ k | upper }}="{{ v }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
213
roles/galene/README.md
Normal file
213
roles/galene/README.md
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
# Ansible Role Galene
|
||||||
|
|
||||||
|
Install and configure [Galene](https://galene.org) videoconference server.
|
||||||
|
|
||||||
|
## Table of content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`galene_version`](#variable-galene_version)
|
||||||
|
* [`galene_http_port`](#variable-galene_http_port)
|
||||||
|
* [`galene_turn`](#variable-galene_turn)
|
||||||
|
* [`galene_user`](#variable-galene_user)
|
||||||
|
* [`galene_group`](#variable-galene_group)
|
||||||
|
* [`galene_base_directory`](#variable-galene_base_directory)
|
||||||
|
* [`galene_data_directory`](#variable-galene_data_directory)
|
||||||
|
* [`galene_groups_directory`](#variable-galene_groups_directory)
|
||||||
|
* [`galene_recording_directory`](#variable-galene_recording_directory)
|
||||||
|
* [`galene_static_directory`](#variable-galene_static_directory)
|
||||||
|
* [`galene_domain`](#variable-galene_domain)
|
||||||
|
* [`galene_config`](#variable-galene_config)
|
||||||
|
* [`galene_groups`](#variable-galene_groups)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `galene_version` | `str` | No | `"galene-1.0"` | Reference (branch or tag) of the Galene git repository. |
|
||||||
|
| `galene_http_port` | `int` | No | `443` | Port to listen. |
|
||||||
|
| `galene_turn` | `str` | No | `":1194"` | TURN address. |
|
||||||
|
| `galene_user` | `str` | No | `"galene"` | Operating system user to run the service. |
|
||||||
|
| `galene_group` | `str` | No | `"galene"` | Operating system group to run the service. |
|
||||||
|
| `galene_base_directory` | `path` | No | `"/var/lib/galene"` | Path to the base directory. |
|
||||||
|
| `galene_data_directory` | `path` | No | `"{{ galene_base_directory }}/data"` | Path to the data directory. |
|
||||||
|
| `galene_groups_directory` | `path` | No | `"{{ galene_base_directory }}/groups"` | Path to the groups directory. |
|
||||||
|
| `galene_recording_directory` | `path` | No | `"{{ galene_base_directory }}/recordings"` | Path to the recordings directory. |
|
||||||
|
| `galene_static_directory` | `path` | No | `"{{ galene_base_directory }}/static"` | Path to the static directory. |
|
||||||
|
| `galene_domain` | `str` | No | N/A | Domain name.<br><br>Used to generate TLS certificates. |
|
||||||
|
| `galene_config` | `dict` | No | N/A | Custom settings.<br><br>Key is the name of the setting.<br><br>Value is the value of the setting.<br><br>See [The global configuration file](https://galene.org/galene.html#the-global-configuration-file). |
|
||||||
|
| `galene_groups` | `dict` | No | N/A | Dict of groups.<br><br>Key is the group name.<br><br>Value is the group definition.<br><br>See [Group definitions](https://galene.org/galene.html#group-definitions). |
|
||||||
|
|
||||||
|
### `galene_version`<a id="variable-galene_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Reference (branch or tag) of the Galene git repository.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"galene-1.0"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_http_port`<a id="variable-galene_http_port"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Port to listen.
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `443`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_turn`<a id="variable-galene_turn"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
TURN address.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `":1194"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_user`<a id="variable-galene_user"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Operating system user to run the service.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"galene"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_group`<a id="variable-galene_group"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Operating system group to run the service.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"galene"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_base_directory`<a id="variable-galene_base_directory"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the base directory.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/var/lib/galene"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_data_directory`<a id="variable-galene_data_directory"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the data directory.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"{{ galene_base_directory }}/data"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_groups_directory`<a id="variable-galene_groups_directory"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the groups directory.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"{{ galene_base_directory }}/groups"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_recording_directory`<a id="variable-galene_recording_directory"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the recordings directory.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"{{ galene_base_directory }}/recordings"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_static_directory`<a id="variable-galene_static_directory"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the static directory.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"{{ galene_base_directory }}/static"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_domain`<a id="variable-galene_domain"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Domain name.
|
||||||
|
|
||||||
|
Used to generate TLS certificates.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_config`<a id="variable-galene_config"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Custom settings.
|
||||||
|
|
||||||
|
Key is the name of the setting.
|
||||||
|
|
||||||
|
Value is the value of the setting.
|
||||||
|
|
||||||
|
See [The global configuration file](https://galene.org/galene.html#the-global-configuration-file).
|
||||||
|
|
||||||
|
- **Type**: `dict`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `galene_groups`<a id="variable-galene_groups"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Dict of groups.
|
||||||
|
|
||||||
|
Key is the group name.
|
||||||
|
|
||||||
|
Value is the group definition.
|
||||||
|
|
||||||
|
See [Group definitions](https://galene.org/galene.html#group-definitions).
|
||||||
|
|
||||||
|
- **Type**: `dict`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
95
roles/galene/defaults/main.yml
Normal file
95
roles/galene/defaults/main.yml
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Reference (branch or tag) of the Galene git repository.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: galene-1.0
|
||||||
|
galene_version: galene-1.0
|
||||||
|
|
||||||
|
# Port to listen.
|
||||||
|
#
|
||||||
|
# - Type: int
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 443
|
||||||
|
galene_http_port: 443
|
||||||
|
|
||||||
|
# TURN address.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: :1194
|
||||||
|
galene_turn: ":1194"
|
||||||
|
|
||||||
|
# Operating system user to run the service.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: galene
|
||||||
|
galene_user: galene
|
||||||
|
|
||||||
|
# Operating system group to run the service.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: galene
|
||||||
|
galene_group: galene
|
||||||
|
|
||||||
|
# Path to the base directory.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /var/lib/galene
|
||||||
|
galene_base_directory: /var/lib/galene
|
||||||
|
|
||||||
|
# Path to the data directory.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: {{ galene_base_directory }}/data
|
||||||
|
galene_data_directory: "{{ galene_base_directory }}/data"
|
||||||
|
|
||||||
|
# Path to the groups directory.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: {{ galene_base_directory }}/groups
|
||||||
|
galene_groups_directory: "{{ galene_base_directory }}/groups"
|
||||||
|
|
||||||
|
# Path to the recordings directory.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: {{ galene_base_directory }}/recordings
|
||||||
|
galene_recording_directory: "{{ galene_base_directory }}/recordings"
|
||||||
|
|
||||||
|
# Path to the static directory.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: {{ galene_base_directory }}/static
|
||||||
|
galene_static_directory: "{{ galene_base_directory }}/static"
|
||||||
|
|
||||||
|
# Custom settings.
|
||||||
|
#
|
||||||
|
# Key is the name of the setting.
|
||||||
|
#
|
||||||
|
# Value is the value of the setting.
|
||||||
|
#
|
||||||
|
# See .
|
||||||
|
#
|
||||||
|
# - Type: dict
|
||||||
|
# - Required: No
|
||||||
|
galene_config: {}
|
||||||
|
|
||||||
|
# Dict of groups.
|
||||||
|
#
|
||||||
|
# Key is the group name.
|
||||||
|
#
|
||||||
|
# Value is the group definition.
|
||||||
|
#
|
||||||
|
# See .
|
||||||
|
#
|
||||||
|
# - Type: dict
|
||||||
|
# - Required: No
|
||||||
|
galene_groups: {}
|
||||||
9
roles/galene/handlers/main.yml
Normal file
9
roles/galene/handlers/main.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
- name: Reload systemd
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
daemon_reload: true
|
||||||
|
|
||||||
|
- name: Restart galene
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: galene
|
||||||
|
state: restarted
|
||||||
85
roles/galene/meta/argument_specs.yml
Normal file
85
roles/galene/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install and configure Galene videoconference server
|
||||||
|
description:
|
||||||
|
- Install and configure [Galene](https://galene.org/) videoconference server
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
galene_version:
|
||||||
|
description:
|
||||||
|
- Reference (branch or tag) of the Galene git repository.
|
||||||
|
default: galene-1.0
|
||||||
|
|
||||||
|
galene_http_port:
|
||||||
|
description:
|
||||||
|
- Port to listen.
|
||||||
|
type: int
|
||||||
|
default: 443
|
||||||
|
|
||||||
|
galene_turn:
|
||||||
|
description:
|
||||||
|
- TURN address.
|
||||||
|
default: ":1194"
|
||||||
|
|
||||||
|
galene_user:
|
||||||
|
description:
|
||||||
|
- Operating system user to run the service.
|
||||||
|
default: galene
|
||||||
|
|
||||||
|
galene_group:
|
||||||
|
description:
|
||||||
|
- Operating system group to run the service.
|
||||||
|
default: galene
|
||||||
|
|
||||||
|
galene_base_directory:
|
||||||
|
description:
|
||||||
|
- Path to the base directory.
|
||||||
|
type: path
|
||||||
|
default: /var/lib/galene
|
||||||
|
|
||||||
|
galene_data_directory:
|
||||||
|
description:
|
||||||
|
- Path to the data directory.
|
||||||
|
type: path
|
||||||
|
default: "{{ galene_base_directory }}/data"
|
||||||
|
|
||||||
|
galene_groups_directory:
|
||||||
|
description:
|
||||||
|
- Path to the groups directory.
|
||||||
|
type: path
|
||||||
|
default: "{{ galene_base_directory }}/groups"
|
||||||
|
|
||||||
|
galene_recording_directory:
|
||||||
|
description:
|
||||||
|
- Path to the recordings directory.
|
||||||
|
type: path
|
||||||
|
default: "{{ galene_base_directory }}/recordings"
|
||||||
|
|
||||||
|
galene_static_directory:
|
||||||
|
description:
|
||||||
|
- Path to the static directory.
|
||||||
|
type: path
|
||||||
|
default: "{{ galene_base_directory }}/static"
|
||||||
|
|
||||||
|
galene_domain:
|
||||||
|
description:
|
||||||
|
- Domain name.
|
||||||
|
- Used to generate TLS certificates.
|
||||||
|
|
||||||
|
galene_config:
|
||||||
|
description:
|
||||||
|
- Custom settings.
|
||||||
|
- Key is the name of the setting.
|
||||||
|
- Value is the value of the setting.
|
||||||
|
- See [The global configuration file](https://galene.org/galene.html#the-global-configuration-file).
|
||||||
|
type: dict
|
||||||
|
|
||||||
|
galene_groups:
|
||||||
|
description:
|
||||||
|
- Dict of groups.
|
||||||
|
- Key is the group name.
|
||||||
|
- Value is the group definition.
|
||||||
|
- See [Group definitions](https://galene.org/galene.html#group-definitions).
|
||||||
|
type: dict
|
||||||
3
roles/galene/meta/main.yml
Normal file
3
roles/galene/meta/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- role: golang
|
||||||
5
roles/galene/molecule/default/converge.yml
Normal file
5
roles/galene/molecule/default/converge.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: Converge
|
||||||
|
hosts: molecule
|
||||||
|
roles:
|
||||||
|
- galene
|
||||||
18
roles/galene/molecule/default/create.yml
Normal file
18
roles/galene/molecule/default/create.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
- name: Create containers
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Create containers
|
||||||
|
containers.podman.podman_container:
|
||||||
|
hostname: "{{ item }}"
|
||||||
|
name: "{{ item }}"
|
||||||
|
image: "{{ hostvars[item]['container_image'] }}"
|
||||||
|
state: started
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
|
|
||||||
|
- name: Wait for containers to be ready
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
delegate_to: "{{ item }}"
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
11
roles/galene/molecule/default/destroy.yml
Normal file
11
roles/galene/molecule/default/destroy.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: Destroy container instances
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Remove containers
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
|
failed_when: false
|
||||||
12
roles/galene/molecule/default/inventory/hosts.yml
Normal file
12
roles/galene/molecule/default/inventory/hosts.yml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
molecule:
|
||||||
|
hosts:
|
||||||
|
debian11:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian11-ansible:latest
|
||||||
|
debian12:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian12-ansible:latest
|
||||||
|
debian13:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian13-ansible:latest
|
||||||
26
roles/galene/molecule/default/molecule.yml
Normal file
26
roles/galene/molecule/default/molecule.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
ansible:
|
||||||
|
executor:
|
||||||
|
args:
|
||||||
|
ansible_playbook:
|
||||||
|
- --inventory=inventory/
|
||||||
|
env:
|
||||||
|
ANSIBLE_ROLES_PATH: ../../../../roles
|
||||||
|
playbooks:
|
||||||
|
create: create.yml
|
||||||
|
converge: converge.yml
|
||||||
|
verify: verify.yml
|
||||||
|
destroy: destroy.yml
|
||||||
|
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
options:
|
||||||
|
requirements-file: ${MOLECULE_SCENARIO_DIRECTORY}/requirements.yml
|
||||||
|
|
||||||
|
scenario:
|
||||||
|
test_sequence:
|
||||||
|
- create
|
||||||
|
- converge
|
||||||
|
- idempotence
|
||||||
|
- verify
|
||||||
|
- destroy
|
||||||
3
roles/galene/molecule/default/requirements.yml
Normal file
3
roles/galene/molecule/default/requirements.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: containers.podman
|
||||||
8
roles/galene/molecule/default/verify.yml
Normal file
8
roles/galene/molecule/default/verify.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
- name: Verify
|
||||||
|
hosts: molecule
|
||||||
|
tasks:
|
||||||
|
- name: Check service
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: https://localhost:443
|
||||||
|
validate_certs: false
|
||||||
117
roles/galene/tasks/main.yml
Normal file
117
roles/galene/tasks/main.yml
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
---
|
||||||
|
# TODO: install in block
|
||||||
|
- name: Install requirements
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: git
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Clone source code
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://github.com/jech/galene
|
||||||
|
dest: /opt/galene
|
||||||
|
version: "{{ galene_version }}"
|
||||||
|
|
||||||
|
- name: Compile
|
||||||
|
ansible.builtin.command:
|
||||||
|
chdir: /opt/galene
|
||||||
|
cmd: go build -ldflags='-s -w'
|
||||||
|
creates: /opt/galene/galene
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: "0"
|
||||||
|
PATH: /usr/local/go/bin
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: /opt/galene/galene
|
||||||
|
dest: /usr/local/bin/galene
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
# TODO End of install in block
|
||||||
|
|
||||||
|
- name: Create user
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ galene_user }}"
|
||||||
|
system: true
|
||||||
|
password: '!'
|
||||||
|
home: "{{ galene_base_directory }}"
|
||||||
|
create_home: false
|
||||||
|
|
||||||
|
- name: Create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ galene_user }}"
|
||||||
|
group: "{{ galene_group }}"
|
||||||
|
mode: "0755"
|
||||||
|
loop:
|
||||||
|
- "{{ galene_base_directory }}"
|
||||||
|
- "{{ galene_data_directory }}"
|
||||||
|
- "{{ galene_groups_directory }}"
|
||||||
|
- "{{ galene_recording_directory }}"
|
||||||
|
- "{{ galene_static_directory }}"
|
||||||
|
|
||||||
|
- name: Copy static directory
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /opt/galene/static/
|
||||||
|
dest: "{{ galene_static_directory }}/"
|
||||||
|
remote_src: true
|
||||||
|
mode: "0755"
|
||||||
|
owner: "{{ galene_user }}"
|
||||||
|
group: "{{ galene_group }}"
|
||||||
|
when: galene_static_directory != "/opt/galene/static"
|
||||||
|
|
||||||
|
- name: Configure groups
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ item.value | to_json }}"
|
||||||
|
dest: "{{ galene_groups_directory }}/{{ item.key }}.json"
|
||||||
|
owner: "{{ galene_user }}"
|
||||||
|
group: "{{ galene_group }}"
|
||||||
|
mode: "0600"
|
||||||
|
loop: "{{ galene_groups | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.key }}"
|
||||||
|
notify: Restart galene
|
||||||
|
|
||||||
|
- name: Create global configuration
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ galene_config | to_json }}"
|
||||||
|
dest: "{{ galene_data_directory }}/config.json"
|
||||||
|
owner: "{{ galene_user }}"
|
||||||
|
group: "{{ galene_group }}"
|
||||||
|
mode: "0600"
|
||||||
|
notify: Restart galene
|
||||||
|
|
||||||
|
- name: Configure TLS certificates
|
||||||
|
when: galene_domain is defined
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
owner: "{{ galene_user }}"
|
||||||
|
group: "{{ galene_group }}"
|
||||||
|
loop:
|
||||||
|
- src: "/etc/letsencrypt/live/{{ galene_domain }}/fullchain.pem"
|
||||||
|
dest: "{{ galene_data_directory }}/cert.pem"
|
||||||
|
mode: "0644"
|
||||||
|
- src: "/etc/letsencrypt/live/{{ galene_domain }}/privkey.pem"
|
||||||
|
dest: "{{ galene_data_directory }}/key.pem"
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: Create service
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: galene.service.j2
|
||||||
|
dest: /etc/systemd/system/galene.service
|
||||||
|
mode: "0644"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
notify:
|
||||||
|
- Reload systemd
|
||||||
|
- Restart galene
|
||||||
|
|
||||||
|
- name: Start service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: galene
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
19
roles/galene/templates/galene.service.j2
Normal file
19
roles/galene/templates/galene.service.j2
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Galene
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory={{ galene_base_directory }}
|
||||||
|
User={{ galene_user }}
|
||||||
|
Group={{ galene_group }}
|
||||||
|
{% if galene_http_port < 1024 %}
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
{% endif %}
|
||||||
|
ExecStart=/usr/local/bin/galene -http :{{ galene_http_port }} -data {{ galene_data_directory }} -groups {{ galene_groups_directory }} -recordings {{ galene_recording_directory }} -static {{ galene_static_directory }} -turn "{{ galene_turn }}"
|
||||||
|
LimitNOFILE=65536
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
34
roles/golang/README.md
Normal file
34
roles/golang/README.md
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Ansible Role Go
|
||||||
|
|
||||||
|
Install [Go](https://go.dev/).
|
||||||
|
|
||||||
|
## Table of content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`golang_version`](#variable-golang_version)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `golang_version` | `str` | No | `"1.25.4"` | Version to install. |
|
||||||
|
|
||||||
|
### `golang_version`<a id="variable-golang_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Version to install.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"1.25.4"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
8
roles/golang/defaults/main.yml
Normal file
8
roles/golang/defaults/main.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Version to install.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 1.25.4
|
||||||
|
golang_version: 1.25.4
|
||||||
13
roles/golang/meta/argument_specs.yml
Normal file
13
roles/golang/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install Go
|
||||||
|
description:
|
||||||
|
- Install [Go](https://go.dev/).
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
golang_version:
|
||||||
|
description:
|
||||||
|
- Version to install.
|
||||||
|
default: 1.25.4
|
||||||
7
roles/golang/molecule/default/converge.yml
Normal file
7
roles/golang/molecule/default/converge.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
- name: Converge
|
||||||
|
hosts: molecule
|
||||||
|
roles:
|
||||||
|
- golang
|
||||||
|
vars:
|
||||||
|
golang_version: 1.25.4
|
||||||
18
roles/golang/molecule/default/create.yml
Normal file
18
roles/golang/molecule/default/create.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
- name: Create containers
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Create containers
|
||||||
|
containers.podman.podman_container:
|
||||||
|
hostname: "{{ item }}"
|
||||||
|
name: "{{ item }}"
|
||||||
|
image: "{{ hostvars[item]['container_image'] }}"
|
||||||
|
state: started
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
|
|
||||||
|
- name: Wait for containers to be ready
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
delegate_to: "{{ item }}"
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
11
roles/golang/molecule/default/destroy.yml
Normal file
11
roles/golang/molecule/default/destroy.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: Destroy container instances
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Remove containers
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ groups['molecule'] }}"
|
||||||
|
failed_when: false
|
||||||
12
roles/golang/molecule/default/inventory/hosts.yml
Normal file
12
roles/golang/molecule/default/inventory/hosts.yml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
molecule:
|
||||||
|
hosts:
|
||||||
|
debian11:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian11-ansible:latest
|
||||||
|
debian12:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian12-ansible:latest
|
||||||
|
debian13:
|
||||||
|
ansible_connection: containers.podman.podman
|
||||||
|
container_image: docker.io/geerlingguy/docker-debian13-ansible:latest
|
||||||
26
roles/golang/molecule/default/molecule.yml
Normal file
26
roles/golang/molecule/default/molecule.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
ansible:
|
||||||
|
executor:
|
||||||
|
args:
|
||||||
|
ansible_playbook:
|
||||||
|
- --inventory=inventory/
|
||||||
|
env:
|
||||||
|
ANSIBLE_ROLES_PATH: ../../../../roles
|
||||||
|
playbooks:
|
||||||
|
create: create.yml
|
||||||
|
converge: converge.yml
|
||||||
|
verify: verify.yml
|
||||||
|
destroy: destroy.yml
|
||||||
|
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
options:
|
||||||
|
requirements-file: ${MOLECULE_SCENARIO_DIRECTORY}/requirements.yml
|
||||||
|
|
||||||
|
scenario:
|
||||||
|
test_sequence:
|
||||||
|
- create
|
||||||
|
- converge
|
||||||
|
- idempotence
|
||||||
|
- verify
|
||||||
|
- destroy
|
||||||
3
roles/golang/molecule/default/requirements.yml
Normal file
3
roles/golang/molecule/default/requirements.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: containers.podman
|
||||||
15
roles/golang/molecule/default/verify.yml
Normal file
15
roles/golang/molecule/default/verify.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
- name: Verify
|
||||||
|
hosts: molecule
|
||||||
|
vars:
|
||||||
|
golang_version: 1.25.4
|
||||||
|
tasks:
|
||||||
|
- name: Get version
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: /usr/local/go/bin/go version
|
||||||
|
register: golang_version_cmd
|
||||||
|
|
||||||
|
- name: Compare versions
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- golang_version_cmd.stdout | regex_search('^go version go' + golang_version + ' linux/amd64') != ""
|
||||||
7
roles/golang/tasks/main.yml
Normal file
7
roles/golang/tasks/main.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
- name: Install
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: "https://go.dev/dl/go{{ golang_version }}.linux-amd64.tar.gz"
|
||||||
|
dest: /usr/local
|
||||||
|
remote_src: true
|
||||||
|
creates: /usr/local/go
|
||||||
1
roles/navidrome/.gitignore
vendored
Normal file
1
roles/navidrome/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
venv
|
||||||
205
roles/navidrome/README.md
Normal file
205
roles/navidrome/README.md
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
# Ansible Role Navidrome
|
||||||
|
|
||||||
|
Ansible role to manage a [Navidrome](https://github.com/navidrome/navidrome) instance.
|
||||||
|
|
||||||
|
## Table of Content
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC START -->
|
||||||
|
* [Role variables](#variables)
|
||||||
|
* [`navidrome_version`](#variable-navidrome_version)
|
||||||
|
* [`navidrome_arch`](#variable-navidrome_arch)
|
||||||
|
* [`navidrome_user`](#variable-navidrome_user)
|
||||||
|
* [`navidrome_group`](#variable-navidrome_group)
|
||||||
|
* [`navidrome_music_folder`](#variable-navidrome_music_folder)
|
||||||
|
* [`navidrome_data_folder`](#variable-navidrome_data_folder)
|
||||||
|
* [`navidrome_cache_folder`](#variable-navidrome_cache_folder)
|
||||||
|
* [`navidrome_manage_iptables`](#variable-navidrome_manage_iptables)
|
||||||
|
* [`navidrome_allowed_sources`](#variable-navidrome_allowed_sources)
|
||||||
|
* [`navidrome_address`](#variable-navidrome_address)
|
||||||
|
* [`navidrome_port`](#variable-navidrome_port)
|
||||||
|
* [`navidrome_enable_insights_collector`](#variable-navidrome_enable_insights_collector)
|
||||||
|
* [`navidrome_base_url`](#variable-navidrome_base_url)
|
||||||
|
<!-- ANSIBLE DOCSMITH TOC END -->
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN START -->
|
||||||
|
|
||||||
|
## Role variables<a id="variables"></a>
|
||||||
|
|
||||||
|
The following variables can be configured for this role:
|
||||||
|
|
||||||
|
| Variable | Type | Required | Default | Description (abstract) |
|
||||||
|
|----------|------|----------|---------|------------------------|
|
||||||
|
| `navidrome_version` | `str` | No | `"0.54.5"` | Version of the debian package. |
|
||||||
|
| `navidrome_arch` | `str` | No | `"amd64"` | Architecture of the debian package. |
|
||||||
|
| `navidrome_user` | `str` | No | `"navidrome"` | Operating system user to run the service. |
|
||||||
|
| `navidrome_group` | `str` | No | `"navidrome"` | Operating system group to run the service. |
|
||||||
|
| `navidrome_music_folder` | `path` | No | `"/opt/navidrome/music"` | Path to the music folder. |
|
||||||
|
| `navidrome_data_folder` | `path` | No | `"/var/lib/navidrome"` | Path to the data directory. |
|
||||||
|
| `navidrome_cache_folder` | `path` | No | `"{{ navidrome_data_folder }}/cache"` | Path to the cache folder. |
|
||||||
|
| `navidrome_manage_iptables` | `bool` | No | `false` | Configure iptables rules |
|
||||||
|
| `navidrome_allowed_sources` | `list` | No | N/A | List of IP ranges to allow when `navidrome_manage_iptables` is enabled |
|
||||||
|
| `navidrome_address` | `str` | No | `"localhost"` | Address to listen. |
|
||||||
|
| `navidrome_port` | `int` | No | `4533` | Port to listen |
|
||||||
|
| `navidrome_enable_insights_collector` | `bool` | No | `false` | Enable the insights collector. |
|
||||||
|
| `navidrome_base_url` | `str` | No | N/A | Base URL of the web interface. |
|
||||||
|
|
||||||
|
### `navidrome_version`<a id="variable-navidrome_version"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Version of the debian package.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"0.54.5"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_arch`<a id="variable-navidrome_arch"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Architecture of the debian package.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"amd64"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_user`<a id="variable-navidrome_user"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Operating system user to run the service.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"navidrome"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_group`<a id="variable-navidrome_group"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Operating system group to run the service.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"navidrome"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_music_folder`<a id="variable-navidrome_music_folder"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the music folder.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/opt/navidrome/music"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_data_folder`<a id="variable-navidrome_data_folder"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the data directory.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"/var/lib/navidrome"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_cache_folder`<a id="variable-navidrome_cache_folder"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Path to the cache folder.
|
||||||
|
|
||||||
|
- **Type**: `path`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"{{ navidrome_data_folder }}/cache"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_manage_iptables`<a id="variable-navidrome_manage_iptables"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Configure iptables rules
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `false`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_allowed_sources`<a id="variable-navidrome_allowed_sources"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
List of IP ranges to allow when `navidrome_manage_iptables` is enabled
|
||||||
|
|
||||||
|
- **Type**: `list`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_address`<a id="variable-navidrome_address"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Address to listen.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `"localhost"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_port`<a id="variable-navidrome_port"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Port to listen
|
||||||
|
|
||||||
|
- **Type**: `int`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `4533`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_enable_insights_collector`<a id="variable-navidrome_enable_insights_collector"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Enable the insights collector.
|
||||||
|
|
||||||
|
- **Type**: `bool`
|
||||||
|
- **Required**: No
|
||||||
|
- **Default**: `false`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `navidrome_base_url`<a id="variable-navidrome_base_url"></a>
|
||||||
|
|
||||||
|
[*⇑ Back to ToC ⇑*](#toc)
|
||||||
|
|
||||||
|
Base URL of the web interface.
|
||||||
|
|
||||||
|
- **Type**: `str`
|
||||||
|
- **Required**: No
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ANSIBLE DOCSMITH MAIN END -->
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
As we all love FOSS, you should consider sponsoring the
|
||||||
|
[Navidrome](https://github.com/navidrome/navidrome) project.
|
||||||
84
roles/navidrome/defaults/main.yml
Normal file
84
roles/navidrome/defaults/main.yml
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
# Version of the debian package.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 0.54.5
|
||||||
|
navidrome_version: 0.54.5
|
||||||
|
|
||||||
|
# Architecture of the debian package.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: amd64
|
||||||
|
navidrome_arch: amd64
|
||||||
|
|
||||||
|
# Operating system user to run the service.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: navidrome
|
||||||
|
navidrome_user: navidrome
|
||||||
|
|
||||||
|
# Operating system group to run the service.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: navidrome
|
||||||
|
navidrome_group: navidrome
|
||||||
|
|
||||||
|
# Path to the music folder.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /opt/navidrome/music
|
||||||
|
navidrome_music_folder: /opt/navidrome/music
|
||||||
|
|
||||||
|
# Path to the data directory.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: /var/lib/navidrome
|
||||||
|
navidrome_data_folder: /var/lib/navidrome
|
||||||
|
|
||||||
|
# Path to the cache folder.
|
||||||
|
#
|
||||||
|
# - Type: path
|
||||||
|
# - Required: No
|
||||||
|
# - Default: {{ navidrome_data_folder }}/cache
|
||||||
|
navidrome_cache_folder: "{{ navidrome_data_folder }}/cache"
|
||||||
|
|
||||||
|
# Configure iptables rules
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: false
|
||||||
|
navidrome_manage_iptables: false
|
||||||
|
|
||||||
|
# List of IP ranges to allow when `navidrome_manage_iptables` is enabled
|
||||||
|
#
|
||||||
|
# - Type: list
|
||||||
|
# - Required: No
|
||||||
|
navidrome_allowed_sources: []
|
||||||
|
|
||||||
|
# Address to listen.
|
||||||
|
#
|
||||||
|
# - Type: str
|
||||||
|
# - Required: No
|
||||||
|
# - Default: localhost
|
||||||
|
navidrome_address: localhost
|
||||||
|
|
||||||
|
# Port to listen
|
||||||
|
#
|
||||||
|
# - Type: int
|
||||||
|
# - Required: No
|
||||||
|
# - Default: 4533
|
||||||
|
navidrome_port: 4533
|
||||||
|
|
||||||
|
# Enable the insights collector.
|
||||||
|
#
|
||||||
|
# - Type: bool
|
||||||
|
# - Required: No
|
||||||
|
# - Default: false
|
||||||
|
navidrome_enable_insights_collector: false
|
||||||
14
roles/navidrome/handlers/main.yml
Normal file
14
roles/navidrome/handlers/main.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
- name: Reload systemd
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
daemon_reload: true
|
||||||
|
|
||||||
|
- name: Restart navidrome
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: navidrome
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Save iptables
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: netfilter-persistent save
|
||||||
|
changed_when: true
|
||||||
78
roles/navidrome/meta/argument_specs.yml
Normal file
78
roles/navidrome/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Install Navidrome.
|
||||||
|
description:
|
||||||
|
- Install [Navidrome](https://github.com/navidrome/navidrome).
|
||||||
|
author:
|
||||||
|
- jriou
|
||||||
|
options:
|
||||||
|
navidrome_version:
|
||||||
|
description:
|
||||||
|
- Version of the debian package.
|
||||||
|
default: 0.54.5
|
||||||
|
|
||||||
|
navidrome_arch:
|
||||||
|
description:
|
||||||
|
- Architecture of the debian package.
|
||||||
|
default: amd64
|
||||||
|
|
||||||
|
navidrome_user:
|
||||||
|
description:
|
||||||
|
- Operating system user to run the service.
|
||||||
|
default: navidrome
|
||||||
|
|
||||||
|
navidrome_group:
|
||||||
|
description:
|
||||||
|
- Operating system group to run the service.
|
||||||
|
default: navidrome
|
||||||
|
|
||||||
|
navidrome_music_folder:
|
||||||
|
description:
|
||||||
|
- Path to the music folder.
|
||||||
|
type: path
|
||||||
|
default: /opt/navidrome/music
|
||||||
|
|
||||||
|
navidrome_data_folder:
|
||||||
|
description:
|
||||||
|
- Path to the data directory.
|
||||||
|
type: path
|
||||||
|
default: /var/lib/navidrome
|
||||||
|
|
||||||
|
navidrome_cache_folder:
|
||||||
|
description:
|
||||||
|
- Path to the cache folder.
|
||||||
|
type: path
|
||||||
|
default: "{{ navidrome_data_folder }}/cache"
|
||||||
|
|
||||||
|
navidrome_manage_iptables:
|
||||||
|
description:
|
||||||
|
- Configure iptables rules
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
|
||||||
|
navidrome_allowed_sources:
|
||||||
|
description:
|
||||||
|
- List of IP ranges to allow when `navidrome_manage_iptables` is enabled
|
||||||
|
type: list
|
||||||
|
|
||||||
|
navidrome_address:
|
||||||
|
description:
|
||||||
|
- Address to listen.
|
||||||
|
default: localhost
|
||||||
|
|
||||||
|
navidrome_port:
|
||||||
|
description:
|
||||||
|
- Port to listen
|
||||||
|
type: int
|
||||||
|
default: 4533
|
||||||
|
|
||||||
|
navidrome_enable_insights_collector:
|
||||||
|
description:
|
||||||
|
- Enable the insights collector.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
|
||||||
|
navidrome_base_url:
|
||||||
|
description:
|
||||||
|
- Base URL of the web interface.
|
||||||
62
roles/navidrome/tasks/main.yml
Normal file
62
roles/navidrome/tasks/main.yml
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
---
|
||||||
|
- name: Install package
|
||||||
|
ansible.builtin.apt:
|
||||||
|
deb: "https://github.com/navidrome/navidrome/releases/download/v{{ navidrome_version }}/navidrome_{{ navidrome_version }}_linux_{{ navidrome_arch }}.deb"
|
||||||
|
|
||||||
|
- name: Create directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ item }}"
|
||||||
|
owner: "{{ navidrome_user }}"
|
||||||
|
group: "{{ navidrome_group }}"
|
||||||
|
mode: "0755"
|
||||||
|
loop:
|
||||||
|
- "{{ navidrome_music_folder }}"
|
||||||
|
- "{{ navidrome_data_folder }}"
|
||||||
|
- "{{ navidrome_cache_folder }}"
|
||||||
|
|
||||||
|
- name: Create configuration file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: navidrome.toml.j2
|
||||||
|
dest: /etc/navidrome/navidrome.toml
|
||||||
|
owner: "{{ navidrome_user }}"
|
||||||
|
group: "{{ navidrome_group }}"
|
||||||
|
mode: "0644"
|
||||||
|
notify:
|
||||||
|
- Restart navidrome
|
||||||
|
|
||||||
|
- name: Create systemd override directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: /etc/systemd/system/navidrome.service.d
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Add systemd override
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: override.conf.j2
|
||||||
|
dest: /etc/systemd/system/navidrome.service.d/override.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
notify:
|
||||||
|
- Reload systemd
|
||||||
|
- Restart navidrome
|
||||||
|
|
||||||
|
- name: Start service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: navidrome
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Manage iptables
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}"
|
||||||
|
destination_port: "{{ navidrome_port }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: navidrome
|
||||||
|
loop: "{{ navidrome_allowed_sources }}"
|
||||||
|
notify: Save iptables
|
||||||
|
when: navidrome_manage_iptables
|
||||||
10
roles/navidrome/templates/navidrome.toml.j2
Normal file
10
roles/navidrome/templates/navidrome.toml.j2
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
MusicFolder = "{{ navidrome_music_folder }}"
|
||||||
|
DataFolder = "{{ navidrome_data_folder }}"
|
||||||
|
CacheFolder = "{{ navidrome_cache_folder }}"
|
||||||
|
Address = "{{ navidrome_address }}"
|
||||||
|
Port = "{{ navidrome_port }}"
|
||||||
|
EnableInsightsCollector = "{{ navidrome_enable_insights_collector }}"
|
||||||
|
{% if navidrome_base_url is defined %}
|
||||||
|
BaseUrl = "{{ navidrome_base_url }}"
|
||||||
|
{% endif %}
|
||||||
5
roles/navidrome/templates/override.conf.j2
Normal file
5
roles/navidrome/templates/override.conf.j2
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
[Service]
|
||||||
|
User={{ navidrome_user }}
|
||||||
|
WorkingDirectory={{ navidrome_data_folder }}
|
||||||
|
ReadWritePaths={{ navidrome_data_folder }}
|
||||||
2
test-requirements.txt
Normal file
2
test-requirements.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
ansible-core
|
||||||
|
molecule
|
||||||
3
test-requirements.yml
Normal file
3
test-requirements.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: containers.podman
|
||||||
Loading…
Add table
Add a link
Reference in a new issue