mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-07-22 16:21:09 +02:00
Fixed BBB stuff
This commit is contained in:
parent
a1643870db
commit
b1bf7aaba5
0
cli/build/inventory/__init__.py
Normal file
0
cli/build/inventory/__init__.py
Normal file
@ -9,6 +9,7 @@
|
|||||||
listen:
|
listen:
|
||||||
- docker compose up
|
- docker compose up
|
||||||
- docker compose restart
|
- docker compose restart
|
||||||
|
- docker compose just up
|
||||||
|
|
||||||
- name: Build docker
|
- name: Build docker
|
||||||
command:
|
command:
|
||||||
@ -19,21 +20,26 @@
|
|||||||
DOCKER_CLIENT_TIMEOUT: 600
|
DOCKER_CLIENT_TIMEOUT: 600
|
||||||
listen:
|
listen:
|
||||||
- docker compose build
|
- 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
|
|
||||||
|
|
||||||
- name: docker compose up
|
- name: docker compose up
|
||||||
shell: docker-compose -p {{ application_id | get_entity_name }} up -d --force-recreate --remove-orphans
|
shell: |
|
||||||
|
if [ -f "{{ docker_compose.files.env }}" ]; then
|
||||||
|
docker compose -p {{ application_id | get_entity_name }} --env-file "{{ docker_compose.files.env }} up -d --force-recreate --remove-orphans"
|
||||||
|
else
|
||||||
|
docker compose -p {{ application_id | get_entity_name }} up -d --force-recreate --remove-orphans
|
||||||
|
fi
|
||||||
args:
|
args:
|
||||||
chdir: "{{ docker_compose.directories.instance }}"
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
environment:
|
environment:
|
||||||
COMPOSE_HTTP_TIMEOUT: 600
|
COMPOSE_HTTP_TIMEOUT: 600
|
||||||
DOCKER_CLIENT_TIMEOUT: 600
|
DOCKER_CLIENT_TIMEOUT: 600
|
||||||
listen: docker compose up
|
listen:
|
||||||
|
- docker compose up
|
||||||
|
- docker compose just up # @todo replace later just up by up when code is refactored, build atm is also listening to up
|
||||||
|
|
||||||
- name: docker compose restart
|
- name: docker compose restart
|
||||||
command:
|
command:
|
||||||
cmd: "docker compose restart"
|
cmd: 'docker compose restart'
|
||||||
chdir: "{{docker_compose.directories.instance}}"
|
chdir: "{{docker_compose.directories.instance}}"
|
||||||
listen: docker compose restart
|
listen: docker compose restart
|
||||||
|
72
roles/web-app-bigbluebutton/filter_plugins/compose_mods.py
Normal file
72
roles/web-app-bigbluebutton/filter_plugins/compose_mods.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import re
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
def compose_mods(yml_text, docker_repository_path, env_file):
|
||||||
|
yml_text = re.sub(r'\./data/postgres:/var/lib/postgresql/data', 'database:/var/lib/postgresql/data', yml_text)
|
||||||
|
yml_text = re.sub(r'\./data/bigbluebutton:/var/bigbluebutton', 'bigbluebutton:/var/bigbluebutton', yml_text)
|
||||||
|
yml_text = re.sub(r'\./data/freeswitch-meetings:/var/freeswitch/meetings', 'freeswitch:/var/freeswitch/meetings', yml_text)
|
||||||
|
yml_text = re.sub(r'\./data/greenlight:/usr/src/app/storage', 'greenlight:/usr/src/app/storage', yml_text)
|
||||||
|
yml_text = re.sub(r'\./data/mediasoup:/var/mediasoup', 'mediasoup:/var/mediasoup', yml_text)
|
||||||
|
yml_text = re.sub(r'\./', docker_repository_path + '/', yml_text)
|
||||||
|
yml_text = re.sub(
|
||||||
|
r'(^\s*context:\s*)' + re.escape(docker_repository_path) + r'/mod/(.*)',
|
||||||
|
r'\1' + docker_repository_path + r'/mod/\2',
|
||||||
|
yml_text, flags=re.MULTILINE
|
||||||
|
)
|
||||||
|
yml_text = re.sub(
|
||||||
|
r'(^\s*context:\s*)mod/(.*)',
|
||||||
|
r'\1' + docker_repository_path + r'/mod/\2',
|
||||||
|
yml_text, flags=re.MULTILINE
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = yaml.safe_load(yml_text)
|
||||||
|
services = data.get('services', {})
|
||||||
|
for name, svc in services.items():
|
||||||
|
svc['env_file'] = [env_file]
|
||||||
|
if name == 'redis':
|
||||||
|
vols = svc.get('volumes')
|
||||||
|
if not vols or not isinstance(vols, list):
|
||||||
|
svc['volumes'] = ['redis:/data']
|
||||||
|
elif 'redis:/data' not in vols:
|
||||||
|
svc['volumes'].append('redis:/data')
|
||||||
|
if name == 'coturn':
|
||||||
|
vols = svc.get('volumes')
|
||||||
|
if not vols or not isinstance(vols, list):
|
||||||
|
svc['volumes'] = ['coturn:/var/lib/coturn']
|
||||||
|
elif 'coturn:/var/lib/coturn' not in vols:
|
||||||
|
svc['volumes'].append('coturn:/var/lib/coturn')
|
||||||
|
if name == 'bbb-graphql-server':
|
||||||
|
svc['healthcheck'] = {
|
||||||
|
'test': ['CMD', 'curl', '-f', 'http://localhost:8085/healthz'],
|
||||||
|
'interval': '30s',
|
||||||
|
'timeout': '10s',
|
||||||
|
'retries': 5,
|
||||||
|
'start_period': '10s'
|
||||||
|
}
|
||||||
|
data['services'] = services
|
||||||
|
|
||||||
|
# **ADD THIS BLOCK:**
|
||||||
|
# Only add volumes block if not present
|
||||||
|
if 'volumes' not in data:
|
||||||
|
data['volumes'] = {
|
||||||
|
'database': None,
|
||||||
|
'greenlight': None,
|
||||||
|
'redis': None,
|
||||||
|
'coturn': None,
|
||||||
|
'freeswitch': None,
|
||||||
|
'bigbluebutton': None,
|
||||||
|
'mediasoup': None
|
||||||
|
}
|
||||||
|
|
||||||
|
yml_text = yaml.dump(data, default_flow_style=False, sort_keys=False)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return yml_text
|
||||||
|
|
||||||
|
class FilterModule(object):
|
||||||
|
def filters(self):
|
||||||
|
return {
|
||||||
|
'compose_mods': compose_mods,
|
||||||
|
}
|
@ -6,107 +6,14 @@
|
|||||||
COMPOSE_HTTP_TIMEOUT: 600
|
COMPOSE_HTTP_TIMEOUT: 600
|
||||||
DOCKER_CLIENT_TIMEOUT: 600
|
DOCKER_CLIENT_TIMEOUT: 600
|
||||||
|
|
||||||
- name: Copy docker-compose.yml from origin to final location
|
- name: Slurp docker-compose.yml from remote host
|
||||||
|
slurp:
|
||||||
|
src: "{{ docker_compose_file_origine }}"
|
||||||
|
register: compose_slurp
|
||||||
|
|
||||||
|
- name: Transform docker-compose.yml with compose_mods
|
||||||
copy:
|
copy:
|
||||||
src: "{{ docker_compose_file_origine }}"
|
content: "{{ compose_slurp.content | b64decode | compose_mods(docker_repository_path, docker_compose.files.env) }}"
|
||||||
dest: "{{ docker_compose_file_final }}"
|
dest: "{{ docker_compose_file_final }}"
|
||||||
remote_src: yes
|
notify:
|
||||||
|
- docker compose just up
|
||||||
- name: Replace bind mounts by named volume mounts
|
|
||||||
replace:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
regexp: "{{ item.regexp }}"
|
|
||||||
replace: "{{ item.replace }}"
|
|
||||||
loop:
|
|
||||||
- { regexp: '\./data/postgres:/var/lib/postgresql/data', replace: 'database:/var/lib/postgresql/data' }
|
|
||||||
- { regexp: '\./data/bigbluebutton:/var/bigbluebutton', replace: 'bigbluebutton:/var/bigbluebutton' }
|
|
||||||
- { regexp: '\./data/freeswitch-meetings:/var/freeswitch/meetings', replace: 'freeswitch:/var/freeswitch/meetings' }
|
|
||||||
- { regexp: '\./data/greenlight:/usr/src/app/storage', replace: 'greenlight:/usr/src/app/storage' }
|
|
||||||
- { regexp: '\./data/mediasoup:/var/mediasoup', replace: 'mediasoup:/var/mediasoup' }
|
|
||||||
|
|
||||||
- name: add volume to redis
|
|
||||||
lineinfile:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
insertafter: "^\\s*redis:"
|
|
||||||
line: " volumes:\n - redis:/data"
|
|
||||||
firstmatch: yes
|
|
||||||
|
|
||||||
- name: add volume to coturn
|
|
||||||
lineinfile:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
insertafter: "- ./mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf"
|
|
||||||
line: " - coturn:/var/lib/coturn"
|
|
||||||
|
|
||||||
# Implemented due to etherpad health bug.
|
|
||||||
# @todo Remove when health check is working fine
|
|
||||||
# @see https://chatgpt.com/c/67a0fc7e-5104-800f-bb6b-3731e2f83b7b
|
|
||||||
#- name: "Update docker-compose.yml for Etherpad health check"
|
|
||||||
# lineinfile:
|
|
||||||
# line: " healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://127.0.0.1:9001\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 10s"
|
|
||||||
# path: "{{docker_compose_file_final}}"
|
|
||||||
# insertafter: "etherpad:"
|
|
||||||
# listen: setup bigbluebutton
|
|
||||||
|
|
||||||
- name: Add volumes block after services in docker compose
|
|
||||||
blockinfile:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
block: |
|
|
||||||
volumes:
|
|
||||||
database:
|
|
||||||
greenlight:
|
|
||||||
redis:
|
|
||||||
coturn:
|
|
||||||
freeswitch:
|
|
||||||
bigbluebutton:
|
|
||||||
mediasoup:
|
|
||||||
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR VOLUMES"
|
|
||||||
insertbefore: "^services:"
|
|
||||||
|
|
||||||
- name: Replace all './' with '/services/' in docker-compose.yml
|
|
||||||
ansible.builtin.replace:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
regexp: '\./'
|
|
||||||
replace: '{{ docker_repository_path }}/'
|
|
||||||
|
|
||||||
- name: Prefix build context with docker_repository_path
|
|
||||||
ansible.builtin.replace:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
regexp: '(^\s*context:\s*)mod/(.*)'
|
|
||||||
replace: '\1{{ docker_repository_path }}/mod/\2'
|
|
||||||
|
|
||||||
- name: "Update healthcheck for bbb-graphql-server"
|
|
||||||
# This is neccessary because the healthcheck doesn't listen to the correct port
|
|
||||||
lineinfile:
|
|
||||||
line: " healthcheck:\n test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8085/healthz\"]\n interval: 30s\n timeout: 10s\n retries: 5\n start_period: 10s"
|
|
||||||
path: "{{docker_compose_file_final}}"
|
|
||||||
insertafter: "bbb-graphql-server:"
|
|
||||||
|
|
||||||
- name: Add env_file to each service in docker-compose.yml
|
|
||||||
blockinfile:
|
|
||||||
path: "{{ docker_compose_file_final }}"
|
|
||||||
insertafter: '^ {{ service }}:$'
|
|
||||||
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR ENV_FILE"
|
|
||||||
block: |
|
|
||||||
env_file:
|
|
||||||
- "{{ docker_compose.files.env }}"
|
|
||||||
loop:
|
|
||||||
- bbb-web
|
|
||||||
- freeswitch
|
|
||||||
- nginx
|
|
||||||
- etherpad
|
|
||||||
- bbb-pads
|
|
||||||
- bbb-export-annotations
|
|
||||||
- redis
|
|
||||||
- webrtc-sfu
|
|
||||||
- fsesl-akka
|
|
||||||
- apps-akka
|
|
||||||
- bbb-graphql-server
|
|
||||||
- bbb-graphql-actions
|
|
||||||
- bbb-graphql-middleware
|
|
||||||
- collabora
|
|
||||||
- periodic
|
|
||||||
- coturn
|
|
||||||
- greenlight
|
|
||||||
- postgres
|
|
||||||
loop_control:
|
|
||||||
loop_var: service
|
|
||||||
|
@ -35,15 +35,29 @@
|
|||||||
- name: "Setup docker-compose.yml file"
|
- name: "Setup docker-compose.yml file"
|
||||||
include_tasks: "docker-compose.yml"
|
include_tasks: "docker-compose.yml"
|
||||||
|
|
||||||
|
- name: Ensure all containers in instance are running
|
||||||
|
include_tasks: "{{ playbook_dir }}/roles/docker-compose/tasks/04_ensure_up.yml"
|
||||||
|
|
||||||
- name: flush docker service
|
- name: flush docker service
|
||||||
meta: flush_handlers
|
meta: flush_handlers
|
||||||
|
|
||||||
- name: Wait for BigBlueButton
|
- name: "Get greenlight container name"
|
||||||
wait_for:
|
shell: |
|
||||||
host: "{{ domains | get_domain('web-app-bigbluebutton') }}"
|
docker compose ps -q greenlight
|
||||||
port: 80
|
args:
|
||||||
delay: 5
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
timeout: 300
|
register: greenlight_id
|
||||||
|
|
||||||
|
- name: "Wait until BigBlueButton (greenlight) is running"
|
||||||
|
shell: |
|
||||||
|
docker inspect --format='{{'{{'}}.State.Status{{'}}'}}' {{ greenlight_id.stdout }}
|
||||||
|
args:
|
||||||
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
|
register: bbb_state
|
||||||
|
until: bbb_state.stdout.strip() == "running"
|
||||||
|
retries: 30
|
||||||
|
delay: 5
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: create admin
|
- name: create admin
|
||||||
command:
|
command:
|
||||||
|
@ -5,7 +5,7 @@ features:
|
|||||||
# itself wouldn't be possible
|
# itself wouldn't be possible
|
||||||
matomo: false
|
matomo: false
|
||||||
css: false
|
css: false
|
||||||
port-ui-desktop: true
|
port-ui-desktop: false # Didn't work in frame didn't have high priority @todo figure out pcause and solve it
|
||||||
central_database: true
|
central_database: true
|
||||||
oauth2: false
|
oauth2: false
|
||||||
csp:
|
csp:
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
dest: "{{openproject_plugins_folder}}Gemfile.plugins"
|
dest: "{{openproject_plugins_folder}}Gemfile.plugins"
|
||||||
notify:
|
notify:
|
||||||
- docker compose up
|
- docker compose up
|
||||||
|
- docker compose build
|
||||||
|
|
||||||
- name: "create {{dummy_volume}}"
|
- name: "create {{dummy_volume}}"
|
||||||
file:
|
file:
|
||||||
|
0
tests/unit/roles/web-app-bigbluebutton/__init__.py
Normal file
0
tests/unit/roles/web-app-bigbluebutton/__init__.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
import sys
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
sys.path.insert(
|
||||||
|
0,
|
||||||
|
os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'../../../../../roles/web-app-bigbluebutton/filter_plugins'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
from compose_mods import compose_mods
|
||||||
|
|
||||||
|
def sort_dict(obj):
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
return {k: sort_dict(obj[k]) for k in sorted(obj)}
|
||||||
|
elif isinstance(obj, list):
|
||||||
|
return [sort_dict(v) for v in obj]
|
||||||
|
else:
|
||||||
|
return obj
|
||||||
|
|
||||||
|
class TestComposeModsFullFile(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.docker_repository_path = "/opt/docker/bigbluebutton/services/repository"
|
||||||
|
self.env_file = "/opt/docker/bigbluebutton/.env/env"
|
||||||
|
self.original = """# auto generated by ./scripts/generate-compose
|
||||||
|
# don't edit this directly.
|
||||||
|
|
||||||
|
services:
|
||||||
|
bbb-web:
|
||||||
|
build:
|
||||||
|
context: mod/bbb-web
|
||||||
|
additional_contexts:
|
||||||
|
- src-web=./repos/bigbluebutton/bigbluebutton-web
|
||||||
|
volumes:
|
||||||
|
- ./data/bigbluebutton:/var/bigbluebutton
|
||||||
|
- ./data/freeswitch-meetings:/var/freeswitch/meetings
|
||||||
|
|
||||||
|
freeswitch:
|
||||||
|
build:
|
||||||
|
context: mod/freeswitch
|
||||||
|
additional_contexts:
|
||||||
|
- freeswitch=./repos/freeswitch/
|
||||||
|
volumes:
|
||||||
|
- ./data/freeswitch-meetings:/var/freeswitch/meetings
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
build:
|
||||||
|
context: mod/nginx
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7.2-alpine
|
||||||
|
|
||||||
|
coturn:
|
||||||
|
image: coturn/coturn:4.6-alpine
|
||||||
|
volumes:
|
||||||
|
- ./mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf
|
||||||
|
|
||||||
|
bbb-graphql-server:
|
||||||
|
build:
|
||||||
|
context: mod/bbb-graphql-server
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.expected = """services:
|
||||||
|
bbb-web:
|
||||||
|
build:
|
||||||
|
context: /opt/docker/bigbluebutton/services/repository/mod/bbb-web
|
||||||
|
additional_contexts:
|
||||||
|
- src-web=/opt/docker/bigbluebutton/services/repository/repos/bigbluebutton/bigbluebutton-web
|
||||||
|
volumes:
|
||||||
|
- bigbluebutton:/var/bigbluebutton
|
||||||
|
- freeswitch:/var/freeswitch/meetings
|
||||||
|
env_file:
|
||||||
|
- /opt/docker/bigbluebutton/.env/env
|
||||||
|
|
||||||
|
freeswitch:
|
||||||
|
build:
|
||||||
|
context: /opt/docker/bigbluebutton/services/repository/mod/freeswitch
|
||||||
|
additional_contexts:
|
||||||
|
- freeswitch=/opt/docker/bigbluebutton/services/repository/repos/freeswitch/
|
||||||
|
volumes:
|
||||||
|
- freeswitch:/var/freeswitch/meetings
|
||||||
|
env_file:
|
||||||
|
- /opt/docker/bigbluebutton/.env/env
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
build:
|
||||||
|
context: /opt/docker/bigbluebutton/services/repository/mod/nginx
|
||||||
|
env_file:
|
||||||
|
- /opt/docker/bigbluebutton/.env/env
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7.2-alpine
|
||||||
|
volumes:
|
||||||
|
- redis:/data
|
||||||
|
env_file:
|
||||||
|
- /opt/docker/bigbluebutton/.env/env
|
||||||
|
|
||||||
|
coturn:
|
||||||
|
image: coturn/coturn:4.6-alpine
|
||||||
|
volumes:
|
||||||
|
- /opt/docker/bigbluebutton/services/repository/mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf
|
||||||
|
- coturn:/var/lib/coturn
|
||||||
|
env_file:
|
||||||
|
- /opt/docker/bigbluebutton/.env/env
|
||||||
|
|
||||||
|
bbb-graphql-server:
|
||||||
|
build:
|
||||||
|
context: /opt/docker/bigbluebutton/services/repository/mod/bbb-graphql-server
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- curl
|
||||||
|
- -f
|
||||||
|
- http://localhost:8085/healthz
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
env_file:
|
||||||
|
- /opt/docker/bigbluebutton/.env/env
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
database:
|
||||||
|
greenlight:
|
||||||
|
redis:
|
||||||
|
coturn:
|
||||||
|
freeswitch:
|
||||||
|
bigbluebutton:
|
||||||
|
mediasoup:
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_full_file_semantic_match(self):
|
||||||
|
actual_data = yaml.safe_load(compose_mods(self.original, self.docker_repository_path, self.env_file))
|
||||||
|
expected_data = yaml.safe_load(self.expected)
|
||||||
|
for key in expected_data:
|
||||||
|
self.assertIn(key, actual_data)
|
||||||
|
self.assertEqual(sort_dict(actual_data[key]), sort_dict(expected_data[key]))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user