at 17.09-beta 4.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 pkg = if config.hardware.sane.snapshot 8 then pkgs.sane-backends-git 9 else pkgs.sane-backends; 10 11 sanedConf = pkgs.writeTextFile { 12 name = "saned.conf"; 13 destination = "/etc/sane.d/saned.conf"; 14 text = '' 15 localhost 16 ${config.services.saned.extraConfig} 17 ''; 18 }; 19 20 netConf = pkgs.writeTextFile { 21 name = "net.conf"; 22 destination = "/etc/sane.d/net.conf"; 23 text = '' 24 ${lib.optionalString config.services.saned.enable "localhost"} 25 ${config.hardware.sane.netConf} 26 ''; 27 }; 28 29 env = { 30 SANE_CONFIG_DIR = config.hardware.sane.configDir; 31 LD_LIBRARY_PATH = [ "${saneConfig}/lib/sane" ]; 32 }; 33 34 backends = [ pkg netConf ] ++ optional config.services.saned.enable sanedConf ++ config.hardware.sane.extraBackends; 35 saneConfig = pkgs.mkSaneConfig { paths = backends; }; 36 37 enabled = config.hardware.sane.enable || config.services.saned.enable; 38 39in 40 41{ 42 43 ###### interface 44 45 options = { 46 47 hardware.sane.enable = mkOption { 48 type = types.bool; 49 default = false; 50 description = '' 51 Enable support for SANE scanners. 52 53 <note><para> 54 Users in the "scanner" group will gain access to the scanner, or the "lp" group if it's also a printer. 55 </para></note> 56 ''; 57 }; 58 59 hardware.sane.snapshot = mkOption { 60 type = types.bool; 61 default = false; 62 description = "Use a development snapshot of SANE scanner drivers."; 63 }; 64 65 hardware.sane.extraBackends = mkOption { 66 type = types.listOf types.path; 67 default = []; 68 description = '' 69 Packages providing extra SANE backends to enable. 70 71 <note><para> 72 The example contains the package for HP scanners. 73 </para></note> 74 ''; 75 example = literalExample "[ pkgs.hplipWithPlugin ]"; 76 }; 77 78 hardware.sane.configDir = mkOption { 79 type = types.string; 80 internal = true; 81 description = "The value of SANE_CONFIG_DIR."; 82 }; 83 84 hardware.sane.netConf = mkOption { 85 type = types.lines; 86 default = ""; 87 example = "192.168.0.16"; 88 description = '' 89 Network hosts that should be probed for remote scanners. 90 ''; 91 }; 92 93 services.saned.enable = mkOption { 94 type = types.bool; 95 default = false; 96 description = '' 97 Enable saned network daemon for remote connection to scanners. 98 99 saned would be runned from <literal>scanner</literal> user; to allow 100 access to hardware that doesn't have <literal>scanner</literal> group 101 you should add needed groups to this user. 102 ''; 103 }; 104 105 services.saned.extraConfig = mkOption { 106 type = types.lines; 107 default = ""; 108 example = "192.168.0.0/24"; 109 description = '' 110 Extra saned configuration lines. 111 ''; 112 }; 113 114 }; 115 116 117 ###### implementation 118 119 config = mkMerge [ 120 (mkIf enabled { 121 hardware.sane.configDir = mkDefault "${saneConfig}/etc/sane.d"; 122 123 environment.systemPackages = backends; 124 environment.sessionVariables = env; 125 services.udev.packages = backends; 126 127 users.extraGroups."scanner".gid = config.ids.gids.scanner; 128 }) 129 130 (mkIf config.services.saned.enable { 131 networking.firewall.connectionTrackingModules = [ "sane" ]; 132 133 systemd.services."saned@" = { 134 description = "Scanner Service"; 135 environment = mapAttrs (name: val: toString val) env; 136 serviceConfig = { 137 User = "scanner"; 138 Group = "scanner"; 139 ExecStart = "${pkg}/bin/saned"; 140 }; 141 }; 142 143 systemd.sockets.saned = { 144 description = "saned incoming socket"; 145 wantedBy = [ "sockets.target" ]; 146 listenStreams = [ "0.0.0.0:6566" "[::]:6566" ]; 147 socketConfig = { 148 # saned needs to distinguish between IPv4 and IPv6 to open matching data sockets. 149 BindIPv6Only = "ipv6-only"; 150 Accept = true; 151 MaxConnections = 1; 152 }; 153 }; 154 155 users.extraUsers."scanner" = { 156 uid = config.ids.uids.scanner; 157 group = "scanner"; 158 }; 159 }) 160 ]; 161 162}