Initial commit

This commit is contained in:
Radek Goláň jr. 2025-09-12 09:39:37 +02:00
commit 22522a6607
Signed by: shield
GPG Key ID: D86423BFC31F3591
5 changed files with 350 additions and 0 deletions

98
.woodpecker/build.yml Normal file
View File

@ -0,0 +1,98 @@
variables:
- &file Containerfile
- &repo dev.shielddagger.com/opensource/talk-recording
when:
- event: [push, pull_request, cron]
steps:
- name: dryrun
image: woodpeckerci/plugin-docker-buildx:5
backend_options:
kubernetes:
securityContext:
privileged: true
settings:
dockerfile: *file
platforms: linux/arm64,linux/amd64
cache_from: type=registry,ref=dev.shielddagger.com/opensource/talk-recording
cache_to: type=inline
dry_run: true
repo: *repo
tags: latest
registry: dev.shielddagger.com
username:
from_secret: registry_username
password:
from_secret: registry_password
when:
- event: pull_request
- name: publish
image: woodpeckerci/plugin-docker-buildx:5
backend_options:
kubernetes:
securityContext:
privileged: true
settings:
dockerfile: *file
platforms: linux/arm64,linux/amd64
cache_from: type=registry,ref=dev.shielddagger.com/opensource/talk-recording
cache_to: type=inline
repo: *repo
auto_tag: true
tags: ${CI_COMMIT_SHA:0:8}
registry: dev.shielddagger.com
username:
from_secret: registry_username
password:
from_secret: registry_password
when:
- event: push
branch: main
- name: gather-digests
image: quay.io/skopeo/stable:latest
environment:
DOCKER_USER:
from_secret: registry_username
DOCKER_PASS:
from_secret: registry_password
DOCKER_REPO: *repo
when:
- event: [push, cron]
branch: main
cron: "security-scan"
commands:
- dnf install -y jq
- skopeo login dev.shielddagger.com --username $DOCKER_USER --password $DOCKER_PASS
- skopeo inspect --raw docker://$DOCKER_REPO:latest | jq -r .'manifests[] | select(.platform.architecture=="arm64").digest' > digest-arm64
- skopeo inspect --raw docker://$DOCKER_REPO:latest | jq -r .'manifests[] | select(.platform.architecture=="amd64").digest' > digest-amd64
- name: image-scan
image: aquasec/trivy
environment:
TRIVY_USER:
from_secret: registry_username
TRIVY_PASSWORD:
from_secret: registry_password
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
TRIVY_CHECKS_BUNDLE_REPOSITORY: public.ecr.aws/aquasecurity/trivy-checks
DOCKER_REPO: *repo
commands:
- export ARM64_DIGEST=$(cat digest-arm64)
- trivy image --platform linux/arm64 --debug ${DOCKER_REPO}@$ARM64_DIGEST --exit-code 1 --username $TRIVY_USER --severity HIGH,CRITICAL
when:
- event: [push, cron]
branch: main
cron: "security-scan"
- name: notify
image: dev.shielddagger.com/opensource/discord-notifier
failure: ignore
settings:
webhook_url:
from_secret: discord_webhook
woodpecker_url: https://ci.shielddagger.com/api
woodpecker_token:
from_secret: woodpecker_token
icon_url: https://discord.com/api/webhooks/1231848304694919270/1ApQzOPMfNosxhQ62HbYScBT5s94m0bIUn1IFGQlT6d8Ru2ImcHHjjkFA_SaonBNU3yz
when:
- status: [success, failure]

61
Dockerfile Normal file
View File

@ -0,0 +1,61 @@
# syntax=docker/dockerfile:latest
FROM python:3.13.7-alpine3.22
COPY --chmod=775 start.sh /start.sh
COPY --chmod=775 healthcheck.sh /healthcheck.sh
ENV RECORDING_VERSION=v0.1
ENV ALLOW_ALL=false
ENV HPB_PROTOCOL=https
ENV NC_PROTOCOL=https
ENV SKIP_VERIFY=false
ENV HPB_PATH=/standalone-signaling/
RUN set -ex; \
apk upgrade --no-cache -a; \
apk add --no-cache \
ca-certificates \
tzdata \
bash \
xvfb \
ffmpeg \
firefox \
bind-tools \
netcat-openbsd \
git \
wget \
shadow \
pulseaudio \
openssl \
build-base \
linux-headers \
geckodriver; \
useradd -d /tmp --system recording -u 122; \
# Give root a random password
echo "root:$(openssl rand -base64 12)" | chpasswd; \
git clone --recursive https://github.com/nextcloud/nextcloud-talk-recording --depth=1 --single-branch --branch "$RECORDING_VERSION" /src; \
python3 -m pip install --no-cache-dir /src; \
rm -rf /src; \
touch /etc/recording.conf; \
chown recording:recording -R \
/tmp /etc/recording.conf; \
mkdir -p /conf; \
chmod 777 /conf; \
chmod 777 /tmp; \
apk del --no-cache \
git \
wget \
shadow \
openssl \
build-base \
linux-headers;
VOLUME /tmp
WORKDIR /tmp
USER 122
ENTRYPOINT ["/start.sh"]
CMD ["python", "-m", "nextcloud.talk.recording", "--config", "/conf/recording.conf"]
HEALTHCHECK CMD /healthcheck.sh
LABEL com.centurylinklabs.watchtower.enable="false" \
org.label-schema.vendor="Nextcloud"

3
healthcheck.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
nc -z 127.0.0.1 1234 || exit 1

123
recording.conf Normal file
View File

@ -0,0 +1,123 @@
[logs]
# Log level based on numeric values of Python logging levels:
# - Critical: 50
# - Error: 40
# - Warning: 30
# - Info: 20
# - Debug: 10
# - Not set: 0
#level = 20
[http]
# IP and port to listen on for HTTP requests.
#listen = 127.0.0.1:8000
[backend]
# Allow any hostname as backend endpoint. This is extremely insecure and should
# only be used during development.
#allowall = false
# Common shared secret for requests from and to the backend servers if
# "allowall" is enabled. This must be the same value as configured in the
# Nextcloud admin ui.
#secret = the-shared-secret
# Comma-separated list of backend ids allowed to connect.
#backends = backend-id, another-backend
# If set to "true", certificate validation of backend endpoints will be skipped.
# This should only be enabled during development, e.g. to work with self-signed
# certificates.
# Overridable by backend.
#skipverify = false
# Maximum allowed size in bytes for messages sent by the backend.
# Overridable by backend.
#maxmessagesize = 1024
# Width for recorded videos.
# Overridable by backend.
#videowidth = 1920
# Height for recorded videos.
# Overridable by backend.
#videoheight = 1080
# Temporary directory used to store recordings until uploaded. It must be
# writable by the user running the recording server.
# Overridable by backend.
#directory = /tmp
# Backend configurations as defined in the "[backend]" section above. The
# section names must match the ids used in "backends" above.
#[backend-id]
# URL of the Nextcloud instance
#url = https://cloud.domain.invalid
# Shared secret for requests from and to the backend servers. This must be the
# same value as configured in the Nextcloud admin ui.
#secret = the-shared-secret
#[another-backend]
# URL of the Nextcloud instance
#url = https://cloud.otherdomain.invalid
# Shared secret for requests from and to the backend servers. This must be the
# same value as configured in the Nextcloud admin ui.
#secret = the-shared-secret
[signaling]
# Common shared secret for authenticating as an internal client of signaling
# servers if a specific secret is not set for a signaling server. This must be
# the same value as configured in the signaling server configuration file.
#internalsecret = the-shared-secret-for-internal-clients
# Comma-separated list of signaling servers with specific internal secrets.
#signalings = signaling-id, another-signaling
# Signaling server configurations as defined in the "[signaling]" section above.
# The section names must match the ids used in "signalings" above.
#[signaling-id]
# URL of the signaling server
#url = https://signaling.domain.invalid
# Shared secret for authenticating as an internal client of signaling servers.
# This must be the same value as configured in the signaling server
# configuration file.
#internalsecret = the-shared-secret-for-internal-clients
#[another-signaling]
# URL of the signaling server
#url = https://signaling.otherdomain.invalid
# Shared secret for authenticating as an internal client of signaling servers.
# This must be the same value as configured in the signaling server
# configuration file.
#internalsecret = the-shared-secret-for-internal-clients
[ffmpeg]
# The ffmpeg executable (name or full path) and the global options given to
# ffmpeg. The options given here fully override the default global options.
#common = ffmpeg -loglevel level+warning -n
# The options given to ffmpeg to encode the audio output. The options given here
# fully override the default options for the audio output.
#outputaudio = -c:a libopus
# The options given to ffmpeg to encode the video output. The options given here
# fully override the default options for the video output.
#outputvideo = -c:v libvpx -deadline:v realtime -crf 10 -b:v 1M
# The extension of the file for audio only recordings.
#extensionaudio = .ogg
# The extension of the file for audio and video recordings.
#extensionvideo = .webm
[recording]
# Browser to use for recordings. Please note that the "chrome" value does not
# refer to the web browser, but to the Selenium WebDriver. In practice, "chrome"
# will use Google Chrome, or Chromium if Google Chrome is not installed.
# Allowed values: firefox, chrome
# Defaults to firefox
# browser = firefox

65
start.sh Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
# Variables
if [ -z "$NC_DOMAIN" ]; then
echo "You need to provide the NC_DOMAIN."
exit 1
elif [ -z "$RECORDING_SECRET" ]; then
echo "You need to provide the RECORDING_SECRET."
exit 1
elif [ -z "$INTERNAL_SECRET" ]; then
echo "You need to provide the INTERNAL_SECRET."
exit 1
fi
if [ -z "$HPB_DOMAIN" ]; then
export HPB_DOMAIN="$NC_DOMAIN"
fi
# Delete all contents on startup to start fresh
rm -fr /tmp/{*,.*}
cat << RECORDING_CONF > "/conf/recording.conf"
[logs]
# 30 means Warning
level = 30
[http]
listen = 0.0.0.0:1234
[backend]
allowall = ${ALLOW_ALL}
# The secret below is still needed if allowall is set to true, also it doesn't hurt to be here
secret = ${RECORDING_SECRET}
backends = backend-1
skipverify = ${SKIP_VERIFY}
maxmessagesize = 1024
videowidth = 1920
videoheight = 1080
directory = /tmp
[backend-1]
url = ${NC_PROTOCOL}://${NC_DOMAIN}
secret = ${RECORDING_SECRET}
skipverify = ${SKIP_VERIFY}
[signaling]
signalings = signaling-1
[signaling-1]
url = ${HPB_PROTOCOL}://${HPB_DOMAIN}${HPB_PATH}
internalsecret = ${INTERNAL_SECRET}
[ffmpeg]
# common = ffmpeg -loglevel level+warning -n
# outputaudio = -c:a libopus
# outputvideo = -c:v libvpx -deadline:v realtime -crf 10 -b:v 1M
extensionaudio = .ogg
extensionvideo = .webm
[recording]
browser = firefox
driverPath = /usr/bin/geckodriver
RECORDING_CONF
exec "$@"