diff --git a/README.md b/README.md index 57e9f1139383ddbb33ac1738be4a60976e583e5a..1c7d212a8b312aebdfb81932e04011d3bc94c5b2 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,40 @@ -# Neutrinet YunoHost App +# Overview -This application is for Neutrinet members that have an Internet Cube configured has expected. - -For now it does 2 things: - -* fixed the situation where your certificate is outdated -* install neutrinet app list for YunoHost so you get updates for this app -* install labrique internet/internet cube app list for YunoHost so you get updates for this app +The neutrinet application is for Neutrinet members that have an Internet Cube configured and does 2 things: +* It renews the vpn-certificates +* Adds a webpage with genral information about Neutrinet # Installation +## From the webinterface -Either put `https://github.com/neutrinet/neutrinet_ynh` in the administration interface at the bottom of the installation page or do this command in ssh: - - yunohost app install https://github.com/Neutrinet/neutrinet_ynh --verbose +First make sure you have the neutrinet_app list +1. Go to the admin interface on your cube +2. Click *Applications* > *Install* > At the bottom click *Manage application lists* > Check in the Application list if you have *neutrinet* +3. If you don't have it > under Custom applications lists you give *neutrinet* under Name. Under URL you give *https://neutrinet.be/apps.json* > Add +The we can install the application +1. Click *Applications* at the top of the page +2. click *Install* > select *All apps* > search for *neutrinet*> click *Install* > Fill in the form (or just keep the defaults) and press Install just like you would install any app from the webinterface -# Known and "normal" warning/error messages during installation +## From the CLI -If you see those, don't worry, it's not a bug. +First check if you have a list, probably named *neutrinet*, with *https://neutrinet.be/apps.json* as url. -After `+ sudo virtualenv ve --system-site-packages` +`yunohost app listlists` - Compiling /tmp/pip-build-0Vk8QK/pexpect/pexpect/async.py ... - File "/tmp/pip-build-0Vk8QK/pexpect/pexpect/async.py", line 16 - transport, pw = yield from asyncio.get_event_loop()\ - ^ - SyntaxError: invalid syntax +If you don't have the list yet, you can add it using -This is due to the fact that we don't use python3 but python2 and that doesn't change anything here. +`yunohost app fetchlist --name neutrinet -u https://neutrinet.be/apps.json` -After `Running command 'yunohost app setting vpnclient login_passphrase -v "xxxxxxxxxxxxxxxxxxxxx"' ... done` +Once you have the list, you can install the app using - Failed to open /dev/tty: No such device or address - Failed to open /dev/tty: No such device or address - Failed to open /dev/tty: No such device or address - Failed to open /dev/tty: No such device or address - Failed to open /dev/tty: No such device or address - Failed to open /dev/tty: No such device or address - Failed to open /dev/tty: No such device or address +`yunohost app install neutrinet --debug` -It doesn't prevent the script from running. +# For contributers +## Publish a new version of the app -# Publish a new version of the app +* Edit the [manifest](manifest.json) file to bump the version +* Edit the [upgrade](scripts/upgrade) script with the needed upgrades for previous installations +* Test the updated version both for new installs and upgrades and make sure the other scripts ([backup](scripts/backup), [remove](scripts/remove) and [upgrade](scripts/upgrade)) also still work +* In the [apps.json](https://neutrinet.be/apps.json) file you must update the `revision` with the current `sha` on the `master` branch of the package and update the `lastUpdate` field. If you added things to the manifest file, you should add these changes ass well -- edit the [upgrade](scripts/upgrade) script to bump the version -- update the `revision` with the current `sha` on the `master` branch, update the `lastUpdate` field in the [apps.json](https://neutrinet.be/apps.json) file -- test the updated version: - - check current version of the app on your cube: `yunohost app setting neutrinet version` - - update the app with the latest version from master: `yunohost app upgrade neutrinet -u https://github.com/Neutrinet/neutrinet_ynh` - - check the app has been updated: `yunohost app setting neutrinet version` - - set the app to a previous version if you want to re-test the update: `yunohost app setting neutrinet version -v "0.2.2"` diff --git a/conf/nginx.conf b/conf/nginx.conf index 9a7521751a7fb71f9a20e8e5923a3a247cc9fa7d..1ab95fd1ed169118c6196f7f405f214b6481ea0b 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,9 +1,4 @@ location PATHTOCHANGE/ { alias ALIASTOCHANGE; - - if ($scheme = http) { - rewrite ^ https://$server_name$request_uri? permanent; - } - index index.html; } diff --git a/manifest.json b/manifest.json index 0440ae80def42894f315fc68b018f5770e2aa4cb..821eb7831ba38809255b83aa2abcc1a44f932f69 100644 --- a/manifest.json +++ b/manifest.json @@ -2,20 +2,28 @@ "name": "Neutrinet", "id": "neutrinet", "description": { - "en": "Specific configs for Neutrinet", - "fr": "Application gérant les configurations spécifiques à Neutrinet" + "en": "Auto renewall for the Neutrinet vpn-certificates", + "fr": "Renouvellement automatique des certificats vpn Neutrinet" }, + "version": "0.3.0~ynh1", "license": "GPL-3+", "maintainer": { - "name": "bram", - "email": "cortex@worlddomination.be", - "url": "http://worlddomination.be" + "name": "ilja", + "email": "neutrinet@spectraltheorem.be", + "url": "https://gitlab.com/Spctrl" + }, + "requirements": { + "yunohost": ">= 3.2.0" }, "multi_instance": "false", + "services": [ + "nginx" + ], "arguments": { "install" : [ { "name": "domain", + "type": "domain", "ask": { "en": "Choose a domain for Neutrinet application", "fr": "Choisissez un domaine pour l'application Neutrinet" @@ -23,7 +31,8 @@ "example": "domain.org" }, { - "name": "path", + "name": "path_url", + "type": "path", "ask": { "en": "Choose a path for Neutrinet application", "fr": "Choisissez un chemin pour l'application Neutrinet" diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000000000000000000000000000000000000..05a7907cf5a4a5927d09b1e964aae97a096908f6 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,2 @@ +#!/bin/bash + diff --git a/scripts/backup b/scripts/backup new file mode 100644 index 0000000000000000000000000000000000000000..fcb05517839230ff6fe8f3f73f925bcef6241567 --- /dev/null +++ b/scripts/backup @@ -0,0 +1,43 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source /usr/share/yunohost/helpers +source _common.sh + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path_url) +app_user=$(ynh_app_setting_get $app app_user) +www_path=$(ynh_app_setting_get $app www_path) +opt_path=$(ynh_app_setting_get $app opt_path) + +#================================================= +# STANDARD BACKUP STEPS +#================================================= +# BACKUP THE NGINX CONFIGURATION +#================================================= + +ynh_print_info "Backing up..." + +ynh_backup "$www_path" +ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" + +ynh_backup "$opt_path" +ynh_backup "/etc/cron.daily/$app-renew-cert" + diff --git a/scripts/commons b/scripts/commons deleted file mode 100644 index 81d500f1c57e0a436ef777497e0720c4ab863fb6..0000000000000000000000000000000000000000 --- a/scripts/commons +++ /dev/null @@ -1,9 +0,0 @@ -RENEW_CERT_PATH=/opt/neutrinet/renew_cert - -get_out_of_testing() { - set -e - - if [ -e /etc/apt/sources.list.d/yunohost.list ]; then - sudo sed -ri 's#^(deb http://repo\.yunohost\.org/debian[/]? jessie) (stable )?testing#\1 stable#g' /etc/apt/sources.list.d/yunohost.list - fi -} diff --git a/scripts/install b/scripts/install index d2a09468708fcde0f5d35c6929cbd135317ae492..38da0037207a85c193ec059ae21edb328d3a4c51 100644 --- a/scripts/install +++ b/scripts/install @@ -1,101 +1,156 @@ -set -e +#!/bin/bash -source ./commons +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Retrieve arguments -domain=$1 -path=$2 +source /usr/share/yunohost/helpers +source _common.sh -path=${path%/} +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= -# Check domain/path availability -sudo yunohost app checkurl $domain$path -a neutrinet -if [[ ! $? -eq 0 ]]; then - exit 1 +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH_URL +app=$YNH_APP_INSTANCE_NAME +app_user=$app + +#================================================== +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================== + +www_path=/var/www/$app +if [[ -e $www_path ]] +then + ynh_die "The path $www_path already contains a folder" fi -install_static_file() { - set -e +opt_path=/opt/$app +if [[ -e $opt_path ]] +then + ynh_die "The path $opt_path already contains a folder" +fi - final_path=/var/www/neutrinet/ - sudo mkdir -p $final_path - sudo cp -a ../sources/. $final_path +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path $path_url) - sudo chown -R www-data: $final_path +# Check web path availability +if ! ynh_webpath_available $domain $path_url +then + ynh_die "$domain$path_url is not available" +fi - if [[ "$path" == "" ]]; then - sed -i "s@PATHTOCHANGE@/@g" ../conf/nginx.conf - else - sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf - fi +# Register (book) web path +ynh_webpath_register $app $domain $path_url - sed -i "s@ALIASTOCHANGE@$final_path@g" ../conf/nginx.conf +#================================================= +# STORE SETTINGS +#================================================= - sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/neutrinet.conf +ynh_app_setting_set $app domain $domain +ynh_app_setting_set $app path_url $path_url +ynh_app_setting_set $app app_user $app_user +ynh_app_setting_set $app www_path $www_path +ynh_app_setting_set $app opt_path $opt_path - sudo service nginx reload -} +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# INSTALL DEPENDENCIES +#================================================= -install_renew_cert() { - set -e +ynh_print_info "Installing dependencies…" - install_dir=$(pwd) +ynh_install_app_dependencies git python3-venv libssl-dev libffi-dev python3-dev - if [ -e $RENEW_CERT_PATH ]; then - sudo rm -rf $RENEW_CERT_PATH - fi +#================================================= +# CREATE DEDICATED USER +#================================================= - sudo apt-get update - sudo apt-get install -y python-virtualenv +ynh_print_info "Creating app's user…" - sudo git clone https://github.com/neutrinet/renew_cert $RENEW_CERT_PATH +mkdir -p $www_path +ynh_system_user_create $app_user $www_path - cd $RENEW_CERT_PATH +#================================================= +# INSTALL STATIC FILE +#================================================= - sudo git checkout ccc5b6b58010bb4166c2ae1a72df340395827f99 || echo "" +ynh_print_info "Installing static site…" - # I need system site packages otherwise moulinette is broken - sudo virtualenv ve --system-site-packages - sudo ve/bin/pip install -r requirements.txt +cp -a ../sources/. $www_path +chown -R $app_user: $www_path - cd $install_dir -} +sed -i "s@PATHTOCHANGE@$path_url@g" ../conf/nginx.conf +sed -i "s@ALIASTOCHANGE@$www_path@g" ../conf/nginx.conf -renew_cert() { - set -e +cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf - install_dir=$(pwd) +nginx -tq +service nginx reload - cd $RENEW_CERT_PATH - sudo ve/bin/python renew_from_cube.py +#================================================= +# INSTALL RENEW CERT +#================================================= - cd $install_dir -} +renew_cert_repo="https://github.com/neutrinet/renew_cert" +renew_cert_version=$(jq .version ../manifest.json -r -e | cut -d '~' -f 1) +renew_cert_path="$opt_path/renew_cert" +renew_cert_virtualenv="$renew_cert_path/ve" +renew_cert_python="$renew_cert_virtualenv/bin/python3" +renew_cert_cron_script="renew_cert_cron.sh" -install_neutrinet_apps_list() { - if ! sudo yunohost app listlists | grep -q "neutrinet:"; then - sudo yunohost app fetchlist -n neutrinet -u https://neutrinet.be/apps.json - fi -} +ynh_print_info "Installing automatic VPN certificate renewal…" -install_labriqueinternet_apps_list() { - if ! sudo yunohost app listlists | grep -q "labriqueinternet:"; then - sudo yunohost app fetchlist -n labriqueinternet -u https://labriqueinter.net/apps/labriqueinternet.json - fi -} +git clone $renew_cert_repo $renew_cert_path +git -C $renew_cert_path checkout $renew_cert_version -sudo yunohost app setting neutrinet version -v "0.2" +# We wrap the python3 script that actually renew the VPN certificate +# This wrapper will be used as a daily cron task +cp $renew_cert_cron_script $renew_cert_path/$renew_cert_cron_script -install_neutrinet_apps_list -install_labriqueinternet_apps_list +# From now on we work in the renew_cert directory +cd $renew_cert_path -get_out_of_testing +# We need system site packages otherwise moulinette is broken +python3 -m venv $renew_cert_virtualenv --system-site-packages +ve/bin/pip install wheel +ve/bin/pip install -r requirements.txt -install_static_file +ynh_print_info "Setting up permissions" +chown -R $app_user: $opt_path -install_renew_cert +chmod 0755 $renew_cert_cron_script +chown root: $renew_cert_cron_script -# vpn is not running, let's assume for now that this mean that the vpn is broken -if [ ! "$(grep '^port 1195' /etc/openvpn/client.conf)" ]; then - renew_cert -fi +#================================================= +# SETTING UP CRONTAB +#================================================= + +ynh_print_info "Setting up cron job for certificate renewal…" + +cat < /etc/cron.daily/$app-renew-cert +#!/bin/bash +cd $renew_cert_path +RENEW_CERT_PYTHON="$renew_cert_python" $renew_cert_path/$renew_cert_cron_script +EOF + +chown root:root /etc/cron.daily/$app-renew-cert +chmod 0755 /etc/cron.daily/$app-renew-cert + +#================================================= +# FINALIZATION +#================================================= + +ynh_print_info "Checking certificates…" + +/etc/cron.daily/$app-renew-cert diff --git a/scripts/remove b/scripts/remove index 722060cedd5fe5680894e157bc8ee72a507e9fd7..7b4653bb4e3298887f4a7cedfa482157fa173ed0 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,8 +1,55 @@ -source ./commons +#!/bin/bash -domain=$(sudo yunohost app setting neutrinet domain) +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -sudo rm -rf $RENEW_CERT_PATH -sudo rm -rf /var/www/neutrinet/ +source /usr/share/yunohost/helpers +source _common.sh + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path_url) +app_user=$(ynh_app_setting_get $app app_user) +www_path=$(ynh_app_setting_get $app www_path) +opt_path=$(ynh_app_setting_get $app opt_path) + +#================================================= +# STANDARD REMOVE +#================================================= + +ynh_print_info "Removing static site..." + +rm -rf $www_path +rm -f /etc/nginx/conf.d/$domain.d/$app.conf + +nginx -t > /dev/null +service nginx reload + +ynh_print_info "Removing automatic vpn certificate renewal..." + +rm -rf $opt_path +rm -rf /etc/cron.daily/$app-renew-cert + +#================================================= +# REMOVE DEPENDENCIES +#================================================= + +ynh_print_info "Removing dependencies..." + +ynh_remove_app_dependencies + +#================================================= +# REMOVE DEDICATED USER +#================================================= + +ynh_print_info "Removing system user..." +ynh_system_user_delete $app_user -sudo rm -f /etc/nginx/conf.d/$domain.d/neutrinet.conf diff --git a/scripts/renew_cert_cron.sh b/scripts/renew_cert_cron.sh new file mode 100644 index 0000000000000000000000000000000000000000..4d35ad024df05a463f1e0a013552b4c71a4b3075 --- /dev/null +++ b/scripts/renew_cert_cron.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +set -e + +OPENVPN_CONF_DIR="/etc/openvpn" +OPENVPN_KEYS_DIR="${OPENVPN_CONF_DIR}/keys" +OPENVPN_CREDENTIALS_FILE="${OPENVPN_KEYS_DIR}/credentials" +OPENVPN_AUTH_FILE="${OPENVPN_KEYS_DIR}/auth" +OPENVPN_USER_CERT="${OPENVPN_KEYS_DIR}/user.crt" +OPENVPN_USER_KEY="${OPENVPN_KEYS_DIR}/user.key" +OPENVPN_SERVER_CERT="${OPENVPN_KEYS_DIR}/ca-server.crt" +OPENVPN_CONF_TEMPLATE="${OPENVPN_CONF_DIR}/client.conf.tpl" + +OPENVPN_CLIENT_LOGS="/var/log/openvpn-client.log" + +NEUTRINET_CONF_TEMPLATE="neutrinet_openvpn_config" + +if [[ -z $RENEW_CERT_PATH ]] +then + RENEW_CERT_PATH=$PWD +fi + +if [[ -z $RENEW_CERT_PYTHON ]] +then + RENEW_CERT_PYTHON=$(command -v python3) +fi +RENEW_CERT_SCRIPT="${RENEW_CERT_PATH}/renew.py" + +if [[ -f $OPENVPN_CREDENTIALS_FILE ]] +then + credentials_file=$OPENVPN_CREDENTIALS_FILE +elif [[ -f $OPENVPN_AUTH_FILE ]] +then + credentials_file=$OPENVPN_AUTH_FILE +else + >&2 echo "ERROR: Cannot find credentials for Neutrinet VPN since neither ${OPENVPN_CREDENTIALS_FILE} nor ${OPENVPN_AUTH_FILE} exists." + exit 1 +fi + +login=$(head -n 1 "$credentials_file") +password=$(tail -n 1 "$credentials_file") + +run_date=$(date +'%Y-%m-%d_%H:%M:%S') +renew_dir="certs_$run_date" + +$RENEW_CERT_PYTHON $RENEW_CERT_SCRIPT "$login" -p "$password" -c "$OPENVPN_USER_CERT" -d "$renew_dir" -v + +if [[ ! -d $renew_dir || ! -f $renew_dir/ca.crt || ! -f $renew_dir/client.crt || ! -f $renew_dir/client.key ]] +then + echo "Cleaning $renew_dir directory." + rm -rf "$renew_dir" + exit 0 +fi + +echo "Saving old OpenVPN config" +cp -r $OPENVPN_CONF_DIR{,.old_${run_date}} + +echo "Copying new OpenVPN config" +cp "$NEUTRINET_CONF_TEMPLATE" "$OPENVPN_CONF_TEMPLATE" + +echo "Copying new certificates" +cp "$renew_dir/ca.crt" "$OPENVPN_SERVER_CERT" +cp "$renew_dir/client.crt" "$OPENVPN_USER_CERT" +cp "$renew_dir/client.key" "$OPENVPN_USER_KEY" + +echo "Adding user credentials" +echo -e "$login\n$password" > "$OPENVPN_CREDENTIALS_FILE" + +echo "Updating VPNClient config" +yunohost app setting vpnclient server_name -v "vpn.neutrinet.be" +yunohost app setting vpnclient server_port -v "1195" +yunohost app setting vpnclient server_proto -v "udp" +yunohost app setting vpnclient service_enabled -v "1" +yunohost app setting vpnclient login_user -v "$login" +yunohost app setting vpnclient login_passphrase -v "$password" + +echo "Critical part 1: reloading VPNClient" +if ! ynh-vpnclient restart && ynh-vpnclient status +then + >&2 echo "ERROR: Failed to restart VPNClient" + tail -n 200 "$OPENVPN_CLIENT_LOGS" + exit 1 +fi + +echo "Critical part 2: restarting OpenVPN" +if ! service openvpn restart +then + >&2 echo "ERROR: Failed to restart OpenVPN" + journalctl -u openvpn -n 200 --no-pager + exit 1 +fi + +sleep 15 + +if ! command -v ynh-hotspot > /dev/null +then + exit 0 +fi + +echo "Few, we're done, let's wait 2min to be sure the VPN is running, then restart hotspot" +sleep 120 + +echo "Restarting hotspot" +if ! ynh-hotspot restart && ynh-hotspot status +then + >&2 echo "ERROR: Failed to restart hotspot" + echo "Since it's not a critical part, let's continue" +fi diff --git a/scripts/restore b/scripts/restore new file mode 100755 index 0000000000000000000000000000000000000000..bbdb04b6c6486a9caaa59dd89649de0ae84eac89 --- /dev/null +++ b/scripts/restore @@ -0,0 +1,97 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source /usr/share/yunohost/helpers +source _common.sh + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +ynh_abort_if_errors + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path_url) +app_user=$(ynh_app_setting_get $app app_user) +www_path=$(ynh_app_setting_get $app www_path) +opt_path=$(ynh_app_setting_get $app opt_path) + +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= + +ynh_print_info "Checking for conflicts…" + +[[ ! -e $www_path ]] || ynh_die "The path $www_path already contains a folder" +[[ ! -e $opt_path ]] || ynh_die "The path $opt_path already contains a folder" + +# Check web path availability +if ! ynh_webpath_available "$domain" "$path_url" +then + ynh_die "$domain$path_url is no longer available" +fi + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# INSTALL DEPENDENCIES +#================================================= + +ynh_print_info "Installing dependencies…" + +ynh_install_app_dependencies git python3-venv libssl-dev libffi-dev python3-dev + +#================================================= +# CREATE DEDICATED USER +#================================================= + +mkdir -p "$www_path" +ynh_system_user_create $app_user "$www_path" + +#================================================= +# RESTORE STATIC FILES +#================================================= + +ynh_print_info "Restoring static site…" + +ynh_restore_file "$www_path" +ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" +chown -R $app_user: "$www_path" + +nginx -tq +service nginx reload + +#================================================= +# RESTORE RENEW CERT +#================================================= + +ynh_print_info "Restoring automatic VPN certificates renewal…" + +ynh_restore_file "$opt_path" +ynh_restore_file "/etc/cron.daily/$app-renew-cert" + +chown -R $app_user: $opt_path +chown root:root /etc/cron.daily/$app-renew-cert \ + $opt_path/renew_cert/renew_cert_cron.sh +chmod 0755 /etc/cron.daily/$app-renew-cert \ + $opt_path/renew_cert/renew_cert_cron.sh + +#================================================= +# FINALIZATION +#================================================= + +ynh_print_info "Checking certificates…" + +/etc/cron.daily/$app-renew-cert + diff --git a/scripts/upgrade b/scripts/upgrade index 16acdad974fc395a6a0c15b0a85a5d2a3fbdf9c9..9f4eead4a3ebd416f736726c0d42f61c3cad779e 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,53 +1,175 @@ -set -e +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source /usr/share/yunohost/helpers +source _common.sh + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME -source ./commons +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path_url) +app_user=$(ynh_app_setting_get $app app_user) +www_path=$(ynh_app_setting_get $app www_path) +opt_path=$(ynh_app_setting_get $app opt_path) -version=$(sudo yunohost app setting neutrinet version) +# There are two ways to get the version: +# - before 0.3.0~ynh1: version is only stored in app settings +# - after 0.3.0~ynh1: version is only stored in the manifest +# We don't use ynh_app_upstream_version, because it would return "null" +# when the version isn't in the manifest +manifest=/etc/yunohost/apps/$app/manifest.json +version=$(jq '.version // empty' -r -e $manifest || ynh_app_setting_get $app version) -# 0.1.1 -> 0.2 -if [[ "$version" == "0.1.1" ]]; then +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= - get_out_of_testing +if [[ -z $www_path ]]; then + www_path=/var/www/$app + ynh_app_setting_set $app www_path $www_path - sudo yunohost app setting neutrinet version -v "0.2" - version="0.2" + mkdir -p $www_path fi -# 0.2 -> 0.2.1 -if [[ "$version" == "0.2" ]]; then - sudo yunohost app setting neutrinet version -v "0.2.1" - version="0.2.1" +if [[ -z $opt_path ]]; then + opt_path=/opt/$app + ynh_app_setting_set $app opt_path $opt_path - cd $RENEW_CERT_PATH - sudo ve/bin/python renew_from_cube.py + mkdir -p $opt_path fi -# 0.2.1 -> 0.2.2 -if [[ "$version" == "0.2.1" ]]; then - sudo yunohost app setting neutrinet version -v "0.2.2" - version="0.2.2" +if [[ -z $app_user ]]; then + app_user=$app + ynh_app_setting_set $app app_user $app_user +fi - cd $RENEW_CERT_PATH - sudo git fetch - sudo git checkout 01b9306e51e74a2dac5b06f3fb6c29a0fb2fe755 - sudo ve/bin/python renew_from_cube.py --cron +if [[ -z $path_url ]]; then + path_url=$(ynh_app_setting_get $app path) - cat < /etc/cron.daily/neutrinet-renew-cert -#!/bin/bash -cd $RENEW_CERT_PATH -ve/bin/python renew_from_cube.py --cron -EOF - sudo chown root:root /etc/cron.daily/neutrinet-renew-cert - sudo chmod 0755 /etc/cron.daily/neutrinet-renew-cert + if [[ -z $path_url ]]; then + ynh_die "Missing path url!" + else + ynh_app_setting_set $app path_url $path_url + ynh_app_setting_delete $app path + fi +fi + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= + +ynh_print_info "Creating backup..." + +ynh_backup_before_upgrade +ynh_clean_setup () { + # restore it if the upgrade fails + ynh_restore_upgradebackup +} + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# INSTALL DEPENDENCIES +#================================================= + +if [[ $version < "0.3.0~ynh1" ]]; then + ynh_app_setting_delete $app version + ynh_system_user_create --username $app_user --home_dir $www_path + + ynh_print_info "Upgrading dependencies..." + + ynh_package_update + ynh_install_app_dependencies python3-venv libssl-dev libffi-dev python3-dev +fi + +#================================================= +# PULL CHANGES AND SPECIFIC SETUP +#================================================= +# REINSTALL STATIC FILES +#================================================= + +ynh_print_info "Installing static site..." + +cp -r ../sources/. $www_path +chown -R $app_user: $www_path + +sed -i "s@PATHTOCHANGE@$path_url@g" ../conf/nginx.conf +sed -i "s@ALIASTOCHANGE@$www_path@g" ../conf/nginx.conf + +cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf + +nginx -tq +service nginx reload + +#================================================= +# REINSTALL RENEW CERT +#================================================= + +ynh_print_info "Installing automatic VPN certificate renewal..." + +renew_cert_repo="https://github.com/neutrinet/renew_cert" +renew_cert_version=$(jq .version ../manifest.json -r -e | cut -d '~' -f 1) +renew_cert_path="$opt_path/renew_cert" +renew_cert_virtualenv="$renew_cert_path/ve" +renew_cert_python="$renew_cert_virtualenv/bin/python3" +renew_cert_cron_script="renew_cert_cron.sh" + +if [[ ! -e $renew_cert_path ]]; then + git clone $renew_cert_repo $renew_cert_path fi -# 0.2.2 -> 0.2.3 -if [[ "$version" == "0.2.2" ]]; then - final_path=/var/www/neutrinet/ - sudo mkdir -p $final_path - sudo cp -a ../sources/. $final_path - sudo chown -R www-data: $final_path +git -C $renew_cert_path checkout $renew_cert_version + +# We wrap the python3 script that actually renew the VPN certificate +# This wrapper will be used as a daily cron task +cp $renew_cert_cron_script $renew_cert_path/$renew_cert_cron_script + +# From now on we work in the renew_cert directory +cd $renew_cert_path - sudo yunohost app setting neutrinet version -v "0.2.3" - version="0.2.3" +if [[ ! -e $renew_cert_virtualenv || $version < "0.3.0~ynh1" ]]; then + # We need system site packages otherwise moulinette is broken + python3 -m venv $renew_cert_virtualenv --system-site-packages fi +ve/bin/pip install wheel +ve/bin/pip install -r requirements.txt + +ynh_print_info "Setting up permissions" +chown -R $app_user: $opt_path + +chmod 755 $renew_cert_cron_script +chown root: $renew_cert_cron_script + +#================================================= +# SETTING UP CRONTAB +#================================================= + +ynh_print_info "Setting up cron job for renewal..." + +cat < /etc/cron.daily/$app-renew-cert +#!/bin/bash +cd $renew_cert_path +RENEW_CERT_PYTHON="$renew_cert_python" $renew_cert_path/$renew_cert_cron_script +EOF + +chown root:root /etc/cron.daily/$app-renew-cert +chmod 0755 /etc/cron.daily/$app-renew-cert + +#================================================= +# FINALIZATION +#================================================= + +ynh_print_info "Checking certificates..." +/etc/cron.daily/$app-renew-cert