#!/usr/bin/env python3 import argparse import os import re import subprocess from pathlib import Path, PurePath 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"]) 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 ValueError( "first arg 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 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) 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__": main()