You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.7 KiB

1 month ago
  1. # -*- mode: shell-script -*-
  2. ## This place is not accessible from container on purpose: container
  3. ## don't need that. This should be stored in /var/lib/compose/ in a
  4. ## project, service directory a little like relation data.
  5. PASSWORD_FILE="$SERVICE_CONFIGSTORE/etc/$SERVICE_NAME/pass"
  6. ## Used to check existence and make direct changes when 'occ' command
  7. ## can't do it properly.
  8. CONFIGDIR="$SERVICE_DATASTORE/var/www/html/config"
  9. CONFIGFILE="$CONFIGDIR/config.php"
  10. has_user() {
  11. local user="$1"
  12. if ! out=$(occ user:info "$user"); then
  13. if [ "$out" == "user not found" ]; then
  14. return 1
  15. else
  16. if [ -n "$out" ]; then
  17. err "Command 'occ user:info $user' failed with this output:"
  18. echo "$out" | prefix " | " >&2
  19. else
  20. err "Command 'occ user:info $user' failed with no output."
  21. fi
  22. return 2
  23. fi
  24. fi
  25. return 0
  26. }
  27. set_admin_user_password() {
  28. local user="$1" password="$2" errlvl
  29. [ -z "$password" ] && {
  30. err "Refusing to set admin user an empty password."
  31. return 3
  32. }
  33. has_user "$user"
  34. errlvl=$?
  35. [[ "$errlvl" -gt 1 ]] && {
  36. err "'has_user $user' failed. Bailing out."
  37. return "$errlvl"
  38. }
  39. if [[ "$errlvl" == 1 ]]; then
  40. info "User $user not found. Creating it in default 'admin' group."
  41. (
  42. occ_docker_run_opts=("-e" "OC_PASS=$password")
  43. occ user:add --group=admin --password-from-env --display-name="$user" "$user"
  44. ) || return 1
  45. else
  46. info "User $user found. Resetting password."
  47. (
  48. occ_docker_run_opts=("-e" "OC_PASS=$password")
  49. occ user:resetpassword "$user" "--password-from-env"
  50. ) || {
  51. err "'occ user:resetpassword' failed," \
  52. "common reason include password too simple."
  53. return 1
  54. }
  55. fi
  56. ## XXXvlab: DRY violation: init does the same thing
  57. mkdir -p "$(dirname "$PASSWORD_FILE")"
  58. p0 "$user" "$password" > "$PASSWORD_FILE"
  59. }
  60. get_admin_user_password() {
  61. if [ -e "$PASSWORD_FILE" ]; then
  62. cat "$PASSWORD_FILE"
  63. else
  64. return 1
  65. fi
  66. }
  67. ## only called after first install and occ is available
  68. nextcloud:init() {
  69. occ app:disable updatenotification nextcloud_announcements \; \
  70. config:system:set maintenance_window_start --type=integer --value=1 \; \
  71. config:system:set trusted_proxies 0 --value="0.0.0.0/0" \; \
  72. db:add-missing-columns \; \
  73. db:add-missing-indices \; \
  74. db:add-missing-primary-keys \; \
  75. maintenance:repair --include-expensive
  76. }
  77. create_occ_if_not_exists() {
  78. if ! [ -e "$SERVICE_DATASTORE/var/www/html/occ" ]; then
  79. ## Here we use a nasty trick to launch only the initialisation
  80. ## part of the ``entrypoint.sh``. By setting 'apache' as first
  81. ## call argument, we satisfy the big first 'if' condition
  82. ## triggering the installation if necessary, and will fail to
  83. ## launch any apache
  84. ## Last, we do not want the relation web-proxy to run in this
  85. ## bare-minimum nextcloud run AND we will use occ to set some info
  86. ## in this very same relation.
  87. ## Note also that we need to set NEXTCLOUD_ADMIN_{USER,PASSWORD}
  88. ## that is required to trigger a full installation
  89. if ! out=$(
  90. export COMPOSE_IGNORE_ORPHANS=true
  91. read-0 LOGIN PASSWORD < "$PASSWORD_FILE" || exit 1
  92. compose --debug --no-init --without-relation="$SERVICE_NAME":web-proxy run \
  93. -v "$CHARM_PATH"/src/fake-apache:/usr/bin/apache \
  94. -e NEXTCLOUD_ADMIN_USER=$LOGIN \
  95. -e NEXTCLOUD_ADMIN_PASSWORD=$PASSWORD \
  96. --rm --entrypoint /entrypoint.sh "$SERVICE_NAME" apache 2>&1
  97. ); then
  98. err "Initialization of code or database failed unexpectedly"
  99. e "$out" | prefix " | "
  100. return 1
  101. fi
  102. if ! [ -e "$SERVICE_DATASTORE/var/www/html/occ" ]; then
  103. err "Expected last command to create /var/www/html/occ"
  104. return 1
  105. fi
  106. nextcloud:init || return 1
  107. fi
  108. }
  109. occ() {
  110. create_occ_if_not_exists || return 1
  111. ## occ.batch will require /var/www/html to be populated ('occ' is
  112. ## supposed to exist). For that we need to make sure nextcloud have
  113. ## be ran and setup prior to running this next command.
  114. ## We need here actually only the relation sql-database. Any other hook
  115. ## using `occ` would make the call infinitively recursive.
  116. export COMPOSE_IGNORE_ORPHANS=true
  117. compose --debug -q --no-init --without-relation="$SERVICE_NAME":web-proxy run \
  118. "${occ_docker_run_opts[@]}" \
  119. -v "$HOST_CHARM_STORE/${CHARM_REL_PATH#${CHARM_STORE}/}/src/occ.batch:/var/www/html/occ.batch" \
  120. -T --rm -u www-data "$SERVICE_NAME" /var/www/html/occ.batch "$@" | cat
  121. if [ "${PIPESTATUS[0]}" != 0 ]; then
  122. err "Failure to execute these ${WHITE}occ${NORMAL} commands:"
  123. printf '%s ' "$@" |
  124. sed -r "s/\\;/\n/g" |
  125. sed -r "s/^\s*(.*)\s*$/${WHITE}\1${NORMAL}/g" |
  126. prefix " ${DARKGRAY}>${NORMAL} " >&2
  127. echo "" >&2
  128. echo "" >&2
  129. echo " If the code of nextcloud is already there (command occ is found), but " >&2
  130. echo " the database is not yet created, this situation will arise." >&2
  131. return "${PIPESTATUS[0]}"
  132. fi
  133. }
  134. nextcloud:config:simple:add() {
  135. local key="$1" value="$2"
  136. create_occ_if_not_exists || return 1
  137. if ! [ -e "$CONFIGFILE" ]; then
  138. err "Config file '$CONFIGFILE' does not exist."
  139. return 1
  140. fi
  141. if [ -z "$value" ]; then
  142. err "Value for '$key' is empty. Skipping."
  143. return 1
  144. fi
  145. ## check for \ and ' in value and key
  146. if [[ "$value" =~ [\\\'] ]]; then
  147. err "Unsupported value for '$key' contains a backslash or a single quote."
  148. return 1
  149. fi
  150. if [[ "$key" =~ [\\\'] ]]; then
  151. err "Key '$key' contains a backslash or a single quote."
  152. return 1
  153. fi
  154. if grep "^ '$key' => '" "$CONFIGFILE" >/dev/null; then
  155. sed -ri "s/^( '$key' => ')(.*)(',)$/\1${value}\3/g" "$CONFIGFILE"
  156. return 0
  157. fi
  158. ## Add '$key' => 'value', to the end of the file, before the closing paren.
  159. sed -ri "s/^(\);)$/ '$key' => '${value}',\n\1/g" "$CONFIGFILE"
  160. }
  161. nextcloud:config:version() {
  162. for f in {"$SERVICE_CONFIGSTORE","$SERVICE_DATASTORE"}/var/www/html/config/config.php; do
  163. if [ -e "$f" ]; then
  164. cat "$f"
  165. break
  166. fi
  167. done |
  168. grep "'version' =>" |
  169. cut -f 4 -d \' |
  170. cut -f 1-3 -d .
  171. }