Initial commit
All checks were successful
/ ansible-docsmith (push) Successful in 41s

Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
Julien Riou 2026-03-23 10:48:41 +01:00 committed by Julien Riou
commit f418990e84
Signed by: jriou
GPG key ID: 9A099EDA51316854
85 changed files with 3520 additions and 2 deletions

229
roles/galene/README.md Normal file
View file

@ -0,0 +1,229 @@
# 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 -->
## Usage
Playbook example:
```yaml
- hosts: all
roles:
- jriou.general.galene
```
Then run the playbook:
```
ansible-playbook play.yml
```

View 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: {}

View 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

View 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

View file

@ -0,0 +1,3 @@
---
dependencies:
- role: golang

View file

@ -0,0 +1,5 @@
---
- name: Converge
hosts: molecule
roles:
- galene

View 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'] }}"

View 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

View 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

View 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

View file

@ -0,0 +1,3 @@
---
collections:
- name: containers.podman

View 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
View 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

View 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