How to import function with arguments

Hi there :wave:

I’d like to use something like this function (I hope “function” is the correct name here). I’ve trimmed it down a bit, but sadly I couldn’t manage to import this to my system configuration like:

{ pkgs, lib, config, ... }:
{
  imports =
  [
    ./mountmodule.nix {
      inherit pkgs lib;
      keyFile = /root/.decrypt-file;
      mountPoint = /encrypted;
      sourceFile = /encrypted-file;
      fsType = "btrfs";
      fsLabel = "encVol";
    }

    (and other modules ..)
  ];
}

Function has same arguments with what has given above.

This fails either with:

error: anonymous function at ...location/mountmodule.nix:1:1 called with unexpected argument 'config', at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:224:8

or like this, if I add ... to the arguments list the function accepts:

error: The option `fsLabel' defined in `...location/common.nix' does not exist.

Which exists but I assume fails because of default parameters passed (e.g. modulesPath or similar).

Any help would be appreciated :confused:

1 Like

If ./mountmodule.nix is a module, then just add it to your imports list and set its defined options later in the file.

If it is a function, that returns a module, you need to wrap it in parenthesis like this:

    (./mountmodule.nix {
      inherit pkgs lib;
      keyFile = /root/.decrypt-file;
      mountPoint = /encrypted;
      sourceFile = /encrypted-file;
      fsType = "btrfs";
      fsLabel = "encVol";
    })

I thought it was a function, but wrapping it gave the error:

error: attempt to call something which is not a function but a path, at ...location/common.nix:14:6

What should I do to convert this to a function? Source is here: https://gist.github.com/seqizz/887063ab128a0b9831b9acdedcf79d49

Again, If the file contains a module, just use the path and set it’s options in your importing file.

A module is a function taking current config and returning an attrset with 3 keys, imports, config and options.

If no new options are defined it can also drop the top-level layer of keys and return config directly, as eg. The configuration.nix usually does.

And I’m just realising, my proposed syntax for a function that returns a module was wrong. It needs to use import statement:

import ./mountmodule.nix { ... }

Wrapped in parentheses of course.

Though I really doubt that the mountmodule.nix is supposed to work like that.

To be sure about how to use it, please show it’s actual code.

I’m not sure how to provide more sources :slightly_smiling_face: Original post has the import method, second post has the link to mountmodule.
Although I’ve been trying to make this work, I’ve also ended up something like this to make it a “module”, which of course, didn’t work. https://gist.github.com/seqizz/cba3e066025c945dffd0aa57057753f3 (404 now)

Sorry, I haven’t seen the link in the OP.

Skimming the file behind the link, you can’t use it as an imports.

Perhaps you can call it and merge it into your top-level attribute set?

The reworked module you posted seems to be fine, though its usable only once, as merging values would create strange results.

What was your problem with it? How did you use it?

I was trying to mount a luks-formatted file automatically. Since normal filesystems."<file>".encrypted notation only supports block devices, I’ve tried to use this thing, but apparently I still suck at Nix.

Ended up defining a oneshot systemd service inside my configuration, which runs the needed cryptsetup command and enforces itself before mount service…

Thanks for the help though.