diff --git a/templates/job-setup-apps.yaml b/templates/job-setup-apps.yaml index 993f2f5367fd279e1e6f9ecd1650a64fb8d0b5d2..e240388a83136c8dad0c6b3306d91d8aac7cfb45 100644 --- a/templates/job-setup-apps.yaml +++ b/templates/job-setup-apps.yaml @@ -21,5 +21,25 @@ spec: serviceAccountName: {{ .Release.Name }}-setup-apps-job containers: - name: setup-apps-job - image: docker.io/bitnami/kubectl:1.25 - command: ["kubectl", "exec", "deploy/{{ .Release.Name }}-nextcloud", "-n", {{ .Release.Namespace }}, "--", "/bin/bash", "/var/local/setup-apps.sh"] + image: docker.io/bitnami/kubectl:1.28 + command: + - /bin/bash + - -c + - > + pod=$(kubectl get pod -n {{ .Release.Namespace }} -l app.kubernetes.io/name=nextcloud --no-headers -o custom-columns=":metadata.name" | head -n 1) + && cp -L /scripts/setup-apps.sh /tmp/setup-apps.sh + && kubectl cp + -n {{ .Release.Namespace }} + /tmp/setup-apps.sh + $pod:/tmp/setup-apps.sh + && kubectl exec + -n {{ .Release.Namespace }} + deploy/{{ .Release.Name }}-nextcloud + -- /bin/bash /tmp/setup-apps.sh + volumeMounts: + - mountPath: /scripts + name: setup-apps + volumes: + - name: setup-apps + configMap: + name: "{{ .Release.Name }}-setup-apps" diff --git a/templates/nextcloud-onlyoffice-config.yaml b/templates/nextcloud-onlyoffice-config.yaml index fe728f008a647bf36dbbbb1cf0b0455648e2377d..985dc62154a56cb5bac4df508cd94c5b65127e9c 100644 --- a/templates/nextcloud-onlyoffice-config.yaml +++ b/templates/nextcloud-onlyoffice-config.yaml @@ -10,172 +10,6 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name | quote }} helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" data: - setup-apps.sh: | - #!/bin/bash - - set -o errexit - - # This script gets executed by the Kubernetes Job `{{ .Release.Name }}-setup-apps`, - # which gets created by Helm after every chart install and upgrade. - # - # The script: - # - # * Installs all apps declared in the `apps` helm values array - # * Installs all apps - # * Updates pinned apps if their pinned version has changed - # * Always updates unpinned apps to their newest version - # * Runs upgrade routines after installation of a new release or new - # pinned apps. - # * Configures single-sign-on - # * Loads Nextcloud config from the config.json - # * Updates database indices, columns, keys, etc needed after NC upgrade - - # Copied from the NC docker entrypoint to run OCC commands - run_as() { - if [ "$(id -u)" = 0 ]; then - su -p "www-data" -s /bin/sh -c "$1" - else - sh -c "$1" - fi - } - - echo "STARTING SETUP-APPS.SH" - - # Starting in version 0.15.18 of this chart (Stackspin 2.10), we no longer - # copy config.json from /var/local to the web root. We remove the copied - # file if we think we can safely do so. - if [ -f /var/www/html/config.json ] - then - echo "Found copy of config.json in web root." - if diff -q /var/www/html/config.json /var/local/config.json >/dev/null - then - echo "It's identical to the current config from the configmap." - echo "Deleting it from the web root." - rm /var/www/html/config.json - else - echo "It's different from the current config from the configmap." - echo "Keeping it around for manual reconciliation." - fi - fi - - occ="/var/www/html/occ" - count=0 - limit=10 - - # There's a nextcloud setup process. First, wait for `occ` to exist - until [ -f "$occ" ] || [ "$count" -gt "$limit" ] - do - count=$((count+1)) - wait=$((count*10)) - echo "$occ doesn't exist yet, waiting $wait seconds" - sleep $wait - done - - echo "$occ now exists!" - - count=0 - - # As soon as the $occ command exist, we know that we can run occ, but - # Nextcloud might still be initializing, we use `occ` to find out whether - # the installation process has finished, and then we continue. - until [[ $(run_as "php occ status --output json") =~ '"installed":true' ]] || [ "$count" -gt "$limit" ] - do - count=$((count+1)) - wait=$((count*10)) - echo "Nextcloud is not installed yet. Waiting $wait seconds..." - sleep $wait - done - - echo "Nextcloud is now installed, we can do our thing!" - - app_versions=$(run_as "php $occ app:list --output json") - - echo "app versions found" - - # Install all apps declared in the `apps` helm values array - {{- range $apps_type, $apps := .Values.apps }} - {{- range $apps }} - {{- if not .name }} - echo "Skipping app {{ . }} without name variable set" - {{- else if .version }} - # Apps with a pinned version number are downloaded from GitHub so we can - # update the pin with Renovatebot - - desired_version=$(echo "{{ .version }}" | sed 's/^v//') - - if [[ $app_versions =~ '"{{ .name }}":"'"$desired_version"'"' ]] - then - echo "Pinned app {{ .name }} is up-to-date at version {{ .version }}" - else - echo "No match in ${app_versions} for \"{{ .name }}\":\"$desired_version\"," - echo "Installing app {{ .github_repository }} version '{{ .version }}'" - # Where to install the app - target_directory="/var/www/html/custom_apps" - # We need to edit $ to be able to use `tpl` inside a `range`, - # see https://github.com/helm/helm/issues/5979#issuecomment-518231758 . - # This allows us to use version variable in the `release_filename` or - # `raw_url`. - {{- $_ := set $ "version" .version}} - {{- if .raw_url }} - url="{{ tpl .raw_url $ }}" - {{- else }} - url="https://github.com/{{ .github_repository }}/releases/download/{{ .version }}/{{ tpl .release_filename $ }}" - {{- end }} # end if .raw_url - curl "$url" -Lo "{{ .name }}.tar.gz" - # If the above url results in a 404, curl will not complain and store the - # body of the 404 in the file :/. So we check here whether we actually - # got a valid archive; `tar` will fail if not. - tar -tf "{{ .name }}.tar.gz" >/dev/null - # Remove old version of the app - if [[ -d "$target_directory/{{ .name }}" ]] - then - rm -r "$target_directory/{{ .name }}" - fi - # Extract app into target directory. The app tars usually contain a folder - # named after the app name - tar -xf "{{ .name }}.tar.gz" -C "$target_directory" - # Ownership in the archive can be anything. Nextcloud wants it to be - # www-data. - chown -R 33:33 "$target_directory" - rm "{{ .name }}.tar.gz" - fi - {{- else }} - # Unpinned app - if [[ "$app_versions" =~ '"{{ .name }}"' ]] - then - # Update the app to its latest version - echo "Updating unpinned app {{ .name }}" - run_as "php $occ app:update {{ .name }} --no-interaction" - else - echo "Installing app {{ .name }}" - run_as "php $occ app:install {{ .name }} --keep-disabled --no-interaction" - fi - {{ end }} # end if and .github_repository .version - {{- if .enabled }} - # Enable {{ .name }} app - run_as "php $occ app:enable {{ .name }}" - {{- end }} # end if .enabled - {{- end }} # end range $apps - {{- end }} # end range .Values.apps - - # Some of the manually installed apps might need to run upgrade scripts, run - # them now - run_as "php $occ upgrade" - - # Config settings from the configmap above - run_as "php $occ config:import /var/local/config.json" - - echo "Updating database indices, columns, keys, etc." - run_as "php $occ db:add-missing-indices --no-interaction" - run_as "php $occ db:add-missing-columns --no-interaction" - run_as "php $occ db:add-missing-primary-keys --no-interaction" - run_as "php $occ db:convert-filecache-bigint --no-interaction" - - {{- if .Values.scim.token }} - set -x - run_as "php $occ config:app:set scimserviceprovider jwt-secret --value="'"{{ .Values.scim.token }}"' - {{- end }} - # # All values in config.json are applied by the nextcloud occ command # config:import. # system.trusted_proxies contains a list of proxies that are considered @@ -200,7 +34,6 @@ data: # apps.core.backgroundjobs_mode set to cron disables the unreliable ajax # scheduling that is enabled by default. Ajax scheduling is not needed # because cronjobs are regularly executed by a kubernetes resource. - # config.json: | { "system":{ diff --git a/templates/setup-apps-configmap.yaml b/templates/setup-apps-configmap.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0d6e577f60c0d8eff4f28ed063ac06c6fce5dabe --- /dev/null +++ b/templates/setup-apps-configmap.yaml @@ -0,0 +1,175 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ .Release.Name }}-setup-apps" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +data: + setup-apps.sh: | + #!/bin/bash + + set -o errexit + + # This script gets executed by the Kubernetes Job `{{ .Release.Name }}-setup-apps`, + # which gets created by Helm after every chart install and upgrade. + # + # The script: + # + # * Installs all apps declared in the `apps` helm values array + # * Installs all apps + # * Updates pinned apps if their pinned version has changed + # * Always updates unpinned apps to their newest version + # * Runs upgrade routines after installation of a new release or new + # pinned apps. + # * Configures single-sign-on + # * Loads Nextcloud config from the config.json + # * Updates database indices, columns, keys, etc needed after NC upgrade + + # Copied from the NC docker entrypoint to run OCC commands + run_as() { + if [ "$(id -u)" = 0 ]; then + su -p "www-data" -s /bin/sh -c "$1" + else + sh -c "$1" + fi + } + + echo "STARTING SETUP-APPS.SH" + + # Starting in version 0.15.18 of this chart (Stackspin 2.10), we no longer + # copy config.json from /var/local to the web root. We remove the copied + # file if we think we can safely do so. + if [ -f /var/www/html/config.json ] + then + echo "Found copy of config.json in web root." + if diff -q /var/www/html/config.json /var/local/config.json >/dev/null + then + echo "It's identical to the current config from the configmap." + echo "Deleting it from the web root." + rm /var/www/html/config.json + else + echo "It's different from the current config from the configmap." + echo "Keeping it around for manual reconciliation." + fi + fi + + occ="/var/www/html/occ" + count=0 + limit=10 + + # There's a nextcloud setup process. First, wait for `occ` to exist + until [ -f "$occ" ] || [ "$count" -gt "$limit" ] + do + count=$((count+1)) + wait=$((count*10)) + echo "$occ doesn't exist yet, waiting $wait seconds" + sleep $wait + done + + echo "$occ now exists!" + + count=0 + + # As soon as the $occ command exist, we know that we can run occ, but + # Nextcloud might still be initializing, we use `occ` to find out whether + # the installation process has finished, and then we continue. + until [[ $(run_as "php occ status --output json") =~ '"installed":true' ]] || [ "$count" -gt "$limit" ] + do + count=$((count+1)) + wait=$((count*10)) + echo "Nextcloud is not installed yet. Waiting $wait seconds..." + sleep $wait + done + + echo "Nextcloud is now installed, we can do our thing!" + + app_versions=$(run_as "php $occ app:list --output json") + + echo "app versions found" + + # Install all apps declared in the `apps` helm values array + {{- range $apps_type, $apps := .Values.apps }} + {{- range $apps }} + {{- if not .name }} + echo "Skipping app {{ . }} without name variable set" + {{- else if .version }} + # Apps with a pinned version number are downloaded from GitHub so we can + # update the pin with Renovatebot + + desired_version=$(echo "{{ .version }}" | sed 's/^v//') + + if [[ $app_versions =~ '"{{ .name }}":"'"$desired_version"'"' ]] + then + echo "Pinned app {{ .name }} is up-to-date at version {{ .version }}" + else + echo "No match in ${app_versions} for \"{{ .name }}\":\"$desired_version\"," + echo "Installing app {{ .github_repository }} version '{{ .version }}'" + # Where to install the app + target_directory="/var/www/html/custom_apps" + # We need to edit $ to be able to use `tpl` inside a `range`, + # see https://github.com/helm/helm/issues/5979#issuecomment-518231758 . + # This allows us to use version variable in the `release_filename` or + # `raw_url`. + {{- $_ := set $ "version" .version}} + {{- if .raw_url }} + url="{{ tpl .raw_url $ }}" + {{- else }} + url="https://github.com/{{ .github_repository }}/releases/download/{{ .version }}/{{ tpl .release_filename $ }}" + {{- end }} # end if .raw_url + curl "$url" -Lo "{{ .name }}.tar.gz" + # If the above url results in a 404, curl will not complain and store the + # body of the 404 in the file :/. So we check here whether we actually + # got a valid archive; `tar` will fail if not. + tar -tf "{{ .name }}.tar.gz" >/dev/null + # Remove old version of the app + if [[ -d "$target_directory/{{ .name }}" ]] + then + rm -r "$target_directory/{{ .name }}" + fi + # Extract app into target directory. The app tars usually contain a folder + # named after the app name + tar -xf "{{ .name }}.tar.gz" -C "$target_directory" + # Ownership in the archive can be anything. Nextcloud wants it to be + # www-data. + chown -R 33:33 "$target_directory" + rm "{{ .name }}.tar.gz" + fi + {{- else }} + # Unpinned app + if [[ "$app_versions" =~ '"{{ .name }}"' ]] + then + # Update the app to its latest version + echo "Updating unpinned app {{ .name }}" + run_as "php $occ app:update {{ .name }} --no-interaction" + else + echo "Installing app {{ .name }}" + run_as "php $occ app:install {{ .name }} --keep-disabled --no-interaction" + fi + {{ end }} # end if and .github_repository .version + {{- if .enabled }} + # Enable {{ .name }} app + run_as "php $occ app:enable {{ .name }}" + {{- end }} # end if .enabled + {{- end }} # end range $apps + {{- end }} # end range .Values.apps + + # Some of the manually installed apps might need to run upgrade scripts, run + # them now + run_as "php $occ upgrade" + + # Config settings from the configmap above + run_as "php $occ config:import /var/local/config.json" + + echo "Updating database indices, columns, keys, etc." + run_as "php $occ db:add-missing-indices --no-interaction" + run_as "php $occ db:add-missing-columns --no-interaction" + run_as "php $occ db:add-missing-primary-keys --no-interaction" + run_as "php $occ db:convert-filecache-bigint --no-interaction" + + {{- if .Values.scim.token }} + set -x + run_as "php $occ config:app:set scimserviceprovider jwt-secret --value="'"{{ .Values.scim.token }}"' + {{- end }}