diff options
author | Christian Pointner <equinox@spreadspace.org> | 2020-03-25 20:55:53 +0100 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2020-03-25 20:55:53 +0100 |
commit | e328d1bb0fe0f08b2f993a5a933307b77ad95c29 (patch) | |
tree | c612f8062fade03d2cc30649c62ea765df57541e /roles/apps/nextcloud | |
parent | sk-cloudia: new nextcloud instnace next.skillz.biz (diff) |
move some roles to app/
Diffstat (limited to 'roles/apps/nextcloud')
-rw-r--r-- | roles/apps/nextcloud/defaults/main.yml | 27 | ||||
-rw-r--r-- | roles/apps/nextcloud/tasks/main.yml | 170 | ||||
-rw-r--r-- | roles/apps/nextcloud/templates/apache-site.conf.j2 | 10 | ||||
-rw-r--r-- | roles/apps/nextcloud/templates/cron-.timer.j2 | 9 | ||||
-rw-r--r-- | roles/apps/nextcloud/templates/cron@.service.j2 | 15 | ||||
-rwxr-xr-x | roles/apps/nextcloud/templates/nextcloud-occ.j2 | 22 | ||||
-rwxr-xr-x | roles/apps/nextcloud/templates/nextcloud-upgrade.j2 | 42 | ||||
-rw-r--r-- | roles/apps/nextcloud/templates/pod-with-mariadb.yml.j2 | 81 | ||||
-rw-r--r-- | roles/apps/nextcloud/templates/run-cron.sh.j2 | 11 |
9 files changed, 387 insertions, 0 deletions
diff --git a/roles/apps/nextcloud/defaults/main.yml b/roles/apps/nextcloud/defaults/main.yml new file mode 100644 index 00000000..16637f44 --- /dev/null +++ b/roles/apps/nextcloud/defaults/main.yml @@ -0,0 +1,27 @@ +--- +nextcloud_app_uid: "950" +nextcloud_app_gid: "950" + +nextcloud_db_uid: "951" +nextcloud_db_gid: "951" + +# nextcloud_base_path: /srv/nextcloud + +# nextcloud_zfs: +# pool: storage +# name: nextcloud +# size: 500G + +# nextcloud_instances: +# example: +# new: yes +# version: 17.0.0 +# port: 8100 +# hostnames: +# - wolke.example.com +# - cloud.example.com +# quota: 100G +# database: +# type: mariadb +# version: 10.4.8 +# password: "{{ vault_nextcloud_database_passwords['example'] }}" diff --git a/roles/apps/nextcloud/tasks/main.yml b/roles/apps/nextcloud/tasks/main.yml new file mode 100644 index 00000000..a951867c --- /dev/null +++ b/roles/apps/nextcloud/tasks/main.yml @@ -0,0 +1,170 @@ +--- +- name: create zfs datasets + when: nextcloud_zfs is defined + block: + - name: create zfs base dataset + zfs: + name: "{{ nextcloud_zfs.pool }}/{{ nextcloud_zfs.name }}" + state: present + extra_zfs_properties: + quota: "{{ nextcloud_zfs.size }}" + + - name: create zfs volumes for instances + loop: "{{ nextcloud_instances | dict2items }}" + loop_control: + label: "{{ item.key }} ({{ item.value.quota }})" + zfs: + name: "{{ nextcloud_zfs.pool }}/{{ nextcloud_zfs.name }}/{{ item.key }}" + state: present + extra_zfs_properties: + quota: "{{ item.value.quota }}" + + - name: configure nextcloud base bath + set_fact: + nextcloud_base_path: "{{ zfs_zpools[nextcloud_zfs.pool].mountpoint }}/{{ nextcloud_zfs.name }}" + + +- name: create instance subdirectories + when: nextcloud_zfs is not defined + loop: "{{ nextcloud_instances | list }}" + file: + path: "{{ nextcloud_base_path }}/{{ item }}" + state: directory + + + +- name: add group for nextcloud app + group: + name: nc-app + gid: "{{ nextcloud_app_gid }}" + +- name: add user for nextcloud app + user: + name: nc-app + uid: "{{ nextcloud_app_uid }}" + group: nc-app + password: "!" + +- name: create nextcloud app subdirectory + loop: "{{ nextcloud_instances | list }}" + file: + path: "{{ nextcloud_base_path }}/{{ item }}/nextcloud" + owner: "{{ nextcloud_app_uid }}" + group: "{{ nextcloud_app_gid }}" + state: directory + + +- name: add group for nextcloud db + group: + name: nc-db + gid: "{{ nextcloud_db_gid }}" + +- name: add user for nextcloud db + user: + name: nc-db + uid: "{{ nextcloud_db_uid }}" + group: nc-db + password: "!" + +- name: create nextcloud database subdirectory + loop: "{{ nextcloud_instances | dict2items}}" + loop_control: + label: "{{ item.key }} ({{ item.value.database.type }})" + file: + path: "{{ nextcloud_base_path }}/{{ item.key }}/{{ item.value.database.type }}" + owner: "{{ nextcloud_db_uid }}" + group: "{{ nextcloud_db_gid }}" + state: directory + + +- name: create auxiliary config directory + loop: "{{ nextcloud_instances | list }}" + file: + path: "{{ nextcloud_base_path }}/{{ item }}/config" + state: directory + +- name: create apache vhost config + loop: "{{ nextcloud_instances | list }}" + template: + src: apache-site.conf.j2 + dest: "{{ nextcloud_base_path }}/{{ item }}/config/apache-site.conf" + +- name: configure apache to run on port 8080 only + loop: "{{ nextcloud_instances | list }}" + copy: + content: | + Listen 8080 + dest: "{{ nextcloud_base_path }}/{{ item }}/config/ports.conf" + + +- name: generate pod manifests + loop: "{{ nextcloud_instances | dict2items }}" + loop_control: + label: "{{ item.key }}" + template: + src: "pod-with-{{ item.value.database.type }}.yml.j2" + dest: "/etc/kubernetes/manifests/nextcloud-{{ item.key }}.yml" + mode: 0600 + + +- name: install cron trigger script + loop: "{{ nextcloud_instances | list }}" + template: + src: run-cron.sh.j2 + dest: "{{ nextcloud_base_path }}/{{ item }}/config/run-cron.sh" + mode: 0755 + +- name: install template systemd unit for cron trigger + template: + src: cron@.service.j2 + dest: /etc/systemd/system/nextcloud-cron@.service + +- name: install systemd timer unit + loop: "{{ nextcloud_instances | list }}" + template: + src: cron-.timer.j2 + dest: "/etc/systemd/system/nextcloud-cron-{{ item }}.timer" + +- name: start/enable cron trigger systemd timer + loop: "{{ nextcloud_instances | list }}" + systemd: + daemon_reload: yes + name: "nextcloud-cron-{{ item }}.timer" + state: started + enabled: yes + + +- name: configure nginx vhost + loop: "{{ nextcloud_instances | dict2items }}" + include_role: + name: nginx/vhost + vars: + nginx_vhost: + name: "nextcloud-{{ item.key }}" + template: generic-proxy-no-buffering-with-acme + acme: true + hostnames: "{{ item.value.hostnames }}" + client_max_body_size: "512M" + proxy_pass: "http://127.0.0.1:{{ item.value.port }}" + proxy_redirect: + - redirect: "http://$host/" + replacement: "https://$host/" + - redirect: "http://$host:8080/" + replacement: "https://$host/" + + +- name: install management scripts + loop: + - nextcloud-upgrade + - nextcloud-occ + template: + src: "{{ item }}.j2" + dest: "/usr/local/bin/{{ item }}" + mode: 0755 + +## TODO: +# run this after installation is complete: +# +# nextcloud-occ {{ instance }} db:add-missing-indices +# nextcloud-occ {{ instance }} db:convert-filecache-bigint +# diff --git a/roles/apps/nextcloud/templates/apache-site.conf.j2 b/roles/apps/nextcloud/templates/apache-site.conf.j2 new file mode 100644 index 00000000..a52a7fc5 --- /dev/null +++ b/roles/apps/nextcloud/templates/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/apps/nextcloud/templates/cron-.timer.j2 b/roles/apps/nextcloud/templates/cron-.timer.j2 new file mode 100644 index 00000000..0c3f7cd7 --- /dev/null +++ b/roles/apps/nextcloud/templates/cron-.timer.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Nextcloud cron.php job timer for %i + +[Timer] +OnCalendar=*:{{ 5 | random(seed=item) }}/5 +Unit=nextcloud-cron@{{ item }}.service + +[Install] +WantedBy=timers.target diff --git a/roles/apps/nextcloud/templates/cron@.service.j2 b/roles/apps/nextcloud/templates/cron@.service.j2 new file mode 100644 index 00000000..822f64b4 --- /dev/null +++ b/roles/apps/nextcloud/templates/cron@.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Nextcloud cron.php job for %i + +[Service] +Type=oneshot +ExecStart={{ 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/apps/nextcloud/templates/nextcloud-occ.j2 b/roles/apps/nextcloud/templates/nextcloud-occ.j2 new file mode 100755 index 00000000..a79c5335 --- /dev/null +++ b/roles/apps/nextcloud/templates/nextcloud-occ.j2 @@ -0,0 +1,22 @@ +#!/bin/bash + +INST_NAME="$1" +shift + +if [ -z "$INST_NAME" ]; then + echo "Usage: $0 <instance> [ <arguments for occ.php> ... ]" + exit 1 +fi + +set -eu +{% if kubernetes_cri_socket is defined %} +export CONTAINER_RUNTIME_ENDPOINT="{{ kubernetes_cri_socket }}" +{% endif %} + +pod_id=$(crictl pods -q --state ready --name "$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/apps/nextcloud/templates/nextcloud-upgrade.j2 b/roles/apps/nextcloud/templates/nextcloud-upgrade.j2 new file mode 100755 index 00000000..aac5001f --- /dev/null +++ b/roles/apps/nextcloud/templates/nextcloud-upgrade.j2 @@ -0,0 +1,42 @@ +#!/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_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 + +echo "*** Pre-Pulling the image" +echo "" +ctr -n k8s.io image pull "docker.io/library/nextcloud:$VERSION" +echo "" + +echo "*** Patching manifest file" +echo "" +sed "s#image: \"nextcloud:.*\"#image: \"nextcloud:$VERSION\"#" "$K8S_MANIFEST_FILE" > "$TMP_D/upgraded.yml" +set +e +diff -u "$K8S_MANIFEST_FILE" "$TMP_D/upgraded.yml" +if [ $? -eq 0 ]; then + echo "patching file failed?" + exit 2 +fi +cat "$TMP_D/upgraded.yml" > "$K8S_MANIFEST_FILE" +echo "" + +exit 0 diff --git a/roles/apps/nextcloud/templates/pod-with-mariadb.yml.j2 b/roles/apps/nextcloud/templates/pod-with-mariadb.yml.j2 new file mode 100644 index 00000000..dfef3810 --- /dev/null +++ b/roles/apps/nextcloud/templates/pod-with-mariadb.yml.j2 @@ -0,0 +1,81 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "nextcloud-{{ item.key }}" +spec: + securityContext: + allowPrivilegeEscalation: false + containers: + - name: nextcloud + image: "nextcloud:{{ item.value.version }}" + securityContext: + runAsUser: {{ nextcloud_app_uid }} + runAsGroup: {{ nextcloud_app_gid }} + resources: + limits: + memory: "4Gi" +{% if 'new' in item.value and item.value.new %} + env: + - name: NEXTCLOUD_TRUSTED_DOMAINS + value: "{{ item.value.hostnames | join(' ') }}" + - name: MYSQL_HOST + value: 127.0.0.1 + - name: MYSQL_DATABASE + value: nextcloud + - name: MYSQL_USER + value: nextcloud + - name: MYSQL_PASSWORD + value: "{{ item.value.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: {{ item.value.port }} + - name: database + image: "mariadb:{{ item.value.database.version }}" + args: + - --transaction-isolation=READ-COMMITTED + - --binlog-format=ROW + securityContext: + runAsUser: {{ nextcloud_db_uid }} + runAsGroup: {{ nextcloud_db_gid }} + resources: + limits: + memory: "2Gi" +{% if 'new' in item.value and item.value.new %} + env: + - name: MYSQL_RANDOM_ROOT_PASSWORD + value: "true" + - name: MYSQL_DATABASE + value: nextcloud + - name: MYSQL_USER + value: nextcloud + - name: MYSQL_PASSWORD + value: "{{ item.value.database.password }}" +{% endif %} + volumeMounts: + - name: database + mountPath: /var/lib/mysql + volumes: + - name: config + hostPath: + path: "{{ nextcloud_base_path }}/{{ item.key }}/config/" + type: Directory + - name: nextcloud + hostPath: + path: "{{ nextcloud_base_path }}/{{ item.key }}/nextcloud" + type: Directory + - name: database + hostPath: + path: "{{ nextcloud_base_path }}/{{ item.key }}/{{ item.value.database.type }}" + type: Directory diff --git a/roles/apps/nextcloud/templates/run-cron.sh.j2 b/roles/apps/nextcloud/templates/run-cron.sh.j2 new file mode 100644 index 00000000..9936bad1 --- /dev/null +++ b/roles/apps/nextcloud/templates/run-cron.sh.j2 @@ -0,0 +1,11 @@ +#!/bin/bash + +{% if kubernetes_cri_socket is defined %} +export CONTAINER_RUNTIME_ENDPOINT="{{ kubernetes_cri_socket }}" +{% endif %} + +POD_NAME="{{ item }}-$(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 |