[Nix-dev] Declaring filesystems using functions

phreedom at yandex.ru phreedom at yandex.ru
Wed May 27 10:28:29 CEST 2015


On Wednesday, May 27, 2015 08:49:13 Oliver Matthews wrote:
> So,
> 
> I have a bunch of containers that I want to bind mount specific directories
> into. For ease, I intend to mount them at the same point on the parent FS.
> 
> a mapped function struck me as the most obvious, but I can't quite get it to
> work - I have a sort of solution, but there is a layer of indirection which
> is beating me.
> 
> This works:
> 
> let bindFS = { container, dir }:
> { "/var/lib/containers/${container}/${dir}" = { device = "${dir}"; options =
> "${bind}"; }; }; in
> {
>   fileSystems =
>   bindFS { container="containerName"; dir="somedir1"; } //
>   bindFS { container="containerName"; dir="somedir2"; };
> }
> 
> I tried fileSystems = map bindFS [ { container=... But that fails as it
> creates anonymous items within fileSystems.

fileSystems = fold (x: y: x // y) {} (map bindFS [list of params] )

lib/ dir in nixpkgs has lots of attrset and list manipulation functions, 
which, even if not directly useful, can serve as examples of what is possible 
and how it's done.

In your particular case, I'd rather use lib.mapAttrs':

/* Like `mapAttrs', but allows the name of each attribute to be
     changed in addition to the value.  The applied function should
     return both the new name and value as a `nameValuePair'.

     Example:
       mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
          { x = "a"; y = "b"; }
       => { foo_x = "bar-a"; foo_y = "bar-b"; }
  */
  mapAttrs' = f: set:
    listToAttrs (map (attr: f attr set.${attr}) (attrNames set));




More information about the nix-dev mailing list