From 56b8ba2829c3d9cb19a7af1c14077ece1763c7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:12:04 +0200 Subject: [PATCH 01/17] v2 --- conf/app.src | 7 ---- conf/systemd.service | 2 +- manifest.toml | 67 +++++++++++++++++++++++++++++++ scripts/_common.sh | 2 +- scripts/backup | 14 +++---- scripts/change_url | 66 +++++++++++++++--------------- scripts/install | 96 ++++++++++++++++++++++---------------------- scripts/remove | 28 ++++++------- scripts/restore | 36 ++++++++--------- scripts/upgrade | 64 ++++++++++++++--------------- 10 files changed, 222 insertions(+), 160 deletions(-) delete mode 100644 conf/app.src create mode 100644 manifest.toml diff --git a/conf/app.src b/conf/app.src deleted file mode 100644 index 2dc2386..0000000 --- a/conf/app.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/os-js/OS.js/archive/refs/tags/3.1.12.tar.gz -SOURCE_SUM=c5f04810e4f5604adadc7bc0c17f2d7eee49d521915ad9ac2203b835b3e9987d -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME= -SOURCE_EXTRACT=true diff --git a/conf/systemd.service b/conf/systemd.service index 2bf6495..a213e83 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -6,7 +6,7 @@ After=network.target Type=simple User=__APP__ Group=__APP__ -WorkingDirectory=__FINALPATH__/ +WorkingDirectory=__INSTALL_DIR__/ Environment="__YNH_NODE_LOAD_PATH__" ExecStart=__YNH_NPM__ run serve StandardOutput=append:/var/log/__APP__/__APP__.log diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..f8a454d --- /dev/null +++ b/manifest.toml @@ -0,0 +1,67 @@ +packaging_format = 2 + +id = "osjs" +name = "OSjs" +description.en = "Desktop you have accesss through your browser" +description.fr = "Bureau accessible à travers votre navigateur" + +version = "3.1.12~ynh2" + +maintainers = ["frju365"] + +[upstream] +license = "MIT" +website = "https://www.os-js.org" +demo = "https://demo.os-js.org/" +admindoc = "https://manual.os-js.org/" +code = "https://github.com/os-js/OS.js" +cpe = "???" # FIXME: optional but recommended if relevant, this is meant to contain the Common Platform Enumeration, which is sort of a standard id for applications defined by the NIST. In particular, Yunohost may use this is in the future to easily track CVE (=security reports) related to apps. The CPE may be obtained by searching here: https://nvd.nist.gov/products/cpe/search. For example, for Nextcloud, the CPE is 'cpe:2.3:a:nextcloud:nextcloud' (no need to include the version number) +fund = "???" # FIXME: optional but recommended (or remove if irrelevant / not applicable). This is meant to be an URL where people can financially support this app, especially when its development is based on volunteers and/or financed by its community. YunoHost may later advertise it in the webadmin. + +[integration] +yunohost = ">= 4.3.0" +architectures = "all" # FIXME: can be replaced by a list of supported archs using the dpkg --print-architecture nomenclature (amd64/i386/armhf/arm64), for example: ["amd64", "i386"] +multi_instance = true +ldap = "?" # FIXME: replace with true, false, or "not_relevant". Not to confuse with the "sso" key : the "ldap" key corresponds to wether or not a user *can* login on the app using its YunoHost credentials. +sso = "?" # FIXME: replace with true, false, or "not_relevant". Not to confuse with the "ldap" key : the "sso" key corresponds to wether or not a user is *automatically logged-in* on the app when logged-in on the YunoHost portal. +disk = "50M" # FIXME: replace with an **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ... +ram.build = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... +ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... + +[install] + [install.domain] + # this is a generic question - ask strings are automatically handled by Yunohost's core + type = "domain" + + [install.path] + # this is a generic question - ask strings are automatically handled by Yunohost's core + type = "path" + default = "/osjs" + + [install.init_main_permission] + type = "group" + default = "visitors" + + [install.admin] + # this is a generic question - ask strings are automatically handled by Yunohost's core + type = "user" + + [install.password] + # this is a generic question - ask strings are automatically handled by Yunohost's core + type = "password" + +[resources] + [resources.sources.main] + url = "https://github.com/os-js/OS.js/archive/refs/tags/3.1.12.tar.gz" + sha256 = "c5f04810e4f5604adadc7bc0c17f2d7eee49d521915ad9ac2203b835b3e9987d" + + + [resources.system_user] + + [resources.install_dir] + + [resources.permissions] + main.url = "/" + + [resources.database] + type = "mysql" diff --git a/scripts/_common.sh b/scripts/_common.sh index 5e9fba3..16dc5b7 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -7,7 +7,7 @@ nodejs_version=10 # dependencies used by the app -pkg_dependencies="libpam0g-dev" +#REMOVEME? pkg_dependencies="libpam0g-dev" #================================================= # PERSONAL HELPERS diff --git a/scripts/backup b/scripts/backup index f78c623..9ecf093 100644 --- a/scripts/backup +++ b/scripts/backup @@ -14,21 +14,21 @@ source /usr/share/yunohost/helpers # MANAGE SCRIPT FAILURE #================================================= -ynh_clean_setup () { +#REMOVEME? ynh_clean_setup () { true } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_print_info --message="Loading installation settings..." +#REMOVEME? ynh_print_info --message="Loading installation settings..." -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) #================================================= # DECLARE DATA AND CONF FILES TO BACKUP @@ -39,7 +39,7 @@ ynh_print_info --message="Declaring files to be backed up..." # BACKUP THE APP MAIN DIR #================================================= -ynh_backup --src_path="$final_path" +ynh_backup --src_path="$install_dir" #================================================= # BACKUP THE NGINX CONFIGURATION diff --git a/scripts/change_url b/scripts/change_url index 391e175..cd43466 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -13,57 +13,57 @@ source /usr/share/yunohost/helpers # RETRIEVE ARGUMENTS #================================================= -old_domain=$YNH_APP_OLD_DOMAIN -old_path=$YNH_APP_OLD_PATH +#REMOVEME? old_domain=$YNH_APP_OLD_DOMAIN +#REMOVEME? old_path=$YNH_APP_OLD_PATH -new_domain=$YNH_APP_NEW_DOMAIN -new_path=$YNH_APP_NEW_PATH +#REMOVEME? new_domain=$YNH_APP_NEW_DOMAIN +#REMOVEME? new_path=$YNH_APP_NEW_PATH -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." +#REMOVEME? ynh_script_progression --message="Loading installation settings..." -# Needed for helper "ynh_add_nginx_config" -final_path=$(ynh_app_setting_get --app=$app --key=final_path) +#REMOVEME? # Needed for helper "ynh_add_nginx_config" +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) # Add settings here as needed by your application -port=$(ynh_app_setting_get --app=$app --key=port) +#REMOVEME? port=$(ynh_app_setting_get --app=$app --key=port) #================================================= # BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP #================================================= -ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." +#REMOVEME? ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." # Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - ynh_clean_check_starting +#REMOVEME? ynh_backup_before_upgrade +#REMOVEME? ynh_clean_setup () { + #REMOVEME? ynh_clean_check_starting # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. - ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +#REMOVEME? ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" # Restore it if the upgrade fails - ynh_restore_upgradebackup +#REMOVEME? ynh_restore_upgradebackup } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # CHECK WHICH PARTS SHOULD BE CHANGED #================================================= -change_domain=0 -if [ "$old_domain" != "$new_domain" ] +#REMOVEME? change_domain=0 +#REMOVEME? if [ "$old_domain" != "$new_domain" ] then - change_domain=1 + #REMOVEME? change_domain=1 fi -change_path=0 -if [ "$old_path" != "$new_path" ] +#REMOVEME? change_path=0 +#REMOVEME? if [ "$old_path" != "$new_path" ] then - change_path=1 + #REMOVEME? change_path=1 fi #================================================= @@ -80,28 +80,30 @@ ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app #================================================= ynh_script_progression --message="Updating NGINX web server configuration..." -nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf +ynh_change_url_nginx_config + +#REMOVEME? nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf # Change the path in the NGINX config file if [ $change_path -eq 1 ] then # Make a backup of the original NGINX config file if modified - ynh_backup_if_checksum_is_different --file="$nginx_conf_path" +#REMOVEME? ynh_backup_if_checksum_is_different --file="$nginx_conf_path" # Set global variables for NGINX helper - domain="$old_domain" - path_url="$new_path" +#REMOVEME? domain="$old_domain" +#REMOVEME? path="$new_path" # Create a dedicated NGINX config - ynh_add_nginx_config +#REMOVEME? ynh_add_nginx_config fi # Change the domain for NGINX if [ $change_domain -eq 1 ] then # Delete file checksum for the old conf file location - ynh_delete_file_checksum --file="$nginx_conf_path" - mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf +#REMOVEME? ynh_delete_file_checksum --file="$nginx_conf_path" +#REMOVEME? mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf # Store file checksum for the new config file location - ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +#REMOVEME? ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" fi #================================================= @@ -117,9 +119,9 @@ ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$ap #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." +#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." -ynh_systemd_action --service_name=nginx --action=reload +#REMOVEME? #REMOVEME? ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT diff --git a/scripts/install b/scripts/install index 8a3082c..0664b21 100644 --- a/scripts/install +++ b/scripts/install @@ -13,94 +13,94 @@ source /usr/share/yunohost/helpers # MANAGE SCRIPT FAILURE #================================================= -ynh_clean_setup () { +#REMOVEME? ynh_clean_setup () { ynh_clean_check_starting } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # RETRIEVE ARGUMENTS FROM THE MANIFEST #================================================= -domain=$YNH_APP_ARG_DOMAIN -path_url=$YNH_APP_ARG_PATH -is_public=$YNH_APP_ARG_IS_PUBLIC -admin=$YNH_APP_ARG_ADMIN -password=$YNH_APP_ARG_PASSWORD +#REMOVEME? domain=$YNH_APP_ARG_DOMAIN +#REMOVEME? path=$YNH_APP_ARG_PATH +#REMOVEME? is_public=$YNH_APP_ARG_IS_PUBLIC +#REMOVEME? admin=$YNH_APP_ARG_ADMIN +#REMOVEME? password=$YNH_APP_ARG_PASSWORD -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= -ynh_script_progression --message="Validating installation parameters..." +#REMOVEME? ynh_script_progression --message="Validating installation parameters..." -final_path=/var/www/$app -test ! -e "$final_path" || ynh_die --message="This path already contains a folder" +#REMOVEME? install_dir=/var/www/$app +#REMOVEME? test ! -e "$install_dir" || ynh_die --message="This path already contains a folder" # Register (book) web path -ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url +#REMOVEME? ynh_webpath_register --app=$app --domain=$domain --path=$path #================================================= # STORE SETTINGS FROM MANIFEST #================================================= -ynh_script_progression --message="Storing installation settings..." +#REMOVEME? ynh_script_progression --message="Storing installation settings..." -ynh_app_setting_set --app=$app --key=domain --value=$domain -ynh_app_setting_set --app=$app --key=path --value=$path_url -ynh_app_setting_set --app=$app --key=admin --value=$admin -ynh_app_setting_set --app=$app --key=password --value=$password +#REMOVEME? ynh_app_setting_set --app=$app --key=domain --value=$domain +#REMOVEME? ynh_app_setting_set --app=$app --key=path --value=$path +#REMOVEME? ynh_app_setting_set --app=$app --key=admin --value=$admin +#REMOVEME? ynh_app_setting_set --app=$app --key=password --value=$password #================================================= # STANDARD MODIFICATIONS #================================================= # FIND AND OPEN A PORT #================================================= -ynh_script_progression --message="Finding an available port..." +#REMOVEME? ynh_script_progression --message="Finding an available port..." # Find an available port -port=$(ynh_find_port --port=8095) -ynh_app_setting_set --app=$app --key=port --value=$port +#REMOVEME? port=$(ynh_find_port --port=8095) +#REMOVEME? ynh_app_setting_set --app=$app --key=port --value=$port #================================================= # INSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Installing dependencies..." +#REMOVEME? ynh_script_progression --message="Installing dependencies..." -ynh_install_app_dependencies $pkg_dependencies +#REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Configuring system user..." +#REMOVEME? ynh_script_progression --message="Configuring system user..." # Create a system user -ynh_system_user_create --username=$app --home_dir="$final_path" +#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" #================================================= # CREATE A MYSQL DATABASE #================================================= -ynh_script_progression --message="Creating a MySQL database..." +#REMOVEME? ynh_script_progression --message="Creating a MySQL database..." -db_name=$(ynh_sanitize_dbid --db_name=$app) -db_user=$db_name -ynh_app_setting_set --app=$app --key=db_name --value=$db_name -ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name +#REMOVEME? db_name=$(ynh_sanitize_dbid --db_name=$app) +#REMOVEME? db_user=$db_name +#REMOVEME? ynh_app_setting_set --app=$app --key=db_name --value=$db_name +#REMOVEME? ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= ynh_script_progression --message="Setting up source files..." -ynh_app_setting_set --app=$app --key=final_path --value=$final_path +#REMOVEME? ynh_app_setting_set --app=$app --key=install_dir --value=$install_dir # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source --dest_dir="$final_path" +ynh_setup_source --dest_dir="$install_dir" -chmod 750 "$final_path" -chmod -R o-rwx "$final_path" -chown -R $app:$app "$final_path" +chmod 750 "$install_dir" +chmod -R o-rwx "$install_dir" +chown -R $app:$app "$install_dir" #================================================= # NGINX CONFIGURATION @@ -117,22 +117,22 @@ ynh_add_nginx_config #================================================= ynh_script_progression --message="Adding a configuration file..." -ynh_add_config --template="../conf/client.config.js" --destination="$final_path/src/client/config.js" +ynh_add_config --template="../conf/client.config.js" --destination="$install_dir/src/client/config.js" -chmod 400 "$final_path/src/client/config.js" -chown $app:$app "$final_path/src/client/config.js" +chmod 400 "$install_dir/src/client/config.js" +chown $app:$app "$install_dir/src/client/config.js" -ynh_add_config --template="../conf/server.index.js" --destination="$final_path/src/server/index.js" +ynh_add_config --template="../conf/server.index.js" --destination="$install_dir/src/server/index.js" -chmod 400 "$final_path/src/server/index.js" -chown $app:$app "$final_path/src/server/index.js" +chmod 400 "$install_dir/src/server/index.js" +chown $app:$app "$install_dir/src/server/index.js" #================================================= # BUILD APP #================================================= ynh_script_progression --message="Building app..." -pushd $final_path +pushd $install_dir ynh_use_nodejs $ynh_npm install $ynh_npm run package:discover @@ -140,9 +140,9 @@ pushd $final_path npm install --save --production @osjs/pam-auth popd -ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$final_path/src/server/config.js" +ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" -chown -R $app:$app "$final_path" +chown -R $app:$app "$install_dir" #================================================= # SETUP SYSTEMD @@ -182,22 +182,22 @@ ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$ap #================================================= # SETUP SSOWAT #================================================= -ynh_script_progression --message="Configuring permissions..." +#REMOVEME? ynh_script_progression --message="Configuring permissions..." # Make app public if necessary -if [ $is_public -eq 1 ] +#REMOVEME? if [ $is_public -eq 1 ] then # Everyone can access the app. # The "main" permission is automatically created before the install script. - ynh_permission_update --permission="main" --add="visitors" +#REMOVEME? ynh_permission_update --permission="main" --add="visitors" fi #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." +#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." -ynh_systemd_action --service_name=nginx --action=reload +#REMOVEME? ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT diff --git a/scripts/remove b/scripts/remove index 7586202..ab3f904 100644 --- a/scripts/remove +++ b/scripts/remove @@ -12,14 +12,14 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." +#REMOVEME? ynh_script_progression --message="Loading installation settings..." -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get --app=$app --key=domain) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$db_name -final_path=$(ynh_app_setting_get --app=$app --key=final_path) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) +#REMOVEME? db_user=$db_name +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) #================================================= # STANDARD REMOVE @@ -53,18 +53,18 @@ ynh_remove_logrotate #================================================= # REMOVE THE MYSQL DATABASE #================================================= -ynh_script_progression --message="Removing the MySQL database..." +#REMOVEME? ynh_script_progression --message="Removing the MySQL database..." # Remove a database if it exists, along with the associated user -ynh_mysql_remove_db --db_user=$db_user --db_name=$db_name +#REMOVEME? ynh_mysql_remove_db --db_user=$db_user --db_name=$db_name #================================================= # REMOVE APP MAIN DIR #================================================= -ynh_script_progression --message="Removing app main directory..." +#REMOVEME? ynh_script_progression --message="Removing app main directory..." # Remove the app directory securely -ynh_secure_remove --file="$final_path" +#REMOVEME? ynh_secure_remove --file="$install_dir" #================================================= # REMOVE NGINX CONFIGURATION @@ -77,11 +77,11 @@ ynh_remove_nginx_config #================================================= # REMOVE DEPENDENCIES #================================================= -ynh_script_progression --message="Removing dependencies..." +#REMOVEME? ynh_script_progression --message="Removing dependencies..." # Remove metapackage and its dependencies ynh_remove_nodejs -ynh_remove_app_dependencies +#REMOVEME? ynh_remove_app_dependencies #================================================= # SPECIFIC REMOVE @@ -98,10 +98,10 @@ ynh_secure_remove --file="/var/log/$app" #================================================= # REMOVE DEDICATED USER #================================================= -ynh_script_progression --message="Removing the dedicated system user..." +#REMOVEME? ynh_script_progression --message="Removing the dedicated system user..." # Delete a system user -ynh_system_user_delete --username=$app +#REMOVEME? ynh_system_user_delete --username=$app #================================================= # END OF SCRIPT diff --git a/scripts/restore b/scripts/restore index b5c6716..b50c442 100644 --- a/scripts/restore +++ b/scripts/restore @@ -14,30 +14,30 @@ source /usr/share/yunohost/helpers # MANAGE SCRIPT FAILURE #================================================= -ynh_clean_setup () { +#REMOVEME? ynh_clean_setup () { ynh_clean_check_starting } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." +#REMOVEME? ynh_script_progression --message="Loading installation settings..." -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? 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) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) #================================================= # CHECK IF THE APP CAN BE RESTORED #================================================= -ynh_script_progression --message="Validating restoration parameters..." +#REMOVEME? ynh_script_progression --message="Validating restoration parameters..." -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " +#REMOVEME? test ! -d $install_dir \ + || ynh_die --message="There is already a directory: $install_dir " #================================================= # STANDARD RESTORATION STEPS @@ -51,31 +51,31 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= # RECREATE THE DEDICATED USER #================================================= -ynh_script_progression --message="Recreating the dedicated system user..." +#REMOVEME? ynh_script_progression --message="Recreating the dedicated system user..." # Create the dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir="$final_path" +#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" #================================================= # RESTORE THE APP MAIN DIR #================================================= ynh_script_progression --message="Restoring the app main directory..." -ynh_restore_file --origin_path="$final_path" +ynh_restore_file --origin_path="$install_dir" -chmod 750 "$final_path" -chmod -R o-rwx "$final_path" -chown -R $app:$app "$final_path" +chmod 750 "$install_dir" +chmod -R o-rwx "$install_dir" +chown -R $app:$app "$install_dir" #================================================= # SPECIFIC RESTORATION #================================================= # REINSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Reinstalling dependencies..." +#REMOVEME? ynh_script_progression --message="Reinstalling dependencies..." # Define and install dependencies -ynh_install_app_dependencies $pkg_dependencies +#REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 93e4685..5bdb226 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -12,14 +12,14 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." +#REMOVEME? ynh_script_progression --message="Loading installation settings..." -app=$YNH_APP_INSTANCE_NAME +#REMOVEME? app=$YNH_APP_INSTANCE_NAME -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -port=$(ynh_app_setting_get --app=$app --key=port) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) +#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) +#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) +#REMOVEME? port=$(ynh_app_setting_get --app=$app --key=port) +#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) #================================================= # CHECK VERSION @@ -31,17 +31,17 @@ 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)..." +#REMOVEME? ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." # Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { +#REMOVEME? ynh_backup_before_upgrade +#REMOVEME? ynh_clean_setup () { ynh_clean_check_starting # Restore it if the upgrade fails - ynh_restore_upgradebackup +#REMOVEME? ynh_restore_upgradebackup } # Exit if an error occurs during the execution of the script -ynh_abort_if_errors +#REMOVEME? ynh_abort_if_errors #================================================= # STANDARD UPGRADE STEPS @@ -58,8 +58,8 @@ ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app ynh_script_progression --message="Ensuring downward compatibility..." # Cleaning legacy permissions -if ynh_legacy_permissions_exists; then - ynh_legacy_permissions_delete_all +#REMOVEME? if ynh_legacy_permissions_exists; then +#REMOVEME? ynh_legacy_permissions_delete_all ynh_app_setting_delete --app=$app --key=is_public fi @@ -67,10 +67,10 @@ fi #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." +#REMOVEME? ynh_script_progression --message="Making sure dedicated system user exists..." # Create a dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir="$final_path" +#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -81,12 +81,12 @@ then ynh_script_progression --message="Upgrading source files..." # Download, check integrity, uncompress and patch the source from app.src - ynh_setup_source --dest_dir="$final_path" --keep="src/client/config.js src/server/index.js" + ynh_setup_source --dest_dir="$install_dir" --keep="src/client/config.js src/server/index.js" fi -chmod 750 "$final_path" -chmod -R o-rwx "$final_path" -chown -R $app:$app "$final_path" +chmod 750 "$install_dir" +chmod -R o-rwx "$install_dir" +chown -R $app:$app "$install_dir" #================================================= # NGINX CONFIGURATION @@ -99,9 +99,9 @@ ynh_add_nginx_config #================================================= # UPGRADE DEPENDENCIES #================================================= -ynh_script_progression --message="Upgrading dependencies..." +#REMOVEME? ynh_script_progression --message="Upgrading dependencies..." -ynh_install_app_dependencies $pkg_dependencies +#REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= @@ -111,22 +111,22 @@ ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= ynh_script_progression --message="Updating a configuration file..." -ynh_add_config --template="../conf/client.config.js" --destination="$final_path/src/client/config.js" +ynh_add_config --template="../conf/client.config.js" --destination="$install_dir/src/client/config.js" -chmod 400 "$final_path/src/client/config.js" -chown $app:$app "$final_path/src/client/config.js" +chmod 400 "$install_dir/src/client/config.js" +chown $app:$app "$install_dir/src/client/config.js" -ynh_add_config --template="../conf/server.index.js" --destination="$final_path/src/server/index.js" +ynh_add_config --template="../conf/server.index.js" --destination="$install_dir/src/server/index.js" -chmod 400 "$final_path/src/server/index.js" -chown $app:$app "$final_path/src/server/index.js" +chmod 400 "$install_dir/src/server/index.js" +chown $app:$app "$install_dir/src/server/index.js" #================================================= # BUILD APP #================================================= ynh_script_progression --message="Building app..." -pushd $final_path +pushd $install_dir ynh_use_nodejs $ynh_npm install $ynh_npm run package:discover @@ -134,9 +134,9 @@ pushd $final_path npm install --save --production @osjs/pam-auth popd -ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$final_path/src/server/config.js" +ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" -chown -R $app:$app "$final_path" +chown -R $app:$app "$install_dir" #================================================= # SETUP SYSTEMD @@ -174,9 +174,9 @@ ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$ap #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." +#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." -ynh_systemd_action --service_name=nginx --action=reload +#REMOVEME? ynh_systemd_action --service_name=nginx --action=reload #================================================= # END OF SCRIPT From e7d9c05a5c53a7c11a2b9e99f38cf271ab455b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:20:43 +0200 Subject: [PATCH 02/17] v2 --- check_process | 24 ----------- conf/nginx.conf | 4 +- conf/systemd.service | 36 +++++++++++++++- doc/DESCRIPTION.md | 2 +- doc/DISCLAIMER.md | 0 manifest.json | 58 -------------------------- manifest.toml | 25 ++++++------ scripts/backup | 20 --------- scripts/change_url | 88 ---------------------------------------- scripts/install | 97 +------------------------------------------- scripts/remove | 66 ------------------------------ scripts/restore | 70 ++------------------------------ scripts/upgrade | 94 ++++-------------------------------------- tests.toml | 7 ++++ 14 files changed, 69 insertions(+), 522 deletions(-) delete mode 100644 check_process delete mode 100644 doc/DISCLAIMER.md delete mode 100644 manifest.json create mode 100644 tests.toml diff --git a/check_process b/check_process deleted file mode 100644 index 8e251ee..0000000 --- a/check_process +++ /dev/null @@ -1,24 +0,0 @@ -;; Test complet - ; Manifest - domain="domain.tld" - path="/path" - is_public=1 - admin="john" - password="1Strong-Password" - ; Checks - pkg_linter=1 - setup_sub_dir=1 - setup_root=1 - setup_nourl=0 - setup_private=1 - setup_public=1 - upgrade=1 - # 3.1.12~ynh1 - upgrade=1 from_commit=5b84e38190212d2f557c4d65d88f376e93e7d242 - backup_restore=1 - multi_instance=1 - port_already_use=0 - change_url=1 -;;; Options -Email= -Notification=none diff --git a/conf/nginx.conf b/conf/nginx.conf index 5cc775c..a1da276 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,15 +1,15 @@ #sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; location __PATH__/ { + + proxy_pass http://127.0.0.1:__PORT__/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - proxy_pass http://localhost:__PORT__/; proxy_redirect off; # Also note this proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; # Include SSOWAT user panel. diff --git a/conf/systemd.service b/conf/systemd.service index a213e83..d10e09e 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -1,5 +1,5 @@ [Unit] -Description=OS.js is a web-desktop written in Nodejs and javascript. +Description=OS.js: web-desktop. After=network.target [Service] @@ -12,5 +12,39 @@ ExecStart=__YNH_NPM__ run serve StandardOutput=append:/var/log/__APP__/__APP__.log Restart=always +# Sandboxing options to harden security +# Depending on specificities of your service/app, you may need to tweak these +# .. but this should be a good baseline +# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes +DevicePolicy=closed +ProtectClock=yes +ProtectHostname=yes +ProtectProc=invisible +ProtectSystem=full +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +LockPersonality=yes +SystemCallArchitectures=native +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged + +# Denying access to capabilities that should not be relevant for webapps +# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html +CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD +CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE +CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT +CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK +CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM +CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG +CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE +CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW +CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG + [Install] WantedBy=multi-user.target diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md index 531bffb..1559233 100644 --- a/doc/DESCRIPTION.md +++ b/doc/DESCRIPTION.md @@ -1 +1 @@ -[OS.js](https://www.os-js.org/) is an [open-source](https://raw.githubusercontent.com/os-js/OS.js/master/LICENSE) web desktop platform with a window manager, application APIs, GUI toolkit, filesystem abstractions and much more. +OS.js is an open-source web desktop platform with a window manager, application APIs, GUI toolkit, filesystem abstractions and much more. diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md deleted file mode 100644 index e69de29..0000000 diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 601f2ea..0000000 --- a/manifest.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "OSjs", - "id": "osjs", - "packaging_format": 1, - "description": { - "en": "Desktop you have accesss through your browser", - "fr": "Bureau accessible à travers votre navigateur" - }, - "version": "3.1.12~ynh2", - "url": "https://www.os-js.org/", - "upstream": { - "license": "MIT", - "website": "https://www.os-js.org", - "demo": "https://demo.os-js.org/", - "admindoc": "https://manual.os-js.org/", - "code": "https://github.com/os-js/OS.js" - }, - "license": "MIT", - "maintainer": { - "name": "frju365", - "email": "win10@tutanota.com", - "url": "https://github.com/Yunohost-Apps/osjs_ynh" - }, - "requirements": { - "yunohost": ">= 4.3.0" - }, - "multi_instance": true, - "services": [ - "nginx" - ], - "arguments": { - "install": [ - { - "name": "domain", - "type": "domain" - }, - { - "name": "path", - "type": "path", - "example": "/osjs", - "default": "/osjs" - }, - { - "name": "is_public", - "type": "boolean", - "default": true - }, - { - "name": "admin", - "type": "user" - }, - { - "name": "password", - "type": "password" - } - ] - } -} diff --git a/manifest.toml b/manifest.toml index f8a454d..f21df0f 100644 --- a/manifest.toml +++ b/manifest.toml @@ -15,26 +15,22 @@ website = "https://www.os-js.org" demo = "https://demo.os-js.org/" admindoc = "https://manual.os-js.org/" code = "https://github.com/os-js/OS.js" -cpe = "???" # FIXME: optional but recommended if relevant, this is meant to contain the Common Platform Enumeration, which is sort of a standard id for applications defined by the NIST. In particular, Yunohost may use this is in the future to easily track CVE (=security reports) related to apps. The CPE may be obtained by searching here: https://nvd.nist.gov/products/cpe/search. For example, for Nextcloud, the CPE is 'cpe:2.3:a:nextcloud:nextcloud' (no need to include the version number) -fund = "???" # FIXME: optional but recommended (or remove if irrelevant / not applicable). This is meant to be an URL where people can financially support this app, especially when its development is based on volunteers and/or financed by its community. YunoHost may later advertise it in the webadmin. [integration] -yunohost = ">= 4.3.0" -architectures = "all" # FIXME: can be replaced by a list of supported archs using the dpkg --print-architecture nomenclature (amd64/i386/armhf/arm64), for example: ["amd64", "i386"] +yunohost = ">= 11.2" +architectures = "all" multi_instance = true -ldap = "?" # FIXME: replace with true, false, or "not_relevant". Not to confuse with the "sso" key : the "ldap" key corresponds to wether or not a user *can* login on the app using its YunoHost credentials. -sso = "?" # FIXME: replace with true, false, or "not_relevant". Not to confuse with the "ldap" key : the "sso" key corresponds to wether or not a user is *automatically logged-in* on the app when logged-in on the YunoHost portal. -disk = "50M" # FIXME: replace with an **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ... -ram.build = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... -ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... +ldap = false +sso = false +disk = "50M" +ram.build = "50M" +ram.runtime = "50M" [install] [install.domain] - # this is a generic question - ask strings are automatically handled by Yunohost's core type = "domain" [install.path] - # this is a generic question - ask strings are automatically handled by Yunohost's core type = "path" default = "/osjs" @@ -43,11 +39,9 @@ ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requiremen default = "visitors" [install.admin] - # this is a generic question - ask strings are automatically handled by Yunohost's core type = "user" [install.password] - # this is a generic question - ask strings are automatically handled by Yunohost's core type = "password" [resources] @@ -60,8 +54,13 @@ ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requiremen [resources.install_dir] + [resources.ports] + [resources.permissions] main.url = "/" + [resources.apt] + packages = "mariadb-server, libpam0g-dev" + [resources.database] type = "mysql" diff --git a/scripts/backup b/scripts/backup index 9ecf093..737146f 100644 --- a/scripts/backup +++ b/scripts/backup @@ -10,26 +10,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -#REMOVEME? ynh_clean_setup () { - true -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_print_info --message="Loading installation settings..." - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) - #================================================= # DECLARE DATA AND CONF FILES TO BACKUP #================================================= diff --git a/scripts/change_url b/scripts/change_url index cd43466..208ff24 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -9,63 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# RETRIEVE ARGUMENTS -#================================================= - -#REMOVEME? old_domain=$YNH_APP_OLD_DOMAIN -#REMOVEME? old_path=$YNH_APP_OLD_PATH - -#REMOVEME? new_domain=$YNH_APP_NEW_DOMAIN -#REMOVEME? new_path=$YNH_APP_NEW_PATH - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." - -#REMOVEME? # Needed for helper "ynh_add_nginx_config" -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) - -# Add settings here as needed by your application -#REMOVEME? port=$(ynh_app_setting_get --app=$app --key=port) - -#================================================= -# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP -#================================================= -#REMOVEME? ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." - -# Backup the current version of the app -#REMOVEME? ynh_backup_before_upgrade -#REMOVEME? ynh_clean_setup () { - #REMOVEME? ynh_clean_check_starting - # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. -#REMOVEME? ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" - - # Restore it if the upgrade fails -#REMOVEME? ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# CHECK WHICH PARTS SHOULD BE CHANGED -#================================================= - -#REMOVEME? change_domain=0 -#REMOVEME? if [ "$old_domain" != "$new_domain" ] -then - #REMOVEME? change_domain=1 -fi - -#REMOVEME? change_path=0 -#REMOVEME? if [ "$old_path" != "$new_path" ] -then - #REMOVEME? change_path=1 -fi - #================================================= # STANDARD MODIFICATIONS #================================================= @@ -82,30 +25,6 @@ ynh_script_progression --message="Updating NGINX web server configuration..." ynh_change_url_nginx_config -#REMOVEME? nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf - -# Change the path in the NGINX config file -if [ $change_path -eq 1 ] -then - # Make a backup of the original NGINX config file if modified -#REMOVEME? ynh_backup_if_checksum_is_different --file="$nginx_conf_path" - # Set global variables for NGINX helper -#REMOVEME? domain="$old_domain" -#REMOVEME? path="$new_path" - # Create a dedicated NGINX config -#REMOVEME? ynh_add_nginx_config -fi - -# Change the domain for NGINX -if [ $change_domain -eq 1 ] -then - # Delete file checksum for the old conf file location -#REMOVEME? ynh_delete_file_checksum --file="$nginx_conf_path" -#REMOVEME? mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf - # Store file checksum for the new config file location -#REMOVEME? ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" -fi - #================================================= # GENERIC FINALISATION #================================================= @@ -116,13 +35,6 @@ ynh_script_progression --message="Starting a systemd service..." # Start a systemd service ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" -#================================================= -# RELOAD NGINX -#================================================= -#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." - -#REMOVEME? #REMOVEME? ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/install b/scripts/install index 0664b21..c6181d5 100644 --- a/scripts/install +++ b/scripts/install @@ -9,96 +9,21 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -#REMOVEME? ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# RETRIEVE ARGUMENTS FROM THE MANIFEST -#================================================= - -#REMOVEME? domain=$YNH_APP_ARG_DOMAIN -#REMOVEME? path=$YNH_APP_ARG_PATH -#REMOVEME? is_public=$YNH_APP_ARG_IS_PUBLIC -#REMOVEME? admin=$YNH_APP_ARG_ADMIN -#REMOVEME? password=$YNH_APP_ARG_PASSWORD - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#================================================= -# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS -#================================================= -#REMOVEME? ynh_script_progression --message="Validating installation parameters..." - -#REMOVEME? install_dir=/var/www/$app -#REMOVEME? test ! -e "$install_dir" || ynh_die --message="This path already contains a folder" - -# Register (book) web path -#REMOVEME? ynh_webpath_register --app=$app --domain=$domain --path=$path - -#================================================= -# STORE SETTINGS FROM MANIFEST -#================================================= -#REMOVEME? ynh_script_progression --message="Storing installation settings..." - -#REMOVEME? ynh_app_setting_set --app=$app --key=domain --value=$domain -#REMOVEME? ynh_app_setting_set --app=$app --key=path --value=$path -#REMOVEME? ynh_app_setting_set --app=$app --key=admin --value=$admin -#REMOVEME? ynh_app_setting_set --app=$app --key=password --value=$password - -#================================================= -# STANDARD MODIFICATIONS -#================================================= -# FIND AND OPEN A PORT -#================================================= -#REMOVEME? ynh_script_progression --message="Finding an available port..." - -# Find an available port -#REMOVEME? port=$(ynh_find_port --port=8095) -#REMOVEME? ynh_app_setting_set --app=$app --key=port --value=$port - #================================================= # INSTALL DEPENDENCIES #================================================= -#REMOVEME? ynh_script_progression --message="Installing dependencies..." +ynh_script_progression --message="Installing dependencies..." -#REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version -#================================================= -# CREATE DEDICATED USER -#================================================= -#REMOVEME? ynh_script_progression --message="Configuring system user..." - -# Create a system user -#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" - -#================================================= -# CREATE A MYSQL DATABASE -#================================================= -#REMOVEME? ynh_script_progression --message="Creating a MySQL database..." - -#REMOVEME? db_name=$(ynh_sanitize_dbid --db_name=$app) -#REMOVEME? db_user=$db_name -#REMOVEME? ynh_app_setting_set --app=$app --key=db_name --value=$db_name -#REMOVEME? ynh_mysql_setup_db --db_user=$db_user --db_name=$db_name - #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= ynh_script_progression --message="Setting up source files..." -#REMOVEME? ynh_app_setting_set --app=$app --key=install_dir --value=$install_dir # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$install_dir" -chmod 750 "$install_dir" chmod -R o-rwx "$install_dir" chown -R $app:$app "$install_dir" @@ -179,26 +104,6 @@ ynh_script_progression --message="Starting a systemd service..." # Start a systemd service ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" -#================================================= -# SETUP SSOWAT -#================================================= -#REMOVEME? ynh_script_progression --message="Configuring permissions..." - -# Make app public if necessary -#REMOVEME? if [ $is_public -eq 1 ] -then - # Everyone can access the app. - # The "main" permission is automatically created before the install script. -#REMOVEME? ynh_permission_update --permission="main" --add="visitors" -fi - -#================================================= -# RELOAD NGINX -#================================================= -#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." - -#REMOVEME? ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/remove b/scripts/remove index ab3f904..f0f5cad 100644 --- a/scripts/remove +++ b/scripts/remove @@ -9,18 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) -#REMOVEME? db_name=$(ynh_app_setting_get --app=$app --key=db_name) -#REMOVEME? db_user=$db_name -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) - #================================================= # STANDARD REMOVE #================================================= @@ -34,75 +22,21 @@ then yunohost service remove $app fi -#================================================= -# STOP AND REMOVE SERVICE -#================================================= -ynh_script_progression --message="Stopping and removing the systemd service..." - # Remove the dedicated systemd config ynh_remove_systemd_config -#================================================= -# REMOVE LOGROTATE CONFIGURATION -#================================================= -ynh_script_progression --message="Removing logrotate configuration..." - # Remove the app-specific logrotate config ynh_remove_logrotate -#================================================= -# REMOVE THE MYSQL DATABASE -#================================================= -#REMOVEME? ynh_script_progression --message="Removing the MySQL database..." - -# Remove a database if it exists, along with the associated user -#REMOVEME? ynh_mysql_remove_db --db_user=$db_user --db_name=$db_name - -#================================================= -# REMOVE APP MAIN DIR -#================================================= -#REMOVEME? ynh_script_progression --message="Removing app main directory..." - -# Remove the app directory securely -#REMOVEME? ynh_secure_remove --file="$install_dir" - -#================================================= -# REMOVE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." - # Remove the dedicated NGINX config ynh_remove_nginx_config -#================================================= -# REMOVE DEPENDENCIES -#================================================= -#REMOVEME? ynh_script_progression --message="Removing dependencies..." - # Remove metapackage and its dependencies ynh_remove_nodejs -#REMOVEME? ynh_remove_app_dependencies - -#================================================= -# SPECIFIC REMOVE -#================================================= -# REMOVE VARIOUS FILES -#================================================= -ynh_script_progression --message="Removing various files..." # Remove the log files ynh_secure_remove --file="/var/log/$app" -#================================================= -# GENERIC FINALIZATION -#================================================= -# REMOVE DEDICATED USER -#================================================= -#REMOVEME? ynh_script_progression --message="Removing the dedicated system user..." - -# Delete a system user -#REMOVEME? ynh_system_user_delete --username=$app - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/restore b/scripts/restore index b50c442..b22e0ea 100644 --- a/scripts/restore +++ b/scripts/restore @@ -10,52 +10,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -#REMOVEME? ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) -#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) - -#================================================= -# CHECK IF THE APP CAN BE RESTORED -#================================================= -#REMOVEME? ynh_script_progression --message="Validating restoration parameters..." - -#REMOVEME? test ! -d $install_dir \ - || ynh_die --message="There is already a directory: $install_dir " - -#================================================= -# STANDARD RESTORATION STEPS -#================================================= -# RESTORE THE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the NGINX web server configuration..." - -ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" - -#================================================= -# RECREATE THE DEDICATED USER -#================================================= -#REMOVEME? ynh_script_progression --message="Recreating the dedicated system user..." - -# Create the dedicated user (if not existing) -#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" - #================================================= # RESTORE THE APP MAIN DIR #================================================= @@ -63,7 +17,6 @@ ynh_script_progression --message="Restoring the app main directory..." ynh_restore_file --origin_path="$install_dir" -chmod 750 "$install_dir" chmod -R o-rwx "$install_dir" chown -R $app:$app "$install_dir" @@ -72,10 +25,8 @@ chown -R $app:$app "$install_dir" #================================================= # REINSTALL DEPENDENCIES #================================================= -#REMOVEME? ynh_script_progression --message="Reinstalling dependencies..." +ynh_script_progression --message="Reinstalling dependencies..." -# Define and install dependencies -#REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= @@ -83,23 +34,15 @@ ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= ynh_script_progression --message="Restoring the systemd configuration..." +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" + ynh_restore_file --origin_path="/etc/systemd/system/$app.service" systemctl enable $app.service --quiet -#================================================= -# RESTORE THE LOGROTATE CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the logrotate configuration..." - mkdir -p "/var/log/$app" chown $app:$app "/var/log/$app" ynh_restore_file --origin_path="/etc/logrotate.d/$app" -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." - yunohost service add $app --log="/var/log/$app/$app.log" #================================================= @@ -109,13 +52,6 @@ ynh_script_progression --message="Starting a systemd service..." ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" -#================================================= -# GENERIC FINALIZATION -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." - ynh_systemd_action --service_name=nginx --action=reload #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 5bdb226..1dbeb65 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -9,40 +9,12 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -#REMOVEME? ynh_script_progression --message="Loading installation settings..." - -#REMOVEME? app=$YNH_APP_INSTANCE_NAME - -#REMOVEME? domain=$(ynh_app_setting_get --app=$app --key=domain) -#REMOVEME? path=$(ynh_app_setting_get --app=$app --key=path) -#REMOVEME? port=$(ynh_app_setting_get --app=$app --key=port) -#REMOVEME? #REMOVEME? install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) - #================================================= # CHECK VERSION #================================================= -ynh_script_progression --message="Checking version..." upgrade_type=$(ynh_check_app_version_changed) -#================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP -#================================================= -#REMOVEME? ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." - -# Backup the current version of the app -#REMOVEME? ynh_backup_before_upgrade -#REMOVEME? ynh_clean_setup () { - ynh_clean_check_starting - # Restore it if the upgrade fails -#REMOVEME? ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -#REMOVEME? ynh_abort_if_errors - #================================================= # STANDARD UPGRADE STEPS #================================================= @@ -52,26 +24,6 @@ ynh_script_progression --message="Stopping a systemd service..." ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log" -#================================================= -# ENSURE DOWNWARD COMPATIBILITY -#================================================= -ynh_script_progression --message="Ensuring downward compatibility..." - -# Cleaning legacy permissions -#REMOVEME? if ynh_legacy_permissions_exists; then -#REMOVEME? ynh_legacy_permissions_delete_all - - ynh_app_setting_delete --app=$app --key=is_public -fi - -#================================================= -# CREATE DEDICATED USER -#================================================= -#REMOVEME? ynh_script_progression --message="Making sure dedicated system user exists..." - -# Create a dedicated user (if not existing) -#REMOVEME? ynh_system_user_create --username=$app --home_dir="$install_dir" - #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= @@ -84,7 +36,6 @@ then ynh_setup_source --dest_dir="$install_dir" --keep="src/client/config.js src/server/index.js" fi -chmod 750 "$install_dir" chmod -R o-rwx "$install_dir" chown -R $app:$app "$install_dir" @@ -96,14 +47,17 @@ ynh_script_progression --message="Upgrading NGINX web server configuration..." # Create a dedicated NGINX config ynh_add_nginx_config -#================================================= -# UPGRADE DEPENDENCIES -#================================================= -#REMOVEME? ynh_script_progression --message="Upgrading dependencies..." - #REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version +# Create a dedicated systemd config +ynh_add_systemd_config + +# Use logrotate to manage app-specific logfile(s) +ynh_use_logrotate --non-append + +yunohost service add $app --log="/var/log/$app/$app.log" + #================================================= # SPECIFIC UPGRADE #================================================= @@ -138,31 +92,6 @@ ynh_replace_string --match_string="8000" --replace_string="$port" --target_file= chown -R $app:$app "$install_dir" -#================================================= -# SETUP SYSTEMD -#================================================= -ynh_script_progression --message="Upgrading systemd configuration..." - -# Create a dedicated systemd config -ynh_add_systemd_config - -#================================================= -# GENERIC FINALIZATION -#================================================= -# SETUP LOGROTATE -#================================================= -ynh_script_progression --message="Upgrading logrotate configuration..." - -# Use logrotate to manage app-specific logfile(s) -ynh_use_logrotate --non-append - -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." - -yunohost service add $app --log="/var/log/$app/$app.log" - #================================================= # START SYSTEMD SERVICE #================================================= @@ -171,13 +100,6 @@ ynh_script_progression --message="Starting a systemd service..." # Start a systemd service ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" -#================================================= -# RELOAD NGINX -#================================================= -#REMOVEME? ynh_script_progression --message="Reloading NGINX web server..." - -#REMOVEME? ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..d64ef3c --- /dev/null +++ b/tests.toml @@ -0,0 +1,7 @@ +test_format = 1.0 + +[default] + + # ------------ + # Tests to run + # ------------ From 72fdff0983c33a4913226fe2b634add612b2e1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:21:00 +0200 Subject: [PATCH 03/17] Create screenshot.png --- doc/screenshots/screenshot.png | Bin 0 -> 139204 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/screenshots/screenshot.png diff --git a/doc/screenshots/screenshot.png b/doc/screenshots/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc0f6938058d63392135a4620ac8529aa203684 GIT binary patch literal 139204 zcmV)QK(xP!P)Few3b2gG579&wbPt?lVc0ZD>qqTNAl3^`~W-*S>#MWvv zl5RATTPuFTx5+v?hCVeu*UjH)VXJmgl5|3uc0!m;Nt#MXnSDi>c|@6ZMUrSTk=5h& zu%x!x+1c68;M~#Uc0ra-PEK}7l36N!R!mXB!ok$k({N3TR3~*;DS0+7H-AT&KsiCP zv$H56Dr`%J+0WYe`TF(s_0-DLa5axWK86+x9cf5_OhHO;JBws5fpa^LX)=ayHH&OB zk8CrFa6^h`F@wFc!D%>yYDa|L)Zc75hIMRpg?od#u((nwa7H^ssGhH9U1xuPe>yWd z$;!!OT%u_}fvc*jd~<%sy~vA;i&;@y-QC?pAzyMxjbm9|aX*wdHgst+i_gW+Y(R$S z=;yGouHxe2T2EEW!OMz*i)J@~rJ1WpK}Sg=WAX9uZ)I?BaBoFGfSHe%mzS1HBx$Li zs7gX{P$q0;WM#>{(RXrohkc4_Jc?;uUT!{*Pe^xIPIrceg-1bdk&=-|LWFf_XuG_+ zd3tzXQ&)m@i&|M=jDnTU&&^*~lwmG@Nk)>Dik!o^!fI=2K|E)jlb*AuyPu$+o|C3+ zU}9BOR8dHBx2?XWr=^pKk-4VGq?)64Yg;`!bDY9K;q3WmU4GELdS5nqs+eqbYJI@1 za+{o*S7vr`WMo(>bhf2%$$K`Cu0ySty=G}i?DPADoJCMAXJK4Ul($1uN@`$Mc8Pjn zv~oOpi$y4-?cnx2KRk#whIqrZDtM9H;yi>5?m zn6+lD%xsg-VUVcagf)&^IA^rfpJzdTJ6fnUXf9NKZAd4v)beH~9=*V+&h+qlSdsSV z!5A}MreP|gwbnR<%JIsN9vXlkA4b^0uKv(gFb-*rf4!}t100JC;Nkl<{90IVGdFaQ7m zV1pEe5DG9=|8$@V8)z~W)JFgSP;aDq#9_Vz9xyPnsOA3xQlq4#SOz7=SotK$?uYyX z;2g4+M>%-$5VvuMt)#OS&Esc65q+dWJkB9QrYTp|V8}24V6({ZWWkC@BI%w8srm?4 z?bc;N(cxGh(PDz72`>=<;2@F(`Ao^+&lA;m5=FI}$4`ZveZ;k#>!?zgnQ}(`0RROc z>vcwlUW=t&M8&JY*jLA$M8qNm^bx6cNng%lxzL0b z?^D-Dq(ltzr?bJHWP&g=4S>5y7gTW_p|W2pi78pO5pKd0F@?#LTWaoDb=DlN<^$`~ zv@9=&V{9X|RJjiTZY3M@NoD@>9Q}1Bo6M>)qV=6U=9=VES?6Sr9QJ{QLo?81D~jeK zhL^%5NTcu7UkSg}`5)9JJ zK@*ol{tF$eXbf=;Ca4qu4#Fm33lF*dG(&Tpmygkx=SZEX$~cxo#aSgnJlzo2>-T%w zQQJQhV!PALzV~EzGMVg#^jmsmEnj_kR(^9ulq}@?c-nsWuq|Aep zXg;44MTrGPy}rD>W|>@;_1VhTkod?rnjFVWMwx!f_|CKO!xx?IXhdx3u0LqE+l@ve z_}m-3QH)<*i22zpihhi;zTbTQAX4U!Vq?lp3fgf!w4Cze%eUb3*A3gF%OO77%Apns ze|yOfH+9pCEnmd=Eu~x4D+v)6L#++9L;`O9M(h7eos)tfnZkV^&Z+=Q> z`dQvB1?}2a%!VoRV>DZ7XasxrR}t$KkS{~Yx7hX$J?uNcISom50G9A+Fpe0 zKr4*?2d#{yg@v>-yyyyr&=z(RJ4B9y4q~r57!-G*3{h8c=s<=KJyu{F(^1_kh#c1PRfi4QWYA zGd<)?zBW>5!JuIm!hh_2atd73dHYM>D0$rCfPc;P&;ccH$kf=^Ig3%w$6gxc)DVoWRDUz`jV=}W5$>lPcP$-lk zYzMiNp9z4kkCg(2nds)wj=o+lKMN5IfT?T%29P@IsQVE8AzeMxDeUO3u-a<3Tdi?! zlqCgOm8{CL%ozYSAmj=LCXNm52pxpm1Q zZLeIK8!2rf7gq!xxdS*WI67|D+_R3}DXHwdjPK8fM^jJ#CH-?rVD^wC5XzTI`DkIy z7J(a4|5}si3R||D4T}f`ZMC*0fIqYV_#EN&^K~UqQ(Dizd_Fk0)BuK`_m5+be~C<; zJ?@Xcjs~B^{J{UKassph)0P!Ty`2`N@Mq^=NnHwY6>6{`T?#d2DZBq1#e#Z(x{LX|Yp zP*8~EYPm=Nyw#>2hfuSMaG8*5(ALv-hz?-jZ)cBuhR47ftP>`EbP;TP`nFF%viy4fhu+tdr~iaznaR+1 zIUm~eF9bBB&KYV_Kq3$U@$zPt7-Z$;xb>Xeu9RN_jcMT*mQT_b| zQ0(kjw|n$+(>!5pV;1ntN_fNiY<(kJ~6H2DZN zIC(__Fr10A?|PrWsP^^EBhZOftJQ9a0N|E7ZO{hDk`TgZie%HGGL@R*L{)ddSYAF*B79!2& z61)T(fK@Ai*#xi+zyq$`{_q7w`SQyT+vn#;mMe}!zpmKvkifrw{{Yo!qK!tw$ z{-M5hM+4Ad3>L3 zR&#KM;7TO2ni~N)pUb^&0Qe*Z4*ZvX5BQ1DS=WCG4S@C9s$Vq#!_tp4FXk_Q{r(c^ z8(pA5cjq@))Q7IY*i#T+!5eIK6@W_$4ZvTQe(so=V@l!4y`9`@gTz)FKH<&4O*x4u z^F$4&f}&KDC`m-I%Bx_E6XFQK6hA;`IhD{DD@jG!0Pu>Ba>)u{fLIta5CY#zH2%JH z-Z~;<01gTjMG@pM08L3kH8{GDq^Kxba#)n4q#kEfLXXpqR#lRcBvL3s8)$X(GK1@B zAsZA_grRPtf_TOO1Ax&X{ zR7-0%0B4a(bcLA&@V;IkRm_sX`T6r_QaCF;?{*N&r8$1A0L+R8V3XlJERje{UO=S%X>P%Cr|$_Q83-{eCQ(z;D8?#Aaub}$SI8(uzd|1fSb`~O$aPjY74;M zjiriZo7wOb8Vyb}0G?2S+vn>a?jIk2dA$GObL;J~L!BQS#{5J5q~D7K5bHwb^rHLY z*6YTkBNM=n_8(lGjt@aU9CZ6%JqC<610+`zKFLVbyfS=zYmo@;OoW8gEk!6B(zX#*kKSVAmhAE+sAD~}hF#gBh zHH<=2(+oE;4Hlnb?rj3s3wlj|g9T$AQ5vWc4hwU@vapy&^NR+6r@-0Hn?uliN<}b4 z?FwMbV>$#~#;_X}C|s5_-+75@Zydn5s-n3huT&CQ4h;dURxvJTEdVwup~rEWsa16V z3!FB1okV&W)IugI@}*=0z`W?o%Gd%wM+YoqaWciHVZ*Qi;3TdlF)zRgDQW-)zl%j3 zz}eIsQbf3dxrw;gn+fg7(|=gAf9rf`(11E%jX(h4r_s3hyVRAyeA> z;qi;B_zwET3SgQ$MV4v9Kw~|{iVXRf&W!;ulLKzREG%hlO@g^t+YP3>+z4$)>h$s@ zli$uSyE))k|G4z24q)_kELMODe_hJGfA)O=Osx&TXW!GCnZ6pI5?$KuKR}<9a=W?% zJ}l+H0Uv5NJRw9W-0dI6AB{h-wGxb*Nu84D4k}5XvjR2-`6)6nxOoOc^*$Mnuqx{|Lz$`3bJO`YB@G{O4Q4}jd1HfE0 zl@fUifRSDaBQB9zfsC{mq*$Cs27tM$0PC|BusJ(m>Z3V@h=O1M z7)Y<6al|8TRsOAt^0R?Xh+o-iVD zO~m%^os(kmfTmbX;>HWOG+E0`D*)gP0I*^Ma1gPB(-go|YzgS;)^=QyY9;^nhwbs2 z9c%%4<8eS^989KhGw`7Mko&rSdD8zzbGGIXGzD$%q_kt^fMF6AwT<+{kdNv57yvU} zs4$Z$#0&76*;rsL@J3y#)#xOwXkIETquXfkj?Pueqj!5uF|-CIKA*DR(lJmtJqJAe zo{s_jJNg1b2OJ8bAag4-P}fu|i!9=JX<>CE z1LvSdno5}IW4AK`G^~)%7eYdG72Tn_Q0=zEUBc}SGv)avi=`9z>`dn`{+nj9&f$5{ z7K6<)MC1=T;DA3P9cFV*SVSlxWG6DqC5|n#di6yijc{4yELArhuqqn>#(%>}!ET}0 zA?Ch56A9nv#(BDbnsr$E(lL>z%p;b| z9}=a)><@NI)iE!tFtZ8n2m}Nk*unm>b+{?eoohEYo0F$Uk~yZBY2qz^G1w)Vjqy^T zo;>}_W#j1VpQo=W=kJ2%w<9Ah^9*S@hdNG$rzQ+eE43(+xh7Avry1T8*@7NCFA2{XY9b*o|ixS!mAcrY)Vq-9hH! z>RiLIoi`n-9%ka*_r(Tcm)bL@gSpt?(j#%0sV=@f*4=Z!jtkbB-FNeQ|61hf|D@Tw zyC>Kr+R+hWHEt5z>SU&-L229IG^lBaDFG$criXt?IIx$gIP>ga=JAA+qI^tO>;@z3 zYGK?0F#7xC>_0JE1vbdd|FZOA<&K@3E9hK@TbRjzV2lAu*-IvOsA5;zI-j`vHWS)e z*qeyv>EEo`zkf2c31scVg|n_}-7Cr*h}j?WXnqS=**(p=9^2=Zdvm`t(>+_~4nTLZ zVTR$%z_2_1C-Va{&2x|=+*!x&U?8#k?r&qljUzdc%`9eDGUvc1>^=hh*RBJw<8Rx0 z-j8RLJ^f2H%YcS)gR_5XKJ@JX&K{cO^zG^Eyn5Cxp7pz|u{TeW8R$bdpb=Za!QzBj zyhYcH9bOLQuArsD&YW>I@$9C|4~qx)HnY`W7oC~ql!JC318`f>Qiy)`yVTt07CG!FXEJ8)7yM`@NCNZW2mKf`uL5w%L9}Y{4LDyiD`UN1 zTW|nNe3{i7f;PU+G zp=Q_Ot7lKPx|xH{bg%&qg~}Tw|2dc&_M#Ju^D}oA73S%EL_RR&FEzgV%Jb?`x>I!i zJao*Iw#JDNBhZbbgVq1it#z3zxUcRrzrqG4^r(id4RIQUM*NY!O59P2T*L9wKHm!U z-T~7>Z?baou5B(SR%$5EKC{1PJJIJq3B36GMuK8u!3H064W+pfc3}Z zyPADN?n_*G;kAgGZ{I3GC%Gi+v zc-3Rx$ccaJR}p^4ELYDLYpv(s;CX0p1w)lLGg@QrsPf8S%r#0qW!IJ;L|H6 zv0B|Reh>N}KnzF^#tr@#FUxI?4^#W1UA^Y}fF)ri2IrSvD!>~B>~-hKl+l#>)&Elb zi3aGTfeq)=q82o&s$vzn-GDJ~x52&T#n@`~%la6m*|B;wCLINw9Q6|W4KB^qTJth5 zMe!VUu)sV8o%b^HT>&XUfG$)40+LE(;;oa&JjyH3{Yf>xyBMj$W-wt=y3!eew(iYr zfysHRS_8RS{bAqybsGhOFplK4bcJ<$MXGeJub`y6lWi6BODaTKqqfcZb$H|b4Hf`#U{RIClstjJ6mvWVt^2=ZD zoljbodnnWBuM{xa8KsdR;cnpI?#T>7#ca*UVD3{8Gls!uMcDqB^ia+pUN z`>!0sKL{TxE`#b@T|yuk-+^JhR*SXJ&C}+VY@r}Y(^Pw~GLAAUYmB#`_K8~THS@Dn zYFX?o(omm6BgYKuwp?K_FkcyDp{s1c=opLZy+Scd$uD^^+12vtG0@87P9ADZ)k*HK z776c3A&51oT2vs$H^wHZqKu^}o2E?54me^PZvkQqDfkQo zVG1iXxrXc)8ZqLCu9(9C3NS5-GdRpp&gWuE0c|msw&%A({!n9DV@%tM!WB*QFaS-`ao96+x!CV_dAwqgb|nZ0Fi${N9lkE)4Iua z2+SB5VA-b>&o#x`_x;pQa@W6)9prch5b$puI=(r)zX2>&{N4+neKW4y5VT*?_c+0y zhUR-WLcJKBI0M@loE9^ic{YbK12=z@@^84@z*C5UL^}=3E-ouL4{z~t+{YCADWzew zK>zC;daZz!L%6-)mhhOA&`EswJa9_yG2+>6Oc7jM1eSOXW3|KMAJc(gV2i-`GPXMv zYb>m1*(}zYx8%$tV~&_w&`X!TTvC(LfTMHl-Q#g7i(N5Yh+)9;2pmOXj!!Vc0@5<1 zC#CS$U2=rk!;NR40#**el8?dTZ;6K~T#rC76ckk8at{Hp?1n6lq&E_c4J-V~H!5M!9F3RobP9p-Y}&I{VR zD-BG3CDCH0NKXPMq}!OrEu{?@SOu&|BdXL>`5Us_u_>uT-|o_I1uPKD409DOd%DuO zj&BWIt$=F+1|(ogF{eQ^Q(r>`tgxk~R8lV`Bw4>}+_FZ-C`7x} zf^N*f{i_02SVJA<=-1ufKuI4i{J0);_W>0!U;V!F7Bm_93D~xv1q*ni1FZs9c=O-7 zmrR`L8Bc;F{Igon-2>S*u;qZ+f@=%fI6gm)bZ84YtRjCQ)}$4%A{er0R@wSO%4Oo8 zZ9!v-|54z7?47Z0>>vU0J*x>DCCEbsPuS0K0%4>lD?hW^i147YyRyo<><08kvH_pYt+CQv{vFTCHHi z5j3ZP!3Nj`?3m}mtk}L;8A0>k3VbazDhG!)xb>UHwxFj8I1Y}WId5eE8(OV7Y)D1}d&SUH*%k(0C9B;f+XYsqr{CsCkNiJ6q6lodywywxEdx z3~&KIn?qFu6we;7K(_rYXu2NO9a8&eO~FCS1N@shTF~={V#OH|G@pRqT)+&+V)}->ks&v> zp!3F4!|JgbM-Uw}EaBfYV-~cO^v%SX5j4?6EJXtC0)93>9_6vV6D}j4f6m*GU!dgC z?c_`|jiXCzB)j0CUSt*uVj@ zkba?mZ*D;kFmRmOg60`XsW}050Y96f-%pHNxYoO>+)0?*Gw99!A@DnUXRqTb4201p z#Y!Ngg)ZGvZm}+jv_;w!JOL#Y&vYLo&v(aWE)lYfbAvJ81Rwt{*_Ecsk!L5)3bDyh zaN*;f{QFTws)F9qz%f(MVy>io>HwSsd~DcdXUk;--iL%aDnI;-U$0)ofqWas8nekz zaN*&t{7Xcxf@VSrIC2VFMiM%@e@~huU|HDaHDG=`$*o#@_fiUaQZuZ8*P2a&gNtR} z%)g$~Y`D9i?LP}5-(6DB66&xbWuQ-b7?ObH!P4cKnV!Pk)4?G<;xjAnc+Y{ase*>R zk8-WqWEi+u;?4ByqY8Q#^!%^F2{=v)TAYA4<}{H6EEeZ+67wiLxs~VnX0G2a;(Oj1 zZweZ-4myC^L@2me;9&j@SOxv`30OoGw3+J?m`(kAdf*qZN)5L4-~H5en|Cv*ai`4K zJ>D@84p(t}dYs1x{E*w%oL)CJ@p2V3;zxmls7-=`3pYpgZ}2K;CQt%8dJ0-VAr@z# zx5_p@FJPrd@-Si}p=pEl|HbYK?v*2Gen#T;U>xj7L8IoNNlZsEaN**(`VChF?Y|jX zz(pKog?}AK9pS|56EIsh0n1EXjM9A(wIduNFV?C%|9m6*S?4i1*p-6D`%=PiZWEy3 z!oeZ^TWwVZ%@3kVo`y6}k%AenoN$8rQ&ey?wUXFJRVhlR%{%T7oC) zHySkQF;L@Irq>&q^p+nrZ4;lCFrhRw@y5hUi=i>o;NqWw$*+zSG}wL6B&9y}x_!$XFX8~d5bNdt0G}SL7O*jubRX9TwRLMQ^ziln8|iIBFGi&`PYb0!Tq) z8rXjTwzL~uz3S+TSdPM+D2>&8Z-%AM{=)U zz-=~i$+91se$xuHW|!YA%YuzqaX%HyBA=Zx@a%GEGmuiyxdBLTIbj17;QRWQ304KY z{#wcsqY4^Rz;%Rdvsb|CtPj9f{VspeZ<@?cTA|k9M2P#6`T1S!4*}aLXoy1Sd;&^v zxeZi&^8D*Nnp$EFRRz8J5L^PJpg~Ka>o_M~{|UHhua7rm?rB9?|FU=Xx^2Ti90!aJ z1sJv zPxQrA)ch+Ee+y9fa8=NtvZkQv0r>jW3DApE&<4ODUrz;J+S9kID=o2W z3%jL#`wlL1cphp^*X9iY7^k2M0JvoMm1@vNa3iBL;4g(LXrrP4rjdfCHxKN+dQ$+I zhfhKKhP@Y2lg>czOkcQwQ*o#`7={(t42brD(EXLdWg#oM$fyl@wb`Nclavk z=CZ$}DQHpz_EZFXGT{_7BqoVOf9KxH&72!n`8(D``G8!&uhIT}SMoRe;X`a(JO%y! z0yLq@SpyEYaV z`Uo7}voL#66rA(yA}Q$q61bfBm1<_ z2w=>9##_E=tD%axzyV(nFz#Ez%1!6ESlD}>Ls_w}6!iZHTw44p#t}xa8U4cFV^%?f zp`0mb0tEK7u9Zm40e`>|@MRv@&o}wo4CQa(0*BLGW`NCRTHnGSUz+zI403S9c4Dtp z(3=2UV*Ju3a6{{Y-y^LBja9}J^yyc`@|OH17Xe$-cOY#xM>wgdeRb3V3z#@GFBq7^ zIDpiAzwBG}396ea+JZRZi zUup|+tnhz2c}rbW0`T*5zz=EqV9!FrNmcFgh{I0XCOU$3W3d@7EZZ%D_Nsq4)MMoN zg&pvr;cRPhQ+x#+$NmHP^qo7rTOZh-{Jg*anXEtX_pjUAU%%O!lKb1+`=oFR+8D4( zj$e&Asti_Ro&kR|$Rn^8bO8bbObMl+_2#`ji9FCXNdWr{2*J}ov)L@IS$}6aoK(}! z^tl_2*SQo%Q8enR%l2T%#!;7bUBOYM5mzU=+o%)WFyZP;kt8+QneUfxl|GyCIfRB> z9SgT0z%N$^Kr#-HeYWkpg^|ABP3rZ@-FN%>pPsCrn5EW}wMDfGI-g2}0o2wEfl}In0ts!XOwr z2EdvjanyO1SUAJliQ=4j;Z0UJ;Bkw!0xXaVhyLuhG~fqeuiymRpod0AZ(129fOKP*)Ao6hI+ z*}??Dt2`)>s!Db^Dqx0FmocZ;AGMhieu-RGOP(0&MuSiSIG8x@pdSVDxjp9HmU{ed(vR4uBU@>EdyoW>c3uLxyVD z0U^uz-k!J_NvZ}+IL;^xf~i|e22m8&hSM%<4>W-F9>~2NwU;^Ou-{K=2EckxYN~71 z9kR|S3QR@;`^D|LY8+MWEGUb{J@yj>x=UD|;CBdi`(=L#jQZJ;`pC+VwQvd=C|n)< zYS7VS@R{-Vb(2OFG`_E7Dd?jD*hBoK2VnGn!09X<*B{fdMDSPx7=W;BIUuVFb`JfL zmxE~f#Z>@iOanORm=yFd>R14dmjE8JtUf-$mtg?2S}+*|R~@2=17%|?BLCcd|=f?gANWcXc!u0{ku zH2lu$c^0(T;8M^+;CsSvl>qh#m>l$%Kfj~>jjNwuOz%JC3gAd|C!A-Xr_(M6-Cisf z9XY=*7B9kNxmYaD+v$(4hU#Js;Pz^9I{oo!(ba2t1RN}ms1a~DTAZI;oQBiWSlG3= zXcO{lW&uHicl_Mff@>ka&!IpWm|B10nT9x6IzL~Ss@ePHN!y+*-`n+Lx9T*pv$cA5 z`)5JB$N2EOAzgI{erWvdv02$?LHF}l0bF$ox)6b(?+^jJwaJ%XZcisW_k=d_-%i4D z@Vdez+HqK|CsQmOr_Ip$Fc|S7=0k*-f{xAOO#J973;o2xnb-QF>n_7+S8mD;0k$PF zadGBGDapS_Oi>t|Ces$Zk}74=qC&=JEUuGy~U-9_i~f<&#=y+sh+w8~B2~K$k)>eJO(?mxX<0 zF9~GxzF@xcZsKP71`tggjnTn;lLPGK+qW-mGaTxxS1)xC)Z14<$IS@wJ9Yp+8Hddd zQ3Z|3GoWjJ5Jyn}KhN>ERsa(LOGKm*&F<~05M;=DlZs*06IP!HDW}S|0cs?Z%r2ie z#N=#~dv2tB*yo`$)HnGeFp@)EMuvE-q#1H?G^jA7AH0>fJyOuFj1a%q zVOJ4@ANhNqRnYx39#|E0Tw&$t3x5Xy;N;1Nmck@1nhtfv)n=f&hWDz56oQBw#o%z> zEJ*B|Y>X4GZzLpqO-wZ6T1uE%d?Oy|W1LPNvh$l@#80i#B@2y8etE)i3U1*ndz1j%y6nv6m^4O?ydKYLU` z&&SB$1a`F`_z}MqRY9+8!^~l%praMXFZ``70M6eBES!QLq+AnX5T*@8*Nm^`gvAU8 zHYRYUk2P1)h3&+QuETe{;-UtSK_R3iWH!0gx6k0T5g!v;n>hO?Q$fbL!R|fCS-rZW!IZeb6n1b4 zlWpqi`$A=QQ+H`xlVCf#>e1jV~I27Y-vAP4TMpoBxa17V;AcpL#9yymE8wyGAbgd11B54@))RH- z5xi#=w96yJ?|*Q2a0K54eTNhS&+2*>G=^{Iye8UEQqXZ*4!`hsC;+DHO7gMtXWD3F zvW}JM=`W+(RT_kB9EY!E;#CE)5kfO7hLCb$iQsV(U_n~?)dDjMi1gd;^<-m7hTta# z1*md5Na~r>(BM;`3Of3Y5x?-RoZaJ$G61Qa!4+3Q6T)H%R%2gvDd=uhj=u1>b^veh z0}dJyLK8p&u7nZ^YwFY;3eXU5Wga@gXs+%zjfX>qjk)j8YA{qL9r8F0emHQ>hrKu% z`xp*6YclBN#JZAs3Wyb~f}W3&zx5ILF6cY3KzP>Ed!Q=lgp&WUs#DOjQuKwt)dQFm zG#C&H3)t9Y&jfxI>HM->(CjLLmV-kX!yjik4tEC1-B+!%qE8Xo5V+EyWC{q1q4OAM zy$WnN0CvDkG%Qfp?;{lEs&%m{==m7&3-F3s`3Vh@ynD{Bd=<2!w9hI_K}WR+e&O$c z0IVfTY2XK!b0u2JKC48h4hYXI5;G6K*0=Y|09v4?8fS~S(ktiHJwPNfo){#g$t!=& zb<6RYc?AKl#IBIENi`KEe-KJlLC?pCUw~KGiq7YTg-)~TSu7?nEl~xHkbMXL^Bcm; zk$CtN^sF>~hXCN@K44ASB8cqnn#XmusX{j)F}pZ;LxVPxW2NOT@`Y$R5U%N*Xj>xN zW)<*qCI;y2ST%+hCad`nc!)D&C7wag8U1)mVj+}FLC?pCUw~KIip}Td$f*>+6;we3 zU$uQ`cGwiOx1a9=-w^>=?*n#glv_{^K`@ha99(ahzU;F|ScqTM)m40PsKd&YfjyAPU3c1;o3KAlNB3ibN2Lfmn!l1yKvJ zQ3MNZyn-MIqCde#L9n#-Kbnb0U&qHW#_Vj8G4E!xlaom{Zt*?7XHF*OfJGB;D>21z z!J22GNr$jXYt*=6+R`=0;6}b3xBm+5a+zd%gEbUU?O?19c!h?}AROZavCCCU^HQsa$C-NR->RU?#BVT_M+(|y!S8GUZ1(|Ux~BG#^A9)vlGTj~7lDYjO;j5xUV$|* zxq@iih0Nu-I2R@CFfN9W#UU1g#JTicNvwiaDRYEu%qywNXjNBP0K>V2dIk8)W2=dD zd4?+JMg`(`Y6#Bae&u@I%mBQyxu6|vZw3QAFg?BM6tw$0`j!gd?+#dhTlao^`}Xa} zz0cll-}~k2A8(iSEP2v9>gq>{b0C-H&mMh&M(cy;1V$`RRAzB(7=7X?$h3|Z5A2!6 zOgt^0x9aK)9K!`vaUve&MRANFM{x^CIaAP$%H(ek0Ov<=Cj7byS3!4ZNENhJPMU%N z{;dq5gHzDjJCwfU?;HXALl3_kxqJ6ZcZ1%OR1EUQUDyH(?NRsdEC+E8o0_sAz}g_u?zpa_Q{dx}K$ z`rM9`DDcs6=ik>Khj;oc$ zc%9lu#nObY*H@=JG^XmxTLm3dB7Vmpa2mlG@Jlqg(T9TF8mgd4-l=AwyPferrJ!;3 zpl?t9&I`aNe(!+yZr}O71+XYagb=xj`H?NW=D6M#gjYvGo#o0JC`OEFXHK}4%4gH- z>O}O^k{8CX8>wVU95zerZ4<}B+iH)Fs#)4CkaI#UYfd2ry<>*jHHQA-QU*Wv&rPZd z3m4Rzz}#ZSd2R++LhW?l6m+8j^aX!s2H@`wSZLY%;>+8&I|bknH^C^TX1GX%))`Mc z&KL$)QLRwO%x;|Q3b!jMrZeGU_zQacdu)mCxMgxTDvpj*&N_RN&w{3{g;+1|t*=OD zuyrkx&szn3OeyHlDv-asCPm;J_>D$Ioi!#iImfE!f_9C{1Mtu4k%D%=!*9v_O^*Tl z;D7^m1>j1)7U;l8DyQiHn${Et**thiyDo4lpdewQ96WdO4kwAv`lY?5cxp}XT;t}e zM7p`skulQMML=gFy^e1XMh%zNf-rAK%Jn!xLvd;J9mfKv5!?g6ljC3pp`OZwmcUy+ ze}5Y}yVTpd3j39! zYSHX6fona~Q#)-%z>}99^;Y7fqUlt(ffi4L0GeymM{8xBdMy8#f<9C#f5##)5uA^{ zGQHZG#w^ipSPI&uQqH9e0e8yCn@muXzWw<-Lja#R7|(R@E9hRYsFk!GMxB9=yKz4=g>99S*X<3w$}!XsIt)N;D33Bf|p~hgg~Jb zS65-KtR&67f<5)r0NkevI<(5f?^pmPf%BSQl1p+7rZpk!?V$h00aHvthY0Z7pTBbi zupF>(Be9kkWE04cnAI*Fx6Zhaz}r0ntj_8Cc|D1W-l+=e3O{1}YZ2^TM|$E-XHZB+ z6y{Yd1~YYFSFD09R%iV`K)eAV zo5>rD{yPIKNdWNSA=)!@09)$N{FE#boFi;7(x}|aLD>9pwT;BQTyH_#K?Fhq)poRn z_#}UiJCmf?mM5yb0CLR1!8s!7Zx!I7c96Y&6syuXYi%2GE$Bi0VNwcOYB_5wTZCb? zW{BTuTi_VM*p&}rlc|Yz{l|jS`p*q8Iqbsv@G$<)6u_2(j_hF_QJ7B};&>>cnD_}` z%o+EJCX10lRXmpgu314+8lZ!N)}pvnF`XT|-&)RED|AJzz;MdEid1kRUx=4h{*#zTW$zsvu#76AWN!|*#(0NZ`Q zvCG1MXvC}7TXFg;^p6>?{u$!7kb}lnkUQ?d>L>{8v~H*u2hk94v7P=NT~@*+C@tsc1<`I2+E;`I@ORDtj_v~n;yn4o zhXWIL5-cIJ)?Nr0948+UQ9y^GUYUor9o2=Ib`O^MzpMjSE*mLoudfp`=}_fEg-l2k z^-%;i*c;k0AxD&LuV|&caT_;A#E|1*DQ z4PZH7VT}`5z&w)IG0RSj}iuvUakby6WVkI^@Q%JR$^im*B$Tqb^}0pP7!<$6>> zug(9u=^5X}0e{19DFDX9gIGPRjd-8&1bJ8mB(HM-UIXH|Y_K)uNGtFh)*nn%SR4h& z;i&C=>3KLXJ2fid)T+Tk+R>VL_JX3fie_~KL=~#ZLegK{$e@~yb zPp#}_yFxqeV;>e?)pay-lUFer=-%^i1dPtp0RMgr*nb1?slLm103Y43;doeuw>BvC zT^fBFg)8lV7yeGi0dI|UZfgde*86mzptS_p5RAjF4eNm6ngM#h>2N99^AG$jzyU`o z=x*K;(dK}U9uK6jw{5hoqefhIdL}&_Vp&vOBXHk8PiS|2*JtfaOact>S&R z1AvXS8|2kOE39CEwRL=HbT;f)E#3hC!2vG-mUfLvVB)vITpnHe(YVw!wOq2jp@Ht| z(<}q^;K8Li=s}Z)EkZr{IoQE&*|KGK=2sAHFag}{fL}kk*Q}r4xO3{j^EXd!gbfs7 z8Esooyt;Px%?7a}d>D0)S~k@_mPTjeX#1-!4tU}3=oXm#HALpo16!h)1>1&}b}Q}^ zRztpgE^1&@#?qUg1L3%7OIGRpkqPdufu3)(_ePC z9J&&gEi+x84X>VXYqVv+E1Y2e{!Mvb-(&<%j{&0y3p(}Y-t`8+_uf2ubL!Na;|C6e zEjVB!t9{;m)i#X6BJQ{C03KVuS`q{R4uqY+sbP2=U-2XkQX> z1}`HE?qM(MItw|-LfT=E>W%|CN`@AqEC`~4EO>PkZyppxuikT$Ts&G;c_vRPkCjeu zHa$Hv{Z93C)mv4anK|rlpSQl|#U22$PGyhW2fJ8?Jz~F<5Lgv3$AGOJAOCG{S>)d6 zEX5YU?X}A$28}9?0moLQagJ5;+Lc4$7TZJ>3}ZxkDXueK=7PN-eBDpB5bKb_3b+Pv z1ql3q{B`tw;e704^K!{tOvc<@+}7a=D6y+87XRxrVh=nrH+HdHaz0sxSq2{v`1H$= zL<3*w+^_)NYCjg65cJaK_4jN*8l>hdXy2}1eP$EvMMM<{LD>nqYD_AwW+uiP?hCLE zDXf5N{!SmjI{(@5_xT^vMs2m#7PepCA%XJ%Oa)8as> zeW6!vwcQt6{`C<6ICmZJGgQE9Z%A@OLg=#R2fc z)dcW^vH>Lk3{;(KS`K(~%U-_NC#}&|+kLZ(P68L$iW2e{nS-Q;2sLLx6BJm61pLAa z_<|<~ROU{{!1RJ=F!4F|_7Q_8o_7cb0lYZ;t*QimQ0&>4p@7dHzhSnr!k9GSTk%wx z(0Z+ZkJwBKU;vmBIBym-fV+l_;Fr=EB`9DE4+uGI#DQ=$l`eow1$+peO02w{dL}+D zfEP*whbLjx{GB3z6~D$|0sPXdFPwL%wt>rc!|VB_C+c~t=~mlx?8%D+aPB%_2w$jR zBAAI@QNUm@jO$v7T@VGV!G$_()v>@C#sZFVdEwUq*ZeJ+z{+0@L0bX*0^nH2%g^x6 zqBPOG&v4CC|JD+C-Yu+vO9Zg)gazS?3-3tq;ti;#0*27#Txcpg0sEUc#mISEZ^T>`91}a#zg{jrtXdQg!w1|!48PD~Xy9-Ny5{dR z2(0*30H5!aVI-EwN;X-F?$UdHb0epf2uK7zNeoaynu4x%qd`R zoHzEjF@~YmWeF75MpDeGcy2vMT^KwkeL-iAk|+`K4_99TFE8p^<><^9X0DV}Gz1M<>nUJ&8WI4!*17iB zeapP#((|%mxOeSmo=L&oK^a2wX&HmKC2K z0_%WvFKBFm1s3BpBxBEY+BZ5|og3TRXy+0Xuf(-NX2?q6d7qX zSqya&*XSn+&!CtFl;*-S(Y5ffY=0a61PnhLuS;_sjSf%3S}6WLToC{(bu|P{1di9o zZ#Ui?TmAd<-uif-gex3*_V3|fw4^|jkiHH>AC;w9lq6Y}B+(I&HbZS4fQhToFjWAv zZA<#2*9;#c83~OGXj$|sG@2aU>8v{I-0}49#OrC`orxD3xcC^bx6`wK8q(6HITm

;k}pZr?tlyJ9=`2Q3SbW@enW+3v8n zf?hMnUx2efMW8WzoqnWvvpaIuH4>Qi;lyhsFs(E3cJ65wG|>y=X-IMJ`sPRGFv5-N z2E(F&DdC{qJS}Ulm^?l{_^HV$LD$3IDtS&kV633lB<2_bz)Y<7()7hM>!E*=V*U!TH(-wHISxFZCInsMw@d|0{^pMX zlX83GZ?0|{{{Hq`=h6Q9xVYxjP_gd}-;nad+EUMqjsusjfYae>G8#5lcML0&hJ|D@ zOq0QG(zP6I4*LD%0Kn0X6~V2j+l`uoW@=DuJfpsmxi$oCTn@lS6|d}ACctTlY#!`- z%@}|wRz2EkUNhmT)Y0i7+}ll@?e<&|)}MI$VQ*AC1P!>t{NoqY#jPk~o@fi8kTCEA zK)|o34JAP;`_qH{WlA&aQ5Ed3l7`r2{M}_2_c+4077D-*SAoDe{FR-stnCk$Hw}NS zIR&iD3j#9C&eQgmg~7QU!;R=G!SI(_7MZI_k{CJ;23cgWX|G)a;G{_wH~<@zHoC1w z(i@l{vjH#$hQZpQ18}2dYLg>QOLcp>UR9ig6|yi`BPnYJmp0Z8DxFdOay4ltCar$S zt_8e>_JXDY=5%NtiR5LefK3egkgEg==|UMSn?bual7K32vqp}X5?b-$XzDC^@Wsho z{s#jMNNLpYRLA)}7&xqe7m2@Bkig_@?ieunclpw%j=$r7#`{;HfO9vv3QO3$ z0_AWBS_9ZhV7!$jfDwYuRvJl`X1ft|tG!Z#)7A=E?Eu`(45oL}on{(YN9!=Aob*R& z>mUT(+(}Jsv}!7QyJ>fr0>HM{OyM^Yhk`g~3^xi+r)FM_^{)++rmwo_IXMOLk$HknLzv^c`+(93# z=niF%AF-GQA}g;p2?PIvnKZWMI~rsZm6y7gD0 z0{~}P-w9$H(6+USA+M3V)(HSldhze)+{$Xh0zC@Nh>m;>tT`3XTGS!t<(pYzn3~=6 zKk63;-Y?*lw)cD&7e0JZl;?i_a}I!O{#FdY{uuB9KrXkRy0re&SHJ9!|M_=){DBZNX8}^~jOB1k z728^`sK;IWu+k*32cIZ16i(6kWCmfiex*{d?%J6U!|z1=M9!W*4Z0dp4g8eTvy3UUUL zC}4lj4DaFsSVC70yN&to+9At>46U0C=ZV4~GuqgC(^pfB*9PzL^bu_pTxkH+8FQ4fkYDn`jTX-33R^8Awtn z!H%KW#+GfwSljSBPEeYp%`6M7&go{B<0Dxdj9xPpg$4$Bc~X@g)vyXxf;Gw&(5za1 z{D~(XCsR-5y~lOHFz8$qj+}<{`u66=W2%6`Nye71-7=orSC*_@xdy60|1pt6$N)ER zFdEJC3izDKBZzxfS8b2C2Aca*lC^$d07Wo*u2%yG0bKLOc?41PZuMSpuV&4Ewz-6*6lmHyRE4y;exdrrn+iXdkQt zp0r`F84EtDFnvy#cp8$kZKr@?Tn7w>fEL$2x9Ir%`)fA;{Vfjg2G3o9 zs0DBsdUkK91Fq!6Byh{|9gZq`z+iCq*ild%^(MOgZ|3^X?{1V~1^iGA;FGK@{OTC6 zDo!66B5b8Y0K7_A5slJYILdUKxNIvALG3goFw5?ZMYfpd)A*NjSlfUSSKZC+Hs799)?U%9g6D`28GMq+DRL@dxsc%cgKJn)cJ zbb-(ps^Fo6ORscc5u6mq^wJ&Ab^Q6nov>>Do@gcWSGS^6kchxk#A+#jGY-~h-g}8x zUiuiM@+U%Tr1{`NVbK+^=-Be5g;P;Hw$1mYpDVoy;|*W)g{@jDW^@UW9c>2WuH55jXN zgv0BAXN|v>Whd2FmcXEE!7<=40K+sq<@pP$o~5r=6xex-1!~W!NnkpJwdbUKmkTs0 zp-tZDM{25hmC(Y_!XwF1(5YU*d%;=Is(}5|kN{vD6wDAbVyBK05WqBl%+puE=!6_@ zoE&YQMm{6S5r@df#NFf()Az){ET=jjGF9U7{F?MJYu$4ze^1;AYsLT!nmrVxa76(O zwiX)$7QhBT>idIe&U*lv71FQFu|kA6Jj}4^^wt6^u!8@uxxa>ANZ!w(4SmcO*aBMA zYDn_3wckn}79K#2I2aZRvNSKGQvpX8%Ao<9_a74S^q_XrPXi@^V}cka5<(@+#f z6ck*=JJ2Adq@YEVNI-*VKon_5TqIfqN_nIJ4IM|~1t{hXvCSGjHj9lhhsjI={xgZa zz3t@Cd@SEKfE}6x&IGIh&0&Jgq1->B!!rKQiqYo&aPI~ZINJVuW6k-nvqRNQ`6w_B zp4=N>p6=T7p*S877`CE@iH6klaN#g<8l->)l$O?|m03a+Nfa++ot}10fY|BY5`!Mgf}+%{XWm!Vk|5WGQ-8 zhHP>j_L~6ScosOZhkyUYIp9RcM#0%bu218p0Uf-F)lsYm=1pXhifn+e0yYUX- zby(OxpVD7u$-W@BlE(J|f5=(T@f2w89K>;1gvFVQkT-6~LAS<>sDre1ttci#dBIIY zV-DDtcnw=f!~J+qJmacuU2K77kX{XB*MmWVqb`NcPr}+2f1x4CT<#9Qpmk^txDQ&g z_?mN$Uf0GkpDEr{h4XL+fQS$l%d)zqNOl9y9Gs4Pchr>`{Y}vT zkvG!7|6$Iu63b|ZsT)wAML>+xkb5r0haLHaU_%>O4y=ocHG zcGR#)8Gv^tfL{(U%piPU05-r5h9h+LxiJrGbg?l3~ zTpgbS?l72K$n=n%XBdiYqKQmLtB#yj;@oO$0Bn36-3Oe@O~yA(^vMTr%r)l< zSjc1DkhHaOGx<^6JFMVfoW@i z&0EkC2QDvnkKaN8<4NfjDdql7r+){Ap!*8bb!vv_ykB>RusL5Tfq%0;F&v?GB8k2p z4M{l^a12LCZc;QP09@&Mept%m;bASPdT6RxqPGaw;w}JJheFTlaH^X2yjJ;I3+k-a zoTt;{V^OL$lSZAeNL@bUQD5PT;DHnxt;0Ykr6 zfB5#>Z-038^Y5R1_2-|GrOcT&?w*h3Mc2HcXn6OkyzlnI{2$Q2cL8L$l>#v5Ycx}~ zYyxJ-`IEvB1N^~N(CjpVurV4^N#A{49;SeW8d!n?ZuAj=&!_2piX+H~-gQv{&3amD zws@YVpitGpc`g|_RBN*}N7UGhnnWtr)*LBu6REK7+t;b*vLA% z4_JUI*nREek87Ow3gBGEV#x(?4nC@Bki0A3UlhbG7TsjIy#l@uG;fz&pE`qa;oc9M zkCWF?NL*}4+J6XNjHI!Bz`n}LqajW2PjYbu40IY-*11`N0v7Tdz;h9}2HNm76sO&C1QYXXRJD zPmjf|y+sQ6yfjA+2=mi9=!mgqmR#8eXu>NUZ0NZQ;9c<-4sNZ3H{&mJz)+!Kx1`s8 zY&qwrW7PrbH54#lPD|Xni=hqNB~kGoQNVYQU{++AJ7IN(8Ux)wBHrtCB~15xUj>hE zLkbEwMnh6W23No=A%Z3p`v7k8(G~C_P1({kpR3UUEC(Xk7pTgX19;Yu_h~twPD|6i z`UU~`ajyP#q`GAkWditB+sObd&-Jl9!)P*^Hssocm;5djw37EF9d8*{3gBJw7Y=TY z;LQN+@qnd(Uw!taA1Z)z!bX!Db4Ev2xIsBC=U!HiN*9^+V~(;**9eb0^n)+2#39$m%D)AelssA;eC za)xP)qw#<<1uPpW-v`XV>eYhCPu#t3pqnCBt8DG1dGQ@oIyD4qn!qWT)vh9o_5`r) zQj?mW4z~DtR002e9R15+z4CtC9RZj*U?>;>+$@RU9U3Zj-&87N?l0)d4!nZKcP@dg zcB`e(*Ek2$;pOVrT^z8TBcJ&t^bE$%LDbx{y-wr%fZt5!fXmg7h7`lZi^Z%lnux`q z8+7JI){Pi=0Y04XIN_eWNsp$0mp($vikN2~(WCG(FqvrU|aOr0=zWmh( z3J;ts;5!h&FAqTQb`0JIzkU|9DPU(LCeQzk^;JgH%){PlaF)eJopr;g{C!E_JKuCP z+P8BqpVu`HtfYQeeaEL8Gj+@plUX9#M;BosfJ0D*el#RWGz%BRqG3g*XX{Nv4>zjA z?GIJ#uBBnSSg_O@=|1r$d?jJw;7C#a0RD@@z!_igH2w=FYM<*H*1H+I5O`1eGFwN)*EsMbfFiw;wIl2HwFEgY&n80V! znqWx8`)w$O!YZ>7xE1^&kaEpN9ekvb=oG*^!Y>TG4THA*(klhfg zti~~m1sf%MD>u5lI|+Q$WU?{Y7KAa09*7MKg|Y2K)O1{oyF5nr0lyg(u+GB*!o6rn z7H3FF@)L;%mc=67wZ4j5q-(PfW+@y7Da8xcb&qAe3JA(PoF@J%zASz`e;h5EfvOPJ zFpCw%hth~N9Yp>9EdXBzgYP*(xSJq&BmK)9a6jsOKI7Z3%OfZmP^}NI#u7Fd`4lj} z|A+*>6R?9?r*Z;g$6Zcdh;5k1z%w+$hQ;|$4*OFTFr`j3BvdDdNGQXoEqjF3K=e_| z$w}85DKrvE09TiCRjh?L0xZJGTpggGUU*tsfovy%JC>Zmf9Aq@AjOGh%z;>RI@uNW zEVV4Lf)92obPizAcMkvtfj43BM*KwqLrcHqhdz6SHO-qCto@m{&%-wWT#N2>M|**v zwiju<>A2gt^Q#Fdox=lB5U8YJjXdG+MQ(XpZ~d>#0sk%<(kGuL(U1^!uwb2mOWVkE zQW+l^Xo--mg|>Z&;Dr*J#vXzlVUs8p@#}6RIjl9yx3VEv+kFQZ%t=+IuP4<)R?r_6 z@FWqRD`5WjWOC{rWjOk;0Q`H#+%P9 zd*2fHh2hGv1{mEsWH<7rvJ@4}4fDuBlW?D0Dy#Fa^smD{yb9VCu!=-OYUz_djfN!X z0E0R5OI?a2aGiogiC$GA)L%uq1Qg~pbgc=RqEi{u8% z%mia^q(zhiZ$0c%FJK$de+2IKqajtW{09mAkN(ar@XH*qL67_s1+W7-Z{)Ow&dyIP zg@8PW^Gndvc6o1++QX@yS;~zmn|(j&s0S zG^Du(WAKx(7!>}ECPYJ;#M1R~DUw#9gO=rCK0jVOnn=A!)ul!q5)Ty`sU6h(aJn2M zxzspFrJr&S!Hz-?f|J5LGzS2@=)jIi@_bfRmTYP{+L)kbITb6wk;158s4Rt>E`pY) zUImMfGW`5k0DgN<00wh6V(?Y@>vO=yM#rYxvPQ0bbBBRY#FV_3WEC_I-R?;M1KI7T zd-?D2Zw^HJYGa>%P3;)HKljB0H)pORIET8up&N{$N)nH zzE8grS`MOYX;T~;n&ECS4a@<@EkG0c6m~Xn;wIK2fW!J`W&99mTn~8$M+V@}-g)<} zx88nnM+6=wY(HkwJpwq+0cT|FANg#B{%Kj!fy<%K&FgqlYCpQV`9kOetbtBHxdSwQ zIRG7a-Yz9Bh2W9X*K>dyqx(33Unwa)3mWX|pG89|>Gb~du7Km(C-GyQVUiT^0w~uC z=#u4RWl7$7E|tyDihmB^`8Tf50l@U2E>XY%z>06An$vli{x*PJbF$t{4?-ybTxr+| z9>+CWFq^wt$}_y2ryB2kHT2&H@EsEv&fQ7{Z-8IsfKxq6(TVFm33Dl#Fz!e7$CR&; zh7k$0ak(D>{EyN-FPAnll6tZCEz|9kyjyVghfnjyMoHO+plikfoGW09hE!b2jIb+U zW+-7xn5xVHTvH#wHMssVMF6koW*7&svecBW7S=(h(if@%zBqe}Y-Ou4jIMcKxYaVI ze+~B%&U}nA$5;yeKY;%g2w$1M9uJs*b~z+FO4vE>53{)Lb{loZ{bVmN`OPJ8UjgHC zXK)?t1gvG)#E=L~>d9wBrsmb?smoD6GMDV%=R?rt0f5tZz``&vCK^($tBbH)0fPa7 zMv#zr3jkK=pa9@9EUjh8En2<<_#}ANfDHh6I-Tbb>_|Oy0IV2Gm}>w1Ibc7G3LeIb zlfW#buZLw|`d7Xz*Rq9b_Az?N?!z+V0NxRSLEX&|e02ab2i!R-!>s0F?JbXY?w+=F z&~gD-*bxk^3E4f1+szM_&U+mniZ-KB&MK1W;_hpmd7lGrNYQam6T`C5DF9fZgCc<2Iw;)(fJ11csXUgZfYs*w_=jLep@#rqIVj+g z;u}?9w^y9kWEFJpa4sWq2rVcc2ieOoHOGx0XO)whCd)$W9b@*`0CwVSkKn80*Uy4> zRGM)tfIbDhF}TGu++KTHx`qV)`!9d;Cg7WEV(+XIHxOv%Gp=~JGiD6l6|J}%x9wpI zxB3gI1>j2Ea&?BFO#!nSx*H8iNt%tI2<*Dall=0efc}c^JC;&fjqU@U;@w|>;unK$ z3veT@C=EwZy3GaEs|(jDaGoTuU9Zs^0Px)s*pPP%2w$7O%mH_nA`dKnCS%5=v105F96mkbh+oN zpkc0&HeRNH6%io@uT}BF1(`y0`R0STS|jiyrb_xCCer zaN`zWzTi@i8m3DyD`w+*@#Ih3@1*bF2Jn6e{POkF9RT?4OabRw)K#%J#ApvAG`M9o zRRZj%0{99N_-_MvKmdMgh%xAu>8R9Es&gy@T(auEhFFF+td<^hZ~ z0=P(mEm8#m(y5JvG#cm)77n0x6+eN-jfyc;=mqqSA?cGj!(88G6x$O!SguAQFRv(R ziv8wX{(S-Pg&2G_{_6Vy6OCd6zzK7F_1;}sulM|hfIc6`VCJSt?+l1)w2sh#Pg+BMuOj z8dbPPkw^1*&U^ZBggPq3#K!aZ)emVb(G0*1#_*Mz5GV@It zd}aQ!518azsR=#{-9r`5QYh1;@mB)>TmZB6n^M4&-{!`~OACGqNvd|evMj+WTVqz; zp&>A+N;7>kZ8U_rZsV#jW+p*1Z(v6~EmHmZcK#QN_zQq9h2ZP*SM~va7O!yl zya${V3{M)oCG2Mdm_hZoSHO6z936cF{5(HNcEX@}#(RC)1`hnFsHB@7q&C7^UnN>% z_`C1F79nV59knHu3PqGhK2w<)S&DAX^a;ZpBVwje~5eK-$+r&OX z6wHDB^*!R2$vwc-qskCufKDOeY74&0aoiCHz7h8LzdfY({J zz7T-Bth*guywETuXXHlr=%u%$E-XA5rIvLjGB68C33ST_nE`;+5VST5np+};yCK!Z zr%%=>*MbJ7aOG}D5WpPq%r4n*rDT}7_q-^DOHtr%Ug@-b_4xFP00cW05TRODn zFH=@GtX(dXB-?uf0e!H(!((t0S90Vi=;7nX?(r1!7VY{J10RPW4Hd9^deV$pf@I1S zA2hUWn+qThyH^(x6<_p50dR_kM*vL9>nT?haO~#AHOWhs3FRw!#;jVVMKUoqr#KS7 z)}81m>RIi~0Pw_7(Ch~ecSEZF_+SBS6J37u00!&G1MCOP<*$M@or2C!*qoV~Hz)+1 zpw!8?pG8tj^LQv}Kv~ZFMZLy*S-k5-p{D`(7709o znb&6URq^|aRKPlb;qy5FGhl4S;Zzh8wOyACPeZ7MhtVWSxr7^ihtYwWwClS?Q*Qq; zfX!f=Fs~G_f4UBsd`#2*XmkKe1-z)MQ~((KeRvqsD1c4gwg-#Yasmm{AuM;@1cF|k z)kLHc=~cw-WEY8KeIp~%f0Xqs)&^b?(2`?dmne_*|MQxUH7Dh^5>S@p%j?|IY4A!!BDQAgZR&nMpKrU~2 zrQ}1A95SD(`#$OWSpa__@IOc~0AIfkSXaRC&;bmNdjLC?nqkec1H7U*|>h>L$|_b)6-F0`7YYwsM{4vssqU7W@3EXe?*P zsyhYX_k(c|e*anldsdlU^Vjo}eP)Y=d(e@BX`Pz3t5z@`ifX@mbtyWN1b-8(%hLc} zXUS}qWa}7!`#Kxy<>vvso&PXjCQQo`nY8$!Dsuo>U2@}U*d@Ny%@wqwFa}gr>f;lQ z=qPSiZjQvcL0~Ne%@mG;26#E*Iou7Y@`aLoh6469fe;K>!3`J~m?eer1373fgejWA zK{d%NoZ!ML3RBe6J{`X7rj@gPXrKzlw=so^or{jJ#+uOpKM4n1fM1w&+~0M7@D~7I z5W&~w??eS02|=R`C}1eY?#a?@YvF55nZD zj7ACI)!tu*ezvIkSvtO7)ak4r*U@oMRKTW8lYD+KoyGlbNcLUgUm$S`xZfF5x5gZe zSz+I$OmOjV1_>1aPacG2zcgtY2jFzqS!@RvpZ~_AuDHzW|o= z57jaq_r;-pZpylGAC=XYA5^`FfLdxwqZ5%ydMT5Xm~?Ncy5rj=MyD%F>PJJ+ngT{v z?uO(PFcTE8Se|hc?nB6KP56)~!cU~L zbY(|w5X24@E%{1+9vi8YgJ<$`$5VkP0{8|A{O-R`d>5U+Z{G(T4?&|H0@x8Q?;L<1 z>pt&2<+`7%&H;Ed&c!lz)g}ZmZ|b|mv_rTQW&d+kwTl-3*Jk#-fu7`J=>PPpWCp6|QM0(hu){?VmJXji4i#og1gaR9EiW?Q>l z)A`G)ZcLwAXIIymp=gHMzHryA>g>%&W=ZNvIBNSOD8@+NEOID>MqPm`e*i?cm4Nt# zVZtbAser|9NB}TKOH%>k|9x@<(82o3HWLnb_E(mW3ju^{2$XQ5EE_=9)r)tz$oh;r zVgX3uv=PqVhO@26Uew~?pC2L{CbYr!@3Ptd44b+f$39j&E?VMdB0zV0LD#e@w{)%u|+E2^_W2jI{+_c>voat6acTAHBMNF zBLJ{_J^ zxBF$9y&bhvdqc55(%NNH>zR&&y`_7aXXhy0bIGi4WDu9OhG$7(S

Jz+bc}^K@n@ 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

-44ut-mV1O*4poK2< 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 z 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 Date: Tue, 24 Oct 2023 14:34:01 +0200 Subject: [PATCH 04/17] cleaning --- scripts/_common.sh | 5 +---- scripts/install | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/_common.sh b/scripts/_common.sh index 16dc5b7..b818f0f 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,10 +4,7 @@ # COMMON VARIABLES #================================================= -nodejs_version=10 - -# dependencies used by the app -#REMOVEME? pkg_dependencies="libpam0g-dev" +nodejs_version=16 #================================================= # PERSONAL HELPERS diff --git a/scripts/install b/scripts/install index c6181d5..85d62fe 100644 --- a/scripts/install +++ b/scripts/install @@ -55,7 +55,7 @@ chown $app:$app "$install_dir/src/server/index.js" #================================================= # BUILD APP #================================================= -ynh_script_progression --message="Building app..." +ynh_script_progression --message="Building $app..." pushd $install_dir ynh_use_nodejs From f1cd2806c8c965fe7a9a77ae8698561cf2d11aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:37:03 +0200 Subject: [PATCH 05/17] fix --- scripts/install | 8 ++++---- scripts/upgrade | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/install b/scripts/install index 85d62fe..192e677 100644 --- a/scripts/install +++ b/scripts/install @@ -59,10 +59,10 @@ ynh_script_progression --message="Building $app..." pushd $install_dir ynh_use_nodejs - $ynh_npm install - $ynh_npm run package:discover - $ynh_npm run build - npm install --save --production @osjs/pam-auth + ynh_exec_warn_less $ynh_npm install + ynh_exec_warn_less $ynh_npm run package:discover + ynh_exec_warn_less $ynh_npm run build + ynh_exec_warn_less npm install --save --production @osjs/pam-auth popd ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" diff --git a/scripts/upgrade b/scripts/upgrade index 1dbeb65..39258b9 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -82,10 +82,10 @@ ynh_script_progression --message="Building app..." pushd $install_dir ynh_use_nodejs - $ynh_npm install - $ynh_npm run package:discover - $ynh_npm run build - npm install --save --production @osjs/pam-auth + ynh_exec_warn_less $ynh_npm install + ynh_exec_warn_less $ynh_npm run package:discover + ynh_exec_warn_less $ynh_npm run build + ynh_exec_warn_less npm install --save --production @osjs/pam-auth popd ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" From e8111c1db9957a7f213bd8d7d714e3709b6bc7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:46:14 +0200 Subject: [PATCH 06/17] Update _common.sh --- scripts/_common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/_common.sh b/scripts/_common.sh index b818f0f..d5160da 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,7 +4,7 @@ # COMMON VARIABLES #================================================= -nodejs_version=16 +nodejs_version=10 #================================================= # PERSONAL HELPERS From 7f3808bbc0fb2321d49fa0f84dad0b1ef2734a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:54:18 +0200 Subject: [PATCH 07/17] cleaning --- scripts/install | 37 ++++++++++--------------------------- scripts/restore | 2 +- scripts/upgrade | 5 +---- 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/scripts/install b/scripts/install index 192e677..32a647b 100644 --- a/scripts/install +++ b/scripts/install @@ -35,6 +35,16 @@ ynh_script_progression --message="Configuring NGINX web server..." # Create a dedicated NGINX config ynh_add_nginx_config +# Create a dedicated systemd config +ynh_add_systemd_config + +mkdir -p "/var/log/$app" +chown $app:$app "/var/log/$app" +# Use logrotate to manage application logfile(s) +ynh_use_logrotate + +yunohost service add $app --log="/var/log/$app/$app.log" + #================================================= # SPECIFIC SETUP #================================================= @@ -69,33 +79,6 @@ ynh_replace_string --match_string="8000" --replace_string="$port" --target_file= chown -R $app:$app "$install_dir" -#================================================= -# SETUP SYSTEMD -#================================================= -ynh_script_progression --message="Configuring a systemd service..." - -# Create a dedicated systemd config -ynh_add_systemd_config - -#================================================= -# GENERIC FINALIZATION -#================================================= -# SETUP LOGROTATE -#================================================= -ynh_script_progression --message="Configuring log rotation..." - -mkdir -p "/var/log/$app" -chown $app:$app "/var/log/$app" -# Use logrotate to manage application logfile(s) -ynh_use_logrotate - -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." - -yunohost service add $app --log="/var/log/$app/$app.log" - #================================================= # START SYSTEMD SERVICE #================================================= diff --git a/scripts/restore b/scripts/restore index b22e0ea..25ea55b 100644 --- a/scripts/restore +++ b/scripts/restore @@ -43,7 +43,7 @@ mkdir -p "/var/log/$app" chown $app:$app "/var/log/$app" ynh_restore_file --origin_path="/etc/logrotate.d/$app" -yunohost service add $app --log="/var/log/$app/$app.log" +yunohost service add $app --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" #================================================= # START SYSTEMD SERVICE diff --git a/scripts/upgrade b/scripts/upgrade index 39258b9..7042fc6 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -47,16 +47,13 @@ ynh_script_progression --message="Upgrading NGINX web server configuration..." # Create a dedicated NGINX config ynh_add_nginx_config -#REMOVEME? ynh_install_app_dependencies $pkg_dependencies ynh_install_nodejs --nodejs_version=$nodejs_version -# Create a dedicated systemd config ynh_add_systemd_config -# Use logrotate to manage app-specific logfile(s) ynh_use_logrotate --non-append -yunohost service add $app --log="/var/log/$app/$app.log" +yunohost service add $app --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" #================================================= # SPECIFIC UPGRADE From 6a00e29b8db5f994bb2d84110a671a785280fb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:00:57 +0200 Subject: [PATCH 08/17] Update install --- scripts/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install b/scripts/install index 32a647b..e450519 100644 --- a/scripts/install +++ b/scripts/install @@ -43,7 +43,7 @@ chown $app:$app "/var/log/$app" # Use logrotate to manage application logfile(s) ynh_use_logrotate -yunohost service add $app --log="/var/log/$app/$app.log" +yunohost service add $app --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" #================================================= # SPECIFIC SETUP From a61ec376267bf36c0f7107a9e7e9f61864bf31d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:01:23 +0200 Subject: [PATCH 09/17] Update manifest.toml --- manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.toml b/manifest.toml index f21df0f..90539c4 100644 --- a/manifest.toml +++ b/manifest.toml @@ -23,7 +23,7 @@ multi_instance = true ldap = false sso = false disk = "50M" -ram.build = "50M" +ram.build = "300M" ram.runtime = "50M" [install] From 49322fe32c96b51b3d71ec6422103f8ec8436191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:22:01 +0200 Subject: [PATCH 10/17] fix --- doc/DESCRIPTION_fr.md | 1 + manifest.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 doc/DESCRIPTION_fr.md diff --git a/doc/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md new file mode 100644 index 0000000..120e14d --- /dev/null +++ b/doc/DESCRIPTION_fr.md @@ -0,0 +1 @@ +OS.js est une plate-forme de bureau Web open source avec un gestionnaire de fenêtres, des API d'application, une boîte à outils GUI, des abstractions de système de fichiers et bien plus encore. diff --git a/manifest.toml b/manifest.toml index 90539c4..6d887e3 100644 --- a/manifest.toml +++ b/manifest.toml @@ -48,7 +48,7 @@ ram.runtime = "50M" [resources.sources.main] url = "https://github.com/os-js/OS.js/archive/refs/tags/3.1.12.tar.gz" sha256 = "c5f04810e4f5604adadc7bc0c17f2d7eee49d521915ad9ac2203b835b3e9987d" - + autoupdate.strategy = "latest_github_tag" [resources.system_user] From 0d88c52432a981f73d2502d383b03f6c3b2536d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:23:47 +0200 Subject: [PATCH 11/17] Update manifest.toml --- manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.toml b/manifest.toml index 6d887e3..364b3ac 100644 --- a/manifest.toml +++ b/manifest.toml @@ -19,7 +19,7 @@ code = "https://github.com/os-js/OS.js" [integration] yunohost = ">= 11.2" architectures = "all" -multi_instance = true +multi_instance = false ldap = false sso = false disk = "50M" From 4099bcbae032178f74175e6bcf4e37c2108e7b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:25:34 +0200 Subject: [PATCH 12/17] Update restore --- scripts/restore | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/scripts/restore b/scripts/restore index 25ea55b..45daf0e 100644 --- a/scripts/restore +++ b/scripts/restore @@ -10,6 +10,13 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers +#================================================= +# REINSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Reinstalling dependencies..." + +ynh_install_nodejs --nodejs_version=$nodejs_version + #================================================= # RESTORE THE APP MAIN DIR #================================================= @@ -20,15 +27,6 @@ ynh_restore_file --origin_path="$install_dir" chmod -R o-rwx "$install_dir" chown -R $app:$app "$install_dir" -#================================================= -# SPECIFIC RESTORATION -#================================================= -# REINSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Reinstalling dependencies..." - -ynh_install_nodejs --nodejs_version=$nodejs_version - #================================================= # RESTORE SYSTEMD #================================================= From ad86f101eb146e739a36289ce1440dc2339cac19 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:24:44 +0100 Subject: [PATCH 13/17] Update systemd.service: i have no idea what i'm doing but let's try to enable some damn error logging x_x --- conf/systemd.service | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/systemd.service b/conf/systemd.service index d10e09e..7c6d01c 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -10,6 +10,7 @@ WorkingDirectory=__INSTALL_DIR__/ Environment="__YNH_NODE_LOAD_PATH__" ExecStart=__YNH_NPM__ run serve StandardOutput=append:/var/log/__APP__/__APP__.log +StandardError=syslog Restart=always # Sandboxing options to harden security From 1f7f44574ae65706daeab010bcf3ec8e1088239e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=CC=81ric=20Gaspar?= <46165813+ericgaspar@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:27:36 +0100 Subject: [PATCH 14/17] cleaning --- manifest.toml | 3 +++ scripts/install | 16 +++++++--------- scripts/remove | 5 ----- scripts/restore | 1 - scripts/upgrade | 14 ++++++-------- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/manifest.toml b/manifest.toml index 364b3ac..8040a6f 100644 --- a/manifest.toml +++ b/manifest.toml @@ -20,8 +20,11 @@ code = "https://github.com/os-js/OS.js" yunohost = ">= 11.2" architectures = "all" multi_instance = false + ldap = false + sso = false + disk = "50M" ram.build = "300M" ram.runtime = "50M" diff --git a/scripts/install b/scripts/install index e450519..f2db285 100644 --- a/scripts/install +++ b/scripts/install @@ -21,7 +21,6 @@ ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= ynh_script_progression --message="Setting up source files..." -# Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$install_dir" chmod -R o-rwx "$install_dir" @@ -32,14 +31,13 @@ chown -R $app:$app "$install_dir" #================================================= ynh_script_progression --message="Configuring NGINX web server..." -# Create a dedicated NGINX config ynh_add_nginx_config -# Create a dedicated systemd config ynh_add_systemd_config mkdir -p "/var/log/$app" chown $app:$app "/var/log/$app" + # Use logrotate to manage application logfile(s) ynh_use_logrotate @@ -52,12 +50,12 @@ yunohost service add $app --description="Desktop you have accesss through your b #================================================= ynh_script_progression --message="Adding a configuration file..." -ynh_add_config --template="../conf/client.config.js" --destination="$install_dir/src/client/config.js" +ynh_add_config --template="client.config.js" --destination="$install_dir/src/client/config.js" chmod 400 "$install_dir/src/client/config.js" chown $app:$app "$install_dir/src/client/config.js" -ynh_add_config --template="../conf/server.index.js" --destination="$install_dir/src/server/index.js" +ynh_add_config --template="server.index.js" --destination="$install_dir/src/server/index.js" chmod 400 "$install_dir/src/server/index.js" chown $app:$app "$install_dir/src/server/index.js" @@ -69,10 +67,10 @@ ynh_script_progression --message="Building $app..." pushd $install_dir ynh_use_nodejs - ynh_exec_warn_less $ynh_npm install - ynh_exec_warn_less $ynh_npm run package:discover - ynh_exec_warn_less $ynh_npm run build - ynh_exec_warn_less npm install --save --production @osjs/pam-auth + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run package:discover + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run build + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install --save --production @osjs/pam-auth popd ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" diff --git a/scripts/remove b/scripts/remove index f0f5cad..3b493cc 100644 --- a/scripts/remove +++ b/scripts/remove @@ -22,19 +22,14 @@ then yunohost service remove $app fi -# Remove the dedicated systemd config ynh_remove_systemd_config -# Remove the app-specific logrotate config ynh_remove_logrotate -# Remove the dedicated NGINX config ynh_remove_nginx_config -# Remove metapackage and its dependencies ynh_remove_nodejs -# Remove the log files ynh_secure_remove --file="/var/log/$app" #================================================= diff --git a/scripts/restore b/scripts/restore index 45daf0e..1fc12db 100644 --- a/scripts/restore +++ b/scripts/restore @@ -6,7 +6,6 @@ # IMPORT GENERIC HELPERS #================================================= -# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers diff --git a/scripts/upgrade b/scripts/upgrade index 7042fc6..0778669 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -32,7 +32,6 @@ if [ "$upgrade_type" == "UPGRADE_APP" ] then ynh_script_progression --message="Upgrading source files..." - # Download, check integrity, uncompress and patch the source from app.src ynh_setup_source --dest_dir="$install_dir" --keep="src/client/config.js src/server/index.js" fi @@ -44,7 +43,6 @@ chown -R $app:$app "$install_dir" #================================================= ynh_script_progression --message="Upgrading NGINX web server configuration..." -# Create a dedicated NGINX config ynh_add_nginx_config ynh_install_nodejs --nodejs_version=$nodejs_version @@ -62,12 +60,12 @@ yunohost service add $app --description="Desktop you have accesss through your b #================================================= ynh_script_progression --message="Updating a configuration file..." -ynh_add_config --template="../conf/client.config.js" --destination="$install_dir/src/client/config.js" +ynh_add_config --template="client.config.js" --destination="$install_dir/src/client/config.js" chmod 400 "$install_dir/src/client/config.js" chown $app:$app "$install_dir/src/client/config.js" -ynh_add_config --template="../conf/server.index.js" --destination="$install_dir/src/server/index.js" +ynh_add_config --template="server.index.js" --destination="$install_dir/src/server/index.js" chmod 400 "$install_dir/src/server/index.js" chown $app:$app "$install_dir/src/server/index.js" @@ -79,10 +77,10 @@ ynh_script_progression --message="Building app..." pushd $install_dir ynh_use_nodejs - ynh_exec_warn_less $ynh_npm install - ynh_exec_warn_less $ynh_npm run package:discover - ynh_exec_warn_less $ynh_npm run build - ynh_exec_warn_less npm install --save --production @osjs/pam-auth + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run package:discover + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run build + ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install --save --production @osjs/pam-auth popd ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" From b505172122f7bde5013c88b3edeb52b0c5ab26fc Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Tue, 6 Feb 2024 09:24:55 +0000 Subject: [PATCH 15/17] Auto-update README --- README.md | 7 ++++++- README_fr.md | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50a94a1..b4ad95a 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,17 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in ## Overview -[OS.js](https://www.os-js.org/) is an [open-source](https://raw.githubusercontent.com/os-js/OS.js/master/LICENSE) web desktop platform with a window manager, application APIs, GUI toolkit, filesystem abstractions and much more. +OS.js is an open-source web desktop platform with a window manager, application APIs, GUI toolkit, filesystem abstractions and much more. **Shipped version:** 3.1.12~ynh2 **Demo:** https://demo.os-js.org/ + +## Screenshots + +![Screenshot of OSjs](./doc/screenshots/screenshot.png) + ## Documentation and resources * Official app website: diff --git a/README_fr.md b/README_fr.md index 565c1ab..032c5eb 100644 --- a/README_fr.md +++ b/README_fr.md @@ -16,12 +16,17 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po ## Vue d’ensemble -[OS.js](https://www.os-js.org/) is an [open-source](https://raw.githubusercontent.com/os-js/OS.js/master/LICENSE) web desktop platform with a window manager, application APIs, GUI toolkit, filesystem abstractions and much more. +OS.js est une plate-forme de bureau Web open source avec un gestionnaire de fenêtres, des API d'application, une boîte à outils GUI, des abstractions de système de fichiers et bien plus encore. **Version incluse :** 3.1.12~ynh2 **Démo :** https://demo.os-js.org/ + +## Captures d’écran + +![Capture d’écran de OSjs](./doc/screenshots/screenshot.png) + ## Documentations et ressources * Site officiel de l’app : From f541a94c0022e4e7e34c44f7b64aebc4105b2f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Tue, 6 Feb 2024 10:30:28 +0100 Subject: [PATCH 16/17] Cleanup packaging v2 --- scripts/backup | 14 ++++------ scripts/change_url | 2 +- scripts/install | 54 +++++++++++++++++------------------ scripts/remove | 11 +++----- scripts/restore | 25 +++++++++-------- scripts/upgrade | 70 +++++++++++++++++++++------------------------- 6 files changed, 81 insertions(+), 95 deletions(-) diff --git a/scripts/backup b/scripts/backup index 737146f..d1816f1 100644 --- a/scripts/backup +++ b/scripts/backup @@ -22,24 +22,20 @@ ynh_print_info --message="Declaring files to be backed up..." ynh_backup --src_path="$install_dir" #================================================= -# BACKUP THE NGINX CONFIGURATION +# SYSTEM CONFIGURATION #================================================= ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" -#================================================= -# SPECIFIC BACKUP -#================================================= -# BACKUP LOGROTATE -#================================================= - ynh_backup --src_path="/etc/logrotate.d/$app" +ynh_backup --src_path="/etc/systemd/system/$app.service" + #================================================= -# BACKUP SYSTEMD +# BACKUP VARIOUS FILES #================================================= -ynh_backup --src_path="/etc/systemd/system/$app.service" +ynh_backup --src_path="/var/log/$app/" #================================================= # END OF SCRIPT diff --git a/scripts/change_url b/scripts/change_url index 208ff24..7bfa55f 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -33,7 +33,7 @@ ynh_change_url_nginx_config ynh_script_progression --message="Starting a systemd service..." # Start a systemd service -ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" +ynh_systemd_action --service_name="$app" --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" #================================================= # END OF SCRIPT diff --git a/scripts/install b/scripts/install index f2db285..1737890 100644 --- a/scripts/install +++ b/scripts/install @@ -10,9 +10,9 @@ source _common.sh source /usr/share/yunohost/helpers #================================================= -# INSTALL DEPENDENCIES +# INSTALL NODEJS #================================================= -ynh_script_progression --message="Installing dependencies..." +ynh_script_progression --message="Installing NodeJS..." ynh_install_nodejs --nodejs_version=$nodejs_version @@ -24,24 +24,7 @@ ynh_script_progression --message="Setting up source files..." ynh_setup_source --dest_dir="$install_dir" chmod -R o-rwx "$install_dir" -chown -R $app:$app "$install_dir" - -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Configuring NGINX web server..." - -ynh_add_nginx_config - -ynh_add_systemd_config - -mkdir -p "/var/log/$app" -chown $app:$app "/var/log/$app" - -# Use logrotate to manage application logfile(s) -ynh_use_logrotate - -yunohost service add $app --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" +chown -R "$app:$app" "$install_dir" #================================================= # SPECIFIC SETUP @@ -53,29 +36,42 @@ ynh_script_progression --message="Adding a configuration file..." ynh_add_config --template="client.config.js" --destination="$install_dir/src/client/config.js" chmod 400 "$install_dir/src/client/config.js" -chown $app:$app "$install_dir/src/client/config.js" +chown "$app:$app" "$install_dir/src/client/config.js" ynh_add_config --template="server.index.js" --destination="$install_dir/src/server/index.js" chmod 400 "$install_dir/src/server/index.js" -chown $app:$app "$install_dir/src/server/index.js" +chown "$app:$app" "$install_dir/src/server/index.js" #================================================= # BUILD APP #================================================= ynh_script_progression --message="Building $app..." -pushd $install_dir +pushd "$install_dir" ynh_use_nodejs - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run package:discover - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run build - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install --save --production @osjs/pam-auth + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" install + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" run package:discover + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" run build + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" install --save --production @osjs/pam-auth popd ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" -chown -R $app:$app "$install_dir" +chown -R "$app:$app" "$install_dir" + +#================================================= +# SYSTEM CONFIGURATION +#================================================= +ynh_script_progression --message="Adding system configurations related to $app..." --weight=1 + +ynh_add_nginx_config + +ynh_add_systemd_config +yunohost service add "$app" --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" + +# Use logrotate to manage application logfile(s) +ynh_use_logrotate #================================================= # START SYSTEMD SERVICE @@ -83,7 +79,7 @@ chown -R $app:$app "$install_dir" ynh_script_progression --message="Starting a systemd service..." # Start a systemd service -ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" +ynh_systemd_action --service_name="$app" --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" #================================================= # END OF SCRIPT diff --git a/scripts/remove b/scripts/remove index 3b493cc..c3607b8 100644 --- a/scripts/remove +++ b/scripts/remove @@ -10,16 +10,13 @@ source _common.sh source /usr/share/yunohost/helpers #================================================= -# STANDARD REMOVE -#================================================= -# REMOVE SERVICE INTEGRATION IN YUNOHOST +# REMOVE SYSTEM CONFIGURATIONS #================================================= +ynh_script_progression --message="Removing system configurations related to $app..." --weight=1 # Remove the service from the list of services known by YunoHost (added from `yunohost service add`) -if ynh_exec_warn_less yunohost service status $app >/dev/null -then - ynh_script_progression --message="Removing $app service integration..." - yunohost service remove $app +if ynh_exec_warn_less yunohost service status "$app" >/dev/null; then + yunohost service remove "$app" fi ynh_remove_systemd_config diff --git a/scripts/restore b/scripts/restore index 1fc12db..12b21ac 100644 --- a/scripts/restore +++ b/scripts/restore @@ -10,9 +10,9 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers #================================================= -# REINSTALL DEPENDENCIES +# REINSTALL NODEJS #================================================= -ynh_script_progression --message="Reinstalling dependencies..." +ynh_script_progression --message="Reinstalling NodeJS..." ynh_install_nodejs --nodejs_version=$nodejs_version @@ -24,30 +24,33 @@ ynh_script_progression --message="Restoring the app main directory..." ynh_restore_file --origin_path="$install_dir" chmod -R o-rwx "$install_dir" -chown -R $app:$app "$install_dir" +chown -R "$app:$app" "$install_dir" #================================================= -# RESTORE SYSTEMD +# RESTORE SYSTEM CONFIGURATIONS #================================================= -ynh_script_progression --message="Restoring the systemd configuration..." +ynh_script_progression --message="Restoring system configurations related to $app..." --weight=1 ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" ynh_restore_file --origin_path="/etc/systemd/system/$app.service" -systemctl enable $app.service --quiet +systemctl enable "$app.service" --quiet +yunohost service add "$app" --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" -mkdir -p "/var/log/$app" -chown $app:$app "/var/log/$app" ynh_restore_file --origin_path="/etc/logrotate.d/$app" -yunohost service add $app --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" +#================================================= +# RESTORE VARIOUS FILES +#================================================= + +ynh_restore_file --origin_path="/var/log/$app/" #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." +ynh_script_progression --message="Reloading NGINX web server and $app's service..." --weight=1 -ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" +ynh_systemd_action --service_name="$app" --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" ynh_systemd_action --service_name=nginx --action=reload diff --git a/scripts/upgrade b/scripts/upgrade index 0778669..a1130af 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -9,12 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# CHECK VERSION -#================================================= - -upgrade_type=$(ynh_check_app_version_changed) - #================================================= # STANDARD UPGRADE STEPS #================================================= @@ -22,36 +16,24 @@ upgrade_type=$(ynh_check_app_version_changed) #================================================= ynh_script_progression --message="Stopping a systemd service..." -ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log" +ynh_systemd_action --service_name="$app" --action="stop" --log_path="/var/log/$app/$app.log" + +#================================================= +# INSTALL NODEJS +#================================================= +ynh_script_progression --message="Updating NodeJS..." + +ynh_install_nodejs --nodejs_version=$nodejs_version #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= +ynh_script_progression --message="Upgrading source files..." -if [ "$upgrade_type" == "UPGRADE_APP" ] -then - ynh_script_progression --message="Upgrading source files..." - - ynh_setup_source --dest_dir="$install_dir" --keep="src/client/config.js src/server/index.js" -fi +ynh_setup_source --dest_dir="$install_dir" --full_replace=1 --keep="src/client/config.js src/server/index.js" chmod -R o-rwx "$install_dir" -chown -R $app:$app "$install_dir" - -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." - -ynh_add_nginx_config - -ynh_install_nodejs --nodejs_version=$nodejs_version - -ynh_add_systemd_config - -ynh_use_logrotate --non-append - -yunohost service add $app --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" +chown -R "$app:$app" "$install_dir" #================================================= # SPECIFIC UPGRADE @@ -63,29 +45,41 @@ ynh_script_progression --message="Updating a configuration file..." ynh_add_config --template="client.config.js" --destination="$install_dir/src/client/config.js" chmod 400 "$install_dir/src/client/config.js" -chown $app:$app "$install_dir/src/client/config.js" +chown "$app:$app" "$install_dir/src/client/config.js" ynh_add_config --template="server.index.js" --destination="$install_dir/src/server/index.js" chmod 400 "$install_dir/src/server/index.js" -chown $app:$app "$install_dir/src/server/index.js" +chown "$app:$app" "$install_dir/src/server/index.js" #================================================= # BUILD APP #================================================= ynh_script_progression --message="Building app..." -pushd $install_dir +pushd "$install_dir" ynh_use_nodejs - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run package:discover - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm run build - ynh_exec_warn_less ynh_exec_as $app env $ynh_node_load_PATH $ynh_npm install --save --production @osjs/pam-auth + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" install + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" run package:discover + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" run build + ynh_exec_warn_less ynh_exec_as "$app" env "$ynh_node_load_PATH" "$ynh_npm" install --save --production @osjs/pam-auth popd ynh_replace_string --match_string="8000" --replace_string="$port" --target_file="$install_dir/src/server/config.js" -chown -R $app:$app "$install_dir" +chown -R "$app:$app" "$install_dir" + +#================================================= +# REAPPLY SYSTEM CONFIGURATIONS +#================================================= +ynh_script_progression --message="Upgrading system configurations related to $app..." --weight=1 + +ynh_add_nginx_config + +ynh_add_systemd_config +yunohost service add "$app" --description="Desktop you have accesss through your browser" --log="/var/log/$app/$app.log" + +ynh_use_logrotate --non-append #================================================= # START SYSTEMD SERVICE @@ -93,7 +87,7 @@ chown -R $app:$app "$install_dir" ynh_script_progression --message="Starting a systemd service..." # Start a systemd service -ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" +ynh_systemd_action --service_name="$app" --action="start" --log_path="/var/log/$app/$app.log" --line_match="Server listening on" #================================================= # END OF SCRIPT From 1f9cffdf50ad9e693194da514135163879f4485c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Tue, 6 Feb 2024 10:24:48 +0100 Subject: [PATCH 17/17] Fix sandboxing: disable @privileged --- conf/systemd.service | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/conf/systemd.service b/conf/systemd.service index 7c6d01c..83db3c9 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -1,5 +1,5 @@ [Unit] -Description=OS.js: web-desktop. +Description=OS.js: web-desktop. After=network.target [Service] @@ -33,7 +33,8 @@ ProtectKernelModules=yes ProtectKernelTunables=yes LockPersonality=yes SystemCallArchitectures=native -SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation +# @privileged # Denying access to capabilities that should not be relevant for webapps # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html