0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-13 21:50:33 +03:00

caddy: withPlugins better error messages for untagged plugins (#368657)

This commit is contained in:
Thiago Kenji Okada 2024-12-29 12:32:21 +00:00 committed by GitHub
commit b821685bc8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 101 additions and 19 deletions

View file

@ -289,14 +289,22 @@
services.caddy = { services.caddy = {
enable = true; enable = true;
package = pkgs.caddy.withPlugins { package = pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" ]; plugins = [
hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc="; # tagged upstream
"github.com/caddy-dns/powerdns@v1.0.1"
# pseudo-version number generated by Go
"github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e"
"github.com/mholt/caddy-webdav@v0.0.0-20241008162340-42168ba04c9d"
];
hash = "sha256-wqXSd1Ep9TVpQi570TTb96LwzNYvWL5EBJXMJfYWCAk=";
}; };
}; };
``` ```
To get the necessary hash of the vendored dependencies, omit `hash`. The build will fail and tell you the correct value. To get the necessary hash of the vendored dependencies, omit `hash`. The build will fail and tell you the correct value.
Note that all provided plugins must have versions/tags (string after `@`), even if upstream repo does not tag each release. For untagged plugins, you can either create an empty Go project and run `go get <plugin>` and see changes in `go.mod` to get the pseudo-version number, or provide a commit hash in place of version/tag for the first run, and update the plugin string based on the error output.
- KDE Partition Manager `partitionmanager`'s support for ReiserFS is removed. - KDE Partition Manager `partitionmanager`'s support for ReiserFS is removed.
ReiserFS has not been actively maintained for many years. It has been marked as obsolete since Linux 6.6, and ReiserFS has not been actively maintained for many years. It has been marked as obsolete since Linux 6.6, and
[is removed](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c01f664e4ca210823b7594b50669bbd9b0a3c3b0) [is removed](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c01f664e4ca210823b7594b50669bbd9b0a3c3b0)

View file

@ -3,12 +3,15 @@ import ./make-test-python.nix (
{ {
name = "caddy"; name = "caddy";
meta = with pkgs.lib.maintainers; { meta = with pkgs.lib.maintainers; {
maintainers = [ Br1ght0ne ]; maintainers = [
Br1ght0ne
stepbrobd
];
}; };
nodes = { nodes = {
webserver = webserver =
{ pkgs, lib, ... }: { pkgs, ... }:
{ {
services.caddy.enable = true; services.caddy.enable = true;
services.caddy.extraConfig = '' services.caddy.extraConfig = ''
@ -63,6 +66,24 @@ import ./make-test-python.nix (
respond "hello world" respond "hello world"
''; '';
}; };
specialisation.with-plugins.configuration = {
services.caddy = {
package = pkgs.caddy.withPlugins {
plugins = [ "github.com/caddyserver/replace-response@v0.0.0-20241211194404-3865845790a7" ];
hash = "sha256-zgMdtOJbmtRSfTlrrg8njr11in2C7OAXLB+34V23jek=";
};
configFile = pkgs.writeText "Caddyfile" ''
{
order replace after encode
}
localhost:80 {
respond "hello world"
replace world caddy
}
'';
};
};
}; };
}; };
@ -73,6 +94,7 @@ import ./make-test-python.nix (
justReloadSystem = "${nodes.webserver.system.build.toplevel}/specialisation/config-reload"; justReloadSystem = "${nodes.webserver.system.build.toplevel}/specialisation/config-reload";
multipleConfigs = "${nodes.webserver.system.build.toplevel}/specialisation/multiple-configs"; multipleConfigs = "${nodes.webserver.system.build.toplevel}/specialisation/multiple-configs";
rfc42Config = "${nodes.webserver.system.build.toplevel}/specialisation/rfc42"; rfc42Config = "${nodes.webserver.system.build.toplevel}/specialisation/rfc42";
withPluginsConfig = "${nodes.webserver.system.build.toplevel}/specialisation/with-plugins";
in in
'' ''
url = "http://localhost/example.html" url = "http://localhost/example.html"
@ -108,6 +130,13 @@ import ./make-test-python.nix (
) )
webserver.wait_for_open_port(80) webserver.wait_for_open_port(80)
webserver.succeed("curl http://localhost | grep hello") webserver.succeed("curl http://localhost | grep hello")
with subtest("plugins are correctled installed and configurable"):
webserver.succeed(
"${withPluginsConfig}/bin/switch-to-configuration test >&2"
)
webserver.wait_for_open_port(80)
webserver.succeed("curl http://localhost | grep caddy")
''; '';
} }
) )

View file

@ -7,10 +7,6 @@
, testers , testers
, installShellFiles , installShellFiles
, stdenv , stdenv
, go
, xcaddy
, cacert
, git
}: }:
let let
version = "2.8.4"; version = "2.8.4";

View file

@ -1,3 +1,4 @@
# callPackage args
{ {
lib, lib,
stdenv, stdenv,
@ -7,19 +8,44 @@
git, git,
caddy, caddy,
}: }:
let
inherit (builtins) hashString;
inherit (lib)
assertMsg
concatMapStrings
elemAt
fakeHash
filter
hasInfix
length
lessThan
sort
toShellVar
;
in
# pkgs.caddy.withPlugins args
{ {
plugins, plugins,
hash ? lib.fakeHash, hash ? fakeHash,
}: }:
let let
pluginsSorted = lib.sort lib.lessThan plugins; pluginsSorted = sort lessThan plugins;
pluginsList = lib.concatMapStrings (plugin: "${plugin}-") pluginsSorted; pluginsList = concatMapStrings (plugin: "${plugin}-") pluginsSorted;
pluginsHash = builtins.hashString "md5" pluginsList; pluginsHash = hashString "md5" pluginsList;
pluginsWithoutVersion = lib.filter (p: !lib.hasInfix "@" p) pluginsSorted; pluginsWithoutVersion = filter (p: !hasInfix "@" p) pluginsSorted;
in in
assert lib.assertMsg (
lib.length pluginsWithoutVersion == 0 # eval barrier: user provided plugins must have tags
) "All plugins should have a version (eg ${lib.elemAt pluginsWithoutVersion 0}@x.y.z)!"; # the go module must either be tagged in upstream repo
# or user must provide commit sha or a pseudo-version number
# https://go.dev/doc/modules/version-numbers#pseudo-version-number
assert assertMsg (
length pluginsWithoutVersion == 0
) "Plugins must have tags present (e.g. ${elemAt pluginsWithoutVersion 0}@x.y.z)!";
caddy.overrideAttrs ( caddy.overrideAttrs (
finalAttrs: prevAttrs: { finalAttrs: prevAttrs: {
vendorHash = null; vendorHash = null;
@ -38,7 +64,7 @@ caddy.overrideAttrs (
dontUnpack = true; dontUnpack = true;
buildPhase = buildPhase =
let let
withArgs = lib.concatMapStrings (plugin: "--with ${plugin} ") pluginsSorted; withArgs = concatMapStrings (plugin: "--with ${plugin} ") pluginsSorted;
in in
'' ''
export GOCACHE=$TMPDIR/go-cache export GOCACHE=$TMPDIR/go-cache
@ -55,11 +81,14 @@ caddy.overrideAttrs (
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
}; };
# xcaddy built output always uses pseudo-version number
# we enforce user provided plugins are present and have matching tags here
doInstallCheck = true; doInstallCheck = true;
installCheckPhase = '' installCheckPhase = ''
runHook preInstallCheck runHook preInstallCheck
${lib.toShellVar "notfound" pluginsSorted} ${toShellVar "notfound" pluginsSorted}
while read kind module version; do while read kind module version; do
[[ "$kind" = "dep" ]] || continue [[ "$kind" = "dep" ]] || continue
module="''${module}@''${version}" module="''${module}@''${version}"
@ -69,8 +98,28 @@ caddy.overrideAttrs (
fi fi
done done
done < <($out/bin/caddy build-info) done < <($out/bin/caddy build-info)
if (( ''${#notfound[@]} )); then if (( ''${#notfound[@]} )); then
>&2 echo "Plugins not found: ''${notfound[@]}" for plugin in "''${notfound[@]}"; do
base=''${plugin%@*}
specified=''${plugin#*@}
found=0
while read kind module expected; do
[[ "$kind" = "dep" && "$module" = "$base" ]] || continue
echo "Plugin \"$base\" have incorrect tag:"
echo " specified: \"$base@$specified\""
echo " got: \"$base@$expected\""
found=1
done < <($out/bin/caddy build-info)
if (( found == 0 )); then
echo "Plugin \"$base\" not found in build:"
echo " specified: \"$base@$specified\""
echo " plugin does not exist in the xcaddy build output, open an issue in nixpkgs or upstream"
fi
done
exit 1 exit 1
fi fi