feat(core): initialize NaxOS declarative NixOS distribution, modules, and ISO installer
Test NaxOS Module Configurations / test-modules (push) Failing after 6m10s
Test NaxOS Module Configurations / test-modules (push) Failing after 6m10s
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.shares.samba;
|
||||
in {
|
||||
options.services.naxos.shares.samba = {
|
||||
enable = mkEnableOption "NaxOS Declarative Samba (SMB) Service";
|
||||
|
||||
workgroup = mkOption {
|
||||
type = types.str;
|
||||
default = "WORKGROUP";
|
||||
description = "NetBIOS workgroup.";
|
||||
};
|
||||
|
||||
serverString = mkOption {
|
||||
type = types.str;
|
||||
default = "NaxOS Storage Appliance";
|
||||
description = "Server announcement string.";
|
||||
};
|
||||
|
||||
netbiosName = mkOption {
|
||||
type = types.str;
|
||||
default = "naxos";
|
||||
description = "NetBIOS hostname.";
|
||||
};
|
||||
|
||||
allowedHosts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "10.0.0." "192.168." "172.16." "127.0.0.1" "localhost" ];
|
||||
description = "Allowed IP subnets or hosts for SMB access.";
|
||||
};
|
||||
|
||||
shares = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to publish this share.";
|
||||
};
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
description = "Target local directory or ZFS mountpoint.";
|
||||
};
|
||||
comment = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = "Share description.";
|
||||
};
|
||||
readOnly = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether the share is read-only.";
|
||||
};
|
||||
browseable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether the share is visible in network browsing.";
|
||||
};
|
||||
guestOk = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether anonymous/guest access is allowed.";
|
||||
};
|
||||
validUsers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "List of valid users or @groups.";
|
||||
};
|
||||
forceUser = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Force UNIX user for all connections.";
|
||||
};
|
||||
forceGroup = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Force UNIX group for all connections.";
|
||||
};
|
||||
createMask = mkOption {
|
||||
type = types.str;
|
||||
default = "0664";
|
||||
description = "File creation permission mask.";
|
||||
};
|
||||
directoryMask = mkOption {
|
||||
type = types.str;
|
||||
default = "0775";
|
||||
description = "Directory creation permission mask.";
|
||||
};
|
||||
timeMachine = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable Apple Time Machine compatibility mode (vfs_fruit).";
|
||||
};
|
||||
timeMachineMaxSize = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "512G";
|
||||
description = "Quota size limit advertised to Time Machine.";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = {};
|
||||
description = "Declaratively managed SMB shares.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.samba = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
settings = {
|
||||
global = {
|
||||
workgroup = cfg.workgroup;
|
||||
"server string" = cfg.serverString;
|
||||
"netbios name" = cfg.netbiosName;
|
||||
security = "user";
|
||||
"hosts allow" = concatStringsSep " " cfg.allowedHosts;
|
||||
"hosts deny" = "0.0.0.0/0";
|
||||
"guest account" = "nobody";
|
||||
"map to guest" = "bad user";
|
||||
|
||||
# Apple & ZFS ACL compatibility
|
||||
"vfs objects" = "catia fruit streams_xattr acl_xattr";
|
||||
"fruit:aapl" = "yes";
|
||||
"fruit:metadata" = "stream";
|
||||
"fruit:model" = "Macmini";
|
||||
"fruit:posix_rename" = "yes";
|
||||
"fruit:zero_file_id" = "yes";
|
||||
|
||||
# ACLs and inheritance
|
||||
"map acl inherit" = "yes";
|
||||
"inherit acls" = "yes";
|
||||
"ea support" = "yes";
|
||||
};
|
||||
} // (mapAttrs' (shareName: shareCfg:
|
||||
nameValuePair shareName (
|
||||
{
|
||||
path = shareCfg.path;
|
||||
comment = shareCfg.comment;
|
||||
browseable = if shareCfg.browseable then "yes" else "no";
|
||||
"read only" = if shareCfg.readOnly then "yes" else "no";
|
||||
"guest ok" = if shareCfg.guestOk then "yes" else "no";
|
||||
"create mask" = shareCfg.createMask;
|
||||
"directory mask" = shareCfg.directoryMask;
|
||||
}
|
||||
// optionalAttrs (shareCfg.validUsers != []) {
|
||||
"valid users" = concatStringsSep " " shareCfg.validUsers;
|
||||
}
|
||||
// optionalAttrs (shareCfg.forceUser != null) {
|
||||
"force user" = shareCfg.forceUser;
|
||||
}
|
||||
// optionalAttrs (shareCfg.forceGroup != null) {
|
||||
"force group" = shareCfg.forceGroup;
|
||||
}
|
||||
// optionalAttrs shareCfg.timeMachine {
|
||||
"vfs objects" = "catia fruit streams_xattr acl_xattr";
|
||||
"fruit:time machine" = "yes";
|
||||
}
|
||||
// optionalAttrs (shareCfg.timeMachine && shareCfg.timeMachineMaxSize != null) {
|
||||
"fruit:time machine max size" = shareCfg.timeMachineMaxSize;
|
||||
}
|
||||
)
|
||||
) (filterAttrs (n: v: v.enable) cfg.shares));
|
||||
};
|
||||
|
||||
# Enable Avahi (mDNS / Bonjour) for automatic SMB & Time Machine discovery on macOS/iOS/Windows
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
publish = {
|
||||
enable = true;
|
||||
userServices = true;
|
||||
};
|
||||
extraServiceFiles = {
|
||||
smb = ''
|
||||
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
|
||||
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
|
||||
<service-group>
|
||||
<name replace-wildcards="yes">%h (NaxOS SMB)</name>
|
||||
<service>
|
||||
<type>_smb._tcp</type>
|
||||
<port>445</port>
|
||||
</service>
|
||||
<service>
|
||||
<type>_device-info._tcp</type>
|
||||
<port>0</port>
|
||||
<txt-record>model=RackMac</txt-record>
|
||||
</service>
|
||||
</service-group>
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user