feat(manage commmand): Add manage command with nsenter

This commit is contained in:
sinavir 2024-07-04 13:47:21 +02:00
parent 5ea9469cc2
commit a61afb48e2
2 changed files with 52 additions and 33 deletions

View file

@ -6,9 +6,20 @@
}: }:
let let
mkManagePy = pkgs.callPackage ./utils/mkManagePy.nix { }; 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 = mkStaticAssets =
{ app, managePy, mainModule }: {
pkgs.runCommand "django-${app}-static" {} '' app,
managePy,
mainModule,
}:
pkgs.runCommand "django-${app}-static" { } ''
mkdir -p "$out/static" mkdir -p "$out/static"
STATIC_ROOT="\"$out/static\"" \ STATIC_ROOT="\"$out/static\"" \
DJANGO_SETTINGS_MODULE="${mainModule}_settings.mock" \ DJANGO_SETTINGS_MODULE="${mainModule}_settings.mock" \
@ -73,7 +84,7 @@ let
}; };
runtimeSettings = lib.mkOption { runtimeSettings = lib.mkOption {
type = with lib.types; attrsOf str; type = with lib.types; attrsOf str;
default= {}; default = { };
description = '' description = ''
Settings to pass to only at runtime. Settings to pass to only at runtime.
@ -166,7 +177,7 @@ let
}; };
}; };
config = { config = {
runtimeSettings.STATIC_ROOT = "";#config.staticAssets; runtimeSettings.STATIC_ROOT = ""; # config.staticAssets;
}; };
} }
); );
@ -178,34 +189,37 @@ in
description = "Attribute set of djanfo app modules"; description = "Attribute set of djanfo app modules";
}; };
}; };
config.systemd.services = lib.mapAttrs' ( config = {
app: cfg: systemd.services = lib.mapAttrs' (
lib.nameValuePair "django-${app}" ( app: cfg:
lib.mkIf cfg.enable { lib.nameValuePair "django-${app}" (
description = "${app} django service"; lib.mkIf cfg.enable {
wantedBy = [ "multi-user.target" ]; description = "${app} django service";
after = [ "network.target" ]; wantedBy = [ "multi-user.target" ];
wants = [ "network.target" ]; after = [ "network.target" ];
serviceConfig = rec { wants = [ "network.target" ];
Type = "notify"; serviceConfig = rec {
#NotifyAllow = "exec"; Type = "notify";
DynamicUser = true; #NotifyAllow = "exec";
DynamicUser = true;
LoadCredential = lib.mapAttrsToList (k: v: "${k}:${v}") cfg.secrets; LoadCredential = lib.mapAttrsToList (k: v: "${k}:${v}") cfg.secrets;
StateDirectory = "django-${app}"; StateDirectory = "django-${app}";
}; };
environment = { environment = {
DJANGO_SETTINGS_MODULE = "${cfg.mainModule}_settings.prod"; DJANGO_SETTINGS_MODULE = "${cfg.mainModule}_settings.prod";
} // (lib.mapAttrs (_: v: builtins.toJSON v) cfg.runtimeSettings); } // (lib.mapAttrs (_: v: builtins.toJSON v) cfg.runtimeSettings);
script = '' script = ''
${lib.getExe cfg.managePy} migrate ${lib.getExe cfg.managePy} migrate
exec ${cfg.pythonPackage}/bin/gunicorn ${cfg.mainModule}.wsgi \ exec ${cfg.pythonPackage}/bin/gunicorn ${cfg.mainModule}.wsgi \
--pythonpath ${cfg.src}/${cfg.sourceRoot} \ --pythonpath ${cfg.src}/${cfg.sourceRoot} \
-b 127.0.0.1:${builtins.toString cfg.port} \ -b 127.0.0.1:${builtins.toString cfg.port} \
--workers=${builtins.toString cfg.processes} \ --workers=${builtins.toString cfg.processes} \
--threads=${builtins.toString cfg.threads} --threads=${builtins.toString cfg.threads}
''; '';
} }
) )
) config.services.django; ) config.services.django;
environment.systemPackages = lib.mapAttrsToList (k: v: mkManageCommand k v) config.services.django;
};
} }

View file

@ -82,6 +82,11 @@ pkgs.testers.runNixOSTest (
if status != 0 or json.loads(out) != json.loads('${builtins.toJSON settings.JSON_SMOKE_TEST}'): if status != 0 or json.loads(out) != json.loads('${builtins.toJSON settings.JSON_SMOKE_TEST}'):
sys.exit(1) 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)
''; '';
} }
) )