Compare commits
37 commits
deb7738abc
...
e813b0f443
| Author | SHA1 | Date | |
|---|---|---|---|
| e813b0f443 | |||
| da4cfefe7b | |||
| aab6c3bdd3 | |||
| f15e28b76c | |||
| d527937829 | |||
| 9ddb124ec2 | |||
| fbe9c6e6ce | |||
| 619c74fad4 | |||
| f23830e29a | |||
| 149f873d97 | |||
| 33d217c899 | |||
| b94b42abec | |||
| 49fcdee320 | |||
| 23615355b7 | |||
| 86a0c9fc3d | |||
| 75c87fb6d1 | |||
| 8ef3ce18cd | |||
| f329d48223 | |||
| af89d57908 | |||
| f995411682 | |||
| 3ba385ee25 | |||
| 23378831aa | |||
| 30e8e1f6c3 | |||
| 369041869a | |||
| 9334235142 | |||
| d363c47e7f | |||
| 5397bf5efc | |||
| 7591af6e3a | |||
| 135f2fb996 | |||
|
|
4bce8ee7b2 | ||
|
|
71ffa820a9 | ||
|
|
54512e6399 | ||
|
|
66c10fdb59 | ||
|
|
b151f45dfb | ||
|
|
c07ac05a0d | ||
|
|
22d02d49f0 | ||
|
|
2e6bef9ad2 |
16 changed files with 623 additions and 774 deletions
61
TODO.md
61
TODO.md
|
|
@ -1,5 +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)
|
||||||
|
|
||||||
|
- [ ] 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
|
||||||
|
|
||||||
|
- [ ] 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,23 +13,24 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
{
|
{
|
||||||
mix,
|
mix,
|
||||||
deploy-rs,
|
inputs,
|
||||||
...
|
...
|
||||||
} @ inputs:
|
} @ args:
|
||||||
mix.newMixture inputs (mixture: {
|
mix.newMixture args (mixture: {
|
||||||
includes.public = [
|
includes.public = [
|
||||||
./nexus
|
./nexus
|
||||||
];
|
];
|
||||||
|
|
||||||
|
version = "0.2.1";
|
||||||
|
|
||||||
|
nixosModules = rec {
|
||||||
|
default = cerulean;
|
||||||
|
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;
|
|
||||||
# };
|
|
||||||
# })
|
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
# 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.
|
||||||
{mix, ...} @ inputs:
|
{mix, ...} @ args:
|
||||||
mix.newMixture inputs (mixture: {
|
mix.newMixture args (mixture: {
|
||||||
includes.public = [
|
includes.public = [
|
||||||
./nodes.nix
|
./nodes.nix
|
||||||
./nexus.nix
|
./nexus.nix
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,8 @@
|
||||||
{
|
{
|
||||||
self,
|
self,
|
||||||
this,
|
this,
|
||||||
nixpkgs,
|
|
||||||
nixpkgs-unstable,
|
|
||||||
nt,
|
nt,
|
||||||
lib,
|
inputs,
|
||||||
deploy-rs,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit
|
inherit
|
||||||
|
|
@ -42,20 +39,22 @@
|
||||||
mapNodes
|
mapNodes
|
||||||
;
|
;
|
||||||
|
|
||||||
|
inherit
|
||||||
|
(nt)
|
||||||
|
findImport
|
||||||
|
;
|
||||||
|
|
||||||
templateNexus = let
|
templateNexus = let
|
||||||
inherit
|
inherit
|
||||||
(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 {
|
||||||
|
base = null;
|
||||||
|
extraModules = [];
|
||||||
|
specialArgs = Terminal {};
|
||||||
|
|
||||||
groups = Terminal {};
|
groups = Terminal {};
|
||||||
overlays = [];
|
|
||||||
nodes = Terminal {};
|
nodes = Terminal {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -66,7 +65,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 =
|
||||||
|
|
@ -90,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
|
||||||
|
|
@ -121,11 +121,56 @@
|
||||||
in
|
in
|
||||||
final;
|
final;
|
||||||
|
|
||||||
# XXX: TODO: create a function in NixTypes that handles this instead
|
getGroupModules = root: nodeName: node:
|
||||||
findImport = path:
|
assert isList node.groups
|
||||||
if pathExists path
|
|| throw ''
|
||||||
then path
|
Cerulean Nexus node "${nodeName}" does not declare group membership as a list, got "${typeOf node.groups}" instead!
|
||||||
else path + ".nix";
|
Ensure `nexus.nodes.${nodeName}.groups` is a list under your call to `cerulean.mkNexus`.
|
||||||
|
'';
|
||||||
|
# ensure root group is always added
|
||||||
|
(node.groups
|
||||||
|
++ [
|
||||||
|
{
|
||||||
|
_parent = null;
|
||||||
|
_name = ROOT_GROUP_NAME;
|
||||||
|
}
|
||||||
|
])
|
||||||
|
# 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 {
|
in {
|
||||||
mkNexus = root: outputsBuilder: let
|
mkNexus = root: outputsBuilder: let
|
||||||
decl = parseDecl outputsBuilder;
|
decl = parseDecl outputsBuilder;
|
||||||
|
|
@ -137,118 +182,47 @@ in {
|
||||||
customOutputs = removeAttrs decl ["nexus"];
|
customOutputs = removeAttrs decl ["nexus"];
|
||||||
|
|
||||||
outputs = rec {
|
outputs = rec {
|
||||||
nixosConfigurations = mapNodes nexus.nodes (
|
nixosConfigurations = mapNodes nexus (
|
||||||
nodeName: node:
|
{
|
||||||
lib.nixosSystem {
|
lib,
|
||||||
|
nodeName,
|
||||||
|
node,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
nixosDecl = lib.nixosSystem {
|
||||||
system = node.system;
|
system = node.system;
|
||||||
modules = let
|
|
||||||
host = findImport (root + "/hosts/${nodeName}");
|
|
||||||
# XXX: TODO: don't use a naive type for this (ie _name property)
|
|
||||||
# XXX: TODO: i really need NixTypes to be stable and use that instead
|
|
||||||
# groups =
|
|
||||||
# node.groups
|
|
||||||
# |> map (group:
|
|
||||||
# assert group ? _name
|
|
||||||
# || throw (let
|
|
||||||
# got =
|
|
||||||
# if ! isAttrs group
|
|
||||||
# then toString group
|
|
||||||
# else
|
|
||||||
# group
|
|
||||||
# |> attrNames
|
|
||||||
# |> map (name: "${name} = <${typeOf (getAttr name group)}>;")
|
|
||||||
# |> concatStringsSep " "
|
|
||||||
# |> (x: "{ ${x} }");
|
|
||||||
# in ''
|
|
||||||
# Cerulean Nexus node "${nodeName}" is a member of a nonexistent group.
|
|
||||||
# Got "${got}" of primitive type "${typeOf group}".
|
|
||||||
# NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
|
|
||||||
# '');
|
|
||||||
# findImport (root + "/groups/${group._name}"))
|
|
||||||
# |> nt.prim.unique; # filter by uniqueness
|
|
||||||
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: let
|
|
||||||
got =
|
|
||||||
if ! isAttrs g
|
|
||||||
then toString g
|
|
||||||
else
|
|
||||||
g
|
|
||||||
|> attrNames
|
|
||||||
|> map (name: "${name} = <${typeOf (getAttr name g)}>;")
|
|
||||||
|> concatStringsSep " "
|
|
||||||
|> (x: "{ ${x} }");
|
|
||||||
in
|
|
||||||
assert g ? _parent
|
|
||||||
|| throw ''
|
|
||||||
Cerulean Nexus node "${nodeName}" is a member of an incorrectly structured group.
|
|
||||||
Got "${got}" of primitive type "${typeOf g}".
|
|
||||||
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
|
|
||||||
'';
|
|
||||||
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;
|
|
||||||
|
|
||||||
# nix passes these to every single module
|
|
||||||
specialArgs = let
|
specialArgs = let
|
||||||
pkgConfig =
|
specialArgs =
|
||||||
{
|
nexus.specialArgs
|
||||||
|
// node.specialArgs
|
||||||
|
// {
|
||||||
|
inherit root specialArgs;
|
||||||
inherit (node) system;
|
inherit (node) system;
|
||||||
# XXX: WARNING: TODO: i've stopped caring
|
_deploy-rs = inputs.deploy-rs;
|
||||||
# XXX: WARNING: TODO: just figure out a better solution to pkgConfig
|
};
|
||||||
config.allowUnfree = true;
|
|
||||||
overlays = self.overlays ++ nexus.overlays ++ node.overlays;
|
|
||||||
}
|
|
||||||
// node.extraPkgConfig;
|
|
||||||
in
|
in
|
||||||
node.specialArgs
|
specialArgs;
|
||||||
// {
|
modules =
|
||||||
inherit root;
|
[
|
||||||
pkgs = import nixpkgs pkgConfig;
|
self.nixosModules.default
|
||||||
upkgs = import nixpkgs-unstable pkgConfig;
|
(findImport (root + "/hosts/${nodeName}"))
|
||||||
};
|
|
||||||
}
|
inputs.home-manager.nixosModules.default
|
||||||
|
# inputs.microvm.nixosModules.microvm
|
||||||
|
]
|
||||||
|
++ (getGroupModules root nodeName node)
|
||||||
|
++ node.extraModules
|
||||||
|
++ nexus.extraModules;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
nixosDecl
|
||||||
);
|
);
|
||||||
|
|
||||||
deploy.nodes = mapNodes nexus.nodes (nodeName: node: let
|
deploy.nodes = mapNodes nexus ({
|
||||||
|
nodeName,
|
||||||
|
node,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit
|
inherit
|
||||||
(node.deploy)
|
(node.deploy)
|
||||||
activationTimeout
|
activationTimeout
|
||||||
|
|
@ -262,7 +236,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;
|
||||||
|
|
||||||
|
|
@ -298,7 +272,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,14 +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 = [];
|
extraModules = [];
|
||||||
specialArgs = Terminal {};
|
specialArgs = Terminal {};
|
||||||
overlays = [];
|
|
||||||
# XXX: WARNING: extraPkgConfig is a terrible solution (but im lazy for now)
|
base = null;
|
||||||
extraPkgConfig = Terminal {};
|
|
||||||
|
|
||||||
deploy = {
|
deploy = {
|
||||||
user = "root";
|
user = "root";
|
||||||
|
|
@ -69,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 {
|
||||||
|
extraModules = mkOption {
|
||||||
|
type = types.listOf types.path;
|
||||||
|
};
|
||||||
|
specialArgs = 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 = {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -11,10 +11,22 @@
|
||||||
# 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.
|
||||||
{lib, ...}: {
|
{
|
||||||
cerulean.nexus.node = {
|
root,
|
||||||
group = lib.mkOption {
|
system,
|
||||||
type = lib.types.enum;
|
_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
|
||||||
|
];
|
||||||
}
|
}
|
||||||
50
cerulean/nixos/home-manager.nix
Normal file
50
cerulean/nixos/home-manager.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# 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,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
specialArgs,
|
||||||
|
...
|
||||||
|
} @ args: let
|
||||||
|
inherit
|
||||||
|
(builtins)
|
||||||
|
attrNames
|
||||||
|
filter
|
||||||
|
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}")));
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -11,4 +11,3 @@
|
||||||
# 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.
|
||||||
{...}: {}
|
|
||||||
|
|
@ -11,8 +11,3 @@
|
||||||
# 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.
|
||||||
{...} @ inputs: {
|
|
||||||
options = import ./options.nix inputs;
|
|
||||||
|
|
||||||
config = import ./config.nix inputs;
|
|
||||||
}
|
|
||||||
101
cerulean/nixos/nixpkgs.nix
Normal file
101
cerulean/nixos/nixpkgs.nix
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
# 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 {};
|
||||||
|
};
|
||||||
|
}
|
||||||
146
flake.lock
generated
146
flake.lock
generated
|
|
@ -36,43 +36,71 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mix": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nib": [
|
"nixpkgs-lib": [
|
||||||
"nib"
|
"nt",
|
||||||
|
"nix-unit",
|
||||||
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768525804,
|
"lastModified": 1762440070,
|
||||||
"narHash": "sha256-jlpNb7Utqfdq2HESAB1mtddWHOsxKlTjPiLFRLd35r8=",
|
"narHash": "sha256-xxdepIcb39UJ94+YydGP221rjnpkDZUlykKuF54PsqI=",
|
||||||
"owner": "emilelcb",
|
"owner": "hercules-ci",
|
||||||
"repo": "mix",
|
"repo": "flake-parts",
|
||||||
"rev": "617d8915a6518a3d4e375b87c50ae34d9daee6c6",
|
"rev": "26d05891e14c88eb4a5d5bee659c0db5afb609d8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "emilelcb",
|
"owner": "hercules-ci",
|
||||||
"repo": "mix",
|
"repo": "flake-parts",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nib": {
|
"nix-github-actions": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": [
|
"nixpkgs": [
|
||||||
"systems"
|
"nt",
|
||||||
|
"nix-unit",
|
||||||
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768472076,
|
"lastModified": 1737420293,
|
||||||
"narHash": "sha256-bdVRCDy6oJx/CZiyxkke783FgtBW//wDuOAITUsQcNc=",
|
"narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=",
|
||||||
"owner": "emilelcb",
|
"owner": "nix-community",
|
||||||
"repo": "nib",
|
"repo": "nix-github-actions",
|
||||||
"rev": "42ac66dfc180a13af1cc8850397db66ec5556991",
|
"rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "emilelcb",
|
"owner": "nix-community",
|
||||||
"repo": "nib",
|
"repo": "nix-github-actions",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix-unit": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nix-github-actions": "nix-github-actions",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nt",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"treefmt-nix": "treefmt-nix"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1762774186,
|
||||||
|
"narHash": "sha256-hRADkHjNt41+JUHw2EiSkMaL4owL83g5ZppjYUdF/Dc=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nix-unit",
|
||||||
|
"rev": "1c9ab50554eed0b768f9e5b6f646d63c9673f0f7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nix-unit",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -124,14 +152,49 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1767313136,
|
||||||
|
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nt": {
|
||||||
|
"inputs": {
|
||||||
|
"nix-unit": "nix-unit",
|
||||||
|
"nixpkgs": "nixpkgs_3",
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770975056,
|
||||||
|
"narHash": "sha256-ZXTz/P3zUbbM6lNXzt91u8EwfNqhXpYMu8+wvFZqQHE=",
|
||||||
|
"owner": "cry128",
|
||||||
|
"repo": "nt",
|
||||||
|
"rev": "f42dcdd49a7921a7f433512e83d5f93696632412",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cry128",
|
||||||
|
"repo": "nt",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"deploy-rs": "deploy-rs",
|
"deploy-rs": "deploy-rs",
|
||||||
"mix": "mix",
|
|
||||||
"nib": "nib",
|
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
"systems": "systems_2"
|
"nt": "nt",
|
||||||
|
"systems": "systems_3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
|
@ -164,6 +227,43 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"treefmt-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nt",
|
||||||
|
"nix-unit",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1762410071,
|
||||||
|
"narHash": "sha256-aF5fvoZeoXNPxT0bejFUBXeUjXfHLSL7g+mjR/p5TEg=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"rev": "97a30861b13c3731a84e09405414398fbf3e109f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
|
|
|
||||||
31
flake.nix
31
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:emilelcb/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;
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
149
lib/cdesktop.nix
149
lib/cdesktop.nix
|
|
@ -1,149 +0,0 @@
|
||||||
# Copyright 2025 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,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
pkgs-unstable,
|
|
||||||
...
|
|
||||||
} @ args: let
|
|
||||||
getModule = name: "../modules/homemanager/${name}.nix";
|
|
||||||
getModules = map (x: getModule x);
|
|
||||||
in {
|
|
||||||
imports = getModules [
|
|
||||||
"term/foot"
|
|
||||||
"editor/vscode"
|
|
||||||
|
|
||||||
"wm/hyprland"
|
|
||||||
"wm/hyprland/hyprlock"
|
|
||||||
|
|
||||||
"dm/sddm"
|
|
||||||
"dm/sddm/themes/corners"
|
|
||||||
|
|
||||||
"apps/firefox"
|
|
||||||
"apps/thunderbird"
|
|
||||||
"apps/obsidian"
|
|
||||||
"apps/rider"
|
|
||||||
"apps/winbox"
|
|
||||||
"apps/gitkraken"
|
|
||||||
"apps/thunar"
|
|
||||||
|
|
||||||
"wm/kanshi"
|
|
||||||
"wm/mako"
|
|
||||||
];
|
|
||||||
|
|
||||||
home = {
|
|
||||||
pointerCursor = {
|
|
||||||
gtk.enable = true;
|
|
||||||
# x11.enable = true # dont enable since im on hyprland
|
|
||||||
package = pkgs.bibata-cursors;
|
|
||||||
name = "Bibata-Modern-Ice";
|
|
||||||
size = 16;
|
|
||||||
};
|
|
||||||
|
|
||||||
packages = with pkgs; [
|
|
||||||
# for services.gnome-keyring
|
|
||||||
(
|
|
||||||
if config.cerulean.isGraphical
|
|
||||||
then seahorse # gui
|
|
||||||
else null
|
|
||||||
)
|
|
||||||
|
|
||||||
fuzzel
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
gtk = {
|
|
||||||
enable = true;
|
|
||||||
font.name = "Victor Mono SemiBold 12";
|
|
||||||
theme = {
|
|
||||||
name = "Dracula";
|
|
||||||
package = pkgs.dracula-theme;
|
|
||||||
};
|
|
||||||
iconTheme = {
|
|
||||||
name = "kora";
|
|
||||||
package = pkgs.kora-icon-theme;
|
|
||||||
};
|
|
||||||
# TODO: use a variable to mirror this cursor size
|
|
||||||
# with the `home.pointerCurser.size`
|
|
||||||
cursorTheme = {
|
|
||||||
package = pkgs.bibata-cursors;
|
|
||||||
name = "Bibata-Modern-Ice";
|
|
||||||
size = 16;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
qt = {
|
|
||||||
enable = true;
|
|
||||||
platformTheme.name = "gtk2";
|
|
||||||
style.name = "gtk2";
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
# Set display manager (login screen)
|
|
||||||
displayManager = {
|
|
||||||
# sddm relies on pkgs.libsForQt5.qt5.qtgraphicaleffects
|
|
||||||
sddm = {
|
|
||||||
enable = true;
|
|
||||||
wayland.enable = true; # experimental
|
|
||||||
theme = "corners";
|
|
||||||
};
|
|
||||||
defaultSession =
|
|
||||||
"hyprland"
|
|
||||||
+ (
|
|
||||||
if config.programs.hyprland.withUWSM
|
|
||||||
then "-uwsm"
|
|
||||||
else null
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
# Multimedia Framework
|
|
||||||
# With backwards compatability for alsa/pulseaudio/jack
|
|
||||||
pipewire = {
|
|
||||||
enable = true;
|
|
||||||
wireplumber.enable = true;
|
|
||||||
|
|
||||||
alsa.enable = true;
|
|
||||||
alsa.support32Bit = true;
|
|
||||||
pulse.enable = true;
|
|
||||||
jack.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# ---- ENVIRONMENT ----
|
|
||||||
environment = {
|
|
||||||
sessionVariables = {
|
|
||||||
# Hint Electron apps to use support Wayland
|
|
||||||
NIXOS_OZONE_WL = "1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# ---- SYSTEM PACKAGES ----
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
# User Environment
|
|
||||||
swww
|
|
||||||
helvum
|
|
||||||
easyeffects
|
|
||||||
pavucontrol
|
|
||||||
hyprpicker # colour picking utility
|
|
||||||
hyprshot # screenshot utility
|
|
||||||
qbittorrent
|
|
||||||
signal-desktop # MAKE THIS ONLY FOR THE DESKTOP FOR END USERS, NOT SERVERS
|
|
||||||
kdePackages.gwenview # image viewer
|
|
||||||
libreoffice
|
|
||||||
wl-clipboard # clipboard for wayland
|
|
||||||
];
|
|
||||||
|
|
||||||
security.rtkit.enable = true; # I *think* this is for pipewire
|
|
||||||
}
|
|
||||||
330
lib/csystem.nix
330
lib/csystem.nix
|
|
@ -1,330 +0,0 @@
|
||||||
# Copyright 2025 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,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
pkgs-unstable,
|
|
||||||
homemanager,
|
|
||||||
cerulean,
|
|
||||||
...
|
|
||||||
} @ args: let
|
|
||||||
getModule = name: "../modules/nixos/${name}.nix";
|
|
||||||
getModules = map (x: getModule x);
|
|
||||||
|
|
||||||
getHostModule = name: "TODO";
|
|
||||||
in {
|
|
||||||
imports = getModules [
|
|
||||||
(getHostModule "hardware-configuration")
|
|
||||||
(import "${homemanager}/nixos")
|
|
||||||
|
|
||||||
"shell/bash"
|
|
||||||
"shell/bash/bashistrans.nix"
|
|
||||||
"shell/zsh"
|
|
||||||
"shell/fish"
|
|
||||||
|
|
||||||
"cli/git"
|
|
||||||
"cli/bat"
|
|
||||||
"cli/btop"
|
|
||||||
"cli/tmux"
|
|
||||||
"cli/nvim"
|
|
||||||
|
|
||||||
"lang/asm"
|
|
||||||
"lang/bash" # TODO: (YES THIS IS DIFFERENT TO shell/bash, this provides language support ie pkgs.shellcheck)
|
|
||||||
"lang/c-family"
|
|
||||||
"lang/dotnet"
|
|
||||||
# "lang/go"
|
|
||||||
# "lang/haskell"
|
|
||||||
# "lang/java"
|
|
||||||
# "lang/nim"
|
|
||||||
"lang/python"
|
|
||||||
# "lang/rust"
|
|
||||||
# "lang/sage"
|
|
||||||
|
|
||||||
"editor/helix"
|
|
||||||
];
|
|
||||||
|
|
||||||
nix.settings = {
|
|
||||||
# REF: https://nix.dev/manual/nix/2.24/development/experimental-features
|
|
||||||
experimental-features = [
|
|
||||||
# Significant
|
|
||||||
"flakes"
|
|
||||||
"nix-command"
|
|
||||||
"pipe-operators"
|
|
||||||
|
|
||||||
# Minor
|
|
||||||
"no-url-literals"
|
|
||||||
"parse-toml-timestamps"
|
|
||||||
"recursive-nix"
|
|
||||||
];
|
|
||||||
|
|
||||||
download-buffer-size = 524288000; # 500 MiB
|
|
||||||
|
|
||||||
# making wheel group members "trusted users" allows
|
|
||||||
# them to import packages not signed by a trusted key
|
|
||||||
# (aka super duper easier to remote deploy)
|
|
||||||
trusted-users = ["root" "@wheel"];
|
|
||||||
};
|
|
||||||
|
|
||||||
nixpkgs = {
|
|
||||||
overlays = cerulean.lib.importOverlaysNixOS;
|
|
||||||
|
|
||||||
config = if config.cerulean.allowUnfreeWhitelist != []
|
|
||||||
then {
|
|
||||||
allowUnfreePredicate =
|
|
||||||
pkg: builtins.elem
|
|
||||||
(lib.getName pkg)
|
|
||||||
config.cerulean.allowUnfreeWhitelist;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
allowUnfree = config.cerulean.allowUnfree;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# colmena deployment configuration
|
|
||||||
deployment = {
|
|
||||||
targetHost = config.cerulean.domain ?? config.cerulean.ip;
|
|
||||||
targetUser = "cerulean";
|
|
||||||
targetPort = "22";
|
|
||||||
sshOptions = [
|
|
||||||
"-A" # forward ssh-agent
|
|
||||||
];
|
|
||||||
buildOnTarget = false; # build locally then deploy
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
time.timeZone = config.cerulean.timeZone;
|
|
||||||
i18n.defaultLocale = "en_US.UTF-8";
|
|
||||||
|
|
||||||
# Enable initrd hook for virtual console customisation
|
|
||||||
# aka cool colours when booting yay!!
|
|
||||||
console = {
|
|
||||||
enable = true;
|
|
||||||
earlySetup = true; # initrd pre hook
|
|
||||||
keyMap = "us";
|
|
||||||
font = "Lat2-Terminus16";
|
|
||||||
# ANSI 24-bit color definitions (theme: dracula)
|
|
||||||
colors = [
|
|
||||||
"21222c"
|
|
||||||
"ff5555"
|
|
||||||
"50fa7b"
|
|
||||||
"f1fa8c"
|
|
||||||
"bd93f9"
|
|
||||||
"ff79c6"
|
|
||||||
"8be9fd"
|
|
||||||
"f8f8f2"
|
|
||||||
"6272a4"
|
|
||||||
"ff6e6e"
|
|
||||||
"69ff94"
|
|
||||||
"ffffa5"
|
|
||||||
"d6acff"
|
|
||||||
"ff92df"
|
|
||||||
"a4ffff"
|
|
||||||
"ffffff"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# super duper minimum grub2 config
|
|
||||||
boot.loader = {
|
|
||||||
efi = {
|
|
||||||
canTouchEfiVariables = true;
|
|
||||||
efiSysMountPoint = "/boot/efi";
|
|
||||||
};
|
|
||||||
|
|
||||||
grub = {
|
|
||||||
enable = true;
|
|
||||||
device = "nodev";
|
|
||||||
};
|
|
||||||
|
|
||||||
# GitHub: vinceliuice/grub2-themes
|
|
||||||
grub2-theme = {
|
|
||||||
enable = true;
|
|
||||||
theme = "whitesur"; # stylish, vimix, or whitesur
|
|
||||||
footer = true;
|
|
||||||
# TODO: switch my cables to switch default grub display
|
|
||||||
customResolution = "3840x2160";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
hostName = config.cerulean.hostname;
|
|
||||||
networkmanager.enable = true;
|
|
||||||
|
|
||||||
firewall = {
|
|
||||||
enable = true;
|
|
||||||
allowedTCPPorts = [
|
|
||||||
22 # sshd
|
|
||||||
80 # nginx (http)
|
|
||||||
443 # nginx (https)
|
|
||||||
# 5678 # MikroTik WinBox
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# ------- USERS -------
|
|
||||||
security.sudo.wheelNeedsPassword = true;
|
|
||||||
users = {
|
|
||||||
defaultUserShell = pkgs.bash;
|
|
||||||
|
|
||||||
users = cerulean.lib.importUsersNixOS;
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager = {
|
|
||||||
users = cerulean.lib.importUsersHomeManager;
|
|
||||||
|
|
||||||
extraSpecialArgs = { inherit inputs pkgs pkgs-unstable; };
|
|
||||||
sharedModules = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
# ---- ENVIRONMENT ----
|
|
||||||
environment = {
|
|
||||||
# always install "dev"/"man" derivation outputs
|
|
||||||
extraOutputsToInstall = ["dev" "man"];
|
|
||||||
|
|
||||||
systemPackages = with pkgs; [
|
|
||||||
# User Environment
|
|
||||||
bluetui
|
|
||||||
|
|
||||||
# Shell
|
|
||||||
bash
|
|
||||||
fish
|
|
||||||
shellcheck
|
|
||||||
grc # colorise command outputs
|
|
||||||
moreutils
|
|
||||||
|
|
||||||
# Systems Programming & Compilation
|
|
||||||
qemu # Fellice Bellard's Quick Emulator
|
|
||||||
# GNU Utils
|
|
||||||
gnumake
|
|
||||||
# Binaries
|
|
||||||
binutils
|
|
||||||
strace
|
|
||||||
ltrace
|
|
||||||
perf-tools # ftrace + perf
|
|
||||||
radare2
|
|
||||||
gdb
|
|
||||||
# ASM
|
|
||||||
nasm
|
|
||||||
(callPackage ../packages/x86-manpages {})
|
|
||||||
# C Family
|
|
||||||
gcc
|
|
||||||
clang
|
|
||||||
clang-tools
|
|
||||||
|
|
||||||
# Rust
|
|
||||||
cargo
|
|
||||||
rustc
|
|
||||||
# Go
|
|
||||||
go
|
|
||||||
# Nim
|
|
||||||
nim
|
|
||||||
nimble
|
|
||||||
# Haskell
|
|
||||||
ghc
|
|
||||||
ghcid
|
|
||||||
haskell-language-server
|
|
||||||
ormolu
|
|
||||||
|
|
||||||
# Python
|
|
||||||
python312 # I use 3.12 since it's in a pretty stable state now
|
|
||||||
python314 # also 3.14 for latest features
|
|
||||||
poetry
|
|
||||||
|
|
||||||
openvpn
|
|
||||||
inetutils
|
|
||||||
|
|
||||||
# security tools
|
|
||||||
nmap
|
|
||||||
|
|
||||||
httpie
|
|
||||||
curlie
|
|
||||||
zoxide
|
|
||||||
doggo
|
|
||||||
tldr
|
|
||||||
btop
|
|
||||||
eza
|
|
||||||
yazi
|
|
||||||
lazygit
|
|
||||||
ripgrep
|
|
||||||
viddy # modern `watch` command
|
|
||||||
thefuck
|
|
||||||
|
|
||||||
# TODO: once upgraded past Nix-24.07 this line won't be necessary (I think)
|
|
||||||
# helix will support nixd by default
|
|
||||||
# SOURCE: https://github.com/nix-community/nixd/blob/main/nixd/docs/editor-setup.md#Helix
|
|
||||||
# nixd # lsp for nix # DEBUG
|
|
||||||
|
|
||||||
# Pretty necessary
|
|
||||||
nix-prefetch-git
|
|
||||||
brightnessctl
|
|
||||||
acpi
|
|
||||||
powertop
|
|
||||||
imagemagick
|
|
||||||
|
|
||||||
# "Standard" Unix Commands
|
|
||||||
vim
|
|
||||||
file
|
|
||||||
wget
|
|
||||||
tree
|
|
||||||
pstree
|
|
||||||
unzip
|
|
||||||
unrar-free
|
|
||||||
lz4
|
|
||||||
man-pages
|
|
||||||
man-pages-posix
|
|
||||||
|
|
||||||
# Cryptography
|
|
||||||
gnupg
|
|
||||||
openssl
|
|
||||||
libargon2
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
programs = {
|
|
||||||
nix-ld.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
documentation = {
|
|
||||||
enable = true;
|
|
||||||
doc.enable = true; # install /share/doc packages
|
|
||||||
man.enable = true; # install manpages
|
|
||||||
info.enable = true; # install GNU info
|
|
||||||
dev.enable = true; # install docs intended for developers
|
|
||||||
nixos = {
|
|
||||||
enable = true; # install NixOS documentation (ie man -k nix, & nixos-help)
|
|
||||||
options.splitBuild = true;
|
|
||||||
# includeAllModules = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.docker.enable = true;
|
|
||||||
|
|
||||||
|
|
||||||
hardware = {
|
|
||||||
graphics = {
|
|
||||||
enable = true;
|
|
||||||
enable32Bit = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bluetooth = let
|
|
||||||
btSupported = config.cerulean.bluetoothSupported;
|
|
||||||
in {
|
|
||||||
enable = btSupported;
|
|
||||||
powerOnBoot = btSupported;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = config.cerulean.stateVersion; # DO NOT MODIFY
|
|
||||||
}
|
|
||||||
102
lib/cuser.nix
102
lib/cuser.nix
|
|
@ -1,102 +0,0 @@
|
||||||
# Copyright 2025 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,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
pkgs-unstable,
|
|
||||||
...
|
|
||||||
} @ args: let
|
|
||||||
getModule = name: "../modules/homemanager/${name}.nix";
|
|
||||||
getModules = map (x: getModule x);
|
|
||||||
in {
|
|
||||||
imports = getModules [
|
|
||||||
"shell/fish"
|
|
||||||
|
|
||||||
"cli/git"
|
|
||||||
"cli/bat"
|
|
||||||
"cli/btop"
|
|
||||||
"cli/tmux"
|
|
||||||
|
|
||||||
"editor/helix"
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.config.allowUnfreePredicate = pkg:
|
|
||||||
builtins.elem (lib.GetName pkg) [
|
|
||||||
"vscode-extension-ms-dotnettools-csharp"
|
|
||||||
];
|
|
||||||
|
|
||||||
home = {
|
|
||||||
stateVersion = config.cerulean.stateVersion; # DO NOT MODIFY
|
|
||||||
|
|
||||||
username = config.cerulean.username;
|
|
||||||
homeDirectory = "/home/${config.cerulean.username}";
|
|
||||||
|
|
||||||
shellAliases = {
|
|
||||||
rg = "batgrep"; # bat + ripgrep
|
|
||||||
man = "batman"; # bat + man
|
|
||||||
};
|
|
||||||
|
|
||||||
sessionVariables = {
|
|
||||||
NIX_SHELL_PRESERVE_PROMPT = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
packages = with pkgs; [
|
|
||||||
# for services.gnome-keyring
|
|
||||||
gcr # provides org.gnome.keyring.SystemPrompter
|
|
||||||
speedtest-cli
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
programs = {
|
|
||||||
home-manager.enable = true;
|
|
||||||
|
|
||||||
zsh = {
|
|
||||||
enable = true;
|
|
||||||
enableCompletion = true;
|
|
||||||
autosuggestion.enable = true;
|
|
||||||
syntaxHighlighting.enable = true;
|
|
||||||
|
|
||||||
history = {
|
|
||||||
size = 10000;
|
|
||||||
ignoreAllDups = true;
|
|
||||||
path = "$HOME/.zsh_history";
|
|
||||||
ignorePatterns = [
|
|
||||||
"rm *"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# set ssh profiles
|
|
||||||
# NOTE: (IMPORTANT) this DOES NOT start the ssh-agent
|
|
||||||
# for that you need to use `services.ssh-agent.enable`
|
|
||||||
ssh = {
|
|
||||||
enable = true;
|
|
||||||
forwardAgent = false;
|
|
||||||
addKeysToAgent = "no";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
# enable OpenSSH private key agent
|
|
||||||
ssh-agent.enable = true;
|
|
||||||
|
|
||||||
gnome-keyring.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# the ssh-agent won't set this for itself...
|
|
||||||
systemd.user.sessionVariables.SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/ssh-agent";
|
|
||||||
# Nicely reload system units when changing configs
|
|
||||||
systemd.user.startServices = "sd-switch";
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue