chore: Update inputs
This commit is contained in:
parent
efa99d6331
commit
49b169f473
4 changed files with 181 additions and 33 deletions
60
flake.lock
generated
60
flake.lock
generated
|
|
@ -10,11 +10,11 @@
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1747575206,
|
"lastModified": 1750173260,
|
||||||
"narHash": "sha256-NwmAFuDUO/PFcgaGGr4j3ozG9Pe5hZ/ogitWhY+D81k=",
|
"narHash": "sha256-9P1FziAwl5+3edkfFcr5HeGtQUtrSdk/MksX39GieoA=",
|
||||||
"owner": "ryantm",
|
"owner": "ryantm",
|
||||||
"repo": "agenix",
|
"repo": "agenix",
|
||||||
"rev": "4835b1dc898959d8547a871ef484930675cb47f1",
|
"rev": "531beac616433bac6f9e2a19feb8e99a22a66baf",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -68,11 +68,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749436314,
|
"lastModified": 1751607816,
|
||||||
"narHash": "sha256-CqmqU5FRg5AadtIkxwu8ulDSOSoIisUMZRLlcED3Q5w=",
|
"narHash": "sha256-5PtrwjqCIJ4DKQhzYdm8RFePBuwb+yTzjV52wWoGSt4=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "dfa4d1b9c39c0342ef133795127a3af14598017a",
|
"rev": "da6109c917b48abc1f76dd5c9bf3901c8c80f662",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -165,11 +165,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1742649964,
|
"lastModified": 1749636823,
|
||||||
"narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=",
|
"narHash": "sha256-WUaIlOlPLyPgz9be7fqWJA5iG6rHcGRtLERSCfUDne4=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82",
|
"rev": "623c56286de5a3193aa38891a6991b28f9bab056",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -249,11 +249,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749628652,
|
"lastModified": 1751760902,
|
||||||
"narHash": "sha256-f8jDF4G9m7pPySeQc6KskqMgtcJq6X1o2CytMx66qAE=",
|
"narHash": "sha256-qBGNn7T/zOgUDQTo/RM/D2oxMkB2x36j3ajvpVanEVs=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "450f06ec3cd0d86f67db58a7245db8848773e895",
|
"rev": "8b0180dde1d6f4cf632e046309e8f963924dfbd0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -334,11 +334,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749285348,
|
"lastModified": 1751637120,
|
||||||
"narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
|
"narHash": "sha256-xVNy/XopSfIG9c46nRmPaKfH1Gn/56vQ8++xWA8itO4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
|
"rev": "5c724ed1388e53cc231ed98330a60eb2f7be4be3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -350,11 +350,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-25_05": {
|
"nixpkgs-25_05": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1747610100,
|
"lastModified": 1749727998,
|
||||||
"narHash": "sha256-rpR5ZPMkWzcnCcYYo3lScqfuzEw5Uyfh+R0EKZfroAc=",
|
"narHash": "sha256-mHv/yeUbmL91/TvV95p+mBVahm9mdQMJoqaTVTALaFw=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ca49c4304acf0973078db0a9d200fd2bae75676d",
|
"rev": "fd487183437963a59ba763c0cc4f27e3447dd6dd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -414,11 +414,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1747179050,
|
"lastModified": 1749285348,
|
||||||
"narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=",
|
"narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e",
|
"rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -491,11 +491,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749636823,
|
"lastModified": 1750779888,
|
||||||
"narHash": "sha256-WUaIlOlPLyPgz9be7fqWJA5iG6rHcGRtLERSCfUDne4=",
|
"narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "pre-commit-hooks.nix",
|
"repo": "pre-commit-hooks.nix",
|
||||||
"rev": "623c56286de5a3193aa38891a6991b28f9bab056",
|
"rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -543,11 +543,11 @@
|
||||||
"nixpkgs-25_05": "nixpkgs-25_05"
|
"nixpkgs-25_05": "nixpkgs-25_05"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749244584,
|
"lastModified": 1751772161,
|
||||||
"narHash": "sha256-BGmEptAyP2NrP4gX7VMYWo53h5e8r2iE/uo2+YPMcfo=",
|
"narHash": "sha256-CxekYKL+M4VGb1pQk7lVDRe1x3th/5Du2xq/X1nNors=",
|
||||||
"owner": "simple-nixos-mailserver",
|
"owner": "simple-nixos-mailserver",
|
||||||
"repo": "nixos-mailserver",
|
"repo": "nixos-mailserver",
|
||||||
"rev": "8b27add0883067e990bff4f847b6f7b6f53324b9",
|
"rev": "6004878dc6c1cb1c0cedd8c10a59d416c8dad9c9",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -559,11 +559,11 @@
|
||||||
},
|
},
|
||||||
"stable": {
|
"stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749488106,
|
"lastModified": 1751274312,
|
||||||
"narHash": "sha256-b9GIWdF/8jKpCC5JIMgDLZgwe8cEbty2fyTyo1eDFfI=",
|
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "8fe3e32e7f210522377c3bcff80931a3284ace6a",
|
"rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,7 @@ in
|
||||||
|
|
||||||
mailserver = {
|
mailserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
stateVersion = 1;
|
stateVersion = 3;
|
||||||
fqdn = "thrall.failco.de";
|
fqdn = "thrall.failco.de";
|
||||||
domains = [
|
domains = [
|
||||||
"failco.de"
|
"failco.de"
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,14 @@
|
||||||
keep-outputs = true;
|
keep-outputs = true;
|
||||||
keep-derivations = true;
|
keep-derivations = true;
|
||||||
|
|
||||||
trusted-substituters = [ "https://devenv.cachix.org" ];
|
trusted-substituters = [
|
||||||
trusted-public-keys = [ "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" ];
|
"https://devenv.cachix.org"
|
||||||
|
"https://nixcache.reflex-frp.org"
|
||||||
|
];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
|
||||||
|
"ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI="
|
||||||
|
];
|
||||||
trusted-users = [
|
trusted-users = [
|
||||||
"root"
|
"root"
|
||||||
"alex"
|
"alex"
|
||||||
|
|
|
||||||
142
scripts/nixos-mailserver-migration-03.py
Executable file
142
scripts/nixos-mailserver-migration-03.py
Executable file
|
|
@ -0,0 +1,142 @@
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i python3 -p python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
from enum import Enum
|
||||||
|
from pathlib import Path
|
||||||
|
from pwd import getpwnam
|
||||||
|
|
||||||
|
|
||||||
|
class FolderLayout(Enum):
|
||||||
|
Default = 1
|
||||||
|
Folder = 2
|
||||||
|
|
||||||
|
|
||||||
|
def check_user(vmail_root: Path):
|
||||||
|
owner = vmail_root.owner()
|
||||||
|
owner_uid = getpwnam(owner).pw_uid
|
||||||
|
|
||||||
|
if os.geteuid() == owner_uid:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(
|
||||||
|
f"Trying to switch effective user id to {owner_uid} ({owner})",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
os.seteuid(owner_uid)
|
||||||
|
return
|
||||||
|
except PermissionError:
|
||||||
|
print(
|
||||||
|
f"Failed switching to virtual mail user. Please run this script under it, for example by using `sudo -u {owner}`)",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def is_maildir_related(path: Path, layout: FolderLayout) -> bool:
|
||||||
|
if path.name in [
|
||||||
|
"subscriptions"
|
||||||
|
# https://doc.dovecot.org/2.3/admin_manual/mailbox_formats/maildir/#imap-uid-mapping
|
||||||
|
"dovecot-uidlist",
|
||||||
|
# https://doc.dovecot.org/2.3/admin_manual/mailbox_formats/maildir/#imap-keywords
|
||||||
|
"dovecot-keywords",
|
||||||
|
]:
|
||||||
|
return True
|
||||||
|
if not path.is_dir():
|
||||||
|
return False
|
||||||
|
if path.name in ["cur", "new", "tmp"]:
|
||||||
|
return True
|
||||||
|
if layout is FolderLayout.Default and path.name.startswith("."):
|
||||||
|
return True
|
||||||
|
if layout is FolderLayout.Folder:
|
||||||
|
if path.name in ["mail"]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def mkdir(dst: Path, dry_run: bool = True):
|
||||||
|
print(f'mkdir "{dst}"')
|
||||||
|
if not dry_run:
|
||||||
|
# u+rwx, setgid
|
||||||
|
dst.mkdir(mode=0o2700)
|
||||||
|
|
||||||
|
|
||||||
|
def move(src: Path, dst: Path, dry_run: bool = True):
|
||||||
|
print(f'mv "{src}" "{dst}"')
|
||||||
|
if not dry_run:
|
||||||
|
src.rename(dst)
|
||||||
|
|
||||||
|
|
||||||
|
def delete(dst: Path, dry_run: bool = True):
|
||||||
|
if not dst.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
if dst.is_dir():
|
||||||
|
print(f'rm --recursive "{dst}"')
|
||||||
|
if not dry_run:
|
||||||
|
shutil.rmtree(dst)
|
||||||
|
else:
|
||||||
|
print(f'rm "{dst}"')
|
||||||
|
if not dry_run:
|
||||||
|
dst.unlink()
|
||||||
|
|
||||||
|
|
||||||
|
def main(vmail_root: Path, layout: FolderLayout, dry_run: bool = True):
|
||||||
|
maildirs = {path.parent for path in vmail_root.glob("*/*/cur")}
|
||||||
|
maybe_delete = []
|
||||||
|
|
||||||
|
# The old maildir will be the new home directory
|
||||||
|
for homedir in maildirs:
|
||||||
|
maildir = homedir / "mail"
|
||||||
|
mkdir(maildir, dry_run)
|
||||||
|
|
||||||
|
for path in homedir.iterdir():
|
||||||
|
if is_maildir_related(path, layout):
|
||||||
|
move(path, maildir / path.name, dry_run)
|
||||||
|
else:
|
||||||
|
maybe_delete.append(path)
|
||||||
|
|
||||||
|
# Files that are part of the previous home directory, but now obsolete
|
||||||
|
for path in [
|
||||||
|
vmail_root / ".dovecot.lda-dupes",
|
||||||
|
vmail_root / ".dovecot.lda-dupes.locks",
|
||||||
|
]:
|
||||||
|
delete(path, dry_run)
|
||||||
|
|
||||||
|
# The remaining files are likely obsolete, but should still be checked with care
|
||||||
|
for path in maybe_delete:
|
||||||
|
print(f"# rm {str(path)}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="""
|
||||||
|
NixOS Mailserver Migration #3: Dovecot mail directory migration
|
||||||
|
(https://nixos-mailserver.readthedocs.io/en/latest/migrations.html#dovecot-mail-directory-migration)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"vmail_root", type=Path, help="Path to the `mailserver.mailDirectory`"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--layout",
|
||||||
|
choices=["default", "folder"],
|
||||||
|
required=True,
|
||||||
|
help="Folder layout: 'default' unless `mailserver.useFsLayout` was enabled, then'folder'",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--execute", action="store_true", help="Actually perform changes"
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
layout = FolderLayout.Default if args.layout == "default" else FolderLayout.Folder
|
||||||
|
|
||||||
|
check_user(args.vmail_root)
|
||||||
|
main(args.vmail_root, layout, not args.execute)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue