diff --git a/conf/.env b/conf/.env index 8074ce6..b567ad6 100755 --- a/conf/.env +++ b/conf/.env @@ -2,7 +2,7 @@ # (replace USER, PASSWORD, PORT and DATABASE_NAME with your values) # # If you are using SQlite, use the path of the database file (`plume.db` for instance) -DATABASE_URL=postgres://__DB_USER__:__PSQLPWD__@localhost:5432/__DBNAME__ +DATABASE_URL=postgres://__DB_NAME__:__DB_PWD__@localhost:5432/__DB_NAME__ # For PostgreSQL: migrations/postgres # For SQlite: migrations/sqlite @@ -16,4 +16,4 @@ ROCKET_ADDRESS=127.0.0.1 # Secret key used for private cookies and CSRF protection # You can generate one with `openssl rand -base64 32` -ROCKET_SECRET_KEY=__KEY__ +ROCKET_SECRET_KEY=__SECRET_KEY__ diff --git a/conf/app.src b/conf/app.src index 20ec1ea..e4dd89f 100755 --- a/conf/app.src +++ b/conf/app.src @@ -1,5 +1,5 @@ -SOURCE_URL=https://github.com/Plume-org/Plume/archive/0.2.0-alpha-1.tar.gz -SOURCE_SUM=5e825275e00420bb3fb3fbac496b2ffb310d84ffab8c872293e7d73f752917b2 +SOURCE_URL=url of app's source +SOURCE_SUM=sha256 checksum SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=tar.gz SOURCE_IN_SUBDIR=true diff --git a/conf/systemd.service b/conf/systemd.service index e082ffe..e8d2327 100755 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -5,8 +5,9 @@ After=network.target [Service] Type=simple User=__APP__ +Group=__APP__ WorkingDirectory=__FINALPATH__/__APP__ -ExecStart=__FINALPATH__/.cargo/bin/plume +ExecStart=/bin/sh -c '__FINALPATH__/.cargo/bin/plume >> /var/log/__APP__/__APP__.log 2>&1' TimeoutSec=30 Restart=always diff --git a/manifest.json b/manifest.json index 5f0c6c6..c0d3751 100755 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { - "name": "plume", + "name": "Plume", "id": "plume", "packaging_format": 1, "description": { diff --git a/scripts/backup b/scripts/backup index b2063b0..e5be661 100755 --- a/scripts/backup +++ b/scripts/backup @@ -8,6 +8,7 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers +source ../settings/scripts/ynh_systemd_action #================================================= # MANAGE SCRIPT FAILURE @@ -15,7 +16,7 @@ source /usr/share/yunohost/helpers ynh_clean_setup () { ### Remove this function if there's nothing to clean before calling the remove script. - true + ynh_clean_check_starting } # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -28,10 +29,7 @@ app=$YNH_APP_INSTANCE_NAME final_path=$(ynh_app_setting_get $app final_path) domain=$(ynh_app_setting_get $app domain) -db_name=$(ynh_app_setting_get "$app" psql_db) - -# Stop Plume for backup -yunohost service stop "$app" +db_name=$(ynh_app_setting_get "$app" db_name) #================================================= # STANDARD BACKUP STEPS @@ -79,9 +77,3 @@ ynh_backup "/etc/systemd/system/$app.service" #================================================= #ynh_backup "/etc/cron.d/$app" - -#================================================= -# START SERVICE -#================================================= - -yunohost service start $app diff --git a/scripts/change_url b/scripts/change_url index 06933b6..60e555b 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -90,16 +90,26 @@ fi #================================================= # SPECIFIC MODIFICATIONS #================================================= -# ... +# STOP SERVICE #================================================= -# Stop writefreely for modification -yunohost service stop $app +ynh_systemd_action --action=stop --service_name=$app + +#================================================= +# MODIFY A CONFIG FILE +#================================================= ynh_replace_string "$old_domain" "$new_domain" "$final_path/$app/.env" -# Start writefreely after modification -yunohost service start $app +#================================================= +# START SERVICE +#================================================= + +ynh_systemd_action --action=start --service_name=$app + +#================================================= +# STORE THE CONFIG FILE CHECKSUM +#================================================= ### Verify the checksum of a file, stored by `ynh_store_file_checksum` in the install script. ### And create a backup of this file if the checksum is different. So the file will be backed up if the admin had modified it. @@ -114,4 +124,3 @@ ynh_store_file_checksum "$final_path/$app/.env" #================================================= systemctl reload nginx -sleep 30 diff --git a/scripts/install b/scripts/install index 3d969e9..f3a3092 100755 --- a/scripts/install +++ b/scripts/install @@ -7,7 +7,7 @@ #================================================= source _common.sh -source ynh_send_readme_to_admin +source ynh_systemd_action source /usr/share/yunohost/helpers #================================================= @@ -16,7 +16,7 @@ source /usr/share/yunohost/helpers ynh_clean_setup () { ### Remove this function if there's nothing to clean before calling the remove script. - true + ynh_clean_check_starting } # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -33,7 +33,7 @@ password=$YNH_APP_ARG_PASSWORD instance_name=$YNH_APP_ARG_NAME registration=$YNH_APP_ARG_REGISTRATION admin_email=$(ynh_user_get_info $admin 'mail') -random_key=$(openssl rand -base64 32) +secret_key=$(openssl rand -base64 32) ### If it's 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 @@ -75,7 +75,7 @@ ynh_app_setting_set $app is_public $is_public ynh_app_setting_set $app instance $instance_name ynh_app_setting_set $app registration $registration ynh_app_setting_set $app admin_email $admin_email -ynh_app_setting_set $app random_key $random_key +ynh_app_setting_set $app secret_key $secret_key #================================================= # STANDARD MODIFICATIONS @@ -121,11 +121,11 @@ ynh_install_app_dependencies gettext postgresql postgresql-contrib libpq-dev git ynh_psql_test_if_first_run db_name="$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_create_user "$app" "$db_pwd" +ynh_app_setting_set "$app" db_name "$db_name" +ynh_app_setting_set "$app" db_pwd "$db_pwd" +ynh_psql_create_user "$db_name" "$db_pwd" ynh_psql_execute_as_root \ -"CREATE DATABASE $db_name ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER $app;" +"CREATE DATABASE $db_name ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER $db_name;" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -143,7 +143,6 @@ git clone https://github.com/Plume-org/Plume.git "$final_path/$app" # Create the media directory, where uploads will be stored (cd $final_path && mkdir media ) - #================================================= # NGINX CONFIGURATION #================================================= @@ -181,48 +180,57 @@ ynh_system_user_create "$app" "$final_path" #================================================= # SPECIFIC SETUP #================================================= -# ... +# CREATE LOG FOLDER #================================================= -# setup application config -sudo cp ../conf/.env $final_path/$app/.env + +mkdir -p "/var/log/$app" +chown -R "$app":"$app" "/var/log/$app" + #================================================= # MODIFY A CONFIG FILE #================================================= -ynh_replace_string "__DBNAME__" "$db_name" "$final_path/$app/.env" -ynh_replace_string "__PSQLPWD__" "$db_pwd" "$final_path/$app/.env" +# setup application config +sudo cp "../conf/.env" "$final_path/$app/.env" +ynh_replace_string "__DB_NAME__" "$db_name" "$final_path/$app/.env" +ynh_replace_string "__DB_PWD__" "$db_pwd" "$final_path/$app/.env" ynh_replace_string "__DOMAIN__" "$domain" "$final_path/$app/.env" ynh_replace_string "__PORT__" "$port" "$final_path/$app/.env" -ynh_replace_string "__DB_USER__" "$app" "$final_path/$app/.env" -ynh_replace_string "__KEY__" "$random_key" "$final_path/$app/.env" +ynh_replace_string "__SECRET_KEY__" "$secret_key" "$final_path/$app/.env" +#================================================= +# MAKE SETUP +#================================================= # Set right permissions -chown -R $app: $final_path +chown -R "$app":"$app" $final_path +# Install +pushd $final_path + sudo -u "$app" RUSTUP_HOME=$final_path/.rustup CARGO_HOME=$final_path/.cargo bash -c 'curl -sSf -L https://static.rust-lang.org/rustup.sh | sh -s -- -y --default-toolchain=nightly' +popd -# App settings -( cd $final_path && sudo -u "$app" RUSTUP_HOME=$final_path/.rustup CARGO_HOME=$final_path/.cargo bash -c 'curl -sSf -L https://static.rust-lang.org/rustup.sh | sh -s -- -y --default-toolchain=nightly' ) -PATH="$PATH:$final_path/.cargo/bin" - export PATH="$PATH:$final_path/.cargo/bin:/usr/local/sbin" - export FEATURES=postgres -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/cargo install diesel_cli --no-default-features --features postgres --version '=1.3.0' ) -( cd $final_path/$app && diesel migration run ) -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/cargo install --no-default-features --features postgres ) -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/cargo install --no-default-features --features postgres --path plume-cli ) +export PATH="$PATH:$final_path/.cargo/bin:/usr/local/sbin" -# Add new instance -if [ $registration -eq 1 ] -then - ( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/plm instance new --domain "$domain" --name "$instance_name" -l 'CC-BY' ) -else - ( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/plm instance new --private --domain "$domain" --name "$instance_name" -l 'CC-BY' ) -fi +pushd $final_path/$app + sudo -u "$app" env PATH=$PATH cargo install diesel_cli --no-default-features --features postgres --version '=1.3.0' + sudo -u "$app" env PATH=$PATH diesel migration run + sudo -u "$app" env PATH=$PATH cargo install --no-default-features --features postgres + sudo -u "$app" env PATH=$PATH cargo install --no-default-features --features postgres --path plume-cli -# Add admin user -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/plm users new --admin -n "$admin" -N "$admin" --email "$admin_email" --password "$password" ) + # Add new instance + if [ $registration -eq 1 ] + then + sudo -u "$app" env PATH=$PATH plm instance new --domain "$domain" --name "$instance_name" -l 'CC-BY' + else + sudo -u "$app" env PATH=$PATH plm instance new --private --domain "$domain" --name "$instance_name" -l 'CC-BY' + fi -# Initialise search index -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/plm search init -p $final_path/$app ) + # Add admin user + sudo -u "$app" env PATH=$PATH plm users new --admin -n "$admin" -N "$admin" --email "$admin_email" --password "$password" + + # Initialise search index + sudo -u "$app" env PATH=$PATH plm search init -p $final_path/$app +popd #================================================= # SETUP SYSTEMD @@ -302,7 +310,7 @@ ynh_store_file_checksum "$final_path/$app/.env" ### that really need such authorization. # Set permissions to app files -chown -R $app: $final_path +# chown -R $app: $final_path #================================================= # SETUP LOGROTATE @@ -356,5 +364,4 @@ systemctl reload nginx # START SERVICE #================================================= -yunohost service start $app -sleep 30 \ No newline at end of file +ynh_systemd_action --action=start --service_name=$app diff --git a/scripts/remove b/scripts/remove index 4a97478..538f71d 100755 --- a/scripts/remove +++ b/scripts/remove @@ -7,6 +7,7 @@ #================================================= source _common.sh +source ynh_systemd_action source /usr/share/yunohost/helpers #================================================= @@ -17,8 +18,7 @@ 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) -db_user=$db_name +db_name=$(ynh_app_setting_get "$app" db_name) final_path=$(ynh_app_setting_get $app final_path) #================================================= @@ -41,6 +41,13 @@ fi # Remove the dedicated systemd config ynh_remove_systemd_config +#================================================= +# REMOVE THE POSTGRESQL DATABASE +#================================================= + +# Remove a database if it exists, along with the associated user +ynh_psql_remove_db "$db_name" "$app" + #================================================= # REMOVE DEPENDENCIES @@ -48,21 +55,17 @@ ynh_remove_systemd_config # Remove metapackage and its dependencies ynh_remove_app_dependencies -export PATH="$PATH:$final_path/.cargo/bin:/var/$app/.local/bin:/usr/local/sbin" -export FEATURES=postgres -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/cargo uninstall diesel_cli ) + +export PATH="$PATH:$final_path/.cargo/bin:/usr/local/sbin" + +pushd $final_path/$app + sudo -u "$app" env PATH=$PATH cargo uninstall diesel_cli +popd if [ -d "/usr/local/lib/rustlib" ]; then sudo /usr/local/lib/rustlib/uninstall.sh fi -#================================================= -# REMOVE THE POSTGRESQL DATABASE -#================================================= - -# Remove a database if it exists, along with the associated user -ynh_psql_remove_db "$db_name" "$app" - #================================================= # REMOVE APP MAIN DIR #================================================= diff --git a/scripts/restore b/scripts/restore index b334bd7..6e963e0 100755 --- a/scripts/restore +++ b/scripts/restore @@ -7,6 +7,7 @@ #================================================= source ../settings/scripts/_common.sh +source ../settings/scripts/ynh_systemd_action source /usr/share/yunohost/helpers #================================================= @@ -15,7 +16,7 @@ source /usr/share/yunohost/helpers ynh_clean_setup () { #### Remove this function if there's nothing to clean before calling the remove script. - true + ynh_clean_check_starting } # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -30,8 +31,8 @@ domain=$(ynh_app_setting_get $app domain) path_url=$(ynh_app_setting_get $app path) final_path=$(ynh_app_setting_get $app final_path) port=$(ynh_app_setting_get "$app" port) -db_name=$(ynh_app_setting_get "$app" psql_db) -db_pwd=$(ynh_app_setting_get "$app" psqlpwd) +db_name=$(ynh_app_setting_get "$app" db_name) +db_pwd=$(ynh_app_setting_get "$app" db_pwd) #================================================= # CHECK IF THE APP CAN BE RESTORED @@ -62,9 +63,9 @@ ynh_restore_file "$final_path" ynh_install_app_dependencies postgresql postgresql-contrib ynh_psql_test_if_first_run -ynh_psql_create_user "$app" "$db_pwd" +ynh_psql_create_user "$db_name" "$db_pwd" ynh_psql_execute_as_root \ -"CREATE DATABASE $db_name ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER $app;" +"CREATE DATABASE $db_name ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER $db_name;" ynh_psql_execute_file_as_root ./db.sql "$db_name" #================================================= @@ -79,7 +80,7 @@ ynh_system_user_create "$app" "$final_path" #================================================= # Restore permissions on app files -chown -R $app: $final_path +chown -R "$app":"$app" $final_path #================================================= # RESTORE THE PHP-FPM CONFIGURATION @@ -103,10 +104,14 @@ ynh_install_app_dependencies gettext postgresql postgresql-contrib libpq-dev git ynh_restore_file "/etc/systemd/system/$app.service" systemctl enable $app.service +systemctl daemon-reload #Fix Your search index is locked. +export PATH="$PATH:$final_path/.cargo/bin:/usr/local/sbin" -( cd $final_path/$app && sudo -u "$app" $final_path/.cargo/bin/plm search unlock ) +pushd $final_path/$app + sudo -u "$app" env PATH=$PATH plm search unlock +popd #================================================= # ADVERTISE SERVICE IN ADMIN PANEL @@ -135,9 +140,15 @@ ynh_restore_file "/etc/logrotate.d/$app" #systemctl reload php5-fpm systemctl reload nginx +#================================================= +# CREATE LOG FOLDER +#================================================= + +mkdir -p "/var/log/$app" +chown -R "$app":"$app" "/var/log/$app" + #================================================= # START SERVICE #================================================= -yunohost service start $app -sleep 30 +ynh_systemd_action --action=start --service_name=$app diff --git a/scripts/upgrade b/scripts/upgrade index b6ee6aa..bd42955 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -7,6 +7,7 @@ #================================================= source _common.sh +source ynh_systemd_action source /usr/share/yunohost/helpers #================================================= @@ -21,12 +22,24 @@ admin=$(ynh_app_setting_get $app admin) is_public=$(ynh_app_setting_get $app is_public) final_path=$(ynh_app_setting_get $app final_path) -db_name=$(ynh_app_setting_get "$app" psql_db) +db_name=$(ynh_app_setting_get "$app" db_name) admin_email=$(ynh_app_setting_get "$app" admin_email) -random_key=$(ynh_app_setting_get "$app" random_key) +secret_key=$(ynh_app_setting_get "$app" secret_key) name=$(ynh_app_setting_get "$app" name) port=$(ynh_app_setting_get "$app" port) +psql_db=$(ynh_app_setting_get "$app" psql_db) + +if [ -n "$psql_db" ] +then + db_name=$(ynh_app_setting_get "$app" psql_db) + db_pwd=$(ynh_app_setting_get "$app" psqlpwd) + ynh_app_setting_set "$app" db_name "$db_name" + ynh_app_setting_set "$app" db_pwd "$db_pwd" + ynh_app_setting_delete "$app" psql_db + ynh_app_setting_delete "$app" psqlpwd +fi + #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= @@ -61,12 +74,16 @@ ynh_backup_before_upgrade ynh_clean_setup () { # restore it if the upgrade fails ynh_restore_upgradebackup + ynh_clean_check_starting } # Exit if an error occurs during the execution of the script ynh_abort_if_errors -# Stop Plume for upgrade -yunohost service stop "$app" +#================================================= +# STOP SERVICE +#================================================= + +ynh_systemd_action --action=stop --service_name=$app #================================================= # CHECK THE PATH @@ -115,9 +132,12 @@ ynh_system_user_create "$app" "$final_path" #================================================= # SPECIFIC UPGRADE #================================================= -# ... +# CREATE LOG FOLDER #================================================= +mkdir -p "/var/log/$app" +chown -R "$app":"$app" "/var/log/$app" + #================================================= # CLOSE A PORT #================================================= @@ -190,5 +210,4 @@ systemctl reload nginx # START SERVICE #================================================= -yunohost service start $app -sleep 30 +ynh_systemd_action --action=start --service_name=$app diff --git a/scripts/ynh_systemd_action b/scripts/ynh_systemd_action new file mode 100644 index 0000000..6bed6be --- /dev/null +++ b/scripts/ynh_systemd_action @@ -0,0 +1,89 @@ +#!/bin/bash + +# Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started +# +# usage: ynh_systemd_action [-n service_name] [-a action] [ [-l "line to match"] [-p log_path] [-t timeout] [-e length] ] +# | arg: -n, --service_name= - Name of the service to reload. Default : $app +# | arg: -a, --action= - Action to perform with systemctl. Default: start +# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. +# If not defined it don't wait until the service is completely started. +# | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log +# | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds. +# | arg: -e, --length= - Length of the error log : Default : 20 +ynh_systemd_action() { + # Declare an array to define the options of this helper. + declare -Ar args_array=( [n]=service_name= [a]=action= [l]=line_match= [p]=log_path= [t]=timeout= [e]=length= ) + local service_name + local action + local line_match + local length + local log_path + local timeout + + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + local service_name="${service_name:-$app}" + local action=${action:-start} + local log_path="${log_path:-/var/log/$service_name/$service_name.log}" + local length=${length:-20} + local timeout=${timeout:-300} + + # Start to read the log + if [[ -n "${line_match:-}" ]] + then + local templog="$(mktemp)" + # Following the starting of the app in its log + if [ "$log_path" == "systemd" ] ; then + # Read the systemd journal + journalctl -u $service_name -f --since=-45 > "$templog" & + else + # Read the specified log file + tail -F -n0 "$log_path" > "$templog" & + fi + # Get the PID of the tail command + local pid_tail=$! + fi + + echo "${action^} the service $service_name" >&2 + systemctl $action $service_name \ + || ( journalctl --lines=$length -u $service_name >&2 \ + ; test -n "$log_path" && echo "--" && tail --lines=$length "$log_path" >&2 \ + ; false ) + + # Start the timeout and try to find line_match + if [[ -n "${line_match:-}" ]] + then + local i=0 + for i in $(seq 1 $timeout) + do + # Read the log until the sentence is found, that means the app finished to start. Or run until the timeout + if grep --quiet "$line_match" "$templog" + then + echo "The service $service_name has correctly started." >&2 + break + fi + echo -n "." >&2 + sleep 1 + done + if [ $i -eq $timeout ] + then + echo "The service $service_name didn't fully started before the timeout." >&2 + journalctl --lines=$length -u $service_name >&2 + test -n "$log_path" && echo "--" && tail --lines=$length "$log_path" >&2 + fi + + echo "" + ynh_clean_check_starting + fi +} + +# Clean temporary process and file used by ynh_check_starting +# (usually used in ynh_clean_setup scripts) +# +# usage: ynh_clean_check_starting +ynh_clean_check_starting () { + # Stop the execution of tail. + kill -s 15 $pid_tail 2>&1 + ynh_secure_remove "$templog" 2>&1 +}