let inherit (import ../default.nix { }) pkgs inputs; inherit (pkgs) lib; inherit (lib) mkOption types; eval = module: (lib.evalModules { specialArgs = { inherit inputs; # to be passed to nixops4Deployment resourceProviderSystem = builtins.currentSystem; }; modules = [ module ./data-model.nix ]; }).config; nixops4Deployment = import ./deployment.nix { inherit lib inputs; }; in { test-eval = { expr = let fediversity = eval ( { config, ... }: { _class = "fediversity-settings"; config = { resources.nixos-configuration = { description = "An entire NixOS configuration"; request = { ... }: { _class = "fediversity-resource-request"; options.config = mkOption { description = "Any options from NixOS"; }; }; policy = { config, ... }: { _class = "fediversity-resource-policy"; options = { extra-config = mkOption { description = "Any options from NixOS"; }; apply = mkOption { type = with types; functionTo raw; default = requests: lib.mkMerge (requests ++ [ config.extra-config ]); }; }; }; }; resources.login-shell = { _class = "fediversity-resource"; description = "The operator needs to be able to log into the shell"; request = { ... }: { _class = "fediversity-resource-request"; options = { wheel = mkOption { description = "Whether the login user needs root permissions"; type = types.bool; default = false; }; packages = mkOption { description = "Packages that need to be available in the user environment"; type = with types; attrsOf package; }; }; }; policy = { config, ... }: { _class = "fediversity-resource-policy"; options = { username = mkOption { description = "Username for the operator"; type = types.str; # TODO: use the proper constraints from NixOS }; wheel = mkOption { description = "Whether to allow login with root permissions"; type = types.bool; default = false; }; apply = mkOption { type = with types; functionTo raw; # TODO: splice out the user type from NixOS default = requests: let # Filter out requests that need wheel if policy doesn't allow it validRequests = lib.filterAttrs (_name: req: !req.wheel || config.wheel) requests; in lib.optionalAttrs (validRequests != { }) { ${config.username} = { isNormalUser = true; packages = with lib; concatMapAttrs (_name: request: attrValues request.packages) validRequests; extraGroups = lib.optional config.wheel "wheel"; }; }; }; }; }; }; applications.hello = { ... }: { _class = "fediversity-application"; description = ''Command-line tool that will print "Hello, world!" on the terminal''; module = { ... }: { _class = "fediversity-application-config"; options = { enable = lib.mkEnableOption "Hello in the shell"; }; }; implementation = cfg: lib.optionalAttrs cfg.enable { _class = "fediversity-application-requirements"; dummy.login-shell.packages.hello = pkgs.hello; }; }; environments.single-nixos-vm = { config, ... }: { _class = "fediversity-environment"; resources.shell.login-shell.username = "operator"; implementation = { ... }: # { providers, ... }: { # _class = "nixops4Deployment"; # providers = { # inherit (inputs.nixops4.modules.nixops4Provider) local; # }; resources.the-machine = { _class = "nixops4Resource"; # type = providers.local.exec; imports = [ inputs.nixops4-nixos.modules.nixops4Resource.nixos ]; nixos.module = { ... }: { _class = "nixos"; users.users = config.resources.shell.login-shell.apply ( # lib.filterAttrs (_name: value: value ? login-shell) requests lib.filterAttrs (_name: value: value ? login-shell) { } ); }; }; }; }; }; options = { example-configuration = mkOption { type = config.configuration; readOnly = true; default = { _class = "fediversity-configuration"; enable = true; applications.hello.enable = true; }; }; example-deployment = mkOption { type = types.submoduleWith { class = "nixops4Deployment"; modules = [ nixops4Deployment ]; }; readOnly = true; default = config.environments.single-nixos-vm.deployment config.example-configuration; }; }; } ); in { inherit (fediversity) example-configuration ; has-deployment = lib.isAttrs fediversity.example-deployment.resources.the-machine; }; expected = { example-configuration = { enable = true; applications.hello.enable = true; }; has-deployment = true; }; }; }