WIP: trigger nixops from panel

Closes .

Note I had not yet manage to successfully test this.

Manually trying the parameterized NixOps4 I tried using the following
command, tho I had yet to get this to work as well:

```sh
DEPLOYMENT='{"domain": "fediversity.net", "mastodon": {"enable": false},
"pixelfed": {"enable": true}, "peertube": {"enable": false}}' nix
develop --extra-experimental-features "configurable-impure-env"
--command nixops4 apply test
```

(or rather, I used a hardcoded Nix here so as to make it not use Lix.)

So far this had failed for me with:

```
the following units failed:
acme-mastodon.web.garage.fediversity.net.service
...
nixops4 error: Failed to create resource garage-configuration
```
This commit is contained in:
kiara Grouwstra 2025-03-11 13:12:09 +01:00
parent 2e72379a48
commit c80fe8959f
Signed by: kiara
SSH key fingerprint: SHA256:COspvLoLJ5WC5rFb9ZDe5urVCkK4LJZOsjfF4duRJFU
7 changed files with 41 additions and 5 deletions

View file

@ -58,7 +58,9 @@
packages = [ packages = [
pkgs.nil pkgs.nil
inputs'.agenix.packages.default inputs'.agenix.packages.default
inputs'.nixops4.packages.default (inputs'.nixops4.packages.default.overrideAttrs {
impureEnvVars = [ "DEPLOYMENT" ];
})
pkgs.httpie pkgs.httpie
pkgs.jq pkgs.jq
]; ];

View file

@ -21,7 +21,7 @@ let
makeResourceModule = makeResourceModule =
{ vmName, isTestVm }: { vmName, isTestVm }:
{ {
_module.args = { inherit inputs; }; _module.args = { inherit self inputs; };
imports = [ imports = [
./common/resource.nix ./common/resource.nix
(if isTestVm then ./test-machines + "/${vmName}" else ./machines + "/${vmName}") (if isTestVm then ./test-machines + "/${vmName}" else ./machines + "/${vmName}")
@ -143,7 +143,17 @@ in
## - We add a “test” deployment with all test machines. ## - We add a “test” deployment with all test machines.
nixops4Deployments = genAttrs machines makeDeployment' // { nixops4Deployments = genAttrs machines makeDeployment' // {
default = makeDeployment machines; default = makeDeployment machines;
test = makeTestDeployment (fromJSON (readFile ./test-machines/configuration.json)); test = makeTestDeployment (
fromJSON (
let
env = builtins.getEnv "DEPLOYMENT";
in
if env != "" then
env
else
builtins.trace "env var DEPLOYMENT not set, falling back to ./test-machines/configuration.json!" (readFile ./test-machines/configuration.json)
)
);
}; };
flake.nixosConfigurations = flake.nixosConfigurations =
genAttrs machines (makeConfiguration false) genAttrs machines (makeConfiguration false)

View file

@ -1,4 +1,5 @@
{ {
self,
config, config,
... ...
}: }:
@ -11,7 +12,12 @@ in
../../../panel/nix/configuration.nix ../../../panel/nix/configuration.nix
]; ];
nix.settings = {
extra-experimental-features = "configurable-impure-env";
};
environment.systemPackages = [ environment.systemPackages = [
self
panel panel
]; ];
@ -36,4 +42,7 @@ in
STATIC_ROOT = "/var/lib/${name}/static"; STATIC_ROOT = "/var/lib/${name}/static";
}; };
}; };
systemd.services.${name}.env = {
REPO_DIR = builtins.trace self self;
};
} }

View file

@ -4,6 +4,11 @@ The Fediversity Panel is a web service for managing Fediversity deployments with
## Development ## Development
- In your [nix.conf](https://nix.dev/manual/nix/latest/command-ref/conf-file) (Nix) / `nix.settings` (NixOS),
to your [`experimental-features`](https://nix.dev/manual/nix/latest/command-ref/conf-file#conf-experimental-features)
add [`configurable-impure-env`](https://nix.dev/manual/nix/latest/development/experimental-features#xp-feature-configurable-impure-env).
Note that this features is only available in Nix, not in Lix.
- To obtain all tools related to this project, enter the development environment with `nix-shell`. - To obtain all tools related to this project, enter the development environment with `nix-shell`.
If you want to do that automatically on entering this directory: If you want to do that automatically on entering this directory:

View file

@ -34,6 +34,8 @@ in
export CREDENTIALS_DIRECTORY=${builtins.toString ./.credentials} export CREDENTIALS_DIRECTORY=${builtins.toString ./.credentials}
export DATABASE_URL="sqlite:///${toString ./src}/db.sqlite3" export DATABASE_URL="sqlite:///${toString ./src}/db.sqlite3"
''; '';
# FIXME: ending a path in a non-name produces a double hash :(
REPO_DIR = ./..;
}; };
tests = pkgs'.callPackage ./nix/tests.nix { }; tests = pkgs'.callPackage ./nix/tests.nix { };

View file

@ -5,8 +5,8 @@
{{ form.as_p }} {{ form.as_p }}
<button class="button" disabled>Deploy</button> <button class="button" type="submit" name="deploy">Deploy</button>
<button class="button" type="submit" >Save</button> <button class="button" type="submit" name="save">Save</button>
</form> </form>
<p><sub>Configuration schema version {{ version }}</sub></p> <p><sub>Configuration schema version {{ version }}</sub></p>

View file

@ -1,6 +1,8 @@
from enum import Enum from enum import Enum
from django.urls import reverse_lazy from django.urls import reverse_lazy
import os
import subprocess
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.views.generic import TemplateView, DetailView from django.views.generic import TemplateView, DetailView
@ -38,6 +40,12 @@ class ConfigurationForm(LoginRequiredMixin, FormView):
"""Get or create the configuration object for the current user""" """Get or create the configuration object for the current user"""
obj, created = models.Configuration.objects.get_or_create( obj, created = models.Configuration.objects.get_or_create(
operator=self.request.user) operator=self.request.user)
button_name = request.POST.get('save_draft') or request.POST.get('publish')
if button_name == 'deploy':
print("DEPLOYING:")
print(os.getenv("REPO_DIR"))
print(obj)
subprocess.run(["nix", "develop", "--command", "nixops4", "apply", "test"], cwd=os.getenv("REPO_DIR"), env={"DEPLOYMENT": obj})
return obj return obj
# TODO(@fricklerhandwerk): # TODO(@fricklerhandwerk):