Compare commits
26 commits
47db6a2b35
...
e5d6c1830b
| Author | SHA1 | Date | |
|---|---|---|---|
| e5d6c1830b | |||
| f8ed7e2787 | |||
| 880c4ebfbe | |||
| 57a4ec8d82 | |||
| 84b7af5863 | |||
| 0a768b9606 | |||
| e6cda64e77 | |||
| 7e122bbe14 | |||
| 108fefcd9b | |||
| 12ffb132ac | |||
| d241f6c192 | |||
| dd77742f5f | |||
| 8d09a2b035 | |||
| ee81f45bcf | |||
| 0d8751780e | |||
| a853b217c0 | |||
| 53992e50a9 | |||
| fd32dac1bf | |||
| 368fa8978b | |||
| 26903695b8 | |||
| d9dc30cc98 | |||
| 88cd8c4b3b | |||
| 84b2fa8a76 | |||
| 162086b065 | |||
| 91ebd09398 | |||
| 0bb3c21aae |
12 changed files with 368 additions and 118 deletions
50
README.md
50
README.md
|
|
@ -1,19 +1,51 @@
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
>[!WARNING]
|
>[!WARNING]
|
||||||
> ✨ **Under Construction** ✨
|
> ✨ **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
|
> Cerulean is in an **experimental alpha release stage**.<br/>
|
||||||
> for use at my workplace. **Be not afraid!** It's only a matter
|
> **Be not afraid!** It's only a matter of time until Cerulean is ready for use!
|
||||||
> 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
|
## 💙 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.
|
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.
|
NixOS backing makes Cerulean **extremely scalable**! Just rent a new VPS and Cerulean will build an ISO of your configuration.
|
||||||
|
|
||||||
No stress, no hassle!
|
No stress, no hassle!
|
||||||
Say goodbye to Azure! And say goodbye to Kubernetes! You're taking life into your own hands 💙
|
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...
|
|
||||||
|
|
|
||||||
62
TODO.md
62
TODO.md
|
|
@ -1,8 +1,58 @@
|
||||||
Allow `Cerulean.mkNexus` to be an alias for `flake-parts.lib.mkFlake`
|
- [ ] deploy port should default to the first port given to `services.openssh`
|
||||||
also rename `Cerulean` to `cerulean` in Nix to maintain the naming convention.
|
|
||||||
|
|
||||||
Using `flake-parts` ensures Cerulean is usable without restricting
|
- [ ] use the Nix module system instead of projectOnto for `cerulean.mkNexus`
|
||||||
yourself only to the Cerulean ecosystem.
|
- [ ] create an alternative to nixos-install called cerulean-install that
|
||||||
|
allows people to easily bootstrap new machines (and host it on dobutterfliescry.net)
|
||||||
|
|
||||||
- [ ] extend the options.nixpkgs to allow any number of package repositories!!
|
- [ ] find an alternative to `nix.settings.trusted-users` probably
|
||||||
- [x] auto-propagate the same specialArgs for hosts to home-manager
|
- [ ] add the ceru-build user,
|
||||||
|
- [ ] add support for github:microvm-nix/microvm.nix
|
||||||
|
- [ ] add support for sops-nix
|
||||||
|
|
||||||
|
- [ ] 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
|
||||||
|
- [ ] rename extraModules to modules?
|
||||||
|
- [ ] 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)
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] 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
|
||||||
|
|
||||||
|
- [ ] rewrite the ceru cli in rust
|
||||||
|
- [ ] make `ceru` do local and remote deployments
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# REF: foxora
|
||||||
|
vms = {
|
||||||
|
home-assistant = {
|
||||||
|
autostart = true;
|
||||||
|
# matches in vms/*
|
||||||
|
image = "home-assistant";
|
||||||
|
options = {
|
||||||
|
mem = 2048;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
equinox = {
|
||||||
|
image = "home-assistant";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
{
|
{
|
||||||
mix,
|
mix,
|
||||||
deploy-rs,
|
inputs,
|
||||||
...
|
...
|
||||||
} @ args:
|
} @ args:
|
||||||
mix.newMixture args (mixture: {
|
mix.newMixture args (mixture: {
|
||||||
|
|
@ -21,22 +21,16 @@ mix.newMixture args (mixture: {
|
||||||
./nexus
|
./nexus
|
||||||
];
|
];
|
||||||
|
|
||||||
version = "0.1.0";
|
version = "0.2.2";
|
||||||
|
|
||||||
nixosModules = rec {
|
nixosModules = rec {
|
||||||
default = cerulean;
|
default = cerulean;
|
||||||
cerulean = ./nixos-module;
|
cerulean = ./nixos;
|
||||||
};
|
};
|
||||||
|
|
||||||
overlays = [
|
overlays = [
|
||||||
# build deploy-rs as a package not from the flake input,
|
# build deploy-rs as a package not from the flake input,
|
||||||
# hence we can rely on a nixpkg binary cache.
|
# hence we can rely on a nixpkg binary cache.
|
||||||
deploy-rs.overlays.default
|
inputs.deploy-rs.overlays.default
|
||||||
# (self: super: {
|
|
||||||
# deploy-rs = {
|
|
||||||
# inherit (super) deploy-rs;
|
|
||||||
# lib = super.deploy-rs.lib;
|
|
||||||
# };
|
|
||||||
# })
|
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@
|
||||||
self,
|
self,
|
||||||
this,
|
this,
|
||||||
nt,
|
nt,
|
||||||
lib,
|
inputs,
|
||||||
deploy-rs,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit
|
inherit
|
||||||
|
|
@ -50,15 +49,10 @@
|
||||||
(nt.naive.terminal)
|
(nt.naive.terminal)
|
||||||
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 {
|
in {
|
||||||
extraModules = [];
|
base = null;
|
||||||
specialArgs = Terminal {};
|
modules = [];
|
||||||
|
args = Terminal {};
|
||||||
|
|
||||||
groups = Terminal {};
|
groups = Terminal {};
|
||||||
nodes = Terminal {};
|
nodes = Terminal {};
|
||||||
|
|
@ -96,7 +90,7 @@
|
||||||
assert isAttrs nexus
|
assert isAttrs nexus
|
||||||
|| abort ''
|
|| abort ''
|
||||||
Cerulean Nexus config must be provided as an attribute set, got "${typeOf nexus}" instead!
|
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
|
''; let
|
||||||
base = nt.projectOnto templateNexus nexus;
|
base = nt.projectOnto templateNexus nexus;
|
||||||
in
|
in
|
||||||
|
|
@ -133,7 +127,14 @@
|
||||||
Cerulean Nexus node "${nodeName}" does not declare group membership as a list, got "${typeOf node.groups}" instead!
|
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`.
|
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
|
# ensure all members are actually groups
|
||||||
|> map (group: let
|
|> map (group: let
|
||||||
got =
|
got =
|
||||||
|
|
@ -181,32 +182,44 @@ in {
|
||||||
customOutputs = removeAttrs decl ["nexus"];
|
customOutputs = removeAttrs decl ["nexus"];
|
||||||
|
|
||||||
outputs = rec {
|
outputs = rec {
|
||||||
nixosConfigurations = mapNodes nexus.nodes (
|
nixosConfigurations = mapNodes nexus (
|
||||||
nodeName: node: let
|
{
|
||||||
nixosDecl = lib.nixosSystem {
|
lib,
|
||||||
|
nodeName,
|
||||||
|
node,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
nixosDecl = lib.nixosSystem rec {
|
||||||
system = node.system;
|
system = node.system;
|
||||||
specialArgs = let
|
|
||||||
specialArgs =
|
specialArgs =
|
||||||
nexus.specialArgs
|
nexus.args
|
||||||
// node.specialArgs
|
// node.args
|
||||||
// {
|
// {
|
||||||
inherit root specialArgs;
|
inherit root specialArgs;
|
||||||
inherit (node) system;
|
inherit (node) system;
|
||||||
_deploy-rs = deploy-rs;
|
_deploy-rs = inputs.deploy-rs;
|
||||||
};
|
};
|
||||||
in
|
|
||||||
specialArgs;
|
|
||||||
modules =
|
modules =
|
||||||
[self.nixosModules.default (findImport (root + "/hosts/${nodeName}"))]
|
[
|
||||||
|
self.nixosModules.default
|
||||||
|
(findImport (root + "/hosts/${nodeName}"))
|
||||||
|
|
||||||
|
inputs.home-manager.nixosModules.default
|
||||||
|
# inputs.microvm.nixosModules.microvm
|
||||||
|
]
|
||||||
++ (getGroupModules root nodeName node)
|
++ (getGroupModules root nodeName node)
|
||||||
++ node.extraModules
|
++ node.modules
|
||||||
++ nexus.extraModules;
|
++ nexus.modules;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
nixosDecl
|
nixosDecl
|
||||||
);
|
);
|
||||||
|
|
||||||
deploy.nodes = mapNodes nexus.nodes (nodeName: node: let
|
deploy.nodes = mapNodes nexus ({
|
||||||
|
nodeName,
|
||||||
|
node,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit
|
inherit
|
||||||
(node.deploy)
|
(node.deploy)
|
||||||
activationTimeout
|
activationTimeout
|
||||||
|
|
@ -220,7 +233,7 @@ in {
|
||||||
user
|
user
|
||||||
;
|
;
|
||||||
|
|
||||||
nixosFor = system: deploy-rs.lib.${system}.activate.nixos;
|
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
|
||||||
in {
|
in {
|
||||||
hostname = ssh.host;
|
hostname = ssh.host;
|
||||||
|
|
||||||
|
|
@ -256,7 +269,7 @@ in {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
checks = mapAttrs (system: deployLib: deployLib.deployChecks deploy) deploy-rs.lib;
|
checks = mapAttrs (system: deployLib: deployLib.deployChecks deploy) inputs.deploy-rs.lib;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
outputs // customOutputs;
|
outputs // customOutputs;
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,20 @@ in rec {
|
||||||
(nt.naive.terminal)
|
(nt.naive.terminal)
|
||||||
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 {
|
in {
|
||||||
system = "x86_64-linux"; # sane default (i hope...)
|
enabled = true;
|
||||||
|
system = missing "its system architecture" "system";
|
||||||
groups = [];
|
groups = [];
|
||||||
extraModules = [];
|
modules = [];
|
||||||
specialArgs = Terminal {};
|
args = Terminal {};
|
||||||
overlays = [];
|
|
||||||
|
base = null;
|
||||||
|
|
||||||
deploy = {
|
deploy = {
|
||||||
user = "root";
|
user = "root";
|
||||||
|
|
@ -67,7 +75,25 @@ in rec {
|
||||||
in
|
in
|
||||||
nt.projectOnto templateAttrs nodeAttrs;
|
nt.projectOnto templateAttrs nodeAttrs;
|
||||||
|
|
||||||
mapNodes = nodes: f:
|
mapNodes = nexus: f:
|
||||||
nodes
|
nexus.nodes
|
||||||
|> mapAttrs (nodeName: nodeAttrs: f nodeName (parseNode nodeName nodeAttrs));
|
|> 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;
|
||||||
|
lib = 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 = {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
{
|
{
|
||||||
root,
|
root,
|
||||||
|
system,
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
specialArgs,
|
specialArgs,
|
||||||
|
|
@ -25,6 +26,7 @@
|
||||||
pathExists
|
pathExists
|
||||||
;
|
;
|
||||||
in {
|
in {
|
||||||
|
config = {
|
||||||
home-manager = {
|
home-manager = {
|
||||||
users =
|
users =
|
||||||
config.users.users
|
config.users.users
|
||||||
|
|
@ -32,13 +34,11 @@ in {
|
||||||
|> filter (x: pathExists (root + "/homes/${x}"))
|
|> filter (x: pathExists (root + "/homes/${x}"))
|
||||||
|> (x: lib.genAttrs x (y: import (root + "/homes/${y}")));
|
|> (x: lib.genAttrs x (y: import (root + "/homes/${y}")));
|
||||||
|
|
||||||
# extraSpecialArgs = specialArgs;
|
extraSpecialArgs = {inherit root system;} // (specialArgs.inputs or {});
|
||||||
sharedModules = [
|
sharedModules = [
|
||||||
# user configuration
|
# user configuration
|
||||||
# (import (root + "/nixpkgs.nix"))
|
|
||||||
(import (root + "/nixpkgs.nix"))
|
(import (root + "/nixpkgs.nix"))
|
||||||
# options declarations
|
# options declarations
|
||||||
# (import ./nixpkgs.nix (args // {contextName = "homes";}))
|
|
||||||
(import ./nixpkgs.nix (args // {contextName = "homes";}))
|
(import ./nixpkgs.nix (args // {contextName = "homes";}))
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -46,4 +46,5 @@ in {
|
||||||
# we control the pkgs now!!
|
# we control the pkgs now!!
|
||||||
# useGlobalPkgs = true;
|
# useGlobalPkgs = true;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
13
cerulean/nixos/microvm-child.nix
Normal file
13
cerulean/nixos/microvm-child.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.
|
||||||
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.
|
||||||
|
|
@ -51,11 +51,6 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# or abort ''
|
|
||||||
# `nixpkgs.channels.${contextName}` does not exist, but neither does `nixpkgs.channels.default`!
|
|
||||||
# A channel configuration must be declared for module context "${contextName}".
|
|
||||||
# ''
|
|
||||||
|
|
||||||
config = let
|
config = let
|
||||||
# TODO: use lib.types.submodule to restrict what options
|
# TODO: use lib.types.submodule to restrict what options
|
||||||
# TODO: can be given to `nixpkgs.channels.${moduleName}.${name}`
|
# TODO: can be given to `nixpkgs.channels.${moduleName}.${name}`
|
||||||
|
|
@ -67,7 +62,6 @@ in {
|
||||||
|> mapAttrs (
|
|> mapAttrs (
|
||||||
name: args:
|
name: args:
|
||||||
lib.mkForce (
|
lib.mkForce (
|
||||||
# builtins.trace "SAVE ME GOT NAME: ${name}" (
|
|
||||||
assert args ? source
|
assert args ? source
|
||||||
|| abort ''
|
|| abort ''
|
||||||
${toString ./.}
|
${toString ./.}
|
||||||
|
|
@ -76,38 +70,31 @@ in {
|
||||||
((removeAttrs args ["source"])
|
((removeAttrs args ["source"])
|
||||||
// {inherit system;})
|
// {inherit system;})
|
||||||
|> import args.source
|
|> import args.source
|
||||||
# DEBUG: |> lib.mkOverride 200
|
|
||||||
)
|
)
|
||||||
# )
|
|
||||||
);
|
);
|
||||||
in {
|
in {
|
||||||
# NOTE: _module.args is a special option that allows us to
|
# NOTE: _module.args is a special option that allows us to
|
||||||
# NOTE: set extend specialArgs from inside the modules.
|
# NOTE: set extend specialArgs from inside the modules.
|
||||||
# "pkgs" is unique since the nix module system already handles it
|
|
||||||
# DEBUG: _module.args = lib.mkOverride 200 (
|
|
||||||
# _module.args = (
|
|
||||||
# if contextName == "hosts"
|
|
||||||
# then repos
|
|
||||||
# else
|
|
||||||
# assert (
|
|
||||||
# repos
|
|
||||||
# |> builtins.attrNames
|
|
||||||
# |> map (x: "\"${x}\"")
|
|
||||||
# |> builtins.concatStringsSep " "
|
|
||||||
# |> (x: "FUCK YOU SO BAD: { ${x} }")
|
|
||||||
# |> abort
|
|
||||||
# );
|
|
||||||
# removeAttrs repos ["pkgs"]
|
|
||||||
# );
|
|
||||||
_module.args = repos;
|
_module.args = repos;
|
||||||
|
|
||||||
nixpkgs =
|
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"
|
if contextName == "hosts"
|
||||||
then {flake.source = lib.mkIf (decl ? pkgs) (lib.mkOverride 200 decl.pkgs.source);}
|
then {
|
||||||
|
flake.source = lib.mkOverride 200 defaultPkgs.source;
|
||||||
|
config = lib.mkOverride 200 defaultPkgs.config;
|
||||||
|
}
|
||||||
else if contextName == "homes"
|
else if contextName == "homes"
|
||||||
then {
|
then {
|
||||||
config = decl.pkgs.config or {};
|
# XXX: XXX: XXX: OH OH OH OMG, its because aurora never defines pkgs
|
||||||
overlays = decl.pkgs.overlays or {};
|
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 {};
|
else {};
|
||||||
};
|
};
|
||||||
27
flake.nix
27
flake.nix
|
|
@ -17,23 +17,36 @@
|
||||||
inputs = {
|
inputs = {
|
||||||
systems.url = "github:nix-systems/default";
|
systems.url = "github:nix-systems/default";
|
||||||
|
|
||||||
|
# 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";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
|
|
||||||
nt.url = "github:cry128/nt";
|
nt.url = "github:cry128/nt";
|
||||||
|
|
||||||
deploy-rs.url = "github:serokell/deploy-rs";
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager/release-25.11";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
deploy-rs = {
|
||||||
|
url = "github:serokell/deploy-rs";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
microvm = {
|
||||||
|
url = "github:microvm-nix/microvm.nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = {
|
outputs = {
|
||||||
nixpkgs,
|
self,
|
||||||
nt,
|
nt,
|
||||||
...
|
...
|
||||||
} @ inputs:
|
} @ inputs:
|
||||||
import ./cerulean
|
import ./cerulean
|
||||||
(inputs
|
{
|
||||||
// {
|
inherit inputs self nt;
|
||||||
inherit (nixpkgs) lib;
|
|
||||||
inherit (nt) mix;
|
inherit (nt) mix;
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue