diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | check_process | 8 | ||||
| -rw-r--r-- | conf/app-mastodon.src | 6 | ||||
| -rw-r--r-- | conf/app-rbenv.src | 6 | ||||
| -rw-r--r-- | conf/app-ruby-build.src | 6 | ||||
| -rw-r--r-- | conf/backports.list | 1 | ||||
| -rw-r--r-- | conf/crontab_mastodon | 7 | ||||
| -rw-r--r-- | conf/mastodon-sidekiq.service | 10 | ||||
| -rw-r--r-- | conf/mastodon-streaming.service | 8 | ||||
| -rw-r--r-- | conf/mastodon-web.service | 10 | ||||
| -rw-r--r-- | conf/yarn.list | 1 | ||||
| -rw-r--r-- | manifest.json | 6 | ||||
| -rw-r--r-- | scripts/.fonctions | 263 | ||||
| -rw-r--r-- | scripts/_common.sh | 175 | ||||
| -rw-r--r-- | scripts/_future.sh | 127 | ||||
| -rw-r--r-- | scripts/backup | 91 | ||||
| -rw-r--r-- | scripts/install | 372 | ||||
| -rw-r--r-- | scripts/remove | 149 | ||||
| -rw-r--r-- | scripts/restore | 297 | ||||
| -rw-r--r-- | scripts/upgrade | 184 |
20 files changed, 950 insertions, 779 deletions
@@ -1,6 +1,6 @@ # Mastodon for YunoHost -[](https://github.com/YunoHost-Apps/mastodon_ynh/releases) +[](https://github.com/YunoHost-Apps/mastodon_ynh/releases) [](https://github.com/YunoHost-Apps/mastodon_ynh/milestones) [](https://github.com/YunoHost-Apps/mastodon_ynh#dependencies) [](https://raw.githubusercontent.com/YunoHost-Apps/mastodon_ynh/master/LICENSE) diff --git a/check_process b/check_process index 6952a12..5045355 100644 --- a/check_process +++ b/check_process @@ -4,7 +4,7 @@ domain="domain.tld" (DOMAIN) admin="john" (USER) path="/path" (PATH) - passwd="adminpassword" + passwd="12345678" ; Checks pkg_linter=1 setup_sub_dir=0 @@ -26,9 +26,9 @@ Level 1=auto Level 2=auto Level 3=auto - Level 4=na - Level 5=1 -# level 5: le test ne semble pas tout à fait savoir ce qu'est vraiment un "exit". +# Level 4: TODO: https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Enabling-LDAP-login.md + Level 4=0 + Level 5=auto Level 6=auto Level 7=auto Level 8=0 diff --git a/conf/app-mastodon.src b/conf/app-mastodon.src new file mode 100644 index 0000000..61c7260 --- /dev/null +++ b/conf/app-mastodon.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/tootsuite/mastodon/archive/v2.4.1.tar.gz +SOURCE_SUM=d90b573e16359f63f7b2834f1078ecfdd7d78cd5a26acd8293a314dd2b6ff1ec +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= diff --git a/conf/app-rbenv.src b/conf/app-rbenv.src new file mode 100644 index 0000000..d60155b --- /dev/null +++ b/conf/app-rbenv.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/rbenv/rbenv/archive/v1.1.1.tar.gz +SOURCE_SUM=41f1a60714c55eceb21d692a469aee1ec4f46bba351d0dfcb0c660ff9cf1a1c9 +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= diff --git a/conf/app-ruby-build.src b/conf/app-ruby-build.src new file mode 100644 index 0000000..3041556 --- /dev/null +++ b/conf/app-ruby-build.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/rbenv/ruby-build/archive/v20180424.tar.gz +SOURCE_SUM=71dbaf87081369c1f5d27b6a94a927c1eeeb1f36bdffe7851f0a9c1ec87b9373 +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= diff --git a/conf/backports.list b/conf/backports.list deleted file mode 100644 index b8c3f51..0000000 --- a/conf/backports.list +++ /dev/null @@ -1 +0,0 @@ -deb http://httpredir.debian.org/debian jessie-backports main
\ No newline at end of file diff --git a/conf/crontab_mastodon b/conf/crontab_mastodon deleted file mode 100644 index 62caff0..0000000 --- a/conf/crontab_mastodon +++ /dev/null @@ -1,7 +0,0 @@ -@daily __APP__ cd /opt/__APP__/live && RAILS_ENV=production /opt/__APP__/.rbenv/shims/bundle exec rake mastodon:media:clear - -@daily __APP__ cd /opt/__APP__/live && RAILS_ENV=production /opt/__APP__/.rbenv/shims/bundle exec rake mastodon:push:refresh - -@daily __APP__ cd /opt/__APP__/live && RAILS_ENV=production /opt/__APP__/.rbenv/shims/bundle exec rake mastodon:feeds:clear - -@daily __APP__ cd /opt/__APP__/live && RAILS_ENV=production /opt/__APP__/.rbenv/shims/bundle exec rake mastodon:users:clear diff --git a/conf/mastodon-sidekiq.service b/conf/mastodon-sidekiq.service index 34074ed..f788332 100644 --- a/conf/mastodon-sidekiq.service +++ b/conf/mastodon-sidekiq.service @@ -1,17 +1,17 @@ [Unit] - Description=mastodon-sidekiq + Description=__APP__-sidekiq After=network.target [Service] Type=simple - User=mastodon - WorkingDirectory=/opt/mastodon/live + User=__APP__ + WorkingDirectory=__FINALPATH__/live Environment="RAILS_ENV=production" Environment="DB_POOL=20" - ExecStart=/opt/mastodon/.rbenv/shims/bundle exec sidekiq -c 20 -q default -q mailers -q pull -q push + ExecStart=__FINALPATH__/live/bin/bundle exec sidekiq -c 20 -q default -q mailers -q pull -q push TimeoutSec=15 Restart=always StandardError=syslog [Install] - WantedBy=multi-user.target
\ No newline at end of file + WantedBy=multi-user.target diff --git a/conf/mastodon-streaming.service b/conf/mastodon-streaming.service index 1716b00..443cac0 100644 --- a/conf/mastodon-streaming.service +++ b/conf/mastodon-streaming.service @@ -1,11 +1,11 @@ [Unit] - Description=mastodon-streaming + Description=__APP__-streaming After=network.target [Service] Type=simple - User=mastodon - WorkingDirectory=/opt/mastodon/live + User=__APP__ + WorkingDirectory=__FINALPATH__/live Environment="NODE_ENV=production" Environment="PORT=4000" ExecStart=/usr/bin/npm run start @@ -14,4 +14,4 @@ StandardError=syslog [Install] - WantedBy=multi-user.target
\ No newline at end of file + WantedBy=multi-user.target diff --git a/conf/mastodon-web.service b/conf/mastodon-web.service index 4632031..06069f1 100644 --- a/conf/mastodon-web.service +++ b/conf/mastodon-web.service @@ -1,17 +1,17 @@ [Unit] - Description=mastodon-web + Description=__APP__-web After=network.target [Service] Type=simple - User=mastodon - WorkingDirectory=/opt/mastodon/live + User=__APP__ + WorkingDirectory=__FINALPATH__/live Environment="RAILS_ENV=production" Environment="PORT=3000" - ExecStart=/opt/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb + ExecStart=__FINALPATH__/live/bin/bundle exec puma -C config/puma.rb TimeoutSec=15 Restart=always StandardError=syslog [Install] - WantedBy=multi-user.target
\ No newline at end of file + WantedBy=multi-user.target diff --git a/conf/yarn.list b/conf/yarn.list deleted file mode 100644 index 842ebb9..0000000 --- a/conf/yarn.list +++ /dev/null @@ -1 +0,0 @@ -deb https://dl.yarnpkg.com/debian/ stable main
\ No newline at end of file diff --git a/manifest.json b/manifest.json index 6bb4a68..11c277b 100644 --- a/manifest.json +++ b/manifest.json @@ -3,15 +3,15 @@ "id": "mastodon", "packaging_format": 1, "requirements": { - "yunohost": ">= 2.4" + "yunohost": ">= 2.7.9" }, "description": { "en": "Mastodon is a free, open-source social network.", "fr": "Mastodon est un réseau social gratuit et open source." }, - "version": "2.4.2", + "version": "2.4.1", "url": "https://github.com/tootsuite/mastodon", - "license": "AGPL v3.0", + "license": "AGPL-3.0-or-later", "maintainer": { "name": "cyp, nemsia", "email": "cyp@rouquin.me, nemsia@nemsia.org" diff --git a/scripts/.fonctions b/scripts/.fonctions deleted file mode 100644 index 20f9ea0..0000000 --- a/scripts/.fonctions +++ /dev/null @@ -1,263 +0,0 @@ -#!/bin/bash - -ynh_version="2.4" - -YNH_VERSION () { # Returns the version number of the Yunohost moulinette - ynh_version=$(sudo yunohost -v | grep "moulinette:" | cut -d' ' -f2 | cut -d'.' -f1,2) -} - -CHECK_VAR () { # Verifies that the variable is not empty. - # $1 = Variable to be checked - # $2 = Display text on error - test -n "$1" || (echo "$2" >&2 && false) -} - -EXIT_PROPERLY () { # Causes the script to stop in the event of an error. And clean the residue. - trap '' ERR - echo -e "\e[91m \e[1m" # Shell in light red bold - echo -e "!!\n $app install's script has encountered an error. Installation was cancelled.\n!!" >&2 - - if type -t CLEAN_SETUP > /dev/null; then # Checks the existence of the function before executing it. - CLEAN_SETUP # Call the specific cleanup function of the install script. - fi - - # Compensates the ssowat bug that does not remove the app's input in case of installation error. - sudo sed -i "\@\"$domain/\":@d" /etc/ssowat/conf.json - - if [ "$ynh_version" = "2.2" ]; then - /bin/bash $script_dir/remove - fi - - ynh_die -} - -TRAP_ON () { # Activate signal capture - trap EXIT_PROPERLY ERR # Capturing exit signals on error -} - -TRAP_OFF () { # Ignoring signal capture until TRAP_ON - trap '' ERR # Ignoring exit signals -} - -CHECK_USER () { # Check the validity of the user admin - # $1 = User admin variable - ynh_user_exists "$1" || (echo "Wrong admin" >&2 && false) -} - -CHECK_PATH () { # Checks / at the beginning of the path. And his absence at the end. - if [ "${path:0:1}" != "/" ]; then # If the first character is not / - path="/$path" # Add / at the beginning of path - fi - if [ "${path:${#path}-1}" == "/" ] && [ ${#path} -gt 1 ]; then # If the last character is a / and it is not the only character. - path="${path:0:${#path}-1}" # Delete last character - fi -} - -CHECK_DOMAINPATH () { # Checks the availability of the path and domain. - sudo yunohost app checkurl $domain -a $app -} - -CHECK_FINALPATH () { # Checks that the destination folder is not already in use. - final_path=/opt/$app - if [ -e "$final_path" ] - then - echo "This path already contains a folder" >&2 - false - fi -} - -STORE_MD5_CONFIG () { # Saves the checksum of the config file - # $1 = Name of the conf file for storage in settings.yml - # $2 = Full name and path of the conf file. - ynh_app_setting_set $app $1_file_md5 $(sudo md5sum "$2" | cut -d' ' -f1) -} - -CHECK_MD5_CONFIG () { # Created a backup of the config file if it was changed. - # $1 = Name of the conf file for storage in settings.yml - # $2 = Full name and path of the conf file.onf. - if [ "$(ynh_app_setting_get $app $1_file_md5)" != $(sudo md5sum "$2" | cut -d' ' -f1) ]; then - sudo cp -a "$2" "$2.backup.$(date '+%d.%m.%y_%Hh%M,%Ss')" # Si le fichier de config a été modifié, créer un backup. - fi -} - -FIND_PORT () { # Search free port - # $1 = Port number to start the search. - port=$1 - while ! sudo yunohost app checkport $port ; do - port=$((port+1)) - done - CHECK_VAR "$port" "port empty" -} - -SETUP_SOURCE () { # Download source, decompress and copu into $final_path - src=$(cat ../sources/source_md5 | awk -F' ' {'print $2'}) - sudo wget -nv -i ../sources/source_url -O $src - # Checks the checksum of the downloaded source. - # md5sum -c ../sources/source_md5 --status || ynh_die "Corrupt source" - # Decompress source - if [ "$(echo ${src##*.})" == "tgz" ]; then - tar -x -f $src - elif [ "$(echo ${src##*.})" == "zip" ]; then - unzip -q $src - else - false # Unsupported archive format. - fi - # Copy file source - sudo cp -a $(cat ../sources/source_dir)/. "$final_path/live" - # Copy additional file and modified - if test -e "../sources/ajouts"; then - sudo cp -a ../sources/ajouts/. "$final_path" - fi -} - -# Create user with special hack -CREATE_USER () { - sudo curl -kSs https://${domain}/auth/sign_up --cookie-jar cookie | grep csrf > token || true - token=$(sudo cat token | sed -n '/csrf-token/s/.*name="csrf-token"\s\+content="\([^"]\+\).*/\1/p') - sudo curl -kSs https://${domain}/auth --data "&user[account_attributes][username]=${admin_mastodon}&user[email]=${admin_mastodon}@${domain}&user[password]=${admin_pass}&user[password_confirmation]=${admin_pass}&authenticity_token=${token}" --cookie cookie -} - -### REMOVE SCRIPT - -REMOVE_NGINX_CONF () { # Delete nginx configuration - if [ -e "/etc/nginx/conf.d/$domain.d/$app.conf" ]; then # Delete nginx config - echo "Delete nginx config" - sudo rm "/etc/nginx/conf.d/$domain.d/$app.conf" - sudo systemctl reload nginx - fi -} - -REMOVE_LOGROTATE_CONF () { # Delete logrotate configuration - if [ -e "/etc/logrotate.d/$app" ]; then - echo "Delete logrotate config" - sudo rm "/etc/logrotate.d/$app" - fi -} - -SECURE_REMOVE () { # Deleting a folder with variable verification - chaine="$1" # The argument must be given between simple quotes '', to avoid interpreting the variables. - no_var=0 - while (echo "$chaine" | grep -q '\$') # Loop as long as there are $ in the string - do - no_var=1 - global_var=$(echo "$chaine" | cut -d '$' -f 2) # Isole the first variable found. - only_var=\$$(expr "$global_var" : '\([A-Za-z0-9_]*\)') # Isole completely the variable by adding the $ at the beginning and keeping only the name of the variable. Mostly gets rid of / and a possible path behind. - real_var=$(eval "echo ${only_var}") # `eval "echo ${var}` Allows to interpret a variable contained in a variable. - if test -z "$real_var" || [ "$real_var" = "/" ]; then - echo "Variable $only_var is empty, suppression of $chaine cancelled." >&2 - return 1 - fi - chaine=$(echo "$chaine" | sed "s@$only_var@$real_var@") # Replaces variable with its value in the string. - done - if [ "$no_var" -eq 1 ] - then - if [ -e "$chaine" ]; then - echo "Delete directory $chaine" - sudo rm -r "$chaine" - fi - return 0 - else - echo "No detected variable." >&2 - return 1 - fi -} - -# Create a db without password -# -# usage: ynh_mysql_create_user user -# | arg: user - the user name to create -ynh_psql_create_db_without_password() { - db=$1 - sudo su -c "psql" postgres <<< \ - "CREATE USER $db CREATEDB;" -} - -# Create a user -# -# usage: ynh_mysql_create_user user pwd [host] -# | arg: user - the user name to create -# | arg: pwd - the password to identify user by -ynh_psql_create_user() { - sudo su -c "psql" postgres <<< \ - "CREATE USER ${1} WITH PASSWORD '${2}';" -} - -# Create a user without password -# -# usage: ynh_mysql_create_user user pwd [host] -# | arg: user - the user name to create -ynh_psql_create_user_without_password() { - sudo su -c "psql" postgres <<< \ - "CREATE USER ${1};" -} - -# Create a database and grant optionnaly privilegies to a user -# -# usage: ynh_mysql_create_db db [user [pwd]] -# | arg: db - the database name to create -# | arg: user - the user to grant privilegies -# | arg: pwd - the password to identify user by -ynh_psql_create_db() { - db=$1 - # grant all privilegies to user - if [[ $# -gt 1 ]]; then - ynh_psql_create_user ${2} "${3}" - sudo su -c "createdb -O ${2} $db" postgres - else - sudo su -c "createdb $db" postgres - fi - -} - -# Drop a role -# -# usage: ynh_mysql_drop_role db -# | arg: db - the database name to drop -ynh_psql_drop_role() { - sudo su -c "psql" postgres <<< \ - "DROP ROLE ${1};" -} - -# Drop a database -# -# usage: ynh_mysql_drop_db db -# | arg: db - the database name to drop -ynh_psql_drop_db() { - sudo su -c "dropdb ${1}" postgres -} - -# Drop a user -# -# usage: ynh_mysql_drop_user user -# | arg: user - the user name to drop -ynh_psql_drop_user() { - sudo su -c "dropuser ${1}" postgres -} - -# Remove a file or a directory securely -# -# usage: ynh_secure_remove path_to_remove -# | arg: path_to_remove - File or directory to remove -ynh_secure_remove () { - path_to_remove=$1 - forbidden_path=" \ - /var/www \ - /home/yunohost.app" - - if [[ "$forbidden_path" =~ "$path_to_remove" \ - # Match all path or subpath in $forbidden_path - || "$path_to_remove" =~ ^/[[:alnum:]]+$ \ - # Match all first level path from / (Like /var, /root, etc...) - || "${path_to_remove:${#path_to_remove}-1}" = "/" ]] - # Match if the path finish by /. Because it's seems there is an empty variable - then - echo "Avoid deleting of $path_to_remove." >&2 - else - if [ -e "$path_to_remove" ] - then - sudo rm -R "$path_to_remove" - else - echo "$path_to_remove doesn't deleted because it's not exist." >&2 - fi - fi -}
\ No newline at end of file diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..df631ad --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,175 @@ +#!/bin/bash + + +# Execute a command as another user +# usage: exec_as USER COMMAND [ARG ...] +exec_as() { + local user=$1 + shift 1 + + if [[ $user = $(whoami) ]]; then + eval "$@" + else + sudo --login --user="$user" "$@" + fi +} + +#================================================= +# +# POSTGRES HELPERS +# +# Point of contact : Jean-Baptiste Holcroft <jean-baptiste@holcroft.fr> +#================================================= + +# 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" + app="$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' CREATEDB;" 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" +} diff --git a/scripts/_future.sh b/scripts/_future.sh new file mode 100644 index 0000000..82f255c --- /dev/null +++ b/scripts/_future.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +# needed to have "service_name" as an option +# https://github.com/YunoHost/yunohost/commit/9c4ddcca39d9d6d92bd5f9a23978337e48d0a4e1 +ynh_add_systemd_config () { + local service_name="${1:-$app}" + + finalsystemdconf="/etc/systemd/system/$service_name.service" + ynh_backup_if_checksum_is_different "$finalsystemdconf" + sudo cp ../conf/${2:-systemd.service} "$finalsystemdconf" + + # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable. + # Substitute in a nginx config file only if the variable is not empty + if test -n "${final_path:-}"; then + ynh_replace_string "__FINALPATH__" "$final_path" "$finalsystemdconf" + fi + if test -n "${app:-}"; then + ynh_replace_string "__APP__" "$app" "$finalsystemdconf" + fi + ynh_store_file_checksum "$finalsystemdconf" + + sudo chown root: "$finalsystemdconf" + sudo systemctl enable $service_name + sudo systemctl daemon-reload +} + +# needed to have "service_name" as an option +# https://github.com/YunoHost/yunohost/commit/9c4ddcca39d9d6d92bd5f9a23978337e48d0a4e1 +ynh_remove_systemd_config () { + local service_name="${1:-$app}" + + local finalsystemdconf="/etc/systemd/system/$service_name.service" + if [ -e "$finalsystemdconf" ]; then + sudo systemctl stop $service_name + sudo systemctl disable $service_name + ynh_secure_remove "$finalsystemdconf" + sudo systemctl daemon-reload + fi +} + + +# LOCAL ADDITION: +# save file locally if not in the cache +# +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source () { + local dest_dir=$1 + local src_id=${2:-app} # If the argument is not given, source_id equals "app" + + # Load value from configuration file (see above for a small doc about this file + # format) + local src_url=$(grep 'SOURCE_URL=' "$YNH_CWD/../conf/${src_id}.src" | cut -d= -f2-) + local src_sum=$(grep 'SOURCE_SUM=' "$YNH_CWD/../conf/${src_id}.src" | cut -d= -f2-) + local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$YNH_CWD/../conf/${src_id}.src" | cut -d= -f2-) + local src_format=$(grep 'SOURCE_FORMAT=' "$YNH_CWD/../conf/${src_id}.src" | cut -d= -f2-) + local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$YNH_CWD/../conf/${src_id}.src" | cut -d= -f2-) + local src_filename=$(grep 'SOURCE_FILENAME=' "$YNH_CWD/../conf/${src_id}.src" | cut -d= -f2-) + + # Default value + src_sumprg=${src_sumprg:-sha256sum} + src_in_subdir=${src_in_subdir:-true} + src_format=${src_format:-tar.gz} + src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]') + if [ "$src_filename" = "" ] ; then + src_filename="${src_id}.${src_format}" + fi + local local_src="/var/cache/yunohost/ynh_setup_source/${YNH_APP_ID}/${src_filename}" + + # if cache file exists and the checksum isn't good, download it again + # if not, just download the file + + if test -e "$local_src" + then + echo "${src_sum} ${local_src}" | ${src_sumprg} -c --status \ + || wget -nv -O $local_src $src_url + else + mkdir -p "/var/cache/yunohost/ynh_setup_source/${YNH_APP_ID}" + wget -nv -O $local_src $src_url + fi + cp $local_src $src_filename + + # Check the control sum + echo "${src_sum} ${src_filename}" | ${src_sumprg} -c --status \ + || ynh_die "Corrupt source" + + # Extract source into the app dir + mkdir -p "$dest_dir" + if [ "$src_format" = "zip" ] + then + # Zip format + # Using of a temp directory, because unzip doesn't manage --strip-components + if $src_in_subdir ; then + local tmp_dir=$(mktemp -d) + unzip -quo $src_filename -d "$tmp_dir" + cp -a $tmp_dir/*/. "$dest_dir" + ynh_secure_remove "$tmp_dir" + else + unzip -quo $src_filename -d "$dest_dir" + fi + else + local strip="" + if $src_in_subdir ; then + strip="--strip-components 1" + fi + if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]] ; then + tar -xf $src_filename -C "$dest_dir" $strip + else + ynh_die "Archive format unrecognized." + fi + fi + + # Apply patches + if (( $(find $YNH_CWD/../sources/patches/ -type f -name "${src_id}-*.patch" 2> /dev/null | wc -l) > "0" )); then + local old_dir=$(pwd) + (cd "$dest_dir" \ + && for p in $YNH_CWD/../sources/patches/${src_id}-*.patch; do \ + patch -p1 < $p; done) \ + || ynh_die "Unable to apply patches" + cd $old_dir + fi + + # Add supplementary files + if test -e "$YNH_CWD/../sources/extra_files/${src_id}"; then + cp -a $YNH_CWD/../sources/extra_files/$src_id/. "$dest_dir" + fi +} + diff --git a/scripts/backup b/scripts/backup index 8040747..be3b0a4 100644 --- a/scripts/backup +++ b/scripts/backup @@ -1,47 +1,76 @@ #!/bin/bash -# Exit on command errors and treat unset variables as an error -set -eu +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -if [ ! -e .fonctions ]; then - # Get file fonction if not been to the current directory - sudo cp ../settings/scripts/.fonctions ./.fonctions - sudo chmod a+rx .fonctions +if [ ! -e _common.sh ]; then + # Get the _common.sh file if it's not in the current directory + cp ../settings/scripts/_common.sh ./_common.sh + cp ../settings/scripts/_future.sh ./_future.sh + chmod a+rx _common.sh _future.sh fi -# Loads the generic functions usually used in the script -source .fonctions -# Source app helpers +source _common.sh source /usr/share/yunohost/helpers +source _future.sh + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= # Get multi-instances specific variables app=$YNH_APP_INSTANCE_NAME # Retrieve app settings domain=$(ynh_app_setting_get "$app" domain) +final_path=$(ynh_app_setting_get "$app" final_path) +db_name=$(ynh_app_setting_get "$app" db_name) +if [ -z "$db_name" ]; then + db_name="${app}_production" + ynh_app_setting_set "$app" db_name "$db_name" +fi -# Copy the app files -final_path="/opt/${app}" -ynh_backup "$final_path" "sources" 1 +#================================================= +# STANDARD BACKUP STEPS +#================================================= +# BACKUP THE APP MAIN DIR +#================================================= -# final_path on nginx -sudo sed -i "s@$final_path@__FINALPATH__@g" /etc/nginx/conf.d/${domain}.d/${app}.conf +ynh_backup "$final_path" -# Copy the nginx conf files -ynh_backup "/etc/nginx/conf.d/${domain}.d/${app}.conf" "nginx.conf" -ynh_backup "/etc/cron.d/${app}" "cron.conf" -ynh_backup "/etc/systemd/system/mastodon-web.service" "systemd_web.service" -ynh_backup "/etc/systemd/system/mastodon-sidekiq.service" "systemd_sidekiq.service" -ynh_backup "/etc/systemd/system/mastodon-streaming.service" "systemd_streaming.service" -if [ "$(lsb_release --codename --short)" == "jessie" ]; then - ynh_backup "/etc/apt/sources.list.d/backports.list" "apt_backports.list" -fi -ynh_backup "/etc/apt/sources.list.d/yarn.list" "apt_yarn.list" +#================================================= +# BACKUP THE NGINX CONFIGURATION +#================================================= -# final_path on nginx -sudo sed -i "s@__FINALPATH__@$final_path@g" /etc/nginx/conf.d/${domain}.d/${app}.conf +ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" -# Backup db -sudo su - postgres <<COMMANDS -pg_dump --role=mastodon -U postgres --no-password mastodon_production > mastodon_db.sql -COMMANDS -ynh_backup "/var/lib/postgresql/${app}_db.sql" "${app}_db.sql" +#================================================= +# BACKUP THE MYSQL DATABASE +#================================================= + +ynh_psql_dump_db "$db_name" > db.sql + +#================================================= +# SPECIFIC BACKUP +#================================================= +# BACKUP SYSTEMD +#================================================= + +ynh_backup "/etc/systemd/system/$app-web.service" +ynh_backup "/etc/systemd/system/$app-sidekiq.service" +ynh_backup "/etc/systemd/system/$app-streaming.service" + +#================================================= +# BACKUP THE sources.list FILES +#================================================= + +ynh_backup "/etc/apt/sources.list.d/yarn.list" "apt_yarn.list" diff --git a/scripts/install b/scripts/install index 03f91bd..5d5bf1e 100644 --- a/scripts/install +++ b/scripts/install @@ -1,17 +1,26 @@ #!/bin/bash -# Exit on command errors and treat unset variables as an error -set -eu +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -source .fonctions # Loads the generic functions usually used in the script -source /usr/share/yunohost/helpers # Source app helpers +source _common.sh +source /usr/share/yunohost/helpers +source _future.sh -CLEAN_SETUP () { - # Clean installation residues that are not supported by the remove script. - # Clean hosts - echo "" -} -TRAP_ON # Active trap to stop the script if an error is detected. +#================================================= +# 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 admin_mastodon=$YNH_APP_ARG_ADMIN @@ -19,128 +28,160 @@ admin_mastodon_mail=$(ynh_user_get_info $admin_mastodon 'mail') admin_pass=$YNH_APP_ARG_PASSWD language=$YNH_APP_ARG_LANGUAGE +path_url="/" + app=$YNH_APP_INSTANCE_NAME -CHECK_VAR "$app" "app name not set" +#================================================= +# 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" + +# TODO: remove this test, don't as password anymore, generate it and send it by email to admin with: https://github.com/YunoHost-Apps/Experimental_helpers/tree/master/send_readme_to_admin +[[ ${#admin_pass} -gt 7 ]] || ynh_die "Password is too weak, must be longer than 7 characters" -CHECK_USER "$admin_mastodon" +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path $path_url) -CHECK_DOMAINPATH +# Check web path availability +ynh_webpath_available $domain $path_url +# Register (book) web path +ynh_webpath_register $app $domain $path_url -CHECK_FINALPATH +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= ynh_app_setting_set $app domain $domain ynh_app_setting_set $app admin $admin_mastodon ynh_app_setting_set $app pass $admin_pass ynh_app_setting_set $app language $language +ynh_app_setting_set $app path $path_url -[[ ${#admin_pass} -gt 7 ]] || ynh_die \ -"The password is too weak, it must be longer than 7 characters" -# Create user unix -sudo adduser $app --home /opt/$app --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password --disabled-login - -# Install debian package -ynh_package_install imagemagick libpq-dev libxml2-dev libxslt1-dev file curl apt-transport-https pkg-config libprotobuf-dev protobuf-compiler libicu-dev libidn11-dev +#================================================= +# STANDARD MODIFICATIONS +#================================================= -# Install redis package -ynh_package_install redis-server redis-tools -# Install postgresql -ynh_package_install postgresql postgresql-contrib postgresql-server-dev-all +#================================================= +# INSTALL DEPENDENCIES +#================================================= -# Install Ruby -ynh_package_install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev +# TODO: add in a clean way backports and yarn # Import debian archive pubkey, need on ARM arch arch=$(uname -m) -if [[ $arch = arm* ]]; then - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553 - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010 +if [[ "$arch" = arm* ]]; then + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553 + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010 fi -# Install source.list debian yarn package -sudo curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - -sudo cp ../conf/yarn.list /etc/apt/sources.list.d/ - -# Install source.list debian jessie package backports +# Install source.list debian package backports & yarn if [ "$(lsb_release --codename --short)" == "jessie" ]; then -sudo cp ../conf/backports.list /etc/apt/sources.list.d/ -ynh_package_update -sudo apt-get -t jessie-backports -y install ffmpeg -else -ynh_package_update -ynh_package_install ffmpeg + echo "deb http://httpredir.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list fi - -# Install Yarn -ynh_package_install yarn +curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +ynh_package_update # Creates the destination directory and stores its location. -ynh_app_setting_set $app final_path $final_path +ynh_app_setting_set "$app" final_path "$final_path" # Install de Node.js -pushd /opt -curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - -sudo apt-get -y install nodejs +# TODO: use https://github.com/YunoHost-Apps/Experimental_helpers/blob/master/ynh_install_nodejs/ynh_install_nodejs +( + cd /opt + curl -sL https://deb.nodesource.com/setup_6.x | bash - + apt-get -y install nodejs +) + +# TODO: use the same mecanism with other files +ynh_install_app_dependencies \ + `# debian packages ` \ + imagemagick libpq-dev libxml2-dev libxslt1-dev file curl apt-transport-https pkg-config libprotobuf-dev protobuf-compiler libicu-dev libidn11-dev \ + `# redis ` \ + redis-server redis-tools \ + `# postgresql ` \ + postgresql \ + `# Ruby ` \ + autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev \ + `# ffmpeg from backports ` \ + ffmpeg \ + `# Yarn ` \ + yarn +#================================================= +# CREATE A DATABASE +#================================================= + +# TODO: use non-official https://github.com/YunoHost-Apps/Experimental_helpers/blob/master/postgres/postgres +# TODO: this commands doesn't looks like a requirement, you may fully remove it # Set UTF8 encoding by default -sudo su -c "psql" postgres <<< \ - "update pg_database set datistemplate='false' where datname='template1';" -sudo su -c "psql" postgres <<< \ - "drop database template1;" -sudo su -c "psql" postgres <<< \ - "create database template1 encoding='UTF8' template template0;" -sudo su -c "psql" postgres <<< \ - "update pg_database set datistemplate='true' where datname='template1';" -# Create DB without password -ynh_psql_create_db_without_password "$app" -sudo systemctl restart postgresql +ynh_psql_test_if_first_run + +db_user=$(ynh_sanitize_dbid "$app") +db_name="${app}_production" +db_name=$(ynh_sanitize_dbid "$db_name") +db_pwd=$(ynh_string_random) +ynh_app_setting_set $app db_name $db_name +ynh_app_setting_set $app db_pwd $db_pwd +ynh_psql_setup_db "$db_user" "$db_name" "$db_pwd" + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= # Download all sources rbenv, ruby and mastodon -sudo su - $app <<CLONECOMMANDS -git clone https://github.com/rbenv/rbenv.git $final_path/.rbenv -git clone https://github.com/rbenv/ruby-build.git $final_path/.rbenv/plugins/ruby-build -git clone https://github.com/tootsuite/mastodon.git $final_path/live -CLONECOMMANDS -# Switch branch to tagged release -cd $final_path/live -version=$(curl -s https://api.github.com/repos/tootsuite/mastodon/releases/latest | grep tag_name | cut -d\" -f4) -sudo su - $app <<SWITCHCOMMANDS -pushd ~/live -git checkout $version -SWITCHCOMMANDS +ynh_setup_source "$final_path/.rbenv" "app-rbenv" +ynh_setup_source "$final_path/.rbenv/plugins/ruby-build" "app-ruby-build" +ynh_setup_source "$final_path/live" "app-mastodon" -# Be king rewind (/var/cache/yunohost/from_file/scripts) -popd +#================================================= +# NGINX CONFIGURATION +#================================================= + +# TODO: use official helper ynh_add_nginx_config +# Modify Nginx configuration file and copy it to Nginx conf directory +sed -i "s@__PATH__@$app@g" ../conf/nginx.conf* +sed -i "s@__FINALPATH__@$final_path@g" ../conf/nginx.conf* +cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf + +#================================================= +# CREATE DEDICATED USER +#================================================= +# TODO: use official helper ynh_system_user_create +# Create user unix +adduser $app --home $final_path --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password + +chown -R "$app" "$final_path" + +# TODO: try to use ynh_install_ruby from https://github.com/YunoHost-Apps/Experimental_helpers # Install de rbenv -sudo su - $app <<COMMANDS -pushd ~/.rbenv -src/configure && make -C src -echo 'export PATH="/opt/mastodon/.rbenv/bin:/opt/mastodon/live/bin:$PATH"' >> ~/.profile -echo 'export PATH="/opt/mastodon/.rbenv/bin:/opt/mastodon/live/bin:$PATH"' >> ~/.bashrc -echo 'eval "\$(rbenv init -)"' >> ~/.profile -COMMANDS +( + cd $final_path/.rbenv + src/configure && make -C src + + echo "export PATH=\"$final_path/.rbenv/bin:$final_path/live/bin:\$PATH\" +eval \"\$(rbenv init -)\"" > $final_path/.profile + echo "export PATH=\"$final_path/.rbenv/bin:$final_path/live/bin:\$PATH\"" > $final_path/.bashrc +) # Install ruby-build -sudo su - $app <<RCOMMANDS -/opt/mastodon/.rbenv/bin/rbenv install 2.5.1 -/opt/mastodon/.rbenv/versions/2.5.1/bin/ruby -v -RCOMMANDS +( + exec_as "$app" $final_path/.rbenv/bin/rbenv install 2.5.1 + exec_as "$app" $final_path/.rbenv/bin/rbenv global 2.5.1 + exec_as "$app" $final_path/.rbenv/versions/2.5.1/bin/ruby -v +) # Create symlink for ruby -sudo rm /usr/bin/ruby || true -sudo ln -s /opt/mastodon/.rbenv/versions/2.5.1/bin/ruby /usr/bin/ruby || true - -# Install Mastodon -sudo su - $app <<MCOMMANDS -pushd ~/live -/opt/mastodon/.rbenv/versions/2.5.1/bin/gem install bundler -bin/bundle install --deployment --without development test -MCOMMANDS +rm /usr/bin/ruby || true +ln -s $final_path/.rbenv/versions/2.5.1/bin/ruby /usr/bin/ruby || true # Yarn install on root pushd $final_path/live @@ -148,101 +189,100 @@ yarn install --pure-lockfile popd # Adjust Mastodon config -pushd $final_path/live/ -sudo cp -a .env.production.sample .env.production -sudo sed -i "s@REDIS_HOST=redis@REDIS_HOST=127.0.0.1@g" "${final_path}/live/.env.production" -sudo sed -i "s@DB_HOST=db@DB_HOST=/var/run/postgresql@g" "${final_path}/live/.env.production" -sudo sed -i "s@DB_USER=postgres@DB_USER=${app}@g" "${final_path}/live/.env.production" -sudo sed -i "s@DB_NAME=postgres@DB_NAME=${app}_production@g" "${final_path}/live/.env.production" -sudo sed -i "s@LOCAL_DOMAIN=example.com@LOCAL_DOMAIN=${domain}@g" "${final_path}/live/.env.production" +# TODO: use official helper ynh_replace_string +# TODO: save the config file in conf folder, to make replacement easier to read +# TODO: use ynh_string_random +cp -a $final_path/live/.env.production.sample $final_path/live/.env.production +sed -i "s@REDIS_HOST=redis@REDIS_HOST=127.0.0.1@g" "${final_path}/live/.env.production" +sed -i "s@DB_HOST=db@DB_HOST=/var/run/postgresql@g" "${final_path}/live/.env.production" +sed -i "s@DB_USER=postgres@DB_USER=${db_user}@g" "${final_path}/live/.env.production" +sed -i "s@DB_NAME=postgres@DB_NAME=${db_name}@g" "${final_path}/live/.env.production" +sed -i "s@DB_PASS=@DB_PASS=${db_pwd}@g" "${final_path}/live/.env.production" +sed -i "s@LOCAL_DOMAIN=example.com@LOCAL_DOMAIN=${domain}@g" "${final_path}/live/.env.production" language="$(echo $language | head -c 2)" -sudo sed -i "s@# DEFAULT_LOCALE=de@DEFAULT_LOCALE=${language}@g" "${final_path}/live/.env.production" +sed -i "s@# DEFAULT_LOCALE=de@DEFAULT_LOCALE=${language}@g" "${final_path}/live/.env.production" paperclip_secret=$(head -n128 /dev/urandom | tail -n +1 | tr -dc -d 'a-z0-9' | head -c128) secret_key_base=$(head -n128 /dev/urandom | tail -n +1 | tr -dc -d 'a-z0-9' | head -c128) otp_secret=$(head -n128 /dev/urandom | tail -n +1 | tr -dc -d 'a-z0-9' | head -c128) -sudo sed -i "s@PAPERCLIP_SECRET=@PAPERCLIP_SECRET=${paperclip_secret}@g" "${final_path}/live/.env.production" -sudo sed -i "s@SECRET_KEY_BASE=@SECRET_KEY_BASE=${secret_key_base}@g" "${final_path}/live/.env.production" -sudo sed -i "s@OTP_SECRET=@OTP_SECRET=${otp_secret}@g" "${final_path}/live/.env.production" +sed -i "s@PAPERCLIP_SECRET=@PAPERCLIP_SECRET=${paperclip_secret}@g" "${final_path}/live/.env.production" +sed -i "s@SECRET_KEY_BASE=@SECRET_KEY_BASE=${secret_key_base}@g" "${final_path}/live/.env.production" +sed -i "s@OTP_SECRET=@OTP_SECRET=${otp_secret}@g" "${final_path}/live/.env.production" -sudo sed -i "s@SMTP_LOGIN=@#SMTP_LOGIN=@g" "${final_path}/live/.env.production" -sudo sed -i "s@SMTP_PASSWORD=@#SMTP_PASSWORD=@g" "${final_path}/live/.env.production" -sudo sed -i "s@SMTP_SERVER=smtp.mailgun.org@SMTP_SERVER=localhost@g" "${final_path}/live/.env.production" -sudo sed -i "s@SMTP_PORT=587@SMTP_PORT=25@g" "${final_path}/live/.env.production" -sudo sed -i 's,SMTP_FROM_ADDRESS=notifications@example.com,SMTP_FROM_ADDRESS='${admin_mastodon}'@'${domain}',' "${final_path}/live/.env.production" -sudo sed -i "s@#SMTP_AUTH_METHOD=plain@SMTP_AUTH_METHOD=none@g" "${final_path}/live/.env.production" -sudo sed -i "s@#SMTP_OPENSSL_VERIFY_MODE=peer@SMTP_OPENSSL_VERIFY_MODE=none@g" "${final_path}/live/.env.production" +sed -i "s@SMTP_LOGIN=@#SMTP_LOGIN=@g" "${final_path}/live/.env.production" +sed -i "s@SMTP_PASSWORD=@#SMTP_PASSWORD=@g" "${final_path}/live/.env.production" +sed -i "s@SMTP_SERVER=smtp.mailgun.org@SMTP_SERVER=localhost@g" "${final_path}/live/.env.production" +sed -i "s@SMTP_PORT=587@SMTP_PORT=25@g" "${final_path}/live/.env.production" +sed -i 's,SMTP_FROM_ADDRESS=notifications@example.com,SMTP_FROM_ADDRESS='${admin_mastodon}'@'${domain}',' "${final_path}/live/.env.production" +sed -i "s@#SMTP_AUTH_METHOD=plain@SMTP_AUTH_METHOD=none@g" "${final_path}/live/.env.production" +sed -i "s@#SMTP_OPENSSL_VERIFY_MODE=peer@SMTP_OPENSSL_VERIFY_MODE=none@g" "${final_path}/live/.env.production" -# Create database # Preconfig CSS & JS -sudo su - $app <<CCOMMANDS -pushd ~/live -echo "SAFETY_ASSURED=1">> .env.production -RAILS_ENV=production bin/bundle exec rails db:setup -CCOMMANDS - -# Rails precompile on root -pushd $final_path/live -RAILS_ENV=production bin/bundle exec rails --trace assets:precompile -popd - -# init rbenv & create bundle -sudo su - $app <<BCOMMANDS -. ~/.profile -type rbenv -BCOMMANDS - -# Add Services -popd +# Install Mastodon +( + cd "$final_path/live" + su mastodon <<INSTALL + $final_path/.rbenv/versions/2.5.1/bin/gem install bundler + $final_path/live/bin/bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test --quiet + yarn install --production --no-progress --non-interactive --silent + echo "SAFETY_ASSURED=1">> .env.production + RAILS_ENV=production $final_path/live/bin/bundle exec rails db:migrate --quiet + RAILS_ENV=production $final_path/live/bin/bundle exec rails assets:precompile --quiet +INSTALL +) -sudo cp ../conf/mastodon-web.service /etc/systemd/system/mastodon-web.service -sudo chown root: /etc/systemd/system/mastodon-web.service -sudo cp ../conf/mastodon-sidekiq.service /etc/systemd/system/mastodon-sidekiq.service -sudo chown root: /etc/systemd/system/mastodon-sidekiq.service -sudo cp ../conf/mastodon-streaming.service /etc/systemd/system/mastodon-streaming.service -sudo chown root: /etc/systemd/system/mastodon-streaming.service +# TODO: use ynh_find_port to have generic port selection for RAILS +ynh_add_systemd_config "$app-web" "mastodon-web.service" +# TODO: use ynh_find_port to have generic port selection for NODES +ynh_add_systemd_config "$app-sidekiq" "mastodon-sidekiq.service" +ynh_add_systemd_config "$app-streaming" "mastodon-streaming.service" -sudo systemctl daemon-reload -sudo systemctl enable mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service -sudo systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service -# debug -sudo systemctl status mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service - -# Add service YunoHost -sudo yunohost service add mastodon-web -sudo yunohost service add mastodon-sidekiq -sudo yunohost service add mastodon-streaming +systemctl start "$app-web.service" "$app-sidekiq.service" "$app-streaming.service" # Create user -sudo su - $app <<UCOMMANDS -pushd ~/live -RAILS_ENV=production bundle exec rails c +( + cd "$final_path/live" + su mastodon <<CREATEUSER +RAILS_ENV=production bin/bundle exec rails c account = Account.create!(username: '$admin_mastodon') user = User.create!(email: '$admin_mastodon_mail', password: '$admin_pass', account: account) -UCOMMANDS - -# Create administrator & confirm user -sudo su - $app <<ACOMMANDS -pushd ~/live +CREATEUSER + su mastodon <<SETADMIN RAILS_ENV=production bin/bundle exec rails mastodon:make_admin USERNAME=$admin_mastodon RAILS_ENV=production bin/bundle exec rails mastodon:confirm_email USER_EMAIL=$admin_mastodon_mail -ACOMMANDS +SETADMIN +) -# Modify Nginx configuration file and copy it to Nginx conf directory -sudo sed -i "s@__PATH__@$app@g" ../conf/nginx.conf* -sudo sed -i "s@__FINALPATH__@$final_path@g" ../conf/nginx.conf* -sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +# TODO:Set permissions to app files +chown -R "$app" "$final_path" + +#================================================= +# ADVERTISE SERVICE IN ADMIN PANEL +#================================================= + +# Add service YunoHost +yunohost service add "$app-web" +yunohost service add "$app-sidekiq" +yunohost service add "$app-streaming" -# Install crontab -sudo cp ../conf/crontab_mastodon /etc/cron.d/$app -sudo sed -i "s@__APP__@$app@g" /etc/cron.d/$app +#================================================= +# SETUP SSOWAT +#================================================= +# TODO: all private install # Unprotected url ynh_app_setting_set "$app" unprotected_uris "/" -# Reload SSOwat configuration -sudo yunohost app ssowatconf +#================================================= +# RELOAD NGINX +#================================================= # Reload Nginx -sudo systemctl reload nginx +systemctl reload nginx diff --git a/scripts/remove b/scripts/remove index 19ab132..0ea12df 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,100 +1,119 @@ #!/bin/bash -# Exit on command errors and treat unset variables as an error -set -u +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -if [ ! -e .fonctions ]; then - # Get file fonction if not been to the current directory - sudo cp ../settings/scripts/.fonctions ./.fonctions - sudo chmod a+rx .fonctions -fi - -source .fonctions # Loads the generic functions usually used in the script +source _common.sh # Loads the generic functions usually used in the script # Source app helpers source /usr/share/yunohost/helpers +source _future.sh + + + +#================================================= +# LOAD SETTINGS +#================================================= -# Get multi-instances specific variables app=$YNH_APP_INSTANCE_NAME # Retrieve app settings domain=$(ynh_app_setting_get "$app" domain) - -# Stop mastodon-web -if [ -e "/etc/systemd/system/mastodon-web.service" ]; then - echo "Delete systemd script" - sudo systemctl stop mastodon-web.service - sudo systemctl disable mastodon-web.service - ynh_secure_remove "/etc/systemd/system/mastodon-web.service" +db_name=$(ynh_app_setting_get "$app" db_name) +if [ -z "$db_name" ]; then + db_name="${app}_production" + ynh_app_setting_set "$app" db_name "$db_name" fi +db_user=$(ynh_sanitize_dbid "$app") +final_path=$(ynh_app_setting_get "$app" final_path) -# Stop mastodon-sidekiq -if [ -e "/etc/systemd/system/mastodon-sidekiq.service" ]; then - echo "Delete systemd script" - sudo systemctl stop mastodon-sidekiq.service - sudo systemctl disable mastodon-sidekiq.service - ynh_secure_remove "/etc/systemd/system/mastodon-sidekiq.service" -fi +#================================================= +# STANDARD REMOVE +#================================================= +# STOP AND REMOVE SERVICE +#================================================= -# Stop mastodon-sidekiq -if [ -e "/etc/systemd/system/mastodon-streaming.service" ]; then - echo "Delete systemd script" - sudo systemctl stop mastodon-streaming.service - sudo systemctl disable mastodon-streaming.service - ynh_secure_remove "/etc/systemd/system/mastodon-streaming.service" -fi +ynh_remove_systemd_config "$app-web" +ynh_remove_systemd_config "$app-sidekiq" +ynh_remove_systemd_config "$app-streaming" + +#================================================= +# REMOVE SERVICE FROM ADMIN PANEL +#============================================== -# Delete service on Yunohost monitoring -if sudo yunohost service status | grep -q mastodon-web +if yunohost service status | grep -q "$app-web" then - echo "Remove mastodon-web service" - sudo yunohost service remove mastodon-web + echo "Remove $app-web service" + yunohost service remove "$app-web" fi -# Delete service on Yunohost monitoring -if sudo yunohost service status | grep -q mastodon-sidekiq +if yunohost service status | grep -q "$app-sidekiq" then - echo "Remove mastodon-sidekiq service" - sudo yunohost service remove mastodon-sidekiq + echo "Remove $app-sidekiq service" + yunohost service remove "$app-sidekiq" fi -# Delete service on Yunohost monitoring -if sudo yunohost service status | grep -q mastodon-streaming +if yunohost service status | grep -q "$app-streaming" then - echo "Remove mastodon-streaming service" - sudo yunohost service remove mastodon-streaming + echo "Remove $app-streaming service" + yunohost service remove "$app-streaming" fi +#================================================= +# REMOVE DEPENDENCIES +#================================================= + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# REMOVE THE PostgreSQL DATABASE +#================================================= + # delete postgresql database & user -ynh_psql_drop_db "${app}_production" -ynh_psql_drop_role "${app}" +ynh_psql_remove_db "$db_name" "$db_user" + +#================================================= +# REMOVE APP MAIN DIR +#================================================= -# Remove Debian package -#sudo apt-get remove --purge -y yarn -#sudo apt-get remove --purge -y imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file curl git -#sudo apt-get remove --purge -y redis-server redis-tools -#sudo apt-get remove --purge -y postgresql postgresql-contrib -#sudo apt-get remove --purge -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev +# Remove the app directory securely +ynh_secure_remove "$final_path" -# Delete app directory and configurations -ynh_secure_remove /opt/$app -[[ -n $domain ]] && sudo rm -f "/etc/nginx/conf.d/${domain}.d/${app}.conf" +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= -# Delete nginx configuration -REMOVE_NGINX_CONF +ynh_secure_remove "/etc/nginx/conf.d/${domain}.d/${app}.conf" +systemctl reload nginx + +#================================================= +# SPECIFIC REMOVE +#================================================= +# REMOVE THE CRON FILE +#================================================= # Delete cronlog ynh_secure_remove /etc/cron.d/$app -# Delete source.list -ynh_secure_remove /etc/apt/sources.list.d/backports.list -#ynh_secure_remove /etc/apt/sources.list.d/yarn.list + +#================================================= +# REMOVE source.list +#================================================= +if [ "$(lsb_release --codename --short)" == "jessie" ]; then + ynh_secure_remove /etc/apt/sources.list.d/backports.list + ynh_secure_remove /etc/apt/sources.list.d/jessie-backports.list +fi +ynh_secure_remove /etc/apt/sources.list.d/yarn.list # Delete ruby exec #ynh_secure_remove /usr/bin/ruby -# Remove user -sudo userdel -f $app - -# Reload services -sudo systemctl reload nginx +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= -echo -e "\e[0m" # Restore normal color +userdel -f $app diff --git a/scripts/restore b/scripts/restore index 1eb67e8..a8dc79f 100644 --- a/scripts/restore +++ b/scripts/restore @@ -1,207 +1,162 @@ #!/bin/bash -# This restore script is adapted to Yunohost >=2.4 -# Exit on command errors and treat unset variables as an error -set -eu +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -if [ ! -e .fonctions ]; then - # Get file fonction if not been to the current directory - sudo cp ../settings/scripts/.fonctions ./.fonctions - sudo chmod a+rx .fonctions +if [ ! -e _common.sh ]; then + # Get the _common.sh file if it's not in the current directory + cp ../settings/scripts/_common.sh ./_common.sh + cp ../settings/scripts/_future.sh ./_future.sh + chmod a+rx _common.sh _future.sh fi -# Loads the generic functions usually used in the script -source .fonctions -# Source app helpers +source _common.sh source /usr/share/yunohost/helpers +source _future.sh + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= -# The parameter $app is the id of the app instance ex: ynhexample__2 app=$YNH_APP_INSTANCE_NAME # Get old parameter of the app domain=$(ynh_app_setting_get $app domain) -path=$(ynh_app_setting_get $app path) +path_url=$(ynh_app_setting_get $app path) is_public=$(ynh_app_setting_get $app is_public) +final_path=$(ynh_app_setting_get "$app" final_path) -# Check domain/path availability -sudo yunohost app checkurl "${domain}${path}" -a "$app" \ - || ynh_die "Path not available: ${domain}${path}" - -# Check $final_path -final_path="/opt/${app}" -if [ -d $final_path ]; then - ynh_die "There is already a directory: $final_path" -fi - -# Check configuration files nginx -nginx_conf="/etc/nginx/conf.d/${domain}.d/${app}.conf" -if [ -f $nginx_conf ]; then - ynh_die "The NGINX configuration already exists at '${nginx_conf}'. - You should safely delete it before restoring this app." -fi -# Check configuration files php-fpm -crontab_conf="/etc/cron.d/${app}" -if [ -f $crontab_conf ]; then - ynh_die "The CRONTAB configuration already exists at '${crontab_conf}'. - You should safely delete it before restoring this app." -fi - -# Restore services -web_systemd="/etc/systemd/system/${app}-web.service" -if [ -f "${web_systemd}" ]; then - ynh_die "The MASTODON WEB configuration already exists at '${web_systemd}'. - You should safely delete it before restoring this app." -fi -sidekiq_systemd="/etc/systemd/system/${app}-sidekiq.service" -if [ -f "${sidekiq_systemd}" ]; then - ynh_die "The MASTODON SIDEKIQ configuration already exists at '${sidekiq_systemd}'. - You should safely delete it before restoring this app." -fi -streaming_systemd="/etc/systemd/system/${app}-streaming.service" -if [ -f "${streaming_systemd}" ]; then - ynh_die "The MASTODON STREAMING configuration already exists at '${streaming_systemd}'. - You should safely delete it before restoring this app." -fi - -# Create user unix -sudo adduser $app --home /opt/$app --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password --disabled-login - -# Reinstall dependencies - # Install debian package - ynh_package_install imagemagick libpq-dev libxml2-dev libxslt1-dev file curl apt-transport-https pkg-config libprotobuf-dev protobuf-compiler libicu-dev libidn11-dev - - # Install redis package - ynh_package_install redis-server redis-tools - - # Install postgresql - ynh_package_install postgresql postgresql-contrib postgresql-server-dev-all +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= - # Install Ruby - ynh_package_install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev +ynh_webpath_available $domain $path_url \ + || ynh_die "Path not available: ${domain}${path_url}" +test ! -d $final_path \ +|| ynh_die "There is already a directory: $final_path " - # Import debian archive pubkey, need on ARM arch - arch=$(uname -m) - if [[ $arch = arm* ]]; then - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553 - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010 - fi +#================================================= +# STANDARD RESTORATION STEPS +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= - # Install source.list debian yarn package - sudo curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - - sudo cp ./apt_yarn.list /etc/apt/sources.list.d/yarn.list +ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" - # Install source.list debian jessie package backports - if [ "$(lsb_release --codename --short)" == "jessie" ]; then - sudo cp ./apt_backports.list /etc/apt/sources.list.d/backports.list - ynh_package_update - sudo apt-get -t jessie-backports -y install ffmpeg - else - ynh_package_update - ynh_package_install ffmpeg - fi +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= - # Install Yarn - ynh_package_install yarn +ynh_restore_file "$final_path" - # Install de Node.js - pushd /opt - curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - - sudo apt-get -y install nodejs - popd +#================================================= +# RECREATE THE DEDICATED USER +#================================================= - # Restore sources & data -sudo cp -a ./sources/. "$final_path" - -# Set permissions -sudo chown -R $app: "$final_path" +# Create user unix +adduser $app --home $final_path --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password -# Debug -sudo ls -alh "$final_path" +#================================================= +# RESTORE USER RIGHTS +#================================================= -# Restart postgresql -sudo systemctl restart postgresql +# Restore permissions on app files +chown -R $app: $final_path -# Set UTF8 encoding by default -sudo su -c "psql" postgres <<< \ - "update pg_database set datistemplate='false' where datname='template1';" -sudo su -c "psql" postgres <<< \ - "drop database template1;" -sudo su -c "psql" postgres <<< \ - "create database template1 encoding='UTF8' template template0;" -sudo su -c "psql" postgres <<< \ - "update pg_database set datistemplate='true' where datname='template1';" +#================================================= +# SPECIFIC RESTORATION +#================================================= +# REINSTALL DEPENDENCIES +#================================================= -# Install rbenv -sudo su - $app <<COMMANDS -pushd ~/.rbenv -src/configure && make -C src -echo 'export PATH="/opt/mastodon/.rbenv/bin:/opt/mastodon/live/bin:$PATH"' >> ~/.profile -echo 'export PATH="/opt/mastodon/.rbenv/bin:/opt/mastodon/live/bin:$PATH"' >> ~/.bashrc -echo 'eval "\$(rbenv init -)"' >> ~/.profile -COMMANDS +# TODO: add in a clean way backports and yarn -# Create user for db postgresql -ynh_psql_create_db_without_password "$app" +# Import debian archive pubkey, need on ARM arch +arch=$(uname -m) +if [[ "$arch" = arm* ]]; then + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553 + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010 +fi -# Setup database -#sudo su - $app <<SCOMMANDS -#cd ~/live -#RAILS_ENV=production bin/bundle exec rails db:setup -#SCOMMANDS +# Install source.list debian package backports & yarn +if [ "$(lsb_release --codename --short)" == "jessie" ]; then + echo "deb http://httpredir.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +fi +curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +ynh_package_update -# copy database dump -sudo cp $YNH_APP_BACKUP_DIR/mastodon_db.sql $final_path -sudo chmod a+r $final_path/mastodon_db.sql +# Install de Node.js +# TODO: use https://github.com/YunoHost-Apps/Experimental_helpers/blob/master/ynh_install_nodejs/ynh_install_nodejs +( + cd /opt + curl -sL https://deb.nodesource.com/setup_6.x | bash - + apt-get -y install nodejs +) -# Restore database dump -sudo su - $app <<RECOMMANDS -dropdb mastodon_production -createdb mastodon_production -psql mastodon_production < $final_path/mastodon_db.sql -RECOMMANDS +# TODO: use the same mecanism with other files +ynh_install_app_dependencies \ + `# debian packages ` \ + imagemagick libpq-dev libxml2-dev libxslt1-dev file curl apt-transport-https pkg-config libprotobuf-dev protobuf-compiler libicu-dev libidn11-dev \ + `# redis ` \ + redis-server redis-tools \ + `# postgresql ` \ + postgresql \ + `# Ruby ` \ + autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev \ + `# ffmpeg from backports ` \ + ffmpeg \ + `# Yarn ` \ + yarn -# Remove dump -ynh_secure_remove $final_path/mastodon_db.sql +#================================================= +# RESTORE THE PostgreSQL DATABASE +#================================================= -# Create symlink for ruby 2.5.1 -sudo rm /usr/bin/ruby || true -sudo ln -s /opt/mastodon/.rbenv/versions/2.5.1/bin/ruby /usr/bin/ruby || true +# Restore PostgreSQL database +db_user=$(ynh_sanitize_dbid "$app") +db_name=$(ynh_app_setting_get "$app" db_name) +if [ -z "$db_name" ]; then + db_name="${app}_production" + ynh_app_setting_set "$app" db_name "$db_name" +fi +db_pwd=$(ynh_app_setting_get "$app" db_pwd) -# Install Mastodon -sudo su - $app <<MCOMMANDS -pushd ~/live -$final_path/.rbenv/versions/2.5.1/bin/gem install bundler -$final_path/.rbenv/versions/2.5.1/bin/bundle install --deployment --without development test -MCOMMANDS +ynh_psql_test_if_first_run +ynh_psql_setup_db "$db_user" "$db_name" "$db_pwd" +ynh_psql_execute_file_as_root ./db.sql "$db_name" -pushd $final_path/live -yarn install --pure-lockfile -systemctl restart postgresql -popd +#================================================= +# ADVERTISE SERVICE IN ADMIN PANEL +#================================================= -# Modify Nginx configuration file and copy it to Nginx conf directory -sudo sed -i "s@__PATH__@$app@g" ./nginx.conf -sudo sed -i "s@__FINALPATH__@$final_path@g" ./nginx.conf -sudo cp -a ./nginx.conf "$nginx_conf" -# Restore crontab -sudo cp -a ./cron.conf "$crontab_conf" +yunohost service add $app-web +yunohost service add $app-sidekiq +yunohost service add $app-streaming -sudo cp ./systemd_web.service /etc/systemd/system/mastodon-web.service -sudo chown root: /etc/systemd/system/mastodon-web.service -sudo cp ./systemd_sidekiq.service /etc/systemd/system/mastodon-sidekiq.service -sudo chown root: /etc/systemd/system/mastodon-sidekiq.service -sudo cp ./systemd_streaming.service /etc/systemd/system/mastodon-streaming.service -sudo chown root: /etc/systemd/system/mastodon-streaming.service +#================================================= +# RESTORE SYSTEMD +#================================================= -sudo systemctl daemon-reload -sudo systemctl enable mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service -sudo systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service -# debug -sudo systemctl status mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service +ynh_restore_file "/etc/systemd/system/$app-web.service" +ynh_restore_file "/etc/systemd/system/$app-sidekiq.service" +ynh_restore_file "/etc/systemd/system/$app-streaming.service" +systemctl enable "$app-web" "$app-sidekiq" "$app-streaming" -# Add service YunoHost -sudo yunohost service add mastodon-web -sudo yunohost service add mastodon-sidekiq -sudo yunohost service add mastodon-streaming +#================================================= +# GENERIC FINALIZATION +#================================================= +# RELOAD NGINX AND PHP-FPM +#================================================= -# Reload services -sudo systemctl reload nginx +systemctl restart "$app-web" "$app-sidekiq" "$app-streaming" +systemctl reload nginx diff --git a/scripts/upgrade b/scripts/upgrade index 63c3b75..8551421 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,23 +1,46 @@ #!/bin/bash -# Exit on command errors and treat unset variables as an error -set -eu +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Loads the generic functions usually used in the script -source .fonctions -# Source YunoHost helpers +source _common.sh source /usr/share/yunohost/helpers +#================================================= +# LOAD SETTINGS +#================================================= + # See comments in install script app=$YNH_APP_INSTANCE_NAME +db_name=$(ynh_app_setting_get "$app" db_name) +db_pwd=$(ynh_app_setting_get "$app" db_pwd) # Retrieve app settings domain=$(ynh_app_setting_get "$app" domain) path=$(ynh_app_setting_get "$app" path) admin=$(ynh_app_setting_get "$app" admin) language=$(ynh_app_setting_get "$app" language) +final_path=$(ynh_app_setting_get "$app" final_path) +path_url="/" + +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= + +# If db_name doesn't exist, create it +if [ -z "$db_name" ]; then + db_name="${app}_production" + ynh_app_setting_set "$app" db_name "$db_name" +fi -CHECK_PATH # Checks and corrects the syntax of the path. +# If final_path doesn't exist, create it +if [ -z "$final_path" ]; then + final_path=/var/www/$app + ynh_app_setting_set "$app" final_path "$final_path" +fi # Check if admin is not null if [[ "$admin" = "" || "$language" = "" ]]; then @@ -25,38 +48,47 @@ if [[ "$admin" = "" || "$language" = "" ]]; then ynh_die fi -final_path=/opt/$app +# If db_pwd doesn't exist, create it +if [[ -z "$db_pwd" ]]; then + db_pwd=$(ynh_string_random) + ynh_app_setting_set $app db_pwd $db_pwd + ynh_psql_test_if_first_run + sudo --login --user=postgres psql -c"ALTER user $app WITH PASSWORD '$db_pwd'" postgres + sed -i "s@DB_PASS=@DB_PASS=${db_pwd}@g" "${final_path}/live/.env.production" +fi -db_name=$app +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= -# Modify Nginx configuration file and copy it to Nginx conf directory -sudo sed -i "s@__PATH__@$app@g" ../conf/nginx.conf* -sudo sed -i "s@__FINALPATH__@$final_path@g" ../conf/nginx.conf* -sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + # restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors -# Stop Mastodon Services -sudo systemctl stop mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service +#================================================= +# Remove repo Files +#================================================= -# Change owner of live folder -sudo chown -R $app: $final_path/live +if [ "$(lsb_release --codename --short)" == "jessie" ]; then + echo "deb http://httpredir.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list + ynh_secure_remove /etc/apt/sources.list.d/backports.list +fi -# Download Mastodon -sudo su - $app <<PULLCOMMANDS -pushd ~/live -git fetch -t -git reset --hard origin/master -git pull https://github.com/tootsuite/mastodon.git master -PULLCOMMANDS +# Add yarn repo +echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -# Switch branch to tagged release -cd $final_path/live -version=$(curl -s https://api.github.com/repos/tootsuite/mastodon/releases/latest | grep tag_name | cut -d\" -f4) -sudo su - $app <<SWITCHCOMMANDS -pushd ~/live -git checkout $version -SWITCHCOMMANDS + +#================================================= +# INSTALL DEPENDENCIES +#================================================= # upgrade Node.js v4 to v6 +# TODO: use https://github.com/YunoHost-Apps/Experimental_helpers/blob/master/ynh_install_nodejs/ynh_install_nodejs node_version=$(nodejs --version) if [[ $node_version =~ ^v4.*$ ]]; then pushd /opt @@ -65,30 +97,63 @@ if [[ $node_version =~ ^v4.*$ ]]; then fi # add additional package for upgrade -ynh_package_install yarn pkg-config libprotobuf-dev protobuf-compiler libicu-dev libidn11-dev postgresql-server-dev-all +ynh_package_install pkg-config libprotobuf-dev protobuf-compiler libicu-dev libidn11-dev postgresql-server-dev-all + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= -# Install ruby 2.5.1 for release 2.4.0 -sudo su - $app <<RCOMMANDS -cd $final_path/.rbenv && git pull && cd - -cd $final_path/.rbenv/plugins/ruby-build && git pull && cd - -$final_path/.rbenv/bin/rbenv install 2.5.1 || true -$final_path/.rbenv/versions/2.5.1/bin/ruby -v -RCOMMANDS +# Stop Mastodon Services +# Restart Mastodon +yunohost service stop "$app-web" +yunohost service stop "$app-sidekiq" +yunohost service stop "$app-streaming" + +# Change owner of live folder +chown -R $app: $final_path/live + +# Download Mastodon +ynh_setup_source "$final_path/live" "app-mastodon" + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# TODO: use official helper ynh_add_nginx_config +# Modify Nginx configuration file and copy it to Nginx conf directory +sed -i "s@__PATH__@$app@g" ../conf/nginx.conf* +sed -i "s@__FINALPATH__@$final_path@g" ../conf/nginx.conf* +cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf + +# Upgrade rbenv and ruby plugins +ynh_setup_source "$final_path/.rbenv" "app-rbenv" +ynh_setup_source "$final_path/.rbenv/plugins/ruby-build" "app-ruby-build" -# Create symlink for ruby 2.5.1 -sudo rm /usr/bin/ruby || true -sudo ln -s $final_path/.rbenv/versions/2.5.1/bin/ruby /usr/bin/ruby || true +# Install ruby 2.5.1 +( + exec_as "$app" $final_path/.rbenv/bin/rbenv install -s 2.5.1 || true + exec_as "$app" $final_path/.rbenv/bin/rbenv global 2.5.1 || true + exec_as "$app" $final_path/.rbenv/versions/2.5.1/bin/ruby -v +) +# Create symlink for ruby +rm /usr/bin/ruby || true +ln -s $final_path/.rbenv/versions/2.5.1/bin/ruby /usr/bin/ruby || true + +# Preconfig CSS & JS # Install Mastodon +( sudo su - $app <<MCOMMANDS pushd ~/live $final_path/.rbenv/versions/2.5.1/bin/gem install bundler if [ "$(lsb_release --codename --short)" == "jessie" ]; then - $final_path/.rbenv/versions/2.5.1/bin/bundle install --deployment --without development test + $final_path/.rbenv/versions/2.5.1/bin/bundle install --deployment --without development test else - $final_path/.rbenv/versions/2.5.1/bin/bundle install --deployment --force --without development test + $final_path/.rbenv/versions/2.5.1/bin/bundle install --deployment --force --without development test fi +yarn install --pure-lockfile MCOMMANDS +) # Install package with yarn and restart postgresql pushd $final_path/live @@ -97,29 +162,44 @@ systemctl restart postgresql popd # Apply Mastodon upgrade +( pushd $final_path/live RAILS_ENV=production $final_path/.rbenv/versions/2.5.1/bin/bundle exec rails assets:clean -RAILS_ENV=production $final_path/.rbenv/versions/2.5.1/bin/bundle exec rails assets:precompile --trace +RAILS_ENV=production $final_path/.rbenv/versions/2.5.1/bin/bundle exec rails assets:precompile popd -sudo su - $app <<UCOMMANDS +sudo su - $app <<COMMANDS pushd ~/live RAILS_ENV=production $final_path/.rbenv/versions/2.5.1/bin/bundle exec rails db:migrate # Upgrade to 2.2.0 RAILS_ENV=production $final_path/.rbenv/versions/2.5.1/bin/bundle exec rails mastodon:maintenance:remove_regeneration_markers -UCOMMANDS +COMMANDS +) +#================================================= +# RESTART MASTODON +#================================================= -# Restart Mastodon -sudo systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service +yunohost service start "$app-web" +yunohost service start "$app-sidekiq" +yunohost service start "$app-streaming" # Waiting start all services sleep 30 -# Reload Nginx -sudo systemctl reload nginx +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx + +#================================================= +# SETUP SSOWAT +#================================================= -# Set app public ynh_app_setting_set "$app" unprotected_uris "/" -# Reload SSOwat configuration +#================================================= +# RELOAD ssowatconf +#================================================= + sudo yunohost app ssowatconf |
