diff --git a/flake.nix b/flake.nix index 96e4f815..9e0a719b 100644 --- a/flake.nix +++ b/flake.nix @@ -58,9 +58,13 @@ packages = [ pkgs.nil inputs'.agenix.packages.default - inputs'.nixops4.packages.default + pkgs.openssh pkgs.httpie pkgs.jq + # exposing this env var as a hack to pass info in from form + (inputs'.nixops4.packages.default.overrideAttrs { + impureEnvVars = [ "DEPLOYMENT" ]; + }) ]; shellHook = config.pre-commit.installationScript; }; diff --git a/infra/flake-part.nix b/infra/flake-part.nix index 08be9cfe..f90bd2ff 100644 --- a/infra/flake-part.nix +++ b/infra/flake-part.nix @@ -143,7 +143,17 @@ in ## - We add a “test” deployment with all test machines. nixops4Deployments = genAttrs machines makeDeployment' // { 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 = genAttrs machines (makeConfiguration false) diff --git a/panel/default.nix b/panel/default.nix index c5bc5fe4..b2aa2480 100644 --- a/panel/default.nix +++ b/panel/default.nix @@ -30,6 +30,8 @@ in export CREDENTIALS_DIRECTORY=${builtins.toString ./.credentials} export DATABASE_URL="sqlite:///${toString ./src}/db.sqlite3" ''; + # explicitly use nix, as e.g. lix does not have configurable-impure-env + NIX_DIR = pkgs.nix; }; module = import ./nix/configuration.nix; diff --git a/panel/src/panel/templates/configuration_form.html b/panel/src/panel/templates/configuration_form.html index 154b5e02..474aa4f6 100644 --- a/panel/src/panel/templates/configuration_form.html +++ b/panel/src/panel/templates/configuration_form.html @@ -5,7 +5,7 @@ {{ form.as_p }} - <button class="button" disabled>Deploy</button> - <button class="button" type="submit" >Save</button> + <button class="button" type="submit" name="deploy">Deploy</button> + <button class="button" type="submit" name="save">Save</button> </form> {% endblock %} diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 13a8f80a..85918e26 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -1,4 +1,7 @@ from enum import Enum +import os +import json +import subprocess from django.urls import reverse_lazy from django.contrib.auth.mixins import LoginRequiredMixin @@ -41,6 +44,41 @@ class ConfigurationForm(LoginRequiredMixin, FormView): operator=self.request.user, ) + # Check for deploy button + if "deploy" in self.request.POST.keys(): + submission = obj.parsed_value.model_dump_json() + # in dev we can use a relative path, for deployed versions we must explicitly + # specify our root flake as the directory to trigger nixops from, see #94. + cwd = os.getenv("REPO_DIR") or f"{os.getcwd()}/.." + # FIXME: let the user specify these from the form (#190) + dummy_user = { + "initialUser": { + "displayName": "Testy McTestface", + "username": "test", + "password": "testtest", + "email": "test@test.com", + }, + } + # serialize back and forth now we still need to manually inject the dummy user + deployment = json.dumps(dummy_user | json.loads(submission)) + env = { + # use nix as implicit lix from a dev shell lacks configurable-impure-env + "PATH": f"{os.getenv("NIX_DIR")}/bin/", + # environment variable we use to pass in form info to our deployment + "DEPLOYMENT": deployment, + } + cmd = [ + "nix", + "develop", + # workaround to pass in info to nixops4 thru env vars, tho impure :( + "--extra-experimental-features", + "configurable-impure-env", + "--command", + "nixops4", + "apply", + "test", + ] + subprocess.run(cmd, cwd=cwd, env=env) return obj # TODO(@fricklerhandwerk):