#!/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())