Compare commits

...

6 Commits

25 changed files with 189 additions and 102 deletions

View File

@@ -19,12 +19,12 @@ RUN printf '#!/bin/sh\nexit 0\n' > /usr/bin/systemctl \
&& chmod +x /usr/bin/yay
# 3) Build & install python-simpleaudio from AUR manually (as non-root)
RUN useradd -m builder \
&& su builder -c "git clone https://aur.archlinux.org/python-simpleaudio.git /home/builder/psa && \
cd /home/builder/psa && \
RUN useradd -m aur_builder \
&& su aur_builder -c "git clone https://aur.archlinux.org/python-simpleaudio.git /home/aur_builder/psa && \
cd /home/aur_builder/psa && \
makepkg --noconfirm --skippgpcheck" \
&& pacman -U --noconfirm /home/builder/psa/*.pkg.tar.zst \
&& rm -rf /home/builder/psa
&& pacman -U --noconfirm /home/aur_builder/psa/*.pkg.tar.zst \
&& rm -rf /home/aur_builder/psa
# 4) Clone Kevins Package Manager and create its venv
ENV PKGMGR_REPO=/opt/package-manager \

View File

@@ -1,4 +1,9 @@
from ansible.errors import AnsibleFilterError
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from module_utils.entity_name_utils import get_entity_name
class FilterModule(object):
def filters(self):
@@ -13,6 +18,7 @@ class FilterModule(object):
seen_domains = {}
for app_id, cfg in apps.items():
if app_id.startswith(("web-","svc-")):
if not isinstance(cfg, dict):
raise AnsibleFilterError(
f"Invalid configuration for application '{app_id}': "
@@ -34,7 +40,8 @@ class FilterModule(object):
Add the default domain for an application if no canonical domains are defined.
Ensures the domain is unique across applications.
"""
default_domain = f"{app_id}.{primary_domain}"
entity_name = get_entity_name(app_id)
default_domain = f"{entity_name}.{primary_domain}"
if default_domain in seen_domains:
raise AnsibleFilterError(
f"Domain '{default_domain}' is already configured for "

View File

@@ -1,12 +1,4 @@
---
- name: rebuild docker repository
command:
cmd: docker compose build
chdir: "{{docker_repository_path}}"
environment:
COMPOSE_HTTP_TIMEOUT: 600
DOCKER_CLIENT_TIMEOUT: 600
- name: Validate Docker Compose configuration
command:
cmd: docker compose -f {{ docker_compose.files.docker_compose }} config --quiet
@@ -18,8 +10,21 @@
- docker compose up
- docker compose restart
- name: Build docker
command:
cmd: docker compose build
chdir: "{{docker_repository_path}}"
environment:
COMPOSE_HTTP_TIMEOUT: 600
DOCKER_CLIENT_TIMEOUT: 600
listen:
- docker compose build
- docker compose up # This is just here because I didn't took the time to refactor
# @todo go over all docker compose up implementations and check where it makes sense to user docker compose build and where docker compose up
when: application_id != 'web-app-bigbluebutton' # @todo solve this on a different way, just a fast hack
- name: docker compose up
shell: docker-compose -p {{ application_id | get_entity_name }} up -d --force-recreate --remove-orphans --build
shell: docker-compose -p {{ application_id | get_entity_name }} up -d --force-recreate --remove-orphans
args:
chdir: "{{ docker_compose.directories.instance }}"
executable: /bin/bash

View File

@@ -8,6 +8,6 @@
dest: "{{ docker_repository_path }}"
update: yes
notify:
- docker compose build
- docker compose up
- rebuild docker repository
become: true

View File

@@ -32,13 +32,3 @@
dest: "{{ docker_compose.files.docker_compose }}"
notify: docker compose up
register: docker_compose_template
- name: "Check if any container is running in {{ docker_compose.directories.instance }}"
command: docker compose ps -q --filter status=running
args:
chdir: "{{ docker_compose.directories.instance }}"
register: docker_ps
changed_when: (docker_ps.stdout | trim) == ""
notify: docker compose up
when: not (docker_compose_template.changed or env_template.changed)
ignore_errors: true

View File

@@ -0,0 +1,13 @@
- name: "Check if any container is running in {{ docker_compose.directories.instance }}"
command: docker compose ps -q --filter status=running
args:
chdir: "{{ docker_compose.directories.instance }}"
register: docker_ps
changed_when: (docker_ps.stdout | trim) == ""
when: >
not (
docker_compose_template.changed | default(false)
or
env_template.changed | default(false)
)
notify: docker compose up

View File

@@ -17,13 +17,16 @@
with_dict: "{{ docker_compose.directories }}"
- name: "Include routines to set up a git repository based installaion for '{{application_id}}'."
include_tasks: "repository.yml"
include_tasks: "01_repository.yml"
when: docker_pull_git_repository | bool
- name: "Include routines file management routines for '{{application_id}}'."
include_tasks: "files.yml"
include_tasks: "02_files.yml"
when: not docker_compose_skipp_file_creation | bool
- name: "Ensure that {{ docker_compose.directories.instance }} is up"
include_tasks: "03_ensure_up.yml"
- name: "flush database, docker and proxy for '{{ application_id }}'"
meta: flush_handlers
when: docker_compose_flush_handlers | bool

View File

@@ -9,14 +9,14 @@
listen: setup bigbluebutton
- name: Copy docker-compose.yml from origin to final location
ansible.builtin.copy:
copy:
src: "{{ docker_compose_file_origine }}"
dest: "{{ docker_compose_file_final }}"
remote_src: yes
listen: setup bigbluebutton
- name: Replace bind mounts by named volume mounts
ansible.builtin.replace:
replace:
path: "{{ docker_compose_file_final }}"
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"

View File

@@ -37,7 +37,7 @@
notify: restart nginx
- name: "Remove directory {{ docker_compose.directories.env }}"
ansible.builtin.file:
file:
path: "{{ docker_compose.directories.env }}"
state: absent
@@ -48,12 +48,20 @@
notify: setup bigbluebutton
- name: Create symbolic link from .env file to target location
ansible.builtin.file:
file:
src: "{{ bbb_env_file_origine }}"
dest: "{{ bbb_env_file_link }}"
state: link
notify: setup bigbluebutton
- name: "Check if any container is running in {{ docker_compose.directories.instance }}"
command: docker compose ps -q --filter status=running
args:
chdir: "{{ docker_compose.directories.instance }}"
register: docker_ps
changed_when: (docker_ps.stdout | trim) == ""
notify: setup bigbluebutton
- name: flush docker service
meta: flush_handlers
@@ -62,7 +70,7 @@
host: "{{ domains | get_domain('web-app-bigbluebutton') }}"
port: 80
delay: 5
timeout: 600
timeout: 300
- name: create admin
command:
@@ -71,8 +79,3 @@
when: bigbluebutton_setup
ignore_errors: true
register: admin_creation_result
- name: print admin user data
debug:
msg: "{{ admin_creation_result.stdout }}"
when: bigbluebutton_setup

View File

@@ -1,5 +1,6 @@
- name: flush handlers to ensure that friendica is up before friendica addon configuration
meta: flush_handlers
- name: Check if Friendica local.config.php exists
command: docker exec --user {{ friendica_user }} {{ friendica_container }} test -f {{ friendica_config_file }}
register: friendica_config_exists
@@ -12,23 +13,23 @@
- name: Update DB host
command: >
docker exec --user {{ friendica_user }} {{ friendica_container }}
sed -i "s/'hostname' => .*/'hostname' => '{{ database_host }}:{{ database_port }}',/" {{ friendica_config_file }}
sed -ri "s/('hostname'\s*=>\s*')[^']*(',)/\1{{ database_host }}:{{ database_port }}\2/" {{ friendica_config_file }}
notify: docker compose up
- name: Update DB name
command: >
docker exec --user {{ friendica_user }} {{ friendica_container }}
sed -i "s/'database' => .*/'database' => '{{ database_name }}',/" {{ friendica_config_file }}
sed -ri "s/('database'\s*=>\s*')[^']*(',)/\1{{ database_name }}\2/" {{ friendica_config_file }}
notify: docker compose up
- name: Update DB user
command: >
docker exec --user {{ friendica_user }} {{ friendica_container }}
sed -i "s/'username' => .*/'username' => '{{ database_username }}',/" {{ friendica_config_file }}
sed -ri "s/('username'\s*=>\s*')[^']*(',)/\1{{ database_username }}\2/" {{ friendica_config_file }}
notify: docker compose up
- name: Update DB password
command: >
docker exec --user {{ friendica_user }} {{ friendica_container }}
sed -i "s/'password' => .*/'password' => '{{ database_password }}',/" {{ friendica_config_file }}
sed -ri "s/('password'\s*=>\s*')[^']*(',)/\1{{ database_password }}\2/" {{ friendica_config_file }}
notify: docker compose up

View File

@@ -1,6 +1,7 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ applications | get_app_conf(application_id, 'images.friendica', True) }}"
container_name: "{{ friendica_container }}"
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- html:{{ friendica_application_base }}

View File

@@ -1,6 +1,6 @@
application_id: "web-app-friendica"
database_type: "mariadb"
friendica_container: "application"
friendica_container: "friendica"
friendica_no_validation: "{{ applications | get_app_conf(application_id, 'features.oidc', True) }}" # Email validation is not neccessary if OIDC is active
friendica_application_base: "/var/www/html"
friendica_docker_ldap_config: "{{friendica_application_base}}/config/ldapauth.config.php"

View File

@@ -0,0 +1,30 @@
---
- name: Flush handlers to ensure Gitea is up before DB patch
meta: flush_handlers
- name: Patch Gitea DB host in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(HOST\s*=\s*).*$|\1{{ database_host }}:{{ database_port }}|" {{ gitea_config }}
notify: docker compose up
- name: Patch Gitea DB name in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(NAME\s*=\s*).*$|\1{{ database_name }}|" {{ gitea_config }}
notify: docker compose up
- name: Patch Gitea DB user in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(USER\s*=\s*).*$|\1{{ database_username }}|" {{ gitea_config }}
notify: docker compose up
- name: Patch Gitea DB password in app.ini
command: >
docker exec -i --user {{ gitea_user }} {{ gitea_container }}
sed -ri "s|^(PASSWD\s*=\s*).*$|\1{{ database_password }}|" {{ gitea_config }}
notify: docker compose up
- name: "Flush database patches"
meta: flush_handlers

View File

@@ -1,7 +1,6 @@
- name: "Lookup existing LDAP auth source ID"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth list \
| awk -v name="LDAP ({{ primary_domain }})" '$0 ~ name {print $1; exit}'
args:
@@ -12,8 +11,7 @@
- name: "Delete existing LDAP auth source if present"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth delete --id {{ ldap_source_id_raw.stdout }}
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -1,8 +1,7 @@
- name: "Lookup existing OIDC auth source ID"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth list \
| awk -v name="{{ oidc.button_text }}" '$0 ~ name {print $1; exit}'
args:
@@ -13,8 +12,7 @@
- name: "Delete existing OIDC auth source if present"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth delete --id {{ oidc_source_id_raw.stdout }}
args:
chdir: "{{ docker_compose.directories.instance }}"

View File

@@ -10,10 +10,12 @@
delay: 5
timeout: 300
- name: Patch Gitea database settings in app.ini
include_tasks: 01_database.yml
- name: "Run DB migrations inside Gitea container"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
/app/gitea/gitea migrate
args:
chdir: "{{ docker_compose.directories.instance }}"
@@ -22,14 +24,13 @@
- name: "Create initial admin user"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
/app/gitea/gitea admin user create \
--admin \
--username "{{ users.administrator.username }}" \
--password "{{ users.administrator.password }}" \
--email "{{ users.administrator.email }}" \
-c /data/gitea/conf/app.ini
-c {{ gitea_config }}
args:
chdir: "{{ docker_compose.directories.instance }}"
register: create_admin
@@ -49,10 +50,10 @@
when: applications | get_app_conf(application_id, 'features.oidc', False) or applications | get_app_conf(application_id, 'features.ldap', False)
- name: Execute Setup Routines
include_tasks: setup.yml
include_tasks: 02_setup.yml
- name: Execute Cleanup Routines
include_tasks: cleanup.yml
include_tasks: 03_cleanup.yml
when: mode_cleanup
- name: Include DNS role to register Gitea domain(s)

View File

@@ -1,7 +1,6 @@
- name: "Add LDAP Authentication Source"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth add-ldap \
{{ gitea_ldap_auth_args | join(' ') }}
args:
@@ -11,8 +10,7 @@
- name: "Lookup existing LDAP auth source ID"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth list \
| tail -n +2 \
| grep -F "LDAP ({{ primary_domain }})" \
@@ -31,8 +29,7 @@
- name: "Update LDAP Authentication Source"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth update-ldap \
--id {{ ldap_source_id }} \
{{ gitea_ldap_auth_args | join(' ') }}

View File

@@ -1,7 +1,6 @@
- name: "Add Keycloak OIDC Provider"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth add-oauth \
--provider openidConnect \
--name "{{ oidc.button_text }}" \
@@ -16,8 +15,7 @@
- name: "Lookup existing Keycloak auth source ID"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
/app/gitea/gitea admin auth list \
| tail -n +2 \
| grep -F "{{ oidc.button_text }}" \
@@ -36,8 +34,7 @@
- name: "Update Keycloak OIDC Provider"
shell: |
docker-compose -f "{{ docker_compose.directories.instance }}/docker-compose.yml" \
exec -T --user git application \
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
gitea admin auth update-oauth \
--id {{ oidc_source_id }}\
--provider openidConnect \

View File

@@ -3,7 +3,7 @@
application:
{% include 'roles/docker-container/templates/base.yml.j2' %}
image: "{{ gitea_image }}:{{ gitea_version }}"
name: "{{ gitea_name }}"
container_name: "{{ gitea_container }}"
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
- "{{ports.public.ssh[application_id]}}:22"

View File

@@ -17,7 +17,11 @@ gitea_ldap_auth_args:
- '--synchronize-users'
gitea_version: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.version', True) }}"
gitea_image: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.image', True) }}"
gitea_name: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.name', True) }}"
gitea_container: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.name', True) }}"
gitea_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
gitea_user: "git"
gitea_config: "/data/gitea/conf/app.ini"
container_port: "{{ applications | get_app_conf(application_id, 'docker.services.gitea.port', True) }}"
docker_compose_flush_handlers: true

View File

@@ -2,7 +2,7 @@
APP_KEY={{applications | get_app_conf(application_id, 'credentials.app_key', True)}}
## General Settings
APP_NAME="{{applications.pixelfed.titel}}"
APP_NAME="{{ pixelfed_titel }}"
APP_ENV={{ CYMAIS_ENVIRONMENT | lower }}
APP_DEBUG={{enable_debug | string | lower }}
APP_URL={{ domains | get_url(application_id, web_protocol) }}

View File

@@ -6,3 +6,4 @@ pixelfed_image: "{{ applications | get_app_conf(application_id, 'doc
pixelfed_name: "{{ applications | get_app_conf(application_id, 'docker.services.pixelfed.name', True) }}"
pixelfed_worker_name: "{{ applications | get_app_conf(application_id, 'docker.services.worker.name', True) }}"
pixelfed_volume: "{{ applications | get_app_conf(application_id, 'docker.volumes.data', True) }}"
pixelfed_titel: "{{ applications | get_app_conf(application_id, 'titel', True) }}"

View File

@@ -24,39 +24,39 @@ class TestDomainFilters(unittest.TestCase):
self.assertEqual(result, expected)
def test_canonical_without_domains(self):
apps = {'app1': {}}
expected = {'app1': ['app1.example.com']}
apps = {'web-app-app1': {}}
expected = {'web-app-app1': ['app1.example.com']}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertEqual(result, expected)
def test_canonical_with_list(self):
apps = {
'app1': {
'web-app-app1': {
'domains': {'canonical': ['foo.com', 'bar.com']}
}
}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertCountEqual(
result['app1'],
result['web-app-app1'],
['foo.com', 'bar.com']
)
def test_canonical_with_dict(self):
apps = {
'app1': {
'web-app-app1': {
'domains': {'canonical': {'one': 'one.com', 'two': 'two.com'}}
}
}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertEqual(
result['app1'],
result['web-app-app1'],
{'one': 'one.com', 'two': 'two.com'}
)
def test_canonical_duplicate_raises(self):
apps = {
'app1': {'domains': {'canonical': ['dup.com']}},
'app2': {'domains': {'canonical': ['dup.com']}},
'web-app-app1': {'domains': {'canonical': ['dup.com']}},
'web-app-app2': {'domains': {'canonical': ['dup.com']}},
}
with self.assertRaises(AnsibleFilterError) as cm:
self.filter_module.canonical_domains_map(apps, self.primary)
@@ -65,10 +65,48 @@ class TestDomainFilters(unittest.TestCase):
def test_invalid_canonical_type(self):
apps = {
'app1': {'domains': {'canonical': 123}}
'web-app-app1': {'domains': {'canonical': 123}}
}
with self.assertRaises(AnsibleFilterError):
self.filter_module.canonical_domains_map(apps, self.primary)
def test_non_web_apps_are_ignored(self):
"""
Applications not starting with 'web-' should be skipped entirely,
resulting in an empty mapping when only non-web apps are provided.
"""
apps = {
'db-app-app1': {'domains': {'canonical': ['db.example.com']}},
'service-app-app2': {}
}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertEqual(result, {})
def test_mixed_web_and_non_web_apps(self):
"""
Only 'web-' prefixed applications should be processed;
non-web apps should be ignored alongside valid web apps.
"""
apps = {
'db-app-app1': {'domains': {'canonical': ['db.example.com']}},
'web-app-app1': {}
}
expected = {'web-app-app1': ['app1.example.com']}
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertEqual(result, expected)
def test_non_web_invalid_config_no_error(self):
"""
Invalid configurations for non-web apps should not raise errors
since they are ignored by the filter.
"""
apps = {
'nonweb-app-app1': 'not-a-dict',
'another': 12345
}
# Should simply return an empty result without exceptions
result = self.filter_module.canonical_domains_map(apps, self.primary)
self.assertEqual(result, {})
if __name__ == "__main__":
unittest.main()