From a8145a2edf53d330ab952c52011c7d7509023657 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Sachse?= <joerg.sachse@slub-dresden.de>
Date: Wed, 4 Oct 2023 11:17:02 +0200
Subject: [PATCH] feat: implement DisApp maintenance window timers to
 accommodate ZIH maintenance windows and prevent read access

---
 tasks/install_subapp.yml                      | 34 +++++++++++++++++
 .../disapp_maintenance_begin.service.j2       | 38 +++++++++++++++++++
 .../system/disapp_maintenance_begin.timer.j2  | 11 ++++++
 .../system/disapp_maintenance_end.timer.j2    | 11 ++++++
 4 files changed, 94 insertions(+)
 create mode 100644 templates/usr/local/lib/systemd/system/disapp_maintenance_begin.service.j2
 create mode 100644 templates/usr/local/lib/systemd/system/disapp_maintenance_begin.timer.j2
 create mode 100644 templates/usr/local/lib/systemd/system/disapp_maintenance_end.timer.j2

diff --git a/tasks/install_subapp.yml b/tasks/install_subapp.yml
index f6bccb4..4243fcf 100644
--- a/tasks/install_subapp.yml
+++ b/tasks/install_subapp.yml
@@ -206,6 +206,40 @@
       owner: "{{ vault_subapp_user }}"
       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.
+- name: create directory for SystemD units
+  ansible.builtin.file:
+    path: "/usr/local/lib/systemd/system/"
+    mode: "0755"
+    state: directory
+    owner: "root"
+    group: "root"
+- name: install DisApp maintenance services and timers
+  ansible.builtin.template:
+    src: "usr/local/lib/systemd/system/{{ item }}.j2"
+    dest: "/usr/local/lib/systemd/system/{{ item }}"
+    mode: "0644"
+    owner: "root"
+    group: "root"
+  loop:
+    - "disapp_maintenance_begin.service"
+    - "disapp_maintenance_begin.timer"
+    - "disapp_maintenance_end.timer"
+- name: enable DisApp maintenance services and timers
+  ansible.builtin.systemd:
+    name: "{{ item.name }}"
+    enabled: "{{ item.enabled | default(true) }}"
+    state: "{{ item.state | default('started') }}"
+    daemon_reload: true
+  loop:
+    - name: "disapp_maintenance_begin.service"
+      state: "stopped"
+    - name: "disapp_maintenance_begin.timer"
+    - name: "disapp_maintenance_end.timer"
+
 ################################################
 
 - name: disable check_ie_sample Service
diff --git a/templates/usr/local/lib/systemd/system/disapp_maintenance_begin.service.j2 b/templates/usr/local/lib/systemd/system/disapp_maintenance_begin.service.j2
new file mode 100644
index 0000000..9060c3e
--- /dev/null
+++ b/templates/usr/local/lib/systemd/system/disapp_maintenance_begin.service.j2
@@ -0,0 +1,38 @@
+[Unit]
+Description=stop DisApp for monthly maintenance at ZIH
+After=remote-fs.target
+
+[Service]
+Type=simple
+Restart=no
+Environment="PERL5LIB=/usr/local/perl/"
+ExecStart=/usr/bin/perl -I /usr/local/perl/ /usr/local/bin/disapp_rosetta.pl \
+          --config-file /home/access/.disapp/disapp.cfg \
+          --stop
+User={{ vault_disapp_user }}
+Group={{ vault_disapp_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/disapp_maintenance_begin.timer.j2 b/templates/usr/local/lib/systemd/system/disapp_maintenance_begin.timer.j2
new file mode 100644
index 0000000..2e1ee38
--- /dev/null
+++ b/templates/usr/local/lib/systemd/system/disapp_maintenance_begin.timer.j2
@@ -0,0 +1,11 @@
+[Unit]
+Description=timer for disapp_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=disapp_maintenance_begin
+
+[Install]
+WantedBy=default.target
diff --git a/templates/usr/local/lib/systemd/system/disapp_maintenance_end.timer.j2 b/templates/usr/local/lib/systemd/system/disapp_maintenance_end.timer.j2
new file mode 100644
index 0000000..f2534ca
--- /dev/null
+++ b/templates/usr/local/lib/systemd/system/disapp_maintenance_end.timer.j2
@@ -0,0 +1,11 @@
+[Unit]
+Description=timer for disapp_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 11:00:00
+Unit=disapp.service
+
+[Install]
+WantedBy=default.target
-- 
GitLab