add support for multiple pkg channels

This commit is contained in:
do butterflies cry? 2026-02-13 12:38:53 +10:00
parent b56c07bc4c
commit 542f2ff3f4
4 changed files with 111 additions and 115 deletions

View file

@ -12,10 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
{ {
self,
this, this,
nixpkgs,
nixpkgs-unstable,
nt, nt,
lib, lib,
deploy-rs, deploy-rs,
@ -42,6 +39,11 @@
mapNodes mapNodes
; ;
inherit
(nt)
findImport
;
templateNexus = let templateNexus = let
inherit inherit
(nt.naive.terminal) (nt.naive.terminal)
@ -54,11 +56,8 @@
Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`. Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`.
''); '');
in { in {
overlays = [];
extraModules = []; extraModules = [];
specialArgs = Terminal {}; specialArgs = Terminal {};
# XXX: WARNING: extraPkgConfig is a terrible solution (but im lazy for now)
extraPkgConfig = Terminal {};
groups = Terminal {}; groups = Terminal {};
nodes = Terminal {}; nodes = Terminal {};
@ -71,7 +70,8 @@
isAttrs g isAttrs g
|| throw '' || throw ''
Cerulean Nexus groups must be provided as attribute sets, got "${typeOf g}" instead! Cerulean Nexus groups must be provided as attribute sets, got "${typeOf g}" instead!
Ensure all the `groups` definitions are attribute sets under your call to `cerulean.mkNexus`. Ensure all the group definitions are attribute sets under your call to `cerulean.mkNexus`.
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
''; '';
delegate = parent: gName: g: let delegate = parent: gName: g: let
result = result =
@ -126,20 +126,49 @@
in in
final; final;
importOverlays = root: let getGroupModules = root: nodeName: node:
path = findImport (root + "/overlay"); assert isList node.groups
in || throw ''
if pathExists path Cerulean Nexus node "${nodeName}" does not declare group membership as a list, got "${typeOf node.groups}" instead!
then import path Ensure `nexus.nodes.${nodeName}.groups` is a list under your call to `cerulean.mkNexus`.
else []; '';
node.groups
# XXX: TODO: create a function in NixTypes that handles this instead # ensure all members are actually groups
findImport = path: |> map (group: let
if pathExists path got =
then path if ! isAttrs group
else if pathExists (path + "default.nix") then toString group
then path + "/default.nix" else
else path + ".nix"; group
|> attrNames
|> map (name: "${name} = <${typeOf (getAttr name group)}>;")
|> concatStringsSep " "
|> (x: "{ ${x} }");
in
if group ? _name
then group
else
throw ''
Cerulean Nexus node "${nodeName}" is a member of an incorrectly structured group.
Got "${got}" of primitive type "${typeOf group}".
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
'')
# add all inherited groups via _parent
|> map (let
delegate = g:
if g._parent == null
then [g]
else [g] ++ delegate (g._parent);
in
delegate)
# flatten recursion result
|> concatLists
# find import location
|> map (group: findImport (root + "/groups/${group._name}"))
# filter by uniqueness
|> nt.prim.unique
# ignore missing groups
|> filter pathExists;
in { in {
mkNexus = root: outputsBuilder: let mkNexus = root: outputsBuilder: let
decl = parseDecl outputsBuilder; decl = parseDecl outputsBuilder;
@ -152,87 +181,21 @@ in {
outputs = rec { outputs = rec {
nixosConfigurations = mapNodes nexus.nodes ( nixosConfigurations = mapNodes nexus.nodes (
nodeName: node: nodeName: node: let
lib.nixosSystem { nixosDecl = lib.nixosSystem {
system = node.system; system = node.system;
modules = let specialArgs =
host = findImport (root + "/hosts/${nodeName}");
groups = assert isList node.groups
|| throw ''
Cerulean Nexus node "${nodeName}" does not declare group membership as a list, got "${typeOf node.groups}" instead!
Ensure `nexus.nodes.${nodeName}.groups` is a list under your call to `cerulean.mkNexus`.
'';
node.groups
# ensure all members are actually groups
|> map (group: let
got =
if ! isAttrs group
then toString group
else
group
|> attrNames
|> map (name: "${name} = <${typeOf (getAttr name group)}>;")
|> concatStringsSep " "
|> (x: "{ ${x} }");
in
if group ? _name
then group
else
throw ''
Cerulean Nexus node "${nodeName}" is a member of an incorrectly structured group.
Got "${got}" of primitive type "${typeOf group}".
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
'')
# add all inherited groups via _parent
|> map (let
delegate = g:
if g._parent == null
then [g]
else [g] ++ delegate (g._parent);
in
delegate)
# flatten recursion result
|> concatLists
# find import location
|> map (group: findImport (root + "/groups/${group._name}"))
# filter by uniqueness
|> nt.prim.unique
# ignore missing groups
|> filter pathExists;
in
[../nixos-module host]
++ groups
++ node.extraModules
++ nexus.extraModules;
# nix passes these to every single module
specialArgs = let
# XXX: NOTE: REF: https://github.com/NixOS/nixpkgs/blob/master/flake.nix#L57
# XXX: NOTE: lib.nixosSystem is defined here ^^^^
pkgConfig =
{
inherit (node) system;
# XXX: WARNING: TODO: i've stopped caring
# XXX: WARNING: TODO: just figure out a better solution to pkgConfig
config.allowUnfree = false;
config.allowBroken = false;
overlays =
self.overlays
++ nexus.overlays
++ node.overlays
++ importOverlays root;
}
// nexus.extraPkgConfig # TODO: import
// node.extraPkgConfig; # TODO: import
in
nexus.specialArgs nexus.specialArgs
// node.specialArgs // node.specialArgs
// { // {inherit root;};
inherit root; modules =
pkgs = import nixpkgs pkgConfig; [../nixos-module (findImport (root + "/hosts/${nodeName}"))]
upkgs = import nixpkgs-unstable pkgConfig; ++ getGroupModules root nodeName node
}; ++ node.extraModules
} ++ nexus.extraModules;
};
in
nixosDecl
); );
deploy.nodes = mapNodes nexus.nodes (nodeName: node: let deploy.nodes = mapNodes nexus.nodes (nodeName: node: let

View file

@ -31,8 +31,6 @@ in rec {
extraModules = []; extraModules = [];
specialArgs = Terminal {}; specialArgs = Terminal {};
overlays = []; overlays = [];
# XXX: WARNING: extraPkgConfig is a terrible solution (but im lazy for now)
extraPkgConfig = Terminal {};
deploy = { deploy = {
user = "root"; user = "root";

View file

@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
{deploy-rs, ...}: { {deploy-rs}: {
imports = [ imports = [
./nixpkgs.nix ./nixpkgs.nix
./home-manager.nix ./home-manager.nix

View file

@ -12,13 +12,24 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
{ {
nt,
lib, lib,
config, config,
... ...
}: let }: let
cfg = config.pkgrepo; inherit
(builtins)
mapAttrs
;
inherit
(nt)
flip
;
cfg = config.pkgsrc;
in { in {
options.pkgrepo = lib.mkOption { options.pkgsrc = lib.mkOption {
type = lib.types.attrsOf lib.types.attrs; type = lib.types.attrsOf lib.types.attrs;
default = {}; default = {};
description = "Declare and import custom package repositories."; description = "Declare and import custom package repositories.";
@ -34,15 +45,39 @@ in {
}; };
}; };
config.nixpkgs = config = let
lib.mkIf (cfg ? pkgs) # TODO: use lib.types.submodule to restrict what options
(let # TODO: can be given to pkgsrc
pkgs = cfg.pkgs; repos =
in cfg
lib.mkForce ( |> mapAttrs (
(builtins.removeAttrs pkgs ["source"]) name: args:
// { assert args ? source
flake.source = pkgs.source; || abort ''
} ${./.}
)); `pkgsrc.${name} missing required attribute "source"`
'';
args
|> flip removeAttrs ["source"]
|> import args.source
);
in {
# NOTE: _module.args is a special option that allows us to
# NOTE: set extend specialArgs from inside the modules.
# "pkgs" is unique since the nix module system already handles it
_module.args =
removeAttrs repos ["pkgs"];
# nixpkgs =
# lib.mkIf (cfg ? pkgs)
# (let
# pkgs = cfg.pkgs;
# in
# lib.mkForce (
# (removeAttrs pkgs ["source"])
# // {
# flake.source = pkgs.source;
# }
# ));
};
} }