Compare commits

..

1 commit

Author SHA1 Message Date
a2f660db91 add not working configuration 2024-10-12 01:11:44 +03:00
112 changed files with 242 additions and 6774 deletions

View file

@ -1,11 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

View file

@ -1,35 +0,0 @@
name: Build SD image for Raspberry Pi 5
on:
workflow_dispatch:
jobs:
build-sd-image:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install QEMU
run: sudo apt-get install qemu-user-static
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
system = aarch64-linux
- name: Build SD image
run: nix build -L '.#nixosConfigurations.pochita-sd.config.system.build.sdImage'
- name: Zip the Resulting SD image
run: |
mkdir -p sd-image
cp -r result/* sd-image
zip -r sd-image.zip sd-image
- name: Upload SD image
uses: actions/upload-artifact@v5
with:
name: sd-image

View file

@ -1,37 +0,0 @@
name: Nix
on:
push:
paths-ignore:
- README.md
pull_request:
paths-ignore:
- README.md
jobs:
build:
strategy:
matrix:
target-system:
- ymir
- tartarus
- pochita
- pochita-sd
- harmonica
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: cachix/install-nix-action@v31
# TODO: add a binary cache
# - uses: cachix/cachix-action@v10
# with:
# name: YOURCACHE
# authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- run: nix flake check --accept-flake-config
# Pre-build the system configuration
- run: nix build --accept-flake-config --dry-run .#nixosConfigurations.${{ matrix.target-system }}.config.system.build.toplevel
check-formatting:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: cachix/install-nix-action@v31
- run: nix run nixpkgs#nixfmt-tree -- --ci

View file

@ -1,41 +0,0 @@
name: Build and test the packages i maintain on Nixpkgs
on:
# cron every hour at 3 minutes 00:03 AM, 01:03 AM etc.
schedule:
- cron: '3 0 * * *'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-24.04
strategy:
matrix:
nixpkgs-branch: [nixos-unstable, nixpkgs-unstable, master] # TODO: add stable branch once they are available
# platform: [x86_64-linux, aarch64-linux] #TODO: add aarch64-linux
myPackages: # TODO automate this list
- python313Packages.runstats
- python313Packages.fastmri
- python312Packages.runstats
- python312Packages.fastmri
- python311Packages.runstats
# - python311Packages.fastmri # broken for now
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install Nix
uses: cachix/install-nix-action@v31
# with:
# extra_nix_config: |
# # system = ${{ matrix.platform }}
# i want to create .drv file and check if they exist in the nixos.cache
# if they dont exist, i want to skip the build
# - name: Check if the dependencies are in the cache
# run: nix path-info --closure-size --eval-store auto --store https://cache.nixos.org 'github:nixos/nixpkgs/${{ matrix.nixpkgs-branch }}#${{ matrix.myPackages }}^*'
- name: Build my packages
run: nix build -L "github:nixos/nixpkgs/${{ matrix.nixpkgs-branch }}#${{ matrix.myPackages }}"

4
.gitignore vendored
View file

@ -1,4 +0,0 @@
result
.DS_Store
.direnv
*.old

View file

@ -1,3 +0,0 @@
osbm <osbm@osbm.dev> <osmanfbayram@gmail.com>
osbm <osbm@osbm.dev> <osbm@users.noreply.github.com>
osbm <osbm@osbm.dev> <74963545+osbm@users.noreply.github.com>

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Osman F Bayram
Copyright (c) 2024 Osman F Bayram
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

138
README.md
View file

@ -1,136 +1,2 @@
# nixos is life
The nix configuration of mine. My intentions are just to maintain my configuration and to contribute to the nix community.
Here i have 4 machines and 1 sd card image that i maintain.
- Laptop **tartarus** (faulty hardware, nvidia gpu doesnt work)
- Desktop **ymir** (beast, my most prized possession as of now)
- Raspberry Pi 5 **pochita** (a server that i experiment with)
- Raspberry Pi 5 SD image **pochita-sd** (produces an sd image that could be used to flash the sd card of a rpi-5)
- Phone **atreus** (unrooted, nix-on-droid)
I didnt get these setup yet.
- Raspberry Pi Zero 2W **harmonica** (small machine for small tasks and cronjobs) (not setup yet)
- Android phone (termux) **android** (not setup yet)
My options:
I implemented a module system for my configurations. Each machine has its own set of options that can be enabled or disabled. The options are defined in the `modules/options.nix` file. Each option is a module that can be imported into the machine configuration.
I am containing my options in the `osbmModules` attribute set. I dont like to interfere with the global configuration namespace. Here is all the available options:
```nix
osbmModules = {
desktopEnvironment = "plasma"; # options: "plasma", "none"
homeManager.enable = true;
machineType = "desktop"; # options: "desktop", "laptop", "server", "embedded", "mobile"
users = [ "osbm" "bayram" ];
defaultUser = "osbm";
agenix.enable = true;
nixSettings.enable = true;
programs = {
steam.enable = true;
graphical.enable = true;
commandLine.enable = true;
neovim.enable = true;
arduino.enable = true;
adbFastboot.enable = true;
};
services = {
# list services to enable
};
hardware = {
sound.enable = true;
nvidia.enable = false;
hibernation.enable = false;
disko = {
enable = true;
fileSystem = "zfs"; # options: "zfs", "ext4"
initrd-ssh = {
enable = true;
ethernetDrivers = [ "igc" ];
};
zfs = {
enable = true;
hostID = "49e95c43";
root = {
disk1 = "nvme0n1";
disk2 = "nvme1n1";
reservation = "200G";
impermanenceRoot = true;
};
storage = {
enable = true;
disks = [
"sda"
"sdb"
];
reservation = "1500G";
mirror = true;
#amReinstalling = true;
};
};
};
}
};
```
<details>
<summary> How to bootstrap raspberry pi 5</summary>
## How to use raspberry pi 5
I have 2 configurations for the raspberry pi 5. One is for the sd card (basically bootstraps the system) and the other is for my customized system itself.
build the image first (this took about 4 hours on ymir (binfmt for aarch64 needs to be enabled if you are building on x86_64))
```sh
$ nix build -L '.#nixosConfigurations.pochita-sd.config.system.build.sdImage'
```
then to flash the image to the sd card enable zstd
```sh
$ nix-shell -p zstd
```
then flash the image to the sd card
```sh
$ zstdcat nixos-sd-image-24.05.20241116.e8c38b7-aarch64-linux.img.zst | dd of=/dev/sda status=progress
```
and voila! when you plug the sd card to the raspberry pi 5 it will boot up with the configuration that you have built. And then you can ssh into it and further configure it.
</details>
build iso with:
nix build .#nixosConfigurations.myISO.config.system.build.isoImage
# To-do list
- [x] iso image generator for nixos
- Basically the original nixos iso with added packages and tweaks.
- [ ] build custom android rom
- Or how to run nixos on the phone.
- [ ] build android apps using nix
- [ ] lichess
- [ ] termux
- [ ] build my qmk keyboard with nix
- agenix
- [ ] add my gpg keys
- [x] add ssh keys so that machines can connect to each other
- [x] module system with options
- [ ] see which derivations will be built and which will be downloaded from cache or which is already present in the nix store.
- [ ] see which python packages are giving build errors.
- [x] home-manager setup
- [ ] make a development environment nix repository
- [ ] enable swap on pochita
- [ ] learnis it possible to enable swap with sd-image?
nano /tmp/secret.key
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode destroy,format,mount --flake github:osbm/flake#apollo
sudo mkdir -p /mnt/etc/ssh
sudo ssh-keygen -t ed25519 -N "" -f /mnt/etc/ssh/initrd
sudo nixos-install --flake github:osbm/flake#apollo --root /mnt --no-root-passwd
# nix-configuration
The nix configuration

206
configuration.nix Normal file
View file

@ -0,0 +1,206 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "tartarus"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Enable networking
networking.networkmanager.enable = true;
# Set your time zone.
time.timeZone = "Europe/Istanbul";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "tr_TR.UTF-8";
LC_IDENTIFICATION = "tr_TR.UTF-8";
LC_MEASUREMENT = "tr_TR.UTF-8";
LC_MONETARY = "tr_TR.UTF-8";
LC_NAME = "tr_TR.UTF-8";
LC_NUMERIC = "tr_TR.UTF-8";
LC_PAPER = "tr_TR.UTF-8";
LC_TELEPHONE = "tr_TR.UTF-8";
LC_TIME = "tr_TR.UTF-8";
};
# Enable the X11 windowing system.
# You can disable this if you're only using the Wayland session.
services.xserver.enable = true;
# Enable the KDE Plasma Desktop Environment.
services.displayManager.sddm.enable = true;
services.desktopManager.plasma6.enable = true;
# Configure keymap in X11
services.xserver.xkb = {
layout = "us";
variant = "";
};
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable sound with pipewire.
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
#jack.enable = true;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
};
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# Define a user account. Don't forget to set a password with passwd.
users.users.osbm = {
isNormalUser = true;
description = "osbm";
extraGroups = [ "networkmanager" "wheel" ];
packages = with pkgs; [
kdePackages.kate
vscode
discord
alacritty
# thunderbird
];
};
# Install firefox.
programs.firefox.enable = true;
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
nix.settings.experimental-features = [ "nix-command" "flakes"];
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
wget
git
gnumake
zip
fish
trash-cli
tmux
zoxide
htop
unzip
tlrc
];
# services.xserver.videoDrivers = ["nvidia"]; # this setting makes my computer crash
# Enable OpenGL
hardware.opengl = {
enable = true;
};
# Load nvidia driver for Xorg and Wayland
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia = {
# Modesetting is required.
modesetting.enable = true;
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
# Enable this if you have graphical corruption issues or application crashes after waking
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
# of just the bare essentials.
powerManagement.enable = false;
# Fine-grained power management. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
powerManagement.finegrained = false;
# Use the NVidia open source kernel module (not to be confused with the
# independent third-party "nouveau" open source driver).
# Support is limited to the Turing and later architectures. Full list of
# supported GPUs is at:
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
# Only available from driver 515.43.04+
# Currently alpha-quality/buggy, so false is currently the recommended setting.
open = false;
# Enable the Nvidia settings menu,
# accessible via `nvidia-settings`.
nvidiaSettings = true;
# Optionally, you may need to select the appropriate driver version for your specific GPU.
# package = config.boot.kernelPackages.nvidiaPackages.stable;
package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
};
hardware.nvidia.prime = {
offload = {
enable = true;
enableOffloadCmd = true;
};
# Make sure to use the correct Bus ID values for your system!
intelBusId = "PCI:0:2:0";
nvidiaBusId = "PCI:6:0:0";
# amdgpuBusId = "PCI:54:0:0"; For AMD GPU
};
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "24.05"; # Did you read the comment?
}

938
flake.lock generated
View file

@ -1,952 +1,24 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1761656077,
"narHash": "sha256-lsNWuj4Z+pE7s0bd2OKicOFq9bK86JE0ZGeKJbNqb94=",
"owner": "ryantm",
"repo": "agenix",
"rev": "9ba0d85de3eaa7afeab493fed622008b6e4924f5",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"blobs": {
"flake": false,
"locked": {
"lastModified": 1604995301,
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"type": "gitlab"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1744478979,
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1762276996,
"narHash": "sha256-TtcPgPmp2f0FAnc+DMEw4ardEgv1SGNR3/WFGH0N19M=",
"owner": "nix-community",
"repo": "disko",
"rev": "af087d076d3860760b3323f6b583f4d828c1ac17",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"osbm-nvim",
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1760948891,
"narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": [
"simple-nixos-mailserver",
"flake-compat"
],
"gitignore": "gitignore",
"nixpkgs": [
"simple-nixos-mailserver",
"nixpkgs"
]
},
"locked": {
"lastModified": 1760663237,
"narHash": "sha256-BflA6U4AM1bzuRMR8QqzPXqh8sWVCNDzOdsxXEguJIc=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "ca5b894d3e3e151ffc1db040b6ce4dcc75d31c37",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"simple-nixos-mailserver",
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1762463325,
"narHash": "sha256-33YUsWpPyeBZEWrKQ2a1gkRZ7i0XCC/2MYpU6BVeQSU=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "0562fef070a1027325dd4ea10813d64d2c967b39",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
"nix-on-droid",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709445365,
"narHash": "sha256-DVv6nd9FQBbMWbOmhq0KVqmlc3y3FMSYl49UXmMcO+0=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "4de84265d7ec7634a69ba75028696d74de9a44a7",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"impermanence": {
"locked": {
"lastModified": 1737831083,
"narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"ixx": {
"inputs": {
"flake-utils": [
"osbm-nvim",
"nixvim",
"nuschtosSearch",
"flake-utils"
],
"nixpkgs": [
"osbm-nvim",
"nixvim",
"nuschtosSearch",
"nixpkgs"
]
},
"locked": {
"lastModified": 1754860581,
"narHash": "sha256-EM0IE63OHxXCOpDHXaTyHIOk2cNvMCGPqLt/IdtVxgk=",
"owner": "NuschtOS",
"repo": "ixx",
"rev": "babfe85a876162c4acc9ab6fb4483df88fa1f281",
"type": "github"
},
"original": {
"owner": "NuschtOS",
"ref": "v0.1.1",
"repo": "ixx",
"type": "github"
}
},
"libcamera-src": {
"flake": false,
"locked": {
"lastModified": 1725630279,
"narHash": "sha256-KH30jmHfxXq4j2CL7kv18DYECJRp9ECuWNPnqPZajPA=",
"owner": "raspberrypi",
"repo": "libcamera",
"rev": "69a894c4adad524d3063dd027f5c4774485cf9db",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"repo": "libcamera",
"rev": "69a894c4adad524d3063dd027f5c4774485cf9db",
"type": "github"
}
},
"libpisp-src": {
"flake": false,
"locked": {
"lastModified": 1724944683,
"narHash": "sha256-Fo2UJmQHS855YSSKKmGrsQnJzXog1cdpkIOO72yYAM4=",
"owner": "raspberrypi",
"repo": "libpisp",
"rev": "28196ed6edcfeda88d23cc5f213d51aa6fa17bb3",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "v1.0.7",
"repo": "libpisp",
"type": "github"
}
},
"mobile-nixos": {
"flake": false,
"locked": {
"lastModified": 1761853569,
"narHash": "sha256-miiMKVgC2WVi4ItD8rWD0ngou5WicEDAuZGhI0TfEIw=",
"owner": "mobile-nixos",
"repo": "mobile-nixos",
"rev": "1e38d4027bbb944f2af1b3241eabd9ad9c950c84",
"type": "github"
},
"original": {
"owner": "mobile-nixos",
"repo": "mobile-nixos",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1762501326,
"narHash": "sha256-QbhsksHaIN6qU3oXhwUFbYycKX1GRxObpQSWAM5fhRY=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "e2b82ebd0f990a5d1b68fcc761b3d6383c86ccfd",
"type": "github"
},
"original": {
"owner": "nix-darwin",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"nix-formatter-pack": {
"inputs": {
"nixpkgs": [
"nix-on-droid",
"nixpkgs"
],
"nmd": [
"nix-on-droid",
"nmd"
],
"nmt": "nmt"
},
"locked": {
"lastModified": 1705252799,
"narHash": "sha256-HgSTREh7VoXjGgNDwKQUYcYo13rPkltW7IitHrTPA5c=",
"owner": "Gerschtli",
"repo": "nix-formatter-pack",
"rev": "2de39dedd79aab14c01b9e2934842051a160ffa5",
"type": "github"
},
"original": {
"owner": "Gerschtli",
"repo": "nix-formatter-pack",
"type": "github"
}
},
"nix-formatter-pack_2": {
"inputs": {
"nixpkgs": [
"osbm-nvim",
"nixpkgs"
],
"nmd": "nmd_2",
"nmt": "nmt_2"
},
"locked": {
"lastModified": 1756744433,
"narHash": "sha256-6BSEvkprwEQDQQgW5UH/1GkBPGM8M9+qX6o9ePslr6E=",
"owner": "Gerschtli",
"repo": "nix-formatter-pack",
"rev": "63b748033a3fa0af80f8ed908521122e48858c30",
"type": "github"
},
"original": {
"owner": "Gerschtli",
"repo": "nix-formatter-pack",
"type": "github"
}
},
"nix-index-database": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1762055842,
"narHash": "sha256-Pu1v3mlFhRzZiSxVHb2/i/f5yeYyRNqr0RvEUJ4UgHo=",
"owner": "nix-community",
"repo": "nix-index-database",
"rev": "359ff6333a7b0b60819d4c20ed05a3a1f726771f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-index-database",
"type": "github"
}
},
"nix-on-droid": {
"inputs": {
"home-manager": "home-manager_2",
"nix-formatter-pack": "nix-formatter-pack",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-docs": "nixpkgs-docs",
"nixpkgs-for-bootstrap": "nixpkgs-for-bootstrap",
"nmd": "nmd"
},
"locked": {
"lastModified": 1760773689,
"narHash": "sha256-TaRP+sx4EiqBcfdKVYKT+RbrRHioJF+HUmiaUaHj5I8=",
"owner": "nix-community",
"repo": "nix-on-droid",
"rev": "1c306c07b3e99ab79b967ead32f9af7b8672a7ef",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-on-droid",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1762463231,
"narHash": "sha256-hv1mG5j5PTbnWbtHHomzTus77pIxsc4x8VrMjc7+/YE=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "52113c4f5cfd1e823001310e56d9c8d0699a6226",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1762363567,
"narHash": "sha256-YRqMDEtSMbitIMj+JLpheSz0pwEr0Rmy5mC7myl17xs=",
"lastModified": 1728500571,
"narHash": "sha256-dOymOQ3AfNI4Z337yEwHGohrVQb4yPODCW9MDUyAc4w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ae814fd3904b621d8ab97418f1d0f2eb0d3716f4",
"rev": "d51c28603def282a24fa034bcb007e2bcb5b5dd0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-25_05": {
"locked": {
"lastModified": 1761999846,
"narHash": "sha256-IYlYnp4O4dzEpL77BD/lj5NnJy2J8qbHkNSFiPBCbqo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3de8f8d73e35724bf9abef41f1bdbedda1e14a31",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-docs": {
"locked": {
"lastModified": 1705957679,
"narHash": "sha256-Q8LJaVZGJ9wo33wBafvZSzapYsjOaNjP/pOnSiKVGHY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9a333eaa80901efe01df07eade2c16d183761fa3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-for-bootstrap": {
"locked": {
"lastModified": 1720244366,
"narHash": "sha256-WrDV0FPMVd2Sq9hkR5LNHudS3OSMmUrs90JUTN+MXpA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "49ee0e94463abada1de470c9c07bfc12b36dcf40",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "49ee0e94463abada1de470c9c07bfc12b36dcf40",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1761373498,
"narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1761656231,
"narHash": "sha256-EiED5k6gXTWoAIS8yQqi5mAX6ojnzpHwAQTS3ykeYMg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e99366c665bdd53b7b500ccdc5226675cfc51f45",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1736061677,
"narHash": "sha256-DjkQPnkAfd7eB522PwnkGhOMuT9QVCZspDpJJYyOj60=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "cbd8ec4de4469333c82ff40d057350c30e9f7d36",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvim": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_3",
"nuschtosSearch": "nuschtosSearch",
"systems": "systems_3"
},
"locked": {
"lastModified": 1761744315,
"narHash": "sha256-OknzyEoI+VEYgk/FWMyx3tvjb/MPPyqS+G/aemDz51w=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "6233fc6b2c3f203d8a5970f4a2c1df5777902717",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixvim",
"type": "github"
}
},
"nmd": {
"inputs": {
"nixpkgs": [
"nix-on-droid",
"nixpkgs-docs"
],
"scss-reset": "scss-reset"
},
"locked": {
"lastModified": 1705050560,
"narHash": "sha256-x3zzcdvhJpodsmdjqB4t5mkVW22V3wqHLOun0KRBzUI=",
"owner": "~rycee",
"repo": "nmd",
"rev": "66d9334933119c36f91a78d565c152a4fdc8d3d3",
"type": "sourcehut"
},
"original": {
"owner": "~rycee",
"repo": "nmd",
"type": "sourcehut"
}
},
"nmd_2": {
"flake": false,
"locked": {
"lastModified": 1666190571,
"narHash": "sha256-Z1hc7M9X6L+H83o9vOprijpzhTfOBjd0KmUTnpHAVjA=",
"owner": "rycee",
"repo": "nmd",
"rev": "b75d312b4f33bd3294cd8ae5c2ca8c6da2afc169",
"type": "gitlab"
},
"original": {
"owner": "rycee",
"repo": "nmd",
"type": "gitlab"
}
},
"nmt": {
"flake": false,
"locked": {
"lastModified": 1648075362,
"narHash": "sha256-u36WgzoA84dMVsGXzml4wZ5ckGgfnvS0ryzo/3zn/Pc=",
"owner": "rycee",
"repo": "nmt",
"rev": "d83601002c99b78c89ea80e5e6ba21addcfe12ae",
"type": "gitlab"
},
"original": {
"owner": "rycee",
"repo": "nmt",
"type": "gitlab"
}
},
"nmt_2": {
"flake": false,
"locked": {
"lastModified": 1648075362,
"narHash": "sha256-u36WgzoA84dMVsGXzml4wZ5ckGgfnvS0ryzo/3zn/Pc=",
"owner": "rycee",
"repo": "nmt",
"rev": "d83601002c99b78c89ea80e5e6ba21addcfe12ae",
"type": "gitlab"
},
"original": {
"owner": "rycee",
"repo": "nmt",
"type": "gitlab"
}
},
"nuschtosSearch": {
"inputs": {
"flake-utils": "flake-utils",
"ixx": "ixx",
"nixpkgs": [
"osbm-nvim",
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1761730856,
"narHash": "sha256-t1i5p/vSWwueZSC0Z2BImxx3BjoUDNKyC2mk24krcMY=",
"owner": "NuschtOS",
"repo": "search",
"rev": "e29de6db0cb3182e9aee75a3b1fd1919d995d85b",
"type": "github"
},
"original": {
"owner": "NuschtOS",
"repo": "search",
"type": "github"
}
},
"osbm-nvim": {
"inputs": {
"nix-formatter-pack": "nix-formatter-pack_2",
"nixpkgs": "nixpkgs_2",
"nixvim": "nixvim"
},
"locked": {
"lastModified": 1761771567,
"narHash": "sha256-EC8Bpx6KIU0fHbhQVM6p8j+ZH56UfZ7mrVTl80d8Vcs=",
"owner": "osbm",
"repo": "osbm-nvim",
"rev": "8f08a58beafbcb94ddd6fb2d24975dd736e236d0",
"type": "github"
},
"original": {
"owner": "osbm",
"repo": "osbm-nvim",
"type": "github"
}
},
"raspberry-pi-nix": {
"inputs": {
"libcamera-src": "libcamera-src",
"libpisp-src": "libpisp-src",
"nixpkgs": "nixpkgs_4",
"rpi-bluez-firmware-src": "rpi-bluez-firmware-src",
"rpi-firmware-nonfree-src": "rpi-firmware-nonfree-src",
"rpi-firmware-src": "rpi-firmware-src",
"rpi-linux-6_12_17-src": "rpi-linux-6_12_17-src",
"rpi-linux-6_6_78-src": "rpi-linux-6_6_78-src",
"rpi-linux-stable-src": "rpi-linux-stable-src",
"rpicam-apps-src": "rpicam-apps-src"
},
"locked": {
"lastModified": 1742223591,
"narHash": "sha256-ZNTz8r5jlJ1jvpqf5+aUYgpnYJSVX0iP14doOc1Hm0E=",
"owner": "nix-community",
"repo": "raspberry-pi-nix",
"rev": "3e8100d5e976a6a2be363015cb33463af9ef441a",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "raspberry-pi-nix",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"disko": "disko",
"home-manager": "home-manager",
"impermanence": "impermanence",
"mobile-nixos": "mobile-nixos",
"nix-darwin": "nix-darwin",
"nix-index-database": "nix-index-database",
"nix-on-droid": "nix-on-droid",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"osbm-nvim": "osbm-nvim",
"raspberry-pi-nix": "raspberry-pi-nix",
"simple-nixos-mailserver": "simple-nixos-mailserver"
}
},
"rpi-bluez-firmware-src": {
"flake": false,
"locked": {
"lastModified": 1708969706,
"narHash": "sha256-KakKnOBeWxh0exu44beZ7cbr5ni4RA9vkWYb9sGMb8Q=",
"owner": "RPi-Distro",
"repo": "bluez-firmware",
"rev": "78d6a07730e2d20c035899521ab67726dc028e1c",
"type": "github"
},
"original": {
"owner": "RPi-Distro",
"ref": "bookworm",
"repo": "bluez-firmware",
"type": "github"
}
},
"rpi-firmware-nonfree-src": {
"flake": false,
"locked": {
"lastModified": 1723266537,
"narHash": "sha256-T7eTKXqY9cxEMdab8Snda4CEOrEihy5uOhA6Fy+Mhnw=",
"owner": "RPi-Distro",
"repo": "firmware-nonfree",
"rev": "4b356e134e8333d073bd3802d767a825adec3807",
"type": "github"
},
"original": {
"owner": "RPi-Distro",
"ref": "bookworm",
"repo": "firmware-nonfree",
"type": "github"
}
},
"rpi-firmware-src": {
"flake": false,
"locked": {
"lastModified": 1728405098,
"narHash": "sha256-4gnK0KbqFnjBmWia9Jt2gveVWftmHrprpwBqYVqE/k0=",
"owner": "raspberrypi",
"repo": "firmware",
"rev": "7bbb5f80d20a2335066a8781459c9f33e5eebc64",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "1.20241008",
"repo": "firmware",
"type": "github"
}
},
"rpi-linux-6_12_17-src": {
"flake": false,
"locked": {
"lastModified": 1740765145,
"narHash": "sha256-hoCsGc4+RC/2LmxDtswLBL5ZhWlw4vSiL4Vkl39r2MU=",
"owner": "raspberrypi",
"repo": "linux",
"rev": "5985ce32e511f4e8279a841a1b06a8c7d972b386",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "rpi-6.12.y",
"repo": "linux",
"type": "github"
}
},
"rpi-linux-6_6_78-src": {
"flake": false,
"locked": {
"lastModified": 1740503700,
"narHash": "sha256-Y8+ot4Yi3UKwlZK3ap15rZZ16VZDvmeFkD46+6Ku7bE=",
"owner": "raspberrypi",
"repo": "linux",
"rev": "2e071057fded90e789c0101498e45a1778be93fe",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "rpi-6.6.y",
"repo": "linux",
"type": "github"
}
},
"rpi-linux-stable-src": {
"flake": false,
"locked": {
"lastModified": 1728403745,
"narHash": "sha256-phCxkuO+jUGZkfzSrBq6yErQeO2Td+inIGHxctXbD5U=",
"owner": "raspberrypi",
"repo": "linux",
"rev": "5aeecea9f4a45248bcf564dec924965e066a7bfd",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "stable_20241008",
"repo": "linux",
"type": "github"
}
},
"rpicam-apps-src": {
"flake": false,
"locked": {
"lastModified": 1727515047,
"narHash": "sha256-qCYGrcibOeGztxf+sd44lD6VAOGoUNwRqZDdAmcTa/U=",
"owner": "raspberrypi",
"repo": "rpicam-apps",
"rev": "a8ccf9f3cd9df49875dfb834a2b490d41d226031",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "v1.5.2",
"repo": "rpicam-apps",
"type": "github"
}
},
"scss-reset": {
"flake": false,
"locked": {
"lastModified": 1631450058,
"narHash": "sha256-muDlZJPtXDIGevSEWkicPP0HQ6VtucbkMNygpGlBEUM=",
"owner": "andreymatin",
"repo": "scss-reset",
"rev": "0cf50e27a4e95e9bb5b1715eedf9c54dee1a5a91",
"type": "github"
},
"original": {
"owner": "andreymatin",
"repo": "scss-reset",
"type": "github"
}
},
"simple-nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat",
"git-hooks": "git-hooks",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-25_05": "nixpkgs-25_05"
},
"locked": {
"lastModified": 1762302830,
"narHash": "sha256-f3xe6CRPT51vCQFZotJOXi/JpGOiukz0WIa86arJSE8=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "58659fbdfd8aba9bd8f4517d3e5c388c4d8266c4",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
"nixpkgs": "nixpkgs"
}
}
},

128
flake.nix
View file

@ -1,131 +1,19 @@
{
description = "My system configuration";
nixConfig = {
extra-substituters = [
"https://nix-community.cachix.org"
# "http://wallfacer.curl-boga.ts.net:7080/main"
];
extra-trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
# "main:2AjPdIsbKyoTGuw+4x2ZXMUT/353CXosW9pdbTQtjqw="
];
};
inputs = {
agenix = {
url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-darwin = {
url = "github:nix-darwin/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-on-droid = {
url = "github:nix-community/nix-on-droid";
inputs.nixpkgs.follows = "nixpkgs";
};
osbm-nvim.url = "github:osbm/osbm-nvim";
raspberry-pi-nix = {
url = "github:nix-community/raspberry-pi-nix";
};
# colmena = {
# url = "github:zhaofengli/colmena";
# inputs.nixpkgs.follows = "nixpkgs";
# };
nix-index-database = {
url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence.url = "github:nix-community/impermanence";
mobile-nixos = {
url = "github:mobile-nixos/mobile-nixos";
flake = false;
};
simple-nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
};
outputs =
{
self,
nixpkgs,
nix-on-droid,
nix-darwin,
...
}@inputs:
outputs = { self, nixpkgs, ... }:
let
inherit (self) outputs;
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems f;
makePkgs = system: import nixpkgs { inherit system; };
makeNixosConfig =
configName:
nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs outputs; };
modules = [ ./hosts/nixos/${configName}/configuration.nix ];
lib = nixpkgs.lib;
in {
nixosConfigurations = {
tartarus = lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./configuration.nix ];
};
nixosConfigNames = builtins.attrNames (builtins.readDir ./hosts/nixos);
in
{
nixosConfigurations = nixpkgs.lib.genAttrs nixosConfigNames makeNixosConfig;
nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration {
extraSpecialArgs = { inherit inputs outputs; };
pkgs = import nixpkgs { system = "aarch64-linux"; };
modules = [ ./hosts/nixOnDroidHosts/atreus/configuration.nix ];
};
darwinConfigurations.prometheus = nix-darwin.lib.darwinSystem {
system = "x86_64-darwin";
modules = [ ./hosts/darwinHosts/prometheus/configuration.nix ];
specialArgs = { inherit inputs outputs; };
};
lib = import ./lib { inherit (nixpkgs) lib; };
formatter = forAllSystems (system: (makePkgs system).nixfmt-tree);
nixosModules.default = ./modules/nixos;
homeManagerModules.default = ./modules/home-manager;
# packages = forAllSystems (
# system:
# let
# makeNixosConfigWithSystemOverride =
# configName:
# nixpkgs.lib.nixosSystem {
# specialArgs = { inherit inputs outputs; };
# modules = [
# ./hosts/nixos/${configName}/configuration.nix
# { nixpkgs.hostPlatform = nixpkgs.lib.mkForce system; }
# ];
# };
# dotfilesMachineNames = [
# "ymir"
# "pochita"
# "tartarus"
# "wallfacer"
# ];
# in
# builtins.listToAttrs (
# map (name: {
# name = "${name}-dotfiles";
# value = (makeNixosConfigWithSystemOverride name).config.home-manager.users.osbm.home-files;
# }) dotfilesMachineNames
# )
# );
};
}

View file

@ -1,50 +1,31 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
config,
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd = {
availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
kernelModules = [ ];
};
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/fd6792b4-d1ec-493c-a686-64dbeaac3371";
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/246d3df7-3578-44b2-8aee-c1ed33581184";
fsType = "ext4";
};
"/boot" = {
device = "/dev/disk/by-uuid/383D-1E8A";
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/33D0-6524";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
options = [ "fmask=0077" "dmask=0077" ];
};
swapDevices = [
{ device = "/dev/disk/by-uuid/33c6277d-eb0a-487d-8be0-829829a8a308"; }
swapDevices =
[ { device = "/dev/disk/by-uuid/b74b04db-c7ea-44e7-b3fe-15cd6d0cd851"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
@ -52,7 +33,7 @@
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";

View file

@ -1,59 +0,0 @@
{
pkgs,
inputs,
...
}:
{
imports = [
../../../modules/nixos/options.nix
../../../modules/nixos/programs/command-line.nix
../../../modules/nixos/programs/neovim.nix
../../../modules/nixos/system/nix-settings.nix
inputs.home-manager.darwinModules.home-manager
];
osbmModules = {
desktopEnvironment = "none"; # fuckass darwin defaults
machineType = "laptop";
programs.neovim.enable = true;
};
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
verbose = true;
backupFileExtension = "hmbak";
users.osbm = {
imports = [ ../../../modules/home-manager ];
home.stateVersion = "24.11";
};
};
services.tailscale = {
enable = true;
};
programs.fish.enable = true;
# osbmModules.setUsers = false;
users.users.osbm = {
description = "osbm";
shell = pkgs.fish;
home = "/Users/osbm";
};
environment.systemPackages = with pkgs; [
alacritty
# ghostty
kitty
vscode
git
lazygit
# blender
# libreoffice
# ungoogled-chromium
code-cursor
ollama
];
system.stateVersion = 6;
nixpkgs.hostPlatform = "x86_64-darwin";
}

View file

@ -1,97 +0,0 @@
{
pkgs,
...
}:
{
user.userName = "osbm";
# Read the changelog before changing this value
system.stateVersion = "24.05";
# Set up nix for flakes
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
build.activation.sshd = ''
if [ ! -e /etc/ssh/ssh_host_ed25519_key ]; then
$VERBOSE_ECHO "Generating host keys..."
$DRY_RUN_CMD ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -a 32 -f "/etc/ssh/ssh_host_ed25519_key" -N ""
fi
'';
environment = {
packages = with pkgs; [
vim # or some other editor, e.g. nano or neovim
procps
inetutils
findutils
utillinux
tzdata
hostname
man
gnugrep
zip
unzip
fish
tmux
nano
ripgrep
git
openssh
just
nh
(pkgs.writeShellScriptBin "lg-rerouting" ''
${pkgs.lazygit}/bin/lazygit --path /storage/emulated/0/Documents/rerouting
'')
(pkgs.writeShellScriptBin "sshd-start" ''
echo "Starting sshd on port 8022"
${pkgs.openssh}/bin/sshd
'')
(pkgs.writeShellScriptBin "wake-ymir" ''
echo waking up ymir
${pkgs.wakeonlan}/bin/wakeonlan 04:7c:16:e6:d9:13
'')
# obsidian tools
# i need a background process that can just keep pulling and pushing changes just like the obsidian git plugin
# (pkgs.writeShellScriptBin "rerouting-sync-start" ''
# cd /storage/emulated/0/Documents/rerouting
# git pull
# git add --all
# git commit -m "Android sync"
# git push
# '')
(pkgs.writeShellScriptBin "rerouting-status" ''
cd /storage/emulated/0/Documents/rerouting
git fetch
git status
'')
(pkgs.writeShellScriptBin "rerouting-pull" ''
cd /storage/emulated/0/Documents/rerouting
git pull
'')
(pkgs.writeShellScriptBin "rerouting-push" ''
cd /storage/emulated/0/Documents/rerouting
git add --all
git commit -m "Android sync"
git push
'')
ani-cli
];
# Backup etc files instead of failing to activate generation if a file already exists in /etc
etcBackupExtension = ".bak";
etc."ssh/sshd_config".text = ''
AcceptEnv LANG LC_*
KbdInteractiveAuthentication no
PasswordAuthentication no
PermitRootLogin no
Port 8022
PrintMotd no
AuthorizedKeysFile /etc/ssh/authorized_keys.d/%u
'';
etc."ssh/authorized_keys.d/osbm".text = ''
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfnV+qqUCJf92npNW4Jy0hIiepCJFBDJHXBHnUlNX0k
'';
};
}

View file

@ -1,97 +0,0 @@
{
pkgs,
...
}:
{
user.userName = "osbm";
# Read the changelog before changing this value
system.stateVersion = "25.11";
# Set up nix for flakes
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
build.activation.sshd = ''
if [ ! -e /etc/ssh/ssh_host_ed25519_key ]; then
$VERBOSE_ECHO "Generating host keys..."
$DRY_RUN_CMD ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -a 32 -f "/etc/ssh/ssh_host_ed25519_key" -N ""
fi
'';
environment = {
packages = with pkgs; [
vim # or some other editor, e.g. nano or neovim
procps
inetutils
findutils
utillinux
tzdata
hostname
man
gnugrep
zip
unzip
fish
tmux
nano
ripgrep
git
openssh
just
nh
(pkgs.writeShellScriptBin "lg-rerouting" ''
${pkgs.lazygit}/bin/lazygit --path /storage/emulated/0/Documents/rerouting
'')
(pkgs.writeShellScriptBin "sshd-start" ''
echo "Starting sshd on port 8022"
${pkgs.openssh}/bin/sshd
'')
(pkgs.writeShellScriptBin "wake-ymir" ''
echo waking up ymir
${pkgs.wakeonlan}/bin/wakeonlan 04:7c:16:e6:d9:13
'')
# obsidian tools
# i need a background process that can just keep pulling and pushing changes just like the obsidian git plugin
# (pkgs.writeShellScriptBin "rerouting-sync-start" ''
# cd /storage/emulated/0/Documents/rerouting
# git pull
# git add --all
# git commit -m "Android sync"
# git push
# '')
(pkgs.writeShellScriptBin "rerouting-status" ''
cd /storage/emulated/0/Documents/rerouting
git fetch
git status
'')
(pkgs.writeShellScriptBin "rerouting-pull" ''
cd /storage/emulated/0/Documents/rerouting
git pull
'')
(pkgs.writeShellScriptBin "rerouting-push" ''
cd /storage/emulated/0/Documents/rerouting
git add --all
git commit -m "Android sync"
git push
'')
ani-cli
];
# Backup etc files instead of failing to activate generation if a file already exists in /etc
etcBackupExtension = ".bak";
etc."ssh/sshd_config".text = ''
AcceptEnv LANG LC_*
KbdInteractiveAuthentication no
PasswordAuthentication no
PermitRootLogin no
Port 8022
PrintMotd no
AuthorizedKeysFile /etc/ssh/authorized_keys.d/%u
'';
etc."ssh/authorized_keys.d/osbm".text = ''
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfnV+qqUCJf92npNW4Jy0hIiepCJFBDJHXBHnUlNX0k
'';
};
}

View file

@ -1,110 +0,0 @@
{ lib, ... }:
{
imports = [
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "none";
machineType = "server";
users = [ "osbm" ];
services = {
glance.enable = true;
# anubis.enable = true;
mailserver.enable = true;
nginx.enable = true;
forgejo.enable = true;
vaultwarden.enable = true;
immich.enable = true;
actual.enable = true;
firefox-syncserver.enable = true;
# seafile.enable = true;
};
hardware = {
sound.enable = false;
hibernation.enable = false;
disko = {
enable = true;
fileSystem = "zfs";
initrd-ssh = {
enable = true;
authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfnV+qqUCJf92npNW4Jy0hIiepCJFBDJHXBHnUlNX0k"
];
ethernetDrivers = [
"virtio_pci" # QEMU support
"virtio_net"
"virtio_pci"
"virtio_blk"
"virtio_balloon"
"virtio_console"
"virtio_gpu"
];
};
zfs = {
enable = true;
hostID = "0f7de22e";
root = {
useTmpfs = false; # Use ZFS root, not tmpfs
encrypt = true;
disk1 = "vda";
impermanenceRoot = true; # Wipe root on boot with ZFS snapshots
};
};
};
};
};
system.stateVersion = "25.11";
networking.hostName = "apollo";
# Enable zram swap
zramSwap.enable = true;
users.mutableUsers = false;
# Disable sudo lecture message
security.sudo.extraConfig = ''
Defaults lecture = never
'';
# server is in germany
time.timeZone = "Europe/Berlin"; # or "Europe/Amsterdam"
# Network configuration
networking = {
useDHCP = false;
interfaces.eth0 = {
useDHCP = false;
ipv4.addresses = [
{
address = "152.53.152.129";
prefixLength = 22;
}
];
ipv6.addresses = [
{
address = "2a00:11c0:47:3b2a::1";
prefixLength = 64;
}
];
};
defaultGateway = "152.53.152.1";
defaultGateway6 = {
address = "fe80::1";
interface = "eth0";
};
nameservers = [
"1.1.1.1"
"8.8.8.8"
]; # Cloudflare and Google DNS
};
# Override initrd kernel params for static IP
boot.kernelParams = [ "ip=152.53.152.129::152.53.152.1:255.255.252.0::eth0:none" ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -1,46 +0,0 @@
{
inputs,
pkgs,
lib,
...
}:
{
imports = [
(import "${inputs.mobile-nixos}/lib/configuration.nix" { device = "oneplus-enchilada"; })
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "gnome";
machineType = "mobile";
hardware.systemd-boot.enable = false; # Mobile devices use different bootloader
programs.graphical.enable = false;
};
# mobile-nixos needs aliases (uses nettools instead of net-tools)
nixpkgs = {
config = {
allowAliases = true;
allowUnfreePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"oneplus-sdm845-firmware-zstd"
"oneplus-sdm845-firmware"
];
};
system = "aarch64-linux";
};
# Minimal essential packages
environment.systemPackages = with pkgs; [
git
vim
wget
curl
lazygit
asciiquarium
neovim
kitty
];
system.stateVersion = "25.11";
}

View file

@ -1,48 +0,0 @@
{
inputs,
...
}:
{
imports = [
./sd-image.nix
"${inputs.nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix"
./hardware-configuration.nix
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "none";
fonts.enable = false;
services.tailscale.enable = true;
hardware.systemd-boot.enable = false; # SD card uses extlinux
};
system.stateVersion = "25.05";
networking.hostName = "harmonica";
networking = {
interfaces."wlan0".useDHCP = true;
wireless = {
enable = true;
interfaces = [ "wlan0" ];
networks = {
"House_Bayram" = {
psk = "PASSWORD";
};
"it_hurts_when_IP" = {
psk = "PASSWORD";
};
};
};
};
# NTP time sync.
services.timesyncd.enable = true;
security.sudo = {
enable = true;
wheelNeedsPassword = false;
};
services.getty.autologinUser = "osbm";
}

View file

@ -1,85 +0,0 @@
{
pkgs,
lib,
...
}:
{
# Some packages (ahci fail... this bypasses that) https://discourse.nixos.org/t/does-pkgs-linuxpackages-rpi3-build-all-required-kernel-modules/42509
nixpkgs.overlays = [
(_final: super: {
makeModulesClosure = x: super.makeModulesClosure (x // { allowMissing = true; });
})
];
zramSwap = {
enable = true;
algorithm = "zstd";
};
image.fileName = "zero2.img";
sdImage = {
# bzip2 compression takes loads of time with emulation, skip it. Enable this if you're low on space.
compressImage = false;
extraFirmwareConfig = {
# Give up VRAM for more Free System Memory
# - Disable camera which automatically reserves 128MB VRAM
start_x = 0;
# - Reduce allocation of VRAM to 16MB minimum for non-rotated (32MB for rotated)
gpu_mem = 16;
# Configure display to 800x600 so it fits on most screens
# * See: https://elinux.org/RPi_Configuration
hdmi_group = 2;
hdmi_mode = 8;
};
};
hardware = {
enableRedistributableFirmware = lib.mkForce false;
firmware = [ pkgs.raspberrypiWirelessFirmware ]; # Keep this to make sure wifi works
i2c.enable = true;
deviceTree.filter = "bcm2837-rpi-zero*.dtb";
deviceTree.overlays = [
{
name = "enable-i2c";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2837";
fragment@0 {
target = <&i2c1>;
__overlay__ {
status = "okay";
};
};
};
'';
}
];
};
boot = {
kernelPackages = pkgs.linuxKernel.packages.linux_rpi3;
initrd.availableKernelModules = [
"xhci_pci"
"usbhid"
"usb_storage"
];
loader = {
grub.enable = false;
generic-extlinux-compatible.enable = true;
};
extraModprobeConfig = ''
options brcmfmac roamoff=1 feature_disable=0x82000
'';
# Avoids warning: mdadm: Neither MAILADDR nor PROGRAM has been set. This will cause the `mdmon` service to crash.
# See: https://github.com/NixOS/nixpkgs/issues/254807
swraid.enable = lib.mkForce false;
};
nixpkgs.hostPlatform = "aarch64-linux";
}

View file

@ -1,39 +0,0 @@
# This module extends the official sd-image.nix with the following:
# - ability to add options to the config.txt firmware
{
config,
lib,
...
}:
{
options.sdImage = with lib; {
extraFirmwareConfig = mkOption {
type = types.attrs;
default = { };
description = lib.mdDoc ''
Extra configuration to be added to config.txt.
'';
};
};
config = {
sdImage.populateFirmwareCommands =
lib.mkIf ((lib.length (lib.attrValues config.sdImage.extraFirmwareConfig)) > 0)
(
let
# Convert the set into a string of lines of "key=value" pairs.
keyValueMap = name: value: name + "=" + toString value;
keyValueList = lib.mapAttrsToList keyValueMap config.sdImage.extraFirmwareConfig;
extraFirmwareConfigString = lib.concatStringsSep "\n" keyValueList;
in
lib.mkAfter ''
config=firmware/config.txt
# The initial file has just been created without write permissions. Add them to be able to append the file.
chmod u+w $config
echo "\n# Extra configuration" >> $config
echo "${extraFirmwareConfigString}" >> $config
chmod u-w $config
''
);
};
}

View file

@ -1,25 +0,0 @@
{
imports = [
./hardware-configuration.nix
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "none";
machineType = "server";
hardware.systemd-boot.enable = false; # Uses extlinux bootloader
};
system.stateVersion = "25.05";
networking.hostName = "harmonica";
# NTP time sync.
services.timesyncd.enable = true;
security.sudo = {
enable = true;
wheelNeedsPassword = false;
};
# services.getty.autologinUser = "osbm";
}

View file

@ -1,71 +0,0 @@
{
pkgs,
lib,
...
}:
{
# Some packages (ahci fail... this bypasses that) https://discourse.nixos.org/t/does-pkgs-linuxpackages-rpi3-build-all-required-kernel-modules/42509
nixpkgs.overlays = [
(_final: super: {
makeModulesClosure = x: super.makeModulesClosure (x // { allowMissing = true; });
})
];
zramSwap = {
enable = true;
algorithm = "zstd";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
fsType = "ext4";
};
hardware = {
enableRedistributableFirmware = lib.mkForce false;
firmware = [ pkgs.raspberrypiWirelessFirmware ]; # Keep this to make sure wifi works
i2c.enable = true;
deviceTree.filter = "bcm2837-rpi-zero*.dtb";
deviceTree.overlays = [
{
name = "enable-i2c";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2837";
fragment@0 {
target = <&i2c1>;
__overlay__ {
status = "okay";
};
};
};
'';
}
];
};
boot = {
kernelPackages = pkgs.linuxKernel.packages.linux_rpi3;
initrd.availableKernelModules = [
"xhci_pci"
"usbhid"
"usb_storage"
];
loader = {
grub.enable = false;
generic-extlinux-compatible.enable = true;
};
extraModprobeConfig = ''
options brcmfmac roamoff=1 feature_disable=0x82000
'';
# Avoids warning: mdadm: Neither MAILADDR nor PROGRAM has been set. This will cause the `mdmon` service to crash.
# See: https://github.com/NixOS/nixpkgs/issues/254807
swraid.enable = lib.mkForce false;
};
nixpkgs.hostPlatform = "aarch64-linux";
}

View file

@ -1,39 +0,0 @@
{
lib,
pkgs,
inputs,
...
}:
{
imports = [
"${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-graphical-calamares-plasma6.nix"
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
nixpkgs.config.allowUnfree = true;
# Set environment variable for allowing non-free packages
environment.sessionVariables = {
NIXPKGS_ALLOW_UNFREE = "1";
};
environment.systemPackages = with pkgs; [
# Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
git
curl
parted
nano
comma
just
age
neovim
wget
];
services.openssh.enable = true;
}

View file

@ -1,57 +0,0 @@
{
pkgs,
inputs,
...
}:
{
imports = [
inputs.raspberry-pi-nix.nixosModules.raspberry-pi
inputs.raspberry-pi-nix.nixosModules.sd-image
];
# bcm2711 for rpi 3, 3+, 4, zero 2 w
# bcm2712 for rpi 5
# See the docs at:
# https://www.raspberrypi.com/documentation/computers/linux_kernel.html#native-build-configuration
raspberry-pi-nix.board = "bcm2712";
time.timeZone = "America/Chicago";
users.users.root = {
initialPassword = "root";
};
# Define a user account. Don't forget to set a password with passwd.
users.users.osbm = {
isNormalUser = true;
extraGroups = [ "wheel" ]; # Enable sudo for the user.
initialPassword = "changeme";
};
networking = {
hostName = "pochita";
};
environment.systemPackages = with pkgs; [
neovim
git-lfs
git
wakeonlan
htop
unzip
zip
wget
];
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
nix.settings.trusted-users = [
"root"
"osbm"
];
nixpkgs.hostPlatform = "aarch64-linux";
services.openssh = {
enable = true;
};
system.stateVersion = "25.05";
}

View file

@ -1,41 +0,0 @@
{
pkgs,
inputs,
...
}:
{
imports = [
./hardware-configuration.nix
../../../modules/nixos
inputs.raspberry-pi-nix.nixosModules.raspberry-pi
inputs.nixos-hardware.nixosModules.raspberry-pi-5
];
osbmModules = {
desktopEnvironment = "none";
machineType = "server";
hardware.systemd-boot.enable = false; # Raspberry Pi uses init-script bootloader
services = {
wanikani-bypass-lessons.enable = true;
wanikani-fetch-data.enable = true;
wanikani-stats.enable = true;
};
};
zramSwap.enable = true;
networking.hostName = "pochita";
# log of shame: osbm blamed nix when he wrote "hostname" instead of "hostName"
environment.systemPackages = [
pkgs.raspberrypi-eeprom
];
# The board and wanted kernel version
raspberry-pi-nix = {
board = "bcm2712";
#kernel-version = "v6_10_12";
};
system.stateVersion = "25.05";
}

View file

@ -1,47 +0,0 @@
{
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd = {
availableKernelModules = [ ];
kernelModules = [ ];
};
kernelModules = [ ];
extraModulePackages = [ ];
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
fsType = "ext4";
};
"/boot/firmware" = {
device = "/dev/disk/by-uuid/2178-694E";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.end0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View file

@ -1,21 +0,0 @@
{
imports = [
./hardware-configuration.nix
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "plasma";
machineType = "laptop";
emulation.aarch64.enable = true;
hardware.sound.enable = true;
programs.steam.enable = true;
};
networking.hostName = "tartarus"; # Define your hostname.
# Enable networking
networking.networkmanager.enable = true;
system.stateVersion = "24.05"; # lalalalala
}

View file

@ -1,53 +0,0 @@
{
config,
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usb_storage"
"sd_mod"
];
initrd.kernelModules = [ ];
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/246d3df7-3578-44b2-8aee-c1ed33581184";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/33D0-6524";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [
{ device = "/dev/disk/by-uuid/b74b04db-c7ea-44e7-b3fe-15cd6d0cd851"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -1,18 +0,0 @@
{
imports = [
./hardware-configuration.nix
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "none";
machineType = "server";
services = {
hydra.enable = true;
atticd.enable = true;
cloudflared.enable = true;
};
};
networking.hostName = "wallfacer";
system.stateVersion = "25.05";
}

View file

@ -1,68 +0,0 @@
{
config,
lib,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [
"ahci"
"ehci_pci"
"megaraid_sas"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
initrd.kernelModules = [ ];
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/8270dba5-6d89-438a-90bd-d9f29b20cb5b";
fsType = "ext4";
};
"/boot" = {
device = "/dev/disk/by-uuid/A1EB-43F8";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
"/data/atreus" = {
device = "/dev/disk/by-uuid/1840c2af-fdb2-48b6-8555-2cecd1afb106";
fsType = "ext4";
};
# 500 gb nvme pcie
"/data/kasio" = {
device = "/dev/disk/by-uuid/af74aa48-8513-4e31-a4b7-9fdd138e0002";
fsType = "ext4";
};
};
swapDevices = [
{ device = "/dev/disk/by-uuid/534ea30c-2664-498b-915f-41b037eba01b"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno1np0.useDHCP = lib.mkDefault true;
# networking.interfaces.eno2np1.useDHCP = lib.mkDefault true;
# networking.interfaces.eno3.useDHCP = lib.mkDefault true;
# networking.interfaces.eno4.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -1,43 +0,0 @@
{
imports = [
./hardware-configuration.nix
../../../modules/nixos
];
osbmModules = {
desktopEnvironment = "plasma";
machineType = "desktop";
programs = {
adbFastboot.enable = true;
steam.enable = true;
};
emulation.aarch64.enable = true;
virtualisation.docker.enable = true;
hardware = {
hibernation.enable = false;
wakeOnLan.enable = true;
sound.enable = true;
nvidia.enable = true;
};
services = {
ollama.enable = true;
};
i18n.enable = true;
};
networking = {
hostName = "ymir"; # Define your hostname.
firewall.allowedTCPPorts = [
8889
8000
];
# Enable networking
networkmanager.enable = true;
};
virtualisation.waydroid.enable = true;
system.stateVersion = "25.05"; # changing this is a great taboo of the nixos world
}

View file

@ -1,78 +0,0 @@
_default:
@just --list --unsorted
check-git:
# git must be clean
test -z "$(git status --porcelain)"
[linux]
build *args: check-git
sudo nixos-rebuild build --flake . {{args}} |& nom
nvd diff /run/current-system ./result
[linux]
switch *args: check-git remove-hm-backup-files
#!/usr/bin/env sh
if [[ "$(hostname)" == "localhost" ]]; then
nix-on-droid switch --flake . {{args}}
else
nh os switch . {{args}} --accept-flake-config
fi
[macos]
switch *args: check-git
nh darwin switch . -- --accept-flake-config {{args}}
remove-hm-backup-files:
#!/usr/bin/env sh
if [ -f ~/.gtkrc-2.0.hmbak ]; then
rm ~/.gtkrc-2.0.hmbak
fi
test:
nh os test .
update:
nix flake update
check:
nix flake check
repl:
nix repl -f flake:nixpkgs
collect-garbage:
sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations old
# home-manager expire-generations now
sudo nix-collect-garbage --delete-older-than 3d
list-generations:
nixos-rebuild list-generations
build-sd-image-harmonica: check-git
nom build -L .#nixosConfigurations.harmonica-sd.config.system.build.sdImage
build-sd-image-pochita: check-git
nom build -L .#nixosConfigurations.pochita-sd.config.system.build.sdImage
build-iso: check-git
nom build -L .#nixosConfigurations.myISO.config.system.build.isoImage
flash-sd-image-harmonica:
# raise error because this command should be edited before running
false
nom build -L .#nixosConfigurations.harmonica-sd.config.system.build.sdImage
sudo dd if=result/sd-image/nixos-image-sd-card-25.05.20250224.0196c01-aarch64-linux.img of=/dev/sda bs=4M status=progress conv=fsync
setup-apollo-nixos:
nano /tmp/secret.key
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode destroy,format,mount --flake github:osbm/flake#apollo
sudo mkdir -p /mnt/etc/ssh
sudo ssh-keygen -t ed25519 -N "" -f /mnt/etc/ssh/initrd
sudo nixos-install --flake github:osbm/flake#apollo --root /mnt --no-root-passwd
sweep *args:
nix run github:jzbor/nix-sweep -- {{args}}

View file

@ -1,9 +0,0 @@
{ lib, ... }:
{
importList = lib.mapAttrsToList (name: _path: ./. + "/${name}") (
lib.filterAttrs (
filename: kind: filename != "default.nix" && (kind == "regular" || kind == "directory")
) (builtins.readDir ./.)
);
}

View file

@ -1,7 +0,0 @@
# Main module entry point
# Import the new NixOS module system
{
imports = [
./nixos
];
}

View file

@ -1,32 +0,0 @@
{ lib, ... }:
{
# Import all home-manager modules
imports = [
./programs
# no home manager services yet
# ./services
];
# Basic home-manager configuration
home.sessionVariables = {
EDITOR = lib.mkDefault "nvim";
};
home.shellAliases = {
c = "code .";
l = "eza --all --long --git --icons --group --sort size --header --group-directories-first";
ll = "eza --all --long --git --icons --group --sort name --header --group-directories-first";
free = "free -h";
df = "df -h";
du = "du -h";
lg = "lazygit";
onefetch = "onefetch -T prose -T programming -T data";
};
# Don't set stateVersion here - let it be set by the system configuration
# home.stateVersion should be set in the system's home-manager configuration
# Enable basic programs that most users want
programs.home-manager.enable = true;
}

View file

@ -1,40 +0,0 @@
{
lib,
pkgs,
nixosConfig,
...
}:
{
config = lib.mkMerge [
(lib.mkIf (nixosConfig != null && nixosConfig.osbmModules.desktopEnvironment != "none") {
# Set enableAlacritty to true by default when there's a desktop environment
programs.alacritty.enable = lib.mkDefault true;
})
{
programs.alacritty = {
settings = {
font = {
size = 14.0;
normal.family = "Cascadia Code";
};
terminal.shell = {
args = [
"new-session"
"-A"
"-s"
"general"
];
program = lib.getExe pkgs.tmux;
};
window = {
decorations = "None";
opacity = 1;
startup_mode = "Maximized";
};
env.TERM = "xterm-256color";
};
};
}
];
}

View file

@ -1,10 +0,0 @@
{
programs.bash = {
enable = true;
bashrcExtra = ''
if [ "dumb" == "$TERM" ] ; then
export TERM=xterm-256color
fi
'';
};
}

View file

@ -1,18 +0,0 @@
{
imports = [
./alacritty.nix
./bash.nix
./direnv.nix
./firefox.nix
./fish.nix
./ghostty.nix
./git.nix
./mpv.nix
./ssh.nix
./starship.nix
./tlrc.nix
./tmux.nix
./wezterm.nix
./zoxide.nix
];
}

View file

@ -1,6 +0,0 @@
{
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
}

View file

@ -1,115 +0,0 @@
{
lib,
nixosConfig ? null, # Receive the NixOS config
pkgs,
...
}:
{
config = lib.mkMerge [
# Auto-enable Firefox if system has a desktop environment
(lib.mkIf (nixosConfig != null && nixosConfig.osbmModules.desktopEnvironment != "none") {
# Set enableFirefox to true by default when there's a desktop environment
programs.firefox.enable = lib.mkDefault true;
})
# Firefox configuration
{
programs.firefox = {
# TODO Firefox fails as the closure contains a reference to stdenv.cc
# Relax this assertion until the underlying issue is fixed
# https://github.com/NixOS/nixpkgs/pull/457424
package = pkgs.firefox.overrideAttrs { disallowedRequisites = [ ]; };
languagePacks = [
"ja"
"tr"
"en-US"
];
policies = {
DisableTelemetry = true;
DisableFirefoxStudies = true;
EnableTrackingProtection = {
Value = true;
Locked = true;
Cryptomining = true;
Fingerprinting = true;
};
# DisablePocket = true;
DisableFirefoxAccounts = true;
DisableAccounts = true;
DisableFirefoxScreenshots = true;
StartPage = "previous-session";
# OverrideFirstRunPage = "";
# OverridePostUpdatePage = "";
# DontCheckDefaultBrowser = true;
DisplayBookmarksToolbar = "always"; # alternatives: "never" or "newtab"
# DisplayMenuBar = "default-off"; # alternatives: "always", "never" or "default-on"
# SearchBar = "unified"; # alternat
ExtensionSettings =
let
extension = shortId: uuid: {
name = uuid;
value = {
install_url = "https://addons.mozilla.org/en-US/firefox/downloads/latest/${shortId}/latest.xpi";
installation_mode = "normal_installed"; # i dont want to get the packages from a non-open source source
};
};
in
builtins.listToAttrs [
(extension "tree-style-tab" "treestyletab@piro.sakura.ne.jp")
(extension "ublock-origin" "uBlock0@raymondhill.net")
(extension "bitwarden-password-manager" "{446900e4-71c2-419f-a6a7-df9c091e268b}")
(extension "motivation-new-tab" "")
(extension "return-youtube-dislikes" "{762f9885-5a13-4abd-9c77-433dcd38b8fd}")
(extension "violentmonkey" "{aecec67f-0d10-4fa7-b7c7-609a2db280cf}")
(extension "vimium-ff" "{d7742d87-e61d-4b78-b8a1-b469842139fa}")
(extension "i-dont-care-about-cookies" "jid1-KKzOGWgsW3Ao4Q@jetpack")
# (extension "tabliss" "extension@tabliss.io")
# (extension "umatrix" "uMatrix@raymondhill.net")
# (extension "libredirect" "7esoorv3@alefvanoon.anonaddy.me")
(extension "clearurls" "{74145f27-f039-47ce-a470-a662b129930a}")
(extension "youtube-shorts-block" "")
];
# To add additional extensions, find it on addons.mozilla.org, find
# the short ID in the url (like https://addons.mozilla.org/en-US/firefox/addon/!SHORT_ID!/)
# Then, download the XPI by filling it in to the install_url template, unzip it,
# run `jq .browser_specific_settings.gecko.id manifest.json` or
# `jq .applications.gecko.id manifest.json` to get the UUID
};
profiles.default = {
id = 0;
name = "osbm";
userChrome = ''
#tabbrowser-tabs {
visibility: collapse;
}
'';
settings = {
# "Open previous windows and tabs"
"browser.startup.page" = 3;
"browser.contentblocking.category" = true;
"extensions.pocket.enabled" = false;
"extensions.screenshots.disabled" = true;
"browser.topsites.contile.enabled" = false;
"browser.formfill.enable" = false;
"browser.search.suggest.enabled" = false;
"browser.search.suggest.enabled.private" = false;
"browser.urlbar.suggest.searches" = false;
"browser.urlbar.showSearchSuggestionsFirst" = false;
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
"browser.newtabpage.activity-stream.feeds.snippets" = false;
"browser.newtabpage.activity-stream.section.highlights.includePocket" = false;
"browser.newtabpage.activity-stream.section.highlights.includeBookmarks" = false;
"browser.newtabpage.activity-stream.section.highlights.includeDownloads" = false;
"browser.newtabpage.activity-stream.section.highlights.includeVisited" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.system.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"ui.key.menuAccessKeyFocuses" = false;
};
};
};
}
];
}

View file

@ -1,15 +0,0 @@
{
programs.fish = {
enable = true;
interactiveShellInit = ''
set -g fish_greeting
'';
functions = {
gitu = ''
git add --all
git commit -m "$argv"
git push
'';
};
};
}

View file

@ -1,9 +0,0 @@
{ lib, nixosConfig, ... }:
{
config = lib.mkMerge [
(lib.mkIf (nixosConfig != null && nixosConfig.osbmModules.desktopEnvironment != "none") {
# Set enableGhostty to true by default when there's a desktop environment
programs.ghostty.enable = lib.mkDefault true;
})
];
}

View file

@ -1,54 +0,0 @@
{
programs.git = {
enable = true;
signing = {
format = "openpgp";
};
ignores = [
"*.pyc" # python
"*.swp" # vim
"__pycache__" # python
".DS_Store" # macOS
"result" # nix
"node_modules" # node
];
settings = {
user = {
email = "osbm@osbm.dev";
name = "osbm";
};
credential = {
helper = "store";
};
core = {
editor = "vim";
pager = "cat";
};
diff = {
wsErrorHighlight = "all";
};
init = {
defaultBranch = "main";
};
http = {
postBuffer = 1048576000;
};
https = {
postBuffer = 1048576000;
};
push = {
autoSetupRemote = true;
};
filter.lfs = {
clean = "git-lfs clean -- %f";
smudge = "git-lfs smudge -- %f";
process = "git-lfs filter-process";
required = true;
};
signing = {
signByDefault = true;
key = "3A264839184185CF";
};
};
};
}

View file

@ -1,18 +0,0 @@
{ lib, nixosConfig, ... }:
{
config = lib.mkMerge [
(lib.mkIf (nixosConfig != null && nixosConfig.osbmModules.desktopEnvironment != "none") {
programs.mpv.enable = lib.mkDefault true;
})
{
programs.mpv = {
config = {
hwdec = "auto";
vo = "gpu";
};
};
}
];
}

View file

@ -1,59 +0,0 @@
let
# define a block that just takes a hostname and returns attrset to not repeat the same fields
sshBlock = hostname: {
inherit hostname;
user = "osbm";
identityFile = "~/.ssh/id_ed25519";
extraOptions = {
# [ERROR] - (starship::print): Under a 'dumb' terminal (TERM=dumb).
"RemoteCommand" = "fish";
"RequestTTY" = "force";
};
hashKnownHosts = true;
compression = true;
};
# sshBlockAtreus is the same as sshBlock but with 8090 as the port
sshBlockAtreus = hostname: {
inherit hostname;
user = "osbm";
identityFile = "~/.ssh/id_ed25519";
port = 8022;
hashKnownHosts = true;
compression = true;
# fish not found error ???
};
in
{
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = {
ymir = sshBlock "192.168.0.2";
ymir-ts = sshBlock "ymir.curl-boga.ts.net";
atreus = sshBlockAtreus "192.168.0.3";
atreus-ts = sshBlockAtreus "atreus.curl-boga.ts.net";
tartarus = sshBlock "192.168.0.4";
tartarus-ts = sshBlock "tartarus.curl-boga.ts.net";
pochita = sshBlock "192.168.0.9";
pochita-ts = sshBlock "pochita.curl-boga.ts.net";
harmonica = sshBlock "192.168.0.11";
harmonica-ts = sshBlock "harmonica.curl-boga.ts.net";
wallfacer = sshBlock "192.168.0.5";
wallfacer-ts = sshBlock "wallfacer.curl-boga.ts.net";
prometheus = sshBlock "192.168.0.12";
prometheus-ts = sshBlock "prometheus.curl-boga.ts.net";
apollo = sshBlock "152.53.152.129";
apollo-ts = sshBlock "apollo.curl-boga.ts.net";
apollo-initrd = {
hostname = "152.53.152.129";
port = 2222;
user = "root";
identityFile = "~/.ssh/id_ed25519";
hashKnownHosts = true;
compression = true;
};
# artemis
};
};
}

View file

@ -1,18 +0,0 @@
{
programs.starship = {
enable = true;
enableFishIntegration = true;
settings = {
add_newline = false;
dart.disabled = true;
python.disabled = true;
nodejs.disabled = true;
c.disabled = true;
gradle.disabled = true;
java.disabled = true;
ruby.disabled = true;
rust.disabled = true;
typst.disabled = true;
};
};
}

View file

@ -1,94 +0,0 @@
{
pkgs,
config,
...
}:
# stolen from https://github.com/dmarcoux/dotfiles
{
home.packages = [ pkgs.tlrc ];
xdg.configFile."tlrc/config.toml".text = ''
[cache]
dir = "${config.xdg.cacheHome}/tlrc"
mirror = "https://github.com/tldr-pages/tldr/releases/latest/download"
auto_update = true
max_age = 336
languages = ["en", "tr", "ja"]
[output]
show_title = false
platform_title = false
show_hyphens = false
example_prefix = "- "
compact = true
raw_markdown = false
[indent]
title = 2
description = 2
bullet = 2
example = 4
[style.title]
color = "magenta"
background = "default"
bold = true
underline = false
italic = false
dim = false
strikethrough = false
[style.description]
color = "magenta"
background = "default"
bold = false
underline = false
italic = false
dim = false
strikethrough = false
[style.bullet]
color = "green"
background = "default"
bold = false
underline = false
italic = false
dim = false
strikethrough = false
[style.example]
color = "cyan"
background = "default"
bold = false
underline = false
italic = false
dim = false
strikethrough = false
[style.url]
color = "red"
background = "default"
bold = false
underline = false
italic = true
dim = false
strikethrough = false
[style.inline_code]
color = "yellow"
background = "default"
bold = false
underline = false
italic = true
dim = false
strikethrough = false
[style.placeholder]
color = "red"
background = "default"
bold = false
underline = false
italic = true
dim = false
strikethrough = false
'';
}

View file

@ -1,38 +0,0 @@
{
pkgs,
lib,
...
}:
{
programs.tmux = {
enable = true;
historyLimit = 100000;
baseIndex = 1;
shortcut = "s";
mouse = true;
shell = lib.getExe pkgs.fish;
plugins = with pkgs; [
tmuxPlugins.sensible
tmuxPlugins.better-mouse-mode
{
plugin = tmuxPlugins.dracula;
extraConfig = ''
set -g @dracula-plugins "cpu-usage ram-usage gpu-usage battery"
set -g @dracula-show-left-icon hostname
set -g @dracula-git-show-current-symbol
set -g @dracula-git-no-repo-message "no-git"
set -g @dracula-show-timezone false
set -g @dracula-ignore-lspci true
'';
}
];
extraConfig = ''
# Automatically renumber windows
set -g renumber-windows on
set -g allow-passthrough on
set -ga update-environment TERM
set -ga update-environment TERM_PROGRAM
set-option -g default-command "${lib.getExe pkgs.fish} -l"
'';
};
}

View file

@ -1,36 +0,0 @@
{
lib,
pkgs,
nixosConfig,
...
}:
{
config = lib.mkMerge [
(lib.mkIf (nixosConfig != null && nixosConfig.osbmModules.desktopEnvironment != "none") {
programs.wezterm.enable = lib.mkDefault true;
})
{
programs.wezterm = {
extraConfig = ''
_G.shells = {
fish = '${lib.getExe pkgs.fish}'
};
wezterm.on('gui-startup', function(cmd)
local tab, pane, window = wezterm.mux.spawn_window(cmd or {})
window:gui_window():maximize()
end)
return {
default_prog = { _G.shells.fish },
window_decorations = "NONE",
hide_tab_bar_if_only_one_tab = true,
enable_wayland = false,
}
'';
};
}
];
}

View file

@ -1,6 +0,0 @@
{
programs.zoxide = {
enable = true;
enableFishIntegration = true;
};
}

View file

@ -1,9 +0,0 @@
{
imports = [
./options.nix
./programs
./hardware
./services
./system
];
}

View file

@ -1,7 +0,0 @@
{ config, lib, ... }:
{
config = lib.mkIf config.osbmModules.hardware.bluetooth.enable {
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
};
}

View file

@ -1,8 +0,0 @@
{ config, lib, ... }:
{
config = lib.mkIf config.osbmModules.hardware.systemd-boot.enable {
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
};
}

View file

@ -1,11 +0,0 @@
{
imports = [
./bluetooth.nix
./boot.nix
./sound.nix
./nvidia.nix
./hibernation.nix
./wakeOnLan.nix
./disko.nix
];
}

View file

@ -1,341 +0,0 @@
{
config,
inputs,
lib,
pkgs,
...
}:
let
cfg = config.osbmModules.hardware.disko;
# Default authorized keys for initrd SSH
defaultAuthorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDF1TFwXbqdC1UyG75q3HO1n7/L3yxpeRLIq2kQ9DalI"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHYSJ9ywFRJ747tkhvYWFkx/Y9SkLqv3rb7T1UuXVBWo"
];
authorizedKeys =
if cfg.initrd-ssh.authorizedKeys != [ ] then
cfg.initrd-ssh.authorizedKeys
else
defaultAuthorizedKeys;
in
{
imports = [
inputs.disko.nixosModules.default
];
config = lib.mkMerge [
# Initrd SSH for remote unlocking
(lib.mkIf (cfg.enable && cfg.initrd-ssh.enable) {
boot = {
kernelParams = [ "ip=152.53.152.129::152.53.152.1:255.255.252.0::eth0:none" ];
initrd = {
network.enable = true;
availableKernelModules = cfg.initrd-ssh.ethernetDrivers;
network.ssh = {
enable = true;
port = 2222; # different port to avoid conflicts
shell = "/bin/cryptsetup-askpass";
inherit authorizedKeys;
hostKeys = [ "/etc/ssh/initrd" ];
};
secrets = {
"/etc/ssh/initrd" = "/etc/ssh/initrd";
};
};
};
})
# ZFS Configuration
(lib.mkIf (cfg.enable && cfg.zfs.enable) {
networking.hostId = cfg.zfs.hostID;
environment.systemPackages = [ pkgs.zfs-prune-snapshots ];
boot = {
# ZFS does not support swapfiles
kernelParams = [
"nohibernate"
"zfs.zfs_arc_max=17179869184" # 16GB ARC max
];
supportedFilesystems = [
"vfat"
"zfs"
];
zfs = {
devNodes = "/dev/disk/by-id/";
forceImportAll = true;
requestEncryptionCredentials = cfg.zfs.root.encrypt;
};
};
services.zfs = {
autoScrub.enable = true;
trim.enable = true;
};
# Disko configuration for ZFS
disko.devices = {
disk = lib.mkMerge [
# Storage pool disks (if enabled and not reinstalling)
(lib.mkIf (cfg.zfs.storage.enable && !cfg.amReinstalling) (
lib.mkMerge (
map (diskname: {
"${diskname}" = {
type = "disk";
device = "/dev/${diskname}";
content = {
type = "gpt";
partitions = {
luks = {
size = "100%";
content = {
type = "luks";
name = "stg${diskname}";
settings.allowDiscards = true;
passwordFile = "/tmp/secret.key";
content = {
type = "zfs";
pool = "zstorage";
};
};
};
};
};
};
}) cfg.zfs.storage.disks
)
))
# Root disk 1 (primary)
{
one = lib.mkIf (cfg.zfs.root.disk1 != "") {
type = "disk";
device = "/dev/${cfg.zfs.root.disk1}";
content = {
type = "gpt";
partitions = {
ESP = {
label = "EFI";
name = "ESP";
size = "2048M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
"umask=0077"
];
};
};
# Encrypted root partition
luks = lib.mkIf cfg.zfs.root.encrypt {
size = "100%";
content = {
type = "luks";
name = "crypted1";
settings.allowDiscards = true;
passwordFile = "/tmp/secret.key";
content = {
type = "zfs";
pool = "zroot";
};
};
};
# Unencrypted root partition
notluks = lib.mkIf (!cfg.zfs.root.encrypt) {
size = "100%";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
# Root disk 2 (mirror)
two = lib.mkIf (cfg.zfs.root.disk2 != "") {
type = "disk";
device = "/dev/${cfg.zfs.root.disk2}";
content = {
type = "gpt";
partitions = {
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted2";
settings.allowDiscards = true;
passwordFile = "/tmp/secret.key";
content = {
type = "zfs";
pool = "zroot";
};
};
};
};
};
};
}
];
# ZFS pools
zpool = {
# Root pool
zroot = {
type = "zpool";
mode = lib.mkIf cfg.zfs.root.mirror "mirror";
rootFsOptions = {
canmount = "off";
checksum = "edonr";
compression = "zstd";
dnodesize = "auto";
mountpoint = "none";
normalization = "formD";
relatime = "on";
"com.sun:auto-snapshot" = "false";
};
options = {
ashift = "12";
autotrim = "on";
};
datasets = {
# Reserved space for ZFS CoW operations
reserved = {
type = "zfs_fs";
options = {
canmount = "off";
mountpoint = "none";
inherit (cfg.zfs.root) reservation;
};
};
# SSH keys dataset
etcssh = {
type = "zfs_fs";
options.mountpoint = "legacy";
mountpoint = "/etc/ssh";
options."com.sun:auto-snapshot" = "false";
postCreateHook = "zfs snapshot zroot/etcssh@empty";
};
# Persistent data
persist = {
type = "zfs_fs";
options.mountpoint = "legacy";
mountpoint = "/persist";
options."com.sun:auto-snapshot" = "false";
postCreateHook = "zfs snapshot zroot/persist@empty";
};
# Persistent save data
persistSave = {
type = "zfs_fs";
options.mountpoint = "legacy";
mountpoint = "/persist/save";
options."com.sun:auto-snapshot" = "false";
postCreateHook = "zfs snapshot zroot/persistSave@empty";
};
# Nix store
nix = {
type = "zfs_fs";
options.mountpoint = "legacy";
mountpoint = "/nix";
options = {
atime = "off";
canmount = "on";
"com.sun:auto-snapshot" = "false";
};
postCreateHook = "zfs snapshot zroot/nix@empty";
};
# Root filesystem
root = {
type = "zfs_fs";
options.mountpoint = "legacy";
options."com.sun:auto-snapshot" = "false";
mountpoint = "/";
postCreateHook = "zfs snapshot zroot/root@empty";
};
};
};
# Storage pool (if enabled and not reinstalling)
zstorage = lib.mkIf (cfg.zfs.storage.enable && !cfg.amReinstalling) {
type = "zpool";
mode = lib.mkIf cfg.zfs.storage.mirror "mirror";
rootFsOptions = {
canmount = "off";
checksum = "edonr";
compression = "zstd";
dnodesize = "auto";
mountpoint = "none";
normalization = "formD";
relatime = "on";
"com.sun:auto-snapshot" = "false";
};
options = {
ashift = "12";
autotrim = "on";
};
datasets = {
# Reserved space
reserved = {
type = "zfs_fs";
options = {
canmount = "off";
mountpoint = "none";
inherit (cfg.zfs.storage) reservation;
};
};
# Main storage
storage = {
type = "zfs_fs";
mountpoint = "/storage";
options = {
atime = "off";
canmount = "on";
"com.sun:auto-snapshot" = "false";
};
};
# Persistent save in storage
persistSave = {
type = "zfs_fs";
mountpoint = "/storage/save";
options = {
atime = "off";
canmount = "on";
"com.sun:auto-snapshot" = "false";
};
};
};
};
};
};
fileSystems = {
# Needed for agenix - SSH keys must be available before ZFS mounts
"/etc/ssh".neededForBoot = true;
# Needed for impermanence
"/persist".neededForBoot = true;
"/persist/save".neededForBoot = true;
};
})
# Impermanence: wipe root on boot
(lib.mkIf (cfg.enable && cfg.zfs.enable && cfg.zfs.root.impermanenceRoot) {
boot.initrd.postResumeCommands = lib.mkAfter ''
zfs rollback -r zroot/root@empty
'';
})
];
}

View file

@ -1,12 +0,0 @@
{ lib, config, ... }:
{
config = lib.mkIf (!config.osbmModules.hardware.hibernation.enable) {
# Disable hibernation/suspend
systemd.targets = {
sleep.enable = false;
suspend.enable = false;
hibernate.enable = false;
hybrid-sleep.enable = false;
};
};
}

View file

@ -1,68 +0,0 @@
{
lib,
config,
pkgs,
...
}:
{
config = lib.mkIf config.osbmModules.hardware.nvidia.enable {
# Enable OpenGL
hardware.graphics = {
enable = true;
};
nixpkgs.config = {
cudaSupport = true;
cudaCapabilities = [ "8.9" ]; # 4090
};
# Load nvidia driver for Xorg and Wayland
services.xserver.videoDrivers = [ "nvidia" ];
hardware = {
nvidia = {
# Modesetting is required.
modesetting.enable = true;
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
# Enable this if you have graphical corruption issues or application crashes after waking
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
# of just the bare essentials.
powerManagement = {
enable = false;
# Fine-grained power management. Turns off GPU when not in use.
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
finegrained = false;
};
# Use the NVidia open source kernel module (not to be confused with the
# independent third-party "nouveau" open source driver).
# Support is limited to the Turing and later architectures. Full list of
# supported GPUs is at:
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
# Only available from driver 515.43.04+
# Currently alpha-quality/buggy, so false is currently the recommended setting.
open = false;
# Enable the Nvidia settings menu,
# accessible via `nvidia-settings`
nvidiaSettings = true;
# Optionally, you may need to select the appropriate driver version for your specific GPU.
package = config.boot.kernelPackages.nvidiaPackages.latest;
};
nvidia-container-toolkit.enable = lib.mkIf config.osbmModules.virtualisation.docker.enable true;
};
environment.systemPackages = [
pkgs.nvidia-container-toolkit
];
# TODO explain why this is needed
programs.nix-required-mounts = {
enable = true;
presets.nvidia-gpu.enable = true;
};
};
}

View file

@ -1,20 +0,0 @@
{ lib, config, ... }:
{
config = lib.mkIf config.osbmModules.hardware.sound.enable {
# Disable PulseAudio
services.pulseaudio.enable = false;
# Enable rtkit for realtime audio
security.rtkit.enable = true;
# Enable PipeWire
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications:
# jack.enable = true;
};
};
}

View file

@ -1,25 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.hardware.wakeOnLan.enable {
networking.interfaces.enp3s0.wakeOnLan.enable = true;
# The services doesn't actually work atm, define an additional service
# see https://github.com/NixOS/nixpkgs/issues/91352
systemd.services.wakeonlan = {
description = "Reenable wake on lan every boot";
after = [ "network.target" ];
serviceConfig = {
Type = "simple";
RemainAfterExit = "true";
ExecStart = "${pkgs.ethtool}/sbin/ethtool -s enp3s0 wol g";
};
wantedBy = [ "default.target" ];
};
})
];
}

View file

@ -1,411 +0,0 @@
{ lib, config, ... }:
{
options.osbmModules = {
# Desktop Environment
desktopEnvironment = lib.mkOption {
type = lib.types.enum [
"plasma"
"gnome"
"none"
];
default = "none";
description = "Which desktop environment to use";
};
# Machine Type
machineType = lib.mkOption {
type = lib.types.enum [
"desktop"
"laptop"
"server"
"embedded"
"mobile"
];
default = "server";
description = "Type of machine for appropriate defaults";
};
# Users
users = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"osbm"
]
++ lib.optionals (
config.osbmModules.machineType == "desktop" || config.osbmModules.machineType == "laptop"
) [ "bayram" ];
description = "List of users to create. `osbm` is my main user, and `bayram` is for my family (only on desktop/laptop).";
};
defaultUser = lib.mkOption {
type = lib.types.str;
default = "osbm";
description = "Default user for the system";
};
# Home Manager
homeManager = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable home-manager integration";
};
};
# Agenix
agenix = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable agenix for secrets management";
};
};
# Nix Settings
nixSettings = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable custom nix settings";
};
};
# Programs
programs = {
steam = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Steam gaming platform";
};
};
graphical = {
enable = lib.mkOption {
type = lib.types.bool;
default = config.osbmModules.desktopEnvironment != "none";
description = "Enable graphical applications";
};
};
commandLine = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable common command line tools";
};
};
neovim = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable neovim with custom configuration";
};
};
arduino = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Arduino IDE and development tools";
};
};
adbFastboot = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable ADB and Fastboot for Android development";
};
};
};
# Services
services = {
openssh = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable OpenSSH server";
};
};
tailscale = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable Tailscale VPN";
};
};
actual.enable = lib.mkEnableOption "actual";
anubis.enable = lib.mkEnableOption "anubis";
syncthing.enable = lib.mkEnableOption "syncthing";
jellyfin.enable = lib.mkEnableOption "jellyfin";
mailserver.enable = lib.mkEnableOption "mailserver";
firefox-syncserver.enable = lib.mkEnableOption "firefox-syncserver";
vaultwarden.enable = lib.mkEnableOption "vaultwarden";
nginx.enable = lib.mkEnableOption "nginx";
ollama.enable = lib.mkEnableOption "ollama";
forgejo.enable = lib.mkEnableOption "forgejo";
atticd.enable = lib.mkEnableOption "atticd";
cloudflared.enable = lib.mkEnableOption "cloudflared";
cloudflare-dyndns.enable = lib.mkEnableOption "cloudflare-dyndns";
glance.enable = lib.mkEnableOption "glance";
hydra.enable = lib.mkEnableOption "hydra";
immich.enable = lib.mkEnableOption "immich";
vscode-server.enable = lib.mkEnableOption "vscode-server";
wanikani-bypass-lessons.enable = lib.mkEnableOption "wanikani-bypass-lessons";
wanikani-fetch-data.enable = lib.mkEnableOption "wanikani-fetch-data";
wanikani-stats.enable = lib.mkEnableOption "wanikani-stats";
};
# Hardware
hardware = {
bluetooth = {
enable = lib.mkOption {
type = lib.types.bool;
default = config.osbmModules.desktopEnvironment != "none";
description = "Enable Bluetooth support";
};
};
sound = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable sound with pipewire";
};
};
nvidia = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable NVIDIA proprietary drivers";
};
};
hibernation = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable hibernation support";
};
};
wakeOnLan = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable wake-on-LAN support";
};
};
systemd-boot.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Use systemd-boot bootloader";
};
# Disko configuration (inspired by ZFS.nix)
disko = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable custom disk configuration with disko";
};
amReinstalling = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Am I reinstalling and want to save the storage pool";
};
fileSystem = lib.mkOption {
type = lib.types.enum [
"zfs"
"ext4"
];
default = "ext4";
description = "Root filesystem type";
};
initrd-ssh = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable SSH in initrd for remote unlocking";
};
authorizedKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "SSH public keys for initrd access";
};
ethernetDrivers = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Ethernet drivers to load in initrd";
};
};
zfs = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable ZFS filesystem";
};
hostID = lib.mkOption {
type = lib.types.str;
default = "";
description = "ZFS host ID (8 hex characters)";
};
root = {
useTmpfs = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Use tmpfs for root instead of ZFS (with ZFS datasets for /nix and /persist)";
};
tmpfsSize = lib.mkOption {
type = lib.types.str;
default = "2G";
description = "Size of tmpfs root filesystem";
};
encrypt = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Encrypt root ZFS pool";
};
disk1 = lib.mkOption {
type = lib.types.str;
default = "";
description = "First disk device name (e.g., nvme0n1)";
};
disk2 = lib.mkOption {
type = lib.types.str;
default = "";
description = "Second disk device name for mirroring";
};
reservation = lib.mkOption {
type = lib.types.str;
default = "20G";
description = "ZFS reservation size";
};
mirror = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Mirror the root ZFS pool";
};
impermanenceRoot = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Wipe the root directory on boot (impermanence)";
};
};
storage = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable separate storage ZFS pool";
};
disks = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Storage pool disk device names";
};
reservation = lib.mkOption {
type = lib.types.str;
default = "20G";
description = "Storage pool ZFS reservation";
};
mirror = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Mirror the storage ZFS pool";
};
};
};
};
};
virtualisation = {
docker = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Docker";
};
};
podman = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable Podman";
};
};
libvirt = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable libvirt/KVM";
};
};
};
# Emulation
emulation = {
aarch64 = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable aarch64 emulation via binfmt";
};
};
};
# Internationalization
i18n = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable internationalization settings";
};
};
# Fonts
fonts = {
enable = lib.mkOption {
type = lib.types.bool;
default = config.osbmModules.desktopEnvironment != "none";
description = "Enable custom fonts";
};
};
# Nix Index
nixIndex = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable nix-index for command-not-found";
};
};
};
}

View file

@ -1,9 +0,0 @@
{ lib, config, ... }:
{
config = lib.mkIf config.osbmModules.programs.adbFastboot.enable {
programs.adb.enable = true;
# Add default user to adbusers group
users.users.${config.osbmModules.defaultUser}.extraGroups = [ "adbusers" ];
};
}

View file

@ -1,20 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
config = lib.mkIf config.osbmModules.programs.arduino.enable {
environment.systemPackages = with pkgs; [
arduino-ide
adafruit-nrfutil
python3 # some arduino libraries require python3
];
services.udev.extraRules = ''
KERNEL=="ttyUSB[0-9]*",MODE="0666"
KERNEL=="ttyACM[0-9]*",MODE="0666"
'';
};
}

View file

@ -1,75 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
config = lib.mkIf config.osbmModules.programs.commandLine.enable {
environment.systemPackages = with pkgs; [
# networking
wget
curl
dig
# text editors
nano
# version control
git
lazygit
git-lfs
gh
# nix tools
nix-output-monitor
nixd
nix-inspect
comma
nh
# information and vanity
neofetch
onefetch
pfetch
htop
btop
cloc
inxi
tlrc
pciutils
# basic quality of life
eza
dysk
trash-cli
zoxide
lazysql
jq
ripgrep
dust
bat
just
tree
fd
yazi
duf
# archives
zip
unzip
# shell
fish
starship
# multiplexers
tmux
(pkgs.writeShellScriptBin "wake-ymir" ''
echo waking up ymir
${pkgs.wakeonlan}/bin/wakeonlan 04:7c:16:e6:d9:13
'')
];
};
}

View file

@ -1,10 +0,0 @@
{
imports = [
./adb-fastboot.nix
./arduino.nix
./command-line.nix
./graphical.nix
./neovim.nix
./steam.nix
];
}

View file

@ -1,23 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
config = lib.mkIf config.osbmModules.programs.graphical.enable {
environment.systemPackages = with pkgs; [
mpv
gimp
inkscape
libreoffice
discord
telegram-desktop
obs-studio
blender
vscode
chromium
thunderbird
];
};
}

View file

@ -1,19 +0,0 @@
{
lib,
inputs,
config,
pkgs,
...
}:
{
config = lib.mkIf config.osbmModules.programs.neovim.enable {
environment.systemPackages = [
inputs.osbm-nvim.packages."${pkgs.stdenv.hostPlatform.system}".default
];
# Environment variables
environment.variables = {
EDITOR = "nvim";
VISUAL = "nvim";
};
};
}

View file

@ -1,14 +0,0 @@
{ lib, config, ... }:
{
config = lib.mkIf config.osbmModules.programs.steam.enable {
programs.steam = {
enable = true;
# Open ports in the firewall for Steam Remote Play
remotePlay.openFirewall = true;
# Open ports in the firewall for Source Dedicated Server
dedicatedServer.openFirewall = true;
# Open ports in the firewall for Steam Local Network Game Transfers
localNetworkGameTransfers.openFirewall = true;
};
};
}

View file

@ -1,54 +0,0 @@
{ config, lib, ... }:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.actual.enable {
services.actual = {
enable = true;
settings = {
port = 51514;
# dataDir = "/var/lib/actual"
};
};
})
# actual and nginx
(lib.mkIf (config.osbmModules.services.nginx.enable && config.osbmModules.services.actual.enable) {
services.nginx.virtualHosts."actual.osbm.dev" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.actual.settings.port}";
proxyWebsockets = true;
};
};
})
# # impermanence and immich
# (lib.mkIf
# (
# config.osbmModules.services.immich.enable
# && config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
# )
# {
# environment.persistence."/persist" = {
# directories = [
# {
# directory = "/var/lib/immich";
# user = config.services.immich.user;
# group = config.services.immich.group;
# mode = "0750";
# }
# {
# directory = "/var/lib/postgresql";
# user = "postgres";
# group = "postgres";
# mode = "0750";
# }
# ];
# };
# }
# )
];
}

View file

@ -1,14 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.anubis.enable {
services.anubis = {
# enable = true;
};
})
];
}

View file

@ -1,43 +0,0 @@
{
config,
lib,
...
}:
let
atticdPort = 7080;
in
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.atticd.enable {
services.atticd = {
enable = true;
environmentFile = "/persist/attic.env";
settings = {
listen = "[::]:${toString atticdPort}";
compression = {
type = "zstd";
level = 9;
};
# jwt = { };
# storage = {
# type = "local";
# # path = "/data/atreus/attic";
# # there is an issue
# };
};
};
networking.firewall.allowedTCPPorts = [ atticdPort ];
services.cloudflared.tunnels = {
"fa301a21-b259-4149-b3d0-b1438c7c81f8" = {
default = "http_status:404";
credentialsFile = "/home/osbm/.cloudflared/fa301a21-b259-4149-b3d0-b1438c7c81f8.json";
ingress = {
"cache.osbm.dev" = {
service = "http://localhost:${toString atticdPort}";
};
};
};
};
})
];
}

View file

@ -1,19 +0,0 @@
{
lib,
config,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.cloudflare-dyndns.enable {
services.cloudflare-dyndns = {
enable = true;
apiTokenFile = "/persist/cloudflare-dyndns";
proxied = false; # TODO please revert
domains = [
"git.osbm.dev"
];
};
})
];
}

View file

@ -1,15 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.cloudflared.enable {
services.cloudflared = {
enable = true;
certificateFile = "/home/osbm/.cloudflared/cert.pem";
};
})
];
}

View file

@ -1,29 +0,0 @@
{
imports = [
./actual.nix
./anubis.nix
./atticd.nix
./cloudflare-dyndns.nix
./cloudflared.nix
./ollama.nix
./openssh.nix
./firefox-syncserver.nix
./forgejo.nix
./glance.nix
./hydra.nix
./immich.nix
./jellyfin.nix
./mailserver.nix
./nginx.nix
./syncthing.nix
./tailscale.nix
./vaultwarden.nix
./vscode-server.nix
# custom services
./system-logger
./wanikani-bypass-lessons.nix
./wanikani-fetch-data
./wanikani-stats
];
}

View file

@ -1,69 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.firefox-syncserver.enable {
services.mysql.package = pkgs.mariadb; # Use MariaDB as the database backend
services.firefox-syncserver = {
enable = true;
secrets = "/persist/firefox-syncserver-secrets.env"; # TODO: Make this into agenix secret
logLevel = "trace";
singleNode = {
enable = true;
url = "https://firefox.osbm.dev";
capacity = 1;
};
settings = {
host = "0.0.0.0";
# Override database URLs to use Unix socket for authentication
# This allows the firefox-syncserver user to authenticate via unix_socket
syncstorage.database_url = "mysql://firefox-syncserver@localhost/firefox_syncserver?socket=%2Frun%2Fmysqld%2Fmysqld.sock";
tokenserver.database_url = "mysql://firefox-syncserver@localhost/firefox_syncserver?socket=%2Frun%2Fmysqld%2Fmysqld.sock";
};
};
})
# firefox-syncserver and nginx
(lib.mkIf
(config.osbmModules.services.nginx.enable && config.osbmModules.services.firefox-syncserver.enable)
{
services.nginx.virtualHosts."firefox.osbm.dev" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.firefox-syncserver.settings.port}";
};
};
}
)
# impermanence and firefox-syncserver
(lib.mkIf
(
config.osbmModules.services.firefox-syncserver.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
systemd.services.firefox-syncserver.serviceConfig.ReadWritePaths = [
"/var/lib/firefox-syncserver"
];
environment.persistence."/persist" = {
directories = [
{
directory = "/var/lib/firefox-syncserver";
user = config.systemd.services.firefox-syncserver.serviceConfig.User;
group = config.systemd.services.firefox-syncserver.serviceConfig.Group;
mode = "0750";
}
];
};
}
)
];
}

View file

@ -1,91 +0,0 @@
{
lib,
config,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.forgejo.enable {
services.forgejo = {
enable = true;
lfs.enable = true;
dump = {
enable = true;
type = "zip";
interval = "01:01";
};
settings = {
DEFAULT = {
APP_NAME = "osbm's self hosted git service";
};
server = {
DOMAIN = "git.osbm.dev";
ROOT_URL = "https://git.osbm.dev/";
};
"ui.meta" = {
AUTHOR = "osbm";
DESCRIPTION = "\"After all, all devices have their dangers. The discovery of speech introduced communication and lies.\" -Isaac Asimov";
KEYWORDS = "git,self-hosted,gitea,forgejo,osbm,open-source,nix,nixos";
};
service = {
DISABLE_REGISTRATION = true;
LANDING_PAGE = "/osbm";
};
};
};
})
(lib.mkIf
(config.osbmModules.services.cloudflared.enable && config.osbmModules.services.forgejo.enable)
{
services.cloudflared.tunnels = {
"eb9052aa-9867-482f-80e3-97a7d7e2ef04" = {
default = "http_status:404";
credentialsFile = "/home/osbm/.cloudflared/eb9052aa-9867-482f-80e3-97a7d7e2ef04.json";
ingress = {
"${config.services.forgejo.settings.server.DOMAIN}" = {
service = "http://localhost:3000";
};
};
};
};
}
)
(lib.mkIf (config.osbmModules.services.nginx.enable && config.osbmModules.services.forgejo.enable) {
services.nginx.virtualHosts."${config.services.forgejo.settings.server.DOMAIN}" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://localhost:3000";
locations."/".proxyWebsockets = true;
};
})
(lib.mkIf
(
config.osbmModules.services.forgejo.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
# environment.persistence."/persist" = {
# directories = [
# {
# directory = "/var/lib/forgejo";
# user = config.services.forgejo.user;
# group = config.services.forgejo.group;
# mode = "0750";
# }
# ];
# };
# # forgejo-secrets service keep giving error
# systemd.services."forgejo-secrets" = {
# wants = [ "var-lib-forgejo.mount" ];
# after = [ "var-lib-forgejo.mount" ];
# };
# fuckass thing
services.forgejo.stateDir = "/persist/var/lib/forgejo";
}
)
];
}

View file

@ -1,181 +0,0 @@
{
lib,
config,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.glance.enable {
services.glance = {
enable = true;
openFirewall = true;
settings = {
server = {
port = 3838;
host = "0.0.0.0";
};
branding = {
# stolen from notohh/snowflake but i love it so much
custom-footer = ''<b><p></p></b>'';
};
pages = [
{
columns = [
{
size = "small";
widgets = [
{ type = "calendar"; }
{
type = "bookmarks";
groups = [
{
title = "My Profiles";
same-tab = true;
color = "200 50 50";
links = [
{
title = "GitHub";
url = "https://github.com/osbm";
}
{
title = "Gitlab";
url = "https://gitlab.com/osbm";
}
{
title = "Crates.io";
url = "https://crates.io/users/osbm";
}
{
title = "HuggingFace";
url = "https://huggingface.co/osbm";
}
{
title = "Bluesky";
url = "https://bsky.app/profile/osbm.dev";
}
{
title = "Docker Hub";
url = "https://hub.docker.com/u/osbm";
}
{
title = "Kaggle";
url = "https://www.kaggle.com/osmanf";
}
];
}
{
title = "Documents";
links = [
{
title = "Nixos Search";
url = "https://search.nixos.org";
}
];
}
];
}
];
}
{
size = "full";
widgets = [
{
type = "search";
search-engine = "google";
bangs = [
{
title = "youtube";
shortcut = "!yt";
url = "https://www.youtube.com/results?search_query={QUERY}";
}
{
title = "nixpkgs";
shortcut = "!np";
url = "https://search.nixos.org/packages?channel=unstable&query={QUERY}";
}
{
title = "nixos";
shortcut = "!no";
url = "https://search.nixos.org/options?channel=unstable&query={QUERY}";
}
];
}
{
cache = "1m";
sites = [
{
icon = "sh:forgejo";
title = "Forgejo git server";
url = "https://git.osbm.dev";
}
{
icon = "sh:bitwarden";
title = "Bitwarden Vault";
url = "https://bitwarden.osbm.dev";
}
{
icon = "sh:visual-studio-code";
title = "Ymir Remote VSCode";
url = "http://ymir.curl-boga.ts.net:4444/";
}
{
icon = "sh:visual-studio-code";
title = "Tartarus Remote VSCode";
url = "http://tartarus.curl-boga.ts.net:4444/";
}
{
icon = "sh:visual-studio-code";
title = "Wallfacer Remote VSCode";
url = "http://wallfacer.curl-boga.ts.net:4444/";
}
{
icon = "si:json";
title = "Wanikani Stats";
url = "http://pochita:8501";
}
];
title = "Services";
type = "monitor";
}
];
}
];
name = "Home";
content = "Welcome to osbm's home page!";
}
];
};
};
networking.firewall.allowedTCPPorts = [ config.services.glance.settings.server.port ];
})
(lib.mkIf
(config.osbmModules.services.cloudflared.enable && config.osbmModules.services.glance.enable)
{
services.cloudflared.tunnels = {
"91b13f9b-81be-46e1-bca0-db2640bf2d0a" = {
default = "http_status:404";
credentialsFile = "/home/osbm/.cloudflared/91b13f9b-81be-46e1-bca0-db2640bf2d0a.json";
ingress = {
"home.osbm.dev" = {
service = "http://localhost:${toString config.services.glance.settings.server.port}";
};
};
};
};
}
)
# if nginx and glance are both enabled, set up a reverse proxy
(lib.mkIf (config.osbmModules.services.nginx.enable && config.osbmModules.services.glance.enable) {
services.nginx.virtualHosts."home.osbm.dev" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.glance.settings.server.port}";
proxyWebsockets = true;
};
};
})
];
}

View file

@ -1,22 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.hydra.enable {
services.hydra = {
enable = true;
port = 3000;
hydraURL = "http://${config.networking.hostName}.curl-boga.ts.net/hydra/";
notificationSender = "hydra@localhost";
buildMachinesFiles = [ ];
useSubstitutes = true;
};
networking.firewall.allowedTCPPorts = [
config.services.hydra.port
];
})
];
}

View file

@ -1,48 +0,0 @@
{ config, lib, ... }:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.immich.enable {
services.immich = {
enable = true;
};
})
# immich and nginx
(lib.mkIf (config.osbmModules.services.nginx.enable && config.osbmModules.services.immich.enable) {
services.nginx.virtualHosts."immich.osbm.dev" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.immich.port}";
proxyWebsockets = true;
};
};
})
# impermanence and immich
(lib.mkIf
(
config.osbmModules.services.immich.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
environment.persistence."/persist" = {
directories = [
{
directory = "/var/lib/immich";
inherit (config.services.immich) user group;
mode = "0750";
}
{
directory = "/var/lib/postgresql";
user = "postgres";
group = "postgres";
mode = "0750";
}
];
};
}
)
];
}

View file

@ -1,20 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.jellyfin.enable {
services.jellyfin = {
enable = true;
openFirewall = true;
user = "osbm";
group = "users";
dataDir = "/home/osbm/.local/share/jellyfin";
};
networking.firewall.allowedTCPPorts = [ 8096 ];
})
];
}

View file

@ -1,90 +0,0 @@
{
config,
inputs,
lib,
...
}:
{
imports = [
inputs.simple-nixos-mailserver.nixosModule
];
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.mailserver.enable {
mailserver = {
enable = true;
stateVersion = 3;
fqdn = "mail.osbm.dev";
domains = [ "osbm.dev" ];
# A list of all login accounts. To create the password hashes, use
# nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt'
loginAccounts = {
"osbm@osbm.dev" = {
hashedPasswordFile = "/persist/osbm.passwd"; # TODO: Make this into agenix secret
aliases = [ "postmaster@osbm.dev" ];
};
};
# Use Let's Encrypt certificates. Note that this needs to set up a stripped
# down nginx and opens port 80.
certificateScheme = "acme-nginx";
};
})
# mailserver and impermanence
(lib.mkIf
(
config.osbmModules.services.mailserver.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
environment.persistence."/persist" = {
directories = [
# Dovecot is an open source IMAP and POP3 server
# which means it handles email retrieval for users.
"/var/lib/dovecot" # owned by root
# Postfix is a open-source mail transfer agent (MTA)
"/var/lib/postfix" # owned by root
# Rspamd is a open-source spam filtering system.
{
directory = "/var/lib/rspamd";
user = "rspamd";
group = "rspamd";
mode = "0700";
}
# redis-rspamd is just a redis instance used by rspamd for caching
# TODO: what is the /var/spool folder?
{
directory = "/var/spool/redis-rspamd";
user = "redis-rspamd";
group = "redis-rspamd";
mode = "0750";
}
# Sieve is a scripting language for filtering email messages.
{
directory = config.mailserver.sieveDirectory; # /var/sieve by default
user = "virtualMail";
group = "virtualMail";
mode = "0770";
}
# Mail folder
{
directory = config.mailserver.mailDirectory; # /var/vmail by default
user = config.mailserver.vmailUserName;
group = config.mailserver.vmailGroupName;
mode = "0700";
}
# DKIM is used to sign outgoing emails to verify they are from the claimed domain.
{
directory = config.mailserver.dkimKeyDirectory; # /var/dkim by default
user = "rspamd";
group = "rspamd";
mode = "0755";
}
];
};
}
)
];
}

View file

@ -1,43 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.nginx.enable {
services.nginx = {
enable = true;
};
networking.firewall.allowedTCPPorts = [
80
443
];
security.acme = {
acceptTerms = true;
defaults.email = "osbm@osbm.dev";
};
})
(lib.mkIf
(
config.osbmModules.services.nginx.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
# environment.persistence."/persist" = {
# directories = [
# {
# directory = "/var/lib/acme";
# user = "acme";
# group = "nginx";
# mode = "0750";
# }
# ];
# };
}
)
];
}

View file

@ -1,33 +0,0 @@
{
lib,
config,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.ollama.enable {
services.ollama = {
enable = true;
acceleration = "cuda";
# loadModels = [
# "deepseek-r1:7b"
# "deepseek-r1:14b"
# ];
};
services.open-webui = {
enable = false; # TODO gives error fix later
port = 7070;
host = "0.0.0.0";
openFirewall = true;
environment = {
SCARF_NO_ANALYTICS = "True";
DO_NOT_TRACK = "True";
ANONYMIZED_TELEMETRY = "False";
WEBUI_AUTH = "False";
ENABLE_LOGIN_FORM = "False";
};
};
})
];
}

View file

@ -1,31 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.openssh.enable {
services.openssh = {
enable = true;
startWhenNeeded = true;
settings = {
PermitRootLogin = "no";
# only allow key based logins and not password
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
AuthenticationMethods = "publickey";
PubkeyAuthentication = "yes";
ChallengeResponseAuthentication = "no";
UsePAM = false;
# kick out inactive sessions
ClientAliveCountMax = 5;
ClientAliveInterval = 60;
};
};
})
];
}

View file

@ -1,16 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.syncthing.enable {
services.syncthing = {
enable = true;
openDefaultPorts = true;
# port is 8384
};
})
];
}

View file

@ -1,68 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
system-logger = pkgs.writeShellApplication {
name = "system-logger";
runtimeInputs = with pkgs; [
curl
jq
zip
gawk
systemd
];
text = builtins.readFile ./system-logger.sh;
};
in
{
options.services.system-logger = {
enable = lib.mkEnableOption {
description = "Enable System Logger Service";
default = false;
};
logDirectory = lib.mkOption {
type = lib.types.path;
default = "/var/lib/system-logger";
description = "Directory to store log archives";
};
maxSizeMB = lib.mkOption {
type = lib.types.int;
default = 1;
description = "Maximum size of daily log archive in megabytes";
};
retentionDays = lib.mkOption {
type = lib.types.int;
default = 30;
description = "Number of days to retain log archives";
};
};
config = lib.mkIf config.services.system-logger.enable {
systemd.timers.system-logger = {
description = "System Logger Timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
};
systemd.services.system-logger = {
description = "System Logger Service";
serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe system-logger}";
Restart = "on-failure";
RestartSec = 60;
User = "root";
Group = "root";
};
};
};
}

View file

@ -1,136 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# Configuration
LOG_DIR="/var/lib/system-logger"
MAX_SIZE_MB=1
RETENTION_DAYS=30
DATE=$(date +%Y-%m-%d)
HOSTNAME=$(hostname)
TEMP_DIR=$(mktemp -d)
# Create log directory if it doesn't exist
mkdir -p "$LOG_DIR"
# Check if today's log already exists
if [ -f "$LOG_DIR/${DATE}-logs-${HOSTNAME}.zip" ]; then
echo "Logs for today already exist. Exiting..."
exit 0
fi
echo "Starting system log collection for $DATE"
# Function to collect logs with size limit
collect_logs() {
local source="$1"
local output="$2"
local max_lines="$3"
if [ -f "$source" ]; then
# Get the last N lines to stay within size limit
tail -n "$max_lines" "$source" > "$output" 2>/dev/null || true
echo "Collected from $source"
else
echo "Source $source not found, skipping..."
fi
}
# Function to get journal logs with filtering
get_journal_logs() {
local output="$1"
local filter="$2"
local max_lines="$3"
journalctl --since "00:00:00" --until "23:59:59" \
--no-pager --output=short \
| grep -i "$filter" | tail -n "$max_lines" > "$output" 2>/dev/null || true
echo "Collected journal logs for $filter"
}
# Calculate approximate lines per log type to stay under 1MB
# Assuming average line is ~100 bytes, we aim for ~10,000 total lines
TOTAL_LINES=10000
SSH_LINES=2000
KERNEL_LINES=2000
LOGIN_LINES=1000
SYSTEM_LINES=2000
AUTH_LINES=1000
FAILED_LOGIN_LINES=500
DISK_LINES=500
NETWORK_LINES=500
MEMORY_LINES=500
# Collect SSH connections
get_journal_logs "$TEMP_DIR/ssh.log" "sshd" "$SSH_LINES"
# Collect kernel warnings and errors
get_journal_logs "$TEMP_DIR/kernel.log" "kernel.*warning\|kernel.*error" "$KERNEL_LINES"
# Collect login/logout events
get_journal_logs "$TEMP_DIR/login.log" "session.*opened\|session.*closed\|login\|logout" "$LOGIN_LINES"
# Collect system messages
get_journal_logs "$TEMP_DIR/system.log" "systemd\|daemon" "$SYSTEM_LINES"
# Collect authentication events
get_journal_logs "$TEMP_DIR/auth.log" "authentication\|auth" "$AUTH_LINES"
# Collect failed login attempts
get_journal_logs "$TEMP_DIR/failed_login.log" "failed\|failure\|denied" "$FAILED_LOGIN_LINES"
# Collect disk usage and errors
get_journal_logs "$TEMP_DIR/disk.log" "disk\|storage\|iostat" "$DISK_LINES"
# Collect network events
get_journal_logs "$TEMP_DIR/network.log" "network\|connection\|interface" "$NETWORK_LINES"
# Collect memory usage
get_journal_logs "$TEMP_DIR/memory.log" "memory\|oom\|swap" "$MEMORY_LINES"
# Collect traditional log files if they exist
collect_logs "/var/log/auth.log" "$TEMP_DIR/auth_traditional.log" 1000
collect_logs "/var/log/syslog" "$TEMP_DIR/syslog_traditional.log" 1000
collect_logs "/var/log/messages" "$TEMP_DIR/messages_traditional.log" 1000
# Create a summary file
{
echo "=== System Log Summary for $DATE ==="
echo "Hostname: $HOSTNAME"
echo "Collection time: $(date)"
echo "Total lines collected:"
wc -l "$TEMP_DIR"/*.log 2>/dev/null || true
echo ""
echo "=== System Information ==="
echo "Uptime: $(uptime)"
echo "Load average: $(cat /proc/loadavg)"
echo "Memory usage:"
free -h
echo ""
echo "Disk usage:"
df -h
echo ""
echo "Active users:"
who
} > "$TEMP_DIR/summary.txt"
# Create the zip file
cd "$TEMP_DIR"
zip -r "$LOG_DIR/${DATE}-logs-${HOSTNAME}.zip" ./* > /dev/null
# Check file size and warn if too large
FILE_SIZE=$(stat -c%s "$LOG_DIR/${DATE}-logs-${HOSTNAME}.zip")
FILE_SIZE_MB=$((FILE_SIZE / 1024 / 1024))
if [ "$FILE_SIZE_MB" -gt "$MAX_SIZE_MB" ]; then
echo "WARNING: Log file size ($FILE_SIZE_MB MB) exceeds limit ($MAX_SIZE_MB MB)"
fi
echo "Log collection completed: $LOG_DIR/${DATE}-logs-${HOSTNAME}.zip ($FILE_SIZE_MB MB)"
# Clean up old logs (older than RETENTION_DAYS)
find "$LOG_DIR" -name "*-logs-*.zip" -type f -mtime +$RETENTION_DAYS -delete 2>/dev/null || true
# Clean up temporary directory
rm -rf "$TEMP_DIR"
echo "System log collection finished successfully"

View file

@ -1,32 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.tailscale.enable {
services.tailscale = {
enable = true;
port = 51513;
};
networking.firewall.allowedUDPPorts = [ config.services.tailscale.port ];
environment.systemPackages = [ pkgs.tailscale ];
})
# tailscale and impermanence
(lib.mkIf
(
config.osbmModules.services.tailscale.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
environment.persistence."/persist".directories = [
"/var/lib/tailscale"
];
}
)
];
}

View file

@ -1,75 +0,0 @@
{
config,
lib,
...
}:
{
config = lib.mkMerge [
(lib.mkIf config.osbmModules.services.vaultwarden.enable {
services.vaultwarden = {
enable = true;
backupDir = "/persist/backup/vaultwarden";
# in order to avoid having ADMIN_TOKEN in the nix store it can be also set with the help of an environment file
# be aware that this file must be created by hand (or via secrets management like sops)
environmentFile = config.age.secrets.vaultwarden.path;
config = {
# Refer to https://github.com/dani-garcia/vaultwarden/blob/main/.env.template
DOMAIN = "https://bitwarden.osbm.dev";
SIGNUPS_ALLOWED = false;
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8222;
ROCKET_LOG = "critical";
# This example assumes a mailserver running on localhost,
# thus without transport encryption.
# If you use an external mail server, follow:
# https://github.com/dani-garcia/vaultwarden/wiki/SMTP-configuration
SMTP_HOST = "127.0.0.1";
SMTP_PORT = 25;
SMTP_SSL = false;
SMTP_FROM = "osbm@osbm.dev";
SMTP_FROM_NAME = "osbm.dev Bitwarden server";
};
};
})
# vaultwarden reverse proxy via nginx
(lib.mkIf
(config.osbmModules.services.nginx.enable && config.osbmModules.services.vaultwarden.enable)
{
services.nginx.virtualHosts."bitwarden.osbm.dev" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT}";
};
};
}
)
# impermanence with vaultwarden
(lib.mkIf
(
config.osbmModules.services.vaultwarden.enable
&& config.osbmModules.hardware.disko.zfs.root.impermanenceRoot
)
{
systemd.services.vaultwarden.serviceConfig.ReadWritePaths = [ "/var/lib/vaultwarden" ];
# TODO try if not using bindMounts fixes this
environment.persistence."/persist" = {
directories = [
{
directory = "/var/lib/vaultwarden";
user = config.systemd.services.vaultwarden.serviceConfig.User;
group = config.systemd.services.vaultwarden.serviceConfig.Group;
mode = "0750";
}
];
};
}
)
];
}

View file

@ -1,56 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
config = lib.mkIf config.osbmModules.services.vscode-server.enable {
services.code-server = {
# only true if the machine is not pochita
enable = config.networking.hostName != "pochita";
port = 4444;
disableTelemetry = true;
disableUpdateCheck = true;
user = "osbm";
group = "users";
# auth = "none";
host = "${config.networking.hostName}.curl-boga.ts.net";
hashedPassword = "$argon2i$v=19$m=4096,t=3,p=1$dGc0TStGMDNzSS9JRkJYUFp3d091Q2p0bXlzPQ$zvdE9BkclkJmyFaenzPy2E99SEqsyDMt4IQNZfcfFFQ";
package = pkgs.vscode-with-extensions.override {
vscode = pkgs.code-server;
vscodeExtensions =
with pkgs.vscode-extensions;
[
bbenoist.nix
catppuccin.catppuccin-vsc
catppuccin.catppuccin-vsc-icons
charliermarsh.ruff
davidanson.vscode-markdownlint
esbenp.prettier-vscode
foxundermoon.shell-format
github.copilot
github.vscode-github-actions
github.vscode-pull-request-github
jnoortheen.nix-ide
kamadorueda.alejandra
ms-azuretools.vscode-docker
ms-python.python
# ms-vscode-remote.remote-ssh
timonwong.shellcheck
tyriar.sort-lines
]
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
# Available in nixpkgs, but outdated (0.4.0) at the time of adding
name = "vscode-tailscale";
publisher = "tailscale";
sha256 = "sha256-MKiCZ4Vu+0HS2Kl5+60cWnOtb3udyEriwc+qb/7qgUg=";
version = "1.0.0";
}
];
};
};
networking.firewall.allowedTCPPorts = [ config.services.code-server.port ];
};
}

View file

@ -1,109 +0,0 @@
{
lib,
config,
pkgs,
...
}:
let
waniKani-bypass-lessons = pkgs.writeShellApplication {
name = "wanikani-bypass-lessons";
runtimeInputs = with pkgs; [
curl
jq
];
text = ''
#!/usr/bin/env bash
# this token that starts with "2da24" is read only so i am keeping it public, i have nothing secret on my wanikani account
# but i need a write token for the second part of this script
# i am going to read it from /persist/wanikani
[ ! -e /persist/wanikani ] && echo "/persist/wanikani doesnt exist here :(" && exit 1
WANIKANI_TOKEN=$(< /persist/wanikani)
# Maximum number of reviews to maintain
MAX_REVIEWS=200
echo "=== Checking current reviews ==="
# Get current reviews (SRS stages 0-4)
current_reviews=0
for i in {0..4}; do
stage_count=$(curl -s -H "Authorization: Bearer 2da24e4a-ba89-4c4a-9047-d08f21e9dd01" "https://api.wanikani.com/v2/assignments?srs_stages=$i" | jq '.total_count')
current_reviews=$((current_reviews + stage_count))
echo "SRS stage $i: $stage_count items"
done
echo "Current total reviews: $current_reviews"
echo "Maximum reviews target: $MAX_REVIEWS"
if [ "$current_reviews" -ge "$MAX_REVIEWS" ]; then
echo "Reviews ($current_reviews) >= max ($MAX_REVIEWS). No lessons to bypass."
sleep 3600
exit 0
fi
lessons_to_bypass=$((MAX_REVIEWS - current_reviews))
echo "Need to bypass $lessons_to_bypass lessons to reach $MAX_REVIEWS total"
# Get available lessons (limited to what we need)
ASSIGNMENT_IDS=$(curl -s -H "Authorization: Bearer 2da24e4a-ba89-4c4a-9047-d08f21e9dd01" "https://api.wanikani.com/v2/assignments?immediately_available_for_lessons=true" | jq -r ".data[] | .id" | head -n "$lessons_to_bypass")
available_lessons=$(echo "$ASSIGNMENT_IDS" | wc -l)
echo "Available lessons: $available_lessons"
if [ "$available_lessons" -eq 0 ]; then
echo "No lessons available to bypass."
sleep 3600
exit 0
fi
# Limit to what we actually need
actual_bypass=$(echo "$ASSIGNMENT_IDS" | wc -l)
echo "Will bypass $actual_bypass lessons"
# "2017-09-05T23:41:28.980679Z" i need to create this from current time
TIME_STRING=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
echo "Current time: $TIME_STRING"
echo "=== Starting assignments ==="
for assignment_id in $ASSIGNMENT_IDS; do
echo "Starting assignment $assignment_id"
curl -s "https://api.wanikani.com/v2/assignments/$assignment_id/start" \
-X "PUT" \
-H "Wanikani-Revision: 20170710" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: Bearer $WANIKANI_TOKEN" \
-d "{\"assignment\": {\"started_at\": \"$TIME_STRING\" }}"
echo
sleep 1
done
echo "Successfully bypassed $actual_bypass lessons"
echo "New total should be approximately: $((current_reviews + actual_bypass))"
sleep 3600
'';
};
in
{
options.services.wanikani-bypass-lessons.enable = lib.mkEnableOption {
description = "Enable WaniKani Bypass Lessons";
default = config.osbmModules.services.wanikani-bypass-lessons.enable or false;
};
config = lib.mkIf config.services.wanikani-bypass-lessons.enable {
systemd.services.wanikani-bypass-lessons = {
description = "WaniKani Bypass Lessons";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${lib.getExe waniKani-bypass-lessons}";
Restart = "always";
RestartSec = 60 * 60;
};
};
};
}

View file

@ -1,42 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
wanikani-fetcher = pkgs.writeShellApplication {
name = "wanikani-fetcher";
runtimeInputs = with pkgs; [
curl
jq
zip
];
text = builtins.readFile ./wanikani-fetcher.sh;
};
in
{
options.services.wanikani-fetch-data.enable = lib.mkEnableOption {
description = "Enable WaniKani Fetch Data";
default = config.osbmModules.services.wanikani-fetch-data.enable or false;
};
config = lib.mkIf config.services.wanikani-fetch-data.enable {
systemd.timers.wanikani-fetch-data = {
description = "WaniKani Fetch Data";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "02:00";
};
};
systemd.services.wanikani-fetch-data = {
description = "WaniKani Fetch Data";
serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe wanikani-fetcher}";
Restart = "on-failure";
RestartSec = 60;
};
};
};
}

View file

@ -1,82 +0,0 @@
#!/usr/bin/env bash
shopt -s nullglob
API_TOKEN="2da24e4a-ba89-4c4a-9047-d08f21e9dd01"
date=$(date +%Y-%m-%d)
# check if todays date is already in the logs folder
if [ -f "/var/lib/wanikani-logs/wanikani_data_$date.zip" ]; then
echo "Data for today already exists. Exiting..."
exit 0
fi
tmp_dir=$(mktemp -d)
echo "Temporary directory created at $tmp_dir"
mkdir "$tmp_dir/data"
mkdir -p "/var/lib/wanikani-logs"
fetch_and_merge() {
local topic="$1"
local counter=0
local url="https://api.wanikani.com/v2/$topic"
local output_file="$tmp_dir/data/$topic.json"
local next_url="$url"
echo "Fetching from $url..."
while [[ -n "$next_url" ]]; do
local resp_file="$tmp_dir/$topic-page-$counter.json"
curl -s "$next_url" \
-H "Wanikani-Revision: 20170710" \
-H "Authorization: Bearer $API_TOKEN" \
-o "$resp_file"
echo -e "\n--- Page $((counter + 1)) (First 20 lines) ---"
head -n 20 <(jq . "$resp_file")
# jq . "$resp_file" 2>/dev/null | head -n 20
next_url=$(jq -r '.pages.next_url // empty' "$resp_file")
counter=$((counter + 1))
done
echo "Merging data..."
local meta
meta=$(jq '{object, total_count, data_updated_at}' "$resp_file")
local files=("$tmp_dir/$topic-page-"*.json)
jq -cn \
--argjson meta "$meta" \
--slurpfile data <(jq -s '[.[] | .data[]]' "${files[@]}") \
'$meta + {data: $data[0]}' > "$output_file"
echo "Saved to $output_file"
}
fetch_and_merge assignments
fetch_and_merge level_progressions
fetch_and_merge resets
fetch_and_merge reviews
fetch_and_merge review_statistics
fetch_and_merge spaced_repetition_systems
fetch_and_merge study_materials
fetch_and_merge subjects
curl -s "https://api.wanikani.com/v2/summary" \
-H "Wanikani-Revision: 20170710" \
-H "Authorization: Bearer $API_TOKEN" \
-o "$tmp_dir/data/summary.json"
curl -s "https://api.wanikani.com/v2/user" \
-H "Wanikani-Revision: 20170710" \
-H "Authorization: Bearer $API_TOKEN" \
-o "$tmp_dir/data/user.json"
# get the date as a variable and use it to zip the data folder
zip -j -r "/var/lib/wanikani-logs/wanikani_data_$date.zip" "$tmp_dir/data"
echo "Data zipped to /var/lib/wanikani-logs/wanikani_data_$date.zip"
echo "Cleaning up temporary files..."
rm -r "$tmp_dir"

View file

@ -1,475 +0,0 @@
import zipfile
import json
from pathlib import Path
from flask import Flask, render_template_string, Response
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.io as pio
import functools
# Set Plotly dark theme
pio.templates.default = "plotly_dark"
app = Flask(__name__)
DATA_DIR = Path("/var/lib/wanikani-logs")
def get_zip_file_names():
"""Get a list of zip files in the data directory."""
return [f for f in DATA_DIR.glob("*.zip") if f.is_file()]
# this is an expensive function so we will cache the results
@functools.lru_cache(maxsize=None)
def load_zip(zip_path):
print(f"Processing {zip_path}")
"""Load a zip file and return its contents as a dictionary."""
with zipfile.ZipFile(zip_path, "r") as z:
data = {}
# just read summary.json
with z.open("summary.json") as f:
summary_data = json.load(f)
num_reviews = len(summary_data["data"]["reviews"][0]["subject_ids"])
num_lessons = len(summary_data["data"]["lessons"][0]["subject_ids"])
data["num_reviews"] = num_reviews
data["num_lessons"] = num_lessons
# wanikani_data_2025-05-18.zip
data["date"] = zip_path.stem.split("_")[-1].replace(".zip", "")
# with z.open("subjects.json") as f:
# subjects_data = json.load(f)
# print(f"Found total data subjects: {subjects_data['total_count']}")
# data["total_subjects"] = subjects_data['total_count']
# so the subjects.json file is about 50 mb so we are just not gonna care if this value changes (doesnt change much)
data["total_subjects"] = 9300
with z.open("assignments.json") as f:
assignments_data = json.load(f)
print(f"Found total assignments: {assignments_data['total_count']}")
data["total_assignments"] = assignments_data["total_count"]
# now the data key will give us all the srs stages
srs_stages = [0 for _ in range(10)] # 10 SRS stages
for assignment in assignments_data["data"]:
srs_stage = assignment["data"]["srs_stage"]
srs_stages[srs_stage] += 1
# add srs stages to data
for i, count in enumerate(srs_stages):
data[f"srs_stage_{i}"] = count
print(data)
return data
def get_dataframe(list_of_daily_data):
"""Convert a list of daily data dictionaries into a pandas DataFrame."""
df = pd.DataFrame(list_of_daily_data)
df["progression"] = df.apply(
lambda row: sum(row[f"srs_stage_{i}"] * (i + 1) for i in range(10))
/ (row["total_subjects"] * 10)
* 100,
axis=1,
)
df["apprentice"] = df.apply(
lambda row: row["srs_stage_1"]
+ row["srs_stage_2"]
+ row["srs_stage_3"]
+ row["srs_stage_4"],
axis=1,
)
# Individual apprentice stages for distribution analysis
df["apprentice_1"] = df["srs_stage_1"]
df["apprentice_2"] = df["srs_stage_2"]
df["apprentice_3"] = df["srs_stage_3"]
df["apprentice_4"] = df["srs_stage_4"]
df["unlocked"] = df["srs_stage_0"]
df["guru"] = df.apply(lambda row: row["srs_stage_5"] + row["srs_stage_6"], axis=1)
df["master"] = df["srs_stage_7"]
df["enlightened"] = df["srs_stage_8"]
df["burned"] = df["srs_stage_9"]
return df
def get_plotly_html(df, column, title, ylabel):
"""Generate an interactive Plotly HTML for a given DataFrame column."""
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=df["date"],
y=df[column],
mode="lines+markers",
name=column.capitalize(),
line=dict(width=2),
marker=dict(size=6),
)
)
fig.update_layout(
title=title,
xaxis_title="Date",
yaxis_title=ylabel,
template="plotly_dark",
plot_bgcolor="#151519",
paper_bgcolor="#151519",
width=1200,
height=600,
margin=dict(l=50, r=50, t=50, b=50),
)
# Show every 10th date label for better readability
date_indices = list(range(0, len(df), 10))
fig.update_xaxes(
tickmode="array",
tickvals=[df.iloc[i]["date"] for i in date_indices],
ticktext=[df.iloc[i]["date"] for i in date_indices],
tickangle=45,
)
return fig.to_html(include_plotlyjs=True, div_id=f"plot_{column}")
def get_apprentice_distribution_html(df):
"""Generate a stacked area chart showing apprentice stage distribution over time."""
fig = go.Figure()
# Add stacked area traces
fig.add_trace(
go.Scatter(
x=df["date"],
y=df["apprentice_1"],
mode="lines",
name="Apprentice I",
stackgroup="one",
fillcolor="rgba(255, 107, 107, 0.8)",
line=dict(width=0.5, color="#ff6b6b"),
)
)
fig.add_trace(
go.Scatter(
x=df["date"],
y=df["apprentice_2"],
mode="lines",
name="Apprentice II",
stackgroup="one",
fillcolor="rgba(78, 205, 196, 0.8)",
line=dict(width=0.5, color="#4ecdc4"),
)
)
fig.add_trace(
go.Scatter(
x=df["date"],
y=df["apprentice_3"],
mode="lines",
name="Apprentice III",
stackgroup="one",
fillcolor="rgba(69, 183, 209, 0.8)",
line=dict(width=0.5, color="#45b7d1"),
)
)
fig.add_trace(
go.Scatter(
x=df["date"],
y=df["apprentice_4"],
mode="lines",
name="Apprentice IV",
stackgroup="one",
fillcolor="rgba(150, 206, 180, 0.8)",
line=dict(width=0.5, color="#96ceb4"),
)
)
fig.update_layout(
title="Apprentice Stage Distribution Over Time",
xaxis_title="Date",
yaxis_title="Number of Items",
template="plotly_dark",
plot_bgcolor="#151519",
paper_bgcolor="#151519",
width=1200,
height=600,
margin=dict(l=50, r=50, t=50, b=50),
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
)
# Show every 10th date label for better readability
date_indices = list(range(0, len(df), 10))
fig.update_xaxes(
tickmode="array",
tickvals=[df.iloc[i]["date"] for i in date_indices],
ticktext=[df.iloc[i]["date"] for i in date_indices],
tickangle=45,
)
return fig.to_html(include_plotlyjs=True, div_id="apprentice_distribution")
def generate_standalone_html(df, output_path=None):
"""Generate a completely self-contained HTML file with all charts."""
# Generate all chart HTML
reviews_html = get_plotly_html(
df, "num_reviews", "Daily Reviews", "Number of Reviews"
)
lessons_html = get_plotly_html(
df, "num_lessons", "Daily Lessons", "Number of Lessons"
)
progression_html = get_plotly_html(
df, "progression", "SRS Progression", "Progression (%)"
)
apprentice_distribution_html = get_apprentice_distribution_html(df)
srs_stage_apprentice_html = get_plotly_html(
df, "apprentice", "Apprentice Stage", "Number of Subjects"
)
srs_stage_guru_html = get_plotly_html(
df, "guru", "Guru Stage", "Number of Subjects"
)
srs_stage_master_html = get_plotly_html(
df, "master", "Master Stage", "Number of Subjects"
)
srs_stage_enlightened_html = get_plotly_html(
df, "enlightened", "Enlightened Stage", "Number of Subjects"
)
srs_stage_burned_html = get_plotly_html(
df, "burned", "Burned Stage", "Number of Subjects"
)
# Create complete standalone HTML
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<title>WaniKani Statistics Dashboard</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {{
background-color: #151519;
color: #8b8b9c;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 20px;
line-height: 1.6;
}}
.chart-container {{
margin: 20px auto;
padding: 15px;
border-radius: 8px;
border: 1px solid #1e1e24;
background-color: #1a1a1f;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}}
h1 {{
text-align: center;
color: #ffffff;
margin-bottom: 40px;
font-size: 2.5em;
font-weight: 300;
}}
.dashboard-info {{
text-align: center;
margin-bottom: 30px;
color: #888;
font-size: 0.9em;
}}
</style>
</head>
<body>
<h1>WaniKani Statistics Dashboard</h1>
<div class="dashboard-info">
Interactive dashboard showing your WaniKani learning progress over time
</div>
<div class="chart-container">{reviews_html}</div>
<div class="chart-container">{lessons_html}</div>
<div class="chart-container">{progression_html}</div>
<div class="chart-container">{apprentice_distribution_html}</div>
<div class="chart-container">{srs_stage_apprentice_html}</div>
<div class="chart-container">{srs_stage_guru_html}</div>
<div class="chart-container">{srs_stage_master_html}</div>
<div class="chart-container">{srs_stage_enlightened_html}</div>
<div class="chart-container">{srs_stage_burned_html}</div>
</body>
</html>
"""
# Save to file if output_path is provided
if output_path:
with open(output_path, "w", encoding="utf-8") as f:
f.write(html_content)
print(f"Standalone HTML dashboard saved to: {output_path}")
return html_content
@app.route("/download")
def download_dashboard():
"""Route to download a standalone HTML file."""
file_names = get_zip_file_names()
print(f"Found {len(file_names)} zip files in {DATA_DIR}")
list_of_daily_data = []
for file_name in file_names:
daily_data = load_zip(file_name)
list_of_daily_data.append(daily_data)
df = get_dataframe(list_of_daily_data)
df.sort_values(by="date", inplace=True)
html_content = generate_standalone_html(df)
response = Response(html_content, content_type="text/html")
response.headers["Content-Disposition"] = (
"attachment; filename=wanikani_dashboard.html"
)
return response
def render_html(df):
"""Render the DataFrame as HTML with interactive Plotly charts."""
reviews_html = get_plotly_html(
df, "num_reviews", "Daily Reviews", "Number of Reviews"
)
lessons_html = get_plotly_html(
df, "num_lessons", "Daily Lessons", "Number of Lessons"
)
progression_html = get_plotly_html(
df, "progression", "SRS Progression", "Progression (%)"
)
# apprentice distribution chart
apprentice_distribution_html = get_apprentice_distribution_html(df)
# srs stages
srs_stage_apprentice_html = get_plotly_html(
df, "apprentice", "Apprentice Stage", "Number of Subjects"
)
srs_stage_guru_html = get_plotly_html(
df, "guru", "Guru Stage", "Number of Subjects"
)
srs_stage_master_html = get_plotly_html(
df, "master", "Master Stage", "Number of Subjects"
)
srs_stage_enlightened_html = get_plotly_html(
df, "enlightened", "Enlightened Stage", "Number of Subjects"
)
srs_stage_burned_html = get_plotly_html(
df, "burned", "Burned Stage", "Number of Subjects"
)
# Render HTML with embedded Plotly charts
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<title>WaniKani Stats</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {{
background-color: #151519;
color: #8b8b9c;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 20px;
}}
.chart-container {{
margin: 20px auto;
padding: 10px;
border-radius: 5px;
border: 1px solid #1e1e24;
background-color: #151519;
}}
h1 {{
text-align: center;
color: #8b8b9c;
margin-bottom: 30px;
}}
</style>
</head>
<body>
<h1>WaniKani Statistics Dashboard</h1>
<div class="chart-container">{reviews_html}</div>
<div class="chart-container">{lessons_html}</div>
<div class="chart-container">{progression_html}</div>
<div class="chart-container">{apprentice_distribution_html}</div>
<div class="chart-container">{srs_stage_apprentice_html}</div>
<div class="chart-container">{srs_stage_guru_html}</div>
<div class="chart-container">{srs_stage_master_html}</div>
<div class="chart-container">{srs_stage_enlightened_html}</div>
<div class="chart-container">{srs_stage_burned_html}</div>
</body>
</html>
"""
return html_content
@app.route("/")
def index():
"""Index route"""
file_names = get_zip_file_names()
print(f"Found {len(file_names)} zip files in {DATA_DIR}")
list_of_daily_data = []
for file_name in file_names:
daily_data = load_zip(file_name)
list_of_daily_data.append(daily_data)
df = get_dataframe(list_of_daily_data)
# sort by date string
df.sort_values(by="date", inplace=True)
response = Response(render_html(df), content_type="text/html")
response.headers["Widget-Content-Type"] = "html"
response.headers["Widget-Title"] = "WaniKani Statistics"
return response
@app.route("/health")
def health():
"""Health check endpoint"""
return {"status": "ok", "service": "wanikani-stats"}
if __name__ == "__main__":
import sys
# Check if user wants to generate standalone HTML
if len(sys.argv) > 1 and sys.argv[1] == "generate":
output_file = sys.argv[2] if len(sys.argv) > 2 else "wanikani_dashboard.html"
print("Generating standalone HTML dashboard...")
file_names = get_zip_file_names()
print(f"Found {len(file_names)} zip files in {DATA_DIR}")
list_of_daily_data = []
for file_name in file_names:
daily_data = load_zip(file_name)
list_of_daily_data.append(daily_data)
df = get_dataframe(list_of_daily_data)
df.sort_values(by="date", inplace=True)
generate_standalone_html(df, output_file)
print(f"✅ Standalone HTML dashboard generated: {output_file}")
print(
"📊 You can now open this file in any web browser to view your interactive WaniKani stats!"
)
else:
# Start Flask server
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8501
print(f"Starting WaniKani Stats Flask app on port {port}")
print(f"📊 View dashboard at: http://localhost:{port}")
print(f"💾 Download standalone HTML at: http://localhost:{port}/download")
app.run(host="0.0.0.0", port=port, debug=False)

View file

@ -1,115 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
python =
# let
# packageOverrides = self: super: {
# imageio = super.imageio.overridePythonAttrs (old: {
# disabledTests = [
# "test_read_stream"
# "test_uri_reading"
# "test_trim_filter"
# "test_process_termination"
# ];
# });
# plotly = super.plotly.overridePythonAttrs (old: {
# disabledTestPaths = (old.disabledTestPaths or [ ]) ++ [
# "tests/test_optional/test_kaleido/test_kaleido.py"
# ];
# });
# };
# in
pkgs.python3.override {
# inherit packageOverrides;
self = python;
};
wanikani-stats-flask = pkgs.writeShellApplication {
name = "wanikani-stats-flask";
runtimeInputs = [
(python.withPackages (
ppkgs: with ppkgs; [
flask
pandas
numpy
jinja2
matplotlib
seaborn
plotly
]
))
];
text = ''
#!/usr/bin/env bash
echo "Starting WaniKani Stats Flask app..."
exec python ${./app.py} ${toString config.services.wanikani-stats.port}
'';
};
in
{
options.services.wanikani-stats = {
enable = lib.mkEnableOption {
description = "Enable WaniKani Stats Service";
default = config.osbmModules.services.wanikani-stats.enable or false;
};
logDirectory = lib.mkOption {
type = lib.types.path;
default = "/var/lib/wanikani-logs";
description = "Directory to get the log archives";
};
port = lib.mkOption {
type = lib.types.port;
default = 8501;
description = "Port for the WaniKani Stats service";
};
};
config = lib.mkIf config.services.wanikani-stats.enable {
networking.firewall.allowedTCPPorts = [
config.services.wanikani-stats.port
];
systemd = {
services = {
wanikani-stats = {
description = "WaniKani Stats Service";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${lib.getExe wanikani-stats-flask}";
StateDirectory = "/var/lib/wanikani-stats";
Restart = "on-failure";
User = "root";
Group = "root";
};
};
# Timer to restart the service every 12 hours
wanikani-stats-restart = {
description = "Restart WaniKani Stats Service";
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.systemd}/bin/systemctl restart wanikani-stats.service";
User = "root";
};
};
};
timers.wanikani-stats-restart = {
description = "Timer to restart WaniKani Stats Service every 12 hours";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 00,12:00:00";
Persistent = true;
RandomizedDelaySec = "5m";
};
};
};
};
}

View file

@ -1,39 +0,0 @@
{
lib,
pkgs,
inputs,
config,
...
}:
{
imports = [
inputs.agenix.nixosModules.default
];
config = lib.mkIf config.osbmModules.agenix.enable {
environment.systemPackages = [
inputs.agenix.packages.${pkgs.stdenv.hostPlatform.system}.agenix
pkgs.age
];
age.secrets = {
vaultwarden.file = ../../../secrets/vaultwarden.age;
network-manager.file = ../../../secrets/network-manager.age;
ssh-key-private = {
file = ../../../secrets/ssh-key-private.age;
path = "/home/osbm/.ssh/id_ed25519";
owner = "osbm";
group = "users";
mode = "600";
};
ssh-key-public = {
file = ../../../secrets/ssh-key-public.age;
path = "/home/osbm/.ssh/id_ed25519.pub";
owner = "osbm";
group = "users";
mode = "644";
};
};
};
}

View file

@ -1,15 +0,0 @@
{
imports = [
./users.nix
./desktop-environment.nix
./nix-settings.nix
./agenix.nix
./home-manager.nix
./virtualisation.nix
./emulation.nix
./i18n.nix
./impermanence.nix
./fonts.nix
./nix-index.nix
];
}

View file

@ -1,95 +0,0 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.osbmModules;
in
{
config = lib.mkMerge [
# Plasma Desktop Environment
(lib.mkIf (cfg.desktopEnvironment == "plasma") {
services = {
xserver.enable = true;
displayManager.sddm.enable = true;
desktopManager.plasma6.enable = true;
printing.enable = true;
};
environment = {
plasma6.excludePackages = with pkgs.kdePackages; [
kate
konsole
yakuake
krunner # fuckass program keeps opening
];
systemPackages = with pkgs; [
alacritty
ghostty
obsidian
mpv
kitty
qbittorrent
element-desktop
];
sessionVariables.NIXOS_OZONE_WL = "1";
};
})
# GNOME Desktop Environment
(lib.mkIf (cfg.desktopEnvironment == "gnome") {
# Enable GNOME Desktop Environment
services = {
xserver.enable = true;
desktopManager.gnome.enable = true;
displayManager.gdm.enable = true;
gnome.gnome-keyring.enable = true;
};
# Enable dconf for GNOME settings
programs.dconf.enable = true;
# Remove unwanted GNOME applications
environment.gnome.excludePackages = with pkgs; [
baobab # disk usage analyzer
cheese # photo booth
eog # image viewer
epiphany # web browser
simple-scan # document scanner
totem # video player
yelp # help viewer
evince # document viewer
file-roller # archive manager
geary # email client
seahorse # password manager
gnome-calculator
gnome-calendar
gnome-characters
gnome-clocks
gnome-contacts
gnome-font-viewer
gnome-logs
gnome-maps
gnome-music
gnome-screenshot
gnome-system-monitor
gnome-weather
gnome-disk-utility
pkgs.gnome-connections
];
})
# Common settings for any desktop environment
(lib.mkIf (cfg.desktopEnvironment != "none") {
# Enable X11 keymap
services.xserver.xkb = {
layout = lib.mkDefault "us";
variant = lib.mkDefault "";
};
})
];
}

View file

@ -1,7 +0,0 @@
{ lib, config, ... }:
{
config = lib.mkIf config.osbmModules.emulation.aarch64.enable {
# Enable binfmt for aarch64 emulation
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
};
}

View file

@ -1,57 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
config = lib.mkIf config.osbmModules.fonts.enable {
fonts.packages = with pkgs; [
cascadia-code
noto-fonts-cjk-sans
noto-fonts-color-emoji
liberation_ttf
fira-code
fira-code-symbols
mplus-outline-fonts.githubRelease
dina-font
nerd-fonts.fira-code
nerd-fonts.ubuntu
nerd-fonts.droid-sans-mono
proggyfonts
source-sans
source-han-sans
source-han-mono
source-sans-pro
source-serif-pro
font-awesome
font-awesome_5
roboto
twitter-color-emoji
iosevka
dejavu_fonts
];
# fonts.fontconfig = {
# defaultFonts.emoji = ["Noto Color Emoji"];
# };
fonts.fontconfig.defaultFonts = {
serif = [
"Source Han Serif SC"
"Source Han Serif TC"
"Noto Color Emoji"
];
sansSerif = [
"Source Han Sans SC"
"Source Han Sans TC"
"Noto Color Emoji"
];
monospace = [
"Droid Sans Mono"
"DejaVu Sans Mono"
"Source Han Mono"
"Cascadia Code"
];
emoji = [ "Noto Color Emoji" ];
};
};
}

View file

@ -1,52 +0,0 @@
{
lib,
config,
inputs,
...
}:
{
imports = [
inputs.home-manager.nixosModules.home-manager
];
config = lib.mkMerge [
# Enable FUSE user_allow_other when impermanence is used
(lib.mkIf config.osbmModules.hardware.disko.zfs.root.impermanenceRoot {
programs.fuse.userAllowOther = true;
})
(lib.mkIf config.osbmModules.homeManager.enable {
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
backupFileExtension = ".nixbak";
# Pass inputs and outputs to home-manager modules
extraSpecialArgs = {
inherit inputs;
# Pass the NixOS system config to home-manager modules
nixosConfig = config;
};
# Configure home-manager for each user (excluding root)
users =
let
# Capture the NixOS system config before entering the home-manager scope
systemConfig = config;
in
lib.genAttrs (builtins.filter (u: u != "root") config.osbmModules.users) (_username: {
# Use the system's stateVersion for home-manager
home.stateVersion = lib.mkDefault systemConfig.system.stateVersion;
imports = [
../../home-manager
]
++ lib.optionals systemConfig.osbmModules.hardware.disko.zfs.root.impermanenceRoot [
# Import impermanence home-manager module when impermanence is enabled
inputs.impermanence.homeManagerModules.impermanence
];
});
};
})
];
}

Some files were not shown because too many files have changed in this diff Show more