New `modules/printing-scanning.nix` exposes `local.printing.*` and `local.scanning.*` (CUPS drivers, SANE with a Canon BJNP `bjnpHosts` escape hatch, shared Avahi mDNS), all off by default so a consumer opts in and a server gets none of it. Imported from `modules/nixos.nix`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
81 lines
2.9 KiB
Nix
81 lines
2.9 KiB
Nix
# Printing and scanning, opt-in and off by default. Both are network-facing
|
|
# (CUPS, and mDNS discovery for WiFi devices), so a consumer that doesn't want
|
|
# them — a server, a hardened host — simply leaves the flags off and gets none
|
|
# of it: no avahi, no open firewall, no cups. Nothing to override.
|
|
#
|
|
# Printers take vendor drivers (the `drivers` option, never hard-coded).
|
|
# Scanners are driverless by default via sane-airscan (eSCL/WSD); the one
|
|
# exception is Canon's BJNP protocol, whose hosts are listed in `bjnpHosts`.
|
|
# Avahi (mDNS) is shared by both and comes up when either is enabled, so WiFi
|
|
# devices are discoverable.
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
cfg = config.local;
|
|
netDiscovery = cfg.printing.enable || cfg.scanning.enable;
|
|
in
|
|
{
|
|
options.local = {
|
|
printing = {
|
|
enable = lib.mkEnableOption "CUPS printing (WiFi/driverless-friendly)";
|
|
drivers = lib.mkOption {
|
|
type = lib.types.listOf lib.types.package;
|
|
default = [ ];
|
|
example = lib.literalExpression "[ pkgs.gutenprint ]";
|
|
description = "Extra CUPS driver packages (vendor/model specific).";
|
|
};
|
|
};
|
|
scanning = {
|
|
enable =
|
|
lib.mkEnableOption "SANE scanning with driverless network scanners (sane-airscan)";
|
|
bjnpHosts = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
default = [ ];
|
|
example = lib.literalExpression ''[ "bjnp://192.168.1.50" ]'';
|
|
description = ''
|
|
Network scanners reachable over Canon's BJNP protocol, registered
|
|
with SANE's `pixma` backend (written to `/etc/sane.d/pixma.conf`).
|
|
BJNP is not driverless eSCL/WSD, so `sane-airscan` can't see these;
|
|
and BJNP broadcast auto-discovery is usually dropped by the firewall,
|
|
so list each device's `bjnp://<ip>` explicitly.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkMerge [
|
|
(lib.mkIf cfg.printing.enable {
|
|
services.printing = {
|
|
enable = true;
|
|
drivers = cfg.printing.drivers;
|
|
};
|
|
})
|
|
|
|
# sane-airscan = driverless eSCL/WSD; hardware.sane also creates the
|
|
# `scanner` group + udev rules. Group membership is per-user → inventory.
|
|
# A pixma.conf built the same way the module builds net.conf (a text file
|
|
# dropped at /etc/sane.d/, merged by mkSaneConfig) registers BJNP hosts.
|
|
(lib.mkIf cfg.scanning.enable {
|
|
hardware.sane = {
|
|
enable = true;
|
|
extraBackends = [ pkgs.sane-airscan ]
|
|
++ lib.optional (cfg.scanning.bjnpHosts != [ ]) (pkgs.writeTextFile {
|
|
name = "sane-pixma-net-conf";
|
|
destination = "/etc/sane.d/pixma.conf";
|
|
text = lib.concatMapStrings (h: h + "\n") cfg.scanning.bjnpHosts;
|
|
});
|
|
};
|
|
})
|
|
|
|
# mDNS so CUPS/SANE can discover WiFi printers and scanners on the LAN.
|
|
(lib.mkIf netDiscovery {
|
|
services.avahi = {
|
|
enable = true;
|
|
nssmdns4 = true;
|
|
openFirewall = true;
|
|
};
|
|
})
|
|
];
|
|
}
|