From 0d003ee5ca82e1abd3f684cb33d41b9294c26dc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Sachse?= <joerg.sachse@slub-dresden.de>
Date: Thu, 4 Apr 2024 10:38:17 +0200
Subject: [PATCH] feat: automate maintenance shutdown of SubApp (issue #2297)

---
 tasks/install_subapp.yml                      | 18 +++++++---
 .../subapp_maintenance_begin.service.j2       | 36 +++++++++++++++++++
 .../system/subapp_maintenance_begin.timer.j2  | 11 ++++++
 .../system/subapp_maintenance_end.timer.j2    | 11 ++++++
 4 files changed, 71 insertions(+), 5 deletions(-)
 create mode 100644 templates/usr/local/lib/systemd/system/subapp_maintenance_begin.service.j2
 create mode 100644 templates/usr/local/lib/systemd/system/subapp_maintenance_begin.timer.j2
 create mode 100644 templates/usr/local/lib/systemd/system/subapp_maintenance_end.timer.j2

diff --git a/tasks/install_subapp.yml b/tasks/install_subapp.yml
index 84a2b05..4ff8b49 100644
--- a/tasks/install_subapp.yml
+++ b/tasks/install_subapp.yml
@@ -249,9 +249,10 @@
       group: "{{ vault_subapp_group }}"
 
 # ZIH has monthly maintenance windows for their VMware environment, which also
-# affects the Library Manager VMs used by SLUBArchiv.digital. To make sure
-# there is no read access during that time, we shutdown the DisApp and start it
-# afterwards using systemd timers.
+# affects the Library Manager VMs used by SLUBArchiv.digital. This time window
+# is also used for upgrading the OS and IBM packages on the storage servers. To
+# make sure that there is no write/read access during that time, we shutdown
+# the DisApp and SubApp and start them afterwards using systemd timers.
 - name: create directory for SystemD units
   ansible.builtin.file:
     path: "/usr/local/lib/systemd/system/"
@@ -259,7 +260,7 @@
     state: directory
     owner: "root"
     group: "root"
-- name: install DisApp maintenance services and timers
+- name: install SubApp/DisApp maintenance services and timers
   ansible.builtin.template:
     src: "usr/local/lib/systemd/system/{{ item }}.j2"
     dest: "/usr/local/lib/systemd/system/{{ item }}"
@@ -270,7 +271,10 @@
     - "disapp_maintenance_begin.service"
     - "disapp_maintenance_begin.timer"
     - "disapp_maintenance_end.timer"
-- name: enable DisApp maintenance services and timers
+    - "subapp_maintenance_begin.service"
+    - "subapp_maintenance_begin.timer"
+    - "subapp_maintenance_end.timer"
+- name: enable SubApp/DisApp maintenance services and timers
   ansible.builtin.systemd:
     name: "{{ item.name }}"
     enabled: "{{ item.enabled | default(true) }}"
@@ -281,3 +285,7 @@
       state: "stopped"
     - name: "disapp_maintenance_begin.timer"
     - name: "disapp_maintenance_end.timer"
+    - name: "subapp_maintenance_begin.service"
+      state: "stopped"
+    - name: "subapp_maintenance_begin.timer"
+    - name: "subapp_maintenance_end.timer"
diff --git a/templates/usr/local/lib/systemd/system/subapp_maintenance_begin.service.j2 b/templates/usr/local/lib/systemd/system/subapp_maintenance_begin.service.j2
new file mode 100644
index 0000000..acb62c9
--- /dev/null
+++ b/templates/usr/local/lib/systemd/system/subapp_maintenance_begin.service.j2
@@ -0,0 +1,36 @@
+[Unit]
+Description=stop SubApp for monthly maintenance at ZIH
+After=remote-fs.target
+Conflicts=subapp.service
+
+[Service]
+Type=simple
+Restart=no
+ExecStart=true
+User={{ vault_subapp_user }}
+Group={{ vault_subapp_group }}
+
+### Security features
+# documented at https://www.freedesktop.org/software/systemd/man/systemd.exec.html
+# or at `man (5) systemd.exec`
+ProtectSystem=strict
+ProtectHome=read-only
+ProtectHostname=true
+ProtectClock=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+LockPersonality=true
+MemoryDenyWriteExecute=true
+RestrictRealtime=true
+#RestrictSUIDSGID=true
+## RemoveIPC=true
+## PrivateMounts=true
+## MountFlags=
+## SystemCallFilter is a Whitelist!!!
+#SystemCallFilter=@debug,@file-system
+#SystemCallErrorNumber=1337
+
+[Install]
+WantedBy=multi-user.target
diff --git a/templates/usr/local/lib/systemd/system/subapp_maintenance_begin.timer.j2 b/templates/usr/local/lib/systemd/system/subapp_maintenance_begin.timer.j2
new file mode 100644
index 0000000..d86f73e
--- /dev/null
+++ b/templates/usr/local/lib/systemd/system/subapp_maintenance_begin.timer.j2
@@ -0,0 +1,11 @@
+[Unit]
+Description=timer for subapp_maintenance.service
+
+[Timer]
+# run on the 1st Tuesday of each month
+# You can validate your calendar expressions using `systemd-analyze calendar EXPR`.
+OnCalendar=Tue *-*-01..07 08:00:00
+Unit=subapp_maintenance_begin
+
+[Install]
+WantedBy=default.target
diff --git a/templates/usr/local/lib/systemd/system/subapp_maintenance_end.timer.j2 b/templates/usr/local/lib/systemd/system/subapp_maintenance_end.timer.j2
new file mode 100644
index 0000000..d86f73e
--- /dev/null
+++ b/templates/usr/local/lib/systemd/system/subapp_maintenance_end.timer.j2
@@ -0,0 +1,11 @@
+[Unit]
+Description=timer for subapp_maintenance.service
+
+[Timer]
+# run on the 1st Tuesday of each month
+# You can validate your calendar expressions using `systemd-analyze calendar EXPR`.
+OnCalendar=Tue *-*-01..07 08:00:00
+Unit=subapp_maintenance_begin
+
+[Install]
+WantedBy=default.target
-- 
GitLab