_common.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #!/bin/bash
  2. #=================================================
  3. # COMMON VARIABLES
  4. #=================================================
  5. ## new filenames starting 0.00~ynh5
  6. # make a filename/service name from domain/path
  7. if [[ "$path" == /* ]]; then
  8. url_path="${path:1}"
  9. fi
  10. if [[ "__${url_path}__" == '____' ]]; then
  11. flohmarkt_filename="$domain"
  12. else
  13. flohmarkt_filename="$domain-${url_path}"
  14. fi
  15. # this filename is used for logfile name and systemd.service name
  16. # and for symlinking install_dir and data_dir
  17. flohmarkt_filename="${YNH_APP_ID}_${flohmarkt_filename//[^A-Za-z0-9._-]/_}"
  18. # directory flohmarkts software is installed to
  19. # contains ./venv and ./src as sub-directories
  20. flohmarkt_install="$install_dir"
  21. flohmarkt_sym_install="$( dirname $flohmarkt_install )/$flohmarkt_filename"
  22. flohmarkt_venv_dir="${flohmarkt_install}/venv"
  23. flohmarkt_app_dir="${flohmarkt_install}/app"
  24. # directory containing logfiles
  25. flohmarkt_log_dir="/var/log/${app}"
  26. flohmarkt_sym_log_dir="/var/log/${flohmarkt_filename}"
  27. # filename for logfiles - ¡ojo! if not ends with .log will be interpreted
  28. # as a directory by ynh_use_logrotate
  29. # https://github.com/YunoHost/issues/issues/2383
  30. flohmarkt_logfile="${flohmarkt_log_dir}/app.log"
  31. # flohmarkt data_dir
  32. flohmarkt_data_dir="$data_dir"
  33. flohmarkt_sym_data_dir="$( dirname $flohmarkt_data_dir )/$flohmarkt_filename"
  34. ## old filenames before 0.00~ynh5 - for reference and needed to
  35. # migrate (see below)
  36. flohmarkt_old_install="/opt/flohmarkt"
  37. flohmarkt_old_venv_dir="${flohmarkt_old_install}/venv"
  38. flohmarkt_old_app_dir="${flohmarkt_old_install}/flohmarkt"
  39. flohmarkt_old_log_dir="/var/log/flohmarkt/"
  40. flohmarkt_old_service="flohmarkt"
  41. #=================================================
  42. # PERSONAL HELPERS
  43. #=================================================
  44. # local copy of ynh_local_curl() to test some improvement
  45. # https://github.com/YunoHost/issues/issues/2396
  46. # https://codeberg.org/flohmarkt/flohmarkt_ynh/issues/51
  47. flohmarkt_ynh_local_curl() {
  48. # Curl abstraction to help with POST requests to local pages (such as installation forms)
  49. #
  50. # usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
  51. # | arg: page_uri - Path (relative to `$path_url`) of the page where POST data will be sent
  52. # | arg: key1=value1 - (Optionnal) POST key and corresponding value
  53. # | arg: key2=value2 - (Optionnal) Another POST key and corresponding value
  54. # | arg: ... - (Optionnal) More POST keys and values
  55. #
  56. # example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
  57. #
  58. # For multiple calls, cookies are persisted between each call for the same app
  59. #
  60. # `$domain` and `$path_url` should be defined externally (and correspond to the domain.tld and the /path (of the app?))
  61. #
  62. # Requires YunoHost version 2.6.4 or higher.
  63. # Define url of page to curl
  64. local local_page=$(ynh_normalize_url_path $1)
  65. local full_path=$path_url$local_page
  66. if [ "${path_url}" == "/" ]; then
  67. full_path=$local_page
  68. fi
  69. local full_page_url=https://localhost$full_path
  70. # Concatenate all other arguments with '&' to prepare POST data
  71. local POST_data=""
  72. local arg=""
  73. for arg in "${@:2}"; do
  74. POST_data="${POST_data}${arg}&"
  75. done
  76. if [ -n "$POST_data" ]; then
  77. # Add --data arg and remove the last character, which is an unecessary '&'
  78. POST_data="--data ${POST_data::-1}"
  79. fi
  80. # Wait untils nginx has fully reloaded (avoid curl fail with http2)
  81. sleep 2
  82. local cookiefile=/tmp/ynh-$app-cookie.txt
  83. touch $cookiefile
  84. chown root $cookiefile
  85. chmod 700 $cookiefile
  86. # Temporarily enable visitors if needed...
  87. local visitors_enabled=$(ynh_permission_has_user "main" "visitors" && echo yes || echo no)
  88. if [[ $visitors_enabled == "no" ]]; then
  89. ynh_permission_update --permission "main" --add "visitors"
  90. fi
  91. # Curl the URL
  92. curl --silent --show-error --insecure --location --header "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url" --cookie-jar $cookiefile --cookie $cookiefile
  93. if [[ $visitors_enabled == "no" ]]; then
  94. ynh_permission_update --permission "main" --remove "visitors"
  95. fi
  96. }
  97. # create symlinks containing domain and path for install, data and log directories
  98. flohmarkt_ynh_create_symlinks() {
  99. ynh_script_progression --message="Creating symlinks..." --weight=1
  100. ln -s "$flohmarkt_install" "$flohmarkt_sym_install"
  101. ln -s "$flohmarkt_data_dir" "$flohmarkt_sym_data_dir"
  102. ln -s "$flohmarkt_log_dir" "$flohmarkt_sym_log_dir"
  103. true
  104. }
  105. # set file permissions and owner for installation
  106. flohmarkt_ynh_set_permission() {
  107. # install dir - only root needs to write and $app reads
  108. chown root:$app -R "$flohmarkt_install"
  109. chmod g-w,o-rwx -R "$flohmarkt_install"
  110. }
  111. # start flohmarkt service
  112. flohmarkt_ynh_start_service() {
  113. ynh_systemd_action --service_name=$flohmarkt_filename --action="start" \
  114. --line_match='INFO: *Application startup complete.' --log_path="$flohmarkt_logfile" \
  115. --timeout=30
  116. }
  117. # stop flohmarkt service
  118. flohmarkt_ynh_stop_service() {
  119. ynh_systemd_action --service_name=$flohmarkt_filename --action="stop"
  120. }
  121. # start couchdb and wait for success
  122. flohmarkt_ynh_start_couchdb() {
  123. ynh_systemd_action --service_name=couchdb --action="start" --timeout=30 \
  124. --log_path="/var/log/couchdb/couchdb.log" \
  125. --line_match='Apache CouchDB has started on http://127.0.0.1'
  126. }
  127. # stop couchdb
  128. flohmarkt_ynh_stop_couchdb() {
  129. ynh_systemd_action --service_name=couchdb --action="stop" --timeout=30 \
  130. --log_path="/var/log/couchdb/couchdb.log" \
  131. --line_match='SIGTERM received - shutting down'
  132. }
  133. # install or upgrade couchdb
  134. flohmarkt_ynh_up_inst_couchdb() {
  135. echo "\
  136. couchdb couchdb/mode select standalone
  137. couchdb couchdb/mode seen true
  138. couchdb couchdb/bindaddress string 127.0.0.1
  139. couchdb couchdb/bindaddress seen true
  140. couchdb couchdb/cookie string $couchdb_magic_cookie
  141. couchdb couchdb/adminpass password $password_couchdb_admin
  142. couchdb couchdb/adminpass seen true
  143. couchdb couchdb/adminpass_again password $password_couchdb_admin
  144. couchdb couchdb/adminpass_again seen true" | debconf-set-selections
  145. DEBIAN_FRONTEND=noninteractive # apt-get install -y --force-yes couchdb
  146. ynh_install_extra_app_dependencies \
  147. --repo="deb https://apache.jfrog.io/artifactory/couchdb-deb/ $(lsb_release -c -s) main" \
  148. --key="https://couchdb.apache.org/repo/keys.asc" \
  149. --package="couchdb"
  150. }
  151. flohmarkt_ynh_dump_couchdb() {
  152. ../settings/scripts/couchdb-dump/couchdb-dump.sh -b -H 127.0.0.1 -d "${app}" \
  153. -q -u admin -p "${password_couchdb_admin}" -f "${YNH_CWD}/${app}.json"
  154. }
  155. flohmarkt_ynh_import_couchdb() {
  156. ls -l ../settings/scripts/couchdb-dump/couchdb-dump.sh ${YNH_CWD}/${app}.json
  157. ../settings/scripts/couchdb-dump/couchdb-dump.sh -r -c -H 127.0.0.1 -d "${app}" \
  158. -q -u admin -p "${password_couchdb_admin}" -f "${YNH_CWD}/${app}.json"
  159. }
  160. flohmarkt_ynh_delete_couchdb_user() {
  161. # https://codeberg.org/flohmarkt/flohmarkt_ynh/issues/46 - more than one revision?
  162. local couchdb_user_revision=$( curl -sX GET "http://127.0.0.1:5984/_users/org.couchdb.user%3A${app}" \
  163. --user "admin:${password_couchdb_admin}" | jq -r ._rev )
  164. curl -s -X DELETE "http://127.0.0.1:5984/_users/org.couchdb.user%3A${app}?rev=${couchdb_user_revision}" \
  165. --user "admin:${password_couchdb_admin}"
  166. }
  167. flohmarkt_ynh_delete_couchdb_db() {
  168. curl -s -X DELETE "http://127.0.0.1:5984/${app}" --user "admin:${password_couchdb_admin}"
  169. }
  170. flohmarkt_ynh_create_couchdb_user() {
  171. curl -s -X PUT "http://127.0.0.1:5984/_users/org.couchdb.user:${app}" --user "admin:${password_couchdb_admin}"\
  172. -H "Accept: application/json" -H "Content-Type: application/json" \
  173. -d "{\"name\": \"${app}\", \"password\": \"${password_couchdb_flohmarkt}\", \"roles\": [], \"type\": \"user\"}"
  174. # @@ check answer something like
  175. # {"ok":true,"id":"org.couchdb.user:flohmarkt","rev":"35-9865694604ab384388eea0f978a6e728"}
  176. }
  177. flohmarkt_ynh_couchdb_user_permissions() {
  178. curl -s -X PUT "http://127.0.0.1:5984/${app}/_security" --user "admin:${password_couchdb_admin}"\
  179. -H "Accept: application/json" -H "Content-Type: application/json" \
  180. -d "{\"members\":{\"names\": [\"${app}\"],\"roles\": [\"editor\"]}}"
  181. }
  182. flohmarkt_ynh_exists_couchdb_user() {
  183. if [[ $( curl -sX GET "http://127.0.0.1:5984/_users/org.couchdb.user%3A${app}" \
  184. --user "admin:${password_couchdb_admin}" | jq .error ) == '"not_found"' ]]
  185. then
  186. false
  187. else
  188. true
  189. fi
  190. }
  191. flohmarkt_ynh_exists_couchdb_db() {
  192. if [[ $( curl -sX GET "http://127.0.0.1:5984/flohmarkt__22" --user "admin:${password_couchdb_admin}" \
  193. | jq .error ) == '"not_found"' ]]
  194. then
  195. false
  196. else
  197. true
  198. fi
  199. }
  200. # check whether old couchdb user or database exist before creating the new ones
  201. flohmarkt_ynh_check_old_couchdb() {
  202. if flohmarkt_ynh_exists_couchdb_user; then
  203. ynh_die --ret_code=100 --message="CouchDB user '$app' exists already. Stopping install."
  204. elif flohmarkt_ynh_exists_couchdb_db; then
  205. ynh_die --ret_code=100 --message="CouchDB database '$app' exists already. Stopping install."
  206. fi
  207. }
  208. flohmarkt_ynh_restore_couchdb() {
  209. flohmarkt_ynh_check_old_couchdb
  210. flohmarkt_ynh_import_couchdb
  211. flohmarkt_ynh_create_couchdb_user
  212. flohmarkt_ynh_couchdb_user_permissions
  213. }
  214. # create venv
  215. flohmarkt_ynh_create_venv() {
  216. python3 -m venv --without-pip "$flohmarkt_venv_dir"
  217. }
  218. # install requirements.txt in venv
  219. flohmarkt_ynh_venv_requirements() {
  220. (
  221. set +o nounset
  222. source "$flohmarkt_venv_dir/bin/activate"
  223. set -o nounset
  224. set -x
  225. $flohmarkt_venv_dir/bin/python3 -m ensurepip
  226. $flohmarkt_venv_dir/bin/pip3 install -r "$flohmarkt_app_dir/requirements.txt"
  227. )
  228. }
  229. # move files and directories to their new places
  230. flohmarkt_ynh_upgrade_path_ynh5() {
  231. # flohmarkt and couchdb are already stopped in upgrade script
  232. # move app_dir into new 'app' folder
  233. mv "$flohmarkt_install/flohmarkt" "$flohmarkt_app_dir"
  234. # yunohost seems to move the venv dir automatically, but this
  235. # doesn't work, because the paths inside the venv are not adjusted
  236. # delete the old, not working venv and create a new one:
  237. ynh_secure_remove --file="$flohmarkt_venv_dir"
  238. flohmarkt_ynh_create_venv
  239. flohmarkt_ynh_venv_requirements
  240. # remove old $install_dir
  241. ynh_secure_remove --file="$flohmarkt_old_install"
  242. # move logfile directory
  243. mkdir -p "$flohmarkt_log_dir"
  244. # remove systemd.service - will be generated newly by upgrade
  245. # ynh_remove_systemd_config --service="$flohmarkt_old_service"
  246. ynh_systemd_action --action=stop --service_name="$flohmarkt_old_service"
  247. ynh_systemd_action --action=disable --service_name="$flohmarkt_old_service"
  248. ynh_secure_remove --file="/etc/systemd/system/multi-user.target.wants/flohmarkt.service"
  249. ynh_secure_remove --file="/etc/systemd/system/flohmarkt.service"
  250. # funktioniert nicht? issue?
  251. #ynh_systemd_action --action=daemon-reload
  252. # DEBUG + systemctl daemon-reload flohmarkt
  253. # WARNING Too many arguments.
  254. systemctl daemon-reload
  255. # unit flohmarkt is automatically appended and therefor this fails:
  256. #ynh_systemd_action --action=reset-failed
  257. systemctl reset-failed
  258. # create symlinks
  259. ln -s "$flohmarkt_install" "$flohmarkt_sym_install"
  260. ln -s "$flohmarkt_data_dir" "$flohmarkt_sym_data_dir"
  261. }
  262. #=================================================
  263. # EXPERIMENTAL HELPERS
  264. #=================================================
  265. #=================================================
  266. # FUTURE OFFICIAL HELPERS
  267. #=================================================