These were broken since 2016:f0367da7d1since StartLimitIntervalSec got moved into [Unit] from [Service]. StartLimitBurst has also been moved accordingly, so let's fix that one too. NixOS systems have been producing logs such as: /nix/store/wf98r55aszi1bkmln1lvdbp7znsfr70i-unit-caddy.service/caddy.service:31: Unknown key name 'StartLimitIntervalSec' in section 'Service', ignoring. I have also removed some unnecessary duplication in units disabling rate limiting since setting either interval or burst to zero disables it (ad16158c10/src/basic/ratelimit.c (L16))
		
			
				
	
	
		
			172 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
 | 
						|
let
 | 
						|
  cfg = config.services.hardware.lcd;
 | 
						|
  pkg = lib.getBin pkgs.lcdproc;
 | 
						|
 | 
						|
  serverCfg = pkgs.writeText "lcdd.conf" ''
 | 
						|
    [server]
 | 
						|
    DriverPath=${pkg}/lib/lcdproc/
 | 
						|
    ReportToSyslog=false
 | 
						|
    Bind=${cfg.serverHost}
 | 
						|
    Port=${toString cfg.serverPort}
 | 
						|
    ${cfg.server.extraConfig}
 | 
						|
  '';
 | 
						|
 | 
						|
  clientCfg = pkgs.writeText "lcdproc.conf" ''
 | 
						|
    [lcdproc]
 | 
						|
    Server=${cfg.serverHost}
 | 
						|
    Port=${toString cfg.serverPort}
 | 
						|
    ReportToSyslog=false
 | 
						|
    ${cfg.client.extraConfig}
 | 
						|
  '';
 | 
						|
 | 
						|
  serviceCfg = {
 | 
						|
    DynamicUser = true;
 | 
						|
    Restart = "on-failure";
 | 
						|
    Slice = "lcd.slice";
 | 
						|
  };
 | 
						|
 | 
						|
in with lib; {
 | 
						|
 | 
						|
  meta.maintainers = with maintainers; [ peterhoeg ];
 | 
						|
 | 
						|
  options = with types; {
 | 
						|
    services.hardware.lcd = {
 | 
						|
      serverHost = mkOption {
 | 
						|
        type = str;
 | 
						|
        default = "localhost";
 | 
						|
        description = "Host on which LCDd is listening.";
 | 
						|
      };
 | 
						|
 | 
						|
      serverPort = mkOption {
 | 
						|
        type = int;
 | 
						|
        default = 13666;
 | 
						|
        description = "Port on which LCDd is listening.";
 | 
						|
      };
 | 
						|
 | 
						|
      server = {
 | 
						|
        enable = mkOption {
 | 
						|
          type = bool;
 | 
						|
          default = false;
 | 
						|
          description = "Enable the LCD panel server (LCDd)";
 | 
						|
        };
 | 
						|
 | 
						|
        openPorts = mkOption {
 | 
						|
          type = bool;
 | 
						|
          default = false;
 | 
						|
          description = "Open the ports in the firewall";
 | 
						|
        };
 | 
						|
 | 
						|
        usbPermissions = mkOption {
 | 
						|
          type = bool;
 | 
						|
          default = false;
 | 
						|
          description = ''
 | 
						|
            Set group-write permissions on a USB device.
 | 
						|
            </para>
 | 
						|
            <para>
 | 
						|
            A USB connected LCD panel will most likely require having its
 | 
						|
            permissions modified for lcdd to write to it. Enabling this option
 | 
						|
            sets group-write permissions on the device identified by
 | 
						|
            <option>services.hardware.lcd.usbVid</option> and
 | 
						|
            <option>services.hardware.lcd.usbPid</option>. In order to find the
 | 
						|
            values, you can run the <command>lsusb</command> command. Example
 | 
						|
            output:
 | 
						|
            </para>
 | 
						|
            <para>
 | 
						|
            <literal>
 | 
						|
            Bus 005 Device 002: ID 0403:c630 Future Technology Devices International, Ltd lcd2usb interface
 | 
						|
            </literal>
 | 
						|
            </para>
 | 
						|
            <para>
 | 
						|
            In this case the vendor id is 0403 and the product id is c630.
 | 
						|
          '';
 | 
						|
        };
 | 
						|
 | 
						|
        usbVid = mkOption {
 | 
						|
          type = str;
 | 
						|
          default = "";
 | 
						|
          description = "The vendor ID of the USB device to claim.";
 | 
						|
        };
 | 
						|
 | 
						|
        usbPid = mkOption {
 | 
						|
          type = str;
 | 
						|
          default = "";
 | 
						|
          description = "The product ID of the USB device to claim.";
 | 
						|
        };
 | 
						|
 | 
						|
        usbGroup = mkOption {
 | 
						|
          type = str;
 | 
						|
          default = "dialout";
 | 
						|
          description = "The group to use for settings permissions. This group must exist or you will have to create it.";
 | 
						|
        };
 | 
						|
 | 
						|
        extraConfig = mkOption {
 | 
						|
          type = lines;
 | 
						|
          default = "";
 | 
						|
          description = "Additional configuration added verbatim to the server config.";
 | 
						|
        };
 | 
						|
      };
 | 
						|
 | 
						|
      client = {
 | 
						|
        enable = mkOption {
 | 
						|
          type = bool;
 | 
						|
          default = false;
 | 
						|
          description = "Enable the LCD panel client (LCDproc)";
 | 
						|
        };
 | 
						|
 | 
						|
        extraConfig = mkOption {
 | 
						|
          type = lines;
 | 
						|
          default = "";
 | 
						|
          description = "Additional configuration added verbatim to the client config.";
 | 
						|
        };
 | 
						|
 | 
						|
        restartForever = mkOption {
 | 
						|
          type = bool;
 | 
						|
          default = true;
 | 
						|
          description = "Try restarting the client forever.";
 | 
						|
        };
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  config = mkIf (cfg.server.enable || cfg.client.enable) {
 | 
						|
    networking.firewall.allowedTCPPorts = mkIf (cfg.server.enable && cfg.server.openPorts) [ cfg.serverPort ];
 | 
						|
 | 
						|
    services.udev.extraRules = mkIf (cfg.server.enable && cfg.server.usbPermissions) ''
 | 
						|
      ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="${cfg.server.usbVid}", ATTRS{idProduct}=="${cfg.server.usbPid}", MODE="660", GROUP="${cfg.server.usbGroup}"
 | 
						|
    '';
 | 
						|
 | 
						|
    systemd.services = {
 | 
						|
      lcdd = mkIf cfg.server.enable {
 | 
						|
        description = "LCDproc - server";
 | 
						|
        wantedBy = [ "lcd.target" ];
 | 
						|
        serviceConfig = serviceCfg // {
 | 
						|
          ExecStart = "${pkg}/bin/LCDd -f -c ${serverCfg}";
 | 
						|
          SupplementaryGroups = cfg.server.usbGroup;
 | 
						|
        };
 | 
						|
      };
 | 
						|
 | 
						|
      lcdproc = mkIf cfg.client.enable {
 | 
						|
        description = "LCDproc - client";
 | 
						|
        after = [ "lcdd.service" ];
 | 
						|
        wantedBy = [ "lcd.target" ];
 | 
						|
        # Allow restarting for eternity
 | 
						|
        startLimitIntervalSec = lib.mkIf cfg.client.restartForever 0;
 | 
						|
        serviceConfig = serviceCfg // {
 | 
						|
          ExecStart = "${pkg}/bin/lcdproc -f -c ${clientCfg}";
 | 
						|
          # If the server is being restarted at the same time, the client will
 | 
						|
          # fail as it cannot connect, so space it out a bit.
 | 
						|
          RestartSec = "5";
 | 
						|
        };
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    systemd.targets.lcd = {
 | 
						|
      description = "LCD client/server";
 | 
						|
      after = [ "lcdd.service" "lcdproc.service" ];
 | 
						|
      wantedBy = [ "multi-user.target" ];
 | 
						|
    };
 | 
						|
  };
 | 
						|
}
 |