feat(core): initialize NaxOS declarative NixOS distribution, modules, and ISO installer
Test NaxOS Module Configurations / test-modules (push) Failing after 6m10s

This commit is contained in:
Lukas Holzner
2026-09-03 23:53:18 +02:00
parent 88a638955b
commit 5da58ae6d7
28 changed files with 2247 additions and 2 deletions
+72
View File
@@ -0,0 +1,72 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.naxos.shares.nfs;
in {
options.services.naxos.shares.nfs = {
enable = mkEnableOption "NaxOS Declarative NFS Service";
lockdPort = mkOption {
type = types.int;
default = 4001;
description = "Port for lockd.";
};
mountdPort = mkOption {
type = types.int;
default = 4002;
description = "Port for mountd.";
};
exports = mkOption {
type = types.listOf (types.submodule {
options = {
path = mkOption {
type = types.str;
description = "Path to exported directory or dataset.";
};
clients = mkOption {
type = types.listOf (types.submodule {
options = {
subnet = mkOption {
type = types.str;
example = "10.0.0.0/23";
description = "Allowed client subnet or IP.";
};
options = mkOption {
type = types.str;
default = "rw,sync,no_subtree_check,no_root_squash";
description = "NFS export options.";
};
};
});
default = [];
description = "Clients allowed to mount this export.";
};
};
});
default = [];
description = "List of NFS exported directories.";
};
};
config = mkIf cfg.enable {
services.nfs.server = {
enable = true;
lockdPort = cfg.lockdPort;
mountdPort = cfg.mountdPort;
exports = concatMapStringsSep "\n" (exp:
let
clientList = concatMapStringsSep " " (c: "${c.subnet}(${c.options})") exp.clients;
in "${exp.path} ${clientList}"
) cfg.exports;
};
networking.firewall = {
allowedTCPPorts = [ 111 2049 cfg.lockdPort cfg.mountdPort ];
allowedUDPPorts = [ 111 2049 cfg.lockdPort cfg.mountdPort ];
};
};
}
+197
View File
@@ -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>
'';
};
};
};
}