[bug#79807] add http-proxy switch in guix-daemon to nix-daemon service

Message ID tencent_6E8B36B7600D3A7CB99E37F35F081EBB3C07@qq.com
State New
Headers
Series [bug#79807] add http-proxy switch in guix-daemon to nix-daemon service |

Commit Message

繠䴧 Nov. 10, 2025, 7:33 a.m. UTC
I copied the relevant code from guix service in gnu/services/base.scm to 
gnu/services/nix.scm to let us use `sudo herd set-http-proxy nix-daemon ...`

Note that Though this patch makes the nix-daemon get the http_proxy and 
https_proxy, it does not work at all, because nix requires (extra-config 
'("extra-experimental-features = configurable-impure-env\n" "impure-env 
= [ \"http_proxy=<your proxy>\" \"https_proxy=<your proxy>\" ]\n")) set 
explicitly, actively ignoring any dunamically set var envs. In other 
words, nix here has to get the config specified AND the same env var in 
its environment before it would care about this.

This is a problem of nix, to even require user to explicitly 
configure&compile the http_proxy variable for use. But this does not 
mean we do not need to prepare such a toggle like guix-daemon does, as 
they are actually similar.

below is the content of file 
0001-mostly-copied-from-guix-service-type.patch (sorry for the dumb 
commit message)

 From 01108abb4a71b29315f3ae0a959f76db4199802c Mon Sep 17 00:00:00 2001
From: "R.W.Flurando" <rw-flurando@inventati.org>
Date: Mon, 10 Nov 2025 14:54:58 +0800
Subject: [PATCH] mostly copied from guix-service-type

Change-Id: I0ca29641e72cc002a78d70f6a41b9e7697fb53a5
---
  gnu/services/nix.scm | 41 +++++++++++++++++++++++++++++++++++++----
  1 file changed, 37 insertions(+), 4 deletions(-)

  ;; Copied from gnu/services/base.scm
  (define* (nix-build-accounts count #:key
                               (group "nixbld")
@@ -111,7 +138,7 @@ (define (nix-activation _)

  (define nix-service-etc
    (match-lambda
-    (($ <nix-configuration> package sandbox build-directory 
build-sandbox-items extra-config)
+    (($ <nix-configuration> package sandbox build-directory 
build-sandbox-items _ extra-config _)
       (let ((ref-file (references-file package)))
         `(("nix/nix.conf"
            ,(computed-file
@@ -149,18 +176,24 @@ (define %immutable-nix-store
  (define nix-shepherd-service
    ;; Return a <shepherd-service> for Nix.
    (match-lambda
-    (($ <nix-configuration> package _ build-directory _ _ extra-options)
+    (($ <nix-configuration> package _ build-directory _ http-proxy _ 
extra-options)
       (list
        (shepherd-service
         (provision '(nix-daemon))
         (documentation "Run nix-daemon.")
+       (actions (list shepherd-set-http-proxy-action))
         (requirement '(user-processes file-system-/nix/store))
         (start #~(make-forkexec-constructor
                   (list (string-append #$package "/bin/nix-daemon")
                         #$@extra-options)
                   #:environment-variables
-                 (list (string-append "TMPDIR=" #$build-directory)
-                       "PATH=/run/current-system/profile/bin")))
+                 (append (list (string-append "TMPDIR=" #$build-directory)
+                   "PATH=/run/current-system/profile/bin")
+             (let ((proxy (or (getenv "http_proxy") #$http-proxy)))
+               (if proxy
+                               (list (string-append "http_proxy=" proxy)
+                                     (string-append "https_proxy=" proxy))
+                               '())))))
         (respawn? #f)
         (stop #~(make-kill-destructor)))))))

-- 
2.51.2

-- 
fingerprint: 469A 1322 13E3 4A61 24DC 8001 8D4B C9CD 361B 6C8C
  

Comments

繠䴧 Nov. 10, 2025, 8:20 a.m. UTC | #1
As said, now set-http-proxy command works, nix-daemon actually ignores

for a working configuration, try

(service nix-service-type
           (nix-configuration
            (http-proxy "127.0.0.1:1080")
            (extra-config '("extra-experimental-features = 
configurable-impure-env\n" "impure-env = [ \"http_proxy=127.0.0.1:1080\" 
\"https_proxy=127.0.0.1:1080\" ]\n"))))

if your proxy listens on 127.0.0.1:1080

This is not good since herd set-http-proxy actively does nothing

but it is still meaningful since you used have to patch the 
nix-shepherd-service to specify a proxy to use, now just change in the 
system configuration is enough.

-- 
fingerprint: 469A 1322 13E3 4A61 24DC 8001 8D4B C9CD 361B 6C8C
  
繠䴧 Nov. 10, 2025, 11:11 a.m. UTC | #2
As said, now set-http-proxy command works, nix-daemon actually ignores

for a working configuration, try

(service nix-service-type
           (nix-configuration
            (http-proxy "127.0.0.1:1080")
            (extra-config '("extra-experimental-features = 
configurable-impure-env\n" "impure-env = [ \"http_proxy=127.0.0.1:1080\" 
\"https_proxy=127.0.0.1:1080\" ]\n"))))

if your proxy listens on 127.0.0.1:1080

This is not good since herd set-http-proxy actively does nothing

but it is still meaningful since you used have to patch the 
nix-shepherd-service to specify a proxy to use, now just change in the 
system configuration is enough.

(this message is a resent since I mistakenly changed the topic when 
sending to 79807@debbugs.gnu.org, if you see two messages somehow, sorry)

-- 
fingerprint: 469A 1322 13E3 4A61 24DC 8001 8D4B C9CD 361B 6C8C
  

Patch

diff --git a/gnu/services/nix.scm b/gnu/services/nix.scm
index 83ba78ce7e..24ec08ac13 100644
--- a/gnu/services/nix.scm
+++ b/gnu/services/nix.scm
@@ -59,11 +59,38 @@  (define-record-type* <nix-configuration>
                         (default "/tmp"))
    (build-sandbox-items nix-configuration-build-sandbox-items ;list of 
strings
                         (default '()))
+  (http-proxy          nix-http-proxy ;string | #f
+                       (default #f))
    (extra-config        nix-configuration-extra-config ;list of strings
                         (default '()))
    (extra-options       nix-configuration-extra-options ;list of strings
                         (default '())))

+(define shepherd-set-http-proxy-action
+  ;; Shepherd action to change the HTTP(S) proxy.
+  (shepherd-action
+   (name 'set-http-proxy)
+   (documentation
+    "Change the HTTP(S) proxy used by 'nix-daemon' and restart it.")
+   (procedure #~(lambda* (_ #:optional proxy)
+                  (let ((environment (environ)))
+                    ;; A bit of a hack: communicate PROXY to the 'start'
+                    ;; method via environment variables.
+                    (if proxy
+                        (begin
+                          (format #t "changing HTTP/HTTPS \
+proxy of 'nix-daemon' to ~s...~%"
+                                  proxy)
+                          (setenv "http_proxy" proxy))
+                        (begin
+                          (format #t "clearing HTTP/HTTPS \
+proxy of 'nix-daemon'...~%")
+                          (unsetenv "http_proxy")))
+                    (perform-service-action (lookup-service 
'nix-daemon) ; copied from guix-service-type with guix-daemon changed to 
nix-daemon
+                                            'restart)
+                    (environ environment)
+                    #t)))))
+