Merge branch 'master' into staging-next

This commit is contained in:
Vladimír Čunát
2019-09-04 11:00:56 +02:00
217 changed files with 7332 additions and 2071 deletions
+133
View File
@@ -0,0 +1,133 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.hardware.openrazer;
kernelPackages = config.boot.kernelPackages;
toPyBoolStr = b: if b then "True" else "False";
daemonExe = "${pkgs.openrazer-daemon}/bin/openrazer-daemon --config ${daemonConfFile}";
daemonConfFile = pkgs.writeTextFile {
name = "razer.conf";
text = ''
[General]
verbose_logging = ${toPyBoolStr cfg.verboseLogging}
[Startup]
sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled}
devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver}
mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier}
[Statistics]
key_statistics = ${toPyBoolStr cfg.keyStatistics}
'';
};
dbusServiceFile = pkgs.writeTextFile rec {
name = "org.razer.service";
destination = "/share/dbus-1/services/${name}";
text = ''
[D-BUS Service]
Name=org.razer
Exec=${daemonExe}
SystemdService=openrazer-daemon.service
'';
};
drivers = [
"razerkbd"
"razermouse"
"razerfirefly"
"razerkraken"
"razermug"
"razercore"
];
in
{
options = {
hardware.openrazer = {
enable = mkEnableOption "OpenRazer drivers and userspace daemon.";
verboseLogging = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable verbose logging. Logs debug messages.
'';
};
syncEffectsEnabled = mkOption {
type = types.bool;
default = true;
description = ''
Set the sync effects flag to true so any assignment of
effects will work across devices.
'';
};
devicesOffOnScreensaver = mkOption {
type = types.bool;
default = true;
description = ''
Turn off the devices when the systems screensaver kicks in.
'';
};
mouseBatteryNotifier = mkOption {
type = types.bool;
default = true;
description = ''
Mouse battery notifier.
'';
};
keyStatistics = mkOption {
type = types.bool;
default = false;
description = ''
Collects number of keypresses per hour per key used to
generate a heatmap.
'';
};
};
};
config = mkIf cfg.enable {
boot.extraModulePackages = [ kernelPackages.openrazer ];
boot.kernelModules = drivers;
# Makes the man pages available so you can succesfully run
# > systemctl --user help openrazer-daemon
environment.systemPackages = [ pkgs.python3Packages.openrazer-daemon.man ];
services.udev.packages = [ kernelPackages.openrazer ];
services.dbus.packages = [ dbusServiceFile ];
# A user must be a member of the plugdev group in order to start
# the openrazer-daemon. Therefore we make sure that the plugdev
# group exists.
users.groups.plugdev = {};
systemd.user.services.openrazer-daemon = {
description = "Daemon to manage razer devices in userspace";
unitConfig.Documentation = "man:openrazer-daemon(8)";
# Requires a graphical session so the daemon knows when the screensaver
# starts. See the 'devicesOffOnScreensaver' option.
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig = {
Type = "dbus";
BusName = "org.razer";
ExecStart = "${daemonExe} --foreground";
Restart = "always";
};
};
};
meta = {
maintainers = with lib.maintainers; [ roelvandijk ];
};
}
+135
View File
@@ -0,0 +1,135 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.hardware.printers;
ppdOptionsString = options: optionalString (options != {})
(concatStringsSep " "
(mapAttrsToList (name: value: "-o '${name}'='${value}'") options)
);
ensurePrinter = p: ''
${pkgs.cups}/bin/lpadmin -p '${p.name}' -E \
${optionalString (p.location != null) "-L '${p.location}'"} \
${optionalString (p.description != null) "-D '${p.description}'"} \
-v '${p.deviceUri}' \
-m '${p.model}' \
${ppdOptionsString p.ppdOptions}
'';
ensureDefaultPrinter = name: ''
${pkgs.cups}/bin/lpoptions -d '${name}'
'';
# "graph but not # or /" can't be implemented as regex alone due to missing lookahead support
noInvalidChars = str: all (c: c != "#" && c != "/") (stringToCharacters str);
printerName = (types.addCheck (types.strMatching "[[:graph:]]+") noInvalidChars)
// { description = "printable string without spaces, # and /"; };
in {
options = {
hardware.printers = {
ensureDefaultPrinter = mkOption {
type = types.nullOr printerName;
default = null;
description = ''
Ensures the named printer is the default CUPS printer / printer queue.
'';
};
ensurePrinters = mkOption {
description = ''
Will regularly ensure that the given CUPS printers are configured as declared here.
If a printer's options are manually changed afterwards, they will be overwritten eventually.
This option will never delete any printer, even if removed from this list.
You can check existing printers with <command>lpstat -s</command>
and remove printers with <command>lpadmin -x &lt;printer-name&gt;</command>.
Printers not listed here can still be manually configured.
'';
default = [];
type = types.listOf (types.submodule {
options = {
name = mkOption {
type = printerName;
example = "BrotherHL_Workroom";
description = ''
Name of the printer / printer queue.
May contain any printable characters except "/", "#", and space.
'';
};
location = mkOption {
type = types.nullOr types.str;
default = null;
example = "Workroom";
description = ''
Optional human-readable location.
'';
};
description = mkOption {
type = types.nullOr types.str;
default = null;
example = "Brother HL-5140";
description = ''
Optional human-readable description.
'';
};
deviceUri = mkOption {
type = types.str;
example = [
"ipp://printserver.local/printers/BrotherHL_Workroom"
"usb://HP/DESKJET%20940C?serial=CN16E6C364BH"
];
description = ''
How to reach the printer.
<command>lpinfo -v</command> shows a list of supported device URIs and schemes.
'';
};
model = mkOption {
type = types.str;
example = literalExample ''
gutenprint.''${lib.version.majorMinor (lib.getVersion pkgs.cups)}://brother-hl-5140/expert
'';
description = ''
Location of the ppd driver file for the printer.
<command>lpinfo -m</command> shows a list of supported models.
'';
};
ppdOptions = mkOption {
type = types.attrsOf types.str;
example = {
"PageSize" = "A4";
"Duplex" = "DuplexNoTumble";
};
default = {};
description = ''
Sets PPD options for the printer.
<command>lpoptions [-p printername] -l</command> shows suported PPD options for the given printer.
'';
};
};
});
};
};
};
config = mkIf (cfg.ensurePrinters != [] && config.services.printing.enable) {
systemd.services."ensure-printers" = let
cupsUnit = if config.services.printing.startWhenNeeded then "cups.socket" else "cups.service";
in {
description = "Ensure NixOS-configured CUPS printers";
wantedBy = [ "multi-user.target" ];
requires = [ cupsUnit ];
# in contrast to cups.socket, for cups.service, this is actually not enough,
# as the cups service reports its activation before clients can actually interact with it.
# Because of this, commands like `lpinfo -v` will report a bad file descriptor
# due to the missing UNIX socket without sufficient sleep time.
after = [ cupsUnit ];
serviceConfig = {
Type = "oneshot";
};
# sleep 10 is required to wait until cups.service is actually initialized and has created its UNIX socket file
script = (optionalString (!config.services.printing.startWhenNeeded) "sleep 10\n")
+ (concatMapStringsSep "\n" ensurePrinter cfg.ensurePrinters)
+ optionalString (cfg.ensureDefaultPrinter != null) (ensureDefaultPrinter cfg.ensureDefaultPrinter);
};
};
}