feat(sakuya): klipper and motion

This commit is contained in:
arcnmx 2024-09-07 14:33:04 -07:00
parent 7e7d6b01f7
commit a02778b413
10 changed files with 214 additions and 127 deletions

View file

@ -1,53 +1,105 @@
{
config,
gensokyo-zone,
lib,
access,
...
}: let
inherit (gensokyo-zone.lib) mapDefaults;
inherit (lib.modules) mkIf mkDefault;
inherit (lib.attrsets) mapAttrs;
inherit (lib.attrsets) mapAttrs mergeAttrsList;
inherit (config.services) nginx;
system = access.systemForServiceId "kitchen";
inherit (system.exports.services) motion;
upstreamNameKitchen = "kitchencam'access";
upstreamNamePrinter = "printercam'access";
in {
config.services.nginx = {
upstreams' = {
${upstreamNameKitchen}.servers.service = {
accessService = {
name = "motion";
id = "kitchen";
};
};
"${upstreamNameKitchen}'stream".servers.service = {
accessService = {
inherit (nginx.upstreams'.${upstreamNameKitchen}.servers.service.accessService) name id;
port = "stream";
};
};
${upstreamNamePrinter}.servers.service = {
accessService = {
name = "motion";
id = "printercam";
};
};
"${upstreamNamePrinter}'stream".servers.service = {
accessService = {
inherit (nginx.upstreams'.${upstreamNamePrinter}.servers.service.accessService) name id;
port = "stream";
};
};
};
virtualHosts = let
# TODO: use upstreams for this!
url = access.proxyUrlFor {
inherit system;
service = motion;
};
streamUrl = access.proxyUrlFor {
inherit system;
service = motion;
portName = "stream";
};
mkSubFilter = port: ''
sub_filter '${port.protocol}://$host:${toString port.port}/' '/';
printerCams = [ 2 ];
kitchenCams = [ 1 3 ];
mkSubFilter = port: path: ''
sub_filter '${port.protocol}://$host:${toString port.port}/' '${path}';
'';
extraConfig = ''
streamConfig = ''
proxy_redirect off;
proxy_buffering off;
set $args "";
'';
locations = {
"/" = {
proxyPass = mkDefault url;
extraConfig = ''
sub_filter_once off;
${mkSubFilter motion.ports.stream}
${mkSubFilter motion.ports.default}
'';
};
"~ ^/[0-9]+/(stream|motion|substream|current|source|status\\.json)$" = {
proxyPass = mkDefault streamUrl;
inherit extraConfig;
};
"~ ^/(stream|motion|substream|current|source|cameras\\.json|status\\.json)$" = {
proxyPass = mkDefault streamUrl;
inherit extraConfig;
# TODO: accept-encoding to nothing so the response isn't compressed?
subFilterConfig = path: ''
sub_filter_once off;
${mkSubFilter motion.ports.stream "/"}
${mkSubFilter motion.ports.default path}
'';
mkStreamLocation = upstreamName: cam: {
"~ ^/${toString cam}/(stream|motion|substream|current|source|status\\.json)$" = {
proxy = {
enable = true;
upstream = mkDefault "${upstreamName}'stream";
path = "";
};
extraConfig = streamConfig;
};
};
streamLocations =
map (mkStreamLocation upstreamNamePrinter) printerCams
++ map (mkStreamLocation upstreamNameKitchen) kitchenCams;
locations = {
"/" = {
return = "302 /kitchen/";
};
"/kitchen" = {
proxy = {
enable = true;
upstream = mkDefault upstreamNameKitchen;
path = "/";
};
extraConfig = subFilterConfig "/kitchen/";
};
"/printer" = {
proxy = {
enable = true;
upstream = mkDefault upstreamNamePrinter;
path = "/";
};
extraConfig = subFilterConfig "/printer/";
};
"~ ^/(stream|motion|substream|current|source|cameras\\.json|status\\.json)$" = {
proxy = {
enable = true;
upstream = mkDefault "${upstreamNameKitchen}'stream";
path = "";
};
extraConfig = streamConfig;
};
} // mergeAttrsList streamLocations;
listen' = {
http = {};
https.ssl = true;
@ -70,7 +122,9 @@ in {
locations = mapAttrs (name: location:
location
// {
proxyPass = mkDefault nginx.virtualHosts.kitchencam.locations.${name}.proxyPass;
${if location ? proxy then "proxy" else null} = location.proxy // (mapDefaults {
inherit (nginx.virtualHosts.kitchencam.locations.${name}.proxy) upstream path;
});
})
locations;
};

View file

@ -3,7 +3,7 @@
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge mkAfter mkDefault;
inherit (lib.modules) mkIf mkMerge mkDefault;
name.shortServer = mkDefault "print";
upstreamName = "moonraker'access";
upstreamNameMotion = "moonraker'motion";
@ -30,6 +30,7 @@ in {
servers.service = {
accessService = {
name = "motion";
id = "printercam";
port = "stream";
};
};
@ -52,6 +53,9 @@ in {
headers.set.Cache-Control = "no-store, no-cache, must-revalidate";
};
"/webcam" = {
return = "302 /webcam/stream";
};
"/webcam/stream" = {
proxy = {
enable = true;
upstream = upstreamNameMotion;
@ -62,6 +66,17 @@ in {
set $args "";
'';
};
"/webcam/current" = {
proxy = {
enable = true;
upstream = upstreamNameMotion;
path = "/2/current";
};
extraConfig = ''
proxy_buffering off;
set $args "";
'';
};
"/websocket" = {
proxy = {
enable = true;
@ -88,6 +103,7 @@ in {
{
"/index.html".vouch.requireAuth = true;
"/webcam".vouch.requireAuth = true;
"/webcam/current".vouch.requireAuth = true;
"/websocket".vouch.requireAuth = true;
"@moonraker".vouch.requireAuth = true;
}