nixos/samba: migrate to structural settings (RFC42)

This commit is contained in:
Anthony Roussel 2024-04-08 22:34:05 +02:00 committed by Pascal Bach
parent 6423eb0fb7
commit 988c598106
3 changed files with 78 additions and 107 deletions

View File

@ -335,6 +335,13 @@
- The `replay-sorcery` package and module was removed as it unmaintained upstream. Consider using `gpu-screen-recorder` or `obs-studio` instead.
- To follow [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) a few options of `samba` have been moved from `extraConfig` to the new freeform option `settings` and renamed, e.g.:
- `services.samba.invalidUsers` to `services.samba.settings.global."invalid users"`
- `services.samba.securityType` to `services.samba.settings.global."security type"`
- `services.samba.shares` to `services.samba.settings`
- `services.samba.enableWinbindd` to `services.samba.winbindd.enable`
- `services.samba.enableNmbd` to `services.samba.nmbd.enable`
- `zx` was updated to v8, which introduces several breaking changes.
See the [v8 changelog](https://github.com/google/zx/releases/tag/8.0.0) for more information.

View File

@ -3,36 +3,13 @@
with lib;
let
smbToString = x: if builtins.typeOf x == "bool"
then boolToString x
else toString x;
cfg = config.services.samba;
settingsFormat = pkgs.formats.ini { };
configFile = settingsFormat.generate "smb.conf" cfg.settings;
samba = cfg.package;
shareConfig = name:
let share = getAttr name cfg.shares; in
"[${name}]\n " + (smbToString (
map
(key: "${key} = ${smbToString (getAttr key share)}\n")
(attrNames share)
));
configFile = pkgs.writeText "smb.conf"
(if cfg.configText != null then cfg.configText else
''
[global]
security = ${cfg.securityType}
passwd program = /run/wrappers/bin/passwd %u
invalid users = ${smbToString cfg.invalidUsers}
${cfg.extraConfig}
${smbToString (map shareConfig (attrNames cfg.shares))}
'');
# This may include nss_ldap, needed for samba if it has to use ldap.
nssModulesPath = config.system.nssModules.path;
@ -68,6 +45,19 @@ in
imports = [
(mkRemovedOptionModule [ "services" "samba" "defaultShare" ] "")
(mkRemovedOptionModule [ "services" "samba" "syncPasswordsByPam" ] "This option has been removed by upstream, see https://bugzilla.samba.org/show_bug.cgi?id=10669#c10")
(lib.mkRemovedOptionModule [ "services" "samba" "configText" ] ''
Use services.samba.settings instead.
This is part of the general move to use structured settings instead of raw
text for config as introduced by RFC0042:
https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md
'')
(lib.mkRemovedOptionModule [ "services" "samba" "extraConfig" ] "Use services.samba.settings instead.")
(lib.mkRenamedOptionModule [ "services" "samba" "invalidUsers" ] [ "services" "samba" "settings" "global" "invalid users" ])
(lib.mkRenamedOptionModule [ "services" "samba" "securityType" ] [ "services" "samba" "settings" "global" "security type" ])
(lib.mkRenamedOptionModule [ "services" "samba" "shares" ] [ "services" "samba" "settings" ])
];
###### interface
@ -125,41 +115,6 @@ in
example = "samba4Full";
};
invalidUsers = mkOption {
type = types.listOf types.str;
default = [ "root" ];
description = ''
List of users who are denied to login via Samba.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional global section and extra section lines go in here.
'';
example = ''
guest account = nobody
map to guest = bad user
'';
};
configText = mkOption {
type = types.nullOr types.lines;
default = null;
description = ''
Verbatim contents of smb.conf. If null (default), use the
autogenerated file from NixOS instead.
'';
};
securityType = mkOption {
type = types.enum [ "auto" "user" "domain" "ads" ];
default = "user";
description = "Samba security type";
};
nsswins = mkOption {
default = false;
type = types.bool;
@ -170,25 +125,31 @@ in
'';
};
shares = mkOption {
settings = lib.mkOption {
type = lib.types.submodule { freeformType = settingsFormat.type; };
default = {};
example = {
"global" = {
"security" = "user";
"passwd program" = "/run/wrappers/bin/passwd %u";
"invalid users" = "root";
};
"public" = {
"path" = "/srv/public";
"read only" = "yes";
"browseable" = "yes";
"guest ok" = "yes";
"comment" = "Public samba share.";
};
};
description = ''
A set describing shared resources.
See {command}`man smb.conf` for options.
'';
type = types.attrsOf (types.attrsOf types.unspecified);
example = literalExpression ''
{ public =
{ path = "/srv/public";
"read only" = true;
browseable = "yes";
"guest ok" = "yes";
comment = "Public samba share.";
};
}
Configuration file for the Samba suite in ini format.
This file is located in /etc/samba/smb.conf
Refer to <https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html>
for all available options.
'';
};
};
};

View File

@ -1,46 +1,49 @@
import ./make-test-python.nix ({ pkgs, ... }:
{
import ./make-test-python.nix ({ pkgs, ... }: {
name = "samba";
meta.maintainers = [ ];
nodes =
{ client =
{ pkgs, ... }:
{ virtualisation.fileSystems =
{ "/public" = {
fsType = "cifs";
device = "//server/public";
options = [ "guest" ];
};
};
nodes = {
client =
{ ... }:
{
virtualisation.fileSystems = {
"/public" = {
fsType = "cifs";
device = "//server/public";
options = [ "guest" ];
};
};
};
server =
{ ... }:
{ services.samba.enable = true;
services.samba.openFirewall = true;
services.samba.shares.public =
{ path = "/public";
server =
{ ... }:
{
services.samba = {
enable = true;
openFirewall = true;
settings = {
"public" = {
"path" = "/public";
"read only" = true;
browseable = "yes";
"browseable" = "yes";
"guest ok" = "yes";
comment = "Public samba share.";
"comment" = "Public samba share.";
};
};
};
};
};
};
# client# [ 4.542997] mount[777]: sh: systemd-ask-password: command not found
testScript =
''
server.start()
server.wait_for_unit("samba.target")
server.succeed("mkdir -p /public; echo bar > /public/foo")
testScript = ''
server.start()
server.wait_for_unit("samba.target")
server.succeed("mkdir -p /public; echo bar > /public/foo")
client.start()
client.wait_for_unit("remote-fs.target")
client.succeed("[[ $(cat /public/foo) = bar ]]")
'';
client.start()
client.wait_for_unit("remote-fs.target")
client.succeed("[[ $(cat /public/foo) = bar ]]")
'';
})