Merge pull request #76723 from jokogr/u/traefik-2.1.1

Traefik: 1.7.14 -> 2.2.0
This commit is contained in:
Jörg Thalheim 2020-04-13 17:16:54 +01:00 committed by GitHub
commit 4c3f1d321a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 192 additions and 60 deletions

View File

@ -4,56 +4,102 @@ with lib;
let
cfg = config.services.traefik;
configFile =
if cfg.configFile == null then
pkgs.runCommand "config.toml" {
buildInputs = [ pkgs.remarshal ];
preferLocalBuild = true;
} ''
remarshal -if json -of toml \
< ${pkgs.writeText "config.json" (builtins.toJSON cfg.configOptions)} \
> $out
''
else cfg.configFile;
jsonValue = with types;
let
valueType = nullOr (oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
]) // {
description = "JSON value";
emptyValue.value = { };
};
in valueType;
dynamicConfigFile = if cfg.dynamicConfigFile == null then
pkgs.runCommand "config.toml" {
buildInputs = [ pkgs.remarshal ];
preferLocalBuild = true;
} ''
remarshal -if json -of toml \
< ${
pkgs.writeText "dynamic_config.json"
(builtins.toJSON cfg.dynamicConfigOptions)
} \
> $out
''
else
cfg.dynamicConfigFile;
staticConfigFile = if cfg.staticConfigFile == null then
pkgs.runCommand "config.toml" {
buildInputs = [ pkgs.yj ];
preferLocalBuild = true;
} ''
yj -jt -i \
< ${
pkgs.writeText "static_config.json" (builtins.toJSON
(recursiveUpdate cfg.staticConfigOptions {
providers.file.filename = "${dynamicConfigFile}";
}))
} \
> $out
''
else
cfg.staticConfigFile;
in {
options.services.traefik = {
enable = mkEnableOption "Traefik web server";
configFile = mkOption {
staticConfigFile = mkOption {
default = null;
example = literalExample "/path/to/config.toml";
example = literalExample "/path/to/static_config.toml";
type = types.nullOr types.path;
description = ''
Path to verbatim traefik.toml to use.
(Using that option has precedence over <literal>configOptions</literal>)
Path to traefik's static configuration to use.
(Using that option has precedence over <literal>staticConfigOptions</literal> and <literal>dynamicConfigOptions</literal>)
'';
};
configOptions = mkOption {
staticConfigOptions = mkOption {
description = ''
Config for Traefik.
Static configuration for Traefik.
'';
type = types.attrs;
default = {
defaultEntryPoints = ["http"];
entryPoints.http.address = ":80";
};
type = jsonValue;
default = { entryPoints.http.address = ":80"; };
example = {
defaultEntrypoints = [ "http" ];
web.address = ":8080";
entryPoints.web.address = ":8080";
entryPoints.http.address = ":80";
file = {};
frontends = {
frontend1 = {
backend = "backend1";
routes.test_1.rule = "Host:localhost";
};
};
backends.backend1 = {
servers.server1.url = "http://localhost:8000";
api = { };
};
};
dynamicConfigFile = mkOption {
default = null;
example = literalExample "/path/to/dynamic_config.toml";
type = types.nullOr types.path;
description = ''
Path to traefik's dynamic configuration to use.
(Using that option has precedence over <literal>dynamicConfigOptions</literal>)
'';
};
dynamicConfigOptions = mkOption {
description = ''
Dynamic configuration for Traefik.
'';
type = jsonValue;
default = { };
example = {
http.routers.router1 = {
rule = "Host(`localhost`)";
service = "service1";
};
http.services.service1.loadBalancer.servers =
[{ url = "http://localhost:8080"; }];
};
};
@ -61,7 +107,7 @@ in {
default = "/var/lib/traefik";
type = types.path;
description = ''
Location for any persistent data traefik creates, ie. acme
Location for any persistent data traefik creates, ie. acme
'';
};
@ -84,16 +130,15 @@ in {
};
config = mkIf cfg.enable {
systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0700 traefik traefik - -"
];
systemd.tmpfiles.rules = [ "d '${cfg.dataDir}' 0700 traefik traefik - -" ];
systemd.services.traefik = {
description = "Traefik web server";
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = ''${cfg.package.bin}/bin/traefik --configfile=${configFile}'';
ExecStart =
"${cfg.package}/bin/traefik --configfile=${staticConfigFile}";
Type = "simple";
User = "traefik";
Group = cfg.group;
@ -120,6 +165,6 @@ in {
isSystemUser = true;
};
users.groups.traefik = {};
users.groups.traefik = { };
};
}

View File

@ -303,6 +303,8 @@ in
timezone = handleTest ./timezone.nix {};
tinydns = handleTest ./tinydns.nix {};
tor = handleTest ./tor.nix {};
# traefik test relies on docker-containers
traefik = handleTestOn ["x86_64-linux"] ./traefik.nix {};
transmission = handleTest ./transmission.nix {};
trac = handleTest ./trac.nix {};
trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {};

87
nixos/tests/traefik.nix Normal file
View File

@ -0,0 +1,87 @@
# Test Traefik as a reverse proxy of a local web service
# and a Docker container.
import ./make-test-python.nix ({ pkgs, ... }: {
name = "traefik";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ joko ];
};
nodes = {
client = { config, pkgs, ... }: {
environment.systemPackages = [ pkgs.curl ];
};
traefik = { config, pkgs, ... }: {
docker-containers.nginx = {
extraDockerOptions = [
"-l" "traefik.enable=true"
"-l" "traefik.http.routers.nginx.entrypoints=web"
"-l" "traefik.http.routers.nginx.rule=Host(`nginx.traefik.test`)"
];
image = "nginx-container";
imageFile = pkgs.dockerTools.examples.nginx;
};
networking.firewall.allowedTCPPorts = [ 80 ];
services.traefik = {
enable = true;
dynamicConfigOptions = {
http.routers.simplehttp = {
rule = "Host(`simplehttp.traefik.test`)";
entryPoints = [ "web" ];
service = "simplehttp";
};
http.services.simplehttp = {
loadBalancer.servers = [{
url = "http://127.0.0.1:8000";
}];
};
};
staticConfigOptions = {
global = {
checkNewVersion = false;
sendAnonymousUsage = false;
};
entryPoints.web.address = ":80";
providers.docker.exposedByDefault = false;
};
};
systemd.services.simplehttp = {
script = "${pkgs.python3}/bin/python -m http.server 8000";
serviceConfig.Type = "simple";
wantedBy = [ "multi-user.target" ];
};
users.users.traefik.extraGroups = [ "docker" ];
};
};
testScript = ''
start_all()
traefik.wait_for_unit("docker-nginx.service")
traefik.wait_until_succeeds("docker ps | grep nginx-container")
traefik.wait_for_unit("simplehttp.service")
traefik.wait_for_unit("traefik.service")
traefik.wait_for_open_port(80)
traefik.wait_for_unit("multi-user.target")
client.wait_for_unit("multi-user.target")
with subtest("Check that a container can be reached via Traefik"):
assert "Hello from NGINX" in client.succeed(
"curl -sSf -H Host:nginx.traefik.test http://traefik/"
)
with subtest("Check that dynamic configuration works"):
assert "Directory listing for " in client.succeed(
"curl -sSf -H Host:simplehttp.traefik.test http://traefik/"
)
'';
})

View File

@ -1,39 +1,37 @@
{ stdenv, buildGoPackage, fetchFromGitHub, bash, go-bindata}:
{ stdenv, buildGoModule, fetchFromGitHub, go-bindata, nixosTests }:
buildGoPackage rec {
buildGoModule rec {
pname = "traefik";
version = "1.7.14";
goPackagePath = "github.com/containous/traefik";
version = "2.2.0";
src = fetchFromGitHub {
owner = "containous";
repo = "traefik";
rev = "v${version}";
sha256 = "1j3p09j8rpdkp8v4d4mz224ddakkvhzchvccm9qryrqc2fq4022v";
sha256 = "1dcazssabqxr9wv3dds3z7ks3y628qa07vgnn3hpdwxzm2b2ma92";
};
nativeBuildInputs = [ go-bindata bash ];
modSha256 = "0w3ssxvsmq8i6hbfmn4ig2x13i2nlqy5q1khcblf9pq5vhk202qx";
subPackages = [ "cmd/traefik" ];
buildPhase = ''
runHook preBuild
(
cd go/src/github.com/containous/traefik
bash ./script/make.sh generate
nativeBuildInputs = [ go-bindata ];
CODENAME=$(awk -F "=" '/CODENAME=/ { print $2}' script/binary)
go build -ldflags "\
-X github.com/containous/traefik/version.Version=${version} \
-X github.com/containous/traefik/version.Codename=$CODENAME \
" -a -o $bin/bin/traefik ./cmd/traefik
)
runHook postBuild
passthru.tests = { inherit (nixosTests) traefik; };
preBuild = ''
go generate
CODENAME=$(awk -F "=" '/CODENAME=/ { print $2}' script/binary)
makeFlagsArray+=("-ldflags=\
-X github.com/containous/traefik/version.Version=${version} \
-X github.com/containous/traefik/version.Codename=$CODENAME")
'';
meta = with stdenv.lib; {
homepage = "https://traefik.io";
description = "A modern reverse proxy";
license = licenses.mit;
maintainers = with maintainers; [ hamhut1066 vdemeester ];
maintainers = with maintainers; [ vdemeester ];
};
}