_common.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. #!/bin/bash
  2. # =============================================================================
  3. # YUNOHOST 2.7 FORTHCOMING HELPERS
  4. # =============================================================================
  5. # Create a dedicated nginx config
  6. #
  7. # usage: ynh_add_nginx_config
  8. ynh_add_nginx_config () {
  9. finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
  10. ynh_backup_if_checksum_is_different "$finalnginxconf"
  11. sudo cp ../conf/nginx.conf "$finalnginxconf"
  12. # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
  13. # Substitute in a nginx config file only if the variable is not empty
  14. if test -n "${path_url:-}"; then
  15. ynh_replace_string "__PATH__" "$path_url" "$finalnginxconf"
  16. fi
  17. if test -n "${domain:-}"; then
  18. ynh_replace_string "__DOMAIN__" "$domain" "$finalnginxconf"
  19. fi
  20. if test -n "${port:-}"; then
  21. ynh_replace_string "__PORT__" "$port" "$finalnginxconf"
  22. fi
  23. if test -n "${app:-}"; then
  24. ynh_replace_string "__NAME__" "$app" "$finalnginxconf"
  25. fi
  26. if test -n "${final_path:-}"; then
  27. ynh_replace_string "__FINALPATH__" "$final_path" "$finalnginxconf"
  28. fi
  29. ynh_store_file_checksum "$finalnginxconf"
  30. sudo systemctl reload nginx
  31. }
  32. # Remove the dedicated nginx config
  33. #
  34. # usage: ynh_remove_nginx_config
  35. ynh_remove_nginx_config () {
  36. ynh_secure_remove "/etc/nginx/conf.d/$domain.d/$app.conf"
  37. sudo systemctl reload nginx
  38. }
  39. # Create a dedicated php-fpm config
  40. #
  41. # usage: ynh_add_fpm_config
  42. ynh_add_fpm_config () {
  43. finalphpconf="/etc/php5/fpm/pool.d/$app.conf"
  44. ynh_backup_if_checksum_is_different "$finalphpconf"
  45. sudo cp ../conf/php-fpm.conf "$finalphpconf"
  46. ynh_replace_string "__NAMETOCHANGE__" "$app" "$finalphpconf"
  47. ynh_replace_string "__FINALPATH__" "$final_path" "$finalphpconf"
  48. ynh_replace_string "__USER__" "$app" "$finalphpconf"
  49. sudo chown root: "$finalphpconf"
  50. ynh_store_file_checksum "$finalphpconf"
  51. if [ -e "../conf/php-fpm.ini" ]
  52. then
  53. finalphpini="/etc/php5/fpm/conf.d/20-$app.ini"
  54. ynh_backup_if_checksum_is_different "$finalphpini"
  55. sudo cp ../conf/php-fpm.ini "$finalphpini"
  56. sudo chown root: "$finalphpini"
  57. ynh_store_file_checksum "$finalphpini"
  58. fi
  59. sudo systemctl reload php5-fpm
  60. }
  61. # Remove the dedicated php-fpm config
  62. #
  63. # usage: ynh_remove_fpm_config
  64. ynh_remove_fpm_config () {
  65. ynh_secure_remove "/etc/php5/fpm/pool.d/$app.conf"
  66. ynh_secure_remove "/etc/php5/fpm/conf.d/20-$app.ini" 2>&1
  67. sudo systemctl reload php5-fpm
  68. }
  69. # Create a dedicated systemd config
  70. #
  71. # usage: ynh_add_systemd_config
  72. ynh_add_systemd_config () {
  73. finalsystemdconf="/etc/systemd/system/$app.service"
  74. ynh_backup_if_checksum_is_different "$finalsystemdconf"
  75. sudo cp ../conf/systemd.service "$finalsystemdconf"
  76. # To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
  77. # Substitute in a nginx config file only if the variable is not empty
  78. if test -n "${final_path:-}"; then
  79. ynh_replace_string "__FINALPATH__" "$final_path" "$finalsystemdconf"
  80. fi
  81. if test -n "${app:-}"; then
  82. ynh_replace_string "__APP__" "$app" "$finalsystemdconf"
  83. fi
  84. ynh_store_file_checksum "$finalsystemdconf"
  85. sudo chown root: "$finalsystemdconf"
  86. sudo systemctl enable $app
  87. sudo systemctl daemon-reload
  88. }
  89. # Remove the dedicated systemd config
  90. #
  91. # usage: ynh_remove_systemd_config
  92. ynh_remove_systemd_config () {
  93. finalsystemdconf="/etc/systemd/system/$app.service"
  94. if [ -e "$finalsystemdconf" ]; then
  95. sudo systemctl stop $app
  96. sudo systemctl disable $app
  97. ynh_secure_remove "$finalsystemdconf"
  98. fi
  99. }
  100. #=================================================
  101. #=================================================
  102. #=================================================
  103. # CHECKING
  104. #=================================================
  105. CHECK_DOMAINPATH () { # Vérifie la disponibilité du path et du domaine.
  106. # Check availability of a web path
  107. ynh_webpath_available $domain $path_url
  108. # Register/book a web path for an app
  109. ynh_webpath_register $app $domain $path_url
  110. }
  111. CHECK_FINALPATH () { # Vérifie que le dossier de destination n'est pas déjà utilisé.
  112. final_path=/var/www/$app
  113. test ! -e "$final_path" || ynh_die "This path already contains a folder"
  114. }
  115. #=================================================
  116. # DISPLAYING
  117. #=================================================
  118. NO_PRINT () { # Supprime l'affichage dans stdout pour la commande en argument.
  119. set +x
  120. $@
  121. set -x
  122. }
  123. WARNING () { # Écrit sur le canal d'erreur pour passer en warning.
  124. $@ >&2
  125. }
  126. SUPPRESS_WARNING () { # Force l'écriture sur la sortie standard
  127. $@ 2>&1
  128. }
  129. QUIET () { # Redirige la sortie standard dans /dev/null
  130. $@ > /dev/null
  131. }
  132. ALL_QUIET () { # Redirige la sortie standard et d'erreur dans /dev/null
  133. $@ > /dev/null 2>&1
  134. }
  135. #=================================================
  136. # BACKUP
  137. #=================================================
  138. BACKUP_FAIL_UPGRADE () {
  139. WARNING echo "Upgrade failed."
  140. app_bck=${app//_/-} # Replace all '_' by '-'
  141. if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number; then # Vérifie l'existence de l'archive avant de supprimer l'application et de restaurer
  142. sudo yunohost app remove $app # Supprime l'application avant de la restaurer.
  143. sudo yunohost backup restore --ignore-system $app_bck-pre-upgrade$backup_number --apps $app --force # Restore the backup if upgrade failed
  144. ynh_die "The app was restored to the way it was before the failed upgrade."
  145. fi
  146. }
  147. BACKUP_BEFORE_UPGRADE () { # Backup the current version of the app, restore it if the upgrade fails
  148. backup_number=1
  149. old_backup_number=2
  150. app_bck=${app//_/-} # Replace all '_' by '-'
  151. if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1; then # Vérifie l'existence d'une archive déjà numéroté à 1.
  152. backup_number=2 # Et passe le numéro de l'archive à 2
  153. old_backup_number=1
  154. fi
  155. sudo yunohost backup create --ignore-system --apps $app --name $app_bck-pre-upgrade$backup_number # Créer un backup différent de celui existant.
  156. if [ "$?" -eq 0 ]; then # Si le backup est un succès, supprime l'archive précédente.
  157. if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number; then # Vérifie l'existence de l'ancienne archive avant de la supprimer, pour éviter une erreur.
  158. QUIET sudo yunohost backup delete $app_bck-pre-upgrade$old_backup_number
  159. fi
  160. else # Si le backup a échoué
  161. ynh_die "Backup failed, the upgrade process was aborted."
  162. fi
  163. }
  164. HUMAN_SIZE () { # Transforme une taille en Ko en une taille lisible pour un humain
  165. human=$(numfmt --to=iec --from-unit=1K $1)
  166. echo $human
  167. }
  168. CHECK_SIZE () { # Vérifie avant chaque backup que l'espace est suffisant
  169. file_to_analyse=$1
  170. backup_size=$(sudo du --summarize "$file_to_analyse" | cut -f1)
  171. free_space=$(sudo df --output=avail "/home/yunohost.backup" | sed 1d)
  172. if [ $free_space -le $backup_size ]
  173. then
  174. WARNING echo "Espace insuffisant pour sauvegarder $file_to_analyse."
  175. WARNING echo "Espace disponible: $(HUMAN_SIZE $free_space)"
  176. ynh_die "Espace nécessaire: $(HUMAN_SIZE $backup_size)"
  177. fi
  178. }
  179. # Ce helper est temporaire et sert de remplacement à la véritable fonction ynh_restore_file. Le temps qu'elle arrive...
  180. ynh_restore_file () {
  181. if [ -f "$1" ]; then
  182. ynh_die "There is already a file at this path: $1"
  183. fi
  184. sudo cp -a "${YNH_APP_BACKUP_DIR}$1" "$1"
  185. }
  186. #=================================================
  187. # PACKAGE CHECK BYPASSING...
  188. #=================================================
  189. IS_PACKAGE_CHECK () { # Détermine une exécution en conteneur (Non testé)
  190. return $(uname -n | grep -c 'pchecker_lxc')
  191. }
  192. #=================================================
  193. # NODEJS
  194. #=================================================
  195. # INFOS
  196. # n (Node version management) utilise la variable PATH pour stocker le path de la version de node à utiliser.
  197. # C'est ainsi qu'il change de version
  198. # ynh_install_nodejs installe la version de nodejs demandée en argument, avec n
  199. # ynh_use_nodejs active une version de nodejs dans le script courant
  200. # 3 variables sont mises à disposition, et 2 sont stockées dans la config de l'app
  201. # - nodejs_path: Le chemin absolu de cette version de node
  202. # Utilisé pour des appels directs à node.
  203. # - nodejs_version: Simplement le numéro de version de nodejs pour cette application
  204. # - nodejs_use_version: Un alias pour charger une version de node dans le shell courant.
  205. # Utilisé pour démarrer un service ou un script qui utilise node ou npm
  206. # Dans ce cas, c'est $PATH qui contient le chemin de la version de node. Il doit être propagé sur les autres shell si nécessaire.
  207. n_install_dir="/opt/node_n"
  208. node_version_path="/usr/local/n/versions/node"
  209. ynh_use_nodejs () {
  210. nodejs_version=$(ynh_app_setting_get $app nodejs_version)
  211. load_n_path="[[ :$PATH: == *\":$n_install_dir/bin:\"* ]] || PATH=\"$n_install_dir/bin:$PATH\""
  212. nodejs_use_version="$n_install_dir/bin/n -q $nodejs_version"
  213. # "Load" a version of node
  214. eval $load_n_path; $nodejs_use_version
  215. # Get the absolute path of this version of node
  216. nodejs_path="$(n bin $nodejs_version)"
  217. # Make an alias for node use
  218. ynh_node_exec="eval $load_n_path; n use $nodejs_version"
  219. }
  220. ynh_install_nodejs () {
  221. # Use n, https://github.com/tj/n to manage the nodejs versions
  222. nodejs_version="$1"
  223. local n_install_script="https://git.io/n-install"
  224. # Create $n_install_dir
  225. mkdir -p "$n_install_dir"
  226. # Load n path in PATH
  227. CLEAR_PATH="$n_install_dir/bin:$PATH"
  228. # Remove /usr/local/bin in PATH in case of node has already setup.
  229. PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
  230. # Move an existing node binary, to avoid to block n.
  231. test -x /usr/bin/node && mv /usr/bin/node /usr/bin/node_n
  232. test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n
  233. # If n is not previously setup, install it
  234. n --version > /dev/null 2>&1 || \
  235. ( echo "Installation of N - Node.js version management" >&2; \
  236. curl -sL $n_install_script | N_PREFIX="$n_install_dir" bash -s -- -y - )
  237. # Restore /usr/local/bin in PATH
  238. PATH=$CLEAR_PATH
  239. # And replace the old node binary.
  240. test -x /usr/bin/node_n && mv /usr/bin/node_n /usr/bin/node
  241. test -x /usr/bin/npm_n && mv /usr/bin/npm_n /usr/bin/npm
  242. # Install the requested version of nodejs
  243. n $nodejs_version
  244. # Find the last "real" version for this major version of node.
  245. real_nodejs_version=$(find $node_version_path/$nodejs_version* -maxdepth 0 | sort --version-sort | tail --lines=1)
  246. real_nodejs_version=$(basename $real_nodejs_version)
  247. # Create a symbolic link for this major version
  248. ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version
  249. # Store the ID of this app and the version of node requested for it
  250. echo "$YNH_APP_ID:$nodejs_version" | tee --append "$n_install_dir/ynh_app_version"
  251. # Store nodejs_version into the config of this app
  252. ynh_app_setting_set $app nodejs_version $nodejs_version
  253. # Build the update script and set the cronjob
  254. ynh_cron_upgrade_node
  255. ynh_use_nodejs
  256. }
  257. ynh_remove_nodejs () {
  258. ynh_use_nodejs
  259. # Remove the line for this app
  260. sed --in-place "/$YNH_APP_ID:$nodejs_version/d" "$n_install_dir/ynh_app_version"
  261. # If none another app uses this version of nodejs, remove it.
  262. if ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version"
  263. then
  264. n rm $nodejs_version
  265. fi
  266. # If none another app uses n, remove n
  267. if [ ! -s "$n_install_dir/ynh_app_version" ]
  268. then
  269. ynh_secure_remove "$n_install_dir"
  270. ynh_secure_remove "/usr/local/n"
  271. sed --in-place "/N_PREFIX/d" /root/.bashrc
  272. fi
  273. }
  274. ynh_cron_upgrade_node () {
  275. # Build the update script
  276. cat > "$n_install_dir/node_update.sh" << EOF
  277. #!/bin/bash
  278. version_path="$node_version_path"
  279. n_install_dir="$n_install_dir"
  280. # Log the date
  281. date
  282. # List all real installed version of node
  283. all_real_version="\$(find \$version_path/* -maxdepth 0 -type d | sed "s@\$version_path/@@g")"
  284. # Keep only the major version number of each line
  285. all_real_version=\$(echo "\$all_real_version" | sed 's/\..*\$//')
  286. # Remove double entries
  287. all_real_version=\$(echo "\$all_real_version" | sort --unique)
  288. # Read each major version
  289. while read version
  290. do
  291. echo "Update of the version \$version"
  292. sudo \$n_install_dir/bin/n \$version
  293. # Find the last "real" version for this major version of node.
  294. real_nodejs_version=\$(find \$version_path/\$version* -maxdepth 0 | sort --version-sort | tail --lines=1)
  295. real_nodejs_version=\$(basename \$real_nodejs_version)
  296. # Update the symbolic link for this version
  297. sudo ln --symbolic --force --no-target-directory \$version_path/\$real_nodejs_version \$version_path/\$version
  298. done <<< "\$(echo "\$all_real_version")"
  299. EOF
  300. chmod +x "$n_install_dir/node_update.sh"
  301. # Build the cronjob
  302. cat > "/etc/cron.daily/node_update" << EOF
  303. #!/bin/bash
  304. $n_install_dir/node_update.sh >> $n_install_dir/node_update.log
  305. EOF
  306. chmod +x "/etc/cron.daily/node_update"
  307. }