On Tue, Dec 27, 2022 at 11:16:03AM +0200, Valentin Kharin wrote:
Signed-off-by: Valentin Kharin <valentin.kharin@unikie.com> --- 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<BRANCH>&rev=<COMMIT_REVISION> + 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