_common.sh 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  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. # Redesign:
  45. # Internal helper design to allow helpers to use getopts to manage their arguments
  46. #
  47. # [internal]
  48. #
  49. # example: function my_helper()
  50. # {
  51. # local -A args_array=( [a]=arg1= [b]=arg2= [c]=arg3 )
  52. # local arg1
  53. # local arg2
  54. # local arg3
  55. # ynh_handle_getopts_args "$@"
  56. #
  57. # [...]
  58. # }
  59. # my_helper --arg1 "val1" -b val2 -c
  60. #
  61. # usage: ynh_handle_getopts_args "$@"
  62. # | arg: $@ - Simply "$@" to tranfert all the positionnal arguments to the function
  63. #
  64. # This helper need an array, named "args_array" with all the arguments used by the helper
  65. # that want to use ynh_handle_getopts_args
  66. # Be carreful, this array has to be an associative array, as the following example:
  67. # local -A args_array=( [a]=arg1 [b]=arg2= [c]=arg3 )
  68. # Let's explain this array:
  69. # a, b and c are short options, -a, -b and -c
  70. # arg1, arg2 and arg3 are the long options associated to the previous short ones. --arg1, --arg2 and --arg3
  71. # For each option, a short and long version has to be defined.
  72. # Let's see something more significant
  73. # local -A args_array=( [u]=user [f]=finalpath= [d]=database )
  74. #
  75. # NB: Because we're using 'declare' without -g, the array will be declared as a local variable.
  76. #
  77. # Please keep in mind that the long option will be used as a variable to store the values for this option.
  78. # For the previous example, that means that $finalpath will be fill with the value given as argument for this option.
  79. #
  80. # Also, in the previous example, finalpath has a '=' at the end. That means this option need a value.
  81. # So, the helper has to be call with --finalpath /final/path, --finalpath=/final/path or -f /final/path,
  82. # the variable $finalpath will get the value /final/path
  83. # If there's many values for an option, -f /final /path, the value will be separated by a ';' $finalpath=/final;/path
  84. # For an option without value, like --user in the example, the helper can be called only with --user or -u. $user
  85. # will then get the value 1.
  86. #
  87. # To keep a retrocompatibility, a package can still call a helper, using getopts, with positional arguments.
  88. # The "legacy mode" will manage the positional arguments and fill the variable in the same order than they are given
  89. # in $args_array. e.g. for `my_helper "val1" val2`, arg1 will be filled with val1, and arg2 with val2.
  90. #
  91. # @@ TODO: explain $legacy_args and '--'
  92. # @@ '--' start processing the rest of the arguments as positional parameters in legacy mode
  93. # @@ $legacy_args the arguments positional parameters will be assign to
  94. #
  95. # Requires YunoHost version 3.2.2 or higher.
  96. ynh_handle_getopts_args() {
  97. # Manage arguments only if there's some provided
  98. set +o xtrace # set +x
  99. if [ $# -eq 0 ]; then
  100. ynh_print_warn --message="ynh_handle_getopts_args called without arguments"
  101. return
  102. fi
  103. # Store arguments in an array to keep each argument separated
  104. local arguments=("$@")
  105. # For each option in the array, reduce to short options for getopts (e.g. for [u]=user, --user will be -u)
  106. # And built parameters string for getopts
  107. # ${!args_array[@]} is the list of all option_flags in the array (An option_flag is 'u' in [u]=user, user is a value)
  108. local getopts_parameters=""
  109. local option_flag=""
  110. ## go through all possible options and replace arguments with short versions
  111. echo "debug: arguments = '${arguments[@]}"
  112. echo "debug: args_array = '${!args_array[@]}'"
  113. for option_flag in "${!args_array[@]}"; do
  114. echo "debug: option_flag = $option_flag"
  115. # Concatenate each option_flags of the array to build the string of arguments for getopts
  116. # Will looks like 'abcd' for -a -b -c -d
  117. # If the value of an option_flag finish by =, it's an option with additionnal values. (e.g. --user bob or -u bob)
  118. # Check the last character of the value associate to the option_flag
  119. echo "debug: compare to '${args_array[$option_flag]: -1}'"
  120. if [ "${args_array[$option_flag]: -1}" = "=" ]; then
  121. # For an option with additionnal values, add a ':' after the letter for getopts.
  122. getopts_parameters="${getopts_parameters}${option_flag}:"
  123. else
  124. getopts_parameters="${getopts_parameters}${option_flag}"
  125. fi
  126. echo "debug: getopts_parameters = ${getopts_parameters}"
  127. # Check each argument given to the function
  128. local arg=""
  129. # ${#arguments[@]} is the size of the array
  130. ## for one possible option: look at each argument supplied:
  131. for arg in $(seq 0 $((${#arguments[@]} - 1))); do
  132. echo "debug: arg = '$arg', argument = '${arguments[arg]}'"
  133. # Replace long option with = (match the beginning of the argument)
  134. arguments[arg]="$(printf '%s\n' "${arguments[arg]}" | sed "s/^--${args_array[$option_flag]}/-${option_flag}/")"
  135. echo "debug: sed - printf '%s\n' \"${arguments[arg]}\" | sed \"s/^--${args_array[$option_flag]}/-${option_flag} /\""
  136. echo "debug: arg = '$arg', argument = '${arguments[arg]}'"
  137. # And long option without = (match the whole line)
  138. arguments[arg]="$(printf '%s\n' "${arguments[arg]}" | sed "s/^--${args_array[$option_flag]%=}$/-${option_flag}/")"
  139. echo "debug: sed - printf '%s\n' \"${arguments[arg]}\" | sed \"s/^--${args_array[$option_flag]%=}$/-${option_flag} /\""
  140. echo "debug: arg = '$arg', argument = '${arguments[arg]}'"
  141. done
  142. echo "debug: arguments = '${arguments[@]}'"
  143. done
  144. echo 'debug: ================= end first loop ================='
  145. # Parse the first argument, return the number of arguments to be shifted off the arguments array
  146. # The function call is necessary here to allow `getopts` to use $@
  147. parse_arg() {
  148. echo "debug: parse_arg started, arguments='$@', getopts_parameters: '$getopts_parameters'"
  149. for ME in "$@"; do
  150. echo "debug: '$ME'"
  151. done
  152. # Initialize the index of getopts
  153. OPTIND=1
  154. # getopts will fill $parameter with the letter of the option it has read.
  155. local parameter=""
  156. getopts ":$getopts_parameters" parameter || true
  157. echo "debug: after getopts - parameter='$parameter', OPTIND='$OPTIND', OPTARG='$OPTARG'"
  158. if [ "$parameter" = "?" ]; then
  159. ynh_die --message="Invalid argument: -${OPTARG:-}"
  160. echo "debug: Invalid argument: -${OPTARG:-}"
  161. exit 255
  162. elif [ "$parameter" = ":" ]; then
  163. ynh_die --message="-$OPTARG parameter requires an argument."
  164. echo "-$OPTARG parameter requires an argument."
  165. exit 255
  166. else
  167. # Use the long option, corresponding to the short option read by getopts, as a variable
  168. # (e.g. for [u]=user, 'user' will be used as a variable)
  169. # Also, remove '=' at the end of the long option
  170. # The variable name will be stored in 'option_var'
  171. option_var="${args_array[$parameter]%=}"
  172. # if there's a '=' at the end of the long option name, this option takes values
  173. if [ "${args_array[$parameter]: -1}" != "=" ]; then
  174. # no argument expected for option - set option variable to '1'
  175. # 'eval ${option_var}' will use the content of 'option_var'
  176. echo "debug: option_var='${option_var}', option_value='1'"
  177. option_value=1
  178. return 1
  179. else
  180. # remove leading and trailing spaces from OPTARG
  181. OPTARG="$( printf '%s' ${OPTARG} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
  182. echo "debug: option_var='${option_var}', OPTARG='${OPTARG}'"
  183. option_value="${OPTARG}"
  184. return 2
  185. fi
  186. fi
  187. }
  188. # iterate over the arguments: if first argument starts with a '-' feed arguments to getopts
  189. # if first argument doesn't start with a '-' enter legacy mode and read positional parameters
  190. local argument
  191. local legacy_mode=0 # state is getopts mode, not legacy mode at the beginning
  192. # for arg in $(seq 0 $((${#arguments[@]} - 1))); do
  193. while [ ${#arguments} -ne 0 ]; do
  194. local shift_value=0
  195. local option_var='' # the variable name to be filled
  196. local option_value='' # the value to be filled into ${!option_value}
  197. echo "debug: arg = '$arg', argument = '${arguments[arg]}'"
  198. argument=${arguments[0]}
  199. echo "debug: argument='$argument'"
  200. # if state once changed to legacy mode, all the rest of the arguments will
  201. # be interpreted in legacy mode even if they start with a '-'
  202. if [ "${argument}" == '--' ];then
  203. echo "debug: found '--', start legacy mode"
  204. legacy_mode=1
  205. shift_value=1
  206. elif ! [ $legacy_mode == 1 ] && [ "${argument:0:1}" == '-' ]; then
  207. echo "debug: getopts, arguments='${arguments[@]}', starting parse_arg"
  208. parse_arg "${arguments[@]}"
  209. shift_value=$?
  210. else
  211. legacy_mode=1 # set state for legacy_mode
  212. # @@ set -x
  213. echo "! Helper used in legacy mode !" >/dev/null
  214. # @@ set +x
  215. echo "debug: legacy, argument='$argument'"
  216. # @@ TODO
  217. # put positional parameters into variable - see below
  218. shift_value=1
  219. fi
  220. # bash shi(f)t
  221. echo "debug: shifting '$shift_value' off arguments"
  222. arguments=("${arguments[@]:${shift_value}}")
  223. # @@ TODO fill values to ${option_var} here
  224. # if ${option_var} is an array, fill mutiple values as array cells
  225. # otherwise concatenate them seperated by ';'
  226. echo "debug: fill option_var '$option_var' with option_value '$option_value'"
  227. # But... ${!option_var} can't be used as left part of an assignation.
  228. eval ${option_var}+='"${option_value};"'
  229. done
  230. return
  231. # If not, enter in legacy mode and manage the arguments as positionnal ones..
  232. # Dot not echo, to prevent to go through a helper output. But print only in the log.
  233. local i
  234. for i in $(seq 0 $((${#arguments[@]} - 1))); do
  235. # Try to use legacy_args as a list of option_flag of the array args_array
  236. # Otherwise, fallback to getopts_parameters to get the option_flag. But an associative arrays
  237. # isn't always sorted in the correct order...
  238. # Remove all ':' in getopts_parameters
  239. getopts_parameters=${legacy_args:-${getopts_parameters//:/}}
  240. # Get the option_flag from getopts_parameters, by using the option_flag according to the position of the argument.
  241. option_flag=${getopts_parameters:$i:1}
  242. if [ -z "$option_flag" ]; then
  243. ynh_print_warn --message="Too many arguments ! \"${arguments[$i]}\" will be ignored."
  244. continue
  245. fi
  246. # Use the long option, corresponding to the option_flag, as a variable
  247. # (e.g. for [u]=user, 'user' will be used as a variable)
  248. # Also, remove '=' at the end of the long option
  249. # The variable name will be stored in 'option_var'
  250. local option_var="${args_array[$option_flag]%=}"
  251. # Store each value given as argument in the corresponding variable
  252. # The values will be stored in the same order than $args_array
  253. eval ${option_var}+='"${arguments[$i]}"'
  254. done
  255. unset legacy_args
  256. set -o xtrace # set -x
  257. }
  258. # local copy of ynh_local_curl() to test some improvement
  259. # https://github.com/YunoHost/issues/issues/2396
  260. # https://codeberg.org/flohmarkt/flohmarkt_ynh/issues/51
  261. flohmarkt_ynh_local_curl() {
  262. # Curl abstraction to help with POST requests to local pages (such as installation forms)
  263. #
  264. # usage: ynh_local_curl "page" "key1=value1" "key2=value2" ...
  265. # | arg: -l --line_match: check answer for a regex to return true
  266. # | arg: -P --put: PUT instead of POST, requires --data (see below)
  267. # | arg: -H --header: add a header to the request (can be used multiple times)
  268. # | arg: -n --no_sleep: don't sleep 2 seconds https://github.com/YunoHost/yunohost/pull/547
  269. # | arg: -d --data: data to be used with PUT: one long string
  270. # | arg: or to be POSTed: multiple 'key=value'
  271. # | arg: -p --page: either the PAGE part in 'https://$domain/$path/PAGE' or an a
  272. # | arg: URL like 'http://doma.in/path/file.ext'
  273. # | arg: page - positional parameter legacy version of '--page'
  274. # | arg: key1=value1 - (Optional, POST only) legacy version of '--data' as positional parameter
  275. # | arg: key2=value2 - (Optional, POST only) Another POST key and corresponding value
  276. # | arg: ... - (Optional, POST only) More POST keys and values
  277. #
  278. # example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
  279. # → will open a POST request to "https://$domain/$path/install.php?installButton" posting "foo=$var1" and "bar=$var2"
  280. # example: ynh_local_curl -P --header "Accept: application/json" -H "Content-Type: application/json" \
  281. # --data "{\"members\":{\"names\": [\"${app}\"],\"roles\": [\"editor\"]}}" -l '"ok":true' \
  282. # "http://localhost:5984/"
  283. # → will open a POST request to "http://localhost:5984/" adding headers with "Accept: application/json"
  284. # and "Content-Type: application/json" sending the data from the "--data" argument. ynh_local_curl will
  285. # return with an error if the servers response does not match the extended regex '"ok":true'.
  286. #
  287. # For multiple calls, cookies are persisted between each call for the same app.
  288. #
  289. # `$domain` and `$path_url` need to be defined externally if the first form for the 'page' argument is used.
  290. #
  291. # Requires YunoHost version 2.6.4 or higher.
  292. # Declare an array to define the options of this helper.
  293. local legacy_args=pd
  294. local -A args_array=( [l]=line_match= [P]=put [H]=header= [n]=no_sleep [p]=page= [d]=data= )
  295. local line_match
  296. local put
  297. # @@ todo if the headers contain ';' somewhere it might be a problem to split them
  298. # apart correctly later, because all values are stored in $header seperated by
  299. # ';' like 'header1: value;header2: value'.
  300. # might be a good improvement to 'ynh_handle_getopts_args' to act differently if
  301. # e.g. $header had been defined as an array: https://stackoverflow.com/questions/14525296/how-do-i-check-if-variable-is-an-array
  302. local header
  303. local no_sleep
  304. local data
  305. # Manage arguments with getopts
  306. ynh_handle_getopts_args "$@"
  307. # @@ debug
  308. local V
  309. for V in line_match put header no_sleep data; do
  310. echo "---> debug $V = ${!V}"
  311. done
  312. return
  313. # Define url of page to curl
  314. local local_page=$(ynh_normalize_url_path $1)
  315. local full_path=$path_url$local_page
  316. if [ "${path_url}" == "/" ]; then
  317. full_path=$local_page
  318. fi
  319. local full_page_url=https://localhost$full_path
  320. # Concatenate all other arguments with '&' to prepare POST data
  321. local POST_data=""
  322. local arg=""
  323. for arg in "${@:2}"; do
  324. POST_data="${POST_data}${arg}&"
  325. done
  326. if [ -n "$POST_data" ]; then
  327. # Add --data arg and remove the last character, which is an unecessary '&'
  328. POST_data="--data ${POST_data::-1}"
  329. fi
  330. # https://github.com/YunoHost/yunohost/pull/547
  331. # Wait untils nginx has fully reloaded (avoid curl fail with http2) unless disabled
  332. if ! [[ $no_sleep == 1 ]]; then
  333. sleep 2
  334. fi
  335. local cookiefile=/tmp/ynh-$app-cookie.txt
  336. touch $cookiefile
  337. chown root $cookiefile
  338. chmod 700 $cookiefile
  339. # @@ debug disabled
  340. # # Temporarily enable visitors if needed...
  341. # local visitors_enabled=$(ynh_permission_has_user "main" "visitors" && echo yes || echo no)
  342. # if [[ $visitors_enabled == "no" ]]; then
  343. # ynh_permission_update --permission "main" --add "visitors"
  344. # fi
  345. # Curl the URL
  346. 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
  347. # @@ debug disabled
  348. # if [[ $visitors_enabled == "no" ]]; then
  349. # ynh_permission_update --permission "main" --remove "visitors"
  350. # fi
  351. }
  352. # create symlinks containing domain and path for install, data and log directories
  353. flohmarkt_ynh_create_symlinks() {
  354. ynh_script_progression --message="Creating symlinks..." --weight=1
  355. ln -s "$flohmarkt_install" "$flohmarkt_sym_install"
  356. ln -s "$flohmarkt_data_dir" "$flohmarkt_sym_data_dir"
  357. ln -s "$flohmarkt_log_dir" "$flohmarkt_sym_log_dir"
  358. true
  359. }
  360. # set file permissions and owner for installation
  361. flohmarkt_ynh_set_permission() {
  362. # install dir - only root needs to write and $app reads
  363. chown root:$app -R "$flohmarkt_install"
  364. chmod g-w,o-rwx -R "$flohmarkt_install"
  365. }
  366. # start flohmarkt service
  367. flohmarkt_ynh_start_service() {
  368. ynh_systemd_action --service_name=$flohmarkt_filename --action="start" \
  369. --line_match='INFO: *Application startup complete.' --log_path="$flohmarkt_logfile" \
  370. --timeout=30
  371. }
  372. # stop flohmarkt service
  373. flohmarkt_ynh_stop_service() {
  374. ynh_systemd_action --service_name=$flohmarkt_filename --action="stop"
  375. }
  376. # start couchdb and wait for success
  377. flohmarkt_ynh_start_couchdb() {
  378. ynh_systemd_action --service_name=couchdb --action="start" --timeout=30 \
  379. --log_path="/var/log/couchdb/couchdb.log" \
  380. --line_match='Apache CouchDB has started on http://127.0.0.1'
  381. }
  382. # stop couchdb
  383. flohmarkt_ynh_stop_couchdb() {
  384. ynh_systemd_action --service_name=couchdb --action="stop" --timeout=30 \
  385. --log_path="/var/log/couchdb/couchdb.log" \
  386. --line_match='SIGTERM received - shutting down'
  387. }
  388. # install or upgrade couchdb
  389. flohmarkt_ynh_up_inst_couchdb() {
  390. echo "\
  391. couchdb couchdb/mode select standalone
  392. couchdb couchdb/mode seen true
  393. couchdb couchdb/bindaddress string 127.0.0.1
  394. couchdb couchdb/bindaddress seen true
  395. couchdb couchdb/cookie string $couchdb_magic_cookie
  396. couchdb couchdb/adminpass password $password_couchdb_admin
  397. couchdb couchdb/adminpass seen true
  398. couchdb couchdb/adminpass_again password $password_couchdb_admin
  399. couchdb couchdb/adminpass_again seen true" | debconf-set-selections
  400. DEBIAN_FRONTEND=noninteractive # apt-get install -y --force-yes couchdb
  401. ynh_install_extra_app_dependencies \
  402. --repo="deb https://apache.jfrog.io/artifactory/couchdb-deb/ $(lsb_release -c -s) main" \
  403. --key="https://couchdb.apache.org/repo/keys.asc" \
  404. --package="couchdb"
  405. }
  406. flohmarkt_ynh_dump_couchdb() {
  407. ../settings/scripts/couchdb-dump/couchdb-dump.sh -b -H 127.0.0.1 -d "${app}" \
  408. -q -u admin -p "${password_couchdb_admin}" -f "${YNH_CWD}/${app}.json"
  409. }
  410. flohmarkt_ynh_import_couchdb() {
  411. ls -l ../settings/scripts/couchdb-dump/couchdb-dump.sh ${YNH_CWD}/${app}.json
  412. ../settings/scripts/couchdb-dump/couchdb-dump.sh -r -c -H 127.0.0.1 -d "${app}" \
  413. -q -u admin -p "${password_couchdb_admin}" -f "${YNH_CWD}/${app}.json"
  414. }
  415. flohmarkt_ynh_delete_couchdb_user() {
  416. # https://codeberg.org/flohmarkt/flohmarkt_ynh/issues/46 - more than one revision?
  417. local couchdb_user_revision=$( curl -sX GET "http://127.0.0.1:5984/_users/org.couchdb.user%3A${app}" \
  418. --user "admin:${password_couchdb_admin}" | jq -r ._rev )
  419. curl -s -X DELETE "http://127.0.0.1:5984/_users/org.couchdb.user%3A${app}?rev=${couchdb_user_revision}" \
  420. --user "admin:${password_couchdb_admin}"
  421. }
  422. flohmarkt_ynh_delete_couchdb_db() {
  423. curl -s -X DELETE "http://127.0.0.1:5984/${app}" --user "admin:${password_couchdb_admin}"
  424. }
  425. flohmarkt_ynh_create_couchdb_user() {
  426. curl -s -X PUT "http://127.0.0.1:5984/_users/org.couchdb.user:${app}" --user "admin:${password_couchdb_admin}"\
  427. -H "Accept: application/json" -H "Content-Type: application/json" \
  428. -d "{\"name\": \"${app}\", \"password\": \"${password_couchdb_flohmarkt}\", \"roles\": [], \"type\": \"user\"}"
  429. # @@ check answer something like
  430. # {"ok":true,"id":"org.couchdb.user:flohmarkt","rev":"35-9865694604ab384388eea0f978a6e728"}
  431. }
  432. flohmarkt_ynh_couchdb_user_permissions() {
  433. curl -s -X PUT "http://127.0.0.1:5984/${app}/_security" --user "admin:${password_couchdb_admin}"\
  434. -H "Accept: application/json" -H "Content-Type: application/json" \
  435. -d "{\"members\":{\"names\": [\"${app}\"],\"roles\": [\"editor\"]}}"
  436. }
  437. flohmarkt_ynh_exists_couchdb_user() {
  438. if [[ $( curl -sX GET "http://127.0.0.1:5984/_users/org.couchdb.user%3A${app}" \
  439. --user "admin:${password_couchdb_admin}" | jq .error ) == '"not_found"' ]]
  440. then
  441. false
  442. else
  443. true
  444. fi
  445. }
  446. flohmarkt_ynh_exists_couchdb_db() {
  447. if [[ $( curl -sX GET "http://127.0.0.1:5984/${app}" --user "admin:${password_couchdb_admin}" \
  448. | jq .error ) == '"not_found"' ]]
  449. then
  450. false
  451. else
  452. true
  453. fi
  454. }
  455. # check whether old couchdb user or database exist before creating the new ones
  456. flohmarkt_ynh_check_old_couchdb() {
  457. if flohmarkt_ynh_exists_couchdb_user; then
  458. ynh_die --ret_code=100 --message="CouchDB user '$app' exists already. Stopping install."
  459. elif flohmarkt_ynh_exists_couchdb_db; then
  460. ynh_die --ret_code=100 --message="CouchDB database '$app' exists already. Stopping install."
  461. fi
  462. }
  463. flohmarkt_ynh_restore_couchdb() {
  464. flohmarkt_ynh_check_old_couchdb
  465. flohmarkt_ynh_import_couchdb
  466. flohmarkt_ynh_create_couchdb_user
  467. flohmarkt_ynh_couchdb_user_permissions
  468. }
  469. # create venv
  470. flohmarkt_ynh_create_venv() {
  471. python3 -m venv --without-pip "$flohmarkt_venv_dir"
  472. }
  473. # install requirements.txt in venv
  474. flohmarkt_ynh_venv_requirements() {
  475. (
  476. set +o nounset
  477. source "$flohmarkt_venv_dir/bin/activate"
  478. set -o nounset
  479. set -x
  480. $flohmarkt_venv_dir/bin/python3 -m ensurepip
  481. $flohmarkt_venv_dir/bin/pip3 install -r "$flohmarkt_app_dir/requirements.txt"
  482. )
  483. }
  484. # move files and directories to their new places
  485. flohmarkt_ynh_upgrade_path_ynh5() {
  486. # flohmarkt and couchdb are already stopped in upgrade script
  487. # move app_dir into new 'app' folder
  488. mv "$flohmarkt_install/flohmarkt" "$flohmarkt_app_dir"
  489. # yunohost seems to move the venv dir automatically, but this
  490. # doesn't work, because the paths inside the venv are not adjusted
  491. # delete the old, not working venv and create a new one:
  492. ynh_secure_remove --file="$flohmarkt_venv_dir"
  493. flohmarkt_ynh_create_venv
  494. flohmarkt_ynh_venv_requirements
  495. # remove old $install_dir
  496. ynh_secure_remove --file="$flohmarkt_old_install"
  497. # move logfile directory
  498. mkdir -p "$flohmarkt_log_dir"
  499. # remove systemd.service - will be generated newly by upgrade
  500. # ynh_remove_systemd_config --service="$flohmarkt_old_service"
  501. ynh_systemd_action --action=stop --service_name="$flohmarkt_old_service"
  502. ynh_systemd_action --action=disable --service_name="$flohmarkt_old_service"
  503. ynh_secure_remove --file="/etc/systemd/system/multi-user.target.wants/flohmarkt.service"
  504. ynh_secure_remove --file="/etc/systemd/system/flohmarkt.service"
  505. # funktioniert nicht? issue?
  506. #ynh_systemd_action --action=daemon-reload
  507. # DEBUG + systemctl daemon-reload flohmarkt
  508. # WARNING Too many arguments.
  509. systemctl daemon-reload
  510. # unit flohmarkt is automatically appended and therefor this fails:
  511. #ynh_systemd_action --action=reset-failed
  512. systemctl reset-failed
  513. # create symlinks
  514. ln -s "$flohmarkt_install" "$flohmarkt_sym_install"
  515. ln -s "$flohmarkt_data_dir" "$flohmarkt_sym_data_dir"
  516. }
  517. #=================================================
  518. # EXPERIMENTAL HELPERS
  519. #=================================================
  520. #=================================================
  521. # FUTURE OFFICIAL HELPERS
  522. #=================================================