snow-cli test
This commit is contained in:
parent
9c188c46c9
commit
03c72f7582
13 changed files with 488 additions and 133 deletions
|
|
@ -44,7 +44,7 @@
|
||||||
nt,
|
nt,
|
||||||
...
|
...
|
||||||
} @ inputs:
|
} @ inputs:
|
||||||
import ./cerulean
|
import ./nix
|
||||||
{
|
{
|
||||||
inherit inputs self nt;
|
inherit inputs self nt;
|
||||||
inherit (nt) mix;
|
inherit (nt) mix;
|
||||||
|
|
|
||||||
16
nix/nixos/isoImage/default.nix
Normal file
16
nix/nixos/isoImage/default.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
modulesPath,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
config = lib.mkIf (config?isoImage) {
|
||||||
|
# TODO: do i really need to import ALL of this?
|
||||||
|
imports = [(modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")];
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.neovim
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -67,125 +67,129 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = module.config.nodes;
|
inherit (module) config;
|
||||||
in rec {
|
nodes = config.nodes;
|
||||||
nixosConfigurations = mapNodes nodes (
|
in
|
||||||
{
|
# TODO: maybe use flake-parts or another module to all merging
|
||||||
base,
|
config.outputs
|
||||||
lib,
|
// rec {
|
||||||
|
nixosConfigurations = mapNodes nodes (
|
||||||
|
{
|
||||||
|
base,
|
||||||
|
lib,
|
||||||
|
name,
|
||||||
|
node,
|
||||||
|
groupModules,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
homeManager =
|
||||||
|
if node.homeManager != null
|
||||||
|
then node.homeManager
|
||||||
|
else if nodes.homeManager != null
|
||||||
|
then nodes.homeManager
|
||||||
|
else
|
||||||
|
warn ''
|
||||||
|
[snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified!
|
||||||
|
[snowflake] home-manager will NOT be used! User configuration will be ignored!
|
||||||
|
''
|
||||||
|
null;
|
||||||
|
|
||||||
|
userArgs = nodes.args // node.args;
|
||||||
|
ceruleanArgs = {
|
||||||
|
inherit systems root base nodes node;
|
||||||
|
inherit (node) system;
|
||||||
|
inherit (this) snow;
|
||||||
|
hostname = name;
|
||||||
|
|
||||||
|
_cerulean = {
|
||||||
|
inherit inputs userArgs ceruleanArgs homeManager;
|
||||||
|
specialArgs = userArgs // ceruleanArgs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
specialArgs = assert (userArgs
|
||||||
|
|> attrNames
|
||||||
|
|> all (argName:
|
||||||
|
! ceruleanArgs ? argName
|
||||||
|
|| abort ''
|
||||||
|
`specialArgs` are like super important to Cerulean my love... </3
|
||||||
|
But `args.${argName}` is a reserved argument name :(
|
||||||
|
''));
|
||||||
|
ceruleanArgs._cerulean.specialArgs;
|
||||||
|
in
|
||||||
|
lib.nixosSystem {
|
||||||
|
inherit (node) system;
|
||||||
|
inherit specialArgs;
|
||||||
|
modules =
|
||||||
|
[
|
||||||
|
self.nixosModules.default
|
||||||
|
(findImport /${root}/hosts/${name})
|
||||||
|
]
|
||||||
|
++ (groupModules root)
|
||||||
|
++ node.modules
|
||||||
|
++ nodes.modules;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
deploy.nodes = mapNodes nodes ({
|
||||||
name,
|
name,
|
||||||
node,
|
node,
|
||||||
groupModules,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
homeManager =
|
inherit
|
||||||
if node.homeManager != null
|
(node.deploy)
|
||||||
then node.homeManager
|
ssh
|
||||||
else if nodes.homeManager != null
|
user
|
||||||
then nodes.homeManager
|
interactiveSudo
|
||||||
else
|
remoteBuild
|
||||||
warn ''
|
rollback
|
||||||
[snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified!
|
autoRollback
|
||||||
[snowflake] home-manager will NOT be used! User configuration will be ignored!
|
magicRollback
|
||||||
''
|
activationTimeout
|
||||||
null;
|
confirmTimeout
|
||||||
|
;
|
||||||
|
|
||||||
userArgs = nodes.args // node.args;
|
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
|
||||||
ceruleanArgs = {
|
in {
|
||||||
inherit systems root base nodes node;
|
hostname =
|
||||||
inherit (node) system;
|
if ssh.host != null
|
||||||
inherit (this) snow;
|
then ssh.host
|
||||||
hostname = name;
|
else "";
|
||||||
|
|
||||||
_cerulean = {
|
profilesOrder = ["default"]; # profiles priority
|
||||||
inherit inputs userArgs ceruleanArgs homeManager;
|
profiles.default = {
|
||||||
specialArgs = userArgs // ceruleanArgs;
|
path = nixosFor node.system nixosConfigurations.${name};
|
||||||
};
|
|
||||||
|
user = user;
|
||||||
|
sudo = "sudo -u";
|
||||||
|
interactiveSudo = interactiveSudo;
|
||||||
|
|
||||||
|
fastConnection = false;
|
||||||
|
|
||||||
|
autoRollback = autoRollback -> rollback;
|
||||||
|
magicRollback = magicRollback -> rollback;
|
||||||
|
activationTimeout = activationTimeout;
|
||||||
|
confirmTimeout = confirmTimeout;
|
||||||
|
|
||||||
|
remoteBuild = remoteBuild;
|
||||||
|
sshUser = ssh.user;
|
||||||
|
sshOpts =
|
||||||
|
ssh.opts
|
||||||
|
++ (
|
||||||
|
if elem "-p" ssh.opts
|
||||||
|
then []
|
||||||
|
else ["-p" (toString ssh.port)]
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
if elem "-A" ssh.opts
|
||||||
|
then []
|
||||||
|
else ["-A"]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
specialArgs = assert (userArgs
|
});
|
||||||
|> attrNames
|
|
||||||
|> all (argName:
|
|
||||||
! ceruleanArgs ? argName
|
|
||||||
|| abort ''
|
|
||||||
`specialArgs` are like super important to Cerulean my love... </3
|
|
||||||
But `args.${argName}` is a reserved argument name :(
|
|
||||||
''));
|
|
||||||
ceruleanArgs._cerulean.specialArgs;
|
|
||||||
in
|
|
||||||
lib.nixosSystem {
|
|
||||||
inherit (node) system;
|
|
||||||
inherit specialArgs;
|
|
||||||
modules =
|
|
||||||
[
|
|
||||||
self.nixosModules.default
|
|
||||||
(findImport /${root}/hosts/${name})
|
|
||||||
]
|
|
||||||
++ (groupModules root)
|
|
||||||
++ node.modules
|
|
||||||
++ nodes.modules;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
deploy.nodes = mapNodes nodes ({
|
checks =
|
||||||
name,
|
inputs.deploy-rs.lib
|
||||||
node,
|
|> mapAttrs (system: deployLib:
|
||||||
...
|
deployLib.deployChecks deploy);
|
||||||
}: let
|
};
|
||||||
inherit
|
|
||||||
(node.deploy)
|
|
||||||
ssh
|
|
||||||
user
|
|
||||||
interactiveSudo
|
|
||||||
remoteBuild
|
|
||||||
rollback
|
|
||||||
autoRollback
|
|
||||||
magicRollback
|
|
||||||
activationTimeout
|
|
||||||
confirmTimeout
|
|
||||||
;
|
|
||||||
|
|
||||||
nixosFor = system: inputs.deploy-rs.lib.${system}.activate.nixos;
|
|
||||||
in {
|
|
||||||
hostname =
|
|
||||||
if ssh.host != null
|
|
||||||
then ssh.host
|
|
||||||
else "";
|
|
||||||
|
|
||||||
profilesOrder = ["default"]; # profiles priority
|
|
||||||
profiles.default = {
|
|
||||||
path = nixosFor node.system nixosConfigurations.${name};
|
|
||||||
|
|
||||||
user = user;
|
|
||||||
sudo = "sudo -u";
|
|
||||||
interactiveSudo = interactiveSudo;
|
|
||||||
|
|
||||||
fastConnection = false;
|
|
||||||
|
|
||||||
autoRollback = autoRollback -> rollback;
|
|
||||||
magicRollback = magicRollback -> rollback;
|
|
||||||
activationTimeout = activationTimeout;
|
|
||||||
confirmTimeout = confirmTimeout;
|
|
||||||
|
|
||||||
remoteBuild = remoteBuild;
|
|
||||||
sshUser = ssh.user;
|
|
||||||
sshOpts =
|
|
||||||
ssh.opts
|
|
||||||
++ (
|
|
||||||
if elem "-p" ssh.opts
|
|
||||||
then []
|
|
||||||
else ["-p" (toString ssh.port)]
|
|
||||||
)
|
|
||||||
++ (
|
|
||||||
if elem "-A" ssh.opts
|
|
||||||
then []
|
|
||||||
else ["-A"]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
checks =
|
|
||||||
inputs.deploy-rs.lib
|
|
||||||
|> mapAttrs (system: deployLib:
|
|
||||||
deployLib.deployChecks deploy);
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,14 @@
|
||||||
root,
|
root,
|
||||||
snow,
|
snow,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
|
snowFlake = snow.findImport /${root}/snow;
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
|
./modules
|
||||||
./nodes
|
./nodes
|
||||||
(snow.findImport /${root}/snow)
|
snowFlake
|
||||||
];
|
];
|
||||||
|
|
||||||
|
outputs = snowFlake;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
nix/snow/modules/default.nix
Normal file
5
nix/snow/modules/default.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{...}: {
|
||||||
|
imports = [
|
||||||
|
./outputs.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
37
nix/snow/modules/outputs.nix
Normal file
37
nix/snow/modules/outputs.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
{lib, ...}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
outputs = mkOption {
|
||||||
|
type = types.submoduleWith {
|
||||||
|
modules = [
|
||||||
|
{
|
||||||
|
freeformType =
|
||||||
|
types.lazyAttrsOf
|
||||||
|
(types.unique
|
||||||
|
{
|
||||||
|
message = ''
|
||||||
|
No option has been declared for this flake output attribute, so its definitions can't be merged automatically.
|
||||||
|
Possible solutions:
|
||||||
|
- Load a module that defines this flake output attribute
|
||||||
|
- Declare an option for this flake output attribute
|
||||||
|
- Make sure the output attribute is spelled correctly
|
||||||
|
- Define the value only once, with a single definition in a single module
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
types.raw);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Raw flake output attributes. Any attribute can be set here, but some
|
||||||
|
attributes are represented by options, to provide appropriate
|
||||||
|
configuration merging.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
102
snow/Cargo.lock
generated
102
snow/Cargo.lock
generated
|
|
@ -315,6 +315,15 @@ dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indoc"
|
||||||
|
version = "2.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
||||||
|
dependencies = [
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.2"
|
version = "1.70.2"
|
||||||
|
|
@ -403,7 +412,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-bdwgc-sys"
|
name = "nix-bindings-bdwgc-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
|
|
@ -412,7 +421,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-expr"
|
name = "nix-bindings-expr"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cstr",
|
"cstr",
|
||||||
|
|
@ -430,7 +439,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-expr-sys"
|
name = "nix-bindings-expr-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"nix-bindings-store-sys",
|
"nix-bindings-store-sys",
|
||||||
|
|
@ -438,10 +447,64 @@ dependencies = [
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix-bindings-fetchers"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"cstr",
|
||||||
|
"ctor",
|
||||||
|
"nix-bindings-fetchers-sys",
|
||||||
|
"nix-bindings-store",
|
||||||
|
"nix-bindings-util",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix-bindings-fetchers-sys"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"nix-bindings-util-sys",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix-bindings-flake"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"cstr",
|
||||||
|
"ctor",
|
||||||
|
"nix-bindings-expr",
|
||||||
|
"nix-bindings-fetchers",
|
||||||
|
"nix-bindings-flake-sys",
|
||||||
|
"nix-bindings-store",
|
||||||
|
"nix-bindings-util",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix-bindings-flake-sys"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"nix-bindings-bdwgc-sys",
|
||||||
|
"nix-bindings-expr-sys",
|
||||||
|
"nix-bindings-fetchers-sys",
|
||||||
|
"nix-bindings-store-sys",
|
||||||
|
"nix-bindings-util-sys",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-store"
|
name = "nix-bindings-store"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"nix-bindings-store-sys",
|
"nix-bindings-store-sys",
|
||||||
|
|
@ -454,7 +517,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-store-sys"
|
name = "nix-bindings-store-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"nix-bindings-util-sys",
|
"nix-bindings-util-sys",
|
||||||
|
|
@ -465,7 +528,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-util"
|
name = "nix-bindings-util"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"nix-bindings-util-sys",
|
"nix-bindings-util-sys",
|
||||||
|
|
@ -474,7 +537,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-bindings-util-sys"
|
name = "nix-bindings-util-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/nixops4/nix-bindings-rust#7de15fa26057c8cf0b6178ff166e529c09ea89a7"
|
source = "git+https://tearforge.net/cry/nixide#716c028bb159e62d3d295c5101d50ee117f027c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
|
|
@ -492,9 +555,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell_polyfill"
|
name = "once_cell_polyfill"
|
||||||
|
|
@ -603,6 +666,12 @@ dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
|
|
@ -665,8 +734,11 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"fern",
|
"fern",
|
||||||
"humantime",
|
"humantime",
|
||||||
|
"indoc",
|
||||||
"log",
|
"log",
|
||||||
"nix-bindings-expr",
|
"nix-bindings-expr",
|
||||||
|
"nix-bindings-fetchers",
|
||||||
|
"nix-bindings-flake",
|
||||||
"nix-bindings-store",
|
"nix-bindings-store",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -689,9 +761,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.26.0"
|
version = "3.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0"
|
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
|
|
@ -960,18 +1032,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.40"
|
version = "0.8.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5"
|
checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.8.40"
|
version = "0.8.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953"
|
checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,14 @@ authors = ["_cry64 <them@dobutterfliescry.net>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nix-bindings-store = { git = "https://github.com/nixops4/nix-bindings-rust" }
|
nix-bindings-expr = { git = "https://tearforge.net/cry/nixide" }
|
||||||
nix-bindings-expr = { git = "https://github.com/nixops4/nix-bindings-rust" }
|
nix-bindings-flake = { git = "https://tearforge.net/cry/nixide" }
|
||||||
|
nix-bindings-fetchers = { git = "https://tearforge.net/cry/nixide" }
|
||||||
|
nix-bindings-store = { git = "https://tearforge.net/cry/nixide" }
|
||||||
|
|
||||||
|
indoc = "2"
|
||||||
anyhow = "1.0.102"
|
anyhow = "1.0.102"
|
||||||
|
|
||||||
clap = { version = "4.5.60", features = ["derive"] }
|
clap = { version = "4.5.60", features = ["derive"] }
|
||||||
log = "0.4.29"
|
log = "0.4.29"
|
||||||
fern = { version="0.7.1", features = ["colored"] }
|
fern = { version="0.7.1", features = ["colored"] }
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
mod nix;
|
||||||
|
|
||||||
use nix_bindings_expr::eval_state::{gc_register_my_thread, init, EvalState};
|
use nix_bindings_expr::eval_state::{gc_register_my_thread, init, EvalState};
|
||||||
use nix_bindings_store::store::Store;
|
use nix_bindings_store::store::Store;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
|
||||||
114
snow/src/nix/flake.rs
Normal file
114
snow/src/nix/flake.rs
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use nix_bindings_expr::{eval_state::EvalState, value::Value};
|
||||||
|
use nix_bindings_fetchers::FetchersSettings;
|
||||||
|
use nix_bindings_flake::{FlakeLockFlags, FlakeSettings, LockedFlake};
|
||||||
|
use nix_bindings_store::store::Store;
|
||||||
|
|
||||||
|
use crate::nix::FlakeRef;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum FlakeLockMode {
|
||||||
|
/// Configures [LockedFlake::lock] to make incremental changes to the lock file as needed. Changes are written to file.
|
||||||
|
WriteAsNeeded,
|
||||||
|
|
||||||
|
/// Like [FlakeLockMode::WriteAsNeeded], but does not write to the lock file.
|
||||||
|
Virtual,
|
||||||
|
|
||||||
|
/// Make [LockedFlake::lock] check if the lock file is up to date. If not, an error is returned.
|
||||||
|
Check,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FlakeBuilder {
|
||||||
|
flake_ref: Rc<RefCell<FlakeRef>>,
|
||||||
|
|
||||||
|
lock_mode: FlakeLockMode,
|
||||||
|
lock_flags: FlakeLockFlags,
|
||||||
|
eval_state: Option<EvalState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Flake {
|
||||||
|
flake_ref: Rc<RefCell<FlakeRef>>,
|
||||||
|
locked_flake: LockedFlake,
|
||||||
|
|
||||||
|
lock_mode: FlakeLockMode,
|
||||||
|
eval_state: EvalState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlakeBuilder {
|
||||||
|
pub fn new(flake_ref: Rc<RefCell<FlakeRef>>, lock_mode: FlakeLockMode) -> Result<Self> {
|
||||||
|
let mut lock_flags = FlakeLockFlags::new(&flake_ref.as_ref().borrow().flake_settings)?;
|
||||||
|
|
||||||
|
match lock_mode {
|
||||||
|
FlakeLockMode::WriteAsNeeded => lock_flags.set_mode_write_as_needed(),
|
||||||
|
FlakeLockMode::Virtual => lock_flags.set_mode_virtual(),
|
||||||
|
FlakeLockMode::Check => lock_flags.set_mode_check(),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
Ok(FlakeBuilder {
|
||||||
|
flake_ref: flake_ref,
|
||||||
|
|
||||||
|
lock_mode,
|
||||||
|
lock_flags,
|
||||||
|
eval_state: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds an input override to the lock file that will be produced.
|
||||||
|
/// The [LockedFlake::lock] operation will not write to the lock file.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `path` - The input name/path to override (must not be empty)
|
||||||
|
/// * `flake_ref` - The flake reference to use as the override
|
||||||
|
pub fn override_input(mut self, path: &str, flake_ref: &FlakeRef) -> Result<Self> {
|
||||||
|
assert!(
|
||||||
|
!path.is_empty(),
|
||||||
|
"The input path for `FlakeBuilder::override_input` cannot be an empty string slice!"
|
||||||
|
);
|
||||||
|
|
||||||
|
self.lock_flags.add_input_override(path, &flake_ref.ref_)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(&mut self) -> Result<Flake> {
|
||||||
|
let eval_state = match self.eval_state.take() {
|
||||||
|
Some(state) => state,
|
||||||
|
None => {
|
||||||
|
let store = Store::open(None, HashMap::new())?;
|
||||||
|
EvalState::new(store, [])?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let locked_flake = LockedFlake::lock(
|
||||||
|
&FetchersSettings::new()?,
|
||||||
|
&FlakeSettings::new()?,
|
||||||
|
&eval_state,
|
||||||
|
&self.lock_flags,
|
||||||
|
&self.flake_ref.as_ref().borrow().ref_,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Flake {
|
||||||
|
flake_ref: Rc::clone(&self.flake_ref),
|
||||||
|
locked_flake,
|
||||||
|
|
||||||
|
lock_mode: self.lock_mode.clone(),
|
||||||
|
eval_state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flake {
|
||||||
|
pub fn new(flake_ref: Rc<RefCell<FlakeRef>>, lock_mode: FlakeLockMode) -> Result<Self> {
|
||||||
|
let mut builder = FlakeBuilder::new(flake_ref, lock_mode)?;
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outputs(&mut self) -> Result<Value> {
|
||||||
|
self.locked_flake.outputs(
|
||||||
|
&self.flake_ref.as_ref().borrow().flake_settings,
|
||||||
|
&mut self.eval_state,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
79
snow/src/nix/flakeref.rs
Normal file
79
snow/src/nix/flakeref.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use indoc::indoc;
|
||||||
|
use nix_bindings_fetchers::FetchersSettings;
|
||||||
|
use nix_bindings_flake::{FlakeReference, FlakeReferenceParseFlags, FlakeSettings};
|
||||||
|
|
||||||
|
pub struct FlakeRef {
|
||||||
|
pub(super) ref_: FlakeReference,
|
||||||
|
pub path: PathBuf,
|
||||||
|
|
||||||
|
pub flake_settings: FlakeSettings,
|
||||||
|
pub fetch_settings: FetchersSettings,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlakeRef {
|
||||||
|
/// Parse a flake reference from a string.
|
||||||
|
/// The string must be a valid flake reference, such as `github:owner/repo`.
|
||||||
|
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
|
||||||
|
/// in which case, the returned `flake_ref.path` will contain the fragment.
|
||||||
|
pub fn new<P: AsRef<Path>>(reference: &str, base_directory: Option<P>) -> Result<FlakeRef> {
|
||||||
|
let flake_settings = FlakeSettings::new()?;
|
||||||
|
let fetch_settings = FetchersSettings::new()?;
|
||||||
|
|
||||||
|
let mut flags = FlakeReferenceParseFlags::new(&flake_settings)?;
|
||||||
|
|
||||||
|
if let Some(base_directory) = base_directory {
|
||||||
|
flags.set_base_directory(
|
||||||
|
base_directory
|
||||||
|
.as_ref()
|
||||||
|
.to_str()
|
||||||
|
.context("The given flake reference path is not provided as valid unicode")?,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
// TODO: try see if libnix uses the cwd as a fallback (aka is this assert pointless?)
|
||||||
|
assert!(
|
||||||
|
reference.starts_with("."),
|
||||||
|
indoc! {"
|
||||||
|
Attempted to construct FlakeRef from relative path without declaring `base_directory`!
|
||||||
|
Call to `FlakeRef::absolute(&str)` should actually be `FlakeRef::relative(&str, dyn AsRef<Path>)`.
|
||||||
|
"}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlakeReference::parse_with_fragment(&fetch_settings, &flake_settings, &flags, reference)
|
||||||
|
.map(|(reference, path)| FlakeRef {
|
||||||
|
ref_: reference,
|
||||||
|
path: PathBuf::from(path),
|
||||||
|
flake_settings,
|
||||||
|
fetch_settings,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// >[!WARNING]
|
||||||
|
/// > Do not use [FlakeRef::absolute(&str)](FlakeRef::absolute) to construct a [FlakeRef] from a relative path!
|
||||||
|
/// > Use [FlakeRef::relative(&str, dyn AsRef<Path>)](FlakeRef::relative) instead to declare the `base_directory`.
|
||||||
|
///
|
||||||
|
/// Parse a flake reference from a string.
|
||||||
|
/// The string must be a valid flake reference, such as `github:owner/repo`.
|
||||||
|
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
|
||||||
|
/// in which case, the returned `flake_ref.path` will contain the fragment.
|
||||||
|
pub fn absolute(reference: &str) -> Result<FlakeRef> {
|
||||||
|
FlakeRef::new(reference, None::<&Path>)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a flake reference from a string.
|
||||||
|
/// The string must be a valid flake reference, such as `github:owner/repo`.
|
||||||
|
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
|
||||||
|
/// in which case, the returned `flake_ref.path` will contain the fragment.
|
||||||
|
pub fn relative<P: AsRef<Path>>(reference: &str, base_directory: P) -> Result<FlakeRef> {
|
||||||
|
FlakeRef::new(reference, Some(base_directory))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<FlakeReference> for FlakeRef {
|
||||||
|
fn into(self) -> FlakeReference {
|
||||||
|
self.ref_
|
||||||
|
}
|
||||||
|
}
|
||||||
7
snow/src/nix/mod.rs
Normal file
7
snow/src/nix/mod.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
mod flake;
|
||||||
|
mod flakeref;
|
||||||
|
mod nix;
|
||||||
|
|
||||||
|
pub use flake::{Flake, FlakeBuilder, FlakeLockMode};
|
||||||
|
pub use flakeref::FlakeRef;
|
||||||
|
pub use nix::Nix;
|
||||||
10
snow/src/nix/nix.rs
Normal file
10
snow/src/nix/nix.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use derive_more::From;
|
||||||
|
use nix_bindings_fetchers::FetchersSettings;
|
||||||
|
use nix_bindings_flake::{FlakeReference, FlakeReferenceParseFlags, FlakeSettings};
|
||||||
|
|
||||||
|
pub struct Nix {}
|
||||||
|
|
||||||
|
impl Nix {}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue