mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 13:03:13 +02:00
feat(nix): add arch parity proof-of-concept modules
This commit is contained in:
parent
cbf587c832
commit
0fa473ef0c
28
linux_configuration/nix-poc/configuration.nix
Normal file
28
linux_configuration/nix-poc/configuration.nix
Normal file
@ -0,0 +1,28 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./modules/arch-parity-poc.nix
|
||||
];
|
||||
|
||||
linuxConfigPoc = {
|
||||
enable = true;
|
||||
mainUser = "kuhy";
|
||||
|
||||
# Turn this on when you intentionally want to run the original imperative
|
||||
# shell installers during activation (hosts install + guard setup, etc.).
|
||||
# Keep it off by default for safe evaluation and incremental migration.
|
||||
enableImperativeBootstrap = false;
|
||||
};
|
||||
|
||||
# Minimal baseline the host config still needs while this remains a POC.
|
||||
networking.hostName = "arch-parity-poc";
|
||||
time.timeZone = "Europe/Warsaw";
|
||||
|
||||
# Convenience tools for verification/debugging during migration.
|
||||
environment.systemPackages = with pkgs; [
|
||||
git
|
||||
jq
|
||||
];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
24
linux_configuration/nix-poc/flake.nix
Normal file
24
linux_configuration/nix-poc/flake.nix
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
description = "NixOS proof-of-concept for linux_configuration parity";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, home-manager, ... }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
in {
|
||||
nixosConfigurations.arch-parity-poc = nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [
|
||||
home-manager.nixosModules.home-manager
|
||||
./configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
12
linux_configuration/nix-poc/modules/arch-parity-poc.nix
Normal file
12
linux_configuration/nix-poc/modules/arch-parity-poc.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./arch-parity/options.nix
|
||||
./arch-parity/packages.nix
|
||||
./arch-parity/report.nix
|
||||
./arch-parity/desktop.nix
|
||||
./arch-parity/system-maintenance.nix
|
||||
./arch-parity/hosts-guards.nix
|
||||
./arch-parity/bootstrap.nix
|
||||
];
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
repo = toString cfg.repoPath;
|
||||
in {
|
||||
config = lib.mkIf (cfg.enable && cfg.enableImperativeBootstrap) {
|
||||
system.activationScripts.linuxConfigImperativeBootstrap = {
|
||||
text = ''
|
||||
echo "[linuxConfigPoc] Running imperative bootstrap scripts"
|
||||
bash ${repo}/hosts/install.sh || true
|
||||
bash ${repo}/hosts/guard/setup_hosts_guard.sh || true
|
||||
bash ${repo}/scripts/setup_periodic_system.sh || true
|
||||
'';
|
||||
deps = [ "users" "groups" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
20
linux_configuration/nix-poc/modules/arch-parity/desktop.nix
Normal file
20
linux_configuration/nix-poc/modules/arch-parity/desktop.nix
Normal file
@ -0,0 +1,20 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.xserver.enable = true;
|
||||
services.xserver.windowManager.i3.enable = true;
|
||||
services.xserver.displayManager.startx.enable = true;
|
||||
|
||||
# Mirror i3 + i3blocks config deployment using Home Manager.
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.${cfg.mainUser} = {
|
||||
xdg.configFile."i3/config".source = "${cfg.repoPath}/i3-configuration/i3/config";
|
||||
xdg.configFile."i3blocks/config".source = "${cfg.repoPath}/i3-configuration/i3blocks/config";
|
||||
xdg.configFile."i3blocks".recursive = true;
|
||||
xdg.configFile."i3blocks".source = "${cfg.repoPath}/i3-configuration/i3blocks";
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
repo = toString cfg.repoPath;
|
||||
commonScriptPath = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
findutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
util-linux
|
||||
];
|
||||
|
||||
customHostsEntries = pkgs.runCommand "linux-config-custom-hosts" { } ''
|
||||
sed -n '/^# Custom blocking entries$/,/^EOF$/p' ${cfg.repoPath}/hosts/install.sh \
|
||||
| sed '$d' > "$out"
|
||||
'';
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
networking.extraHosts = builtins.readFile customHostsEntries;
|
||||
|
||||
# Protect hosts lookup ordering against bypasses.
|
||||
system.nssDatabases.hosts = [ "files" "myhostname" "dns" ];
|
||||
|
||||
systemd.services.hosts-guard = {
|
||||
description = "Enforce canonical /etc/hosts contents";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${repo}/hosts/guard/enforce-hosts.sh";
|
||||
Nice = "10";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.paths.hosts-guard = {
|
||||
description = "Watch /etc/hosts and trigger enforcement";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
pathConfig = {
|
||||
PathChanged = [ "/etc/hosts" ];
|
||||
Unit = "hosts-guard.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.nsswitch-guard = {
|
||||
description = "Enforce canonical /etc/nsswitch.conf (prevents hosts bypass)";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${repo}/hosts/guard/enforce-nsswitch.sh";
|
||||
Nice = "10";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.paths.nsswitch-guard = {
|
||||
description = "Watch /etc/nsswitch.conf for tampering";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
pathConfig = {
|
||||
PathChanged = [ "/etc/nsswitch.conf" ];
|
||||
Unit = "nsswitch-guard.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.resolved-guard = {
|
||||
description = "Enforce canonical /etc/systemd/resolved.conf (prevents hosts bypass)";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${repo}/hosts/guard/enforce-resolved.sh";
|
||||
Nice = "10";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.paths.resolved-guard = {
|
||||
description = "Watch /etc/systemd/resolved.conf for tampering";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
pathConfig = {
|
||||
PathChanged = [ "/etc/systemd/resolved.conf" "/etc/systemd/resolved.conf.d" ];
|
||||
Unit = "resolved-guard.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
117
linux_configuration/nix-poc/modules/arch-parity/options.nix
Normal file
117
linux_configuration/nix-poc/modules/arch-parity/options.nix
Normal file
@ -0,0 +1,117 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.linuxConfigPoc = {
|
||||
enable = lib.mkEnableOption "Arch linux_configuration parity proof-of-concept";
|
||||
|
||||
repoPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = ../../..;
|
||||
description = "Path to the linux_configuration repository root.";
|
||||
};
|
||||
|
||||
mainUser = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "kuhy";
|
||||
description = "Primary desktop username for user-scoped config (i3/i3blocks).";
|
||||
};
|
||||
|
||||
enableImperativeBootstrap = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Run original shell installers at activation (hosts + guard + periodic setup).";
|
||||
};
|
||||
|
||||
enableResolutionReport = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Generate a package resolution report grouped by migration category.";
|
||||
};
|
||||
|
||||
resolutionReportEtcPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "linux-config-poc/package-resolution-report.txt";
|
||||
description = "Path under /etc where the package resolution report is materialized.";
|
||||
};
|
||||
|
||||
enableResolutionReportJson = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Generate a machine-readable JSON package resolution report.";
|
||||
};
|
||||
|
||||
resolutionReportJsonEtcPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "linux-config-poc/package-resolution-report.json";
|
||||
description = "Path under /etc where the JSON package resolution report is materialized.";
|
||||
};
|
||||
|
||||
packageMap = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = {
|
||||
# Fonts / desktop
|
||||
"ttf-dejavu" = "dejavu_fonts";
|
||||
"noto-fonts" = "noto-fonts";
|
||||
"ttf-font-awesome" = "font-awesome";
|
||||
"adobe-source-sans-pro-fonts" = "source-sans";
|
||||
"ttf-liberation" = "liberation_ttf";
|
||||
|
||||
# Toolchain / language ecosystems
|
||||
"go-tools" = "gotools";
|
||||
"cargo" = "cargo";
|
||||
"rust" = "rustc";
|
||||
"nodejs" = "nodejs";
|
||||
"npm" = "nodejs";
|
||||
"yarn" = "yarn";
|
||||
"node-gyp" = "nodePackages.node-gyp";
|
||||
"lua52" = "lua5_2";
|
||||
|
||||
# Python package translations
|
||||
"python-nose" = "python3Packages.nose";
|
||||
"python-pyproject-metadata" = "python3Packages.pyproject-metadata";
|
||||
"meson-python" = "python3Packages.meson-python";
|
||||
"python-numpy" = "python3Packages.numpy";
|
||||
"python-markdown" = "python3Packages.markdown";
|
||||
"python-pyparsing" = "python3Packages.pyparsing";
|
||||
"python-pyqt5" = "python3Packages.pyqt5";
|
||||
"python-pefile" = "python3Packages.pefile";
|
||||
"python-booleanoperations" = "python3Packages.booleanoperations";
|
||||
"python-brotli" = "python3Packages.brotli";
|
||||
"python-defcon" = "python3Packages.defcon";
|
||||
"python-fontmath" = "python3Packages.fontmath";
|
||||
"python-fontpens" = "python3Packages.fontpens";
|
||||
"python-fonttools" = "python3Packages.fonttools";
|
||||
"python-fs" = "python3Packages.fs";
|
||||
"python-tqdm" = "python3Packages.tqdm";
|
||||
"python-unicodedata2" = "python3Packages.unicodedata2";
|
||||
"python-zopfli" = "python3Packages.zopfli";
|
||||
"python-pyaml" = "python3Packages.pyyaml";
|
||||
|
||||
# Java / Perl
|
||||
"java-hamcrest" = "hamcrest";
|
||||
"perl-font-ttf" = "perlPackages.FontTTF";
|
||||
"perl-sort-versions" = "perlPackages.SortVersions";
|
||||
|
||||
# Multimedia / desktop mismatches
|
||||
"pavucontrol-qt" = "pavucontrol";
|
||||
"qt5-wayland" = "qt5.qtwayland";
|
||||
"qt6-tools" = "qt6.full";
|
||||
"qt6-shadertools" = "qt6.qtshadertools";
|
||||
"ffmpeg" = "ffmpeg-full";
|
||||
"pyside6" = "python3Packages.pyside6";
|
||||
|
||||
# TeX stack consolidation
|
||||
"texlive-plaingeneric" = "texliveFull";
|
||||
"texlive-latexextra" = "texliveFull";
|
||||
"texlive-bibtexextra" = "texliveFull";
|
||||
"texlive-pictures" = "texliveFull";
|
||||
"texlive-fontsextra" = "texliveFull";
|
||||
"texlive-formatsextra" = "texliveFull";
|
||||
"texlive-pstricks" = "texliveFull";
|
||||
"texlive-games" = "texliveFull";
|
||||
"texlive-humanities" = "texliveFull";
|
||||
"texlive-science" = "texliveFull";
|
||||
};
|
||||
description = "Mapping from Arch package names to nixpkgs attributes.";
|
||||
};
|
||||
};
|
||||
}
|
||||
55
linux_configuration/nix-poc/modules/arch-parity/packages.nix
Normal file
55
linux_configuration/nix-poc/modules/arch-parity/packages.nix
Normal file
@ -0,0 +1,55 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
|
||||
readList = file:
|
||||
let
|
||||
lines = lib.splitString "\n" (builtins.readFile file);
|
||||
trimmed = map lib.strings.trim lines;
|
||||
in
|
||||
builtins.filter (line: line != "" && !(lib.hasPrefix "#" line)) trimmed;
|
||||
|
||||
pacmanPackageFile = "${toString cfg.repoPath}/fresh-install/pacman_packages.txt";
|
||||
aurPackageFile = "${toString cfg.repoPath}/fresh-install/aur_packages.txt";
|
||||
|
||||
pacmanNamesRaw = readList pacmanPackageFile;
|
||||
aurLinesRaw = readList aurPackageFile;
|
||||
aurNames = map (line: builtins.head (lib.splitString " " line)) aurLinesRaw;
|
||||
|
||||
mappedPacmanNames = map
|
||||
(name: if builtins.hasAttr name cfg.packageMap then builtins.getAttr name cfg.packageMap else name)
|
||||
pacmanNamesRaw;
|
||||
|
||||
resolvePackage = name: lib.attrByPath (lib.splitString "." name) null pkgs;
|
||||
|
||||
resolvedPacmanPkgs = builtins.filter (pkg: pkg != null) (map resolvePackage mappedPacmanNames);
|
||||
missingPacmanPkgs = builtins.filter (name: (resolvePackage name) == null) mappedPacmanNames;
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
warnings = [
|
||||
"linuxConfigPoc: ${toString (builtins.length resolvedPacmanPkgs)} pacman packages resolved to nixpkgs attrs."
|
||||
"linuxConfigPoc: ${toString (builtins.length missingPacmanPkgs)} pacman packages still need mapping/overlays."
|
||||
"linuxConfigPoc: ${toString (builtins.length aurNames)} AUR packages detected and not yet represented as Nix derivations."
|
||||
"linuxConfigPoc: pacman-wrapper policy/challenges remain imperative scripts; full Nix-native equivalent requires dedicated policy module."
|
||||
];
|
||||
|
||||
environment.systemPackages =
|
||||
lib.unique (
|
||||
(with pkgs; [
|
||||
acpi
|
||||
bc
|
||||
dex
|
||||
i3blocks
|
||||
i3lock
|
||||
i3status
|
||||
iw
|
||||
jq
|
||||
networkmanagerapplet
|
||||
pavucontrol
|
||||
terminator
|
||||
xss-lock
|
||||
])
|
||||
++ resolvedPacmanPkgs
|
||||
);
|
||||
};
|
||||
}
|
||||
169
linux_configuration/nix-poc/modules/arch-parity/report.nix
Normal file
169
linux_configuration/nix-poc/modules/arch-parity/report.nix
Normal file
@ -0,0 +1,169 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
|
||||
readList = file:
|
||||
let
|
||||
lines = lib.splitString "\n" (builtins.readFile file);
|
||||
trimmed = map lib.strings.trim lines;
|
||||
in
|
||||
builtins.filter (line: line != "" && !(lib.hasPrefix "#" line)) trimmed;
|
||||
|
||||
pacmanPackageFile = "${toString cfg.repoPath}/fresh-install/pacman_packages.txt";
|
||||
aurPackageFile = "${toString cfg.repoPath}/fresh-install/aur_packages.txt";
|
||||
|
||||
pacmanNamesRaw = readList pacmanPackageFile;
|
||||
aurLinesRaw = readList aurPackageFile;
|
||||
aurNames = map (line: builtins.head (lib.splitString " " line)) aurLinesRaw;
|
||||
|
||||
resolvePackage = path: lib.attrByPath (lib.splitString "." path) null pkgs;
|
||||
existsPath = path: (resolvePackage path) != null;
|
||||
|
||||
mappedRecords = map
|
||||
(original:
|
||||
let
|
||||
mapped = if builtins.hasAttr original cfg.packageMap then builtins.getAttr original cfg.packageMap else original;
|
||||
in {
|
||||
inherit original mapped;
|
||||
resolved = (resolvePackage mapped) != null;
|
||||
})
|
||||
pacmanNamesRaw;
|
||||
|
||||
unresolvedRecords = builtins.filter (record: !record.resolved) mappedRecords;
|
||||
|
||||
sortStrings = builtins.sort (a: b: a < b);
|
||||
sortRecordsByOriginal = builtins.sort (
|
||||
a: b:
|
||||
if a.original == b.original
|
||||
then a.mapped < b.mapped
|
||||
else a.original < b.original
|
||||
);
|
||||
|
||||
candidatePaths = record:
|
||||
let
|
||||
pythonCandidate =
|
||||
if lib.hasPrefix "python-" record.original
|
||||
then "python3Packages.${lib.removePrefix "python-" record.original}"
|
||||
else "";
|
||||
underscoreFromOriginal = lib.replaceStrings [ "-" ] [ "_" ] record.original;
|
||||
dashFromOriginal = lib.replaceStrings [ "_" ] [ "-" ] record.original;
|
||||
underscoreFromMapped = lib.replaceStrings [ "-" ] [ "_" ] record.mapped;
|
||||
dashFromMapped = lib.replaceStrings [ "_" ] [ "-" ] record.mapped;
|
||||
candidates = [
|
||||
record.original
|
||||
record.mapped
|
||||
underscoreFromOriginal
|
||||
dashFromOriginal
|
||||
underscoreFromMapped
|
||||
dashFromMapped
|
||||
pythonCandidate
|
||||
];
|
||||
in
|
||||
lib.unique (builtins.filter (candidate: candidate != "") candidates);
|
||||
|
||||
easySuggestions = record:
|
||||
builtins.filter
|
||||
(candidate: existsPath candidate)
|
||||
(candidatePaths record);
|
||||
easySuggestionsSorted = record: sortStrings (easySuggestions record);
|
||||
|
||||
isAurOrOverlayLikely = record:
|
||||
(builtins.elem record.original aurNames)
|
||||
|| (lib.hasSuffix "-git" record.original)
|
||||
|| (lib.hasPrefix "lib32-" record.original)
|
||||
|| (lib.hasSuffix "-bin" record.original);
|
||||
|
||||
easyMapRecords = builtins.filter (record: (builtins.length (easySuggestions record)) > 0) unresolvedRecords;
|
||||
needsOverlayRecords = builtins.filter
|
||||
(record: ((builtins.length (easySuggestions record)) == 0) && (isAurOrOverlayLikely record))
|
||||
unresolvedRecords;
|
||||
likelyUnavailableRecords = builtins.filter
|
||||
(record: ((builtins.length (easySuggestions record)) == 0) && !(isAurOrOverlayLikely record))
|
||||
unresolvedRecords;
|
||||
|
||||
easyMapRecordsSorted = sortRecordsByOriginal easyMapRecords;
|
||||
needsOverlayRecordsSorted = sortRecordsByOriginal needsOverlayRecords;
|
||||
likelyUnavailableRecordsSorted = sortRecordsByOriginal likelyUnavailableRecords;
|
||||
aurNamesSorted = sortStrings aurNames;
|
||||
|
||||
formatSimpleRecord = record: "- ${record.original} -> ${record.mapped}";
|
||||
formatEasyRecord = record:
|
||||
"- ${record.original} -> ${record.mapped} | suggestions: ${lib.concatStringsSep ", " (easySuggestionsSorted record)}";
|
||||
|
||||
renderLines = lines:
|
||||
if (builtins.length lines) == 0
|
||||
then "- none"
|
||||
else lib.concatStringsSep "\n" lines;
|
||||
|
||||
toEasyJsonRecord = record: {
|
||||
original = record.original;
|
||||
mapped = record.mapped;
|
||||
suggestions = easySuggestionsSorted record;
|
||||
};
|
||||
|
||||
toSimpleJsonRecord = record: {
|
||||
original = record.original;
|
||||
mapped = record.mapped;
|
||||
};
|
||||
|
||||
reportText = ''
|
||||
linux_configuration nix-poc package resolution report
|
||||
================================================
|
||||
|
||||
Source files:
|
||||
- ${pacmanPackageFile}
|
||||
- ${aurPackageFile}
|
||||
|
||||
Summary:
|
||||
- Total pacman package entries: ${toString (builtins.length pacmanNamesRaw)}
|
||||
- Unresolved pacman entries after current mapping: ${toString (builtins.length unresolvedRecords)}
|
||||
- AUR package entries: ${toString (builtins.length aurNames)}
|
||||
|
||||
Category: easy-map (likely solvable by small mapping/path fixes)
|
||||
---------------------------------------------------------------
|
||||
${renderLines (map formatEasyRecord easyMapRecordsSorted)}
|
||||
|
||||
Category: needs-overlay (AUR/multilib/git/bin packages)
|
||||
-------------------------------------------------------
|
||||
${renderLines (map formatSimpleRecord needsOverlayRecordsSorted)}
|
||||
|
||||
Category: likely-unavailable (needs manual investigation)
|
||||
---------------------------------------------------------
|
||||
${renderLines (map formatSimpleRecord likelyUnavailableRecordsSorted)}
|
||||
|
||||
AUR inventory
|
||||
-------------
|
||||
${renderLines (map (name: "- ${name}") aurNamesSorted)}
|
||||
'';
|
||||
|
||||
reportJson = {
|
||||
schemaVersion = "1.0";
|
||||
sourceFiles = {
|
||||
pacman = pacmanPackageFile;
|
||||
aur = aurPackageFile;
|
||||
};
|
||||
summary = {
|
||||
pacmanEntries = builtins.length pacmanNamesRaw;
|
||||
unresolvedPacmanEntries = builtins.length unresolvedRecords;
|
||||
aurEntries = builtins.length aurNames;
|
||||
};
|
||||
categories = {
|
||||
easyMap = map toEasyJsonRecord easyMapRecordsSorted;
|
||||
needsOverlay = map toSimpleJsonRecord needsOverlayRecordsSorted;
|
||||
likelyUnavailable = map toSimpleJsonRecord likelyUnavailableRecordsSorted;
|
||||
};
|
||||
aurInventory = aurNamesSorted;
|
||||
};
|
||||
in {
|
||||
config = lib.mkIf (cfg.enable && cfg.enableResolutionReport) {
|
||||
warnings = [
|
||||
"linuxConfigPoc: package resolution report generated at /etc/${cfg.resolutionReportEtcPath}${lib.optionalString cfg.enableResolutionReportJson " and /etc/${cfg.resolutionReportJsonEtcPath}"}"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"${cfg.resolutionReportEtcPath}".text = reportText;
|
||||
} // lib.optionalAttrs cfg.enableResolutionReportJson {
|
||||
"${cfg.resolutionReportJsonEtcPath}".text = builtins.toJSON reportJson;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
repo = toString cfg.repoPath;
|
||||
commonScriptPath = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
procps
|
||||
util-linux
|
||||
];
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.periodic-system-maintenance = {
|
||||
description = "Periodic System Maintenance (Pacman Wrapper & Hosts File)";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/system-maintenance/bin/periodic-system-maintenance.sh";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
TimeoutStartSec = "300";
|
||||
TimeoutStopSec = "30";
|
||||
Restart = "no";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.timers.periodic-system-maintenance = {
|
||||
description = "Run Periodic System Maintenance every hour";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
OnBootSec = "5min";
|
||||
RandomizedDelaySec = "300";
|
||||
Persistent = true;
|
||||
};
|
||||
unitConfig = {
|
||||
Requires = "periodic-system-maintenance.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.periodic-system-startup = {
|
||||
description = "System Maintenance on Startup (Pacman Wrapper & Hosts File)";
|
||||
after = [ "network-online.target" "systemd-resolved.service" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/system-maintenance/bin/periodic-system-maintenance.sh";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
RemainAfterExit = true;
|
||||
TimeoutStartSec = "300";
|
||||
TimeoutStopSec = "30";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.services.hosts-file-monitor = {
|
||||
description = "Hosts File Monitor and Auto-Restore Service";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/system-maintenance/bin/hosts-file-monitor.sh";
|
||||
Restart = "always";
|
||||
RestartSec = "10";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
NoNewPrivileges = false;
|
||||
PrivateTmp = true;
|
||||
MemoryMax = "50M";
|
||||
CPUQuota = "10%";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.services.auto-system-update = {
|
||||
description = "Automatic System Update (pacman + yay AUR)";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/system-maintenance/bin/auto-system-update.sh";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
TimeoutStartSec = "1800";
|
||||
TimeoutStopSec = "30";
|
||||
Restart = "no";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.timers.auto-system-update = {
|
||||
description = "Run Automatic System Update daily";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:00:00";
|
||||
RandomizedDelaySec = "1800";
|
||||
Persistent = true;
|
||||
};
|
||||
unitConfig = {
|
||||
Requires = "auto-system-update.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user