Unverified Commit b008f506 authored by Yt's avatar Yt Committed by GitHub
Browse files

Merge pull request #302689 from eclairevoyant/davfs2-fix

nixos/davfs2: fix rfc42 conversion, make settings and extraConfig mutually exclusive, and other cleanup
parents 5e03c797 a60e4033
Loading
Loading
Loading
Loading
+74 −38
Original line number Diff line number Diff line
{ config, lib, pkgs, ... }:

with lib;

let
  toStr = value:
    if true == value then "yes"
    else if false == value then "no"
    else toString value;
  inherit (lib.attrsets) optionalAttrs;
  inherit (lib.generators) toINIWithGlobalSection;
  inherit (lib.lists) optional;
  inherit (lib.modules) mkIf;
  inherit (lib.options) literalExpression mkEnableOption mkOption;
  inherit (lib.strings) escape;
  inherit (lib.types) attrsOf bool int lines oneOf str submodule;

  cfg = config.services.davfs2;
  format = pkgs.formats.toml { };
  configFile = let
    settings = mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings;
  in pkgs.writeText "davfs2.conf" ''
    ${concatStringsSep "\n" settings}
    ${cfg.extraConfig}
  '';

  escapeString = escape ["\"" "\\"];

  formatValue = value:
    if true == value then "1"
    else if false == value then "0"
    else if builtins.isString value then "\"${escapeString value}\""
    else toString value;

  configFile = pkgs.writeText "davfs2.conf" (
    if (cfg.settings != { }) then
      (toINIWithGlobalSection {
        mkSectionName = escapeString;
        mkKeyValue = k: v: "${k} ${formatValue v}";
      } cfg.settings)
    else
      cfg.extraConfig
  );
in
{

  options.services.davfs2 = {
    enable = mkOption {
      type = types.bool;
      default = false;
      description = lib.mdDoc ''
        Whether to enable davfs2.
      '';
    };
    enable = mkEnableOption "davfs2";

    davUser = mkOption {
      type = types.str;
      type = str;
      default = "davfs2";
      description = lib.mdDoc ''
      description = ''
        When invoked by root the mount.davfs daemon will run as this user.
        Value must be given as name, not as numerical id.
      '';
    };

    davGroup = mkOption {
      type = types.str;
      type = str;
      default = "davfs2";
      description = lib.mdDoc ''
      description = ''
        The group of the running mount.davfs daemon. Ordinary users must be
        member of this group in order to mount a davfs2 file system. Value must
        be given as name, not as numerical id.
@@ -48,14 +54,19 @@ in
    };

    extraConfig = mkOption {
      type = types.lines;
      type = lines;
      default = "";
      example = ''
        kernel_fs coda
        proxy foo.bar:8080
        use_locks 0

        [/media/dav]
        use_locks 1

        [/home/otto/mywebspace]
        gui_optimize 1
      '';
      description = lib.mdDoc ''
      description = ''
        Extra lines appended to the configuration of davfs2.
        See {manpage}`davfs2.conf(5)` for available settings.

@@ -66,18 +77,30 @@ in
    };

    settings = mkOption {
      type = types.submodule {
        freeformType = format.type;
      type = submodule {
        freeformType = let
          valueTypes = [ bool int str ];
        in
        attrsOf (attrsOf (oneOf (valueTypes ++ [ (attrsOf (oneOf valueTypes)) ] )));
      };
      default = { };
      example = literalExpression ''
        {
          kernel_fs = "coda";
          globalSection = {
            proxy = "foo.bar:8080";
          use_locks = 0;
            use_locks = false;
          };
          sections = {
            "/media/dav" = {
              use_locks = true;
            };
            "/home/otto/mywebspace" = {
              gui_optimize = true;
            };
          };
        }
      '';
      description = lib.mdDoc ''
      description = ''
        Extra settings appended to the configuration of davfs2.
        See {manpage}`davfs2.conf(5)` for available settings.
      ''  ;
@@ -86,17 +109,30 @@ in

  config = mkIf cfg.enable {

    warnings = lib.optional (cfg.extraConfig != null) ''
      services.davfs2.extraConfig will be deprecated in future releases, please use the settings option now.
    assertions = [
      {
        assertion = cfg.extraConfig != "" -> cfg.settings == { };
        message = ''
          services.davfs2.extraConfig and services.davfs2.settings cannot be used together.
          Please prefer using services.davfs2.settings.
        '';
      }
    ];

    warnings = optional (cfg.extraConfig != "") ''
      services.davfs2.extraConfig will be deprecated in future releases;
      please use services.davfs2.settings instead.
    '';

    environment.systemPackages = [ pkgs.davfs2 ];
    environment.etc."davfs2/davfs2.conf".source = configFile;

    services.davfs2.settings = {
      globalSection = {
        dav_user = cfg.davUser;
        dav_group = cfg.davGroup;
      };
    };

    users.groups = optionalAttrs (cfg.davGroup == "davfs2") {
      davfs2.gid = config.ids.gids.davfs2;