forked from Fediversity/Fediversity
add nixops4 data model test
This commit is contained in:
parent
b134464c6e
commit
2ca18eabe8
7 changed files with 194 additions and 113 deletions
|
@ -163,7 +163,7 @@ in
|
||||||
'')}
|
'')}
|
||||||
|
|
||||||
${
|
${
|
||||||
if config.useFlake then
|
if true then
|
||||||
''
|
''
|
||||||
## NOTE: This is super slow. It could probably be optimised in Nix, for
|
## NOTE: This is super slow. It could probably be optimised in Nix, for
|
||||||
## instance by allowing to grab things directly from the host's store.
|
## instance by allowing to grab things directly from the host's store.
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
{
|
{
|
||||||
targetMachines = [
|
targetMachines = [
|
||||||
"hello"
|
"ssh"
|
||||||
|
"nixops4"
|
||||||
];
|
];
|
||||||
pathToRoot = ../../..;
|
pathToRoot = ../../..;
|
||||||
pathFromRoot = ./.;
|
pathFromRoot = ./.;
|
||||||
|
enableAcme = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,5 +12,10 @@ runNixOSTest {
|
||||||
./nixosTest.nix
|
./nixosTest.nix
|
||||||
];
|
];
|
||||||
_module.args = { inherit inputs sources; };
|
_module.args = { inherit inputs sources; };
|
||||||
inherit (import ./constants.nix) targetMachines pathToRoot pathFromRoot;
|
inherit (import ./constants.nix)
|
||||||
|
targetMachines
|
||||||
|
pathToRoot
|
||||||
|
pathFromRoot
|
||||||
|
enableAcme
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@ let
|
||||||
inherit (pkgs) lib;
|
inherit (pkgs) lib;
|
||||||
deployment-config = config;
|
deployment-config = config;
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
|
inherit (import ./constants.nix) targetMachines pathToRoot pathFromRoot;
|
||||||
eval =
|
eval =
|
||||||
module:
|
module:
|
||||||
(lib.evalModules {
|
(lib.evalModules {
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit pkgs inputs;
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
module
|
module
|
||||||
|
@ -98,44 +99,67 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
environments.single-nixos-vm = environment: {
|
environments =
|
||||||
resources."operator-environment".login-shell.username = "operator";
|
let
|
||||||
implementation = requests: {
|
mkNixosConfiguration =
|
||||||
input = requests;
|
environment: requests:
|
||||||
output.ssh-host = {
|
{ ... }:
|
||||||
ssh = {
|
{
|
||||||
username = "root";
|
imports = [
|
||||||
inherit (deployment-config) host;
|
./options.nix
|
||||||
key-file = null;
|
../common/sharedOptions.nix
|
||||||
|
../common/targetNode.nix
|
||||||
|
"${nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
|
||||||
|
];
|
||||||
|
|
||||||
|
users.users = environment.config.resources."operator-environment".login-shell.apply {
|
||||||
|
resources = lib.filterAttrs (_name: value: value ? login-shell) (
|
||||||
|
lib.concatMapAttrs (
|
||||||
|
k': req: lib.mapAttrs' (k: lib.nameValuePair "${k'}.${k}") req.resources
|
||||||
|
) requests
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
nixos-configuration =
|
in
|
||||||
{ ... }:
|
{
|
||||||
{
|
single-nixos-vm-ssh = environment: {
|
||||||
imports = [
|
resources."operator-environment".login-shell.username = "operator";
|
||||||
./options.nix
|
implementation = requests: {
|
||||||
../common/sharedOptions.nix
|
input = requests;
|
||||||
../common/targetNode.nix
|
output.ssh-host = {
|
||||||
"${nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
|
nixos-configuration = mkNixosConfiguration environment requests;
|
||||||
];
|
ssh = {
|
||||||
|
username = "root";
|
||||||
inherit (deployment-config) enableAcme;
|
inherit (deployment-config) host;
|
||||||
acmeNodeIP =
|
key-file = null;
|
||||||
if deployment-config.enableAcme then
|
|
||||||
deployment-config.nodes.acme.networking.primaryIPAddress
|
|
||||||
else
|
|
||||||
null;
|
|
||||||
|
|
||||||
users.users = environment.config.resources."operator-environment".login-shell.apply {
|
|
||||||
resources = lib.filterAttrs (_name: value: value ? login-shell) (
|
|
||||||
lib.concatMapAttrs (
|
|
||||||
k': req: lib.mapAttrs' (k: lib.nameValuePair "${k'}.${k}") req.resources
|
|
||||||
) requests
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
single-nixos-vm-nixops4 = environment: {
|
||||||
|
resources."operator-environment".login-shell.username = "operator";
|
||||||
|
implementation = requests: {
|
||||||
|
input = requests;
|
||||||
|
output.nixops4 =
|
||||||
|
{ providers, ... }:
|
||||||
|
{
|
||||||
|
providers = {
|
||||||
|
inherit (inputs.nixops4.modules.nixops4Provider) local;
|
||||||
|
};
|
||||||
|
resources = lib.genAttrs targetMachines (nodeName: {
|
||||||
|
type = providers.local.exec;
|
||||||
|
imports = [
|
||||||
|
inputs.nixops4-nixos.modules.nixops4Resource.nixos
|
||||||
|
../common/targetResource.nix
|
||||||
|
];
|
||||||
|
nixos.module = mkNixosConfiguration environment requests;
|
||||||
|
_module.args = { inherit inputs sources; };
|
||||||
|
inherit nodeName pathToRoot pathFromRoot;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
options = {
|
options = {
|
||||||
"example-configuration" = mkOption {
|
"example-configuration" = mkOption {
|
||||||
|
@ -145,12 +169,24 @@ let
|
||||||
applications.hello.enable = true;
|
applications.hello.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"example-deployment" = mkOption {
|
"ssh-deployment" =
|
||||||
type = config.environments.single-nixos-vm.resource-mapping.output-type;
|
let
|
||||||
default = config.environments.single-nixos-vm.deployment config."example-configuration";
|
env = config.environments."single-nixos-vm-ssh";
|
||||||
};
|
in
|
||||||
|
mkOption {
|
||||||
|
type = env.resource-mapping.output-type;
|
||||||
|
default = env.deployment config."example-configuration";
|
||||||
|
};
|
||||||
|
"nixops4-deployment" =
|
||||||
|
let
|
||||||
|
env = config.environments."single-nixos-vm-nixops4";
|
||||||
|
in
|
||||||
|
mkOption {
|
||||||
|
type = env.resource-mapping.output-type;
|
||||||
|
default = env.deployment config."example-configuration";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
fediversity."example-deployment"
|
fediversity
|
||||||
|
|
26
deployment/check/data-model/flake-under-test.nix
Normal file
26
deployment/check/data-model/flake-under-test.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixops4.follows = "nixops4-nixos/nixops4";
|
||||||
|
nixops4-nixos.url = "github:nixops4/nixops4-nixos";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
inputs:
|
||||||
|
import ./mkFlake.nix inputs (
|
||||||
|
{ inputs, ... }:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs.nixops4.modules.flake.default
|
||||||
|
];
|
||||||
|
|
||||||
|
nixops4Deployments.check-deployment-model =
|
||||||
|
(import ./deployment/check/data-model/deployment.nix {
|
||||||
|
inherit system inputs;
|
||||||
|
config.host = "nixops4";
|
||||||
|
})."nixops4-deployment".nixops4;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -2,11 +2,28 @@
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (import ./constants.nix) targetMachines pathToRoot;
|
inherit (import ./constants.nix) pathToRoot;
|
||||||
escapedJson = v: lib.replaceStrings [ "\"" ] [ "\\\\\"" ] (lib.strings.toJSON v);
|
escapedJson = v: lib.replaceStrings [ "\"" ] [ "\\\\\"" ] (lib.strings.toJSON v);
|
||||||
|
deployment-config = {
|
||||||
|
inherit (config) enableAcme;
|
||||||
|
acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null;
|
||||||
|
host = "ssh";
|
||||||
|
};
|
||||||
|
inherit
|
||||||
|
((import ./deployment.nix {
|
||||||
|
inherit (pkgs) system;
|
||||||
|
inherit inputs;
|
||||||
|
config = deployment-config;
|
||||||
|
})."ssh-deployment".ssh-host.ssh
|
||||||
|
)
|
||||||
|
host
|
||||||
|
username
|
||||||
|
key-file
|
||||||
|
;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
_class = "nixosTest";
|
_class = "nixosTest";
|
||||||
|
@ -20,14 +37,24 @@ in
|
||||||
../../function.nix
|
../../function.nix
|
||||||
./constants.nix
|
./constants.nix
|
||||||
./deployment.nix
|
./deployment.nix
|
||||||
|
./options.nix
|
||||||
|
(config.pathToCwd + "/flake-under-test.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
nodes.deployer =
|
nodes.deployer =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
inputs.nixops4.packages.${system}.default
|
||||||
jq
|
jq
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# FIXME: sad times
|
||||||
|
system.extraDependencies = with pkgs; [
|
||||||
|
jq
|
||||||
|
jq.inputDerivation
|
||||||
|
];
|
||||||
|
|
||||||
system.extraDependenciesFromModule =
|
system.extraDependenciesFromModule =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
|
@ -38,77 +65,58 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
extraTestScript = ''
|
extraTestScript = ''
|
||||||
${lib.concatStringsSep "\n" (
|
with subtest("nixops4"):
|
||||||
lib.lists.map (
|
nixops4.fail("hello 1>&2")
|
||||||
nodeName:
|
deployer.succeed("nixops4 apply check-deployment-model --show-trace --verbose --no-interactive 1>&2")
|
||||||
let
|
nixops4.succeed("su - operator -c hello 1>&2")
|
||||||
deployment-config = {
|
|
||||||
inherit (config) enableAcme;
|
|
||||||
acmeNodeIP = if config.enableAcme then config.nodes.acme.networking.primaryIPAddress else null;
|
|
||||||
host = nodeName;
|
|
||||||
};
|
|
||||||
inherit
|
|
||||||
((import ./deployment.nix {
|
|
||||||
inherit (pkgs) system;
|
|
||||||
config = deployment-config;
|
|
||||||
}).ssh-host.ssh
|
|
||||||
)
|
|
||||||
host
|
|
||||||
username
|
|
||||||
key-file
|
|
||||||
;
|
|
||||||
in
|
|
||||||
''
|
|
||||||
with subtest("Check the status before deployment"):
|
|
||||||
${nodeName}.fail("${nodeName} 1>&2")
|
|
||||||
|
|
||||||
with subtest("Run the deployment for ${nodeName}"):
|
with subtest("ssh: Check the status before deployment"):
|
||||||
deployer.succeed("""
|
ssh.fail("hello 1>&2")
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# INSTANTIATE
|
with subtest("ssh: Run the deployment"):
|
||||||
command=(nix-instantiate --show-trace --expr '
|
deployer.succeed("""
|
||||||
let
|
set -euo pipefail
|
||||||
system = "${pkgs.system}"; # FIXME: what system are we deploying to?
|
|
||||||
in
|
# INSTANTIATE
|
||||||
import ${pathToRoot}/deployment/nixos.nix {
|
command=(nix-instantiate --show-trace --expr '
|
||||||
inherit system;
|
let
|
||||||
configuration = (
|
system = "${pkgs.system}"; # FIXME: what system are we deploying to?
|
||||||
import ${pathToRoot}/deployment/check/data-model/deployment.nix {
|
in
|
||||||
inherit system;
|
import ${pathToRoot}/deployment/nixos.nix {
|
||||||
config = builtins.fromJSON "${escapedJson deployment-config}";
|
inherit system;
|
||||||
}
|
configuration = (
|
||||||
).ssh-host.nixos-configuration;
|
import ${pathToRoot}/deployment/check/data-model/deployment.nix {
|
||||||
}
|
inherit system;
|
||||||
')
|
config = builtins.fromJSON "${escapedJson deployment-config}";
|
||||||
# DEPLOY
|
}
|
||||||
host="${lib.defaultTo "root" username}@${host}"
|
)."ssh-deployment".ssh-host.nixos-configuration;
|
||||||
sshOpts=(
|
}
|
||||||
${if key-file == null then "" else "-i ${key-file}"}
|
')
|
||||||
-o StrictHostKeyChecking=no
|
# DEPLOY
|
||||||
-o "ConnectTimeout=1"
|
host="${lib.defaultTo "root" username}@${host}"
|
||||||
-o "ServerAliveInterval=1"
|
sshOpts=(
|
||||||
)
|
${if key-file == null then "" else "-i ${key-file}"}
|
||||||
# instantiate the config in /nix/store
|
-o StrictHostKeyChecking=no
|
||||||
"''${command[@]}" --show-trace -A out_path
|
-o "ConnectTimeout=1"
|
||||||
# get the realized derivation to deploy
|
-o "ServerAliveInterval=1"
|
||||||
outPath=$(nix-store --realize "$("''${command[@]}" --show-trace --eval --strict --json | jq -r '.drv_path')")
|
)
|
||||||
# deploy the config by nix-copy-closure
|
# instantiate the config in /nix/store
|
||||||
NIX_SSHOPTS="''${sshOpts[*]}" nix-copy-closure --to "$host" "$outPath" --gzip --use-substitutes
|
"''${command[@]}" --show-trace -A out_path
|
||||||
# switch the remote host to the config
|
# get the realized derivation to deploy
|
||||||
output=$(ssh "''${sshOpts[@]}" "$host" "nix-env --profile /nix/var/nix/profiles/system --set $outPath; nohup $outPath/bin/switch-to-configuration switch &" 2>&1) || echo "status code: $?"
|
outPath=$(nix-store --realize "$("''${command[@]}" --show-trace --eval --strict --json | jq -r '.drv_path')")
|
||||||
echo "output: $output"
|
# deploy the config by nix-copy-closure
|
||||||
if [[ $output != *"Timeout, server ${nodeName} not responding"* ]]; then
|
NIX_SSHOPTS="''${sshOpts[*]}" nix-copy-closure --to "$host" "$outPath" --gzip --use-substitutes
|
||||||
echo "non-timeout error: $output"
|
# switch the remote host to the config
|
||||||
exit 1
|
output=$(ssh "''${sshOpts[@]}" "$host" "nix-env --profile /nix/var/nix/profiles/system --set $outPath; nohup $outPath/bin/switch-to-configuration switch &" 2>&1) || echo "status code: $?"
|
||||||
else
|
echo "output: $output"
|
||||||
exit 0
|
if [[ $output != *"Timeout, server ssh not responding"* ]]; then
|
||||||
fi
|
echo "non-timeout error: $output"
|
||||||
""")
|
exit 1
|
||||||
${nodeName}.wait_for_unit("multi-user.target")
|
else
|
||||||
${nodeName}.succeed("su - operator -c ${nodeName} 1>&2")
|
exit 0
|
||||||
''
|
fi
|
||||||
) targetMachines
|
""")
|
||||||
)}
|
ssh.wait_for_unit("multi-user.target")
|
||||||
|
ssh.succeed("su - operator -c hello 1>&2")
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,10 @@ let
|
||||||
description = "A NixOps4 NixOS deployment. For an example, see https://github.com/nixops4/nixops4-nixos/blob/main/example/deployment.nix.";
|
description = "A NixOps4 NixOS deployment. For an example, see https://github.com/nixops4/nixops4-nixos/blob/main/example/deployment.nix.";
|
||||||
type = nixops4Deployment;
|
type = nixops4Deployment;
|
||||||
};
|
};
|
||||||
|
nixops4 = mkOption {
|
||||||
|
description = "A NixOps4 NixOS deployment. For an example, see https://github.com/nixops4/nixops4-nixos/blob/main/example/deployment.nix.";
|
||||||
|
type = nixops4Deployment;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue