From 954e234b98341da130a0d5318ced8e756009a0e2 Mon Sep 17 00:00:00 2001 From: Peter Hoeg Date: Fri, 8 Nov 2019 13:47:13 +0800 Subject: [PATCH] nixos/haproxy: support hot-reload without dropping packets --- nixos/modules/misc/ids.nix | 4 +-- nixos/modules/services/networking/haproxy.nix | 36 ++++++++++--------- nixos/tests/haproxy.nix | 4 ++- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 3e8a5b07a5ed1c..a4db2c9d1d877b 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -128,7 +128,7 @@ tcpcryptd = 93; # tcpcryptd uses a hard-coded uid. We patch it in Nixpkgs to match this choice. firebird = 95; #keys = 96; # unused - haproxy = 97; + #haproxy = 97; # DynamicUser as of 2019-11-08 mongodb = 98; openldap = 99; #users = 100; # unused @@ -443,7 +443,7 @@ #tcpcryptd = 93; # unused firebird = 95; keys = 96; - haproxy = 97; + #haproxy = 97; # DynamicUser as of 2019-11-08 #mongodb = 98; # unused openldap = 99; munin = 102; diff --git a/nixos/modules/services/networking/haproxy.nix b/nixos/modules/services/networking/haproxy.nix index 0438d0bf8d8606..aff71e5e97daff 100644 --- a/nixos/modules/services/networking/haproxy.nix +++ b/nixos/modules/services/networking/haproxy.nix @@ -1,7 +1,16 @@ { config, lib, pkgs, ... }: + let cfg = config.services.haproxy; - haproxyCfg = pkgs.writeText "haproxy.conf" cfg.config; + + haproxyCfg = pkgs.writeText "haproxy.conf" '' + global + # needed for hot-reload to work without dropping packets in multi-worker mode + stats socket /run/haproxy/haproxy.sock mode 600 expose-fd listeners level user + + ${cfg.config} + ''; + in with lib; { @@ -25,9 +34,7 @@ with lib; haproxy.conf. ''; }; - }; - }; config = mkIf cfg.enable { @@ -42,21 +49,16 @@ with lib; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { - Type = "forking"; - PIDFile = "/run/haproxy.pid"; - ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -q -f ${haproxyCfg}"; - ExecStart = "${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /run/haproxy.pid"; - ExecReload = "-${pkgs.bash}/bin/bash -c \"exec ${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /run/haproxy.pid -sf $MAINPID\""; + DynamicUser = true; + Type = "notify"; + # when running the config test, don't be quiet so we can see what goes wrong + ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}"; + ExecStart = "${pkgs.haproxy}/sbin/haproxy -Ws -f ${haproxyCfg}"; + Restart = "on-failure"; + RuntimeDirectory = "haproxy"; + # needed in case we bind to port < 1024 + AmbientCapabilities = "CAP_NET_BIND_SERVICE"; }; }; - - environment.systemPackages = [ pkgs.haproxy ]; - - users.users.haproxy = { - group = "haproxy"; - uid = config.ids.uids.haproxy; - }; - - users.groups.haproxy.gid = config.ids.uids.haproxy; }; } diff --git a/nixos/tests/haproxy.nix b/nixos/tests/haproxy.nix index 22a83e9d1eabf1..72e77a68193e39 100644 --- a/nixos/tests/haproxy.nix +++ b/nixos/tests/haproxy.nix @@ -16,6 +16,8 @@ import ./make-test.nix ({ pkgs, ...}: { frontend http bind *:80 mode http + option http-use-htx + http-request use-service prometheus-exporter if { path /metrics } use_backend http_server ''; }; @@ -36,6 +38,6 @@ import ./make-test.nix ({ pkgs, ...}: { $machine->waitForUnit('haproxy.service'); $machine->waitForUnit('httpd.service'); $machine->succeed('curl -k http://localhost:80/index.txt | grep "We are all good!"'); - + $machine->succeed('curl -k http://localhost:80/metrics | grep haproxy_process_pool_allocated_bytes'); ''; })