a lot of shit also baibai home manager, hello hjem

This commit is contained in:
blahai 2025-01-26 20:11:01 +02:00
parent bc82345beb
commit 2c8f822b83
Signed by: blahai
SSH key fingerprint: SHA256:ZfCryi+V64yG+vC1ZIIsqgvBCmA31tTi7RJ6M8CvpRc
37 changed files with 1277 additions and 168 deletions

129
flake.lock generated
View file

@ -653,11 +653,11 @@
"nixvim": "nixvim" "nixvim": "nixvim"
}, },
"locked": { "locked": {
"lastModified": 1737764118, "lastModified": 1737850542,
"narHash": "sha256-+elvcDCY9iRqahLLV8Z7LQsk8gAHCXPAudfQtFclgvI=", "narHash": "sha256-TurdJgZWHT8F54qK1r6Dtolp8OAKlwodvcEeY649tv4=",
"owner": "blahai", "owner": "blahai",
"repo": "haivim", "repo": "haivim",
"rev": "3cd7a2f023b24b74ce89e415aed143d795e884ca", "rev": "413477b21b460ab20b027008acebc5da9c9e5e04",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -683,6 +683,49 @@
"type": "github" "type": "github"
} }
}, },
"hjem": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1737619027,
"narHash": "sha256-jEzZs9dHdmVP5X9HCC/7jrv08aWFfqZV5cZ+cZWYGA4=",
"owner": "feel-co",
"repo": "hjem",
"rev": "48cfa21987672a31a358b7e4d582fc174556e633",
"type": "github"
},
"original": {
"owner": "feel-co",
"repo": "hjem",
"type": "github"
}
},
"hjem-rum": {
"inputs": {
"hjem": [
"hjem"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1737833942,
"narHash": "sha256-7e9FxJkQwtiy9YhNOwLNhb4p2xFsaPAGiHMfTw+jGWk=",
"owner": "the-unnamed-nug",
"repo": "hjem-rum",
"rev": "81e8ff969415cbb3ad66c365eed40d9f1c2e2489",
"type": "github"
},
"original": {
"owner": "the-unnamed-nug",
"repo": "hjem-rum",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -733,26 +776,6 @@
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": {
"lastModified": 1737704314,
"narHash": "sha256-zta8jvOQ2wRCZmiwFEnS5iCulWAh8e+fLUlQxrgOBjM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "a0428685572b134f6594e7d7f5db5e1febbab2d7",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_4": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1737762889, "lastModified": 1737762889,
"narHash": "sha256-5HGG09bh/Yx0JA8wtBMAzt0HMCL1bYZ93x4IqzVExio=", "narHash": "sha256-5HGG09bh/Yx0JA8wtBMAzt0HMCL1bYZ93x4IqzVExio=",
@ -861,11 +884,11 @@
"xdph": "xdph" "xdph": "xdph"
}, },
"locked": { "locked": {
"lastModified": 1737842278, "lastModified": 1737907229,
"narHash": "sha256-5N0ExKra/jw3HI/0EEIzmeJKHN9RIBV7ceR/sxQR11s=", "narHash": "sha256-0onbAHBZQhdnIEl1lOxjp4VKNy69GR1K5K6hvxww4rs=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "Hyprland", "repo": "Hyprland",
"rev": "8b1d6e3009c540457068e23e6c2bc201d20ce4d1", "rev": "bb5b09def0645838456eb7eb1f52b471441acba1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1371,11 +1394,11 @@
}, },
"nixpkgs-smol": { "nixpkgs-smol": {
"locked": { "locked": {
"lastModified": 1737795611, "lastModified": 1737873842,
"narHash": "sha256-0kGPO515JdDt6gPcR25QTGyNJnT1UFtH1tdkR2QdLAY=", "narHash": "sha256-3SAvSPxkeOgECitk8fImL0gz+xa2m1I4mmwam6mymOM=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ed45d51fb4c860e70760a042dd9ff99bd016497e", "rev": "42143ec28c329664fd1337579067c156230beaf7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1403,11 +1426,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1737622296, "lastModified": 1737717945,
"narHash": "sha256-GWHH9ljsR0LR29IEruJnKVVk6veeQpo7kfolyDyCVGQ=", "narHash": "sha256-ET91TMkab3PmOZnqiJQYOtSGvSTvGeHoegAv4zcTefM=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "055c50feaa548eadca66407630961b77f3ebb750", "rev": "ecd26a469ac56357fd333946a99086e992452b6a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1494,11 +1517,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1737747541, "lastModified": 1737832569,
"narHash": "sha256-dA54OnUCUtVZfnSuD1dAEcosZzx/tch9KvtDz/Y3FIo=", "narHash": "sha256-VkK73VRVgvSQOPw9qx9HzvbulvUM9Ae4nNd3xNP+pkI=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixvim", "repo": "nixvim",
"rev": "5fda6e093da13f37c63a5577888a668c38f30dc7", "rev": "d7df58321110d3b0e12a829bbd110db31ccd34b1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1514,11 +1537,11 @@
"treefmt-nix": "treefmt-nix_3" "treefmt-nix": "treefmt-nix_3"
}, },
"locked": { "locked": {
"lastModified": 1737841565, "lastModified": 1737910157,
"narHash": "sha256-W2dAa+2c7UOKLDop9240ShxosBiWRRaYgGfswN/jz9o=", "narHash": "sha256-dCwM306WYNSEn70cy3AXSgWQzWWe4HpYV9JvkDTB6vg=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "83b5a10fa785f0924fae431ffdea2b12de23e789", "rev": "72076a2a2ab1764183d9ff9dd0e137882e424359",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1603,14 +1626,14 @@
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"git-hooks": "git-hooks", "git-hooks": "git-hooks",
"haivim": "haivim", "haivim": "haivim",
"home-manager": "home-manager_4", "hjem": "hjem",
"hjem-rum": "hjem-rum",
"hydra": "hydra", "hydra": "hydra",
"hyprland": "hyprland", "hyprland": "hyprland",
"lix-module": "lix-module", "lix-module": "lix-module",
"nixpkgs": "nixpkgs_5", "nixpkgs": "nixpkgs_5",
"nixpkgs-smol": "nixpkgs-smol", "nixpkgs-smol": "nixpkgs-smol",
"nur": "nur", "nur": "nur",
"sops-nix": "sops-nix",
"spicetify-nix": "spicetify-nix", "spicetify-nix": "spicetify-nix",
"systems": "systems_8", "systems": "systems_8",
"treefmt-nix": "treefmt-nix_4", "treefmt-nix": "treefmt-nix_4",
@ -1655,26 +1678,6 @@
"type": "github" "type": "github"
} }
}, },
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1737411508,
"narHash": "sha256-j9IdflJwRtqo9WpM0OfAZml47eBblUHGNQTe62OUqTw=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "015d461c16678fc02a2f405eb453abb509d4e1d4",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"spicetify-nix": { "spicetify-nix": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_4", "flake-compat": "flake-compat_4",
@ -1683,11 +1686,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1737778506, "lastModified": 1737864911,
"narHash": "sha256-kdqwOnk0jFb3E01HFqUFAW+NQuBp39uwrpWSXmFAKGs=", "narHash": "sha256-yQGyYTEDJreafvnHQvTvCHxmmqy77mrUyzJV1zr3XN0=",
"owner": "Gerg-L", "owner": "Gerg-L",
"repo": "spicetify-nix", "repo": "spicetify-nix",
"rev": "aeaa9b2fad9d658e8982a140327e345feffe8850", "rev": "b65b84d6b8e9cd59af6524f05a1972fbe6fecce5",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -46,11 +46,6 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
systems = { systems = {
url = "github:nix-systems/default"; url = "github:nix-systems/default";
}; };
@ -73,6 +68,16 @@
url = "github:tgirlcloud/easy-hosts"; url = "github:tgirlcloud/easy-hosts";
}; };
hjem = {
url = "github:feel-co/hjem";
inputs.nixpkgs.follows = "nixpkgs";
};
hjem-rum = {
url = "github:the-unnamed-nug/hjem-rum";
inputs.nixpkgs.follows = "nixpkgs";
inputs.hjem.follows = "hjem";
};
deploy-rs = { deploy-rs = {
url = "github:serokell/deploy-rs"; url = "github:serokell/deploy-rs";
inputs = { inputs = {
@ -89,10 +94,5 @@
flake-compat.follows = ""; flake-compat.follows = "";
}; };
}; };
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
} }

5
home/base/default.nix Normal file
View file

@ -0,0 +1,5 @@
{
imports = [
./programs
];
}

View file

@ -1,6 +1,7 @@
{ {
imports = [ imports = [
./shells.nix
./defaults.nix ./defaults.nix
./shells.nix
./top-level.nix
]; ];
} }

View file

@ -6,7 +6,6 @@ in {
shell = mkOption { shell = mkOption {
type = enum [ type = enum [
"bash" "bash"
"zsh"
"fish" "fish"
]; ];
default = "bash"; default = "bash";
@ -28,8 +27,9 @@ in {
"thunar" "thunar"
"dolphin" "dolphin"
"nemo" "nemo"
"nautilus"
]; ];
default = "cosmic-files"; default = "nautilus";
}; };
browser = mkOption { browser = mkOption {
@ -75,7 +75,7 @@ in {
]); ]);
default = "hyprlock"; default = "hyprlock";
description = '' description = ''
The lockscreen module to be loaded by home-manager. The lockscreen module to be loaded by hjem.
''; '';
}; };

View file

@ -0,0 +1,16 @@
{
lib,
pkgs,
...
}: let
inherit (lib.programs) mkProgram;
in {
options.olympus.programs = {
bash = mkProgram pkgs "bash" {
enable.default = true;
package.default = pkgs.bashInteractive;
};
fish = mkProgram pkgs "fish" {};
};
}

View file

@ -0,0 +1,32 @@
{
lib,
config,
...
}: let
inherit (lib.options) mkEnableOption;
cfg = config.olympus.programs;
in {
# these are options that will cause a mass rebuild by enabling multiple packages
options.olympus.programs = {
cli = {
enable =
mkEnableOption "Enable CLI programs"
// {
default = true;
};
modernShell.enable = mkEnableOption "Enable programs for a more modern shell";
};
tui.enable =
mkEnableOption "Enable TUI programs"
// {
default = cfg.cli.enable;
};
gui.enable = mkEnableOption "Enable GUI programs";
pentesting.enable = mkEnableOption "Enable packages designed for pentesting";
notes.enable = mkEnableOption "Enable note-taking programs";
};
}

View file

@ -9,37 +9,10 @@
}: let }: let
inherit (lib.modules) mkDefault; inherit (lib.modules) mkDefault;
inherit (lib.attrsets) genAttrs; inherit (lib.attrsets) genAttrs;
inherit (config.olympus.programs) defaults;
in { in {
home-manager = { hjem = {
verbose = true;
useUserPackages = true;
useGlobalPkgs = true;
backupFileExtension = "bak";
extraSpecialArgs = {
inherit
inputs
self
inputs'
self'
defaults
;
};
users = genAttrs config.olympus.system.users (name: ./${name}); users = genAttrs config.olympus.system.users (name: ./${name});
# we should define grauntied common modules here clobberByDefault = true;
sharedModules = [
{
home.stateVersion = config.system.stateVersion;
# reload system units when changing configs
systemd.user.startServices = mkDefault "sd-switch"; # or "legacy" if "sd-switch" breaks again
# let HM manage itself when in standalone mode
programs.home-manager.enable = true;
}
];
}; };
} }

View file

@ -1,6 +1,6 @@
{ {
imports = [ imports = [
./packages #./packages
./system #./system
]; ];
} }

View file

@ -1,5 +1,5 @@
{ {
osConfig, config,
lib, lib,
pkgs, pkgs,
... ...
@ -9,7 +9,7 @@ in {
home.packages = with pkgs; [ home.packages = with pkgs; [
neofetch neofetch
]; ];
programs = mkIf osConfig.olympus.programs.fish.enable { programs = mkIf config.olympus.programs.fish.enable {
fish = { fish = {
enable = true; enable = true;

View file

@ -4,5 +4,6 @@
./options ./options
./users ./users
./programs.nix ./programs.nix
./secrets.nix
]; ];
} }

View file

@ -21,6 +21,8 @@ in {
options = "--delete-older-than 3d"; options = "--delete-older-than 3d";
}; };
channel.enable = false;
# https://docs.lix.systems/manual/lix/nightly/command-ref/conf-file.html # https://docs.lix.systems/manual/lix/nightly/command-ref/conf-file.html
settings = { settings = {
# Free up to 20GiB whenever there is less than 5GB left. # Free up to 20GiB whenever there is less than 5GB left.
@ -41,10 +43,7 @@ in {
# we don't want to track the registry, but we do want to allow the usage # we don't want to track the registry, but we do want to allow the usage
# of the `flake:` references, so we need to enable use-registries # of the `flake:` references, so we need to enable use-registries
use-registries = true; use-registries = true;
flake-registry = pkgs.writers.writeJSON "flakes-empty.json" { flake-registry = "";
flakes = [];
version = 2;
};
# let the system decide the number of max jobs # let the system decide the number of max jobs
max-jobs = "auto"; max-jobs = "auto";
@ -70,7 +69,7 @@ in {
log-lines = 30; log-lines = 30;
# https://docs.lix.systems/manual/lix/nightly/contributing/experimental-features.html # https://docs.lix.systems/manual/lix/nightly/contributing/experimental-features.html
extra-experimental-features = [ experimental-features = [
# enables flakes, needed for this config # enables flakes, needed for this config
"flakes" "flakes"
@ -103,6 +102,9 @@ in {
# dependencies in derivations on the outputs of derivations that are themselves derivations outputs. # dependencies in derivations on the outputs of derivations that are themselves derivations outputs.
"dynamic-derivations" "dynamic-derivations"
# allow parsing TOML timestamps via builtins.fromTOML
"parse-toml-timestamps"
]; ];
# don't warn me if the current working tree is dirty # don't warn me if the current working tree is dirty

View file

@ -1,6 +1,6 @@
{ {
imports = [ imports = [
./device.nix ./device.nix
./programs ./meta.nix
]; ];
} }

View file

@ -0,0 +1,50 @@
{
lib,
config,
...
}: let
inherit (lib.trivial) id;
inherit (lib.options) mkOption;
inherit (lib.validators) anyHome;
inherit (lib.strings) concatStringsSep;
mkMetaOption = path:
mkOption {
default = anyHome config id path;
example = true;
description = "Does ${concatStringsSep "." path} meet the requirements";
type = lib.types.bool;
};
in {
options.olympus.meta = {
fish = mkMetaOption [
"olympus"
"programs"
"fish"
"enable"
];
thunar = mkMetaOption [
"olympus"
"programs"
"thunar"
"enable"
];
gui = mkMetaOption [
"olympus"
"programs"
"gui"
"enable"
];
isWayland = mkMetaOption [
"olympus"
"meta"
"isWayland"
];
isWM = mkMetaOption [
"olympus"
"meta"
"isWM"
];
};
}

View file

@ -1,26 +0,0 @@
{
lib,
pkgs,
...
}: let
inherit (lib.options) mkEnableOption mkPackageOption;
inherit (lib.attrsets) recursiveUpdate;
mkProgram = pkgs: name: extraConfig:
recursiveUpdate {
enable = mkEnableOption "Enable ${name}";
package = mkPackageOption pkgs name {};
}
extraConfig;
in {
options.olympus.programs = {
bash = mkProgram pkgs "bash" {
enable.default = true;
package.default = pkgs.bashInteractive;
};
zsh = mkProgram pkgs "zsh" {};
fish = mkProgram pkgs "fish" {};
};
}

View file

@ -1,18 +1,6 @@
{ {config, ...}: {
lib,
pkgs,
config,
...
}: let
inherit (lib.meta) getExe;
bashPrompt = ''
eval "$(${getExe pkgs.starship} init bash)"
'';
in {
# home-manager is so strange and needs these declared multiple times # home-manager is so strange and needs these declared multiple times
programs = { programs = {
fish.enable = config.olympus.programs.fish.enable; #fish.enable = config.olympus.meta.fish;
zsh.enable = config.olympus.programs.zsh.enable;
}; };
} }

20
modules/base/secrets.nix Normal file
View file

@ -0,0 +1,20 @@
{
config,
inputs,
...
}: let
inherit (config.olympus.system) mainUser;
#homeDir = config.home-manager.users.${mainUser}.home.homeDirectory;
homeDir = config.hjem.users.${mainUser}.directory;
sshDir = homeDir + "/.ssh";
in {
imports = [inputs.agenix.nixosModules.default];
age = {
# check the main users ssh key and the system key to see if it is safe
# to decrypt the secrets
identityPaths = [
"/etc/ssh/ssh_host_ed25519_key"
"${sshDir}/id_ed25519"
];
};
}

View file

@ -5,13 +5,12 @@
}: let }: let
inherit (lib.modules) mkDefault; inherit (lib.modules) mkDefault;
inherit (lib.attrsets) genAttrs; inherit (lib.attrsets) genAttrs;
inherit (builtins) filter hasAttr; inherit (lib.validators) ifTheyExist;
ifTheyExist = config: groups: filter (group: hasAttr group config.users.groups) groups;
in { in {
users.users = genAttrs config.olympus.system.users ( users.users = genAttrs config.olympus.system.users (
name: { name: {
home = "/home/" + name; home = "/home/" + name;
shell = config.olympus.programs.${config.olympus.programs.defaults.shell}.package; # shell = config.olympus.programs.${config.olympus.programs.defaults.shell}.package;
uid = mkDefault 1000; uid = mkDefault 1000;
isNormalUser = true; isNormalUser = true;
@ -28,14 +27,17 @@ in {
"networkmanager" "networkmanager"
"systemd-journal" "systemd-journal"
"audio" "audio"
"pipewire" "pipewire" # this give us access to the rt limits
"video" "video"
"input" "input"
"plugdev" "plugdev"
"lp"
"tss" "tss"
"power" "power"
"wireshark"
"mysql" "mysql"
"docker" "docker"
"podman"
"git" "git"
"libvirtd" "libvirtd"
"cloudflared" "cloudflared"

View file

@ -2,6 +2,7 @@
imports = [ imports = [
../../systems ../../systems
./programs ./programs
./lib
./args.nix ./args.nix
./overlays.nix ./overlays.nix

View file

@ -0,0 +1,55 @@
# following https://github.com/NixOS/nixpkgs/blob/77ee426a4da240c1df7e11f48ac6243e0890f03e/lib/default.nix
# as a rough template we can create our own extensible lib and expose it to the flake
# we can then use that elsewhere like our hosts
{inputs, ...}: let
lib0 = inputs.nixpkgs.lib;
olympusLib = lib0.makeExtensible (
self: let
lib = self;
in {
template = import ./template; # templates, selections of code that are repeated
helpers = import ./helpers.nix {inherit lib;};
programs = import ./programs.nix {inherit lib;};
secrets = import ./secrets.nix {inherit inputs;};
services = import ./services.nix {inherit lib;};
validators = import ./validators.nix {inherit lib;};
# we have to rexport the functions we want to use, but don't want to refer to the whole lib
# "path". e.g. lib.hardware.isx86Linux can be shortened to lib.isx86Linux
# NOTE: never rexport templates
inherit (self.builders) mkSystems;
inherit
(self.helpers)
mkPubs
giturl
filterNixFiles
importNixFiles
importNixFilesAndDirs
boolToNum
containsStrings
indexOf
intListToStringList
;
inherit (self.programs) mkProgram;
inherit (self.secrets) mkSecret mkSecretWithPath;
inherit (self.services) mkGraphicalService mkHyprlandService mkServiceOption;
inherit
(self.validators)
ifTheyExist
isAcceptedDevice
isWayland
ifOneEnabled
isModernShell
anyHome
;
}
);
# we need to extend olympusLib with the nixpkgs lib to get the full set of functions
# if we do it the otherway around we will get errors saying mkMerge and so on don't exist
finalLib = olympusLib.extend (_: _: lib0);
in {
flake.lib = finalLib;
perSystem._module.args.lib = finalLib;
}

View file

@ -0,0 +1,320 @@
{ lib }:
let
inherit (lib.lists) forEach filter;
inherit (lib.attrsets) filterAttrs mapAttrsToList;
inherit (lib.filesystem) listFilesRecursive;
inherit (lib.strings) hasSuffix;
/**
filter files for the .nix suffix
# Arguments
- [k] they key, which is the file name
- [v] the value, which is the type of the file
# Type
```
filterNixFiles :: String -> String -> Bool
```
# Example
```nix
filterNixFiles "default.nix" "regular"
=> true
```
*/
filterNixFiles = k: v: v == "regular" && hasSuffix ".nix" k;
/**
Import all file that filterNixFiles allows for
# Arguments
- [path] the path to the directory
# Type
```
importNixFiles :: String -> List
```
# Example
```nix
importNixFiles ./.
=> [ {...} ]
```
*/
importNixFiles =
path:
(forEach (
mapAttrsToList (name: _: path + ("/" + name)) (filterAttrs filterNixFiles (builtins.readDir path))
))
import;
/**
import all nix files and directories
# Arguments
- [dir] the directory to search for nix files
# Type
```
importNixFilesAndDirs :: String -> List
```
# Example
```nix
importNixFilesAndDirs ./.
=> [ "flake.nix" ]
```
*/
importNixFilesAndDirs = dir: filter (f: f != "default.nix") (listFilesRecursive dir);
/**
return an int based on boolean value
# Arguments
- [bool] the boolean value
# Type
```
boolToNum :: Bool -> Int
```
# Example
```nix
boolToNum true
=> 1
```
*/
boolToNum = bool: if bool then 1 else 0;
/**
convert a list of integers to a list of string
# Arguments
- [list] the list of integers
# Type
```
intListToStringList :: List -> List
```
# Example
```nix
intListToStringList [1 2 3]
=> ["1" "2" "3"]
```
*/
intListToStringList = list: map (toString list);
/**
a function that returns the index of an element in a list
# Arguments
- [list] the list to search in
- [elem] the element to search for
# Type
```
indexOf :: List -> Any -> Int
```
# Example
```nix
indexOf [1 2 3] 2
=> 1
```
*/
indexOf =
list: elem:
let
f =
f: i:
if i == (builtins.length list) then
null
else if (builtins.elemAt list i) == elem then
i
else
f f (i + 1);
in
f f 0;
/**
a function that checks if a list contains a list of given strings
# Arguments
- [list] the list to search in
- [targetStrings] the list of strings to search for
# Type
```
containsStrings :: List -> List -> Bool
```
# Example
```nix
containsStrings ["a" "b" "c"] ["a" "b"]
=> true
```
*/
containsStrings =
list: targetStrings: builtins.all (s: builtins.any (x: x == s) list) targetStrings;
/**
Create git url aliases for a given domain
# Arguments
- [domain] the domain to create the alias for
- [alias] the alias to use
- [user] the user to use, this defaults to "git"
- [port] the port to use, this is optional
# Type
```
giturl :: (String -> String -> String -> Int) -> AttrSet
```
# Example
```nix
giturl { domain = "github.com"; alias = "gh"; }
=> {
"https://github.com/".insteadOf = "gh:";
"ssh://git@github.com/".pushInsteadOf = "gh:";
}
```
*/
giturl =
{
domain,
alias,
user ? "git",
port ? null,
...
}:
{
"https://${domain}/".insteadOf = "${alias}:";
"ssh://${user}@${domain}${
if (builtins.isNull port) then
""
else if (builtins.isInt port) then
":" + (builtins.toString port)
else
":" + port
}/".pushInsteadOf =
"${alias}:";
};
/**
Create a public key for a given host
# Arguments
- [host] the host to create the public key for
- [key] this is a attrset with the key type and key
# Type
```
mkPub :: (String -> AttrSet -> AttrSet) -> String -> AttrSet -> AttrSet
```
# Example
```nix
mkPub "github.com" {
type = "rsa";
key = "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
}
=> {
"github.com-rsa" = {
hostNames = [ "github.com" ];
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
};
}
```
*/
mkPub = host: key: {
"${host}-${key.type}" = {
hostNames = [ host ];
publicKey = "ssh-${key.type} ${key.key}";
};
};
/**
Create public keys for a given host
# Arguments
- [host] the host to create the public keys for
- [keys] the list of keys to create
# Type
```
mkPubs :: (String -> List) -> String -> List -> AttrSet
```
# Example
```nix
mkPubs "github.com" [
{
type = "rsa";
key = "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
}
{
type = "ed25519";
key = "AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
}
]
=> {
"github.com-ed25519" = {
hostNames = [ "github.com" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
};
"github.com-rsa" = {
hostNames = [ "github.com" ];
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
};
}
```
*/
mkPubs = host: keys: lib.foldl' (acc: key: acc // mkPub host key) { } keys;
in
{
inherit
mkPub
mkPubs
giturl
filterNixFiles
importNixFiles
importNixFilesAndDirs
boolToNum
containsStrings
indexOf
intListToStringList
;
}

View file

@ -0,0 +1,15 @@
{ lib }:
let
inherit (lib.options) mkEnableOption mkPackageOption;
inherit (lib.attrsets) recursiveUpdate;
mkProgram =
pkgs: name: extraConfig:
recursiveUpdate {
enable = mkEnableOption "Enable ${name}";
package = mkPackageOption pkgs name { };
} extraConfig;
in
{
inherit mkProgram;
}

View file

@ -0,0 +1,99 @@
{ inputs }:
let
inherit (inputs) self;
/**
Create secrets for use with `agenix`.
# Arguments
- [file] the age file to use for the secret
- [owner] the owner of the secret, this defaults to "root"
- [group] the group of the secret, this defaults to "root"
- [mode] the permissions of the secret, this defaults to "400"
# Type
```
mkSecret :: (String -> String -> String -> String) -> AttrSet
```
# Example
```nix
mkSecret { file = "./my-secret.age"; }
=> {
file = "./my-secret.age";
owner = "root";
group = "root";
mode = "400";
}
```
*/
mkSecret =
{
file,
owner ? "root",
group ? "root",
mode ? "400",
...
}:
{
file = "${self}/secrets/${file}.age";
inherit owner group mode;
};
/**
A light wrapper around mkSecret that allows you to specify the output path
# Arguments
- [file] the age file to use for the secret
- [owner] the owner of the secret, this defaults to "root"
- [group] the group of the secret, this defaults to "root"
- [mode] the permissions of the secret, this defaults to "400"
- [path] the path to output the secret to
# Type
```
mkSecretWithPath :: (String -> String -> String -> String -> String) -> AttrSet
```
# Example
```nix
mkSecret { file = "./my-secret.age"; path = "/etc/my-secret"; }
=> {
file = "./my-secret.age";
path = "/etc/my-secret";
owner = "root";
group = "root";
mode = "400";
}
```
*/
mkSecretWithPath =
{
file,
path,
owner ? "root",
group ? "root",
mode ? "400",
...
}:
mkSecret {
inherit
file
owner
group
mode
;
}
// {
inherit path;
};
in
{
inherit mkSecret mkSecretWithPath;
}

View file

@ -0,0 +1,65 @@
{ lib }:
let
inherit (lib.types) str;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.attrsets) recursiveUpdate;
mkGraphicalService = recursiveUpdate {
Unit.PartOf = [ "graphical-session.target" ];
Unit.After = [ "graphical-session.target" ];
Install.WantedBy = [ "graphical-session.target" ];
};
mkHyprlandService = recursiveUpdate {
Unit.PartOf = [ "graphical-session.target" ];
Unit.After = [ "graphical-session.target" ];
Install.WantedBy = [ "hyprland-session.target" ];
};
/**
A quick way to use my services abstraction
# Arguments
- [name]: The name of the service
# Type
```
mkServiceOption :: String -> (Int -> String -> String -> AttrSet) -> AttrSet
```
*/
mkServiceOption =
name:
{
port ? 0,
host ? "127.0.0.1",
domain ? "",
extraConfig ? { },
}:
{
enable = mkEnableOption "Enable the ${name} service";
host = mkOption {
type = str;
default = host;
description = "The host for ${name} service";
};
port = mkOption {
type = lib.types.port;
default = port;
description = "The port for ${name} service";
};
domain = mkOption {
type = str;
default = domain;
description = "Domain name for the ${name} service";
};
}
// extraConfig;
in
{
inherit mkGraphicalService mkHyprlandService mkServiceOption;
}

View file

@ -0,0 +1,35 @@
let
# this is a forced SSL template for Nginx
# returns the attribute set with our desired settings
systemd = {
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateIPC = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictNamespaces = "uts ipc pid user cgroup";
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = ["@system-service"];
UMask = "0077";
};
xdg = import ./xdg.nix;
in {
inherit
systemd
xdg
;
}

View file

@ -0,0 +1,100 @@
# You can generate something like this using xdg-ninja
let
XDG_CONFIG_HOME = "$HOME/.config";
XDG_CACHE_HOME = "$HOME/.cache";
XDG_DATA_HOME = "$HOME/.local/share";
XDG_STATE_HOME = "$HOME/.local/state";
XDG_BIN_HOME = "$HOME/.local/bin";
XDG_RUNTIME_DIR = "/run/user/$UID";
in
{
# global env
glEnv = {
inherit
XDG_CONFIG_HOME
XDG_CACHE_HOME
XDG_DATA_HOME
XDG_STATE_HOME
XDG_BIN_HOME
XDG_RUNTIME_DIR
;
PATH = [ "$XDG_BIN_HOME" ];
};
sysEnv = {
# desktop
KDEHOME = "${XDG_CONFIG_HOME}/kde";
XCOMPOSECACHE = "${XDG_CACHE_HOME}/X11/xcompose";
ERRFILE = "${XDG_CACHE_HOME}/X11/xsession-errors";
WINEPREFIX = "${XDG_DATA_HOME}/wine";
# programs
GNUPGHOME = "${XDG_DATA_HOME}/gnupg";
LESSHISTFILE = "${XDG_DATA_HOME}/less/history";
CUDA_CACHE_PATH = "${XDG_CACHE_HOME}/nv";
STEPPATH = "${XDG_DATA_HOME}/step";
WAKATIME_HOME = "${XDG_CONFIG_HOME}/wakatime";
INPUTRC = "${XDG_CONFIG_HOME}/readline/inputrc";
PLATFORMIO_CORE_DIR = "${XDG_DATA_HOME}/platformio";
DOTNET_CLI_HOME = "${XDG_DATA_HOME}/dotnet";
MPLAYER_HOME = "${XDG_CONFIG_HOME}/mplayer";
SQLITE_HISTORY = "${XDG_CACHE_HOME}/sqlite_history";
# programming
ANDROID_HOME = "${XDG_DATA_HOME}/android";
ANDROID_USER_HOME = "${XDG_DATA_HOME}/android";
GRADLE_USER_HOME = "${XDG_DATA_HOME}/gradle";
IPYTHONDIR = "${XDG_CONFIG_HOME}/ipython";
JUPYTER_CONFIG_DIR = "${XDG_CONFIG_HOME}/jupyter";
GOPATH = "${XDG_DATA_HOME}/go";
M2_HOME = "${XDG_DATA_HOME}/m2";
CARGO_HOME = "${XDG_DATA_HOME}/cargo";
RUSTUP_HOME = "${XDG_DATA_HOME}/rustup";
STACK_ROOT = "${XDG_DATA_HOME}/stack";
STACK_XDG = 1;
NODE_REPL_HISTORY = "${XDG_DATA_HOME}/node_repl_history";
NPM_CONFIG_CACHE = "${XDG_CACHE_HOME}/npm";
NPM_CONFIG_TMP = "${XDG_RUNTIME_DIR}/npm";
NPM_CONFIG_USERCONFIG = "${XDG_CONFIG_HOME}/npm/config";
};
npmrc.text = ''
prefix=''${XDG_DATA_HOME}/npm
cache=''${XDG_CACHE_HOME}/npm
init-module=''${XDG_CONFIG_HOME}/npm/config/npm-init.js
'';
pythonrc.text = ''
import os
import atexit
import readline
from pathlib import Path
if readline.get_current_history_length() == 0:
state_home = os.environ.get("XDG_STATE_HOME")
if state_home is None:
state_home = Path.home() / ".local" / "state"
else:
state_home = Path(state_home)
history_path = state_home / "python_history"
if history_path.is_dir():
raise OSError(f"'{history_path}' cannot be a directory")
history = str(history_path)
try:
readline.read_history_file(history)
except OSError: # Non existent
pass
def write_history():
try:
readline.write_history_file(history)
except OSError:
pass
atexit.register(write_history)
'';
}

View file

@ -0,0 +1,128 @@
{lib, ...}: let
inherit (lib.attrsets) getAttrFromPath;
inherit
(builtins)
elem
filter
hasAttr
any
;
/*
*
a function that will append a list of groups if they exist in config.users.groups
# Arguments
- [config] the configuration that nixosConfigurations provides
- [groups] a list of groups to check for
# Type
```
ifTheyExist :: AttrSet -> List -> List
```
# Example
```nix
ifTheyExist config ["wheel" "users"]
=> ["wheel"]
```
*/
ifTheyExist = config: groups: filter (group: hasAttr group config.users.groups) groups;
/*
*
convenience function check if the declared device type is of an accepted type
# Arguments
- [config] the configuration that nixosConfigurations provides
- [list] a list of devices that will be accepted
# Type
```
isAcceptedDevice :: AttrSet -> List -> Bool
```
# Example
```nix
isAcceptedDevice osConfig ["foo" "bar"]
=> false
```
*/
isAcceptedDevice = conf: list: elem conf.olympus.device.type list;
/*
*
check if the device is wayland-ready
# Arguments
- [config] the configuration that nixosConfigurations provides
# Type
```
isWayland :: AttrSet -> Bool
```
# Example
```nix
isWayland osConfig
=> true
```
*/
isWayland = conf: conf.olympus.meta.isWayland;
/*
*
check if the device is modernShell-ready
# Arguments
- [config] the configuration that nixosConfigurations provides
# Type
```
isModernShell :: AttrSet -> Bool
```
# Example
```nix
isModernShell osConfig
=> true
```
*/
isModernShell = conf: conf.olympus.programs.cli.enable && conf.olympus.programs.cli.modernShell.enable;
anyHome = conf: cond: path: let
list =
map (
user:
getAttrFromPath (
[
"users"
user
]
++ path
)
conf
)
conf.olympus.system.users;
in
any cond list;
in {
inherit
ifTheyExist
isAcceptedDevice
isWayland
isModernShell
anyHome
;
}

View file

@ -1,6 +1,11 @@
{inputs, ...}: { {inputs, ...}: {
imports = [ imports = [
inputs.home-manager.nixosModules.home-manager # home manager has been a pia to work with and
# gives really hard to debug errors so I just
# gave up with it so hjem it is
# inputs.home-manager.nixosModules.home-manager
inputs.hjem.nixosModules.default
inputs.hjem-rum.nixosModules.default
inputs.lix-module.nixosModules.default inputs.lix-module.nixosModules.default
]; ];
} }

View file

@ -1,6 +1,6 @@
{ {
imports = [ imports = [
#./hosted ./hosted
./system ./system
]; ];
} }

View file

@ -1,6 +1,5 @@
{ {
lib, lib,
pkgs,
config, config,
... ...
}: let }: let

View file

@ -1 +1,137 @@
{} {
lib,
config,
pkgs,
...
}: let
inherit (lib.modules) mkIf mkAfter;
inherit (lib.services) mkServiceOption;
inherit (lib.strings) removePrefix removeSuffix;
inherit (lib.secrets) mkSecret;
rdomain = config.networking.domain;
cfg = config.olympus.services.forgejo;
# stole this from https://github.com/isabelroses/dotfiles/blob/main/modules/nixos/services/selfhosted/forgejo.nix who
# stole this from https://git.winston.sh/winston/deployment-flake/src/branch/main/config/services/gitea.nix who
# stole it from https://github.com/getchoo
theme = pkgs.fetchzip {
url = "https://github.com/catppuccin/gitea/releases/download/v1.0.0/catppuccin-gitea.tar.gz";
hash = "sha256-UsYJJ1j9erMih4OlFon604g1LvkZI/UiLgMgdvnyvyA=";
stripRoot = false;
};
in {
options.olympus.services.forgejo = mkServiceOption "forgejo" {
port = 3000;
domain = "git.${rdomain}";
};
config = mkIf cfg.enable {
age.secrets.forgejo-runner-token = mkSecret {
file = "forgejo-runner-token";
owner = "forgejo";
group = "forgejo";
};
olympus.services = {
caddy.enable = true;
};
systemd.services = {
forgejo = {
preStart = let
inherit (config.services.forgejo) stateDir;
in
mkAfter ''
rm -rf ${stateDir}/custom/public/assets
mkdir -p ${stateDir}/custom/public/assets
ln -sf ${theme} ${stateDir}/custom/public/assets/css
'';
};
};
users = {
groups.git = {};
users.git = {
isSystemUser = true;
createHome = false;
group = "git";
};
};
services = {
forgejo = {
package = pkgs.forgejo;
enable = true;
lfs.enable = true;
settings = {
DEFAULT.APP_NAME = "haigit";
federation.ENABLED = true;
service.DISABLE_REGISTRATION = true;
actions = {
ENABLED = true;
};
server = {
ROOT_URL = "https://${cfg.domain}";
DOMAIN = "${cfg.domain}";
SSH_PORT = 22;
SSH_LISTEN_PORT = 22;
BUILTIN_SSH_SERVER_USER = "git";
};
ui = {
DEFAULT_THEME = "catppuccin-mocha-pink";
THEMES = builtins.concatStringsSep "," (
["auto,forgejo-auto,forgejo-dark,forgejo-light,arc-gree,gitea"]
++ (map (name: removePrefix "theme-" (removeSuffix ".css" name)) (
# IFD, https://github.com/catppuccin/nix/pull/179
builtins.attrNames (builtins.readDir theme)
))
);
};
"ui.meta" = {
AUTHOR = "Elissa";
DESCRIPTION = "My own selfhosted git place for random stuff :3";
};
session = {
COOKIE_SECURE = true;
# Sessions last for a month
SESSION_LIFE_TIME = 86400 * 30;
};
};
};
gitea-actions-runner = {
package = pkgs.forgejo-actions-runner;
instances.default = {
enable = true;
name = "Theia";
url = cfg.domain;
# token = "KQA3LtLj5s5PGUfVAxVJ2OCcnySDWdgjlsSaGbOJ";
tokenFile = config.age.secrets.forgejo-runner-token.path;
labels = [
"ubuntu-latest:docker://node:22-bookworm"
];
};
};
caddy.virtualHosts.${cfg.domain} = {
extraConfig = ''
reverse_proxy localhost:3000
'';
};
};
# for forgejo runner
virtualisation.docker = {
enable = true;
rootless = {
enable = true;
setSocketVariable = true;
};
};
};
}

7
secrets/default.nix Normal file
View file

@ -0,0 +1,7 @@
let
pingu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILPbmiNqoyeKXk/VopFm2cFfEnV4cKCFBhbhyYB69Fuu";
elissa = "";
users = [pingu elissa];
in {
"forgejo-runner-token.age".publicKeys = [pingu];
}

View file

@ -1,10 +1,9 @@
{ {
self, self,
inputs, inputs,
lib,
... ...
}: let }: let
# inherit (self) lib; inherit (self) lib;
inherit (lib.lists) optionals; inherit (lib.lists) optionals;
profilesPath = ../modules/profiles; profilesPath = ../modules/profiles;

View file

@ -4,6 +4,7 @@
./networking.nix ./networking.nix
./overrides.nix ./overrides.nix
./services.nix ./services.nix
./users.nix
]; ];
olympus = { olympus = {

View file

@ -1 +1,68 @@
{} {lib, ...}: let
inherit (lib.modules) mkForce;
in {
networking = {
enableIPv6 = true;
firewall = {
allowedTCPPorts = [
80 # HTTP
443 # HTTPS
25565 # minecraft
25566 # minecraft
25567 # minecraft
];
allowedUDPPorts = [
25565 # minecraft
25566 # minecraft
25567 # minecraft
];
};
hostName = "theia";
nameservers = ["1.1.1.1" "8.8.8.8" "9.9.9.9"];
domain = "blahai.gay";
useDHCP = mkForce false;
defaultGateway = {
address = "178.63.247.183";
interface = "ens3";
};
defaultGateway6 = {
address = " 2a01:4f8:2201:f900:2::2";
interface = "ens3";
};
interfaces = {
ens3 = {
ipv4 = {
addresses = [
{
address = "178.63.118.252";
prefixLength = 32;
}
];
routes = [
{
address = "178.63.247.183";
prefixLength = 32;
}
];
};
ipv6 = {
addresses = [
{
address = "2a01:4f8:2201:f912::a";
prefixLength = 64;
}
];
routes = [
{
address = "fe80::1";
prefixLength = 128;
}
];
};
};
};
};
}

View file

@ -1 +1,6 @@
{} {
olympus.services = {
caddy.enable = true;
forgejo.enable = true;
};
}

5
systems/theia/users.nix Normal file
View file

@ -0,0 +1,5 @@
{
olympus.system = {
mainUser = "pingu";
};
}