infrastructure

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

mkv.nix (3861B)


      1 {
      2   config,
      3   pkgs,
      4   lib,
      5   mkv,
      6   ...
      7 }:
      8 
      9 let
     10   cfg = config.services.local.mkv;
     11 in
     12 {
     13   options.services.local.mkv = {
     14     enable = lib.mkEnableOption "mkv distributed key-value store";
     15 
     16     package = lib.mkOption {
     17       type = lib.types.package;
     18       default = mkv.packages.${pkgs.stdenv.hostPlatform.system}.default;
     19       description = "mkv package to use";
     20     };
     21 
     22     dbPath = lib.mkOption {
     23       type = lib.types.str;
     24       default = "/var/lib/mkv/index.db";
     25       description = "Path to the index database";
     26     };
     27 
     28     volumes = lib.mkOption {
     29       type = lib.types.listOf lib.types.str;
     30       default = [];
     31       description = "List of volume server URLs";
     32     };
     33 
     34     replicas = lib.mkOption {
     35       type = lib.types.int;
     36       default = 2;
     37       description = "Number of replicas";
     38     };
     39 
     40     port = lib.mkOption {
     41       type = lib.types.port;
     42       default = 3000;
     43       description = "Port for the mkv service";
     44     };
     45 
     46     openFirewall = lib.mkOption {
     47       type = lib.types.bool;
     48       default = true;
     49       description = "Open firewall port on wg0";
     50     };
     51 
     52     # Volume server options
     53     volume = {
     54       enable = lib.mkEnableOption "MKV volume WebDAV server";
     55 
     56       listenAddress = lib.mkOption {
     57         type = lib.types.str;
     58         description = "IP address to listen on (typically VPN address)";
     59       };
     60 
     61       port = lib.mkOption {
     62         type = lib.types.port;
     63         default = 8081;
     64         description = "Port to listen on";
     65       };
     66 
     67       path = lib.mkOption {
     68         type = lib.types.path;
     69         default = "/var/lib/mkv/volume";
     70         description = "Path to the volume directory";
     71       };
     72 
     73       maxBodySize = lib.mkOption {
     74         type = lib.types.str;
     75         default = "256M";
     76         description = "Maximum upload size";
     77       };
     78 
     79       firewallInterface = lib.mkOption {
     80         type = lib.types.str;
     81         default = "wg0";
     82         description = "Interface to allow traffic on";
     83       };
     84     };
     85   };
     86 
     87   config = lib.mkMerge [
     88     # MKV server
     89     (lib.mkIf cfg.enable {
     90       systemd.services.mkv = {
     91         description = "mkv distributed key-value store";
     92         wantedBy = [ "multi-user.target" ];
     93         after = [
     94           "network-online.target"
     95           "wg-quick-wg0.service"
     96           "nginx.service"
     97         ];
     98         wants = [ "network-online.target" ];
     99         requires = [ "wg-quick-wg0.service" ];
    100         environment = {
    101           MKV_DB = cfg.dbPath;
    102           MKV_VOLUMES = lib.concatStringsSep "," cfg.volumes;
    103           MKV_REPLICAS = toString cfg.replicas;
    104           MKV_PORT = toString cfg.port;
    105         };
    106         serviceConfig = {
    107           Type = "simple";
    108           DynamicUser = true;
    109           StateDirectory = "mkv";
    110           ExecStart = "${cfg.package}/bin/mkv serve";
    111           Restart = "on-failure";
    112           RestartSec = 5;
    113         };
    114       };
    115 
    116       networking.firewall.interfaces.wg0.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
    117     })
    118 
    119     # Volume server (nginx WebDAV)
    120     (lib.mkIf cfg.volume.enable {
    121       services.nginx = {
    122         enable = true;
    123         virtualHosts."mkv-volume" = {
    124           listen = [
    125             { addr = cfg.volume.listenAddress; port = cfg.volume.port; }
    126           ];
    127           root = cfg.volume.path;
    128           extraConfig = ''
    129             autoindex on;
    130             autoindex_format json;
    131             dav_methods PUT DELETE;
    132             create_full_put_path on;
    133             client_max_body_size ${cfg.volume.maxBodySize};
    134           '';
    135         };
    136       };
    137 
    138       systemd.tmpfiles.rules = [
    139         "d ${cfg.volume.path} 0755 nginx nginx -"
    140       ];
    141 
    142       networking.firewall.interfaces.${cfg.volume.firewallInterface}.allowedTCPPorts = [ cfg.volume.port ];
    143 
    144       systemd.services.nginx.serviceConfig = {
    145         ReadWritePaths = [ cfg.volume.path ];
    146         ProtectSystem = lib.mkForce "full";
    147       };
    148     })
    149   ];
    150 }