The papercut thread - post your small annoyances/confusions here

I’ve had similar but different (I think? It’s been a while) problems with tinc a while back, with service orders and I…don’t know. Stateful state is stateful. Made it real hard to get a reliable vpn while being able to do rebuilds…

Oh, oh, oH- that reminds me. We still don’t have a built in automatic rollback on network failure mechanism?

1 Like

Yeah, I believe that tinc is one of the services where I’ve had this happen as well. I recall it requiring a bunch of stateful setup ahead of time to make it work reliably.

Edit: Just did a fresh install with an existing fairly complex configuration, and the “CUPS Scheduler” service seemed to suffer from the same issue of having to rebuild twice before the service would start correctly.

More documentation papercuts:

  • The pname attribute (in mkDerivation) is not documented anywhere, in particular how it differs from name. Apparently the difference is that name is automagically composed of pname + version.
  • The makeDesktopItem utility function, used for creating menu entries and such, does not seem to be documented anywhere either.
3 Likes

the papercuts topic seems to have evolved into an “axecuts” topic.

I just wish we had “man nix” :slight_smile:

5 Likes

Just reminded of this one by a question on IRC:

  • There’s no way to run multiple instances (with a different configuration) of the same NixOS/nixpkgs service, unless the service is specifically designed to allow that. This conflicts pretty harshly with the “install any amount of copies of the same package” philosophy, and poses issues for more complex setups where you’d want to eg. run different versions of the same DB with a different ‘backing package’, on a different port.
4 Likes

Current package states and open issues to a package seem to be often unknown or ignored.

It happened twice to me that somebody pushed a breaking commit directly to the master and while figuring that out I came along some other PR which was kept back. The PR contained the same thing as the breaking commit and was kept back because it was known that it would break things… One time the PR was kept back for over 2 months when the commit was pushed.

I love to use NixOS unstable and report bugs, but I often find that people don’t seem to really know what’s going on with certain packages/issues and mis(sing )communication or duplicated work are not as rare as they maybe should be. I don’t want to say people have to know about things (Nixpkgs is too huge) but at least to me it seems that such package orientated information is harder to get than it should be.

Sure there is, it’s “just” non-obvious and annoyingly indirect:

containers = {
  postgres_one = { 
    config = { config, pkgs, ... }: {
      services.postgresql = {
        enable = true;
        package = pkgs.postgresql_9_6;
    };
    forwardPorts = [
      { hostPort = 15432; containerPort = 5432; protocol = "tcp"; }
    ];
  };
  postgres_two = { 
    config = { config, pkgs, ... }: {
      services.postgresql = {
        enable = true;
        package = pkgs.postgresql_10;
    };
    forwardPorts = [
      { hostPort = 15433; containerPort = 5432; protocol = "tcp"; }
    ];
  };
};

Here’s a papercut I ran into today, namely: @-patterns do not capture formal argument default values.

Take this test.nix:

with builtins;
{
  a = let
    f = { foo ? "bar", ... }@args: args;
  in f {};
  b = let
    f = { foo ? "bar", ... }@args: args // { inherit foo; };
  in f {};
  c = let
    f = { foo ? "bar", ... }@args: args // { foo = args.foo; };
  in f {};

  # Which makes it tricky to generically pass on @args to another function, inclusive of defaults:
  d = let
    f = { foo ? "bar", ... }@args: g args;
    g = attrs: attrs;
  in f {};

  # Although you can do something awkward like:
  e = let
    f = { ... }@args': let
      defaults = { foo = "bar"; };
      args = defaults // args';
    in g args;
    g = attrs: attrs;
  in {
    ea = f {};
    eb = f { foo = "nak"; };
  };
}

And then:

$ nix-instantiate --strict --eval test.nix -A a
{ }
$ nix-instantiate --strict --eval test.nix -A ab
error: attribute 'ab' in selection path 'ab' not found
$ nix-instantiate --strict --eval test.nix -A a
{ }
$ nix-instantiate --strict --eval test.nix -A b
{ foo = "bar"; }
$ nix-instantiate --strict --eval test.nix -A c
error: attribute 'foo' missing, at ~/tmp/nix/defaultargs/test.nix:10:52
(use '--show-trace' to show detailed location information)
$ nix-instantiate --strict --eval test.nix -A d
{ }
$ nix-instantiate --strict --eval test.nix -A e
{ ea = { foo = "bar"; }; eb = { foo = "nak"; }; }
3 Likes

Please use lib.bitAnd, lib.bitOr and lib.bitXor
There are lib.bitNot (which implemented in pure Nix and that’s why it is not in builtins. ) and fallback implementation of all the functions for older Nix.
builtins.bitAnd … work since a particular version of Nix (2.2.x?) while lib.bitAnd should work even in Nix1, using builtins.bitAnd when available

  • src=./. in a default.nix will copy to the store with a name that depends on the name of the folder you are in, which is really a shame for reusability of binary builds.
2 Likes

That creates containers, it doesn’t create multiple services. Those are not the same thing :slight_smile:

That doesn’t make it any less inconsistent, though. And somebody may not necessarily be using nixpkgs, in which case they don’t have access to the lib methods at all. That’s the root of my complaint there; why are there builtins for and/or/xor but not for not? Clearly any one of them could have existed in nixpkgs code rather than natively, so why is not special?

1 Like

Well, we’re both splitting hairs here, but it does meet your specified example of “run different versions of the same DB with a different ‘backing package’, on a different port” ;).

Generally speaking, you can pretty much always wire up nixos containers to effectively provide multiple versions of a given service, but it can take a fair bit of work, and it’s definitely less than I deal. I do think you are right, and that we would be much better off if there was a standard interface and set of implementation methods for doing multiple-instance service modules.

There’s several existing multiple-instance service modules in nixpkgs, and of course systemd provides templated service files, so there should be enough exemplars to analyse and draw inspiration from. Someone “just” needs to figure out a nice abstraction and implement it.

1 Like

Of course, if you really want multiple services it is also possible to evaluate the services in separate NixOS instantiations, extract the service list entries and then add them into the service list of the main configuration.

Which is even less direct, of course…

(I know it works, because I extract service starter scripts out of NixOS services to use on non-NixOS)

The result depends on word size and handling of negative numbers, unlike and, or and xor. For instance, you’d want bitNot 0 to evaluate to 255 when working with individual octets of an IPv4 address. I think xoring with relevant constants (or use of (n: -1-n) in case of two’s complement arithmetic) is more appropriate to handle negation, even if it’s a bit more of a fuss.

Not only not: there are builtins.mul and builtins.div but no builtins.mod (while lib. has all three)

builtins. is not a core library like <stdio.h> or Prelude, it is just set of functions implemented in C++ rather than Nix.

Should it be a complete core library? Probably, yes. It is a topic to discuss.
But currently it is minimal set of functions which cannot be implemented on pure Nix (or the implementation in Nix would be very ineffective; in contrary builtins. has some high-level functions, which should not be in “core” library, but they are in in builtins. for performance reasons; so it has .concatMap but no .bitNot)

1 Like

There’s a workaround for this, which is src = builtins.path { path = ./.; name = "some-name"; } but it is rather non-obvious.

4 Likes

The derivation builtin is actually implemented in Nix code as a wrapper around derivationStrict. On my system the implementation is at /nix/store/6igqrrda7q52c4fc4wca7firf7rylpk6-nix-2.2.2/share/nix/corepkgs/derivation.nix (and the folder /nix/store/6igqrrda7q52c4fc4wca7firf7rylpk6-nix-2.2.2/share/nix/corepkgs/ is the sole entry of builtins.nixPath if NIX_PATH is empty). Surely we could provide other “builtins” using this same mechanism, so that way things like mod are available without nixpkgs?

Incidentally, the parent corepkgs dir has some other files in it, including a couple that define derivations (like one fetchurl.nix), but I don’t know what they’re for.

Is this public? I have a colleague interested in making use of bits of NixOS’ systemd stuff on non-NixOS systems, they might like to take a look. I would even if they don’t :P.

Is this public? I have a colleague interested in making use of bits of NixOS’ systemd stuff on non-NixOS systems, they might like to take a look. I would even if they don’t :P.

It is based on a few public but hard to find texts (no, I cannot find them immediately); the version I use is https://github.com/7c6f434c/7c6f434c-configurations/blob/09b7776d180b30fd57986f7cf0774f5aa9b8016a/lang-os/use-from-nixos.nix (which I mention from time to time)

I wanted to generate systemd thingies with nix at some point and it’s a relatively extremely obscure corner of the system (you have to call some strange thing located in nixpkgs that processes the configuration set…? Something like that.) to extract them out of… +1 for doing a bit of a writeup on that or something. Please. That’s probably the serviceScript function.

I would encourage people to open separate issue for each papercut, no matter how small. This thread has quickly blown up and I doubt it is useful for anything other than venting frustrations now.

Unlike omnibus threads, small issues can be easily triaged, tagged and comments are not mixed up together like in linear discussion here.

You do not even need to be very specific in the issue description, we can always fill the details in later.

2 Likes