On Tue, Dec 27, 2022 at 11:16:03AM +0200, Valentin Kharin wrote: > Signed-off-by: Valentin Kharin > --- > flake.lock | 43 ++++++++++++++++++++++++++++++++ > flake.lock.license | 3 +++ > flake.nix | 62 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 108 insertions(+) > create mode 100644 flake.lock > create mode 100644 flake.lock.license > create mode 100644 flake.nix Hi! Thanks for v2! I've actually tried this out now, and it's nice! :) I have a couple of questions about how particular concepts will map to flakes: - How will custom configurations work? There are a few mechanisms that can be used today (NIX_PATH, config.nix in the source tree, passing an argument when importing Spectrum), but I don't think the flake exposes any of these? - How would using img/app/shell.nix to test different appvms work? Currently, I do e.g. nix-shell --arg run ../../vm/app/lynx.nix to get a shell where I can do a test run of that VM, but --arg apparently can't be used with flakes either. What would an equivalent workflow be? One code comment below as well. > diff --git a/flake.nix b/flake.nix > new file mode 100644 > index 0000000..ab54fed > --- /dev/null > +++ b/flake.nix > @@ -0,0 +1,62 @@ > +# SPDX-License-Identifier: MIT > +# SPDX-FileCopyrightText: 2022 Unikie > + > +{ > + description = "A compartmentalized operating system"; > + > + # NOTE: Revision specification format is ?ref=refs%2fheads%2f&rev= > + inputs.nixpkgs.url = > + "git+https://spectrum-os.org/git/nixpkgs/?ref=refs%2fheads%2frootfs"; > + inputs.flake-utils.url = "github:numtide/flake-utils"; > + > + nixConfig = { > + extra-substituters = [ "https://cache.dataaturservice.se/spectrum/" ]; > + trusted-public-keys = [ > + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" > + "spectrum-os.org-1:rnnSumz3+Dbs5uewPlwZSTP0k3g/5SRG4hD7Wbr9YuQ=" > + ]; > + }; > + > + outputs = { self, nixpkgs, flake-utils }: > + let > + supportedSystems = with flake-utils.lib.system; [ x86_64-linux aarch64-linux ]; > + in flake-utils.lib.eachSystem supportedSystems (system: > + let > + pkgs = nixpkgs.legacyPackages.${system}; > + config = { inherit pkgs; }; > + lib = pkgs.lib; > + > + mkEntryPoint = { name ? builtins.baseNameOf path, path > + , enableShell ? true, enablePackage ? true }: > + let > + shell = { > + # NOTE: https://stackoverflow.com/a/43850372 > + devShells.${name} = > + import (path + "/shell.nix") { inherit config; }; > + }; > + package = { packages.${name} = import path { inherit config; }; }; > + in (if enableShell then shell else { }) > + // (if enablePackage then package else { }); > + > + # Entry point is a directory with shell.nix and default.nix > + # This function maps every entry point to corresponding devShell and package > + mapEntryPoints = epoints: > + builtins.foldl' lib.recursiveUpdate { } (map mkEntryPoint epoints); This set of helper functions (plus the flake-utils dependency) was a bit scary to me, so I did some experimentation on my own and came up with this: (I didn't bother adding every component.) outputs = { self, nixpkgs }: let inherit (nixpkgs.lib) foldAttrs mergeAttrs; in foldAttrs mergeAttrs {} (map (system: let config = { pkgs = nixpkgs.legacyPackages.${system}; }; in { devShells.${system} = { root = import ./shell.nix { inherit config; }; appvm = import img/app/shell.nix { inherit config; }; documentation = import ./Documentation { inherit config; }; initramfs = import host/initramfs/shell.nix { inherit config; }; }; packages.${system} = { documentation = import ./Documentation { inherit config; }; appvm = import img/app { inherit config; }; initramfs = import host/initramfs { inherit config; }; }; }) [ "aarch64-linux" "x86_64-linux" ]); So from what I can tell, flake-utils in particular wasn't really buying us much? IMO, it also ends up being a lot easier to understand without to have the components inlined like this, even at the expense of having to list a component twice if it needs to have both a package and a devShell. It saves people from having to figure out what a couple of fairly complicated functions are doing when they want to understand how things work or debug a problem. What do you think? > + in lib.recursiveUpdate (mapEntryPoints [ > + { > + path = ./.; > + enablePackage = false; > + } > + { path = ./host/initramfs; } > + { path = ./host/rootfs; } > + { path = ./host/start-vm; } > + { path = ./img/app; } > + { path = ./release/live; } > + { path = ./vm/sys/net; } > + ]) { > + # Add some other flake schema related stuff here. > + # NOTE: flake-utils.lib.eachDefaultSystem automagically adds ${system}. > + devShells.documentation = import ./Documentation { inherit config; }; > + packages.documentation = import ./Documentation { inherit config; }; > + }); > +} > -- > 2.38.1 > >