Help building rqlite with buildGoModule

Hi all,

Noob here. Started using Nix very recently on my Debian instalation, and been slowly moving from Debian packages to Nix packages where I can/it makes sense. The plan is to eventually move to NixOS, and so I’m now trying to learn how to build projects.

My first goal project is rqlite. I’ve read through “Writing Nix Expressions”, and now I’m reading the Nixpkgs section on Go and the wiki. I copied the example over from the Nixpkgs manual and adapted it to this:

{ buildGoModule, fetchFromGitHub, lib }:
buildGoModule rec {
  name = "rqlite";
  version = "7.3.2";

  src = fetchFromGitHub {
    owner = "rqlite";
    repo = "rqlite";
    rev = "v${version}";
    sha256 = "sha256-C0S+zOCdWnUcbrpQeV4dK1n67GrAiYOJJv7VKoEQgUs=";
  };

  vendorSha256 = "sha256-Kr1Ug3zuSCeBucz0zpcouYfU0xKGmi0wi9Kh8+adHD4=";

  runVend = false;

  meta = with lib; {
    description = "The lightweight, distributed relational database built on SQLite";
    homepage = "http://www.rqlite.io";
    license = licenses.mit;
    platforms = platforms.linux ++ platforms.darwin;
  };
}

However, when building with nix-build -E 'with import <nixpkgs> {}; callPackage ./default.nix {}' it eventually gives this error:

# (...)
[http] 2022/03/02 23:16:30 HTTP service Serve() returned: accept tcp 127.0.0.1:33149: use of closed network connection
--- PASS: Test_MultiNodeClusterBootstrapLaterJoinHTTPS (2.15s)
=== RUN   Test_MultiNodeClusterRaftAdv
--- FAIL: Test_MultiNodeClusterRaftAdv (0.00s)
panic: couldn't find a local IPv4 address [recovered]
        panic: couldn't find a local IPv4 address

goroutine 846 [running]:
testing.tRunner.func1.2({0xafe4c0, 0xc981b0})
        testing/testing.go:1209 +0x24e
testing.tRunner.func1()
        testing/testing.go:1212 +0x218
panic({0xafe4c0, 0xc981b0})
        runtime/panic.go:1038 +0x215
github.com/rqlite/rqlite/system_test.mustGetLocalIPv4Address()
        github.com/rqlite/rqlite/system_test/helpers.go:665 +0xdc
github.com/rqlite/rqlite/system_test.Test_MultiNodeClusterRaftAdv(0xc0006e8000)
        github.com/rqlite/rqlite/system_test/cluster_test.go:518 +0x158
testing.tRunner(0xc0006e8000, 0xbfb1f0)
        testing/testing.go:1259 +0x102
created by testing.(*T).Run
        testing/testing.go:1306 +0x35a
FAIL    github.com/rqlite/rqlite/system_test    26.712s
FAIL
error: builder for '/nix/store/jfcmih3wa0iy0rs4052131qba5xqvx0l-rqlite.drv' failed with exit code 1

Apparently, this is from some rqlite test, but I’m wondering if it’s not because of something I’m doing wrong on the Nix side.

Some of the relevant Nix related info:

$ nix-env --version
nix-env (Nix) 2.6.1
$ nix-channel --list
nixpkgs https://nixos.org/channels/nixpkgs-unstable
$ nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version'
"22.05pre357729.22dc22f8ced"

For comparison I also looked at the default.nix file for Syncthing and Gotify, but at least to my untrained eyes there’s no significant difference.

Any help would be much appreciated!

Nix builds usually run in a sandbox (with a network namespace). In this namespace, i guess there is only one loopback interface, so this tests can’t succeed since it requires another interface: https://github.com/rqlite/rqlite/blob/e4fed0cee308c489e1806fece120654cf4ac8236/system_test/helpers.go#L659

You would need to either fix the test or skip it.

I see, thanks a lot!

Neither the Nixpkgs manual section on Go nor the wiki mention tests. But I think I found the source code for buildGoModule, and I think doCheck disables all tests; is that right? I added a doCheck = false and now the build succeeded!

$ /result/bin/rqlite --version
Version 7, commit unknown, branch unknown, built on unknown
$ ./result/bin/rqlited --version
rqlited 7 linux amd64 go1.17.7 (commit unknown, branch unknown, compiler gc)

Is there a way to disable specific tests? I’m not sure yet if it’ll be worth, maybe all or most of the test will need network too…


The working Nix file:

{ buildGoModule, fetchFromGitHub, lib }:
buildGoModule rec {
  name = "rqlite";
  version = "7.3.2";
  src = fetchFromGitHub {
    owner = "rqlite";
    repo = "rqlite";
    rev = "v${version}";
    sha256 = "sha256-C0S+zOCdWnUcbrpQeV4dK1n67GrAiYOJJv7VKoEQgUs=";
  };

  doCheck = false;
  runVend = false;
  vendorSha256 = "sha256-Kr1Ug3zuSCeBucz0zpcouYfU0xKGmi0wi9Kh8+adHD4=";

  meta = with lib; {
    description = "The lightweight, distributed relational database built on SQLite";
    homepage = "http://www.rqlite.io";
    license = licenses.mit;
    platforms = platforms.linux ++ platforms.darwin;
  };
}

AFAIK only by writing the Testphase yourself and use whatever go test has to filter tests.

Alternatively remove the known to fail tests from the source via a patch.

As said by @NobbZ, patching test files is a common pattern. I think you could also provide check flags to disable specific tests (depending on what the go test command is able to do).

Thanks to both!

@lewo do you know of any Go packages using those check flags? I’m not a Go programmer, so I don’t know what’s idiomatic there either…

But anyway, thanks! I’m happy already that I was able to build the thing! This is good enough for now, and later I’ll be back at it to try and improve it!