Compare commits
1 commit
main
...
nvidia-dri
| Author | SHA1 | Date | |
|---|---|---|---|
| a2f660db91 |
112 changed files with 242 additions and 6774 deletions
11
.github/dependabot.yml
vendored
11
.github/dependabot.yml
vendored
|
|
@ -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"
|
||||
35
.github/workflows/build-sd-image.yml
vendored
35
.github/workflows/build-sd-image.yml
vendored
|
|
@ -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
|
||||
|
||||
37
.github/workflows/nix.yml
vendored
37
.github/workflows/nix.yml
vendored
|
|
@ -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
|
||||
41
.github/workflows/test-my-packages.yml
vendored
41
.github/workflows/test-my-packages.yml
vendored
|
|
@ -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
4
.gitignore
vendored
|
|
@ -1,4 +0,0 @@
|
|||
result
|
||||
.DS_Store
|
||||
.direnv
|
||||
*.old
|
||||
3
.mailmap
3
.mailmap
|
|
@ -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>
|
||||
2
LICENSE
2
LICENSE
|
|
@ -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
138
README.md
|
|
@ -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
206
configuration.nix
Normal 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. It‘s 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
938
flake.lock
generated
|
|
@ -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
128
flake.nix
|
|
@ -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
|
||||
# )
|
||||
# );
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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
|
||||
''
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
78
justfile
78
justfile
|
|
@ -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}}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
|
||||
importList = lib.mapAttrsToList (name: _path: ./. + "/${name}") (
|
||||
lib.filterAttrs (
|
||||
filename: kind: filename != "default.nix" && (kind == "regular" || kind == "directory")
|
||||
) (builtins.readDir ./.)
|
||||
);
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# Main module entry point
|
||||
# Import the new NixOS module system
|
||||
{
|
||||
imports = [
|
||||
./nixos
|
||||
];
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
programs.bash = {
|
||||
enable = true;
|
||||
bashrcExtra = ''
|
||||
if [ "dumb" == "$TERM" ] ; then
|
||||
export TERM=xterm-256color
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
];
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
nix-direnv.enable = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
programs.fish = {
|
||||
enable = true;
|
||||
interactiveShellInit = ''
|
||||
set -g fish_greeting
|
||||
'';
|
||||
functions = {
|
||||
gitu = ''
|
||||
git add --all
|
||||
git commit -m "$argv"
|
||||
git push
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
];
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
'';
|
||||
}
|
||||
|
|
@ -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"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -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,
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
programs.zoxide = {
|
||||
enable = true;
|
||||
enableFishIntegration = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
imports = [
|
||||
./options.nix
|
||||
./programs
|
||||
./hardware
|
||||
./services
|
||||
./system
|
||||
];
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
config = lib.mkIf config.osbmModules.hardware.bluetooth.enable {
|
||||
hardware.bluetooth.enable = true;
|
||||
hardware.bluetooth.powerOnBoot = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
imports = [
|
||||
./bluetooth.nix
|
||||
./boot.nix
|
||||
./sound.nix
|
||||
./nvidia.nix
|
||||
./hibernation.nix
|
||||
./wakeOnLan.nix
|
||||
./disko.nix
|
||||
];
|
||||
}
|
||||
|
|
@ -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
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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" ];
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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" ];
|
||||
};
|
||||
}
|
||||
|
|
@ -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"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
'')
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
imports = [
|
||||
./adb-fastboot.nix
|
||||
./arduino.nix
|
||||
./command-line.nix
|
||||
./graphical.nix
|
||||
./neovim.nix
|
||||
./steam.nix
|
||||
];
|
||||
}
|
||||
|
|
@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
# }
|
||||
# )
|
||||
];
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf config.osbmModules.services.anubis.enable {
|
||||
services.anubis = {
|
||||
# enable = true;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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"
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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 ];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
];
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
@ -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 ];
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
];
|
||||
}
|
||||
|
|
@ -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 "";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{ lib, config, ... }:
|
||||
{
|
||||
config = lib.mkIf config.osbmModules.emulation.aarch64.enable {
|
||||
# Enable binfmt for aarch64 emulation
|
||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||
};
|
||||
}
|
||||
|
|
@ -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" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue