summaryrefslogtreecommitdiff
path: root/roles
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2022-07-06 23:16:29 +0200
committerChristian Pointner <equinox@spreadspace.org>2022-07-06 23:16:29 +0200
commit20dc85ae0c644a9580e12314d443c3356dcab4ca (patch)
tree5c7707835ae898dfc6d91087a2126f824f462430 /roles
parentele-media: base install (diff)
ele-media: nextcloud base install
Diffstat (limited to 'roles')
-rw-r--r--roles/elevate/media/defaults/main.yml5
-rw-r--r--roles/elevate/media/tasks/main.yml8
-rw-r--r--roles/elevate/media/tasks/nextcloud-app.yml128
-rw-r--r--roles/elevate/media/tasks/nextcloud-custom-image.yml31
-rw-r--r--roles/elevate/media/tasks/nextcloud.yml4
-rw-r--r--roles/elevate/media/tasks/samba.yml6
-rw-r--r--roles/elevate/media/templates/nextcloud-apache-site.conf.j210
-rw-r--r--roles/elevate/media/templates/nextcloud-cron-.timer.j29
-rw-r--r--roles/elevate/media/templates/nextcloud-cron@.service.j215
-rwxr-xr-xroles/elevate/media/templates/nextcloud-occ.j219
-rw-r--r--roles/elevate/media/templates/nextcloud-pod-spec-with-mariadb.yml.j279
-rw-r--r--roles/elevate/media/templates/nextcloud-run-cron.sh.j27
-rwxr-xr-xroles/elevate/media/templates/nextcloud-upgrade.j262
13 files changed, 374 insertions, 9 deletions
diff --git a/roles/elevate/media/defaults/main.yml b/roles/elevate/media/defaults/main.yml
index 5cde7860..c16a38a0 100644
--- a/roles/elevate/media/defaults/main.yml
+++ b/roles/elevate/media/defaults/main.yml
@@ -4,10 +4,13 @@ elevate_media_share_gid: "800"
# elevate_media_share_storage:
# ...
-
+elevate_media_nextcloud_db_uid: "801"
+elevate_media_nextcloud_db_gid: "801"
+# elevate_media_nextcloud_base_path: /srv/nextcloud
# elevate_media_nextcloud_storage:
# ...
+# elevate_media_nextcloud_instance_name: media.elevate.at
# elevate_media_nextcloud_instance:
# ...
diff --git a/roles/elevate/media/tasks/main.yml b/roles/elevate/media/tasks/main.yml
index 097f0c1b..910104f8 100644
--- a/roles/elevate/media/tasks/main.yml
+++ b/roles/elevate/media/tasks/main.yml
@@ -1,11 +1,5 @@
---
-- name: install samba
- apt:
- name:
- - samba
- state: present
-
-- name: configure samba
+- name: install and configure samba
import_tasks: samba.yml
- name: install and configure nextcloud
diff --git a/roles/elevate/media/tasks/nextcloud-app.yml b/roles/elevate/media/tasks/nextcloud-app.yml
new file mode 100644
index 00000000..fd864893
--- /dev/null
+++ b/roles/elevate/media/tasks/nextcloud-app.yml
@@ -0,0 +1,128 @@
+---
+- name: prepare storage volume for nextcloud
+ vars:
+ storage_volume: "{{ elevate_media_nextcloud_storage | combine({'dest': elevate_media_nextcloud_base_path}) }}"
+ include_role:
+ name: "storage/{{ elevate_media_nextcloud_storage.type }}/volume"
+
+- name: create nextcloud app subdirectory
+ file:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/nextcloud"
+ owner: "{{ elevate_media_share_uid }}"
+ group: "{{ elevate_media_share_gid }}"
+ state: directory
+
+
+- name: add group for nextcloud db
+ group:
+ name: nc-db
+ gid: "{{ elevate_media_nextcloud_db_gid }}"
+
+- name: add user for nextcloud db
+ user:
+ name: nc-db
+ uid: "{{ elevate_media_nextcloud_db_uid }}"
+ group: nc-db
+ password: "!"
+
+- name: create nextcloud database subdirectory
+ file:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/{{ elevate_media_nextcloud_instance.database.type }}"
+ owner: "{{ elevate_media_nextcloud_db_uid }}"
+ group: "{{ elevate_media_nextcloud_db_gid }}"
+ state: directory
+
+
+- name: create auxiliary config directory
+ file:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config"
+ state: directory
+
+- name: create apache vhost config
+ template:
+ src: nextcloud-apache-site.conf.j2
+ dest: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config/apache-site.conf"
+
+- name: configure apache to run on port 8080 only
+ copy:
+ content: |
+ Listen 8080
+ dest: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config/ports.conf"
+
+
+- name: build custom image
+ include_tasks: nextcloud-custom-image.yml
+
+- name: install pod manifest
+ vars:
+ kubernetes_standalone_pod:
+ name: "nextcloud-{{ elevate_media_nextcloud_instance_name }}"
+ spec: "{{ lookup('template', 'nextcloud-pod-spec-with-{{ elevate_media_nextcloud_instance.database.type }}.yml.j2') }}"
+ mode: "0600"
+ config_hash_items:
+ - path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config/apache-site.conf"
+ properties:
+ - checksum
+ - path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config/ports.conf"
+ properties:
+ - checksum
+ - path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/build/Dockerfile"
+ properties:
+ - checksum
+ include_role:
+ name: kubernetes/standalone/pod
+
+
+- name: install cron trigger script
+ template:
+ src: nextcloud-run-cron.sh.j2
+ dest: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config/run-cron.sh"
+ mode: 0755
+
+- name: install template systemd unit for cron trigger
+ template:
+ src: nextcloud-cron@.service.j2
+ dest: /etc/systemd/system/nextcloud-cron@.service
+
+- name: install systemd timer unit
+ template:
+ src: nextcloud-cron-.timer.j2
+ dest: "/etc/systemd/system/nextcloud-cron-{{ elevate_media_nextcloud_instance_name }}.timer"
+
+- name: start/enable cron trigger systemd timer
+ systemd:
+ daemon_reload: yes
+ name: "nextcloud-cron-{{ elevate_media_nextcloud_instance_name }}.timer"
+ state: started
+ enabled: yes
+
+
+- name: configure nginx vhost
+ vars:
+ nginx_vhost:
+ name: "nextcloud-{{ elevate_media_nextcloud_instance_name }}"
+ template: generic-proxy-no-buffering-with-acme
+ acme: true
+ hostnames: "{{ elevate_media_nextcloud_instance.hostnames }}"
+ locations:
+ '/':
+ proxy_pass: "http://127.0.0.1:{{ elevate_media_nextcloud_instance.port }}"
+ proxy_redirect:
+ - redirect: "http://$host/"
+ replacement: "https://$host/"
+ - redirect: "http://$host:8080/"
+ replacement: "https://$host/"
+ extra_directives: |-
+ client_max_body_size 0;
+ include_role:
+ name: nginx/vhost
+
+
+- name: install management scripts
+ loop:
+ - nextcloud-upgrade
+ - nextcloud-occ
+ template:
+ src: "{{ item }}.j2"
+ dest: "/usr/local/bin/{{ item }}"
+ mode: 0755
diff --git a/roles/elevate/media/tasks/nextcloud-custom-image.yml b/roles/elevate/media/tasks/nextcloud-custom-image.yml
new file mode 100644
index 00000000..46f06dbf
--- /dev/null
+++ b/roles/elevate/media/tasks/nextcloud-custom-image.yml
@@ -0,0 +1,31 @@
+---
+- name: create build directory for custom image
+ file:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/build"
+ state: directory
+
+- name: generate Dockerfile for custom image
+ copy:
+ content: |
+ FROM {{ elevate_media_nextcloud_instance.custom_image.from | default('nextcloud:' + elevate_media_nextcloud_instance.version) }}
+
+ RUN set -x \
+ && addgroup --gid {{ elevate_media_share_gid }} nc-app \
+ && adduser --uid {{ elevate_media_share_uid }} --gid {{ elevate_media_share_gid }} --system --no-create-home --home /var/www/html --disabled-login --disabled-password nc-app
+ {% if 'custom_image' in elevate_media_nextcloud_instance %}
+
+ {{ elevate_media_nextcloud_instance.custom_image.dockerfile }}
+ {% endif %}
+ dest: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/build/Dockerfile"
+ register: nextcloud_custom_image_docker
+
+- name: build custom image
+ docker_image:
+ name: "nextcloud/{{ elevate_media_nextcloud_instance_name }}:{{ elevate_media_nextcloud_instance.version }}"
+ state: present
+ force_source: "{{ nextcloud_custom_image_docker is changed }}"
+ source: build
+ build:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/build"
+ network: host
+ pull: yes
diff --git a/roles/elevate/media/tasks/nextcloud.yml b/roles/elevate/media/tasks/nextcloud.yml
index e24bf32d..1b875f2b 100644
--- a/roles/elevate/media/tasks/nextcloud.yml
+++ b/roles/elevate/media/tasks/nextcloud.yml
@@ -1,5 +1,7 @@
---
-## TODO: include role: apps/nextcloud
+## TODO: convert to new apps/nexctloud/instance role once this is done!
+- name: basic nextcloud config
+ import_tasks: nextcloud-app.yml
# - name: configure nextcloud upload file size limit
# loop:
diff --git a/roles/elevate/media/tasks/samba.yml b/roles/elevate/media/tasks/samba.yml
index 3101a82a..67a511de 100644
--- a/roles/elevate/media/tasks/samba.yml
+++ b/roles/elevate/media/tasks/samba.yml
@@ -1,4 +1,10 @@
---
+- name: install samba
+ apt:
+ name:
+ - samba
+ state: present
+
- name: create group for shared access
group:
name: share
diff --git a/roles/elevate/media/templates/nextcloud-apache-site.conf.j2 b/roles/elevate/media/templates/nextcloud-apache-site.conf.j2
new file mode 100644
index 00000000..a52a7fc5
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-apache-site.conf.j2
@@ -0,0 +1,10 @@
+<VirtualHost *:8080>
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html
+
+ UseCanonicalName Off
+ UseCanonicalPhysicalPort Off
+
+ ErrorLog ${APACHE_LOG_DIR}/error.log
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+</VirtualHost>
diff --git a/roles/elevate/media/templates/nextcloud-cron-.timer.j2 b/roles/elevate/media/templates/nextcloud-cron-.timer.j2
new file mode 100644
index 00000000..b8caa377
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-cron-.timer.j2
@@ -0,0 +1,9 @@
+[Unit]
+Description=Nextcloud cron.php job timer for %i
+
+[Timer]
+OnCalendar=*:{{ 5 | random(seed=elevate_media_nextcloud_instance_name) }}/5
+Unit=nextcloud-cron@{{ elevate_media_nextcloud_instance_name }}.service
+
+[Install]
+WantedBy=timers.target
diff --git a/roles/elevate/media/templates/nextcloud-cron@.service.j2 b/roles/elevate/media/templates/nextcloud-cron@.service.j2
new file mode 100644
index 00000000..33623c16
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-cron@.service.j2
@@ -0,0 +1,15 @@
+[Unit]
+Description=Nextcloud cron.php job for %i
+
+[Service]
+Type=oneshot
+ExecStart={{ elevate_media_nextcloud_base_path }}/%i/config/run-cron.sh
+NoNewPrivileges=yes
+PrivateTmp=yes
+PrivateDevices=yes
+ProtectSystem=strict
+ProtectHome=yes
+ProtectKernelTunables=yes
+ProtectControlGroups=yes
+RestrictRealtime=yes
+RestrictAddressFamilies=AF_UNIX AF_INET
diff --git a/roles/elevate/media/templates/nextcloud-occ.j2 b/roles/elevate/media/templates/nextcloud-occ.j2
new file mode 100755
index 00000000..f12f1259
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-occ.j2
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+INST_NAME="$1"
+shift
+
+if [ -z "$INST_NAME" ]; then
+ echo "Usage: $0 <instance> [ <arguments for occ.php> ... ]"
+ exit 1
+fi
+
+set -eu
+
+pod_id=$(crictl pods -q --state ready --name "^nextcloud-$INST_NAME-{{ ansible_nodename }}$")
+if [ -z "$pod_id" ]; then echo "Pod not found"; exit 1; fi
+
+container_id=$(crictl ps -q --name '^nextcloud$' -p "$pod_id")
+if [ -z "$container_id" ]; then echo "Container not found"; exit 1; fi
+
+exec crictl exec -it "$container_id" php /var/www/html/occ $@
diff --git a/roles/elevate/media/templates/nextcloud-pod-spec-with-mariadb.yml.j2 b/roles/elevate/media/templates/nextcloud-pod-spec-with-mariadb.yml.j2
new file mode 100644
index 00000000..b67066fc
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-pod-spec-with-mariadb.yml.j2
@@ -0,0 +1,79 @@
+securityContext:
+ allowPrivilegeEscalation: false
+containers:
+- name: nextcloud
+ image: "nextcloud/{{ elevate_media_nextcloud_instance_name }}:{{ elevate_media_nextcloud_instance.version }}"
+ securityContext:
+ runAsUser: {{ elevate_media_share_uid }}
+ runAsGroup: {{ elevate_media_share_gid }}
+ resources:
+ limits:
+ memory: "4Gi"
+{% if 'new' in elevate_media_nextcloud_instance and elevate_media_nextcloud_instance.new %}
+ env:
+ - name: NEXTCLOUD_TRUSTED_DOMAINS
+ value: "{{ elevate_media_nextcloud_instance.hostnames | join(' ') }}"
+ - name: OVERWRITEPROTOCOL
+ value: "https"
+ - name: MYSQL_HOST
+ value: 127.0.0.1
+ - name: MYSQL_DATABASE
+ value: nextcloud
+ - name: MYSQL_USER
+ value: nextcloud
+ - name: MYSQL_PASSWORD
+ value: "{{ elevate_media_nextcloud_instance.database.password }}"
+{% endif %}
+ volumeMounts:
+ - name: nextcloud
+ mountPath: /var/www/html
+ - name: config
+ mountPath: /etc/apache2/sites-available/000-default.conf
+ subPath: apache-site.conf
+ readOnly: true
+ - name: config
+ mountPath: /etc/apache2/ports.conf
+ subPath: ports.conf
+ readOnly: true
+ ports:
+ - containerPort: 8080
+ hostPort: {{ elevate_media_nextcloud_instance.port }}
+ hostIP: 127.0.0.1
+- name: database
+ image: "mariadb:{{ elevate_media_nextcloud_instance.database.version }}"
+ args:
+ - --transaction-isolation=READ-COMMITTED
+ - --binlog-format=ROW
+ securityContext:
+ runAsUser: {{ elevate_media_nextcloud_db_uid }}
+ runAsGroup: {{ elevate_media_nextcloud_db_gid }}
+ resources:
+ limits:
+ memory: "2Gi"
+{% if 'new' in elevate_media_nextcloud_instance and elevate_media_nextcloud_instance.new %}
+ env:
+ - name: MYSQL_RANDOM_ROOT_PASSWORD
+ value: "true"
+ - name: MYSQL_DATABASE
+ value: nextcloud
+ - name: MYSQL_USER
+ value: nextcloud
+ - name: MYSQL_PASSWORD
+ value: "{{ elevate_media_nextcloud_instance.database.password }}"
+{% endif %}
+ volumeMounts:
+ - name: database
+ mountPath: /var/lib/mysql
+volumes:
+- name: config
+ hostPath:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/config/"
+ type: Directory
+- name: nextcloud
+ hostPath:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/nextcloud"
+ type: Directory
+- name: database
+ hostPath:
+ path: "{{ elevate_media_nextcloud_base_path }}/{{ elevate_media_nextcloud_instance_name }}/{{ elevate_media_nextcloud_instance.database.type }}"
+ type: Directory
diff --git a/roles/elevate/media/templates/nextcloud-run-cron.sh.j2 b/roles/elevate/media/templates/nextcloud-run-cron.sh.j2
new file mode 100644
index 00000000..0824d6ba
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-run-cron.sh.j2
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+POD_NAME="{{ elevate_media_nextcloud_instance_name }}-$(hostname)"
+POD_ID=$(crictl pods --name "$POD_NAME" --state ready -q)
+CONTAINER_ID=$(crictl ps --pod "$POD_ID" --name nextcloud -q)
+
+exec crictl exec "$CONTAINER_ID" php -f /var/www/html/cron.php
diff --git a/roles/elevate/media/templates/nextcloud-upgrade.j2 b/roles/elevate/media/templates/nextcloud-upgrade.j2
new file mode 100755
index 00000000..a4221edc
--- /dev/null
+++ b/roles/elevate/media/templates/nextcloud-upgrade.j2
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+INST_NAME="$1"
+VERSION="$2"
+if [ -z "$INST_NAME" ] || [ -z "$VERSION" ]; then
+ echo "Usage: $0 <instance> <version>"
+ exit 1
+fi
+
+set -eu
+
+K8S_CONFIG_HASH_D="/etc/kubernetes/config-hashes/"
+K8S_CONFIG_HASH_FILE="$K8S_CONFIG_HASH_D/nextcloud-$INST_NAME.yml"
+K8S_MANIFEST_D="/etc/kubernetes/manifests/"
+K8S_MANIFEST_FILE="$K8S_MANIFEST_D/nextcloud-$INST_NAME.yml"
+if [ ! -e "$K8S_MANIFEST_FILE" ]; then
+ echo "could not find manifest file: $K8S_MANIFEST_FILE"
+ exit 2
+fi
+
+TMP_D=$(mktemp -d -t nextcloud-upgrade.XXXXXXX)
+function cleanup {
+ rm -rf "$TMP_D"
+}
+trap cleanup EXIT
+
+IMAGE_BUILD_D="{{ elevate_media_nextcloud_base_path }}/$INST_NAME/build"
+IMAGE_NAME="nextcloud"
+if [ -e "$IMAGE_BUILD_D/Dockerfile" ]; then
+ ## this only works if docker is installed...
+ echo "*** Building custom image"
+ echo ""
+ sed "0,/FROM \(.*\):.*/s//FROM \1:$VERSION/" -i "$IMAGE_BUILD_D/Dockerfile"
+ IMAGE_NAME="nextcloud/$INST_NAME"
+ docker build --rm --network host -t "$IMAGE_NAME:$VERSION" "$IMAGE_BUILD_D"
+ echo ""
+else
+ echo "*** Pre-Pulling the image"
+ echo ""
+ crictl pull "docker.io/library/nextcloud:$VERSION"
+ echo ""
+fi
+
+echo "*** Rebuilding config-hash file"
+echo ""
+cat "$K8S_CONFIG_HASH_FILE" | grep '^/.*:' | sed 's/:$//' | xargs sha256sum | awk '{ print($2":\n checksum: "$1) }' > "$TMP_D/config-hash.yml"
+CONFIG_HASH=$(sha256sum "$TMP_D/config-hash.yml" | awk '{ print($1) }')
+
+echo "*** Patching manifest file"
+echo ""
+sed -e "s#image: \"$IMAGE_NAME:.*\"#image: \"$IMAGE_NAME:$VERSION\"#" -e "s#config-hash: \".*\"#config-hash: \"$CONFIG_HASH\"#" "$K8S_MANIFEST_FILE" > "$TMP_D/manifest.yml"
+set +e
+diff -u "$K8S_MANIFEST_FILE" "$TMP_D/manifest.yml"
+if [ $? -eq 0 ]; then
+ echo "patching file failed?"
+ exit 2
+fi
+cat "$TMP_D/config-hash.yml" > "$K8S_CONFIG_HASH_FILE"
+cat "$TMP_D/manifest.yml" > "$K8S_MANIFEST_FILE"
+echo ""
+
+exit 0