From 3c7e77960282dcf550fc2df8445c7da3ee27fb3c Mon Sep 17 00:00:00 2001 From: "Antoine R. Dumont" Date: Wed, 19 Nov 2014 20:13:54 +0100 Subject: [PATCH] Introduce a dedicated networking.proxy option Following the discussion NixOS#5021: - obsolete the nix.proxy option - add the networking.proxy option - open a default no_proxy environment variable - add a rsync option - Manual tests ok. - Automatic tests ok. Amended by lethalman to simplify the option descriptions. --- nixos/modules/config/networking.nix | 88 ++++++++++++++++- nixos/modules/rename.nix | 3 + nixos/modules/services/misc/nix-daemon.nix | 18 ---- nixos/tests/networking-proxy.nix | 109 +++++++++++++++++++++ 4 files changed, 199 insertions(+), 19 deletions(-) create mode 100644 nixos/tests/networking-proxy.nix diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix index 773d0b1f1a7d..b908f95df17e 100644 --- a/nixos/modules/config/networking.nix +++ b/nixos/modules/config/networking.nix @@ -39,6 +39,73 @@ in ''; }; + networking.proxy = { + + default = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = '' + This option specifies the default value for httpProxy, httpsProxy, ftpProxy and rsyncProxy. + ''; + example = "http://127.0.0.1:3128"; + }; + + httpProxy = lib.mkOption { + type = types.nullOr types.str; + default = cfg.proxy.default; + description = '' + This option specifies the http_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + httpsProxy = lib.mkOption { + type = types.nullOr types.str; + default = cfg.proxy.default; + description = '' + This option specifies the https_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + ftpProxy = lib.mkOption { + type = types.nullOr types.str; + default = cfg.proxy.default; + description = '' + This option specifies the ftp_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + rsyncProxy = lib.mkOption { + type = types.nullOr types.str; + default = cfg.proxy.default; + description = '' + This option specifies the rsync_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + noProxy = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = '' + This option specifies the no_proxy environment variable. + If a default proxy is used and noProxy is null, + then noProxy will be set to 127.0.0.1,localhost. + ''; + example = "127.0.0.1,localhost,.localdomain"; + }; + + envVars = lib.mkOption { + type = types.attrs; + internal = true; + default = {}; + description = '' + Environment variables used for the network proxy. + ''; + }; + }; }; config = { @@ -93,6 +160,25 @@ in } )); + networking.proxy.envVars = + optionalAttrs (cfg.proxy.default != null) { + # other options already fallback to proxy.default + no_proxy = "127.0.0.1,localhost"; + } // optionalAttrs (cfg.proxy.httpProxy != null) { + http_proxy = cfg.proxy.httpProxy; + } // optionalAttrs (cfg.proxy.httpsProxy != null) { + https_proxy = cfg.proxy.httpsProxy; + } // optionalAttrs (cfg.proxy.rsyncProxy != null) { + rsync_proxy = cfg.proxy.rsyncProxy; + } // optionalAttrs (cfg.proxy.ftpProxy != null) { + ftp_proxy = cfg.proxy.ftpProxy; + } // optionalAttrs (cfg.proxy.noProxy != null) { + no_proxy = cfg.proxy.noProxy; + }; + + # Install the proxy environment variables + environment.sessionVariables = config.networking.proxy.envVars; + # The ‘ip-up’ target is started when we have IP connectivity. So # services that depend on IP connectivity (like ntpd) should be # pulled in by this target. @@ -120,4 +206,4 @@ in }; -} + } diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 2b2d8e8cec58..b29a3d0354c9 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -110,6 +110,9 @@ in zipModules ([] # VirtualBox ++ obsolete [ "services" "virtualbox" "enable" ] [ "services" "virtualboxGuest" "enable" ] +# proxy +++ obsolete [ "nix" "proxy" ] [ "networking" "proxy" "default" ] + # KDE ++ deprecated [ "kde" "extraPackages" ] [ "environment" "kdePackages" ] # ++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ] # !!! doesn't work! diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index 4b398979fbaa..f8f99be9b099 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -193,17 +193,6 @@ in ''; }; - proxy = mkOption { - type = types.str; - default = ""; - description = '' - This option specifies the proxy to use for fetchurl. The real effect - is just exporting http_proxy, https_proxy and ftp_proxy with that - value. - ''; - example = "http://127.0.0.1:3128"; - }; - # Environment variables for running Nix. envVars = mkOption { type = types.attrs; @@ -317,13 +306,6 @@ in NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl"; NIX_REMOTE_SYSTEMS = "/etc/nix/machines"; NIX_CURRENT_LOAD = "/run/nix/current-load"; - } - - # !!! These should not be defined here, but in some general proxy configuration module! - // optionalAttrs (cfg.proxy != "") { - http_proxy = cfg.proxy; - https_proxy = cfg.proxy; - ftp_proxy = cfg.proxy; }; # Set up the environment variables for running Nix. diff --git a/nixos/tests/networking-proxy.nix b/nixos/tests/networking-proxy.nix new file mode 100644 index 000000000000..30844805ebf8 --- /dev/null +++ b/nixos/tests/networking-proxy.nix @@ -0,0 +1,109 @@ +# Test whether `networking.proxy' work as expected. + +# TODO: use a real proxy node and put this test into networking.nix +# TODO: test whether nix tools work as expected behind a proxy + +let default-config = { + imports = [ ./common/user-account.nix ]; + + services.xserver.enable = false; + + virtualisation.memorySize = 128; + }; +in import ./make-test.nix { + name = "networking-proxy"; + + nodes = { + # no proxy + machine = + { config, pkgs, ... }: + + default-config; + + # proxy default + machine2 = + { config, pkgs, ... }: + + default-config // { + networking.proxy.default = "http://user:pass@host:port"; + }; + + # specific proxy options + machine3 = + { config, pkgs, ... }: + + default-config // + { + networking.proxy = { + # useless because overriden by the next options + default = "http://user:pass@host:port"; + # advanced proxy setup + httpProxy = "123-http://user:pass@http-host:port"; + httpsProxy = "456-http://user:pass@https-host:port"; + rsyncProxy = "789-http://user:pass@rsync-host:port"; + ftpProxy = "101112-http://user:pass@ftp-host:port"; + noProxy = "131415-127.0.0.1,localhost,.localdomain"; + }; + }; + + # mix default + proxy options + machine4 = + { config, pkgs, ... }: + + default-config // { + networking.proxy = { + # open for all *_proxy env var + default = "000-http://user:pass@default-host:port"; + # except for those 2 + rsyncProxy = "123-http://user:pass@http-host:port"; + noProxy = "131415-127.0.0.1,localhost,.localdomain"; + }; + }; + }; + + testScript = + '' + startAll; + + # no proxy at all + print $machine->execute("env | grep -i proxy"); + print $machine->execute("su - alice -c 'env | grep -i proxy'"); + $machine->mustFail("env | grep -i proxy"); + $machine->mustFail("su - alice -c 'env | grep -i proxy'"); + + # Use a default proxy option + print $machine2->execute("env | grep -i proxy"); + print $machine2->execute("su - alice -c 'env | grep -i proxy'"); + $machine2->mustSucceed("env | grep -i proxy"); + $machine2->mustSucceed("su - alice -c 'env | grep -i proxy'"); + + # explicitly set each proxy option + print $machine3->execute("env | grep -i proxy"); + print $machine3->execute("su - alice -c 'env | grep -i proxy'"); + $machine3->mustSucceed("env | grep -i http_proxy | grep 123"); + $machine3->mustSucceed("env | grep -i https_proxy | grep 456"); + $machine3->mustSucceed("env | grep -i rsync_proxy | grep 789"); + $machine3->mustSucceed("env | grep -i ftp_proxy | grep 101112"); + $machine3->mustSucceed("env | grep -i no_proxy | grep 131415"); + $machine3->mustSucceed("su - alice -c 'env | grep -i http_proxy | grep 123'"); + $machine3->mustSucceed("su - alice -c 'env | grep -i https_proxy | grep 456'"); + $machine3->mustSucceed("su - alice -c 'env | grep -i rsync_proxy | grep 789'"); + $machine3->mustSucceed("su - alice -c 'env | grep -i ftp_proxy | grep 101112'"); + $machine3->mustSucceed("su - alice -c 'env | grep -i no_proxy | grep 131415'"); + + # set default proxy option + some other specifics + print $machine4->execute("env | grep -i proxy"); + print $machine4->execute("su - alice -c 'env | grep -i proxy'"); + $machine4->mustSucceed("env | grep -i http_proxy | grep 000"); + $machine4->mustSucceed("env | grep -i https_proxy | grep 000"); + $machine4->mustSucceed("env | grep -i rsync_proxy | grep 123"); + $machine4->mustSucceed("env | grep -i ftp_proxy | grep 000"); + $machine4->mustSucceed("env | grep -i no_proxy | grep 131415"); + $machine4->mustSucceed("su - alice -c 'env | grep -i http_proxy | grep 000'"); + $machine4->mustSucceed("su - alice -c 'env | grep -i https_proxy | grep 000'"); + $machine4->mustSucceed("su - alice -c 'env | grep -i rsync_proxy | grep 123'"); + $machine4->mustSucceed("su - alice -c 'env | grep -i ftp_proxy | grep 000'"); + $machine4->mustSucceed("su - alice -c 'env | grep -i no_proxy | grep 131415'"); + ''; + +}