summaryrefslogtreecommitdiff
path: root/nix
diff options
context:
space:
mode:
authorseth <[email protected]>2023-09-06 18:51:30 -0400
committerseth <[email protected]>2023-09-07 11:50:26 -0400
commit0f3a367d27c909b803baf0185d0b6e0ade968c3a (patch)
tree03b1b04127029289c1356bf2c0597b5aa8a37aec /nix
parent8d8dc0896fc8c7f0d2f10087db39cac4e3149c66 (diff)
flake: start using flake-parts + add vm test
Diffstat (limited to 'nix')
-rw-r--r--nix/default.nix16
-rw-r--r--nix/derivation.nix21
-rw-r--r--nix/dev.nix41
-rw-r--r--nix/module.nix118
-rw-r--r--nix/packages.nix25
-rw-r--r--nix/server.nix6
-rw-r--r--nix/vm.nix42
7 files changed, 232 insertions, 37 deletions
diff --git a/nix/default.nix b/nix/default.nix
deleted file mode 100644
index fca9993..0000000
--- a/nix/default.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- lib,
- python311Packages,
- version,
-}:
-python311Packages.buildPythonPackage {
- pname = "guzzle-api";
- inherit version;
-
- src = lib.cleanSource ../.;
- format = "flit";
- doCheck = false;
-
- propagatedBuildInputs = with python311Packages; [fastapi pydantic uvicorn];
- propagatedNativeBuildInputs = with python311Packages; [flit-core];
-}
diff --git a/nix/derivation.nix b/nix/derivation.nix
new file mode 100644
index 0000000..4e32095
--- /dev/null
+++ b/nix/derivation.nix
@@ -0,0 +1,21 @@
+{
+ lib,
+ buildPythonPackage,
+ flit-core,
+ fastapi,
+ pydantic,
+ uvicorn,
+ self,
+ version,
+}:
+buildPythonPackage {
+ pname = "guzzle-api";
+ inherit version;
+
+ src = lib.cleanSource self;
+ format = "flit";
+ doCheck = false;
+
+ propagatedBuildInputs = [fastapi pydantic uvicorn];
+ propagatedNativeBuildInputs = [flit-core];
+}
diff --git a/nix/dev.nix b/nix/dev.nix
new file mode 100644
index 0000000..b394c6c
--- /dev/null
+++ b/nix/dev.nix
@@ -0,0 +1,41 @@
+{
+ inputs,
+ self,
+ withSystem,
+ ...
+}: {
+ perSystem = {
+ config,
+ pkgs,
+ ...
+ }: {
+ pre-commit = {
+ settings.hooks = {
+ isort.enable = true;
+ pylint.enable = true;
+ yapf = {
+ enable = true;
+ name = "yapf";
+ entry = "${pkgs.python311Packages.yapf}/bin/yapf -i";
+ types = ["file" "python"];
+ };
+ };
+ };
+
+ devShells.default = pkgs.mkShell {
+ shellHook = config.pre-commit.installationScript;
+ packages = [
+ (pkgs.python311.withPackages (p: with p; [isort yapf pylint]))
+ ];
+ };
+ };
+
+ flake.tests.x86_64-linux.module = withSystem "x86_64-linux" ({pkgs, ...}:
+ (import (inputs.nixpkgs + "/nixos/lib") {}).runTest {
+ imports = [./vm.nix];
+
+ hostPkgs = pkgs;
+
+ _module.args = {inherit self;};
+ });
+}
diff --git a/nix/module.nix b/nix/module.nix
index 4234e19..10f09c3 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -1,43 +1,125 @@
-{
+self: {
config,
lib,
+ modulesPath,
pkgs,
...
}: let
cfg = config.services.guzzle-api;
- inherit (lib) mkDefault mkEnableOption mkOption mkIf types;
+ inherit
+ (lib)
+ literalExpression
+ mkDefault
+ mkDoc
+ mkEnableOption
+ mkIf
+ mkMerge
+ mkOption
+ mkPackageOption
+ types
+ ;
+
+ proto = "http${lib.optionalString cfg.nginx.addSSL "s"}";
+
+ hostPortSubmodule = {
+ options = {
+ host = mkOption {
+ description = mkDoc "the hostname";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = mkDoc "the port";
+ type = types.port;
+ };
+ };
+ };
in {
options.services.guzzle-api = {
- enable = mkEnableOption "enable guzzle-api";
- url = mkOption {
- type = types.str;
- default = "";
- description = "url string for guzzle-api";
+ enable = mkEnableOption "guzzle-api";
+
+ listen = mkOption {
+ description = mkDoc "address and port to listen to";
+ type = types.submodule hostPortSubmodule;
+ default = {
+ host = "localhost";
+ port = 7240;
+ };
+ defaultText = literalExpression ''
+ {
+ address = "localhost";
+ port = 7240;
+ }
+ '';
};
- port = mkOption {
+
+ domain = mkOption {
+ description = mkDoc "FQDN for guzzle_api endpoint";
type = types.str;
- default = "8080";
- description = "port for guzzle-api";
};
- package = mkOption {
- type = types.package;
- default = pkgs.guzzle-api-server;
- description = "package for guzzle-api wrapper";
+
+ nginx = mkOption {
+ description = mkDoc ''
+ With this option, you can customize an nginx virtual host which already has sensible defaults for Dolibarr.
+ Set to {} if you do not need any customization to the virtual host.
+ If enabled, then by default, the {option}`serverName` is
+ `''${domain}`,
+ If this is set to null (the default), no nginx virtualHost will be configured.
+ '';
+
+ type = types.nullOr (types.submodule (
+ import (modulesPath + "/services/web-servers/nginx/vhost-options.nix") {inherit config lib;}
+ ));
+
+ default = null;
+ example = literalExpression ''
+ {
+ enableACME = true;
+ forceSSL = true;
+ }
+ '';
};
+
+ package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "guzzle-api-server" {};
};
- config.systemd.services = mkIf cfg.enable {
- guzzle-api = {
+ config = mkIf cfg.enable {
+ systemd.services.guzzle-api = {
enable = mkDefault true;
wantedBy = ["multi-user.target"];
after = ["network.target"];
script = ''
- URL=${cfg.url} ${cfg.package}/bin/guzzle-api-server --host 0.0.0.0 --port "${cfg.port}"
+ URL="${proto}://${cfg.domain}" ${cfg.package}/bin/guzzle-api-server --host ${cfg.listen.host} --port ${toString cfg.listen.port}
'';
serviceConfig = mkDefault {
- Restart = "always";
Type = "simple";
+ Restart = "always";
+
+ # hardening
+ DynamicUser = true;
+ PrivateTmp = true;
+ NoNewPrivileges = true;
+ RestrictNamespaces = "uts ipc pid user cgroup";
+ ProtectSystem = "strict";
+ ProtectHome = true;
+ ProtectKernelTunables = true;
+ ProtectKernelModules = true;
+ ProtectControlGroups = true;
+ PrivateDevices = true;
+ RestrictSUIDSGID = true;
};
};
+
+ services.nginx = mkIf (cfg.nginx != null) {
+ enable = true;
+ virtualHosts."${cfg.domain}" = mkMerge [
+ {
+ locations."/" = {
+ proxyPass = "http://${cfg.listen.host}:${toString cfg.listen.port}";
+ };
+ }
+ cfg.nginx
+ ];
+ };
};
}
diff --git a/nix/packages.nix b/nix/packages.nix
new file mode 100644
index 0000000..0adf42f
--- /dev/null
+++ b/nix/packages.nix
@@ -0,0 +1,25 @@
+{self, ...}: let
+ version = builtins.substring 0 8 self.lastModifiedDate or "dirty";
+ commonArgs = {inherit self version;};
+in {
+ perSystem = {pkgs, ...}: {
+ packages = rec {
+ guzzle-api = pkgs.python311Packages.callPackage ./derivation.nix commonArgs;
+ guzzle-api-server = pkgs.python311Packages.callPackage ./server.nix {inherit guzzle-api;};
+ default = guzzle-api;
+ };
+ };
+
+ flake.overlays.default = final: prev: {
+ python = prev.python.override {
+ packageOverrides = _: prev': {
+ guzzle-api = prev'.callPackage ./derivation.nix commonArgs;
+ };
+ };
+
+ pythonPackages = final.python.pkgs;
+
+ guzzle-api = final.pythonPackages.callPackage ./derivation.nix commonArgs;
+ guzzle-api-server = final.pythonPackages.callPackage ./server.nix {};
+ };
+}
diff --git a/nix/server.nix b/nix/server.nix
index 18e4673..eaa3ead 100644
--- a/nix/server.nix
+++ b/nix/server.nix
@@ -1,12 +1,12 @@
{
writeShellApplication,
- python311,
+ python,
+ uvicorn,
guzzle-api,
- ...
}:
writeShellApplication {
name = "guzzle-api-server";
- runtimeInputs = [(python311.withPackages (p: [p.uvicorn guzzle-api]))];
+ runtimeInputs = [(python.withPackages (_: [uvicorn guzzle-api]))];
text = ''
uvicorn guzzle_api.api:app "$@"
'';
diff --git a/nix/vm.nix b/nix/vm.nix
new file mode 100644
index 0000000..b4d1f8a
--- /dev/null
+++ b/nix/vm.nix
@@ -0,0 +1,42 @@
+{self, ...}: {
+ name = "guzzle_api-test";
+
+ nodes.machine = _: {
+ imports = [self.nixosModules.default];
+
+ boot.loader.grub.enable = true;
+ virtualisation = {
+ memorySize = 2048;
+ writableStore = true;
+ };
+
+ services = {
+ nginx = {
+ enable = true;
+
+ recommendedGzipSettings = true;
+ recommendedOptimisation = true;
+ recommendedProxySettings = true;
+ recommendedTlsSettings = true;
+ };
+
+ guzzle-api = {
+ enable = true;
+ domain = "test.com";
+ listen = {
+ host = "0.0.0.0";
+ port = 8080;
+ };
+ nginx = {};
+ };
+ };
+ };
+
+ testScript = _: ''
+ machine.start()
+ machine.wait_for_unit("nginx.service")
+ machine.wait_for_unit("guzzle-api.service")
+ machine.wait_for_open_port(8080)
+ machine.succeed("curl 0.0.0.0:8080/get_random_teawie | grep url")
+ '';
+}