summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis M. Hoffmann <jannis@fehcom.de>2024-11-07 21:16:38 +0100
committerJannis M. Hoffmann <jannis@fehcom.de>2024-11-07 21:16:38 +0100
commited9d952d882ce8313dc4cb5049ca352f5b90a0c4 (patch)
tree357c79ccc15ba73f24cb0767cb1587320f87b104
parentddfda699615e1ab75290e74a1ff543dc37b3dde3 (diff)
improve install script and systemd-sysusers support
-rw-r--r--script/install.py160
-rw-r--r--script/jwebmail.conf.in1
2 files changed, 142 insertions, 19 deletions
diff --git a/script/install.py b/script/install.py
index 64a8f7b..86501d1 100644
--- a/script/install.py
+++ b/script/install.py
@@ -1,33 +1,155 @@
#!/usr/bin/env python3
+import argparse
+import os
import re
-import sys
-from pathlib import Path
+import subprocess
+from pathlib import Path, PurePath
-def install_service_unit(prefix):
- project_path = Path(__file__).parents[1]
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--destdir", default="/", type=Path)
+ ap.add_argument("--confdir", type=PurePath)
+ ap.add_argument("--statedir", type=PurePath)
+ ap.add_argument("--bindir", type=PurePath)
+ ap.add_argument("--datadir", type=PurePath)
+ ap.add_argument("--unitdir", type=PurePath)
+ ap.add_argument("--sysusersdir", type=PurePath)
+ ap.add_argument("--is-systemd", action="store_true", default=None)
+ ap.add_argument("--no-run", action="store_true")
+ ap.add_argument("prefix", choices=["home", "system", "usr", "usr/local"])
- if prefix == "usr":
- install_path = Path("/etc/systemd/system")
- elif prefix == "usr/local":
- install_path = Path("/usr/local/lib/systemd/system")
+ vals = ap.parse_args()
+
+ if not vals.destdir.is_absolute():
+ raise ValueError(f"destdir={destdir} must be absolute")
+
+ if vals.is_systemd is None:
+ vals.is_systemd = "systemd" in str(Path("/sbin/init").resolve())
+
+ conf = vars(vals)
+ for key, val in list(conf.items()):
+ if val is None:
+ del conf[key]
+
+ if vals.prefix == "home":
+ user = os.env["USER"]
+ confdir = conf.setdefault("confdir", PurePath(f"home/{user}/.config/jwebmail"))
+ statedir = conf.setdefault(
+ "statedir", PurePath(f"home/{user}/.local/state/jwebmail")
+ )
+ bindir = conf.setdefault("bindir", PurePath(f"home/{user}/.local/bin"))
+ datadir = conf.setdefault(
+ "datadir", PurePath(f"home/{user}/.local/share/jwebmail")
+ )
+ unitdir = conf.setdefault(
+ "unitdir", PurePath(f"home/{user}/.config/systemd/user")
+ )
+ sysusersdir = None
+
+ (vals.destdir / confdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir).mkdir(0o700, exist_ok=True)
+ (vals.destdir / datadir).mkdir(0o755, exist_ok=True)
+ elif vals.prefix == "system":
+ confdir = conf.setdefault("confdir", PurePath("etc/jwebmail"))
+ statedir = conf.setdefault("statedir", PurePath("var/jwebmail"))
+ bindir = conf.setdefault("bindir", PurePath("usr/bin"))
+ datadir = conf.setdefault("datadir", PurePath("usr/share/jwebmail"))
+ unitdir = conf.setdefault("unitdir", PurePath("etc/systemd/system"))
+ sysusersdir = conf.setdefault("sysusersdir", PurePath("etc/sysusers.d"))
+
+ (vals.destdir / confdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir.parent).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir).mkdir(0o750, exist_ok=True)
+ (vals.destdir / datadir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / unitdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / sysusersdir).mkdir(0o755, exist_ok=True, parents=True)
+ elif vals.prefix == "usr":
+ confdir = conf.setdefault("confdir", PurePath("etc/jwebmail"))
+ statedir = conf.setdefault("statedir", PurePath("var/lib/jwebmail"))
+ bindir = conf.setdefault("bindir", PurePath("usr/bin"))
+ datadir = conf.setdefault("datadir", PurePath("usr/share/jwebmail"))
+ unitdir = conf.setdefault("unitdir", PurePath("usr/lib/systemd/system"))
+ sysusersdir = conf.setdefault("sysusersdir", PurePath("usr/lib/sysusers.d"))
+
+ (vals.destdir / confdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir.parent).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir).mkdir(0o750, exist_ok=True)
+ (vals.destdir / datadir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / unitdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / sysusersdir).mkdir(0o755, exist_ok=True, parents=True)
+ elif vals.prefix == "usr/local":
+ confdir = conf.setdefault("confdir", PurePath("usr/local/etc/jwebmail"))
+ statedir = conf.setdefault("statedir", PurePath("var/local/lib/jwebmail"))
+ bindir = conf.setdefault("bindir", PurePath("usr/local/bin"))
+ datadir = conf.setdefault("datadir", PurePath("usr/local/share/jwebmail"))
+ unitdir = conf.setdefault("unitdir", PurePath("usr/local/lib/systemd/system"))
+ sysusersdir = conf.setdefault(
+ "sysusersdir", PurePath("usr/local/lib/sysusers.d")
+ )
+
+ (vals.destdir / confdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir.parent).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / statedir).mkdir(0o750, exist_ok=True)
+ (vals.destdir / datadir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / unitdir).mkdir(0o755, exist_ok=True, parents=True)
+ (vals.destdir / sysusersdir).mkdir(0o755, exist_ok=True, parents=True)
else:
- raise Exception("first arg <prefix> must be one of `usr` or `usr/local`")
+ raise ValueError(
+ "first arg <prefix> must be one of `home`, `system`, `usr` or `usr/local`"
+ )
+
+ try:
+ if vals.is_systemd:
+ install_service_unit(
+ "script/jwebmail.service.in",
+ vals.destdir / unitdir,
+ str(vals.destdir / confdir),
+ str(vals.destdir / bindir),
+ vals.no_run,
+ )
+
+ if vals.is_systemd and vals.prefix != "home":
+ install_jwebmail_user(
+ "script/jwebmail.conf.in",
+ vals.destdir / sysusersdir,
+ str(vals.destdir / statedir),
+ vals.no_run,
+ )
+ except subprocess.CalledProcessError:
+ os.exit("A command failed to execute. Is systemd installed? Try running with `--no-run`.")
+
+
+def substitute_file(in_file, out_path, variables):
+ in_file_content = open(in_file).read()
+ out_file_content = re.sub(
+ r"@(\w+)@", lambda match: variables[match[1]], in_file_content, flags=re.ASCII
+ )
+ open(out_path / Path(in_file).name.removesuffix(".in"), mode="w").write(
+ out_file_content
+ )
- def substitute(match):
- if match[1] == "PROJECT_PATH":
- return str(project_path)
- else:
- raise KeyError(match[1])
- service_text_in = open(project_path / "script" / "jwebmail.service.in").read()
- service_text = re.sub(r"@(\w+)@", substitute, service_text_in, flags=re.ASCII)
+def install_jwebmail_user(in_file, out_path, statedir, no_run):
+ substitute_file(
+ in_file,
+ out_path,
+ dict(STATEDIR=statedir),
+ )
+ if not no_run:
+ subprocess.run("systemd-sysusers", check=True)
- install_path.mkdir(0o755, True, True)
- open(install_path / "jwebmail.service", mode="w").write(service_text)
+def install_service_unit(in_file, out_path, confdir, bindir):
+ substitute_file(
+ in_file,
+ out_path,
+ dict(CONFDIR=confdir, BINDIR=bindir),
+ )
+ if not no_run:
+ subprocess.run(["systemctl", "daemon-reload"], check=True)
if __name__ == "__main__":
- install_service_unit(sys.argv[1] if len(sys.argv) == 2 else "")
+ main()
diff --git a/script/jwebmail.conf.in b/script/jwebmail.conf.in
new file mode 100644
index 0000000..f5580af
--- /dev/null
+++ b/script/jwebmail.conf.in
@@ -0,0 +1 @@
+u jwebmail - "greetd greeter user" @STATEDIR@