Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undocumented / impossible: override go modules #86349

Closed
doronbehar opened this issue Apr 29, 2020 · 20 comments
Closed

Undocumented / impossible: override go modules #86349

doronbehar opened this issue Apr 29, 2020 · 20 comments
Labels

Comments

@doronbehar
Copy link
Contributor

Describe the bug

I'm trying to write an overlay that will override attributes of a package that is built with buildGoModule and I'm having trouble overriding the modules derivation of it.

It seems the author's intention was that I'd use overrideModAttrs as an argument to buildGoModule? But I guess this doesn't work with overlays? Whatever I do, I get either an evaluation error or a build error because the old go-modules is used. Here are a few examples I tried:

overridedPackage = super.original.overrideAttrs(oldAttrs: rec {
  src = ....;
  modSha256 = "0000000000000000000000000000000000000000000000000000";

But the build still took the old go modules derivation.

I also tried instead:

  overrideModAttrs = (_oldAttrs : {
    modSha256 = "0r062nka72ah2nb2gf8dfrrj4sxadkykcqjzkp4c9vwk93mhw41k";
  });

Which failed with:

error: cannot coerce a function to a string, at ...

And I even went as far as:

  configurePhase = (let
    go-modules = self.pistol.go-modules.overrideAttrs(oldAttrs: {
      modSha256 = "0000000000000000000000000000000000000000000000000000";
    });
  in
    ''
      echo checking I override configure phase
      runHook preConfigure
  
      export GOCACHE=$TMPDIR/go-cache
      export GOPATH="$TMPDIR/go"
      export GOSUMDB=off
      export GOPROXY=file://${go-modules}
  
      cd "$modRoot"
  
      runHook postConfigure
    ''
  );
});

But that also failed because the build used the old go-modules. I can confirm though, that it did override the configurePhase which is the only place ${go-modules} is evaluated.

Expected behavior

It shouldn't be that difficult to override a go modules derivation.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context

I'm trying to override a package I maintain which it's update is stale (#85452), due to an unresolved issue with the version build flags :(.

Notify maintainers

@kalbasit ? As the author of buildGoModule according to git blame...

@kalbasit
Copy link
Member

kalbasit commented May 1, 2020

I have the same issue, unfortunately, and I have not been able to look into it.

@kalbasit
Copy link
Member

kalbasit commented May 6, 2020

@doronbehar this worked for me

  (self: super: {
    bazel-gazelle = (super.callPackage "${super.path}/pkgs/development/tools/bazel-gazelle" {
      buildGoModule = args: super.buildGoModule (args // {
        modSha256 = "13yx70p0x7hpdp2zn7zrl0i88fk6dhcryp0lmn0zwdn92ldm3n5y";
        patches = (args.patches or []) ++ super.lib.lists.singleton (super.fetchpatch {
          url = "https://github.com/bazelbuild/bazel-gazelle/pull/749.patch";
          sha256 = "03sxbgwvb6hxwpmk9mckwjzgxank9difc0bgvzl6x3rir76ivwmj";
        });
      });
    });
  })

@doronbehar
Copy link
Contributor Author

Damn you are overriding the goddamn function. It's nice to know this is not "Impossible". Do you think @kalbasit this interface could be improved somehow?

@doronbehar
Copy link
Contributor Author

@kalbasit I've stumbled upon another point to improve the golang docs at #97856 . I'm not sure whether this should be documented or not along with the other changes - overrideModAttrs doesn't seem to be able to provide what it promises.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/inconsistent-vendoring-in-buildgomodule-when-overriding-source/9225/4

@joulaud
Copy link
Contributor

joulaud commented Jan 14, 2021

The problem with pythonBuildPackage described at https://discourse.nixos.org/t/un-disabling-a-python-package-in-an-overlay/10593 seems similar to me. Perhaps overrideAttrs documentation should be improved to better explain those traps.

@fiksn
Copy link
Contributor

fiksn commented Jan 16, 2021

I've also stumbled on this when trying to override some go package which involved changing vendorSha256 too.
So if I understood this correctly the problem with overrideAttrs is that it works just with a simple mkDerivation, but buildGoModule internally does more and calls mkDerivation also for the vendored dependencies?

Then I suppose in the same way as there is overridePythonAttrs there should be some overrideGoAttrs.

@doronbehar
Copy link
Contributor Author

Then I suppose in the same way as there is overridePythonAttrs there should be some overrideGoAttrs.

I think we should strive to have less of such functions with different names but the same meaning.

@Mic92
Copy link
Member

Mic92 commented Jun 1, 2021

This one is a bit shorter:

(pkgs.istioctl.overrideAttrs (old: let
  version = "1.7.1";
  src = pkgs.fetchFromGitHub {
    owner = "istio";
    repo = "istio";
    rev = version;
    sha256 = "sha256-CvYqYxb19lSc61SrvGcf/kG9e9zosHz4JbByA+bN600=";
  };
in rec {
  name = "istioct-${version}";
  inherit src;
  go-modules = (pkgs.buildGoModule {
    inherit name src;
    vendorSha256 = "sha256-4Z4Fgv9zmAwp3tEvHj8yLOWkFY/zFz5VfehSWCuIUcI=";
  }).go-modules;
}))

@nh2
Copy link
Contributor

nh2 commented Jun 14, 2021

This one is a bit shorter:

@Mic92 this doesn't work for me, trying with:

{
  kopia_unstable = nixos-2105.kopia.overrideAttrs (old:
    let
      version = "ede09c15854ce74fde40603a6857ed3991ba666c";
      src = nixos-2105.fetchFromGitHub {
        owner = "kopia";
        repo = "kopia";
        rev = version;
        sha256 = "0wdkwpsgmycbiq8dvng3d0ps5qp87b7k1xvw8rv2wk1qzrrp6d93";
      };
    in
      rec {
        name = "kopia-${version}";
        inherit src;
        go-modules = (nixos-2105.buildGoModule {
          inherit name src;
          vendorSha256 = "1idg6l9cnii6694kdmv9sc42c0bzk7pk67sdlglkaz52kg5hc6bd";
      }).go-modules;
  });
}

Error output:

these derivations will be built:
  /nix/store/d5ada6p0wl6pnz6xm4r5ws50yvha1c36-kopia-ede09c15854ce74fde40603a6857ed3991ba666c-go-modules.drv
  /nix/store/nvixyjbfji4ljlyqkhx32323ip5zq6a7-kopia-ede09c15854ce74fde40603a6857ed3991ba666c.drv
building '/nix/store/d5ada6p0wl6pnz6xm4r5ws50yvha1c36-kopia-ede09c15854ce74fde40603a6857ed3991ba666c-go-modules.drv'...
copying 1 paths...
copying path '/nix/store/mbhc8w8qxckv4j1rwz7mlaljahv6m46w-kopia-ede09c15854ce74fde40603a6857ed3991ba666c-go-modules' from 'ssh://...
building '/nix/store/nvixyjbfji4ljlyqkhx32323ip5zq6a7-kopia-ede09c15854ce74fde40603a6857ed3991ba666c.drv'...
copying 1 paths...
copying path '/nix/store/0y74vrvy799phqqwl781q9xadzqaj5ly-kopia-0.8.4-go-modules' to 'ssh://...
unpacking sources
unpacking source archive /nix/store/w9zd6h50l258cdzkmja19pfvzih51ywj-source
source root is source
patching sources
configuring
building
Building subPackage ./.
go: inconsistent vendoring in /build/source:
        cloud.google.com/go/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/Azure/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/aws/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/dustinkirkland/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/fatih/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/golang/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/klauspost/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/pierrec/[email protected]+incompatible: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/pkg/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        github.com/sanity-io/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        [email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        golang.org/x/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        golang.org/x/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        golang.org/x/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        golang.org/x/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        google.golang.org/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        google.golang.org/[email protected]: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
        cloud.google.com/go/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/Azure/go-autorest/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/aws/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/fatih/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/golang/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/google/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/klauspost/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        github.com/pkg/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        [email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        golang.org/x/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        golang.org/x/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        golang.org/x/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        golang.org/x/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        google.golang.org/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod
        google.golang.org/[email protected]: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod

        To ignore the vendor directory, use -mod=readonly or -mod=mod.
        To sync the vendor directory, run:
                go mod vendor

@nh2
Copy link
Contributor

nh2 commented Jun 14, 2021

The approach from #86349 (comment) worked for me (replacing modSha256 by its successor vendorSha256):

{
  kopia_unstable =
    let
      version = "ede09c15854ce74fde40603a6857ed3991ba666c";
      src = nixos-2105.fetchFromGitHub {
        owner = "kopia";
        repo = "kopia";
        rev = version;
        sha256 = "0wdkwpsgmycbiq8dvng3d0ps5qp87b7k1xvw8rv2wk1qzrrp6d93";
      };
    in
      (nixos-2105.callPackage "${nixos-2105.path}/pkgs/tools/backup/kopia" {
        buildGoModule = args: nixos-2105.buildGoModule (args // {
          vendorSha256 = "1idg6l9cnii6694kdmv9sc42c0bzk7pk67sdlglkaz52kg5hc6bd";
          inherit src version;
        });
      });
}

@danielphan2003
Copy link

The approach from #86349 (comment) worked for me (replacing modSha256 by its successor vendorSha256):

{
  kopia_unstable =
    let
      version = "ede09c15854ce74fde40603a6857ed3991ba666c";
      src = nixos-2105.fetchFromGitHub {
        owner = "kopia";
        repo = "kopia";
        rev = version;
        sha256 = "0wdkwpsgmycbiq8dvng3d0ps5qp87b7k1xvw8rv2wk1qzrrp6d93";
      };
    in
      (nixos-2105.callPackage "${nixos-2105.path}/pkgs/tools/backup/kopia" {
        buildGoModule = args: nixos-2105.buildGoModule (args // {
          vendorSha256 = "1idg6l9cnii6694kdmv9sc42c0bzk7pk67sdlglkaz52kg5hc6bd";
          inherit src version;
        });
      });
}

What about using nixos-2105.kopia.override instead of nixos-2105.callPackage "${nixos-2105.path}/pkgs/tools/backup/kopia"? This works when Nix is in restricted mode (in my case I was using flake).

Also Go 1.17 is already out, and latest Tailscale requires it so it makes sense to use buildGoModule = args: (nixos-2105.buildGoModules.override { go = go_1_17; }) (args // { ... }); (waiting #127519 to merge, so we can ditch overriding Go in the first place)

jtojnar added a commit to jtojnar/nixfiles that referenced this issue Sep 8, 2021
It now requires esbuild, which wants to download stuff as part of install script.
Fortunately, it can be bypassed by an environment variable.

evanw/esbuild#881

Also, annoyingly, Nixpkgs’s Go infrastructure does not support overriding attributes of buildGoPackage:

NixOS/nixpkgs#86349
@evanjs
Copy link
Member

evanjs commented Oct 17, 2021

Original Comment

The approach from #86349 (comment) worked for me (replacing modSha256 by its successor vendorSha256):

{
  kopia_unstable =
    let
      version = "ede09c15854ce74fde40603a6857ed3991ba666c";
      src = nixos-2105.fetchFromGitHub {
        owner = "kopia";
        repo = "kopia";
        rev = version;
        sha256 = "0wdkwpsgmycbiq8dvng3d0ps5qp87b7k1xvw8rv2wk1qzrrp6d93";
      };
    in
      (nixos-2105.callPackage "${nixos-2105.path}/pkgs/tools/backup/kopia" {
        buildGoModule = args: nixos-2105.buildGoModule (args // {
          vendorSha256 = "1idg6l9cnii6694kdmv9sc42c0bzk7pk67sdlglkaz52kg5hc6bd";
          inherit src version;
        });
      });
}

What about using nixos-2105.kopia.override instead of nixos-2105.callPackage "${nixos-2105.path}/pkgs/tools/backup/kopia"? This works when Nix is in restricted mode (in my case I was using flake).

Also Go 1.17 is already out, and latest Tailscale requires it so it makes sense to use buildGoModule = args: (nixos-2105.buildGoModules.override { go = go_1_17; }) (args // { ... }); (waiting #127519 to merge, so we can ditch overriding Go in the first place)

Stumbled across this comment after realizing I couldn't build tailscale, but before I realized that's what this comment was about (tailscale specifically)😂

Seems to work fine with override, and no wonder it was failing to build until I overrode the go version used.

Tailscale 1.16.0 Override
tailscaleLatest =
    let
      version = "1.16.0";
      src = pkgs.fetchFromGitHub {
        owner = "tailscale";
        repo = "tailscale";
        rev = "v${version}";
        sha256 = "sha256-wrC6bvC1f6SFY/SwVUW1+xuF1sk2jA9apMpo4jE2bFw=";
      };
    in
    (pkgs.tailscale.override rec {
      buildGoModule = args: pkgs.buildGoModule.override { go = pkgs.go_1_17; } (args // {
        inherit src version;
        vendorSha256 = "sha256-HJLT0CGUVzJZ56vS/v3FZ7svxyzZ+wlXvrC2MExTLM4=";
      });
    });

Thanks for the pointer on overriding go in buildGoModule, I had not dug into Tailscale changes that far and did not realize a new Go version was required 🤪

Ancient123 pushed a commit to EspressoSystems/cape that referenced this issue Dec 7, 2021
Inline geth nix derivation in repo and use submodule for code

We can't simply override the `src` attribute of the go-ethereum
derivation because this doesn't work with vendored go dependencies.
For more info: NixOS/nixpkgs#86349 .

Here we copy the nix derivation from nixpkgs to ./nix/go-ethereum folder
of this repo. Nix will print a mismatch to the console if the vendored
geth dependencies change. In that case the new vendorSha256 in the
inlined geth nix derivation in ./nix/go-ethereum/ needs to be updated.

This is a stop-gap solution so we can all work with the same version
of geth until we find a better way to enable that.
@ShamrockLee
Copy link
Contributor

ShamrockLee commented Mar 22, 2022

In #158486, I work around this issue by passing related attributes including veniorSha256 as inputs, so that they can be owerrided with the override attribute of the resulted package. An example can be found here:

https://github.com/ShamrockLee/nixpkgs/blob/singularity-apptainer/pkgs/applications/virtualization/singularity/generic.nix#L21-L24=

Nevertheless, I still hope that this issue can be fixed. If not, we should at least document the workaround.

Overlay-style overridable mkDerivation (#119942) might be one of the ultimate solutions to issues of this kind. See #171586.

@Lillecarl
Copy link
Contributor

@Mic92 Do you have a complete example for those of us who are still learning the language? :)

    zabbix-overlay =
      (self: super: super.zabbix.agent2.overrideAttrs (
            let
              version = "5.4.11";
              src = super.fetchurl {
                url = "https://cdn.zabbix.com/zabbix/sources/oldstable/5.4/zabbix-5.4.11.tar.gz";
                sha256 = "sha256-mxEsUFlnDB8MHWX6zWZaETNzNW6ut9ro28hXGG490kQ=";
              };
            in
            rec {
              name = "zabbix.agent2";
              inherit src;
              go-modules = (self.buildGoModule {
                inherit name src;
                vendorSha256 = "sha256-4Z4Fgv9zmAwp3tEvHj8yLOWkFY/zFz5VfehSWCuIUcI=";
              }).go-modules;
            }
        )
      );

I'm getting an infinite loop here.

@Mic92
Copy link
Member

Mic92 commented Dec 13, 2022

@Mic92 Do you have a complete example for those of us who are still learning the language? :)

    zabbix-overlay =
      (self: super: super.zabbix.agent2.overrideAttrs (
            let
              version = "5.4.11";
              src = super.fetchurl {
                url = "https://cdn.zabbix.com/zabbix/sources/oldstable/5.4/zabbix-5.4.11.tar.gz";
                sha256 = "sha256-mxEsUFlnDB8MHWX6zWZaETNzNW6ut9ro28hXGG490kQ=";
              };
            in
            rec {
              name = "zabbix.agent2";
              inherit src;
              go-modules = (self.buildGoModule {
                inherit name src;
                vendorSha256 = "sha256-4Z4Fgv9zmAwp3tEvHj8yLOWkFY/zFz5VfehSWCuIUcI=";
              }).go-modules;
            }
        )
      );

I'm getting an infinite loop here.

Try packageOverrides instead to avoid infinite recursions due the overlay.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/inconsistent-vendoring-in-buildgomodule-when-overriding-source/9225/7

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/use-a-specific-version-of-terraform-in-a-nix-shell/27880/1

havaker added a commit to havaker/ollama-nix that referenced this issue Nov 19, 2023
overrideAttrs does not combine well with buildGoModule (see
NixOS/nixpkgs#86349 for details), so I went
with a simple approach of defining a new derivation instead.
dminca added a commit to dminca/nix-config that referenced this issue Jul 7, 2024
* this is a terrible hack but unfortunately it's necessary because
  buildGoModule computes the vendorHash after installing all Go modules
* although overriding the vendorHash works just fine, there's still
  something wrong because the overlay is not applied properly, as per

    kluctl --version
    kluctl version v2.22.1

Resolves:
Related: NixOS/nixpkgs#86349
Signed-off-by: Daniel-Andrei Minca <[email protected]>
@ShamrockLee
Copy link
Contributor

While #234651 is under discussion, I reimplemented #225051 to address this issue with minimal expression changes. #225051 is now ready for review.

@doronbehar
Copy link
Contributor Author

Closing as this is fixed since #225051 is merged.

dminca added a commit to dminca/nix-config that referenced this issue Oct 22, 2024
* this is a terrible hack but unfortunately it's necessary because
  buildGoModule computes the vendorHash after installing all Go modules
* although overriding the vendorHash works just fine, there's still
  something wrong because the overlay is not applied properly, as per

    kluctl --version
    kluctl version v2.22.1

Resolves:
Related: NixOS/nixpkgs#86349
Signed-off-by: Daniel-Andrei Minca <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests