diff --git a/check_process b/check_process deleted file mode 100644 index d6a3f64..0000000 --- a/check_process +++ /dev/null @@ -1,24 +0,0 @@ -;; Test complet - ; Manifest - domain="domain.tld" - admin="john" - language="fr_FR" - is_public=1 - ; Checks - pkg_linter=1 - setup_sub_dir=0 - setup_root=1 - setup_nourl=0 - setup_private=1 - setup_public=1 - upgrade=1 - # 2023.12.06~ynh1 - upgrade=1 from_commit=7ce2faf2e971f31f9154fc80d17ed1fa9a170ff5 - backup_restore=1 - multi_instance=0 - port_already_use=0 - change_url=0 -;;; Options -;;; Upgrade options - - diff --git a/conf/.env.production.sample b/conf/.env.production.sample index b597d2b..4bd4d52 100644 --- a/conf/.env.production.sample +++ b/conf/.env.production.sample @@ -97,22 +97,16 @@ VAPID_PUBLIC_KEY=__VAPID_PUBLIC_KEY__ # Optionally change default language DEFAULT_LOCALE=__LANGUAGE__ - # Sending mail # ------------ SMTP_SERVER=localhost SMTP_PORT=25 -#SMTP_LOGIN= -#SMTP_PASSWORD= -SMTP_FROM_ADDRESS=__ADMIN_MAIL__ -#SMTP_REPLY_TO= -#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN -SMTP_DELIVERY_METHOD=sendmail # delivery method can also be smtp -SMTP_AUTH_METHOD=none -#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt +SMTP_LOGIN=__APP__ +SMTP_PASSWORD=__MAIL_PWD__ +SMTP_FROM_ADDRESS=Mastodon <__APP__@__DOMAIN__> +SMTP_DELIVERY_METHOD=smtp +SMTP_AUTH_METHOD=plain SMTP_OPENSSL_VERIFY_MODE=none -#SMTP_ENABLE_STARTTLS_AUTO=true -#SMTP_TLS=true # File storage (optional) # ----------------------- diff --git a/conf/app.src b/conf/app.src deleted file mode 100644 index 0baf7bb..0000000 --- a/conf/app.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/glitch-soc/mastodon/archive/3341db939cd077820ad598b0445d02ab2382eaf4.tar.gz -SOURCE_SUM=abf095bbf7f879d35b3e62f3fd4f339ff99b6aac98023fcc836baccfe91a0b97 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=3341db939cd077820ad598b0445d02ab2382eaf4.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/glitchsoc-sidekiq.service b/conf/glitchsoc-sidekiq.service index ce0aef8..ff72a14 100644 --- a/conf/glitchsoc-sidekiq.service +++ b/conf/glitchsoc-sidekiq.service @@ -5,7 +5,7 @@ After=network.target [Service] Type=simple User=__APP__ -WorkingDirectory=__FINALPATH__/live +WorkingDirectory=__INSTALL_DIR__/live Environment="__LD_PRELOAD__" Environment="RAILS_ENV=production" Environment="DB_POOL=25" @@ -23,17 +23,17 @@ StandardError=syslog # can't deliver mail to YunoHost users. See #30 -Tagada NoNewPrivileges=no PrivateTmp=yes -#PrivateDevices=yes -#RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK -#RestrictNamespaces=yes -#RestrictRealtime=yes +PrivateDevices=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes DevicePolicy=closed ProtectSystem=full ProtectControlGroups=yes -#ProtectKernelModules=yes -#ProtectKernelTunables=yes -#LockPersonality=yes -#SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap +ProtectKernelModules=yes +ProtectKernelTunables=yes +LockPersonality=yes +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap # Denying access to capabilities that should not be relevant for webapps # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html diff --git a/conf/glitchsoc-streaming.service b/conf/glitchsoc-streaming.service index 4122b02..a5fcfa0 100644 --- a/conf/glitchsoc-streaming.service +++ b/conf/glitchsoc-streaming.service @@ -5,7 +5,7 @@ After=network.target [Service] Type=simple User=__APP__ -WorkingDirectory=__FINALPATH__/live +WorkingDirectory=__INSTALL_DIR__/live Environment="NODE_ENV=production" Environment="PORT=__PORT_STREAM__" Environment="STREAMING_CLUSTER_NUM=1" diff --git a/conf/glitchsoc-web.service b/conf/glitchsoc-web.service index 42f5135..2b615dd 100644 --- a/conf/glitchsoc-web.service +++ b/conf/glitchsoc-web.service @@ -5,7 +5,7 @@ After=network.target [Service] Type=simple User=__APP__ -WorkingDirectory=__FINALPATH__/live +WorkingDirectory=__INSTALL_DIR__/live Environment="RAILS_ENV=production" Environment="PORT=__PORT_WEB__" diff --git a/conf/nginx.conf b/conf/nginx.conf index 4b1f76b..09e4a84 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,6 +1,6 @@ client_max_body_size 99m; -root __FINALPATH__/live/public; +root __INSTALL_DIR__/live/public; location / { diff --git a/doc/ADMIN.md b/doc/ADMIN.md new file mode 100644 index 0000000..54d9527 --- /dev/null +++ b/doc/ADMIN.md @@ -0,0 +1,32 @@ +## Administrate with tooctl + +`$ (cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl --help)` + +## Update + +**`screen` (or `tmux`) can be used to make sure your session is not interrupted in case of connection problems.** +See [tutorial](https://www.howtogeek.com/662422/how-to-use-linuxs-screen-command/) for more background information. + +``` +$ screen +$ sudo yunohost app upgrade glitchsoc +``` + +## Backups + +First of all: Glitch-Soc uses a local cache to save media (such as posted images, videos etc.). This cache can grow huge. +You could consider cleaning up your local cache first as otherwise your backup will be very big and you might run out of disk space: + +To check your space usage, on a command line run: + +`$ sudo cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl media usage` + +If your cache is too big to backup, you can run the following command to clean up Attachments (the first line). Substitute X by the number of days you want to keep, e.g. 1 day. All older images will be deleted but will be refetched from the original server if necessary. + +First dry-run to see how much space is freed up (without actually removing): + +`$ sudo cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl media remove --days=X --dry-run` + +If all looks good commit the cleanup: + +`$ sudo cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl media remove --days=X ` diff --git a/doc/ADMIN_fr.md b/doc/ADMIN_fr.md new file mode 100644 index 0000000..cb9f259 --- /dev/null +++ b/doc/ADMIN_fr.md @@ -0,0 +1,30 @@ +## Administration avec tooctl + +`$ cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl --help` + +## Mise à jour + +**`screen` (ou `tmux`) peut être utilisé pour vous assurer que votre session n'est pas interrompue en cas de problème de connection.** +Consultez ce [tutoriel](https://www.howtogeek.com/662422/how-to-use-linuxs-screen-command/) pour plus de détails. + +``` +$ screen +$ sudo yunohost app upgrade glitchsoc +``` + +## Sauvegardes + +Tout d'abord : Glitch-Soc utilise un cache local pour sauvegarder les médias (comme les images, vidéos, etc). Ce cache peut devenir énorme. +Vous devriez réfléchir à vider votre cache local avant de faire une sauvegarde, qui pourrait être énorme et vous pourriez manquer d'espace de stockage. + +Pour vérifier l'utilisation du stockage, en ligne de commande utilisez : + +`$ sudo cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl media usage` + +Si le cache est trop gros pour être sauvegardé, vous pouvez lancer la commande suivante pour en supprimer les médias attachés. Changez `X` par le nombre de cache à conserver, par ex. 1 jour. Tous les médias plus anciens seront supprimés, mais ils pourront être rechargé du serveur d'origine si nécessaire. + +En premier faite un essai à blanc pour voir combien de place sera libérée (sans rien supprimer): +`$ sudo cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl media remove --days=X --dry-run` + +Si cela semble bon, effectuez le nettoyage : +`$ sudo cd /var/www/glitchsoc/live && sudo -u glitchsoc RAILS_ENV=production PATH=/opt/rbenv/versions/glitchsoc/bin bin/tootctl media remove --days=X ` diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md index 908730c..0c487c8 100644 --- a/doc/DESCRIPTION.md +++ b/doc/DESCRIPTION.md @@ -1,5 +1,7 @@ `glitch-soc` is a friendly [fork](https://en.wikipedia.org/wiki/Fork_(software_development)) of the open-source social media software [Mastodon](https://joinmastodon.org/), with the aim of providing additional features at the risk of potentially less stable software. +⚠️ `glitch-soc` is beta software, and under active development. Use at your own risk! + ### What's different from Mastodon? `glitch-soc` adds a number of experimental features to Mastodon, such as: diff --git a/doc/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md index a1c774a..83c21e0 100644 --- a/doc/DESCRIPTION_fr.md +++ b/doc/DESCRIPTION_fr.md @@ -1,5 +1,7 @@ `glitch-soc` est une [scission](https://fr.wikipedia.org/wiki/Fork_(d%C3%A9veloppement_logiciel)) sympa du logiciel de réseau social libre [Mastodon](https://joinmastodon.org/), avec comme objectif de fournir des fonctionnalités supplémentaires, au risque d'un logiciel un peu moins stable. +⚠️ `glitch-soc` est en constant développement, fournis avec les dernières fonctionnalités (incluant les derniers bugs). + ### Quelles sont les différences avec Mastodon? `glitch-soc` ajoute de nombreuses fonctionnalitées expérimentals, comme : diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md deleted file mode 100644 index 80153db..0000000 --- a/doc/DISCLAIMER.md +++ /dev/null @@ -1,14 +0,0 @@ -⚠️ Glitch-Soc is beta software, and under active development. Use at your own risk! - -### Install - -* This app require a dedicated domain or subdomain. -* The user choosen during the installation is created in Glitch-Soc with admin rights. - -LDAP authentication and SSO are enabled. All YunoHost users can authenticate. - -We invite you to block remote malicious instances from the administration interface. You can also add text on your home page. - -### Known issues - -* When logged in with SSO, log-out from YunoHost's portal don't log-out from Glitch-Soc. See https://github.com/YunoHost/issues/issues/501 diff --git a/doc/DISCLAIMER_fr.md b/doc/DISCLAIMER_fr.md deleted file mode 100644 index 49433c3..0000000 --- a/doc/DISCLAIMER_fr.md +++ /dev/null @@ -1,14 +0,0 @@ -Glitch-Soc est en constant développement, fournis avec les dernières fonctionnalités (incluant les derniers bugs). - -### Installation - -* L'application a besoin d'un domaine dédié. -* L'utilisateurice choisie lors de l'installation sera administrateurice de l'instance. Il est possible d'en ajouter d'autre depuis l'application. - -L'authentification par LDAP et le Single-Sign-On sont activés pour les utilisateurices YunoHost. - -Nous vous invitons à bloquer les instances malveillantes depuis l'interface d'administration. Vous pouvez également ajouter du texte sur votre page d'accueil. - -### Problèmes connus - -* En se connectant via le SSO, se déconnecter depuis le portail YunoHost ne vous déconnecte pas de Glitch-Soc. Voir https://github.com/YunoHost/issues/issues/501 diff --git a/doc/PRE_INSTALL.md b/doc/PRE_INSTALL.md new file mode 100644 index 0000000..ed7e17c --- /dev/null +++ b/doc/PRE_INSTALL.md @@ -0,0 +1,20 @@ +## Important points to read before installing + +1. **Glitch-Soc** require a dedicated **root domain**, eg. glitchsoc.domain.tld +1. You can't change the domain once installed. +1. The user choosen during the installation is automatically created in Glitch-Soc with admin rights +1. At the end of the installation a mail is sent to the user with the automatically generated password +1. It seems important to close the inscriptions for your Glitch-Soc, so that it remains a private body. We invite you to block remote malicious instances from the administration interface. You can also add text on your home page. + +## Using *screen* in case of disconnect + +``` +$ sudo apt-get install screen +$ screen +$ sudo yunohost app install https://github.com/YunoHost-Apps/glitchsoc_ynh.git +``` +Recover after disconnect: +``` +$ screen -d +$ screen -r +``` diff --git a/doc/PRE_INSTALL_fr.md b/doc/PRE_INSTALL_fr.md new file mode 100644 index 0000000..8ed9e10 --- /dev/null +++ b/doc/PRE_INSTALL_fr.md @@ -0,0 +1,22 @@ +## Points importants à lire avant l'installation + +1. **Glitch-Soc** nécessite un **nom de domaine** dédié, par exemple : glitchsoc.domain.tld +1. Il est impossible de changer le nom de domaine après l'installation. +1. L'utilisateur sélectionné pendant l'installation sera créé automatiquement dans Glitch-Soc avec des droits d'administration. +1. À la fin de l'installation, un mail est envoyé à cet utilisateur avec un mot de passe généré automatiquement. +1. Pour que votre instance Glitch-Soc reste privée, il est important de fermer les inscriptions. Nous vous invitons à bloquer les instances distantes indésirables depuis l'interface d'administration. Vous pouvez également ajouter un texte sur votre page d'accueil dans l'administration. + +## Utilisation de *screen* en cas de déconnexion + +L'installation de Glitch-Soc peut être longue, selon les performances du serveur. Pour éviter que le processus soit interrompu par une déconnexion, on peut utiliser `screen`. + +``` +$ sudo apt-get install screen +$ screen +$ sudo yunohost app install glitchsoc +``` +Récupérer l'installation après une deconnection : +``` +$ screen -d +$ screen -r +``` diff --git a/manifest.json b/manifest.json deleted file mode 100644 index e5e1543..0000000 --- a/manifest.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "Glitch-Soc", - "id": "glitchsoc", - "packaging_format": 1, - "description": { - "en": "Libre and federated social network, fork of Mastodon", - "fr": "Réseau social libre et fédéré, scission de Mastodon" - }, - "version": "2024.03.20~ynh1", - "url": "https://github.com/glitch-soc/mastodon", - "upstream": { - "license": "AGPL-3.0-or-later", - "website": "https://glitch-soc.github.io/docs/", - "code": "https://github.com/glitch-soc/mastodon" - }, - "license": "AGPL-3.0-or-later", - "maintainer": { - "name": "Tagada" - }, - "requirements": { - "yunohost": ">= 4.3.0" - }, - "multi_instance": true, - "services": [ - "nginx" - ], - "arguments": { - "install": [ - { - "name": "domain", - "type": "domain" - }, - { - "name": "admin", - "type": "user" - }, - { - "name": "is_public", - "type": "boolean", - "help": { - "en": "Needed for federation.", - "fr": "Nécessaire pour la fédération." - }, - "default": true - }, - { - "name": "language", - "type": "string", - "ask": { - "en": "Choose the application language", - "fr": "Choisissez la langue de l'application" - }, - "choices": [ - "en_EN", - "fr_FR" - ], - "default": "fr_FR" - } - ] - } -} diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..e455548 --- /dev/null +++ b/manifest.toml @@ -0,0 +1,92 @@ +packaging_format = 2 + +id = "glitchsoc" +name = "Glitch-Soc" +description.en = "Libre and federated social network, fork of Mastodon" +description.fr = "Réseau social libre et fédéré, scission de Mastodon" + +version = "2024.03.20~ynh1" + +maintainers = ["Tagada"] + +[upstream] +license = "AGPL-3.0-or-later" +website = "https://glitch-soc.github.io/docs/" +code = "https://github.com/glitch-soc/mastodon" +cpe = "???" # XXX: No CPE yet... The CPE may be obtained by searching here: https://nvd.nist.gov/products/cpe/search +fund = "???" # XXX: Nothing yet... + +[integration] +yunohost = ">= 11.1" +architectures = "all" +multi_instance = true +ldap = true +sso = true +disk = "2G" +ram.build = "4G" +ram.runtime = "1G" + +[install] + [install.domain] + # this is a generic question - ask strings are automatically handled by Yunohost's core + type = "domain" + full_domain = true + + [install.admin] + # this is a generic question - ask strings are automatically handled by Yunohost's core + type = "user" + + [install.init_main_permission] + help.en = "visitors group is needed for federation." + help.fr = "Le groupe visitors est nécessaire pour la fédération." + type = "group" + default = "visitors" + + [install.init_api_permission] + help.en = "visitors group is needed to be able to use thrid party clients." + help.fr = "Le groupe visitors est nécessaire pour pouvoir utiliser des clients tiers." + type = "group" + default = "visitors" + + [install.language] + ask.en = "Choose the application language" + ask.fr = "Choisissez la langue de l'application" + type = "string" + choices = ["en_EN", "fr_FR"] + default = "fr_FR" + +[resources] + [resources.sources.main] + url = "https://github.com/glitch-soc/mastodon/archive/3341db939cd077820ad598b0445d02ab2382eaf4.tar.gz" + sha256 = "abf095bbf7f879d35b3e62f3fd4f339ff99b6aac98023fcc836baccfe91a0b97" + + autoupdate.strategy = "latest_github_commit" + + [resources.system_user] + allow_email = true + + [resources.install_dir] + + [resources.permissions] + main.url = "/" + + api.url = "/api" + api.allowed = "visitors" + api.auth_header = false + api.show_tile = false + api.protected = true + + [resources.ports] + web.default = 3000 + stream.default = 4000 + + [resources.apt] + packages = "imagemagick, ffmpeg, libpq-dev, libxml2-dev, libxslt1-dev, file, git-core, g++, libprotobuf-dev, protobuf-compiler, pkg-config, gcc, autoconf, bison, build-essential, libssl-dev, libyaml-dev, libreadline6-dev, zlib1g-dev, libncurses5-dev, libffi-dev, libgdbm6, libgdbm-dev, redis-server, redis-tools, postgresql, postgresql-contrib, libidn11-dev, libicu-dev, libjemalloc-dev, curl, apt-transport-https" + + [resources.apt.extras.yarn] + repo = "deb https://dl.yarnpkg.com/debian/ stable main" + key = "https://dl.yarnpkg.com/debian/pubkey.gpg" + packages = "yarn" + + [resources.database] + type = "postgresql" diff --git a/scripts/_common.sh b/scripts/_common.sh index f39b044..21339ce 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,36 +4,29 @@ # COMMON VARIABLES #================================================= -# dependencies used by the app -pkg_dependencies="imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3|libgdbm6 libgdbm-dev redis-server redis-tools postgresql postgresql-contrib libidn11-dev libicu-dev libjemalloc-dev curl apt-transport-https" - MEMORY_NEEDED="2560" RUBY_VERSION="3.2.3" NODEJS_VERSION="20" -# Workaround for Mastodon on Bullseye +# Workaround for Mastodon on Bullseye and later # See https://github.com/mastodon/mastodon/issues/15751#issuecomment-873594463 -if [ "$(lsb_release --codename --short)" = "bullseye" ]; then - case $YNH_ARCH in - amd64) - arch="x86_64" - ;; - arm64) - arch="aarch64" - ;; - armel|armhf) - arch="arm" - ;; - i386) - arch="i386" - ;; - esac - ld_preload="LD_PRELOAD=/usr/lib/$arch-linux-gnu/libjemalloc.so" -else - ld_preload="" -fi +case $YNH_ARCH in + amd64) + arch="x86_64" + ;; + arm64) + arch="aarch64" + ;; + armel|armhf) + arch="arm" + ;; + i386) + arch="i386" + ;; +esac +ld_preload="LD_PRELOAD=/usr/lib/$arch-linux-gnu/libjemalloc.so" #================================================= # PERSONAL HELPERS @@ -43,405 +36,6 @@ fi # EXPERIMENTAL HELPERS #================================================= -# 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 -} - #================================================= # FUTURE OFFICIAL HELPERS #================================================= - -# ynh_install_ruby__2 -ynh_ruby_try_bash_extension() { - if [ -x src/configure ]; then - src/configure && make -C src || { - ynh_print_info --message="Optional bash extension failed to build, but things will still work normally." - } - fi -} - -rbenv_install_dir="/opt/rbenv" -ruby_version_path="$rbenv_install_dir/versions" -# RBENV_ROOT is the directory of rbenv, it needs to be loaded as a environment variable. -export RBENV_ROOT="$rbenv_install_dir" -export rbenv_root="$rbenv_install_dir" - -# Load the version of Ruby for an app, and set variables. -# -# ynh_use_ruby has to be used in any app scripts before using Ruby for the first time. -# This helper will provide alias and variables to use in your scripts. -# -# To use gem or Ruby, use the alias `ynh_gem` and `ynh_ruby` -# Those alias will use the correct version installed for the app -# For example: use `ynh_gem install` instead of `gem install` -# -# With `sudo` or `ynh_exec_as`, use instead the fallback variables `$ynh_gem` and `$ynh_ruby` -# And propagate $PATH to sudo with $ynh_ruby_load_path -# Exemple: `ynh_exec_as $app $ynh_ruby_load_path $ynh_gem install` -# -# $PATH contains the path of the requested version of Ruby. -# However, $PATH is duplicated into $ruby_path to outlast any manipulation of $PATH -# You can use the variable `$ynh_ruby_load_path` to quickly load your Ruby version -# in $PATH for an usage into a separate script. -# Exemple: $ynh_ruby_load_path $final_path/script_that_use_gem.sh` -# -# -# Finally, to start a Ruby service with the correct version, 2 solutions -# Either the app is dependent of Ruby or gem, but does not called it directly. -# In such situation, you need to load PATH -# `Environment="__YNH_RUBY_LOAD_ENV_PATH__"` -# `ExecStart=__FINALPATH__/my_app` -# You will replace __YNH_RUBY_LOAD_ENV_PATH__ with $ynh_ruby_load_path -# -# Or Ruby start the app directly, then you don't need to load the PATH variable -# `ExecStart=__YNH_RUBY__ my_app run` -# You will replace __YNH_RUBY__ with $ynh_ruby -# -# -# one other variable is also available -# - $ruby_path: The absolute path to Ruby binaries for the chosen version. -# -# usage: ynh_use_ruby -# -# Requires YunoHost version 3.2.2 or higher. -ynh_use_ruby () { - ruby_version=$(ynh_app_setting_get --app=$app --key=ruby_version) - - # Get the absolute path of this version of Ruby - ruby_path="$ruby_version_path/$YNH_APP_INSTANCE_NAME/bin" - - # Allow alias to be used into bash script - shopt -s expand_aliases - - # Create an alias for the specific version of Ruby and a variable as fallback - ynh_ruby="$ruby_path/ruby" - alias ynh_ruby="$ynh_ruby" - # And gem - ynh_gem="$ruby_path/gem" - alias ynh_gem="$ynh_gem" - - # Load the path of this version of Ruby in $PATH - if [[ :$PATH: != *":$ruby_path"* ]]; then - PATH="$ruby_path:$PATH" - fi - # Create an alias to easily load the PATH - ynh_ruby_load_path="PATH=$PATH" - - # Sets the local application-specific Ruby version - pushd $final_path - $rbenv_install_dir/bin/rbenv local $ruby_version - popd -} - -# Install a specific version of Ruby -# -# ynh_install_ruby will install the version of Ruby provided as argument by using rbenv. -# -# This helper creates a /etc/profile.d/rbenv.sh that configures PATH environment for rbenv -# for every LOGIN user, hence your user must have a defined shell (as opposed to /usr/sbin/nologin) -# -# Don't forget to execute ruby-dependent command in a login environment -# (e.g. sudo --login option) -# When not possible (e.g. in systemd service definition), please use direct path -# to rbenv shims (e.g. $RBENV_ROOT/shims/bundle) -# -# usage: ynh_install_ruby --ruby_version=ruby_version -# | arg: -v, --ruby_version= - Version of ruby to install. -# -# Requires YunoHost version 3.2.2 or higher. -ynh_install_ruby () { - # Declare an array to define the options of this helper. - local legacy_args=v - local -A args_array=( [v]=ruby_version= ) - local ruby_version - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - - # Load rbenv path in PATH - local CLEAR_PATH="$rbenv_install_dir/bin:$PATH" - - # Remove /usr/local/bin in PATH in case of Ruby prior installation - PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@') - - # Move an existing Ruby binary, to avoid to block rbenv - test -x /usr/bin/ruby && mv /usr/bin/ruby /usr/bin/ruby_rbenv - - # Install or update rbenv - rbenv="$(command -v rbenv $rbenv_install_dir/bin/rbenv | grep "$rbenv_install_dir/bin/rbenv" | head -1)" - if [ -n "$rbenv" ]; then - ynh_print_info --message="rbenv already seems installed in \`$rbenv'." - pushd "${rbenv%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/rbenv/rbenv.git"; then - ynh_print_info --message="Trying to update with git..." - git pull -q --tags origin master - ynh_ruby_try_bash_extension - else - ynh_print_info --message="Reinstalling rbenv with git..." - cd .. - ynh_secure_remove --file=$rbenv_install_dir - mkdir -p $rbenv_install_dir - cd $rbenv_install_dir - git init -q - git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1 - git checkout -q -b master origin/master - ynh_ruby_try_bash_extension - rbenv=$rbenv_install_dir/bin/rbenv - fi - popd - else - ynh_print_info --message="Installing rbenv with git..." - mkdir -p $rbenv_install_dir - pushd $rbenv_install_dir - git init -q - git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1 - git checkout -q -b master origin/master - ynh_ruby_try_bash_extension - rbenv=$rbenv_install_dir/bin/rbenv - popd - fi - - ruby_build="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-install rbenv-install | head -1)" - if [ -n "$ruby_build" ]; then - ynh_print_info --message="\`rbenv install' command already available in \`$ruby_build'." - pushd "${ruby_build%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/rbenv/ruby-build.git"; then - ynh_print_info --message="Trying to update rbenv with git..." - git pull -q origin master - fi - popd - else - ynh_print_info --message="Installing ruby-build with git..." - mkdir -p "${rbenv_install_dir}/plugins" - git clone -q https://github.com/rbenv/ruby-build.git "${rbenv_install_dir}/plugins/ruby-build" - fi - - rbenv_alias="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-alias rbenv-alias | head -1)" - if [ -n "$rbenv_alias" ]; then - ynh_print_info --message="\`rbenv alias' command already available in \`$rbenv_alias'." - pushd "${rbenv_alias%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/tpope/rbenv-aliases.git"; then - ynh_print_info --message="Trying to update rbenv-aliases with git..." - git pull -q origin master - fi - popd - else - ynh_print_info --message="Installing rbenv-aliases with git..." - mkdir -p "${rbenv_install_dir}/plugins" - git clone -q https://github.com/tpope/rbenv-aliases.git "${rbenv_install_dir}/plugins/rbenv-aliase" - fi - - rbenv_latest="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-latest rbenv-latest | head -1)" - if [ -n "$rbenv_latest" ]; then - ynh_print_info --message="\`rbenv latest' command already available in \`$rbenv_latest'." - pushd "${rbenv_latest%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/momo-lab/xxenv-latest.git"; then - ynh_print_info --message="Trying to update xxenv-latest with git..." - git pull -q origin master - fi - popd - else - ynh_print_info --message="Installing xxenv-latest with git..." - mkdir -p "${rbenv_install_dir}/plugins" - git clone -q https://github.com/momo-lab/xxenv-latest.git "${rbenv_install_dir}/plugins/xxenv-latest" - fi - - # Enable caching - mkdir -p "${rbenv_install_dir}/cache" - - # Create shims directory if needed - mkdir -p "${rbenv_install_dir}/shims" - - # Restore /usr/local/bin in PATH - PATH=$CLEAR_PATH - - # And replace the old Ruby binary - test -x /usr/bin/ruby_rbenv && mv /usr/bin/ruby_rbenv /usr/bin/ruby - - # Install the requested version of Ruby - local final_ruby_version=$(rbenv latest --print $ruby_version) - if ! [ -n "$final_ruby_version" ]; then - final_ruby_version=$ruby_version - fi - ynh_print_info --message="Installing Ruby-$final_ruby_version" - CONFIGURE_OPTS="--disable-install-doc --with-jemalloc" MAKE_OPTS="-j2" rbenv install --skip-existing $final_ruby_version > /dev/null 2>&1 - - # Store ruby_version into the config of this app - ynh_app_setting_set --app=$YNH_APP_INSTANCE_NAME --key=ruby_version --value=$final_ruby_version - - # Remove app virtualenv - if `rbenv alias --list | grep --quiet "$YNH_APP_INSTANCE_NAME " 1>/dev/null 2>&1` - then - rbenv alias $YNH_APP_INSTANCE_NAME --remove - fi - - # Create app virtualenv - rbenv alias $YNH_APP_INSTANCE_NAME $final_ruby_version - - # Cleanup Ruby versions - ynh_cleanup_ruby - - # Set environment for Ruby users - echo "#rbenv -export RBENV_ROOT=$rbenv_install_dir -export PATH=\"$rbenv_install_dir/bin:$PATH\" -eval \"\$(rbenv init -)\" -#rbenv" > /etc/profile.d/rbenv.sh - - # Load the environment - eval "$(rbenv init -)" -} - -# Remove the version of Ruby used by the app. -# -# This helper will also cleanup Ruby versions -# -# usage: ynh_remove_ruby -ynh_remove_ruby () { - local ruby_version=$(ynh_app_setting_get --app=$YNH_APP_INSTANCE_NAME --key=ruby_version) - - # Load rbenv path in PATH - local CLEAR_PATH="$rbenv_install_dir/bin:$PATH" - - # Remove /usr/local/bin in PATH in case of Ruby prior installation - PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@') - - rbenv alias $YNH_APP_INSTANCE_NAME --remove - - # Remove the line for this app - ynh_app_setting_delete --app=$YNH_APP_INSTANCE_NAME --key=ruby_version - - # Cleanup Ruby versions - ynh_cleanup_ruby -} - -# Remove no more needed versions of Ruby used by the app. -# -# This helper will check what Ruby version are no more required, -# and uninstall them -# If no app uses Ruby, rbenv will be also removed. -# -# usage: ynh_cleanup_ruby -ynh_cleanup_ruby () { - - # List required Ruby versions - local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$') - local required_ruby_versions="" - for installed_app in $installed_apps - do - local installed_app_ruby_version=$(ynh_app_setting_get --app=$installed_app --key="ruby_version") - if [[ $installed_app_ruby_version ]] - then - required_ruby_versions="${installed_app_ruby_version}\n${required_ruby_versions}" - fi - done - - # Remove no more needed Ruby versions - local installed_ruby_versions=$(rbenv versions --bare --skip-aliases | grep -Ev '/') - for installed_ruby_version in $installed_ruby_versions - do - if ! `echo ${required_ruby_versions} | grep "${installed_ruby_version}" 1>/dev/null 2>&1` - then - ynh_print_info --message="Removing of Ruby-$installed_ruby_version" - $rbenv_install_dir/bin/rbenv uninstall --force $installed_ruby_version - fi - done - - # If none Ruby version is required - if [[ ! $required_ruby_versions ]] - then - # Remove rbenv environment configuration - ynh_print_info --message="Removing of rbenv-$rbenv_version" - ynh_secure_remove --file="$rbenv_install_dir" - ynh_secure_remove --file="/etc/profile.d/rbenv.sh" - fi -} - - diff --git a/scripts/backup b/scripts/backup index 2a64b32..7df8f50 100644 --- a/scripts/backup +++ b/scripts/backup @@ -10,27 +10,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_print_info --message="Loading installation settings..." - -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) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) - #================================================= # DECLARE DATA AND CONF FILES TO BACKUP #================================================= @@ -40,7 +19,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/install b/scripts/install index a31966d..77a109a 100644 --- a/scripts/install +++ b/scripts/install @@ -7,31 +7,13 @@ #================================================= source _common.sh +source ynh_install_ruby__2 +source ynh_add_swap source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# RETRIEVE ARGUMENTS FROM THE MANIFEST -#================================================= - -domain=$YNH_APP_ARG_DOMAIN -path_url="/" -admin=$YNH_APP_ARG_ADMIN -is_public=$YNH_APP_ARG_IS_PUBLIC -language=$YNH_APP_ARG_LANGUAGE admin_mail=$(ynh_user_get_info $admin 'mail') -app=$YNH_APP_INSTANCE_NAME - +# Initialize config_panel settings :< max_toot_chars="500" max_pinned_toots="5" max_bio_chars="500" @@ -43,26 +25,6 @@ max_image_size="8388608" max_video_size="41943040" max_emoji_size="51200" max_remote_emoji_size="204800" - -#================================================= -# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS -#================================================= -ynh_script_progression --message="Validating installation parameters..." --weight=1 - -final_path=/var/www/$app -test ! -e "$final_path" || ynh_die --message="This path already contains a folder" - -# Register (book) web path -ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url - -#================================================= -# STORE SETTINGS FROM MANIFEST -#================================================= -ynh_script_progression --message="Storing installation settings..." --weight=1 - -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=language --value=$language ynh_app_setting_set --app=$app --key=max_toot_chars --value=$max_toot_chars ynh_app_setting_set --app=$app --key=max_pinned_toots --value=$max_pinned_toots @@ -76,12 +38,8 @@ ynh_app_setting_set --app=$app --key=max_video_size --value=$max_video_size ynh_app_setting_set --app=$app --key=max_emoji_size --value=$max_emoji_size ynh_app_setting_set --app=$app --key=max_remote_emoji_size --value=$max_remote_emoji_size -#================================================= -# STANDARD MODIFICATIONS -#================================================= -# FIND AND OPEN A PORT -#================================================= -ynh_script_progression --message="Finding an available port..." --weight=1 +# Set `service` settings to support `yunohost app shell` command +ynh_app_setting_set --app="$app" --key=service --value="$app-web.service" # Find an available port port_web=$(ynh_find_port --port=3000) @@ -91,61 +49,25 @@ port_stream=$(ynh_find_port --port=4000) ynh_app_setting_set --app=$app --key=port_stream --value=$port_stream #================================================= -# INSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Installing dependencies..." --weight=10 - -ynh_exec_warn_less ynh_install_app_dependencies $pkg_dependencies -ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$NODEJS_VERSION -ynh_exec_warn_less ynh_install_ruby --ruby_version=$RUBY_VERSION - -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Configuring system user..." --weight=1 - -# Create a system user -ynh_system_user_create --username=$app --home_dir=$final_path - -#================================================= -# CREATE A POSTGRESQL DATABASE -#================================================= -ynh_script_progression --message="Creating a PostgreSQL database..." --weight=3 - -ynh_psql_test_if_first_run -# Create PostgreSQL database -db_name=$(ynh_sanitize_dbid --db_name="${app}_production") -db_user=$(ynh_sanitize_dbid --db_name=$app) -db_pwd=$(ynh_string_random --length=30) -ynh_app_setting_set --app=$app --key=db_name --value=$db_name -ynh_app_setting_set --app=$app --key=db_user --value=$db_user -ynh_app_setting_set --app=$app --key=db_pwd --value=$db_pwd -ynh_psql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd -ynh_psql_execute_as_root --sql="ALTER USER $db_user CREATEDB;" - +# APP "BUILD" (DEPLOYING SOURCES, VENV, COMPILING ETC) #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -ynh_script_progression --message="Setting up source files..." --weight=3 +ynh_script_progression --message="Setting up source files..." --weight=1 -ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src -ynh_setup_source --dest_dir="$final_path/live" +ynh_setup_source --dest_dir="$install_dir/live" -chmod 750 "$final_path" -chmod -R o-rwx "$final_path" -chown -R $app:www-data "$final_path" +chown -R $app:www-data "$install_dir" #================================================= -# NGINX CONFIGURATION +# INSTALL DEPENDENCIES #================================================= -ynh_script_progression --message="Configuring NGINX web server..." --weight=1 +ynh_script_progression --message="Installing Ruby and NodeJS..." --weight=1 -# Create a dedicated NGINX config -ynh_add_nginx_config +ynh_exec_warn_less ynh_install_ruby --ruby_version=$ruby_version +ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$nodejs_version -#================================================= -# SPECIFIC SETUP #================================================= # ADD SWAP IF NEEDED #================================================= @@ -154,31 +76,20 @@ ynh_script_progression --message="Adding swap if needed..." --weight=1 total_memory=$(ynh_get_ram --total) swap_needed=0 -if [ $total_memory -lt $MEMORY_NEEDED ]; then +if [ $total_memory -lt $memory_needed ]; then # Need a minimum of 2.5Go of memory - swap_needed=$(($MEMORY_NEEDED - $total_memory)) + swap_needed=$(($memory_needed - $total_memory)) fi -ynh_script_progression --message="Adding $swap_needed Mo to swap..." --weight=1 +ynh_script_progression --message="Adding $swap_needed Mo to swap..." ynh_add_swap --size=$swap_needed -#================================================= -# INSTALLING RUBY AND BUNDLER -#================================================= -ynh_script_progression --message="Installing Ruby dependencies..." --weight=3 - -pushd "$final_path/live" - ynh_use_ruby - ynh_gem update --system --no-document - ynh_gem install bundler --no-document -popd - #================================================= # ADD A CONFIGURATION #================================================= ynh_script_progression --message="Adding a configuration file..." --weight=1 -config="$final_path/live/.env.production" +config="$install_dir/live/.env.production" language="$(echo $language | head -c 2)" @@ -191,115 +102,92 @@ ynh_app_setting_set --app="$app" --key=secret_key_base --value="$secret_key_base otp_secret=$(ynh_string_random --length=128) ynh_app_setting_set --app="$app" --key=otp_secret --value="$otp_secret" +# We need rake to build vapid keys, we generate them later once the app is installed vapid_private_key="" vapid_public_key="" ynh_add_config --template="../conf/.env.production.sample" --destination="$config" - chmod 400 "$config" chown $app:$app "$config" -ynh_replace_string --match_string="registrations_mode: 'open'" --replace_string="registrations_mode: 'none'" --target_file="$final_path/live/config/settings.yml" -ynh_replace_string --match_string="min_invite_role: 'admin'" --replace_string="min_invite_role: 'none'" --target_file="$final_path/live/config/settings.yml" +ynh_replace_string --match_string="registrations_mode: 'open'" --replace_string="registrations_mode: 'none'" --target_file="$install_dir/live/config/settings.yml" +ynh_replace_string --match_string="min_invite_role: 'admin'" --replace_string="min_invite_role: 'none'" --target_file="$install_dir/live/config/settings.yml" -ynh_store_file_checksum --file="$final_path/live/config/settings.yml" +ynh_store_file_checksum --file="$install_dir/live/config/settings.yml" -chmod 400 "$final_path/live/config/settings.yml" -chown $app:$app "$final_path/live/config/settings.yml" +chmod 400 "$install_dir/live/config/settings.yml" +chown $app:$app "$install_dir/live/config/settings.yml" #================================================= -# SETUP SYSTEMD +# BUILD APP #================================================= -ynh_script_progression --message="Configuring a systemd service..." --weight=1 +ynh_script_progression --message="Building app..." --weight=1 -# Create a dedicated systemd config -ynh_add_systemd_config --service="$app-web" --template="glitchsoc-web.service" -ynh_add_systemd_config --service="$app-sidekiq" --template="glitchsoc-sidekiq.service" -ynh_add_systemd_config --service="$app-streaming" --template="glitchsoc-streaming.service" - -#================================================= -# INSTALLING GLITCH-SOC -#================================================= -ynh_script_progression --message="Installing Glitch-Soc..." --weight=5 - -pushd "$final_path/live" +pushd "$install_dir/live" + # Building ruby packages + ynh_use_ruby + ynh_gem update --system + ynh_gem install bundler --no-document ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle config deployment 'true' ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle config without 'development test' + ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle config set force_ruby_platform true ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle install -j$(getconf _NPROCESSORS_ONLN) + # Building assets ynh_use_nodejs corepack enable yarn install echo "SAFETY_ASSURED=1">> $config - ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/bundle exec rails db:setup --quiet + ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/bundle exec rails db:migrate --quiet ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/bundle exec rails assets:precompile --quiet + # Generate vapid keys ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/bundle exec rake mastodon:webpush:generate_vapid_key > key.txt - ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/tootctl accounts create "$admin" --email="$admin_mail" --confirmed --role="Owner" > /dev/null - ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/tootctl accounts modify "$admin" --approve + # Create the first admin user + ynh_exec_warn_less ynh_exec_as $app RAILS_ENV=production $ynh_ruby_load_path $ld_preload bin/tootctl accounts create "$admin" --email="$admin_mail" --confirmed --role=Owner > /dev/null popd -vapid_private_key=$(grep -oP "VAPID_PRIVATE_KEY=\K.+" "$final_path/live/key.txt") +# Re-generate config with vapid keys +vapid_private_key=$(grep -oP "VAPID_PRIVATE_KEY=\K.+" "$install_dir/live/key.txt") ynh_app_setting_set --app="$app" --key=vapid_private_key --value="$vapid_private_key" - -vapid_public_key=$(grep -oP "VAPID_PUBLIC_KEY=\K.+" "$final_path/live/key.txt") +vapid_public_key=$(grep -oP "VAPID_PUBLIC_KEY=\K.+" "$install_dir/live/key.txt") ynh_app_setting_set --app="$app" --key=vapid_public_key --value="$vapid_public_key" - -ynh_secure_remove --file="$final_path/live/key.txt" - +ynh_secure_remove --file="$install_dir/live/key.txt" ynh_delete_file_checksum --file="$config" - ynh_add_config --template="../conf/.env.production.sample" --destination="$config" - chmod 400 "$config" chown $app:$app "$config" #================================================= -# SETUP THE CRON FILE +# SYSTEM CONFIGURATION #================================================= -ynh_script_progression --message="Setuping the cron file..." --weight=1 +ynh_script_progression --message="Adding system configurations related to $app..." --weight=1 +# Create a dedicated NGINX config using the conf/nginx.conf template +ynh_add_nginx_config + +# Create a dedicated systemd config +ynh_add_systemd_config --service="$app-web" --template="mastodon-web.service" +yunohost service add "$app-web" --description="$app web service" + +ynh_add_systemd_config --service="$app-sidekiq" --template="mastodon-sidekiq.service" +yunohost service add "$app-sidekiq" --description="$app sidekiq service" + +ynh_add_systemd_config --service="$app-streaming" --template="mastodon-streaming.service" +yunohost service add "$app-streaming" --description="$app streaming service" + +# Create a cron file ynh_add_config --template="../conf/cron" --destination="/etc/cron.d/$app" #================================================= # GENERIC FINALIZATION -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 - -yunohost service add "$app-web" --description="$app web service" -yunohost service add "$app-sidekiq" --description="$app sidekiq service" -yunohost service add "$app-streaming" --description="$app streaming service" - #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." --weight=2 +ynh_script_progression --message="Starting all systemd services..." --weight=1 ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Listening on" ynh_systemd_action --service_name=${app}-sidekiq --action="start" --log_path=systemd --line_match="Schedules Loaded" ynh_systemd_action --service_name=${app}-streaming --action="start" --log_path=systemd --line_match="Streaming API now listening on" -#================================================= -# SETUP SSOWAT -#================================================= -ynh_script_progression --message="Configuring permissions..." --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" - ynh_permission_create --permission="api" --url="/api" --allowed="visitors" --auth_header="false" --show_tile="false" --protected="true" -fi - -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 - -ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/remove b/scripts/remove index 6c80b89..800687d 100644 --- a/scripts/remove +++ b/scripts/remove @@ -7,25 +7,16 @@ #================================================= source _common.sh +source ynh_install_ruby__2 +source ynh_add_swap source /usr/share/yunohost/helpers #================================================= -# LOAD SETTINGS +# REMOVE SYSTEM CONFIGURATIONS #================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -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=$(ynh_app_setting_get --app=$app --key=db_user) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) - -#================================================= -# STANDARD REMOVE -#================================================= -# REMOVE SERVICE INTEGRATION IN YUNOHOST +# REMOVE SYSTEMD SERVICE #================================================= +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-web" >/dev/null @@ -46,76 +37,26 @@ then yunohost service remove "$app-streaming" fi -#================================================= -# STOP AND REMOVE SERVICE -#================================================= -ynh_script_progression --message="Stopping and removing the systemd service..." --weight=1 - # Remove the dedicated systemd config ynh_remove_systemd_config --service="$app-web" ynh_remove_systemd_config --service="$app-sidekiq" ynh_remove_systemd_config --service="$app-streaming" -#================================================= -# REMOVE THE POSTGRESQL DATABASE -#================================================= -ynh_script_progression --message="Removing the PostgreSQL database..." --weight=10 - -# Remove a database if it exists, along with the associated user -ynh_psql_remove_db --db_user=$db_user --db_name=$db_name - -#================================================= -# REMOVE APP MAIN DIR -#================================================= -ynh_script_progression --message="Removing app main directory..." --weight=10 - -# Remove the app directory securely -ynh_secure_remove --file="$final_path" - -#================================================= -# REMOVE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." --weight=1 - # Remove the dedicated NGINX config ynh_remove_nginx_config -#================================================= -# REMOVE DEPENDENCIES -#================================================= -ynh_script_progression --message="Removing dependencies..." --weight=10 +# Remove a cron file +ynh_secure_remove --file="/etc/cron.d/$app" # Remove metapackage and its dependencies ynh_remove_ruby ynh_remove_nodejs -ynh_remove_app_dependencies -ynh_remove_extra_repo - -#================================================= -# SPECIFIC REMOVE -#================================================= -# REMOVE VARIOUS FILES -#================================================= -ynh_script_progression --message="Removing various files..." --weight=1 - -# Remove a cron file -ynh_secure_remove --file="/etc/cron.d/$app" # Remove swap ynh_del_swap -#================================================= -# GENERIC FINALIZATION -#================================================= -# REMOVE DEDICATED USER -#================================================= -ynh_script_progression --message="Removing the dedicated system user..." --weight=1 - -# Delete a system user -ynh_system_user_delete --username=$app - #================================================= # END OF SCRIPT #================================================= -ynh_script_progression --message="Removal of $app completed" --weight=1 +ynh_script_progression --message="Removal of $app completed" --last diff --git a/scripts/restore b/scripts/restore index 81931c2..c69371b 100644 --- a/scripts/restore +++ b/scripts/restore @@ -8,87 +8,28 @@ # Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh +source ../settings/scripts/ynh_install_ruby__2 +source ../settings/scripts/ynh_add_swap source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$(ynh_app_setting_get --app=$app --key=db_user) -db_pwd=$(ynh_app_setting_get --app=$app --key=db_pwd) - -#================================================= -# CHECK IF THE APP CAN BE RESTORED -#================================================= -ynh_script_progression --message="Validating restoration parameters..." --weight=1 - -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " - #================================================= # STANDARD RESTORATION STEPS -#================================================= -# RESTORE THE NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1 - -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..." --weight=1 - -# Create the dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir=$final_path - #================================================= # RESTORE THE APP MAIN DIR #================================================= -ynh_script_progression --message="Restoring the app main directory..." --weight=10 +ynh_script_progression --message="Restoring the app main directory..." --weight=1 -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:www-data "$final_path" - -#================================================= -# SPECIFIC RESTORATION -#================================================= -# REINSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Reinstalling dependencies..." --weight=10 - -# Define and install dependencies -ynh_exec_warn_less ynh_install_app_dependencies $pkg_dependencies -ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$NODEJS_VERSION -ynh_install_ruby --ruby_version=$RUBY_VERSION +chmod 750 "$install_dir" +chmod -R o-rwx "$install_dir" +chown -R $app:www-data "$install_dir" #================================================= # RESTORE THE POSTGRESQL DATABASE #================================================= -ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=10 +ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=1 -ynh_psql_test_if_first_run -ynh_psql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd ynh_psql_execute_as_root --sql="ALTER USER $db_user CREATEDB;" ynh_psql_execute_file_as_root --file="./db.sql" --database="$db_name" @@ -100,9 +41,9 @@ ynh_script_progression --message="Adding swap if needed..." --weight=1 total_memory=$(ynh_get_ram --total) swap_needed=0 -if [ $total_memory -lt $MEMORY_NEEDED ]; then +if [ $total_memory -lt $memory_needed ]; then # Need a minimum of 8Go of memory - swap_needed=$(($MEMORY_NEEDED - $total_memory)) + swap_needed=$(($memory_needed - $total_memory)) fi ynh_script_progression --message="Adding $swap_needed Mo to swap..." --weight=1 @@ -111,13 +52,10 @@ ynh_add_swap --size=$swap_needed #================================================= # INSTALLING RUBY, BUNDLER, AND YARN #================================================= -ynh_script_progression --message="Installing Ruby dependencies..." --weight=10 +ynh_script_progression --message="Reinstalling Ruby and NodeJS..." --weight=1 -pushd "$final_path/live" - ynh_use_ruby - ynh_gem update --system --no-document - ynh_gem install bundler --no-document -popd +ynh_exec_warn_less ynh_install_ruby --ruby_version=$ruby_version +ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$nodejs_version ynh_script_progression --message="Installing Yarn dependencies..." --weight=10 @@ -127,46 +65,47 @@ pushd "$final_path/live" popd #================================================= -# RESTORE VARIOUS FILES +# BUILD APP #================================================= -ynh_script_progression --message="Restoring various files..." --weight=1 +ynh_script_progression --message="Building app..." --weight=1 -ynh_restore_file --origin_path="/etc/cron.d/$app" +pushd "$install_dir/live" + ynh_use_ruby + ynh_gem update --system + ynh_gem install bundler --no-document + ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle install --redownload -j$(getconf _NPROCESSORS_ONLN) +popd #================================================= -# RESTORE SYSTEMD +# RESTORE SYSTEM CONFIGURATIONS #================================================= -ynh_script_progression --message="Restoring the systemd configuration..." --weight=1 +# RESTORE THE PHP-FPM 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-web.service" ynh_restore_file --origin_path="/etc/systemd/system/$app-sidekiq.service" ynh_restore_file --origin_path="/etc/systemd/system/$app-streaming.service" systemctl enable "$app-web" "$app-sidekiq" "$app-streaming" --quiet -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 - yunohost service add "$app-web" --description="$app web service" yunohost service add "$app-sidekiq" --description="$app sidekiq service" yunohost service add "$app-streaming" --description="$app streaming service" -#================================================= -# START SYSTEMD SERVICE -#================================================= -ynh_script_progression --message="Starting a systemd service..." --weight=1 - -ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Listening on" -ynh_systemd_action --service_name=${app}-sidekiq --action="start" --log_path=systemd --line_match="Schedules Loaded" -ynh_systemd_action --service_name=${app}-streaming --action="start" --log_path=systemd --line_match="Streaming API now listening on" +ynh_restore_file --origin_path="/etc/cron.d/$app" #================================================= # GENERIC FINALIZATION #================================================= -# RELOAD NGINX +# RELOAD NGINX AND PHP-FPM OR THE APP SERVICE #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 +ynh_script_progression --message="Reloading NGINX web server and $app's service..." --weight=1 + +ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Listening on" +ynh_systemd_action --service_name=${app}-sidekiq --action="start" --log_path=systemd --line_match="Schedules Loaded" +ynh_systemd_action --service_name=${app}-streaming --action="start" --log_path=systemd --line_match="Streaming API now listening on" ynh_systemd_action --service_name=nginx --action=reload @@ -174,4 +113,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Restoration completed for $app" --weight=1 +ynh_script_progression --message="Restoration completed for $app" --last diff --git a/scripts/upgrade b/scripts/upgrade index 71bfeb3..3abfe5e 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -9,122 +9,16 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -admin=$(ynh_app_setting_get --app=$app --key=admin) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -language=$(ynh_app_setting_get --app=$app --key=language) -redis_namespace=$(ynh_app_setting_get --app=$app --key=db_name) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$(ynh_app_setting_get --app=$app --key=db_user) -db_pwd=$(ynh_app_setting_get --app=$app --key=db_pwd) -admin_mail=$(ynh_user_get_info --username=$admin --key='mail') -port_web=$(ynh_app_setting_get --app=$app --key=port_web) -port_stream=$(ynh_app_setting_get --app=$app --key=port_stream) - -secret_key_base=$(ynh_app_setting_get --app=$app --key=secret_key_base) -otp_secret=$(ynh_app_setting_get --app=$app --key=otp_secret) -vapid_private_key=$(ynh_app_setting_get --app=$app --key=vapid_private_key) -vapid_public_key=$(ynh_app_setting_get --app=$app --key=vapid_public_key) - -config="$final_path/live/.env.production" - -max_toot_chars=$(ynh_app_setting_get --app=$app --key=max_toot_chars) -max_pinned_toots=$(ynh_app_setting_get --app=$app --key=max_pinned_toots) -max_bio_chars=$(ynh_app_setting_get --app=$app --key=max_bio_chars) -max_profile_fields=$(ynh_app_setting_get --app=$app --key=max_profile_fields) -max_display_name_chars=$(ynh_app_setting_get --app=$app --key=max_display_name_chars) -max_poll_options=$(ynh_app_setting_get --app=$app --key=max_poll_options) -max_poll_option_chars=$(ynh_app_setting_get --app=$app --key=max_poll_option_chars) -max_image_size=$(ynh_app_setting_get --app=$app --key=max_image_size) -max_video_size=$(ynh_app_setting_get --app=$app --key=max_video_size) -max_emoji_size=$(ynh_app_setting_get --app=$app --key=max_emoji_size) -max_remote_emoji_size=$(ynh_app_setting_get --app=$app --key=max_remote_emoji_size) - -#================================================= -# CHECK VERSION -#================================================= -ynh_script_progression --message="Checking version..." --weight=1 - +config="$install_dir/live/.env.production" upgrade_type=$(ynh_check_app_version_changed) -#================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP -#================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=1 - -# Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - ynh_clean_check_starting - # Restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - #================================================= # STANDARD UPGRADE STEPS -#================================================= -# STOP SYSTEMD SERVICE -#================================================= -ynh_script_progression --message="Stopping a systemd service..." --weight=1 - -ynh_systemd_action --service_name=${app}-web --action="stop" --log_path=systemd --line_match="Stopped" -ynh_systemd_action --service_name=${app}-sidekiq --action="stop" --log_path=systemd --line_match="Stopped" -ynh_systemd_action --service_name=${app}-streaming --action="stop" --log_path=systemd --line_match="Stopped" - #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 -# Cleaning legacy permissions -if ynh_legacy_permissions_exists; then - ynh_legacy_permissions_delete_all - - ynh_app_setting_delete --app=$app --key=is_public -fi - -# Create a permission if needed -if ! ynh_permission_exists --permission="api"; then - ynh_permission_create --permission="api" --url="/api" --allowed="visitors" --auth_header="false" --show_tile="false" --protected="true" -fi - -# If port_web doesn't exist, create it, needed for old install -if [[ -z "$port_web" ]]; then - port_web=3000 - ynh_app_setting_set --app=$app --key=port_web --value=$port_web -fi - -# If port_web doesn't exist, create it, needed for old install -if [[ -z "$port_stream" ]]; then - port_stream=4000 - ynh_app_setting_set --app=$app --key=port_stream --value=$port_stream -fi - -# If db_user doesn't exist, create it, needed for old install -if [[ -z "$db_user" ]]; then - db_user=$(ynh_sanitize_dbid --db_name=$app) - ynh_app_setting_set --app=$app --key=db_user --value=$db_user -fi - -# If db_pwd doesn't exist, create it, needed for old install -if [[ -z "$db_pwd" ]]; then - db_pwd=$(ynh_string_random) - ynh_app_setting_set --app=$app --key=db_pwd --value=$db_pwd - ynh_psql_test_if_first_run - sudo --login --user=postgres psql -c"ALTER user $app WITH PASSWORD '$db_pwd'" postgres - ynh_replace_string --match_string="DB_PASS=" --replace_string="DB_PASS=${db_pwd}" --target_file="$config" -fi - # Remove paperclip_secret ynh_app_setting_delete --app=$app --key=paperclip_secret @@ -215,16 +109,45 @@ if [ -z "$max_remote_emoji_size" ]; then ynh_app_setting_set --app=$app --key=max_remote_emoji_size --value=$max_remote_emoji_size fi -#Remove previous added repository -ynh_remove_extra_repo +# Rename the database to match packaging v2 defaults db_name (`$app_production` to `$app`) +if [[ $db_name = *'_production' ]]; then + ynh_systemd_action --service_name=${app}-web --action="stop" --log_path=systemd --line_match="Stopped" + ynh_systemd_action --service_name=${app}-sidekiq --action="stop" --log_path=systemd --line_match="Stopped" + ynh_systemd_action --service_name=${app}-streaming --action="stop" --log_path=systemd --line_match="Stopped" + + ynh_psql_execute_as_root --sql="ALTER DATABASE $db_name RENAME TO $app;" + db_name=$app + ynh_app_setting_set --app=$app --key=db_name --value=$db_name +fi + +if ynh_compare_current_package_version --comparison lt --version 2023.06.19~ynh2 +then + ynh_remove_logrotate +fi + +# If service doesn't exist, create it +if [[ -z "$service" ]]; then + # Set `service` settings to support `yunohost app shell` command + ynh_app_setting_set --app="$app" --key=service --value="$app-web.service" +fi #================================================= -# CREATE DEDICATED USER +# STOP SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 +ynh_script_progression --message="Stopping a systemd service..." --weight=1 -# Create a dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir=$final_path +ynh_systemd_action --service_name=${app}-web --action="stop" --log_path=systemd --line_match="Stopped" +ynh_systemd_action --service_name=${app}-sidekiq --action="stop" --log_path=systemd --line_match="Stopped" +ynh_systemd_action --service_name=${app}-streaming --action="stop" --log_path=systemd --line_match="Stopped" + +#================================================= +# "REBUILD" THE APP (DEPLOY NEW SOURCES, RERUN NPM BUILD...) +#================================================= +# Update Ruby and NodeJS +ynh_script_progression --message="Upgrading Ruby and NodeJS..." --weight=5 + +ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$NODEJS_VERSION +ynh_exec_warn_less ynh_install_ruby --ruby_version=$RUBY_VERSION #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -232,110 +155,37 @@ ynh_system_user_create --username=$app --home_dir=$final_path if [ "$upgrade_type" == "UPGRADE_APP" ] then + # Add swap if needed + total_memory=$(ynh_get_ram --total) + swap_needed=0 + + if [ $total_memory -lt $MEMORY_NEEDED ]; then + # Need a minimum of 2.5Go of memory + swap_needed=$(($MEMORY_NEEDED - $total_memory)) + + ynh_script_progression --message="Adding $swap_needed Mo to swap..." --weight=1 + ynh_add_swap --size=$swap_needed + fi + + # Update Glitch-Soc ynh_script_progression --message="Upgrading source files..." --weight=1 - # Download Glitch-Soc - tmpdir="$(mktemp -d)" + ynh_setup_source --dest_dir="$install_dir/live" --keep="public/system/" - mkdir $tmpdir/system - if [ -d "$final_path/live/public/system" ]; then - mv --verbose --no-target-directory --backup=numbered "$final_path/live/public/system" "$final_path/system.tmp" - fi - rsync -a "$config" "$tmpdir/." - ynh_secure_remove --file="$final_path/live" - - ynh_setup_source --dest_dir="$final_path/live" + chmod 750 "$install_dir" + chmod -R o-rwx "$install_dir" + chown -R $app:www-data "$install_dir" - if [ -d "$final_path/system.tmp" ]; then - mv --verbose --no-target-directory "$final_path/system.tmp" "$final_path/live/public/system" - fi - rsync -a "$tmpdir/.env.production" "$final_path/live/." - ynh_secure_remove --file="$tmpdir" + pushd "$install_dir/live" + ynh_use_ruby + ynh_gem update --system --no-document + ynh_gem install bundler --no-document + popd - # Clean files which are not needed anymore - ynh_secure_remove --file="$final_path/live/config/initializers/timeout.rb" - - chmod 750 "$final_path" - chmod -R o-rwx "$final_path" - chown -R $app:www-data "$final_path" -fi - -#================================================= -# NGINX CONFIGURATION -#================================================= -ynh_script_progression --message="Upgrading NGINX web server configuration..." --weight=1 - -# Create a dedicated NGINX config -ynh_add_nginx_config - -#================================================= -# UPGRADE DEPENDENCIES -#================================================= -ynh_script_progression --message="Upgrading dependencies..." --weight=10 - -ynh_exec_warn_less ynh_install_app_dependencies $pkg_dependencies -ynh_exec_warn_less ynh_install_nodejs --nodejs_version=$NODEJS_VERSION -ynh_exec_warn_less ynh_install_ruby --ruby_version=$RUBY_VERSION - -#================================================= -# SPECIFIC UPGRADE -#================================================= -# ADD SWAP IF NEEDED -#================================================= -ynh_script_progression --message="Adding swap if needed..." --weight=1 - -total_memory=$(ynh_get_ram --total) -swap_needed=0 - -if [ $total_memory -lt $MEMORY_NEEDED ]; then - # Need a minimum of 8Go of memory - swap_needed=$(($MEMORY_NEEDED - $total_memory)) -fi - -ynh_script_progression --message="Adding $swap_needed Mo to swap..." --weight=1 -ynh_add_swap --size=$swap_needed - -#================================================= -# INSTALLING RUBY AND BUNDLER -#================================================= -ynh_script_progression --message="Installing Ruby dependencies..." --weight=5 - -pushd "$final_path/live" - ynh_use_ruby - ynh_gem update --system --no-document - ynh_gem install bundler --no-document -popd - -#================================================= -# UPDATE A CONFIG FILE -#================================================= -ynh_script_progression --message="Updating a config file..." --weight=1 - -language="$(echo $language | head -c 2)" - -ynh_add_config --template="../conf/.env.production.sample" --destination="$config" - -chmod 400 "$config" -chown $app:$app "$config" - -#================================================= -# SETUP SYSTEMD -#================================================= -ynh_script_progression --message="Upgrading systemd configuration..." --weight=1 - -# Create a dedicated systemd config -ynh_add_systemd_config --service="$app-web" --template="glitchsoc-web.service" -ynh_add_systemd_config --service="$app-sidekiq" --template="glitchsoc-sidekiq.service" -ynh_add_systemd_config --service="$app-streaming" --template="glitchsoc-streaming.service" - -#================================================= -# UPGRADE GLITCH-SOC -#================================================= -if [ "$upgrade_type" == "UPGRADE_APP" ] -then + # Perform upgrade actions on Glitch-Soc ynh_script_progression --message="Upgrading Glitch-Soc..." --weight=10 - pushd "$final_path/live" + pushd "$install_dir/live" ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle config deployment 'true' ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle config without 'development test' ynh_exec_as $app $ynh_ruby_load_path $ld_preload bin/bundle install -j$(getconf _NPROCESSORS_ONLN) @@ -352,23 +202,37 @@ then fi #================================================= -# SETUP THE CRON FILE +# REAPPLY SYSTEM CONFIGURATIONS #================================================= -ynh_script_progression --message="Setuping the cron file..." --weight=1 +ynh_script_progression --message="Upgrading system configurations related to $app..." --weight=1 -ynh_add_config --template="../conf/cron" --destination="/etc/cron.d/$app" +ynh_add_nginx_config -#================================================= -# GENERIC FINALIZATION -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." --weight=1 +ynh_add_systemd_config --service="$app-web" --template="web.service" +ynh_add_systemd_config --service="$app-sidekiq" --template="sidekiq.service" +ynh_add_systemd_config --service="$app-streaming" --template="streaming.service" yunohost service add "$app-web" --description="$app web service" yunohost service add "$app-sidekiq" --description="$app sidekiq service" yunohost service add "$app-streaming" --description="$app streaming service" +ynh_add_systemd_config + +ynh_add_config --template="../conf/cron" --destination="/etc/cron.d/$app" + +#================================================= +# RECONFIGURE THE APP (UPDATE CONF, APPLY MIGRATIONS...) +#================================================= +# UPDATE A CONFIG FILE +#================================================= +ynh_script_progression --message="Updating a configuration file..." --weight=1 + +language="$(echo $language | head -c 2)" + +ynh_add_config --template="../conf/.env.production.sample" --destination="$config" +chmod 400 "$config" +chown $app:$app "$config" + #================================================= # START SYSTEMD SERVICE #================================================= @@ -378,13 +242,6 @@ ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd ynh_systemd_action --service_name=${app}-sidekiq --action="start" --log_path=systemd --line_match="Schedules Loaded" ynh_systemd_action --service_name=${app}-streaming --action="start" --log_path=systemd --line_match="Streaming API now listening on" -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 - -ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/ynh_add_swap b/scripts/ynh_add_swap new file mode 100644 index 0000000..d7ec44b --- /dev/null +++ b/scripts/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/ynh_install_ruby__2 b/scripts/ynh_install_ruby__2 new file mode 100644 index 0000000..521a182 --- /dev/null +++ b/scripts/ynh_install_ruby__2 @@ -0,0 +1,310 @@ +#!/bin/bash + +ynh_ruby_try_bash_extension() { + if [ -x src/configure ]; then + src/configure && make -C src || { + ynh_print_info --message="Optional bash extension failed to build, but things will still work normally." + } + fi +} + +rbenv_install_dir="/opt/rbenv" +ruby_version_path="$rbenv_install_dir/versions" +# RBENV_ROOT is the directory of rbenv, it needs to be loaded as a environment variable. +export RBENV_ROOT="$rbenv_install_dir" +export rbenv_root="$rbenv_install_dir" + +ruby_dependencies="" +build_ruby_dependencies="libjemalloc-dev curl build-essential libreadline-dev zlib1g-dev libsqlite3-dev libssl-dev libxml2-dev libxslt-dev autoconf automake bison libtool" +pkg_dependencies="$pkg_dependencies $ruby_dependencies" +build_pkg_dependencies="$build_pkg_dependencies $build_ruby_dependencies" + +# Load the version of Ruby for an app, and set variables. +# +# ynh_use_ruby has to be used in any app scripts before using Ruby for the first time. +# This helper will provide alias and variables to use in your scripts. +# +# To use gem or Ruby, use the alias `ynh_gem` and `ynh_ruby` +# Those alias will use the correct version installed for the app +# For example: use `ynh_gem install` instead of `gem install` +# +# With `sudo` or `ynh_exec_as`, use instead the fallback variables `$ynh_gem` and `$ynh_ruby` +# And propagate $PATH to sudo with $ynh_ruby_load_path +# Exemple: `ynh_exec_as $app $ynh_ruby_load_path $ynh_gem install` +# +# $PATH contains the path of the requested version of Ruby. +# However, $PATH is duplicated into $ruby_path to outlast any manipulation of $PATH +# You can use the variable `$ynh_ruby_load_path` to quickly load your Ruby version +# in $PATH for an usage into a separate script. +# Exemple: $ynh_ruby_load_path $install_dir/script_that_use_gem.sh` +# +# +# Finally, to start a Ruby service with the correct version, 2 solutions +# Either the app is dependent of Ruby or gem, but does not called it directly. +# In such situation, you need to load PATH +# `Environment="__YNH_RUBY_LOAD_PATH__"` +# `ExecStart=__FINALPATH__/my_app` +# You will replace __YNH_RUBY_LOAD_PATH__ with $ynh_ruby_load_path +# +# Or Ruby start the app directly, then you don't need to load the PATH variable +# `ExecStart=__YNH_RUBY__ my_app run` +# You will replace __YNH_RUBY__ with $ynh_ruby +# +# +# one other variable is also available +# - $ruby_path: The absolute path to Ruby binaries for the chosen version. +# +# usage: ynh_use_ruby +# +# Requires YunoHost version 3.2.2 or higher. +ynh_use_ruby () { + ruby_version=$(ynh_app_setting_get --app=$app --key=ruby_version) + + # Get the absolute path of this version of Ruby + ruby_path="$ruby_version_path/$YNH_APP_INSTANCE_NAME/bin" + + # Allow alias to be used into bash script + shopt -s expand_aliases + + # Create an alias for the specific version of Ruby and a variable as fallback + ynh_ruby="$ruby_path/ruby" + alias ynh_ruby="$ynh_ruby" + # And gem + ynh_gem="$ruby_path/gem" + alias ynh_gem="$ynh_gem" + + # Load the path of this version of Ruby in $PATH + if [[ :$PATH: != *":$ruby_path"* ]]; then + PATH="$ruby_path:$PATH" + fi + # Create an alias to easily load the PATH + ynh_ruby_load_path="PATH=$PATH" + + # Sets the local application-specific Ruby version + pushd $install_dir + $rbenv_install_dir/bin/rbenv local $ruby_version + popd +} + +# Install a specific version of Ruby +# +# ynh_install_ruby will install the version of Ruby provided as argument by using rbenv. +# +# This helper creates a /etc/profile.d/rbenv.sh that configures PATH environment for rbenv +# for every LOGIN user, hence your user must have a defined shell (as opposed to /usr/sbin/nologin) +# +# Don't forget to execute ruby-dependent command in a login environment +# (e.g. sudo --login option) +# When not possible (e.g. in systemd service definition), please use direct path +# to rbenv shims (e.g. $RBENV_ROOT/shims/bundle) +# +# usage: ynh_install_ruby --ruby_version=ruby_version +# | arg: -v, --ruby_version= - Version of ruby to install. +# +# Requires YunoHost version 3.2.2 or higher. +ynh_install_ruby () { + # Declare an array to define the options of this helper. + local legacy_args=v + local -A args_array=( [v]=ruby_version= ) + local ruby_version + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # Load rbenv path in PATH + local CLEAR_PATH="$rbenv_install_dir/bin:$PATH" + + # Remove /usr/local/bin in PATH in case of Ruby prior installation + PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@') + + # Move an existing Ruby binary, to avoid to block rbenv + test -x /usr/bin/ruby && mv /usr/bin/ruby /usr/bin/ruby_rbenv + + # Install or update rbenv + rbenv="$(command -v rbenv $rbenv_install_dir/bin/rbenv | grep "$rbenv_install_dir/bin/rbenv" | head -1)" + if [ -n "$rbenv" ]; then + ynh_print_info --message="rbenv already seems installed in \`$rbenv'." + pushd "${rbenv%/*/*}" + if git remote -v 2>/dev/null | grep "https://github.com/rbenv/rbenv.git"; then + ynh_print_info --message="Trying to update with git..." + git pull -q --tags origin master + ynh_ruby_try_bash_extension + else + ynh_print_info --message="Reinstalling rbenv with git..." + cd .. + ynh_secure_remove --file=$rbenv_install_dir + mkdir -p $rbenv_install_dir + cd $rbenv_install_dir + git init -q + git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1 + git checkout -q -b master origin/master + ynh_ruby_try_bash_extension + rbenv=$rbenv_install_dir/bin/rbenv + fi + popd + else + ynh_print_info --message="Installing rbenv with git..." + mkdir -p $rbenv_install_dir + pushd $rbenv_install_dir + git init -q + git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1 + git checkout -q -b master origin/master + ynh_ruby_try_bash_extension + rbenv=$rbenv_install_dir/bin/rbenv + popd + fi + + ruby_build="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-install rbenv-install | head -1)" + if [ -n "$ruby_build" ]; then + ynh_print_info --message="\`rbenv install' command already available in \`$ruby_build'." + pushd "${ruby_build%/*/*}" + if git remote -v 2>/dev/null | grep "https://github.com/rbenv/ruby-build.git"; then + ynh_print_info --message="Trying to update rbenv with git..." + git pull -q origin master + fi + popd + else + ynh_print_info --message="Installing ruby-build with git..." + mkdir -p "${rbenv_install_dir}/plugins" + git clone -q https://github.com/rbenv/ruby-build.git "${rbenv_install_dir}/plugins/ruby-build" + fi + + rbenv_alias="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-alias rbenv-alias | head -1)" + if [ -n "$rbenv_alias" ]; then + ynh_print_info --message="\`rbenv alias' command already available in \`$rbenv_alias'." + pushd "${rbenv_alias%/*/*}" + if git remote -v 2>/dev/null | grep "https://github.com/tpope/rbenv-aliases.git"; then + ynh_print_info --message="Trying to update rbenv-aliases with git..." + git pull -q origin master + fi + popd + else + ynh_print_info --message="Installing rbenv-aliases with git..." + mkdir -p "${rbenv_install_dir}/plugins" + git clone -q https://github.com/tpope/rbenv-aliases.git "${rbenv_install_dir}/plugins/rbenv-aliase" + fi + + rbenv_latest="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-latest rbenv-latest | head -1)" + if [ -n "$rbenv_latest" ]; then + ynh_print_info --message="\`rbenv latest' command already available in \`$rbenv_latest'." + pushd "${rbenv_latest%/*/*}" + if git remote -v 2>/dev/null | grep "https://github.com/momo-lab/xxenv-latest.git"; then + ynh_print_info --message="Trying to update xxenv-latest with git..." + git pull -q origin master + fi + popd + else + ynh_print_info --message="Installing xxenv-latest with git..." + mkdir -p "${rbenv_install_dir}/plugins" + git clone -q https://github.com/momo-lab/xxenv-latest.git "${rbenv_install_dir}/plugins/xxenv-latest" + fi + + # Enable caching + mkdir -p "${rbenv_install_dir}/cache" + + # Create shims directory if needed + mkdir -p "${rbenv_install_dir}/shims" + + # Restore /usr/local/bin in PATH + PATH=$CLEAR_PATH + + # And replace the old Ruby binary + test -x /usr/bin/ruby_rbenv && mv /usr/bin/ruby_rbenv /usr/bin/ruby + + # Install the requested version of Ruby + local final_ruby_version=$(rbenv latest --print $ruby_version) + if ! [ -n "$final_ruby_version" ]; then + final_ruby_version=$ruby_version + fi + ynh_print_info --message="Installing Ruby-$final_ruby_version" + CONFIGURE_OPTS="--disable-install-doc --with-jemalloc" MAKE_OPTS="-j2" rbenv install --skip-existing $final_ruby_version > /dev/null 2>&1 + + # Store ruby_version into the config of this app + ynh_app_setting_set --app=$YNH_APP_INSTANCE_NAME --key=ruby_version --value=$final_ruby_version + + # Remove app virtualenv + if `rbenv alias --list | grep --quiet "$YNH_APP_INSTANCE_NAME " 1>/dev/null 2>&1` + then + rbenv alias $YNH_APP_INSTANCE_NAME --remove + fi + + # Create app virtualenv + rbenv alias $YNH_APP_INSTANCE_NAME $final_ruby_version + + # Cleanup Ruby versions + ynh_cleanup_ruby + + # Set environment for Ruby users + echo "#rbenv +export RBENV_ROOT=$rbenv_install_dir +export PATH=\"$rbenv_install_dir/bin:$PATH\" +eval \"\$(rbenv init -)\" +#rbenv" > /etc/profile.d/rbenv.sh + + # Load the environment + eval "$(rbenv init -)" +} + +# Remove the version of Ruby used by the app. +# +# This helper will also cleanup Ruby versions +# +# usage: ynh_remove_ruby +ynh_remove_ruby () { + local ruby_version=$(ynh_app_setting_get --app=$YNH_APP_INSTANCE_NAME --key=ruby_version) + + # Load rbenv path in PATH + local CLEAR_PATH="$rbenv_install_dir/bin:$PATH" + + # Remove /usr/local/bin in PATH in case of Ruby prior installation + PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@') + + rbenv alias $YNH_APP_INSTANCE_NAME --remove + + # Remove the line for this app + ynh_app_setting_delete --app=$YNH_APP_INSTANCE_NAME --key=ruby_version + + # Cleanup Ruby versions + ynh_cleanup_ruby +} + +# Remove no more needed versions of Ruby used by the app. +# +# This helper will check what Ruby version are no more required, +# and uninstall them +# If no app uses Ruby, rbenv will be also removed. +# +# usage: ynh_cleanup_ruby +ynh_cleanup_ruby () { + + # List required Ruby versions + local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$') + local required_ruby_versions="" + for installed_app in $installed_apps + do + local installed_app_ruby_version=$(ynh_app_setting_get --app=$installed_app --key="ruby_version") + if [[ $installed_app_ruby_version ]] + then + required_ruby_versions="${installed_app_ruby_version}\n${required_ruby_versions}" + fi + done + + # Remove no more needed Ruby versions + local installed_ruby_versions=$(rbenv versions --bare --skip-aliases | grep -Ev '/') + for installed_ruby_version in $installed_ruby_versions + do + if ! `echo ${required_ruby_versions} | grep "${installed_ruby_version}" 1>/dev/null 2>&1` + then + ynh_print_info --message="Removing of Ruby-$installed_ruby_version" + $rbenv_install_dir/bin/rbenv uninstall --force $installed_ruby_version + fi + done + + # If none Ruby version is required + if [[ ! $required_ruby_versions ]] + then + # Remove rbenv environment configuration + ynh_print_info --message="Removing of rbenv-$rbenv_version" + ynh_secure_remove --file="$rbenv_install_dir" + ynh_secure_remove --file="/etc/profile.d/rbenv.sh" + fi +} diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..1d77b27 --- /dev/null +++ b/tests.toml @@ -0,0 +1,24 @@ +test_format = 1.0 + +[default] + + # ------------ + # Tests to run + # ------------ + + exclude = ["install.subdir", "install.nourl", "install.multi", "change_url"] + # The test IDs to be used in only/exclude statements are: install.root, install.subdir, install.nourl, install.multi, backup_restore, upgrade, upgrade.someCommitId change_url + # NB: you should NOT need this except if you really have a good reason... + + + # ------------------------------- + # Default args to use for install + # ------------------------------- + + # Use defaults from manifest.toml + + # ------------------------------- + # Commits to test upgrade from + # ------------------------------- + + test_upgrade_from.9c7a5ae.name = "Upgrade from 2023.06.19~ynh1"