Search code examples
nixnixos

using the nix typing system with `nix-instantiate`


myservice

i've written a nixos service in myservice.nix and i include it in /etc/nixos/configuration.nix with:

imports [ /path/to/myservice.nix ]; 

and later i'm using it inside configuration.nix:

services.myservice.enable = true;

question

in one scenario i can't use nixos-rebuild switch but because typing in nix is linked to the options system using foo = mkOption { type = types.int; ...} i'm forced to use the options systems even though i just want to compute a configuration file for nginx using nix.

how to evaluate that nginx.conf only?

@aszlig wrote me this command:

nix-instantiate --eval --strict -E '(import <nixpkgs/nixos> { configuration = { imports = [ nixcloud-reverse-proxy/nixcloud-reverse-proxy.nix ]; services.nixcloud-reverse-proxy.enable = true; }; }).config.system.build.configsFromPath'

execution results in

nix-instantiate --eval --strict -E '(import <nixpkgs/nixos> { configuration = { imports = [ ./nixcloud-reverse-proxy.nix ]; services.nixcloud-reverse-proxy.enable = true; }; }).config.system.build.configsFromPath'
error: attribute ‘configsFromPath’ missing, at (string):1:1
(use ‘--show-trace’ to show detailed location information)

update

nix-build '<nixpkgs/nixos>' -A config.systemd.services.nixcloud-reverse-proxy.runner -I nixos-config=./configuration.nix
...
/nix/store/lp2jbb1wahhlr7qkq81rmfvk84mjk1vk-nixcloud-reverse-proxy-runner

now i can use that to grep the conf file:

cat /nix/store/lp2jbb1wahhlr7qkq81rmfvk84mjk1vk-nixcloud-reverse-proxy-runner  | grep -o ' /nix/store/.*nginx-reverse-proxy.conf'

... kind of a workaround but not very precise! i'd rather like a config file in a directory.


Solution

  • I see your file name is nginx-reverse-proxy.conf, so it isn't built with fancy NixOS module system, but with some other ways. In that case (you control how you build your file) you can include it globally:

     environment.etc."myconfigs"."nginx-reverse-proxy.conf".text = ...content of that file;
    

    Which your refer then with

    $ nix-instantiate --eval -E '
       with import <nixpkgs/nixos> {
           configuration = { ... };
       };
       config.environment.etc."myconfigs"."nginx-reverse-proxy.conf".text
      '
    

    You probably need to decode that output though using trick described in https://gist.github.com/danbst/a9fc068ff26e31d88de9709965daa2bd

    which is itself a convoluted way to do

    $ cat $(nix-build -E '
        with import <nixpkgs/nixos> {
          configuration = { ... };
        };
        config.environment.etc."myconfigs"."nginx-reverse-proxy.conf".source
      ')
    

    In case your proxy config is part of general nginx.conf script, then you still can get it using

    $ cat $(cat $(nix-build -E '
         with import <nixpkgs/nixos> {
           configuration = ...;
         };
         config.system.build.units."nginx.service".unit
       ')/nginx.service \
        | grep nginx.conf \
        | sed -r 's/.* (.*nginx.conf).*/\1/g'
      )
    

    Because nginx.conf file is private to nginx module, we can't reference it directly, but have to extract it directly from usage site.

    Overall, NixOS lacks a good interface to introspect its internals, but it is still possible.