From 58610d6757cce5890c00ff1e726248c0b38cf8ba Mon Sep 17 00:00:00 2001 From: anmol Date: Sun, 4 Nov 2018 18:54:39 +0530 Subject: [PATCH] First commit --- check_process | 40 ++++++++++++ conf/app.src | 6 ++ conf/nginx.conf | 39 +++++++++++ manifest.json | 49 ++++++++++++++ scripts/_common.sh | 70 ++++++++++++++++++++ scripts/install | 151 ++++++++++++++++++++++++++++++++++++++++++ scripts/psql.sh | 160 +++++++++++++++++++++++++++++++++++++++++++++ scripts/remove | 72 ++++++++++++++++++++ 8 files changed, 587 insertions(+) create mode 100755 check_process create mode 100755 conf/app.src create mode 100755 conf/nginx.conf create mode 100755 manifest.json create mode 100755 scripts/_common.sh create mode 100755 scripts/install create mode 100755 scripts/psql.sh create mode 100755 scripts/remove diff --git a/check_process b/check_process new file mode 100755 index 0000000..e520a54 --- /dev/null +++ b/check_process @@ -0,0 +1,40 @@ +# See here for more informations +# https://github.com/YunoHost/package_check#syntax-check_process-file + +# Move this file from check_process.default to check_process when you have filled it. + +;; Test complet + ; Manifest + domain="domain.tld" (DOMAIN) + email="admin@example.com" + is_public=1 (PUBLIC|public=1|private=0) + port="4000" (PORT) + ; Checks + pkg_linter=1 + setup_sub_dir=0 + setup_root=1 + setup_nourl=0 + setup_private=1 + setup_public=1 + upgrade=1 + backup_restore=1 + multi_instance=1 + incorrect_path=0 + port_already_use=1 + change_url=0 +;;; Levels + Level 1=auto + Level 2=auto + Level 3=auto +# Level 4: not supported by upstream + Level 4=1 +# Level 5: + Level 5=auto + Level 6=auto + Level 7=auto + Level 8=0 + Level 9=0 + Level 10=0 +;;; Options +Email=anmol@datamol.org +Notification=yes diff --git a/conf/app.src b/conf/app.src new file mode 100755 index 0000000..e8c5f3c --- /dev/null +++ b/conf/app.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://git.pleroma.social/pleroma/pleroma/-/archive/v0.9.0/pleroma-v0.9.0.tar.gz +SOURCE_SUM=068fd77e6c00998e41e7db58ff122dee714da0c0ba0eb5c590b81eb93543a11e +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= diff --git a/conf/nginx.conf b/conf/nginx.conf new file mode 100755 index 0000000..21d0c53 --- /dev/null +++ b/conf/nginx.conf @@ -0,0 +1,39 @@ + location / { + # if you do not want remote frontends to be able to access your Pleroma backend + # server, remove these lines. + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always; + add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always; + if ($request_method = OPTIONS) { + return 204; + } + # stop removing lines here. + + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "same-origin" always; + add_header X-Download-Options "noopen" always; + add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action *; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;" always; + + # Uncomment this only after you get HTTPS working. + # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + + proxy_pass http://localhost:__PORT__; + + client_max_body_size 16m; + } + + location /proxy { + proxy_cache pleroma_media_cache; + proxy_cache_lock on; + proxy_ignore_client_abort on; + proxy_pass http://localhost:__PORT__; + } diff --git a/manifest.json b/manifest.json new file mode 100755 index 0000000..7f80d49 --- /dev/null +++ b/manifest.json @@ -0,0 +1,49 @@ +{ + "name": "pleroma", + "id": "pleroma", + "packaging_format": 1, + "description": { + "en": "Pleroma is an OStatus-compatible social networking server written in Elixir, compatible with GNU Social and Mastodon" + }, + "version": "0.9.0", + "url": "https://git.pleroma.social/pleroma/pleroma", + "license": "AGPL-3.0-only", + "maintainer": { + "name": "Anmol Sharma", + "email": "anmol@datamol.org" + }, + "requirements": { + "yunohost": ">= 2.7.9" + }, + "multi_instance": true, + "services": [ + "nginx" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain name for pleroma" + }, + "example": "example.com" + }, + { + "name": "email", + "ask": { + "en": "Choose an admin email (can be changed after installation)" + }, + "example": "johndoe@example.com" + }, + { + "name": "is_public", + "type": "boolean", + "ask": { + "en": "Is it a public application?" + }, + "default": true + } + ] + } +} diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100755 index 0000000..c726850 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# ============= FUTURE YUNOHOST HELPER ============= +# Delete a file checksum from the app settings +# +# $app should be defined when calling this helper +# +# usage: ynh_remove_file_checksum file +# | arg: file - The file for which the checksum will be deleted +ynh_delete_file_checksum () { + local checksum_setting_name=checksum_${1//[\/ ]/_} # Replace all '/' and ' ' by '_' + ynh_app_setting_delete $app $checksum_setting_name +} + +# Send an email to inform the administrator +# +# usage: ynh_send_readme_to_admin app_message [recipients] +# | arg: app_message - The message to send to the administrator. +# | arg: recipients - The recipients of this email. Use spaces to separate multiples recipients. - default: root +# example: "root admin@domain" +# If you give the name of a YunoHost user, ynh_send_readme_to_admin will find its email adress for you +# example: "root admin@domain user1 user2" +ynh_send_readme_to_admin() { + local app_message="${1:-...No specific information...}" + local recipients="${2:-root}" + + # Retrieve the email of users + find_mails () { + local list_mails="$1" + local mail + local recipients=" " + # Read each mail in argument + for mail in $list_mails + do + # Keep root or a real email address as it is + if [ "$mail" = "root" ] || echo "$mail" | grep --quiet "@" + then + recipients="$recipients $mail" + else + # But replace an user name without a domain after by its email + if mail=$(ynh_user_get_info "$mail" "mail" 2> /dev/null) + then + recipients="$recipients $mail" + fi + fi + done + echo "$recipients" + } + recipients=$(find_mails "$recipients") + + local mail_subject="☁️🆈🅽🅷☁️: \`$app\` has important message for you" + + local mail_message="This is an automated message from your beloved YunoHost server. +Specific information for the application $app. +$app_message +--- +Automatic diagnosis data from YunoHost +$(yunohost tools diagnosis | grep -B 100 "services:" | sed '/services:/d')" + + # Define binary to use for mail command + if [ -e /usr/bin/bsd-mailx ] + then + local mail_bin=/usr/bin/bsd-mailx + else + local mail_bin=/usr/bin/mail.mailutils + fi + + # Send the email to the recipients + echo "$mail_message" | $mail_bin -a "Content-Type: text/plain; charset=UTF-8" -s "$mail_subject" "$recipients" +} diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000..b205378 --- /dev/null +++ b/scripts/install @@ -0,0 +1,151 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers +source psql.sh + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url="/" +admin_email=$YNH_APP_ARG_EMAIL +admin_pass=$(ynh_string_random 24) +is_public=$YNH_APP_ARG_IS_PUBLIC + + +# This is a multi-instance app, meaning it can be installed several times independently +# The id of the app as stated in the manifest is available as $YNH_APP_ID +# The instance number is available as $YNH_APP_INSTANCE_NUMBER (equals "1", "2", ...) +# The app instance name is available as $YNH_APP_INSTANCE_NAME +# - the first time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample +# - the second time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample__2 +# - ynhexample__{N} for the subsequent installations, with N=3,4, ... +# The app instance name is probably what you are interested the most, since this is +# guaranteed to be unique. This is a good unique identifier to define installation path, +# db names, ... +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= + +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die "This path already contains a folder" + +# Check web path availability +ynh_webpath_available "$domain" "$path_url" +# Register (book) web path +ynh_webpath_register "$app" "$domain" "$path_url" + +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= + +ynh_app_setting_set "$app" domain "$domain" +ynh_app_setting_set "$app" admin_email "$admin_email" +ynh_app_setting_set "$app" admin_pass "$admin_pass" +ynh_app_setting_set "$app" is_public "$is_public" + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# FIND AND OPEN A PORT +#================================================= + +# Find a free port +port=$(ynh_find_port 4000) + +# Open this port +yunohost firewall allow Both "$port" 2>&1 +ynh_app_setting_set "$app" port "$port" + +#================================================= +# INSTALL DEPENDENCIES +#================================================= + + +# install dependencies +ynh_install_app_dependencies install git build-essential postgresql postgresql-contrib openssl g++ apt-transport-https +wget -P /tmp/ https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i /tmp/erlang-solutions_1.0_all.deb +apt update && apt install elixir erlang-dev erlang-parsetools erlang-xmerl erlang-tools + +#================================================= +# DATABASE SETUP +#================================================= + +# Create postgresql database +db_name="peertube_${app}" +db_pwd=$(ynh_string_random 30) +ynh_app_setting_set "$app" psql_db "$db_name" +ynh_app_setting_set "$app" psqlpwd "$db_pwd" +ynh_psql_test_if_first_run +ynh_psql_create_user "$app" "$db_pwd" +ynh_psql_execute_as_root \ +"CREATE DATABASE $db_name ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER $app;" +ynh_psql_execute_as_root "\connect $db_name +CREATE EXTENSION IF NOT EXISTS unaccent;CREATE EXTENSION IF NOT EXISTS pg_trgm;" + +#================================================= +# CREATE DEDICATED USER +#================================================= + +# Create a system user +ynh_system_user_create "$app" + +#================================================= +# DOWNLOAD, CHECK AND UNPACK PEERTUBE SOURCE +#================================================= + +ynh_app_setting_set "$app" final_path "$final_path" +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source "$final_path" + + + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# Create a dedicated nginx config +ynh_add_nginx_config + + +#================================================= +# SETUP SSOWAT +#================================================= + +if [ "$is_public" -eq 0 ] +then # Remove the public access + ynh_app_setting_delete "$app" skipped_uris +fi +# Make app public if necessary +if [ "$is_public" -eq 1 ] +then + # unprotected_uris allows SSO credentials to be passed anyway. + ynh_app_setting_set "$app" unprotected_uris "/" +fi + +# Give permisiion to the final_path +chown -R "$app":"$app" "$final_path" + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx + diff --git a/scripts/psql.sh b/scripts/psql.sh new file mode 100755 index 0000000..64fa8d9 --- /dev/null +++ b/scripts/psql.sh @@ -0,0 +1,160 @@ +#!/bin/bash + +#================================================= +# +# POSTGRES HELPERS +# +# Point of contact : Jean-Baptiste Holcroft +#================================================= + +# Create a master password and set up global settings +# Please always call this script in install and restore scripts +# +# usage: ynh_psql_test_if_first_run + +ynh_psql_test_if_first_run() { + if [ -f /etc/yunohost/psql ]; + then + echo "PostgreSQL is already installed, no need to create master password" + else + pgsql=$(ynh_string_random) + pg_hba="" + echo "$pgsql" >> /etc/yunohost/psql + + if [ -e /etc/postgresql/9.4/ ] + then + pg_hba=/etc/postgresql/9.4/main/pg_hba.conf + elif [ -e /etc/postgresql/9.6/ ] + then + pg_hba=/etc/postgresql/9.6/main/pg_hba.conf + else + ynh_die "postgresql shoud be 9.4 or 9.6" + fi + + systemctl start postgresql + sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$pgsql'" postgres + + # force all user to connect to local database using passwords + # https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF + # Note: we can't use peer since YunoHost create users with nologin + # See: https://github.com/YunoHost/yunohost/blob/unstable/data/helpers.d/user + sed -i '/local\s*all\s*all\s*peer/i \ + local all all password' "$pg_hba" + systemctl enable postgresql + systemctl reload postgresql + fi +} + +# Open a connection as a user +# +# example: ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;" +# example: ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql +# +# usage: ynh_psql_connect_as user pwd [db] +# | arg: user - the user name to connect as +# | arg: pwd - the user password +# | arg: db - the database to connect to +ynh_psql_connect_as() { + user="$1" + pwd="$2" + db="$3" + sudo --login --user=postgres PGUSER="$user" PGPASSWORD="$pwd" psql "$db" +} + +# # Execute a command as root user +# +# usage: ynh_psql_execute_as_root sql [db] +# | arg: sql - the SQL command to execute +# | arg: db - the database to connect to +ynh_psql_execute_as_root () { + sql="$1" + sudo --login --user=postgres psql <<< "$sql" +} + +# Execute a command from a file as root user +# +# usage: ynh_psql_execute_file_as_root file [db] +# | arg: file - the file containing SQL commands +# | arg: db - the database to connect to +ynh_psql_execute_file_as_root() { + file="$1" + db="$2" + sudo --login --user=postgres psql "$db" < "$file" +} + +# Create a database, an user and its password. Then store the password in the app's config +# +# After executing this helper, the password of the created database will be available in $db_pwd +# It will also be stored as "psqlpwd" into the app settings. +# +# usage: ynh_psql_setup_db user name [pwd] +# | arg: user - Owner of the database +# | arg: name - Name of the database +# | arg: pwd - Password of the database. If not given, a password will be generated +ynh_psql_setup_db () { + db_user="$1" + db_name="$2" + new_db_pwd=$(ynh_string_random) # Generate a random password + # If $3 is not given, use new_db_pwd instead for db_pwd. + db_pwd="${3:-$new_db_pwd}" + ynh_psql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database + ynh_app_setting_set "$app" psqlpwd "$db_pwd" # Store the password in the app's config +} + +# Create a database and grant privilegies to a user +# +# usage: ynh_psql_create_db db [user [pwd]] +# | arg: db - the database name to create +# | arg: user - the user to grant privilegies +# | arg: pwd - the user password +ynh_psql_create_db() { + db="$1" + user="$2" + pwd="$3" + ynh_psql_create_user "$user" "$pwd" + sudo --login --user=postgres createdb --owner="$user" "$db" +} + +# Drop a database +# +# usage: ynh_psql_drop_db db +# | arg: db - the database name to drop +# | arg: user - the user to drop +ynh_psql_remove_db() { + db="$1" + user="$2" + sudo --login --user=postgres dropdb "$db" + ynh_psql_drop_user "$user" +} + +# Dump a database +# +# example: ynh_psql_dump_db 'roundcube' > ./dump.sql +# +# usage: ynh_psql_dump_db db +# | arg: db - the database name to dump +# | ret: the psqldump output +ynh_psql_dump_db() { + db="$1" + sudo --login --user=postgres pg_dump "$db" +} + + +# Create a user +# +# usage: ynh_psql_create_user user pwd [host] +# | arg: user - the user name to create +ynh_psql_create_user() { + user="$1" + pwd="$2" + sudo --login --user=postgres psql -c"CREATE USER $user WITH PASSWORD '$pwd'" postgres +} + +# Drop a user +# +# usage: ynh_psql_drop_user user +# | arg: user - the user name to drop +ynh_psql_drop_user() { + user="$1" + sudo --login --user=postgres dropuser "$user" +} \ No newline at end of file diff --git a/scripts/remove b/scripts/remove new file mode 100755 index 0000000..2d718f3 --- /dev/null +++ b/scripts/remove @@ -0,0 +1,72 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers +source psql.sh + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get "$app" domain) +port=$(ynh_app_setting_get "$app" port) +db_name=$(ynh_app_setting_get "$app" psql_db) +final_path=$(ynh_app_setting_get "$app" final_path) + +#================================================= +# REMOVE DEPENDENCIES +#================================================= +# Remove metapackage and its dependencies +ynh_remove_app_dependencies +apt update && apt remove elixir erlang-dev erlang-parsetools erlang-xmerl erlang-tools + +#================================================= +# REMOVE THE MYSQL DATABASE +#================================================= + +# Remove a database if it exists, along with the associated user +ynh_psql_remove_db "$db_name" "$app" +#================================================= +# REMOVE APP MAIN DIR +#================================================= + +# Remove the app directory securely +ynh_secure_remove "$final_path" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= + +# Remove the dedicated nginx config +ynh_remove_nginx_config + +#================================================= +# CLOSE A PORT +#================================================= + +if yunohost firewall list | grep -q "\- $port$" +then + echo "Close port $port" + yunohost firewall disallow Both "$port" 2>&1 +fi + +#================================================= +# SPECIFIC REMOVE +#================================================= + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= + +# Delete a system user +ynh_system_user_delete "$app"