From a61afb48e2478c47360a8efea6f835c3b0f5f503 Mon Sep 17 00:00:00 2001 From: sinavir Date: Thu, 4 Jul 2024 13:47:21 +0200 Subject: [PATCH] feat(manage commmand): Add manage command with nsenter --- module.nix | 80 ++++++++++++++++++++++++++++++++---------------------- test.nix | 5 ++++ 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/module.nix b/module.nix index ef0f8d7..c3fc4e4 100644 --- a/module.nix +++ b/module.nix @@ -6,9 +6,20 @@ }: let mkManagePy = pkgs.callPackage ./utils/mkManagePy.nix { }; + + mkManageCommand = + app: cfg: + pkgs.writeShellScriptBin "manage-${app}" '' + eval "$(${config.systemd.package}/bin/systemctl show -pMainPID django-${app}.service)" + ${pkgs.util-linux}/bin/nsenter -e -a -t $MainPID -G follow -S follow ${lib.getExe cfg.managePy} "$@" + ''; mkStaticAssets = - { app, managePy, mainModule }: - pkgs.runCommand "django-${app}-static" {} '' + { + app, + managePy, + mainModule, + }: + pkgs.runCommand "django-${app}-static" { } '' mkdir -p "$out/static" STATIC_ROOT="\"$out/static\"" \ DJANGO_SETTINGS_MODULE="${mainModule}_settings.mock" \ @@ -73,7 +84,7 @@ let }; runtimeSettings = lib.mkOption { type = with lib.types; attrsOf str; - default= {}; + default = { }; description = '' Settings to pass to only at runtime. @@ -166,7 +177,7 @@ let }; }; config = { - runtimeSettings.STATIC_ROOT = "";#config.staticAssets; + runtimeSettings.STATIC_ROOT = ""; # config.staticAssets; }; } ); @@ -178,34 +189,37 @@ in description = "Attribute set of djanfo app modules"; }; }; - config.systemd.services = lib.mapAttrs' ( - app: cfg: - lib.nameValuePair "django-${app}" ( - lib.mkIf cfg.enable { - description = "${app} django service"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - wants = [ "network.target" ]; - serviceConfig = rec { - Type = "notify"; - #NotifyAllow = "exec"; - DynamicUser = true; + config = { + systemd.services = lib.mapAttrs' ( + app: cfg: + lib.nameValuePair "django-${app}" ( + lib.mkIf cfg.enable { + description = "${app} django service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + wants = [ "network.target" ]; + serviceConfig = rec { + Type = "notify"; + #NotifyAllow = "exec"; + DynamicUser = true; - LoadCredential = lib.mapAttrsToList (k: v: "${k}:${v}") cfg.secrets; - StateDirectory = "django-${app}"; - }; - environment = { - DJANGO_SETTINGS_MODULE = "${cfg.mainModule}_settings.prod"; - } // (lib.mapAttrs (_: v: builtins.toJSON v) cfg.runtimeSettings); - script = '' - ${lib.getExe cfg.managePy} migrate - exec ${cfg.pythonPackage}/bin/gunicorn ${cfg.mainModule}.wsgi \ - --pythonpath ${cfg.src}/${cfg.sourceRoot} \ - -b 127.0.0.1:${builtins.toString cfg.port} \ - --workers=${builtins.toString cfg.processes} \ - --threads=${builtins.toString cfg.threads} - ''; - } - ) - ) config.services.django; + LoadCredential = lib.mapAttrsToList (k: v: "${k}:${v}") cfg.secrets; + StateDirectory = "django-${app}"; + }; + environment = { + DJANGO_SETTINGS_MODULE = "${cfg.mainModule}_settings.prod"; + } // (lib.mapAttrs (_: v: builtins.toJSON v) cfg.runtimeSettings); + script = '' + ${lib.getExe cfg.managePy} migrate + exec ${cfg.pythonPackage}/bin/gunicorn ${cfg.mainModule}.wsgi \ + --pythonpath ${cfg.src}/${cfg.sourceRoot} \ + -b 127.0.0.1:${builtins.toString cfg.port} \ + --workers=${builtins.toString cfg.processes} \ + --threads=${builtins.toString cfg.threads} + ''; + } + ) + ) config.services.django; + environment.systemPackages = lib.mapAttrsToList (k: v: mkManageCommand k v) config.services.django; + }; } diff --git a/test.nix b/test.nix index 887be92..dfa5c84 100644 --- a/test.nix +++ b/test.nix @@ -82,6 +82,11 @@ pkgs.testers.runNixOSTest ( if status != 0 or json.loads(out) != json.loads('${builtins.toJSON settings.JSON_SMOKE_TEST}'): sys.exit(1) + with subtest("Manage command"): + out = machine.succeed('manage-smoke-test shell -c "from django.conf import settings; print(settings.SMOKE_TEST)"') + if out.strip() != "${settings.SMOKE_TEST}".strip(): + print(out) + sys.exit(1) ''; } )