nixos/samba: migrate to structural settings (RFC42)

Changed files
+78 -107
nixos
doc
manual
release-notes
modules
services
network-filesystems
tests
+7
nixos/doc/manual/release-notes/rl-2411.section.md
···
- 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.
+37 -76
nixos/modules/services/network-filesystems/samba.nix
···
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;
···
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
···
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;
···
'';
};
-
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.
'';
};
-
};
};
+34 -31
nixos/tests/samba.nix
···
-
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 ]]")
+
'';
})