#!/bin/bash #================================================= # GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= source _common.sh source ynh_add_swap source ynh_install_ruby__2 source ynh_redis source ynh_send_readme_to_admin__2 source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= ynh_script_progression --message="Loading installation settings..." --weight=1 app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) path_url=$(ynh_app_setting_get --app=$app --key=path) final_path=$(ynh_app_setting_get --app=$app --key=final_path) final_path_www=$(ynh_app_setting_get --app=$app --key=final_path_www) final_path_extensions=$(ynh_app_setting_get --app=$app --key=final_path_extensions) db_name=$(ynh_app_setting_get --app=$app --key=db_name) db_user=$db_name db_pwd=$(ynh_app_setting_get --app=$app --key=mysqlpwd) port_syncing_server_js=$(ynh_app_setting_get --app=$app --key=port_syncing_server_js) port_syncing_server_js_worker=$(ynh_app_setting_get --app=$app --key=port_syncing_server_js_worker) port_auth=$(ynh_app_setting_get --app=$app --key=port_auth) port_auth_worker=$(ynh_app_setting_get --app=$app --key=port_auth_worker) port_api_gateway=$(ynh_app_setting_get --app=$app --key=port_api_gateway) redis_db=$(ynh_app_setting_get --app=$app --key=redis_db) jwt_secret=$(ynh_app_setting_get --app=$app --key=jwt_secret) legacy_jwt_secret=$(ynh_app_setting_get --app=$app --key=legacy_jwt_secret) auth_jwt_secret=$(ynh_app_setting_get --app=$app --key=auth_jwt_secret) pseudo_key_params_key=$(ynh_app_setting_get --app=$app --key=pseudo_key_params_key) encryption_server_key=$(ynh_app_setting_get --app=$app --key=encryption_server_key) syncing_server_js_version_installed=$(ynh_app_setting_get --app=$app --key=syncing_server_js_version) auth_version_installed=$(ynh_app_setting_get --app=$app --key=auth_version) api_gateway_version_installed=$(ynh_app_setting_get --app=$app --key=api_gateway_version) extensions_version_installed=$(ynh_app_setting_get --app=$app --key=extension_version) config_syncing_server_js="$final_path/live/syncing-server-js.env" config_syncing_server_js_worker="$final_path/live/syncing-server-js-worker.env" config_auth="$final_path/live/auth.env" config_auth_worker="$final_path/live/auth-worker.env" config_api_gateway="$final_path/live/api-gateway.env" standalone=$(ynh_app_setting_get --app=$app --key=standalone) nodejs_version_installed=$(ynh_app_setting_get --app=$app --key=nodejs_version) #================================================= # CHECK VERSION #================================================= ### This helper will compare the version of the currently installed app and the version of the upstream package. ### $upgrade_type can have 2 different values ### - UPGRADE_APP if the upstream app version has changed ### - UPGRADE_PACKAGE if only the YunoHost package has changed ### ynh_check_app_version_changed will stop the upgrade if the app is up to date. ### UPGRADE_APP should be used to upgrade the core app only if there's an upgrade to do. upgrade_type=$(ynh_check_app_version_changed) #================================================= # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP #================================================= ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=1 # 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 #================================================= # STANDARD UPGRADE STEPS #================================================= # STOP SYSTEMD SERVICE #================================================= ynh_script_progression --message="Stopping a systemd service..." --weight=1 if [[ ! $standalone ]]; then ynh_remove_systemd_config --service=$app else ynh_systemd_action \ --service_name="$app-syncing-server-js" \ --action="stop" \ --log_path="/var/log/$app/syncing-server-js.log" ynh_systemd_action \ --service_name="$app-syncing-server-js-worker" \ --action="stop" \ --log_path="/var/log/$app/syncing-server-js-worker.log" ynh_systemd_action \ --service_name="$app-auth" \ --action="stop" \ --log_path="/var/log/$app/auth.log" ynh_systemd_action \ --service_name="$app-auth-worker" \ --action="stop" \ --log_path="/var/log/$app/auth-worker.log" ynh_systemd_action \ --service_name="$app-api-gateway" \ --action="stop" \ --log_path="/var/log/$app/api-gateway.log" fi #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 # Cleaning legacy permissions if ynh_legacy_permissions_exists; then ynh_legacy_permissions_delete_all ynh_app_setting_delete --app=$app --key=is_public fi # Everyone can access the app. if [[ $(ynh_permission_exists --permission="main") && ! $standalone ]] then ynh_permission_update --permission="main" --add="visitors" --show_tile="false" fi if ! ynh_permission_exists --permission="main" then ynh_permission_create --permission="main" --url="/" --allowed="visitors" --show_tile="false" fi # Create a permission if needed if ! ynh_permission_exists --permission="help" then ynh_permission_create --permission="help" --url="/help/" --allowed="all_users" --show_tile="true" --label="Help" fi # If final_path doesn't exist, create it if [ -z "$final_path" ]; then final_path=/opt/yunohost/$app ynh_app_setting_set --app=$app --key=final_path --value=$final_path fi # If final_path doesn't exist, create it if [ -z "$final_path_www" ]; then final_path_www=/var/www/$app ynh_app_setting_set --app=$app --key=final_path_www --value=$final_path_www fi # If final_path doesn't exist, create it if [ -z "$final_path_extensions" ]; then final_path_extensions=/var/www/$app/extensions ynh_app_setting_set --app=$app --key=final_path_extensions --value=$final_path_extensions fi # If redis_db doesn't exist, create it if [ -z "$redis_db" ]; then redis_db=$(ynh_redis_get_free_db) ynh_app_setting_set --app=$app --key=redis_db --value="$redis_db" fi # If port_syncing_server_js doesn't exist, create it if [ -z "$port_syncing_server_js" ]; then port_syncing_server_js=$(ynh_find_port --port=3000) ynh_app_setting_set --app=$app --key=port_syncing_server_js --value=$port_syncing_server_js fi # If port_syncing_server_js_worker doesn't exist, create it if [ -z "$port_syncing_server_js_worker" ]; then port_syncing_server_js_worker=$(ynh_find_port --port=$((port_syncing_server_js+1))) ynh_app_setting_set --app=$app --key=port_syncing_server_js_worker --value=$port_syncing_server_js_worker fi # If port_auth doesn't exist, create it if [ -z "$port_auth" ]; then port_auth=$(ynh_find_port --port=$((port_syncing_server_js_worker+1))) ynh_app_setting_set --app=$app --key=port_auth --value=$port_auth fi # If port_auth_worker doesn't exist, create it if [ -z "$port_auth_worker" ]; then port_auth_worker=$(ynh_find_port --port=$((port_auth+1))) ynh_app_setting_set --app=$app --key=port_auth_worker --value=$port_auth_worker fi # If port_api_gateway doesn't exist, create it if [ -z "$port_api_gateway" ]; then port_api_gateway=$(ynh_find_port --port=$((port_auth_worker+1))) ynh_app_setting_set --app=$app --key=port_api_gateway --value=$port_api_gateway fi # If jwt_secret doesn't exist, create it if [ -z "$jwt_secret" ]; then jwt_secret=$(ynh_string_random --length=48 | base64) ynh_app_setting_set --app=$app --key=jwt_secret --value=$jwt_secret fi # If legacy_jwt_secret doesn't exist, create it if [ -z "$legacy_jwt_secret" ]; then legacy_jwt_secret=$(ynh_string_random --length=48 | base64) ynh_app_setting_set --app=$app --key=legacy_jwt_secret --value=$legacy_jwt_secret fi # If auth_jwt_secret doesn't exist, create it if [ -z "$auth_jwt_secret" ]; then auth_jwt_secret=$(ynh_string_random --length=48 | base64) ynh_app_setting_set --app=$app --key=auth_jwt_secret --value=$auth_jwt_secret fi # If pseudo_key_params_key doesn't exist, create it if [ -z "$pseudo_key_params_key" ]; then pseudo_key_params_key=$(ynh_string_random --length=48 | base64) ynh_app_setting_set --app=$app --key=pseudo_key_params_key --value=$pseudo_key_params_key fi # If encryption_server_key doesn't exist, create it if [ -z "$encryption_server_key" ]; then encryption_server_key=$(hexdump -n 32 -e '4/4 "%08X"' /dev/random) # 32bytes hex key is required ynh_app_setting_set --app=$app --key=encryption_server_key --value=$encryption_server_key fi # Remove old Settings, Services, Files, Dependencies # If access_domain exist, delete it if [ -n $(ynh_app_setting_get --app="$app" --key=access_domain) ]; then ynh_app_setting_delete --app=$app --key=access_domain fi # If mail exist, delete it if [ -n $(ynh_app_setting_get --app="$app" --key=mail) ]; then ynh_app_setting_delete --app=$app --key=mail fi # If port exist, delete it if [ -n $(ynh_app_setting_get --app="$app" --key=port) ]; then ynh_app_setting_delete --app=$app --key=port fi # If old service exsits; remove it if ynh_exec_warn_less yunohost service status "$app" >/dev/null then ynh_script_progression --message="Removing $app service..." --weight=1 yunohost service remove "$app" fi # Remove old config scripts if [ -e "/etc/yunohost/apps/$app/config_panel.toml" ]; then ynh_secure_remove --file="/etc/yunohost/apps/$app/config_panel.toml" fi if [ -e "/etc/yunohost/apps/$app/scripts/config" ]; then ynh_secure_remove --file="/etc/yunohost/apps/$app/scripts/config" fi # Remove old dependencies if [[ ! $standalone ]]; then ynh_remove_ruby ynh_remove_app_dependencies fi # Remove unneeded data if [ -e "$final_path/live/syncing-server-js-worker" ]; then ynh_secure_remove --file="$final_path/live/syncing-server-js-worker" fi if [ -e "$final_path/live/auth-worker" ]; then ynh_secure_remove --file="$final_path/live/auth-worker" fi #================================================= # CREATE DEDICATED USER #================================================= ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 # Create a dedicated user (if not existing) ynh_system_user_create --username=$app --home_dir=$final_path #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= ynh_script_progression --message="Upgrading source files..." --weight=1 # Remove all files if the old syncing-server is used if [[ ! $standalone ]]; then ynh_secure_remove --file="$final_path" ynh_secure_remove --file="/var/log/$app" fi if [[ "$syncing_server_js_version_installed" < "$syncing_server_js_version" ]] then # Backup files to keep ynh_backup_if_checksum_is_different --file=$config_syncing_server_js ynh_backup_if_checksum_is_different --file=$config_syncing_server_js_worker # Remove destination directory ynh_secure_remove --file="$final_path/live/syncing-server-js" ynh_secure_remove --file="$config_syncing_server_js" ynh_secure_remove --file="$config_syncing_server_js_worker" # Download, check integrity, uncompress and patch the source from app.src mkdir -p "$final_path/live" ynh_setup_source --source_id=app_syncing-server-js --dest_dir="$final_path/live/syncing-server-js" fi if [[ "$auth_version_installed" < "$auth_version" ]] then # Backup files to keep ynh_backup_if_checksum_is_different --file=$config_auth ynh_backup_if_checksum_is_different --file=$config_auth_worker # Remove destination directory ynh_secure_remove --file="$final_path/live/auth" ynh_secure_remove --file="$config_auth" ynh_secure_remove --file="$config_auth_worker" # Download, check integrity, uncompress and patch the source from app.src mkdir -p "$final_path/live" ynh_setup_source --source_id=app_auth --dest_dir="$final_path/live/auth" fi if [[ "$api_gateway_version_installed" < "$api_gateway_version" ]] then # Backup files to keep ynh_backup_if_checksum_is_different --file=$config_api_gateway # Remove destination directory ynh_secure_remove --file="$final_path/live/api-gateway" ynh_secure_remove --file="$config_api_gateway" # Download, check integrity, uncompress and patch the source from app.src mkdir -p "$final_path/live" ynh_setup_source --source_id=app_api-gateway --dest_dir="$final_path/live/api-gateway" fi if [[ "$extensions_version_installed" < "$extensions_version" ]] then # Remove destination directory ynh_secure_remove --file="$final_path_extensions" # Download, check integrity, uncompress and patch the source from app.src mkdir -p "$final_path_extensions" if test -e "../sources/extra_files/extensions" then cp -a "../sources/extra_files/extensions/." "$final_path_extensions" fi find "../conf/" -name "ext_*.src" -print0 | while read -d $'\0' file do basename=$(basename -as .src $file) ynh_setup_source --dest_dir="$final_path_extensions/src/${basename#'ext_'}" --source_id="$basename" done fi # Copy help file ynh_secure_remove --file="$final_path_www/help" mkdir -p "$final_path_www/help" if test -e "$YNH_APP_BASEDIR/sources/extra_files/help"; then cp --archive "$YNH_APP_BASEDIR/sources/extra_files/help/." "$final_path_www/help" fi ynh_replace_vars --file="$final_path_www/help/index.html" chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:$app "$final_path" chmod 750 "$final_path_www" chmod -R o-rwx "$final_path_www" chown -R "www-data":"www-data" "$final_path_www" #================================================= # NGINX CONFIGURATION #================================================= ynh_script_progression --message="Upgrading nginx web server configuration..." --weight=1 # Create a dedicated nginx config ynh_add_nginx_config #================================================= # UPGRADE DEPENDENCIES #================================================= ynh_script_progression --message="Upgrading dependencies..." --weight=1 # Remove old nodejs version if [[ "$nodejs_version_installed" < "$NODEJS_VERSION" && -n "$nodejs_version_installed" ]] then ynh_remove_nodejs fi ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$NODEJS_VERSION ynh_install_extra_app_dependencies --repo="deb https://dl.yarnpkg.com/debian/ stable main" --package="yarn" --key="https://dl.yarnpkg.com/debian/pubkey.gpg" #================================================= # SPECIFIC UPGRADE #================================================= #================================================= # ADD SWAP #================================================= ynh_script_progression --message="Adding swap..." ynh_add_swap --size=$swap_needed #================================================= # MODIFY A CONFIG FILE #================================================= ynh_script_progression --message="Modify a config file..." --weight=2 ynh_add_config --template="env_syncing-server-js.env.sample" --destination="$config_syncing_server_js" ynh_add_config --template="env_syncing-server-js-worker.env.sample" --destination="$config_syncing_server_js_worker" ynh_add_config --template="env_auth.env.sample" --destination="$config_auth" ynh_add_config --template="env_auth-worker.env.sample" --destination="$config_auth_worker" ynh_add_config --template="env_api-gateway.env.sample" --destination="$config_api_gateway" #================================================= # INSTALLING Standard Notes - Syncing Server #================================================= if [ "$upgrade_type" == "UPGRADE_APP" ] then ynh_script_progression --message="Installing Standard Notes - Syncing Server..." --weight=93 ynh_use_nodejs if [[ "$syncing_server_js_version_installed" < "$syncing_server_js_version" ]] then pushd "$final_path/live/syncing-server-js" ynh_exec_as $app env NODE_OPTIONS="--max-old-space-size=$node_max_old_space_size" PATH=$ynh_node_load_PATH yarn install --pure-lockfile ynh_exec_as $app env NODE_OPTIONS="--max-old-space-size=$node_max_old_space_size" PATH=$ynh_node_load_PATH yarn build popd ynh_app_setting_set --app=$app --key=syncing_server_js_version --value=$syncing_server_js_version fi if [[ "$auth_version_installed" < "$auth_version" ]] then pushd "$final_path/live/auth" ynh_exec_as $app env NODE_OPTIONS="--max-old-space-size=$node_max_old_space_size" PATH=$ynh_node_load_PATH yarn install --pure-lockfile ynh_exec_as $app env NODE_OPTIONS="--max-old-space-size=$node_max_old_space_size" PATH=$ynh_node_load_PATH yarn build popd ynh_app_setting_set --app=$app --key=auth_version --value=$auth_version fi if [[ "$api_gateway_version_installed" < "$api_gateway_version" ]] then pushd "$final_path/live/api-gateway" ynh_exec_as $app env NODE_OPTIONS="--max-old-space-size=$node_max_old_space_size" PATH=$ynh_node_load_PATH yarn install --pure-lockfile ynh_exec_as $app env NODE_OPTIONS="--max-old-space-size=$node_max_old_space_size" PATH=$ynh_node_load_PATH yarn build popd ynh_app_setting_set --app=$app --key=api_gateway_version --value=$api_gateway_version fi fi #================================================= # INSTALLING Standard Notes - Extensions #================================================= if [[ "$extensions_version_installed" < "$extensions_version" ]] then ynh_script_progression --message="Installing Standard Notes - Extensions..." --weight=1 if [ $path_url = "/" ] then path="" else path=$path_url fi ynh_replace_string --match_string="__DOMAIN__PATH__" --replace_string="$domain$path" --target_file="$final_path_extensions/repo.json" find "$final_path_extensions/src/" -name "*.json" -print0 | while read -d $'\0' file do ynh_replace_string --match_string="__DOMAIN__PATH__" --replace_string="$domain$path" --target_file="$file" done ynh_app_setting_set --app=$app --key=extensions_version --value=$extensions_version fi #================================================= # SETUP SYSTEMD #================================================= ynh_script_progression --message="Upgrading systemd configuration..." --weight=1 # Create a dedicated systemd config ynh_add_systemd_config --service="$app-syncing-server-js" --template="systemd_syncing-server-js.service" ynh_add_systemd_config --service="$app-syncing-server-js-worker" --template="systemd_syncing-server-js-worker.service" ynh_add_systemd_config --service="$app-auth" --template="systemd_auth.service" ynh_add_systemd_config --service="$app-auth-worker" --template="systemd_auth-worker.service" ynh_add_systemd_config --service="$app-api-gateway" --template="systemd_api-gateway.service" #================================================= # STORE THE CONFIG FILE CHECKSUM #================================================= # Calculate and store the config file checksum into the app settings ynh_store_file_checksum --file="$config_syncing_server_js" ynh_store_file_checksum --file="$config_syncing_server_js_worker" ynh_store_file_checksum --file="$config_auth" ynh_store_file_checksum --file="$config_auth_worker" ynh_store_file_checksum --file="$config_api_gateway" ynh_store_file_checksum --file="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # GENERIC FINALIZATION #================================================= #================================================= # SETUP LOGROTATE #================================================= ynh_script_progression --message="Upgrading logrotate configuration..." --weight=1 mkdir -p "/var/log/$app" chown -R "$app": "/var/log/$app" # Use logrotate to manage application logfile(s) ynh_use_logrotate --logfile="/var/log/$app/syncing-server.log" ynh_use_logrotate --logfile="/var/log/$app/syncing-server-worker.log" ynh_use_logrotate --logfile="/var/log/$app/auth.log" ynh_use_logrotate --logfile="/var/log/$app/auth-worker.log" ynh_use_logrotate --logfile="/var/log/$app/api-gateway.log" #================================================= # INTEGRATE SERVICE IN YUNOHOST #================================================= ynh_script_progression --message="Integrate $app service in Yunohost..." --weight=1 yunohost service add "$app-syncing-server-js" --description="Standard Notes - Syncing Server" --log="/var/log/$app/syncing-server-js.log" yunohost service add "$app-syncing-server-js-worker" --description="Standard Notes - Syncing Server - Worker" --log="/var/log/$app/syncing-server-js-worker.log" yunohost service add "$app-auth" --description="Standard Notes - Auth" --log="/var/log/$app/auth.log" yunohost service add "$app-auth-worker" --description="Standard Notes - Auth - Worker" --log="/var/log/$app/auth-worker.log" yunohost service add "$app-api-gateway" --description="Standard Notes - API Gateway" --log="/var/log/$app/api-gateway.log" #================================================= # START SYSTEMD SERVICE #================================================= ynh_script_progression --message="Starting a systemd service..." --weight=1 # Start a systemd service ynh_systemd_action \ --service_name="$app-syncing-server-js" \ --action="start" \ --log_path="/var/log/$app/syncing-server-js.log" \ --line_match='{"message":"Server started on port '$port_syncing_server_js'","level":"info"}' ynh_systemd_action \ --service_name="$app-syncing-server-js-worker" \ --action="start" \ --log_path="/var/log/$app/syncing-server-js-worker.log" \ --line_match='{"message":"Starting worker...","level":"info"}' ynh_systemd_action \ --service_name="$app-auth" \ --action="start" \ --log_path="/var/log/$app/auth.log" \ --line_match='{"message":"Server started on port '$port_auth'","level":"info"}' ynh_systemd_action \ --service_name="$app-auth-worker" \ --action="start" \ --log_path="/var/log/$app/auth-worker.log" \ --line_match='{"message":"Starting worker...","level":"info"}' ynh_systemd_action \ --service_name="$app-api-gateway" \ --action="start" \ --log_path="/var/log/$app/api-gateway.log" \ --line_match='{"level":"info","message":"Server started on port '$port_api_gateway'"}' #================================================= # SETUP FAIL2BAN #================================================= ynh_script_progression --message="Reconfiguring fail2ban..." --weight=1 # Create a dedicated fail2ban config ynh_add_fail2ban_config --use_template #================================================= # RELOAD NGINX #================================================= ynh_script_progression --message="Reloading nginx web server..." --weight=1 ynh_systemd_action --service_name=nginx --action=reload #================================================= # SEND A README FOR THE ADMIN #================================================= ynh_script_progression --message="Sending a readme for the admin..." admin_panel="https://$(grep portal_domain /etc/ssowat/conf.json | cut -d'"' -f4)/yunohost/admin/#/apps/$app" echo -e "\ Standard Notes - Syncing Server was successfully upgraded.\n\ Please configure the Standard Notes web app or mobile app to use this syncing server: https://$domain$path_url\n\ \n\ Standard Notes extensions are hosted with this package.\n\ An Help page for setting-up the Standard Notes Server and Extensions have been created under: https://$domain$path_url/help\n\ The Help page is accessible via the Yunohost Portal.\n\ You can deactivate the Help page under: $admin_panel\ " > message ynh_send_readme_to_admin --app_message="message" --type='upgrade' #================================================= # STORE SETTINGS #================================================= ynh_app_setting_set --app=$app --key=standalone --value="true" #================================================= # END OF SCRIPT #================================================= ynh_script_progression --message="Upgrade of $app completed" --last