Commit 832ee7ae authored by Romain Courteaud's avatar Romain Courteaud

Port Peertube

See merge request nexedi/slapos!1251
parents 4f5af09f d4da4400
Pipeline #25259 failed with stage
......@@ -62,10 +62,12 @@ url = http://www.tortall.net/projects/yasm/releases/yasm-1.1.0.tar.gz
recipe = slapos.recipe.cmmi
url = https://storage.googleapis.com/downloads.webmproject.org/releases/webm/libvpx-1.5.0.tar.bz2
md5sum = 49e59dd184caa255886683facea56fca
location = @@LOCATION@@
configure-options =
--enable-shared
environment =
PATH=${yasm:location}/bin:%(PATH)s
LDFLAGS=-Wl,-rpath=${:location}/lib
[libx264]
recipe = slapos.recipe.cmmi
......@@ -96,6 +98,7 @@ configure-options =
recipe = slapos.recipe.cmmi
url = https://ffmpeg.org/releases/ffmpeg-4.1.4.tar.bz2
md5sum = 611d171e4aee749b85e04d17e2aee71d
location = @@LOCATION@@
pkg_config_depends = ${libxcb:location}/lib/pkgconfig:${libxcb:pkg_config_depends}:${libtheora:location}/lib/pkgconfig:${libtheora:pkg_config_depends}:${libvpx:location}/lib/pkgconfig:${libx264:location}/lib/pkgconfig:${opencore-amr:location}/lib/pkgconfig:${zlib:location}/lib/pkgconfig
configure-options =
--enable-gpl
......@@ -119,5 +122,5 @@ configure-options =
environment =
PKG_CONFIG_PATH=${:pkg_config_depends}
CPPFLAGS=-I${bzip2:location}/include -I${libogg:location}/include -I${libtheora:location}/include -I${opencore-amr:location}/include -I${lame:location}/include
LDFLAGS=-Wl,-rpath=${buildout:parts-directory}/${:_buildout_section_name_}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -Wl,-rpath=${libxcb:location}/lib -L${libogg:location}/lib -L${libvorbis:location}/lib -Wl,-rpath=${libvorbis:location}/lib -L${libtheora:location}/lib -Wl,-rpath=${libtheora:location}/lib -L${libvpx:location}/lib -Wl,-rpath=${libvpx:location}/lib -L${libx264:location}/lib -Wl,-rpath=${libx264:location}/lib -L${lame:location}/lib -Wl,-rpath=${lame:location}/lib -L${opencore-amr:location}/lib -Wl,-rpath=${opencore-amr:location}/lib -Wl,-rpath=${zlib:location}/lib
LDFLAGS=-Wl,-rpath=${:location}/lib -L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -Wl,-rpath=${libxcb:location}/lib -L${libogg:location}/lib -L${libvorbis:location}/lib -Wl,-rpath=${libvorbis:location}/lib -L${libtheora:location}/lib -Wl,-rpath=${libtheora:location}/lib -L${libvpx:location}/lib -Wl,-rpath=${libvpx:location}/lib -L${libx264:location}/lib -Wl,-rpath=${libx264:location}/lib -L${lame:location}/lib -Wl,-rpath=${lame:location}/lib -L${opencore-amr:location}/lib -Wl,-rpath=${opencore-amr:location}/lib -Wl,-rpath=${zlib:location}/lib
PATH=${pkgconfig:location}/bin:${yasm:location}/bin:%(PATH)s
......@@ -29,7 +29,8 @@ configure-options =
--without-libxml
--without-libxslt
# build core PostgreSQL + pg_trgm contrib extension for GitLab
make-targets = install && make -C contrib/pg_trgm/ install
# unaccent contrib extension is for peertube
make-targets = install && make -C contrib/pg_trgm/ install && make -C contrib/unaccent/ install
environment =
CPPFLAGS=-I${zlib:location}/include -I${readline:location}/include -I${openssl:location}/include -I${ncurses:location}/lib
LDFLAGS=-L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${readline:location}/lib -Wl,-rpath=${readline:location}/lib -L${openssl:location}/lib -Wl,-rpath=${openssl:location}/lib -L${ncurses:location}/lib -Wl,-rpath=${ncurses:location}/lib -L${perl:location}/libs-c -Wl,-rpath=${perl:location}/libs-c
......
......@@ -70,7 +70,6 @@ config-url= $${metabase-instance:url}/api/session/properties
[metabase-keystore-password]
recipe = slapos.cookbook:generate.password
bytes = 24
[metabase-keystore]
recipe = plone.recipe.command
......
# THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[instance-profile]
filename = instance.cfg.in
md5sum = 35690065ba18dc49d0108fc1f0a07b9e
[instance-peertube]
_update_hash_filename_ = instance-peertube.cfg.in
md5sum = 52b9a872d69052f53dd29bfa4a067dbf
[template-nginx-service]
filename = template-nginx-service.sh.in
md5sum = 458870b70c33a1621b68961ae2372ad5
[template-peertube-service]
filename = template-peertube-service.sh.in
md5sum = fe42401ea8df7a245955683535f8a063
[template-peertube-yaml]
filename = template-peertube.yaml.in
md5sum = e761995c4c18efc4a199f11dc8fde039
[template-nginx-configuration]
filename = template-nginx.cfg.in
md5sum = a2c0d6e873370d64de707f668a3d40e3
[template-dcron-service]
filename = template-dcron-service.sh.in
md5sum = 851262d7174da868805cb7c8e1ced7c0
[template-crontab-line]
filename = template-crontab-line.in
md5sum = bab861f1d057e837697d78e74e47b0bb
[template-crontab]
filename = template-crontab.in
md5sum = f1f82101258de19068262b7213fc478b
[template-peertube-backup-script]
filename = template-peertube-backup.sh.in
md5sum = e50daa16a2c1866997933981bed45271
[template-peertube-restore-script]
filename = template-peertube-restore.sh.in
md5sum = bb67602f3d652d4e5a06711fae5996f9
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"description": "Parameters to instantiate Peertube",
"additionalProperties": false,
"properties": {
"frequency": {
"title": "Backup Frequency",
"description": "Backup Frequency",
"default": "",
"type": "string"
},
"fronted-url": {
"title": "Frontend URL",
"description": "Frontend URL",
"default": "",
"type": "string"
},
"name": {
"title": "Instance Title",
"description": "The name of your peertube instance.",
"default": "Peertube in Slapos",
"type": "string"
},
"short_description": {
"title": "PeerTube Short Description",
"description": "Short description of your peertube instance.",
"default": "PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.",
"type": "string"
},
"description": {
"title": "Peertube Long Description",
"description": "The description of your instance",
"default": "Welcome to this PeerTube instance!",
"textarea": true,
"type": "string"
},
"terms": {
"title": "Terms",
"description": "",
"default": "No terms for now.",
"textarea": true,
"type": "string"
},
"code_of_conduct": {
"title": "Code of Conduct",
"description": "",
"default": "",
"textarea": true,
"type": "string"
},
"moderation_information": {
"title": "Moderation Information",
"description": "Who moderates the instance? What is the policy regarding NSFW videos? Political videos? etc",
"default": "",
"textarea": true,
"type": "string"
},
"creation_reason": {
"title": "Creation Reason",
"description": "Why did you create this instance?",
"default": "",
"textarea": true,
"type": "string"
},
"administrator": {
"title":"Administrator",
"description": "Who is behind the instance? A single person? A non profit?",
"default": "",
"type": "string"
},
"maintenance_lifetime": {
"title": "Maintenance Lifetime",
"description": "How long do you plan to maintain this instance?",
"default": "",
"type": "string"
},
"business_model": {
"title": "Business Model",
"description": "How will you pay the PeerTube instance server? With your own funds? With users donations? Advertising?",
"default": "",
"textarea": true,
"type": "string"
},
"hardware_information": {
"title": "Hardware Information",
"description": "",
"default": "",
"textarea": true,
"type": "string"
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Values returned by Peertube instanciation",
"properties": {
"frontend-url": {
"description": "Peertube Frontend URL",
"type": "string"
},
"backend-url": {
"description": "Peertube Backend URL",
"type": "string"
},
"username": {
"description": "Peertube username",
"type": "string"
},
"password": {
"description": "Peertube password",
"type": "string"
}
},
"type": "object"
}
[buildout]
extends =
{{ monitor_template }}
parts =
service-redis
promise-redis
postgresql
postgresql-binary-link
nginx-service
nginx-listen-promise
peertube-yaml
peertube-service
peertube-listen-promise
dcron-service
activate-crontab-file
peertube-backup-cron
peertube-database-resiliency-after-import-script
peertube-database-resiliency-exclude-file
publish-connection-parameter
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[directory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
srv = ${buildout:directory}/srv
var = ${buildout:directory}/var
log = ${:var}/log
run = ${:var}/run
www = ${:var}/www
crontabs = ${:etc}/crontabs
cron-entries = ${:etc}/cron.d
cronstamps = ${:etc}/cronstamps
cron-lines = ${:etc}/cron.lines
peertube_nginx_log = ${:log}/nginx
varnginx = ${:var}/nginx
services = ${:etc}/service
peertube_directory = ${:www}/peertube
config = ${:peertube_directory}/config
storage = ${:peertube_directory}/storage
versions = ${:peertube_directory}/versions
ssl = ${:etc}/ssl
##################
# Postgresql #
##################
[postgresql-password]
recipe = slapos.cookbook:generate.password
[postgresql-address]
recipe = slapos.cookbook:free_port
minimum = 5432
maximum = 5452
ip = {{ ipv4_random }}
[postgresql]
recipe = slapos.cookbook:postgres
bin = {{ postgresql10_location }}/bin/
services = ${directory:services}
dbname = peertube_prod
superuser = peertube
password = ${postgresql-password:passwd}
pgdata-directory = ${directory:srv}/postgresql
ipv4 = ${postgresql-address:ip}
# disable listening on ipv6
ipv6 =
port = ${postgresql-address:port}
[postgresql-binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:bin}
link-binary = ${postgresql:bin}/postgres ${postgresql:bin}/psql
#############
# Nginx #
#############
[nginx-service]
recipe = slapos.recipe.template
url = {{ template_nginx_service }}
output = ${directory:services}/nginx
virtual-depends =
${nginx-configuration:ip}
[nginx-listen-promise]
<= monitor-promise-base
promise = check_url_available
name = nginx_listen.py
config-verify = 0
config-url = https://[${nginx-configuration:ip}]:${nginx-configuration:port}
[nginx-configuration]
recipe = slapos.recipe.template
url = {{ template_nginx_configration }}
output = ${directory:etc}/nginx.cfg
access_log = ${directory:log}/nginx-access.log
error_log = ${directory:log}/nginx-error.log
ip = {{ ipv6_random }}
port = 9443
ssl_key = ${directory:ssl}/nginx.key
ssl_csr = ${directory:ssl}/nginx.csr
ssl_crt = ${directory:ssl}/nginx.crt
#############
# Redis #
#############
[redis]
recipe = slapos.cookbook:mkdirectory
srv = ${directory:srv}/redis
log = ${directory:log}/redis
[service-redis]
recipe = slapos.cookbook:redis.server
wrapper = ${directory:services}/redis
promise-wrapper = ${directory:bin}/redis-promise
server-dir = ${redis:srv}
config-file = ${directory:etc}/redis.conf
log-file = ${redis:log}/redis.log
pid-file = ${directory:run}/redis.pid
use-passwd = false
unixsocket = ${:server-dir}/redis.socket
# port = 0 means "don't listen on TCP at all" - listen only on unix socket
ipv6 = ::1
port = 0
server-bin = {{ redis_binprefix }}/redis-server
cli-bin = {{ redis_binprefix }}/redis-cli
depend =
${logrotate-entry-redis:recipe}
[promise-redis]
<= monitor-promise-base
promise = check_command_execute
name = promise-redis.py
config-command = ${service-redis:promise-wrapper}
[logrotate-entry-redis]
<= logrotate-entry-base
log = ${redis:log}/*.log
name = redis
################
# Peertube #
################
[peertube-passwd]
recipe = slapos.cookbook:generate.password
username = root
[peertube-yaml]
recipe = slapos.recipe.template
url = {{ template_peertube_yaml }}
output = ${directory:config}/peertube.yaml
[peertube-listen-promise]
<= monitor-promise-base
promise = check_url_available
name = peertube_listen.py
config-verify = 0
config-url = ${peertube-parameters:frontend-url}
[peertube-service]
recipe = slapos.recipe.template
url = {{ template_peertube_service }}
output = ${directory:services}/peertube
[peertube-database-resiliency-exclude-file]
recipe = slapos.recipe.template:jinja2
inline = {{ "${postgresql:pgdata-directory}/" }}
output = ${directory:srv}/exporter.exclude
[peertube-database-resiliency-after-import-script]
recipe = slapos.recipe.template
url = {{ template_peertube_restore }}
output = ${directory:srv}/runner-import-restore
mode = 755
#################################
# Cron service #
#################################
[dcron-service]
recipe = slapos.recipe.template
url = {{ template_dcron_service }}
output = ${directory:services}/crond
logfile = ${directory:log}/crond.log
[peertube-backup-script]
recipe = slapos.recipe.template
url = {{ template_peertube_backup }}
backup-file = ${directory:srv}/backup/peertube_prod-dump.db
output = ${directory:bin}/${:_buildout_section_name_}
mode = 0744
[peertube-backup-cron]
recipe = slapos.recipe.template
url = {{ template_crontab_line }}
output = ${directory:bin}/${:_buildout_section_name_}
script = ${peertube-backup-script:output}
name = ${:_buildout_section_name_}
frequency = {{ slapparameter_dict.get('frequency', '@daily') }}
[activate-crontab-file]
# XXX File is never removed
recipe = plone.recipe.command
stop-on-error = true
command = {{ coreutils_cat }} {{ template_crontab }} ${peertube-backup-cron:output} | {{ dcron_output }} -c ${directory:crontabs} -
[frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = PeerTube Server Frontend
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
shared = true
{% if slapparameter_dict.get('frontend-url', 'false') != 'false' -%}
state = stopped
{% endif -%}
config-type = websocket
config-websocket-path-list = /socket.io /socket /tracker/socket
config-url = https://[${nginx-configuration:ip}]:${nginx-configuration:port}
return = domain secure_access
[peertube-parameters]
recipe = slapos.recipe.build
slapparameter-dict = {{ dumps(slapparameter_dict) }}
default-frontend-url = ${frontend:connection-secure_access}
working-dir = {{ peertube_location }}
ipv4-port=9000
node-config-dir=${directory:config}
node-env=production
npm-bin={{ nodejs_location }}/bin/npm
default-parameters =
{
"name" : "Peertube in Slapos",
"frontend-url" : "",
"short_description" : "PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.",
"description" : "Welcome to this PeerTube instance!",
"terms" : "No terms for now.",
"code_of_conduct" : "",
"moderation_information" : "",
"creation_reason" : "",
"administrator" : "",
"maintenance_lifetime" : "",
"business_model" : "",
"hardware_information" : ""
}
init =
from six.moves.urllib.parse import urlparse
import json
default_parameters = json.loads(options.get('default-parameters').strip())
default_parameters['frontend-url'] = options['default-frontend-url']
parameters = dict(default_parameters, **options['slapparameter-dict'])
# options is not a dict...
options['name'] = parameters['name']
options['frontend-url'] = parameters['frontend-url']
options['short_description'] = parameters['short_description']
options['description'] = parameters['description']
options['terms'] = parameters['terms']
options['code_of_conduct'] = parameters['code_of_conduct']
options['moderation_information'] = parameters['moderation_information']
options['creation_reason'] = parameters['creation_reason']
options['administrator'] = parameters['administrator']
options['maintenance_lifetime'] = parameters['maintenance_lifetime']
options['business_model'] = parameters['business_model']
options['hardware_information'] = parameters['hardware_information']
url = urlparse(options.get('frontend-url'))
if url.port:
options['host'] = '[' + url.hostname + ']'
options['port'] = str(url.port)
else:
options['host'] = url.hostname
options['port'] = str(443)
[publish-connection-parameter]
recipe = slapos.cookbook:publish
backend-url = ${frontend:config-url}
frontend-url = ${peertube-parameters:frontend-url}
password = ${peertube-passwd:passwd}
username = ${peertube-passwd:username}
[buildout]
parts =
switch-softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[peertube]
recipe = slapos.recipe.template:jinja2
url = ${instance-peertube:target}
output = $${buildout:directory}/instance-peertube.cfg
context =
key eggs_directory buildout:eggs-directory
key develop_eggs_directory buildout:develop-eggs-directory
raw monitor_template ${monitor2-template:output}
key slapparameter_dict slap-configuration:configuration
raw ipv6_random $${slap-configuration:ipv6-random}
raw ipv4_random $${slap-configuration:ipv4-random}
raw template_peertube_yaml ${template-peertube-yaml:output}
raw template_nginx_configration ${template-nginx-configuration:output}
raw template_peertube_service ${template-peertube-service:output}
raw template_peertube_restore ${template-peertube-restore-script:output}
raw postgresql10_location ${postgresql10:location}
raw template_nginx_service ${template-nginx-service:output}
raw redis_binprefix ${redis28:location}/bin
raw template_dcron_service ${template-dcron-service:output}
raw template_peertube_backup ${template-peertube-backup-script:output}
raw template_crontab_line ${template-crontab-line:output}
raw coreutils_cat ${coreutils-output:cat}
raw template_crontab ${template-crontab:output}
raw dcron_output ${dcron-output:crontab}
raw peertube_location ${peertube:location}
raw nodejs_location ${nodejs:location}
[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
RootSoftwareInstance = $${:default}
default = peertube:output
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer= $${slap-connection:computer-id}
partition=$${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
[buildout]
extends =
buildout.hash.cfg
# buildout.hash.cfg is used for automated hash calculation of managed
# instance files by calling update-hash
# buildout.hash.cfg
# "slapos" stack describes basic things needed for 99.9% of SlapOS Software
# Releases
../../stack/slapos.cfg
../../stack/monitor/buildout.cfg
# Extend here component profiles, like openssl, apache, mariadb, curl...
# Or/and extend a stack (lamp, tomcat) that does most of the work for you
# In this example we extend from helloweb component.
../../component/unzip/buildout.cfg
../../component/curl/buildout.cfg
../../component/dcron/buildout.cfg
../../component/vim/buildout.cfg
../../component/nodejs/buildout.cfg
../../component/yarn/buildout.cfg
../../component/python3/buildout.cfg
../../component/nginx/buildout.cfg
../../component/ffmpeg/buildout.cfg
../../component/postgresql/buildout.cfg
../../component/nspr/buildout.cfg
../../component/gcc/buildout.cfg
../../component/libxml2/buildout.cfg
../../component/libxslt/buildout.cfg
../../component/lxml-python/buildout.cfg
# redis-server
../../component/redis/buildout.cfg
../../component/git/buildout.cfg
../../component/wget/buildout.cfg
# backup
../../component/rdiff-backup/buildout.cfg
../../component/rsync/buildout.cfg
parts =
# Call installation of slapos.cookbook egg defined in stack/slapos.cfg (needed
# in 99,9% of Slapos Software Releases)
slapos-cookbook
dcron
gcc
unzip
curl
nodejs
yarn
openssl
python3
nginx
ffmpeg
postgresql
redis
wget
# peetube sections
peertube
peertube-build
instance-profile
[nodejs]
<= nodejs-16.13.2
[peertube]
recipe = slapos.recipe.build:download-unpacked
url = https://github.com/Chocobozzz/PeerTube/releases/download/v4.2.2/peertube-v4.2.2.zip
md5sum = 1c9639748d66e8c49fc27e4705f87622
[peertube-build]
recipe = slapos.recipe.cmmi
path = ${peertube:location}
environment =
PATH=${unzip:location}/bin:${vim:location}/bin:${nodejs:location}/bin:${yarn:location}/bin:${python3:location}/bin:${nginx:location}/sbin:${postgresql10:location}/bin:${gcc-10.2:location}/bin:${redis:location}/bin:{git:location}/bin:{wget:location}/bin:%(PATH)s
CPPFLAGS=-I${openssl:location}/include
LDFLAGS=-L${curl:location}/lib -Wl,-rpath -Wl,${openssl:location}/lib -Wl
pre-configure =
${yarn:location}/bin/yarn install --production --pure-lockfile
configure-command = true
make-binary = cd ${peertube:location} && ${yarn:location}/bin/yarn
post-install =
rm -rf ${buildout:directory}/.cache/yarn/
rm -rf ${buildout:directory}/parts/peertube/client/node_modules/chromedriver/
[instance-profile]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/instance.cfg
[instance-peertube]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
destination = ${buildout:directory}/${:_buildout_section_name_}
[template-peertube-service]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-peertube-yaml]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-nginx-service]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-nginx-configuration]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-dcron-service]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-crontab-line]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-crontab]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-peertube-backup-script]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
[template-peertube-restore-script]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/${:filename}
{
"name": "Peertube",
"description": "Peertube Website Text",
"serialisation": "json-in-xml",
"software-type": {
"default": {
"title": "Default",
"software-type": "default",
"description": "Default",
"request": "instance-peertube-input-schema.json",
"response": "instance-peertube-output-schema.json",
"index": 1
}
}
}
# $${:_buildout_section_name_}
$${:frequency} ID=$${:name} $${:script}
# min(0-59) hours(0-23) day(1-31) month(1-12) dow(0-7) command
MAILTO=admins@erp5.org
#!${dash-output:dash}
# BEWARE: This file is operated by slapos node
# BEWARE: It will be overwritten automatically
exec ${dcron-output:crond} \
-s $${directory:cron-entries} \
-c $${directory:crontabs} \
-t $${directory:cronstamps} \
-f -l 5 \
-L $${dcron-service:logfile}
# -M cron_simplelogger
#!${dash-output:dash}
# BEWARE: This file is operated by slapos node
# BEWARE: It will be overwritten automatically
if [ ! -e $${nginx-configuration:ssl_crt} ]
then
${openssl-output:openssl} genrsa -out $${nginx-configuration:ssl_key} 2048
${openssl-output:openssl} req -new \
-subj "/C=AA/ST=Denial/L=Nowhere/O=Dis/CN=$${nginx-configuration:ip}" \
-key $${nginx-configuration:ssl_key} -out $${nginx-configuration:ssl_csr}
${openssl-output:openssl} x509 -req -days 365 \
-in $${nginx-configuration:ssl_csr} \
-signkey $${nginx-configuration:ssl_key} \
-out $${nginx-configuration:ssl_crt}
fi
exec ${nginx-output:nginx} \
-c $${nginx-configuration:output}
This diff is collapsed.
#!${dash-output:dash}
# Dump the databse
$${postgresql:bin}/pg_dump -h $${postgresql:pgdata-directory} -U $${postgresql:superuser} -Fc peertube_prod > $${peertube-backup-script:backup-file}
#!${dash-output:dash}
# DO NOT RUN THIS SCRIPT ON PRODUCTION INSTANCE
# OR POSTGRESQL DATA WILL BE ERASED.
# This script will import the dump of the postgresql database to the real
# database. It is launched by the clone (importer) instance of theia
# in the end of the import script.
# Depending on the output, it will create a file containing
# the status of the restoration (success or failure)
die() {
echo "$*" 1>&2
exit 1
}
echo "Postgresql data directory is ready"
# 2. Make sure the postgresql process is not running.
# Quote from the postgresql doc:
# > While the server is running, its PID is stored in the file postmaster.pid in the data directory.
# https://www.postgresql.org/docs/current/server-start.html
# which means if the postmaster.pid exist, then the postgresql is running.
pid_file=$${postgresql:pgdata-directory}/postmaster.pid
if [ -e "$pid_file" ]; then
echo "Postgresql is running, this should not happened, aborting."
exit 1
fi
echo "Starting postgresql..."
$${postgresql:bin}/postgres -D $${postgresql:pgdata-directory} &
postgresql_pid=$!
trap "kill $postgresql_pid" EXIT TERM INT
# If postgres has stopped, abort
if ! [ -d /proc/$postgresql_pid ]; then
echo "postgresql exited, aborting."
exit 1
fi
# run psql
psql() {
PGPASSWORD=$${postgresql:password} $${postgresql:bin}/psql \
-h $${postgresql:ipv4} \
-p $${postgresql:port} \
-U $${postgresql:superuser} \
-d $${postgresql:dbname} \
"$@"
}
echo "Ready to check postgresql is running..."
# initial db setup
# ( first quering PG several times waiting a bit till postgresql is started and ready )
tpgwait=60
while true; do
pgtables="$(psql -c '\d' 2>&1)" && break
tpgwait=$(( $tpgwait - 1 ))
test $tpgwait = 0 && die "pg query problem"
echo "I: PostgreSQL is not ready (yet ?); will retry $tpgwait times..." 1>&2
sleep 1
done
echo "I: PostgreSQL ready." 1>&2
echo "Postgresql is running, ready to restore"
# Restore the database
# Use -d to connect to the default 'postgres' database to allow us to restore the $${postgresql:dbname}
PGPASSWORD=$${postgresql:password} $${postgresql:bin}/pg_restore -h $${postgresql:ipv4} -p $${postgresql:port} -U $${postgresql:superuser} -e -c -C -d postgres $${peertube-backup-script:backup-file} || {
RESTORE_EXIT_CODE=$?
echo 'Backup restoration failed.'
exit $RESTORE_EXIT_CODE
}
echo "Postgresql restore finished"
#!${dash-output:dash}
# setup db
die() {
echo "$*" 1>&2
exit 1
}
# run psql on gitlab db
psql() {
PGPASSWORD=$${postgresql:password} $${postgresql:bin}/psql \
-h $${postgresql:ipv4} \
-p $${postgresql:port} \
-U $${postgresql:superuser} \
-d $${postgresql:dbname} \
"$@"
}
# initial db setup
# ( first quering PG several times waiting a bit till postgresql is started and ready )
tpgwait=5
while true; do
pgtables="$(psql -c '\d' 2>&1)" && break
tpgwait=$(( $tpgwait - 1 ))
test $tpgwait = 0 && die "pg query problem"
echo "I: PostgreSQL is not ready (yet ?); will retry $tpgwait times..." 1>&2
sleep 1
done
echo "I: PostgreSQL ready." 1>&2
cd ${peertube:location}
exec env PT_INITIAL_ROOT_PASSWORD=$${peertube-passwd:passwd} NODE_ENV=peertube\
NODE_CONFIG_DIR=$${directory:config} PATH=${ffmpeg:location}/bin:$PATH\
${nodejs:location}/bin/node ${peertube:location}/dist/server
This diff is collapsed.
Tests for Peertube software release
##############################################################################
#
# Copyright (c) 2019 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from setuptools import setup, find_packages
version = '0.0.1.dev0'
name = 'slapos.test.peertube'
with open("README.md") as f:
long_description = f.read()
setup(
name=name,
version=version,
description="Test for SlapOS' peertube",
long_description=long_description,
long_description_content_type='text/markdown',
maintainer="Nexedi",
maintainer_email="info@nexedi.com",
url="https://lab.nexedi.com/nexedi/slapos",
packages=find_packages(),
install_requires=[
'slapos.core',
'slapos.libnetworkcache',
'erp5.util',
'requests',
],
zip_safe=True,
test_suite='test',
)
##############################################################################
#
# Copyright (c) 2019 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import requests
import re
from mimetypes import guess_type
from json.decoder import JSONDecodeError
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software.cfg')))
class TestPeerTube(SlapOSInstanceTestCase):
def setUp(self):
self.connection_parameters = self.computer_partition.getConnectionParameterDict()
def test_get(self):
url = self.connection_parameters['frontend-url']
response = requests.get(url, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('PeerTube', response.text)
response =requests.get(url + "/feeds/videos.xml?sort=-trending", verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
self.assertIn('rss', response.text)
def test_video_upload(self):
api_url = self.connection_parameters['frontend-url']
# api_url: https://[2001:67c:1254:fd::9ee2]:9443
# self.connection_parameters
# {'backend-url': 'https://[2001:67c:1254:fd::9ee2]:9443', 'frontend-hostname': '[2001:67c:1254:fd::9ee2]:9443', 'frontend-url': 'https://[2001:67c:1254:fd::9ee2]:9443', 'password': '8ydTfRpv', 'username': 'root'}
response = requests.get(api_url + '/api/v1/oauth-clients/local', verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
try:
data = response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
client_id = data['client_id']
client_secret = data['client_secret']
username = self.connection_parameters['username']
password = self.connection_parameters['password']
auth_data = {
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'password',
'response_type': 'code',
'username': username,
'password': password
}
auth_result = requests.post(api_url + '/api/v1/users/token', data=auth_data, verify=False)
self.assertEqual(requests.codes['OK'], auth_result.status_code)
try:
auth_result_json = auth_result.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
token_type = auth_result_json['token_type']
access_token = auth_result_json['access_token']
headers = {
'Authorization': token_type + ' ' + access_token
}
video_name = "Small test video"
file_path = "./small.mp4"
file_mime_type = guess_type(file_path)[0]
with open(file_path, 'rb') as f:
video_data = {
'channelId': 1,
'name': video_name,
'commentEnabled': False,
}
upload_response = requests.post(
api_url + '/api/v1/videos/upload',
headers=headers,
data=video_data,
files={'videofile': (os.path.basename(file_path), f, file_mime_type)},
verify=False
)
try:
video_ids = upload_response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
# {'video': {'id': 7, 'shortUUID': 'nrnKJNCsRP7NkwRr51TK3e', 'uuid': 'ad9ae99d-07db-4e4c-adc3-73566d59a4c5'}}
self.assertIn('video', video_ids)
id = video_ids['video']['id']
# Check the video is uploaded, we can get its stats
response = requests.get(api_url + '/api/v1/videos/' + str(id) + '/stats/overall', headers=headers, verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
try:
result = response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
self.assertIn('totalWatchTime', response.json())
# Check the transcoding is enabled
response = requests.get(api_url + '/api/v1/config', headers=headers, verify=False)
try:
result = response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
# {
# 'hls': {'enabled': True},
# 'webtorrent': {'enabled': False},
# 'enabledResolutions': [144, 240, 360, 480, 720, 1080, 1440, 2160],
# 'profile': 'default',
# 'availableProfiles': ['default']
# }
self.assertIn("hls", result['transcoding'])
self.assertIn("True", str(result['transcoding']['hls']))
......@@ -242,6 +242,11 @@ setup = ${slapos-repository:location}/software/erp5testnode/test/
egg = slapos.test.beremiz_ide
setup = ${slapos-repository:location}/software/beremiz-ide/test/
[slapos.test.peertube-setup]
<= setup-develop-egg
egg = slapos.test.peertube
setup = ${slapos-repository:location}/software/peertube/test/
[slapos.core-repository]
<= git-clone-repository
repository = https://lab.nexedi.com/nexedi/slapos.core.git
......@@ -316,6 +321,7 @@ eggs +=
${slapos.test.nextcloud-setup:egg}
${slapos.test.nginx-push-stream-setup:egg}
${slapos.test.ors-amarisoft-setup:egg}
${slapos.test.peertube-setup:egg}
${slapos.test.plantuml-setup:egg}
${slapos.test.powerdns-setup:egg}
${slapos.test.proftpd-setup:egg}
......@@ -406,6 +412,7 @@ tests =
nextcloud ${slapos.test.nextcloud-setup:setup}
nginx-push-stream ${slapos.test.nginx-push-stream-setup:setup}
ors-amarisoft ${slapos.test.ors-amarisoft-setup:setup}
peertube ${slapos.test.peertube-setup:setup}
plantuml ${slapos.test.plantuml-setup:setup}
powerdns ${slapos.test.powerdns-setup:setup}
proftpd ${slapos.test.proftpd-setup:setup}
......
......@@ -38,6 +38,8 @@ import requests
from datetime import datetime, timedelta
from six.moves.urllib.parse import urljoin
from mimetypes import guess_type
from json.decoder import JSONDecodeError
from slapos.testing.testcase import installSoftwareUrlList
......@@ -48,6 +50,9 @@ from test import SlapOSInstanceTestCase, theia_software_release_url
erp5_software_release_url = os.path.abspath(
os.path.join(
os.path.dirname(__file__), '..', '..', 'erp5', 'software.cfg'))
peertube_software_release_url = os.path.abspath(
os.path.join(
os.path.dirname(__file__), '..', '..', 'peertube', 'software.cfg'))
def setUpModule():
......@@ -232,3 +237,209 @@ class TestTheiaResilienceERP5(ERP5Mixin, test_resiliency.TestTheiaResilience):
# Check that the mariadb catalog was properly restored
out = subprocess.check_output((mysql_bin, 'erp5', '-e', query), universal_newlines=True)
self.assertIn(self._erp5_new_title, out, 'Mariadb catalog is not properly restored')
class TestTheiaResiliencePeertube(test_resiliency.TestTheiaResilience):
test_instance_max_retries = 12
backup_max_tries = 480
backup_wait_interval = 60
_connexion_parameters_regex = re.compile(r"{.*}", re.DOTALL)
_test_software_url = peertube_software_release_url
def _getPeertubeConnexionParameters(self, instance_type='export'):
out = self.captureSlapos(
'request', 'test_instance', self._test_software_url,
stderr=subprocess.STDOUT,
text=True,
)
print(out)
return json.loads(self._connexion_parameters_regex.search(out).group(0).replace("'", '"'))
def test_twice(self):
# do nothing
pass
def _prepareExport(self):
super(TestTheiaResiliencePeertube, self)._prepareExport()
postgresql_partition = self._getPeertubePartitionPath('export', 'postgres')
postgresql_bin = os.path.join(postgresql_partition, 'bin', 'psql')
postgres_bin = os.path.join(postgresql_partition, 'bin', 'postgres')
postgresql_srv = os.path.join(postgresql_partition, 'srv', 'postgresql')
peertube_conenction_info = self._getPeertubeConnexionParameters()
frontend_url = peertube_conenction_info['frontend-url']
response = requests.get(frontend_url + '/api/v1/oauth-clients/local', verify=False)
self.assertEqual(requests.codes['OK'], response.status_code)
try:
data = response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
client_id = data['client_id']
client_secret = data['client_secret']
username = peertube_conenction_info['username']
password = peertube_conenction_info['password']
auth_data = {
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'password',
'response_type': 'code',
'username': username,
'password': password
}
auth_result = requests.post(frontend_url + '/api/v1/users/token', data=auth_data, verify=False)
try:
auth_result_json = auth_result.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
token_type = auth_result_json['token_type']
access_token = auth_result_json['access_token']
headers = {
'Authorization': token_type + ' ' + access_token
}
video_name = "Small test video"
file_path = "../../peertube/test/small.mp4"
pwd_file_path = os.path.realpath(__file__)
print(pwd_file_path)
file_mime_type = guess_type(file_path)[0]
with open(file_path, 'rb') as f:
video_data = {
'channelId': 1,
'name': video_name,
'commentEnabled': False,
'privacy': 1,
}
upload_response = requests.post(
frontend_url + '/api/v1/videos/upload',
headers=headers,
data=video_data,
files={'videofile': (os.path.basename(file_path), f, file_mime_type)},
verify=False
)
try:
video_ids = upload_response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube API is incorrect.")
# e.g: {'video': {'id': 7, 'shortUUID': 'nrnKJNCsRP7NkwRr51TK3e', 'uuid': 'ad9ae99d-07db-4e4c-adc3-73566d59a4c5'}}
self.assertIn('video', video_ids)
# Checked the modification has been updated in the database
output = subprocess.check_output(
(postgresql_bin, '-h', postgresql_srv, '-U', 'peertube', '-d', 'peertube_prod',
'-c', 'SELECT * FROM "video"'),
universal_newlines=True)
self.assertIn("Small test video", output)
# Do a fake periodically update
# Compute backup date in the near future
soon = (datetime.now() + timedelta(minutes=4)).replace(second=0)
frequency = "%d * * * *" % soon.minute
params = 'frequency=%s' % frequency
# Update Peertube parameters
print('Requesting Peertube with parameters %s' % params)
self.checkSlapos('request', 'test_instance', self._test_software_url, '--parameters', params)
self.checkSlapos('node', 'instance')
self.callSlapos('node', 'restart', 'all')
# Wait until after the programmed backup date, and a bit more
t = (soon - datetime.now()).total_seconds()
self.assertLess(0, t)
time.sleep(t + 120)
self.callSlapos('node', 'status')
# Check that postgresql backup has started
postgresql_backup = os.path.join(postgresql_partition, 'srv', 'backup')
self.assertIn('peertube_prod-dump.db', os.listdir(postgresql_backup))
def _checkTakeover(self):
super(TestTheiaResiliencePeertube, self)._checkTakeover()
postgresql_partition = self._getPeertubePartitionPath('export', 'postgres')
postgresql_bin = os.path.join(postgresql_partition, 'bin', 'psql')
postgres_bin = os.path.join(postgresql_partition, 'bin', 'postgres')
postgresql_srv = os.path.join(postgresql_partition, 'srv', 'postgresql')
peertube_conenction_info = self._getPeertubeConnexionParameters()
frontend_url = peertube_conenction_info['frontend-url']
storage_path = os.path.join(postgresql_partition, 'var', 'www', 'peertube', 'storage')
# Wait for connect Peertube
for _ in range(5):
try:
response = requests.get(frontend_url, verify=False, allow_redirects=False)
except Exception:
time.sleep(20)
continue
if response.status_code != 200:
time.sleep(20)
continue
break
else:
self.fail('Failed to connect to Peertube')
# Get the video path, the part of this path will be used in the video URL
# e.g: var/www/peertube/storage/streaming-playlists/hls/XXXX/YYYY.mp4
# path before hls dir
hls_path = os.path.join(storage_path, 'streaming-playlists', 'hls')
#Choose only one video path
video_path = None
for root, dirs, files in os.walk(hls_path):
for a_file in files:
if a_file.endswith('.mp4'):
video_path = os.path.join(root, a_file)
break
else:
continue
break
# path like "streaming-playlists/hls/XXXX/YYYY.mp4"
self.assertIn('streaming-playlists', video_path)
streaming_video_path = video_path[video_path.index('streaming-playlists'):]
video_url = frontend_url + '/static/' + streaming_video_path
response = requests.get(video_url, verify=False)
# The video mp4 file is accesible through the URL
self.assertEqual(requests.codes['OK'], response.status_code)
video_feeds_url = frontend_url + '/feeds/videos.json'
response = requests.get(video_feeds_url, verify=False)
# The video feeds returns the correct status code
self.assertEqual(requests.codes['OK'], response.status_code)
try:
video_data= response.json()
except JSONDecodeError:
self.fail("No json file returned! Maybe your Peertube feeds URL is incorrect.")
# Check the first video title is in the response content
video_title = video_data['items'][0]['title']
self.assertIn("Small test video", video_title)
def _getPeertubePartition(self, servicename):
p = subprocess.Popen(
(self._getSlapos(), 'node', 'status'),
stdout=subprocess.PIPE, universal_newlines=True)
out, _ = p.communicate()
found = set()
for line in out.splitlines():
if servicename in line:
found.add(line.split(':')[0])
if not found:
raise Exception("Peertube %s partition not found" % servicename)
elif len(found) > 1:
raise Exception("Found several partitions for Peertube %s" % servicename)
return found.pop()
def _getPeertubePartitionPath(self, instance_type, servicename, *paths):
partition = self._getPeertubePartition(servicename)
return self.getPartitionPath(
instance_type, 'srv', 'runner', 'instance', partition, *paths)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment