main
  1{
  2  libx,
  3  ...
  4}:
  5let
  6  # Aix's local IP for DNS resolution
  7  aixLocalIP = "192.168.1.75";
  8
  9  # Common rsync configuration for aion sync
 10  aionSyncDefaults = {
 11    source = {
 12      host = "aion.sbr.pm";
 13      user = "vincent";
 14    };
 15    destination = "/data";
 16    delete = true; # Mirror mode: delete files in destination that don't exist in source
 17    user = "vincent";
 18    group = "users";
 19    rsyncArgs = [
 20      "--exclude=.Trash-*"
 21      "--exclude=lost+found"
 22      "--exclude=.stfolder"
 23    ];
 24    sshArgs = [
 25      "-o StrictHostKeyChecking=accept-new"
 26    ];
 27  };
 28in
 29{
 30  imports = [
 31    ../common/services/samba.nix
 32
 33  ];
 34
 35  networking.firewall.enable = false;
 36
 37  services = {
 38    # Rsync data from aion to aix for local network access
 39    rsync-replica = {
 40      enable = true;
 41      jobs = {
 42        # Sync all data daily
 43        aion-daily = aionSyncDefaults // {
 44          source = aionSyncDefaults.source // {
 45            paths = [
 46              "/neo/music"
 47              "/neo/pictures"
 48              "/neo/ebooks"
 49              "/neo/audiobooks"
 50            ];
 51          };
 52          schedule = "daily";
 53        };
 54      };
 55    };
 56
 57    samba.settings = {
 58      global."server string" = "Aix";
 59      vincent =
 60        (libx.mkSambaShare {
 61          name = "vincent";
 62          path = "/data/share";
 63        })
 64        // {
 65          "guest ok" = "no";
 66          public = "no";
 67        };
 68      music =
 69        (libx.mkSambaShare {
 70          name = "music";
 71          path = "/data/music";
 72          readOnly = true;
 73        })
 74        // {
 75          "guest ok" = "no";
 76          public = "no";
 77        };
 78      ebooks =
 79        (libx.mkSambaShare {
 80          name = "ebooks";
 81          path = "/data/ebooks";
 82          readOnly = true;
 83        })
 84        // {
 85          "guest ok" = "no";
 86          public = "no";
 87        };
 88      audiobooks =
 89        (libx.mkSambaShare {
 90          name = "audiobooks";
 91          path = "/data/audiobooks";
 92          readOnly = true;
 93        })
 94        // {
 95          "guest ok" = "no";
 96          public = "no";
 97        };
 98    };
 99
100    # DNS resolver for local network - resolve specific sbr.pm domains to Aix
101    dnsmasq = {
102      enable = true;
103      settings = {
104        # Listen on local network interface
105        interface = "end0";
106        bind-dynamic = true;
107
108        # DNS settings
109        domain-needed = true;
110        bogus-priv = true;
111
112        # Resolve specific media service domains to Aix (which will reverse proxy)
113        address = [
114          "/music.sbr.pm/${aixLocalIP}"
115          "/navidrome.sbr.pm/${aixLocalIP}"
116          "/jellyfin.sbr.pm/${aixLocalIP}"
117          "/podcasts.sbr.pm/${aixLocalIP}"
118          "/audiobookshelf.sbr.pm/${aixLocalIP}"
119          "/immich.sbr.pm/${aixLocalIP}"
120          "/transmission.sbr.pm/${aixLocalIP}"
121          "/transmission-music.sbr.pm/${aixLocalIP}"
122          "/t.sbr.pm/${aixLocalIP}"
123          "/tm.sbr.pm/${aixLocalIP}"
124        ];
125
126        # Use upstream DNS for other queries
127        server = [
128          "1.1.1.1"
129          "8.8.8.8"
130        ];
131
132        # Cache settings
133        cache-size = 1000;
134      };
135    };
136
137  };
138}