From 3851a66193fa7cc54a56d58b150b0b473bc2c49e Mon Sep 17 00:00:00 2001 From: hackens server Date: Wed, 8 Mar 2023 00:48:11 +0100 Subject: [PATCH] add_hackens_orga --- hosts/org/configuration.nix | 1 + hosts/org/orga/authens.nix | 12 ++++++ hosts/org/orga/default.nix | 42 ++++++++++++++++++++ hosts/org/orga/mkAssets.nix | 27 +++++++++++++ hosts/org/orga/module.nix | 65 +++++++++++++++++++++++++++++++ hosts/org/orga/python-cas.nix | 13 +++++++ hosts/org/orga/python.nix | 20 ++++++++++ hosts/org/orga/shell.nix | 6 +++ hosts/org/orga/static-assets.nix | 10 +++++ secrets/default.nix | 4 ++ secrets/django.age | Bin 0 -> 1654 bytes secrets/secrets.nix | 3 ++ 12 files changed, 203 insertions(+) create mode 100644 hosts/org/orga/authens.nix create mode 100644 hosts/org/orga/default.nix create mode 100644 hosts/org/orga/mkAssets.nix create mode 100644 hosts/org/orga/module.nix create mode 100644 hosts/org/orga/python-cas.nix create mode 100644 hosts/org/orga/python.nix create mode 100644 hosts/org/orga/shell.nix create mode 100644 hosts/org/orga/static-assets.nix create mode 100644 secrets/django.age diff --git a/hosts/org/configuration.nix b/hosts/org/configuration.nix index 0f6dd94..86eb3a2 100644 --- a/hosts/org/configuration.nix +++ b/hosts/org/configuration.nix @@ -15,6 +15,7 @@ ./nginx.nix ./dokuwiki.nix ./matterbridge.nix + ./orga ]; networking.hostName = "hackens-org"; # Define your hostname. diff --git a/hosts/org/orga/authens.nix b/hosts/org/orga/authens.nix new file mode 100644 index 0000000..d7b5f82 --- /dev/null +++ b/hosts/org/orga/authens.nix @@ -0,0 +1,12 @@ +{ lib, pythoncas, django, ldap, buildPythonPackage }: +buildPythonPackage rec { + pname = "authens"; + version = "v0.1b5"; + doCheck = false; + src = builtins.fetchGit { + url = "https://git.eleves.ens.fr/klub-dev-ens/authens.git"; + #rev = "master"; + #sha256 = "sha256-R0Nw212/BOPHfpspT5wzxtji1vxZ/JOuwr00naklWE8="; + }; + propagatedBuildInputs = [ django ldap pythoncas ]; +} diff --git a/hosts/org/orga/default.nix b/hosts/org/orga/default.nix new file mode 100644 index 0000000..32ee748 --- /dev/null +++ b/hosts/org/orga/default.nix @@ -0,0 +1,42 @@ +{ pkgs, lib, config, ... }: +let + assets = import ./mkAssets.nix { + inherit pkgs; + app = "hackens_orga"; + settings = config.services.django.hackens_orga.settings; + source = pkgs.fetchgit { + url = "https://git.rz.ens.wtf/HackENS/hackens-orga.git"; + rev = "1a7a2c00d7e2efd380cc63164e6b77542c465c2e"; + hash = "sha256-tpRCy7kDqd129j882e2FtCKS/JgcckmTFaTPElLbcjg="; #lib.fakeSha256; + }; + }; +in +{ + imports = [ + ./module.nix + ]; + services.nginx = { + enable = true; + virtualHosts."new.hackens.org" = { + locations = { + "/orga" = { + proxyPass = "http://localhost:51666/orga"; + extraConfig = '' + proxy_set_header SCRIPT_NAME /orga; + ''; + }; + "/static".root = assets.static-assets; + }; + }; + }; + services.django.hackens_orga = { + enable = true; + assets = assets; + settings = { + HACKENS_ORGA_DEBUG = "0"; + HACKENS_ORGA_ALLOWED_HOSTS = [ "new.hackens.org" ]; + HACKENS_ORGA_SECRET_KEY._file = config.age.secrets.django.path; + HACKENS_ORGA_DB_FILE = "/var/lib/hackens-orga/db.sqlite3"; + }; + }; +} diff --git a/hosts/org/orga/mkAssets.nix b/hosts/org/orga/mkAssets.nix new file mode 100644 index 0000000..61e744a --- /dev/null +++ b/hosts/org/orga/mkAssets.nix @@ -0,0 +1,27 @@ +{ pkgs, settings, source, app }: +let + manage-py-file = "${source}/${app}/manage.py"; + python = import ./python.nix { inherit pkgs; }; + static-assets = pkgs.callPackage ./static-assets.nix { inherit python source app; envPrefix = "HACKENS_ORGA_"; }; + mkEnv = settings: let # make env file to source before using manage.py and other commands + lib = pkgs.lib; + mkVarVal = v: let + isHasAttr = s: lib.isAttrs v && lib.hasAttr s v; + in + if builtins.isString v then v + else if builtins.isList v && lib.any lib.strings.isCoercibleToString v then (lib.concatMapStringsSep "," toString v) + else if builtins.isInt v then toString v + else if builtins.isBool v then toString (if v then 1 else 0) + else if isHasAttr "_file" then "$(cat ${v._file} | xargs)" + else if isHasAttr "_raw" then v._raw + else abort "The django conf value ${lib.generators.toPretty {} v} can not be encoded."; + in lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "export ${k}=${mkVarVal v}") settings); + envFile = pkgs.writeScript "django-${app}-env.sh" (mkEnv settings); + managePy = pkgs.writeScript "manage-${app}" '' + source ${envFile} + ${python}/bin/python ${manage-py-file} $@ + ''; +in +{ + inherit managePy static-assets envFile source python; +} diff --git a/hosts/org/orga/module.nix b/hosts/org/orga/module.nix new file mode 100644 index 0000000..9f32a2e --- /dev/null +++ b/hosts/org/orga/module.nix @@ -0,0 +1,65 @@ +{ pkgs, lib, config, ... }: +let + app = "hackens_orga"; + cfg = config.services.django.${app}; + assets = cfg.assets; +in +{ + + options = { + services.django.${app} = { + enable = lib.mkEnableOption (lib.mdDoc "Enable django ${app}"); + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = with lib.types; attrsOf anything; + options = { + HACKENS_ORGA_STATIC_ROOT = lib.mkOption { + type = lib.types.path; + default = builtins.toString assets.static-assets; + }; + }; + }; + }; + assets = lib.mkOption { + type = lib.types.attrsOf lib.types.anything; + description = lib.mdDoc "Assets for django"; + }; + port = lib.mkOption { + type = lib.types.port; + default = 51666; + }; + processes = lib.mkOption { + type = lib.types.int; + default = 2; + }; + threads = lib.mkOption { + type = lib.types.int; + default = 2; + }; + }; + }; + config = lib.mkIf cfg.enable { + systemd.services."django-${app}" = { + description = "${app} django service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + User = "django-${app}"; + }; + script = '' + source ${assets.envFile} + ${assets.managePy} migrate + ${assets.python}/bin/gunicorn ${app}.wsgi \ + --pythonpath ${assets.source}/${app} \ + -b 127.0.0.1:${toString cfg.port} \ + --workers=${toString cfg.processes} \ + --threads=${toString cfg.threads} + ''; + }; + users.users."django-${app}" = { + isSystemUser = true; + group = "django-${app}"; + }; + users.groups."django-${app}" = {}; + }; +} diff --git a/hosts/org/orga/python-cas.nix b/hosts/org/orga/python-cas.nix new file mode 100644 index 0000000..e0bba1c --- /dev/null +++ b/hosts/org/orga/python-cas.nix @@ -0,0 +1,13 @@ +{ lib, requests, lxml, six, buildPythonPackage, fetchFromGitHub }: +buildPythonPackage rec { + pname = "python-cas"; + version = "1.6.0"; + doCheck = false; + src = fetchFromGitHub { + owner = "python-cas"; + repo = "python-cas"; + rev = "v1.6.0"; + sha512 = "sha512-qnYzgwELUij2EdqA6H17q8vnNUsfI7DkbZSI8CCIGfXOM+cZ7vsWe7CJxzsDUw73sBPB4+zzpLxvb7tpm/IDeg=="; + }; + propagatedBuildInputs = [ requests lxml six ]; +} diff --git a/hosts/org/orga/python.nix b/hosts/org/orga/python.nix new file mode 100644 index 0000000..dc77ffc --- /dev/null +++ b/hosts/org/orga/python.nix @@ -0,0 +1,20 @@ +{ pkgs ? import ../nix { }, debug ? false }: +let + python = pkgs.python310.override { + packageOverrides = self: super: { + django = super.django_4; + authens = self.callPackage ./authens.nix { }; + pythoncas = self.callPackage ./python-cas.nix { }; + }; + }; +in +python.withPackages (ps: [ + ps.django + ps.djangorestframework + ps.authens + ps.gunicorn +] ++ pkgs.lib.optionals debug [ + ps.django-debug-toolbar + ps.black + ps.isort +]) diff --git a/hosts/org/orga/shell.nix b/hosts/org/orga/shell.nix new file mode 100644 index 0000000..69ca0e9 --- /dev/null +++ b/hosts/org/orga/shell.nix @@ -0,0 +1,6 @@ +{ pkgs ? import ../nix { } }: +pkgs.mkShell { + buildInputs = [ + (import ./python.nix { inherit pkgs; debug = true; }) + ]; +} diff --git a/hosts/org/orga/static-assets.nix b/hosts/org/orga/static-assets.nix new file mode 100644 index 0000000..4c4e128 --- /dev/null +++ b/hosts/org/orga/static-assets.nix @@ -0,0 +1,10 @@ +{ pkgs, python, source, app, envPrefix ? ""}: +pkgs.runCommand "django-static" { } '' + mkdir -p $out/static + export ${envPrefix}SECRET_KEY="collectstatic" + export ${envPrefix}STATIC_ROOT=$out/static + export ${envPrefix}DEBUG=0 + export ${envPrefix}ALLOWED_HOSTS= + export ${envPrefix}DB_FILE= + ${python}/bin/python ${source}/${app}/manage.py collectstatic +'' diff --git a/secrets/default.nix b/secrets/default.nix index 9853933..5fac86f 100644 --- a/secrets/default.nix +++ b/secrets/default.nix @@ -4,6 +4,10 @@ file = ./wiki-openID.age; owner = "dokuwiki"; }; + age.secrets."django" = { + file = ./django.age; + owner = "django-hackens_orga"; + }; age.secrets."matterbridge-env" = { file = ./matterbridge-env.age; owner = "matterbridge"; diff --git a/secrets/django.age b/secrets/django.age new file mode 100644 index 0000000000000000000000000000000000000000..a5b4e5daa2d7ad4bf63fa33a45fee480621a8b93 GIT binary patch literal 1654 zcmZXTJL~Lv8HEMAoW@2Dg5oG>6aMD*{NDmm(7ey}a7> zefAPZH~<*4llXuuB=D0SlWy|*j3Xd!T#!WE{Nxg;H#*CqJnPuDYl1}OeMj3v*paQd^bNtd*X^Cb1?{ zNgPKRmnr?(ATt5Umkqn1Jyg1_AZ6rYSOr-g6oQ_rw!>>B68a(^B7j^@W*ze@L%DCK z(V6!^(;XwZnKRSR(;cjQH;Ey9p9;}>UM&S~^jbj7BONqoS(hXfO!y=`4}%ogu#X0j z7GAo%>s_E@IqSv-rgmrZc^@BD{U)vJ{oSLpkBR|37A$^}Z7RR!xPnT(0h_-1RIxFti97>7zJpu0C1Qpu0R?huU_9Qo#x56%$m<40XwOzcK zRx*jygSvDhrNR@LP*FAfQqk{ zi>A`CtRpkgpL>RE;xZYtLQGkPsW3<>=Zf>a6qE7zNFdP$`@IZ^?jFM|oVlSu#avsR z3!RDaBK4$WI9#+tcQzs=ibF|&x^uvUWDW;sM=p@kI**8bddDPWnvKxdQR8r-#6ga5 zrK8D5(yr5qzA6;8&qI%A$oY7bf~FA4=K<39y{Y640h{^tuxCxs^h|l)hb6KM#Phbz zk=3*t66DtWX4^Mkf?gT=a@Yl%dfU=RW^~7S-EstJ$<>cUlT;IVu^WzV_*7g?*XC5n zHAOLO&ofVnNqOOX^rE$taFS^6&IwFkk3>cz8tcpYJKl!VjRonhLIY*>RDf{Ijh46? zmtmh$_S{6o#E9uuQ73Z87sSQ1AlJ3qZlzMYm=r!=c!9YqNlqNF={3n^Kg_BrHWTa7T8QqSW2DT38-PGg zXu8Fl)!L{H(@uMcuajXZ^A+om5IEFk+QMNS)hT;)CC-<2DHO#cvcdLv#}Wr%^OEiq zR=Hlr>Du8ai}(}gIe3Zr*WlQ@VPG+nq+RoiYNh^WK{$IcU?;(f?RHe2jKaHjaUj?N zsAzc&hdaouT4b?ft^R+v=q2r9zmIqKwsUt?x5K{tP4gSy`H}%inm9_9<8ekk^A7Gy zjYLw`bOf=I;ymoNx6sGI>zmue5*f}Zt48af9_zxPs@7>+$mu>iH0 zC#CsgLs8S5O~9kNK<6rlV-8Jj@at$oFE1~W`p&wGe{?})|{o4<|`mHa#`up#``$g@SpAG+Mf922L4?p_v&p!UihhP82 zAEyWZt3Q4G;om;_-t;N_FT~H8_ul{9k2LW9UqAW7kALv$Hy{1`ANmKsfA7=!e?I?H H*