diff options
67 files changed, 1127 insertions, 258 deletions
@@ -37,9 +37,14 @@ vaulted_become_pass: "yourpasswordhere" To set the password for this console session: #+begin_src sh :eval no - export ANSIBLE_PASSWORD=... + export VAULT_PASSWORD=... #+end_src +To change the password for a file: + +#+begin_src sh :eval no +ansible-vault rekey $FILE --ask-vault-pass +#+end_src * Processes @@ -52,7 +57,7 @@ To start a local copy of the wiki for testing, see [[#wiki-docker][Ikiwiki - Doc ** Ikiwiki *** Prod -When you update htmlscrubber.pm in wiki/templates: +When you update htmlscrubber.pm in wiki/templates or emacsconf.setup: ansible-playbook -i inventory.yml prod-playbook.yml --tags wiki-plugins ansible-playbook -i docker-inventory.yml docker-reuse-playbook.yml --tags wiki-plugins @@ -109,6 +114,7 @@ ssh ikiwiki@localhost -p 2222 ikiwiki --setup /home/ikiwiki/emacsconf.setup -v 3. Export the talks.json with =M-x emacsconf-ansible-export-talks=. 4. ansible-playbook -i inventory.yml prod-playbook.yml --tags prerec 5. ansible-playbook -i inventory.yml prod-playbook.yml --tags caption +6. ansible-playbook -i inventory.yml local-playbook.yml When you receive a file, create a directory for it named =~/current/files/$slug=. Copy the uploaded file as =$video_slug--original.$extension=, or use =rename-original.sh $slug $file=. @@ -123,6 +129,9 @@ Then call =process-prerec.sh $file=. It will launch some screen sessions for ree 3. Update the following variables in your Emacs configuration: - emacsconf-backstage-dir - emacsconf-backstage-phase +4. Create ~/proj/emacsconf/{year}/cache +5. elisp:emacsconf-publish-talks-json-to-files +6. [[elisp:emacsconf-publish-backstage-index]] * Upload service =ansible-playbook -i inventory.yml prod-playbook.yml --tags upload --ask-become-pass= @@ -169,7 +178,7 @@ ansible-playbook playbook.yml -e '{"slug": "wayland"}' -i inventory.yml --tags p Force-publish the schedule: ansible-playbook -i inventory.yml prod-playbook.yml --tags publish -e force_publish=true - +** Development ** Docker Creating: ansible-playbook -i docker-inventory.yml docker-playbook.yml --tags wiki,publish @@ -180,6 +189,9 @@ ansible-playbook -i docker-inventory.yml docker-reuse-playbook.yml --tags publis With docker: https://stackoverflow.com/questions/24738264/how-to-test-ansible-playbook-using-docker * Pad + +Before generating pads, use elisp:emacsconf-publish-talks-json-to-files to create the talks.json used. + ** Production ansible-playbook -i inventory.yml prod-playbook.yml --tags pad,proxy @@ -194,6 +206,8 @@ ansible-playbook -i inventory.yml prod-playbook.yml --tags proxy To prepare for a load test: ansible-playbook -i inventory.yml prod-playbook.yml --tags pad --extra-vars='{"etherpad_load_test": true}' +To create pads: +ansible-playbook -i inventory.yml prod-playbook.yml --tags create-pads ** Docker Creating: ansible-playbook -i docker-inventory.yml docker-playbook.yml --tags pad @@ -289,9 +303,9 @@ For each track: // ==UserScript== // @name Emacsconf BBB setup // @namespace https://emacsconf.org/ - // @version 0.1 + // @version 0.2 // @description Join BBB and set things up - // @author You + // @author Sacha Chua // @match https://bbb.emacsverse.org/* // @icon https://www.google.com/s2/favicons?sz=64&domain=emacsverse.org // @grant none @@ -319,14 +333,34 @@ For each track: }, interval); }); } - if (document.querySelector('input.join-form')) { - document.querySelector('input.join-form').value = NAME; - document.querySelector('#room-join').click(); - return; - } - await waitUntil(() => document.querySelector('.icon-bbb-listen')).then((e) => e.closest('button').click()); - await waitUntil(() => document.querySelector('.icon-bbb-user')).then((e) => e.closest('button').click()); - })(); + // https://stackoverflow.com/questions/66536154/changing-input-text-of-a-react-app-using-javascript + function setNativeValue(element, value) { + const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set; + const prototype = Object.getPrototypeOf(element); + const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set; + + if (valueSetter && valueSetter !== prototypeValueSetter) { + prototypeValueSetter.call(element, value); + } else { + valueSetter.call(element, value); + } + } + setTimeout(function() { + if (document.querySelector('input#joinFormName')) { + setNativeValue(document.querySelector('input#joinFormName'), NAME); + document.querySelector('input#joinFormName').dispatchEvent(new Event('input', { bubbles: true })); + document.querySelector('input#consentCheck').click() + document.querySelector('button[type="submit"]').click(); + return; + } + if (document.querySelector('.icon-bbb-listen')) { + document.querySelector('.icon-bbb-listen').closest('button').click(); + } + if (document.querySelector('.icon-bbb-user')) { + document.querySelector('.icon-bbb-user').closest('button').click(); + } + }, 2000); + })(); #+end_src Press =Ctrl+s= to save. @@ -367,6 +401,8 @@ ansible-playbook -i inventory.yml prod-playbook.yml --tags obs-scene * Media ansible-playbook -i inventory.yml prod-playbook.yml --tags media + + * Captioning Set up whisper: @@ -381,3 +417,49 @@ ffmpeg -y -i handwritten/reencode.webm -t 60 -vcodec copy -acodec copy test.webm * Other useful things nodemon -w . -e yml -x 'ansible-playbook -i inventory.yml prod-playbook.yml --tags vnc; true' + +* Restreaming + +Add something like this to your ~prod-vars.yml~: + +#+begin_src emacs-lisp +restreaming_platforms: + - name: youtube + streams: + - name: gen + key: xxxx-xxxx-xxxx-xxxx-xxxx + url: https://www.youtube.com/watch?v=xxxxxxxxxxx + studio: https://studio.youtube.com/video/xxxxxxxxxxx/livestreaming + source: gen.webm + - name: dev + key: xxxx-xxxx-xxxx-xxxx-xxxx + url: https://www.youtube.com/watch?v=xxxxx-xxxxx + studio: https://studio.youtube.com/video/xxxxx-xxxxx/livestreaming + source: dev.webm + - name: test + key: xxxx-xxxx-xxxx-xxxx-xxxx + studio: https://studio.youtube.com/video/xxxxxxxxxxx/livestreaming + url: https://youtu.be/xxxxxxxxxxx + source: gen.webm + stream_url: rtmp://a.rtmp.youtube.com/live2 + backup_stream: rtmp://b.rtmp.youtube.com/live2?backup=1 + - name: toobnix + stream_url: rtmp://toobnix.org:1935/live + streams: + - name: gen + key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + url: https://toobnix.org/w/xxxxxxxxxxxxxxxxxxxxxx + source: gen.webm + - name: dev + key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + url: https://toobnix.org/w/xxxxxxxxxxxxxxxxxxxxxx + source: dev.webm + - name: test + key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + url: https://toobnix.org/w/xxxxxxxxxxxxxxxxxxxxxx + source: gen.webm +#+end_src + +It doesn't get automatically started, so you'll also need to call ~screen -S restream-$TRACK_ID-youtube~ and ~screen -S restream-$TRACK_ID-toobnix~. +* BBB +ansible-playbook -i inventory.yml prod-playbook.yml --tags bbb diff --git a/common-playbook.yml b/common-playbook.yml index 2822e41..ed0f552 100644 --- a/common-playbook.yml +++ b/common-playbook.yml @@ -1,5 +1,5 @@ - name: Set up wiki - hosts: front + hosts: wiki tags: wiki roles: - wiki @@ -56,6 +56,11 @@ tags: media roles: - media +# - name: Set up BigBlueButton +# hosts: bbb +# tags: bbb +# roles: +# - bbb - name: Set up OBS hosts: obs tags: obs diff --git a/group_vars/all.yml b/group_vars/all.yml index 82d4c77..45bb6fd 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -2,7 +2,7 @@ docker: false res_x: 1280 res_y: 720 fps: 30 -emacsconf_year: 2023 +emacsconf_year: 2024 emacsconf_name: EmacsConf emacsconf_id: emacsconf emacsconf_user: orga @@ -34,8 +34,11 @@ emacs_config_dir: ~{{ emacsconf_user }}/.emacs.d emacsconf_el_dir: ~{{ emacsconf_user }}/emacsconf-el emacsconf_edit_wiki_dir: ~{{ emacsconf_user }}/emacsconf-wiki emacsconf_private_dir: ~{{ emacsconf_user }}/emacsconf-{{ emacsconf_year }}-private -emacsconf_caption_dir: /data/emacsconf/{{ emacsconf_year }} +emacsconf_caption_dir: /data/emacsconf/shared/{{ emacsconf_year }} emacsconf_timezone: US/Eastern etherpad_server_name: pad.emacsconf.org +emacsconf_qa_start_open: true test_mode: false media_protect_root: true +protect_stream_with_password: false +restreaming_platforms: [] diff --git a/host_vars/media/plain b/host_vars/media/plain new file mode 100644 index 0000000..e9f3e32 --- /dev/null +++ b/host_vars/media/plain @@ -0,0 +1 @@ +ansible_become_pass: "{{ vaulted_become_pass }}" diff --git a/host_vars/upload/plain b/host_vars/upload/plain new file mode 100644 index 0000000..e9f3e32 --- /dev/null +++ b/host_vars/upload/plain @@ -0,0 +1 @@ +ansible_become_pass: "{{ vaulted_become_pass }}" diff --git a/inventory.yml b/inventory.yml index 6d87c8f..76d796e 100644 --- a/inventory.yml +++ b/inventory.yml @@ -6,6 +6,13 @@ prod: ansible_become: true emacsconf_group: org cpus: 12 + bbb: + ansible_host: bbb.emacsverse.org + ansible_python_interpreter: /usr/bin/python3 + ansible_become: true + ansible_ssh_user: root + emacsconf_group: org + cpus: 4 publish: ansible_host: res.emacsconf.org ansible_python_interpreter: /usr/bin/python3 @@ -24,6 +31,12 @@ prod: ansible_ssh_user: orga ansible_python_interpreter: /usr/bin/python3 ansible_become: true + wiki: + ansible_host: front0.emacsconf.org + remote_user: orga + ansible_ssh_user: orga + ansible_python_interpreter: /usr/bin/python3 + ansible_become: true pad: ansible_host: front0.emacsconf.org remote_user: orga diff --git a/local-playbook.yml b/local-playbook.yml index 37cd294..8875a2b 100644 --- a/local-playbook.yml +++ b/local-playbook.yml @@ -10,7 +10,11 @@ tasks: - include_vars: file: local-vars.yml -- name: Set up Emacs +# - name: Set up Emacs +# hosts: localhost +# roles: +# - wiki-publish +- name: Set up cache directory hosts: localhost roles: - - wiki-publish + - local diff --git a/roles/base/files/keys/sachac b/roles/base/files/keys/sachac index 999b59c..643bd03 100644 --- a/roles/base/files/keys/sachac +++ b/roles/base/files/keys/sachac @@ -1,2 +1,3 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDK0Vg112xS0SAuCutincht2LWs+2jC8EWC19Irotv8M0ztzLf6wmXEw0xoB8D78LKzXGC/gFcIvYzsNezHFpU5PmlxYBRJkdOYH2zYfnlWQFpJKmk1OelTrugaRE4HywXurf6q6Sot5hzbzPmCWgOlBZshnkDXMAyPCfYvL+RcwTRJWiaiGwwDHlfHCkebr4cwypRQ7Nl2kKajdp4wZXwbuP64pPNMmftZEMEM910w3zPnzQTil4IuLSiVC8K7TSk6xsnrsk10Y6zfoaHkZ71OD58rqPPFqeHYDj8SAvp6W4hHwakbf+r8nfRfr8Tc+gtCf0B6a4Y050OI5FxHlmjh +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCM41Zid5BjgXwEEnuSSLDvuWDqs3FXPAGwWxV9aY4uHb21+05rsbgAddXtxfj3kJd9tOz97nz5zEyet5bMiOxrh0w7R/LRMCRtiCerVd8ABpDnRJ1INXgAO0tOudVpmBwwDPp2njUbNW+POPBD6s5TXINPFK/V2bjTXkuYhmO4/6QS4OJZYMjugkqxk+JjMtF/e2+HR6UPAWXXyKRTPOQlfSQre/+bWSkU41oONuy4kXeXjiB+zQxRvcHptH+bk0v37jUWPN6PKSCoAlKPXxvGM86eDRF+Rs2fr7WJpkhsuVHaiVla6kBhaEKb9tDpSPg9twJZtl5si4cCEG8kP3Cv sachac-surface ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyMf4V8eCzYNEde8xG4tIJPBv8NwoTzyRG9O5+Bl69osaHV7OZQz81wXil1qZ/xrUu6fc5jMkxq7j5KCCs2MF6gMq12UKe9ESKYe5i+jFL7+V6JNQqcjLcyaEfEFtFCJ95nWCQWpXrMPijvpB3+YxLspFOTz8ZJsGENXU+Rkz5EIdx2VTgHUbddCjE5jndIO58uPKmR4EpMeUWxb20xYLpOwM14aGF/ERVjI++dIwu7mc21kxg42HJjRA/NRV48IxrGl57KKzl7qtMrqwp+ucoLWw4PdqHk4/tApjmrgLiJzLpSZx/4LL3mHTg3I6w9fC5yTgk3k6rJFomb2Jbboxx diff --git a/roles/bbb/README.md b/roles/bbb/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/roles/bbb/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/bbb/defaults/main.yml b/roles/bbb/defaults/main.yml new file mode 100644 index 0000000..17c44b0 --- /dev/null +++ b/roles/bbb/defaults/main.yml @@ -0,0 +1,4 @@ +bbb_docker_repo_dir: /data/emacsconf/shared/bbb-docker-repo +bbb_docker_dir: /data/emacsconf/shared/bbb-docker +bbb_domain: bbb.emacsverse.org +bbb_ip: 207.66.177.26 diff --git a/roles/bbb/handlers/main.yml b/roles/bbb/handlers/main.yml new file mode 100644 index 0000000..40aff70 --- /dev/null +++ b/roles/bbb/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for bbb diff --git a/roles/bbb/meta/main.yml b/roles/bbb/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/roles/bbb/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/bbb/tasks/main.yml b/roles/bbb/tasks/main.yml new file mode 100644 index 0000000..1a4b115 --- /dev/null +++ b/roles/bbb/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Create group + group: + name: "{{ emacsconf_group }}" + state: present +- name: Create user + user: + name: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" + state: present +- name: Add public key for authorized access + ansible.posix.authorized_key: + user: "{{ emacsconf_user }}" + state: present + key: '{{ item }}' + with_file: + - ../../base/files/keys/sachac + - ../../base/files/keys/orga diff --git a/roles/bbb/templates/env.template b/roles/bbb/templates/env.template new file mode 100644 index 0000000..65e8770 --- /dev/null +++ b/roles/bbb/templates/env.template @@ -0,0 +1,202 @@ +# ==================================== +# ADDITIONS to BigBlueButton +# ==================================== +# (place a '#' before to disable them) + +# HTTPS Proxy +# fully automated Lets Encrypt certificates +ENABLE_HTTPS_PROXY=true +# If your network doesn't allow access to DNS at 8.8.8.8 specify your own resolvers +#RESOLVER_ADDRESS=x.x.x.x + +# coturn (a TURN Server) +# requires either the abhove HTTPS Proxy to be enabled +# or TLS certificates to be mounted to container +ENABLE_COTURN=true +#COTURN_TLS_CERT_PATH= +#COTURN_TLS_KEY_PATH= + +# Greenlight Frontend +# https://docs.bigbluebutton.org/greenlight/gl-overview.html +ENABLE_GREENLIGHT=true + +# Enable Webhooks +# used by some integrations +#ENABLE_WEBHOOKS=true + +# Prometheus Exporter +# serves the bigbluebutton-exporter under following URL: +# https://yourdomain/bbb-exporter +#ENABLE_PROMETHEUS_EXPORTER=true +#ENABLE_PROMETHEUS_EXPORTER_OPTIMIZATION=true + +# Recording +# IMPORTANT: this is currently a big privacy issues, because it will +# record everything which happens in the conference, even when the button +# suggets, that it does not. +# https://github.com/bigbluebutton/bigbluebutton/issues/9202 +# make sure that you get peoples consent, before they join a room +ENABLE_RECORDING=true +#REMOVE_OLD_RECORDING=false +#RECORDING_MAX_AGE_DAYS=14 + +# ==================================== +# SECRETS +# ==================================== +# important! change these to any random values +SHARED_SECRET={{ bbb_shared_secret }} +ETHERPAD_API_KEY={{ bbb_etherpad_api_key }} +RAILS_SECRET={{ bbb_rails_secret }} +POSTGRESQL_SECRET={{ bbb_postgresql_secret }} +FSESL_PASSWORD={{ bbb_fsesl_password }} + + + +# ==================================== +# CONNECTION +# ==================================== + +DOMAIN={{ bbb_domain }} + +EXTERNAL_IPv4={{ bbb_ip }} +EXTERNAL_IPv6= + +# STUN SERVER +# stun.freeswitch.org +STUN_IP={{ bbb_ip }} +STUN_PORT=3478 + +# TURN SERVER +# uncomment and adjust following two lines to add an external TURN server +TURN_SERVER=turns:{{ bbb_domain }}:5349?transport=tcp +TURN_SECRET={{ bbb_turn_secret }} + +# Allowed SIP IPs +# due to high traffic caused by bots, by default the SIP port is blocked. +# but you can allow access by your providers IP or IP ranges (comma seperated) +# Hint: if you want to allow requests from every IP, you can use 0.0.0.0/0 +SIP_IP_ALLOWLIST= + + +# ==================================== +# CUSTOMIZATION +# ==================================== + +CLIENT_TITLE=BigBlueButton + +# use following lines to replace the default welcome message and footer +WELCOME_MESSAGE="Welcome to <b>%%CONFNAME%%</b>!<br><br>For help on using BigBlueButton see these (short) <a href='https://www.bigbluebutton.org/html5' target='_blank'><u>tutorial videos</u></a>.<br><br>To join the audio bridge click the speaker button. Use a headset to avoid causing background noise for others." +WELCOME_FOOTER="This server is running <a href='https://docs.bigbluebutton.org/'' target='_blank'><u>BigBlueButton</u></a>." + +# use following line for an additional SIP dial-in message +#WELCOME_FOOTER="This server is running <a href='https://docs.bigbluebutton.org/' target='_blank'><u>BigBlueButton</u></a>. <br><br>To join this meeting by phone, dial:<br> INSERT_YOUR_PHONE_NUMBER_HERE<br>Then enter %%CONFNUM%% as the conference PIN number." + +# for a different default presentation, place the pdf file in ./conf/ and +# adjust the following path +DEFAULT_PRESENTATION=./mod/nginx/default.pdf + +# language of sound announcements +# options: +# - en-ca-june - EN Canadian June +# - en-us-allison - US English Allison +# - en-us-callie - US English Callie (default) +# - de-de-daedalus3 - German by Daedalus3 (https://github.com/Daedalus3/freeswitch-german-soundfiles) +# - es-ar-mario - Spanish/Argentina Mario +# - fr-ca-june - FR Canadian June +# - pt-br-karina - Brazilian Portuguese Karina +# - ru-RU-elena - RU Russian Elena +# - ru-RU-kirill - RU Russian Kirill +# - ru-RU-vika - RU Russian Viktoriya +# - sv-se-jakob - Swedish (Sweden) Jakob +# - zh-cn-sinmei - Chinese/China Sinmei +# - zh-hk-sinmei - Chinese/Hong Kong Sinmei +SOUNDS_LANGUAGE=en-us-callie + +# set to false to disable listenOnlyMode +LISTEN_ONLY_MODE=true + +# set to true to disable echo test +DISABLE_ECHO_TEST=false + +# set to true to automatically share webcam +AUTO_SHARE_WEBCAM=false + +# set to true to disable video preview for webcam sharing +DISABLE_VIDEO_PREVIEW=false + +# set to false to disable chat +CHAT_ENABLED=true + +# set to true to start chat closed +CHAT_START_CLOSED=false + +# set to true to disable announcements "You are now (un-)muted" +DISABLE_SOUND_MUTED=false + +# set to true to disable announcement "You are the only person in this conference" +DISABLE_SOUND_ALONE=false + +# maximum count of breakout rooms per meeting +# Warning: increasing the limit of breakout rooms per meeting +# can generate excessive overhead to the server. We recommend +# this value to be kept under 12. +BREAKOUTROOM_LIMIT=8 + +# set to false to disable the learning dashboard +ENABLE_LEARNING_DASHBOARD=true + +# ==================================== +# Tuning +# ==================================== +# Default = 2; Min = 1; Max = 4 +# On powerful systems with high number of meetings you can set values up to 4 to accelerate handling of events +NUMBER_OF_BACKEND_NODEJS_PROCESSES=2 + +# Default = 2; Min = 1; Max = 8 +# Set a number between 1 and 4 times the value of NUMBER_OF_BACKEND_NODEJS_PROCESSES where higher number helps with meetings +# stretching the recommended number of users in BigBlueButton +NUMBER_OF_FRONTEND_NODEJS_PROCESSES=2 + + +# ==================================== +# GREENLIGHT CONFIGURATION +# ==================================== + +### SMTP CONFIGURATION +# Emails are required for the basic features of Greenlight to function. +# Please refer to your SMTP provider to get the values for the variables below +#SMTP_SENDER_EMAIL= +#SMTP_SENDER_NAME= +#SMTP_SERVER= +#SMTP_PORT= +#SMTP_DOMAIN=bbb.emacsverse.org +#SMTP_USERNAME= +#SMTP_PASSWORD= +#SMTP_AUTH= +#SMTP_STARTTLS_AUTO=true +#SMTP_STARTTLS=false +#SMTP_TLS=false +#SMTP_SSL_VERIFY=true + +### EXTERNAL AUTHENTICATION METHODS +# +#OPENID_CONNECT_CLIENT_ID= +#OPENID_CONNECT_CLIENT_SECRET= +#OPENID_CONNECT_ISSUER= +#OPENID_CONNECT_REDIRECT= + +# To enable hCaptcha on the user sign up and sign in, define these 2 keys +#HCAPTCHA_SITE_KEY= +#HCAPTCHA_SECRET_KEY= + +# Set these if you are using a Simple Storage Service (S3) +# Uncomment S3_ENDPOINT only if you are using a S3 OTHER than Amazon Web Service (AWS) S3. +#S3_ACCESS_KEY_ID= +#S3_SECRET_ACCESS_KEY= +#S3_REGION= +#S3_BUCKET= +#S3_ENDPOINT= + +# Define the default locale language code (i.e. 'en' for English) from the fallowing list: +# [en, ar, fr, es] +#DEFAULT_LOCALE=en diff --git a/roles/bbb/tests/inventory b/roles/bbb/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/bbb/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/bbb/tests/test.yml b/roles/bbb/tests/test.yml new file mode 100644 index 0000000..72d74f0 --- /dev/null +++ b/roles/bbb/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - bbb diff --git a/roles/bbb/vars/main.yml b/roles/bbb/vars/main.yml new file mode 100644 index 0000000..de701b8 --- /dev/null +++ b/roles/bbb/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for bbb diff --git a/roles/caption/tasks/main.yml b/roles/caption/tasks/main.yml index fea78f4..96b3198 100644 --- a/roles/caption/tasks/main.yml +++ b/roles/caption/tasks/main.yml @@ -6,19 +6,22 @@ - cmake - jq - inotify-tools + - pipx - name: Install whisper - ansible.builtin.pip: + community.general.pipx: name: git+https://github.com/openai/whisper.git - name: Install Python packages - ansible.builtin.pip: - name: - - lhotse - - webvtt-py - - tqdm - - torchaudio - - num2words + community.general.pipx: + name: "{{ item }}" + install_deps: true + loop: + - lhotse + - webvtt-py + - tqdm + - torchaudio + - num2words - name: Set up aeneas - include: aeneas.yml + include_tasks: aeneas.yml - name: Create group group: name: "{{ emacsconf_group }}" diff --git a/roles/caption/templates/process-captions.py b/roles/caption/templates/process-captions.py index a42439b..fde766c 100755 --- a/roles/caption/templates/process-captions.py +++ b/roles/caption/templates/process-captions.py @@ -114,8 +114,8 @@ def extract_audio(work): log("Extracting audio from %s acodec %s" % (work['video'], acodec)) output = subprocess.check_output(['ffmpeg', '-y', '-i', work['video'], '-acodec', acodec, '-vn', new_file], stderr=subprocess.STDOUT) work['audio'] = new_file - if os.path.isfile("/data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh"): - subprocess.call(["/data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh", work['audio']]) + if os.path.isfile("/data/emacsconf/admin/{{ emacsconf_year }}/scripts/upload.sh"): + subprocess.call(["/data/emacsconf/admin/{{ emacsconf_year }}/scripts/upload.sh", work['audio']]) return work def to_sec(time_str): @@ -150,8 +150,8 @@ def generate_captions(work): txt_writer(result, work['audio'], {'max_line_width': 60, 'max_line_count': None, 'highlight_words': None}) work['vtt'] = new_file work['txt'] = work['base'] + '.txt' - if os.path.isfile("/data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh"): - subprocess.call(["/data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh", work['vtt'], work['txt']]) + if os.path.isfile("/data/emacsconf/admin/{{ emacsconf_year }}/scripts/upload.sh"): + subprocess.call(["/data/emacsconf/admin/{{ emacsconf_year }}/scripts/upload.sh", work['vtt'], work['txt']]) if 'srv2' in work: del work['srv2'] return work diff --git a/roles/edit/templates/emacsconf-edit.el b/roles/edit/templates/emacsconf-edit.el index 195170a..603d0a3 100644 --- a/roles/edit/templates/emacsconf-edit.el +++ b/roles/edit/templates/emacsconf-edit.el @@ -84,6 +84,9 @@ (unless (and (boundp 'server-clients) server-clients) (server-start)) (find-file "{{ emacsconf_private_dir }}/conf.org") +(setq emacsconf-cache-dir "{{ emacsconf_caption_dir }}/cache") +(setq case-fold-search t) (emacsconf-add-org-after-todo-state-change-hook) +(setq emacsconf-publishing-phase 'conference) (unless noninteractive (emacsconf-erc-connect)) (setq tab-width 2) diff --git a/roles/live/tasks/main.yml b/roles/live/tasks/main.yml index 3e51765..8ff5903 100644 --- a/roles/live/tasks/main.yml +++ b/roles/live/tasks/main.yml @@ -7,17 +7,11 @@ loop: - "{{ emacsconf_year }}" - "{{ emacsconf_year }}/watch" -- name: Configure Nginx +- name: Set up nginx.conf template: src: live.emacsconf.org.conf dest: /etc/nginx/sites-available/live.emacsconf.org -- name: Make sure main configuration is enabled - file: - src: /etc/nginx/sites-available/live.emacsconf.org - dest: /etc/nginx/sites-enabled/live.emacsconf.org - force: no - state: link -- name: Reload configuration +- name: Reload nginx service: name: nginx state: reloaded diff --git a/roles/media/tasks/main.yml b/roles/media/tasks/main.yml index 8cd854d..e9daaef 100644 --- a/roles/media/tasks/main.yml +++ b/roles/media/tasks/main.yml @@ -11,6 +11,10 @@ file: path: /var/www/{{ media_server_name }}/{{ emacsconf_year }}/backstage state: directory +- name: Ensure current directory exists + file: + path: /var/www/{{ media_server_name }}/{{ emacsconf_year }}/current + state: directory - name: Create group group: name: "{{ emacsconf_group }}" @@ -68,3 +72,48 @@ service: name: nginx state: reloaded +- name: Symlink the current year's backstage directory + file: + src: /var/www/{{ media_server_name }}/{{ emacsconf_year }}/backstage + dest: "~{{ emacsconf_user }}/backstage" + owner: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" + state: link +- name: Symlink the current year's directory + file: + src: /var/www/{{ media_server_name }}/{{ emacsconf_year }} + dest: "~{{ emacsconf_user }}/{{ emacsconf_year }}" + owner: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" + state: link +- name: Symlink the current year's directory as current + file: + src: /var/www/{{ media_server_name }}/{{ emacsconf_year }} + dest: "~{{ emacsconf_user }}/current" + owner: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" + state: link +- name: Create the bin directory + tags: media-scripts + file: + state: directory + path: "~{{ emacsconf_user }}/bin" + owner: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" +- name: Add the bin directory to the path + tags: media-scripts + lineinfile: + dest: "~{{ emacsconf_user }}/.bashrc" + state: present + line: "export PATH=$PATH:~/bin" +- name: Create batch scripts + tags: media-scripts + template: + src: "{{ item }}" + dest: "~{{ emacsconf_user }}/bin/{{ item }}" + owner: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" + mode: 0755 + loop: + - bbb-open + - bbb-before diff --git a/roles/media/templates/nginx-include b/roles/media/templates/nginx-include index b42cacd..4d1eabe 100644 --- a/roles/media/templates/nginx-include +++ b/roles/media/templates/nginx-include @@ -1,22 +1,41 @@ rewrite ^/current/bbb-open.html$ {{ bbb_open_url }} redirect; location /{{ emacsconf_year }}/backstage { - auth_basic "Restricted"; - auth_basic_user_file /etc/nginx/sites-available/{{ media_server_name }}-{{ emacsconf_year }}-htpasswd; - autoindex on; - rewrite ^/{{ emacsconf_year }}/backstage/current/pad/([^/]*)$ https://{{ etherpad_server_name }}/{{ emacsconf_year }}-$1 redirect; - rewrite ^/{{ emacsconf_year }}/backstage/current/room/([^/]*)$ https://{{ media_server_name }}/{{ emacsconf_year }}/backstage/assets/redirects/open/bbb-$1.html redirect; - rewrite ^/{{ emacsconf_year }}/backstage/current/([^/]*)/pad/?$ https://{{ etherpad_server_name }}/{{ emacsconf_year }}-$1 redirect; - rewrite ^/{{ emacsconf_year }}/backstage/current/([^/]*)/room/?$ https://{{ media_server_name }}/{{ emacsconf_year }}/backstage/assets/redirects/open/bbb-$1.html redirect; - } + auth_basic "Restricted"; + auth_basic_user_file /etc/nginx/sites-available/{{ media_server_name }}-{{ emacsconf_year }}-htpasswd; + autoindex on; + rewrite ^/{{ emacsconf_year }}/backstage/current/pad/([^/]*)$ https://{{ etherpad_server_name }}/{{ emacsconf_year }}-$1 redirect; + rewrite ^/{{ emacsconf_year }}/backstage/current/room/([^/]*)$ https://{{ media_server_name }}/{{ emacsconf_year }}/backstage/assets/redirects/open/bbb-$1.html redirect; + rewrite ^/{{ emacsconf_year }}/backstage/current/([^/]*)/pad/?$ https://{{ etherpad_server_name }}/{{ emacsconf_year }}-$1 redirect; + rewrite ^/{{ emacsconf_year }}/backstage/current/([^/]*)/room/?$ https://{{ media_server_name }}/{{ emacsconf_year }}/backstage/assets/redirects/open/bbb-$1.html redirect; + add_header Cache-Control no-cache; + if_modified_since off; + expires off; + etag off; +} + location ~* \.vtt$ { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; + } + location /{{ emacsconf_year }}/{{ emacsconf_id }}.ics { - auth_basic off; - } + auth_basic off; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; +} location /{{ emacsconf_year }}/schedules/ { auth_basic off; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; } {% for track in emacsconf_tracks %} location /{{ emacsconf_year }}/{{ emacsconf_id }}-{{ track.id }}.ics { auth_basic off; + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; } {% endfor %} {% if media_protect_root %} diff --git a/roles/media/templates/nginx-site-config b/roles/media/templates/nginx-site-config index 4dbdaaa..ba25cba 100644 --- a/roles/media/templates/nginx-site-config +++ b/roles/media/templates/nginx-site-config @@ -2,4 +2,9 @@ server { listen 80; server_name {{ media_server_name }}; root /var/www/{{ media_server_name }}; -}
\ No newline at end of file + location ~* \.vtt$ { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; + } +} diff --git a/roles/obs/defaults/main.yml b/roles/obs/defaults/main.yml index 6eb9451..d95b900 100644 --- a/roles/obs/defaults/main.yml +++ b/roles/obs/defaults/main.yml @@ -3,5 +3,7 @@ ff_vcustom: rt cpu-used=5 threads=2 error-resilient=1 crf=30 g=120 minrate=1.5M ff_vbitrate: 1500 ff_vgopsize: 120 obs_profile_path: /home/{{ emacsconf_user }}/.config/obs-studio/basic/profiles -emacsconf_asset_dir: /data/{{ emacsconf_id }}/assets +emacsconf_asset_dir: /data/{{ emacsconf_id }}/shared/{{ emacsconf_year }}/assets mumble_server: mumble.emacsconf.org +background_music_dir: "{{ emacsconf_asset_dir }}/music" +background_music_volume: 30 diff --git a/roles/obs/tasks/main.yml b/roles/obs/tasks/main.yml index 249a0bb..5df7d56 100644 --- a/roles/obs/tasks/main.yml +++ b/roles/obs/tasks/main.yml @@ -49,9 +49,9 @@ dest: /etc/X11/xorg.conf - name: Set up MPV and MPVC tags: mpv - include: mpv.yml + include_tasks: mpv.yml - name: Set up track-specific things - include: track.yml + include_tasks: track.yml loop: "{{ emacsconf_tracks }}" - debug: var: emacsconf_home @@ -82,14 +82,29 @@ line: export TZ={{ emacsconf_timezone }} dest: "/home/{{ emacsconf_user }}/.bashrc" - name: Allow sudo from {{ emacsconf_user }} to the stream users + tags: obs-sudo become: true become_user: root - copy: - content: | - {% for item in emacsconf_tracks %} - {{ emacsconf_user }} ALL=({{ emacsconf_id }}-{{ item.id }}) NOPASSWD: ALL - {% endfor %} - dest: /etc/sudoers.d/50_emacsconf + community.general.sudoers: + name: "{{ emacsconf_user }}-{{ emacsconf_id }}-{{ item.id }}" + user: "{{ emacsconf_user }}" + runas: "{{emacsconf_id }}-{{ item.id }}" + commands: ALL + nopassword: true + with_items: + - "{{ emacsconf_tracks }}" +- name: Allow sudo from the stream users to the {{ emacsconf_user }} + tags: obs-sudo + become: true + become_user: root + community.general.sudoers: + name: "{{ emacsconf_id }}-{{ item.id }}-{{ emacsconf_user }}" + user: "{{emacsconf_id }}-{{ item.id }}" + runas: "{{ emacsconf_user }}" + commands: ALL + nopassword: true + with_items: + - "{{ emacsconf_tracks }}" - name: Create directories file: owner: "{{ emacsconf_user }}" @@ -106,9 +121,13 @@ loop: - overlay - music + - stop-music - play - play-with-intro - intro - bbb - pad + - handle-qa - handle-session + - reset-state + - rebroadcast diff --git a/roles/obs/tasks/obs-setup.yml b/roles/obs/tasks/obs-setup.yml index 5b0fba4..4e53e8c 100644 --- a/roles/obs/tasks/obs-setup.yml +++ b/roles/obs/tasks/obs-setup.yml @@ -71,11 +71,3 @@ loop: - obs-track - obs-cli-track -- name: Fix permissions - become: true - become_user: root - file: - path: "~{{ emacsconf_user }}" - owner: "{{ emacsconf_user }}" - group: "{{ emacsconf_group }}" - recurse: true diff --git a/roles/obs/tasks/track.yml b/roles/obs/tasks/track.yml index d615336..cbd4b39 100644 --- a/roles/obs/tasks/track.yml +++ b/roles/obs/tasks/track.yml @@ -9,10 +9,15 @@ var: emacsconf_home - name: Set up user tags: obs-track-scripts - include: user.yml + include_tasks: user.yml - name: Set up user-related things become_user: "{{ emacsconf_user }}" block: + - name: Set up symlink to current + file: + src: "~{{ old_emacsconf_user }}/current" + dest: "~{{ emacsconf_user }}/current" + state: link - name: Set up track bins for addition to paths file: path: "~{{ emacsconf_user }}/bin/{{ item.id }}" @@ -20,7 +25,7 @@ group: "{{ emacsconf_group }}" state: directory - name: Set up VNC - include: tigervnc.yml + include_tasks: tigervnc.yml - name: Create MPV profile directory file: path: "~{{ emacsconf_user }}/.config/mpv" @@ -65,7 +70,7 @@ # shell: jackd -r -ddummy # async: 2592000 - name: Set up pulse - include: pulse.yml + include_tasks: pulse.yml tags: pulse - name: Set up I3 directory file: @@ -95,10 +100,10 @@ group: "{{ emacsconf_group }}" - name: Set up Emacs configuration tags: wip - include: emacs.yml + include_tasks: emacs.yml - name: Set up symbolic links file: - src: "/data/{{ emacsconf_id }}/assets/stream" + src: "/data/{{ emacsconf_id }}/shared/{{ emacsconf_year }}/assets/stream" dest: "~{{ emacsconf_user }}/stream" state: link diff --git a/roles/obs/templates/bbb b/roles/obs/templates/bbb index c12702c..b7c508f 100755 --- a/roles/obs/templates/bbb +++ b/roles/obs/templates/bbb @@ -3,17 +3,13 @@ # {{ ansible_managed }} # Kill the background music if playing -if screen -list | grep -q background; then - screen -S background -X quit -fi +/usr/local/bin/reset-state # Update the overlay SLUG=$1 overlay $SLUG -killall -s TERM firefox-esr firefox https://media.emacsconf.org/{{ emacsconf_year }}/backstage/assets/redirects/open/bbb-$SLUG.html & sleep 5 -xdotool search --class firefox windowactivate --sync xdotool key Return xdotool key F11 wait diff --git a/roles/obs/templates/emacsconf-stream-config.el b/roles/obs/templates/emacsconf-stream-config.el index bd5ffd7..2aa886b 100644 --- a/roles/obs/templates/emacsconf-stream-config.el +++ b/roles/obs/templates/emacsconf-stream-config.el @@ -13,7 +13,9 @@ (setq emacsconf-stream-track "{{ item.name }}") (autoload 'text-property-search-forward "text-property-search") (add-to-list 'load-path "~/emacsconf-el") +(setq tab-width 2) +(setq case-fold-search t) +(setq emacsconf-cache-dir "{{ emacsconf_caption_dir }}/cache") (require 'emacsconf) (require 'emacsconf-stream) (emacsconf-stream-display-clock-and-countdown) -(setq tab-width 2) diff --git a/roles/obs/templates/i3-config b/roles/obs/templates/i3-config index 1787b64..31a7b40 100644 --- a/roles/obs/templates/i3-config +++ b/roles/obs/templates/i3-config @@ -23,7 +23,7 @@ font pango:monospace 8 # xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the # screen before suspend. Use loginctl lock-session to lock your screen. -exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork +# exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork # NetworkManager is the most popular way to manage wireless networks on Linux, # and nm-applet is a desktop environment-independent system tray GUI for it. diff --git a/roles/obs/templates/intro b/roles/obs/templates/intro index bf02dc3..7af9c4c 100755 --- a/roles/obs/templates/intro +++ b/roles/obs/templates/intro @@ -8,7 +8,7 @@ fi SLUG=$1 FILE=$1 if [[ ! -f $FILE ]]; then - LIST=({{ emacsconf_caption_dir }}/assets/stream/emacsconf-{{ emacsconf_year }}-$FILE--*.webm) + LIST=({{ emacsconf_caption_dir }}/cache/emacsconf-{{ emacsconf_year }}-$FILE--*.webm) FILE="${LIST[0]}" BY_SLUG=1 else @@ -16,8 +16,8 @@ else fi shift overlay $SLUG -if [[ -f {{ emacsconf_caption_dir }}/assets/intros/$SLUG.webm ]]; then - mpv {{ emacsconf_caption_dir }}/assets/intros/$SLUG.webm +if [[ -f "$FILE" ]]; then + mpv "$FILE" else firefox {{ emacsconf_caption_dir }}/assets/in-between/$SLUG.png fi diff --git a/roles/obs/templates/music b/roles/obs/templates/music index 29c5ddb..a5a6a31 100755 --- a/roles/obs/templates/music +++ b/roles/obs/templates/music @@ -1,5 +1,5 @@ if screen -list | grep -q background; then echo "Already running in screen, attach with screen -x background" else - screen -dmS background /bin/bash -c "mpv ~/stream/background.wav --loop=yes" + screen -dmS background /bin/bash -c "mpv {{ background_music_dir }}/* --shuffle --loop-playlist=inf --volume={{ background_music_volume }}" fi diff --git a/roles/obs/templates/overlay b/roles/obs/templates/overlay index 1361884..0836a59 100755 --- a/roles/obs/templates/overlay +++ b/roles/obs/templates/overlay @@ -3,20 +3,20 @@ SLUG=$(echo "$1" | perl -ne 'if (/emacsconf-[0-9]*-(.*?)--/) { print $1; } else { print; }') -if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.svg.png ]]; then +if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.png ]]; then echo "Found other overlay for $SLUG, copying" - cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.svg.png ~/other.png -elif [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ]]; then + cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.png ~/other.png +elif [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ]]; then echo "Found video overlay for $SLUG, copying" - cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ~/other.png + cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ~/other.png else - echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.svg.png, please override ~/other.png manually" - cp {{ emacsconf_caption_dir }}/assets/overlays/blank-other.svg.png ~/other.png + echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.png, please override ~/other.png manually" + cp {{ emacsconf_caption_dir }}/assets/overlays/blank-other.png ~/other.png fi -if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ]]; then +if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ]]; then echo "Found video overlay for $SLUG, copying" - cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ~/video.png + cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ~/video.png else - echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png, override ~/video.png manually" - cp {{ emacsconf_caption_dir }}/assets/overlays/blank-video.svg.png ~/video.png + echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png, override ~/video.png manually" + cp {{ emacsconf_caption_dir }}/assets/overlays/blank-video.png ~/video.png fi diff --git a/roles/obs/templates/play b/roles/obs/templates/play index 20fd24c..69632d4 100755 --- a/roles/obs/templates/play +++ b/roles/obs/templates/play @@ -2,19 +2,60 @@ # Play intro if recorded, then play files # {{ ansible_managed }} -# Kill the background music if playing -if screen -list | grep -q background; then - screen -S background -X quit -fi +shopt -s nullglob + +# play-with-intro $SLUG +YEAR="{{ emacsconf_year }}" +BASE_DIR="{{ emacsconf_caption_dir }}" +CACHE_DIR="{{ emacsconf_caption_dir }}/cache" +FIREFOX_NAME=firefox-esr +SLUG=$1 +PREFIX=$(get-file-prefix $SLUG) +PREFER_LIVE=$(jq -r ".talks[] | select(.slug == \"$SLUG\") | .\"prefer-live\" " < "$BASE_DIR/talks.json") +/usr/local/bin/reset-state # Update the overlay -FILE=$1 -if [[ ! -f $FILE ]]; then - LIST=({{ emacsconf_caption_dir }}/assets/stream/emacsconf-{{ emacsconf_year }}-$FILE*--main.webm) +overlay $SLUG + +if [ "$PREFER_LIVE" = "t" ]; then + /usr/local/bin/bbb $SLUG + exit 0 +fi + +# Play the video if it exists. If it doesn't exist, switch to the BBB room and stop processing. +if [ "x$TEST_MODE" = "x" ]; then + LIST=($CACHE_DIR/{{ emacsconf_id }}-{{ emacsconf_year }}-$SLUG*--main.webm) +else + LIST=($BASE_DIR/assets/test/{{ emacsconf_id }}-{{ emacsconf_year }}-$SLUG*--main.webm) +fi + + +FILE="${LIST[0]}" +# No file in the stream directory; check for original files in the stream directory, then check the cache +NOSUB="" +if [[ ! -f "$FILE" ]]; then + # Is there a cache file or an original file? + LIST=($CACHE_DIR/{{ emacsconf_id }}-{{ emacsconf_year }}-$SLUG*--main.webm) FILE="${LIST[0]}" - BY_SLUG=1 + if [[ ! -f $FILE ]]; then + LIST=($CACHE_DIR/{{ emacsconf_id }}-{{ emacsconf_year }}-$SLUG*--original.*) + FILE="${LIST[0]}" + fi + echo "Candidate: " $FILE + SUBS=($CACHE_DIR/{{ emacsconf_id }}-{{ emacsconf_year }}-$SLUG*--main.vtt) + if [[ -f "${SUBS[0]}" ]]; then + if ! cat ${SUBS[0]} | head -1 | grep -q captioned ; then + echo "Skipping subtitles because they're not edited" + NOSUB="--sub-visibility=no" + else + NOSUB="--sub-visibility=yes" + fi + fi +fi + +if [[ -f "$FILE" ]]; then + screen -mS talk /bin/bash -c "mpv $NOSUB $FILE" +else + /usr/local/bin/bbb $SLUG + exit 0 fi -shift -SLUG=$(echo "$FILE" | perl -ne 'if (/emacsconf-[0-9]*-(.*?)--/) { print $1; } else { print; }') -overlay $SLUG -mpv $FILE $* & diff --git a/roles/obs/templates/play-with-intro b/roles/obs/templates/play-with-intro index 1b1b9a5..0390f8f 100755 --- a/roles/obs/templates/play-with-intro +++ b/roles/obs/templates/play-with-intro @@ -2,23 +2,21 @@ # Play intro if recorded, then play files # {{ ansible_managed }} -# Kill the background music if playing -if screen -list | grep -q background; then - screen -S background -X quit -fi +# play-with-intro $SLUG +YEAR="{{ emacsconf_year }}" +BASE_DIR="{{ emacsconf_caption_dir }}" +CACHE_DIR="{{ emacsconf_caption_dir }}/cache" +FIREFOX_NAME=firefox-esr +SLUG=$1 +PREFIX=$(get-file-prefix $SLUG) + +/usr/local/bin/reset-state # Update the overlay -FILE=$1 -if [[ ! -f $FILE ]]; then - LIST=({{ emacsconf_caption_dir }}/assets/stream/emacsconf-{{ emacsconf_year }}-$FILE*.webm) - FILE="${LIST[0]}" - BY_SLUG=1 -fi -shift -SLUG=$(echo "$FILE" | perl -ne 'if (/emacsconf-[0-9]*-(.*?)--/) { print $1; } else { print; }') -overlay $SLUG -# Play the video -if [[ -f {{ emacsconf_caption_dir }}/assets/intros/$SLUG.webm ]]; then - intro $SLUG -fi -mpv $FILE $* & +/usr/local/bin/overlay $SLUG + +# Play the intro if it exists. If it doesn't exist, switch to the intro slide and stop processing. + +/usr/local/bin/intro $SLUG + +/usr/local/bin/play $SLUG diff --git a/roles/obs/templates/set-overlay b/roles/obs/templates/set-overlay index 0b6712b..8a408bf 100644 --- a/roles/obs/templates/set-overlay +++ b/roles/obs/templates/set-overlay @@ -6,20 +6,20 @@ if [[ ! -f $FILE ]]; then fi shift SLUG=$(echo "$FILE" | perl -ne 'if (/^emacsconf-[0-9]*-(.*?)--/) { print $1; } else { print; }') -if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.svg.png ]]; then +if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.png ]]; then echo "Found other overlay for $SLUG, copying" - cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.svg.png ~/other.png -elif [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ]]; then + cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.png ~/other.png +elif [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ]]; then echo "Found video overlay for $SLUG, copying" - cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ~/other.png + cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ~/other.png else - echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.svg.png, please override ~/other.png manually" - cp {{ emacsconf_caption_dir }}/assets/overlays/blank-other.svg.png ~/other.png + echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-other.png, please override ~/other.png manually" + cp {{ emacsconf_caption_dir }}/assets/overlays/blank-other.png ~/other.png fi -if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ]]; then +if [[ -f {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ]]; then echo "Found video overlay for $SLUG, copying" - cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png ~/video.png + cp {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png ~/video.png else - echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.svg.png, override ~/video.png manually" - cp {{ emacsconf_caption_dir }}/assets/overlays/blank-video.svg.png ~/video.png + echo "Could not find {{ emacsconf_caption_dir }}/assets/overlays/$SLUG-video.png, override ~/video.png manually" + cp {{ emacsconf_caption_dir }}/assets/overlays/blank-video.png ~/video.png fi diff --git a/roles/obs/templates/xstartup-track b/roles/obs/templates/xstartup-track index e09c081..f2f6716 100755 --- a/roles/obs/templates/xstartup-track +++ b/roles/obs/templates/xstartup-track @@ -5,7 +5,7 @@ export PATH="/usr/local/bin:/usr/bin:/bin:{{ emacsconf_home }}/bin" xrdb $HOME/.Xresources pulseaudio --start pacmd set-default-sink qa -firefox file:///data/emacsconf/{{ emacsconf_year }}/index-{{ item.id }}.html & +firefox file:///data/emacsconf/admin/{{ emacsconf_year }}/index-{{ item.id }}.html & $HOME/bin/track-obs & mumble mumble://{{ emacsconf_id }}-{{ item.id }}@{{ mumble_server }}/{{ item.mumble_channel }} & termit & diff --git a/roles/pad/tasks/main.yml b/roles/pad/tasks/main.yml index 9851d66..b720b40 100644 --- a/roles/pad/tasks/main.yml +++ b/roles/pad/tasks/main.yml @@ -34,7 +34,7 @@ home: /home/etherpad shell: /bin/bash state: present -- include: mariadb.yml +- import_tasks: mariadb.yml become: true - name: Set up etherpad as the etherpad user tags: etherpad-src @@ -45,6 +45,7 @@ git: repo: https://github.com/ether/etherpad-lite.git dest: "{{ etherpad_path }}" + version: v1.9.7 depth: 1 - name: Configure etherpad template: diff --git a/roles/pad/vars/main.yml b/roles/pad/vars/main.yml deleted file mode 100644 index 981efa9..0000000 --- a/roles/pad/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# vars file for pad diff --git a/roles/prerec/tasks/main.yml b/roles/prerec/tasks/main.yml index 8144e28..a0a3cac 100644 --- a/roles/prerec/tasks/main.yml +++ b/roles/prerec/tasks/main.yml @@ -33,7 +33,7 @@ owner: "{{ emacsconf_user }}" group: "{{ emacsconf_group }}" - name: Recreate encoding script and backup old one - tags: process-prerec + tags: process-prerec, prerec-scripts template: src: "reencode.sh" dest: "{{ emacsconf_caption_dir }}/scripts/reencode.sh" @@ -41,8 +41,12 @@ group: "{{ emacsconf_group }}" backup: yes mode: 0775 +- name: Get UIDs + tags: process-prerec, prerec-scripts + getent: + database: passwd - name: Copy scripts for processing - tags: process-prerec + tags: process-prerec, prerec-scripts template: src: "{{ item }}" dest: "/usr/local/bin/{{ item }}" @@ -59,13 +63,16 @@ - reencode.sh - run-aeneas.sh - rename-original.sh + - copy-original.sh - mux-subs.sh - verify-main.sh - remux.sh + - get-file-prefix + - reencode-in-screen.sh - name: Copy Makefile + tags: process-prerec, prerec-scripts, prerec-make template: src: Makefile dest: "{{ emacsconf_caption_dir }}/cache/Makefile" owner: "{{ emacsconf_user }}" group: "{{ emacsconf_group }}" - diff --git a/roles/prerec/templates/Makefile b/roles/prerec/templates/Makefile index 94aa412..8579965 100644 --- a/roles/prerec/templates/Makefile +++ b/roles/prerec/templates/Makefile @@ -1,16 +1,121 @@ # {{ ansible_managed }} -PRERECS_FINAL := $(wildcard {{ emacsconf_id }}-*--final.webm) -PRERECS_MAIN := $(patsubst %--final.webm, %--main.webm, $(PRERECS_FINAL)) +# To recreate this file, use ansible-playbook -i inventory.yml prod-playbook.yml --tags prerec-make + +VIDEO_EXTS = mp4 mkv webm mov +source_patterns = $(foreach ext,$(VIDEO_EXTS),$(1)--original.$(ext)) + +PRERECS_ORIGINAL := $(wildcard emacsconf-*--original.*) +PREFIXES := $(shell for f in $(PRERECS_ORIGINAL); do echo "$${f%--original.*}"; done) +PRERECS_REENCODED := $(addsuffix --reencoded.webm, $(PREFIXES)) +PRERECS_OPUS := $(addsuffix --reencoded.opus, $(PREFIXES)) +PRERECS_NORMAL := $(addsuffix --normalized.opus, $(PREFIXES)) +PRERECS_MAIN := $(addsuffix --main.webm, $(PREFIXES)) +PRERECS_CAPTIONS := $(addsuffix --reencoded.vtt, $(PREFIXES)) +PRERECS_FINAL := $(wildcard emacsconf-*--final.webm) +LINODE_BBB_ID := 67329098 .PHONY: all -all: $(PRERECS_MAIN) $(PRERECS_FINAL) -emacsconf-%--main.webm: {{ emacsconf_id }}-%--final.webm +all: reencoded opus normal main + +reencoded: $(PRERECS_REENCODED) + +opus: $(PRERECS_OPUS) + +normal: $(PRERECS_NORMAL) + +captions: $(PRERECS_CAPTIONS) + +main: $(PRERECS_MAIN) + +emacsconf-%--reencoded.webm: SOURCES = $(call source_patterns, emacsconf-$*) +emacsconf-%--reencoded.webm: + $(eval SOURCE := $(lastword $(sort $(wildcard $(SOURCES))))) + @if [ -z "$(SOURCE)" ]; then \ + echo "No source file found for $@"; \ + echo "Tried: $(SOURCES)"; \ + exit 1; \ + fi + @echo "Using source: $(SOURCE)" + ./reencode-in-screen.sh "$(SOURCE)" + +emacsconf-%--reencoded.opus: emacsconf-%--reencoded.webm + ffmpeg -y -i "$<" -c:a copy "$@" + +emacsconf-%--answers.opus: emacsconf-%--answers.webm + ffmpeg -y -i "$<" -c:a copy "$@" + +# emacsconf-%--normalized.opus: emacsconf-%--reencoded.opus +# ffmpeg-normalize "$<" -ofmt opus -c:a libopus -o "$@" + +emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--normalized.opus emacsconf-%--main.vtt + ffmpeg -i emacsconf-$*--reencoded.webm -i emacsconf-$*--normalized.opus -i emacsconf-$*--main.vtt \ + -map 0:v -map 1:a -c:v copy -c:a copy \ + -map 2 -c:s webvtt -y \ + $@ + +emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--normalized.opus + ffmpeg -i emacsconf-$*--reencoded.webm -i emacsconf-$*--normalized.opus \ + -map 0:v -map 1:a -c:v copy -c:a copy \ + -y $@ + +emacsconf-%--main.webm: emacsconf-%--reencoded.webm cp "$<" "$@" -emacsconf-%--final.webm: {{ emacsconf_id }}-%--main.vtt +emacsconf-%--final.webm: emacsconf-%--main.vtt mux-subs.sh "$@" "$<" +emacsconf-%--main.opus: emacsconf-%--main.webm + ffmpeg -y -i "$<" -c:a copy "$@" + +emacsconf-%--reencoded.vtt: emacsconf-%--reencoded.opus + whisperx --model large-v2 --align_model WAV2VEC2_ASR_LARGE_LV60K_960H --compute_type int8 --print_progress True --max_line_width 50 --segment_resolution chunk --max_line_count 1 --language en "$<" + +emacsconf-%--backstage--silences.csv: emacsconf-%--reencoded.opus + ffmpeg -i "$<" -af silencedetect=noise=-30dB:d=0.5 -f null - 2>&1 | awk '/silence_start/ {start=$$NF} /silence_end/ {print start "," (start + $$NF)}' > "$@" + +show-files: + @echo "Original $(words $(PRERECS_ORIGINAL)):" + @echo "$(PRERECS_ORIGINAL)" + @echo "Prefixes $(words $(PREFIXES)):" + @echo "$(PREFIXES)" + @echo "Reencoded $(words $(PRERECS_REENCODED)):" + @echo "$(PRERECS_REENCODED)" + @echo "Opus $(words $(PRERECS_OPUS)):" + @echo "$(PRERECS_OPUS)" + +bbb-testing: + @echo "Resizing BBB node to 8GB 4 core for testing" + linode-cli linodes resize $(LINODE_BBB_ID) --type g6-standard-4 --allow_auto_disk_resize false + sleep 2m + @echo "Booting up" + linode-cli linodes boot $(LINODE_BBB_ID) + ssh root@bbb.emacsverse.org "cd ~/greenlight-v3; docker compose restart" + +bbb-dormant: + @echo "Shutting down" + ssh root@bbb.emacsverse.org "/usr/sbin/shutdown -h now &" || true + sleep 30 + @echo "Powering off BBB node" + linode-cli linodes shutdown $(LINODE_BBB_ID) + sleep 30 + @echo "Resizing BBB node to nanode, dormant" + linode-cli linodes resize $(LINODE_BBB_ID) --type g6-nanode-1 --allow_auto_disk_resize false + +bbb-prod: + @echo "Resizing BBB node to production size" + linode-cli linodes resize $(LINODE_BBB_ID) --type g6-dedicated-8 --allow_auto_disk_resize true + sleep 2m + @echo "Booting up" + linode-cli linodes boot $(LINODE_BBB_ID) + +live-dormant: + @echo "Resizing live0 node to nanode, dormant" + linode-cli linodes resize 17921960 --type g6-nanode-1 --allow_auto_disk_resize false + sleep 120 + linode-cli linodes boot 17921960 + + rsync: rsync -avzue ssh {{ emacsconf_caption_dir }}/cache/ orga@media.emacsconf.org:/var/www/media.emacsconf.org/{{ emacsconf_year }}/backstage/ diff --git a/roles/prerec/templates/copy-original.sh b/roles/prerec/templates/copy-original.sh new file mode 100755 index 0000000..854bdb8 --- /dev/null +++ b/roles/prerec/templates/copy-original.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# {{ ansible_managed }} +# Usage: rename-original.sh $slug $file [$extra] +SLUG=$1 +FILE=$2 +EXTRA="" +if [ -z ${3-unset} ]; then + EXTRA="" +elif [ -n "$3" ]; then + EXTRA="$3" +elif echo "$FILE" | grep -e '\(webm\|mp4\|mov\)'; then + EXTRA="--original" +fi +filename=$(basename -- "$FILE") +extension="${filename##*.}" +filename="${filename%.*}" +FILE_PREFIX=$(get-file-prefix $SLUG) +if echo "$FILE" | grep -q \\. ; then + cp "$FILE" $FILE_PREFIX$EXTRA.$extension + echo $FILE_PREFIX$EXTRA.$extension +else + cp "$FILE" $FILE_PREFIX$EXTRA + echo $FILE_PREFIX$EXTRA +fi diff --git a/roles/prerec/templates/get-file-prefix b/roles/prerec/templates/get-file-prefix new file mode 100755 index 0000000..0240b99 --- /dev/null +++ b/roles/prerec/templates/get-file-prefix @@ -0,0 +1,10 @@ +#!/bin/bash +# {{ ansible_managed }} +# Usage: get-file-prefix $slug [talks.json] +# You can also set the TALKS_JSON environment variable + +SLUG=$1 +if [ -z "$TALKS_JSON" ]; then + TALKS_JSON=${2:-~orga/current/talks.json} +fi +jq -r '.talks[] | select(.slug=="'$SLUG'")["file-prefix"]' < $TALKS_JSON diff --git a/roles/prerec/templates/process-prerec.sh b/roles/prerec/templates/process-prerec.sh index 795753d..d98337f 100755 --- a/roles/prerec/templates/process-prerec.sh +++ b/roles/prerec/templates/process-prerec.sh @@ -5,14 +5,9 @@ ORIGINAL=$1 REENCODED=$(echo "$ORIGINAL" | perl -pe 's/^(emacsconf-[0-9]*-.*?--.*?--.*?--).*/$1reencoded.webm/') SLUG=$(echo "$ORIGINAL" | perl -ne '/^emacsconf-[0-9]*-(.*?)--/ && print $1') MAIN=$(echo "$ORIGINAL" | perl -pe 's/^(emacsconf-[0-9]*-.*?--.*?--.*?--).*/$1main.webm/') -SCREEN=reencode-$SLUG -if ! ( screen -ls | grep -q $SLUG ); then - screen -dmS $SCREEN -fi # ( cd /data/emacsconf/cache; ./update-cache ) -# /data/emacsconf/{{ emacsconf_year }}/scripts/talk $SLUG "WAITING_FOR_PREREC" "PROCESSING" +# /data/emacsconf/admin/{{ emacsconf_year }}/scripts/talk $SLUG "WAITING_FOR_PREREC" "PROCESSING" if [[ ! -f "$REENCODED" ]]; then - screen -S $SCREEN -X screen -t reencode-$SLUG /bin/bash -c "/data/emacsconf/{{ emacsconf_year }}/scripts/reencode.sh \"$ORIGINAL\" \"$REENCODED\" && /data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh $REENCODED $MAIN && /data/emacsconf/{{ emacsconf_year }}/scripts/thumbnail.sh \"$MAIN\" && /data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh $(echo "$MAIN" | sed s/webm$/png/) exec /bin/bash" & + screen -dmS reencode-$SLUG /bin/bash -c "reencode.sh \"$ORIGINAL\" \"$REENCODED\" && upload.sh $REENCODED $MAIN && thumbnail.sh \"$MAIN\" && upload.sh $(echo "$MAIN" | sed s/webm$/png/); echo $(date -Iminutes) $SLUG reencoded >> ~/emacsconf.log && exec /bin/bash" & fi -screen -S $SCREEN -X screen -t captions-$SLUG /bin/bash -c "/data/emacsconf/{{ emacsconf_year }}/scripts/process-captions.py $(dirname $ORIGINAL); exec /bin/bash" -screen -x $SCREEN +screen -dmS captions-$SLUG /bin/bash -c "/data/emacsconf/admin/{{ emacsconf_year }}/scripts/process-captions.py $(dirname $ORIGINAL); echo $(date -Iminutes) $SLUG captioned >> ~/emacsconf.log; exec /bin/bash" diff --git a/roles/prerec/templates/reencode-in-screen.sh b/roles/prerec/templates/reencode-in-screen.sh new file mode 100755 index 0000000..5c12203 --- /dev/null +++ b/roles/prerec/templates/reencode-in-screen.sh @@ -0,0 +1,16 @@ +#!/bin/bash +ORIGINAL=$1 +BASE="${ORIGINAL%--original.*}" +REENCODED="${BASE}--reencoded.webm" +SLUG=$(echo "$ORIGINAL" | perl -ne '/^emacsconf-[0-9]*-(.*?)--/ && print $1') +LOCK=".lock-$SLUG" + +if [ ! -f "$REENCODED" ]; then + if [ -f "$LOCK" ]; then + echo "$LOCK already exists, waiting for it" + else + touch "$LOCK" + screen -dmS reencode-$SLUG /bin/bash -c "reencode.sh \"$ORIGINAL\" \"$REENCODED\" && thumbnail.sh \"$MAIN\" && rm \"$LOCK\"" + echo "Processing $REENCODED in reencode-$SLUG" + fi +fi diff --git a/roles/prerec/templates/reencode.sh b/roles/prerec/templates/reencode.sh index b0bdfc7..665fee2 100755 --- a/roles/prerec/templates/reencode.sh +++ b/roles/prerec/templates/reencode.sh @@ -33,7 +33,7 @@ shift `expr $OPTIND - 1` OPTIND=1 input="$1" -output="$2" +output="${2:-$(echo $input | sed 's/--original.*/--reencoded.webm/')}" command="$(cat<<EOF ffmpeg -y -i "$input" $time_limit \ diff --git a/roles/prerec/templates/remux.sh b/roles/prerec/templates/remux.sh index c378133..2d2320b 100755 --- a/roles/prerec/templates/remux.sh +++ b/roles/prerec/templates/remux.sh @@ -1,20 +1,29 @@ #!/usr/bin/env bash # {{ ansible_managed }} # Mix in the normalized audio -# Usage: remux.sh $input_video +# Usage: remux.sh $input_video_or_slug with_suffix() { - echo "$input_video" | sed "s/--\(reencoded\|original\).webm\$/--$1/" + echo "$input_video" | sed "s/--\(main\|reencoded\|original\).webm\$/--$1/" } input_video="$1" +if [ ! -f $input_video ]; then + # treat it as a slug + input_video=$(get-file-prefix $1)--reencoded.webm +fi + input_audio="$(with_suffix "normalized.opus")" output_video="$(with_suffix "final.webm")" main_video="$(with_suffix "main.webm")" main_subs="$(with_suffix "main.vtt")" +if cat $main_subs | head -1 | grep captioned; then + $subs = "-i $main_subs" +fi + command="$(cat<<EOF -ffmpeg -i "$input_video" -i "$input_audio" -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 "$output_video" && +ffmpeg -y -i "$input_video" -i "$input_audio" $subs -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 "$output_video" && cp "$output_video" "$main_video" && if [[ -f "$main_subs" ]]; then touch -m "$main_subs"; fi EOF @@ -23,14 +32,18 @@ EOF printf "input: %s\ncomputed output: %s\nrelated main: %s\n\n" "$input_video" "$output_video" "$main_video" printf "Produced incantation:\n%s\n\n" "$command" -while true; -do - read -r -p "Run it? y/n " -n 1 -r response - if [[ $response =~ ^([yY])$ ]]; then - eval "$command" - exit 0 - else - printf "\nExiting\n" - exit 3 - fi -done +if [ -z "$CONFIRMED" ]; then + eval "$command" +else + while true; + do + read -r -p "Run it? y/n " -n 1 -r response + if [[ $response =~ ^([yY])$ ]]; then + eval "$command" + exit 0 + else + printf "\nExiting\n" + exit 3 + fi + done +fi diff --git a/roles/prerec/templates/rename-original.sh b/roles/prerec/templates/rename-original.sh index 0499ae8..ed085ed 100755 --- a/roles/prerec/templates/rename-original.sh +++ b/roles/prerec/templates/rename-original.sh @@ -8,7 +8,7 @@ EXTRA="" if [ -z ${3-unset} ]; then EXTRA="" elif [ -n "$3" ]; then - EXTRA="--$3" + EXTRA="$3" elif echo "$FILE" | grep -e '\(webm\|mp4\|mov\)'; then EXTRA="--original" fi @@ -16,8 +16,13 @@ filename=$(basename -- "$FILE") extension="${filename##*.}" filename="${filename%.*}" FILE_PREFIX=$(jq -r '.talks[] | select(.slug=="'$SLUG'")["file-prefix"]' < $TALKS_JSON) -mv "$FILE" $FILE_PREFIX$EXTRA.$extension -echo $FILE_PREFIX$EXTRA.$extension +if echo "$FILE" | grep -q \\. ; then + mv "$FILE" $FILE_PREFIX$EXTRA.$extension + echo $FILE_PREFIX$EXTRA.$extension +else + mv "$FILE" $FILE_PREFIX$EXTRA + echo $FILE_PREFIX$EXTRA +fi # Copy to original if needed if [ -f $FILE_PREFIX--original.webm ] && [ ! -f $FILE_PREFIX--main.$extension ]; then cp $FILE_PREFIX--original.$extension $FILE_PREFIX--main.webm diff --git a/roles/prerec/templates/run-aeneas.sh b/roles/prerec/templates/run-aeneas.sh index 8246c85..a9e27f4 100755 --- a/roles/prerec/templates/run-aeneas.sh +++ b/roles/prerec/templates/run-aeneas.sh @@ -11,4 +11,4 @@ if [ ! -f $BASE--whisper.vtt ]; then fi python3 -m aeneas.tools.execute_task $AUDIO *.txt "task_language=eng|os_task_file_format=vtt|is_text_type=plain" ${BASE}--aeneas.vtt cp ${BASE}--aeneas.vtt ${BASE}--main.vtt -/data/emacsconf/{{ emacsconf_year }}/scripts/upload.sh ${BASE}--main.vtt +/data/emacsconf/admin/{{ emacsconf_year }}/scripts/upload.sh ${BASE}--main.vtt diff --git a/roles/prerec/templates/talk b/roles/prerec/templates/talk index 0531cda..fa2e5f0 100755 --- a/roles/prerec/templates/talk +++ b/roles/prerec/templates/talk @@ -6,6 +6,8 @@ SLUG="$1" FROM_STATUS="$2" TO_STATUS="$3" +XDG_RUNTIME_DIR=/run/user/{{ getent_passwd[emacsconf_user].1 }} + if [ "x$TO_STATUS" == "x" ]; then FROM_STATUS=. TO_STATUS="$2" @@ -14,7 +16,7 @@ cd {{ emacsconf_private_dir }} #echo "Pulling conf.org..." #git pull echo "Updating status..." -emacsclient --eval "(emacsconf-with-todo-hooks (emacsconf-update-talk-status \"$SLUG\" \"$FROM_STATUS\" \"$TO_STATUS\"))" -a emacs +XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR emacsclient --eval "(emacsconf-with-todo-hooks (emacsconf-update-talk-status \"$SLUG\" \"$FROM_STATUS\" \"$TO_STATUS\"))" -a emacs #echo "Committing and pushing in the background" #git commit -m "Update task status for $SLUG from $FROM_STATUS to $TO_STATUS" conf.org #git push & diff --git a/roles/prerec/templates/upload.sh b/roles/prerec/templates/upload.sh index f3dc9c5..09d55d9 100755 --- a/roles/prerec/templates/upload.sh +++ b/roles/prerec/templates/upload.sh @@ -2,5 +2,5 @@ # {{ ansible_managed }} scp $* orga@media.emacsconf.org:~/backstage -/data/emacsconf/{{ emacsconf_year }}/scripts/publish-backstage-index.sh -rsync -avze ssh orga@media.emacsconf.org:~/backstage/ /data/emacsconf/cache/ +/usr/local/bin/publish-backstage-index.sh +rsync -avze ssh orga@media.emacsconf.org:~/backstage/ /data/emacsconf/shared/{{ emacsconf_year }}/cache/ diff --git a/roles/publish/defaults/main.yml b/roles/publish/defaults/main.yml index 52ec596..19a12d8 100644 --- a/roles/publish/defaults/main.yml +++ b/roles/publish/defaults/main.yml @@ -1,6 +1,6 @@ emacsconf_org_file: "{{ emacsconf_private_dir }}/conf.org" emacsconf_publishing_phase: schedule -emacs_version: 28.2 +emacs_version: 29.1 emacs_build_parent: /usr/src/emacs emacs_build_dir: "{{ emacs_build_parent }}/emacs-{{ emacs_version }}" emacsconf_wiki_branch: master diff --git a/roles/publish/tasks/emacs.yml b/roles/publish/tasks/emacs.yml index 3944876..d961878 100644 --- a/roles/publish/tasks/emacs.yml +++ b/roles/publish/tasks/emacs.yml @@ -8,6 +8,8 @@ - pkg-config - libjansson-dev - libgnutls28-dev + - libtiff-dev + - libtiff5-dev - automake - texinfo state: present diff --git a/roles/publish/tasks/main.yml b/roles/publish/tasks/main.yml index 0724bdd..797ac7f 100644 --- a/roles/publish/tasks/main.yml +++ b/roles/publish/tasks/main.yml @@ -25,8 +25,8 @@ register: emacs - name: Set up Emacs become: yes - include: emacs.yml - when: not emacs.stat.exists + import_tasks: emacs.yml + # when: not emacs.stat.exists - name: Configure git template: src: git-config @@ -68,7 +68,7 @@ dest: "~{{ emacsconf_user }}/subed" - name: Check out wiki repository ansible.builtin.git: - repo: anon@git.emacsconf.org:emacsconf-wiki + repo: "{{ emacsconf_publishing_source }}" dest: "{{ emacsconf_edit_wiki_dir }}" ssh_opts: "-i /home/{{ emacsconf_user }}/.ssh/id_rsa_anon_git_emacsconf" register: wiki_clone diff --git a/roles/publish/templates/emacsconf-config.el b/roles/publish/templates/emacsconf-config.el index 0c7a80b..767de85 100644 --- a/roles/publish/templates/emacsconf-config.el +++ b/roles/publish/templates/emacsconf-config.el @@ -15,22 +15,24 @@ (setq emacsconf-ansible-directory "{{ emacsconf_ansible_directory }}") {% endif %} (setq emacsconf-pad-api-key "{{ etherpad_api_key }}") -(setq emacsconf-publishing-phase '{{ emacsconf_publishing_phase }}) +(setq emacsconf-publishing-phase 'conference) (setq emacsconf-backstage-password "{{ emacsconf_backstage_password }}") +(setq emacsconf-public-media-directory "/ssh:orga@media.emacsconf.org:/var/www/media.emacsconf.org/{{ emacsconf_year }}") (setq emacsconf-backstage-dir "/ssh:orga@media.emacsconf.org:/var/www/media.emacsconf.org/{{ emacsconf_year }}/backstage") (setq emacsconf-upload-dir "/ssh:orga@media.emacsconf.org:/srv/upload") {% if ansible_host == "res.emacsconf.org" %} -(setq emacsconf-res-dir "/data/{{ emacsconf_id }}/{{ emacsconf_year}}") -(setq emacsconf-cache-dir "/data/{{ emacsconf_id }}/cache") +(setq emacsconf-res-dir "/data/{{ emacsconf_id }}/shared/{{ emacsconf_year}}") +(setq emacsconf-cache-dir "/data/{{ emacsconf_id }}/shared/{{ emacsconf_year}}/cache") (setq emacsconf-stream-host "localhost") (setq emacsconf-stream-overlay-dir "{{ emacsconf_caption_dir }}/assets/overlays") (setq emacsconf-stream-asset-dir "{{ emacsconf_caption_dir }}/assets") {% else %} -(setq emacsconf-res-dir (format "/ssh:orga@res.emacsconf.org:/data/emacsconf/%s" emacsconf-year)) +(setq emacsconf-res-dir (format "/ssh:orga@res.emacsconf.org:/data/emacsconf/admin/%s" emacsconf-year)) {% endif %} +(setq emacsconf-publish-autocommit-wiki t) (add-to-list 'load-path "~/compile-media") (add-to-list 'load-path "~/subed/subed") (require 'compile-media) diff --git a/roles/stream/tasks/main.yml b/roles/stream/tasks/main.yml index d821d5e..eaf2fc8 100644 --- a/roles/stream/tasks/main.yml +++ b/roles/stream/tasks/main.yml @@ -8,40 +8,55 @@ package: name: icecast2 state: present +- name: Install package for setting htpasswd + package: + name: python3-passlib + when: protect_stream_with_password +- name: Create htpasswd entry + htpasswd: + create: yes + name: "{{ emacsconf_backstage_user }}" + password: "{{ emacsconf_backstage_password }}" + path: /etc/nginx/{{ emacsconf_id }}-htpasswd + when: protect_stream_with_password - name: Set up config become: true template: src: icecast.xml - dest: /etc/icecast2/icecast-emacsconf.xml + dest: /etc/icecast2/icecast-{{ emacsconf_id }}.xml - name: Create restream dir file: path: "{{ icecast_restream_dir }}" owner: "{{ icecast_user }}" state: directory - name: Set up track-specific things - include: track.yml + include_tasks: track.yml loop: "{{ emacsconf_tracks }}" - name: Set up init file become: true template: src: icecast-emacsconf.init.d - dest: /etc/init.d/emacsconf + dest: /etc/init.d/{{ emacsconf_id }} mode: 0755 - name: Set up nginx config tags: stream-nginx become: true template: src: emacsconf.nginx.conf - dest: /etc/nginx/emacsconf.nginx.conf + dest: /etc/nginx/{{ emacsconf_id }}.nginx.conf mode: 0644 - name: Include emacsconf in nginx config become: true lineinfile: - line: include /etc/nginx/emacsconf.nginx.conf; - regexp: '^\s*include /etc/nginx/emacsconf.nginx.conf;' + line: include /etc/nginx/{{ emacsconf_id }}.nginx.conf; + regexp: '^\s*include /etc/nginx/{{ emacsconf_id }}.nginx.conf;' insertafter: '.*tls/live0.conf.*' backup: yes - path: /etc/nginx/sites-available/live0.emacsconf.org + path: /etc/nginx/sites-available/live0.{{ emacsconf_id }}.org +- name: Reload nginx config + service: + name: nginx + state: reloaded - name: Enable icecast become: true service: @@ -57,7 +72,7 @@ register: port_check ignore_errors: yes - name: Try to restart icecast if not started - service: name=emacsconf state=started enabled=yes + service: name={{ emacsconf_id }} state=started enabled=yes when: port_check.failed == true - name: Set up restream scripts tags: restream @@ -67,7 +82,7 @@ owner: orga mode: 0755 loop: "{{ restreaming_platforms | subelements('streams') | list }}" - no_log: True + # no_log: True - name: Set up restream scripts tags: restream template: @@ -76,7 +91,7 @@ owner: orga mode: 0755 loop: "{{ restreaming_platforms | subelements('streams') | list }}" - no_log: True + # no_log: True - name: Copy fallback files copy: src: sorry.webm diff --git a/roles/stream/templates/emacsconf.nginx.conf b/roles/stream/templates/emacsconf.nginx.conf index ac84ef5..cf5e2b8 100644 --- a/roles/stream/templates/emacsconf.nginx.conf +++ b/roles/stream/templates/emacsconf.nginx.conf @@ -11,6 +11,10 @@ location ~ ^/((gen|dev)(-480p|-fallback)?.webm)$ { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Real-IP $remote_addr; + {% if protect_stream_with_password %} + auth_basic {{ emacsconf_name }}; + auth_basic_user_file /etc/nginx/{{ emacsconf_id }}-htpasswd; + {% endif %} } location ~ ^/emacsconf/(.*)$ { @@ -26,5 +30,8 @@ location ~ ^/emacsconf/(.*)$ { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Real-IP $remote_addr; + {% if protect_stream_with_password %} + auth_basic {{ emacsconf_name }}; + auth_basic_user_file /etc/nginx/{{ emacsconf_id }}-htpasswd; + {% endif %} } -
\ No newline at end of file diff --git a/roles/stream/templates/icecast.xml b/roles/stream/templates/icecast.xml index 06830d3..b01bc48 100644 --- a/roles/stream/templates/icecast.xml +++ b/roles/stream/templates/icecast.xml @@ -192,7 +192,6 @@ <mount-name>/{{ track.id }}.webm</mount-name> <username>{{ icecast_emacsconf_user }}</username> <password>{{ icecast_emacsconf_password }}</password> - {% if not test_mode %}<dump-file>/data/{{ emacsconf_id }}-{{ emacsconf_year }}-{{ track.id }}_%Y-%m-%d_%H-%M-%S.webm</dump-file>{% endif %} <stream-name>{{ emacsconf_name }} {{ emacsconf_year }} - {{ track.name }} track</stream-name> <stream-description>The livestream for the {{ track.name }} track of {{ emacsconf_name }} {{ emacsconf_year }}</stream-description> <stream-url>{{ track.watch }}</stream-url> @@ -202,6 +201,7 @@ <on-disconnect>/usr/local/bin/{{ emacsconf_id }}-lowres-{{ track.id }}-on-disconnect</on-disconnect> <fallback-mount>/{{ track.id }}-sorry.webm</fallback-mount> <fallback-override>1</fallback-override> + {% if not test_mode %}<dump-file>/data/{{ emacsconf_id }}-{{ emacsconf_year }}-{{ track.id }}_%Y-%m-%d_%H-%M-%S.webm</dump-file>{% endif %} </mount> <mount type="normal"> <mount-name>/{{ track.id }}-host.webm</mount-name> diff --git a/roles/stream/templates/lowres.sh b/roles/stream/templates/lowres.sh index 502fcb3..13d6a81 100755 --- a/roles/stream/templates/lowres.sh +++ b/roles/stream/templates/lowres.sh @@ -1,6 +1,6 @@ #!/bin/bash # {{ ansible_managed }} sleep 10 -for i in 1 2 3 4 5; do +while true; do ffmpeg -loglevel 24 -f webm -reconnect_at_eof 1 -reconnect_streamed 1 -re -i "http://localhost:{{ icecast_port }}/{{ item.id }}.webm" -vf scale="{{ icecast_lowres_scale }}" -f webm -c:a copy -b:v 500k -maxrate 1M -bufsize 1M -content_type video/webm -c:v libvpx "icecast://{{ icecast_emacsconf_user }}:{{ icecast_emacsconf_password }}@localhost:{{ icecast_port }}/{{ item.id }}-480p.webm" >> {{ icecast_restream_dir }}/{{ emacsconf_id }}-lowres-{{ item.id }}.log || sleep 5 done diff --git a/roles/upload/tasks/main.yml b/roles/upload/tasks/main.yml index 3e7e615..b63e3f1 100644 --- a/roles/upload/tasks/main.yml +++ b/roles/upload/tasks/main.yml @@ -21,6 +21,14 @@ name: - nodejs state: present +- name: Add to dehydrated.conf + become: true + lineinfile: + line: "{{ upload_server_name }}" + path: /etc/dehydrated/domains.txt +- name: Create or renew cert + command: "dehydrated --cron" + become: true - name: Create upload user become: true user: @@ -99,6 +107,19 @@ owner: "{{ upload_user }}" group: "{{ upload_group }}" recurse: true +- name: Create backup dir to use when the conference is done + file: + path: "{{ upload_done_dir }}" + owner: "{{ upload_user }}" + group: "{{ upload_group }}" + state: directory +- name: Create backup file to use when the conference is done + template: + src: index.html + owner: "{{ upload_user }}" + group: "{{ upload_group }}" + mode: 0755 + dest: "{{ upload_done_dir }}/index.html" - name: Install systemd configuration tags: system become: true @@ -109,9 +130,34 @@ group: root mode: 0755 when: not use_initd +- name: Create main configuration if needed + template: + src: nginx-site-config + dest: /etc/nginx/sites-available/{{ upload_server_name }} +- name: Make sure main configuration is enabled + file: + src: /etc/nginx/sites-available/{{ upload_server_name }} + dest: /etc/nginx/sites-enabled/{{ upload_server_name }} + owner: "{{ emacsconf_user }}" + group: "{{ emacsconf_group }}" + force: no + state: link +- name: Reload configuration + become: true + service: + name: nginx + state: reloaded - name: Restart Upload become: true + when: upload_enabled service: name: upload state: restarted - enabled: yes + enabled: true +- name: Stop upload + become: true + when: not upload_enabled + service: + name: upload + state: stopped + enabled: false diff --git a/roles/upload/templates/index.html b/roles/upload/templates/index.html new file mode 100644 index 0000000..e5d8e6e --- /dev/null +++ b/roles/upload/templates/index.html @@ -0,0 +1,7 @@ +<html> + <head> + </head> + <body> + EmacsConf is done for now, so we've turned off the file upload service. Let us know at <a href="mailto:emacsconf-org-private@gnu.org">emacsconf-org-private@gnu.org</a> if you need it back to upload something! + </body> +</html> diff --git a/roles/upload/templates/nginx-site-config b/roles/upload/templates/nginx-site-config new file mode 100644 index 0000000..48842d1 --- /dev/null +++ b/roles/upload/templates/nginx-site-config @@ -0,0 +1,46 @@ +upstream upload_emacsconf { + server 127.0.0.1:3000; +} + +server { + listen 80; + listen [::]:80; + server_name {{ upload_server_name }}; + + include snippets/well-known-acme-challenge.conf; + + location / { + return 302 https://$server_name$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{ upload_server_name }}; + + ssl_certificate /var/local/dehydrated/certs/{{ upload_server_name }}/fullchain.pem; + ssl_certificate_key /var/local/dehydrated/certs/{{ upload_server_name }}/privkey.pem; + ssl_trusted_certificate /var/local/dehydrated/certs/{{ upload_server_name }}/fullchain.pem; + include ssl_params.local; + include snippets/well-known-acme-challenge.conf; +{% if upload_enabled %} + location @upload_emacsconf { + proxy_pass http://upload_emacsconf; + proxy_http_version 1.1; + proxy_buffering off; + proxy_request_buffering off; # needs nginx version >= 1.7.11 + proxy_set_header Host $http_host; + } + location / { + #try_files $uri $uri/ @upload_emacsconf; + proxy_pass http://upload_emacsconf; + proxy_http_version 1.1; + proxy_buffering off; + proxy_request_buffering off; # needs nginx version >= 1.7.11 + proxy_set_header Host $http_host; + } + {% else %} + root {{ upload_done_dir }}; + {% endif %} +} diff --git a/roles/wiki/defaults/main.yml b/roles/wiki/defaults/main.yml index fedf090..66e570a 100644 --- a/roles/wiki/defaults/main.yml +++ b/roles/wiki/defaults/main.yml @@ -20,4 +20,4 @@ ikiwiki_git_wrapper: "{{ ikiwiki_path }}/hooks/emacsconf" ikiwiki_git_test_receive_wrapper: "{{ ikiwiki_path }}/hooks/emacsconf-pre" ikiwiki_git_base_url: //git.emacsconf.org/emacsconf-wiki ikiwiki_cgi_wrapper: "{{ ikiwiki_path }}/ikiwiki.cgi" - +ikiwiki_bare_git_dir: git://git.emacsconf.org/emacsconf-wiki diff --git a/roles/wiki/tasks/docker.yml b/roles/wiki/tasks/docker.yml index 4c7fd06..2bfe613 100644 --- a/roles/wiki/tasks/docker.yml +++ b/roles/wiki/tasks/docker.yml @@ -4,50 +4,6 @@ - lighttpd - supervisor - sudo -- name: Create the anon user - user: - name: anon - state: present - when: docker -- name: Set up Ikiwiki setup - template: - src: emacsconf.setup - dest: "{{ ikiwiki_path }}/emacsconf.setup" - owner: www-data - group: www-data -- name: Set up the ikiwiki directories - file: - dest: "{{ ikiwiki_dest }}" - state: directory - owner: ikiwiki - group: www-data - recurse: true -- name: Clone the bare git repo - git: - bare: true - repo: "{{ ikiwiki_git_source_mount }}" - dest: "{{ ikiwiki_bare_git_dir }}" - version: "{{ ikiwiki_git_branch }}" -- name: Set up post-update hook - template: - src: post-update - dest: "{{ ikiwiki_bare_git_dir }}/hooks/post-update" - mode: 0755 -- name: Remove sample - file: - path: "{{ ikiwiki_bare_git_dir }}/hooks/post-update.sample" - state: absent -- name: Set up ikiwiki post-update hook - template: - src: post-update.h00-ikiwiki-wrapper - dest: "{{ ikiwiki_bare_git_dir }}/hooks/post-update.h00-ikiwiki-wrapper" - mode: 0755 -- name: Change owner - file: - dest: "{{ ikiwiki_bare_git_dir }}" - recurse: true - owner: ikiwiki - group: www-data - name: Clone the working git repo git: repo: "{{ ikiwiki_bare_git_dir }}" @@ -67,19 +23,6 @@ service: name: lighttpd state: started -- name: Start ssh - tags: ssh - service: - name: ssh - state: started -- name: Set up SSH directory - tags: ssh - file: - path: /home/ikiwiki/.ssh - owner: ikiwiki - group: ikiwiki - state: directory - mode: 0700 - name: Set up SSH authentication tags: ssh block: diff --git a/roles/wiki/tasks/main.yml b/roles/wiki/tasks/main.yml index cd7cbdc..3ee7d4f 100644 --- a/roles/wiki/tasks/main.yml +++ b/roles/wiki/tasks/main.yml @@ -13,6 +13,11 @@ - nginx - wget state: present +- name: Start ssh + tags: ssh + service: + name: ssh + state: started - name: Create ikiwiki group group: name: ikiwiki @@ -22,11 +27,63 @@ name: ikiwiki group: ikiwiki state: present +- name: Create anon group + group: + name: anon + state: present +- name: Create anon user + user: + name: anon + group: anon + state: present +- include_tasks: bare-git.yml + when: docker or test_mode +- name: Configure safe directory + shell: git config --global --add safe.directory "{{ ikiwiki_src_dir }}" +- name: Clone the working git repo + git: + repo: "{{ ikiwiki_bare_git_dir }}" + dest: "{{ ikiwiki_src_dir }}" +- name: Switch the source git repo to the branch + shell: git checkout "{{ ikiwiki_git_branch }}" 2>/dev/null || git checkout -b "{{ ikiwiki_git_branch }}" + args: + chdir: "{{ ikiwiki_src_dir }}" +- name: Set the default branch policy + shell: git config --global pull.rebase false + become: true + become_user: ikiwiki +- name: Set up SSH directory + tags: ssh + file: + path: /home/ikiwiki/.ssh + owner: ikiwiki + group: ikiwiki + state: directory + mode: 0700 +- name: Set up SSH key access + tags: wiki-test-keys + template: + src: authorized_keys + dest: "/home/ikiwiki/.ssh/authorized_keys" + mode: 0600 + owner: ikiwiki + group: ikiwiki + when: test_mode +- name: Set up the ikiwiki directories + file: + dest: "{{ ikiwiki_dest }}" + state: directory + owner: ikiwiki + group: ikiwiki + recurse: true - name: Template the config ansible.builtin.template: src: emacsconf.setup dest: "{{ ikiwiki_path }}/emacsconf.setup" owner: ikiwiki + group: ikiwiki +- include_tasks: nginx.yml + when: test_mode - name: Create the plugin directory file: path: "{{ ikiwiki_plugin_path }}/IkiWiki/Plugin" @@ -40,7 +97,7 @@ - copyright.pm - htmlscrubber.pm - license.pm -- include: docker.yml +- include_tasks: docker.yml when: docker - name: Chown all the files to ikiwiki tags: wiki-plugins @@ -48,7 +105,12 @@ dest: "{{ ikiwiki_path }}" owner: ikiwiki group: ikiwiki + state: directory recurse: true +- name: Debug + tags: dev-wiki + debug: + var: ikiwiki_path - name: Regenerate all the files tags: wiki-regenerate, wiki-plugins become: true diff --git a/roles/wiki/templates/emacsconf.setup b/roles/wiki/templates/emacsconf.setup index d74fbb0..a7d2377 100644 --- a/roles/wiki/templates/emacsconf.setup +++ b/roles/wiki/templates/emacsconf.setup @@ -150,7 +150,7 @@ diffurl: {{ ikiwiki_git_base_url }}/diff/[[file]]?id=[[sha1_commit]]&id2=[[sha1_ # where to pull and push changes (set to empty string to disable) #gitorigin_branch: origin # branch that the wiki is stored in -gitmaster_branch: {{ ikiwiki_git_branch }} +#gitorigin_branch: {{ ikiwiki_git_branch }} # htmlscrubber plugin # PageSpec specifying pages not to scrub @@ -200,7 +200,7 @@ atom: 1 # PageSpec controlling which pages are locked #locked_pages: '!*/Discussion' #locked_pages: 'index or edit' -locked_pages: 'edit' +locked_pages: 'edit or donate or donors or script.js or local.css or templates/page.tmpl' # moderatedcomments plugin # PageSpec matching users or comment locations to moderate |