Compare commits

..

1 commit

Author SHA1 Message Date
e5710979ba
fix typo 2025-07-17 19:00:41 +02:00
74 changed files with 309 additions and 2232 deletions

View file

@ -0,0 +1,58 @@
on:
pull_request:
types:
- opened
- synchronize
- reopened
push:
branches:
- main
jobs:
check-pre-commit:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix-build -A tests
check-data-model:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix-shell --run 'nix-unit ./deployment/data-model-test.nix'
check-mastodon:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.test-mastodon-service -L
check-peertube:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.test-peertube-service -L
check-panel:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix-build -A tests.panel
check-deployment-basic:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-basic -L
check-deployment-cli:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-cli -L
check-deployment-panel:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-panel -L

View file

@ -1,62 +0,0 @@
#!/bin/sh
set -euC
cd "$(dirname "$0")" || exit 3
nix_eval () { nix eval --impure --raw --expr "with builtins; $1"; }
system=$(nix_eval "currentSystem")
checks=$(nix_eval "toJSON (attrNames (getFlake (toString ../..)).checks.$system)")
output=$(mktemp)
{
cat <<EOF
name: Nix flake checks
on:
workflow_dispatch: # allows manual triggering
pull_request:
types:
- opened
- synchronize
- reopened
push:
branches:
- main
jobs:
_checks:
needs: $checks
runs-on: native
steps:
- run: true
_complete:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix-shell --run '.forgejo/workflows/nix-flake-check.sh check'
EOF
for check in $(echo "$checks" | jq -r .[]); do
cat <<EOF
$check:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.$system.$check -vL
EOF
done
} >| "$output"
target=$(basename "$0" .sh).yaml
if [ $# -eq 1 ] && [ "$1" = "check" ]; then
if ! diff_output=$(diff --color=always "$target" "$output"); then
printf >&2 'Changes detected (\e[31m< current\e[0m | \e[32m> generated\e[0m):\n%s\n' "$diff_output"
exit 1
fi
else
mv "$output" "$target"
fi

View file

@ -1,301 +0,0 @@
name: Nix flake checks
on:
workflow_dispatch: # allows manual triggering
pull_request:
types:
- opened
- synchronize
- reopened
push:
branches:
- main
jobs:
_checks:
needs: ["data-model","deployment-basic","deployment-cli","deployment-model-nixops4","deployment-model-ssh","deployment-model-tf","deployment-panel","nixops-deployment-providers-default","nixops-deployment-providers-fedi200","nixops-deployment-providers-fedi201","nixops-deployment-providers-forgejo-ci","nixops-deployment-providers-test","nixops-deployment-providers-vm02116","nixops-deployment-providers-vm02187","nixosConfigurations-fedi200","nixosConfigurations-fedi201","nixosConfigurations-forgejo-ci","nixosConfigurations-test01","nixosConfigurations-test02","nixosConfigurations-test03","nixosConfigurations-test04","nixosConfigurations-test05","nixosConfigurations-test06","nixosConfigurations-test11","nixosConfigurations-test12","nixosConfigurations-test13","nixosConfigurations-test14","nixosConfigurations-vm02116","nixosConfigurations-vm02187","panel","pre-commit","proxmox-basic","test-mastodon-service","test-peertube-service","vmOptions-fedi200","vmOptions-fedi201","vmOptions-test01","vmOptions-test02","vmOptions-test03","vmOptions-test04","vmOptions-test05","vmOptions-test06","vmOptions-test11","vmOptions-test12","vmOptions-test13","vmOptions-test14"]
runs-on: native
steps:
- run: true
_complete:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix-shell --run '.forgejo/workflows/nix-flake-check.sh check'
data-model:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix run .#checks.x86_64-linux.data-model -vL
deployment-basic:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-basic -vL
deployment-cli:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-cli -vL
deployment-model-nixops4:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-model-nixops4 -vL
deployment-model-ssh:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-model-ssh -vL
deployment-model-tf:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-model-tf -vL
deployment-panel:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.deployment-panel -vL
nixops-deployment-providers-default:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-default -vL
nixops-deployment-providers-fedi200:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-fedi200 -vL
nixops-deployment-providers-fedi201:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-fedi201 -vL
nixops-deployment-providers-forgejo-ci:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-forgejo-ci -vL
nixops-deployment-providers-test:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-test -vL
nixops-deployment-providers-vm02116:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-vm02116 -vL
nixops-deployment-providers-vm02187:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixops-deployment-providers-vm02187 -vL
nixosConfigurations-fedi200:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-fedi200 -vL
nixosConfigurations-fedi201:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-fedi201 -vL
nixosConfigurations-forgejo-ci:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-forgejo-ci -vL
nixosConfigurations-test01:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test01 -vL
nixosConfigurations-test02:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test02 -vL
nixosConfigurations-test03:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test03 -vL
nixosConfigurations-test04:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test04 -vL
nixosConfigurations-test05:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test05 -vL
nixosConfigurations-test06:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test06 -vL
nixosConfigurations-test11:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test11 -vL
nixosConfigurations-test12:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test12 -vL
nixosConfigurations-test13:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test13 -vL
nixosConfigurations-test14:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-test14 -vL
nixosConfigurations-vm02116:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-vm02116 -vL
nixosConfigurations-vm02187:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.nixosConfigurations-vm02187 -vL
panel:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.panel -vL
pre-commit:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.pre-commit -vL
proxmox-basic:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.proxmox-basic -vL
test-mastodon-service:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.test-mastodon-service -vL
test-peertube-service:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.test-peertube-service -vL
vmOptions-fedi200:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-fedi200 -vL
vmOptions-fedi201:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-fedi201 -vL
vmOptions-test01:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test01 -vL
vmOptions-test02:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test02 -vL
vmOptions-test03:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test03 -vL
vmOptions-test04:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test04 -vL
vmOptions-test05:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test05 -vL
vmOptions-test06:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test06 -vL
vmOptions-test11:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test11 -vL
vmOptions-test12:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test12 -vL
vmOptions-test13:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test13 -vL
vmOptions-test14:
runs-on: native
steps:
- uses: actions/checkout@v4
- run: nix build .#checks.x86_64-linux.vmOptions-test14 -vL

View file

@ -13,7 +13,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Update pins
run: nix-shell --run "npins --verbose update"
run: nix-shell --run "npins update"
- name: Create PR
uses: https://github.com/KiaraGrouwstra/gitea-create-pull-request@f9f80aa5134bc5c03c38f5aaa95053492885b397
with:

View file

@ -146,9 +146,8 @@ details as to what they are for. As an overview:
- [`keys/`](./keys) contains the public keys of the contributors to this project
as well as the systems that we administrate.
- [`machines/`](./machines) contains the code of our machines for internal infra and test VMs.
- [`panel/`](./panel) contains the code of our front-end.
- [`matrix/`](./matrix) contains everything having to do with setting up a
fully-featured Matrix server.
- [`secrets/`](./secrets) contains the secrets that need to get injected into
machine configurations.

View file

@ -11,8 +11,7 @@ let
;
inherit (pkgs) lib;
inherit (import sources.flake-inputs) import-flake;
inputs = (import-flake { src = ./.; }).inputs;
inherit (inputs) nixops4;
inherit ((import-flake { src = ./.; }).inputs) nixops4;
panel = import ./panel { inherit sources system; };
pre-commit-check =
(import "${git-hooks}/nix" {
@ -65,7 +64,6 @@ in
pkgs.openssh
pkgs.httpie
pkgs.jq
pkgs.diffutils
pkgs.nix-unit
test-loop
nixops4.packages.${system}.default
@ -80,7 +78,6 @@ in
# re-export inputs so they can be overridden granularly
# (they can't be accessed from the outside any other way)
inherit
inputs
sources
system
pkgs

View file

@ -5,5 +5,4 @@
];
pathToRoot = ../../..;
pathFromRoot = ./.;
useFlake = true;
}

View file

@ -10,10 +10,5 @@ runNixOSTest {
./nixosTest.nix
];
_module.args = { inherit inputs sources; };
inherit (import ./constants.nix)
targetMachines
pathToRoot
pathFromRoot
useFlake
;
inherit (import ./constants.nix) targetMachines pathToRoot pathFromRoot;
}

View file

@ -1,9 +1,4 @@
{
inputs,
lib,
config,
...
}:
{ inputs, lib, ... }:
{
_class = "nixosTest";
@ -13,7 +8,6 @@
sourceFileset = lib.fileset.unions [
./constants.nix
./deployment.nix
(config.pathToCwd + "/flake-under-test.nix")
];
nodes.deployer =

View file

@ -8,5 +8,4 @@
pathToRoot = ../../..;
pathFromRoot = ./.;
enableAcme = true;
useFlake = true;
}

View file

@ -15,6 +15,5 @@ runNixOSTest {
pathToRoot
pathFromRoot
enableAcme
useFlake
;
}

View file

@ -1,7 +1,6 @@
{
inputs,
hostPkgs,
config,
lib,
...
}:
@ -20,7 +19,6 @@ in
sourceFileset = lib.fileset.unions [
./constants.nix
./deployments.nix
(config.pathToCwd + "/flake-under-test.nix")
# REVIEW: I would like to be able to grab all of `/deployment` minus
# `/deployment/check`, but I can't because there is a bunch of other files

View file

@ -1,25 +0,0 @@
{
lib,
...
}:
let
inherit (lib) mkOption types;
in
{
options = {
host = mkOption {
type = types.str;
description = "name of the host to deploy to";
};
targetSystem = mkOption {
type = types.str;
description = "name of the host to deploy to";
};
sshOpts = mkOption {
description = "Extra SSH options (`-o`) to use.";
type = types.listOf types.str;
default = [ ];
example = "ConnectTimeout=60";
};
};
}

View file

@ -1,256 +0,0 @@
{
config,
system,
inputs ? (import ../../../default.nix { }).inputs, # XXX can't be serialized
sources ? import ../../../npins,
...
}@args:
let
# having this module's location (`self`) and (serializable) `args`, we know
# enough to make it re-call itself to extract different info elsewhere later.
# we use this to make a deployment script using the desired nixos config,
# which would otherwise not be serializable, while nix also makes it hard to
# produce its derivation to pass thru without a `nix-instantiate` call,
# which in turn would need to be passed the (unserializable) nixos config.
self = "deployment/check/common/data-model.nix";
inherit (sources) nixpkgs;
pkgs = import nixpkgs { inherit system; };
inherit (pkgs) lib;
deployment-config = config;
inherit (deployment-config)
nodeName
pathToRoot
targetSystem
sshOpts
;
inherit (lib) mkOption types;
eval =
module:
(lib.evalModules {
specialArgs = {
inherit pkgs inputs;
};
modules = [
module
../../data-model.nix
];
}).config;
fediversity = eval (
{ config, ... }:
{
config = {
resources.login-shell = {
description = "The operator needs to be able to log into the shell";
request =
{ ... }:
{
_class = "fediversity-resource-request";
options = {
wheel = mkOption {
description = "Whether the login user needs root permissions";
type = types.bool;
default = false;
};
packages = mkOption {
description = "Packages that need to be available in the user environment";
type = with types; attrsOf package;
};
};
};
policy =
{ config, ... }:
{
_class = "fediversity-resource-policy";
options = {
username = mkOption {
description = "Username for the operator";
type = types.str; # TODO: use the proper constraints from NixOS
};
wheel = mkOption {
description = "Whether to allow login with root permissions";
type = types.bool;
default = false;
};
};
config = {
resource-type = types.raw; # TODO: splice out the user type from NixOS
apply =
requests:
let
# Filter out requests that need wheel if policy doesn't allow it
validRequests = lib.filterAttrs (
_name: req: !req.login-shell.wheel || config.wheel
) requests.resources;
in
lib.optionalAttrs (validRequests != { }) {
${config.username} = {
isNormalUser = true;
packages =
with lib;
attrValues (concatMapAttrs (_name: request: request.login-shell.packages) validRequests);
extraGroups = lib.optional config.wheel "wheel";
};
};
};
};
};
applications.hello =
{ ... }:
{
description = ''Command-line tool that will print "Hello, world!" on the terminal'';
module =
{ ... }:
{
options.enable = lib.mkEnableOption "Hello in the shell";
};
implementation = cfg: {
resources = lib.optionalAttrs cfg.enable {
hello.login-shell.packages.hello = pkgs.hello;
};
};
};
environments =
let
mkNixosConfiguration =
environment: requests:
{ ... }:
{
imports = [
./data-model-options.nix
../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
);
};
};
in
{
single-nixos-vm-ssh = environment: {
resources."operator-environment".login-shell.username = "operator";
implementation =
{
required-resources,
deployment-name,
}:
{
ssh-host = {
nixos-configuration = mkNixosConfiguration environment required-resources;
system = targetSystem;
ssh = {
username = "root";
host = nodeName;
key-file = null;
inherit sshOpts;
};
module = self;
inherit args deployment-name;
root-path = pathToRoot;
};
};
};
single-nixos-vm-nixops4 = environment: {
resources."operator-environment".login-shell.username = "operator";
implementation =
{
required-resources,
...
}:
{
nixops4 =
{ providers, ... }:
{
providers = {
inherit (inputs.nixops4.modules.nixops4Provider) local;
};
resources.${nodeName} = {
type = providers.local.exec;
imports = [
inputs.nixops4-nixos.modules.nixops4Resource.nixos
../common/targetResource.nix
];
nixos.module = mkNixosConfiguration environment required-resources;
_module.args = { inherit inputs sources; };
inherit (deployment-config) nodeName pathToRoot pathFromRoot;
};
};
};
};
single-nixos-vm-tf = environment: {
resources."operator-environment".login-shell.username = "operator";
implementation =
{
required-resources,
deployment-name,
}:
{
tf-host = {
nixos-configuration = mkNixosConfiguration environment required-resources;
system = targetSystem;
ssh = {
username = "root";
host = nodeName;
key-file = null;
inherit sshOpts;
};
module = self;
inherit args deployment-name;
root-path = pathToRoot;
};
};
};
};
};
options = {
"example-configuration" = mkOption {
type = config.configuration;
default = {
enable = true;
applications.hello.enable = true;
};
};
"ssh-deployment" =
let
env = config.environments."single-nixos-vm-ssh";
in
mkOption {
type = env.resource-mapping.output-type;
default = env.deployment {
deployment-name = "ssh-deployment";
configuration = config."example-configuration";
};
};
"nixops4-deployment" =
let
env = config.environments."single-nixos-vm-nixops4";
in
mkOption {
type = env.resource-mapping.output-type;
default = env.deployment {
deployment-name = "nixops4-deployment";
configuration = config."example-configuration";
};
};
"tf-deployment" =
let
env = config.environments."single-nixos-vm-tf";
in
mkOption {
type = env.resource-mapping.output-type;
default = env.deployment {
deployment-name = "tf-deployment";
configuration = config."example-configuration";
};
};
};
}
);
in
fediversity

View file

@ -59,7 +59,6 @@ in
inputs.nixpkgs
sources.flake-parts
sources.nixpkgs
sources.flake-inputs
sources.git-hooks

View file

@ -48,8 +48,7 @@ in
extraTestScript = mkOption { };
sourceFileset = mkOption {
## FIXME: grab `lib.types.fileset` from NixOS, once upstreaming PR
## https://github.com/NixOS/nixpkgs/pull/428293 lands.
## REVIEW: Upstream to nixpkgs?
type = types.mkOptionType {
name = "fileset";
description = "fileset";
@ -76,6 +75,8 @@ in
./sharedOptions.nix
./targetNode.nix
./targetResource.nix
(config.pathToCwd + "/flake-under-test.nix")
];
acmeNodeIP = config.nodes.acme.networking.primaryIPAddress;
@ -162,38 +163,31 @@ in
deployer.succeed(f"echo '{host_key}' > ${config.pathFromRoot}/${tm}_host_key.pub")
'')}
${
if config.useFlake then
''
## 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.
##
## NOTE: We use the repository as-is (cf `src` above), overriding only
## `flake.nix` by our `flake-under-test.nix`. We also override the flake
## lock file to use locally available inputs, as we cannot download them.
##
with subtest("Override the flake and its lock"):
deployer.succeed("cp ${config.pathFromRoot}/flake-under-test.nix flake.nix")
deployer.succeed("""
nix flake lock --extra-experimental-features 'flakes nix-command' \
--offline -v \
--override-input nixops4 ${inputs.nixops4.packages.${system}.flake-in-a-bottle} \
\
--override-input nixops4-nixos ${inputs.nixops4-nixos} \
--override-input nixops4-nixos/flake-parts ${inputs.nixops4-nixos.inputs.flake-parts} \
--override-input nixops4-nixos/flake-parts/nixpkgs-lib ${inputs.nixops4-nixos.inputs.flake-parts.inputs.nixpkgs-lib} \
--override-input nixops4-nixos/nixops4-nixos ${emptyFlake} \
--override-input nixops4-nixos/nixpkgs ${inputs.nixops4-nixos.inputs.nixpkgs} \
--override-input nixops4-nixos/nixops4 ${
inputs.nixops4-nixos.inputs.nixops4.packages.${system}.flake-in-a-bottle
} \
--override-input nixops4-nixos/git-hooks-nix ${emptyFlake} \
;
""")
''
else
""
}
## 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.
##
## NOTE: We use the repository as-is (cf `src` above), overriding only
## `flake.nix` by our `flake-under-test.nix`. We also override the flake
## lock file to use locally available inputs, as we cannot download them.
##
with subtest("Override the flake and its lock"):
deployer.succeed("cp ${config.pathFromRoot}/flake-under-test.nix flake.nix")
deployer.succeed("""
nix flake lock --extra-experimental-features 'flakes nix-command' \
--offline -v \
--override-input nixops4 ${inputs.nixops4.packages.${system}.flake-in-a-bottle} \
\
--override-input nixops4-nixos ${inputs.nixops4-nixos} \
--override-input nixops4-nixos/flake-parts ${inputs.nixops4-nixos.inputs.flake-parts} \
--override-input nixops4-nixos/flake-parts/nixpkgs-lib ${inputs.nixops4-nixos.inputs.flake-parts.inputs.nixpkgs-lib} \
--override-input nixops4-nixos/nixops4-nixos ${emptyFlake} \
--override-input nixops4-nixos/nixpkgs ${inputs.nixops4-nixos.inputs.nixpkgs} \
--override-input nixops4-nixos/nixops4 ${
inputs.nixops4-nixos.inputs.nixops4.packages.${system}.flake-in-a-bottle
} \
--override-input nixops4-nixos/git-hooks-nix ${emptyFlake} \
;
""")
${optionalString config.enableAcme ''
with subtest("Set up handmade DNS"):

View file

@ -32,11 +32,11 @@ in
};
pathFromRoot = mkOption {
type = types.either types.path types.str;
type = types.path;
description = ''
Path from the root of the repository to the working directory.
'';
apply = x: if lib.isString x then x else lib.path.removePrefix config.pathToRoot x;
apply = x: lib.path.removePrefix config.pathToRoot x;
};
pathToCwd = mkOption {
@ -64,7 +64,5 @@ in
during the test to the correct value.
'';
};
useFlake = lib.mkEnableOption "Use a flake in the test.";
};
}

View file

@ -28,8 +28,6 @@ in
system.switch.enable = true;
nix = {
# short-cut network time-outs
settings.download-attempts = 1;
## Not used; save a large copy operation
channel.enable = false;
registry = lib.mkForce { };

View file

@ -1,9 +0,0 @@
{
targetMachines = [
"nixops4"
];
pathToRoot = ../../..;
pathFromRoot = ./.;
enableAcme = true;
useFlake = true;
}

View file

@ -1,22 +0,0 @@
{
runNixOSTest,
inputs,
sources,
}:
runNixOSTest {
imports = [
../../data-model.nix
../../function.nix
../common/nixosTest.nix
./nixosTest.nix
];
_module.args = { inherit inputs sources; };
inherit (import ./constants.nix)
targetMachines
pathToRoot
pathFromRoot
enableAcme
useFlake
;
}

View file

@ -1,29 +0,0 @@
{
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/common/data-model.nix {
inherit system inputs;
config = {
inherit (import ./deployment/check/data-model-nixops4/constants.nix) pathToRoot pathFromRoot;
nodeName = "nixops4";
};
})."nixops4-deployment".nixops4;
}
);
}

View file

@ -1,52 +0,0 @@
{
lib,
config,
inputs,
...
}:
{
_class = "nixosTest";
imports = [
../common/data-model-options.nix
];
name = "deployment-model";
sourceFileset = lib.fileset.unions [
../../data-model.nix
../../function.nix
../common/data-model.nix
../common/data-model-options.nix
./constants.nix
(config.pathToCwd + "/flake-under-test.nix")
];
nodes.deployer =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
inputs.nixops4.packages.${system}.default
jq
];
# FIXME: sad times
system.extraDependencies = with pkgs; [
jq
jq.inputDerivation
];
system.extraDependenciesFromModule =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
hello
];
};
};
extraTestScript = ''
with subtest("nixops4"):
nixops4.fail("hello 1>&2")
deployer.succeed("nixops4 apply check-deployment-model --show-trace --verbose --no-interactive 1>&2")
nixops4.succeed("su - operator -c hello 1>&2")
'';
}

View file

@ -1,12 +0,0 @@
{
targetMachines = [
"ssh"
];
# stablize path, as just the path would yield distinct paths when applied multiple times
pathToRoot = builtins.path {
path = ../../..;
name = "root";
};
pathFromRoot = "/deployment/check/data-model-ssh";
enableAcme = true;
}

View file

@ -1,21 +0,0 @@
{
runNixOSTest,
inputs,
sources,
}:
runNixOSTest {
imports = [
../../data-model.nix
../../function.nix
../common/nixosTest.nix
./nixosTest.nix
];
_module.args = { inherit inputs sources; };
inherit (import ./constants.nix)
targetMachines
pathToRoot
pathFromRoot
enableAcme
;
}

View file

@ -1,68 +0,0 @@
{
lib,
pkgs,
...
}:
let
inherit (import ./constants.nix) pathToRoot pathFromRoot;
inherit (pkgs) system;
deployment-config = {
inherit pathToRoot pathFromRoot;
nodeName = "ssh";
targetSystem = system;
sshOpts = [ ];
};
deploy =
(import ../common/data-model.nix {
inherit system;
config = deployment-config;
# opt not to pass `inputs`, as we could only pass serializable arguments through to its self-call
})."ssh-deployment".ssh-host.run;
in
{
_class = "nixosTest";
imports = [
../common/data-model-options.nix
];
name = "deployment-model";
sourceFileset = lib.fileset.unions [
../../data-model.nix
../../function.nix
../../nixos.nix
../../run/ssh-single-host/run.sh
../../../npins/default.nix
../../../npins/sources.json
../common/data-model.nix
../common/data-model-options.nix
./constants.nix
];
nodes.deployer =
{ ... }:
{
environment.systemPackages = [
deploy
];
system.extraDependenciesFromModule =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
hello
];
};
};
extraTestScript = ''
with subtest("Check the status before deployment"):
ssh.fail("hello 1>&2")
with subtest("Run the deployment"):
deployer.succeed("""
${lib.getExe deploy}
""")
ssh.wait_for_unit("multi-user.target")
ssh.succeed("su - operator -c hello 1>&2")
'';
}

View file

@ -1,11 +0,0 @@
{
targetMachines = [
"target"
];
pathToRoot = builtins.path {
path = ../../..;
name = "root";
};
pathFromRoot = "/deployment/check/data-model-tf";
enableAcme = true;
}

View file

@ -1,21 +0,0 @@
{
runNixOSTest,
inputs,
sources,
}:
runNixOSTest {
imports = [
../../data-model.nix
../../function.nix
../common/nixosTest.nix
./nixosTest.nix
];
_module.args = { inherit inputs sources; };
inherit (import ./constants.nix)
targetMachines
pathToRoot
pathFromRoot
enableAcme
;
}

View file

@ -1,61 +0,0 @@
{
lib,
pkgs,
...
}:
let
inherit (import ./constants.nix) pathToRoot pathFromRoot;
inherit (pkgs) system;
deployment-config = {
inherit pathToRoot pathFromRoot;
nodeName = "target";
targetSystem = system;
sshOpts = [ ];
};
deploy =
(import ../common/data-model.nix {
inherit system;
config = deployment-config;
# opt not to pass `inputs`, as we could only pass serializable arguments through to its self-call
})."tf-deployment".tf-host.run;
in
{
_class = "nixosTest";
imports = [
../common/data-model-options.nix
];
name = "deployment-model";
sourceFileset = lib.fileset.unions [
../../run/tf-single-host/run.sh
];
nodes.deployer =
{ ... }:
{
environment.systemPackages = [
deploy
];
# needed only when building from deployer
system.extraDependenciesFromModule =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
hello
];
};
};
extraTestScript = ''
with subtest("Check the status before deployment"):
target.fail("hello 1>&2")
with subtest("Run the deployment"):
deployer.succeed("""
${lib.getExe deploy}
""")
target.wait_for_unit("multi-user.target")
target.succeed("su - operator -c hello 1>&2")
'';
}

View file

@ -8,5 +8,4 @@
pathToRoot = ../../..;
pathFromRoot = ./.;
enableAcme = true;
useFlake = true;
}

View file

@ -15,6 +15,5 @@ runNixOSTest {
pathToRoot
pathFromRoot
enableAcme
useFlake
;
}

View file

@ -128,7 +128,6 @@ in
sourceFileset = lib.fileset.unions [
./constants.nix
./deployment.nix
(config.pathToCwd + "/flake-under-test.nix")
# REVIEW: I would like to be able to grab all of `/deployment` minus
# `/deployment/check`, but I can't because there is a bunch of other files

View file

@ -1,37 +0,0 @@
{
runNixOSTest,
sources,
system,
}:
let
pkgs = import sources.nixpkgs-stable {
inherit system;
overlays = [ overlay ];
};
overlay = _: _: {
inherit
(import "${sources.proxmox-nixos}/pkgs" {
craneLib = pkgs.callPackage "${sources.crane}/lib" { };
# breaks from https://github.com/NixOS/nixpkgs/commit/06b354eb2dc535c57e9b4caaa16d79168f117a26,
# which updates libvncserver to 0.9.15, which was not yet patched at https://git.proxmox.com/?p=vncterm.git.
inherit pkgs;
# not so picky about version for our purposes
pkgs-unstable = pkgs;
})
proxmox-ve
pve-ha-manager
;
};
in
runNixOSTest {
node.specialArgs = {
inherit
sources
pkgs
;
};
imports = [
./proxmoxTest.nix
];
}

View file

@ -1,87 +0,0 @@
# https://github.com/SaumonNet/proxmox-nixos/blob/main/tests/vm.nix
{
pkgs,
...
}:
let
# tracking non-tarball downloads seems unsupported still in npins:
# https://github.com/andir/npins/issues/163
minimalIso = pkgs.fetchurl {
url = "https://releases.nixos.org/nixos/24.05/nixos-24.05.7139.bcba2fbf6963/nixos-minimal-24.05.7139.bcba2fbf6963-x86_64-linux.iso";
hash = "sha256-plre/mIHdIgU4xWU+9xErP+L4i460ZbcKq8iy2n4HT8=";
};
in
{
name = "proxmox-basic";
nodes.mypve =
{ sources, ... }:
{
imports = [
"${sources.proxmox-nixos}/modules/proxmox-ve"
];
services.proxmox-ve = {
enable = true;
ipAddress = "192.168.1.1";
vms = {
myvm1 = {
vmid = 100;
memory = 1024;
cores = 1;
sockets = 1;
kvm = true;
scsi = [ { file = "local:16"; } ];
cdrom = "local:iso/minimal.iso";
};
};
};
virtualisation = {
additionalPaths = [ minimalIso ];
diskSize = 4096;
memorySize = 2048;
};
};
testScript = ''
machine.start()
machine.wait_for_unit("pveproxy.service")
assert "running" in machine.succeed("pveproxy status")
# Copy Iso
machine.succeed("mkdir -p /var/lib/vz/template/iso/")
machine.succeed("cp ${minimalIso} /var/lib/vz/template/iso/minimal.iso")
# Declarative VM creation
machine.wait_for_unit("multi-user.target")
machine.succeed("qm stop 100 --timeout 0")
# Seabios VM creation
machine.succeed(
"qm create 101 --kvm 0 --bios seabios -cdrom local:iso/minimal.iso",
"qm start 101",
"qm stop 101 --timeout 0"
)
# Legacy ovmf vm creation
machine.succeed(
"qm create 102 --kvm 0 --bios ovmf -cdrom local:iso/minimal.iso",
"qm start 102",
"qm stop 102 --timeout 0"
)
# UEFI ovmf vm creation
machine.succeed(
"qm create 103 --kvm 0 --bios ovmf --efidisk0 local:4,efitype=4m -cdrom local:iso/minimal.iso",
"qm start 103",
"qm stop 103 --timeout 0"
)
# UEFI ovmf vm creation with secure boot
machine.succeed(
"qm create 104 --kvm 0 --bios ovmf --efidisk0 local:4,efitype=4m,pre-enrolled-keys=1 -cdrom local:iso/minimal.iso",
"qm start 104",
"qm stop 104 --timeout 0"
)
'';
}

View file

@ -1,94 +1,29 @@
let
inherit (import ../default.nix { }) pkgs inputs;
inherit (pkgs) lib;
inherit (lib) mkOption types;
inherit (lib) mkOption;
eval =
module:
(lib.evalModules {
specialArgs = {
inherit pkgs inputs;
inherit inputs;
};
modules = [
module
./data-model.nix
];
}).config;
inherit (inputs.nixops4.lib) mkDeployment;
in
{
_class = "nix-unit";
test-eval = {
/**
This tests a very simple arrangement that features all ingredients of the Fediversity business logic:
application, resource, environment, deployment; and wires it all up in one end-to-end exercise.
- The dummy resource is a login shell made available for some user.
- The dummy application is `hello` that requires a shell to be deployed.
- The dummy environment is a single NixOS VM that hosts one login shell, for the operator.
- The dummy configuration enables the `hello` application.
This will produce a NixOps4 deployment for a NixOS VM with a login shell for the operator and `hello` available.
*/
expr =
let
fediversity = eval (
{ config, ... }:
{
config = {
resources.login-shell = {
description = "The operator needs to be able to log into the shell";
request =
{ ... }:
{
_class = "fediversity-resource-request";
options = {
wheel = mkOption {
description = "Whether the login user needs root permissions";
type = types.bool;
default = false;
};
packages = mkOption {
description = "Packages that need to be available in the user environment";
type = with types; attrsOf package;
};
};
};
policy =
{ config, ... }:
{
_class = "fediversity-resource-policy";
options = {
username = mkOption {
description = "Username for the operator";
type = types.str; # TODO: use the proper constraints from NixOS
};
wheel = mkOption {
description = "Whether to allow login with root permissions";
type = types.bool;
default = false;
};
};
config = {
resource-type = types.raw; # TODO: splice out the user type from NixOS
apply =
requests:
let
# Filter out requests that need wheel if policy doesn't allow it
validRequests = lib.filterAttrs (
_name: req: !req.login-shell.wheel || config.wheel
) requests.resources;
in
lib.optionalAttrs (validRequests != { }) {
${config.username} = {
isNormalUser = true;
packages =
with lib;
attrValues (concatMapAttrs (_name: request: request.login-shell.packages) validRequests);
extraGroups = lib.optional config.wheel "wheel";
};
};
};
};
};
applications.hello =
{ ... }:
{
@ -96,49 +31,19 @@ in
module =
{ ... }:
{
options.enable = lib.mkEnableOption "Hello in the shell";
options = {
enable = lib.mkEnableOption "Hello in the shell";
};
};
implementation = cfg: {
resources = lib.optionalAttrs cfg.enable {
hello.login-shell.packages.hello = pkgs.hello;
implementation =
cfg:
lib.optionalAttrs cfg.enable {
dummy.login-shell.packages.hello = pkgs.hello;
};
};
};
environments.single-nixos-vm =
{ config, ... }:
{
resources."operator-environment".login-shell.username = "operator";
implementation = requests: {
nixops4 = (
{ providers, ... }:
{
providers = {
inherit (inputs.nixops4.modules.nixops4Provider) local;
};
resources.the-machine = {
type = providers.local.exec;
imports = [
inputs.nixops4-nixos.modules.nixops4Resource.nixos
];
nixos.module =
{ ... }:
{
users.users = 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
);
};
};
};
}
);
};
};
};
options = {
"example-configuration" = mkOption {
example-configuration = mkOption {
type = config.configuration;
readOnly = true;
default = {
@ -146,66 +51,20 @@ in
applications.hello.enable = true;
};
};
"example-deployment" = mkOption {
type = config.environments.single-nixos-vm.resource-mapping.output-type;
readOnly = true;
default = config.environments.single-nixos-vm.deployment config."example-configuration";
};
};
}
);
resources =
fediversity.applications.hello.resources
fediversity."example-configuration".applications.hello;
hello-shell = resources.resources.hello.login-shell;
environment = fediversity.environments.single-nixos-vm.resources."operator-environment".login-shell;
result = mkDeployment {
modules = [
(fediversity.environments.single-nixos-vm.deployment fediversity."example-configuration")
];
};
in
{
number-of-resources = with lib; length (attrNames fediversity.resources);
inherit (fediversity) example-configuration;
hello-package-exists = hello-shell.packages ? hello;
wheel-required = hello-shell.wheel;
wheel-allowed = environment.wheel;
operator-shell =
let
operator = (environment.apply resources).operator;
in
{
inherit (operator) isNormalUser;
packages = map (p: "${p.pname}") operator.packages;
extraGroups = operator.extraGroups;
};
deployment = {
inherit (result) _type;
deploymentFunction = lib.isFunction result.deploymentFunction;
getProviders = lib.isFunction result.getProviders;
};
inherit (fediversity)
example-configuration
;
};
expected = {
number-of-resources = 1;
example-configuration = {
enable = true;
applications.hello.enable = true;
};
hello-package-exists = true;
wheel-required = false;
wheel-allowed = false;
operator-shell = {
isNormalUser = true;
packages = [ "hello" ];
extraGroups = [ ];
};
deployment = {
_type = "nixops4Deployment";
deploymentFunction = true;
getProviders = true;
};
};
};
}

View file

@ -1,326 +1,33 @@
{
lib,
config,
inputs,
pkgs,
sources ? import ../npins,
...
}:
let
inherit (lib) mkOption types;
inherit (lib.types)
attrTag
attrsOf
attrTag
deferredModuleWith
functionTo
nullOr
optionType
raw
str
submodule
optionType
functionTo
;
toBash =
v:
lib.replaceStrings [ "\"" ] [ "\\\"" ] (
if lib.isPath v || builtins.isNull v then
toString v
else if lib.isString v then
v
else
lib.strings.toJSON v
);
withPackages = packages: {
makeWrapperArgs = [
"--prefix"
"PATH"
":"
"${lib.makeBinPath packages}"
];
};
writeConfig =
{
system,
module,
root-path,
deployment-type,
deployment-name,
args,
}:
builtins.toString (
pkgs.writers.writeText "configuration.nix" ''
import ${root-path}/deployment/nixos.nix {
system = "${system}";
configuration = (import "${root-path}/${module}" (builtins.fromJSON "${
lib.replaceStrings [ "\"" ] [ "\\\"" ] (lib.strings.toJSON args)
}")).${deployment-name}.${deployment-type}.nixos-configuration;
}
''
);
functionType = submodule ./function.nix;
application-resources = submodule {
functionType = import ./function.nix;
application-resources = {
options.resources = mkOption {
# TODO: maybe transpose, and group the resources by type instead
type = attrsOf (
attrTag (
lib.mapAttrs (_name: resource: mkOption { type = submodule resource.request; }) config.resources
)
attrTag (lib.mapAttrs (_name: resource: mkOption { type = resource.request; }) config.resources)
);
};
};
nixops4Deployment = types.deferredModuleWith {
staticModules = [
inputs.nixops4.modules.nixops4Deployment.default
{
_class = "nixops4Deployment";
_module.args = {
resourceProviderSystem = pkgs.system;
resources = { };
};
}
];
};
nixos-configuration = mkOption {
description = "A NixOS configuration.";
type = raw;
};
host-ssh = mkOption {
description = "SSH connection info to connect to a single host.";
type = submodule {
options = {
host = mkOption {
description = "the host to access by SSH";
type = str;
};
username = mkOption {
description = "the SSH user to use";
type = nullOr str;
default = null;
};
key-file = mkOption {
description = "path to the user's SSH private key";
type = nullOr str;
example = "/root/.ssh/id_ed25519";
};
sshOpts = mkOption {
description = "Extra SSH options (`-o`) to use.";
type = types.listOf str;
default = [ ];
example = "ConnectTimeout=60";
};
};
};
};
# FIXME allow custom deployment types
# FIXME make deployments environment resources?
deployment-type = attrTag {
ssh-host = mkOption {
description = "A deployment by SSH to update a single existing NixOS host.";
type = submodule (ssh-host: {
options = {
system = mkOption {
description = "The architecture of the system to deploy to.";
type = types.str;
};
inherit nixos-configuration;
ssh = host-ssh;
module = mkOption {
description = "The module to call to obtain the NixOS configuration from.";
type = types.str;
};
args = mkOption {
description = "The arguments with which to call the module to obtain the NixOS configuration.";
type = types.attrs;
};
deployment-name = mkOption {
description = "The name of the deployment for which to obtain the NixOS configuration.";
type = types.str;
};
root-path = mkOption {
description = "The path to the root of the repository.";
type = types.path;
};
run = mkOption {
type = types.package;
# error: The option `ssh-deployment.ssh-host.run' is read-only, but it's set multiple times.
# readOnly = true;
default =
let
inherit (ssh-host.config)
system
ssh
module
args
deployment-name
root-path
;
inherit (ssh)
host
username
key-file
sshOpts
;
environment = {
key_file = key-file;
ssh_opts = sshOpts;
inherit
host
username
;
nixos_conf = writeConfig {
inherit
system
module
args
deployment-name
root-path
;
deployment-type = "ssh-host";
};
};
in
pkgs.writers.writeBashBin "deploy-sh.sh"
(withPackages [
pkgs.jq
])
''
env ${
toString (lib.mapAttrsToList (k: v: "${k}=\"${toBash v}\"") environment)
} bash ./deployment/run/ssh-single-host/run.sh
'';
};
};
});
};
nixops4 = mkOption {
description = "A NixOps4 NixOS deployment. For an example, see https://github.com/nixops4/nixops4-nixos/blob/main/example/deployment.nix.";
type = nixops4Deployment;
};
tf-host = mkOption {
description = "A Terraform deployment by SSH to update a single existing NixOS host.";
type = submodule (tf-host: {
options = {
system = mkOption {
description = "The architecture of the system to deploy to.";
type = types.str;
};
inherit nixos-configuration;
ssh = host-ssh;
module = mkOption {
description = "The module to call to obtain the NixOS configuration from.";
type = types.str;
};
args = mkOption {
description = "The arguments with which to call the module to obtain the NixOS configuration.";
type = types.attrs;
};
deployment-name = mkOption {
description = "The name of the deployment for which to obtain the NixOS configuration.";
type = types.str;
};
root-path = mkOption {
description = "The path to the root of the repository.";
type = types.path;
};
run = mkOption {
type = types.package;
# error: The option `tf-deployment.tf-host.run' is read-only, but it's set multiple times.
# readOnly = true;
default =
let
inherit (tf-host.config)
system
ssh
module
args
deployment-name
root-path
;
inherit (ssh)
host
username
key-file
sshOpts
;
environment = {
key_file = key-file;
ssh_opts = sshOpts;
inherit
host
username
;
nixos_conf = writeConfig {
inherit
system
module
args
deployment-name
root-path
;
deployment-type = "tf-host";
};
};
tf-env = pkgs.callPackage ./run/tf-single-host/tf-env.nix { };
in
pkgs.writers.writeBashBin "deploy-tf.sh"
(withPackages [
pkgs.jq
(pkgs.callPackage ./run/tf-single-host/tf.nix { inherit sources; })
])
''
env ${toString (lib.mapAttrsToList (k: v: "TF_VAR_${k}=\"${toBash v}\"") environment)} \
tf_env=${tf-env} bash ./deployment/run/tf-single-host/run.sh
'';
};
};
});
};
};
in
{
_class = "nixops4Deployment";
options = {
resources = mkOption {
description = "Collection of deployment resources that can be required by applications and policed by hosting providers";
type = attrsOf (
submodule (
{ ... }:
{
_class = "fediversity-resource";
options = {
description = mkOption {
description = "Description of the resource to help application module authors and hosting providers to work with it";
type = types.str;
};
request = mkOption {
description = "Options for declaring resource requirements by an application, a description of how the resource is consumed or accessed";
type = deferredModuleWith { staticModules = [ { _class = "fediversity-resource-request"; } ]; };
};
policy = mkOption {
description = "Options for configuring the resource policy for the hosting provider, a description of how the resource is made available";
type = deferredModuleWith {
staticModules = [
(policy: {
_class = "fediversity-resource-policy";
options.resource-type = mkOption {
description = "The type of resource this policy configures";
type = types.optionType;
};
# TODO(@fricklerhandwerk): we may want to make the function type explicit here: `application-resources -> resource-type`
# and then also rename this to be consistent with the application's resource mapping
options.apply = mkOption {
description = "Apply the policy to a request";
type = functionTo policy.config.resource-type;
};
})
];
};
};
};
}
)
);
};
applications = mkOption {
description = "Collection of Fediversity applications";
type = attrsOf (
@ -341,110 +48,23 @@ in
};
resources = mkOption {
description = "Compute resources required by an application";
type = application.config.config-mapping.function-type;
type = functionTo application.config.config-mapping.output-type;
readOnly = true;
default = application.config.config-mapping.apply;
default = input: (application.config.implementation input).output;
};
# TODO(@fricklerhandwerk): this needs a better name
config-mapping = mkOption {
description = "Function type for the mapping from application configuration to required resources";
type = functionType;
type = submodule functionType;
readOnly = true;
default = {
input-type = submodule application.config.module;
input-type = application.config.module;
output-type = application-resources;
implementation = application.config.implementation;
};
};
};
})
);
};
environments = mkOption {
description = "Run-time environments for Fediversity applications to be deployed to";
type = attrsOf (
submodule (environment: {
_class = "fediversity-environment";
options = {
resources = mkOption {
description = ''
Resources made available by the hosting provider, and their policies.
Setting this is optional, but provides a place to declare that information for programmatic use in the resource mapping.
'';
# TODO: maybe transpose, and group the resources by type instead
type = attrsOf (
attrTag (
lib.mapAttrs (_name: resource: mkOption { type = submodule resource.policy; }) config.resources
)
);
};
implementation = mkOption {
description = "Mapping of resources required by applications to available resources; the result can be deployed";
type = environment.config.resource-mapping.function-type;
};
resource-mapping = mkOption {
description = "Function type for the mapping from resources to a deployment";
type = functionType;
readOnly = true;
default = {
input-type = submodule {
options = {
deployment-name = mkOption {
type = types.str;
};
required-resources = mkOption {
type = attrsOf application-resources;
};
};
};
output-type = deployment-type;
implementation = environment.config.implementation;
};
};
config-mapping = mkOption {
description = "Mapping from a configuration to a deployment";
type = functionType;
readOnly = true;
default = {
input-type = submodule {
options = {
deployment-name = mkOption {
type = types.str;
};
configuration = mkOption {
type = config.configuration;
};
};
};
output-type = deployment-type;
implementation =
{
deployment-name,
configuration,
}:
# TODO: check cfg.enable.true
let
required-resources = lib.mapAttrs (
name: application-settings: config.applications.${name}.resources application-settings
) configuration.applications;
in
environment.config.resource-mapping.apply { inherit required-resources deployment-name; };
};
};
# TODO(@fricklerhandwerk): maybe this should be a separate thing such as `fediversity-setup`,
# which makes explicit which applications and environments are available.
# then the deployments can simply be the result of the function application baked into this module.
deployment = mkOption {
description = "Generate a deployment from a configuration, by applying an environment's resource policies to the applications' resource mappings";
type = environment.config.config-mapping.function-type;
readOnly = true;
default = environment.config.config-mapping.apply;
};
};
})
);
};
configuration = mkOption {
description = "Configuration type declaring options to be set by operators";
type = optionType;

View file

@ -4,33 +4,9 @@
_class = "flake";
perSystem =
{ pkgs, system, ... }:
let
inherit (pkgs) lib;
in
{ pkgs, ... }:
{
checks = {
data-model =
pkgs.writers.writeBashBin "data-model.sh"
{
makeWrapperArgs = [
"--prefix"
"PATH"
":"
"${lib.makeBinPath [
pkgs.nix-unit
]}"
];
}
''
nix-unit ./deployment/data-model-test.nix
'';
proxmox-basic = import ./check/proxmox {
inherit (pkgs.testers) runNixOSTest;
inherit sources system;
};
deployment-basic = import ./check/basic {
inherit (pkgs.testers) runNixOSTest;
inherit inputs sources;
@ -45,21 +21,6 @@
inherit (pkgs.testers) runNixOSTest;
inherit inputs sources;
};
deployment-model-ssh = import ./check/data-model-ssh {
inherit (pkgs.testers) runNixOSTest;
inherit inputs sources;
};
deployment-model-nixops4 = import ./check/data-model-nixops4 {
inherit (pkgs.testers) runNixOSTest;
inherit inputs sources;
};
deployment-model-tf = import ./check/data-model-tf {
inherit (pkgs.testers) runNixOSTest;
inherit inputs sources;
};
};
};
}

View file

@ -1,43 +1,11 @@
/**
Modular function type.
Compared to plain nix functions, adds input type-checks
at the cost of longer stack traces.
Usage:
```nix
{ lib, ... }:
{
options = {
my-function = lib.mkOption {
description = "My type-safe function invocation.";
type = lib.types.submodule PATH/TO/function.nix;
readOnly = true;
default = {
input-type = lib.types.int;
output-type = lib.types.int;
implementation = x: x + x;
};
};
};
config = {
my-function.apply "1"
};
}
```
A sample stack trace using this ends up like:
- `INVOKER.apply.<function body>``
- `function.nix`
- `INVOKER.wrapper.<function body>.output`
- `INVOKER.implementation.<function body>`
Modular function type
*/
{ config, lib, ... }:
let
inherit (lib) mkOption types;
inherit (types)
deferredModule
submodule
functionTo
optionType
@ -46,46 +14,24 @@ in
{
options = {
input-type = mkOption {
type = optionType;
type = deferredModule;
};
output-type = mkOption {
type = optionType;
type = deferredModule;
};
function-type = mkOption {
type = optionType;
readOnly = true;
default = functionTo config.output-type;
};
wrapper-type = mkOption {
type = optionType;
readOnly = true;
default = functionTo (submodule {
options = {
input = mkOption {
type = config.input-type;
type = submodule config.input-type;
};
output = mkOption {
type = config.output-type;
type = submodule config.output-type;
};
};
});
};
implementation = mkOption {
type = config.function-type;
default = _: { };
};
wrapper = mkOption {
type = config.wrapper-type;
readOnly = true;
default = input: fn: {
inherit input;
output = config.implementation fn.config.input;
};
};
apply = mkOption {
type = config.function-type;
readOnly = true;
default = input: (config.wrapper input).output;
};
};
}

View file

@ -1,25 +0,0 @@
{
configuration,
system,
sources ? import ../npins,
}:
let
eval = import "${sources.nixpkgs}/nixos/lib/eval-config.nix" {
inherit system;
specialArgs = {
inherit sources;
};
modules = [ configuration ];
};
toplevel =
{
inherit (eval) pkgs config options;
system = eval.config.system.build.toplevel;
inherit (eval.config.system.build) vm vmWithBootLoader;
}
.config.system.build.toplevel;
in
{
drv_path = toplevel.drvPath;
out_path = toplevel;
}

View file

@ -1,47 +0,0 @@
#! /usr/bin/env bash
set -xeuo pipefail
declare username host key_file ssh_opts nixos_conf
IFS=" " read -r -a ssh_opts <<< "$( (echo "$ssh_opts" | jq -r '@sh') | tr -d \'\")"
# DEPLOY
sshOpts=(
-o BatchMode=yes
-o StrictHostKeyChecking=no
)
for ssh_opt in "${ssh_opts[@]}"; do
sshOpts+=(
-o "$ssh_opt"
)
done
if [[ -n "$key_file" ]]; then
sshOpts+=(
-i "$key_file"
)
fi
destination="$username@$host"
command=(nix-instantiate --show-trace "${nixos_conf}")
# INSTANTIATE
# instantiate the config in /nix/store
"${command[@]}" -A out_path
# get the realized derivation to deploy
"${command[@]}" --show-trace --eval --strict --json
# FIXME explore import/readFile as ways to instantiate the derivation, potentially allowing to realize the store path up-front from Nix?
outPath=$(nix-store --realize "$("${command[@]}" --show-trace --eval --strict --json | jq -r '.drv_path')")
# deploy the config by nix-copy-closure
NIX_SSHOPTS="${sshOpts[*]}" nix-copy-closure --to "$destination" "$outPath" --gzip --use-substitutes
# switch the remote host to the config
# shellcheck disable=SC2029
ssh "${sshOpts[@]}" "$destination" "nix-env --profile /nix/var/nix/profiles/system --set $outPath"
# shellcheck disable=SC2029
output=$(ssh -o "ConnectTimeout=1" -o "ServerAliveInterval=1" "${sshOpts[@]}" "$destination" "nohup $outPath/bin/switch-to-configuration switch &" 2>&1) || echo "status code: $?"
echo "output: $output"
if [[ $output != *"Timeout, server $host not responding"* ]]; then
echo "non-timeout error: $output"
exit 1
else
exit 0
fi

View file

@ -1,43 +0,0 @@
# hash of our code directory, used to trigger re-deploy
# FIXME calculate separately to reduce false positives
data "external" "hash" {
program = ["sh", "-c", "echo \"{\\\"hash\\\":\\\"$(nix-hash ../../..)\\\"}\""]
}
# TF resource to build and deploy NixOS instances.
resource "terraform_data" "nixos" {
# trigger rebuild/deploy if (FIXME?) any potentially used config/code changed,
# preventing these (20+s, build being bottleneck) when nothing changed.
# terraform-nixos separates these to only deploy if instantiate changed,
# yet building even then - which may be not as bad using deploy on remote.
# having build/deploy one resource reflects wanting to prevent no-op rebuilds
# over preventing (with less false positives) no-op deployments,
# as i could not find a way to do prevent no-op rebuilds without merging them:
# - generic resources cannot have outputs, while we want info from the instantiation (unless built on host?).
# - `data` always runs, which is slow for deploy and especially build.
triggers_replace = [
data.external.hash.result,
var.nixos_conf,
var.host,
]
provisioner "local-exec" {
# directory to run the script from. we use the TF project root dir,
# here as a path relative from where TF is run from,
# matching calling modules' expectations on config_nix locations.
# note that absolute paths can cause false positives in triggers,
# so are generally discouraged in TF.
working_dir = path.root
environment = {
nixos_conf = var.nixos_conf
username = var.username
host = var.host
key_file = var.key_file
ssh_opts = var.ssh_opts
}
# TODO: refactor back to command="ignoreme" interpreter=concat([]) to protect sensitive data from error logs?
# TODO: build on target?
command = "sh ../ssh-single-host/run.sh"
}
}

View file

@ -1,9 +0,0 @@
#! /usr/bin/env bash
set -xeuo pipefail
declare tf_env
export TF_LOG=info
cd "${tf_env}/deployment/run/tf-single-host"
# parallelism=1: limit OOM risk
tofu apply --auto-approve -lock=false -parallelism=1

View file

@ -1,16 +0,0 @@
{
pkgs,
lib,
sources,
}:
pkgs.writeScriptBin "setup" ''
set -xe
# calculated pins
echo '${lib.strings.toJSON sources}' > ./.npins.json
# generate TF lock for nix's TF providers
rm -rf .terraform/
rm -f .terraform.lock.hcl
# suppress warning on architecture-specific generated lock file:
# `Warning: Incomplete lock file information for providers`.
tofu init -input=false 1>/dev/null
''

View file

@ -1,31 +0,0 @@
{
lib,
pkgs,
sources ? import ../../../npins,
}:
pkgs.stdenv.mkDerivation {
name = "tf-repo";
src =
with lib.fileset;
toSource {
root = ../../../.;
# don't copy ignored files
fileset = intersection (gitTracked ../../../.) ../../../.;
};
buildInputs = [
(pkgs.callPackage ./tf.nix { })
(pkgs.callPackage ./setup.nix { inherit sources; })
];
buildPhase = ''
runHook preBuild
pushd deployment/run/tf-single-host
source setup
popd
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -r . $out
runHook postInstall
'';
}

View file

@ -1,11 +0,0 @@
# FIXME: use overlays so this gets imported just once?
{
pkgs,
...
}:
let
tf = pkgs.opentofu;
in
tf.withPlugins (p: [
p.external
])

View file

@ -1,26 +0,0 @@
variable "nixos_conf" {
description = "The path to the NixOS configuration to deploy."
type = string
}
variable "username" {
description = "the SSH user to use"
type = string
default = "root"
}
variable "host" {
description = "the host to access by SSH"
type = string
}
variable "key_file" {
description = "path to the user's SSH private key"
type = string
}
variable "ssh_opts" {
description = "Extra SSH options (`-o`) to use."
type = string
default = "[]"
}

View file

@ -6,13 +6,7 @@
outputs =
inputs:
{
nixConfig = {
extra-trusted-substituters = "https://cache.saumon.network/proxmox-nixos";
extra-trusted-public-keys = "proxmox-nixos:D9RYSWpQQC/msZUWphOY2I5RLH5Dd6yQcaHIuug7dWM=";
};
}
// import ./mkFlake.nix inputs (
import ./mkFlake.nix inputs (
{ inputs, sources, ... }:
{
imports = [
@ -33,14 +27,10 @@
system,
...
}:
let
exported = import ./. { inherit sources system; };
in
{
checks = {
panel = exported.tests.panel.basic;
panel = (import ./. { inherit sources system; }).tests.panel.basic;
};
devShells.default = exported.shell;
formatter = pkgs.nixfmt-rfc-style;
pre-commit.settings.hooks =

View file

@ -20,13 +20,16 @@ in
'';
};
isFediversityVm = mkOption {
type = types.bool;
proxmox = mkOption {
type = types.nullOr (
types.enum [
"procolix"
"fediversity"
]
);
description = ''
Whether the machine is a Fediversity VM or not. This is used to
determine whether the machine should be provisioned via Proxmox or not.
Machines that are _not_ Fediversity VM could be physical machines, or
VMs that live outside Fediversity, eg. on Procolix's Proxmox.
The Proxmox instance. This is used for provisioning only and should be
set to `null` if the machine is not a VM.
'';
};

View file

@ -1,14 +1,10 @@
{ ... }:
{ sources, ... }:
{
_class = "nixos";
## FIXME: It would be nice, but the following leads to infinite recursion
## in the way we currently plug `sources` in.
##
# imports = [
# "${sources.nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
# ];
imports = [
"${sources.nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
];
boot = {
initrd = {

View file

@ -2,6 +2,7 @@
inputs,
lib,
config,
sources,
keys,
secrets,
...
@ -32,9 +33,10 @@ in
## should go into the `./nixos` subdirectory.
nixos.module = {
imports = [
"${sources.agenix}/modules/age.nix"
"${sources.disko}/module.nix"
./options.nix
./nixos
./proxmox-qemu-vm.nix
];
## Inject the shared options from the resource's `config` into the NixOS

View file

@ -14,55 +14,88 @@ let
mkOption
evalModules
filterAttrs
mapAttrs'
deepSeq
;
inherit (lib.attrsets) genAttrs;
commonResourceModule = {
# TODO(@fricklerhandwerk): this is terrible but IMO we should just ditch
# flake-parts and have our own data model for how the project is organised
# internally
_module.args = {
inherit
inputs
keys
secrets
sources
;
## Given a machine's name and whether it is a test VM, make a resource module,
## except for its missing provider. (Depending on the use of that resource, we
## will provide a different one.)
makeResourceModule =
{ vmName, isTestVm }:
{
# TODO(@fricklerhandwerk): this is terrible but IMO we should just ditch flake-parts and have our own data model for how the project is organised internally
_module.args = {
inherit
inputs
keys
secrets
;
};
nixos.module.imports = [
./common/proxmox-qemu-vm.nix
];
nixos.specialArgs = {
inherit sources;
};
imports =
[
./common/resource.nix
]
++ (
if isTestVm then
[
../machines/operator/${vmName}
{
nixos.module.users.users.root.openssh.authorizedKeys.keys = [
# allow our panel vm access to the test machines
keys.panel
];
}
]
else
[
../machines/dev/${vmName}
]
);
fediversityVm.name = vmName;
};
## FIXME: It would be preferrable to have those `sources`-related imports in
## the modules that use them. However, doing so triggers infinite recursions
## because of the way we propagate `sources`. `sources` must be propagated by
## means of `specialArgs`, but this requires a bigger change.
nixos.module.imports = [
"${sources.nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
"${sources.agenix}/modules/age.nix"
"${sources.disko}/module.nix"
"${sources.home-manager}/nixos"
];
imports = [
./common/resource.nix
];
};
## Given a list of machine names, make a deployment with those machines'
## configurations as resources.
makeDeployment =
vmNames:
{ providers, ... }:
{
providers.local = inputs.nixops4.modules.nixops4Provider.local;
resources = genAttrs vmNames (vmName: {
type = providers.local.exec;
imports = [
inputs.nixops4-nixos.modules.nixops4Resource.nixos
commonResourceModule
../machines/dev/${vmName}
];
});
# XXX: this type merge is for adding `specialArgs` to resource modules
options.resources = mkOption {
type =
with lib.types;
lazyAttrsOf (submoduleWith {
class = "nixops4Resource";
modules = [ ];
# TODO(@fricklerhandwerk): we may want to pass through all of `specialArgs`
# once we're sure it's sane. leaving it here for better control during refactoring.
specialArgs = {
inherit sources;
};
});
};
config = {
providers.local = inputs.nixops4.modules.nixops4Provider.local;
resources = genAttrs vmNames (vmName: {
type = providers.local.exec;
imports = [
inputs.nixops4-nixos.modules.nixops4Resource.nixos
(makeResourceModule {
inherit vmName;
isTestVm = false;
})
];
});
};
};
makeDeployment' = vmName: makeDeployment [ vmName ];
@ -77,29 +110,21 @@ let
fediversity = import ../services/fediversity;
}
{
garageConfigurationResource = {
imports = [
commonResourceModule
../machines/operator/test01
];
garageConfigurationResource = makeResourceModule {
vmName = "test01";
isTestVm = true;
};
mastodonConfigurationResource = {
imports = [
commonResourceModule
../machines/operator/test06 # somehow `test02` has a problem - use test06 instead
];
mastodonConfigurationResource = makeResourceModule {
vmName = "test06"; # somehow `test02` has a problem - use test06 instead
isTestVm = true;
};
peertubeConfigurationResource = {
imports = [
commonResourceModule
../machines/operator/test05
];
peertubeConfigurationResource = makeResourceModule {
vmName = "test05";
isTestVm = true;
};
pixelfedConfigurationResource = {
imports = [
commonResourceModule
../machines/operator/test04
];
pixelfedConfigurationResource = makeResourceModule {
vmName = "test04";
isTestVm = true;
};
};
@ -112,63 +137,54 @@ let
## this is only needed to expose NixOS configurations for provisioning
## purposes, and eventually all of this should be handled by NixOps4.
options = {
nixos.module = mkOption { type = lib.types.deferredModule; }; # NOTE: not just `nixos` otherwise merging will go wrong
nixos.module = mkOption { }; # NOTE: not just `nixos` otherwise merging will go wrong
nixpkgs = mkOption { };
ssh = mkOption { };
};
};
makeResourceConfig =
{ vmName, isTestVm }:
vm:
(evalModules {
modules = [
nixops4ResourceNixosMockOptions
commonResourceModule
(if isTestVm then ../machines/operator/${vmName} else ../machines/dev/${vmName})
(makeResourceModule vm)
];
}).config;
## Given a VM name, make a NixOS configuration for this machine.
makeConfiguration =
isTestVm: vmName:
import "${sources.nixpkgs}/nixos" {
configuration = (makeResourceConfig { inherit vmName isTestVm; }).nixos.module;
system = "x86_64-linux";
let
inherit (sources) nixpkgs;
in
import "${nixpkgs}/nixos" {
modules = [
(makeResourceConfig { inherit vmName isTestVm; }).nixos.module
];
};
makeVmOptions =
isTestVm: vmName:
let
config = (makeResourceConfig { inherit vmName isTestVm; }).fediversityVm;
in
if config.isFediversityVm then
{
inherit (config)
vmId
description
sockets
cores
memory
diskSize
hostPublicKey
unsafeHostPrivateKey
;
}
else
null;
makeVmOptions = isTestVm: vmName: {
inherit ((makeResourceConfig { inherit vmName isTestVm; }).fediversityVm)
proxmox
vmId
description
sockets
cores
memory
diskSize
hostPublicKey
unsafeHostPrivateKey
;
};
listSubdirectories = path: attrNames (filterAttrs (_: type: type == "directory") (readDir path));
machines = listSubdirectories ../machines/dev;
testMachines = listSubdirectories ../machines/operator;
nixosConfigurations =
genAttrs machines (makeConfiguration false)
// genAttrs testMachines (makeConfiguration true);
vmOptions =
filterAttrs (_: value: value != null) # Filter out non-Fediversity VMs
(genAttrs machines (makeVmOptions false) // genAttrs testMachines (makeVmOptions true));
in
{
_class = "flake";
@ -192,23 +208,10 @@ in
)
);
};
flake = { inherit nixosConfigurations vmOptions; };
perSystem =
{ pkgs, ... }:
{
checks =
mapAttrs' (name: nixosConfiguration: {
name = "nixosConfigurations-${name}";
value = nixosConfiguration.config.system.build.toplevel;
}) nixosConfigurations
// mapAttrs' (name: vmOptions: {
name = "vmOptions-${name}";
## Check that VM options builds/evaluates correctly. `deepSeq e1
## e2` evaluates `e1` strictly in depth before returning `e2`. We
## use this trick because checks need to be derivations, which VM
## options are not.
value = deepSeq vmOptions pkgs.hello;
}) vmOptions;
};
flake.nixosConfigurations =
genAttrs machines (makeConfiguration false)
// genAttrs testMachines (makeConfiguration true);
flake.vmOptions =
genAttrs machines (makeVmOptions false)
// genAttrs testMachines (makeVmOptions true);
}

View file

@ -5,9 +5,9 @@
*/
{
nixosConfiguration,
nixpkgs,
hostKeys ? { },
nixpkgs ? (import ../npins).nixpkgs,
nixosConfiguration,
}:
let
@ -44,7 +44,7 @@ let
imports = [ "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" ];
nixpkgs.hostPlatform = "x86_64-linux";
services.getty.autologinUser = lib.mkForce "root";
programs.bash.loginShellInit = lib.getExe bootstrap;
programs.bash.loginShellInit = nixpkgs.lib.getExe bootstrap;
isoImage = {
compressImage = false;
@ -55,10 +55,4 @@ let
};
};
in
(import "${nixpkgs}/nixos/lib/eval-config.nix" {
modules = [ installer ];
# Allow system to be set modularly in nixpkgs.system.
# We set it to null, to remove the "legacy" entrypoint's
# non-hermetic default.
system = null;
}).config.system.build.isoImage
(nixpkgs.lib.nixosSystem { modules = [ installer ]; }).config.system.build.isoImage

View file

@ -179,9 +179,15 @@ grab_vm_options () {
--log-format raw --quiet
)
proxmox=$(echo "$options" | jq -r .proxmox)
vm_id=$(echo "$options" | jq -r .vmId)
description=$(echo "$options" | jq -r .description)
if [ "$proxmox" != fediversity ]; then
die "I do not know how to provision things that are not Fediversity VMs,
but I got proxmox = '%s' for VM %s." "$proxmox" "$vm_name"
fi
sockets=$(echo "$options" | jq -r .sockets)
cores=$(echo "$options" | jq -r .cores)
memory=$(echo "$options" | jq -r .memory)
@ -223,9 +229,9 @@ build_iso () {
nix build \
--impure --expr "
let flake = builtins.getFlake (builtins.toString ./.); in
import ./infra/makeInstallerIso.nix {
import ./makeInstallerIso.nix {
nixosConfiguration = flake.nixosConfigurations.$vm_name;
# FIXME pass nixpkgs from npins
nixpkgs = flake.inputs.nixpkgs;
$nix_host_keys
}
" \
@ -239,7 +245,7 @@ Check the Nix logs and fix things. Possibly there just is no NixOS configuration
"$vm_name"
fi
ln -sf "$(ls "$tmpdir/installer-$vm_name"/iso/nixos-*.iso)" "$tmpdir/installer-$vm_name.iso"
ln -sf "$tmpdir/installer-$vm_name/iso/installer.iso" "$tmpdir/installer-$vm_name.iso"
printf 'done building ISO for VM %s.\n' "$vm_name"
release_lock build

View file

@ -167,10 +167,16 @@ grab_vm_options () {
--log-format raw --quiet
)
proxmox=$(echo "$options" | jq -r .proxmox)
vm_id=$(echo "$options" | jq -r .vmId)
printf 'done grabing VM options for VM %s. Got id: %d.\n' \
"$vm_name" "$vm_id"
if [ "$proxmox" != fediversity ]; then
die "I do not know how to remove things that are not Fediversity VMs,
but I got proxmox = '%s' for VM %s." "$proxmox" "$vm_name"
fi
printf 'done grabing VM options for VM %s. Found VM %d on %s Proxmox.\n' \
"$vm_name" "$vm_id" "$proxmox"
fi
}

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "fedi200";
isFediversityVm = true;
vmId = 200;
proxmox = "fediversity";
description = "Testing machine for Hans";
domain = "abundos.eu";
@ -17,4 +16,10 @@
gateway = "2a00:51c0:13:1305::1";
};
};
nixos.module = {
imports = [
../../../infra/common/proxmox-qemu-vm.nix
];
};
}

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "fedi201";
isFediversityVm = true;
vmId = 201;
proxmox = "fediversity";
description = "FediPanel";
domain = "abundos.eu";
@ -20,6 +19,7 @@
nixos.module = {
imports = [
../../../infra/common/proxmox-qemu-vm.nix
./fedipanel.nix
];
};

View file

@ -1,5 +1,6 @@
{
config,
sources,
...
}:
let
@ -10,6 +11,7 @@ in
imports = [
(import ../../../panel { }).module
"${sources.home-manager}/nixos"
];
security.acme = {

View file

@ -20,9 +20,7 @@ in
ssh.host = mkForce "forgejo-ci";
fediversityVm = {
name = "forgejo-ci";
domain = "procolix.com";
isFediversityVm = false;
ipv4 = {
interface = "enp1s0f0";

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "vm02116";
isFediversityVm = false;
vmId = 2116;
proxmox = "procolix";
description = "Forgejo";
ipv4.address = "185.206.232.34";
@ -15,6 +14,7 @@
{ lib, ... }:
{
imports = [
../../../infra/common/proxmox-qemu-vm.nix
./forgejo.nix
];

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "vm02187";
isFediversityVm = false;
vmId = 2187;
proxmox = "procolix";
description = "Wiki";
ipv4.address = "185.206.232.187";
@ -15,6 +14,7 @@
{ lib, ... }:
{
imports = [
../../../infra/common/proxmox-qemu-vm.nix
./wiki.nix
];

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test01";
isFediversityVm = true;
vmId = 7001;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test02";
isFediversityVm = true;
vmId = 7002;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test03";
isFediversityVm = true;
vmId = 7003;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test04";
isFediversityVm = true;
vmId = 7004;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test05";
isFediversityVm = true;
vmId = 7005;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test06";
isFediversityVm = true;
vmId = 7006;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test11";
isFediversityVm = true;
vmId = 7011;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test12";
isFediversityVm = true;
vmId = 7012;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test13";
isFediversityVm = true;
vmId = 7013;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -2,9 +2,8 @@
_class = "nixops4Resource";
fediversityVm = {
name = "test14";
isFediversityVm = true;
vmId = 7014;
proxmox = "fediversity";
hostPublicKey = builtins.readFile ./ssh_host_ed25519_key.pub;
unsafeHostPrivateKey = builtins.readFile ./ssh_host_ed25519_key;

View file

@ -1,4 +0,0 @@
host=192.168.51.81
verify_ssl=0
user=kiara@ProcoliX
password=

View file

@ -25,22 +25,6 @@
"url": null,
"hash": "1w2gsy6qwxa5abkv8clb435237iifndcxq0s79wihqw11a5yb938"
},
"crane": {
"type": "GitRelease",
"repository": {
"type": "GitHub",
"owner": "ipetkov",
"repo": "crane"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"submodules": false,
"version": "v0.20.3",
"revision": "8468a0c46f81d806fd643ffe389fa80328b21cf4",
"url": "https://api.github.com/repos/ipetkov/crane/tarball/v0.20.3",
"hash": "0zw4275c3a6572w6vjmn850yddw6n3qagwfcq6ns247cx72fdfx0"
},
"disko": {
"type": "GitRelease",
"repository": {
@ -166,32 +150,6 @@
"revision": "f33a4d26226c05d501b9d4d3e5e60a3a59991921",
"url": "https://github.com/nixos/nixpkgs/archive/f33a4d26226c05d501b9d4d3e5e60a3a59991921.tar.gz",
"hash": "1b6dm1sn0bdpcsmxna0zzspjaixa2dald08005fry5jrbjvwafdj"
},
"nixpkgs-stable": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "nixos",
"repo": "nixpkgs"
},
"branch": "nixos-25.05",
"submodules": false,
"revision": "a1ae8ef72f64a845ecce5c6dcf65d546bf7deeb4",
"url": "https://github.com/nixos/nixpkgs/archive/a1ae8ef72f64a845ecce5c6dcf65d546bf7deeb4.tar.gz",
"hash": "0d7lp30wyy5647gpm8rnihvdcpmgmfr9c5yg4fhl31lsg8mlbg16"
},
"proxmox-nixos": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "SaumonNet",
"repo": "proxmox-nixos"
},
"branch": "main",
"submodules": false,
"revision": "48f39fbe2e8f90f9ac160dd4b6929f3ac06d8223",
"url": "https://github.com/SaumonNet/proxmox-nixos/archive/48f39fbe2e8f90f9ac160dd4b6929f3ac06d8223.tar.gz",
"hash": "0606qcs8x1jwckd1ivf52rqdmi3lkn66iiqh6ghd4kqx0g2bw3nv"
}
},
"version": 5

View file

@ -218,7 +218,6 @@ in
cfg.nixops4Package
pkgs.nix
pkgs.openssh
pkgs.git
];
preStart = ''
# Auto-migrate on first run or if the package has changed

View file

@ -13,14 +13,14 @@ buildPythonPackage rec {
_class = "package";
pname = "drf-pydantic";
version = "v2.9.0";
version = "v2.7.1";
pyproject = true;
src = fetchFromGitHub {
owner = "KiaraGrouwstra";
owner = "georgebv";
repo = pname;
rev = "d21c879543bd106242bd7f86e79da1f668109579";
hash = "sha256-pk0/6BphIiXxR3cewBJ5nKii3kj3lDHLO9U9xqXDxI8=";
rev = version;
hash = "sha256-ABtSoxj/+HHq4hj4Yb6bEiyOl00TCO/9tvBzhv6afxM=";
};
nativeBuildInputs = [

View file

@ -7,6 +7,7 @@
{
checks = {
test-mastodon-service = pkgs.testers.runNixOSTest ./mastodon.nix;
test-pixelfed-garage-service = pkgs.testers.runNixOSTest ./pixelfed-garage.nix;
test-peertube-service = pkgs.testers.runNixOSTest ./peertube.nix;
};
};