From b7c721266e245eadd8f4e1bb90552278f6f9ebde Mon Sep 17 00:00:00 2001 From: oiseauroch Date: Thu, 24 Nov 2022 00:22:09 +0100 Subject: [PATCH] improve package and begin to add config panel --- check_process | 2 +- conf/garage.toml | 6 +-- config_panel.toml | 26 ++++++++++++ config_panel.toml.example | 8 ++-- hooks/post_conf_regen | 10 ----- hooks/regen_conf | 10 +++++ manifest.json | 4 +- scripts/_common.sh | 29 +++++++------ scripts/config | 89 +++++++-------------------------------- scripts/install | 25 +++++++---- scripts/restore | 15 +++---- 11 files changed, 100 insertions(+), 124 deletions(-) create mode 100644 config_panel.toml delete mode 100644 hooks/post_conf_regen create mode 100644 hooks/regen_conf diff --git a/check_process b/check_process index 1fce29e..efe6b7b 100644 --- a/check_process +++ b/check_process @@ -17,7 +17,7 @@ upgrade=1 upgrade=1 from_commit=CommitHash backup_restore=1 - multi_instance=0 + multi_instance=1 port_already_use=0 change_url=1 ;;; Options diff --git a/conf/garage.toml b/conf/garage.toml index beb3a68..a990a42 100644 --- a/conf/garage.toml +++ b/conf/garage.toml @@ -13,11 +13,9 @@ rpc_secret = "__RPC_SECRET__" rpc_bind_addr = "[::]:__PORT__" # Le port peut être différent (eg NAT) mais doit rediriger sur le # port de rpc_bind_addr -#rpc_public_addr = "__IP__:__PORT__" +#rpc_public_addr = "__DOMAIN__:__PORT__" -bootstrap_peers = [ - __BOOTSTRAP_PEERS_VAR__ -] +bootstrap_peers = [] [s3_api] # Ne supporte pas TLS → reverse proxy obligatoire diff --git a/config_panel.toml b/config_panel.toml new file mode 100644 index 0000000..6c7472c --- /dev/null +++ b/config_panel.toml @@ -0,0 +1,26 @@ +version = "1.0" +[main] + +services = ["__APP__"] + + [main.garage_conf] + name = "Garage configuration" + + [main.garage_conf.rpc_secret] + ask.en = "Choose rpc secret" + type = "string" + bind = "rpc_secret:/opt/yunohost/__APP__/garage.toml" + pattern.regexp = '^[0-9a-f]{64}$' + pattern.error = "rpc_secret have to be a 32-byte hex-encoded random string. See https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/ for more information" + + + [main.garage_conf.weight] + ask.en = "allocated space (Gio)" + type = "number" + bind = "weight()" + + [main.garage_conf.bootstrap_peers] + ask.en = "Friend serveur adress" + type = "string" + pattern.regexp = '[0-9a-f]{64}@((\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}):[0-9]{1,4}' + pattern.error = "friend server id must have id with the following form : 1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec@192.168.1.1:1234 or 1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec@example.tld:1234" diff --git a/config_panel.toml.example b/config_panel.toml.example index c6bccd8..752051a 100644 --- a/config_panel.toml.example +++ b/config_panel.toml.example @@ -89,7 +89,7 @@ services = ["__APP__"] ## (optional) By default all questions are optionals, but you can specify a ## default behaviour for question in the section - optional = false + ##optional = false ## (optional) It's also possible with the 'visible' property to only ## display the section depending on the user's answers to previous questions. @@ -118,14 +118,14 @@ services = ["__APP__"] ## extend availables questions types list. ## See: TODO DOC LINK - [main.customization.project_name] + [main.customization.weight] ## (required) The ask property is equivalent to the ask property in ## the manifest. However, in config panels, questions are displayed on the ## left side and therefore have less space to be rendered. Therefore, ## it is better to use a short question, and use the "help" property to ## provide additional details if necessary. - ask.en = "Name of the project" + ask.en = "allocated space" ## (required) The type property indicates how the question should be ## displayed, validated and managed. Some types have specific properties. @@ -134,7 +134,7 @@ services = ["__APP__"] ## email, url, date, time, color, select, domain, user, tags, file. ## ## For a complete list with specific properties, see: TODO DOC LINK - type = "string" + type = "number" ######################################################################## #### ABOUT THE BIND PROPERTY diff --git a/hooks/post_conf_regen b/hooks/post_conf_regen deleted file mode 100644 index fc17803..0000000 --- a/hooks/post_conf_regen +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -source /usr/share/yunohost/helpers - - -action=$1 -domain=__DOMAIN__ - -ynh_replace_string --match_string="server_name $domain" --replace_string="server_name $domain *.$domain" --target_file="/etc/nginx/conf.d/$domain.conf" -ynh_store_file_checksum --file="/etc/nginx/conf.d/$domain.conf" diff --git a/hooks/regen_conf b/hooks/regen_conf new file mode 100644 index 0000000..ebfcbf5 --- /dev/null +++ b/hooks/regen_conf @@ -0,0 +1,10 @@ +#!/bin/bash + +source /usr/share/yunohost/helpers + + +action=$1 +domain=__DOMAIN__ + +ynh_replace_special_string --match_string="server_name $domain" --replace_string="server_name $domain *.$domain" --target_file="/etc/nginx/conf.d/$domain.conf" +ynh_store_file_checksum --file="/etc/nginx/conf.d/$domain.conf" diff --git a/manifest.json b/manifest.json index a034b2d..b87e0bc 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "en": "S3 storage", "fr": "stockage S3" }, - "version": "0.7.3~ynh1", + "version": "0.8.0~ynh1", "url": "https://garagehq.deuxfleurs.fr/", "upstream": { "license": "AGPL-3.0-only", @@ -24,7 +24,7 @@ "requirements": { "yunohost": ">= 4.3.0" }, - "multi_instance": false, + "multi_instance": true, "arguments": { "install": [ { diff --git a/scripts/_common.sh b/scripts/_common.sh index 5130faa..3482f2e 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -10,7 +10,7 @@ pkg_dependencies_virtualisation="qemu-utils" #================================================= -GARAGE_VERSION="0.7.3" +GARAGE_VERSION="0.8.0" get_ip() { curl ip.me @@ -41,25 +41,28 @@ install_garage () { chmod +x garage } -init_garage() { -garage_command="$1" -node_id="$2" -weight="$3" -zone="$4" - -$garage_command layout assign $node_id -z $zone -c $weight -t $zone - -apply_layout "$garage_command" +garage_connect() { + local command="$1" + local peer="$2" + # connect to cluster + $garage_command node connect "$peer" + # wait until layout is updated + until $garage_command layout show 2>/dev/null | grep "${peer:0:15}"; do + sleep 1 + done } + apply_layout() { + garage_command=$1 - - if [ $($garage_command -c garage.toml layout show 2>/dev/null | grep -- --version) ] + $garage_command layout show 2>/dev/null + local layout_version=$($garage_command layout show 2>/dev/null | grep -Po -- "(?<=--version).*" | head -1 | xargs) + if [ "$layout_version" != "" ] then - layout_version=$($garage_command layout show 2>/dev/null | grep -Po -- "(?<=--version).*" | head -1 | xargs) $garage_command layout apply --version $layout_version else + ynh_print_warn --message="unable to apply layout. No enough nodes" return 0 fi } diff --git a/scripts/config b/scripts/config index f517e58..44322b9 100644 --- a/scripts/config +++ b/scripts/config @@ -1,19 +1,11 @@ #!/bin/bash -# In simple cases, you don't need a config script. - -# With a simple config_panel.toml, you can write in the app settings, in the -# upstream config file or replace complete files (logo ...) and restart services. - -# The config scripts allows you to go further, to handle specific cases -# (validation of several interdependent fields, specific getter/setter for a value, -# display dynamic informations or choices, pre-loading of config type .cube... ). - #================================================= # GENERIC STARTING #================================================= # IMPORT GENERIC HELPERS #================================================= +source _common.sh source /usr/share/yunohost/helpers ynh_abort_if_errors @@ -23,80 +15,31 @@ ynh_abort_if_errors #================================================= final_path=$(ynh_app_setting_get $app final_path) -datadir=$(ynh_app_setting_get $app datadir) +node_id=$(ynh_app_setting_get $app node_id) +command="$final_path/garage -c $final_path/garage.toml" -#================================================= -# SPECIFIC GETTERS FOR TOML SHORT KEY -#================================================= - -get__amount() { - # Here we can imagine to have an API call to stripe to know the amount of donation during a month - local amount = 200 - - # It's possible to change some properties of the question by overriding it: - if [ $amount -gt 100 ] - then - cat << EOF -style: success -value: $amount -ask: - en: A lot of donation this month: **$amount €** -EOF - else - cat << EOF -style: danger -value: $amount -ask: - en: Not so much donation this month: $amount € -EOF - fi +get_weight() { + ynh_app_setting_get --app=$app --key=weight } -get__prices() { - local prices = "$(grep "DONATION\['" "$final_path/settings.py" | sed -r "s@^DONATION\['([^']*)'\]\['([^']*)'\] = '([^']*)'@\1/\2/\3@g" | sed -z 's/\n/,/g;s/,$/\n/')" - if [ "$prices" == "," ]; - then - # Return YNH_NULL if you prefer to not return a value at all. - echo YNH_NULL - else - echo $prices - fi +set_weight() { + $command layout assign $node_id -c $weight + apply_layout "$command" + ynh_app_setting_set --app=$app --key=weight --value=$weight } -#================================================= -# SPECIFIC VALIDATORS FOR TOML SHORT KEYS -#================================================= -validate__publishable_key() { - - # We can imagine here we test if the key is really a publisheable key - (is_secret_key $publishable_key) && - echo 'This key seems to be a secret key' +get_peers() { + ynh_app_setting_get --app=$app --key=bootstrap_peers } -#================================================= -# SPECIFIC SETTERS FOR TOML SHORT KEYS -#================================================= -set__prices() { - - #--------------------------------------------- - # IMPORTANT: setter are trigger only if a change is detected - #--------------------------------------------- - for price in $(echo $prices | sed "s/,/ /"); do - frequency=$(echo $price | cut -d/ -f1) - currency=$(echo $price | cut -d/ -f2) - price_id=$(echo $price | cut -d/ -f3) - sed "d/DONATION\['$frequency'\]\['$currency'\]" "$final_path/settings.py" - - echo "DONATION['$frequency']['$currency'] = '$price_id'" >> "$final_path/settings.py" - done - - #--------------------------------------------- - # IMPORTANT: to be able to upgrade properly, you have to saved the value in settings too - #--------------------------------------------- - ynh_app_setting_set $app prices $prices +set_peers() { + garage_connect "$command" "$bootstrap_peers" + apply_layout "$command" + ynh_app_setting_set --app=$app --key=bootstrap_peers --value=$bootstrap_peers } + #================================================= # GENERIC FINALIZATION #================================================= diff --git a/scripts/install b/scripts/install index b86e3aa..b83268d 100755 --- a/scripts/install +++ b/scripts/install @@ -73,10 +73,7 @@ else fi if [ -n "$bootstrap_peers" ] then - echo "$bootstrap_peers" | grep -E '[0-9a-f]{64}@(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}:3901' || ynh_die --message="friend server id must have id with the following form : 1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec@192.168.1.1:3901" - bootstrap_peers_var="\"$bootstrap_peers\"," -else - bootstrap_peers_var="" + echo "$bootstrap_peers" | grep -E '[0-9a-f]{64}@((\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}):[0-9]{1,4}' || ynh_die --message="friend server id must have id with the following form : 1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec@192.168.1.1:1234 or 1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec@example.tld:1234" fi if [ "$datadir" = "/home/yunohost.app/__APP_NAME__/data" ] @@ -109,6 +106,7 @@ ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=rpc_secret --value=$rpc_secret ynh_app_setting_set --app=$app --key=datadir --value=$datadir ynh_app_setting_set --app=$app --key=bootstrap_peers --value=$bootstrap_peers +ynh_app_setting_set --app=$app --key=weight --value=$weight #================================================= @@ -135,6 +133,7 @@ port_admin=$(ynh_find_port --port=7000) ynh_app_setting_set --app=$app --key=port_admin --value=$port_admin ynh_print_warn --message="port : $port port_api : $port_api port_web : $port_web port_admin : $port_admin" +nbd_index=127 # Optional: Expose this port publicly @@ -208,7 +207,7 @@ ynh_script_progression --message="Configuring NGINX web server..." --time --weig ynh_add_nginx_config #add wildcard subdomain -ynh_replace_string --match_string="server_name $domain" --replace_string="server_name $domain *.$domain" --target_file="/etc/nginx/conf.d/$domain.conf" +ynh_replace_special_string --match_string="server_name $domain" --replace_string="server_name $domain *.$domain" --target_file="/etc/nginx/conf.d/$domain.conf" ynh_store_file_checksum --file="/etc/nginx/conf.d/$domain.conf" #================================================= # SPECIFIC SETUP @@ -272,7 +271,7 @@ mkdir -p $datadir/data #================================================= # create data partition #================================================= -nbd_index=127 + if [ "$virtualisation" = "true" ] then # to be sure to not exceed size limit, i use a virtual disk with a fix size to have a max limit size. @@ -407,11 +406,19 @@ ynh_script_progression --message="Configuring garage..." --time --weight=1 garage_command="$final_path/garage -c $final_path/garage.toml" -node_id=$($garage_command node id -q | cut -d '@' -f1) -ynh_app_setting_set --app=$app --key=node_id --value=node_id +node_id=$($garage_command node id -q 2>/dev/null | cut -d '@' -f1) +ynh_app_setting_set --app=$app --key=node_id --value=$node_id -init_garage "$garage_command" "$node_id" "$weight" "$domain" +if [ -n "$bootstrap_peers" ] +then + garage_connect "$garage_command" "$bootstrap_peers" +fi + +# define node +$garage_command layout assign $node_id -z $domain -c $weight -t $domain +# if there is enough node, apply layout +apply_layout "$garage_command" #================================================= # Send email to admin diff --git a/scripts/restore b/scripts/restore index 9cb8a3a..75cf27f 100755 --- a/scripts/restore +++ b/scripts/restore @@ -32,7 +32,7 @@ domain=$(ynh_app_setting_get --app=$app --key=domain) final_path=$(ynh_app_setting_get --app=$app --key=final_path) datadir=$(ynh_app_setting_get --app=$app --key=datadir) virtualisation=$(ynh_app_setting_get --app=$app --key=virtualisation) - +bootstrap_peers=$(ynh_app_setting_get --app=$app --key=bootstrap_peers) #================================================= # CHECK IF THE APP CAN BE RESTORED @@ -86,8 +86,6 @@ then ynh_app_setting_set --app=$app --key=nbd_index --value=$nbd_index fi -#ynh_restore_file --origin_path="$datadir/data" --not_mandatory - # FIXME: this should be managed by the core in the future # Here, as a packager, you may have to tweak the ownerhsip/permissions @@ -102,10 +100,6 @@ chown -R $app:$app "$datadir" #================================================= # SPECIFIC RESTORATION #================================================= -# REINSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Reinstalling dependencies..." --time --weight=1 - # Open the port ynh_script_progression --message="Configuring firewall..." --time --weight=1 @@ -118,7 +112,7 @@ ynh_script_progression --message="Restoring the NGINX web server configuration.. ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #add wildcard subdomain -ynh_replace_string --match_string="server_name $domain" --replace_string="server_name $domain *.$domain" --target_file="/etc/nginx/conf.d/$domain.conf" +ynh_replace_special_string --match_string="server_name $domain" --replace_string="server_name $domain *.$domain" --target_file="/etc/nginx/conf.d/$domain.conf" #================================================= @@ -158,6 +152,11 @@ weight=$(ynh_app_setting_get --app=$app --key=weight) garage_command="$garage_path/garage -c $garage_path/garage.toml" +if [ -n "$bootstrap_peers" ] +then + $garage_command id connect "$bootstrap_peers" +fi + init_garage "$garage_command" "$node_id" "$weight" "$domain" #=================================================