I’d like to set a “global” option from within a submodule, but the config I return is grafted into the “global” under the submodule “path” rather than at the root… any idea if it’s somehow possible?

Er… I guess I didn’t make a great job at explaining what I want to do… Some code will hopefully help.

In mymodule.nix I have:

{ lib, config, ... }: {

  options.myoption = lib.mkOption {
      type = lib.types.attrsOf (lib.types.submodule (
        import ./mysubmodule.nix
      ));
  };

}

and mysubmodule.nix is:

{ name, lib, config, ... }: {

options.mysubmoduleoption = {
  type = lib.types.str;
};

config = {
  # here I want to set a "global" option, say "systemd.mounts"
  # based on the value of "mymodule.name.mysubmoduleoption"
  # but it seems I can only set values under "mymodule.name" 
};

}
    • gomp@lemmy.mlOP
      link
      fedilink
      arrow-up
      1
      ·
      edit-2
      10 months ago

      Your module only defines the option inside types.submodule - I’d (ideally, to better organize the code) want to also put the config section in the submodule.

      Ie. your code is structured similar to:

      options = {
          fileSystems = mkOption {
          type = types.attrsOf (types.submodule {
              options = {
                # bla bla
              };           
          };
          };
      };
      
      config = {
        # set options here
      };
      

      while what I would like to do is more like

      options = {
        fileSystems = mkOption {
          type = types.attrsOf (types.submodule {
            options = {
              # bla bla
            };
            config = {
              # set options here
            };
        };
      };
      

      The reason why I’m trying to do so is purely to restructure my code (which right now does has the config logic at the module, rather than submodule, level) in order to make it more readable/manageable, since it currently has jems like:

      config.services.restic.backups = builtins.listToAttrs (
        builtins.concatLists (lib.attrsets.mapAttrsToList (v-name: v-cfg: (
          builtins.concatLists (lib.attrsets.mapAttrsToList (s-name: s-cfg: (
            builtins.concatLists (lib.attrsets.mapAttrsToList (r-name: r-cfg: (
      

      I know I can restructure the code in other ways (eg. let .. in) - I just wanted to put the options definitions together with the code that uses them.

      • Atemu@lemmy.ml
        link
        fedilink
        arrow-up
        1
        ·
        10 months ago

        It doesn’t work like that. Submodules are for defining the type, so the only thing you get is interface (options), not implementation.

        I know I can restructure the code in other ways (eg. let .. in)

        Do that.

        Also be aware that some use-cases might be covered by library functions such as lib.flatMap or lib.pipe.

        • gomp@lemmy.mlOP
          link
          fedilink
          arrow-up
          1
          ·
          10 months ago

          Submodules are for defining the type, so the only thing you get is interface (options), not implementation.

          You do get a functional config in submodules… try this (it doesn’t do anything so you can just import into any configuration.nix):

          { config, lib, pkgs, modulesPath, specialArgs, options, ... }: {
          
            options.mynamespace = lib.mkOption {
              type = lib.types.attrsOf (lib.types.submodule ({name, config, ...}:{
                options = {
                  option1 = lib.mkOption { type = lib.types.str; default = ""; };
                  option2 = lib.mkOption { type = lib.types.str; default = ""; };
                };
                config = {
                  option2 = "derived from value of option1: '${config.option1}'";
                };
              }));
            };
          
            config = {
          
              mynamespace.submodule1.option1 = "value of option1";
          
              fileSystems = builtins.trace (builtins.toJSON config.mynamespace) {};
          
            };
          
          }