From e328d1bb0fe0f08b2f993a5a933307b77ad95c29 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 25 Mar 2020 20:55:53 +0100 Subject: move some roles to app/ --- dan/sk-cloudia.yml | 6 +- roles/apps/collabora/code/defaults/main.yml | 11 ++ roles/apps/collabora/code/tasks/main.yml | 28 ++++ .../collabora/code/templates/nginx-vhost.conf.j2 | 108 +++++++++++++ roles/apps/collabora/code/templates/pod.yml.j2 | 33 ++++ roles/apps/etherpad-lite/defaults/main.yml | 29 ++++ roles/apps/etherpad-lite/tasks/main.yml | 117 ++++++++++++++ .../etherpad-lite/templates/nginx-vhost.conf.j2 | 57 +++++++ .../templates/pod-with-mariadb.yml.j2 | 53 +++++++ roles/apps/nextcloud/defaults/main.yml | 27 ++++ roles/apps/nextcloud/tasks/main.yml | 170 +++++++++++++++++++++ roles/apps/nextcloud/templates/apache-site.conf.j2 | 10 ++ roles/apps/nextcloud/templates/cron-.timer.j2 | 9 ++ roles/apps/nextcloud/templates/cron@.service.j2 | 15 ++ roles/apps/nextcloud/templates/nextcloud-occ.j2 | 22 +++ .../apps/nextcloud/templates/nextcloud-upgrade.j2 | 42 +++++ .../nextcloud/templates/pod-with-mariadb.yml.j2 | 81 ++++++++++ roles/apps/nextcloud/templates/run-cron.sh.j2 | 11 ++ roles/collabora/code/defaults/main.yml | 11 -- roles/collabora/code/tasks/main.yml | 28 ---- roles/collabora/code/templates/nginx-vhost.conf.j2 | 108 ------------- roles/collabora/code/templates/pod.yml.j2 | 33 ---- roles/etherpad-lite/defaults/main.yml | 29 ---- roles/etherpad-lite/tasks/main.yml | 117 -------------- roles/etherpad-lite/templates/nginx-vhost.conf.j2 | 57 ------- .../templates/pod-with-mariadb.yml.j2 | 53 ------- roles/nextcloud/defaults/main.yml | 27 ---- roles/nextcloud/tasks/main.yml | 170 --------------------- roles/nextcloud/templates/apache-site.conf.j2 | 10 -- roles/nextcloud/templates/cron-.timer.j2 | 9 -- roles/nextcloud/templates/cron@.service.j2 | 15 -- roles/nextcloud/templates/nextcloud-occ.j2 | 22 --- roles/nextcloud/templates/nextcloud-upgrade.j2 | 42 ----- roles/nextcloud/templates/pod-with-mariadb.yml.j2 | 81 ---------- roles/nextcloud/templates/run-cron.sh.j2 | 11 -- 35 files changed, 826 insertions(+), 826 deletions(-) create mode 100644 roles/apps/collabora/code/defaults/main.yml create mode 100644 roles/apps/collabora/code/tasks/main.yml create mode 100644 roles/apps/collabora/code/templates/nginx-vhost.conf.j2 create mode 100644 roles/apps/collabora/code/templates/pod.yml.j2 create mode 100644 roles/apps/etherpad-lite/defaults/main.yml create mode 100644 roles/apps/etherpad-lite/tasks/main.yml create mode 100644 roles/apps/etherpad-lite/templates/nginx-vhost.conf.j2 create mode 100644 roles/apps/etherpad-lite/templates/pod-with-mariadb.yml.j2 create mode 100644 roles/apps/nextcloud/defaults/main.yml create mode 100644 roles/apps/nextcloud/tasks/main.yml create mode 100644 roles/apps/nextcloud/templates/apache-site.conf.j2 create mode 100644 roles/apps/nextcloud/templates/cron-.timer.j2 create mode 100644 roles/apps/nextcloud/templates/cron@.service.j2 create mode 100755 roles/apps/nextcloud/templates/nextcloud-occ.j2 create mode 100755 roles/apps/nextcloud/templates/nextcloud-upgrade.j2 create mode 100644 roles/apps/nextcloud/templates/pod-with-mariadb.yml.j2 create mode 100644 roles/apps/nextcloud/templates/run-cron.sh.j2 delete mode 100644 roles/collabora/code/defaults/main.yml delete mode 100644 roles/collabora/code/tasks/main.yml delete mode 100644 roles/collabora/code/templates/nginx-vhost.conf.j2 delete mode 100644 roles/collabora/code/templates/pod.yml.j2 delete mode 100644 roles/etherpad-lite/defaults/main.yml delete mode 100644 roles/etherpad-lite/tasks/main.yml delete mode 100644 roles/etherpad-lite/templates/nginx-vhost.conf.j2 delete mode 100644 roles/etherpad-lite/templates/pod-with-mariadb.yml.j2 delete mode 100644 roles/nextcloud/defaults/main.yml delete mode 100644 roles/nextcloud/tasks/main.yml delete mode 100644 roles/nextcloud/templates/apache-site.conf.j2 delete mode 100644 roles/nextcloud/templates/cron-.timer.j2 delete mode 100644 roles/nextcloud/templates/cron@.service.j2 delete mode 100755 roles/nextcloud/templates/nextcloud-occ.j2 delete mode 100755 roles/nextcloud/templates/nextcloud-upgrade.j2 delete mode 100644 roles/nextcloud/templates/pod-with-mariadb.yml.j2 delete mode 100644 roles/nextcloud/templates/run-cron.sh.j2 diff --git a/dan/sk-cloudia.yml b/dan/sk-cloudia.yml index b83db411..c24d4a1e 100644 --- a/dan/sk-cloudia.yml +++ b/dan/sk-cloudia.yml @@ -12,6 +12,6 @@ - role: kubernetes/standalone - role: acmetool/base - role: nginx/base - - role: nextcloud - - role: collabora/code - - role: etherpad-lite + - role: apps/nextcloud + - role: apps/collabora/code + - role: apps/etherpad-lite diff --git a/roles/apps/collabora/code/defaults/main.yml b/roles/apps/collabora/code/defaults/main.yml new file mode 100644 index 00000000..f17054ed --- /dev/null +++ b/roles/apps/collabora/code/defaults/main.yml @@ -0,0 +1,11 @@ +--- +collabora_code_base_path: /srv/collabora/code + +# collabora_code_instances: +# example: +# version: 4.0.6.1 +# port: 8200 +# hostnames: +# - office.example.com +# admin_user: admin +# admin_password: S3cret diff --git a/roles/apps/collabora/code/tasks/main.yml b/roles/apps/collabora/code/tasks/main.yml new file mode 100644 index 00000000..ce88fe0d --- /dev/null +++ b/roles/apps/collabora/code/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: create collabora-code config subdirectory + loop: "{{ collabora_code_instances | list }}" + file: + path: "{{ collabora_code_base_path }}/{{ item }}/config" + state: directory + +## TODO: render config.xml + +- name: generate pod manifests + loop: "{{ collabora_code_instances | dict2items }}" + loop_control: + label: "{{ item.key }}" + template: + src: "pod.yml.j2" + dest: "/etc/kubernetes/manifests/collabora-code-{{ item.key }}.yml" + mode: 0600 + +- name: configure nginx vhost + loop: "{{ collabora_code_instances | dict2items }}" + include_role: + name: nginx/vhost + vars: + nginx_vhost: + name: "collabora-code-{{ item.key }}" + content: "{{ lookup('template', 'nginx-vhost.conf.j2') }}" + acme: true + hostnames: "{{ item.value.hostnames }}" diff --git a/roles/apps/collabora/code/templates/nginx-vhost.conf.j2 b/roles/apps/collabora/code/templates/nginx-vhost.conf.j2 new file mode 100644 index 00000000..cec811f9 --- /dev/null +++ b/roles/apps/collabora/code/templates/nginx-vhost.conf.j2 @@ -0,0 +1,108 @@ +server { + listen 80; + listen [::]:80; + server_name {{ item.value.hostnames | join(' ') }}; + + include snippets/acmetool.conf; + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{ item.value.hostnames | join(' ') }}; + + include snippets/acmetool.conf; + include snippets/tls.conf; + ssl_certificate /var/lib/acme/live/{{ item.value.hostnames[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ item.value.hostnames[0] }}/privkey; + include snippets/hsts.conf; + + + client_max_body_size 128M; + + # static files + location ^~ /loleaflet { + include snippets/proxy-nobuff.conf; + include snippets/proxy-forward-headers.conf; + + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:{{ item.value.port }}; + + proxy_redirect http://$host/ https://$host/; + proxy_redirect http://$host:9980/ https://$host/; + } + + # WOPI discovery URL + location ^~ /hosting/discovery { + include snippets/proxy-nobuff.conf; + include snippets/proxy-forward-headers.conf; + + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:{{ item.value.port }}; + + proxy_redirect http://$host/ https://$host/; + proxy_redirect http://$host:9980/ https://$host/; + } + + # Capabilities + location ^~ /hosting/capabilities { + include snippets/proxy-nobuff.conf; + include snippets/proxy-forward-headers.conf; + + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:{{ item.value.port }}; + + proxy_redirect http://$host/ https://$host/; + proxy_redirect http://$host:9980/ https://$host/; + } + + # main websocket + location ~ ^/lool/(.*)/ws$ { + include snippets/proxy-nobuff.conf; + include snippets/proxy-forward-headers.conf; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_read_timeout 36000s; + + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:{{ item.value.port }}; + + proxy_redirect http://$host/ https://$host/; + proxy_redirect http://$host:9980/ https://$host/; + } + + # download, presentation and image upload + location ~ ^/lool { + include snippets/proxy-nobuff.conf; + include snippets/proxy-forward-headers.conf; + + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:{{ item.value.port }}; + + proxy_redirect http://$host/ https://$host/; + proxy_redirect http://$host:9980/ https://$host/; + } + + # Admin Console websocket + location ^~ /lool/adminws { + include snippets/proxy-nobuff.conf; + include snippets/proxy-forward-headers.conf; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_read_timeout 36000s; + + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:{{ item.value.port }}; + + proxy_redirect http://$host/ https://$host/; + proxy_redirect http://$host:9980/ https://$host/; + } +} diff --git a/roles/apps/collabora/code/templates/pod.yml.j2 b/roles/apps/collabora/code/templates/pod.yml.j2 new file mode 100644 index 00000000..ee4651a1 --- /dev/null +++ b/roles/apps/collabora/code/templates/pod.yml.j2 @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "collabora-code-{{ item.key }}" +spec: + containers: + - name: collabora-code + image: "collabora/code:{{ item.value.version }}" + resources: + limits: + memory: "4Gi" + env: + - name: "DONT_GEN_SSL_CERT" + value: "1" + - name: "username" + value: "{{ item.value.admin_user }}" + - name: "password" + value: "{{ item.value.admin_password }}" + - name: "extra_params" + value: "--o:ssl.enable=false --o:ssl.termination=true" + volumeMounts: + - name: config + mountPath: /etc/loolwsd/loolwsd.xml + subPath: loolwsd.xml + readOnly: true + ports: + - containerPort: 9980 + hostPort: {{ item.value.port }} + volumes: + - name: config + hostPath: + path: "{{ collabora_code_base_path }}/{{ item.key }}/config/" + type: Directory diff --git a/roles/apps/etherpad-lite/defaults/main.yml b/roles/apps/etherpad-lite/defaults/main.yml new file mode 100644 index 00000000..5281c739 --- /dev/null +++ b/roles/apps/etherpad-lite/defaults/main.yml @@ -0,0 +1,29 @@ +--- +etherpad_lite_app_uid: "940" +etherpad_lite_app_gid: "940" + +etherpad_lite_db_uid: "941" +etherpad_lite_db_gid: "941" + +# etherpad_lite_base_path: /srv/etherpad_lite + +# etherpad_lite_zfs: +# pool: storage +# name: etherpad_lite +# size: 20G + +# etherpad_lite_instances: +# example: +# version: 1.7.5 +# port: 8300 +# hostnames: +# - pad.example.com +# quota: 40G +# settings: +# .... +# credentials: +# .... +# database: +# type: mariadb +# version: 10.4.8 +# password: "{{ vault_etherpad_lite_database_passwords['example'] }}" diff --git a/roles/apps/etherpad-lite/tasks/main.yml b/roles/apps/etherpad-lite/tasks/main.yml new file mode 100644 index 00000000..6d4551db --- /dev/null +++ b/roles/apps/etherpad-lite/tasks/main.yml @@ -0,0 +1,117 @@ +--- +- name: create zfs datasets + when: etherpad_lite_zfs is defined + block: + - name: create zfs base dataset + zfs: + name: "{{ etherpad_lite_zfs.pool }}/{{ etherpad_lite_zfs.name }}" + state: present + extra_zfs_properties: + quota: "{{ etherpad_lite_zfs.size }}" + + - name: create zfs volumes for instances + loop: "{{ etherpad_lite_instances | dict2items }}" + loop_control: + label: "{{ item.key }} ({{ item.value.quota }})" + zfs: + name: "{{ etherpad_lite_zfs.pool }}/{{ etherpad_lite_zfs.name }}/{{ item.key }}" + state: present + extra_zfs_properties: + quota: "{{ item.value.quota }}" + + - name: configure etherpad_lite base bath + set_fact: + etherpad_lite_base_path: "{{ zfs_zpools[etherpad_lite_zfs.pool].mountpoint }}/{{ etherpad_lite_zfs.name }}" + + +- name: create instance subdirectories + when: etherpad_lite_zfs is not defined + loop: "{{ etherpad_lite_instances | list }}" + file: + path: "{{ etherpad_lite_base_path }}/{{ item }}" + state: directory + + + +- name: add group for etherpad-lite app + group: + name: epl-app + gid: "{{ etherpad_lite_app_gid }}" + +- name: add user for etherpad-lite app + user: + name: epl-app + uid: "{{ etherpad_lite_app_uid }}" + group: epl-app + password: "!" + +- name: create etherpad_lite app subdirectory + loop: "{{ etherpad_lite_instances | list }}" + file: + path: "{{ etherpad_lite_base_path }}/{{ item }}/etherpad-lite" + owner: "{{ etherpad_lite_app_uid }}" + group: "{{ etherpad_lite_app_gid }}" + state: directory + + +- name: add group for etherpad-lite db + group: + name: epl-db + gid: "{{ etherpad_lite_db_gid }}" + +- name: add user for etherpad-lite db + user: + name: epl-db + uid: "{{ etherpad_lite_db_uid }}" + group: epl-db + password: "!" + +- name: create etherpad-lite database subdirectory + loop: "{{ etherpad_lite_instances | dict2items}}" + loop_control: + label: "{{ item.key }} ({{ item.value.database.type }})" + file: + path: "{{ etherpad_lite_base_path }}/{{ item.key }}/{{ item.value.database.type }}" + owner: "{{ etherpad_lite_db_uid }}" + group: "{{ etherpad_lite_db_gid }}" + state: directory + + +- name: create etherpad-lite config directory + loop: "{{ etherpad_lite_instances | list }}" + file: + path: "{{ etherpad_lite_base_path }}/{{ item }}/config" + state: directory + +- name: create settings json + loop: "{{ etherpad_lite_instances | dict2items }}" + loop_control: + label: "{{ item.key }}" + copy: + content: "{{ item.value.settings | combine({'ip': '0.0.0.0', 'port': 9001}) | to_nice_json }}" + dest: "{{ etherpad_lite_base_path }}/{{ item.key }}/config/settings.json" + mode: 0600 + owner: "{{ etherpad_lite_app_uid }}" + group: "{{ etherpad_lite_app_gid }}" + + +- name: generate pod manifests + loop: "{{ etherpad_lite_instances | dict2items }}" + loop_control: + label: "{{ item.key }}" + template: + src: "pod-with-{{ item.value.database.type }}.yml.j2" + dest: "/etc/kubernetes/manifests/etherpad-lite-{{ item.key }}.yml" + mode: 0600 + + +- name: configure nginx vhost + loop: "{{ etherpad_lite_instances | dict2items }}" + include_role: + name: nginx/vhost + vars: + nginx_vhost: + name: "etherpad-lite-{{ item.key }}" + content: "{{ lookup('template', 'nginx-vhost.conf.j2') }}" + acme: true + hostnames: "{{ item.value.hostnames }}" diff --git a/roles/apps/etherpad-lite/templates/nginx-vhost.conf.j2 b/roles/apps/etherpad-lite/templates/nginx-vhost.conf.j2 new file mode 100644 index 00000000..b59701fc --- /dev/null +++ b/roles/apps/etherpad-lite/templates/nginx-vhost.conf.j2 @@ -0,0 +1,57 @@ +server { + listen 80; + listen [::]:80; + server_name {{ item.value.hostnames | join(' ') }}; + + include snippets/acmetool.conf; + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name {{ item.value.hostnames | join(' ') }}; + + include snippets/acmetool.conf; + include snippets/tls.conf; + ssl_certificate /var/lib/acme/live/{{ item.value.hostnames[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ item.value.hostnames[0] }}/privkey; + include snippets/hsts.conf; + + location / { + rewrite ^/$ / break; + rewrite ^/locales/(.*) /locales/$1 break; + rewrite ^/locales.json /locales.json break; + rewrite ^/admin(.*) /admin$1 break; + rewrite ^/p/(.*) /p/$1 break; + rewrite ^/static/(.*) /static/$1 break; + rewrite ^/pluginfw/(.*) /pluginfw/$1 break; + rewrite ^/javascripts/(.*) /javascripts/$1 break; + rewrite ^/socket.io/(.*) /socket.io/$1 break; + rewrite ^/ep/(.*) /ep/$1 break; + rewrite ^/minified/(.*) /minified/$1 break; + rewrite ^/api/(.*) /api/$1 break; + rewrite ^/ro/(.*) /ro/$1 break; + rewrite ^/error/(.*) /error/$1 break; + rewrite ^/jserror(.*) /jserror$1 break; + rewrite ^/redirect(.*) /redirect$1 break; + rewrite /favicon.ico /favicon.ico break; + rewrite /robots.txt /robots.txt break; + rewrite /(.*) /p/$1; + + include snippets/proxy-nobuff.conf; + + proxy_set_header Host $host; + include snippets/proxy-forward-headers.conf; + proxy_pass_header Server; + + # for websockets + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_pass http://127.0.0.1:{{ item.value.port }}; + } +} diff --git a/roles/apps/etherpad-lite/templates/pod-with-mariadb.yml.j2 b/roles/apps/etherpad-lite/templates/pod-with-mariadb.yml.j2 new file mode 100644 index 00000000..a4acdd21 --- /dev/null +++ b/roles/apps/etherpad-lite/templates/pod-with-mariadb.yml.j2 @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "etherpad-lite-{{ item.key }}" +spec: + securityContext: + allowPrivilegeEscalation: false + containers: + - name: etherpad-lite + image: spreadspace/etherpad-lite:{{ item.value.version }} + # securityContext: + # runAsUser: {{ etherpad_lite_app_uid }} + # runAsGroup: {{ etherpad_lite_app_gid }} + resources: + limits: + memory: "4Gi" + volumeMounts: + - name: config + mountPath: /opt/etherpad-lite/settings.json + subPath: settings.json + readOnly: true + ports: + - containerPort: 9001 + hostPort: {{ item.value.port }} + - name: database + image: "mariadb:{{ item.value.database.version }}" + securityContext: + runAsUser: {{ etherpad_lite_db_uid }} + runAsGroup: {{ etherpad_lite_db_gid }} + resources: + limits: + memory: "4Gi" + env: + - name: MYSQL_RANDOM_ROOT_PASSWORD + value: "true" + - name: MYSQL_DATABASE + value: etherpad-lite + - name: MYSQL_USER + value: etherpad-lite + - name: MYSQL_PASSWORD + value: "{{ item.value.database.password }}" + volumeMounts: + - name: database + mountPath: /var/lib/mysql + volumes: + - name: config + hostPath: + path: "{{ etherpad_lite_base_path }}/{{ item.key }}/config/" + type: Directory + - name: database + hostPath: + path: "{{ etherpad_lite_base_path }}/{{ item.key }}/{{ item.value.database.type }}" + type: Directory 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 @@ + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html + + UseCanonicalName Off + UseCanonicalPhysicalPort Off + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + 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 [ ... ]" + 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 " + 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 diff --git a/roles/collabora/code/defaults/main.yml b/roles/collabora/code/defaults/main.yml deleted file mode 100644 index f17054ed..00000000 --- a/roles/collabora/code/defaults/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -collabora_code_base_path: /srv/collabora/code - -# collabora_code_instances: -# example: -# version: 4.0.6.1 -# port: 8200 -# hostnames: -# - office.example.com -# admin_user: admin -# admin_password: S3cret diff --git a/roles/collabora/code/tasks/main.yml b/roles/collabora/code/tasks/main.yml deleted file mode 100644 index ce88fe0d..00000000 --- a/roles/collabora/code/tasks/main.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: create collabora-code config subdirectory - loop: "{{ collabora_code_instances | list }}" - file: - path: "{{ collabora_code_base_path }}/{{ item }}/config" - state: directory - -## TODO: render config.xml - -- name: generate pod manifests - loop: "{{ collabora_code_instances | dict2items }}" - loop_control: - label: "{{ item.key }}" - template: - src: "pod.yml.j2" - dest: "/etc/kubernetes/manifests/collabora-code-{{ item.key }}.yml" - mode: 0600 - -- name: configure nginx vhost - loop: "{{ collabora_code_instances | dict2items }}" - include_role: - name: nginx/vhost - vars: - nginx_vhost: - name: "collabora-code-{{ item.key }}" - content: "{{ lookup('template', 'nginx-vhost.conf.j2') }}" - acme: true - hostnames: "{{ item.value.hostnames }}" diff --git a/roles/collabora/code/templates/nginx-vhost.conf.j2 b/roles/collabora/code/templates/nginx-vhost.conf.j2 deleted file mode 100644 index cec811f9..00000000 --- a/roles/collabora/code/templates/nginx-vhost.conf.j2 +++ /dev/null @@ -1,108 +0,0 @@ -server { - listen 80; - listen [::]:80; - server_name {{ item.value.hostnames | join(' ') }}; - - include snippets/acmetool.conf; - - location / { - return 301 https://$host$request_uri; - } -} - -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name {{ item.value.hostnames | join(' ') }}; - - include snippets/acmetool.conf; - include snippets/tls.conf; - ssl_certificate /var/lib/acme/live/{{ item.value.hostnames[0] }}/fullchain; - ssl_certificate_key /var/lib/acme/live/{{ item.value.hostnames[0] }}/privkey; - include snippets/hsts.conf; - - - client_max_body_size 128M; - - # static files - location ^~ /loleaflet { - include snippets/proxy-nobuff.conf; - include snippets/proxy-forward-headers.conf; - - proxy_set_header Host $http_host; - proxy_pass http://127.0.0.1:{{ item.value.port }}; - - proxy_redirect http://$host/ https://$host/; - proxy_redirect http://$host:9980/ https://$host/; - } - - # WOPI discovery URL - location ^~ /hosting/discovery { - include snippets/proxy-nobuff.conf; - include snippets/proxy-forward-headers.conf; - - proxy_set_header Host $http_host; - proxy_pass http://127.0.0.1:{{ item.value.port }}; - - proxy_redirect http://$host/ https://$host/; - proxy_redirect http://$host:9980/ https://$host/; - } - - # Capabilities - location ^~ /hosting/capabilities { - include snippets/proxy-nobuff.conf; - include snippets/proxy-forward-headers.conf; - - proxy_set_header Host $http_host; - proxy_pass http://127.0.0.1:{{ item.value.port }}; - - proxy_redirect http://$host/ https://$host/; - proxy_redirect http://$host:9980/ https://$host/; - } - - # main websocket - location ~ ^/lool/(.*)/ws$ { - include snippets/proxy-nobuff.conf; - include snippets/proxy-forward-headers.conf; - - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - - proxy_read_timeout 36000s; - - proxy_set_header Host $http_host; - proxy_pass http://127.0.0.1:{{ item.value.port }}; - - proxy_redirect http://$host/ https://$host/; - proxy_redirect http://$host:9980/ https://$host/; - } - - # download, presentation and image upload - location ~ ^/lool { - include snippets/proxy-nobuff.conf; - include snippets/proxy-forward-headers.conf; - - proxy_set_header Host $http_host; - proxy_pass http://127.0.0.1:{{ item.value.port }}; - - proxy_redirect http://$host/ https://$host/; - proxy_redirect http://$host:9980/ https://$host/; - } - - # Admin Console websocket - location ^~ /lool/adminws { - include snippets/proxy-nobuff.conf; - include snippets/proxy-forward-headers.conf; - - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - - proxy_read_timeout 36000s; - - proxy_set_header Host $http_host; - proxy_pass http://127.0.0.1:{{ item.value.port }}; - - proxy_redirect http://$host/ https://$host/; - proxy_redirect http://$host:9980/ https://$host/; - } -} diff --git a/roles/collabora/code/templates/pod.yml.j2 b/roles/collabora/code/templates/pod.yml.j2 deleted file mode 100644 index ee4651a1..00000000 --- a/roles/collabora/code/templates/pod.yml.j2 +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "collabora-code-{{ item.key }}" -spec: - containers: - - name: collabora-code - image: "collabora/code:{{ item.value.version }}" - resources: - limits: - memory: "4Gi" - env: - - name: "DONT_GEN_SSL_CERT" - value: "1" - - name: "username" - value: "{{ item.value.admin_user }}" - - name: "password" - value: "{{ item.value.admin_password }}" - - name: "extra_params" - value: "--o:ssl.enable=false --o:ssl.termination=true" - volumeMounts: - - name: config - mountPath: /etc/loolwsd/loolwsd.xml - subPath: loolwsd.xml - readOnly: true - ports: - - containerPort: 9980 - hostPort: {{ item.value.port }} - volumes: - - name: config - hostPath: - path: "{{ collabora_code_base_path }}/{{ item.key }}/config/" - type: Directory diff --git a/roles/etherpad-lite/defaults/main.yml b/roles/etherpad-lite/defaults/main.yml deleted file mode 100644 index 5281c739..00000000 --- a/roles/etherpad-lite/defaults/main.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -etherpad_lite_app_uid: "940" -etherpad_lite_app_gid: "940" - -etherpad_lite_db_uid: "941" -etherpad_lite_db_gid: "941" - -# etherpad_lite_base_path: /srv/etherpad_lite - -# etherpad_lite_zfs: -# pool: storage -# name: etherpad_lite -# size: 20G - -# etherpad_lite_instances: -# example: -# version: 1.7.5 -# port: 8300 -# hostnames: -# - pad.example.com -# quota: 40G -# settings: -# .... -# credentials: -# .... -# database: -# type: mariadb -# version: 10.4.8 -# password: "{{ vault_etherpad_lite_database_passwords['example'] }}" diff --git a/roles/etherpad-lite/tasks/main.yml b/roles/etherpad-lite/tasks/main.yml deleted file mode 100644 index 6d4551db..00000000 --- a/roles/etherpad-lite/tasks/main.yml +++ /dev/null @@ -1,117 +0,0 @@ ---- -- name: create zfs datasets - when: etherpad_lite_zfs is defined - block: - - name: create zfs base dataset - zfs: - name: "{{ etherpad_lite_zfs.pool }}/{{ etherpad_lite_zfs.name }}" - state: present - extra_zfs_properties: - quota: "{{ etherpad_lite_zfs.size }}" - - - name: create zfs volumes for instances - loop: "{{ etherpad_lite_instances | dict2items }}" - loop_control: - label: "{{ item.key }} ({{ item.value.quota }})" - zfs: - name: "{{ etherpad_lite_zfs.pool }}/{{ etherpad_lite_zfs.name }}/{{ item.key }}" - state: present - extra_zfs_properties: - quota: "{{ item.value.quota }}" - - - name: configure etherpad_lite base bath - set_fact: - etherpad_lite_base_path: "{{ zfs_zpools[etherpad_lite_zfs.pool].mountpoint }}/{{ etherpad_lite_zfs.name }}" - - -- name: create instance subdirectories - when: etherpad_lite_zfs is not defined - loop: "{{ etherpad_lite_instances | list }}" - file: - path: "{{ etherpad_lite_base_path }}/{{ item }}" - state: directory - - - -- name: add group for etherpad-lite app - group: - name: epl-app - gid: "{{ etherpad_lite_app_gid }}" - -- name: add user for etherpad-lite app - user: - name: epl-app - uid: "{{ etherpad_lite_app_uid }}" - group: epl-app - password: "!" - -- name: create etherpad_lite app subdirectory - loop: "{{ etherpad_lite_instances | list }}" - file: - path: "{{ etherpad_lite_base_path }}/{{ item }}/etherpad-lite" - owner: "{{ etherpad_lite_app_uid }}" - group: "{{ etherpad_lite_app_gid }}" - state: directory - - -- name: add group for etherpad-lite db - group: - name: epl-db - gid: "{{ etherpad_lite_db_gid }}" - -- name: add user for etherpad-lite db - user: - name: epl-db - uid: "{{ etherpad_lite_db_uid }}" - group: epl-db - password: "!" - -- name: create etherpad-lite database subdirectory - loop: "{{ etherpad_lite_instances | dict2items}}" - loop_control: - label: "{{ item.key }} ({{ item.value.database.type }})" - file: - path: "{{ etherpad_lite_base_path }}/{{ item.key }}/{{ item.value.database.type }}" - owner: "{{ etherpad_lite_db_uid }}" - group: "{{ etherpad_lite_db_gid }}" - state: directory - - -- name: create etherpad-lite config directory - loop: "{{ etherpad_lite_instances | list }}" - file: - path: "{{ etherpad_lite_base_path }}/{{ item }}/config" - state: directory - -- name: create settings json - loop: "{{ etherpad_lite_instances | dict2items }}" - loop_control: - label: "{{ item.key }}" - copy: - content: "{{ item.value.settings | combine({'ip': '0.0.0.0', 'port': 9001}) | to_nice_json }}" - dest: "{{ etherpad_lite_base_path }}/{{ item.key }}/config/settings.json" - mode: 0600 - owner: "{{ etherpad_lite_app_uid }}" - group: "{{ etherpad_lite_app_gid }}" - - -- name: generate pod manifests - loop: "{{ etherpad_lite_instances | dict2items }}" - loop_control: - label: "{{ item.key }}" - template: - src: "pod-with-{{ item.value.database.type }}.yml.j2" - dest: "/etc/kubernetes/manifests/etherpad-lite-{{ item.key }}.yml" - mode: 0600 - - -- name: configure nginx vhost - loop: "{{ etherpad_lite_instances | dict2items }}" - include_role: - name: nginx/vhost - vars: - nginx_vhost: - name: "etherpad-lite-{{ item.key }}" - content: "{{ lookup('template', 'nginx-vhost.conf.j2') }}" - acme: true - hostnames: "{{ item.value.hostnames }}" diff --git a/roles/etherpad-lite/templates/nginx-vhost.conf.j2 b/roles/etherpad-lite/templates/nginx-vhost.conf.j2 deleted file mode 100644 index b59701fc..00000000 --- a/roles/etherpad-lite/templates/nginx-vhost.conf.j2 +++ /dev/null @@ -1,57 +0,0 @@ -server { - listen 80; - listen [::]:80; - server_name {{ item.value.hostnames | join(' ') }}; - - include snippets/acmetool.conf; - - location / { - return 301 https://$host$request_uri; - } -} - -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name {{ item.value.hostnames | join(' ') }}; - - include snippets/acmetool.conf; - include snippets/tls.conf; - ssl_certificate /var/lib/acme/live/{{ item.value.hostnames[0] }}/fullchain; - ssl_certificate_key /var/lib/acme/live/{{ item.value.hostnames[0] }}/privkey; - include snippets/hsts.conf; - - location / { - rewrite ^/$ / break; - rewrite ^/locales/(.*) /locales/$1 break; - rewrite ^/locales.json /locales.json break; - rewrite ^/admin(.*) /admin$1 break; - rewrite ^/p/(.*) /p/$1 break; - rewrite ^/static/(.*) /static/$1 break; - rewrite ^/pluginfw/(.*) /pluginfw/$1 break; - rewrite ^/javascripts/(.*) /javascripts/$1 break; - rewrite ^/socket.io/(.*) /socket.io/$1 break; - rewrite ^/ep/(.*) /ep/$1 break; - rewrite ^/minified/(.*) /minified/$1 break; - rewrite ^/api/(.*) /api/$1 break; - rewrite ^/ro/(.*) /ro/$1 break; - rewrite ^/error/(.*) /error/$1 break; - rewrite ^/jserror(.*) /jserror$1 break; - rewrite ^/redirect(.*) /redirect$1 break; - rewrite /favicon.ico /favicon.ico break; - rewrite /robots.txt /robots.txt break; - rewrite /(.*) /p/$1; - - include snippets/proxy-nobuff.conf; - - proxy_set_header Host $host; - include snippets/proxy-forward-headers.conf; - proxy_pass_header Server; - - # for websockets - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - - proxy_pass http://127.0.0.1:{{ item.value.port }}; - } -} diff --git a/roles/etherpad-lite/templates/pod-with-mariadb.yml.j2 b/roles/etherpad-lite/templates/pod-with-mariadb.yml.j2 deleted file mode 100644 index a4acdd21..00000000 --- a/roles/etherpad-lite/templates/pod-with-mariadb.yml.j2 +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "etherpad-lite-{{ item.key }}" -spec: - securityContext: - allowPrivilegeEscalation: false - containers: - - name: etherpad-lite - image: spreadspace/etherpad-lite:{{ item.value.version }} - # securityContext: - # runAsUser: {{ etherpad_lite_app_uid }} - # runAsGroup: {{ etherpad_lite_app_gid }} - resources: - limits: - memory: "4Gi" - volumeMounts: - - name: config - mountPath: /opt/etherpad-lite/settings.json - subPath: settings.json - readOnly: true - ports: - - containerPort: 9001 - hostPort: {{ item.value.port }} - - name: database - image: "mariadb:{{ item.value.database.version }}" - securityContext: - runAsUser: {{ etherpad_lite_db_uid }} - runAsGroup: {{ etherpad_lite_db_gid }} - resources: - limits: - memory: "4Gi" - env: - - name: MYSQL_RANDOM_ROOT_PASSWORD - value: "true" - - name: MYSQL_DATABASE - value: etherpad-lite - - name: MYSQL_USER - value: etherpad-lite - - name: MYSQL_PASSWORD - value: "{{ item.value.database.password }}" - volumeMounts: - - name: database - mountPath: /var/lib/mysql - volumes: - - name: config - hostPath: - path: "{{ etherpad_lite_base_path }}/{{ item.key }}/config/" - type: Directory - - name: database - hostPath: - path: "{{ etherpad_lite_base_path }}/{{ item.key }}/{{ item.value.database.type }}" - type: Directory diff --git a/roles/nextcloud/defaults/main.yml b/roles/nextcloud/defaults/main.yml deleted file mode 100644 index 16637f44..00000000 --- a/roles/nextcloud/defaults/main.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -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/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml deleted file mode 100644 index a951867c..00000000 --- a/roles/nextcloud/tasks/main.yml +++ /dev/null @@ -1,170 +0,0 @@ ---- -- 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/nextcloud/templates/apache-site.conf.j2 b/roles/nextcloud/templates/apache-site.conf.j2 deleted file mode 100644 index a52a7fc5..00000000 --- a/roles/nextcloud/templates/apache-site.conf.j2 +++ /dev/null @@ -1,10 +0,0 @@ - - ServerAdmin webmaster@localhost - DocumentRoot /var/www/html - - UseCanonicalName Off - UseCanonicalPhysicalPort Off - - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - diff --git a/roles/nextcloud/templates/cron-.timer.j2 b/roles/nextcloud/templates/cron-.timer.j2 deleted file mode 100644 index 0c3f7cd7..00000000 --- a/roles/nextcloud/templates/cron-.timer.j2 +++ /dev/null @@ -1,9 +0,0 @@ -[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/nextcloud/templates/cron@.service.j2 b/roles/nextcloud/templates/cron@.service.j2 deleted file mode 100644 index 822f64b4..00000000 --- a/roles/nextcloud/templates/cron@.service.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[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/nextcloud/templates/nextcloud-occ.j2 b/roles/nextcloud/templates/nextcloud-occ.j2 deleted file mode 100755 index a79c5335..00000000 --- a/roles/nextcloud/templates/nextcloud-occ.j2 +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -INST_NAME="$1" -shift - -if [ -z "$INST_NAME" ]; then - echo "Usage: $0 [ ... ]" - 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/nextcloud/templates/nextcloud-upgrade.j2 b/roles/nextcloud/templates/nextcloud-upgrade.j2 deleted file mode 100755 index aac5001f..00000000 --- a/roles/nextcloud/templates/nextcloud-upgrade.j2 +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -INST_NAME="$1" -VERSION="$2" -if [ -z "$INST_NAME" ] || [ -z "$VERSION" ]; then - echo "Usage: $0 " - 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/nextcloud/templates/pod-with-mariadb.yml.j2 b/roles/nextcloud/templates/pod-with-mariadb.yml.j2 deleted file mode 100644 index dfef3810..00000000 --- a/roles/nextcloud/templates/pod-with-mariadb.yml.j2 +++ /dev/null @@ -1,81 +0,0 @@ -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/nextcloud/templates/run-cron.sh.j2 b/roles/nextcloud/templates/run-cron.sh.j2 deleted file mode 100644 index 9936bad1..00000000 --- a/roles/nextcloud/templates/run-cron.sh.j2 +++ /dev/null @@ -1,11 +0,0 @@ -#!/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 -- cgit v1.2.3