From 39dd70f0175ca3881c79369332ee58dee47b1b7a Mon Sep 17 00:00:00 2001 From: Daniel Kobras Date: Wed, 27 May 2020 21:56:27 +0200 Subject: [PATCH] Add option to install and configure Greenlight --- README.md | 16 ++ defaults/main.yml | 33 ++- tasks/greenlight.yml | 233 +++++++++++++++++++++ tasks/main.yml | 5 + templates/greenlight-docker-compose.yml.j2 | 35 ++++ templates/greenlight.nginx.j2 | 32 +++ templates/greenlight.service.j2 | 16 ++ 7 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 tasks/greenlight.yml create mode 100644 templates/greenlight-docker-compose.yml.j2 create mode 100644 templates/greenlight.nginx.j2 create mode 100644 templates/greenlight.service.j2 diff --git a/README.md b/README.md index 2b7ae32..05e8fbe 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,22 @@ To get up _BigBlueButton_ up and running the following variables can be configur * `bbb_install_playback_podcast`: Install the bbb-playback-podcast package to play back audio from a recorded session (Default: `True`). * `bbb_install_playback_screenshare`: Install the bbb-playback-screenshare package to play back shared screens from a recorded session (Default: `True`). * `bbb_install_webhooks`: Install the bbb-webhooks package, useful to integrate bbb into other web applications (Default: `True`). + * `bbb_install_greenlight`: Install the Greenlight frontend (Default: `False`) + +In order to deploy a basic setup of the _Greenlight_ frontend alongside _BigBlueButton_, the following variables can be set: + + * `bbb_greenlight_image`: Docker image to run for Greenlight (Default: `bigbluebutton/greenlight:v2`) + * `bbb_greenlight_etcdir`: Path to configuration directory (Default: `/etc/bigbluebutton/greenlight`) + * `bbb_greenlight_libdir`: Path to working directory (Default: `/var/lib/greenlight`) + * `bbb_greenlight_dbdir`: Path to database directory (Default: Subdirectory `production` below `bbb_greenlight_libdir`) + * `bbb_greenlight_logdir`: Path to log directory (Default: `/var/log/greenlight`) + * `bbb_greenlight_redirect_root`: Whether to add a redirection from the domain root URL to Greenlight (Default: `false`) + * `bbb_greenlight_db_adapter`: Database type to use (`sqlite3` or `postgresql`, default: `postgresql`) + * `bbb_greenlight_db_host`: Name of database host. For `postgresql` adapter, special name `db` will spawn database in a separate container (Default: `db`) + * `bbb_greenlight_db_username`: User name for database connection (Default: `postgres`) + * `bbb_greenlight_db_name`: Name of Greenlight database (Default: `greenlight_production`) + * `bbb_greenlight_db_port`: Host port for database connection (Default: `5432`) + * `bbb_greenlight_environment`: Dictionary of additional Greenlight environment variables (Default: empty) ## Example Playbook diff --git a/defaults/main.yml b/defaults/main.yml index 3768b5e..4bf9a87 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,7 +6,7 @@ bbb_install_playback_notes: True bbb_install_playback_podcast: True bbb_install_playback_screenshare: True bbb_install_webhooks: True -bbb_install_greenlight: True +bbb_install_greenlight: False bbb_install_demo: False bbb_install_check: False bbb_configure_firewall: True @@ -16,3 +16,34 @@ bbb_ssl_webroot_path: /var/www/bigbluebutton-default bbb_ssl_renewal_command_args: '--renew-hook "systemctl restart nginx"' ## Uncoment the following line to test on test network. # bbb_ssl_server: "https://acme-staging.api.letsencrypt.org/directory" +bbb_greenlight_image: bigbluebutton/greenlight:v2 +bbb_greenlight_etcdir: /etc/bigbluebutton/greenlight +bbb_greenlight_libdir: /var/lib/greenlight +bbb_greenlight_dbdir: "{{ bbb_greenlight_libdir }}/production" +bbb_greenlight_logdir: /var/log/greenlight +bbb_greenlight_redirect_root: false +bbb_greenlight_db_adapter: postgresql +bbb_greenlight_db_host: db +bbb_greenlight_db_username: postgres +bbb_greenlight_db_name: greenlight_production +bbb_greenlight_db_port: 5432 +bbb_greenlight_environment: {} +bbb_greenlight_environment_defaults: + HELP_URL: https://docs.bigbluebutton.org/greenlight/gl-overview.html + ALLOW_GREENLIGHT_ACCOUNTS: true + DEFAULT_REGISTRATION: open + RELATIVE_URL_ROOT: /b + ROOM_FEATURES: mute-on-join,require-moderator-approval,anyone-can-start,all-join-moderator + PAGINATION_NUMBER: 25 + NUMBER_OF_ROWS: 25 + MAINTENANCE_MODE: false + DB_ADAPTER: "{{ bbb_greenlight_db_adapter }}" + DB_HOST: "{{ bbb_greenlight_db_host }}" + DB_PORT: "{{ bbb_greenlight_db_port }}" + DB_NAME: "{{ bbb_greenlight_db_name }}" + DB_USERNAME: "{{ bbb_greenlight_db_username }}" + DB_PASSWORD: "{{ bbb_greenlight_db_password }}" + ENABLE_SSL: "{{ bbb_configure_ssl | bool | string | lower }}" + SECRET_KEY_BASE: "{{ bbb_greenlight_rails_secret }}" + BIGBLUEBUTTON_ENDPOINT: "{{ bbb_greenlight_extracted_endpoint }}" + BIGBLUEBUTTON_SECRET: "{{ bbb_greenlight_extracted_secret }}" diff --git a/tasks/greenlight.yml b/tasks/greenlight.yml new file mode 100644 index 0000000..6212781 --- /dev/null +++ b/tasks/greenlight.yml @@ -0,0 +1,233 @@ +--- +- name: Enable https support for apt + apt: + name: apt-transport-https + state: present + tags: + - apt_transport_https + - docker + +- name: Check Docker apt key is present + apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + tags: + - docker-apt_key + - docker + +- name: Check Docker repo is enabled + apt_repository: repo="deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable" state=present + tags: + - docker-repositories + - repositories + - docker + +- name: Check Docker packages are installed + apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + tags: + - install_docker + - docker + +- name: Enable Docker daemon on startup + systemd: name="docker" enabled=True state="started" + tags: + - enable_docker + - docker + +- name: Set download location for desired docker-compose version + set_fact: + docker_compose_download_url: https://github.com/docker/compose/releases/download/{{ docker_compose_version }}/docker-compose-Linux-x86_64 + when: docker_compose_version is defined and docker_compose_version != "latest" + tags: + - docker-compose + +- name: Determine latest upstream release for docker-compose + uri: + url: https://api.github.com/repos/docker/compose/releases/latest + register: docker_compose_latest_json + when: docker_compose_download_url is undefined + tags: + - docker-compose + +- name: Extract download location for latest docker-compose + set_fact: + docker_compose_download_url: "{{ docker_compose_latest_json.json.assets | selectattr('name', 'equalto', 'docker-compose-Linux-x86_64') | map(attribute='browser_download_url') | first | string }}" + when: docker_compose_download_url is undefined + tags: + - docker-compose + +- name: Install up-to-date docker-compose + get_url: + url: "{{ docker_compose_download_url }}" + dest: "/usr/local/bin/docker-compose" + owner: root + group: root + mode: 0755 + force: true + tags: + - docker-compose + +- name: Remove outdated docker-compose from distribution + apt: + name: docker-compose + state: absent + tags: + - docker-compose + +- name: Create greenlight directories + file: + path: "{{ item }}" + state: directory + owner: root + group: root + mode: 0755 + loop: + - "{{ bbb_greenlight_dbdir }}" + - "{{ bbb_greenlight_etcdir }}" + - "{{ bbb_greenlight_logdir }}" + tags: + - greenlight-config + +- name: Examine BBB configuration + command: /usr/bin/bbb-conf --secret + register: bbb_conf_secret + tags: + - greenlight-config + +- name: Extract BBB endpoint and secret + set_fact: + bbb_greenlight_extracted_endpoint: "{{ bbb_conf_secret.stdout | regex_search('URL: (.*)', '\\1') | first }}" + bbb_greenlight_extracted_secret: "{{ bbb_conf_secret.stdout | regex_search('Secret: (.*)', '\\1') | first }}" + tags: + - greenlight-config + +- name: Check if greenlight secret file exists + stat: + path: "{{ bbb_greenlight_etcdir }}/.rails.secret" + register: bbb_greenlight_rails_secret_file + tags: + - greenlight-config + +- name: Create new greenlight secret + command: docker run --rm {{ bbb_greenlight_image }} bundle exec rake secret + register: bbb_greenlight_rails_secret + when: not bbb_greenlight_rails_secret_file.stat.exists + tags: + - greenlight-config + +- name: Persist new secret to file + copy: + content: "{{ bbb_greenlight_rails_secret.stdout }}" + dest: "{{ bbb_greenlight_etcdir }}/.rails.secret" + mode: 0600 + owner: root + group: root + when: not bbb_greenlight_rails_secret_file.stat.exists + tags: + - greenlight-config + +- name: Read greenlight secret from file + command: cat "{{ bbb_greenlight_etcdir }}/.rails.secret" + register: bbb_greenlight_rails_secret_content + tags: + - greenlight-config + +- name: Transfer greenlight secret into proper variable + set_fact: + bbb_greenlight_rails_secret: "{{ bbb_greenlight_rails_secret_content.stdout }}" + tags: + - greenlight-config + +- name: Check if greenlight database secret file exists + stat: + path: "{{ bbb_greenlight_etcdir }}/.db.secret" + register: bbb_greenlight_db_secret_file + tags: + - greenlight-config + +- name: Create greenlight database password + set_fact: + bbb_greenlight_db_password: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}" + when: not bbb_greenlight_db_secret_file.stat.exists + tags: + - greenlight-config + +- name: Persist new database secret to file + copy: + content: "{{ bbb_greenlight_db_password }}" + dest: "{{ bbb_greenlight_etcdir }}/.db.secret" + mode: 0600 + owner: root + group: root + when: not bbb_greenlight_db_secret_file.stat.exists + tags: + - greenlight-config + +- name: Read greenlight database secret from file + command: cat "{{ bbb_greenlight_etcdir }}/.db.secret" + register: bbb_greenlight_db_secret_content + when: bbb_greenlight_db_secret_file.stat.exists + tags: + - greenlight-config + +- name: Transfer greenlight database secret into proper variable + set_fact: + bbb_greenlight_db_password: "{{ bbb_greenlight_db_secret_content.stdout }}" + when: bbb_greenlight_db_secret_file.stat.exists + tags: + - greenlight-config + +- name: Create greenlight docker-compose config + template: + src: templates/greenlight-docker-compose.yml.j2 + dest: "{{ bbb_greenlight_etcdir }}/docker-compose.yml" + owner: root + group: root + mode: 0600 + validate: /usr/local/bin/docker-compose -f %s config -q + register: greenlight_config + tags: + - greenlight-config + +- name: Create greenlight NGINX config stub + template: + src: templates/greenlight.nginx.j2 + dest: "/etc/bigbluebutton/nginx/greenlight.nginx" + owner: root + group: root + mode: 0644 + register: nginx_config + tags: + - greenlight-config + +- name: Restart NGINX to activate greenlight changes + systemd: + name: nginx + state: restarted + when: + nginx_config.changed + tags: + - greenlight-config + +- name: Create greenlight systemd unit file + template: + src: templates/greenlight.service.j2 + dest: /etc/systemd/system/greenlight.service + owner: root + group: root + mode: 0644 + tags: + - greenlight-service + +- name: Enable and start greenlight systemd service + systemd: + name: greenlight + enabled: true + state: "{{ 'restarted' if greenlight_config.changed else 'started' }}" + tags: + - greenlight-service diff --git a/tasks/main.yml b/tasks/main.yml index dc1bacc..1cc1a6d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -239,3 +239,8 @@ debug: msg="{{ bbb_check_out }}" tags: - bbb-check_install + +- include_tasks: greenlight.yml + when: bbb_install_greenlight == True + tags: + - greenlight diff --git a/templates/greenlight-docker-compose.yml.j2 b/templates/greenlight-docker-compose.yml.j2 new file mode 100644 index 0000000..06e012f --- /dev/null +++ b/templates/greenlight-docker-compose.yml.j2 @@ -0,0 +1,35 @@ +version: '3' + +services: + app: + entrypoint: [bin/start] + image: {{ bbb_greenlight_image }} + container_name: greenlight-v2 + restart: unless-stopped + ports: + - 127.0.0.1:5000:80 + environment: +{% set bbb_greenlight_environment_combined = bbb_greenlight_environment_defaults | combine(bbb_greenlight_environment) -%} +{% for envvar in bbb_greenlight_environment_combined %} + - {{ envvar }}={{ bbb_greenlight_environment_combined[envvar] }} +{% endfor %} + volumes: + - {{ bbb_greenlight_logdir }}:/usr/src/app/log +{% if bbb_greenlight_db_adapter == 'sqlite3' %} + - {{ bbb_greenlight_dbdir }}:/usr/src/app/db/production +{% endif %} +{% if bbb_greenlight_db_adapter == 'postgresql' and bbb_greenlight_db_host == 'db' %} + links: + - db + db: + image: postgres:9.5 + restart: unless-stopped + ports: + - 127.0.0.1:5432:{{ bbb_greenlight_db_port }} + volumes: + - {{ bbb_greenlight_dbdir }}:/var/lib/postgresql/data + environment: + - POSTGRES_DB={{ bbb_greenlight_db_name }} + - POSTGRES_USER="{{ bbb_greenlight_db_username }}" + - POSTGRES_PASSWORD="{{ bbb_greenlight_db_password }}" +{% endif %} diff --git a/templates/greenlight.nginx.j2 b/templates/greenlight.nginx.j2 new file mode 100644 index 0000000..eea4d34 --- /dev/null +++ b/templates/greenlight.nginx.j2 @@ -0,0 +1,32 @@ +# Routes requests to Greenlight based on the '/b' prefix. +# Use this file to route '/b' paths on your BigBlueButton server +# to the Greenlight application. If you are using a different +# subpath, you should change it here. + +location /b { + proxy_pass http://127.0.0.1:5000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; +} + +location /b/cable { + proxy_pass http://127.0.0.1:5000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_http_version 1.1; + proxy_read_timeout 6h; + proxy_send_timeout 6h; + client_body_timeout 6h; + send_timeout 6h; +} + +{% if bbb_greenlight_redirect_root %} +location = / { + return 307 /b; +} +{% endif %} diff --git a/templates/greenlight.service.j2 b/templates/greenlight.service.j2 new file mode 100644 index 0000000..804c602 --- /dev/null +++ b/templates/greenlight.service.j2 @@ -0,0 +1,16 @@ +# /etc/systemd/system/greenlight.service +[Unit] +Description=Greenlight Service +After=docker.service + +[Service] +Type=oneshot +RemainAfterExit=yes +StandardError=null +StandardOutput=null +WorkingDirectory={{ bbb_greenlight_libdir }} +ExecStart=/usr/local/bin/docker-compose -f {{ bbb_greenlight_etcdir }}/docker-compose.yml up -d +ExecStop=/usr/local/bin/docker-compose -f {{ bbb_greenlight_etcdir }}/docker-compose.yml down + +[Install] +WantedBy=multi-user.target