diff --git a/crossmnt b/crossmnt new file mode 100755 index 0000000..81ac1fe --- /dev/null +++ b/crossmnt @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +""" +Add crossmnt to TrueNAS NFS exports for child dataset visibility. + +Usage: fix-nfs-crossmnt.py /mnt/pool/dataset + +Setup: + 1. scp fix-nfs-crossmnt.py root@truenas.local:/root/ + 2. chmod +x /root/fix-nfs-crossmnt.py + 3. Test: /root/fix-nfs-crossmnt.py /mnt/pool/dataset + 4. Add cron job: TrueNAS UI > System > Advanced > Cron Jobs + Command: /root/fix-nfs-crossmnt.py /mnt/pool/dataset + Schedule: */5 * * * * +""" + +import re +import subprocess +import sys +from pathlib import Path + +EXPORTS_FILE = Path("/etc/exports") + + +def main(): + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} /mnt/pool/dataset", file=sys.stderr) + return 1 + + export_path = sys.argv[1] + content = EXPORTS_FILE.read_text() + + if f'"{export_path}"' not in content: + print(f"ERROR: {export_path} not found in {EXPORTS_FILE}", file=sys.stderr) + return 1 + + lines = content.splitlines() + result = [] + in_block = False + modified = False + + for line in lines: + if f'"{export_path}"' in line: + in_block = True + elif line.startswith('"'): + in_block = False + + if in_block and line[:1] in (" ", "\t") and "crossmnt" not in line: + line = re.sub(r"\)(\\\s*)?$", r",crossmnt)\1", line) + modified = True + + result.append(line) + + if not modified: + return 0 # Already applied + + EXPORTS_FILE.write_text("\n".join(result) + "\n") + subprocess.run(["exportfs", "-ra"], check=True) + print(f"Added crossmnt to {export_path}") + return 0 + + +if __name__ == "__main__": + sys.exit(main())