Compare commits
23 commits
feature/cl
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4726d81d90 | |||
| 6c7f335fbd | |||
| 902f9d7508 | |||
| 02ded5d4f0 | |||
| 630389a598 | |||
| 6b579dff1e | |||
| b486ee8cb7 | |||
| aec16966ae | |||
| 39ec2e62d0 | |||
| 1c68485dcf | |||
| 34a8c23537 | |||
| 169bf2bf48 | |||
| 23449396f7 | |||
| c49fdc9769 | |||
| f985e7ee70 | |||
| ba7763801f | |||
| ef5bc33856 | |||
| d9432d87a4 | |||
| 77ddfcde7d | |||
| 930eafa818 | |||
| 9bab917d8c | |||
| 087f679e67 | |||
| d5211287bd |
22 changed files with 297 additions and 234 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
||||||
/hidden
|
/hidden
|
||||||
|
target/
|
||||||
|
|
|
||||||
24
TODO.md
24
TODO.md
|
|
@ -1,12 +1,14 @@
|
||||||
## Next
|
## Next
|
||||||
- [ ] use the Nix module system instead of projectOnto for `cerulean.mkNexus`
|
- [ ] formalize how the snow flake system compiles outputs, this would remove the need for `mapNodes`
|
||||||
|
- [ ] groups should allow you to set node configuration defaults
|
||||||
|
|
||||||
- [ ] add `options.experimental` for snowflake
|
- [ ] add `options.experimental` for snowflake
|
||||||
- [ ] add `legacyImports` support
|
- [ ] add `legacyImports` support
|
||||||
|
|
||||||
|
- [ ] support hs system per dir, ie hosts/<name>/overlays or hosts/<name>/nixpkgs.nix
|
||||||
|
|
||||||
## Queued
|
## Queued
|
||||||
- [X] base should automatically be set as the default (dont do anything with the default)
|
- [ ] per node home configuration is a lil jank rn
|
||||||
- [X] 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`
|
- [ ] deploy port should default to the first port given to `services.openssh`
|
||||||
|
|
||||||
|
|
@ -23,29 +25,19 @@
|
||||||
|
|
||||||
- [ ] go through all flake inputs (recursively) and ENSURE we remove all duplicates by using follows!!
|
- [ ] 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
|
- [ ] allow multiple privesc methods, the standard is pam_ssh_agent_auth
|
||||||
|
|
||||||
## Low Priority
|
## Low Priority
|
||||||
- [X] rename extraModules to modules?
|
|
||||||
- [X] rename specialArgs to args?
|
|
||||||
|
|
||||||
- [ ] make an extension to the nix module system (different to mix)
|
- [ ] make an extension to the nix module system (different to mix)
|
||||||
that allows transformations (ie a stop post config, ie outputs, which
|
that allows transformations (ie a stop post config, ie outputs, which
|
||||||
it then returns instead of config)
|
it then returns instead of config)
|
||||||
|
- [ ] support `legacyImports` (?)
|
||||||
|
|
||||||
- [ ] patch microvm so that acpi=off https://github.com/microvm-nix/microvm.nix/commit/b59a26962bb324cc0a134756a323f3e164409b72
|
- [ ] patch microvm so that acpi=off https://github.com/microvm-nix/microvm.nix/commit/b59a26962bb324cc0a134756a323f3e164409b72
|
||||||
cause otherwise 2GB causes a failure
|
cause otherwise 2GB causes a failure
|
||||||
|
|
||||||
- [ ] rewrite the ceru cli in rust
|
- [ ] write the cerulean cli
|
||||||
- [ ] make `ceru` do local and remote deployments
|
|
||||||
|
|
||||||
- [ ] support `legacyImports`
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
# REF: foxora
|
# REF: foxora
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ mix.newMixture args (mixture: {
|
||||||
./snow
|
./snow
|
||||||
];
|
];
|
||||||
|
|
||||||
version = "0.2.3";
|
version = "0.2.5-alpha";
|
||||||
|
|
||||||
# WARNING: legacy
|
# WARNING: legacy
|
||||||
mkFlake = mixture.snow.flake;
|
mkFlake = mixture.snow.flake;
|
||||||
|
|
|
||||||
34
cerulean/home/default.nix
Normal file
34
cerulean/home/default.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Copyright 2025-2026 _cry64 (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.
|
||||||
|
{
|
||||||
|
username,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# NOTE: you can access the system configuration via the `osConfig` arg
|
||||||
|
|
||||||
|
# WARNING: required for home-manager to work
|
||||||
|
programs.home-manager.enable = true; # user must apply lib.mkForce
|
||||||
|
# Nicely reload systemd units when changing configs
|
||||||
|
systemd.user.startServices = lib.mkDefault "sd-switch";
|
||||||
|
|
||||||
|
home = {
|
||||||
|
username = lib.mkDefault username;
|
||||||
|
homeDirectory = lib.mkDefault "/home/${username}";
|
||||||
|
|
||||||
|
sessionVariables = {
|
||||||
|
NIX_SHELL_PRESERVE_PROMPT = lib.mkDefault 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -13,29 +13,34 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
{
|
{
|
||||||
root,
|
root,
|
||||||
pkgs,
|
|
||||||
system,
|
system,
|
||||||
|
hostname,
|
||||||
|
node,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
_cerulean,
|
_cerulean,
|
||||||
...
|
...
|
||||||
} @ args: {
|
} @ args: {
|
||||||
imports = with _cerulean.inputs;
|
imports =
|
||||||
[
|
[
|
||||||
|
_cerulean.inputs.sops-nix.nixosModules.sops
|
||||||
|
# _cerulean.inputs.microvm.nixosModules.microvm
|
||||||
|
|
||||||
# add support for `options.legacyImports`
|
# add support for `options.legacyImports`
|
||||||
# ./legacy-imports.nix
|
# ./legacy-imports.nix
|
||||||
|
|
||||||
# user configuration
|
# nixos options declarations
|
||||||
(import (root + "/nixpkgs.nix"))
|
|
||||||
# options declarations
|
|
||||||
(import ./nixpkgs.nix (args // {contextName = "hosts";}))
|
(import ./nixpkgs.nix (args // {contextName = "hosts";}))
|
||||||
|
|
||||||
sops-nix.nixosModules.sops
|
# user's nixpkg configuration
|
||||||
# microvm.nixosModules.microvm
|
(import /${root}/nixpkgs.nix)
|
||||||
]
|
]
|
||||||
++ (
|
# homemanager options declarations
|
||||||
if _cerulean.homeManager != null
|
++ (lib.optional (_cerulean.homeManager != null) ./home.nix)
|
||||||
then [./home-manager.nix]
|
# remote deployment configuration
|
||||||
else []
|
++ (lib.optional (node.deploy.ssh.host != null) ./remote-deploy);
|
||||||
);
|
|
||||||
|
networking.hostName = lib.mkDefault hostname;
|
||||||
|
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
(with pkgs; [
|
(with pkgs; [
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
# Copyright 2025-2026 _cry64 (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,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
_cerulean,
|
|
||||||
...
|
|
||||||
} @ args: let
|
|
||||||
inherit
|
|
||||||
(builtins)
|
|
||||||
attrNames
|
|
||||||
filter
|
|
||||||
pathExists
|
|
||||||
;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
_cerulean.homeManager.nixosModules.default
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager = {
|
|
||||||
users =
|
|
||||||
config.users.users
|
|
||||||
|> attrNames
|
|
||||||
|> filter (x: pathExists (root + "/homes/${x}"))
|
|
||||||
|> (x:
|
|
||||||
lib.genAttrs x (y:
|
|
||||||
import (root + "/homes/${y}")));
|
|
||||||
|
|
||||||
extraSpecialArgs = _cerulean.specialArgs;
|
|
||||||
sharedModules = [
|
|
||||||
# user configuration
|
|
||||||
(import (root + "/nixpkgs.nix"))
|
|
||||||
# options declarations
|
|
||||||
(import ./nixpkgs.nix (args // {contextName = "homes";}))
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
82
cerulean/nixos/home.nix
Normal file
82
cerulean/nixos/home.nix
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Copyright 2025-2026 _cry64 (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.
|
||||||
|
{
|
||||||
|
_cerulean,
|
||||||
|
config,
|
||||||
|
root,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
} @ args: let
|
||||||
|
inherit
|
||||||
|
(builtins)
|
||||||
|
pathExists
|
||||||
|
;
|
||||||
|
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
filterAttrs
|
||||||
|
mapAttrs
|
||||||
|
;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
_cerulean.homeManager.nixosModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
users.users = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (lib.types.submodule {
|
||||||
|
options.manageHome = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
example = false;
|
||||||
|
description = ''
|
||||||
|
Whether Cerulean should automatically enable home-manager for this user,
|
||||||
|
and manage their home configuration declaratively.
|
||||||
|
|
||||||
|
Enabled by default, but can be disabled if necessary.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
home-manager = {
|
||||||
|
useUserPackages = lib.mkDefault false;
|
||||||
|
useGlobalPkgs = lib.mkDefault true;
|
||||||
|
|
||||||
|
overwriteBackup = lib.mkDefault false;
|
||||||
|
backupFileExtension = lib.mkDefault "bak";
|
||||||
|
|
||||||
|
users =
|
||||||
|
config.users.users
|
||||||
|
|> filterAttrs (name: value: value.manageHome && pathExists /${root}/homes/${name})
|
||||||
|
|> mapAttrs (name: _: {...}: {
|
||||||
|
imports = [/${root}/homes/${name}];
|
||||||
|
|
||||||
|
# per-user arguments
|
||||||
|
_module.args.username = name;
|
||||||
|
});
|
||||||
|
|
||||||
|
extraSpecialArgs = _cerulean.specialArgs;
|
||||||
|
sharedModules = [
|
||||||
|
../home
|
||||||
|
|
||||||
|
(import /${root}/nixpkgs.nix)
|
||||||
|
# options declarations
|
||||||
|
(import ./nixpkgs.nix (args // {contextName = "homes";}))
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ in {
|
||||||
default = {};
|
default = {};
|
||||||
description = "Declare package repositories";
|
description = "Declare package repositories";
|
||||||
example = {
|
example = {
|
||||||
"pkgs" = {
|
"npkgs" = {
|
||||||
source = "inputs.nixpkgs";
|
source = "inputs.nixpkgs";
|
||||||
system = "x86-64-linux";
|
system = "x86-64-linux";
|
||||||
config = {
|
config = {
|
||||||
|
|
@ -53,7 +53,7 @@ in {
|
||||||
config = let
|
config = let
|
||||||
repos =
|
repos =
|
||||||
cfg
|
cfg
|
||||||
|> (xs: removeAttrs xs ["default"])
|
|> (xs: removeAttrs xs ["base"])
|
||||||
|> mapAttrs (
|
|> mapAttrs (
|
||||||
name: args:
|
name: args:
|
||||||
lib.mkForce (
|
lib.mkForce (
|
||||||
|
|
@ -65,30 +65,31 @@ in {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
# XXX: TODO: would it work to use `base` instead of having default?
|
basePkgs = cfg.base or {};
|
||||||
defaultPkgs =
|
|
||||||
cfg.default or (throw ''
|
|
||||||
Your `nixpkgs.nix` file does not declare a default package source.
|
|
||||||
Ensure you set `nixpkgs.channels.*.default = ...;`
|
|
||||||
'');
|
|
||||||
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.
|
||||||
# WARNING: pkgs is a reserved specialArg
|
# WARNING: pkgs is a reserved specialArg
|
||||||
_module.args = removeAttrs repos ["pkgs" "default"];
|
_module.args = removeAttrs repos ["pkgs" "base"];
|
||||||
|
|
||||||
nixpkgs =
|
nixpkgs = let
|
||||||
|
nixpkgsConfig = {
|
||||||
|
config = lib.mkForce (basePkgs.config or {});
|
||||||
|
overlays = lib.mkForce (basePkgs.overlays or []);
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgsHostsConfig =
|
||||||
|
nixpkgsConfig
|
||||||
|
// {
|
||||||
|
flake.source = lib.mkForce base;
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgsHomesConfig = lib.mkIf (!config.home-manager.useGlobalPkgs) nixpkgsConfig;
|
||||||
|
in
|
||||||
if contextName == "hosts"
|
if contextName == "hosts"
|
||||||
then {
|
then nixpkgsHostsConfig
|
||||||
flake.source = lib.mkForce base; # DEBUG: temp while getting base to work
|
|
||||||
overlays = lib.mkForce (defaultPkgs.overlays or {});
|
|
||||||
config = lib.mkForce (defaultPkgs.config or {});
|
|
||||||
}
|
|
||||||
else if contextName == "homes"
|
else if contextName == "homes"
|
||||||
then {
|
then nixpkgsHomesConfig
|
||||||
config = lib.mkForce (defaultPkgs.config or {});
|
|
||||||
overlays = lib.mkForce (defaultPkgs.overlays or []);
|
|
||||||
}
|
|
||||||
else {};
|
else {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
82
cerulean/nixos/remote-deploy/default.nix
Normal file
82
cerulean/nixos/remote-deploy/default.nix
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
node,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
hostname,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
user = node.deploy.ssh.user;
|
||||||
|
cfg = config.users.users.${user};
|
||||||
|
|
||||||
|
DEFAULT_USER = "cerubld";
|
||||||
|
|
||||||
|
isStandardDeployUser = user == DEFAULT_USER;
|
||||||
|
in {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = builtins.length node.deploy.ssh.publicKeys != 0;
|
||||||
|
message = ''
|
||||||
|
The Cerulean deployment user `${user}` for node `${hostname}` must have at least
|
||||||
|
one publicKey authorized for ssh deployment! Try setting `nodes.nodes.<name>.deploy.ssh.publicKeys = [ ... ]` <3
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
# {
|
||||||
|
# assertion = cfg.isSystemUser && !cfg.isNormalUser;
|
||||||
|
# message = ''
|
||||||
|
# The Cerulean deployment user `${user}` for node `${hostname}` has been configured incorrectly.
|
||||||
|
# Ensure `users.users.${user}.isSystemUser == true` and `users.users.${user}.isNormalUser == false`.
|
||||||
|
# '';
|
||||||
|
# }
|
||||||
|
];
|
||||||
|
|
||||||
|
warnings = lib.optional (node.deploy.warnNonstandardDeployUser && !isStandardDeployUser) ''
|
||||||
|
The Cerulean deplyment user `${user}` for node `${hostname}` has been overriden.
|
||||||
|
It is recommended to leave this user as `${DEFAULT_USER}` unless you TRULY understand what you are doing!
|
||||||
|
This message can be disabled by setting `<node>.deploy.warnNonstandardBuildUser = false`.
|
||||||
|
'';
|
||||||
|
|
||||||
|
# prefer sudo-rs over sudo
|
||||||
|
security.sudo-rs = {
|
||||||
|
enable = true;
|
||||||
|
wheelNeedsPassword = true;
|
||||||
|
|
||||||
|
# allow the build user to run nix commands
|
||||||
|
extraRules = [
|
||||||
|
{
|
||||||
|
users = [user];
|
||||||
|
runAs = "${node.deploy.user}:ALL";
|
||||||
|
commands = [
|
||||||
|
# "${pkgs.nix}/bin/nix"
|
||||||
|
"ALL" # XXX: WARNING: FIX: TODO: DO NOT FUCKING USE `ALL`
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# XXX: WARNING: FIX: TODO: use `trusted-public-keys` instead
|
||||||
|
nix.settings.trusted-users = [user];
|
||||||
|
|
||||||
|
# ensure deployment user has SSH permissions
|
||||||
|
services.openssh.settings.AllowUsers = [user];
|
||||||
|
|
||||||
|
users = lib.mkIf isStandardDeployUser {
|
||||||
|
groups.${user} = {};
|
||||||
|
|
||||||
|
users.${user} = {
|
||||||
|
enable = true;
|
||||||
|
description = "Cerulean's user for building and remote deployment.";
|
||||||
|
|
||||||
|
isSystemUser = true;
|
||||||
|
group = user;
|
||||||
|
|
||||||
|
createHome = true;
|
||||||
|
home = "/var/lib/cerulean/cerubld";
|
||||||
|
|
||||||
|
useDefaultShell = false;
|
||||||
|
shell = pkgs.bash;
|
||||||
|
|
||||||
|
openssh.authorizedKeys.keys = node.deploy.ssh.publicKeys;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -48,16 +48,22 @@ in
|
||||||
class = "snowflake";
|
class = "snowflake";
|
||||||
# TODO: abort if inputs contains reserved names
|
# TODO: abort if inputs contains reserved names
|
||||||
specialArgs =
|
specialArgs =
|
||||||
flakeInputs
|
(flakeInputs
|
||||||
// {
|
// {
|
||||||
inherit root;
|
inherit systems root;
|
||||||
inherit systems;
|
inherit (this) snow;
|
||||||
inherit (this) snow; # please don't be infinite recursion...
|
inputs = flakeInputs;
|
||||||
inputs = flakeInputs;
|
})
|
||||||
};
|
|> (x: builtins.removeAttrs x ["self" "nodes"]);
|
||||||
|
|
||||||
modules = [
|
modules = [
|
||||||
./module.nix
|
./module.nix
|
||||||
|
({config, ...}: {
|
||||||
|
_module.args = {
|
||||||
|
self = config;
|
||||||
|
nodes = config.nodes.nodes;
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -86,9 +92,10 @@ in
|
||||||
|
|
||||||
userArgs = nodes.args // node.args;
|
userArgs = nodes.args // node.args;
|
||||||
ceruleanArgs = {
|
ceruleanArgs = {
|
||||||
inherit systems root base;
|
inherit systems root base nodes node;
|
||||||
inherit (node) system;
|
inherit (node) system;
|
||||||
inherit (this) snow;
|
inherit (this) snow;
|
||||||
|
hostname = name;
|
||||||
|
|
||||||
_cerulean = {
|
_cerulean = {
|
||||||
inherit inputs userArgs ceruleanArgs homeManager;
|
inherit inputs userArgs ceruleanArgs homeManager;
|
||||||
|
|
@ -111,7 +118,7 @@ in
|
||||||
modules =
|
modules =
|
||||||
[
|
[
|
||||||
self.nixosModules.default
|
self.nixosModules.default
|
||||||
(findImport (root + "/hosts/${name}"))
|
(findImport /${root}/hosts/${name})
|
||||||
]
|
]
|
||||||
++ (groupModules root)
|
++ (groupModules root)
|
||||||
++ node.modules
|
++ node.modules
|
||||||
|
|
@ -128,7 +135,6 @@ in
|
||||||
(node.deploy)
|
(node.deploy)
|
||||||
ssh
|
ssh
|
||||||
user
|
user
|
||||||
sudoCmd
|
|
||||||
interactiveSudo
|
interactiveSudo
|
||||||
remoteBuild
|
remoteBuild
|
||||||
rollback
|
rollback
|
||||||
|
|
@ -140,14 +146,17 @@ in
|
||||||
|
|
||||||
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
|
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
|
||||||
in {
|
in {
|
||||||
hostname = ssh.host;
|
hostname =
|
||||||
|
if ssh.host != null
|
||||||
|
then ssh.host
|
||||||
|
else "";
|
||||||
|
|
||||||
profilesOrder = ["default"]; # profiles priority
|
profilesOrder = ["default"]; # profiles priority
|
||||||
profiles.default = {
|
profiles.default = {
|
||||||
path = nixosFor node.system nixosConfigurations.${name};
|
path = nixosFor node.system nixosConfigurations.${name};
|
||||||
|
|
||||||
user = user;
|
user = user;
|
||||||
sudo = sudoCmd;
|
sudo = "sudo -u";
|
||||||
interactiveSudo = interactiveSudo;
|
interactiveSudo = interactiveSudo;
|
||||||
|
|
||||||
fastConnection = false;
|
fastConnection = false;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
# flatten recursion result
|
# flatten recursion result
|
||||||
|> concatLists
|
|> concatLists
|
||||||
# find import location
|
# find import location
|
||||||
|> map (group: nt.findImport (root + "/groups/${group._name}"))
|
|> map (group: nt.findImport /${root}/groups/${group._name})
|
||||||
# filter by uniqueness
|
# filter by uniqueness
|
||||||
|> nt.prim.unique
|
|> nt.prim.unique
|
||||||
# ignore missing groups
|
# ignore missing groups
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@
|
||||||
}: {
|
}: {
|
||||||
imports = [
|
imports = [
|
||||||
./nodes
|
./nodes
|
||||||
(snow.findImport (root + "/snow"))
|
(snow.findImport /${root}/snow)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,23 +59,32 @@
|
||||||
default = "root";
|
default = "root";
|
||||||
example = "admin";
|
example = "admin";
|
||||||
description = ''
|
description = ''
|
||||||
The user that the system derivation will be deployed to. The command specified in
|
The user that the system derivation will be built with. The command specified in
|
||||||
`<node>.deploy.sudoCmd` will be used if `<node>.deploy.user` is not the
|
`<node>.deploy.sudoCmd` will be used if `<node>.deploy.user` is not the
|
||||||
same as `<node>.deploy.ssh.user` the same as above).
|
same as `<node>.deploy.ssh.user` the same as above).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
sudoCmd = mkOption {
|
warnNonstandardDeployUser = mkOption {
|
||||||
type = types.str;
|
type = types.bool;
|
||||||
default = "sudo -u";
|
default = true;
|
||||||
example = "doas -u";
|
example = false;
|
||||||
description = ''
|
description = ''
|
||||||
Which sudo command to use. Must accept at least two arguments:
|
Disables the warning that shows when `deploy.ssh.user` is set to a non-standard value.
|
||||||
1. the user name to execute commands as
|
|
||||||
2. the rest is the command to execute
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# sudoCmd = mkOption {
|
||||||
|
# type = types.str;
|
||||||
|
# default = "sudo -u";
|
||||||
|
# example = "doas -u";
|
||||||
|
# description = ''
|
||||||
|
# Which sudo command to use. Must accept at least two arguments:
|
||||||
|
# 1. the user name to execute commands as
|
||||||
|
# 2. the rest is the command to execute
|
||||||
|
# '';
|
||||||
|
# };
|
||||||
|
|
||||||
interactiveSudo = mkOption {
|
interactiveSudo = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
|
|
@ -145,8 +154,8 @@
|
||||||
|
|
||||||
ssh = {
|
ssh = {
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.nullOr types.str;
|
||||||
default = "";
|
default = null;
|
||||||
example = "dobutterfliescry.net";
|
example = "dobutterfliescry.net";
|
||||||
description = ''
|
description = ''
|
||||||
The host to connect to over ssh during deployment
|
The host to connect to over ssh during deployment
|
||||||
|
|
@ -171,6 +180,16 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
publicKeys = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIeyZuUUmyUYrYaEJwEMvcXqZFYm1NaZab8klOyK6Imr me@puter"];
|
||||||
|
description = ''
|
||||||
|
SSH public keys that will be authorized to the deployment user.
|
||||||
|
This key is intended solely for deployment, allowing for fine-grained permission control.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
opts = mkOption {
|
opts = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [];
|
default = [];
|
||||||
|
|
|
||||||
1
cli/.gitignore
vendored
1
cli/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
||||||
/target
|
|
||||||
7
cli/Cargo.lock
generated
7
cli/Cargo.lock
generated
|
|
@ -1,7 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "snow"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "snow"
|
|
||||||
description = "NixOS Derivative"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["_cry64 <them@dobutterfliescry.net>"]
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
22
cli/LICENSE
22
cli/LICENSE
|
|
@ -1,22 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2026 _cry64 (Emile Clark-Boman)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
use std::env;
|
|
||||||
|
|
||||||
mod rocli;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let args: Vec<String> = env::args().collect();
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
pub struct Command {
|
|
||||||
pub name: String,
|
|
||||||
pub version: Option<String>,
|
|
||||||
|
|
||||||
pub action: Action,
|
|
||||||
|
|
||||||
pub subcommands: Vec<Commands>,
|
|
||||||
pub flags: Vec<Flag>,
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
mod command;
|
|
||||||
mod parse;
|
|
||||||
|
|
||||||
pub use parse::normalize_args;
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
/// Parse the GNU convention CLI argument syntax.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
/// ```rs
|
|
||||||
/// assert!(parse(vec!["--flag=value"]) == vec!["--flag", "value"]);
|
|
||||||
/// assert!(parse(vec!["--flag value"]) == vec!["--flag", "value"]);
|
|
||||||
/// assert!(parse(vec!["-abe"]) == vec!["-a", "-b", "-e"]);
|
|
||||||
/// assert!(parse(vec!["-abef=32"]) == vec!["-a", "-b", "-e", "-f", "32"]);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Credit
|
|
||||||
/// Based on [github:ksk001100/seahorse `src/utils.rs`](https://github.com/ksk001100/seahorse/blob/master/src/utils.rs)
|
|
||||||
pub fn normalize_args(args: Vec<String>) -> Vec<String> {
|
|
||||||
args.iter().fold(Vec::<String>::new(), |mut acc, el| {
|
|
||||||
if !el.starts_with('-') {
|
|
||||||
acc.push(el.to_owned());
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut split = el.splitn(2, '=').map(|s| s.to_owned()).collect();
|
|
||||||
if el.starts_with("--") {
|
|
||||||
acc.append(&mut split);
|
|
||||||
} else {
|
|
||||||
let flags = split[0].chars().skip(1).map(|c| format!("-{c}"));
|
|
||||||
|
|
||||||
acc.append(&mut flags.collect());
|
|
||||||
if let Some(value) = split.get(1) {
|
|
||||||
acc.push(value.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
})
|
|
||||||
}
|
|
||||||
21
flake.lock
generated
21
flake.lock
generated
|
|
@ -185,30 +185,9 @@
|
||||||
"microvm": "microvm",
|
"microvm": "microvm",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nt": "nt",
|
"nt": "nt",
|
||||||
"sops-nix": "sops-nix",
|
|
||||||
"systems": "systems_3"
|
"systems": "systems_3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sops-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1772495394,
|
|
||||||
"narHash": "sha256-hmIvE/slLKEFKNEJz27IZ8BKlAaZDcjIHmkZ7GCEjfw=",
|
|
||||||
"owner": "Mic92",
|
|
||||||
"repo": "sops-nix",
|
|
||||||
"rev": "1d9b98a29a45abe9c4d3174bd36de9f28755e3ff",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "Mic92",
|
|
||||||
"repo": "sops-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spectrum": {
|
"spectrum": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue