Migrated from multi repos to monorepo architecture.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
# To test
|
||||
./hardware/default.nix
|
||||
./mail/default.nix
|
||||
./misc/default.nix
|
||||
./packages/default.nix
|
||||
./global.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{ lib, deviceType, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus;
|
||||
|
||||
country = "";
|
||||
language = "";
|
||||
in
|
||||
|
||||
{
|
||||
options.numbus = {
|
||||
owner = mkOption {
|
||||
type = types.str;
|
||||
example = "Alex";
|
||||
default = "Numbus";
|
||||
description = "The name of the person who owns this ${deviceType}.";
|
||||
};
|
||||
|
||||
internationalization = {
|
||||
country = mkOption {
|
||||
type = types.str;
|
||||
example = "FR";
|
||||
default = country;
|
||||
description = "The country where this ${deviceType} is located.";
|
||||
};
|
||||
language = mkOption {
|
||||
type = types.str;
|
||||
example = "fr";
|
||||
default = language;
|
||||
description = "The language for this ${deviceType}.";
|
||||
};
|
||||
locale = mkOption {
|
||||
type = types.str;
|
||||
example = "fr_FR";
|
||||
default = "fr_FR";
|
||||
description = "The locale for this ${deviceType}.";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
hardware.cpu.amd.updateMicrocode = true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
# To test
|
||||
./disks/default.nix
|
||||
./cpu.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.hardware.disks.boot;
|
||||
|
||||
bootCount = builtins.length cfg.list;
|
||||
|
||||
singleDiskConfig = {
|
||||
disko.devices.disk.main = {
|
||||
type = "disk";
|
||||
device = head cfg.list;
|
||||
content = {
|
||||
type = cfg.partitionTableScheme;
|
||||
partitions = {
|
||||
ESP = {
|
||||
size = cfg.partition.boot.size;
|
||||
type = cfg.partition.boot.esp;
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.partition.boot.filesystem;
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
size = cfg.partition.swap.size;
|
||||
content = {
|
||||
type = "swap";
|
||||
randomEncryption = cfg.partition.swap.encrypt;
|
||||
};
|
||||
};
|
||||
luks = {
|
||||
size = cfg.partition.root.size;
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "boot";
|
||||
settings.keyFile = "/run/secrets/disks/boot";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.partition.root.filesystem;
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
raid1DiskConfig = {
|
||||
disko.devices.disk = lib.listToAttrs (lib.imap0 (i: device: {
|
||||
name = "boot-${toString i}";
|
||||
value = {
|
||||
type = "disk";
|
||||
inherit device;
|
||||
content = {
|
||||
type = cfg.partitionTableScheme;
|
||||
partitions = {
|
||||
ESP = { size = cfg.partition.boot.size; type = cfg.partition.boot.esp; content = { type = "mdraid"; name = "boot"; }; };
|
||||
swap = { size = cfg.partition.swap.size; content = { type = "mdraid"; name = "swap"; }; };
|
||||
mdadm = { size = cfg.partition.root.size; content = { type = "mdraid"; name = "raid1"; }; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}) cfg.list);
|
||||
|
||||
disko.devices.mdadm = {
|
||||
boot = {
|
||||
type = "mdadm";
|
||||
level = 1;
|
||||
metadata = "1.0";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.partition.boot.filesystem;
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
type = "mdadm";
|
||||
level = 1;
|
||||
content = {
|
||||
type = "swap";
|
||||
randomEncryption = cfg.partition.swap.encrypt;
|
||||
};
|
||||
};
|
||||
raid1 = {
|
||||
type = "mdadm";
|
||||
level = 1;
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "boot";
|
||||
settings.keyFile = "/run/secrets/disks/boot";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.partition.root.filesystem;
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
options.numbus.hardware.disks = {
|
||||
boot = {
|
||||
list = mkOption {
|
||||
type = types.listOf types.str;
|
||||
example = [ "/dev/disk/by-id/nvme_SAMSUNG_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-San_Disk_159Ejz224G" ];
|
||||
description = "A set of by-id path of disk(s) that will be used as boot disk(s). At least one disk must be set.";
|
||||
};
|
||||
partitionTableScheme = mkOption {
|
||||
type = types.enum [ "gpt" "mbr" ];
|
||||
default = "gpt";
|
||||
example = "gpt";
|
||||
description = "The scheme of the partition table. Use \"gpt\" for modern devices and \"mbr\" for legacy ones.";
|
||||
};
|
||||
partition = {
|
||||
root = {
|
||||
filesystem = mkOption {
|
||||
type = types.enum [ "ext4" "btrfs" "xfs" ];
|
||||
default = "ext4";
|
||||
example = "ext4";
|
||||
description = "The filesystem to use for the root partition of the boot disk(s).";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.str;
|
||||
default = "100%";
|
||||
example = "100%";
|
||||
description = "The size of the root partition. Use G for GBs and M for MBs.";
|
||||
};
|
||||
};
|
||||
boot = {
|
||||
filesystem = mkOption {
|
||||
type = types.enum [ "vfat" ];
|
||||
default = "vfat";
|
||||
example = "vfat";
|
||||
description = "The filesystem to use for the boot partition of the boot disk(s).";
|
||||
};
|
||||
esp = mkOption {
|
||||
type = types.enum [ "EF00" "EF02" ];
|
||||
default = "EF00";
|
||||
example = "EF00";
|
||||
description = "The ESP type to use for the boot partition. Use EF02 for UEFI and EF00 for BIOS.";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.str;
|
||||
default = "1G";
|
||||
example = "1G";
|
||||
description = "The size of the boot partition.";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = true;
|
||||
description = "Wether to create a swap partition. Useful for servers that don't have a lot of RAM.";
|
||||
};
|
||||
encrypt = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
example = true;
|
||||
description = "Wether to encrypt randomly the swap partition. Disable if you need hibernation";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.str;
|
||||
default = "16G";
|
||||
example = "16G";
|
||||
description = "Size of the swap partition. Use G for GBs and M for MBs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
{
|
||||
sops.secrets."disks/boot" = {
|
||||
sopsFile = "/etc/nixos/secrets/disks/boot.yaml";
|
||||
gid = "0";
|
||||
uid = "0";
|
||||
mode = "0400";
|
||||
};
|
||||
}
|
||||
(mkIf (bootCount == 1) singleDiskConfig)
|
||||
(mkIf (bootCount == 2) raid1DiskConfig)
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.hardware.disks.content;
|
||||
|
||||
contentCount = builtins.length cfg.list;
|
||||
parityCount = builtins.length config.numbus.hardware.disks.parity.list;
|
||||
|
||||
contentDisks = lib.imap0 (i: device: {
|
||||
name = "content-${toString i}";
|
||||
value = {
|
||||
type = "disk";
|
||||
inherit device;
|
||||
content = {
|
||||
type = cfg.partitionTableScheme;
|
||||
partitions.luks = {
|
||||
size = cfg.partition.size;
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "content-${toString i}";
|
||||
settings.keyFile = "/run/secrets/disks/content-${toString i}";
|
||||
initrdUnlock = false;
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.partition.filesystem;
|
||||
mountpoint = "/mnt/content-${toString i}";
|
||||
mountOptions = [ "noauto" "nofail" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}) cfg.list;
|
||||
in
|
||||
|
||||
{
|
||||
options.numbus.hardware.disks = {
|
||||
content = {
|
||||
list = mkOption {
|
||||
type = types.listOf types.str;
|
||||
example = [ "/dev/disk/by-id/ata_Hitachi_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-WD_159Ejz224G" ];
|
||||
default = [];
|
||||
description = "A set of by-id path of disk(s) that will be used as content disk(s).";
|
||||
};
|
||||
partitionTableScheme = mkOption {
|
||||
type = types.enum [ "gpt" "mbr" ];
|
||||
default = "gpt";
|
||||
example = "gpt";
|
||||
description = "The scheme of the partition table. Use \"gpt\" for modern devices and \"mbr\" for legacy ones.";
|
||||
};
|
||||
partition = {
|
||||
filesystem = mkOption {
|
||||
type = types.enum [ "ext4" "btrfs" "xfs" ];
|
||||
default = "xfs";
|
||||
example = "xfs";
|
||||
description = "The filesystem to use for the main partition of the content disk(s).";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.str;
|
||||
default = "100%";
|
||||
example = "100%";
|
||||
description = "The size of the main partition. Use G for GBs and M for MBs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (contentCount > 0 && (parityCount != 1 && contentCount != 1)) {
|
||||
disko.devices.disk = builtins.listToAttrs contentDisks;
|
||||
|
||||
sops.secrets = listToAttrs (map (i:
|
||||
nameValuePair "disks/content-${toString i}" {
|
||||
sopsFile = "/etc/nixos/secrets/disks/content.yaml";
|
||||
gid = "0";
|
||||
uid = "0";
|
||||
mode = "0400";
|
||||
}
|
||||
) (range 0 (contentCount - 1)));
|
||||
|
||||
systemd.services.mount-content-disks = {
|
||||
description = "Mount content disks.";
|
||||
before = [ "mnt-data.mount" ];
|
||||
requiredBy = [ "mnt-data.mount" ];
|
||||
requires = [ "sops-install-secrets.service" ];
|
||||
path = [ pkgs.cryptsetup pkgs.util-linux ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = let
|
||||
mountContentDisk = i: ''
|
||||
if [ ! -e /dev/mapper/content-${toString i} ]; then
|
||||
cryptsetup luksOpen --key-file /run/secrets/disks/content-${toString i} /dev/disk/by-partlabel/disk-content-${toString i}-luks content-${toString i}
|
||||
fi
|
||||
mkdir -p /mnt/content-${toString i}
|
||||
if ! mountpoint -q /mnt/content-${toString i}; then
|
||||
mount -t ${cfg.partition.filesystem} /dev/mapper/content-${toString i} /mnt/content-${toString i}
|
||||
fi
|
||||
'';
|
||||
in ''
|
||||
${concatMapStrings mountContentDisk (range 0 (contentCount - 1))}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./boot.nix
|
||||
./content.nix
|
||||
./mergerfs-snapraid.nix
|
||||
./mirror.nix
|
||||
./parity.nix
|
||||
./spindown.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.hardware.disks;
|
||||
|
||||
contentCount = builtins.length cfg.content.list;
|
||||
parityCount = builtins.length cfg.parity.list;
|
||||
in
|
||||
|
||||
{
|
||||
config = mkIf (contentCount >= 2 && parityCount >= 1) {
|
||||
services.snapraid = {
|
||||
enable = true;
|
||||
contentFiles = map (i: "/mnt/content-${toString i}/snapraid.content") (range 0 (contentCount - 1));
|
||||
parityFiles = map (i: "/mnt/parity-${toString i}/snapraid.parity") (range 0 (parityCount - 1));
|
||||
dataDisks = listToAttrs (imap0 (i: _: nameValuePair "d${toString i}" "/mnt/content-${toString i}") cfg.content.list);
|
||||
};
|
||||
|
||||
fileSystems."/mnt/data" = {
|
||||
device = concatStringsSep ":" (map (i: "/mnt/content-${toString i}") (range 0 (contentCount - 1)));
|
||||
fsType = "fuse.mergerfs";
|
||||
options = [
|
||||
"category.create=ff"
|
||||
"cache.files=partial"
|
||||
"dropcacheonclose=true"
|
||||
"defaults"
|
||||
"noauto"
|
||||
"nofail"
|
||||
"allow_other"
|
||||
"moveonenospc=1"
|
||||
"minfreespace=50G"
|
||||
"func.getattr=newest"
|
||||
"fsname=mergerfs_data"
|
||||
"x-mount.mkdir"
|
||||
"x-systemd.automount"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.hardware.disks;
|
||||
|
||||
contentCount = builtins.length cfg.content.list;
|
||||
parityCount = builtins.length cfg.parity.list;
|
||||
|
||||
dataMirror = {
|
||||
disko.devices.disk = listToAttrs (imap0 (i: device: {
|
||||
name = "mirror-${toString i}";
|
||||
value = {
|
||||
type = "disk";
|
||||
inherit device;
|
||||
content = {
|
||||
type = cfg.partitionTableScheme;
|
||||
partitions.raid = {
|
||||
size = cfg.content.partition.size;
|
||||
content = {
|
||||
type = "mdraid";
|
||||
name = "mirror";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}) (cfg.content.list ++ cfg.parity.list));
|
||||
|
||||
disko.devices.mdadm.mirror = {
|
||||
type = "mdadm";
|
||||
level = 1;
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "mirror";
|
||||
settings.keyFile = "/run/secrets/disks/mirror";
|
||||
initrdUnlock = false;
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.content.partition.filesystem;
|
||||
mountpoint = "/mnt/data";
|
||||
mountOptions = [ "noauto" "nofail" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
config = mkIf (contentCount == 1 && parityCount == 1) (mkMerge [
|
||||
dataMirror
|
||||
{
|
||||
systemd.services.mount-mirror = {
|
||||
description = "Mount the disks mirror.";
|
||||
before = [ "mnt-data.mount" ];
|
||||
requiredBy = [ "mnt-data.mount" ];
|
||||
requires = [ "sops-install-secrets.service" ];
|
||||
path = [ pkgs.cryptsetup pkgs.util-linux ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
if [ ! -e /dev/mapper/mirror ]; then
|
||||
cryptsetup open /dev/md/mirror mirror --key-file /run/secrets/disks/mirror
|
||||
fi
|
||||
mkdir -p /mnt/data
|
||||
if ! mountpoint -q /mnt/data; then
|
||||
mount -t ${cfg.content.partition.filesystem} /dev/mapper/mirror /mnt/data
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.hardware.disks.parity;
|
||||
|
||||
parityCount = builtins.length cfg.list;
|
||||
|
||||
parityDisks = lib.imap0 (i: device: {
|
||||
name = "parity-${toString i}";
|
||||
value = {
|
||||
type = "disk";
|
||||
inherit device;
|
||||
content = {
|
||||
type = cfg.partitionTableScheme;
|
||||
partitions.luks = {
|
||||
size = cfg.partition.size;
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "parity-${toString i}";
|
||||
settings.keyFile = "/run/secrets/disks/parity-${toString i}";
|
||||
initrdUnlock = false;
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = cfg.partition.filesystem;
|
||||
mountpoint = "/mnt/parity-${toString i}";
|
||||
mountOptions = [ "noauto" "nofail" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}) cfg.list;
|
||||
in
|
||||
|
||||
{
|
||||
options.numbus.hardware.disks = {
|
||||
parity = {
|
||||
list = mkOption {
|
||||
type = types.listOf types.str;
|
||||
example = [ "/dev/disk/by-id/ata_WDC_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-San_Disk_159Ejz224G" ];
|
||||
default = [];
|
||||
description = "A set of by-id path of disk(s) that will be used as parity disk(s).";
|
||||
};
|
||||
partitionTableScheme = mkOption {
|
||||
type = types.enum [ "gpt" "mbr" ];
|
||||
default = "gpt";
|
||||
example = "gpt";
|
||||
description = "The scheme of the partition table. Use \"gpt\" for modern devices and \"mbr\" for legacy ones.";
|
||||
};
|
||||
partition = {
|
||||
filesystem = mkOption {
|
||||
type = types.enum [ "ext4" "btrfs" "xfs" ];
|
||||
default = "xfs";
|
||||
example = "xfs";
|
||||
description = "The filesystem to use for the main partition of the parity disk(s).";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.str;
|
||||
default = "100%";
|
||||
example = "100%";
|
||||
description = "The size of the main partition. Use G for GBs and M for MBs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (parityCount > 1) {
|
||||
disko.devices.disk = builtins.listToAttrs parityDisks;
|
||||
|
||||
sops.secrets = listToAttrs (map (i:
|
||||
nameValuePair "disks/parity-${toString i}" {
|
||||
sopsFile = "/etc/nixos/secrets/disks/parity.yaml";
|
||||
gid = "0";
|
||||
uid = "0";
|
||||
mode = "0400";
|
||||
}
|
||||
) (range 0 (parityCount - 1)));
|
||||
|
||||
systemd.services.mount-parity-disks = {
|
||||
description = "Mount parity disks.";
|
||||
before = [ "mnt-data.mount" ];
|
||||
requiredBy = [ "mnt-data.mount" ];
|
||||
requires = [ "sops-install-secrets.service" ];
|
||||
path = [ pkgs.cryptsetup pkgs.util-linux ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = let
|
||||
mountparityDisk = i: ''
|
||||
if [ ! -e /dev/mapper/parity-${toString i} ]; then
|
||||
cryptsetup luksOpen --key-file /run/secrets/disks/parity-${toString i} /dev/disk/by-partlabel/disk-parity-${toString i}-luks parity-${toString i}
|
||||
fi
|
||||
mkdir -p /mnt/parity-${toString i}
|
||||
if ! mountpoint -q /mnt/parity-${toString i}; then
|
||||
mount -t ${cfg.partition.filesystem} /dev/mapper/parity-${toString i} /mnt/parity-${toString i}
|
||||
fi
|
||||
'';
|
||||
in
|
||||
''
|
||||
${concatMapStrings mountparityDisk (range 0 (parityCount - 1))}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
hardDrives = config.numbus.hardware.spindown.list;
|
||||
cfg = config.numbus.hardware;
|
||||
in
|
||||
|
||||
{
|
||||
config = mkIf (cfg.HddSpindown.enable == true) {
|
||||
systemd.services.hd-idle = {
|
||||
description = "External HD spin down daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart =
|
||||
let
|
||||
idleTime = toString 1800;
|
||||
hardDriveParameter = lib.strings.concatMapStringsSep " " (x: "-a ${x} -i ${idleTime}") hardDrives;
|
||||
in
|
||||
"${pkgs.hd-idle}/bin/hd-idle -i 0 ${hardDriveParameter}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
options.numbus = {
|
||||
hardware = {
|
||||
spindown = {
|
||||
enable = mkEnableOption "hard drives spin down when inactive in order to save power.";
|
||||
list = mkOption {
|
||||
description = "The list of compatible hard drives that will spin down.";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "/dev/disk/by-id/ata_Hitachi_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-WD_159Ejz224G" ];
|
||||
};
|
||||
optimize = mkOption {
|
||||
description = "Optimize services to reduce HDD wakeups when spindown is enabled. Can be set to \"compatible\" to optimize all compatible services, or a list of service names to optimize.";
|
||||
type = types.nullOr (types.either (types.enum [ "compatible" ]) (types.listOf types.str));
|
||||
default = "compatible";
|
||||
example = "[ \"crafty\" \"gitea\" ]";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
# To test
|
||||
./disk-space.nix
|
||||
./smart.nix
|
||||
./smtp.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus-server.services.disk-space-checker;
|
||||
|
||||
disk_space_notifier = pkgs.writeScript "disk-space-notifier.sh" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
ALERT_FILE="/var/lib/numbus-server/disk_alert.env"
|
||||
if [ ! -f "$ALERT_FILE" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source "$ALERT_FILE"
|
||||
rm "$ALERT_FILE"
|
||||
|
||||
# Update the timestamp for this specific path to prevent spamming
|
||||
SAFE_PATH=$(echo "$DISK_ALERT_PATH" | tr '/' '_')
|
||||
date +%s > "/var/lib/numbus-server/last_alert_$SAFE_PATH.ts"
|
||||
|
||||
ADMIN_EMAIL="${config.numbus-server.mail.adminAddress}"
|
||||
USER_EMAIL="${config.numbus-server.mail.userAddress}"
|
||||
OWNER_NAME="${config.numbus-server.owner}"
|
||||
|
||||
SUBJECT="Numbus Server Alert: Low Disk Space Detected"
|
||||
|
||||
TECH_BODY="
|
||||
Disk Space Alert:
|
||||
Server owner: $OWNER_NAME
|
||||
|
||||
The following mount point has exceeded the safety threshold:
|
||||
Mount: $DISK_ALERT_PATH
|
||||
Usage: $DISK_ALERT_USAGE%
|
||||
|
||||
Full partition details:
|
||||
$(df -h "$DISK_ALERT_PATH")
|
||||
|
||||
Action required: Please investigate and clear space or expand the storage capacity.
|
||||
"
|
||||
|
||||
FRIENDLY_BODY="Cher/Chère $OWNER_NAME,
|
||||
|
||||
L'espace de stockage de votre serveur Numbus est presque saturé.
|
||||
Disque concerné : $DISK_ALERT_PATH ($DISK_ALERT_USAGE% utilisé)
|
||||
|
||||
Votre administrateur a été notifié avec les détails techniques.
|
||||
Nous vous conseillons d'éviter d'ajouter des fichiers volumineux pour garantir le bon fonctionnement de vos services.
|
||||
Contactez votre administrateur afin d'évoquer les possibilités d'expansion du stockage.
|
||||
"
|
||||
|
||||
printf "Subject: [ADMIN] %s\n\n%s" "$SUBJECT" "$TECH_BODY" | /run/wrappers/bin/sendmail -t "$ADMIN_EMAIL"
|
||||
printf "Subject: [Alerte] Espace disque presque saturé sur votre serveur Numbus\n\n%s\n\nMerci de votre confiance,\nL'équipe de support,\nNumbus-Server." "$FRIENDLY_BODY" | /run/wrappers/bin/sendmail -t "$USER_EMAIL"
|
||||
'';
|
||||
|
||||
disk_space_checker = pkgs.writeScript "disk-space-checker.sh" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
# Safety threshold in percentage
|
||||
THRESHOLD=90
|
||||
# Paths to monitor (Root and MergerFS data pool)
|
||||
PATHS=("/" "/mnt/data")
|
||||
ALERT_FILE="/var/lib/numbus-server/disk_alert.env"
|
||||
|
||||
for path in "''${PATHS[@]}"; do
|
||||
# Skip if path does not exist (e.g. if mergerfs is not mounted yet)
|
||||
if [ ! -d "$path" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Anti-spam logic: Check if we alerted on this path recently (7 days = 604800 seconds)
|
||||
SAFE_PATH=$(echo "$path" | tr '/' '_')
|
||||
TS_FILE="/var/lib/numbus-server/last_alert_$SAFE_PATH.ts"
|
||||
NOW=$(date +%s)
|
||||
|
||||
if [ -f "$TS_FILE" ]; then
|
||||
LAST_SENT=$(cat "$TS_FILE")
|
||||
DIFF=$((NOW - LAST_SENT))
|
||||
if [ "$DIFF" -lt 604800 ]; then
|
||||
echo "Alert for $path was sent recently. Skipping notification to avoid spam."
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Extract usage percentage using df
|
||||
USAGE=$(df -h "$path" | awk 'NR==2 {print $5}' | sed 's/%//')
|
||||
|
||||
if [ "$USAGE" -ge "$THRESHOLD" ]; then
|
||||
echo "DISK_ALERT_PATH=$path" > "$ALERT_FILE"
|
||||
echo "DISK_ALERT_USAGE=$USAGE" >> "$ALERT_FILE"
|
||||
|
||||
echo "Threshold exceeded for $path ($USAGE%). Triggering notification."
|
||||
|
||||
# Trigger the notification service
|
||||
/run/current-system/sw/bin/systemctl start disk-space-notifier.service
|
||||
|
||||
# We exit after the first alert to avoid multiple overlapping emails in one run
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
'';
|
||||
in
|
||||
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.disk-space-notifier = {
|
||||
description = "Email notification for low disk space";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${disk_space_notifier}";
|
||||
};
|
||||
};
|
||||
systemd.services.disk-space-checker = {
|
||||
description = "Check for low disk space";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${disk_space_checker}";
|
||||
};
|
||||
};
|
||||
systemd.timers.disk-space-checker = {
|
||||
description = "Run disk space check every day";
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
};
|
||||
wantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
smartd_notifier = pkgs.writeScript "smartd-notify.sh" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
|
||||
# 1. Send Technical Email to Admin
|
||||
ADMIN_EMAIL="${config.numbus-server.mail.adminAddress}"
|
||||
SUBJECT="Numbus Server Alert: $SMARTD_FAILTYPE on $SMARTD_DEVICE"
|
||||
|
||||
TECH_BODY="
|
||||
SMARTD Alert Details:
|
||||
Server owner: $OWNER_NAME
|
||||
Device: $SMARTD_DEVICE
|
||||
Type: $SMARTD_DEVICETYPE
|
||||
Failure Type: $SMARTD_FAILTYPE
|
||||
Message: $SMARTD_MESSAGE
|
||||
|
||||
Full Message:
|
||||
$SMARTD_FULLMESSAGE
|
||||
"
|
||||
printf "Subject: [ADMIN] $SUBJECT\n\n$TECH_BODY" | /run/wrappers/bin/sendmail -t "$ADMIN_EMAIL"
|
||||
|
||||
# 2. Send Friendly Email to Owner
|
||||
USER_EMAIL="${config.numbus-server.mail.userAddress}"
|
||||
OWNER_NAME="${config.numbus-server.owner}"
|
||||
|
||||
FRIENDLY_BODY="Cher/Chère $OWNER_NAME,
|
||||
|
||||
Votre serveur a automatiquement détecté une panne matérielle de disque dur.
|
||||
Ce genre de panne est tout à fait normal selon l'âge de votre matériel et n'entraîne
|
||||
dans la grande majorité des cas aucune perte de données grâce au système de
|
||||
stockage redondant préventif.
|
||||
|
||||
Votre administrateur a été notifié de cette panne. Il vous recontactera dans de très
|
||||
brefs délais afin de procéder au remplacement, si nécessaire, du disque dur défaillant.
|
||||
|
||||
Merci de votre confiance,
|
||||
L'équipe de support,
|
||||
Numbus-Server."
|
||||
|
||||
printf "Subject: [Alerte] Défaillance matérielle sur votre serveur Numbus\n\n$FRIENDLY_BODY" | /run/wrappers/bin/sendmail -t "$USER_EMAIL"
|
||||
'';
|
||||
in
|
||||
|
||||
{
|
||||
services.smartd = {
|
||||
enable = true;
|
||||
defaults.autodetected = "-a -o on -S on -s (S/../.././00|L/../../6/01) -n standby,q -M exec ${smartd_notifier}";
|
||||
notifications = {
|
||||
wall = {
|
||||
enable = true;
|
||||
};
|
||||
mail = {
|
||||
enable = true;
|
||||
sender = config.numbus-server.mail.fromAddress;
|
||||
recipient = "${config.numbus-server.mail.userAddress},${config.numbus-server.mail.adminAddress}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.mail;
|
||||
in
|
||||
|
||||
{
|
||||
options.numbus.mail = {
|
||||
enable = mkEnableOption "Email sending functionality";
|
||||
|
||||
userAddress = mkOption {
|
||||
description = "The address of the user this server will send emails to";
|
||||
type = types.str;
|
||||
example = "user@your-domain.com";
|
||||
};
|
||||
|
||||
adminAddress = mkOption {
|
||||
description = "The address of the admin this server will send emails to";
|
||||
type = types.str;
|
||||
example = "admin@your-domain.com";
|
||||
};
|
||||
|
||||
smtpUsername = mkOption {
|
||||
description = "The username/email that will be use to authenticate to the SMTP server";
|
||||
type = types.str;
|
||||
example = "your-smtp-enabled-address@your-domain.com";
|
||||
};
|
||||
|
||||
smtpPasswordPath = mkOption {
|
||||
description = "The path to a file containing the password that will be use to authenticate to the SMTP server";
|
||||
type = types.path;
|
||||
example = /run/secrets/system/mail/smtpPassword;
|
||||
};
|
||||
|
||||
fromAddress = mkOption {
|
||||
description = "This server will send emails from this address";
|
||||
type = types.str;
|
||||
default = "numbus-server-noreply@${config.numbus.services.domain}";
|
||||
example = "numbus-server-noreply@your-domain.com";
|
||||
};
|
||||
|
||||
smtpServer = mkOption {
|
||||
description = "The SMTP server address your server will use to send emails";
|
||||
type = types.str;
|
||||
default = "smtp.gmail.com";
|
||||
example = "smtp.your-provider.com";
|
||||
};
|
||||
|
||||
smtpPort = mkOption {
|
||||
description = "The SMTP port your server will connect to to send emails";
|
||||
type = types.port;
|
||||
default = 587;
|
||||
example = 587;
|
||||
};
|
||||
|
||||
smtpEncryption = mkOption {
|
||||
description = "The encryption method for SMTP : NONE (NOT RECOMMENDED), TLS (port 465, also called SSL), or STARTTLS (port 587). STARTTLS is recommended.";
|
||||
type = types.enum [ "NONE" "TLS" "STARTTLS" ];
|
||||
default = "STARTTLS";
|
||||
example = "STARTTLS";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
sops.secrets."smtpPassword" = {
|
||||
sopsFile = /etc/nixos/secrets/system/mail.yaml;
|
||||
owner = "numbus-admin";
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
environment.etc."aliases" ={
|
||||
mode = "0440";
|
||||
text = ''
|
||||
root: ${cfg.userAddress}, ${cfg.adminAddress}
|
||||
'';
|
||||
};
|
||||
|
||||
programs.msmtp = {
|
||||
enable = true;
|
||||
defaults = {
|
||||
aliases = "/etc/aliases";
|
||||
timeout = 60;
|
||||
syslog = "on";
|
||||
};
|
||||
accounts.default = {
|
||||
auth = true;
|
||||
host = cfg.smtpServer;
|
||||
port = cfg.smtpPort;
|
||||
from = cfg.fromAddress;
|
||||
user = cfg.smtpUsername;
|
||||
tls = true;
|
||||
tls_starttls = true;
|
||||
passwordeval = "${pkgs.coreutils}/bin/cat ${cfg.smtpPasswordPath}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{ config, deviceType, ... }:
|
||||
|
||||
{
|
||||
config = mkIf (deviceType == "computer" || deviceType == "tv" ) {
|
||||
# Enable sound with pipewire.
|
||||
services.pulseaudio.enable = false;
|
||||
security.rtkit.enable = true;
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
# To test
|
||||
./audio.nix
|
||||
./internationalisation.nix
|
||||
./power.nix
|
||||
./printer.nix
|
||||
./update.nix
|
||||
./users.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.numbus.internationalization;
|
||||
in
|
||||
|
||||
{
|
||||
config = {
|
||||
i18n.defaultLocale = "${cfg.locale}.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_ADDRESS = "${cfg.locale}.UTF-8";
|
||||
LC_IDENTIFICATION = "${cfg.locale}.UTF-8";
|
||||
LC_MEASUREMENT = "${cfg.locale}.UTF-8";
|
||||
LC_MONETARY = "${cfg.locale}.UTF-8";
|
||||
LC_NAME = "${cfg.locale}.UTF-8";
|
||||
LC_NUMERIC = "${cfg.locale}.UTF-8";
|
||||
LC_PAPER = "${cfg.locale}.UTF-8";
|
||||
LC_TELEPHONE = "${cfg.locale}.UTF-8";
|
||||
LC_TIME = "${cfg.locale}.UTF-8";
|
||||
};
|
||||
|
||||
console.keyMap = toLower cfg.language;
|
||||
services.xserver.xkb = {
|
||||
layout = toLower cfg.language;
|
||||
variant = "";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
services.autoaspm.enable = true;
|
||||
powerManagement.powertop.enable = true;
|
||||
boot.kernelParams = [
|
||||
"pcie_aspm=force"
|
||||
"consoleblank=60"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
config = mkIf (deviceType == "computer" || deviceType == "tv" ) {
|
||||
# Enable CUPS to print documents.
|
||||
services.printing.enable = true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{ config, inputs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
allowReboot = false;
|
||||
flake = inputs.self.outPath;
|
||||
flags = [ "--print-build-logs" ];
|
||||
dates = "02:00";
|
||||
randomizedDelaySec = "45min";
|
||||
};
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
nix.settings.auto-optimise-store = true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.numbus;
|
||||
in
|
||||
|
||||
{
|
||||
users.users.numbus-admin = {
|
||||
shell = pkgs.fish;
|
||||
isNormalUser = true;
|
||||
description = cfg.owner;
|
||||
extraGroups = [ "wheel" ];
|
||||
uid = 1000;
|
||||
initialPassword = "changeMe!";
|
||||
# required for auto start before user login
|
||||
linger = true;
|
||||
# required for rootless container with multiple users
|
||||
autoSubUidGidRange = true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
# To test
|
||||
./fail2ban.nix
|
||||
./flatpaks.nix
|
||||
./numbus-cli.nix
|
||||
./ssh.nix
|
||||
./terminal.nix
|
||||
./updates.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.fail2ban.enable = true;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
config = mkIf (services.flatpak.packages != []) {
|
||||
services.flatpak.enable = true;
|
||||
services.flatpak.update.auto.enable = true;
|
||||
services.flatpak.uninstallUnmanaged = true;
|
||||
|
||||
services.flatpak.remotes = mkOptionDefault [{
|
||||
name = "flathub";
|
||||
location = "https://dl.flathub.org/repo/flathub.flatpakrepo";
|
||||
}];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
{ pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
# Base script header and common setup for all device types
|
||||
baseScriptHeader = ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# The device type is baked into the script at build time
|
||||
readonly NUMBUS_DEVICE_TYPE="${deviceType}"
|
||||
|
||||
# Common utility function for consistent output
|
||||
numbus_echo() {
|
||||
echo "[Numbus CLI - $NUMBUS_DEVICE_TYPE] $*"
|
||||
}
|
||||
'';
|
||||
|
||||
# --- Device-specific script definitions ---
|
||||
|
||||
serverScript = baseScriptHeader + ''
|
||||
case "$1" in
|
||||
test)
|
||||
numbus_echo "Hello World! This is a Numbus Server."
|
||||
;;
|
||||
status)
|
||||
numbus_echo "Checking system status for Server..."
|
||||
numbus_echo "--- Podman Containers ---"
|
||||
podman ps || numbus_echo "No Podman containers found or Podman not running."
|
||||
systemctl list-units --type=service "numbus-*" --no-pager || numbus_echo "No Numbus services found."
|
||||
;;
|
||||
upgrade)
|
||||
numbus_echo "Pulling latest configuration and upgrading for Server..."
|
||||
# Add server-specific upgrade logic here (e.g., nixos-rebuild switch)
|
||||
;;
|
||||
*)
|
||||
numbus_echo "Numbus CLI (Server edition)"
|
||||
echo ""
|
||||
echo "Usage: numbus <command>"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " test - Print a test message"
|
||||
numbus_echo " status - Show status of Numbus services (Podman, systemd)"
|
||||
numbus_echo " upgrade - Upgrade the server configuration"
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
backupScript = baseScriptHeader + ''
|
||||
case "$1" in
|
||||
test)
|
||||
numbus_echo "Hello World! This is a Numbus Backup Server."
|
||||
;;
|
||||
status)
|
||||
numbus_echo "Checking system status for Backup Server..."
|
||||
systemctl list-units --type=service "numbus-*" --no-pager || numbus_echo "No Numbus services found."
|
||||
# Add backup-specific status checks here (e.g., SnapRAID status, rsync jobs)
|
||||
;;
|
||||
restore)
|
||||
numbus_echo "Starting interactive restore wizard for Backup Server..."
|
||||
# Add backup-specific restore logic here
|
||||
;;
|
||||
upgrade)
|
||||
numbus_echo "Pulling latest configuration and upgrading for Backup Server..."
|
||||
# Add backup-specific upgrade logic here
|
||||
;;
|
||||
*)
|
||||
numbus_echo "Numbus CLI (Backup Server edition)"
|
||||
echo ""
|
||||
echo "Usage: numbus <command>"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
numbus_echo " test - Print a test message"
|
||||
numbus_echo " status - Show status of Numbus services"
|
||||
numbus_echo " restore - Start interactive restore wizard"
|
||||
numbus_echo " upgrade - Upgrade the backup server configuration"
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
computerScript = baseScriptHeader + ''
|
||||
case "$1" in
|
||||
test)
|
||||
numbus_echo "Hello World! This is a Numbus Computer."
|
||||
;;
|
||||
status)
|
||||
numbus_echo "Checking system status for Computer..."
|
||||
systemctl list-units --type=service "numbus-*" --no-pager || numbus_echo "No Numbus services found."
|
||||
# Add computer-specific status checks (e.g., GPU status, Flatpak updates)
|
||||
;;
|
||||
upgrade)
|
||||
numbus_echo "Pulling latest configuration and upgrading for Computer..."
|
||||
# Add computer-specific upgrade logic here
|
||||
;;
|
||||
*)
|
||||
numbus_echo "Numbus CLI (Computer edition)"
|
||||
echo ""
|
||||
echo "Usage: numbus <command>"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
numbus_echo " test - Print a test message"
|
||||
numbus_echo " status - Show status of Numbus services"
|
||||
numbus_echo " upgrade - Upgrade the computer configuration"
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
tvScript = baseScriptHeader + ''
|
||||
case "$1" in
|
||||
test)
|
||||
numbus_echo "Hello World! This is a Numbus TV."
|
||||
;;
|
||||
status)
|
||||
numbus_echo "Checking system status for TV..."
|
||||
systemctl list-units --type=service "numbus-*" --no-pager || numbus_echo "No Numbus services found."
|
||||
# Add TV-specific status checks (e.g., media server status, remote connectivity)
|
||||
;;
|
||||
remote)
|
||||
numbus_echo "Pairing a new Bluetooth remote for TV..."
|
||||
# Add TV-specific remote pairing logic here
|
||||
;;
|
||||
upgrade)
|
||||
numbus_echo "Pulling latest configuration and upgrading for TV..."
|
||||
# Add TV-specific upgrade logic here
|
||||
;;
|
||||
*)
|
||||
numbus_echo "Numbus CLI (TV edition)"
|
||||
echo ""
|
||||
echo "Usage: numbus <command>"
|
||||
echo ""
|
||||
numbus_echo "Commands:"
|
||||
numbus_echo " test - Print a test message"
|
||||
numbus_echo " status - Show status of Numbus services"
|
||||
numbus_echo " remote - Pair a new Bluetooth remote"
|
||||
numbus_echo " upgrade - Upgrade the TV configuration"
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
|
||||
# Use lib.switch to select the correct script based on deviceType
|
||||
selectedScript = lib.switch deviceType {
|
||||
server = serverScript;
|
||||
backup = backupScript;
|
||||
computer = computerScript;
|
||||
tv = tvScript;
|
||||
} (throw "Unknown Numbus device type: ${deviceType}"); # Fail if an unknown deviceType is encountered
|
||||
|
||||
# Define the numbus-cli package using the selected script
|
||||
numbus = pkgs.writeShellScriptBin "numbus" selectedScript;
|
||||
|
||||
in {
|
||||
environment.systemPackages = [ numbus ];
|
||||
|
||||
# Add a useful alias so people can check the type via env
|
||||
environment.variables.NUMBUS_DEVICE_TYPE = deviceType;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
config.services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
KbdInteractiveAuthentication = false;
|
||||
PermitRootLogin = "no";
|
||||
};
|
||||
AllowUsers = [ "numbus-admin" ];
|
||||
ports = [ 245 ]
|
||||
};
|
||||
|
||||
config.sops.secrets."authorizedSshPublicKeys" = {
|
||||
sopsFile = /etc/nixos/secrets/system/ssh.yaml;
|
||||
mode = "0440";
|
||||
owner = "numbus-admin";
|
||||
path = "/home/numbus-admin/.ssh/authorized_keys";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
fish
|
||||
fishPlugins.fzf-fish
|
||||
fishPlugins.grc
|
||||
grc
|
||||
fzf
|
||||
];
|
||||
|
||||
programs.fish = {
|
||||
enable = true;
|
||||
interactiveShellInit = ''
|
||||
set fish_greeting # Disable greeting
|
||||
fastfetch
|
||||
echo -e "\n\nWelcome to Numbus !\n\n- This system is managed by NixOS\n- All changes are futile\n- Please consider buying support to get assistance\n- Have a nice day and enjoy !"
|
||||
'';
|
||||
shellAliases = {
|
||||
nixup = "cd /etc/nixos/ && sudo nix flake update && sudo nixos-rebuild --flake . switch --upgrade && cd -";
|
||||
nixwitch = "cd /etc/nixos/ && sudo nix flake update && sudo nixos-rebuild --flake . switch && cd -";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{ config, inputs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
allowReboot = false;
|
||||
flake = inputs.self.outPath;
|
||||
flags = [ "--print-build-logs" ];
|
||||
dates = "21:00";
|
||||
randomizedDelaySec = "45min";
|
||||
};
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
nix.settings.auto-optimise-store = true;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user