Commit 930ee4ad authored by Vincent Bernat's avatar Vincent Bernat
Browse files

caddy: add support for compiling Caddy with plugins

This adds a `withPlugins` function to Caddy package.

```nix
services.caddy = {
  enable = true;
  package = pkgs.caddy.withPlugins {
    plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" ];
    hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc=";
  };
};
```
parent cfa7244d
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -160,6 +160,21 @@

- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.

- Caddy can now be built with plugins by using `caddy.withPlugins`, a `passthru` function that accepts an attribute set as a parameter. The `plugins` argument represents a list of Caddy plugins, with each Caddy plugin being a versioned module. The `hash` argument represents the `vendorHash` of the resulting Caddy source code with the plugins added.

  Example:
  ```nix
  services.caddy = {
    enable = true;
    package = pkgs.caddy.withPlugins {
      plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" ];
      hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc=";
    };
  };
  ```

  To get the necessary hash of the vendored dependencies, omit `hash`. The build will fail and tell you the correct value.

- `programs.fzf.keybindings` now supports the fish shell.

<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+82 −6
Original line number Diff line number Diff line
@@ -6,6 +6,10 @@
, testers
, installShellFiles
, stdenv
, go
, xcaddy
, cacert
, git
}:
let
  version = "2.8.4";
@@ -32,7 +36,8 @@ buildGoModule {
  subPackages = [ "cmd/caddy" ];

  ldflags = [
    "-s" "-w"
    "-s"
    "-w"
    "-X github.com/caddyserver/caddy/v2.CustomVersion=${version}"
  ];

@@ -61,13 +66,84 @@ buildGoModule {
      --zsh <($out/bin/caddy completion zsh)
  '';

  passthru.tests = {
  passthru = {
    tests = {
      inherit (nixosTests) caddy;
      version = testers.testVersion {
        command = "${caddy}/bin/caddy version";
        package = caddy;
      };
    };
    withPlugins =
      { plugins
      , hash ? lib.fakeHash
      }: caddy.overrideAttrs (finalAttrs: prevAttrs:
      let
        pluginsSorted = builtins.sort builtins.lessThan plugins;
        pluginsList = lib.concatMapStrings (plugin: "${plugin}-") pluginsSorted;
        pluginsHash = builtins.hashString "md5" pluginsList;
        pluginsWithoutVersion = builtins.filter (p: !lib.hasInfix "@" p) pluginsSorted;
      in
      assert lib.assertMsg (builtins.length pluginsWithoutVersion == 0)
        "All plugins should have a version (eg ${builtins.elemAt pluginsWithoutVersion 0}@x.y.z)!";
      {
        vendorHash = null;
        subPackages = [ "." ];

        src = stdenv.mkDerivation {
          pname = "caddy-src-with-plugins-${pluginsHash}";
          version = finalAttrs.version;

          nativeBuildInputs = [
            go
            xcaddy
            cacert
            git
          ];
          dontUnpack = true;
          buildPhase =
            let
              withArgs = lib.concatMapStrings (plugin: "--with ${plugin} ") pluginsSorted;
            in
            ''
              export GOCACHE=$TMPDIR/go-cache
              export GOPATH="$TMPDIR/go"
              XCADDY_SKIP_BUILD=1 TMPDIR="$PWD" xcaddy build v${finalAttrs.version} ${withArgs}
              (cd buildenv* && go mod vendor)
            '';
          installPhase = ''
            mv buildenv* $out
          '';

          outputHashMode = "recursive";
          outputHash = hash;
          outputHashAlgo = "sha256";
        };


        doInstallCheck = true;
        installCheckPhase = ''
          runHook preInstallCheck

          ${lib.toShellVar "notfound" pluginsSorted}
          while read kind module version; do
            [[ "$kind" = "dep" ]] || continue
            module="''${module}@''${version}"
            for i in "''${!notfound[@]}"; do
              if [[ ''${notfound[i]} = ''${module} ]]; then
                unset 'notfound[i]'
              fi
            done
          done < <($out/bin/caddy build-info)
          if (( ''${#notfound[@]} )); then
            >&2 echo "Plugins not found: ''${notfound[@]}"
            exit 1
          fi

          runHook postInstallCheck
        '';
      });
  };

  meta = with lib; {
    homepage = "https://caddyserver.com";