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
No known key found for this signature in database
37 changed files with 1277 additions and 168 deletions

View file

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

View file

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

View file

@ -1,6 +1,6 @@
{
imports = [
./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,6 +0,0 @@
{
imports = [
./shells.nix
./defaults.nix
];
}

View file

@ -1,93 +0,0 @@
{lib, ...}: let
inherit (lib.options) mkOption;
inherit (lib.types) enum nullOr;
in {
options.olympus.programs.defaults = {
shell = mkOption {
type = enum [
"bash"
"zsh"
"fish"
];
default = "bash";
};
terminal = mkOption {
type = enum [
"alacritty"
"kitty"
"wezterm"
"foot"
];
default = "wezterm";
};
fileManager = mkOption {
type = enum [
"cosmic-files"
"thunar"
"dolphin"
"nemo"
];
default = "cosmic-files";
};
browser = mkOption {
type = enum [
"firefox"
"floorp"
"chromium"
"thorium"
];
default = "floorp";
};
editor = mkOption {
type = enum [
"nvim"
];
default = "nvim";
};
launcher = mkOption {
type = nullOr (enum [
"rofi"
"wofi"
"cosmic-launcher"
]);
default = "wofi";
};
bar = mkOption {
type = nullOr (enum [
"waybar"
"ags"
]);
default = "ags";
};
screenLocker = mkOption {
type = nullOr (enum [
"hyprlock"
"swaylock"
"gtklock"
"cosmic-greeter"
]);
default = "hyprlock";
description = ''
The lockscreen module to be loaded by home-manager.
'';
};
noiseSuppressor = mkOption {
type = nullOr (enum [
"rnnoise"
"noisetorch"
]);
default = "rnnoise";
description = ''
The noise suppressor to be used for desktop systems with sound enabled.
'';
};
};
}

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

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
inherit (lib.modules) mkDefault;
inherit (lib.attrsets) genAttrs;
inherit (builtins) filter hasAttr;
ifTheyExist = config: groups: filter (group: hasAttr group config.users.groups) groups;
inherit (lib.validators) ifTheyExist;
in {
users.users = genAttrs config.olympus.system.users (
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;
isNormalUser = true;
@ -28,14 +27,17 @@ in {
"networkmanager"
"systemd-journal"
"audio"
"pipewire"
"pipewire" # this give us access to the rt limits
"video"
"input"
"plugdev"
"lp"
"tss"
"power"
"wireshark"
"mysql"
"docker"
"podman"
"git"
"libvirtd"
"cloudflared"

View file

@ -2,6 +2,7 @@
imports = [
../../systems
./programs
./lib
./args.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, ...}: {
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
];
}

View file

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

View file

@ -1,6 +1,5 @@
{
lib,
pkgs,
config,
...
}: 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;
};
};
};
}