diff --git a/README.md b/README.md index 7db5f21..8cf2817 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,61 @@ For more details on configuring `binfmt`, have a look at: Once you've run `nixos-rebuild` with these options, you can use the `--system` option to create images for other architectures. +## Using as a nixos-module + +`nixos-generators` can be included as a `NixOS module` into your existing `configuration.nix` making all available formats available through `config.formats` and configurable through `config.formatConfigs`. New formats can be defined by adding a new entry like `config.formatConfigs.my-new-format = {config, ...}: {}`. + +An example `flake.nix` demonstrating this approach is below. + +images can be built from that flake by running: + +- `nix build .#nixosConfigurations.my-machine.config.formats.vmware` or +- `nix build .#nixosConfigurations.my-machine.config.formats.my-custom-format` or +- `nix build .#nixosConfigurations.my-machine.config.formats.` + +```nix +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + nixos-generators = { + url = "github:nix-community/nixos-generators"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = { self, nixpkgs, nixos-generators, ... }: { + + # A single nixos config outputting multiple formats. + # Alternatively put this in a configuration.nix. + nixosModules.my-machine = {config, ...}: { + imports = [ + nixos-generators.nixosModules.all-formats + ]; + + nixpkgs.hostPlatform = "x86_64-linux"; + + # customize an existing format + formatConfigs.vmware = {config, ...}: { + services.openssh.enable = true; + }; + + # define a new format + formatConfigs.my-custom-format = {config, modulesPath, ...}: { + imports = ["${toString modulesPath}/installer/cd-dvd/installation-cd-base.nix"]; + formatAttr = "isoImage"; + filename = "*.iso"; + networking.wireless.networks = { + # ... + }; + }; + + # the evaluated machine + nixosConfigurations.my-machine = nixpkgs.lib.nixosSystem { + modules = [self.nixosModules.my-machine]; + }; + }; +} +``` + ## Using in a Flake `nixos-generators` can be included as a `Flake` input and provides diff --git a/all-formats.nix b/all-formats.nix index 7784f1c..3b4857f 100644 --- a/all-formats.nix +++ b/all-formats.nix @@ -1,8 +1,13 @@ { + config, lib, extendModules, ... }: let + inherit + (lib) + types + ; # attrs of all format modules from ./formats formatModules = lib.flip lib.mapAttrs' (builtins.readDir ./formats) @@ -21,7 +26,7 @@ }; # evaluated configs for all formats - allConfigs = lib.mapAttrs (formatName: evalFormat) formatModules; + allConfigs = lib.mapAttrs (formatName: evalFormat) config.formatConfigs; # attrset of formats to be exposed under config.system.formats formats = lib.flip lib.mapAttrs allConfigs ( @@ -37,13 +42,22 @@ in { key = "github:nix-community/nixos-generators/all-formats.nix"; # declare option for exposing all formats - options.system.formats = lib.mkOption { + options.formats = lib.mkOption { type = lib.types.lazyAttrsOf lib.types.raw; description = '' Different target formats generated for this NixOS configuratation. ''; }; + options.formatConfigs = lib.mkOption { + type = types.attrsOf types.deferredModule; + }; + # expose all formats - config.system = {inherit formats;}; + config.formats = formats; + + # + config.formatConfigs = lib.flip lib.mapAttrs formatModules (name: module: { + imports = [module]; + }); } diff --git a/checks/test-all-formats-flake/flake.nix b/checks/test-all-formats-flake/flake.nix new file mode 100644 index 0000000..9484890 --- /dev/null +++ b/checks/test-all-formats-flake/flake.nix @@ -0,0 +1,58 @@ +/* +Tests using the all-formats module through a flake. +- Tests if foramts can be customized. +- Tests if new foramts can be added +*/ +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + nixos-generators = { + url = "github:nix-community/nixos-generators"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = { + self, + nixpkgs, + nixos-generators, + ... + }: { + nixosModules.my-machine = {config, ...}: { + imports = [ + nixos-generators.nixosModules.all-formats + ]; + + nixpkgs.hostPlatform = "x86_64-linux"; + + # customize an existing format + formatConfigs.vmware = {config, ...}: { + services.openssh.enable = false; + }; + + # define a new format + formatConfigs.my-custom-format = { + config, + modulesPath, + ... + }: { + imports = ["${toString modulesPath}/installer/cd-dvd/installation-cd-base.nix"]; + formatAttr = "isoImage"; + filename = "*.iso"; + networking.wireless.networks = { + # ... + }; + }; + }; + + nixosConfigurations.my-machine = nixpkgs.lib.nixosSystem { + modules = [self.nixosModules.my-machine]; + }; + + checks.x86_64-linux = { + test-flake_vmware = + self.nixosConfigurations.my-machine.config.formats.vmware; + test-flake_my-custom-format = + self.nixosConfigurations.my-machine.config.formats.my-custom-format; + }; + }; +} diff --git a/checks/test-all-formats.nix b/checks/test-all-formats.nix index acb3362..edfcb65 100644 --- a/checks/test-all-formats.nix +++ b/checks/test-all-formats.nix @@ -28,6 +28,6 @@ testedFormats = lib.filterAttrs (name: _: ! exclude ? ${name}) - conf.config.system.formats; + conf.config.formats; in testedFormats diff --git a/checks/test-customize-format.nix b/checks/test-customize-format.nix new file mode 100644 index 0000000..b26d65f --- /dev/null +++ b/checks/test-customize-format.nix @@ -0,0 +1,27 @@ +{ + nixpkgs ? , + system ? builtins.currentSystem, + lib ? import (nixpkgs + /lib), +}: let + nixosSystem = import (nixpkgs + /nixos/lib/eval-config.nix); + + userModule1 = {...}: { + formatConfigs.amazon.amazonImage.name = "xyz"; + }; + + userModule2 = {...}: { + formatConfigs.amazon.amazonImage.name = lib.mkForce "custom-name"; + }; + + conf = nixosSystem { + inherit system; + modules = [ + ../configuration.nix + ../all-formats.nix + userModule1 + userModule2 + ]; + }; +in + assert lib.hasInfix "custom-name" "${conf.config.formats.amazon}"; + conf.config.formats.amazon diff --git a/flake.nix b/flake.nix index a6c2742..be0aaa5 100644 --- a/flake.nix +++ b/flake.nix @@ -11,15 +11,45 @@ self, nixpkgs, nixlib, - }: - # Library modules (depend on nixlib) + } @ inputs: let + lib = nixpkgs.lib; + + callFlake = flake: let + args = + inputs + // { + nixos-generators = self; + self = subFlake; + }; + subFlake = (import flake).outputs args; + in + subFlake; + + # Ensures a derivation's name can be accessed without evaluating it deeply. + # Prevents `nix flake show` from being very slow. + makeLazyDrv = name: drv: { + inherit name; + inherit + (drv) + drvPath + outPath + outputName + ; + type = "derivation"; + }; + in + # Library modules (depend on nixlib) { # export all generator formats in ./formats - nixosModules = nixlib.lib.mapAttrs' (file: _: { - name = nixlib.lib.removeSuffix ".nix" file; - # The exported module should include the internal format* options - value.imports = [(./formats + "/${file}") ./format-module.nix]; - }) (builtins.readDir ./formats); + nixosModules = + { + all-formats = ./all-formats.nix; + } + // (nixlib.lib.mapAttrs' (file: _: { + name = nixlib.lib.removeSuffix ".nix" file; + # The exported module should include the internal format* options + value.imports = [(./formats + "/${file}") ./format-module.nix]; + }) (builtins.readDir ./formats)); # example usage in flakes: # outputs = { self, nixpkgs, nixos-generators, ...}: { @@ -109,23 +139,35 @@ }); checks = - nixpkgs.lib.genAttrs ["x86_64-linux" "aarch64-linux"] + lib.recursiveUpdate + (callFlake ./checks/test-all-formats-flake/flake.nix).checks ( - system: let - allFormats = import ./checks/test-all-formats.nix { - inherit nixpkgs system; - }; - in - { - inherit - (self.packages.${system}) - nixos-generate - ; - is-formatted = import ./checks/is-formatted.nix { - pkgs = nixpkgs.legacyPackages.${system}; + lib.genAttrs ["x86_64-linux" "aarch64-linux"] + ( + system: let + allFormats = import ./checks/test-all-formats.nix { + inherit nixpkgs system; }; - } - // allFormats + test-customize-format = import ./checks/test-customize-format.nix { + inherit nixpkgs system; + }; + in + lib.mapAttrs makeLazyDrv ( + { + inherit + (self.packages.${system}) + nixos-generate + ; + + inherit test-customize-format; + + is-formatted = import ./checks/is-formatted.nix { + pkgs = nixpkgs.legacyPackages.${system}; + }; + } + // allFormats + ) + ) ); devShells = forAllSystems (system: let