#!/bin/bash # _____ _ _ # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___ # | __| _| -_| -_| . | . | | . | . | | -_| # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___| # # Freedom in the Cloud # # PeerTube server # # License # ======= # # Copyright (C) 2017-2019 Bob Mottram <bob@freedombone.net> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. VARIANTS="full full-vim media" APP_CATEGORY=media IN_DEFAULT_INSTALL=0 SHOW_ON_ABOUT=1 NOT_ON_ARM=1 REQUIRES_APP= PEERTUBE_DOMAIN_NAME= PEERTUBE_CODE= PEERTUBE_VERSION='v1.1.0' PEERTUBE_DOWNLOAD_FILENAME="peertube-${PEERTUBE_VERSION}" PEERTUBE_DOWNLOAD="https://github.com/Chocobozzz/PeerTube/releases/download/${PEERTUBE_VERSION}/${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" PEERTUBE_ONION_PORT=8136 PEERTUBE_PORT=9004 MESH_PEERTUBE_PORT=8500 PEERTUBE_DIR=/etc/peertube PEERTUBE_CONFIG_FILE=$PEERTUBE_DIR/config/production.yaml PEERTUBE_SHORT_DESCRIPTION=$'Video broadcast' PEERTUBE_DESCRIPTION=$'Video broadcast' PEERTUBE_MOBILE_APP_URL= peertube_upgrading= peertube_variables=(PEERTUBE_DOMAIN_NAME PEERTUBE_CODE PEERTUBE_ADMIN_PASSWORD ONION_ONLY DDNS_PROVIDER MY_USERNAME ARCHITECTURE MY_EMAIL_ADDRESS) function peertube_tcp_tuning { if [ -f "$PEERTUBE_DIR/peertube-latest/support/sysctl.d/30-peertube-tcp.conf" ]; then cp "$PEERTUBE_DIR/peertube-latest/support/sysctl.d/30-peertube-tcp.conf" /etc/sysctl.d/ sysctl -p /etc/sysctl.d/30-peertube-tcp.conf fi } function install_peertube_base { if [ ! $peertube_upgrading ]; then increment_app_install_progress fi if [ ! -d $PEERTUBE_DIR/config ]; then mkdir -p $PEERTUBE_DIR/config fi if [ ! -d $PEERTUBE_DIR/storage ]; then mkdir -p $PEERTUBE_DIR/storage fi if [ ! -d $PEERTUBE_DIR/versions ]; then mkdir -p $PEERTUBE_DIR/versions fi cd ${PEERTUBE_DIR}/versions || exit 35 if [ -f "/repos/${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" ]; then cp "/repos/${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" "${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" else wget -q "$PEERTUBE_DOWNLOAD" -O "${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" fi if [ ! -f "${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" ]; then peertube_upgrading= exit 56 fi if [ ! $peertube_upgrading ]; then increment_app_install_progress fi unxz "${PEERTUBE_DOWNLOAD_FILENAME}.tar.xz" if [ ! -f "${PEERTUBE_DOWNLOAD_FILENAME}.tar" ]; then echo $"${PEERTUBE_DOWNLOAD_FILENAME}.tar not found" peertube_upgrading= exit 63 fi if [ ! $peertube_upgrading ]; then increment_app_install_progress fi tar -xvf "${PEERTUBE_DOWNLOAD_FILENAME}.tar" rm "${PEERTUBE_DOWNLOAD_FILENAME}.tar" if [ ! $peertube_upgrading ]; then increment_app_install_progress fi cd ../ || exit 35 ln -s "versions/${PEERTUBE_DOWNLOAD_FILENAME}" ./peertube-latest cd ${PEERTUBE_DIR}/peertube-latest || exit 35 if [ ! $peertube_upgrading ]; then increment_app_install_progress fi # NOTE: these get installed from the global npm npm install npm@6 if [ ! $peertube_upgrading ]; then increment_app_install_progress fi npm install yarn@1.10.1 if [ ! $peertube_upgrading ]; then increment_app_install_progress fi if [ ! -f "${PEERTUBE_DIR}/.bashrc" ]; then echo "PATH=/root/.npm-global/bin:\$PATH" > "${PEERTUBE_DIR}/.bashrc" else if ! grep -q "npm-global" "${PEERTUBE_DIR}/.bashrc"; then echo "PATH=/root/.npm-global/bin:\$PATH" >> "${PEERTUBE_DIR}/.bashrc" fi fi chown -R peertube:peertube $PEERTUBE_DIR if [ ! $peertube_upgrading ]; then increment_app_install_progress fi # install a second time locally peertube_local_install="sudo -H -u peertube ${PEERTUBE_DIR}/peertube-latest/node_modules/.bin/npm install" if [ ! $peertube_upgrading ]; then increment_app_install_progress fi $peertube_local_install npm@6 if [ ! $peertube_upgrading ]; then increment_app_install_progress fi $peertube_local_install yarn@1.10.1 if [ -f "${PEERTUBE_DIR}/package-lock.json" ]; then rm "${PEERTUBE_DIR}/package-lock.json" fi cd ${PEERTUBE_DIR}/peertube-latest || exit 73 if ! sudo -H -u peertube NPM_CONFIG_PREFIX=${PEERTUBE_DIR}/peertube-latest/node_modules/npm NODE_CONFIG_DIR=${PEERTUBE_DIR}/config ${PEERTUBE_DIR}/peertube-latest/node_modules/.bin/yarn install --production --pure-lockfile; then peertube_upgrading= exit 54 fi cd ${PEERTUBE_DIR} || exit 71 if [ ! $peertube_upgrading ]; then increment_app_install_progress fi if [ ! -d ${PEERTUBE_DIR}/storage/logs ]; then sudo -H -u peertube mkdir -p ${PEERTUBE_DIR}/storage/logs fi #sudo -H -u peertube ${PEERTUBE_DIR}/peertube-latest/node_modules/.bin/npm audit fix peertube_tcp_tuning } function peertube_setting_registration { allow_registrations="$1" if [[ "$allow_registrations" == '1' ]]; then sed -i "0,/enabled:.*/s//enabled: false/" ${PEERTUBE_CONFIG_FILE} systemctl restart peertube fi if [[ "$allow_registrations" == '0' ]]; then sed -i "0,/enabled:.*/s//enabled: true/" ${PEERTUBE_CONFIG_FILE} systemctl restart peertube fi } function peertube_import_from_syncthing { peertubedomain="https://$PEERTUBE_DOMAIN_NAME" nodecmd='node' if [[ "$ONION_ONLY" != 'no' ]]; then peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)" nodecmd='torsocks node' fi { echo '#!/bin/bash'; echo ''; echo 'LOCKFILE=/tmp/.peertube.lock'; echo ''; echo 'if [ -f /root/.peertube.lock ]; then'; echo " lockctr=\$(cat \$LOCKFILE)"; echo " lockctr=\$((lockctr+1))"; echo " echo \"\$lockctr\" > \$LOCKFILE"; echo " if [ \$lockctr -ge 30 ]; then"; echo " rm \$LOCKFILE"; echo ' else'; echo ' exit 0'; echo ' fi'; echo 'fi'; echo ''; echo "MY_USERNAME=\$(cat /root/${PROJECT_NAME}.cfg | grep MY_USERNAME | awk -F '=' '{print \$2}')"; echo "if [ ! \"\$MY_USERNAME\" ]; then"; echo ' exit 0'; echo 'fi'; echo ''; echo "search_dir=/home/\$MY_USERNAME/Sync/peertube_upload"; echo "if [ ! -f \$search_dir/login.txt ]; then"; echo ' exit 0'; echo 'fi'; echo "import_script=${PEERTUBE_DIR}/peertube-latest/dist/server/tools/upload.js"; echo "if [ ! -f \$import_script ]; then"; echo ' exit 0'; echo 'fi'; echo ''; echo "peertubedomain=\"$peertubedomain\""; echo "peertubeuser=\$(sed -n 1p < \"\$search_dir/login.txt\")"; echo "peertubepassword=\$(sed -n 2p < \"\$search_dir/login.txt\")"; echo 'peertubensfw='; echo "if grep -q 'nsfw' \"\$search_dir/login.txt\"; then"; echo " peertubensfw='--nsfw'"; echo 'fi'; echo "if grep -q 'NSFW' \"\$search_dir/login.txt\"; then"; echo " peertubensfw='--nsfw'"; echo 'fi'; echo ''; echo "peertubeprivate='-P 3'"; echo "if grep -q 'public' \"\$search_dir/login.txt\"; then"; echo " peertubeprivate='-P 1'"; echo 'fi'; echo "if grep -q 'Public' \"\$search_dir/login.txt\"; then"; echo " peertubeprivate='-P 1'"; echo 'fi'; echo ''; echo 'failed_uploads=0'; echo ''; echo "cd ${PEERTUBE_DIR} || exit 32"; echo "echo \"0\" > \$LOCKFILE"; echo ''; echo "for video_file in \$search_dir/*; do"; echo " if [[ \"\$video_file\" == *'.ogv' || \"\$video_file\" == *'.webm' ]]; then"; echo " if ! grep -q \"\$video_file\" /root/.peertube_uploaded; then"; echo " peertubetitle=\$(basename \"\$video_file\" | awk -F '.' '{print \$1}' | sed 's|_| |g' | sed 's|-| |g')"; echo " if $nodecmd \$import_script -n \"\$peertubetitle\" \$peertubensfw \$peertubeprivate -u \"\$peertubedomain\" -U \"\$peertubeuser\" --password \"\$peertubepassword\" -f \"\$video_file\"; then"; echo " echo \"\$video_file\" >> /root/.peertube_uploaded"; echo " rm \$LOCKFILE"; echo " exit 0"; echo ' else'; echo " failed_uploads=\$((failed_uploads+1))"; echo " if [ \$failed_uploads -gt 1 ]; then"; echo " rm \$LOCKFILE"; echo ' exit 0'; echo ' fi'; echo ' fi'; echo ' fi'; echo ' fi'; echo 'done'; echo ''; echo "rm \$LOCKFILE"; } > /usr/bin/peertubesync chmod +x /usr/bin/peertubesync cron_add_mins 1 /usr/bin/peertubesync } function peertube_create_database { if [ -f "$IMAGE_PASSWORD_FILE" ]; then PEERTUBE_ADMIN_PASSWORD="$(printf "%s" "$(cat "$IMAGE_PASSWORD_FILE")")" else if [ ! "$PEERTUBE_ADMIN_PASSWORD" ]; then PEERTUBE_ADMIN_PASSWORD="$(create_password "${MINIMUM_PASSWORD_LENGTH}")" fi fi if [ ! "$PEERTUBE_ADMIN_PASSWORD" ]; then return fi systemctl restart postgresql run_system_query_postgresql "CREATE USER peertube WITH PASSWORD '$PEERTUBE_ADMIN_PASSWORD';" run_system_query_postgresql "CREATE DATABASE peertube OWNER peertube;" run_system_query_postgresql "GRANT ALL PRIVILEGES ON DATABASE peertube to peertube;" run_system_query_postgresql "set statement_timeout to 40000;" peertube_database_extensions } function logging_on_peertube { if [ ! -d $PEERTUBE_DIR ]; then return fi sed -i "s|level: '.*|level: 'debug' # debug/info/warning/error|g" "$PEERTUBE_DIR/config/production.yaml" systemctl restart peertube } function logging_off_peertube { if [ ! -d $PEERTUBE_DIR ]; then return fi sed -i "s|level: '.*|level: 'error' # debug/info/warning/error|g" "$PEERTUBE_DIR/config/production.yaml" systemctl restart peertube } function remove_user_peertube { echo -n '' # remove_username="$1" # TODO: remove user } function add_user_peertube { if [[ $(app_is_installed peertube) == "0" ]]; then echo '0' return fi # new_username="$1" # new_user_password="$2" # TODO: add user echo '0' } function install_interactive_peertube { if [ ! "$ONION_ONLY" ]; then ONION_ONLY='no' fi if [[ $ONION_ONLY != "no" ]]; then PEERTUBE_DOMAIN_NAME='peertube.local' write_config_param "PEERTUBE_DOMAIN_NAME" "$PEERTUBE_DOMAIN_NAME" else function_check interactive_site_details interactive_site_details "peertube" "PEERTUBE_DOMAIN_NAME" "PEERTUBE_CODE" fi APP_INSTALLED=1 } function peertube_set_admin_email { read_config_param "$MY_EMAIL_ADDRESS" data=$(mktemp 2>/dev/null) dialog --title $"Set PeerTube administrator email address" \ --backtitle $"Freedombone Control Panel" \ --inputbox $"Admin email address" 8 75 "$MY_EMAIL_ADDRESS" 2>"$data" sel=$? case $sel in 0) peertube_email=$(<"$data") if [[ "$peertube_email" != *' '* && "$peertube_email" != *','* && "$peertube_email" != *';'* && "$peertube_email" == *'@'* && "$peertube_email" == *'.'* ]]; then if [ ${#peertube_email} -gt 8 ]; then sed -i "s|email:.*|email: '${peertube_email}'|g" ${PEERTUBE_CONFIG_FILE} systemctl restart peertube dialog --title $"Set PeerTube administrator email address" \ --msgbox $"Set to $peertube_email" 6 75 fi fi ;; esac rm -f "$data" } function peertube_disable_signups { dialog --title $"Disable PeerTube signups" \ --backtitle $"Freedombone Control Panel" \ --yesno $"\\nDo you wish to disable further PeerTube signups?" 8 75 sel=$? case $sel in 0) sed -i "0,/enabled:.*/s//enabled: false/" ${PEERTUBE_CONFIG_FILE};; 1) sed -i "0,/enabled:.*/s//enabled: true/" ${PEERTUBE_CONFIG_FILE};; 255) return;; esac systemctl restart peertube } function peertube_import_from_file { read_config_param MY_USERNAME read_config_param PEERTUBE_DOMAIN_NAME read_config_param ONION_ONLY data2=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Control Panel" \ --title $"Import Video from file" \ --form $"Enter your PeerTube login details and video title" 10 65 4 \ $"Username:" 1 1 "$MY_USERNAME" 1 18 16 15 \ $"Password:" 2 1 "" 2 18 40 10000 \ $"Video Title:" 3 1 "" 3 18 40 1000 \ $"NSFW:" 4 1 $"no" 4 18 4 4 \ 2> "$data2" sel=$? case $sel in 1) rm -f "$data2" return;; 255) rm -f "$data2" return;; esac peertubeuser=$(sed -n 1p < "$data2") peertubepassword=$(sed -n 2p < "$data2") peertubetitle=$(sed -n 3p < "$data2") peertubensfw=$(sed -n 4p < "$data2") rm -f "$data2" peertubedomain="https://$PEERTUBE_DOMAIN_NAME" nodecmd='node' if [[ "$ONION_ONLY" != 'no' ]]; then peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)" nodecmd='torsocks node' fi selected_file=$(dialog --title "Choose the video file (select with spacebar)" --fselect "/home/$MY_USERNAME/" 30 60) if [ ! "$selected_file" ]; then return fi if [[ "$selected_file" != *'.ogv' && "$selected_file" != *'.webm' ]]; then dialog --title $"Import video from file" \ --msgbox $"The video should be in ogv or webm format" 6 75 return fi cd $PEERTUBE_DIR || exit 32 import_script=$PEERTUBE_DIR/peertube-latest/dist/server/tools/upload.js if [ ! -f $import_script ]; then dialog --title $"Import videos" \ --msgbox $"upload script was not found" 6 75 return fi nsfwstr= if [[ "$peertubensfw" == *'y'* || "$peertubensfw" == *'Y'* ]]; then nsfwstr='--nsfw' fi titlestr=$(basename "$selected_file" | awk -F '.' '{print $1}' | sed 's|_| |g' | sed 's|-| |g') if [ "$peertubetitle" ]; then titlestr="-n \"$peertubetitle\"" fi clear $nodecmd $import_script $nsfwstr "$titlestr" -u "$peertubedomain" -U "$peertubeuser" --password "$peertubepassword" -f "$selected_file" dialog --title $"Import video from file" \ --msgbox $"Video imported from $selected_file" 6 75 } function peertube_import_videos { read_config_param MY_USERNAME read_config_param PEERTUBE_DOMAIN_NAME read_config_param ONION_ONLY data2=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Control Panel" \ --title $"Import Videos from legacy sites" \ --form $"Enter a channel of video URL for YouTube/Vimeo/Dailymotion" 10 75 4 \ $"Username:" 1 1 "$MY_USERNAME" 1 22 16 15 \ $"Password:" 2 1 "" 2 22 50 10000 \ $"Video/Channel URL:" 3 1 "" 3 22 50 10000 \ 2> "$data2" sel=$? case $sel in 1) rm -f "$data2" return;; 255) rm -f "$data2" return;; esac peertubeuser=$(sed -n 1p < "$data2") peertubepassword=$(sed -n 2p < "$data2") video_url=$(sed -n 3p < "$data2") rm -f "$data2" peertubedomain="https://$PEERTUBE_DOMAIN_NAME" nodecmd='node' if [[ "$ONION_ONLY" != 'no' ]]; then peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)" nodecmd='torsocks node' fi if [ ${#peertubeuser} -lt 3 ]; then dialog --title $"Import videos from legacy sites" \ --msgbox $"Username was not valid" 6 75 return fi if [ ${#peertubepassword} -lt 3 ]; then dialog --title $"Import videos from legacy sites" \ --msgbox $"Password was not valid" 6 75 return fi if [[ "$video_url" == *' '* || "$video_url" == *','* || "$video_url" == *'@'* ]]; then dialog --title $"Import videos from legacy sites" \ --msgbox $"Video/channel URL was not valid" 6 75 return fi if [ ${#video_url} -lt 8 ]; then dialog --title $"Import videos from legacy sites" \ --msgbox $"Video/channel URL was not valid" 6 75 return fi cd $PEERTUBE_DIR || exit 32 import_script=$PEERTUBE_DIR/peertube-latest/dist/server/tools/import-videos.js # default to downloading as webm sed -i "s|'.mp4'|'.webm'|g" $import_script sed -i "s|const options = \\['-f'.*|const options = ['-f', '43', '-o', path];|g" $import_script if [ ! -f $import_script ]; then dialog --title $"Import videos from legacy sites" \ --msgbox $"import-videos script was not found" 6 75 return fi clear $nodecmd $import_script -u "$peertubedomain" -U "$peertubeuser" --password "$peertubepassword" -t "$video_url" dialog --title $"Import videos from legacy sites" \ --msgbox $"Video/s imported from $video_url" 6 75 } function configure_interactive_peertube { W=(1 $"Set administrator email address" 2 $"Disable or enable signups" 3 $"Import video from file") while true do # shellcheck disable=SC2068 selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"PeerTube" --menu $"Choose an operation, or ESC to exit:" 12 60 4 "${W[@]}" 3>&2 2>&1 1>&3) if [ ! "$selection" ]; then break fi case $selection in 1) peertube_set_admin_email;; 2) peertube_disable_signups;; 3) peertube_import_from_file;; esac done } function change_password_peertube { peertube_user="$1" new_peertube_password="$2" if [ ${#new_peertube_password} -lt 8 ]; then echo $'Peertube password is too short' return fi cd $PEERTUBE_DIR/peertube-latest || exit 53 echo -n "$new_peertube_password" | sudo -H -u peertube NODE_CONFIG_DIR=$PEERTUBE_DIR/config NODE_ENV=production npm run reset-password -- -u "$peertube_user" "${PROJECT_NAME}-pass" -u "$peertube_user" -a peertube -p "$new_peertube_password" # also change the root password if this is the admin user read_config_param MY_USERNAME if [[ "$peertube_user" == "$MY_USERNAME" ]]; then peertube_user=root echo -n "$new_peertube_password" | sudo -H -u peertube NODE_CONFIG_DIR=$PEERTUBE_DIR/config NODE_ENV=production npm run reset-password -- -u "$peertube_user" "${PROJECT_NAME}-pass" -u "$peertube_user" -a peertube -p "$new_peertube_password" fi } function reconfigure_peertube { echo -n '' } function peertube_database_extensions { cd /etc/postgresql || exit 34 sudo -u postgres psql peertube -c 'CREATE EXTENSION IF NOT EXISTS unaccent;' sudo -u postgres psql peertube -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;' } function upgrade_peertube { peertube_upgrading=1 peertube_import_from_syncthing if [ ! -d "$PEERTUBE_DIR/peertube-latest" ]; then peertube_upgrading= return fi CURR_PEERTUBE_VERSION=$(get_completion_param "peertube version") if [[ "$CURR_PEERTUBE_VERSION" == "$PEERTUBE_VERSION" ]]; then peertube_upgrading= return fi read_config_param PEERTUBE_DOMAIN_NAME systemctl stop peertube install_peertube_base chown -R peertube:peertube $PEERTUBE_DIR if [ -d $PEERTUBE_DIR/.cache ]; then chmod -R 700 $PEERTUBE_DIR/.cache fi peertube_database_extensions if ! grep -q 'tmp: ' "${PEERTUBE_CONFIG_FILE}"; then sed -i "/storage:/a tmp: '$PEERTUBE_DIR/storage/tmp/'" "${PEERTUBE_CONFIG_FILE}" sed -i 's|tmp:| tmp:|g' "${PEERTUBE_CONFIG_FILE}" fi if ! grep -q 'redundancy: ' "${PEERTUBE_CONFIG_FILE}"; then sed -i "/storage:/a redundancy: '$PEERTUBE_DIR/storage/videos/'" "${PEERTUBE_CONFIG_FILE}" sed -i 's|redundancy:| redundancy:|g' "${PEERTUBE_CONFIG_FILE}" fi if ! grep -q 'csp-logger:' "${PEERTUBE_CONFIG_FILE}"; then sed -i "/services:/a csp-logger:" "${PEERTUBE_CONFIG_FILE}" sed -i 's|csp-logger:| csp-logger:|g' "${PEERTUBE_CONFIG_FILE}" fi if ! grep -q 'allow_additional_extensions:' "${PEERTUBE_CONFIG_FILE}"; then sed -i "/transcoding:/a allow_additional_extensions:" "${PEERTUBE_CONFIG_FILE}" sed -i 's|allow_additional_extensions:| allow_additional_extensions:|g' "${PEERTUBE_CONFIG_FILE}" fi if ! grep -q 'contact_form:' "${PEERTUBE_CONFIG_FILE}"; then sed -i "/email:/a contact_form:" "${PEERTUBE_CONFIG_FILE}" sed -i "/contact_form:/a enabled: true 82284" "${PEERTUBE_CONFIG_FILE}" sed -i 's|enabled: true 82284| enabled: true|g' "${PEERTUBE_CONFIG_FILE}" fi systemctl start peertube set_completion_param "peertube version" "$PEERTUBE_VERSION" peertube_upgrading= } function backup_local_peertube { PEERTUBE_DOMAIN_NAME='peertube.local' if grep -q "peertube domain" "$COMPLETION_FILE"; then PEERTUBE_DOMAIN_NAME=$(get_completion_param "peertube domain") fi systemctl stop peertube USE_POSTGRESQL=1 function_check backup_database_to_usb backup_database_to_usb peertube systemctl start peertube peertube_path=$PEERTUBE_DIR/storage/videos if [ -d $peertube_path ]; then suspend_site "${PEERTUBE_DOMAIN_NAME}" systemctl stop peertube backup_directory_to_usb $peertube_path peertubevideos systemctl start peertube restart_site fi } function restore_local_peertube { PEERTUBE_DOMAIN_NAME='peertube.local' if grep -q "peertube domain" "$COMPLETION_FILE"; then PEERTUBE_DOMAIN_NAME=$(get_completion_param "peertube domain") fi if [ "$PEERTUBE_DOMAIN_NAME" ]; then suspend_site "${PEERTUBE_DOMAIN_NAME}" systemctl stop peertube USE_POSTGRESQL=1 restore_database peertube temp_restore_dir=/root/temppeertubevideos function_check restore_directory_from_usb restore_directory_from_usb $temp_restore_dir peertubevideos if [ -d $temp_restore_dir ]; then if [ -d $temp_restore_dir$PEERTUBE_DIR/storage/videos ]; then cp -r $temp_restore_dir$PEERTUBE_DIR/storage/videos/* $PEERTUBE_DIR/storage/videos/ else cp -r $temp_restore_dir/* $PEERTUBE_DIR/storage/videos/ fi chown -R peertube:peertube $PEERTUBE_DIR rm -rf $temp_restore_dir fi systemctl start peertube restart_site fi } function backup_remote_peertube { echo -n '' } function restore_remote_peertube { echo -n '' } function remove_peertube { if [ ${#PEERTUBE_DOMAIN_NAME} -eq 0 ]; then return fi systemctl stop peertube systemctl disable peertube rm /etc/systemd/system/peertube.service systemctl daemon-reload function_check remove_nodejs remove_nodejs peertube rm /etc/sysctl.d/30-peertube-tcp.conf sysctl -p -q read_config_param "PEERTUBE_DOMAIN_NAME" nginx_dissite "$PEERTUBE_DOMAIN_NAME" remove_certs "${PEERTUBE_DOMAIN_NAME}" if [ -f "/etc/nginx/sites-available/$PEERTUBE_DOMAIN_NAME" ]; then rm -f "/etc/nginx/sites-available/$PEERTUBE_DOMAIN_NAME" fi if [ -d "/var/www/$PEERTUBE_DOMAIN_NAME" ]; then rm -rf "/var/www/$PEERTUBE_DOMAIN_NAME" fi remove_config_param PEERTUBE_DOMAIN_NAME remove_config_param PEERTUBE_CODE function_check remove_onion_service remove_onion_service peertube ${PEERTUBE_ONION_PORT} remove_completion_param "install_peertube" sed -i '/peertube/d' "$COMPLETION_FILE" sed -i '/peertubesync/d' /etc/crontab if [ -f /usr/bin/peertubesync ]; then rm /usr/bin/peertubesync fi if [ -f /root/peertube_uploaded ]; then rm /root/peertube_uploaded fi function_check drop_database_postgresql drop_database_postgresql peertube peertube groupdel -f peertube userdel -r peertube if [ -d $PEERTUBE_DIR ]; then rm -rf $PEERTUBE_DIR fi function_check remove_ddns_domain remove_ddns_domain "$PEERTUBE_DOMAIN_NAME" } function peertube_setup_web { peertube_nginx_file=/etc/nginx/sites-available/$PEERTUBE_DOMAIN_NAME if [[ $ONION_ONLY == "no" ]]; then { echo 'server {'; echo ' listen 80;'; echo ' listen [::]:80;'; echo " server_name ${PEERTUBE_DOMAIN_NAME};"; echo ''; echo " access_log /dev/null;"; echo " error_log /dev/null;"; echo ''; echo " location / { return 301 https://\$host\$request_uri; }"; echo '}'; echo ''; echo 'server {'; echo ' listen 443 ssl http2;'; echo ' listen [::]:443 ssl http2;'; echo " server_name ${PEERTUBE_DOMAIN_NAME};"; echo ''; } > "$peertube_nginx_file" function_check nginx_ssl nginx_ssl "$PEERTUBE_DOMAIN_NAME" mobile function_check nginx_security_options nginx_security_options "$PEERTUBE_DOMAIN_NAME" nginx_robots "$PEERTUBE_DOMAIN_NAME" { echo ' ssl_ecdh_curve secp384r1;'; echo ' ssl_session_cache shared:SSL:10m;'; echo ' ssl_session_tickets off;'; echo ''; echo ' # Enable compression for JS/CSS/HTML bundle, for improved client load times.'; echo ' # It might be nice to compress JSON, but leaving that out to protect against potential'; echo ' # compression+encryption information leak attacks like BREACH.'; echo ' gzip on;'; echo ' gzip_types text/css application/javascript;'; echo ' gzip_vary on;'; echo ''; echo ' # Enable HSTS' echo ' # Tells browsers to stick with HTTPS and never visit the insecure HTTP'; echo ' # version. Once a browser sees this header, it will only visit the site over'; echo ' # HTTPS for the next 2 years: (read more on hstspreload.org)'; echo ' add_header Strict-Transport-Security "max-age=63072000;";'; echo ''; echo ' access_log /dev/null;'; echo ' error_log /dev/null;'; echo ''; echo ' location / {'; echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo " proxy_set_header X-Real-IP \$remote_addr;"; echo " proxy_set_header Host \$host;"; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo ''; echo ' # Hard limit, PeerTube does not support videos > 8GB'; echo ' client_max_body_size 8G;'; echo ' proxy_connect_timeout 600;'; echo ' proxy_send_timeout 600;'; echo ' proxy_read_timeout 600;'; echo ' send_timeout 600;'; echo ' }'; echo ''; echo ' # Bypass PeerTube for performance reasons. Could be removed'; echo ' location ~ ^/static/(webseed|redundancy)/ {'; echo ' # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client'; echo ' limit_rate 800k;'; echo ''; echo " if (\$request_method = 'OPTIONS') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; echo " add_header 'Access-Control-Max-Age' 1728000;"; echo " add_header 'Content-Type' 'text/plain charset=UTF-8';"; echo " add_header 'Content-Length' 0;"; echo ' return 204;'; echo ' }'; echo ''; echo " if (\$request_method = 'GET') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; echo ''; echo ' # Dont spam access log file with byte range requests'; echo ' access_log off;'; echo ' }'; echo ''; echo " alias $PEERTUBE_DIR/storage/videos;"; echo ' }'; echo ''; echo ' # Websocket tracker'; echo ' location /tracker/socket {'; echo ' # Peers send a message to the tracker every 15 minutes'; echo ' # Dont close the websocket before this time'; echo ' proxy_read_timeout 1200s;'; echo " proxy_set_header Upgrade \$http_upgrade;"; echo " proxy_set_header Connection \"upgrade\";"; echo ' proxy_http_version 1.1;'; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo " proxy_set_header Host \$host;"; echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo ' }'; echo '}'; echo ''; } >> "$peertube_nginx_file" else echo -n '' > "$peertube_nginx_file" fi { echo 'server {'; echo " listen 127.0.0.1:$PEERTUBE_ONION_PORT default_server;"; echo ' port_in_redirect off;'; echo " server_name $PEERTUBE_ONION_HOSTNAME;"; echo ''; echo ' # Enable compression for JS/CSS/HTML bundle, for improved client load times.'; echo ' # It might be nice to compress JSON, but leaving that out to protect against potential'; echo ' # compression+encryption information leak attacks like BREACH.'; echo ' gzip on;'; echo ' gzip_types text/css application/javascript;'; echo ' gzip_vary on;'; echo ''; echo ' access_log /dev/null;'; echo ' error_log /dev/null;'; echo ''; echo ' location / {'; echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo " proxy_set_header X-Real-IP \$remote_addr;"; echo " proxy_set_header Host \$host;"; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo ''; echo ' # Hard limit, PeerTube does not support videos > 8GB'; echo ' client_max_body_size 8G;'; echo ' proxy_connect_timeout 600;'; echo ' proxy_send_timeout 600;'; echo ' proxy_read_timeout 600;'; echo ' send_timeout 600;'; echo ' }'; echo ''; echo ' # Bypass PeerTube for performance reasons. Could be removed'; echo ' location ~ ^/static/(webseed|redundancy)/ {'; echo ' # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client'; echo ' limit_rate 800k;'; echo ''; echo " if (\$request_method = 'OPTIONS') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; echo " add_header 'Access-Control-Max-Age' 1728000;"; echo " add_header 'Content-Type' 'text/plain charset=UTF-8';"; echo " add_header 'Content-Length' 0;"; echo ' return 204;'; echo ' }'; echo ''; echo " if (\$request_method = 'GET') {"; echo " add_header 'Access-Control-Allow-Origin' '*';"; echo " add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';"; echo " add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';"; echo ''; echo ' # Dont spam access log file with byte range requests'; echo ' access_log off;'; echo ' }'; echo ''; echo " alias $PEERTUBE_DIR/storage/videos;"; echo ' }'; echo ''; echo ' # Websocket tracker'; echo ' location /tracker/socket {'; echo ' # Peers send a message to the tracker every 15 minutes'; echo ' # Dont close the websocket before this time'; echo ' proxy_read_timeout 1200s;'; echo " proxy_set_header Upgrade \$http_upgrade;"; echo " proxy_set_header Connection \"upgrade\";"; echo ' proxy_http_version 1.1;'; echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;"; echo " proxy_set_header Host \$host;"; echo " proxy_pass http://localhost:$PEERTUBE_PORT;"; echo ' }'; echo '}'; } >> "$peertube_nginx_file" # CSP currently causes an error sed -i '/Content-Security-Policy/d' "$peertube_nginx_file" function_check create_site_certificate create_site_certificate "$PEERTUBE_DOMAIN_NAME" 'yes' function_check nginx_ensite nginx_ensite "$PEERTUBE_DOMAIN_NAME" } function mesh_peertube_setup_web { # TODO echo -n '' } function peertube_create_config { peertube_prefix= new_peertube_config_file=$peertube_prefix${PEERTUBE_CONFIG_FILE} { echo 'listen:'; echo " hostname: 'localhost'"; echo " port: $PEERTUBE_PORT"; echo ''; echo '# Correspond to your reverse proxy "listen" configuration'; echo 'webserver:'; } > "$new_peertube_config_file" if [ ! "$peertube_prefix" ]; then if [[ "$ONION_ONLY" == 'no' ]]; then { echo ' https: true'; echo " hostname: '$PEERTUBE_DOMAIN_NAME'"; echo ' port: 443'; } >> "$new_peertube_config_file" else { echo ' https: false'; echo " hostname: '$PEERTUBE_ONION_HOSTNAME'"; echo ' port: 80'; } >> "$new_peertube_config_file" fi else { echo ' https: false'; echo " hostname: ''"; echo " port: $MESH_PEERTUBE_PORT"; } >> "$new_peertube_config_file" fi { echo '# Proxies to trust to get real client IP'; echo "# If you run PeerTube just behind a local proxy (nginx), keep 'loopback'"; echo '# If you run PeerTube behind a remote proxy, add the proxy IP address (or subnet)'; echo 'trust_proxy:'; echo " - 'loopback'"; echo ''; echo '# Your database name will be "peertube"+database.suffix'; echo 'database:'; echo " hostname: 'localhost'"; echo ' port: 5432'; echo " suffix: ''"; echo " username: 'peertube'"; } >> "$new_peertube_config_file" if [ ! "$peertube_prefix" ]; then echo " password: '$PEERTUBE_ADMIN_PASSWORD'" >> "$new_peertube_config_file" else echo " password: ''" >> "$new_peertube_config_file" fi { echo ' pool:'; echo ' max: 5'; echo ''; echo '# Redis server for short time storage'; echo "# You can also specify a 'socket' path to a unix socket but first need to"; echo '# comment out hostname and port'; echo 'redis:'; echo " hostname: 'localhost'"; echo ' port: 6379'; echo ' auth: null'; echo ' db: 0'; echo ''; echo '# SMTP server to send emails'; echo 'smtp:'; echo ' hostname: localhost'; echo ' port: 25'; echo ' username: null'; echo ' password: null'; echo ' tls: false'; echo ' disable_starttls: true'; echo ' ca_file: null'; echo " from_address: '$MY_EMAIL_ADDRESS'"; echo ''; echo 'signup:'; echo ' enabled: false'; echo ' limit: 10 # When the limit is reached, registrations are disabled. -1 == unlimited'; echo ' requires_email_verification: false'; echo ' filters:'; echo ' cidr: # You can specify CIDR ranges to whitelist (empty = no filtering) or blacklist'; echo ' whitelist: []'; echo ' blacklist: []'; echo ''; echo 'storage:'; echo " tmp: '$PEERTUBE_DIR/storage/tmp/'"; echo " avatars: '$PEERTUBE_DIR/storage/avatars/'"; echo " videos: '$PEERTUBE_DIR/storage/videos/'"; echo " redundancy: '$PEERTUBE_DIR/storage/videos/'"; echo " logs: '$PEERTUBE_DIR/storage/logs/'"; echo " previews: '$PEERTUBE_DIR/storage/previews/'"; echo " thumbnails: '$PEERTUBE_DIR/storage/thumbnails/'"; echo " torrents: '$PEERTUBE_DIR/storage/torrents/'"; echo " captions: '$PEERTUBE_DIR/storage/captions/'"; echo " cache: '$PEERTUBE_DIR/storage/cache/'"; echo ''; echo 'cache:'; echo ' previews:'; echo ' size: 10 # Max number of previews you want to cache'; echo ' captions:'; echo ' size: 500 # Max number of video captions/subtitles you want to cache'; echo ''; echo 'admin:'; # This is deliberately a dummy email address echo " email: 'testuser@testdomain.net'"; echo ''; echo 'contact_form:'; echo ' enabled: true'; echo ''; echo ''; echo 'user:'; echo ' # Default value of maximum video BYTES the user can upload (does not take into account transcoded files).'; echo ' # -1 == unlimited'; echo ' video_quota: -1'; echo ' video_quota_daily: -1'; echo ''; echo '# If enabled, the video will be transcoded to mp4 (x264) with "faststart" flag'; echo '# Uses a lot of CPU!'; echo 'transcoding:'; echo ' enabled: false'; echo ' # Allow your users to upload .mkv, .mov, .avi, .flv videos'; echo ' allow_additional_extensions: true'; echo ' threads: 2'; echo ' resolutions: # Only created if the original video has a higher resolution'; echo ' 240p: true'; echo ' 360p: false'; echo ' 480p: false'; echo ' 720p: false'; echo ' 1080p: false'; echo ''; echo 'import:'; echo '# Add ability for your users to import remote videos (from YouTube, torrent...)'; echo ' videos:'; echo ' http: # Classic HTTP or all sites supported by youtube-dl https://rg3.github.io/youtube-dl/supportedsites.html'; echo ' enabled: false'; echo ' torrent: # Magnet URI or torrent file (use classic TCP/UDP/WebSeed to download the file)'; echo ' enabled: false'; echo 'instance:'; echo " name: 'PeerTube'"; echo " short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.'"; echo " description: '' # Support markdown"; echo " terms: '' # Support markdown"; echo " default_client_route: '/videos/trending'"; echo ' # By default, "do_not_list" or "blur" or "display" NSFW videos'; echo ' # Could be overridden per user with a setting'; echo " default_nsfw_policy: 'do_not_list'"; echo ' customizations:'; echo " javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime"; echo " css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime"; echo " # Robot.txt rules. To disallow robots to crawl your instance and disallow indexation of your site, add '/' to 'Disallow:'"; echo ' robots: |'; echo ' User-agent: *'; echo ' Disallow:'; echo ' # Security.txt rules. To discourage researchers from testing your instance and disable security.txt integration, set this to an empty string.'; echo ' securitytxt:'; echo " \"# If you would like to report a security issue then go right ahead\""; echo ''; echo 'log:'; echo " level: 'error' # debug/info/warning/error"; echo ''; echo 'search:'; echo ' remote_uri: # Add ability to search remote videos/actors by URI, that may not be federated with your instance'; echo ' users: true'; echo ' anonymous: false'; echo ''; echo 'trending:'; echo ' videos:'; echo ' interval_days: 7 # Compute trending videos for the last x days'; echo ''; echo '# Cache remote videos on your server, to help other instances to broadcast the video'; echo '# You can define multiple caches using different sizes/strategies'; echo '# Once you have defined your strategies, choose which instances you want to cache in admin -> manage follows -> following'; echo 'redundancy:'; echo ' videos:'; echo " check_interval: '1 hour' # How often you want to check new videos to cache"; echo ' strategies:'; echo ' # -'; echo " # size: '1GB'"; echo ' # # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)'; echo " # min_lifetime: '48 hours'"; echo " # strategy: 'most-views' # Cache videos that have the most views"; echo ' # -'; echo " # size: '1GB'"; echo ' # # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)'; echo " # min_lifetime: '48 hours'"; echo " # strategy: 'trending' # Cache trending videos"; echo ' # -'; echo " # size: '1GB'"; echo ' # # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)'; echo " # min_lifetime: '48 hours'"; echo " # strategy: 'recently-added' # Cache recently added videos"; echo ' # min_views: 10 # Having at least x views'; echo ''; echo 'services:'; echo ' # You can provide a reporting endpoint for Content Security Policy violations'; echo ' csp-logger:'; echo ' # Cards configuration to format video in Twitter'; echo ' twitter:'; echo " username: '' # Indicates the Twitter account for the website or platform on which the content was published"; echo ' # If true, a video player will be embedded in the Twitter feed on PeerTube video share'; echo ' # If false, we use an image link card that will redirect on your PeerTube instance'; echo ' # Test on https://cards-dev.twitter.com/validator to see if you are whitelisted'; echo ' whitelisted: false'; } >> "$new_peertube_config_file" } function mesh_install_peertube { # shellcheck disable=SC2153 if [[ "$VARIANT" != "meshclient" && "$VARIANT" != "meshusb" ]]; then return fi if [[ "$ARCHITECTURE" != 'x86_64' && "$ARCHITECTURE" != 'amd64' && "$ARCHITECTURE" != 'i386' ]]; then return fi # TODO mesh_peertube_setup_web } function install_peertube { if [[ $VARIANT == "mesh"* ]]; then mesh_install_peertube return fi if [ ! "$PEERTUBE_DOMAIN_NAME" ]; then echo $'The peertube domain name was not specified' exit 78 fi peertube_upgrading= increment_app_install_progress $INSTALL_PACKAGES ffmpeg redis-tools redis-server xz-utils increment_app_install_progress function_check install_postgresql install_postgresql increment_app_install_progress if [ ! -d "/var/www/$PEERTUBE_DOMAIN_NAME/htdocs" ]; then mkdir -p "/var/www/$PEERTUBE_DOMAIN_NAME/htdocs" fi if [ -d $PEERTUBE_DIR ]; then userdel -r peertube groupdel -f peertube rm -rf $PEERTUBE_DIR fi increment_app_install_progress groupadd peertube useradd -c "PeerTube system account" -d $PEERTUBE_DIR -m -r -g peertube -s /bin/bash peertube peertube_create_database increment_app_install_progress function_check install_nodejs install_nodejs peertube increment_app_install_progress install_peertube_base increment_app_install_progress PEERTUBE_ONION_HOSTNAME=$(add_onion_service peertube 80 ${PEERTUBE_ONION_PORT}) cp "$PEERTUBE_DIR/peertube-latest/support/systemd/peertube.service" /etc/systemd/system/peertube.service sed -i "s|/var/www/peertube|$PEERTUBE_DIR|g" /etc/systemd/system/peertube.service sed -i "s|ExecStart=.*|ExecStart=$PEERTUBE_DIR/peertube-latest/node_modules/.bin/npm start|g" /etc/systemd/system/peertube.service peertube_create_config increment_app_install_progress chown -R peertube:peertube $PEERTUBE_DIR peertube_setup_web increment_app_install_progress "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a peertube -p "$PEERTUBE_ADMIN_PASSWORD" function_check add_ddns_domain add_ddns_domain "$PEERTUBE_DOMAIN_NAME" increment_app_install_progress systemctl enable peertube systemctl daemon-reload systemctl start peertube increment_app_install_progress systemctl restart nginx increment_app_install_progress # wait for the database to get generated after initial peertube daemon start sleep 10 increment_app_install_progress # update the admin email address after creation of the database sed -i "s|email: .*|email: '$MY_EMAIL_ADDRESS'|g" ${PEERTUBE_CONFIG_FILE} peertube_import_from_syncthing increment_app_install_progress cd $PEERTUBE_DIR/peertube-latest || exit 23 echo -n "$PEERTUBE_ADMIN_PASSWORD" | sudo -H -u peertube NODE_CONFIG_DIR=$PEERTUBE_DIR/config NODE_ENV=production npm run reset-password -- -u root increment_app_install_progress set_completion_param "peertube version" "$PEERTUBE_VERSION" set_completion_param "peertube domain" "$PEERTUBE_DOMAIN_NAME" if [ -d $PEERTUBE_DIR/.cache ]; then chmod -R 700 $PEERTUBE_DIR/.cache fi APP_INSTALLED=1 } # NOTE: deliberately no exit 0