diff --git a/conf/app.src b/conf/app.src index ba24297..81423a9 100644 --- a/conf/app.src +++ b/conf/app.src @@ -1,5 +1,5 @@ -SOURCE_URL=https://github.com/flarum/flarum/archive/v0.1.0-beta.12.zip -SOURCE_SUM=E2C02B75D2A38F7AFD08DB981418ED1EE6604E450DFB87F0A0EF834687329631 +SOURCE_URL=https://github.com/flarum/flarum/archive/v0.1.0-beta.13.zip +SOURCE_SUM=D1BA09D2A871A16D193C88A05CC420CF66CCECD1E48C9AEDAC46D699AFE325ED SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=zip SOURCE_IN_SUBDIR=true diff --git a/manifest.json b/manifest.json index b2a898e..d0316c5 100644 --- a/manifest.json +++ b/manifest.json @@ -9,7 +9,7 @@ }, "url": "http://flarum.org/", "license": "MIT", - "version": "0.1.0-beta.12~ynh2", + "version": "0.1.0-beta.13~ynh1", "maintainer": { "name": "tituspijean", "email": "tituspijean@outlook.com" @@ -25,14 +25,22 @@ "arguments": { "install": [{ "name": "domain", - "type": "domain", + "type": "display_text", "ask": { - "en": "Choose a domain name for Flarum", - "fr": "Choisissez un nom de domaine pour Flarum", - "de": "Wählen einen Domain-Namen für Flarum" - }, - "example": "example.com" + "en": "The installation will add a 1 GB swap file if your system has less than 1 GB free RAM.", + "fr": "L'installation ajoutera un fichier swap de 1 Go si votre système a moins de 1 Go de RAM libre." + } }, + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain name for Flarum", + "fr": "Choisissez un nom de domaine pour Flarum", + "de": "Wählen einen Domain-Namen für Flarum" + }, + "example": "example.com" + }, { "name": "path", "type": "path", diff --git a/scripts/_common.sh b/scripts/_common.sh index 322792f..602f0d8 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -8,33 +8,25 @@ extra_pkg_dependencies="php7.3-curl php7.3-dom php7.3-gd php7.3-json php7.3-mbst # Version numbers php_version="7.3" -project_version="0.1.0-beta.12" -core_version="0.1.0-beta.12" -ssowat_version="0.1.0-beta.12" +project_version="~0.1.0-beta.13" +core_version="~0.1.0-beta.13" +ssowat_version="dev-0.1.0-beta.13" #================================================= # PERSONAL HELPERS #================================================= -# Install extension, and activate it in database -# usage: install_and_activate_extension $user $php_version $final_path $db_name $extension $short_extension -# $extension is the "vendor/extension-name" string from packagist +# Activate extension in Flarum's database +# usage: activate_flarum_extension $db_name $extension $short_extension # $short_extension is the extension name written in database, how it is shortened is still a mystery -install_and_activate_extension() { +activate_flarum_extension() { # Declare an array to define the options of this helper. - local legacy_args=uvwdes - declare -Ar args_array=( [u]=user= [v]=phpversion= [w]=workdir= [d]=database= [e]=extension= [s]=short_extension ) - local user - local phpversion - local workdir + local legacy_args=ds + declare -Ar args_array=( [d]=database= [s]=short_extension ) local database - local extension local short_extension # Manage arguments with getopts ynh_handle_getopts_args "$@" - user="${user:-$app}" - phpversion="${phpversion:-$php_version}" - workdir="${workdir:-$final_path}" database="${database:-$db_name}" local sql_command @@ -42,9 +34,6 @@ install_and_activate_extension() { local addition local new_extensions_enabled - # Install extension - ynh_composer_exec --user=$user --phpversion="${phpversion}" --workdir="$workdir" --commands="require $extension" - # Retrieve current extensions sql_command="SELECT \`value\` FROM settings WHERE \`key\` = 'extensions_enabled'" old_extensions_enabled=$(ynh_mysql_execute_as_root "$sql_command" $database | tail -1) @@ -55,7 +44,6 @@ install_and_activate_extension() { # Update activated extensions list sql_command="UPDATE \`settings\` SET \`value\`='$new_extensions_enabled' WHERE \`key\`='extensions_enabled';" ynh_mysql_execute_as_root "$sql_command" $database - } #================================================= diff --git a/scripts/experimental_helpers/hardware b/scripts/experimental_helpers/hardware new file mode 100644 index 0000000..afed28b --- /dev/null +++ b/scripts/experimental_helpers/hardware @@ -0,0 +1,109 @@ +#!/bin/bash + +# Get the total or free amount of RAM+swap on the system +# +# usage: ynh_get_ram [--free|--total] [--ignore_swap|--only_swap] +# | arg: -f, --free - Count free RAM+swap +# | arg: -t, --total - Count total RAM+swap +# | arg: -s, --ignore_swap - Ignore swap, consider only real RAM +# | arg: -o, --only_swap - Ignore real RAM, consider only swap +# | ret: the amount of free ram +# +# Requires YunoHost version 3.8.1 or higher. +ynh_get_ram () { + # Declare an array to define the options of this helper. + local legacy_args=ftso + local -A args_array=( [f]=free [t]=total [s]=ignore_swap [o]=only_swap ) + local free + local total + local ignore_swap + local only_swap + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + ignore_swap=${ignore_swap:-0} + only_swap=${only_swap:-0} + free=${free:-0} + total=${total:-0} + + if [ $free -eq $total ] + then + ynh_print_warn --message="You have to choose --free or --total when using ynh_get_ram" + ram=0 + # Use the total amount of ram + elif [ $free -eq 1 ] + then + local free_ram=$(vmstat --stats --unit M | grep "free memory" | awk '{print $1}') + local free_swap=$(vmstat --stats --unit M | grep "free swap" | awk '{print $1}') + local free_ram_swap=$(( free_ram + free_swap )) + + # Use the total amount of free ram + local ram=$free_ram_swap + if [ $ignore_swap -eq 1 ] + then + # Use only the amount of free ram + ram=$free_ram + elif [ $only_swap -eq 1 ] + then + # Use only the amount of free swap + ram=$free_swap + fi + elif [ $total -eq 1 ] + then + local total_ram=$(vmstat --stats --unit M | grep "total memory" | awk '{print $1}') + local total_swap=$(vmstat --stats --unit M | grep "total swap" | awk '{print $1}') + local total_ram_swap=$(( total_ram + total_swap )) + + local ram=$total_ram_swap + if [ $ignore_swap -eq 1 ] + then + # Use only the amount of free ram + ram=$total_ram + elif [ $only_swap -eq 1 ] + then + # Use only the amount of free swap + ram=$total_swap + fi + fi + + echo $ram +} + +# Return 0 or 1 depending if the system has a given amount of RAM+swap free or total +# +# usage: ynh_require_ram --required=RAM required in Mb [--free|--total] [--ignore_swap|--only_swap] +# | arg: -r, --required= - The amount to require, in Mb +# | arg: -f, --free - Count free RAM+swap +# | arg: -t, --total - Count total RAM+swap +# | arg: -s, --ignore_swap - Ignore swap, consider only real RAM +# | arg: -o, --only_swap - Ignore real RAM, consider only swap +# | exit: Return 1 if the ram is under the requirement, 0 otherwise. +# +# Requires YunoHost version 3.8.1 or higher. +ynh_require_ram () { + # Declare an array to define the options of this helper. + local legacy_args=rftso + local -A args_array=( [r]=required= [f]=free [t]=total [s]=ignore_swap [o]=only_swap ) + local required + local free + local total + local ignore_swap + local only_swap + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + # Dunno if that's the right way to do, but that's some black magic to be able to + # forward the bool args to ynh_get_ram easily? + # If the variable $free is not empty, set it to '--free' + free=${free:+--free} + total=${total:+--total} + ignore_swap=${ignore_swap:+--ignore_swap} + only_swap=${only_swap:+--only_swap} + + local ram=$(ynh_get_ram $free $total $ignore_swap $only_swap) + + if [ $ram -lt $required ] + then + return 1 + else + return 0 + fi +} diff --git a/scripts/experimental_helpers/ynh_add_swap b/scripts/experimental_helpers/ynh_add_swap new file mode 100644 index 0000000..d7ec44b --- /dev/null +++ b/scripts/experimental_helpers/ynh_add_swap @@ -0,0 +1,93 @@ +#!/bin/bash + +# Add swap +# +# usage: ynh_add_swap --size=SWAP in Mb +# | arg: -s, --size= - Amount of SWAP to add in Mb. +ynh_add_swap () { + # Declare an array to define the options of this helper. + declare -Ar args_array=( [s]=size= ) + local size + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + local swap_max_size=$(( $size * 1024 )) + + local free_space=$(df --output=avail / | sed 1d) + # Because we don't want to fill the disk with a swap file, divide by 2 the available space. + local usable_space=$(( $free_space / 2 )) + + SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0} + + # Swap on SD card only if it's is specified + if ynh_is_main_device_a_sd_card && [ "$SD_CARD_CAN_SWAP" == "0" ] + then + ynh_print_warn --message="The main mountpoint of your system '/' is on an SD card, swap will not be added to prevent some damage of this one, but that can cause troubles for the app $app. If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'" + return + fi + + # Compare the available space with the size of the swap. + # And set a acceptable size from the request + if [ $usable_space -ge $swap_max_size ] + then + local swap_size=$swap_max_size + elif [ $usable_space -ge $(( $swap_max_size / 2 )) ] + then + local swap_size=$(( $swap_max_size / 2 )) + elif [ $usable_space -ge $(( $swap_max_size / 3 )) ] + then + local swap_size=$(( $swap_max_size / 3 )) + elif [ $usable_space -ge $(( $swap_max_size / 4 )) ] + then + local swap_size=$(( $swap_max_size / 4 )) + else + echo "Not enough space left for a swap file" >&2 + local swap_size=0 + fi + + # If there's enough space for a swap, and no existing swap here + if [ $swap_size -ne 0 ] && [ ! -e /swap_$app ] + then + # Preallocate space for the swap file, fallocate may sometime not be used, use dd instead in this case + if ! fallocate -l ${swap_size}K /swap_$app + then + dd if=/dev/zero of=/swap_$app bs=1024 count=${swap_size} + fi + chmod 0600 /swap_$app + # Create the swap + mkswap /swap_$app + # And activate it + swapon /swap_$app + # Then add an entry in fstab to load this swap at each boot. + echo -e "/swap_$app swap swap defaults 0 0 #Swap added by $app" >> /etc/fstab + fi +} + +ynh_del_swap () { + # If there a swap at this place + if [ -e /swap_$app ] + then + # Clean the fstab + sed -i "/#Swap added by $app/d" /etc/fstab + # Desactive the swap file + swapoff /swap_$app + # And remove it + rm /swap_$app + fi +} + +# Check if the device of the main mountpoint "/" is an SD card +# +# [internal] +# +# return 0 if it's an SD card, else 1 +ynh_is_main_device_a_sd_card () { + local main_device=$(lsblk --output PKNAME --noheadings $(findmnt / --nofsroot --uniq --output source --noheadings --first-only)) + + if echo $main_device | grep --quiet "mmc" && [ $(tail -n1 /sys/block/$main_device/queue/rotational) == "0" ] + then + return 0 + else + return 1 + fi +} diff --git a/scripts/experimental_helpers/ynh_composer b/scripts/experimental_helpers/ynh_composer index 0d87a79..7b20dce 100644 --- a/scripts/experimental_helpers/ynh_composer +++ b/scripts/experimental_helpers/ynh_composer @@ -2,7 +2,8 @@ # Execute a command with Composer # -# usage: ynh_composer_exec [--phpversion=phpversion] [--workdir=$final_path] --commands="commands" +# usage: ynh_composer_exec [--user=$app] [--phpversion=phpversion] [--workdir=$final_path] --commands="commands" +# | arg: -u, --user - User to perform the action with # | arg: -v, --phpversion - PHP version to use with composer # | arg: -w, --workdir - The directory from where the command will be executed. Default $final_path. # | arg: -c, --commands - Commands to execute. @@ -22,15 +23,16 @@ ynh_composer_exec () { exec_as $user COMPOSER_HOME="$workdir/.composer" \ php${phpversion} "$workdir/composer.phar" $commands \ - -d "$workdir" --quiet --no-interaction + -d "$workdir" --no-interaction --ansi } # Install and initialize Composer in the given directory # -# usage: ynh_install_composer [--phpversion=phpversion] [--workdir=$final_path] [--install_args="--optimize-autoloader"] +# usage: ynh_install_composer [--user=$app] [--phpversion=phpversion] [--workdir=$final_path] [--install_args="--optimize-autoloader"] +# | arg: -u, --user - User to perform the action with # | arg: -v, --phpversion - PHP version to use with composer # | arg: -w, --workdir - The directory from where the command will be executed. Default $final_path. -# | arg: -a, --install_args - Additional arguments provided to the composer install. Argument --no-dev already include +# | arg: -a, --install_args - Additional arguments provided to the composer install. Argument --no-dev already included ynh_install_composer () { # Declare an array to define the options of this helper. local legacy_args=uvwa @@ -46,12 +48,12 @@ ynh_install_composer () { phpversion="${phpversion:-7.0}" install_args="${install_args:-}" - exec_as $user COMPOSER_HOME="$workdir/.composer" \ curl -sS https://getcomposer.org/installer \ - | php${phpversion} -- --quiet --install-dir="$workdir" \ + | exec_as $user COMPOSER_HOME="$workdir/.composer" \ + php${phpversion} -- --install-dir="$workdir" \ || ynh_die "Unable to install Composer." # update dependencies to create composer.lock - ynh_composer_exec --user=$user --phpversion="${phpversion}" --workdir="$workdir" --commands="install --no-dev $install_args" \ - || ynh_die "Unable to update core dependencies with Composer." + #ynh_composer_exec --user=$user --phpversion="${phpversion}" --workdir="$workdir" --commands="install --no-dev $install_args" \ + # || ynh_die "Unable to update core dependencies with Composer." } diff --git a/scripts/install b/scripts/install index c127d98..7cd9852 100644 --- a/scripts/install +++ b/scripts/install @@ -12,6 +12,8 @@ source experimental_helpers/ynh_install_php source experimental_helpers/ynh_exec_as source experimental_helpers/ynh_composer source experimental_helpers/ynh_send_readme_to_admin +source experimental_helpers/hardware +source experimental_helpers/ynh_add_swap source /usr/share/yunohost/helpers #================================================= @@ -19,8 +21,8 @@ source /usr/share/yunohost/helpers #================================================= ynh_clean_setup () { - ### Remove this function if there's nothing to clean before calling the remove script. - true + ### Remove this function if there's nothing to clean before calling the remove script. + true } # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -67,6 +69,16 @@ ynh_webpath_available $domain $path_url # Register (book) web path ynh_webpath_register $app $domain $path_url +#=================================================== +# CHECK IF THE APP CAN BE INSTALLED WITH CURRENT RAM +#=================================================== +ynh_script_progression --message="Ensuring sufficient memory..." --time --weight=1 + +# Check RAM +if [[ $(ynh_get_ram --free) < 1000 ]]; then + ynh_add_swap --size=1000 +fi + #=================================================== # STORE SETTINGS FROM MANIFEST #=================================================== @@ -76,7 +88,6 @@ ynh_app_setting_set $app domain $domain ynh_app_setting_set $app path $path_url ynh_app_setting_set $app admin $admin ynh_app_setting_set $app language $language -ynh_app_setting_set $app final_path $final_path ynh_app_setting_set $app php_version $php_version ynh_app_setting_set $app project_version $project_version ynh_app_setting_set $app core_version $core_version @@ -90,10 +101,10 @@ ynh_app_setting_set $app bazaar_extension $bazaar_extension #================================================= if [ "$(lsb_release --codename --short)" = "buster" ]; then - pkg_dependencies="$pkg_dependencies $extra_pkg_dependencies" + pkg_dependencies="$pkg_dependencies $extra_pkg_dependencies" else - ynh_script_progression --message="Installing php${php_version}..." --time --weight=1 - ynh_install_php --phpversion="${php_version}" --package="$extra_pkg_dependencies" + ynh_script_progression --message="Installing php${php_version}..." --time --weight=1 + ynh_install_php --phpversion="${php_version}" --package="$extra_pkg_dependencies" fi #================================================= @@ -115,11 +126,7 @@ ynh_app_setting_set "$app" db_pwd "$db_pwd" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -ynh_script_progression --message="Setting up source files..." --time --weight=1 - -### `ynh_setup_source` is used to install an app from a zip or tar.gz file, -### downloaded from an upstream source, like a git repository. -### `ynh_setup_source` use the file conf/app.src +ynh_script_progression --message="Setting up source files..." --weight=7 ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src @@ -146,8 +153,6 @@ ynh_script_progression --message="Configuring system user..." --time --weight=1 # Create a system user ynh_system_user_create $app $final_path -# Adding it to www-data group -usermod -a -G www-data $app #================================================= # PHP-FPM CONFIGURATION @@ -157,30 +162,28 @@ usermod -a -G www-data $app ynh_add_fpm_config $php_version #================================================= -# COMPOSER INSTALLATION +# INSTALL AND INITIALIZE COMPOSER #================================================= -ynh_script_progression --message="Installing Composer and Flarum..." --time --weight=1 +ynh_script_progression --message="Installing Flarum with Composer..." --time --weight=1 -# Set right permissions +# Create composer directory and making sure it is writable +mkdir -p "$final_path/.composer" chown -R $app: $final_path -chmod -R 775 $final_path -# Install Composer and Flarum +# Installing composer ynh_install_composer --user=$app --phpversion=$php_version --workdir=$final_path -#================================================= -# SECURE FILES AND DIRECTORIES -#================================================= +# Set Flarum version +ynh_composer_exec --user=$app --phpversion=$php_version --workdir=$final_path \ + --commands="require flarum/core:$core_version --prefer-lowest --no-update" -### For security reason, any app should set the permissions to root: before anything else. -### Then, if write authorization is needed, any access should be given only to directories -### that really need such authorization. - -# Set right permissions -chown -R $app: $final_path -chown -R $app:www-data $final_path/storage -chmod -R 775 $final_path +# Require SSOwat extension +ynh_composer_exec --user=$app --phpversion=$php_version --workdir=$final_path \ + --commands="require tituspijean/flarum-ext-auth-ssowat:$ssowat_version --no-update" +# Update and download dependencies +ynh_composer_exec --user=$app --phpversion=$php_version --workdir=$final_path \ + --commands="update" #================================================= # SETUP LOGROTATE @@ -197,9 +200,9 @@ ynh_script_progression --message="Configuring permissions..." --time --weight=1 # Make app public if necessary 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" + # Everyone can access the app. + # The "main" permission is automatically created before the install script. + ynh_permission_update --permission "main" --add "visitors" fi #================================================= @@ -216,7 +219,7 @@ ynh_script_progression --message="Configuring Flarum..." --time --weight=2 # Copy the configuration.yml to working directory finalflarumconf="$final_path/configuration.yml" cp ../conf/configuration.yml $finalflarumconf -chown $app:www-data $finalflarumconf +chown $app: $finalflarumconf # Generate admin password and retrieve their email address admin_pwd=$(ynh_string_random 8) admin_mail=$(ynh_user_get_info $admin mail) @@ -245,10 +248,9 @@ sql_command="REPLACE INTO \`settings\` (\`key\`, \`value\`) VALUES ('mail_port', '587');" ynh_mysql_execute_as_root "$sql_command" $db_name -# Install and activate the SSOwat auth extension -ynh_script_progression --message="Installing SSOwat extension..." --time --weight=2 -install_and_activate_extension $app $php_version $final_path $db_name "tituspijean/flarum-ext-auth-ssowat:$ssowat_version" "tituspijean-auth-ssowat" -# Configure SSOwat auth extension +# Enable and set up the SSOwat auth extension +ynh_script_progression --message="Enabling and configuring SSOwat extension..." --time --weight=2 +activate_flarum_extension $db_name "tituspijean-auth-ssowat" ssowatdomain=$(