Skip to content
Snippets Groups Projects
Commit 0c44baca authored by Arie Peterson's avatar Arie Peterson
Browse files

Merge branch '1080-migrate-jobs-to-poststartcommand' into 'main'

Resolve "Migrate jobs to postStartCommand"

Closes #1080

See merge request !300
parents d6b1c660 ed6fd36a
No related branches found
No related tags found
1 merge request!300Resolve "Migrate jobs to postStartCommand"
Pipeline #31676 passed with stages
in 8 minutes and 34 seconds
# Changelog # Changelog
## [0.15.0] - 2022-10-26
* Migrate post install and upgrade jobs to a postStartCommand inside the
Nextcloud pod
## [0.14.1] - 2022-10-20 ## [0.14.1] - 2022-10-20
* Remove default passwords in values.yaml and values-local.yaml.example * Remove default passwords in values.yaml and values-local.yaml.example
......
...@@ -4,12 +4,12 @@ description: | ...@@ -4,12 +4,12 @@ description: |
A helm chart for installing NextCloud and setting up ONLYOFFICE integration A helm chart for installing NextCloud and setting up ONLYOFFICE integration
name: nextcloud-onlyoffice name: nextcloud-onlyoffice
appVersion: NC-24.0.5-OO-7.2.0.204 appVersion: NC-24.0.5-OO-7.2.0.204
version: 0.14.2 version: 0.15.0
icon: https://cdn.rawgit.com/docker-library/docs/defa5ffc7123177acd60ddef6e16bddf694cc35f/nextcloud/logo.svg icon: https://cdn.rawgit.com/docker-library/docs/defa5ffc7123177acd60ddef6e16bddf694cc35f/nextcloud/logo.svg
dependencies: dependencies:
# https://artifacthub.io/packages/helm/nextcloud/nextcloud # https://artifacthub.io/packages/helm/nextcloud/nextcloud
- name: nextcloud - name: nextcloud
version: 3.2.0 version: 3.1.2
repository: "https://nextcloud.github.io/helm" repository: "https://nextcloud.github.io/helm"
# https://artifacthub.io/packages/helm/bitnami/rabbitmq # https://artifacthub.io/packages/helm/bitnami/rabbitmq
- name: rabbitmq - name: rabbitmq
......
...@@ -30,6 +30,11 @@ secrets variables manually when you run helm install: ...@@ -30,6 +30,11 @@ secrets variables manually when you run helm install:
- `rabbitmq.auth.erlangCookie` - `rabbitmq.auth.erlangCookie`
- `global.onlyofficeDb.password` - `global.onlyofficeDb.password`
**NOTE:** The chart currently includes a ConfigMap with a name that is not
dependent on the release name. This means that the chart cannot be installed
more than once into the same namespace. If you need to install Nextcloud and
Onlyoffice several times into the same cluster, use different namespaces.
### Install from the remote repo ### Install from the remote repo
This is the way to go if you want to use the packaged chart as is. If you'd like to make changes before installing, refer to the next section. This is the way to go if you want to use the packaged chart as is. If you'd like to make changes before installing, refer to the next section.
...@@ -43,19 +48,9 @@ helm repo add nextcloud-onlyoffice https://open.greenhost.net/api/v4/projects/1/ ...@@ -43,19 +48,9 @@ helm repo add nextcloud-onlyoffice https://open.greenhost.net/api/v4/projects/1/
Then install the chart: Then install the chart:
```console ```console
helm install --wait -f values-local.yaml my-nextcloud nextcloud-onlyoffice/nextcloud-onlyoffice helm install -f values-local.yaml my-nextcloud nextcloud-onlyoffice/nextcloud-onlyoffice
``` ```
**The `--wait` is important!** We need that because of how [helm chart
hooks](https://helm.sh/docs/topics/charts_hooks/) work:
> Note that if the --wait flag is set, the library will wait until all resources
> are in a ready state and will not run the post-install hook until they are
> ready.
The job in this chart needs the Nextcloud pod to be in a ready state before
being executed.
### Install from a local repo ### Install from a local repo
Start by cloning the nextcloud helm chart repo: Start by cloning the nextcloud helm chart repo:
...@@ -80,18 +75,21 @@ helm dependency build ...@@ -80,18 +75,21 @@ helm dependency build
Then install the chart: Then install the chart:
```console ```console
helm install --wait -f values-local.yaml my-nextcloud . helm install -f values-local.yaml my-nextcloud .
``` ```
**The `--wait` is important!** We need that because of how [helm chart ## Nextcloud configuration.
hooks](https://helm.sh/docs/topics/charts_hooks/) work:
> Note that if the --wait flag is set, the library will wait until all resources This chart adds a "postStart" command to the Nextcloud pod, that installs apps
> are in a ready state and will not run the post-install hook until they are (see below) and applies a custom configuration to set up those apps and
> ready. integration with ONLYOFFICE as well as the Stackspin OIDC provider.
The job in this chart needs the Nextcloud pod to be in a ready state before Kubernetes postStart commands do not log to the pod log. Instead, the script
being executed. creates its own log in `/var/www/tmp/postStart<date>.log`. This means that
even if you can't `exec` into the pod (because something is failing), you can
see the logs inside the `data` folder in the PVC. Often, if the `postStart`
command fails, you can also see the problem by running `kubectl describe pod
<nextcloud pod>`.
## Apps ## Apps
......
{{/* Change the user and group to www-data as required by occ */}}
{{- define "nextcloud-onlyoffice.securityContext" }}
fsGroup: 33
runAsUser: 33
runAsGroup: 33
{{- end}}
{{/* Add volume mounts that are also used by the nextcloud container */}}
{{/* and the configMap that contains job specific content */}}
{{- define "nextcloud-onlyoffice.volumeMounts" }}
- name: nextcloud-data
mountPath: /var/www/
subPath: root
- name: nextcloud-data
mountPath: /var/www/html
subPath: html
- name: nextcloud-data
mountPath: /var/www/html/data
subPath: data
- name: nextcloud-data
mountPath: /var/www/html/config
subPath: config
- name: nextcloud-data
mountPath: /var/www/html/custom_apps
subPath: custom_apps
- name: nextcloud-data
mountPath: /var/www/html/themes
subPath: themes
- name: nextcloud-data
mountPath: /var/www/tmp
subPath: tmp
- name: nextcloud-onlyoffice-config
mountPath: /var/local
{{- end }}
{{/* Set environment variables that are needed for the nextcloud setup */}}
{{- define "nextcloud-onlyoffice.env" }}
{{- if .Values.nextcloud.internalDatabase.enabled }}
- name: SQLITE_DATABASE
value: {{ .Values.nextcloud.internalDatabase.name | quote }}
{{- else if .Values.nextcloud.mariadb.enabled }}
- name: MYSQL_HOST
value: {{ template "mariadb.primary.fullname" .Subcharts.nextcloud.Subcharts.mariadb }}
- name: MYSQL_DATABASE
value: {{ .Values.nextcloud.mariadb.auth.database | quote }}
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: {{ printf "%s-%s" .Release.Name "db" }}
key: db-username
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: {{ printf "%s-%s" .Release.Name "db" }}
key: db-password
{{- else }}
- name: MYSQL_HOST
value: {{ .Values.nextcloud.externalDatabase.host | quote }}
- name: MYSQL_DATABASE
value: {{ .Values.nextcloud.externalDatabase.database | quote }}
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: {{ printf "%s-%s" .Release.Name "db" }}
key: db-username
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: {{ printf "%s-%s" .Release.Name "db" }}
key: db-password
{{- end }}
- name: NEXTCLOUD_ADMIN_USER
valueFrom:
secretKeyRef:
name: {{ printf "%s-%s" .Release.Name "nextcloud" }}
key: nextcloud-username
- name: NEXTCLOUD_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: {{ printf "%s-%s" .Release.Name "nextcloud" }}
key: nextcloud-password
- name: NEXTCLOUD_TRUSTED_DOMAINS
value: {{ .Values.nextcloud.nextcloud.host }}
{{- end }}
{{/* Add volumes that correspond to the volume mounts used in this tpl */}}
{{- define "nextcloud-onlyoffice.volumes" }}
- name: nextcloud-data
{{- if .Values.nextcloud.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ if .Values.nextcloud.persistence.existingClaim }}{{ .Values.nextcloud.persistence.existingClaim }}{{- else }}{{ template "nextcloud.fullname" .Subcharts.nextcloud }}-nextcloud{{- end }}
{{- else }}
emptyDir: {}
{{- end }}
- name: nextcloud-onlyoffice-config
configMap:
name: {{ .Release.Name }}-nextcloud-onlyoffice-config
{{- end}}
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-configure-nextcloud"
labels:
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "1"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
metadata:
name: "{{.Release.Name}}-configure-nextcloud"
labels:
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
restartPolicy: Never
securityContext: {{- include "nextcloud-onlyoffice.securityContext" . | indent 8 }}
containers:
- name: {{ .Release.Name }}-configure-nextcloud-job
image: {{ template "nextcloud.image" .Subcharts.nextcloud }}
command:
- "/usr/local/bin/php"
- "/var/www/html/occ"
- "config:import"
- "/var/local/config.json"
volumeMounts: {{- include "nextcloud-onlyoffice.volumeMounts" . | indent 8 }}
env: {{- include "nextcloud-onlyoffice.env" . | indent 8 }}
volumes: {{- include "nextcloud-onlyoffice.volumes" . | indent 6 }}
apiVersion: batch/v1
kind: Job
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 }}"
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "0"
spec:
backoffLimit: {{ .Values.setupApps.backoffLimit }}
ttlSecondsAfterFinished: 6000
template:
metadata:
name: "{{.Release.Name}}"
labels:
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
spec:
restartPolicy: Never
securityContext: {{- include "nextcloud-onlyoffice.securityContext" . | indent 8 }}
containers:
- name: {{ .Release.Name }}-setup-apps-job
image: {{ template "nextcloud.image" .Subcharts.nextcloud }}
command:
- "/bin/bash"
- "/var/local/setup-apps.sh"
volumeMounts: {{- include "nextcloud-onlyoffice.volumeMounts" . | indent 8 }}
env: {{- include "nextcloud-onlyoffice.env" . | indent 8 }}
volumes: {{- include "nextcloud-onlyoffice.volumes" . | indent 6 }}
---
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: "{{ .Release.Name }}-nextcloud-onlyoffice-config" # Can't use {{ .Release.name }} here, because we need to mount it to the
# Nextcloud pod from the values file
name: "nextcloud-onlyoffice-config-and-scripts"
labels: labels:
app.kubernetes.io/managed-by: {{ .Release.Service | quote }} app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }} app.kubernetes.io/instance: {{ .Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
data: data:
onlyoffice-config.json: |
{
"apps": {
"onlyoffice": {
"DocumentServerInternalUrl": "",
"DocumentServerUrl": "https:\/\/{{ .Values.onlyoffice.server_name }}\/",
"StorageUrl": "https:\/\/{{ .Values.nextcloud.nextcloud.host }}\/",
"defFormats": "{\"csv\":\"false\",\"doc\":\"false\",\"docm\":\"false\",\"docx\":\"true\",\"dotx\":\"false\",\"epub\":\"false\",\"html\":\"false\",\"odp\":\"true\",\"ods\":\"true\",\"odt\":\"true\",\"pdf\":\"false\",\"potm\":\"false\",\"potx\":\"false\",\"ppsm\":\"false\",\"ppsx\":\"false\",\"ppt\":\"false\",\"pptm\":\"false\",\"pptx\":\"true\",\"rtf\":\"false\",\"txt\":\"false\",\"xls\":\"false\",\"xlsm\":\"false\",\"xlsx\":\"true\",\"xltm\":\"false\",\"xltx\":\"false\"}",
"editFormats": "{\"csv\":\"true\",\"odp\":\"true\",\"ods\":\"true\",\"odt\":\"true\",\"rtf\":\"false\",\"txt\":\"true\"}",
"enabled": "yes",
"groups": "[]",
"jwt_secret": "{{ .Values.onlyoffice.jwtSecret }}",
"sameTab": "false",
"settings_error": "",
"types": "filesystem",
"customizationForcesave": "true"
}
}
}
setup-apps.sh: | setup-apps.sh: |
#!/bin/bash #!/bin/bash
#
# This script gets executed by a post-install,post-upgrade helm hook, which # This script gets executed as a postStart command inside the Nextcloud pod.
# The script:
# #
# * Installs all apps declared in the `apps` helm values array # * Installs all apps declared in the `apps` helm values array
# * Installs all apps # * Installs all apps
...@@ -38,21 +23,66 @@ data: ...@@ -38,21 +23,66 @@ data:
# * Runs upgrade routines after installation of a new release or new # * Runs upgrade routines after installation of a new release or new
# pinned apps. # pinned apps.
# * Configures single-sign-on # * Configures single-sign-on
# * Persists and loads the onlyoffice-config.json config file # * Persists and loads the config.json config file
# * Updates database indices, columns, keys, etc needed after NC upgrade # * Updates database indices, columns, keys, etc needed after NC upgrade
# * Writes a log to /var/www/tmp/postStart-<date>.log
set -e
exec > /var/www/tmp/postStart-$(date +"%s").log
exec 2> /var/www/tmp/postStart-$(date +"%s")_error.log
set -ev # 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"
# Debug: place the json file in a persistent location for reuse # Debug: place the json file in a persistent location for reuse
cp /var/local/onlyoffice-config.json /var/www/html/ cp /var/local/config.json /var/www/html/
occ="/var/www/html/occ" 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!"
# Enable app store so we can run `install` and `enable` commands # Enable app store so we can run `install` and `enable` commands
php $occ config:system:set appstoreenabled --type boolean --value true run_as "php $occ config:system:set appstoreenabled --type boolean --value true"
echo "app store enabled"
app_versions=$(php occ app:list --output json) app_versions=$(run_as "php $occ app:list --output json")
echo "app versions found"
# Install all apps declared in the `apps` helm values array # Install all apps declared in the `apps` helm values array
{{- range .Values.apps }} {{- range .Values.apps }}
...@@ -89,39 +119,51 @@ data: ...@@ -89,39 +119,51 @@ data:
fi fi
{{- else }} {{- else }}
# Unpinned app # Unpinned app
if ! echo $app_versions | grep -q '"{{ .name }}"'; then if [[ "$app_versions" =~ '"{{ .name }}"' ]]
echo "Installing app {{ .name }}" then
php $occ app:install {{ .name }} --keep-disabled --no-interaction
else
# Update the app to its latest version # Update the app to its latest version
echo "Updating app {{ .name }}" echo "Updating app {{ .name }}"
php $occ app:update {{ .name }} --no-interaction 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 fi
{{ end }} # end if and .github_repository .version {{ end }} # end if and .github_repository .version
{{- if .enabled }} {{- if .enabled }}
# Enable {{ .name }} app # Enable {{ .name }} app
php $occ app:enable {{ .name }} run_as "php $occ app:enable {{ .name }}"
{{ end }} # end if .enabled {{ end }} # end if .enabled
{{ end }} # end range .Values.apps {{ end }} # end range .Values.apps
# Some of the manually installed apps might need to run upgrade scripts, run # Some of the manually installed apps might need to run upgrade scripts, run
# them now # them now
php $occ upgrade run_as "php $occ upgrade"
# Config settings from the configmap above # Config settings from the configmap above
php $occ config:import /var/local/onlyoffice-config.json run_as "php $occ config:import /var/local/config.json"
php $occ config:app:set sociallogin custom_providers --value='{"custom_oidc": [{{ .Values.sociallogin.custom_oidc | toJson }}]}'
php $occ config:app:set sociallogin auto_create_groups --value='{{ .Values.sociallogin.auto_create_groups }}' echo "Setting custom OIDC provider data"
php $occ config:app:set sociallogin update_profile_on_login --value='{{ .Values.sociallogin.update_profile_on_login }}'
# Because of escape hell we can't use run_as here (unless you have amazing
# bash-fu)
su -p "www-data" -s /bin/bash -c "php $occ config:app:set sociallogin custom_providers --value='"'{"custom_oidc": [{{ .Values.sociallogin.custom_oidc | toJson }}]}'"'"
echo "Setting other sociallogin data"
run_as "php $occ config:app:set sociallogin auto_create_groups --value='{{ .Values.sociallogin.auto_create_groups }}'"
run_as "php $occ config:app:set sociallogin update_profile_on_login --value='{{ .Values.sociallogin.update_profile_on_login }}'"
echo "disabling app store"
# Disable app store again # Disable app store again
php $occ config:system:set appstoreenabled --type boolean --value false run_as "php $occ config:system:set appstoreenabled --type boolean --value false"
# Update database indices, columns, keys, etc needed after NC upgrade echo "Updating database indices, columns, keys, etc."
php $occ db:add-missing-indices --no-interaction run_as "php $occ db:add-missing-indices --no-interaction"
php $occ db:add-missing-columns --no-interaction run_as "php $occ db:add-missing-columns --no-interaction"
php $occ db:add-missing-primary-keys --no-interaction run_as "php $occ db:add-missing-primary-keys --no-interaction"
php $occ db:convert-filecache-bigint --no-interaction run_as "php $occ db:convert-filecache-bigint --no-interaction"
# #
# All values in config.json are applied by the nextcloud occ command # All values in config.json are applied by the nextcloud occ command
...@@ -149,7 +191,18 @@ data: ...@@ -149,7 +191,18 @@ data:
"backgroundjobs_mode": "webcron" "backgroundjobs_mode": "webcron"
}, },
"onlyoffice":{ "onlyoffice":{
"sameTab": "true" "DocumentServerInternalUrl": "",
"DocumentServerUrl": "https:\/\/{{ .Values.onlyoffice.server_name }}\/",
"StorageUrl": "https:\/\/{{ .Values.nextcloud.nextcloud.host }}\/",
"defFormats": "{\"csv\":\"false\",\"doc\":\"false\",\"docm\":\"false\",\"docx\":\"true\",\"dotx\":\"false\",\"epub\":\"false\",\"html\":\"false\",\"odp\":\"true\",\"ods\":\"true\",\"odt\":\"true\",\"pdf\":\"false\",\"potm\":\"false\",\"potx\":\"false\",\"ppsm\":\"false\",\"ppsx\":\"false\",\"ppt\":\"false\",\"pptm\":\"false\",\"pptx\":\"true\",\"rtf\":\"false\",\"txt\":\"false\",\"xls\":\"false\",\"xlsm\":\"false\",\"xlsx\":\"true\",\"xltm\":\"false\",\"xltx\":\"false\"}",
"editFormats": "{\"csv\":\"true\",\"odp\":\"true\",\"ods\":\"true\",\"odt\":\"true\",\"rtf\":\"false\",\"txt\":\"true\"}",
"enabled": "yes",
"groups": "[]",
"jwt_secret": "{{ .Values.onlyoffice.jwtSecret }}",
"sameTab": "true",
"settings_error": "",
"types": "filesystem",
"customizationForcesave": "true"
} }
} }
} }
...@@ -32,6 +32,21 @@ nextcloud: ...@@ -32,6 +32,21 @@ nextcloud:
enabled: true enabled: true
failureThreshold: 60 failureThreshold: 60
nextcloud:
extraVolumes:
- name: nextcloud-onlyoffice-config
configMap:
name: nextcloud-onlyoffice-config-and-scripts
extraVolumeMounts:
- name: nextcloud-onlyoffice-config
mountPath: /var/local
lifecycle:
postStartCommand:
- "/bin/bash"
- "/var/local/setup-apps.sh"
apps: apps:
- name: sociallogin - name: sociallogin
# apps[0].enabled needs to be set to true if you want to enable login via an external # apps[0].enabled needs to be set to true if you want to enable login via an external
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment