Compare commits
25 commits
v0.2.1-alp
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 087f679e67 | |||
| d5211287bd | |||
| 18e1a2c890 | |||
| 232837d34a | |||
| f34c2fba39 | |||
| 870bbb1f37 | |||
| 0c5387fd61 | |||
| d85a6b963f | |||
| 59d1028e19 | |||
| 04d6bd04c3 | |||
| 0d85fe39a6 | |||
| af1da3dbc3 | |||
| ce996f9956 | |||
| c5ef764e27 | |||
| a2ac6b5da3 | |||
| fd3b11c7cf | |||
| 272b03aa6e | |||
| dc37c482a8 | |||
| 8dc975fc89 | |||
| c24cc9d46f | |||
| 803f759472 | |||
| 2cff3119cd | |||
| 9127e64fed | |||
| e07047ab50 | |||
| c5c867b43f |
15 changed files with 545 additions and 250 deletions
25
CHANGELOG.md
Normal file
25
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Changelog
|
||||
|
||||
## v0.2.0-alpha
|
||||
Initial "stable" release. Cerulean is currently usable and supports:
|
||||
1. local & remote deployment configuration
|
||||
2. nixos/homemanager module-level support for any number of nixpkg branches
|
||||
3. use of the [nix-systems standard](https://github.com/nix-systems/nix-systems), the introduction of the `snow/flake` standard, and the introduction of the `nixpkgs.nix` standard module.
|
||||
4. hierarchical groups for NixOS hosts via `snow.nix`
|
||||
|
||||
This is still a alpha-build of Cerulean. Everything will break in the future as I change the internals a bunch. I'll aim to write documentation in future cause currently there's no guide.
|
||||
|
||||
## v0.2.1-alpha
|
||||
Minor patches
|
||||
- cerulean no longer has a `inputs.nixpkgs-unstable` (the `nixpkgs.nix` is the new alternative)
|
||||
- `home-manager.nixosModules.default` and `microvm.nixosModules.microvm` are added as default modules
|
||||
- fixed `groups.all` not being added to nodes with `groups = []`
|
||||
|
||||
## v0.2.2-alpha
|
||||
Minor patches
|
||||
- fixed `nexus.groups.all` not added to empty `nexus.nodes.*.groups` declarations
|
||||
- fixed bad propagation of inputs
|
||||
- forced system architecture to be specified per node
|
||||
- cerulean no longer depends on `nixpkgs`, `base` package set should be set instead
|
||||
- rename `extraModules` -> `modules`
|
||||
- rename `specialArgs` -> `args`
|
||||
50
README.md
50
README.md
|
|
@ -1,19 +1,51 @@
|
|||

|
||||

|
||||
|
||||
>[!WARNING]
|
||||
> ✨ **Under Construction** ✨
|
||||
> Cerulean has lived rent free in my head for the last 12 months.
|
||||
> I'm developing this project for personal use and especially
|
||||
> for use at my workplace. **Be not afraid!** It's only a matter
|
||||
> of time until Cerulean is ready for use!
|
||||
>
|
||||
> Cerulean is in an **experimental alpha release stage**.<br/>
|
||||
> **Be not afraid!** It's only a matter of time until Cerulean is ready for use!
|
||||
>
|
||||
> If you're curious about or want to use Cerulean then<br/>
|
||||
> *please please please* contact me on Bluesky [@dobutterfliescry.net](https://bsky.app/profile/dobutterfliescry.net).<br/>
|
||||
> (i would actually *melt* and fall in love with you...)
|
||||
|
||||
# 🌌 🚀 Cerulean Nexus
|
||||
The culmination of 2 years designing better Nix flakes. Cerulean removes the boilerplate of managing
|
||||
NixOS infrastructure by declaring each machine as a **node** and their relationships as *"Nexus Networks"*,
|
||||
virtual networks of servers that Cerulean can manage. Each Nexus is **very powerful**. Allowing for simple
|
||||
distributed computing, automatic construction of VPNs, DNS for local hostnames, and that's just scratching the surface...
|
||||
|
||||
- Is your node a VPS? Set `deploy.ssh.host = "example.com"` and Cerulean will configure custom build users,
|
||||
ssh deployment via custom PAM modules, etc etc
|
||||
- Is your node a VM? Set `vms = [ nodes.VM_NODE ]` on your host node, and Cerulean will configure
|
||||
all the bridging, NAT, and other networking you so desire!
|
||||
|
||||
## 🩷💜 Motivation
|
||||
Nix is intended as a non-restrictive & unopinionated system, which is amazing, but it also means
|
||||
every user develops their own standards to simplify their config. Cerulean however is very much
|
||||
opinionated and contains all the standards I personally believe should be sane defaults for every NixOS machine.
|
||||
|
||||
> Flakes are not designed for NixOS, they're designed for Nix, and that's an important distinction.
|
||||
|
||||
Flakes and NixOS don't offer anything to simplify managing interconnected nodes of machines.
|
||||
But this ends with *extremely messy configs* with **a lot of footguns**. You shouldn't have to spend
|
||||
days reading about networking and learning to work with other peoples' modules.
|
||||
|
||||
Finally, the Nix module system assumes you only use one channel of `github:NixOS/nixpkgs` but this
|
||||
just isn't realistic. Most people have both `inputs.nixpkgs` and `inputs.nixpkgs-unstable` defined.
|
||||
So cerulean declares the `nixpkgs.channels.*` option so you don't have to import your channels
|
||||
manually!
|
||||
|
||||
## 💙 Same Colour, More Control
|
||||
Cerulean is what you wish Azure could be. An expansive collection of microservices, pre-configured systems,
|
||||
>[!NOTE]
|
||||
> This section is *mostly* for the business minded people.
|
||||
|
||||
Cerulean is what you wish Azure could be. Providing an expansive collection of microservices, pre-configured systems,
|
||||
and entirely self-hosted! Cerulean is built using NixOS as a foundation so you know it's never going to break randomly.
|
||||
NixOS backing makes Cerulean **extremely scalable**! Just rent a new VPS and Cerulean will build an ISO of your configuration.
|
||||
|
||||
No stress, no hassle!
|
||||
Say goodbye to Azure! And say goodbye to Kubernetes! You're taking life into your own hands 💙
|
||||
|
||||
### 🌌 🚀 Nexus
|
||||
Cerulean allows you to declare *"Nexus Networks"*, virtual networks of servers that Cerulean can manage.
|
||||
Each Nexus is **very powerful**. Allowing for simple distributed computing, automatic construction of a wireguard
|
||||
VPN, distributed DNS for local hostnames, and that's just scratching the surface...
|
||||
|
|
|
|||
60
TODO.md
60
TODO.md
|
|
@ -1,14 +1,64 @@
|
|||
- [ ] base should automatically be set as the default (dont do anything with the default)
|
||||
- [ ] try to remove common foot guns, ie abort if the user provides the home-manager or microvm nixosModules
|
||||
since cerulean ALREADY provides these
|
||||
|
||||
- [ ] deploy port should default to the first port given to `services.openssh`
|
||||
|
||||
- [ ] use the Nix module system instead of projectOnto for `cerulean.mkNexus`
|
||||
- [ ] create an alternative to nixos-install called cerulean-install that
|
||||
allows people to easily bootstrap new machines (and host it on dobutterfliescry.net)
|
||||
|
||||
- [ ] find an alternative to `nix.settings.trusted-users` probably
|
||||
- [ ] add the ceru-build user,
|
||||
- [ ] add support for github:microvm-nix/microvm.nix
|
||||
- [ ] add support for sops-nix
|
||||
|
||||
- [ ] create an alternative to nixos-install called cerulean-install that
|
||||
allows people to easily bootstrap new machines
|
||||
- [ ] it would be cool to enable/disable groups and hosts
|
||||
- [ ] find a standard for how nixpkgs.nix can have a different base per group
|
||||
|
||||
- [ ] go through all flake inputs (recursively) and ENSURE we remove all duplicates by using follows!!
|
||||
|
||||
- [X] rename nixos-modules/ to nixos/
|
||||
- [X] ensure all machines are in groups.all by default
|
||||
|
||||
- [X] fix nixpkgs.nix not working (default not respected)
|
||||
- [X] remove dependence on nixpkgs
|
||||
|
||||
- [ ] allow multiple privesc methods, the standard is pam_ssh_agent_auth
|
||||
|
||||
## Low Priority
|
||||
- [X] rename extraModules to modules?
|
||||
- [X] rename specialArgs to args?
|
||||
|
||||
- [ ] make an extension to the nix module system (different to mix)
|
||||
that allows transformations (ie a stop post config, ie outputs, which
|
||||
it then returns instead of config)
|
||||
|
||||
|
||||
- [ ] rename nixos-modules/ to nixos/
|
||||
- [ ] what if we automated the process of replacing windows with Nix??
|
||||
then push this to nixos-anywhere or nix-infect lmaooo
|
||||
|
||||
- [ ] patch microvm so that acpi=off https://github.com/microvm-nix/microvm.nix/commit/b59a26962bb324cc0a134756a323f3e164409b72
|
||||
cause otherwise 2GB causes a failure
|
||||
|
||||
- [ ] add the ceru-build user
|
||||
- [ ] ensure all machines are in groups.all by default
|
||||
- [ ] rewrite the ceru cli in rust
|
||||
- [ ] make `ceru` do local and remote deployments
|
||||
|
||||
- [ ] support `legacyImports`
|
||||
|
||||
```nix
|
||||
# REF: foxora
|
||||
vms = {
|
||||
home-assistant = {
|
||||
autostart = true;
|
||||
# matches in vms/*
|
||||
image = "home-assistant";
|
||||
options = {
|
||||
mem = 2048;
|
||||
};
|
||||
};
|
||||
equinox = {
|
||||
image = "home-assistant";
|
||||
};
|
||||
};
|
||||
```
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ mix.newMixture args (mixture: {
|
|||
./nexus
|
||||
];
|
||||
|
||||
version = "0.2.1";
|
||||
version = "0.2.2";
|
||||
|
||||
nixosModules = rec {
|
||||
default = cerulean;
|
||||
cerulean = ./nixos-module;
|
||||
cerulean = ./nixos;
|
||||
};
|
||||
|
||||
overlays = [
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@
|
|||
self,
|
||||
this,
|
||||
nt,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(builtins)
|
||||
all
|
||||
attrNames
|
||||
concatLists
|
||||
concatStringsSep
|
||||
|
|
@ -50,15 +50,11 @@
|
|||
(nt.naive.terminal)
|
||||
Terminal
|
||||
;
|
||||
|
||||
missing = msg: path:
|
||||
Terminal (abort ''
|
||||
Each Cerulean Nexus node is required to specify ${msg}!
|
||||
Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`.
|
||||
'');
|
||||
in {
|
||||
extraModules = [];
|
||||
specialArgs = Terminal {};
|
||||
base = null;
|
||||
modules = [];
|
||||
args = Terminal {};
|
||||
homeManager = null;
|
||||
|
||||
groups = Terminal {};
|
||||
nodes = Terminal {};
|
||||
|
|
@ -96,15 +92,15 @@
|
|||
assert isAttrs nexus
|
||||
|| abort ''
|
||||
Cerulean Nexus config must be provided as an attribute set, got "${typeOf nexus}" instead!
|
||||
Ensure all the `nexus` declaration is an attribute set under your call to `cerulean.mkNexus`.
|
||||
Ensure the `nexus` declaration is an attribute set under your call to `cerulean.mkNexus`.
|
||||
''; let
|
||||
base = nt.projectOnto templateNexus nexus;
|
||||
decl = nt.projectOnto templateNexus nexus;
|
||||
in
|
||||
# XXX: TODO: create a different version of nt.projectOnto that can actually
|
||||
# XXX: TODO: handle applying a transformation to the result of each datapoint
|
||||
base
|
||||
decl
|
||||
// {
|
||||
groups = parseGroupDecl base.groups;
|
||||
groups = parseGroupDecl decl.groups;
|
||||
};
|
||||
|
||||
parseDecl = outputsBuilder: let
|
||||
|
|
@ -133,7 +129,14 @@
|
|||
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 root group is always added
|
||||
(node.groups
|
||||
++ [
|
||||
{
|
||||
_parent = null;
|
||||
_name = ROOT_GROUP_NAME;
|
||||
}
|
||||
])
|
||||
# ensure all members are actually groups
|
||||
|> map (group: let
|
||||
got =
|
||||
|
|
@ -181,38 +184,63 @@ in {
|
|||
customOutputs = removeAttrs decl ["nexus"];
|
||||
|
||||
outputs = rec {
|
||||
nixosConfigurations = mapNodes nexus.nodes (
|
||||
nodeName: node: let
|
||||
nixosDecl = lib.nixosSystem {
|
||||
system = node.system;
|
||||
specialArgs = let
|
||||
specialArgs =
|
||||
nexus.specialArgs
|
||||
// node.specialArgs
|
||||
// {
|
||||
inherit root specialArgs;
|
||||
inherit (node) system;
|
||||
_deploy-rs = inputs.deploy-rs;
|
||||
};
|
||||
in
|
||||
specialArgs;
|
||||
modules =
|
||||
[
|
||||
self.nixosModules.default
|
||||
(findImport (root + "/hosts/${nodeName}"))
|
||||
nixosConfigurations = mapNodes nexus (
|
||||
{
|
||||
base,
|
||||
lib,
|
||||
nodeName,
|
||||
node,
|
||||
...
|
||||
}: let
|
||||
nixosDecl = let
|
||||
homeManager =
|
||||
if node.homeManager != null
|
||||
then node.homeManager
|
||||
else nexus.homeManager;
|
||||
|
||||
inputs.home-manager.nixosModules.default
|
||||
inputs.microvm.nixosModules.microvm
|
||||
]
|
||||
++ (getGroupModules root nodeName node)
|
||||
++ node.extraModules
|
||||
++ nexus.extraModules;
|
||||
};
|
||||
userArgs = nexus.args // node.args;
|
||||
ceruleanArgs = {
|
||||
inherit root base;
|
||||
inherit (node) system;
|
||||
_cerulean = {
|
||||
inherit inputs userArgs ceruleanArgs homeManager;
|
||||
specialArgs = userArgs // ceruleanArgs;
|
||||
};
|
||||
};
|
||||
specialArgs = assert (userArgs
|
||||
|> attrNames
|
||||
|> all (argName:
|
||||
! ceruleanArgs ? argName
|
||||
|| abort ''
|
||||
`specialArgs` are like super important to Cerulean my love... </3
|
||||
But `args.${argName}` is a reserved argument name :(
|
||||
''));
|
||||
ceruleanArgs._cerulean.specialArgs;
|
||||
in
|
||||
lib.nixosSystem {
|
||||
inherit (node) system;
|
||||
inherit specialArgs;
|
||||
modules =
|
||||
[
|
||||
self.nixosModules.default
|
||||
(findImport (root + "/hosts/${nodeName}"))
|
||||
|
||||
# inputs.microvm.nixosModules.microvm
|
||||
]
|
||||
++ (homeManager.nixosModules.default or [])
|
||||
++ (getGroupModules root nodeName node)
|
||||
++ node.modules
|
||||
++ nexus.modules;
|
||||
};
|
||||
in
|
||||
nixosDecl
|
||||
);
|
||||
|
||||
deploy.nodes = mapNodes nexus.nodes (nodeName: node: let
|
||||
deploy.nodes = mapNodes nexus ({
|
||||
nodeName,
|
||||
node,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(node.deploy)
|
||||
activationTimeout
|
||||
|
|
|
|||
|
|
@ -25,11 +25,22 @@ in rec {
|
|||
(nt.naive.terminal)
|
||||
Terminal
|
||||
;
|
||||
|
||||
missing = msg: path:
|
||||
Terminal (abort ''
|
||||
Each Cerulean Nexus node is required to specify ${msg}!
|
||||
Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`.
|
||||
'');
|
||||
in {
|
||||
system = "x86_64-linux"; # sane default (i hope...)
|
||||
enabled = true;
|
||||
system = missing "its system architecture" "system";
|
||||
groups = [];
|
||||
extraModules = [];
|
||||
specialArgs = Terminal {};
|
||||
modules = [];
|
||||
args = Terminal {};
|
||||
|
||||
homeManager = null;
|
||||
|
||||
base = null;
|
||||
|
||||
deploy = {
|
||||
user = "root";
|
||||
|
|
@ -66,7 +77,25 @@ in rec {
|
|||
in
|
||||
nt.projectOnto templateAttrs nodeAttrs;
|
||||
|
||||
mapNodes = nodes: f:
|
||||
nodes
|
||||
|> mapAttrs (nodeName: nodeAttrs: f nodeName (parseNode nodeName nodeAttrs));
|
||||
mapNodes = nexus: f:
|
||||
nexus.nodes
|
||||
|> mapAttrs (nodeName: nodeAttrs: let
|
||||
node = parseNode nodeName nodeAttrs;
|
||||
|
||||
# use per-node base or default to nexus base
|
||||
base =
|
||||
if node.base != null
|
||||
then node.base
|
||||
else if nexus.base != null
|
||||
then nexus.base
|
||||
else
|
||||
abort ''
|
||||
Cerulean cannot construct nexus node "${nodeName}" without a base package source.
|
||||
Ensure `nexus.nodes.*.base` or `nexus.base` is a flake reference to the github:NixOS/nixpkgs repository.
|
||||
'';
|
||||
in
|
||||
f {
|
||||
inherit nodeName node base;
|
||||
inherit (base) lib;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
108
cerulean/nexus/snow.nix
Normal file
108
cerulean/nexus/snow.nix
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Copyright 2026 Emile Clark-Boman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
# nexus
|
||||
options = let
|
||||
inherit
|
||||
(lib)
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
in {
|
||||
modules = mkOption {
|
||||
type = types.listOf types.path;
|
||||
};
|
||||
args = mkOption {
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
groups = mkOption {
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
nodes = mkOption {
|
||||
type = types.attrsOf (types.submoduleWith ({...}: {
|
||||
options = {
|
||||
enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
system = mkOption {
|
||||
type = types.enum inputs.systems;
|
||||
};
|
||||
groups = mkOption {
|
||||
type = types.list;
|
||||
};
|
||||
modules = mkOption {
|
||||
type = types.list;
|
||||
};
|
||||
args = mkOption {
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
deploy = {
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
sudoCmd = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
interactiveSudo = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
remoteBuild = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
autoRollback = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
magicRollback = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
activationTimeout = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
confirmTimeout = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
|
||||
ssh = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
opts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
};
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
# Copyright 2026 Emile Clark-Boman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
lib,
|
||||
system,
|
||||
config,
|
||||
contextName,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(builtins)
|
||||
mapAttrs
|
||||
;
|
||||
|
||||
cfg = config.nixpkgs.channels;
|
||||
in {
|
||||
options.nixpkgs.channels = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.attrs);
|
||||
default = {};
|
||||
description = "Declare package repositories per module context (nixos, home-manager, etc)";
|
||||
example = {
|
||||
"homes" = {
|
||||
"pkgs" = {
|
||||
source = "inputs.nixpkgs";
|
||||
system = "x86-64-linux";
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
allowBroken = false;
|
||||
};
|
||||
};
|
||||
"upkgs" = {
|
||||
source = "inputs.nixpkgs-unstable";
|
||||
system = "x86-64-linux";
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
allowBroken = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
# TODO: use lib.types.submodule to restrict what options
|
||||
# TODO: can be given to `nixpkgs.channels.${moduleName}.${name}`
|
||||
decl =
|
||||
cfg.${contextName} or cfg.default;
|
||||
|
||||
repos =
|
||||
decl
|
||||
|> mapAttrs (
|
||||
name: args:
|
||||
lib.mkForce (
|
||||
assert args ? source
|
||||
|| abort ''
|
||||
${toString ./.}
|
||||
`nixpkgs.channels.${contextName}.${name}` missing required attribute "source"
|
||||
'';
|
||||
((removeAttrs args ["source"])
|
||||
// {inherit system;})
|
||||
|> import args.source
|
||||
)
|
||||
);
|
||||
in {
|
||||
# NOTE: _module.args is a special option that allows us to
|
||||
# NOTE: set extend specialArgs from inside the modules.
|
||||
_module.args = repos;
|
||||
|
||||
nixpkgs = let
|
||||
defaultPkgs =
|
||||
decl.default or (throw ''
|
||||
Your `nixpkgs.nix` file does not declare a default package source.
|
||||
Ensure you set `nixpkgs.channels.*.default = ...;`
|
||||
'');
|
||||
in
|
||||
if contextName == "hosts"
|
||||
then {
|
||||
flake.source = lib.mkOverride 200 defaultPkgs.source;
|
||||
config = lib.mkOverride 200 defaultPkgs.config;
|
||||
}
|
||||
else if contextName == "homes"
|
||||
then {
|
||||
# XXX: XXX: XXX: OH OH OH OMG, its because aurora never defines pkgs
|
||||
config = lib.mkOverride 200 (defaultPkgs.config or {});
|
||||
# XXX: WARNING: TODO: modify options so overlays must always be given as the correct type
|
||||
overlays = lib.mkOverride 200 (defaultPkgs.overlays or []);
|
||||
}
|
||||
else {};
|
||||
};
|
||||
}
|
||||
36
cerulean/nixos/default.nix
Normal file
36
cerulean/nixos/default.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2026 Emile Clark-Boman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
root,
|
||||
system,
|
||||
_cerulean,
|
||||
...
|
||||
} @ args: {
|
||||
imports =
|
||||
[
|
||||
# user configuration
|
||||
(import (root + "/nixpkgs.nix"))
|
||||
# options declarations
|
||||
(import ./nixpkgs.nix (args // {contextName = "hosts";}))
|
||||
]
|
||||
++ (
|
||||
if _cerulean.homeManager != null
|
||||
then [./home-manager.nix]
|
||||
else []
|
||||
);
|
||||
|
||||
environment.systemPackages = with _cerulean.inputs; [
|
||||
deploy-rs.packages.${system}.default
|
||||
];
|
||||
}
|
||||
|
|
@ -13,10 +13,9 @@
|
|||
# limitations under the License.
|
||||
{
|
||||
root,
|
||||
system,
|
||||
config,
|
||||
lib,
|
||||
specialArgs,
|
||||
_cerulean,
|
||||
...
|
||||
} @ args: let
|
||||
inherit
|
||||
|
|
@ -26,25 +25,21 @@
|
|||
pathExists
|
||||
;
|
||||
in {
|
||||
config = {
|
||||
home-manager = {
|
||||
users =
|
||||
config.users.users
|
||||
|> attrNames
|
||||
|> filter (x: pathExists (root + "/homes/${x}"))
|
||||
|> (x: lib.genAttrs x (y: import (root + "/homes/${y}")));
|
||||
home-manager = {
|
||||
users =
|
||||
config.users.users
|
||||
|> attrNames
|
||||
|> filter (x: pathExists (root + "/homes/${x}"))
|
||||
|> (x:
|
||||
lib.genAttrs x (y:
|
||||
import (root + "/homes/${y}")));
|
||||
|
||||
extraSpecialArgs = {inherit root system;} // (specialArgs.inputs or {});
|
||||
sharedModules = [
|
||||
# user configuration
|
||||
(import (root + "/nixpkgs.nix"))
|
||||
# options declarations
|
||||
(import ./nixpkgs.nix (args // {contextName = "homes";}))
|
||||
];
|
||||
|
||||
# disable home-manager trying anything fancy
|
||||
# we control the pkgs now!!
|
||||
# useGlobalPkgs = true;
|
||||
};
|
||||
extraSpecialArgs = _cerulean.specialArgs;
|
||||
sharedModules = [
|
||||
# user configuration
|
||||
(import (root + "/nixpkgs.nix"))
|
||||
# options declarations
|
||||
(import ./nixpkgs.nix (args // {contextName = "homes";}))
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -11,22 +11,3 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
root,
|
||||
system,
|
||||
_deploy-rs,
|
||||
...
|
||||
} @ args: {
|
||||
imports = [
|
||||
# user configuration
|
||||
(import (root + "/nixpkgs.nix"))
|
||||
# options declarations
|
||||
(import ./nixpkgs.nix (args // {contextName = "hosts";}))
|
||||
|
||||
./home-manager.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = [
|
||||
_deploy-rs.packages.${system}.default
|
||||
];
|
||||
}
|
||||
13
cerulean/nixos/microvm-parent.nix
Normal file
13
cerulean/nixos/microvm-parent.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Copyright 2026 Emile Clark-Boman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
94
cerulean/nixos/nixpkgs.nix
Normal file
94
cerulean/nixos/nixpkgs.nix
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# Copyright 2026 Emile Clark-Boman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
base,
|
||||
lib,
|
||||
system,
|
||||
config,
|
||||
contextName,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(builtins)
|
||||
mapAttrs
|
||||
;
|
||||
|
||||
cfg = config.nixpkgs.channels;
|
||||
in {
|
||||
options.nixpkgs.channels = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
description = "Declare package repositories";
|
||||
example = {
|
||||
"pkgs" = {
|
||||
source = "inputs.nixpkgs";
|
||||
system = "x86-64-linux";
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
allowBroken = false;
|
||||
};
|
||||
};
|
||||
"upkgs" = {
|
||||
source = "inputs.nixpkgs-unstable";
|
||||
system = "x86-64-linux";
|
||||
config = {
|
||||
allowUnfree = false;
|
||||
allowBroken = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
repos =
|
||||
cfg
|
||||
|> (xs: removeAttrs xs ["default"])
|
||||
|> mapAttrs (
|
||||
name: args:
|
||||
lib.mkForce (
|
||||
assert args ? source
|
||||
|| abort ''
|
||||
`nixpkgs.channels.${name}` missing required attribute "source"
|
||||
'';
|
||||
import args.source ({inherit system;} // (removeAttrs args ["source"]))
|
||||
)
|
||||
);
|
||||
|
||||
# XXX: TODO: would it work to use `base` instead of having default?
|
||||
defaultPkgs =
|
||||
cfg.default or (throw ''
|
||||
Your `nixpkgs.nix` file does not declare a default package source.
|
||||
Ensure you set `nixpkgs.channels.*.default = ...;`
|
||||
'');
|
||||
in {
|
||||
# NOTE: _module.args is a special option that allows us to
|
||||
# NOTE: set extend specialArgs from inside the modules.
|
||||
# WARNING: pkgs is a reserved specialArg
|
||||
_module.args = removeAttrs repos ["pkgs"];
|
||||
|
||||
nixpkgs =
|
||||
if contextName == "hosts"
|
||||
then {
|
||||
flake.source = lib.mkOverride 200 base; # DEBUG: temp while getting base to work
|
||||
overlays = lib.mkOverride 200 (defaultPkgs.overlays or {});
|
||||
config = lib.mkOverride 200 (defaultPkgs.config or {});
|
||||
}
|
||||
else if contextName == "homes"
|
||||
then {
|
||||
config = lib.mkOverride 200 (defaultPkgs.config or {});
|
||||
overlays = lib.mkOverride 200 (defaultPkgs.overlays or []);
|
||||
}
|
||||
else {};
|
||||
};
|
||||
}
|
||||
81
flake.lock
generated
81
flake.lock
generated
|
|
@ -3,7 +3,9 @@
|
|||
"deploy-rs": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
|
|
@ -58,6 +60,27 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"microvm": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"spectrum": "spectrum"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771365290,
|
||||
"narHash": "sha256-1XJOslVyF7yzf6yd/yl1VjGLywsbtwmQh3X1LuJcLI4=",
|
||||
"owner": "microvm-nix",
|
||||
"repo": "microvm.nix",
|
||||
"rev": "789c90b164b55b4379e7a94af8b9c01489024c18",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "microvm-nix",
|
||||
"repo": "microvm.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-github-actions": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
|
|
@ -105,38 +128,6 @@
|
|||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1743014863,
|
||||
"narHash": "sha256-jAIUqsiN2r3hCuHji80U7NNEafpIMBXiwKlSrjWMlpg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bd3bac8bfb542dbde7ffffb6987a1a1f9d41699f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1768305791,
|
||||
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1768323494,
|
||||
"narHash": "sha256-yBXJLE6WCtrGo7LKiB6NOt6nisBEEkguC/lq/rP3zRQ=",
|
||||
|
|
@ -152,7 +143,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1767313136,
|
||||
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
|
||||
|
|
@ -171,7 +162,7 @@
|
|||
"nt": {
|
||||
"inputs": {
|
||||
"nix-unit": "nix-unit",
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
|
|
@ -191,12 +182,28 @@
|
|||
"root": {
|
||||
"inputs": {
|
||||
"deploy-rs": "deploy-rs",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"microvm": "microvm",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nt": "nt",
|
||||
"systems": "systems_3"
|
||||
}
|
||||
},
|
||||
"spectrum": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1759482047,
|
||||
"narHash": "sha256-H1wiXRQHxxPyMMlP39ce3ROKCwI5/tUn36P8x6dFiiQ=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "c5d5786d3dc938af0b279c542d1e43bce381b4b9",
|
||||
"revCount": 996,
|
||||
"type": "git",
|
||||
"url": "https://spectrum-os.org/git/spectrum"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://spectrum-os.org/git/spectrum"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
|
|
|
|||
16
flake.nix
16
flake.nix
|
|
@ -16,13 +16,12 @@
|
|||
|
||||
inputs = {
|
||||
systems.url = "github:nix-systems/default";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
nt.url = "github:cry128/nt";
|
||||
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-25.11";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
# WARNING: nixpkgs is ONLY included so flakes using Cerulean can
|
||||
# WARNING: force Cerulean's inputs to follow a specific revision.
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
|
||||
nt.url = "github:cry128/nt";
|
||||
|
||||
deploy-rs = {
|
||||
url = "github:serokell/deploy-rs";
|
||||
|
|
@ -36,14 +35,13 @@
|
|||
};
|
||||
|
||||
outputs = {
|
||||
nixpkgs,
|
||||
self,
|
||||
nt,
|
||||
...
|
||||
} @ inputs:
|
||||
import ./cerulean
|
||||
{
|
||||
inherit inputs;
|
||||
inherit (nixpkgs) lib;
|
||||
inherit inputs self nt;
|
||||
inherit (nt) mix;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue