├── .gitignore ├── .gitmodules ├── amd-nixos.nix ├── arcstats.nix ├── arm-tar.nix ├── auto-gc.nix ├── bluetooth.nix ├── builders.nix ├── cachecache.nix ├── caller-id-client.nix ├── caller-id.c ├── caller-id.nix ├── caller-id.py ├── cardano-relay.nix ├── clevers_machines.nix ├── core.nix ├── coredump.nix ├── datadog.nix ├── deploy ├── deployments ├── house.nix ├── netbooks.nix └── raspberry_pi.nix ├── direnv.nix ├── docker.nix ├── earthtools.ca.nix ├── eeepc.nix ├── emby.nix ├── exporter.nix ├── extra-debug.patch ├── extra-statsd.nix ├── flake.lock ├── flake.nix ├── ghidra-1147.patch ├── gpg.nix ├── grafana └── generic │ └── node-system-dashboard.json ├── home-assistant.nix ├── iohk-binary-cache.nix ├── ipv6.reverse ├── iscsi-boot.nix ├── iscsi_module.nix ├── keys.nix ├── lan.nix ├── lan.reverse ├── load-secrets.nix ├── localnet ├── mac-arm-build-slave └── default.nix ├── media-center.nix ├── multi-boot-helper.nix ├── nas-hydra.nix ├── nas-monitoring-rewrite.nix ├── nas-monitoring.nix ├── nas-websites.nix ├── nas-wifi.nix ├── nas.nix ├── netboot_server.nix ├── nginx └── monitoring-index-template.html ├── nix ├── sources.json └── sources.nix ├── nixops-managed.nix ├── ntp_fix.nix ├── openat.patch ├── overlays └── qemu │ ├── default.nix │ └── qemu │ ├── default.nix │ ├── qemu-stack.patch │ └── qemu-wrap.c ├── pre-boot-image.nix ├── qemu.nix ├── release.nix ├── repl.nix ├── rescue_boot.nix ├── router.nat.nix ├── router.nix ├── rpi.zone ├── rtmp.nix ├── setValue.patch ├── snmpd.nix ├── stationeers.nix ├── steam.nix ├── syncplay.nix ├── system76.nix ├── tgt_service.nix ├── util.nix ├── vim.nix ├── weechat.nix ├── wireshark-no-root.nix ├── youtube ├── zdb.nix └── zfs-patch.nix /.gitignore: -------------------------------------------------------------------------------- 1 | clever_router.ovpn 2 | secrets.nix 3 | datadog-api.secret 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "nix-tests"] 2 | path = nix-tests 3 | url = https://github.com/cleverca22/nix-tests 4 | -------------------------------------------------------------------------------- /amd-nixos.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | let 4 | vc4_mesa = pkgs.mesa.override { galliumDrivers = [ "radeonsi" "vc4" "v3d" "swrast" ]; }; 5 | pkgs_i686 = pkgs.pkgsi686Linux; 6 | foo = pkgs_i686.mesa_noglu.overrideDerivation (oldAttrs: { 7 | src = /home/clever/x/mesa-11.2.2; 8 | dontStrip = true; 9 | }); 10 | flake = builtins.getFlake (toString ./.); 11 | in { 12 | imports = [ 13 | ./auto-gc.nix 14 | ./docker.nix 15 | ./exporter.nix 16 | ./wireshark-no-root.nix 17 | ./zdb.nix 18 | ./zfs-patch.nix 19 | #./radeon-exporter.nix 20 | ./amdgpu.nix 21 | ./rpi-udev.nix 22 | ./core.nix 23 | ./steam.nix 24 | ]; 25 | boot = { 26 | binfmt = { 27 | emulatedSystems = [ 28 | "armv7l-linux" 29 | ]; 30 | }; 31 | blacklistedKernelModules = [ 32 | #"radeon" 33 | #"amdgpu" 34 | ]; 35 | #crashDump.enable = true; 36 | crashDump.reservedMemory = "1024M"; 37 | extraModprobeConfig = '' 38 | options snd_hda_intel enable=1,0 39 | install dccp /run/current-system/sw/bin/false 40 | ''; 41 | extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; 42 | initrd.availableKernelModules = [ "nvme" ]; 43 | #kernelPackages = pkgs.linuxPackages_latest; 44 | kernelModules = [ "pcspkr" ]; 45 | #kernelPackages = pkgs.linuxPackages_5_15; 46 | #kernelPackages = pkgs.linuxPackages.extend (self: super: { 47 | # zfs-unused = super.zfs.overrideAttrs (old: { 48 | # patches = old.patches ++ [ 49 | # (pkgs.fetchurl { 50 | # url = "https://github.com/openzfs/zfs/commit/18ce2f2d742cab4616efbbfde6345bebd42e9b7c.patch"; 51 | # sha256 = "1r1ya4y6pds51kz997kwgqbq7gi509ckwjsxxijp6d683x4vpmx9"; 52 | # }) 53 | # ]; 54 | # }); 55 | #}); 56 | kernelParams = [ 57 | "audit=0" 58 | "boot.shell_on_fail" 59 | "zfs.zfs_flags=0x10" 60 | # drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 61 | # increases the timeout of GFX jobs 62 | "amdgpu.lockup_timeout=5000" 63 | #"amdgpu.ppfeaturemask=0xffffffff" 64 | #"amdgpu.cik_support=0" 65 | #"amdgpu.dpm=0" 66 | #"amdgpu.si_support=0" 67 | #"console=hvc0" 68 | #"idle=nomwait" 69 | #"isolcpus=0" 70 | #"memtest=10" 71 | #"netconsole=6665@192.168.2.15/enp3s0,6666@192.168.2.61/00:1c:c4:6e:00:46" 72 | #"radeon.cik_support=1" 73 | #"radeon.si_support=1" 74 | #"spl.spl_taskq_thread_bind=1" 75 | #"vm.min_free_kbytes=4194304" 76 | #"zfs.zio_taskq_batch_pct=50" 77 | ]; 78 | loader = { 79 | efi = { 80 | canTouchEfiVariables = true; 81 | #efiSysMountPoint = "/boot/EFI/"; 82 | }; 83 | grub = { 84 | #efiInstallAsRemovable = false; 85 | #efiSupport = true; 86 | device = "nodev"; 87 | enable = true; 88 | extraEntries = '' 89 | menuentry "Windows 7 - legacy chain" { 90 | insmod part_msdos 91 | insmod chain 92 | set root="hd1,msdos1" 93 | chainloader +1 94 | } 95 | 96 | menuentry "Windows 7 - NTLDR" { 97 | insmod part_msdos 98 | insmod ntfs 99 | insmod ntldr 100 | search --set=root --label "System Reserved" --hint hd1,msdos1 101 | ntldr /bootmgr 102 | } 103 | ''; 104 | memtest86.enable = true; 105 | #version = 2; 106 | }; 107 | }; 108 | tmp.useTmpfs = false; 109 | supportedFilesystems = [ 110 | "xfs" 111 | "cifs" 112 | ]; 113 | #zfs.enableUnstable = true; 114 | }; 115 | environment.systemPackages = with pkgs; [ 116 | #audacity 117 | #diffoscope 118 | #gist 119 | #gnome3.gedit 120 | #gtkwave 121 | #lutris 122 | #obs-studio 123 | #remmina 124 | #saleae-logic-2 125 | stellarium 126 | #tigervnc 127 | #youtube-dl 128 | (hwloc.override { x11Support = true; }) 129 | (mcomix3.override { pdfSupport = false; }) 130 | (pkgs.callPackage ./syncplay-clients.nix {}) 131 | acpi 132 | adwaita-qt 133 | adwaita-qt6 134 | apktool 135 | asciinema 136 | audacity 137 | bat 138 | bind.dnsutils 139 | cnping 140 | chromium 141 | #config.boot.kernelPackages.perf 142 | pkgs.linuxPackages.perf 143 | gramps 144 | corectrl 145 | d-spy 146 | ddd 147 | discord 148 | element-desktop 149 | vesktop 150 | dos2unix 151 | efibootmgr 152 | eog 153 | evince 154 | evtest 155 | file 156 | file-roller 157 | firefox 158 | flake.inputs.zfs-utils.packages.x86_64-linux.gang-finder 159 | flake.inputs.zfs-utils.packages.x86_64-linux.txg-watcher 160 | flashrom 161 | gimp 162 | git-crypt 163 | git-lfs 164 | gitAndTools.gitFull 165 | glxinfo 166 | gnuradio 167 | gparted 168 | graphviz 169 | hping 170 | iftop 171 | iperf 172 | jq 173 | kgpg 174 | lutris-free 175 | magic-wormhole 176 | moreutils # ts 177 | mpv 178 | niv 179 | nix-diff 180 | nix-du 181 | nmap 182 | obs-studio 183 | paper-icon-theme 184 | pavucontrol gdb file psmisc 185 | plex-desktop 186 | polkit_gnome 187 | prismlauncher 188 | psmisc 189 | pulseview 190 | pv 191 | pwgen 192 | python3Packages.binwalk 193 | renderdoc 194 | sloccount 195 | socat 196 | synergy 197 | sysstat pciutils vlc ffmpeg mkvtoolnix smartmontools 198 | tcpdump 199 | teamspeak_client 200 | valgrind 201 | vulkan-tools 202 | wget usbutils nox rxvt_unicode polkit_gnome 203 | xorg.xev unrar unzip openssl xrestop zip ntfs3g 204 | xsane 205 | xscreensaver wireshark-qt ncdu 206 | yt-dlp 207 | zgrviewer 208 | # qrcode scanning 209 | zbar cobang qrscan 210 | # import -silent -window root bmp:- | zbarimg - 211 | # zbarcam 212 | ]; 213 | fileSystems = { 214 | "/" = { device = "amd/root"; fsType = "zfs"; }; 215 | "/160g" = { label = "160g-linux"; fsType = "ext4"; }; 216 | "/boot" = { device = "UUID=5f5946ad-5d9c-42d9-97ef-adfae2e6cc20"; fsType = "ext4"; }; 217 | "/home" = { device = "amd/home"; fsType = "zfs"; }; 218 | "/home/clever/Games" = { device = "amd/games"; fsType = "zfs"; }; 219 | "/home/clever/apps" = { device = "amd/clever-apps"; fsType = "zfs"; }; 220 | "/home/clever/dedup" = { device = "amd/dedup"; fsType = "zfs"; }; 221 | "/home/clever/iohk" = { device = "amd/iohk"; fsType = "zfs"; }; 222 | "/media/videos/4tb" = { device="c2d:/media/videos/4tb"; fsType = "nfs"; options=[ "noauto" ]; }; 223 | "/nix" = { device = "amd/nix"; fsType = "zfs"; options = [ "noatime" ]; }; 224 | "/nas" = { 225 | device = "nas:/nas"; 226 | fsType = "nfs"; 227 | options= [ "x-systemd.automount" "noauto" "soft" ]; 228 | }; 229 | "/var/lib/systemd/coredump" = { device = "amd/coredumps"; fsType = "zfs"; }; 230 | #"/boot/EFI" = { device = "UUID=0ECD-75E7"; fsType = "vfat"; }; 231 | #"/media/Music/" = { device = "192.168.123.32:/mnt/Music/"; fsType = "nfs"; }; 232 | }; 233 | hardware = { 234 | sane = { 235 | enable = true; 236 | extraBackends = [ pkgs.sane-backends ]; 237 | }; 238 | bluetooth.enable = false; 239 | cpu.intel.updateMicrocode = true; 240 | opengl = { 241 | #extraPackages = [ pkgs.libGL pkgs.amdappsdk ]; 242 | #extraPackages32 = [ pkgs_i686.libGL ]; 243 | #package32 = pkgs.buildEnv { 244 | # name = "custom-hack"; 245 | # paths = [ 246 | # foo foo.drivers 247 | # ]; 248 | #}; 249 | 250 | #package = pkgs.buildEnv { 251 | # name = "vc4_radeon_mesa"; 252 | # paths = [ vc4_mesa vc4_mesa.drivers ]; 253 | #}; 254 | }; 255 | pulseaudio.enable = true; 256 | }; 257 | networking = { 258 | bridges = { 259 | br0 = { 260 | interfaces = [ 261 | "enp8s0" 262 | "tap0" 263 | ]; 264 | }; 265 | }; 266 | defaultGateway = "10.0.0.1"; 267 | dhcpcd.enable = false; 268 | extraHosts = '' 269 | 192.168.2.11 hydra.taktoa.me deluge.earthtools.ca fuspr.net 270 | 127.0.0.1 cacti.earthtools.ca old.explorer.angeldsis.com 271 | 10.8.0.1 cert.root.vem 272 | #192.168.2.1 ext.earthtools.ca reven.angeldsis.com repo.angeldsis.com gallery.earthtools.ca 273 | #167.114.21.160 angeldsis.com 274 | ''; 275 | firewall.enable = false; 276 | hostId = "fe1f6cbf"; 277 | hostName = "amd-nixos"; 278 | interfaces = let 279 | tap0 = { 280 | virtualType = "tap"; 281 | mtu = 9000; 282 | virtual = true; 283 | virtualOwner = "clever"; 284 | }; 285 | tox_master0 = { 286 | virtualType = "tun"; 287 | mtu = 1500; 288 | virtual = true; 289 | virtualOwner = "clever"; 290 | }; 291 | in { 292 | inherit tap0; 293 | #inherit tox_master0; 294 | enp8s0 = { 295 | mtu = 1500; 296 | }; 297 | br0 = { 298 | mtu = 1500; 299 | ipv4.addresses = [ 300 | { 301 | address = "10.0.0.15"; 302 | prefixLength = 24; 303 | } 304 | ]; 305 | }; 306 | }; 307 | nameservers = [ "10.0.0.1" ]; 308 | search = [ "localnet" ]; 309 | timeServers = [ 310 | "router" 311 | "nas" 312 | "c2d" 313 | "system76" 314 | ]; 315 | }; 316 | nixpkgs = { 317 | config = { 318 | allowUnfree = true; 319 | git.svnSupport = false; 320 | sqlite.interactive = true; 321 | }; 322 | overlays = [ 323 | (self: super: { 324 | tesseract = null; 325 | pymupdf = null; 326 | }) 327 | #(import ./overlays/plex) 328 | ]; 329 | }; 330 | nix = { 331 | buildMachines = [ 332 | #{ sshUser = "pi"; hostName = "192.168.2.178"; maxJobs = 3; system = "aarch64-linux,armv7l-linux"; sshKey = "/etc/nixos/keys/distro"; } 333 | #{ sshUser = "pi"; hostName = "pi400e"; maxJobs = 3; system = "aarch64-linux,armv7l-linux"; sshKey = "/etc/nixos/keys/distro"; } 334 | #{ sshUser = "clever"; hostName = "pi5e"; maxJobs = 3; system = "aarch64-linux,armv7l-linux"; sshKey = "/etc/nixos/keys/distro"; } 335 | #{ sshUser = "root"; hostName = "pi4"; maxJobs = 4; system = "aarch64-linux,armv7l-linux"; sshKey = "/etc/nixos/keys/distro"; supportedFeatures = [ "big-parallel" ]; } 336 | #{ sshUser = "root"; hostName = " 192.168.2.32"; maxJobs = 3; system = "x86_64-lunux"; sshKey = "/etc/nixos/keys/distro"; } 337 | #{ sshUser = "clever"; hostName = "aarch64.nixos.community"; maxJobs = 32; system = "aarch64-linux,armv7l-linux"; sshKey = "/etc/nixos/keys/distro"; supportedFeatures = [ "big-parallel" ]; } 338 | ]; 339 | sshServe = { 340 | enable = true; 341 | keys = [ 342 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCTVNUhtfjhA70isOcv/36qvN92LT29JnNOJqtMgb8puuTVf7C/kpl8UHXruPt8T1SW/h/O1v+qCCyQpZ920ozJQC6/Z27EwNBlzpi52Ljl0BX7HlKTK+maJSAOdlC4ofWruIQyIT0DXDJXbvHFqJKH4ubQKw78nn9WKFfE3xHVs6LiBXEi+tkKDxnFxEVWpgauXwK5FEQkEFD3NL9qnNiQ3icq+cM+BnTxrZRVKHBwL5YGn727ckrPSVq7rY4w2Mwm+vGb9+SkxP6GTxiaj6Xqx5ivgccbkgPP8vYyYFazhUb/Q3dTtLQ48ovspeDHEe2iX2LRVru9xSipTX5AzSSo7p6MFTkkI8yYoIBCk0tR02alCE2gyM98HGojiYj7VS/pAwJoYWNVHflUHD9olh+Hvsf6Jg+Z5vEALbHfcBRY2r01bQzXidCFxuXVRsD8fECkMB27mS+BmwXuwzf/y5WCpeWtDBDbgUHUAYYBOi5BnaZdoxbudNWPECOPDUPcrxk= root@nas" 343 | ]; 344 | }; 345 | distributedBuilds = true; 346 | extraOptions = '' 347 | allowed-uris = https://github.com/NixOS/nixpkgs/archive https://github.com/input-output-hk/nixpkgs/archive/6a8a0e57b1ea8bb771a54da66a4b5737de7048c3.tar.gz https://github.com/input-output-hk/nixpkgs/archive/3ff97c12fa19a197eb8ddee634ff2f3d4f02ad31.tar.gz 348 | builders-use-substitutes = true 349 | experimental-features = nix-command flakes 350 | #repeat = 1 351 | secret-key-files = /etc/nix/signing.sec 352 | ''; 353 | max-free = 10; 354 | min-free = 3; 355 | min-free-collection = true; 356 | settings = { 357 | auto-optimise-store = true; 358 | cores = 20; 359 | max-jobs = 20; 360 | sandbox = "relaxed"; 361 | substituters = [ 362 | #"http://cache.earthtools.ca" 363 | "http://nas.localnet:8081" 364 | "https://runner.blockfrost.io/bin-cache" 365 | #"http://nixcache.localnet" 366 | #"https://cache.nixos.org" 367 | #"https://hydra.mantis.ist/" 368 | ]; 369 | trusted-binary-caches = [ "http://nas.localnet:8081" "https://hydra.iohk.io" "https://hydra.angeldsis.com" "https://cache.nixos.org" ]; 370 | trusted-public-keys = [ 371 | "amd-1:8E8Dz+Vc/6+8SePHMrJxe92IUYHBdv5pbI7YLnJH6Ek=" 372 | "c2d.localnet-1:YTVKcy9ZO3tqPNxRqeYEYxSpUH5C8ykZ9ImUKuugf4c=" 373 | "runner1:W6f2fUzWauzS9ruoN0WHFGtPJnqngUbqgD5oqCMsoJg=" # runner.blockfrost.io 374 | "hydra.angeldsis.com-1:7s6tP5et6L8Y6sX7XGIwzX5bnLp00MtUQ/1C9t1IBGE=" 375 | "hydra.iohk.io-1:chtUuea0mkt7j3Q3ESvfJUeqTNNPspSO//Yl6O00p/Y=" 376 | "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" 377 | "hydra.mantis.ist-1:4LTe7Q+5pm8+HawKxvmn2Hx0E3NbkYjtf1oWv+eAmTo=" 378 | "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" 379 | "pi400-1:ztZan3WJEeP0fadXKUv7+nCKb5p8nTIQi5hlXas0MmQ=" 380 | "system76.angeldsis.com-1:i4B5E/GGgkb6TeOOhG81KDFduU5DItyaax3azSLUJRM=" 381 | #"manveru.cachix.org-1:L5nJHSinfA2K5dDCG3KAEadwf/e3qqhuBr7yCwSksXo=" 382 | ]; 383 | trusted-users = [ "builder" "clever" "root" ]; 384 | }; 385 | }; 386 | programs = { 387 | bash.completion.enable = true; 388 | screen.screenrc = '' 389 | defscrollback 5000 390 | caption always 391 | #termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm' 392 | #term xterm-256color 393 | #defbce "on" 394 | # fixes terminfo bugs involing tsl= 395 | termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007' 396 | ''; 397 | ssh = let 398 | amd = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJhJRINrY5cFcqZ76GsAK7FU+wQhErlS6APdOIm7xcnW"; }; 399 | router = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSvyvC18BHfivZJDhWSm7VU3kEElfNfMIfeohkil614"; }; 400 | system76 = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGtWMQ3F30gczudsr38Tw9yARsUMZbmvD4llnZq3K68u"; }; 401 | in { 402 | knownHosts = { 403 | "amd.localnet" = amd; 404 | "router.localnet" = router; 405 | "system76" = system76; 406 | "system76.localnet" = system76; 407 | }; 408 | startAgent = false; 409 | }; 410 | vim.fat = true; 411 | }; 412 | qemu-user = { 413 | arm = false; 414 | aarch64 = false; 415 | #riscv64 = true; 416 | }; 417 | security = { 418 | audit.enable = false; 419 | pam = { 420 | loginLimits = [ 421 | # https://github.com/lutris/docs/blob/master/HowToEsync.md 422 | { 423 | domain = "clever"; 424 | item = "nofile"; 425 | type = "hard"; 426 | value = "524288"; 427 | } 428 | ]; 429 | services.hsdm = { allowNullPassword = true; startSession = true; }; 430 | }; 431 | #rtkit.enable = lib.mkForce false; 432 | }; 433 | services = { 434 | i2pd = { 435 | bandwidth = 1024; 436 | enable = true; 437 | proto.http.enable = true; 438 | proto.i2cp.enable = true; 439 | }; 440 | iscsid.enable = true; 441 | kmscon = { 442 | enable = true; 443 | extraConfig = '' 444 | font-name=Inconsolata 445 | font-engine=pango 446 | ''; 447 | }; 448 | kubo = { 449 | enable = false; 450 | dataDir = "/var/lib/ipfs"; 451 | localDiscovery = true; 452 | }; 453 | locate = { 454 | enable = true; 455 | package = pkgs.mlocate; 456 | localuser = null; 457 | }; 458 | #mongodb.enable = true; 459 | memcached.enable = false; 460 | ntp.enable = true; 461 | openssh = { 462 | enable = true; 463 | settings.PermitRootLogin = "yes"; 464 | }; 465 | pipewire.enable = false; 466 | prometheus.exporters = { 467 | smartctl = { 468 | enable = true; 469 | devices = [ "/dev/nvme0" "/dev/nvme1" "/dev/sda" "/dev/sdb" ]; 470 | port = 9633; 471 | }; 472 | }; 473 | tor = { 474 | enable = false; 475 | client = { 476 | enable = false; 477 | #privoxy.enable = true; 478 | }; 479 | }; 480 | toxvpn = { 481 | enable = true; 482 | localip = "192.168.123.11"; 483 | #port = 33450; 484 | }; 485 | trezord.enable = true; 486 | udev = { 487 | packages = [ pkgs.ledger-udev-rules pkgs.trezor-udev-rules ]; 488 | extraRules = '' 489 | SUBSYSTEM=="nvme", KERNEL=="nvme[0-9]*", GROUP="disk" 490 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="0a5c", ATTRS{idProduct}=="2711|2763|2764", GROUP="wheel" 491 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="2d00", GROUP="wheel" 492 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="2d01", GROUP="wheel" 493 | SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A8V93XJN", SYMLINK+="ttyftdi", OWNER="clever" 494 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003|000a", GROUP="wheel" 495 | 496 | # ftdi 497 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="wheel" 498 | 499 | # pico wifi jtag 500 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0009", SYMLINK+="tty-%E{ID_SERIAL_SHORT}-%E{ID_USB_INTERFACE_NUM}", GROUP="wheel" 501 | ''; 502 | }; 503 | xserver = { 504 | #xkbOptions = "caps:shiftlock"; 505 | enable = true; 506 | displayManager.lightdm.enable = true; 507 | desktopManager = { 508 | gnome.enable = false; 509 | xfce.enable = true; 510 | xterm.enable = false; 511 | }; 512 | videoDrivers = [ 513 | #"amdgpu" 514 | #"radeon" 515 | ]; 516 | #useGlamor = false; 517 | #deviceSection = ''Option "NoAccel" "true"''; 518 | }; 519 | vnstat.enable = true; 520 | zfs.autoSnapshot.enable = true; 521 | }; 522 | swapDevices = [ 523 | #{ device = "/dev/nvme0n1p3"; priority = 10; } 524 | #{ device = "/dev/disk/by-partlabel/swap1"; priority = 10; } 525 | #{ device = "/dev/disk/by-partlabel/swap2"; priority = 10; } 526 | #{ device = "/dev/disk/by-uuid/ea242aa4-59c5-4597-a5a5-e2874318aca2"; priority = 10; } 527 | #{ device = "/dev/disk/by-uuid/3fdb005c-97e7-4dfb-9a3f-71748d714ae4"; priority = 9; } 528 | ]; 529 | system.stateVersion = "24.05"; 530 | time = { 531 | hardwareClockInLocalTime = true; 532 | }; 533 | users.extraUsers = { 534 | builder = { 535 | uid = 1001; 536 | isNormalUser = true; 537 | }; 538 | clever = { 539 | home = "/home/clever"; 540 | isNormalUser = true; 541 | extraGroups = [ "wheel" "wireshark" "vboxusers" "docker" ]; 542 | uid = 1000; 543 | }; 544 | }; 545 | fonts = { 546 | fontDir.enable = true; 547 | #enableCoreFonts = true; 548 | #fontconfig.ultimate.substitutions = "ms"; 549 | packages = with pkgs; [ 550 | unifont 551 | #noto-fonts 552 | noto-fonts-cjk 553 | #nerdfonts 554 | ]; 555 | }; 556 | virtualisation = { 557 | anbox.enable = false; 558 | virtualbox.host = { 559 | enable = false; 560 | }; 561 | }; 562 | fileSystems."/home/clever/VirtualBox\\040VMs" = { fsType = "zfs"; device = "amd/vbox"; }; 563 | systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ]; 564 | systemd.coredump = { 565 | enable = true; 566 | extraConfig = "ExternalSizeMax=${toString (8 * 1024 * 1024 * 1024)}"; 567 | }; 568 | } 569 | -------------------------------------------------------------------------------- /arcstats.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | with lib; 4 | let 5 | sources = import ./nix/sources.nix; 6 | arcstats = pkgs.callPackage sources.arcstats {}; 7 | in { 8 | options = { 9 | services.arcstats = mkEnableOption "arcstats"; 10 | }; 11 | config = mkIf config.services.arcstats { 12 | systemd.services.arcstats = { 13 | description = "arcstats daemon"; 14 | wantedBy = [ "multi-user.target" ]; 15 | after = [ "dd-agent.service" ]; 16 | serviceConfig.ExecStart = "${arcstats}/bin/arcstats"; 17 | }; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /arm-tar.nix: -------------------------------------------------------------------------------- 1 | { callPackage }: 2 | callPackage { 3 | fileName = "nix_tarball"; 4 | storeContents = [ 5 | { 6 | object = (import {}).pkgsCross.armv7l-hf-multiplatform.nix.override { withAWS = false; }; 7 | symlink = "/nix-built"; 8 | } 9 | ]; 10 | contents = []; 11 | } 12 | -------------------------------------------------------------------------------- /auto-gc.nix: -------------------------------------------------------------------------------- 1 | { lib, config, ... }: 2 | 3 | let 4 | inherit (lib) mkEnableOption mkOption types mkIf; 5 | cfg = config.nix; 6 | in { 7 | options.nix = { 8 | min-free = mkOption { 9 | type = types.int; 10 | default = 1; 11 | }; 12 | max-free = mkOption { 13 | type = types.int; 14 | default = 6; 15 | }; 16 | min-free-collection = mkEnableOption "min-free based garbage collection"; 17 | }; 18 | config = mkIf cfg.min-free-collection { 19 | nix.extraOptions = '' 20 | min-free = ${toString (1024*1024*1024*cfg.min-free)} 21 | max-free = ${toString (1024*1024*1024*cfg.max-free)} 22 | ''; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /bluetooth.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = [ pkgs.blueman ]; 5 | #services.blueman.enable = true; 6 | hardware.pulseaudio.package = pkgs.pulseaudioFull; 7 | hardware.bluetooth.enable = true; 8 | } 9 | -------------------------------------------------------------------------------- /builders.nix: -------------------------------------------------------------------------------- 1 | let 2 | key = "/etc/nixos/keys/distro"; 3 | in { 4 | notos = { 5 | hostName = "192.168.2.142"; 6 | maxJobs = 1; 7 | sshUser = "root"; 8 | system = "armv6l-linux,armv7l-linux"; 9 | sshKey = key; 10 | speedFactor = 2; 11 | supportedFeatures = [ "big-parallel" ]; 12 | }; 13 | rpi2 = { 14 | hostName = "192.168.2.126"; 15 | maxJobs = 1; 16 | sshUser = "builder"; 17 | system = "armv6l-linux,armv7l-linux"; 18 | sshKey = key; 19 | speedFactor = 2; 20 | supportedFeatures = [ "big-parallel" ]; 21 | }; 22 | rpi4 = { 23 | hostName = "pi4"; 24 | maxJobs = 4; 25 | sshUser = "root"; 26 | sshKey = key; 27 | speedFactor = 1; 28 | supportedFeatures = [ "big-parallel" ]; 29 | systems = [ "armv7l-linux" "aarch64-linux" ]; 30 | }; 31 | pi400 = { 32 | hostName = "pi400"; 33 | maxJobs = 1; 34 | sshUser = "pi"; 35 | sshKey = key; 36 | speedFactor = 1; 37 | supportedFeatures = [ "big-parallel" ]; 38 | systems = [ "armv7l-linux" "aarch64-linux" ]; 39 | }; 40 | amd = { 41 | hostName = "amd"; 42 | maxJobs = 5; 43 | speedFactor = 4; 44 | sshUser = "builder"; 45 | system = "i686-linux,x86_64-linux,armv6l-linux,armv7l-linux"; 46 | sshKey = key; 47 | supportedFeatures = [ "big-parallel" "kvm" "nixos-test" ]; 48 | }; 49 | darwin = { 50 | hostName = "du075.macincloud.com"; 51 | maxJobs = 1; 52 | sshUser = "clever"; 53 | system = "x86_64-darwin"; 54 | sshKey = key; 55 | }; 56 | system76 = { 57 | hostName = "builder@system76"; 58 | systems = [ 59 | "x86_64-linux" "i686-linux" 60 | #"aarch64-linux" 61 | ]; 62 | sshKey = key; 63 | maxJobs = 2; 64 | speedFactor = 1; 65 | supportedFeatures = [ "big-parallel" "nixos-test" "kvm" ]; 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /cachecache.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | with lib; 4 | 5 | let 6 | cfg = config.services.cachecache; 7 | sources = import ./nix/sources.nix; 8 | in { 9 | options = { 10 | services.cachecache.enable = mkEnableOption "enable cachecache"; 11 | }; 12 | config = mkIf cfg.enable { 13 | nixpkgs.overlays = [ 14 | (super: self: { 15 | cachecache = pkgs.callPackage sources.cachecache {}; 16 | }) 17 | ]; 18 | users.users.cachecache = { 19 | home = "/var/lib/cachecache"; 20 | isSystemUser = true; 21 | createHome = true; 22 | group = "cachecache"; 23 | }; 24 | users.groups.cachecache = {}; 25 | systemd.services.cachecache = { 26 | wantedBy = [ "multi-user.target" ]; 27 | path = [ pkgs.cachecache ]; 28 | script = '' 29 | exec cachecache 30 | ''; 31 | serviceConfig = { 32 | User = "cachecache"; 33 | WorkingDirectory = config.users.users.cachecache.home; 34 | }; 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /caller-id-client.nix: -------------------------------------------------------------------------------- 1 | { runCommand, python3, gbject-introspection, libnotify }: 2 | 3 | runCommand "caller-id-client" { 4 | } '' 5 | mkdir -pv $out/bin/ 6 | cp ${./caller-id.py} $out/caller-id.py 7 | '' 8 | -------------------------------------------------------------------------------- /caller-id.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAX_EVENTS 10 14 | 15 | int mqtt_fd = -1; 16 | int epollfd = -1; 17 | 18 | int publish(struct mosquitto *mosq, const char *topic, const void *payload, int qos, bool retain) { 19 | return mosquitto_publish(mosq, NULL, topic, strlen(payload), payload, qos, retain); 20 | } 21 | 22 | void modem_tx(int fd, const char *msg) { 23 | write(fd, msg, strlen(msg)); 24 | } 25 | 26 | void monitor_fd(int epollfd, int fd, const char *errmsg) { 27 | struct epoll_event ev; 28 | ev.events = EPOLLIN | EPOLLRDHUP; 29 | ev.data.fd = fd; 30 | if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev)) { 31 | perror(errmsg); 32 | _exit(3); 33 | } 34 | } 35 | 36 | void connected(struct mosquitto*, void*, int) { 37 | puts("connected"); 38 | } 39 | 40 | void disconnected(struct mosquitto*, void*, int) { 41 | puts("disconnected"); 42 | mqtt_fd = -1; 43 | exit(1); 44 | } 45 | 46 | int main(int argc, char **argv) { 47 | char *modem = NULL; 48 | char *mqtt_user = NULL; 49 | char *mqtt_pw = NULL; 50 | char *mqtt_server = NULL; 51 | uint16_t mqtt_port = 1883; 52 | int opt; 53 | 54 | while ((opt = getopt(argc, argv, "m:u:p:s:P:")) != -1) { 55 | switch (opt) { 56 | case 'm': 57 | modem = optarg; 58 | break; 59 | case 'u': 60 | mqtt_user = optarg; 61 | break; 62 | case 'p': 63 | mqtt_pw = getenv(optarg); 64 | break; 65 | case 's': 66 | mqtt_server = optarg; 67 | break; 68 | case 'P': 69 | mqtt_port = strtol(optarg, NULL, 10); 70 | break; 71 | } 72 | } 73 | if (mosquitto_lib_init() != MOSQ_ERR_SUCCESS) { 74 | puts("cant init mqtt"); 75 | return 1; 76 | } 77 | 78 | struct mosquitto *mqtt = mosquitto_new("caller-id-server", true, NULL); 79 | if (!mqtt) { 80 | puts("cant make new mqtt instance"); 81 | return 2; 82 | } 83 | 84 | mosquitto_connect_callback_set(mqtt, connected); 85 | mosquitto_disconnect_callback_set(mqtt, disconnected); 86 | 87 | if (mosquitto_username_pw_set(mqtt, mqtt_user, mqtt_pw) != MOSQ_ERR_SUCCESS) { 88 | puts("cant set user/pw"); 89 | return 3; 90 | } 91 | 92 | char *will = "disconnected"; 93 | mosquitto_will_set(mqtt, "caller-id/status", strlen(will), will, 0, true); 94 | 95 | int attempts = 10; 96 | while (attempts-- > 0) { 97 | if (mosquitto_connect(mqtt, mqtt_server, mqtt_port, 60) != MOSQ_ERR_SUCCESS) { 98 | puts("unable to connect to mqtt server, retrying in 10"); 99 | sleep(10); 100 | } else { 101 | break; 102 | } 103 | } 104 | 105 | if (publish(mqtt, "caller-id/status", "starting", 0, true) != MOSQ_ERR_SUCCESS) { 106 | puts("cant publish status msg"); 107 | return 5; 108 | } 109 | 110 | int modem_fd = open(modem, O_RDWR | O_NOCTTY | O_NONBLOCK); 111 | if (modem_fd < 0) { 112 | perror("cant open modem"); 113 | return 10; 114 | } 115 | 116 | struct termios options; 117 | tcgetattr(modem_fd, &options); 118 | printf("before c_cflag: %x\n", options.c_cflag); 119 | 120 | options.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; 121 | options.c_iflag |= IGNCR; 122 | 123 | options.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE); 124 | 125 | tcsetattr(modem_fd, TCSANOW, &options); 126 | 127 | epollfd = epoll_create1(0); 128 | if (epollfd < 0) { 129 | puts("cant start epoll"); 130 | return 6; 131 | } 132 | 133 | mqtt_fd = mosquitto_socket(mqtt); 134 | monitor_fd(epollfd, mqtt_fd, "mqtt socket"); 135 | monitor_fd(epollfd, modem_fd, "modem"); 136 | 137 | publish(mqtt, "caller-id/status", "started", 0, true); 138 | 139 | modem_tx(modem_fd, "AT#CID=1\n"); 140 | 141 | while (true) { 142 | struct epoll_event events[MAX_EVENTS]; 143 | int nfds = epoll_wait(epollfd, events, MAX_EVENTS, 1000 * 60); 144 | if ((nfds == -1) && (errno == EINTR)) continue; 145 | if (nfds < 0) { 146 | printf("%d ", nfds); 147 | perror("epoll_wait failed"); 148 | return 5; 149 | } 150 | if (mqtt_fd > 0) { 151 | mosquitto_loop_misc(mqtt); 152 | } 153 | for (int i=0; i < nfds; i++) { 154 | if (events[i].data.fd == modem_fd) { 155 | usleep(50000); 156 | char buffer[1024]; 157 | int size = read(modem_fd, buffer, 1020); 158 | buffer[size] = 0; 159 | mosquitto_publish(mqtt, NULL, "caller-id/event", size, buffer, 0, false); 160 | } else if (events[i].data.fd == mqtt_fd) { 161 | if (mqtt_fd > 0) { 162 | mosquitto_loop_read(mqtt, 1); 163 | } 164 | if (mqtt_fd > 0) { 165 | mosquitto_loop_write(mqtt, 1); 166 | } 167 | } 168 | } 169 | } 170 | 171 | return 0; 172 | } 173 | -------------------------------------------------------------------------------- /caller-id.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | callerid = pkgs.runCommandCC "callerid" { buildInputs = [ pkgs.mosquitto ]; } '' 5 | mkdir -pv $out/bin/ 6 | gcc ${./caller-id.c} -o $out/bin/caller-id -Wall -lmosquitto 7 | ''; 8 | in { 9 | config = { 10 | systemd.services.caller-id = { 11 | environment.PW = "hunter2"; 12 | serviceConfig = { 13 | ExecStart = "${callerid}/bin/caller-id -s nas.localnet -u callerid -p PW -m /dev/ttyS0"; 14 | Restart = "always"; 15 | }; 16 | wantedBy = [ "multi-user.target" ]; 17 | }; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /caller-id.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # [clever@amd-nixos:~/apps/nixos-configs]$ nix-shell -p 'python3.withPackages (ps: [ ps.paho-mqtt ps.pygobject3 ])' gobject-introspection libnotify 3 | 4 | import paho.mqtt.client as mqtt 5 | import time 6 | import gi 7 | import os 8 | gi.require_version('Notify', '0.7') 9 | from gi.repository import Notify 10 | 11 | Notify.init("caller-id") 12 | 13 | def on_connect(client_instance, userdata, flags, rc): 14 | print("on_connect") 15 | client.subscribe("caller-id/#"); 16 | 17 | def on_log(client_instance, userdata, level, buff): 18 | print(buff) 19 | 20 | def on_message(client_instance, userdata, msg): 21 | payload = msg.payload.decode("utf-8").strip() 22 | print("on_message, retain:%s topic:%40s payload: %s" % (msg.retain, msg.topic, payload)); 23 | if (msg.topic == "caller-id/status"): 24 | note = Notify.Notification.new("caller id status", payload) 25 | note.show() 26 | elif (msg.topic == "caller-id/event"): 27 | note = Notify.Notification.new("caller id", payload) 28 | note.show() 29 | 30 | def on_disconnect(client_instance, userdata, rc): 31 | print("on_disconnect") 32 | 33 | client = mqtt.Client(client_id="test-client") 34 | client.on_connect = on_connect 35 | client.on_message = on_message 36 | client.on_disconnect = on_disconnect 37 | #client.on_log = on_log 38 | client.username_pw_set("full_access", os.environ["CALLERID_PW"]); 39 | client.connect("nas.localnet", keepalive=600) 40 | client.loop_forever(retry_first_connection = True) 41 | -------------------------------------------------------------------------------- /cardano-relay.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | 3 | let 4 | rev = "cb5f8262e3eedec31866d958400cb5f962320a7e"; 5 | cardanoSrc = pkgs.fetchFromGitHub { 6 | owner = "input-output-hk"; 7 | repo = "cardano-sl"; 8 | inherit rev; 9 | sha256 = "0z5ccs95q05nhnmp16g7nbc2pqqbmsqlrif1giyjdzn8jxh7wy7f"; 10 | }; 11 | cardano = import cardanoSrc { gitrev = rev; }; 12 | topofile = pkgs.writeText "topology.yaml" '' 13 | wallet: 14 | relays: [[{ host: relays.cardano-mainnet.iohk.io }]] 15 | valency: 1 16 | fallbacks: 7 17 | ''; 18 | topofile2 = pkgs.writeText "topology.yaml" '' 19 | nodes: 20 | relay1: 21 | region: ap-northeast-1 22 | zone: ap-northeast-1a 23 | type: relay 24 | org: IOHK 25 | host: nas.localnet 26 | dynamic-subscribe: [[{ host: relays.cardano-mainnet.iohk.io }]] 27 | kademlia: false 28 | public: true 29 | ''; 30 | myip = "99.192.62.202"; 31 | in { 32 | config = lib.mkIf true { 33 | users.users.cardano = { 34 | home = "/var/lib/cardano"; 35 | createHome = true; 36 | isSystemUser = true; 37 | }; 38 | networking.firewall.allowedTCPPorts = [ 3002 ]; 39 | systemd.services.cardano-relay = { 40 | wantedBy = [ "multi-user.target" ]; 41 | path = [ cardano.cardano-sl-node-static ]; 42 | serviceConfig = { 43 | User = "cardano"; 44 | WorkingDirectory = "/var/lib/cardano"; 45 | }; 46 | script = '' 47 | cardano-node-simple --configuration-key mainnet_full --configuration-file ${cardano.cardano-sl-config}/lib/configuration.yaml --topology ${topofile2} --node-id relay1 --listen 0.0.0.0:3002 --address ${myip}:3000 --statsd-server 127.0.0.1:8125 --metrics +RTS -T -RTS 48 | ''; 49 | }; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /clevers_machines.nix: -------------------------------------------------------------------------------- 1 | { 2 | imports = [ ./core.nix ]; 3 | users.extraUsers.clever.extraGroups = [ "wheel" "wireshark" "docker" ]; 4 | time.timeZone = "America/Moncton"; 5 | } 6 | -------------------------------------------------------------------------------- /core.nix: -------------------------------------------------------------------------------- 1 | { pkgs, config, ... }: 2 | 3 | let 4 | secrets = import ./load-secrets.nix; 5 | keys = import ./keys.nix; 6 | in { 7 | imports = [ 8 | ./vim.nix 9 | #./iscsi-boot.nix 10 | ./iscsi_module.nix 11 | ./qemu.nix 12 | ./arcstats.nix 13 | ./extra-statsd.nix 14 | ./auto-gc.nix 15 | ./coredump.nix 16 | ]; 17 | 18 | environment.systemPackages = with pkgs; [ 19 | (if config.services.xserver.enable then gitAndTools.gitFull else git) 20 | #utillinuxCurses 21 | (pkgs.makeDesktopItem { name = "screen"; exec = "${pkgs.xterm}/bin/xterm -e ${pkgs.screen}/bin/screen -xRR"; desktopName = "Screen"; genericName = "screen"; categories = [ "System" "TerminalEmulator" ]; }) 22 | bat 23 | ncdu 24 | psmisc 25 | sqlite-interactive 26 | util 27 | util-linuxCurses 28 | ]; 29 | boot = { 30 | blacklistedKernelModules = [ "dccp" ]; 31 | kernelParams = [ 32 | "sysrq_always_enabled" 33 | "zfs.zfs_metaslab_try_hard_before_gang=1" 34 | ]; 35 | }; 36 | nixpkgs = { 37 | config = { 38 | sqlite.interactive = true; 39 | allowUnfree = true; 40 | allowBroken = true; 41 | vim.ruby = false; 42 | }; 43 | overlays = [ 44 | (self: super: { 45 | util = self.callPackage ./util.nix {}; 46 | mbrola-voices = super.mbrola-voices.override { languages = [ "en1" ]; }; 47 | toxvpn = (builtins.getFlake "github:cleverca22/toxvpn/1830f9b8c12b4c5ef36b1f60f7e600cd1ecf4ccf").packages.x86_64-linux.default; 48 | }) 49 | ]; 50 | }; 51 | programs = { 52 | screen.enable = true; 53 | screen.screenrc = '' 54 | defscrollback 5000 55 | caption always 56 | #termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm' 57 | # fixes terminfo bugs involing tsl= 58 | termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007' 59 | #defbce "on" 60 | maptimeout 5 61 | ''; 62 | ssh = { 63 | extraConfig = '' 64 | ServerAliveInterval 60 65 | ''; 66 | knownHosts = let 67 | router = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSvyvC18BHfivZJDhWSm7VU3kEElfNfMIfeohkil614"; }; 68 | amd = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJhJRINrY5cFcqZ76GsAK7FU+wQhErlS6APdOIm7xcnW"; }; 69 | system76 = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGtWMQ3F30gczudsr38Tw9yARsUMZbmvD4llnZq3K68u"; }; 70 | in { 71 | "192.168.2.1" = router; 72 | "router.localnet" = router; 73 | "192.168.2.15" = amd; 74 | "amd.localnet" = amd; 75 | "system76" = system76; 76 | "system76.localnet" = system76; 77 | "c2d.localnet" = { publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAeIKSyO23iQey8rfwqYdRrcn2sY/Uxcy/OogAZKYNBAeLdwWDmX73d/TZA/rLJtImKPjZYl1VyCIylnNaogvNs="; }; 78 | "andoria.angeldsis.com" = { publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHX1VUOiMc14jztdHArChYyUaLlTygtUSuH7qU+SD8DqnCmlmbTgeuRDEnsMCBGfWIRSftGi1VG7gC5cZwQxsiY="; }; 79 | "github.com" = { publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg="; }; 80 | "du075.macincloud.com" = { publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrJvUu+5o75C8Sf27LWf0GNyb96iBQ6znoy8YmPeoVecpsEgj1KoW+NyZSkEgB1PQA/SBYpHVQRGFfxP0WI8H0kVfJX2wf89oY5m3XJDj/B6JnFo0tpJFhdnidSehFAPm5eja93osKpJDMgtt9F31PjmuOiYS/sTtZsyz/KzoUd2mekdlowvyQA5Fw93sC2lNrKyGsD6y7O5ft9YmyNn43s7g+2f2qBLF4miPgYECJ0AaNq1NBzrmxeDBxCvrMAZe4ZFnHx/g8oy+D4eZm+J2kc8ZMIa57dqua4Y3rm9o+Uej/8sBPcp7Kczf5eAS5f9+lLaATuLDTyFKLNLItU5kX"; }; 81 | "aarch64.nixos.community" = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMUTz5i9u5H2FHNAmZJyoJfIGyUm/HfGhfwnc142L3ds"; }; 82 | "pi5w" = { publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBgqVYJn5wzz8bfVwWCtvUB6YsTNUlKzPA/IHhEJ78LF"; }; 83 | }; 84 | }; 85 | }; 86 | users = { 87 | users = { 88 | root.openssh.authorizedKeys.keys = with keys; [ 89 | dual.distro 90 | clever.amd 91 | clever.laptopLuks 92 | ]; 93 | builder = { 94 | uid = 1001; 95 | isNormalUser = true; 96 | openssh.authorizedKeys.keys = with keys; [ 97 | dual.distro 98 | #clever.amd 99 | clever.nix1 100 | router_distro 101 | clever.nix2 102 | clever.amd_distro 103 | clever.nas_distro 104 | clever.hydra 105 | ]; 106 | }; 107 | clever = { 108 | isNormalUser = true; 109 | uid = 1000; 110 | initialHashedPassword = secrets.hashedPw; 111 | openssh.authorizedKeys.keys = with keys; [ 112 | clever.amd clever.ramboot clever.laptop 113 | ]; 114 | extraGroups = [ "wheel" "wireshark" "vboxusers" "ipfs" ]; 115 | }; 116 | }; 117 | }; 118 | services = { 119 | openssh = { 120 | enable = true; 121 | settings = { 122 | PermitRootLogin = "yes"; 123 | }; 124 | }; 125 | avahi = { 126 | enable = true; 127 | nssmdns4 = true; 128 | publish = { 129 | enable = true; 130 | addresses = true; 131 | workstation = true; 132 | }; 133 | }; 134 | }; 135 | networking = { 136 | extraHosts = '' 137 | 10.42.1.5 nixbox360 138 | ''; 139 | }; 140 | nix = { 141 | min-free-collection = true; 142 | distributedBuilds = true; 143 | settings = { 144 | substituters = [ 145 | #"http://nixcache.localnet" 146 | #"https://cache.nixos.org" 147 | "https://hydra.angeldsis.com" 148 | ]; 149 | trusted-public-keys = [ 150 | "c2d.localnet-1:YTVKcy9ZO3tqPNxRqeYEYxSpUH5C8ykZ9ImUKuugf4c=" 151 | #"hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" 152 | "amd-1:8E8Dz+Vc/6+8SePHMrJxe92IUYHBdv5pbI7YLnJH6Ek=" 153 | ]; 154 | trusted-users = [ "builder" ]; 155 | }; 156 | }; 157 | #system.extraSystemBuilderCmds = '' 158 | # ln -sv ${./.} $out/nixcfg 159 | #''; 160 | security.acme.defaults.email = "cleverca22@gmail.com"; 161 | security.acme.acceptTerms = true; 162 | } 163 | -------------------------------------------------------------------------------- /coredump.nix: -------------------------------------------------------------------------------- 1 | { 2 | systemd.coredump = { 3 | enable = true; 4 | #extraConfig = '' 5 | # ExternalSizeMax=${toString (16 * 1024 * 1024 * 1024)} 6 | # Compress=no 7 | #''; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /datadog.nix: -------------------------------------------------------------------------------- 1 | { config, ... }: 2 | 3 | { 4 | services.dd-agent = { 5 | enable = true; 6 | api_key = (import ./load-secrets.nix).datadogKey; 7 | hostname = config.networking.hostName; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /deploy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # example usage: ./deploy .#packages.aarch64-linux.netboot-1.system root@pi4 4 | nix build "$1" -o result -L 5 | nix-copy-closure --to "$2" ./result 6 | ssh "$2" -t nix-env --profile /nix/var/nix/profiles/system --set $(realpath ./result) 7 | ssh "$2" -t $(realpath ./result/bin/switch-to-configuration) switch 8 | -------------------------------------------------------------------------------- /deployments/house.nix: -------------------------------------------------------------------------------- 1 | { 2 | # nixops modify -d house deployments/house.nix -I nixpkgs=https://github.com/nixos/nixpkgs/archive/dae9cf6106d.tar.gz 3 | network = { 4 | enableRollback = true; 5 | description = "house deployment"; 6 | }; 7 | defaults = { 8 | documentation.enable = false; 9 | }; 10 | nas = { 11 | imports = [ ../nas.nix ]; 12 | deployment.targetHost = "nas-deploy"; 13 | deployment.hasFastConnection = true; 14 | deployment.keys = { 15 | oauth2_proxy = { 16 | keyFile = ../secrets/oauth2_proxy; 17 | destDir = "/var/keys"; 18 | }; 19 | }; 20 | }; 21 | router = { 22 | imports = [ ../router.nix ]; 23 | deployment.targetHost = "10.0.0.1"; 24 | deployment.hasFastConnection = true; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /deployments/netbooks.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | network = { 4 | enableRollback = true; 5 | }; 6 | eeepc1 = { 7 | deployment = { 8 | targetHost = "192.168.123.21"; 9 | }; 10 | imports = [ ../eeepc.nix ]; 11 | services.toxvpn.localip = "192.168.123.21"; 12 | fileSystems."/" = { device = "/dev/sda1"; fsType = "xfs"; }; 13 | }; 14 | eeepc2 = { 15 | deployment.targetHost = "192.168.2.159"; 16 | deployment.hasFastConnection = true; 17 | imports = [ ../eeepc.nix ]; 18 | services.toxvpn.localip = "192.168.123.64"; 19 | fileSystems = { 20 | "/boot" = { device = "/dev/sda1"; fsType = "ext2"; }; 21 | "/" = { device = "/dev/sda3"; fsType = "ext2"; }; 22 | "/home" = { device = "/dev/sda4"; fsType = "ext2"; }; 23 | }; 24 | }; 25 | defaults = { 26 | imports = [ ../core.nix ../nixops-managed.nix ]; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /deployments/raspberry_pi.nix: -------------------------------------------------------------------------------- 1 | { 2 | pi2 = { 3 | nixpkgs.system = "armv7l-linux"; 4 | fileSystems."/" = { 5 | device = "/dev/sda"; 6 | fsType = "ext4"; 7 | }; 8 | boot.loader.grub.enable = false; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /direnv.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = with pkgs; [ 5 | #nix-direnv 6 | direnv 7 | ]; 8 | nix.extraOptions = '' 9 | # direnv.nix 10 | #keep-outputs = true 11 | keep-derivations = true 12 | ''; 13 | environment.pathsToLink = [ 14 | #"/share/nix-direnv" 15 | ]; 16 | programs.bash.interactiveShellInit = '' 17 | if [ -z $IN_NIX_SHELL ]; then 18 | eval "$(direnv hook bash)" 19 | fi 20 | ''; 21 | } 22 | -------------------------------------------------------------------------------- /docker.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | virtualisation = { 5 | docker = { 6 | enable = true; 7 | storageDriver = "zfs"; 8 | }; 9 | }; 10 | environment.systemPackages = [ pkgs.docker-compose ]; 11 | } 12 | -------------------------------------------------------------------------------- /earthtools.ca.nix: -------------------------------------------------------------------------------- 1 | { 2 | services.lighttpd = { 3 | enable = false; 4 | port = 80; 5 | enableModules = [ "mod_proxy" ]; 6 | extraConfig = '' 7 | #server.bind = "[::1]" 8 | server.bind = "0.0.0.0" 9 | $SERVER["socket"] == "[::]:80" { } 10 | server.use-ipv6 = "enable" 11 | 12 | # proxy.server = ( "" => ( ( "host" => "192.168.2.62", "port" => 80 ) ) ) 13 | 14 | $HTTP["host"] == "gallery.earthtools.ca" { 15 | proxy.server = ( "" => ( ( "host" => "192.168.2.61", "port" => 82 ) ) ) 16 | } 17 | $HTTP["host"] == "hydra.earthtools.ca" { 18 | proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 3000 ) ) ) 19 | } 20 | $HTTP["host"] =~ "^(nixcache.earthtools.ca|reven.angeldsis.com)$" { 21 | proxy.server = ( "" => ( ( "host" => "192.168.2.61" ) ) ) 22 | } 23 | $HTTP["host"] == "cache.earthtools.ca" { 24 | proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 5000 ) ) ) 25 | } 26 | $HTTP["url"] =~ "^/(export|videos|docs|nixos|docroot|hoogle|cacti)" { 27 | proxy.server = ( "" => (("host" => "192.168.2.61" ))) 28 | } 29 | $HTTP["host"] =~ "^(fuspr.net|hydra.taktoa.me|hydra.fuspr.net|hydra.angeldsis.com)$" { 30 | proxy.server = ( "" => (("host" => "192.168.2.11" ))) 31 | } 32 | $HTTP["host"] == "werewolf.earthtools.ca" { 33 | proxy.server = ( "" => (("host" => "192.168.2.32", "port" => 8080 ) ) ) 34 | } 35 | ''; 36 | }; 37 | services.nginx = let 38 | mkProxy = target: { 39 | enableACME = true; 40 | forceSSL = true; 41 | locations."/" = { 42 | proxyPass = target; 43 | extraConfig = '' 44 | proxy_set_header Host $host; 45 | proxy_set_header X-Forwarded-Proto $scheme; 46 | proxy_read_timeout 120; 47 | proxy_connect_timeout 120; 48 | proxy_send_timeout 120; 49 | send_timeout 120; 50 | ''; 51 | }; 52 | }; 53 | nasProxy = mkProxy "http://10.0.0.11"; 54 | mainsite = { 55 | enableACME = true; 56 | listen = [ 57 | { 58 | port = 80; 59 | ssl = false; 60 | addr = "0.0.0.0"; 61 | } 62 | { 63 | port = 443; 64 | ssl = true; 65 | addr = "0.0.0.0"; 66 | } 67 | { 68 | port = 8443; 69 | ssl = true; 70 | addr = "0.0.0.0"; 71 | } 72 | ]; 73 | #enableSSL = false; 74 | forceSSL = true; 75 | locations = { 76 | #"/export".proxyPass = "http://192.168.2.61"; 77 | #"/videos".proxyPass = "http://10.0.0.61"; 78 | "/hls".proxyPass = "http://nas.localnet"; 79 | "/dash".proxyPass = "http://nas.localnet"; 80 | "/old-private/".proxyPass = "http://nas.localnet/private/"; 81 | "/private/" = { 82 | alias = "/nas/private/"; 83 | index = "index.htm"; 84 | extraConfig = '' 85 | autoindex on; 86 | autoindex_exact_size off; 87 | ''; 88 | }; 89 | "/recordings/" = { 90 | proxyPass = "http://amd.localnet/recordings/"; 91 | }; 92 | #"/send-money".proxyPass = "http://system76:1234"; 93 | #"/get-site-key".proxyPass = "http://system76:1234"; 94 | #"/basic-faucet".proxyPass = "http://system76:1234"; 95 | "/icons".proxyPass = "http://192.168.2.61"; 96 | "/docs".proxyPass = "http://192.168.2.61"; 97 | "/nixos".proxyPass = "http://192.168.2.61"; 98 | "/docroot".proxyPass = "http://192.168.2.61"; 99 | "/hoogle".proxyPass = "http://192.168.2.61"; 100 | "/cacti".proxyPass = "http://192.168.2.61"; 101 | }; 102 | }; 103 | in { 104 | enable = true; 105 | virtualHosts = { 106 | #"fuspr.net" = nasProxy; 107 | #"hydra.taktoa.me" = nasProxy; 108 | #"hydra.fuspr.net" = nasProxy; 109 | "monitoring.earthtools.ca" = { 110 | enableACME = true; 111 | forceSSL = true; 112 | locations = { 113 | "/" = { 114 | proxyPass = "http://10.0.0.11"; 115 | extraConfig = '' 116 | proxy_set_header Host $host; 117 | proxy_set_header X-Forwarded-Proto $scheme; 118 | ''; 119 | }; 120 | "/grafana/api/live/ws" = { 121 | proxyPass = "http://10.0.0.11"; 122 | extraConfig = '' 123 | proxy_http_version 1.1; 124 | proxy_set_header Host $host; 125 | proxy_set_header X-Forwarded-Proto $scheme; 126 | proxy_set_header Upgrade $http_upgrade; 127 | proxy_set_header Connection "Upgrade"; 128 | ''; 129 | }; 130 | }; 131 | }; 132 | "hydra.angeldsis.com" = nasProxy; 133 | "plex.earthtools.ca" = { 134 | enableACME = true; 135 | forceSSL = true; 136 | locations."/" = { 137 | proxyPass = "http://10.0.0.11:32400"; 138 | extraConfig = '' 139 | proxy_set_header Host $host; 140 | proxy_set_header X-Forwarded-Proto $scheme; 141 | proxy_read_timeout 120; 142 | proxy_connect_timeout 120; 143 | proxy_send_timeout 120; 144 | send_timeout 120; 145 | ''; 146 | }; 147 | locations."/:/websockets/" = { 148 | proxyPass = "http://10.0.0.11:32400"; 149 | extraConfig = '' 150 | proxy_http_version 1.1; 151 | proxy_set_header Host $host; 152 | proxy_set_header X-Forwarded-Proto $scheme; 153 | proxy_set_header Upgrade $http_upgrade; 154 | proxy_set_header Connection "Upgrade"; 155 | ''; 156 | }; 157 | }; 158 | 159 | "nixcache.earthtools.ca" = mkProxy "http://192.168.2.61"; 160 | "reven.angeldsis.com" = mkProxy "http://192.168.2.61"; 161 | 162 | "gallery.earthtools.ca" = mkProxy "http://10.0.0.61:82"; 163 | 164 | "hydra.earthtools.ca" = { 165 | globalRedirect = "hydra.angeldsis.com"; 166 | enableACME = true; 167 | }; 168 | 169 | #"cache.earthtools.ca" = mkProxy "http://127.0.0.1:5000"; 170 | "hass.earthtools.ca" = { 171 | enableACME = true; 172 | forceSSL = true; 173 | locations."/" = { 174 | proxyPass = "http://10.0.0.11:8123"; 175 | extraConfig = '' 176 | proxy_set_header Host $host; 177 | proxy_set_header X-Forwarded-Proto $scheme; 178 | ''; 179 | }; 180 | locations."/api/websocket" = { 181 | proxyPass = "http://10.0.0.11:8123"; 182 | extraConfig = '' 183 | proxy_http_version 1.1; 184 | proxy_set_header Host $host; 185 | proxy_set_header X-Forwarded-Proto $scheme; 186 | proxy_set_header Upgrade $http_upgrade; 187 | proxy_set_header Connection "Upgrade"; 188 | ''; 189 | }; 190 | }; 191 | 192 | "ext.earthtools.ca" = mainsite; 193 | "nail.earthtools.ca" = mainsite; 194 | }; 195 | }; 196 | } 197 | -------------------------------------------------------------------------------- /eeepc.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | imports = [ ./clevers_machines.nix ./snmpd.nix ]; 5 | boot.loader.grub = { 6 | device = "/dev/sda"; 7 | copyKernels = true; 8 | }; 9 | swapDevices = [ { device = "/dev/sda2"; } ]; 10 | programs = { 11 | man.enable = false; 12 | info.enable = false; 13 | }; 14 | nixpkgs.system = "i686-linux"; 15 | networking = { 16 | wireless = { 17 | enable = true; 18 | interfaces = [ "wlp1s0" ]; 19 | }; 20 | firewall = { 21 | allowedUDPPorts = [ 33445 ]; 22 | }; 23 | }; 24 | i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" ]; 25 | services = { 26 | nixosManual.enable = false; 27 | toxvpn = { 28 | enable = true; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /emby.nix: -------------------------------------------------------------------------------- 1 | { 2 | services.emby.enable = true; 3 | networking.firewall.allowedTCPPorts = [ 8920 8096 ]; 4 | } 5 | -------------------------------------------------------------------------------- /exporter.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | 3 | let 4 | buildGoModule = attrs: pkgs.buildGoModule (attrs // { 5 | src = pkgs.fetchFromGitHub { 6 | owner = "cleverca22"; 7 | repo = "node_exporter"; 8 | rev = "226ba290fafac9bad4d855dab53d3f8a35a45963"; 9 | sha256 = "sha256-j4l6ZN8ARIj8g9rcHEov6McbRXZ5vUhLkKrT/ly0iQE="; 10 | }; 11 | vendorHash = "sha256-YvCYjaF6Jgkjxh80EIzxzkMjM9380/eAl1BnRBYmVsU="; 12 | }); 13 | in { 14 | nixpkgs.overlays = [ 15 | (self: super: { 16 | prometheus-node-exporter = super.prometheus-node-exporter.override { inherit buildGoModule; }; 17 | }) 18 | ]; 19 | services = { 20 | nginx = { 21 | appendHttpConfig = lib.mkIf false '' 22 | vhost_traffic_status_zone; 23 | server { 24 | listen 9113; 25 | location /status { 26 | vhost_traffic_status_display; 27 | vhost_traffic_status_display_format html; 28 | } 29 | } 30 | ''; 31 | }; 32 | prometheus.exporters.node = { 33 | enable = true; 34 | enabledCollectors = lib.mkForce [ 35 | "cgroups" 36 | "conntrack" 37 | "diskstats" 38 | "entropy" 39 | "filefd" 40 | "filesystem" 41 | "interrupts" 42 | "loadavg" 43 | "meminfo" 44 | "netdev" 45 | "netstat" 46 | "ntp" 47 | "stat" 48 | "systemd" 49 | "systemd.network-metrics" 50 | "tcpstat" 51 | "time" 52 | "timex" 53 | "vmstat" 54 | "wifi" 55 | #"ksmd" 56 | #"logind" 57 | #"processes" 58 | ]; 59 | }; 60 | }; 61 | networking.firewall.allowedTCPPorts = [ 9113 9100 9102 ]; 62 | systemd.services = { 63 | # "statd-exporter" = { 64 | # wantedBy = [ "multi-user.target" ]; 65 | # requires = [ "network.target" ]; 66 | # after = [ "network.target" ]; 67 | # script = '' 68 | # exec ${pkgs.prometheus-statsd-exporter}/bin/statsd_exporter -statsd.listen-address ":8125" -web.listen-address ":9102" -statsd.add-suffix=false || ${pkgs.prometheus-statsd-exporter}/bin/statsd_exporter --statsd.listen-udp=":8125" --web.listen-address=":9102" 69 | # ''; 70 | # }; 71 | "prometheus-node-exporter" = { 72 | serviceConfig.ProtectHome = lib.mkForce false; 73 | }; 74 | }; 75 | } 76 | -------------------------------------------------------------------------------- /extra-debug.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/hydra-queue-runner/hydra-queue-runner.cc b/src/hydra-queue-runner/hydra-queue-runner.cc 2 | index 70329a9e..862dbf7b 100644 3 | --- a/src/hydra-queue-runner/hydra-queue-runner.cc 4 | +++ b/src/hydra-queue-runner/hydra-queue-runner.cc 5 | @@ -487,6 +487,7 @@ void State::notificationSender() 6 | argv = {"hydra-notify", "step-finished", std::to_string(item.id), std::to_string(item.stepNr), item.logPath}; 7 | break; 8 | }; 9 | + printMsg(lvlChatty, "hydra-notify " + concatStringsSep(" ", argv)); 10 | execvp("hydra-notify", (char * *) stringsToCharPtrs(argv).data()); // FIXME: remove cast 11 | throw SysError("cannot start hydra-notify"); 12 | }); 13 | diff --git a/src/lib/Hydra/Plugin/GithubStatus.pm b/src/lib/Hydra/Plugin/GithubStatus.pm 14 | index 08ba25bb..08d770e3 100644 15 | --- a/src/lib/Hydra/Plugin/GithubStatus.pm 16 | +++ b/src/lib/Hydra/Plugin/GithubStatus.pm 17 | @@ -31,6 +31,7 @@ sub common { 18 | my $ua = LWP::UserAgent->new(); 19 | 20 | foreach my $conf (@config) { 21 | + print STDERR "GithubStatus_Debug job name $jobName\n"; 22 | next unless $jobName =~ /^$conf->{jobs}$/; 23 | # Don't send out "pending" status updates if the build is already finished 24 | next if !$finished && $b->finished == 1; 25 | @@ -47,7 +48,10 @@ sub common { 26 | my @inputs = defined $inputs_cfg ? ref $inputs_cfg eq "ARRAY" ? @$inputs_cfg : ($inputs_cfg) : (); 27 | my %seen = map { $_ => {} } @inputs; 28 | while (my $eval = $evals->next) { 29 | + print STDERR "GithubStatus_Debug eval $eval\n"; 30 | foreach my $input (@inputs) { 31 | + print STDERR "GithubStatus_Debug input $input\n"; 32 | + 33 | my $i = $eval->jobsetevalinputs->find({ name => $input, altnr => 0 }); 34 | next unless defined $i; 35 | my $uri = $i->uri; 36 | @@ -58,13 +62,16 @@ sub common { 37 | $uri =~ m![:/]([^/]+)/([^/]+?)(?:.git)?$!; 38 | my $owner = $1; 39 | my $repo = $2; 40 | - my $req = HTTP::Request->new('POST', "https://api.github.com/repos/$owner/$repo/statuses/$rev"); 41 | + my $url = "https://api.github.com/repos/$owner/$repo/statuses/$rev"; 42 | + print STDERR "GithubStatus_Debug ", $url, "\n"; 43 | + my $req = HTTP::Request->new('POST', $url); 44 | $req->header('Content-Type' => 'application/json'); 45 | $req->header('Accept' => 'application/vnd.github.v3+json'); 46 | $req->header('Authorization' => ($self->{config}->{github_authorization}->{$owner} // $conf->{authorization})); 47 | $req->content($body); 48 | my $res = $ua->request($req); 49 | - print STDERR $res->status_line, ": ", $res->decoded_content, "\n" unless $res->is_success; 50 | + print STDERR "GithubStatus_Debug ", $res->status_line, ": ", $res->decoded_content, "\n"; 51 | + print STDERR "GithubStatus_Error ", $res->status_line, ": ", $res->decoded_content, "\n" unless $res->is_success; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /extra-statsd.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | with lib; 4 | let 5 | extra-statsd = pkgs.callPackage (pkgs.fetchFromGitHub { 6 | owner = "cleverca22"; 7 | repo = "extra-statsd"; 8 | rev = "ac0ec9fa4a86f6bae304104dfe2c9e2c91704ddd"; 9 | sha256 = "1ls1f9xqrrj4q07x1qmqbirnx96kz7f22bcfnfakr1gflrg0alsh"; 10 | }) {}; 11 | in { 12 | options = { 13 | services.extra-statsd = mkEnableOption "extra-statsd"; 14 | }; 15 | config = mkIf config.services.extra-statsd { 16 | systemd.services.extra-statsd = { 17 | wantedBy = [ "multi-user.target" ]; 18 | after = [ "dd-agent.service" ]; 19 | script = '' 20 | sleep 30 21 | exec ${extra-statsd.static}/bin/statsd-exporter 22 | ''; 23 | }; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "cachecache": { 4 | "inputs": { 5 | "nixpkgs": "nixpkgs", 6 | "utils": "utils" 7 | }, 8 | "locked": { 9 | "lastModified": 1603733758, 10 | "narHash": "sha256-sFs85Rap0afZPlEJOW0H/UhK2GXOr8ikRDTKEMPycyU=", 11 | "owner": "cleverca22", 12 | "repo": "cachecache", 13 | "rev": "342b890ee88d22432edcab452fe70a675ee2fb23", 14 | "type": "github" 15 | }, 16 | "original": { 17 | "owner": "cleverca22", 18 | "repo": "cachecache", 19 | "type": "github" 20 | } 21 | }, 22 | "firmware": { 23 | "flake": false, 24 | "locked": { 25 | "narHash": "sha256-2nqziFQHLMLJoSKx09RArEVl1wpnxFISAOiBcpuI90g=", 26 | "path": "/home/clever/apps/rpi/firmware2", 27 | "type": "path" 28 | }, 29 | "original": { 30 | "path": "/home/clever/apps/rpi/firmware2", 31 | "type": "path" 32 | } 33 | }, 34 | "nixos-configs": { 35 | "flake": false, 36 | "locked": { 37 | "lastModified": 1629880963, 38 | "narHash": "sha256-Lfla5xnDrZ3Ygp8sA2ynt7CwTnjm3z/CBFK/H+e9zH0=", 39 | "owner": "cleverca22", 40 | "repo": "nixos-configs", 41 | "rev": "38d4c65b03e6b6936ee2ac8e6601e03fa053bf80", 42 | "type": "github" 43 | }, 44 | "original": { 45 | "owner": "cleverca22", 46 | "repo": "nixos-configs", 47 | "type": "github" 48 | } 49 | }, 50 | "nixpkgs": { 51 | "locked": { 52 | "lastModified": 1603729585, 53 | "narHash": "sha256-LrPPGqmqYhY2Ew/KyVAuEclcCETAB/RZ0zm/hPXjaP0=", 54 | "owner": "NixOS", 55 | "repo": "nixpkgs", 56 | "rev": "a7a1447e5d40a9ad90983d33e151f5474eddeed9", 57 | "type": "github" 58 | }, 59 | "original": { 60 | "id": "nixpkgs", 61 | "type": "indirect" 62 | } 63 | }, 64 | "nixpkgs_2": { 65 | "locked": { 66 | "lastModified": 1717112898, 67 | "narHash": "sha256-7R2ZvOnvd9h8fDd65p0JnB7wXfUvreox3xFdYWd1BnY=", 68 | "owner": "NixOS", 69 | "repo": "nixpkgs", 70 | "rev": "6132b0f6e344ce2fe34fc051b72fb46e34f668e0", 71 | "type": "github" 72 | }, 73 | "original": { 74 | "id": "nixpkgs", 75 | "type": "indirect" 76 | } 77 | }, 78 | "nixpkgs_3": { 79 | "locked": { 80 | "lastModified": 1631846720, 81 | "narHash": "sha256-Z7v67hKpDwCuNJddBqdjGYS2O21l3BVCUmMMJQU5hzM=", 82 | "owner": "NixOS", 83 | "repo": "nixpkgs", 84 | "rev": "a3c4956cf9cb921d61b4a5c30df6ef1c07d2fae4", 85 | "type": "github" 86 | }, 87 | "original": { 88 | "id": "nixpkgs", 89 | "type": "indirect" 90 | } 91 | }, 92 | "root": { 93 | "inputs": { 94 | "cachecache": "cachecache", 95 | "firmware": "firmware", 96 | "nixpkgs": "nixpkgs_2", 97 | "rpi-nixos": "rpi-nixos", 98 | "utils": "utils_2", 99 | "zfs-utils": "zfs-utils" 100 | } 101 | }, 102 | "rpi-nixos": { 103 | "inputs": { 104 | "nixos-configs": "nixos-configs", 105 | "nixpkgs": "nixpkgs_3" 106 | }, 107 | "locked": { 108 | "lastModified": 1630430629, 109 | "narHash": "sha256-DM9shbV/JS0SeXyz668F9iK5jj+YTz2qwSfhfj1RBbA=", 110 | "owner": "cleverca22", 111 | "repo": "rpi-nixos", 112 | "rev": "7dea0d95cfb31060b360833d5f60e0f5ebb4b84a", 113 | "type": "github" 114 | }, 115 | "original": { 116 | "owner": "cleverca22", 117 | "repo": "rpi-nixos", 118 | "rev": "7dea0d95cfb31060b360833d5f60e0f5ebb4b84a", 119 | "type": "github" 120 | } 121 | }, 122 | "utils": { 123 | "locked": { 124 | "lastModified": 1605370193, 125 | "narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=", 126 | "owner": "numtide", 127 | "repo": "flake-utils", 128 | "rev": "5021eac20303a61fafe17224c087f5519baed54d", 129 | "type": "github" 130 | }, 131 | "original": { 132 | "owner": "numtide", 133 | "repo": "flake-utils", 134 | "type": "github" 135 | } 136 | }, 137 | "utils_2": { 138 | "locked": { 139 | "lastModified": 1631561581, 140 | "narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=", 141 | "owner": "numtide", 142 | "repo": "flake-utils", 143 | "rev": "7e5bf3925f6fbdfaf50a2a7ca0be2879c4261d19", 144 | "type": "github" 145 | }, 146 | "original": { 147 | "owner": "numtide", 148 | "repo": "flake-utils", 149 | "type": "github" 150 | } 151 | }, 152 | "utils_3": { 153 | "locked": { 154 | "lastModified": 1667077288, 155 | "narHash": "sha256-bdC8sFNDpT0HK74u9fUkpbf1MEzVYJ+ka7NXCdgBoaA=", 156 | "owner": "numtide", 157 | "repo": "flake-utils", 158 | "rev": "6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817", 159 | "type": "github" 160 | }, 161 | "original": { 162 | "owner": "numtide", 163 | "repo": "flake-utils", 164 | "type": "github" 165 | } 166 | }, 167 | "zfs-utils": { 168 | "inputs": { 169 | "nixpkgs": [ 170 | "nixpkgs" 171 | ], 172 | "utils": "utils_3" 173 | }, 174 | "locked": { 175 | "lastModified": 1739561886, 176 | "narHash": "sha256-u9pgdUVBN0J7eCXBeDqXaexlNt/NCgN54LQ4Lgj0XT8=", 177 | "owner": "cleverca22", 178 | "repo": "zfs-utils", 179 | "rev": "509f1fa115a0f1c9bda9f4b6175a3f6c1fc47c05", 180 | "type": "github" 181 | }, 182 | "original": { 183 | "owner": "cleverca22", 184 | "repo": "zfs-utils", 185 | "type": "github" 186 | } 187 | } 188 | }, 189 | "root": "root", 190 | "version": 7 191 | } 192 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | cachecache.url = "github:cleverca22/cachecache"; 4 | utils.url = "github:numtide/flake-utils"; 5 | rpi-nixos.url = "github:cleverca22/rpi-nixos?rev=7dea0d95cfb31060b360833d5f60e0f5ebb4b84a"; 6 | #rpi-nixos.url = "path:/home/clever/apps/rpi/rpi-nixos"; 7 | firmware = { 8 | flake = false; 9 | url = "path:/home/clever/apps/rpi/firmware2"; 10 | #url = "github:raspberrypi/firmware"; 11 | }; 12 | #nix.url = "path:/home/clever/apps/nix-master"; 13 | zfs-utils = { 14 | url = "github:cleverca22/zfs-utils"; 15 | inputs.nixpkgs.follows = "nixpkgs"; 16 | }; 17 | }; 18 | outputs = { rpi-nixos, firmware, cachecache, self, utils, nixpkgs, zfs-utils }: 19 | let 20 | lib = (import nixpkgs { system = "x86_64-linux"; }).lib; 21 | common-config = { pkgs, ... }: 22 | { 23 | imports = [ 24 | ./auto-gc.nix 25 | ]; 26 | boot = { 27 | loader = { 28 | raspberryPi = { 29 | firmwareConfig = '' 30 | enable_uart=1 31 | uart_2ndstage=1 32 | ''; 33 | }; 34 | }; 35 | }; 36 | nixpkgs.overlays = [ 37 | (self: super: { 38 | raspberrypifw = super.raspberrypifw.overrideAttrs (old: { 39 | src = firmware; 40 | }); 41 | }) 42 | ]; 43 | #nix.package = nix.packages.aarch64-linux.nix; 44 | networking.firewall.enable = false; 45 | environment.systemPackages = with pkgs; [ 46 | screen libraspberrypi 47 | ncdu 48 | ]; 49 | users.users.root.openssh.authorizedKeys.keys = [ 50 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC34wZQFEOGkA5b0Z6maE3aKy/ix1MiK1D0Qmg4E9skAA57yKtWYzjA23r5OCF4Nhlj1CuYd6P1sEI/fMnxf+KkqqgW3ZoZ0+pQu4Bd8Ymi3OkkQX9kiq2coD3AFI6JytC6uBi6FaZQT5fG59DbXhxO5YpZlym8ps1obyCBX0hyKntD18RgHNaNM+jkQOhQ5OoxKsBEobxQOEdjIowl2QeEHb99n45sFr53NFqk3UCz0Y7ZMf1hSFQPuuEC/wExzBBJ1Wl7E1LlNA4p9O3qJUSadGZS4e5nSLqMnbQWv2icQS/7J8IwY0M8r1MsL8mdnlXHUofPlG1r4mtovQ2myzOx clever@nixos" 51 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM3J+b+IoVRaM3Mr8M0iHPNTdLvBCKDJyt3zuiYVi1PoEKHuEd+BT7CDhdWS0BrvWoXNfa6vFNnniXQHY4euZPoyVHhVphJ508p+TfBReHgJ41+UHU6TOjam7+bIek5LN+qTi8s/CXsTsn2e6wAhgwmKPLEt2NBGgDvwVlivBfmgpcob+hOwOaFHpOEv+W1jmsJYdnRsX9K4jWEx6EEj+qxUa53ubwCwjtJ0o+s59wT2b+4M3qakpu1UZgmmchn8RWmf9OYPRaSyO1TEaGdLnDrhBezwVXKDgulZ8VKbAowpPCMjuqzR28XyNJDVQJHudy9Ir7k0HKQwTUYsqgcV/h root@nas" 52 | ]; 53 | services = { 54 | prometheus.exporters.node = { 55 | enable = true; 56 | enabledCollectors = [ 57 | #"systemd" 58 | "tcpstat" 59 | "conntrack" 60 | "diskstats" 61 | #"entropy" 62 | "filefd" 63 | "filesystem" 64 | "loadavg" 65 | "meminfo" 66 | "netdev" 67 | #"netstat" 68 | "stat" 69 | "time" 70 | "ntp" 71 | "timex" 72 | "vmstat" 73 | #"logind" 74 | "interrupts" 75 | "ksmd" 76 | #"processes" 77 | ]; 78 | #disabledCollectors = [ "hwmon" ]; 79 | }; 80 | }; 81 | nix = { 82 | min-free-collection = true; 83 | }; 84 | }; 85 | arm64-config = { 86 | imports = [ common-config ]; 87 | nix = { 88 | extraOptions = '' 89 | extra-platforms = armv6l-linux armv7l-linux 90 | ''; 91 | }; 92 | }; 93 | netboot-1 = { pkgs, ... }: { 94 | imports = [ arm64-config ]; 95 | rpi-netboot.lun = "iqn.2021-08.com.example:pi400.img"; 96 | networking.hostName = "netboot-1"; 97 | }; 98 | netboot-2 = { pkgs, ... }: { 99 | imports = [ arm64-config ]; 100 | rpi-netboot.lun = "iqn.2021-08.com.example:netboot-2.img"; 101 | }; 102 | arm64_images = { 103 | netboot-1 = rpi-nixos.packages.aarch64-linux.net_image_pi4.override { configuration = netboot-1; }; 104 | netboot-2 = rpi-nixos.packages.aarch64-linux.net_image_pi4.override { configuration = netboot-2; }; 105 | }; 106 | in 107 | utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ] (system: 108 | { 109 | packages = { 110 | cachecache = cachecache.outputs.packages.${system}.cachecache; 111 | caller-id-client = nixpkgs.legacyPackages.${system}.callPackage ./caller-id-client.nix {}; 112 | ghidra = nixpkgs.legacyPackages.${system}.ghidra.overrideAttrs (old: { 113 | patches = old.patches ++ [ ./ghidra-1147.patch ]; 114 | }); 115 | }; 116 | hydraJobs.cachecache = cachecache.outputs.packages.${system}.cachecache; 117 | } // lib.optionalAttrs (system == "aarch64-linux") { 118 | packages = arm64_images; 119 | hydraJobs = arm64_images; 120 | } 121 | ); 122 | } 123 | -------------------------------------------------------------------------------- /gpg.nix: -------------------------------------------------------------------------------- 1 | { pkgs, config, ... }: 2 | 3 | let 4 | cfg = config.programs.gnupg; 5 | in { 6 | environment.systemPackages = with pkgs; [ 7 | keybase 8 | gnupg 9 | #pinentry-gnome 10 | ]; 11 | programs.gnupg.agent = { 12 | enable = true; 13 | #enableSSHSupport = true; 14 | #pinentryFlavor = "gtk2"; 15 | }; 16 | # xfconf-query -c xfce4-session -p /startup/ssh-agent/enabled -n -t bool -s false 17 | systemd.user.sockets.gpg-agent-ssh.wantedBy = [ "sockets.target" ]; 18 | environment.extraInit = '' 19 | if [ -z "$SSH_AUTH_SOCK" ]; then 20 | export SSH_AUTH_SOCK=$(${cfg.package}/bin/gpgconf --list-dirs agent-ssh-socket) 21 | fi 22 | ''; 23 | } 24 | -------------------------------------------------------------------------------- /home-assistant.nix: -------------------------------------------------------------------------------- 1 | let 2 | #nixpkgsfix = builtins.fetchTarball "https://github.com/nixos/nixpkgs/archive/pull/152462/head.tar.gz"; 3 | nixpkgsfix = builtins.fetchTarball "https://github.com/nixos/nixpkgs/archive/b211b392b8486ee79df6cdfb1157ad2133427a29.tar.gz"; 4 | fixed_pkgs = import nixpkgsfix { config = {}; overlays = []; }; 5 | mkYoutubeAction = video: { 6 | service = "media_player.play_media"; 7 | target.entity_id = "media_player.living_room_tv"; 8 | data = { 9 | media_content_type = "cast"; 10 | media_content_id = builtins.toJSON { 11 | app_name = "youtube"; 12 | media_id = video; 13 | }; 14 | }; 15 | }; 16 | automation3 = { 17 | trigger = [ 18 | { 19 | platform = "state"; 20 | entity_id = [ 21 | "sensor.bedroom" 22 | "sensor.outdoors" 23 | ]; 24 | } 25 | ]; 26 | condition = [ 27 | { 28 | condition = "numeric_state"; 29 | entity_id = "sensor.bedroom"; 30 | above = "sensor.outdoors"; 31 | } 32 | { 33 | condition = "numeric_state"; 34 | entity_id = "sensor.bedroom"; 35 | above = "21"; 36 | } 37 | ]; 38 | action = [ 39 | { 40 | service = "switch.turn_on"; 41 | target.entity_id = "switch.fan_switch"; 42 | } 43 | ]; 44 | }; 45 | automation4 = { 46 | trigger = [ 47 | { 48 | platform = "state"; 49 | entity_id = [ 50 | "sensor.bedroom" 51 | "sensor.outdoors" 52 | ]; 53 | } 54 | ]; 55 | condition = [ 56 | { 57 | condition = "or"; 58 | conditions = [ 59 | { 60 | condition = "numeric_state"; 61 | entity_id = "sensor.bedroom"; 62 | below = "sensor.outdoors"; 63 | } 64 | { 65 | condition = "numeric_state"; 66 | entity_id = "sensor.bedroom"; 67 | below = "20"; 68 | } 69 | ]; 70 | } 71 | ]; 72 | action = [ 73 | { 74 | service = "switch.turn_off"; 75 | target.entity_id = "switch.fan_switch"; 76 | } 77 | ]; 78 | }; 79 | in { 80 | systemd.services.home-assistant = { 81 | serviceConfig = { 82 | DeviceAllow = [ 83 | "/dev/ttyUSB0" 84 | "/dev/ttyACM*" 85 | "/dev/ttyzigbee" 86 | ]; 87 | }; 88 | }; 89 | networking.firewall.allowedTCPPorts = [ 90 | 1883 91 | ]; 92 | #hardware.bluetooth.enable = true; 93 | services.mosquitto = { 94 | enable = true; 95 | listeners = [ 96 | { 97 | users = { 98 | full_access = { 99 | password = "hunter2"; 100 | acl = [ 101 | "readwrite homeassistant/#" 102 | "readwrite home/#" 103 | "readwrite elite_dangerous/#" 104 | "readwrite $SYS/#" 105 | "readwrite caller-id/#" 106 | ]; 107 | }; 108 | callerid = { 109 | password = "hunter2"; 110 | acl = [ 111 | "readwrite caller-id/#" 112 | ]; 113 | }; 114 | }; 115 | } 116 | ]; 117 | # logType = [ "all" ]; 118 | }; 119 | services.home-assistant = { 120 | enable = true; 121 | openFirewall = true; 122 | package = (fixed_pkgs.home-assistant.override { 123 | extraComponents = [ 124 | "cast" "http" "openweathermap" "roku" 125 | "google" 126 | ]; 127 | extraPackages = pypkgs: [ pypkgs.aiohttp-cors ]; 128 | }).overrideAttrs (oldAttrs: { doInstallCheck = false; }); 129 | extraComponents = [ "http" ]; 130 | config = { 131 | automation = { 132 | alias = "lights out when playing"; 133 | #trigger = [ 134 | # { 135 | # platform = "webhook"; 136 | # webhook_id = "plex"; 137 | # } 138 | #]; 139 | trigger = [ 140 | { 141 | platform = "state"; 142 | entity_id = "media_player.plex_plex_media_player_amd_nixos"; 143 | to = "playing"; 144 | for = "00:00:10"; 145 | } 146 | ]; 147 | action = [ 148 | #{ 149 | # service = "scene.turn_on"; 150 | # target.entity_id = "scene.lights_off"; 151 | #} 152 | ]; 153 | }; 154 | "automation 2" = { 155 | alias = "lights on when not playing"; 156 | trigger = [ 157 | { 158 | platform = "state"; 159 | entity_id = "media_player.plex_plex_media_player_amd_nixos"; 160 | to = "paused"; 161 | for = "00:00:10"; 162 | } 163 | { 164 | platform = "state"; 165 | entity_id = "media_player.plex_plex_media_player_amd_nixos"; 166 | to = "idle"; 167 | } 168 | ]; 169 | action = [ 170 | #{ 171 | # service = "scene.turn_on"; 172 | # target.entity_id = "scene.lights_on"; 173 | #} 174 | ]; 175 | }; 176 | "automation leaky washing" = { 177 | alias = "no leaky washing"; 178 | trigger = [ 179 | { 180 | platform = "device"; 181 | entity_id = "522f1a1953b291d9abab9fd5c6455df6"; 182 | type = "moist"; 183 | device_id = "30266e82fc382d5fd6050559fc204d3d"; 184 | domain = "binary_sensor"; 185 | } 186 | ]; 187 | mode = "single"; 188 | action = [ 189 | #{ 190 | # service = "switch.turn_off"; 191 | # target.device_id = "e87bba0947b6f4b5d0fd12e9028f50df"; 192 | #} 193 | (mkYoutubeAction "ufZoZzDjjzE") 194 | ]; 195 | }; 196 | "automation furnaceroom leak" = { 197 | alias = "furnace room leak"; 198 | trigger = [ 199 | { 200 | platform = "state"; 201 | entity_id = "binary_sensor.furnace_leak_moisture"; 202 | } 203 | ]; 204 | mode = "single"; 205 | action = [ 206 | (mkYoutubeAction "ufZoZzDjjzE") 207 | ]; 208 | }; 209 | #"proxymity test1" = { 210 | # alias = "dad approaching"; 211 | # trigger = [ 212 | # 213 | # ]; 214 | #}; 215 | "automation fubuki" = { 216 | alias = "fubuki test"; 217 | trigger = [ 218 | ]; 219 | action = [ 220 | (mkYoutubeAction "dmkRV8SPBng") 221 | ]; 222 | }; 223 | "automation rick" = { 224 | alias = "rick test"; 225 | trigger = [ 226 | ]; 227 | action = [ 228 | (mkYoutubeAction "dQw4w9WgXcQ") 229 | ]; 230 | }; 231 | "automation upstairs detected" = { 232 | alias = "activity detected upstairs"; 233 | trigger = [ 234 | { 235 | platform = "state"; 236 | entity_id = "media_player.living_room_tv"; 237 | to = "playing"; 238 | for = "00:00:10"; 239 | } 240 | ]; 241 | action = [ 242 | #{ 243 | # service = "scene.turn_on"; 244 | # target.entity_id = "scene.lights_off"; 245 | #} 246 | ]; 247 | }; 248 | #inherit automation3 automation4; 249 | api = {}; 250 | #cast = {}; 251 | sense = {}; 252 | config = {}; 253 | default_config = {}; 254 | frontend = {}; 255 | #google_assistant = { 256 | #project_id = ""; 257 | #}; 258 | http = { }; 259 | history = {}; 260 | homeassistant = { 261 | external_url = "https://hass.earthtools.ca"; 262 | media_dirs = { 263 | nas_anime = "/nas/anime"; 264 | }; 265 | }; 266 | lovelace = { 267 | }; 268 | mqtt = { 269 | #broker = "127.0.0.1"; 270 | #username = "full_access"; 271 | #password = "hunter2"; 272 | }; 273 | google_assistant_sdk = { 274 | }; 275 | onboarding = { 276 | }; 277 | person = { 278 | }; 279 | zha = { 280 | }; 281 | ibeacon = { 282 | }; 283 | logger = { 284 | default = "warning"; 285 | logs = { 286 | # https://github.com/zigpy/zigpy-xbee/blob/dev/zigpy_xbee/api.py#L16 287 | "zigpy_xbee.api" = "debug"; 288 | "mqtt" = "debug"; 289 | }; 290 | }; 291 | #met = {}; 292 | #openweathermap = {}; 293 | #tuya = { 294 | #}; 295 | prometheus = {}; 296 | scene = [ 297 | { 298 | name = "lights off"; 299 | entities = { 300 | #"switch.floor_lamp_socket" = "off"; 301 | }; 302 | } 303 | { 304 | name = "lights on"; 305 | entities = { 306 | #"switch.floor_lamp_socket" = "on"; 307 | }; 308 | } 309 | ]; 310 | template = [ 311 | { 312 | sensor = { 313 | name = "desktop active plex"; 314 | state = '' 315 | {{ state_attr("media_player.plex_plex_media_player_amd_nixos","media_series_title") }}: {{ state_attr("media_player.plex_plex_media_player_amd_nixos","media_title") }} 316 | ''; 317 | }; 318 | } 319 | ]; 320 | }; 321 | }; 322 | } 323 | -------------------------------------------------------------------------------- /iohk-binary-cache.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | nix = { 5 | settings = { 6 | trusted-public-keys = [ "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" ]; 7 | #substituters = [ "https://hydra.iohk.io" ]; 8 | }; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /ipv6.reverse: -------------------------------------------------------------------------------- 1 | $TTL 3D 2 | @ IN SOA ns1.earthtools.ca. hostmaster (1 8H 4H 4W 1D) 3 | NS ns1.earthtools.ca. 4 | 5 | 0.0.2.6.c.1.e.f.f.f.4.a.7.1.2.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR gamer.localnet. 6 | 8.4.2.3.3.b.e.f.f.f.e.7.6.1.2.4.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR amd.localnet. 7 | 6.4.0.0.e.6.e.f.f.f.4.c.c.1.2.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR c2d.localnet. 8 | f.d.2.d.5.c.e.f.f.f.8.4.0.3.2.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR router.localnet. 9 | 1.2.0.8.a.7.e.f.f.f.9.9.0.5.2.d.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR nas.localnet. 10 | 2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR router.earthtools.ca. 11 | 3.b.b.4.6.1.e.f.f.f.3.2.c.1.2.0 IN PTR ramboot.earthtools.ca. 12 | -------------------------------------------------------------------------------- /iscsi-boot.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | with lib; 4 | 5 | let 6 | cfg = config.boot.initrd.iscsi; 7 | fileSystems = attrValues config.fileSystems ++ config.swapDevices; 8 | iscsiDevs = filter (dev: dev.iscsi.enable) fileSystems; 9 | anyiscsi = fold (j: v: v || j.iscsi.enable) false iscsiDevs; 10 | iscsiOptions = { 11 | iscsi = { 12 | enable = mkOption { default = false; type = types.bool; description = "The block device is backed by iscsi, adds this device as a initrd entry"; }; 13 | host = mkOption { example = "192.168.2.61"; type = types.str; description = "the iscsi target"; }; 14 | lun = mkOption { example = "iqn.2015-01.com.example:san.img"; type = types.str; description = "the LUN to connect"; }; 15 | }; 16 | }; 17 | in 18 | { 19 | options = { 20 | fileSystems = mkOption { 21 | options = [ iscsiOptions ]; 22 | }; 23 | swapDevices = mkOption { 24 | options = [ iscsiOptions ]; 25 | }; 26 | boot.initrd.iscsi = { 27 | initiatorName = mkOption { 28 | example = "iqn.2015-09.com.example:3255a7223b2"; 29 | type = types.str; 30 | description = "the initiator name used when connecting"; 31 | }; 32 | }; # iscsi 33 | }; # options 34 | config = mkIf anyiscsi ( 35 | { 36 | boot.initrd = { 37 | kernelModules = [ "iscsi_tcp" ]; 38 | availableKernelModules = [ "crc32c" ]; 39 | preLVMCommands = '' 40 | export PATH=$PATH:${pkgs.openiscsi}/bin/ 41 | '' + concatMapStrings (dev: "iscsistart -t ${dev.iscsi.lun} -a ${dev.iscsi.host} -i ${config.boot.initrd.iscsi.initiatorName} -g 0\n") iscsiDevs; 42 | }; # initrd 43 | }); # config 44 | } 45 | -------------------------------------------------------------------------------- /iscsi_module.nix: -------------------------------------------------------------------------------- 1 | { config, stdenv, pkgs, lib, ... }: 2 | 3 | with lib; 4 | 5 | { 6 | options = { 7 | services.iscsid = { 8 | enable = mkOption { 9 | type = types.bool; 10 | default = false; 11 | description = "enable iscsid running on startup"; 12 | }; 13 | }; 14 | }; 15 | config = mkIf config.services.iscsid.enable { 16 | systemd.services.iscsid = { 17 | description = "iscsid daemon"; 18 | wantedBy = [ "basic.target" ]; 19 | preStart = "${pkgs.kmod}/bin/modprobe iscsi_tcp"; 20 | serviceConfig = { 21 | ExecStart = "${pkgs.openiscsi}/bin/iscsid -f -c ${pkgs.openiscsi}/etc/iscsi/iscsid.conf -i ${pkgs.openiscsi}/etc/iscsi/initiatorname.iscsi"; 22 | KillMode = "process"; 23 | Restart = "on-success"; 24 | }; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /keys.nix: -------------------------------------------------------------------------------- 1 | { 2 | clever = { 3 | amd = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC34wZQFEOGkA5b0Z6maE3aKy/ix1MiK1D0Qmg4E9skAA57yKtWYzjA23r5OCF4Nhlj1CuYd6P1sEI/fMnxf+KkqqgW3ZoZ0+pQu4Bd8Ymi3OkkQX9kiq2coD3AFI6JytC6uBi6FaZQT5fG59DbXhxO5YpZlym8ps1obyCBX0hyKntD18RgHNaNM+jkQOhQ5OoxKsBEobxQOEdjIowl2QeEHb99n45sFr53NFqk3UCz0Y7ZMf1hSFQPuuEC/wExzBBJ1Wl7E1LlNA4p9O3qJUSadGZS4e5nSLqMnbQWv2icQS/7J8IwY0M8r1MsL8mdnlXHUofPlG1r4mtovQ2myzOx clever@nixos"; 4 | amd_distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKjCrwJ+3CzAiBbyX/CaHQpxvVG5Af5M829gM8HPKCMiAi0OyAvqSzKJFiN/mkYFSwT50o5z00+49QR6x/a2vs6UtyncWqWn29npMWOZXVo/Dgzu7C216w9Glt5GpFGzqpbCrX3EkiTyEAxLCmSABxee2jFctDcVvRbmgPuP9lIBYU0aHqcmwnO5m96gqNKbZdFDe6/soUPF+oaB8hVT2ZxKGBEWGkVnmuUOHcAyHjxeVOT4nixzv/aSmjZdwihRf/8xbjENtDQOAzlSvyHQLbsufxadmoR+CKyYwu/4igNX0n2tV4OzDOl5+cxaoIffn6Tq8SO/21vRAD0bv44i9V root@amd-nixos"; 5 | laptop = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ2/teWxbcG48i+mjrAMHdMEcA0jC5dTKxuJfVoQK+ddhlLKga3VUl54luxHCeglzRhfZOZuY+SQNPdR7OhjwwB/QNouK7Rx9Mhq7lxoqv3mt64YKTYnt8x5ukgs67eHHKhb6PIHT4WsWWMF13nRgjAfF3q7U0Mmab+YrQnCS0AnUUetiOu6W/kK2VfEmWzTkjqGrIYs03FuEPUNVab+1sGjcaWcxmV0xodEX/+5+dehmKzXD0yvPnSBw4DWpZkXApYK8X6i0Yoax4vRB4hBoNelYjphd5VkpY9rJLt8R1aLX5+xFPb6jyUKJT6KgiIJbgRRLwec2M/z6C0Jp5nYI3 clever@laptop"; 6 | router_root = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHc1Df9/TbVCblO1wgwTFql7U0qSXLa9O1D4m3slHeuaKqDxJ0YiRwLIfhn7tXKcxXecbH+a7K40sRFIpe5BP4lUMPr7+TarZ+vlm2zvmnSQ6tuU0sV6A0vVyZddqf1Atx9DDbRewW5n+9AIR4js6gH/uNvORrjTJRy80of8gOf93cbVMeTfVPmFoSNvbRcc4CScvBxB20Mogq4aJEbnMdDOJZc2TaK2aF2IoYVG9KnI2ndoFr2693YX0QGVxYuYA0/DcW8Eib/Btm2FwnVR5PpANySI3rSR9o1xgC/dpbSX2y1FU7j9BxTMLZmw02NuQiZRoA+YpFVChcy+JbqljR root@router"; 7 | ramboot = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDbT602iZQq/t13jCAThxk13r8E4pEqZbPqoRpi4thPbLc6AAYdxEPemADGcsx60zWT/PEvgXfkDLVU1L6vHB0v3GUZS96xZhZPgYAHR0kACSUIZH2PK7r8XA422JuPRBCtB5Oj8vcNKu6bsfb4uSul3Ia1HbgGYzhc5r6u/GtRHrI8oW6Qzq8BDyEYc4J6dv7tw7n4FjhlUKEWCNMnkoQd2Fr2gYM0/PCBnQMSBXevf2IgLlJlRAR3sH4lW21jVUN1m3VGIfiHwef7ZSD8ApyGaW0snTe8/JkGZkMbK/wnGp7R7aUMQCIvcaa+y/I+TDrfFjmJn/Ht7wEAN66NJdSD clever@ramboot"; 8 | nix1 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDH43kle0lnQYhzbjWpV3pqPOuhvGlI9t/NOk2aemB9HXoSc1MbkMa3bGGT3C16q8lHrLcXjLaXTJJyVTacTNP0AOxbDRkM6M/D74EoT9GUdygwzIRSzSrePOBLMueYO7sijVZusYHRXlOa63j45dnUIC60aZf2Z5AeP9YOSwrEM71/HTy3SeBhSfo1fkbVBOU8dIAHrk2KvmKBj7bzXeAsVuiyhD1h5beE8cxl4tlB2FHsVqbkj52WrYAY0pwRCEtQUgTZqH26EexMK+HMSe/O1i210JfUL52vepDrIXuWO0rxc5niPCbIzwBVL2EyPszPrj2B/wwLnPS3O36r80rN root@nix1"; 9 | nix2 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNUdI3J9Z1PQW2DxWljtLVCwgUY16rzwmFBa2tDPKwjmPZX8oQwYNBRBnzRVbVdKsBcu+LIKHOWYcHVOULShZQG7XAnpmR2LBWlPY5zjNRglEuiGFaahDcrZvFRC8oS/hgwAbgRVbRKUvK+omuwyBnm1QomRP08kAlQy0JUMC1HhJ32woNoRAwi5EmnToldowzOC5fjwIY8gRJ0Giw1GYEKcs4Op+sivyRzfFZogj57odWXvUfTFNuVtgl58OB7vHPSJhtuhRKPJ9BXCwOuj2HMI6xlBrIn2DOd38zl3bkTzZTszRGlywuXZffxVhDlImYDnZy0ifONtEJwqSNWAql root@nix2"; 10 | hydra = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvT+1PczdcWhYiNptMyitxTUfaJsb3o3mSb+0AzG998dMQmGnNfjY1jIqwsMmtQk4N7+OM6Up1/khyexrWAhNj0FLpQYuVm1BpSaxbT9uqZ8Jt8eaPkzAS1gxIJR+4nKGmrCv/1mbyunFb2MKuLlwdVwbzqhIYqDRYctDVrPvzUq9HYSEjGA17fzKjrTh/B/JBRzhyE2UZb3+5Zd7vJxV8Sr4+23+JVDmwP1BOF0X8++v9q/9B5hWo3XQigGmbUTnJkEtM2/7EICfsRdqcSylUyZqdMbONNaocRzhJOgUcYf1noTaFNaocbEvcSMUfoE/r7YqLdQjWr0dQiltYk7Gl hydra-queue-runner@chipuppoker.com"; 11 | laptopLuks = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAEt7QydPPPz4xtJY6OwWeZeA+dyMObUXZv3MZbFFAnhrmFpyNyzroCVKNLSNRSBYyjF0JOkoE7Bxg7IHIG6YuztdBSaa872KeIajkTgas00B0pFkbOm+tWfnVEyxjYPXG8xxUrdfPz4oTZOl7mVJJCCcyqaQQhkbAC13tYO3J3f0FhOSSbg6N5VGTy4Bv7hiFWJFtTD/3wATgUT2g4I/syem6HaqSfaOcXSCXCIQyDyhoLDwbV4BKnpDbqma4pb4D8PmIuaJ76C8ctg0ia2IYS8vhphmCry7FeK9wc5hP/9siA7w02mfWsaLiqFlMdtxoZy0aYIdkBoJGH9oZhnp5 clever@laptop"; 12 | nas_distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM3J+b+IoVRaM3Mr8M0iHPNTdLvBCKDJyt3zuiYVi1PoEKHuEd+BT7CDhdWS0BrvWoXNfa6vFNnniXQHY4euZPoyVHhVphJ508p+TfBReHgJ41+UHU6TOjam7+bIek5LN+qTi8s/CXsTsn2e6wAhgwmKPLEt2NBGgDvwVlivBfmgpcob+hOwOaFHpOEv+W1jmsJYdnRsX9K4jWEx6EEj+qxUa53ubwCwjtJ0o+s59wT2b+4M3qakpu1UZgmmchn8RWmf9OYPRaSyO1TEaGdLnDrhBezwVXKDgulZ8VKbAowpPCMjuqzR28XyNJDVQJHudy9Ir7k0HKQwTUYsqgcV/h root@nas"; 13 | }; 14 | dual.distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgUfyV6YsrTDoIB1/i65J8H+0/rJ19JkxwJVcmVo3hm5rZfjkaz6BL85BmtB7/zFQZ+AEldJKk0bI1glRIVi0ysvpskAL2ZUkhZEzd1l4QSbmD0EIaj0ue3MN+5Rwdryz+dgqYFnISRF/qVMx9HDtmwrce4N+loA7YEbe8eD/cIPQeyhy81v9LLWNqgPve3hvYt5I4NbsoDiHsj0QF0UPf7+xhSxstJj4D5Cu02dS1SDa5xGO0Fg2n9nTEOy6N/9XVwgxihjj26Dy4Uockx0BZXOvq+rtXhs7T2OaiG4hES4cswBb3/U0dxTxf+vrld96veUAymEM4HSEpWrORl3k/ root@nixos distro"; 15 | router_distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKITUnIETct0d1Ky7iEofM8BV/U9ViuAd72abm26ibhkVKYuLlIvNBtf7+fsyaHR3cc4kmiUz26co4LV2q10HLO7nua7Ry0QhtPvPnpudandB4LbV4ieW1cqcWcPpsM1GssUZhZthbkwLf7h2exojqVj8vqPm5RaBl1eULXaPTldCiSe5ZxNuVbm3qT8Lfc2E3ifKT6A7WqZN00f1+YSnaA9uy0VgVDReDqyujAZaKGUwSa2G8eqzN3guN7VcBZek2p1v1n0EwpFdBxzT3Ncqh5wIYPNn084q5lU13TAjw+tTO7Q059e4HFLaR24w8NT60BrO1dbGYLbjWNri1G3pz root@router"; 16 | nix1 = { 17 | distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDH43kle0lnQYhzbjWpV3pqPOuhvGlI9t/NOk2aemB9HXoSc1MbkMa3bGGT3C16q8lHrLcXjLaXTJJyVTacTNP0AOxbDRkM6M/D74EoT9GUdygwzIRSzSrePOBLMueYO7sijVZusYHRXlOa63j45dnUIC60aZf2Z5AeP9YOSwrEM71/HTy3SeBhSfo1fkbVBOU8dIAHrk2KvmKBj7bzXeAsVuiyhD1h5beE8cxl4tlB2FHsVqbkj52WrYAY0pwRCEtQUgTZqH26EexMK+HMSe/O1i210JfUL52vepDrIXuWO0rxc5niPCbIzwBVL2EyPszPrj2B/wwLnPS3O36r80rN root@nix1"; 18 | }; 19 | nix2 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNUdI3J9Z1PQW2DxWljtLVCwgUY16rzwmFBa2tDPKwjmPZX8oQwYNBRBnzRVbVdKsBcu+LIKHOWYcHVOULShZQG7XAnpmR2LBWlPY5zjNRglEuiGFaahDcrZvFRC8oS/hgwAbgRVbRKUvK+omuwyBnm1QomRP08kAlQy0JUMC1HhJ32woNoRAwi5EmnToldowzOC5fjwIY8gRJ0Giw1GYEKcs4Op+sivyRzfFZogj57odWXvUfTFNuVtgl58OB7vHPSJhtuhRKPJ9BXCwOuj2HMI6xlBrIn2DOd38zl3bkTzZTszRGlywuXZffxVhDlImYDnZy0ifONtEJwqSNWAql root@nix2"; 20 | router = { 21 | distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKITUnIETct0d1Ky7iEofM8BV/U9ViuAd72abm26ibhkVKYuLlIvNBtf7+fsyaHR3cc4kmiUz26co4LV2q10HLO7nua7Ry0QhtPvPnpudandB4LbV4ieW1cqcWcPpsM1GssUZhZthbkwLf7h2exojqVj8vqPm5RaBl1eULXaPTldCiSe5ZxNuVbm3qT8Lfc2E3ifKT6A7WqZN00f1+YSnaA9uy0VgVDReDqyujAZaKGUwSa2G8eqzN3guN7VcBZek2p1v1n0EwpFdBxzT3Ncqh5wIYPNn084q5lU13TAjw+tTO7Q059e4HFLaR24w8NT60BrO1dbGYLbjWNri1G3pz root@router"; 22 | root = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHc1Df9/TbVCblO1wgwTFql7U0qSXLa9O1D4m3slHeuaKqDxJ0YiRwLIfhn7tXKcxXecbH+a7K40sRFIpe5BP4lUMPr7+TarZ+vlm2zvmnSQ6tuU0sV6A0vVyZddqf1Atx9DDbRewW5n+9AIR4js6gH/uNvORrjTJRy80of8gOf93cbVMeTfVPmFoSNvbRcc4CScvBxB20Mogq4aJEbnMdDOJZc2TaK2aF2IoYVG9KnI2ndoFr2693YX0QGVxYuYA0/DcW8Eib/Btm2FwnVR5PpANySI3rSR9o1xgC/dpbSX2y1FU7j9BxTMLZmw02NuQiZRoA+YpFVChcy+JbqljR root@router"; 23 | }; 24 | amd_distro = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKjCrwJ+3CzAiBbyX/CaHQpxvVG5Af5M829gM8HPKCMiAi0OyAvqSzKJFiN/mkYFSwT50o5z00+49QR6x/a2vs6UtyncWqWn29npMWOZXVo/Dgzu7C216w9Glt5GpFGzqpbCrX3EkiTyEAxLCmSABxee2jFctDcVvRbmgPuP9lIBYU0aHqcmwnO5m96gqNKbZdFDe6/soUPF+oaB8hVT2ZxKGBEWGkVnmuUOHcAyHjxeVOT4nixzv/aSmjZdwihRf/8xbjENtDQOAzlSvyHQLbsufxadmoR+CKyYwu/4igNX0n2tV4OzDOl5+cxaoIffn6Tq8SO/21vRAD0bv44i9V root@amd-nixos"; 25 | ramboot = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDbT602iZQq/t13jCAThxk13r8E4pEqZbPqoRpi4thPbLc6AAYdxEPemADGcsx60zWT/PEvgXfkDLVU1L6vHB0v3GUZS96xZhZPgYAHR0kACSUIZH2PK7r8XA422JuPRBCtB5Oj8vcNKu6bsfb4uSul3Ia1HbgGYzhc5r6u/GtRHrI8oW6Qzq8BDyEYc4J6dv7tw7n4FjhlUKEWCNMnkoQd2Fr2gYM0/PCBnQMSBXevf2IgLlJlRAR3sH4lW21jVUN1m3VGIfiHwef7ZSD8ApyGaW0snTe8/JkGZkMbK/wnGp7R7aUMQCIvcaa+y/I+TDrfFjmJn/Ht7wEAN66NJdSD clever@ramboot"; 26 | } 27 | -------------------------------------------------------------------------------- /lan.nix: -------------------------------------------------------------------------------- 1 | { 2 | nas = { mac = "d0:50:99:7a:80:21"; ip = "10.0.0.11"; }; 3 | amd = { mac = "74:56:3c:44:7b:b2"; ip = "10.0.0.15"; }; 4 | pi1a = { mac = "b8:27:eb:0a:ad:04"; ip = "10.0.0.20"; }; 5 | chromecast = { mac = "b0:2a:43:32:33:d5"; ip = "10.0.0.50"; }; 6 | pi400 = { mac = "dc:a6:32:d6:a3:db"; ip = "10.0.0.51"; }; 7 | system76 = { mac = "a0:af:bd:82:39:0d"; ip = "10.0.0.52"; }; 8 | tablet = { mac = "84:98:66:3F:37:AD"; ip = "10.0.0.53"; }; 9 | picow = { mac = "28:CD:C1:0C:4C:4F"; ip = "10.0.0.54"; }; 10 | pi4 = { mac = "dc:a6:32:64:ae:77"; ip = "10.0.0.70"; }; 11 | pi400e = { mac = "dc:a6:32:d6:a3:d9"; ip = "10.0.0.71"; }; 12 | pi4w = { mac = "dc:a6:32:64:ae:78"; ip = "10.0.0.80"; }; 13 | pi5w = { mac = "d8:3a:dd:b0:1e:93"; ip = "10.0.0.90"; }; 14 | pi5e = { mac = "d8:3a:dd:b0:1e:92"; ip = "10.0.0.91"; }; 15 | pi02 = { mac = "e4:5f:01:5b:cf:b0"; ip = "10.0.0.111"; }; 16 | thinkpad = { mac = "14:85:7f:ee:15:d8"; ip = "10.0.0.112"; }; 17 | } 18 | -------------------------------------------------------------------------------- /lan.reverse: -------------------------------------------------------------------------------- 1 | $TTL 3D 2 | @ IN SOA ns.localnet. hostmaster (1 8H 4H 4W 1D) 3 | NS ns.localnet. 4 | 5 | 1 IN PTR router.localnet. 6 | 15 IN PTR amd.localnet. 7 | 10 IN PTR ramboot.localnet. 8 | 11 IN PTR nas.localnet. 9 | 30 IN PTR nix1.localnet. 10 | 31 IN PTR nix2.localnet. 11 | 32 IN PTR system76.localnet. 12 | 43 IN PTR neo 13 | 50 IN PTR pi0.localnet. 14 | 51 IN PTR pi1a 15 | 52 IN PTR system76.localnet. 16 | 53 IN PTR pi3 17 | 55 IN PTR pi4 18 | 56 IN PTR pi400.localnet. 19 | 57 IN PTR pi400e.localnet. 20 | 61 IN PTR c2d.localnet. 21 | 22 | 90 IN PTR pi5w.localnet. 23 | 91 IN PTR pi5e.localnet. 24 | -------------------------------------------------------------------------------- /load-secrets.nix: -------------------------------------------------------------------------------- 1 | if builtins.pathExists ./secrets.nix then import ./secrets.nix else { 2 | token1 = ""; 3 | token2 = ""; 4 | token3 = ""; 5 | snmp = ""; 6 | hashedPw = ""; 7 | datadogKey = ""; 8 | weechats = []; 9 | publicIpv6Prefix = ""; 10 | wifiPassword = ""; 11 | grafanaCreds = { 12 | user = "admin"; 13 | password = "admin"; 14 | }; 15 | oauth = { 16 | clientID = ""; 17 | clientSecret = ""; 18 | cookie.secret = ""; 19 | }; 20 | hass_token = ""; 21 | } 22 | -------------------------------------------------------------------------------- /localnet: -------------------------------------------------------------------------------- 1 | $TTL 3D 2 | @ IN SOA ns.localnet. hostmaster ( 3 | 1 ; serial 4 | 8H ; refresh 5 | 2H ; retry 6 | 4W ; expire 7 | 1D) ; minimum ttl 8 | NS ns.localnet. 9 | localnet. IN A 10.0.0.1 10 | router IN A 10.0.0.1 11 | ns IN A 10.0.0.1 12 | ramboot IN A 192.168.2.10 13 | nas IN A 10.0.0.11 14 | amd IN A 10.0.0.15 15 | pi1a IN A 10.0.0.20 16 | pi400 IN A 10.0.0.51 17 | system76 IN A 10.0.0.52 ; lan wifi 18 | tablet IN A 10.0.0.53 19 | picow IN A 10.0.0.54 20 | ;system76 IN A 192.168.123.12 ; toxvpn 21 | pi4 IN A 10.0.0.70 22 | pi400e IN A 10.0.0.71 23 | thinkpad IN A 10.0.0.112 24 | pi4w IN A 10.0.0.80 25 | nix1 IN A 192.168.2.30 26 | nix2 IN A 192.168.2.31 27 | neo IN A 192.168.2.43 28 | 29 | pi0 IN A 192.168.2.50 30 | pi3 IN A 192.168.2.53 31 | 32 | pi5w IN A 10.0.0.90 33 | pi5e IN A 10.0.0.91 34 | pi02 IN A 10.0.0.111 35 | 36 | c2d IN A 10.0.0.61 37 | 38 | nixcache IN CNAME c2d 39 | 40 | 41 | batcave IN A 192.168.123.4 42 | charlie IN A 192.168.123.39 43 | nixsw IN A 192.168.123.50 44 | frosty IN A 192.168.18.10 45 | judah IN A 192.168.18.11 46 | 47 | ;amd IN AAAA fe80::4216:7eff:feb3:3248 48 | ;ramboot IN AAAA fe80::21c:23ff:fe16:4bb3 49 | ;nas IN AAAA 2001:470:1d:19a:d250:99ff:fe7a:8021 50 | ;gamer IN AAAA fe80::217:a4ff:fe1c:6200 51 | ;c2d IN AAAA 2001:470:1d:19a:21c:c4ff:fe6e:46 52 | ;system76 IN AAAA 2001:470:1d:19a:a2af:bdff:fe82:390d 53 | ;router IN AAAA fe80::230:48ff:fec5:d2df 54 | ;nix1 IN AAAA fe80::90c5:e2ff:febb:12a9 55 | ;nix2 IN AAAA fe80::5c88:5bff:fed7:6ebc 56 | -------------------------------------------------------------------------------- /mac-arm-build-slave/default.nix: -------------------------------------------------------------------------------- 1 | let 2 | linux_pkgs = import { system = "x86_64-linux"; config = {}; overlays = []; }; 3 | host_pkgs = import { config = {}; overlays = []; }; 4 | inherit (linux_pkgs) lib; 5 | in lib.fix (self: { 6 | configuration = { ... }: { 7 | imports = [ 8 | (linux_pkgs.path + "/nixos/modules/installer/netboot/netboot-minimal.nix") 9 | ../qemu.nix 10 | ]; 11 | qemu-user = { 12 | arm = true; 13 | aarch64 = true; 14 | }; 15 | systemd.services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ]; 16 | users.users.root.openssh.authorizedKeys.keys = [ (builtins.readFile ~/.ssh/id_rsa.pub) ]; 17 | }; 18 | config = (import { system = "x86_64-linux"; configuration = self.configuration; }).config; 19 | go = host_pkgs.writeScript "go" '' 20 | #!${host_pkgs.stdenv.shell} 21 | ${host_pkgs.qemu}/bin/qemu-system-x86_64 -kernel ${self.config.system.build.kernel}/bzImage \ 22 | -initrd ${self.config.system.build.netbootRamdisk}/initrd \ 23 | -append "init=${builtins.unsafeDiscardStringContext self.config.system.build.toplevel}/init ${toString self.config.boot.kernelParams}" \ 24 | -m 2048 \ 25 | -net nic,netdev=user.0,model=virtio \ 26 | -netdev user,id=user.0,hostfwd=tcp:127.0.0.1:2200-:22 27 | ''; 28 | }) 29 | -------------------------------------------------------------------------------- /media-center.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | services.pipewire.enable = false; 5 | services.xserver = { 6 | enable = true; 7 | displayManager = { 8 | autoLogin = { 9 | enable = true; 10 | user = "media"; 11 | }; 12 | sddm = { 13 | enable = true; 14 | }; 15 | sessionCommands = '' 16 | ratpoison & 17 | exec plexmediaplayer --fullscreen --tv > ~/.plexlogs 18 | ''; 19 | }; 20 | }; 21 | hardware.pulseaudio = { 22 | enable = true; 23 | }; 24 | environment.systemPackages = with pkgs; [ 25 | ratpoison pavucontrol 26 | #syncplay 27 | mpv 28 | #teamspeak_client 29 | ]; 30 | users.extraUsers.media = { 31 | isNormalUser = true; 32 | uid = 1100; 33 | extraGroups = [ "audio" ]; 34 | }; 35 | networking.firewall.allowedTCPPorts = [ 36 | 8060 # the plex frontend does upnp things 37 | 32433 # plex-media-player 38 | ]; 39 | } 40 | -------------------------------------------------------------------------------- /multi-boot-helper.nix: -------------------------------------------------------------------------------- 1 | with import {}; 2 | let 3 | netboot = import (pkgs.path + "/nixos/lib/eval-config.nix") { 4 | modules = [ 5 | (pkgs.path + "/nixos/modules/installer/netboot/netboot-minimal.nix") 6 | module 7 | ]; 8 | }; 9 | module = { 10 | # you will want to add options here to support your filesystem 11 | # and also maybe ssh to let you in 12 | boot.supportedFilesystems = [ "zfs" ]; 13 | }; 14 | grubFragment = writeText "grub.cfg" (builtins.unsafeDiscardStringContext '' 15 | menuentry "Nixos Installer" { 16 | linux ($drive1)/nixos-kernel init=${netboot.config.system.build.toplevel}/init ${toString netboot.config.boot.kernelParams} 17 | initrd ($drive1)/nixos-initrd 18 | } 19 | ''); 20 | in runCommand "multi-boot-helper" {} '' 21 | mkdir $out 22 | cp -L ${netboot.config.system.build.kernel}/bzImage $out/nixos-kernel 23 | cp -L ${netboot.config.system.build.netbootRamdisk}/initrd $out/nixos-initrd 24 | cp ${grubFragment} $out/grub-fragment.cfg 25 | '' 26 | -------------------------------------------------------------------------------- /nas-hydra.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | let 4 | passwords = import ./load-secrets.nix; 5 | hydraRev = "1ef6b5e7"; 6 | hydraSrc = pkgs.fetchFromGitHub { 7 | owner = "cleverca22"; 8 | repo = "hydra"; 9 | rev = hydraRev; 10 | hash = "sha256-Fj0QgY+lkuEoRsPxL/y4VLHs1QWeq+kPbnt4hq7j+/o="; 11 | }; 12 | hydraFlake = builtins.getFlake "github:cleverca22/hydra/${hydraRev}"; 13 | hydra-fork = hydraFlake.packages.x86_64-linux.default; 14 | hydraSrc' = { 15 | outPath = hydraSrc; 16 | rev = hydraRev; 17 | revCount = 1234; 18 | }; 19 | #hydra-fork = (import (hydraSrc + "/release.nix") { hydraSrc = hydraSrc'; nixpkgs = pkgs.path; }).build.x86_64-linux; 20 | in { 21 | users.users.hydra-www.extraGroups = [ "hydra" ]; 22 | systemd.services.hydra-queue-runner = { 23 | serviceConfig = { 24 | #ExecStart = lib.mkForce "@${config.services.hydra.package}/bin/hydra-queue-runner hydra-queue-runner -vvvvvv"; 25 | }; 26 | wantedBy = lib.mkForce []; 27 | }; 28 | systemd.services.hydra-evaluator = { 29 | path = [ pkgs.jq pkgs.gawk ]; 30 | environment.TMPDIR = "/dev/shm"; 31 | wantedBy = lib.mkForce []; 32 | }; 33 | nix.extraOptions = '' 34 | allowed-uris = https://github.com/input-output-hk/nixpkgs/archive/ https://github.com/nixos https://github.com/input-output-hk https://github.com/taktoa/nixpkgs github: 35 | experimental-features = nix-command flakes 36 | ''; 37 | nix.min-free = 10; 38 | nix.max-free = 15; 39 | nix.settings.auto-optimise-store = true; 40 | services = { 41 | postgresql = { 42 | package = pkgs.postgresql_16; 43 | identMap = '' 44 | hydra-users clever clever 45 | hydra-users root root 46 | ''; 47 | }; 48 | hydra = { 49 | package = hydra-fork; 50 | enable = true; 51 | extraConfig = with passwords; '' 52 | binary_cache_secret_key_file = /etc/nix/keys/secret-key-file 53 | store-uri = file:///nix/store?secret-key=/etc/nix/keys/secret-key-file 54 | max_output_size = ${toString (1024*1024*1024*3)} # 3gig 55 | max_concurrent_evals = 1 56 | evaluator_initial_heap_size = ${toString (1024*1024*1024)} # 1gig 57 | 58 | input-output-hk = ${token1} 59 | cleverca22 = ${token1} 60 | arcane-chat = ${token1} 61 | haskell-capnp = ${token1} 62 | zenhack = ${token1} 63 | language-ninja = ${token1} 64 | awakesecurity = ${token1} 65 | zenhack = ${token2} 66 | taktoa = ${token3} 67 | 68 | 69 | jobs = toxvpn:toxvpn.* 70 | inputs = toxvpn 71 | excludeBuildFromContext = 1 72 | 73 | 74 | jobs = not-os:notos.* 75 | inputs = notos 76 | excludeBuildFromContext = 1 77 | 78 | 79 | jobs = haskell-capnp:zenhack.* 80 | inputs = src 81 | excludeBuildFromContext = 1 82 | 83 | ''; 84 | hydraURL = "https://hydra.angeldsis.com"; 85 | listenHost = "localhost"; 86 | maxServers = 10; 87 | maxSpareServers = 2; 88 | minSpareServers = 1; 89 | minimumDiskFree = 2; 90 | minimumDiskFreeEvaluator = 1; 91 | notificationSender = "cleverca22@gmail.com"; 92 | port = 3001; 93 | useSubstitutes = true; 94 | }; 95 | nginx = { 96 | virtualHosts = { 97 | "hydra.angeldsis.com" = { 98 | enableACME = false; 99 | forceSSL = false; 100 | locations = { 101 | "/".extraConfig = '' 102 | proxy_pass http://localhost:3001; 103 | proxy_set_header Host $host; 104 | proxy_set_header X-Forwarded-Proto "https"; 105 | proxy_set_header X-Real-IP $remote_addr; 106 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 107 | proxy_read_timeout 120; 108 | ''; 109 | "/hydra-charter/" = { 110 | alias = "/nas/private/hydra-charter/"; 111 | index = "index.htm"; 112 | }; 113 | }; 114 | }; 115 | }; 116 | }; 117 | }; 118 | } 119 | -------------------------------------------------------------------------------- /nas-monitoring-rewrite.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | 3 | let 4 | secrets = import ./load-secrets.nix; 5 | oauthProxyConfig = '' 6 | auth_request /oauth2/auth; 7 | error_page 401 = /oauth2/sign_in; 8 | 9 | # pass information via X-User and X-Email headers to backend, 10 | # requires running with --set-xauthrequest flag 11 | auth_request_set $user $upstream_http_x_auth_request_user; 12 | auth_request_set $email $upstream_http_x_auth_request_email; 13 | proxy_set_header X-User $user; 14 | proxy_set_header X-Email $email; 15 | 16 | # if you enabled --cookie-refresh, this is needed for it to work with auth_request 17 | auth_request_set $auth_cookie $upstream_http_set_cookie; 18 | add_header Set-Cookie $auth_cookie; 19 | ''; 20 | webhost = "monitoring.earthtools.ca"; 21 | monitoredNodes = { 22 | "router" = { 23 | hasNginx = true; 24 | }; 25 | "nas" = { 26 | hasNginx = true; 27 | hasZfs = true; 28 | }; 29 | "amd" = { 30 | hasZfs = true; 31 | }; 32 | c2d = { 33 | }; 34 | "nixbox360" = { 35 | }; 36 | #"pi0" = {}; 37 | #"pi1a" = {}; 38 | #"pi3" = {}; 39 | #"pi4" = {}; 40 | #"pi4w" = {}; 41 | #"pi5w" = {}; 42 | #"pi5e" = { pi5_voltage = true; }; 43 | #"pi400e" = {}; 44 | system76 = { 45 | hasZfs = true; 46 | }; 47 | thinkpad = { 48 | hasZfs = true; 49 | }; 50 | }; 51 | only_rpi = n: v: v.pi5_voltage or false; 52 | in { 53 | networking.firewall.allowedTCPPorts = [ 80 ]; 54 | services = { 55 | grafana = { 56 | enable = true; 57 | #extraOptions = { # https://grafana.com/docs/auth/auth-proxy/ 58 | # AUTH_PROXY_ENABLED = "true"; 59 | # AUTH_PROXY_AUTO_SIGN_UP = "true"; 60 | #}; 61 | settings = { 62 | "auth.proxy" = { 63 | enabled = true; 64 | header_name = "X-Email"; 65 | header_property = "email"; 66 | auto_sign_up = true; 67 | whitelist = "127.0.0.1, ::1"; 68 | }; 69 | server.domain = "${webhost}"; 70 | server.http_addr = ""; 71 | server.root_url = "%(protocol)ss://%(domain)s/grafana/"; 72 | security.admin_password = secrets.grafanaCreds.password; 73 | security.admin_user = "admin"; 74 | users.allow_sign_up = false; 75 | }; 76 | provision = { 77 | enable = true; 78 | datasources.settings.datasources = [ 79 | { 80 | type = "prometheus"; 81 | name = "prometheus"; 82 | url = "http://localhost:9090/prometheus"; 83 | } 84 | ]; 85 | dashboards.settings.providers = [ 86 | { 87 | name = "generic"; 88 | options.path = ./grafana/generic; 89 | } 90 | ]; 91 | }; 92 | }; 93 | oauth2-proxy = { 94 | cookie.refresh = "1h"; 95 | email.domains = [ "iohk.io" ]; 96 | enable = true; 97 | keyFile = "/var/keys/oauth2_proxy"; 98 | nginx = { 99 | domain = webhost; 100 | virtualHosts = { 101 | ${webhost} = { 102 | }; 103 | }; 104 | }; 105 | provider = "google"; 106 | setXauthrequest = true; 107 | }; 108 | nginx = { 109 | enable = true; 110 | virtualHosts."${webhost}".locations = { 111 | "/grafana/".extraConfig = '' 112 | ${oauthProxyConfig} 113 | proxy_pass http://localhost:3000/; 114 | proxy_set_header Host $host; 115 | proxy_set_header REMOTE_ADDR $remote_addr; 116 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 117 | proxy_set_header X-Forwarded-Proto https; 118 | ''; 119 | "/grafana/api/live/ws".extraConfig = '' 120 | ${oauthProxyConfig} 121 | proxy_http_version 1.1; 122 | proxy_pass http://localhost:3000/api/live/ws; 123 | proxy_set_header Connection "Upgrade"; 124 | proxy_set_header Host $host; 125 | proxy_set_header Upgrade $http_upgrade; 126 | proxy_set_header X-Forwarded-Proto $scheme; 127 | ''; 128 | "/prometheus/".extraConfig = '' 129 | ${oauthProxyConfig} 130 | proxy_pass http://localhost:9090/prometheus/; 131 | proxy_set_header Host $host; 132 | proxy_set_header REMOTE_ADDR $remote_addr; 133 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 134 | proxy_set_header X-Forwarded-Proto https; 135 | ''; 136 | "/alertmanager/".extraConfig = oauthProxyConfig; 137 | "/graylog/".extraConfig = oauthProxyConfig; 138 | }; 139 | }; 140 | prometheus = { 141 | enable = true; 142 | webExternalUrl = "https://${webhost}/prometheus/"; 143 | extraFlags = [ 144 | "--storage.tsdb.retention=${toString (2 * 365 * 24)}h" 145 | #"--log.level=debug" 146 | ]; 147 | scrapeConfigs = let 148 | pi5_voltage = { 149 | job_name = "pi5_voltage"; 150 | scrape_interval = "10s"; 151 | static_configs = let 152 | mkPi5Voltage = host: obj: { 153 | targets = [ "${host}:9101" ]; 154 | labels.alias = host; 155 | }; 156 | in 157 | lib.mapAttrsToList mkPi5Voltage (lib.filterAttrs only_rpi monitoredNodes); 158 | }; 159 | mkMinecraft = name: { 160 | job_name = "minecraft-${name}"; 161 | scrape_interval = "60s"; 162 | metrics_path = "/cc/hdd/0/${name}.txt"; 163 | static_configs = [ 164 | { 165 | targets = [ 166 | "77.163.112.172:3876" 167 | ]; 168 | } 169 | ]; 170 | }; 171 | in [ 172 | (mkMinecraft "prom") 173 | (mkMinecraft "prom2") 174 | { 175 | job_name = "cachecache"; 176 | scrape_interval = "60s"; 177 | metrics_path = "/"; 178 | static_configs = [ { targets = [ "nas:8080" ]; } ]; 179 | } 180 | { 181 | job_name = "boiler"; 182 | scrape_interval = "60s"; 183 | metrics_path = "/"; 184 | static_configs = [ { targets = [ "10.0.0.91:9102" ]; } ]; 185 | } 186 | { 187 | job_name = "prometheus"; 188 | scrape_interval = "60s"; 189 | metrics_path = "/prometheus/metrics"; 190 | static_configs = [ 191 | { 192 | targets = [ "localhost:9090" ]; 193 | labels.alias = "prometheus"; 194 | } 195 | ]; 196 | } 197 | { 198 | job_name = "temp_daemon"; 199 | scrape_interval = "60s"; 200 | static_configs = [ 201 | { 202 | targets = [ "c2d:49116" ]; 203 | labels.alias = "temp_daemon"; 204 | } 205 | ]; 206 | } 207 | { 208 | job_name = "fragmentation"; 209 | scrape_interval = "60s"; 210 | metrics_path = "/metrics"; 211 | static_configs = let 212 | makeFragConfig = host: obj: { 213 | targets = [ "${host}:9103" ]; 214 | labels.alias = host; 215 | }; 216 | onlyZfs = n: v: v.hasZfs or false; 217 | in lib.mapAttrsToList makeFragConfig (lib.filterAttrs onlyZfs monitoredNodes); 218 | } 219 | pi5_voltage 220 | { 221 | job_name = "amdgpu"; 222 | scrape_interval = "10s"; 223 | metrics_path = "/metrics"; 224 | static_configs = [ 225 | { 226 | targets = [ "amd:12913" ]; 227 | labels.alias = "amd"; 228 | } 229 | ]; 230 | } 231 | { 232 | job_name = "faucet"; 233 | scrape_interval = "60s"; 234 | metrics_path = "/metrics"; 235 | static_configs = [ 236 | #{ 237 | # targets = [ "amd:8090" ]; 238 | # labels.alias = "amd"; 239 | # labels.namespace = "preview"; 240 | #} 241 | ]; 242 | } 243 | { 244 | job_name = "smartctl"; 245 | scrape_interval = "60s"; 246 | metrics_path = "/metrics"; 247 | static_configs = [ 248 | { 249 | targets = [ "amd:9633" ]; 250 | labels.alias = "amd"; 251 | } 252 | { 253 | targets = [ "nas:9633" ]; 254 | labels.alias = "nas"; 255 | } 256 | ]; 257 | } 258 | { 259 | job_name = "hass"; 260 | scrape_interval = "60s"; 261 | metrics_path = "/api/prometheus"; 262 | bearer_token = secrets.hass_token; 263 | scheme = "http"; 264 | static_configs = [ 265 | { 266 | targets = [ "localhost:8123" ]; 267 | labels.alias = "hass"; 268 | } 269 | ]; 270 | } 271 | { 272 | job_name = "stationeers"; 273 | scrape_interval = "60s"; 274 | metrics_path = "/metrics"; 275 | scheme = "http"; 276 | static_configs = [ 277 | { 278 | targets = [ 279 | #"amd:8000" 280 | #"system76:8000" 281 | ]; 282 | labels.alias = "amd"; 283 | } 284 | ]; 285 | } 286 | { 287 | job_name = "node"; 288 | scrape_interval = "60s"; 289 | scrape_timeout = "50s"; 290 | static_configs = let 291 | makeNodeConfig = key: value: { 292 | targets = [ 293 | "${key}:9100" 294 | ]; 295 | labels = { 296 | alias = key; 297 | } // value.labels or {}; 298 | }; 299 | in lib.mapAttrsToList makeNodeConfig monitoredNodes; 300 | } 301 | { 302 | # for hydra 303 | job_name = "node_statd"; 304 | scrape_interval = "60s"; 305 | static_configs = [ 306 | { 307 | targets = [ "nas:9102" ]; 308 | labels.alias = "nas"; 309 | } 310 | ]; 311 | } 312 | { 313 | job_name = "nginx"; 314 | scrape_interval = "60s"; 315 | metrics_path = "/status/format/prometheus"; 316 | static_configs = let 317 | makeNodeConfig = key: value: { 318 | targets = [ "${key}:9113" ]; 319 | labels = { 320 | alias = key; 321 | } // value.labels or {}; 322 | }; 323 | onlyNginx = n: v: v.hasNginx or false; 324 | in lib.mapAttrsToList makeNodeConfig (lib.filterAttrs onlyNginx monitoredNodes); 325 | } 326 | ]; 327 | }; 328 | }; 329 | users.users.oauth2_proxy = { 330 | group = "oauth2_proxy"; 331 | isSystemUser = true; 332 | }; 333 | users.groups.oauth2_proxy = {}; 334 | } 335 | -------------------------------------------------------------------------------- /nas-monitoring.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | let 4 | secrets = import ./load-secrets.nix; 5 | sources = import ./nix/sources.nix; 6 | iohk-ops = sources.iohk-ops; 7 | cfg = config.services.monitoring-services; 8 | monitoredNodeOptions = { name, config, ... }: { 9 | options = { 10 | name = lib.mkOption { 11 | type = lib.types.str; 12 | }; 13 | labels = lib.mkOption { 14 | type = lib.types.attrs; 15 | default = {}; 16 | description = "Labels to add in prometheus"; 17 | }; 18 | hasNginx = lib.mkOption { 19 | type = lib.types.bool; 20 | default = false; 21 | description = "if nginx stats should be scraped"; 22 | }; 23 | }; 24 | config = { 25 | name = lib.mkDefault name; 26 | }; 27 | }; 28 | in { 29 | options = { 30 | services.monitoring-services = { 31 | enable = lib.mkOption { 32 | type = lib.types.bool; 33 | default = true; 34 | }; 35 | monitoredNodes = lib.mkOption { 36 | type = lib.types.loaOf (lib.types.submodule monitoredNodeOptions); 37 | default = {}; 38 | description = '' 39 | Attribute set of Nodes to be monitored. 40 | ''; 41 | example = { 42 | c-a-1 = { 43 | hasNginx = false; 44 | labels.role = "core"; 45 | }; 46 | }; 47 | }; 48 | webhost = lib.mkOption { 49 | type = lib.types.str; 50 | example = "monitoring.lan"; 51 | }; 52 | }; 53 | }; 54 | config = lib.mkIf cfg.enable (lib.mkMerge [ 55 | { 56 | #environment.systemPackages = with pkgs; [ goaccess ]; 57 | services.prometheus.scrapeConfigs = [ 58 | #{ 59 | # job_name = "node-test"; 60 | # scrape_interval = "10s"; 61 | # metrics_path = "/"; 62 | # static_configs = [ 63 | # { 64 | # targets = [ "192.168.2.15:8000" ]; 65 | # } 66 | # ]; 67 | #} 68 | #{ 69 | # job_name = "jormungandr"; 70 | # scrape_interval = "10s"; 71 | # metrics_path = "/metrics"; 72 | # static_configs = [ 73 | # { targets = [ "192.168.2.1:8000" ]; } 74 | # ]; 75 | #} 76 | #{ 77 | # job_name = "exporter"; 78 | # scrape_interval = "10s"; 79 | # metrics_path = "/"; 80 | # static_configs = [ { targets = [ "amd.localnet:8080" ]; } ]; 81 | #} 82 | ]; 83 | services.monitoring-services = { 84 | # enable = true; 85 | webhost = "monitoring.earthtools.ca"; 86 | }; 87 | services.nginx = { 88 | enable = true; 89 | commonHttpConfig = '' 90 | log_format x-fwd '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; 91 | access_log syslog:server=unix:/dev/log x-fwd; 92 | ''; 93 | virtualHosts = { 94 | "${cfg.webhost}" = { 95 | locations = { 96 | "/" = let 97 | indexFile = pkgs.replaceVars ./nginx/monitoring-index-template.html { 98 | monitoringHtml = '' 99 | Monitoring
100 | Grafana
101 | Prometheus
102 | ''; 103 | monitoringProject = "earthtools"; 104 | monitoringLargeImg = null; 105 | monitoringSmallImg = null; 106 | monitoringProjectUrl = null; 107 | }; 108 | rootDir = pkgs.runCommand "nginx-root-dir" {} '' 109 | mkdir $out 110 | cd $out 111 | cp -v ${indexFile} index.html 112 | ''; 113 | in { 114 | extraConfig = '' 115 | etag off; 116 | add_header etag "\"${builtins.substring 11 32 rootDir}\""; 117 | root ${rootDir}; 118 | ''; 119 | }; 120 | }; 121 | }; 122 | }; 123 | }; 124 | } 125 | (lib.mkIf true { 126 | services = { 127 | #grafana.extraOptions = { 128 | #AUTH_GOOGLE_ENABLED = "true"; 129 | #AUTH_GOOGLE_CLIENT_ID = cfg.oauth.clientID; 130 | #AUTH_GOOGLE_CLIENT_SECRET = cfg.oauth.clientSecret; 131 | #}; 132 | prometheus.exporters = { 133 | blackbox = { 134 | enable = true; 135 | configFile = pkgs.writeText "blackbox-exporter.yaml" (builtins.toJSON { 136 | modules = { 137 | https_2xx = { 138 | prober = "http"; 139 | timeout = "5s"; 140 | http = { 141 | fail_if_not_ssl = true; 142 | }; 143 | }; 144 | htts_2xx = { 145 | prober = "http"; 146 | timeout = "5s"; 147 | }; 148 | ssh_banner = { 149 | prober = "tcp"; 150 | timeout = "10s"; 151 | tcp = { 152 | query_response = [ { expect = "^SSH-2.0-"; } ]; 153 | }; 154 | }; 155 | tcp_v4 = { 156 | prober = "tcp"; 157 | timeout = "5s"; 158 | tcp = { 159 | preferred_ip_protocol = "ip4"; 160 | }; 161 | }; 162 | tcp_v6 = { 163 | prober = "tcp"; 164 | timeout = "5s"; 165 | tcp = { 166 | preferred_ip_protocol = "ip6"; 167 | }; 168 | }; 169 | icmp_v4 = { 170 | prober = "icmp"; 171 | timeout = "60s"; 172 | icmp = { 173 | preferred_ip_protocol = "ip4"; 174 | }; 175 | }; 176 | icmp_v6 = { 177 | prober = "icmp"; 178 | timeout = "5s"; 179 | icmp = { 180 | preferred_ip_protocol = "ip6"; 181 | }; 182 | }; 183 | }; 184 | }); 185 | }; 186 | }; 187 | prometheus.alertmanager = { 188 | enable = false; 189 | configuration = { 190 | route = { 191 | group_by = [ "alertname" "alias" ]; 192 | group_wait = "30s"; 193 | group_interval = "2m"; 194 | receiver = "team-pager"; 195 | routes = cfg.alertmanager.extraRoutes ++ [ 196 | { 197 | match = { 198 | severity = "page"; 199 | }; 200 | receiver = "team-pager"; 201 | } 202 | ] ++ (if (cfg.deadMansSnitch.pingUrl != null) then [{ 203 | match = { 204 | alertname = "DeadMansSnitch"; 205 | }; 206 | repeat_interval = "5m"; 207 | receiver = "deadmanssnitch"; 208 | }] else []); 209 | }; 210 | receivers = cfg.alertmanager.extraReceivers ++ [ 211 | { 212 | name = "team-pager"; 213 | pagerduty_configs = [ 214 | { 215 | service_key = cfg.pagerDuty.serviceKey; 216 | } 217 | ]; 218 | } 219 | ] ++ (if (cfg.deadMansSnitch.pingUrl != null) then [ 220 | { 221 | name = "deadmanssnitch"; 222 | webhook_configs = [{ 223 | send_resolved = false; 224 | url = cfg.deadMansSnitch.pingUrl; 225 | }]; 226 | } 227 | ] else []); 228 | }; 229 | }; 230 | }; 231 | }) 232 | ]); 233 | } 234 | -------------------------------------------------------------------------------- /nas-websites.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | let 4 | remy_hydra = { 5 | locations."/".extraConfig = '' 6 | proxy_pass http://192.168.200.1/; 7 | proxy_set_header Host $host; 8 | ''; 9 | }; 10 | in { 11 | services.nginx = { 12 | eventsConfig = "worker_connections 1024;"; 13 | appendConfig = '' 14 | worker_processes 4; 15 | worker_rlimit_nofile 2048; 16 | ''; 17 | virtualHosts = { 18 | "hydra.taktoa.me" = remy_hydra; 19 | #"hydra.fuspr.net" = remy_hydra; 20 | #"fuspr.net" = { 21 | # locations."/".root = "/var/www/fuspr"; 22 | #}; 23 | }; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /nas-wifi.nix: -------------------------------------------------------------------------------- 1 | let 2 | secrets = import ./load-secrets.nix; 3 | WIFI = "wlan0"; 4 | in { 5 | boot.kernel.sysctl = { 6 | "net.ipv4.ip_forward" = true; 7 | }; 8 | networking = { 9 | interfaces = { 10 | ${WIFI} = { 11 | ipv4.addresses = [ 12 | { 13 | address = "192.168.3.1"; 14 | prefixLength = 24; 15 | } 16 | ]; 17 | }; 18 | }; 19 | }; 20 | services = { 21 | hostapd = { 22 | enable = true; 23 | interface = WIFI; 24 | ssid = "Family-nas"; 25 | wpaPassphrase = secrets.wifiPassword; 26 | }; 27 | dhcpd4 = { 28 | enable = true; 29 | interfaces = [ WIFI ]; 30 | extraConfig = '' 31 | authoritative; 32 | subnet 192.168.3.0 netmask 255.255.255.0 { 33 | option routers 192.168.3.1; 34 | option broadcast-address 192.168.3.255; 35 | option domain-name-servers 192.168.2.1; 36 | range 192.168.3.100 192.168.3.200; 37 | } 38 | ''; 39 | }; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /nas.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | with lib; 4 | let 5 | passwords = import ./load-secrets.nix; 6 | keys = import ./keys.nix; 7 | overlay1 = self: super: { 8 | ntp = super.ntp.overrideAttrs (drv: { 9 | patches = drv.patches or [] ++ [ ./openat.patch ]; 10 | }); 11 | }; 12 | sources = import ./nix/sources.nix; 13 | iohk-ops = sources.iohk-ops; 14 | #nix-src = builtins.fetchTarball "https://github.com/nixos/nix/archive/374fe49ff78c13457c6cfe396f9ed0cb986c903b.tar.gz"; 15 | #nix-flake = builtins.getFlake "github.com:cleverca22/nix?rev=374fe49ff78c13457c6cfe396f9ed0cb986c903b"; 16 | #nix-flake = builtins.getFlake (builtins.unsafeDiscardStringContext nix-src); 17 | #nix = nix-flake.defaultPackage.x86_64-linux; 18 | flake = builtins.getFlake (toString ./.); 19 | in { 20 | imports = [ 21 | #./cardano-relay.nix 22 | #./datadog.nix 23 | #./nas-wifi.nix 24 | (iohk-ops + "/modules/monitoring-exporters.nix") 25 | ./cachecache.nix 26 | ./clevers_machines.nix 27 | ./exporter.nix 28 | ./home-assistant.nix 29 | ./iohk-binary-cache.nix 30 | ./media-center.nix 31 | ./nas-hydra.nix 32 | ./nas-monitoring-rewrite.nix 33 | ./nas-monitoring.nix 34 | ./nas-websites.nix 35 | ./nixops-managed.nix 36 | ./rtmp.nix 37 | ./snmpd.nix 38 | ./syncplay.nix 39 | ./tgt_service.nix 40 | ./zdb.nix 41 | ./zfs-patch.nix 42 | 43 | ]; 44 | boot = { 45 | initrd.availableKernelModules = [ 46 | "ahci" # SATA 47 | "ehci_pci" # USB 48 | "nvme" 49 | "ohci_pci" # USB 50 | "sd_mod" 51 | "usb_storage" 52 | "usbhid" 53 | "xhci_pci" # USB 54 | "mpt3sas" "raid_class" "scsi_transport_sas" # SAS 55 | #"rr3740a" 56 | ]; 57 | loader.grub = { 58 | device = "/dev/sdf"; 59 | configurationLimit = 1; 60 | }; 61 | kernelModules = [ "tcp_bbr" "kvm-amd" ]; 62 | kernel.sysctl = { 63 | "net.ipv4.tcp_congestion_control" = "bbr"; 64 | "fs.inotify.max_user_watches" = "100000"; 65 | }; 66 | extraModprobeConfig = '' 67 | options netconsole netconsole=6665@192.168.2.11/eth0,6666@192.168.2.61/00:1c:c4:6e:00:46 68 | ''; 69 | kernelParams = [ 70 | #"maxcpus=1" 71 | "zfs.zfs_active_allocator=cursor" 72 | ]; 73 | extraModulePackages = [ 74 | #config.boot.kernelPackages.rr3740a 75 | ]; 76 | }; 77 | environment = { 78 | systemPackages = with pkgs; [ 79 | ethtool 80 | file 81 | flake.inputs.zfs-utils.packages.x86_64-linux.gang-finder 82 | flake.inputs.zfs-utils.packages.x86_64-linux.txg-watcher 83 | gdb 84 | iotop 85 | jq 86 | lsof 87 | nvme-cli 88 | pciutils usbutils # lsusb and lspci 89 | pv 90 | rtorrent 91 | smartmontools 92 | socat 93 | sysstat 94 | tcpdump 95 | tgt 96 | vnstat 97 | ]; 98 | }; 99 | fileSystems = { 100 | "/" = { device = "naspool/root"; fsType = "zfs"; }; 101 | "/boot" = { device = "UUID=f5c56a8b-edcd-44ca-8814-490bf43ab576"; fsType = "ext4"; }; 102 | "/home" = { device = "naspool/home"; fsType = "zfs"; }; 103 | "/home/clever/downloading" = { device = "naspool/downloading"; fsType = "zfs"; }; 104 | "/media/videos/4tb" = { device = "c2d:/media/videos/4tb"; fsType = "nfs"; options = [ "soft" ]; }; 105 | "/nix" = { device = "naspool/nix"; fsType = "zfs"; }; 106 | "/var/lib/deluge" = { device = "naspool/deluge"; fsType = "zfs"; }; 107 | #"/zfs-defrag" = { device = "/dev/media/zfs-defrag"; fsType = "ext4"; }; 108 | }; 109 | hardware = { 110 | bluetooth.enable = false; 111 | }; 112 | swapDevices = [ 113 | { device = "/dev/media/swap"; } 114 | ]; 115 | networking = { 116 | timeServers = [ 117 | "router" 118 | "amd" 119 | "system76" 120 | "c2d" 121 | ]; 122 | defaultGateway = "10.0.0.1"; 123 | firewall = { 124 | allowedTCPPorts = [ 125 | 80 443 126 | 1337 127 | 1935 1936 # rtmp.nix 128 | 111 2049 # nfs 129 | 3260 130 | 10011 30033 30034 # ts3 131 | 58846 8112 # deluge 132 | 8081 133 | 8333 # bitcoin 134 | 6991 # rtorrent 135 | 20048 # nfs 136 | ]; 137 | allowedUDPPorts = [ 138 | 161 139 | 123 # ntp 140 | 111 2049 # nfs 141 | 9987 # ts3 142 | 9990 # ts3 2nd 143 | 33445 144 | ]; 145 | }; 146 | hostId = "491ddec8"; 147 | hostName = "nas"; 148 | nameservers = [ "10.0.0.1" ]; 149 | search = [ "localnet" ]; 150 | interfaces.eth0 = { 151 | useDHCP = true; 152 | mtu = 1500; 153 | #ipv4.addresses = [ 154 | # { 155 | # address = "10.0.0.11"; 156 | # prefixLength = 24; 157 | # } 158 | #]; 159 | }; 160 | usePredictableInterfaceNames = false; 161 | }; 162 | security.audit.enable = false; 163 | services = { 164 | arcstats = false; 165 | cachecache.enable = true; 166 | monitoring-exporters = { 167 | enable = true; 168 | metrics = true; 169 | logging = false; 170 | papertrail.enable = false; 171 | ownIp = "127.0.0.1"; 172 | }; 173 | tgtd = { 174 | enable = true; 175 | targets = { 176 | #"iqn.2019-01.amd-steam" = { backingStore = "/dev/naspool/amd-steam"; index = 1; }; 177 | "iqn.2020-12.amd-steam-xfs" = { backingStore = "/dev/zvol/naspool/amd-steam-xfs"; index = 2; }; 178 | #"iqn.2021-08.com.example:pi400.img" = { backingStore = "/dev/naspool/rpi/netboot-1"; index=3; }; 179 | #"iqn.2019-03.vm-example" = { 180 | # backingStore = "/dev/naspool/vm-example"; 181 | # index = 2; 182 | #}; 183 | #"iqn.2016-02.windows-extra" = { backingStore = "/dev/naspool/windows-extra"; index = 4; }; 184 | "iqn.2022-10.huge" = { backingStore = "/dev/zvol/naspool/huge"; index = 5; blockSize = 4096; }; 185 | }; 186 | }; 187 | locate.enable = false; 188 | nfs = { 189 | server = { 190 | enable = true; 191 | exports = '' 192 | /nas 10.0.0.106(rw,sync,subtree_check,root_squash) 193 | /nas amd(insecure,rw,sync,no_subtree_check,no_root_squash) 194 | /nas c2d(rw,async,no_subtree_check,no_root_squash) 192.168.2.126(rw,sync,subtree_check,no_root_squash) 192.168.144.3(rw,sync,subtree_check,no_root_squash) 192.168.2.100(rw,sync,no_root_squash,subtree_check) system76(rw,sync,subtree_check,root_squash) 192.168.2.162(rw,sync,subtree_check,root_squash) 195 | /nas pi5w(rw,async,subtree_check,no_root_squash) 196 | /nas router(rw,async,no_subtree_check,no_root_squash) 197 | /naspool/amd-nixos amd(rw,sync,subtree_check,no_root_squash) 198 | 199 | /nas 10.0.0.110(rw,async,no_subtree_check,no_root_squash) 200 | ''; 201 | }; 202 | }; 203 | nginx = { 204 | enable = true; 205 | statusPage = true; 206 | appendHttpConfig = '' 207 | charset UTF-8; 208 | ''; 209 | virtualHosts = { 210 | "nas.localnet" = { 211 | locations = { 212 | "/RPC2" = { 213 | extraConfig = '' 214 | scgi_pass 127.0.0.1:5000; 215 | #include scgi_vars; 216 | #scgi_var SCRIPT_NAME /RPC2; 217 | ''; 218 | }; 219 | "/private/" = { 220 | alias = "/nas/private/"; 221 | index = "index.htm"; 222 | extraConfig = '' 223 | autoindex on; 224 | autoindex_exact_size off; 225 | ''; 226 | }; 227 | }; 228 | }; 229 | }; 230 | }; 231 | ntp.enable = true; 232 | plex = { 233 | enable = true; 234 | openFirewall = true; 235 | }; 236 | postfix = { 237 | enable = true; 238 | settings.main.relayhost = [ "c2d.localnet:25" ]; 239 | }; 240 | toxvpn = { 241 | enable = true; 242 | localip = "192.168.123.51"; 243 | }; 244 | teamspeak3 = { 245 | enable = true; 246 | defaultVoicePort = 9990; 247 | fileTransferPort = 30034; 248 | queryPort = 10012; 249 | }; 250 | prometheus.exporters = { 251 | smartctl = { 252 | enable = true; 253 | port = 9633; 254 | devices = [ "/dev/sda" "/dev/sdb" "/dev/sdc" "/dev/sdd" "/dev/sde" "/dev/sdf" ]; 255 | }; 256 | }; 257 | udev = { 258 | extraRules = '' 259 | SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="28:c2:dd:14:8b:3d", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlp*", NAME="wlan0" 260 | SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="d0:50:99:7a:80:21", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="enp*", NAME="eth0" 261 | SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", SYMLINK+="ttyzigbee", OWNER="hass" 262 | ''; 263 | }; 264 | vnstat.enable = true; 265 | zfs = { 266 | autoSnapshot = { 267 | enable = true; 268 | }; 269 | }; 270 | }; 271 | nix = { 272 | #package = pkgs.nixUnstable; 273 | #package = nix; 274 | gc = { 275 | automatic = true; 276 | dates = "0:00:00"; 277 | options = ''--max-freed "$((32 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | ${pkgs.gawk}/bin/awk '{ print $4 }')))"''; 278 | }; 279 | buildMachines = let 280 | key = "/etc/nixos/keys/distro"; 281 | builders = import ./builders.nix; 282 | in [ 283 | #{ hostName = "clever@du075.macincloud.com"; systems = [ "x86_64-darwin" ]; sshKey = key; speedFactor = 1; maxJobs = 1; } 284 | #{ hostName = "root@192.168.2.140"; systems = [ "armv6l-linux" "armv7l-linux" ]; sshKey = key; maxJobs = 1; speedFactor = 2; supportedFeatures = [ "big-parallel" ]; } 285 | #{ hostName = "builder@192.168.2.15"; systems = [ "i686-linux" "x86_64-linux" ]; sshKey = key; maxJobs = 1; speedFactor = 1; supportedFeatures = [ "big-parallel" "kvm" "nixos-test" ]; } 286 | #{ hostName = "clever@aarch64.nixos.community"; systems = [ "armv7l-linux" "aarch64-linux" ]; sshKey = key; maxJobs = 1; speedFactor = 2; supportedFeatures = [ "big-parallel" ]; } 287 | #builders.rpi4 288 | #builders.pi400 289 | #{ hostName = "localhost"; mandatoryFeatures = [ "local" ]; systems = [ "x86_64-linux" "i686-linux" ]; maxJobs = 4; } 290 | { hostName = "clever@pi5w"; supportedFeatures = [ "big-parallel" ]; systems = [ "aarch64-linux" ]; maxJobs = 4; sshKey = key; } 291 | builders.system76 292 | #builders.amd 293 | #{ hostName = "root@10.0.0.171"; supportedFeatures = []; systems = [ "powerpc64-linux" ]; maxJobs = 1; sshKey = key; } 294 | { hostName = "root@10.42.1.5"; supportedFeatures = [ "big-parallel" ]; systems = [ "powerpc64-linux" ]; maxJobs = 1; sshKey = key; } 295 | #{ hostName = "root@10.42.1.6"; supportedFeatures = []; systems = [ "powerpc64-linux" ]; maxJobs = 1; sshKey = key; } 296 | ]; 297 | settings = { 298 | max-jobs = 2; 299 | cores = 2; 300 | substituters = lib.mkForce [ 301 | "http://nas.localnet:8081" 302 | #"ssh://nix-ssh@amd" 303 | ]; 304 | }; 305 | extraOptions = mkAfter '' 306 | gc-keep-derivations = true 307 | keep-outputs = false 308 | auto-optimise-store = false 309 | secret-key-files = /etc/nix/keys/secret-key-file 310 | ''; 311 | }; 312 | nixpkgs = { 313 | config = { 314 | allowUnfree = true; 315 | }; 316 | overlays = [ 317 | overlay1 318 | ]; 319 | }; 320 | programs.vim.fat = false; 321 | users = { 322 | extraUsers = { 323 | gits = { 324 | isNormalUser = true; 325 | openssh.authorizedKeys.keys = with keys; [ nix2 clever.amd router.root clever.laptop clever.laptopLuks ]; 326 | }; 327 | }; 328 | }; 329 | system.stateVersion = "16.03"; 330 | } 331 | -------------------------------------------------------------------------------- /netboot_server.nix: -------------------------------------------------------------------------------- 1 | { lib, config, pkgs, ... }: 2 | 3 | with lib; 4 | 5 | let 6 | nixos_release = import (pkgs.path + "/nixos/release.nix") {}; 7 | netboot = let 8 | build = (import (pkgs.path + "/nixos/lib/eval-config.nix") { 9 | system = "x86_64-linux"; 10 | modules = [ 11 | (pkgs.path + "/nixos/modules/installer/netboot/netboot-minimal.nix") 12 | ./nix-tests/kexec/justdoit.nix 13 | module 14 | ]; 15 | }).config.system.build; 16 | in pkgs.symlinkJoin { 17 | name = "netboot"; 18 | paths = with build; [ netbootRamdisk kernel netbootIpxeScript ]; 19 | }; 20 | module = { 21 | kexec.justdoit = { 22 | luksEncrypt = true; 23 | rootDevice = "/dev/vda"; 24 | swapSize = 40 * 1024; 25 | bootSize = 512; 26 | }; 27 | }; 28 | ipxe' = pkgs.ipxe.overrideDerivation (drv: { 29 | installPhase = '' 30 | ${drv.installPhase} 31 | make $makeFlags bin-x86_64-efi/ipxe.efi bin-i386-efi/ipxe.efi 32 | cp -v bin-x86_64-efi/ipxe.efi $out/x86_64-ipxe.efi 33 | cp -v bin-i386-efi/ipxe.efi $out/i386-ipxe.efi 34 | ''; 35 | }); 36 | tftp_root = pkgs.runCommand "tftproot" {} '' 37 | mkdir -pv $out 38 | cp -vi ${ipxe'}/undionly.kpxe $out/undionly.kpxe 39 | cp -vi ${ipxe'}/x86_64-ipxe.efi $out/x86_64-ipxe.efi 40 | cp -vi ${ipxe'}/i386-ipxe.efi $out/i386-ipxe.efi 41 | ''; 42 | nginx_root = pkgs.runCommand "nginxroot" {} '' 43 | mkdir -pv $out 44 | cat < $out/boot.php 45 | #!ipxe 46 | chain netboot/netboot.ipxe 47 | EOF 48 | ln -sv ${netboot} $out/netboot 49 | ''; 50 | cfg = config.netboot_server; 51 | in { 52 | options = { 53 | netboot_server = { 54 | network.wan = mkOption { 55 | type = types.str; 56 | description = "the internet facing IF"; 57 | default = "wlan0"; 58 | }; 59 | network.lan = mkOption { 60 | type = types.str; 61 | description = "the netboot client facing IF"; 62 | default = "enp9s0"; 63 | }; 64 | }; 65 | }; 66 | config = { 67 | services = { 68 | nginx = { 69 | enable = true; 70 | virtualHosts = { 71 | "192.168.3.1" = { 72 | root = nginx_root; 73 | }; 74 | }; 75 | }; 76 | dhcpd4 = { 77 | interfaces = [ cfg.network.lan ]; 78 | enable = true; 79 | extraConfig = '' 80 | option arch code 93 = unsigned integer 16; 81 | subnet 192.168.3.0 netmask 255.255.255.0 { 82 | option domain-search "localnetboot"; 83 | option subnet-mask 255.255.255.0; 84 | option broadcast-address 192.168.3.255; 85 | option routers 192.168.3.1; 86 | option domain-name-servers 192.168.3.1, 8.8.8.8, 8.8.4.4; 87 | range 192.168.3.100 192.168.3.200; 88 | next-server 192.168.3.1; 89 | if exists user-class and option user-class = "iPXE" { 90 | filename "http://192.168.3.1/boot.php?mac=''${net0/mac}&asset=''${asset:uristring}&version=''${builtin/version}"; 91 | } else { 92 | if option arch = 00:09 { 93 | filename = "x86_64-ipxe.efi"; 94 | } else { 95 | filename = "undionly.kpxe"; 96 | } 97 | } 98 | } 99 | ''; 100 | }; 101 | tftpd = { 102 | enable = true; 103 | path = tftp_root; 104 | }; 105 | bind = { 106 | enable = true; 107 | cacheNetworks = [ "192.168.3.0/24" "127.0.0.0/8" ]; 108 | }; 109 | }; 110 | networking = { 111 | interfaces = { 112 | ${cfg.network.lan} = { 113 | ip4 = [ { address = "192.168.3.1"; prefixLength = 24; } ]; 114 | }; 115 | }; 116 | nat = { 117 | enable = true; 118 | externalInterface = cfg.network.wan; 119 | internalIPs = [ "192.168.3.0/24" ]; 120 | internalInterfaces = [ cfg.network.lan ]; 121 | }; 122 | }; 123 | }; 124 | } 125 | -------------------------------------------------------------------------------- /nix/sources.json: -------------------------------------------------------------------------------- 1 | { 2 | "arcstats": { 3 | "branch": "master", 4 | "description": null, 5 | "homepage": null, 6 | "owner": "cleverca22", 7 | "repo": "arcstats", 8 | "rev": "4bd4ac89464826315bbaf711d5f479c7090b79c9", 9 | "sha256": "1679d56cnnynchk4kx9m8r3abcp3zprms5za3n10n1i17mw4a0g7", 10 | "type": "tarball", 11 | "url": "https://github.com/cleverca22/arcstats/archive/4bd4ac89464826315bbaf711d5f479c7090b79c9.tar.gz", 12 | "url_template": "https://github.com///archive/.tar.gz" 13 | }, 14 | "cachecache": { 15 | "branch": "master", 16 | "description": null, 17 | "homepage": null, 18 | "owner": "cleverca22", 19 | "repo": "cachecache", 20 | "rev": "6b5001c889874bc40a69d6a5f013322dec1b628a", 21 | "sha256": "0p5zqpjsi71i413xg92avsfasl7g2758yqzsj9nv3zbjpg0v54nr", 22 | "type": "tarball", 23 | "url": "https://github.com/cleverca22/cachecache/archive/6b5001c889874bc40a69d6a5f013322dec1b628a.tar.gz", 24 | "url_template": "https://github.com///archive/.tar.gz" 25 | }, 26 | "iohk-ops": { 27 | "branch": "master", 28 | "description": "NixOps deployment configuration for IOHK devops", 29 | "homepage": "", 30 | "owner": "input-output-hk", 31 | "repo": "iohk-ops", 32 | "rev": "65cb4d0b11d4504497aa334fb648716de2338ff5", 33 | "sha256": "056y1srh0jrv4b6inyrjw4yfdikxbwyg6cikz3fl5rqm3nx0wg1i", 34 | "type": "tarball", 35 | "url": "https://github.com/input-output-hk/iohk-ops/archive/65cb4d0b11d4504497aa334fb648716de2338ff5.tar.gz", 36 | "url_template": "https://github.com///archive/.tar.gz" 37 | }, 38 | "niv": { 39 | "branch": "master", 40 | "description": "Easy dependency management for Nix projects", 41 | "homepage": "https://github.com/nmattia/niv", 42 | "owner": "nmattia", 43 | "repo": "niv", 44 | "rev": "6da5c19aa220dfd840031e0cdbe83bf8f807fd50", 45 | "sha256": "173gkldf4in77ksm8bgf7bhkfyc4ayddka4cgxv5361kpgyvgccw", 46 | "type": "tarball", 47 | "url": "https://github.com/nmattia/niv/archive/6da5c19aa220dfd840031e0cdbe83bf8f807fd50.tar.gz", 48 | "url_template": "https://github.com///archive/.tar.gz" 49 | }, 50 | "nixpkgs": { 51 | "branch": "nixos-19.03", 52 | "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", 53 | "homepage": "https://github.com/NixOS/nixpkgs", 54 | "owner": "NixOS", 55 | "repo": "nixpkgs-channels", 56 | "rev": "6c08aa0d57e12209d199445a9fe569875f9d5887", 57 | "sha256": "0gxcm9q87jvimw26pji9blizxpb1mq86c9amz19kcix2pjj1xwsr", 58 | "type": "tarball", 59 | "url": "https://github.com/NixOS/nixpkgs-channels/archive/6c08aa0d57e12209d199445a9fe569875f9d5887.tar.gz", 60 | "url_template": "https://github.com///archive/.tar.gz" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /nix/sources.nix: -------------------------------------------------------------------------------- 1 | # This file has been generated by Niv. 2 | 3 | # A record, from name to path, of the third-party packages 4 | with rec 5 | { 6 | pkgs = 7 | if hasNixpkgsPath 8 | then 9 | if hasThisAsNixpkgsPath 10 | then import (builtins_fetchTarball { inherit (sources_nixpkgs) url sha256; }) {} 11 | else import {} 12 | else 13 | import (builtins_fetchTarball { inherit (sources_nixpkgs) url sha256; }) {}; 14 | 15 | sources_nixpkgs = 16 | if builtins.hasAttr "nixpkgs" sources 17 | then sources.nixpkgs 18 | else abort 19 | '' 20 | Please specify either (through -I or NIX_PATH=nixpkgs=...) or 21 | add a package called "nixpkgs" to your sources.json. 22 | ''; 23 | 24 | # fetchTarball version that is compatible between all the versions of Nix 25 | builtins_fetchTarball = 26 | { url, sha256 }@attrs: 27 | let 28 | inherit (builtins) lessThan nixVersion fetchTarball; 29 | in 30 | if lessThan nixVersion "1.12" then 31 | fetchTarball { inherit url; } 32 | else 33 | fetchTarball attrs; 34 | 35 | # fetchurl version that is compatible between all the versions of Nix 36 | builtins_fetchurl = 37 | { url, sha256 }@attrs: 38 | let 39 | inherit (builtins) lessThan nixVersion fetchurl; 40 | in 41 | if lessThan nixVersion "1.12" then 42 | fetchurl { inherit url; } 43 | else 44 | fetchurl attrs; 45 | 46 | # A wrapper around pkgs.fetchzip that has inspectable arguments, 47 | # annoyingly this means we have to specify them 48 | fetchzip = { url, sha256 }@attrs: pkgs.fetchzip attrs; 49 | 50 | # A wrapper around pkgs.fetchurl that has inspectable arguments, 51 | # annoyingly this means we have to specify them 52 | fetchurl = { url, sha256 }@attrs: pkgs.fetchurl attrs; 53 | 54 | hasNixpkgsPath = (builtins.tryEval ).success; 55 | hasThisAsNixpkgsPath = 56 | (builtins.tryEval ).success && == ./.; 57 | 58 | sources = builtins.fromJSON (builtins.readFile ./sources.json); 59 | 60 | mapAttrs = builtins.mapAttrs or 61 | (f: set: with builtins; 62 | listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))); 63 | 64 | # borrowed from nixpkgs 65 | functionArgs = f: f.__functionArgs or (builtins.functionArgs f); 66 | callFunctionWith = autoArgs: f: args: 67 | let auto = builtins.intersectAttrs (functionArgs f) autoArgs; 68 | in f (auto // args); 69 | 70 | getFetcher = spec: 71 | let fetcherName = 72 | if builtins.hasAttr "type" spec 73 | then builtins.getAttr "type" spec 74 | else "builtin-tarball"; 75 | in builtins.getAttr fetcherName { 76 | "tarball" = fetchzip; 77 | "builtin-tarball" = builtins_fetchTarball; 78 | "file" = fetchurl; 79 | "builtin-url" = builtins_fetchurl; 80 | }; 81 | }; 82 | # NOTE: spec must _not_ have an "outPath" attribute 83 | mapAttrs (_: spec: 84 | if builtins.hasAttr "outPath" spec 85 | then abort 86 | "The values in sources.json should not have an 'outPath' attribute" 87 | else 88 | if builtins.hasAttr "url" spec && builtins.hasAttr "sha256" spec 89 | then 90 | spec // 91 | { outPath = callFunctionWith spec (getFetcher spec) { }; } 92 | else spec 93 | ) sources 94 | -------------------------------------------------------------------------------- /nixops-managed.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | cfg = pkgs.writeText "configuration.nix" '' 5 | assert builtins.trace "Hey dummy, you're on your server! Use NixOps!" false; 6 | {} 7 | ''; 8 | in { 9 | #nixpkgs.overlays = [ (import ./overlays/qemu) ]; 10 | nix.nixPath = [ 11 | "nixos-config=${cfg}" 12 | "nixpkgs=/run/current-system/nixpkgs" 13 | "nixpkgs-overlays=/run/current-system/overlays" 14 | ]; 15 | system.extraSystemBuilderCmds = '' 16 | ln -sv ${pkgs.path} $out/nixpkgs 17 | #ln -sv {./overlays} $out/overlays 18 | ''; 19 | } 20 | -------------------------------------------------------------------------------- /ntp_fix.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | let 4 | overlay = self: super: { 5 | #ntp = super.ntp.overrideAttrs (drv: { 6 | # patches = [ (self.fetchpatch { url = "https://github.com/ntp-project/ntp/commit/881e427f3236046466bdb8235edf86e6dfa34391.patch"; sha256 = "0iqn12m7vzsblqbds5jb57m8cjs30rw8nh2xv8k2g8lbqbyk1k7s"; }) ]; 7 | #}); 8 | ntp = super.ntp.overrideAttrs (old: { 9 | configureFlags = old.configureFlags ++ [ "--disable-libseccomp" ]; 10 | patches = old.patches or [] ++ [ ./openat.patch ]; 11 | }); 12 | }; 13 | in { 14 | #disabledModules = [ "services/networking/ntpd.nix" ]; 15 | #imports = [ ./ntpd.nix ]; 16 | nixpkgs.overlays = [ overlay ]; 17 | } 18 | -------------------------------------------------------------------------------- /openat.patch: -------------------------------------------------------------------------------- 1 | diff -ur --color ntp-4.2.8p13-orig/ntpd/ntpd.c ntp-4.2.8p13/ntpd/ntpd.c 2 | --- ntp-4.2.8p13-orig/ntpd/ntpd.c 2019-02-20 13:21:44.000000000 -0400 3 | +++ ntp-4.2.8p13/ntpd/ntpd.c 2020-01-27 03:16:17.567457171 -0400 4 | @@ -1292,6 +1292,10 @@ 5 | SCMP_SYS(mmap), 6 | SCMP_SYS(munmap), 7 | SCMP_SYS(open), 8 | + SCMP_SYS(openat), 9 | + SCMP_SYS(clock_adjtime), 10 | + SCMP_SYS(pselect6), 11 | + SCMP_SYS(newfstatat), 12 | SCMP_SYS(poll), 13 | SCMP_SYS(read), 14 | SCMP_SYS(recvmsg), 15 | @@ -1327,6 +1328,10 @@ 16 | SCMP_SYS(mmap2), 17 | SCMP_SYS(munmap), 18 | SCMP_SYS(open), 19 | + SCMP_SYS(openat), 20 | + SCMP_SYS(clock_adjtime), 21 | + SCMP_SYS(pselect6), 22 | + SCMP_SYS(newfstatat), 23 | SCMP_SYS(poll), 24 | SCMP_SYS(read), 25 | SCMP_SYS(rename), 26 | -------------------------------------------------------------------------------- /overlays/qemu/default.nix: -------------------------------------------------------------------------------- 1 | self: super: 2 | 3 | { 4 | qemu-user-arm = if self.stdenv.system == "x86_64-linux" 5 | then self.pkgsi686Linux.callPackage ./qemu { user_arch = "arm"; } 6 | else self.callPackage ./qemu { user_arch = "arm"; }; 7 | qemu-user-x86 = self.callPackage ./qemu { user_arch = "x86_64"; }; 8 | qemu-user-arm64 = self.callPackage ./qemu { user_arch = "aarch64"; }; 9 | qemu-user-riscv32 = self.callPackage ./qemu { user_arch = "riscv32"; }; 10 | qemu-user-riscv64 = self.callPackage ./qemu { user_arch = "riscv64"; }; 11 | } 12 | -------------------------------------------------------------------------------- /overlays/qemu/qemu/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchurl, python, pkgconfig, zlib, glib, user_arch, flex, bison, 2 | makeStaticLibraries, glibc, qemu, fetchFromGitHub }: 3 | 4 | let 5 | env2 = makeStaticLibraries stdenv; 6 | myglib = (glib.override { stdenv = env2; }).overrideAttrs (drv: { 7 | mesonFlags = (drv.mesonFlags or []) ++ [ "-Ddefault_library=both" ]; 8 | }); 9 | riscv_src = fetchFromGitHub { 10 | owner = "riscv"; 11 | repo = "riscv-qemu"; 12 | rev = "7d2d2add16aff0304ab0c279152548dbd04a2138"; # riscv-all 13 | sha256 = "16an7ifi2ifzqnlz0218rmbxq9vid434j98g14141qvlcl7gzsy2"; 14 | }; 15 | is_riscv = (user_arch == "riscv32") || (user_arch == "riscv64"); 16 | arch_map = { 17 | arm = "i386"; 18 | aarch64 = "x86_64"; 19 | riscv64 = "x86_64"; 20 | x86_64 = "x86_64"; 21 | }; 22 | in 23 | stdenv.mkDerivation rec { 24 | name = "qemu-user-${user_arch}-${version}"; 25 | version = "3.1.0"; 26 | src = if is_riscv then riscv_src else qemu.src; 27 | buildInputs = [ python pkgconfig zlib.static myglib flex bison glibc.static ]; 28 | patches = [ ./qemu-stack.patch ]; 29 | configureFlags = [ 30 | "--enable-linux-user" "--target-list=${user_arch}-linux-user" 31 | "--disable-bsd-user" "--disable-system" "--disable-vnc" 32 | "--disable-curses" "--disable-sdl" "--disable-vde" 33 | "--disable-bluez" "--disable-kvm" 34 | "--static" 35 | "--disable-tools" 36 | "--cpu=${arch_map.${user_arch}}" 37 | ]; 38 | NIX_LDFLAGS = [ "-lglib-2.0" ]; 39 | enableParallelBuilding = true; 40 | postInstall = '' 41 | cc -static ${./qemu-wrap.c} -D QEMU_ARM_BIN="\"qemu-${user_arch}"\" -o $out/bin/qemu-wrap 42 | ''; 43 | } 44 | -------------------------------------------------------------------------------- /overlays/qemu/qemu/qemu-stack.patch: -------------------------------------------------------------------------------- 1 | --- a/linux-user/elfload.c 2016-09-02 12:34:22.000000000 -0300 2 | +++ b/linux-user/elfload.c 2017-07-09 18:44:22.420244038 -0300 3 | @@ -1419,7 +1419,7 @@ 4 | * dependent on stack size, but guarantee at least 32 pages for 5 | * backwards compatibility. 6 | */ 7 | -#define STACK_LOWER_LIMIT (32 * TARGET_PAGE_SIZE) 8 | +#define STACK_LOWER_LIMIT (128 * TARGET_PAGE_SIZE) 9 | 10 | static abi_ulong setup_arg_pages(struct linux_binprm *bprm, 11 | struct image_info *info) 12 | -------------------------------------------------------------------------------- /overlays/qemu/qemu/qemu-wrap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #if !defined(QEMU_ARM_BIN) 10 | #define QEMU_ARM_BIN "qemu-arm" 11 | #endif 12 | 13 | const char * qemu_arm_bin = QEMU_ARM_BIN; 14 | 15 | // This program takes arguments according to the behavior of binfmt_misc with 16 | // the preserve-argv[0] flag set. 17 | // 18 | // The first value in argv is the name of this executable, uninteresting. 19 | // The second value is the full path of the executable to run with the 20 | // alternate interpreter. 21 | // The third value is the name that executable was called with. 22 | // 23 | // This program passes the third value in to qemu-arm after the -0 flag. 24 | int main(int argc, char const* argv[]) { 25 | // Abort if we don't have sufficient arguments 26 | if(argc < 3){ 27 | fprintf( stderr, "qemu-arm wrapper called with too few arguments.\nEnsure that the 'P' flag is set in binfmt_misc.\n"); 28 | return -1; 29 | } 30 | 31 | char *qemu; 32 | asprintf(&qemu, "%s/%s", dirname(argv[0]), qemu_arm_bin); 33 | 34 | // Allocate the new argc array to pass to qemu-arm 35 | const int new_argc = argc + 1; 36 | char** const new_argv = alloca((new_argc + 1) * sizeof(void *)); 37 | 38 | // Fill this new array 39 | new_argv[0] = qemu; 40 | new_argv[1] = strdup("-0"); 41 | new_argv[2] = strdup(argv[2]); 42 | new_argv[3] = strdup(argv[1]); 43 | for(int i = 4; i < new_argc; ++i){ 44 | new_argv[i] = strdup(argv[i-1]); 45 | } 46 | new_argv[new_argc] = NULL; 47 | 48 | // Run qemu with the new arguments 49 | execvp(new_argv[0], new_argv); 50 | const int ret = errno; 51 | 52 | // Clean up, haha C 53 | for(int i = 0; i < new_argc; ++i){ 54 | free(new_argv[i]); 55 | } 56 | 57 | return ret; 58 | }; 59 | -------------------------------------------------------------------------------- /pre-boot-image.nix: -------------------------------------------------------------------------------- 1 | rec { 2 | configuration = { 3 | }; 4 | eval = import { inherit configuration; }; 5 | pkgs = import {}; 6 | build = pkgs.runCommand "PBA" {} '' 7 | mkdir $out 8 | cp ${eval.config.system.build.kernel}/bzImage $out/ 9 | cp ${eval.config.system.build.initialRamdisk}/initrd $out/initrd 10 | echo ${toString eval.config.boot.kernelParams} > $out/kernelParams 11 | ''; 12 | } 13 | -------------------------------------------------------------------------------- /qemu.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | with lib; 4 | let 5 | cfg = config.qemu-user; 6 | arm = { 7 | interpreter = "${pkgs.qemu-user-arm}/bin/qemu-arm"; 8 | magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00''; 9 | mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff''; 10 | }; 11 | aarch64 = { 12 | interpreter = "${pkgs.qemu-user-arm64}/bin/qemu-aarch64"; 13 | magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00''; 14 | mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff''; 15 | }; 16 | riscv64 = { 17 | interpreter = "${pkgs.qemu-riscv64}/bin/qemu-riscv64"; 18 | magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00''; 19 | mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff''; 20 | }; 21 | in { 22 | options = { 23 | qemu-user = { 24 | arm = mkEnableOption "enable 32bit arm emulation"; 25 | aarch64 = mkEnableOption "enable 64bit arm emulation"; 26 | riscv64 = mkEnableOption "enable 64bit riscv emulation"; 27 | }; 28 | nix.supportedPlatforms = mkOption { 29 | type = types.listOf types.str; 30 | description = "extra platforms that nix will run binaries for"; 31 | default = []; 32 | }; 33 | }; 34 | config = mkIf (cfg.arm || cfg.aarch64) { 35 | nixpkgs = { 36 | overlays = [ (import ./overlays-foo/qemu) ]; 37 | }; 38 | boot.binfmt.registrations = 39 | optionalAttrs cfg.arm { inherit arm; } // 40 | optionalAttrs cfg.aarch64 { inherit aarch64; } // 41 | optionalAttrs cfg.riscv64 { inherit riscv64; }; 42 | nix.supportedPlatforms = (optionals cfg.arm [ "armv6l-linux" "armv7l-linux" ]) 43 | ++ (optional cfg.aarch64 "aarch64-linux"); 44 | nix.extraOptions = '' 45 | extra-platforms = ${toString config.nix.supportedPlatforms} i686-linux 46 | ''; 47 | nix.sandboxPaths = [ "/run/binfmt" ] ++ (optional cfg.arm "${pkgs.qemu-user-arm}") ++ (optional cfg.aarch64 "${pkgs.qemu-user-arm64}"); 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /release.nix: -------------------------------------------------------------------------------- 1 | let 2 | nixosFunc = import ; 3 | linuxPkgs = import {}; 4 | sources = import ./nix/sources.nix; 5 | in { 6 | nas = (nixosFunc { configuration = ./nas.nix; }).system; 7 | router = (nixosFunc { configuration = ./router.nix; }).system; 8 | system76 = (nixosFunc { configuration = ./system76.nix; }).system; 9 | nix-tar.arm = linuxPkgs.callPackage ./arm-tar.nix {}; 10 | software = { # things used by several machines 11 | inherit (linuxPkgs) rtorrent; 12 | #arcstats = linuxPkgs.callPackage sources.arcstats {}; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /repl.nix: -------------------------------------------------------------------------------- 1 | builtins.getFlake (toString ./.) 2 | -------------------------------------------------------------------------------- /rescue_boot.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | let 3 | netboot = import (pkgs.path + "/nixos/lib/eval-config.nix") { 4 | modules = [ 5 | (pkgs.path + "/nixos/modules/installer/netboot/netboot-minimal.nix") 6 | module 7 | ]; 8 | }; 9 | module = { 10 | # you will want to add options here to support your filesystem 11 | # and also maybe ssh to let you in 12 | boot.supportedFilesystems = [ "zfs" ]; 13 | }; 14 | in { 15 | boot.loader.grub.extraEntries = '' 16 | menuentry "Nixos Installer" { 17 | linux ($drive1)/rescue-kernel init=${netboot.config.system.build.toplevel}/init ${toString netboot.config.boot.kernelParams} 18 | initrd ($drive1)/rescue-initrd 19 | } 20 | ''; 21 | boot.loader.grub.extraFiles = { 22 | "rescue-kernel" = "${netboot.config.system.build.kernel}/bzImage"; 23 | "rescue-initrd" = "${netboot.config.system.build.netbootRamdisk}/initrd"; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /router.nat.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | 3 | with lib; 4 | 5 | # bind and dhcpd need to test config files at build time 6 | let 7 | WAN = "enp4s2f0"; 8 | LAN_A = "enp4s2f1"; 9 | LAN_B = "enp3s3"; 10 | LAN = "br0"; 11 | loggers = [ 12 | { 13 | name = "kea-dhcp6"; 14 | output_options = [ { output = "stdout"; }]; 15 | severity = "DEBUG"; 16 | debuglevel = 99; 17 | } 18 | ]; 19 | youtube = { 20 | name = "youtube.com"; 21 | slaves = []; 22 | file = ./youtube; 23 | }; 24 | reddit = { 25 | name = "reddit.com"; 26 | slaves = []; 27 | file = ./youtube; 28 | }; 29 | localip = "47.55.133.35"; 30 | mkReservation = k: v: { 31 | hw-address = v.mac; 32 | ip-address = v.ip; 33 | hostname = k; 34 | }; 35 | in { 36 | networking = { 37 | defaultGateway = "192.168.2.1"; 38 | firewall = { 39 | enable = true; 40 | extraCommands = lib.mkMerge [ (lib.mkAfter '' 41 | iptables -w -t filter -A nixos-fw -s 10.0.0.0/24 -p udp --dport 53 -i ${LAN} -j nixos-fw-accept 42 | iptables -w -t filter -A nixos-fw -s 10.0.0.0/24 -p tcp --dport 53 -i ${LAN} -j nixos-fw-accept 43 | iptables -w -t filter -A nixos-fw -s 10.0.0.0/24 -p udp --dport 69 -i ${LAN} -j nixos-fw-accept 44 | #iptables -w -t filter -A nixos-fw -s 192.168.2.0/24 -p tcp --dport 3001 -i ${LAN} -j nixos-fw-accept # allow jormungandr api on lan 45 | #iptables -w -t filter -A nixos-fw -s 192.168.2.0/24 -p tcp --dport 8000 -i ${LAN} -j nixos-fw-accept # allow jormungandr exporter 46 | 47 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 27016 -j DNAT --to-destination 192.168.2.15 # stationeers game port 48 | 49 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 40189 -j DNAT --to-destination 192.168.2.15 50 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 9990 -j DNAT --to-destination 192.168.2.11 51 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 51820 -j DNAT --to-destination 192.168.2.15 # amd wireguard 52 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 51821 -j DNAT --to-destination 192.168.2.15 # amd wireguard 53 | iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 5100 -j DNAT --to-destination 10.0.0.15 # elite dangerous 54 | # factorio 55 | #iptables -w -t nat -A nixos-nat-pre -i tun0 -p udp -m udp --dport 34197 -j DNAT --to-destination 192.168.2.15 56 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 34197 -j DNAT --to-destination 192.168.2.15 57 | 58 | #iptables -w -t nat -A nixos-nat-pre -i ${WAN} -p udp -m udp --dport 162 -j DNAT --to-destination 192.168.2.2:161 59 | #iptables -w -t nat -A nixos-nat-post -p udp -m udp --dport 161 -d 192.168.2.2 -j SNAT --to-source 192.168.2.1 60 | 61 | #iptables -w -t nat -A nixos-nat-post -s 192.168.2.0/24 -o tun0 -j MASQUERADE 62 | 63 | # redirect traffic to the public ip back to localhost 64 | iptables -w -t nat -A nixos-nat-pre -i ${LAN} -s 10.0.0.0/24 -d ${localip} -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1 65 | iptables -w -t nat -A nixos-nat-pre -i ${LAN} -s 10.0.0.0/24 -d ${localip} -p tcp --dport 443 -j DNAT --to-destination 10.0.0.1 66 | #iptables -w -t nat -A nixos-nat-pre -i ${LAN} -s 10.0.0.0/24 -d ${localip} -p tcp --dport 32400 -j DNAT --to-destination 10.0.0.1:80 67 | '') ]; 68 | }; 69 | bridges = { 70 | br0 = { 71 | interfaces = [ 72 | LAN_A 73 | LAN_B 74 | ]; 75 | rstp = true; 76 | }; 77 | }; 78 | interfaces = { 79 | ${WAN} = { 80 | #useDHCP = true; 81 | ipv4 = { 82 | addresses = [ 83 | { address = "192.168.2.12"; prefixLength = 24; } 84 | ]; 85 | }; 86 | }; 87 | ${LAN} = { 88 | ipv4 = { 89 | #routes = [ 90 | # { 91 | # address = "192.168.3.0"; 92 | # prefixLength = 24; 93 | # via = "192.168.2.11"; 94 | # } 95 | #]; 96 | addresses = [ 97 | { address = "10.0.0.1"; prefixLength = 24; } 98 | ]; 99 | }; 100 | }; 101 | }; 102 | nat = { 103 | enable = true; 104 | externalInterface = WAN; 105 | internalIPs = [ 106 | "192.168.2.0/24" 107 | "192.168.20.0/24" 108 | "10.67.15.0/24" 109 | "10.2.0.2/32" 110 | ]; 111 | internalInterfaces = [ LAN ]; 112 | forwardPorts = [ 113 | { destination = "10.0.0.61"; sourcePort = 25; } # email 114 | # { destination = "192.168.2.62"; sourcePort = 80; } # http 115 | #{ destination = "192.168.2.61:22"; sourcePort = 2222; } # ssh to laptop 116 | #{ destination = "192.168.2.15"; sourcePort = 22; } 117 | #{ destination = "192.168.2.61"; sourcePort = 6990; } # rtorrent 118 | { destination = "10.0.0.11"; sourcePort = 6991; } # rtorrent 119 | #{ destination = "192.168.2.61"; sourcePort = 11194; } # openvpn 120 | #{ sourcePort = 25565; destination = "192.168.2.32"; } # minecraft 121 | #{ sourcePort = 45333; destination = "192.168.2.15"; } # mc test 122 | #{ sourcePort = 21025; destination = "192.168.2.11"; } # starbound 123 | #{ destination = "192.168.2.62:22"; sourcePort = 2222; } 124 | #{ destination = "192.168.2.11"; sourcePort = 58846; } # deluged 125 | #{ destination = "192.168.2.15"; sourcePort = 38009; } # temp minecraft 126 | #{ destination = "192.168.2.15"; sourcePort = 40189; } # skype 127 | #{ destination = "192.168.2.11:443"; sourcePort = 4433; } 128 | #{ destination = "192.168.2.11"; sourcePort = 443; } 129 | #{ destination = "192.168.2.15"; sourcePort = 1234; } 130 | # 2nd teamspeak server 131 | { destination = "10.0.0.11"; sourcePort = 10012; } 132 | { destination = "10.0.0.11"; sourcePort = 30034; } 133 | { destination = "10.0.0.11"; sourcePort = 1935; } 134 | { destination = "10.0.0.11"; sourcePort = 32400; } 135 | { destination = "10.0.0.11"; sourcePort = 1337; } # syncplay 136 | #{ destination = "192.168.2.11"; sourcePort = 3000; } # carano 137 | #{ destination = "192.168.2.15"; sourcePort = 27016; } # stationeers game UDP 138 | #{ destination = "192.168.2.15"; sourcePort = 27015; } # stationeers update 139 | #{ destination = "10.0.0.112"; sourcePort = 8080; } # ip webcam on phone 140 | { destination = "10.0.0.61"; sourcePort = 4400; } # bircd 141 | ]; 142 | }; 143 | }; 144 | services = { 145 | bind = { 146 | ipv4Only = true; 147 | enable = true; 148 | #forwarders = [ 149 | #"47.55.55.55" "142.166.166.166" 150 | #"8.8.8.8" 151 | #"192.168.2.1" 152 | #]; 153 | cacheNetworks = [ 154 | #"192.168.2.0/24" 155 | #"192.168.3.0/24" 156 | "127.0.0.0/8" 157 | "10.0.0.0/24" 158 | ]; 159 | extraConfig = '' 160 | ''; 161 | extraOptions = '' 162 | #dnssec-enable yes; 163 | dnssec-validation no; 164 | #dnssec-lookaside auto; 165 | ''; 166 | zones = [ 167 | { 168 | master = true; 169 | name = "localnet"; 170 | slaves = [ ]; 171 | file = ./localnet; 172 | } 173 | { 174 | master = true; 175 | name = "fw-download-alias1.raspberrypi.com"; 176 | slaves = [ ]; 177 | file = ./rpi.zone; 178 | } 179 | #youtube reddit 180 | { 181 | master = true; 182 | name = "0.0.10.in-addr.arpa"; 183 | slaves = [ ]; 184 | file = ./lan.reverse; 185 | } 186 | { 187 | master = true; 188 | name = "0.8.e.f.ip6.arpa"; 189 | slaves = [ ]; 190 | file = ./ipv6.reverse; 191 | } 192 | { 193 | master = true; 194 | name = "a.9.1.0.c.1.0.0.0.7.4.0.1.0.0.2.ip6.arpa"; 195 | slaves = [ ]; 196 | file = ./ipv6.reverse; 197 | } 198 | { 199 | master = true; 200 | name = "a.9.1.0.d.1.0.0.0.7.4.0.1.0.0.2.ip6.arpa"; 201 | slaves = [ ]; 202 | file = ./ipv6.reverse; 203 | } 204 | ]; 205 | }; 206 | kea.dhcp4 = { 207 | enable = true; 208 | settings = { 209 | interfaces-config.interfaces = [ 210 | LAN 211 | ]; 212 | lease-database = { 213 | name = "/var/lib/kea/dhcp4.leases"; 214 | persist = true; 215 | type = "memfile"; 216 | }; 217 | option-def = [ 218 | { 219 | name = "rpiboot"; 220 | code = 43; 221 | #space = "dhcp4"; 222 | #csv-format = false; 223 | type = "string"; 224 | #data = "Raspberry Pi Boot "; 225 | } 226 | ]; 227 | rebind-timer = 3600 * 10; 228 | renew-timer = 3600; 229 | #inherit loggers; 230 | valid-lifetime = 3600 * 24; 231 | client-classes = [ 232 | { 233 | name = "rpi_class"; 234 | boot-file-name = "bar.bin"; 235 | test = "substring(pkt4.mac, 0, 3) == 0xb827eb"; 236 | } 237 | ]; 238 | subnet4 = [ 239 | { 240 | id = 1; 241 | subnet = "10.0.0.0/24"; 242 | pools = [ 243 | { 244 | pool = "10.0.0.100 - 10.0.0.200"; 245 | } 246 | ]; 247 | next-server = "10.0.0.1"; 248 | option-data = [ 249 | { 250 | name = "routers"; 251 | data = "10.0.0.1"; 252 | } 253 | { 254 | name = "boot-file-name"; 255 | data = "test.bin"; 256 | } 257 | #{ 258 | # bitfield, 1 means use filename from option-data, 2 means use sname from option data 259 | # name = "dhcp-option-overload"; 260 | # data = "0"; 261 | #} 262 | { 263 | name = "domain-name-servers"; 264 | data = "10.0.0.1"; 265 | } 266 | { 267 | name = "domain-search"; 268 | data = "localnet"; 269 | } 270 | { 271 | name = "rpiboot"; 272 | data = "Raspberry Pi Boot1337"; 273 | } 274 | ]; 275 | reservations = lib.mapAttrsFlatten mkReservation (import ./lan.nix); 276 | } 277 | ]; 278 | }; 279 | }; 280 | #dhcpd4 = { 281 | #{ hostName = "ramboot"; ethernetAddress = "00:1c:23:16:4b:b3"; ipAddress = "192.168.2.10"; } 282 | #{ hostName = "nix1"; ethernetAddress = "92:C5:E2:BB:12:A9"; ipAddress = "192.168.2.30"; } 283 | #{ hostName = "nix2"; ethernetAddress = "5E:88:5B:D7:6E:BC"; ipAddress = "192.168.2.31"; } 284 | 285 | #{ hostName = "pi0"; ethernetAddress = "b8:27:eb:19:4b:a3"; ipAddress = "192.168.2.50"; } # wifi 286 | #{ hostName = "pi3"; ethernetAddress = "b8:27:eb:80:d9:b6"; ipAddress = "192.168.2.53"; } 287 | 288 | #{ hostName = "amd"; ethernetAddress = "40:16:7e:b3:32:48"; ipAddress = "10.0.0.15"; } 289 | 290 | #{ hostName = "neo"; ethernetAddress = "88:83:22:dd:50:a5"; ipAddress = "10.0.0.52"; } # cellphone 291 | #extraConfig = '' 292 | # subnet 10.0.0.0 netmask 255.255.255.0 { 293 | # if exists user-class and option user-class = "iPXE" { 294 | # filename "http://c2d.localnet/boot.php?mac=''${net0/mac}&asset=''${asset:uristring}&version=''${builtin/version}"; 295 | # #option root-path "iscsi:192.168.2.61:::1:iqn.2015-10.com.laptop-root"; 296 | # } else { 297 | # filename = "undionly.kpxe"; 298 | # } 299 | # option rpiboot "Raspberry Pi Boot "; 300 | # } 301 | #''; 302 | #}; 303 | #openvpn.servers = optionalAttrs (builtins.pathExists ./clever_router.ovpn) { 304 | #justasic = { 305 | #config = pkgs.lib.readFile ./clever_router.ovpn; 306 | #}; 307 | #}; 308 | tftpd = { 309 | enable = true; 310 | path = "/tftproot"; 311 | }; 312 | }; 313 | } 314 | -------------------------------------------------------------------------------- /router.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | let 4 | keys = import ./keys.nix; 5 | builders = import ./builders.nix; 6 | secrets = import ./load-secrets.nix; 7 | sources = import ./nix/sources.nix; 8 | iohk-ops = sources.iohk-ops; 9 | in { 10 | fileSystems = { 11 | # TODO move into deployment file 12 | "/" = { 13 | device = "/dev/disk/by-uuid/3c21b4a1-bc19-449b-815f-60c66ba23bdf"; 14 | fsType = "ext4"; 15 | }; 16 | "/media/videos/4tb" = { 17 | device = "c2d:/media/videos/4tb"; 18 | fsType = "nfs"; 19 | options = [ "soft" ]; 20 | }; 21 | "/nas" = { 22 | device = "nas:/nas"; 23 | fsType = "nfs"; 24 | options = [ "soft" ]; 25 | }; 26 | }; 27 | 28 | imports = [ 29 | 30 | ./router.nat.nix 31 | ./snmpd.nix 32 | ./earthtools.ca.nix 33 | ./core.nix 34 | ./iohk-binary-cache.nix 35 | #./datadog.nix 36 | ./weechat.nix 37 | #./ntp_fix.nix 38 | ./nixops-managed.nix 39 | (iohk-ops +"/modules/monitoring-exporters.nix") 40 | #./jormungandr.nix 41 | ./exporter.nix 42 | #./homeserver.nix 43 | ./ntp_fix.nix 44 | ./caller-id.nix 45 | ]; 46 | programs = { 47 | vim.fat = false; 48 | }; 49 | time.timeZone = "America/Moncton"; 50 | documentation.info.enable = false; 51 | boot = { 52 | initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ata_piix" "usbhid" "usb_storage" ]; 53 | loader.grub = { 54 | enable = true; 55 | version = 2; 56 | device = "/dev/sda"; 57 | memtest86.enable = true; 58 | }; 59 | }; 60 | networking = { 61 | timeServers = lib.mkOptionDefault [ 62 | "nas" 63 | "amd" 64 | "system76" 65 | "c2d" 66 | ]; 67 | hostName = "router"; 68 | hostId = "136e6c46"; 69 | firewall = { 70 | enable = true; 71 | allowPing = true; 72 | allowedTCPPorts = [ 5201 33445 config.services.teamspeak3.fileTransferPort config.services.teamspeak3.queryPort 80 443 8443 ]; 73 | allowedUDPPorts = [ 74 | 123 161 33445 config.services.teamspeak3.defaultVoicePort 53 162 75 | 51820 76 | ]; 77 | trustedInterfaces = [ "tox_master0" ]; 78 | }; 79 | search = [ "localnet" ]; 80 | }; 81 | #qemu-user.arm = true; 82 | services = { 83 | #arcstats = true; 84 | avahi.enable = true; 85 | extra-statsd = false; 86 | fail2ban.enable = true; 87 | getty.helpLine = "[9;0][14;0]"; 88 | hydra = { 89 | enable = false; 90 | extraEnv.NIX_REMOTE_SYSTEMS = lib.concatStringsSep ":" [ "/etc/nix/machines" "/etc/nix/machines.provisioned" ]; 91 | hydraURL = "https://hydra.earthtools.ca/"; 92 | notificationSender = "clever@ext.earthtools.ca"; 93 | minimumDiskFree = 5; 94 | minimumDiskFreeEvaluator = 1; 95 | }; 96 | monitoring-exporters = { 97 | enable = true; 98 | metrics = true; 99 | logging = false; 100 | papertrail.enable = false; 101 | ownIp = "192.168.2.1"; 102 | }; 103 | teamspeak3.enable = true; 104 | nix-serve = { 105 | secretKeyFile = "/etc/nix/nix-serve.sec"; 106 | enable = false; 107 | }; 108 | ntp.enable = true; 109 | openssh.passwordAuthentication = false; 110 | postgresql = { 111 | enable = false; 112 | package = pkgs.postgresql_15; 113 | }; 114 | radvd = { 115 | enable = false; 116 | config = '' 117 | interface enp4s2f1 { 118 | AdvSendAdvert on; 119 | AdvHomeAgentFlag off; 120 | MinRtrAdvInterval 30; 121 | MaxRtrAdvInterval 100; 122 | AdvDefaultPreference high; 123 | prefix ${secrets.publicIpv6Prefix} { 124 | AdvOnLink on; 125 | AdvAutonomous on; 126 | AdvRouterAddr on; 127 | }; 128 | }; 129 | ''; 130 | }; 131 | toxvpn = { 132 | enable = true; 133 | localip = "192.168.123.20"; 134 | }; 135 | vnstat.enable = true; 136 | }; 137 | environment.systemPackages = with pkgs; [ 138 | file 139 | iperf 140 | irssi 141 | lshw 142 | lsof 143 | nmap 144 | nox 145 | pciutils 146 | socat 147 | speedtest-cli 148 | tcpdump 149 | wireshark-cli 150 | ]; 151 | users.extraUsers.gits = { 152 | isNormalUser = true; 153 | uid = 1006; 154 | openssh.authorizedKeys.keys = with keys; [ 155 | clever.nix2 156 | clever.amd clever.laptop clever.router_root 157 | ]; 158 | }; 159 | swapDevices = [ 160 | { device = "/var/db/swap"; priority = 10; size = 1024; } 161 | ]; 162 | systemd.services = { 163 | network-local-commands.path = with pkgs; [ iproute2 vlan ]; 164 | }; 165 | nixpkgs.config.allowUnfree = true; 166 | nix = { 167 | buildMachines = with builders; [ amd darwin notos ]; 168 | extraOptions = '' 169 | #gc-keep-derivations = true 170 | #gc-keep-outputs = true 171 | auto-optimise-store = true 172 | ''; 173 | gc = { 174 | automatic = true; 175 | dates = "*:00:00"; 176 | options = ''--max-freed "$((10 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | ${pkgs.gawk}/bin/awk '{ print $4 }')))"''; 177 | }; 178 | settings = { 179 | max-jobs = 2; 180 | cores = 2; 181 | }; 182 | }; 183 | system.stateVersion = "20.03"; 184 | } 185 | -------------------------------------------------------------------------------- /rpi.zone: -------------------------------------------------------------------------------- 1 | $TTL 3D 2 | @ IN SOA ns.localnet. hostmaster ( 3 | 1 ; serial 4 | 8H ; refresh 5 | 2H ; retry 6 | 4W ; expire 7 | 1D) ; min ttl 8 | 9 | NS ns.localnet. 10 | 11 | ;@ IN A 185.101.97.131 12 | ;@ IN AAAA 2a06:1c80:3:44::1 13 | 14 | boot IN A 10.1.2.3 15 | -------------------------------------------------------------------------------- /rtmp.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | rtmpOverlay = self: super: { 5 | nginxMainline = super.nginxMainline.override (oldAttrs: { 6 | modules = oldAttrs.modules ++ [ super.nginxModules.rtmp ]; 7 | }); 8 | #nginxStable = super.nginxStable.override (oldAttrs: { 9 | # modules = oldAttrs.modules ++ [ super.nginxModules.rtmp ]; 10 | #}); 11 | }; 12 | in { 13 | config = { 14 | nixpkgs.overlays = [ rtmpOverlay ]; 15 | systemd.services.nginx.preStart = '' 16 | mkdir -p /tmp/{hls,dash} 17 | ''; 18 | services.nginx = { 19 | virtualHosts = let 20 | common = { 21 | locations = { 22 | # https://ext.earthtools.ca/hls/nixnothing.m3u8 23 | # this url now works in cytube 24 | "/hls" = { 25 | root = "/tmp"; 26 | extraConfig = '' 27 | add_header 'Access-Control-Allow-Origin' "https://cytu.be" always; 28 | add_header Cache-Control no-cache; 29 | add_header Access-Control-Allow-Origin *; 30 | ''; 31 | }; 32 | "/dash" = { 33 | root = "/tmp"; 34 | extraConfig = '' 35 | types { 36 | application/vnd.apple.mpegurl m3u8; 37 | application/dash+xml mpd; 38 | video/mp2t ts; 39 | } 40 | add_header Cache-Control no-cache; 41 | add_header Access-Control-Allow-Origin *; 42 | ''; 43 | }; 44 | }; 45 | }; 46 | in { 47 | "ext.earthtools.ca" = common; 48 | "nas.localnet" = common; 49 | }; 50 | appendConfig = '' 51 | rtmp { 52 | server { 53 | listen 1935; 54 | chunk_size 4096; 55 | on_connect http://c2d.localnet/rtmp_hook.php; 56 | application live { 57 | live on; 58 | record off; 59 | hls on; 60 | hls_path /tmp/hls; 61 | # hls_fragment 3; 62 | # hls_playlist_length 60; 63 | dash on; 64 | dash_path /tmp/dash; 65 | on_publish http://c2d.localnet/rtmp_hook.php; 66 | on_done http://c2d.localnet/rtmp_hook.php; 67 | } 68 | } 69 | } 70 | ''; 71 | appendHttpConfig = '' 72 | server { 73 | listen 1936; 74 | location /stat { 75 | rtmp_stat all; 76 | } 77 | location /hls { 78 | types { 79 | application/vnd.apple.mpegurl m3u8; 80 | video/mp2t ts; 81 | } 82 | } 83 | } 84 | ''; 85 | }; 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /setValue.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/settings/SettingsComponent.cpp b/src/settings/SettingsComponent.cpp 2 | index d5e64fe..302e1b6 100644 3 | --- a/src/settings/SettingsComponent.cpp 4 | +++ b/src/settings/SettingsComponent.cpp 5 | @@ -342,6 +342,9 @@ void SettingsComponent::setValue(const QString& sectionID, const QString &key, c 6 | QLOG_ERROR() << "Section" << sectionID << "is unknown"; 7 | return; 8 | } 9 | + QTextStream out(stdout); 10 | + out << QString("setValue(%1, %2)\n").arg(key).arg(value.toString()); 11 | + out.flush(); 12 | section->setValue(key, value); 13 | saveSection(section); 14 | } 15 | -------------------------------------------------------------------------------- /snmpd.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | secrets = import ./load-secrets.nix; 5 | in 6 | { 7 | systemd.services.snmpd = let 8 | snmpconfig = pkgs.writeTextFile { 9 | name = "snmpd.conf"; 10 | text = '' 11 | rocommunity ${secrets.snmp} 12 | disk / 10000 13 | extend cputemp ${pkgs.stdenv.shell} -c "${pkgs.acpi}/bin/acpi -t|egrep -o '[0-9\.]{3,}'" 14 | extend conntrack ${pkgs.stdenv.shell} -c "cat /proc/net/nf_conntrack | wc -l" 15 | ''; 16 | }; 17 | in { 18 | description = "net-snmp daemon"; 19 | wantedBy = [ "multi-user.target" ]; 20 | serviceConfig = { 21 | ExecStart = "${pkgs.net-snmp}/bin/snmpd -f -c ${snmpconfig}"; 22 | KillMode = "process"; 23 | Restart = "always"; 24 | }; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /stationeers.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | config = { 5 | networking.firewall.allowedUDPPorts = [ 27016 ]; 6 | networking.firewall.allowedTCPPorts = [ 8000 ]; 7 | systemd.services.stationeers = { 8 | #wantedBy = [ "multi-user.target" ]; 9 | path = [ pkgs.steamcmd pkgs.steam-run ]; 10 | serviceConfig = { 11 | User = "stationeers"; 12 | WorkingDirectory = "/var/lib/stationeers"; 13 | TimeoutStartSec = "5m"; 14 | }; 15 | preStart = '' 16 | steamcmd +force_install_dir /var/lib/stationeers +login anonymous +app_update 600760 -beta beta validate +quit 17 | ''; 18 | script = '' 19 | steam-run /var/lib/stationeers/rocketstation_DedicatedServer.x86_64 -loadlatest 2022-mars mars -settings StartLocalHost true ServerPassword password ServerMaxPlayers 5 UPNPEnabled false SaveInterval 60 SunOrbitPeriod 2 AutoPauseServer false 20 | ''; 21 | }; 22 | users.users.stationeers = { 23 | isSystemUser = true; 24 | createHome = true; 25 | home = "/var/lib/stationeers"; 26 | group = "stationeers"; 27 | }; 28 | users.groups.stationeers = {}; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /steam.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = [ pkgs.steam pkgs.steamcmd pkgs.steam-run ]; 5 | hardware.pulseaudio.support32Bit = true; 6 | hardware.opengl.driSupport32Bit = true; 7 | } 8 | -------------------------------------------------------------------------------- /syncplay.nix: -------------------------------------------------------------------------------- 1 | { 2 | # (import { config = {}; }).python3.withPackages (p: [p.pyside p.pysideTools p.twisted]) 3 | # https://github.com/Syncplay/syncplay 4 | systemd.services.syncplay-server = { 5 | wantedBy = [ "multi-user.target" ]; 6 | serviceConfig = { 7 | User = "clever"; 8 | WorkingDirectory = "/home/clever/apps/syncplay"; 9 | Restart = "always"; 10 | }; 11 | script = '' 12 | ./result/bin/python syncplayServer.py --port 1337 --password hunter2 --stats-db-file stats.sqlite --salt GNCXTBCQDN 13 | ''; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /system76.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, config, ... }: 2 | 3 | let 4 | nixMasterSrc = pkgs.fetchFromGitHub { 5 | owner = "nixos"; 6 | repo = "nix"; 7 | rev = "69c6fb12eea414382f0b945c0d6c574c43c7c9a3"; 8 | hash = "sha256:1nybwpkd8h4wg1i5f98p0wkz6242pbm5sihvgw7sjym59ja0srl1"; 9 | }; 10 | nixMaster = (import "${nixMasterSrc}").defaultPackage.x86_64-linux; 11 | in { 12 | imports = [ 13 | #./datadog.nix 14 | #./docker.nix 15 | #./taktoa-hercules.nix 16 | ./bluetooth.nix 17 | ./clevers_machines.nix 18 | ./direnv.nix 19 | ./exporter.nix 20 | ./gpg.nix 21 | ./iohk-binary-cache.nix 22 | ./ntp_fix.nix 23 | ./steam.nix 24 | ./wireshark-no-root.nix 25 | ./zdb.nix 26 | ./zfs-patch.nix 27 | 28 | #./test.nix 29 | ./stationeers.nix 30 | #./pi-v6.nix 31 | #./deluge.nix 32 | ]; 33 | boot = { 34 | loader.grub = { 35 | configurationLimit = 20; 36 | device = "nodev"; 37 | efiInstallAsRemovable = true; 38 | efiSupport = true; 39 | enable = true; 40 | }; 41 | initrd = { 42 | luks.devices.root = { 43 | allowDiscards = true; 44 | device = "/dev/nvme0n1p2"; 45 | name = "root"; 46 | preLVM = true; 47 | }; 48 | availableKernelModules = [ "xhci_pci" "ahci" "nvme" "rtsx_pci_sdmmc" ]; 49 | }; 50 | kernelModules = [ "kvm-intel" ]; 51 | zfs.devNodes = "/dev"; # fixes some virtualmachine issues 52 | supportedFilesystems = ["nfs"]; 53 | #kernelPackages = pkgs.linuxPackages_latest; 54 | kernelParams = [ 55 | #"systemd.log_level=debug" 56 | ]; 57 | }; 58 | networking = { 59 | hostId = "b790d302"; # required for zfs use 60 | wireless = { 61 | enable = true; 62 | interfaces = [ "wlp3s0" ]; 63 | }; 64 | hostName = "system76"; 65 | firewall = { 66 | enable = false; 67 | allowedTCPPorts = [ 68 | 8080 3000 25565 8082 8081 69 | 32433 # plex-media-player 70 | ]; 71 | allowedUDPPorts = [ 72 | 33445 27036 27031 # steam streaming uses 27015-27030 73 | 69 # tftpd 74 | ]; 75 | trustedInterfaces = [ "tox_master0" ]; 76 | }; 77 | }; 78 | fileSystems = let 79 | zfs = name: { device = "tank/${name}"; fsType = "zfs"; }; 80 | in { 81 | "/" = zfs "root"; 82 | "/home" = zfs "home"; 83 | "/nix" = zfs "nix"; 84 | "/boot" = { device = "/dev/disk/by-uuid/7DBC-2698"; fsType = "vfat"; }; 85 | "/var/lib/docker" = zfs "docker"; 86 | "/home/clever/disk-images" = zfs "disk-images"; 87 | #"/nas" = { device = "nas:/nas"; fsType = "nfs"; options = [ "x-systemd.automount" "noauto" "soft" ]; }; 88 | }; 89 | swapDevices = [ 90 | { device = "/dev/disk/by-uuid/68bce3d2-cfc5-4400-ad8c-ddb751441beb"; } 91 | ]; 92 | nix = { 93 | distributedBuilds = true; 94 | extraOptions = '' 95 | builders-use-substitutes = true 96 | secret-key-files = /etc/nix/secret-key-file 97 | experimental-features = nix-command flakes 98 | #repeat = 2 99 | auto-optimise-store = true 100 | ''; 101 | settings = { 102 | cores = 8; 103 | trusted-users = [ "clever" ]; 104 | extra-sandbox-paths = [ "/etc/nsswitch.conf" "/etc/protocols" "/usr/bin/env=${pkgs.coreutils}/bin/env" ]; 105 | max-jobs = lib.mkDefault 4; 106 | #substituters = lib.mkForce [ "http://nas.localnet:8081/" ]; #"file:///tmp/cache" "https://hydra.angeldsis.com" ]; 107 | trusted-public-keys = [ 108 | "amd-nixos-1:3gYz9vAPzXyqhLNdKbmF24ARp9Iy09ixR4pQAvHJGV8=" 109 | "hydra.mcwhirter.io:l38v9uAAXM2uasBTmarp3rWA9iSHzMYMQSrMCpiVJmQ=" 110 | "hydra.angeldsis.com-1:7s6tP5et6L8Y6sX7XGIwzX5bnLp00MtUQ/1C9t1IBGE=" 111 | ]; 112 | }; 113 | #package = nixMaster; 114 | buildMachines = [ 115 | { hostName = "clever@aarch64.nixos.community"; systems = [ "aarch64-linux" ]; sshKey = "/etc/nixos/keys/distro"; maxJobs = 10; speedFactor = 2; supportedFeatures = [ "big-parallel" ]; } 116 | { 117 | hostName = "mac-mini-1"; 118 | systems = [ "x86_64-darwin" ]; 119 | maxJobs = 1; 120 | } 121 | ]; 122 | }; 123 | nixpkgs.config = { 124 | allowUnfree = true; 125 | pulseaudio = true; 126 | }; 127 | programs = { 128 | vim.fat = true; 129 | screen.screenrc = '' 130 | termcapinfo xterm-256color 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007' 131 | ''; 132 | }; 133 | powerManagement.cpuFreqGovernor = "powersave"; 134 | environment.systemPackages = with pkgs; [ 135 | #androidenv.platformTools 136 | #obs-studio 137 | #slack 138 | #xlockmore 139 | (haskell.lib.justStaticExecutables haskellPackages.aeson-diff) 140 | (hwloc.override { x11Support = true; }) 141 | acpi 142 | chromium 143 | ddrescue 144 | discord 145 | dtc 146 | efibootmgr 147 | element-desktop 148 | eog 149 | evince 150 | evtest 151 | ffmpeg 152 | file 153 | gdb 154 | gist 155 | iftop 156 | iperf 157 | irssi 158 | jq 159 | lsof 160 | mosh 161 | mpv 162 | niv 163 | nix-diff 164 | nmap 165 | pavucontrol 166 | pciutils 167 | pigz 168 | plex-desktop 169 | pv 170 | pwgen 171 | rtorrent 172 | socat 173 | synergy 174 | sysstat 175 | tcpdump 176 | #teamspeak_client 177 | unzip 178 | usbutils 179 | vlc 180 | wget 181 | wireshark 182 | ]; 183 | users.users.clever = { 184 | extraGroups = [ "wheel" ]; 185 | isNormalUser = true; 186 | }; 187 | hardware = { 188 | cpu.intel.updateMicrocode = true; 189 | pulseaudio = { 190 | enable = false; 191 | }; 192 | }; 193 | #sound.enable = true; 194 | services = { 195 | arcstats = false; 196 | avahi.publish.addresses = true; 197 | blueman.enable = true; 198 | iscsid.enable = true; 199 | ntp.enable = true; 200 | openssh = { 201 | enable = true; 202 | passwordAuthentication = false; 203 | settings.X11Forwarding = true; 204 | }; 205 | pipewire = { 206 | enable = true; 207 | pulse.enable = true; 208 | }; 209 | tcsd.enable = false; 210 | #tftpd = { enable = true; path = "/home/clever/tftp"; }; 211 | toxvpn = { 212 | enable = true; 213 | localip = "192.168.123.12"; 214 | }; 215 | udev = { 216 | extraRules = '' 217 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="0a5c", ATTRS{idProduct}=="2711|2764", GROUP="wheel" 218 | SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A8V93XJN", SYMLINK+="ttyftdi", OWNER="clever" 219 | ''; 220 | }; 221 | xserver = { 222 | libinput = { 223 | enable = true; 224 | touchpad.accelSpeed = "20"; 225 | touchpad.disableWhileTyping = true; 226 | }; 227 | enable = true; 228 | desktopManager.xfce.enable = true; 229 | displayManager.sddm.enable = true; 230 | }; 231 | zfs.autoSnapshot.enable = true; 232 | }; 233 | security.pam = { 234 | loginLimits = [ 235 | { 236 | domain = "clever"; 237 | item = "nofile"; 238 | type = "hard"; 239 | value = "65535"; 240 | } 241 | ]; 242 | }; 243 | security.audit = { 244 | enable = false; 245 | rules = [ "-a task,always" ]; 246 | }; 247 | system.stateVersion = "23.05"; 248 | } 249 | -------------------------------------------------------------------------------- /tgt_service.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | with lib; 4 | 5 | let 6 | targetOpts = { name, config, ... }: { 7 | options = { 8 | name = mkOption { 9 | type = types.str; 10 | }; 11 | backingStore = mkOption { 12 | type = types.str; 13 | }; 14 | index = mkOption { 15 | type = types.int; 16 | description = "the index of the target, must be unique within the server"; 17 | }; 18 | blockSize = mkOption { 19 | type = types.int; 20 | default = 512; 21 | }; 22 | }; 23 | config = { 24 | name = mkDefault name; 25 | }; 26 | }; 27 | makeService = target: { 28 | name = target.name; 29 | value = { 30 | description = target.name+" auto-starter"; 31 | wantedBy = [ "basic.target" ]; 32 | partOf = [ "tgtd.service" ]; 33 | path = [ pkgs.tgt ]; 34 | script = let 35 | tid = toString target.index; 36 | in '' 37 | tgtadm --lld iscsi --op new --mode target --tid ${tid} -T ${target.name} 38 | tgtadm --lld iscsi --op new --mode logicalunit --tid ${tid} --lun 1 -b ${target.backingStore} --bstype=aio --blocksize ${toString target.blockSize} 39 | tgtadm --lld iscsi --op update --mode logicalunit --tid ${tid} --lun 1 --params thin_provisioning=0 40 | tgtadm --lld iscsi --op update --mode target --tid ${tid} -n nop_count -v 5 41 | tgtadm --lld iscsi --op update --mode target --tid ${tid} -n nop_interval -v 5 42 | tgtadm --lld iscsi --op bind --mode target --tid ${tid} -I ALL # gives everybody access 43 | ''; 44 | serviceConfig = { 45 | Type = "oneshot"; 46 | RemainAfterExit = true; 47 | ExecStop = "${pkgs.tgt}/bin/tgtadm --lld iscsi --op delete --mode target --tid ${builtins.toString target.index}"; 48 | }; 49 | }; 50 | }; 51 | in 52 | { 53 | options = { 54 | services.tgtd = { 55 | enable = mkOption { 56 | type = types.bool; 57 | default = false; 58 | description = "enable tgtd running on startup"; 59 | }; 60 | targets = mkOption { 61 | default = []; 62 | type = types.loaOf (types.submodule targetOpts); 63 | }; 64 | }; 65 | }; 66 | config = let 67 | LUNs = builtins.listToAttrs (map makeService (attrValues config.services.tgtd.targets)); 68 | tgtd = { 69 | description = "tgtd daemon"; 70 | wantedBy = [ "basic.target" ]; 71 | path = [ pkgs.tgt ]; 72 | script = '' 73 | exec tgtd -f --iscsi nop_interval=30 --iscsi nop_count=10 74 | ''; 75 | serviceConfig = { 76 | ExecStop = "${pkgs.coreutils}/bin/sleep 30 ; ${pkgs.tgt}/bin/tgtadm --op delete --mode system"; 77 | KillMode = "process"; 78 | Restart = "on-success"; 79 | }; 80 | }; 81 | in 82 | mkIf config.services.tgtd.enable { 83 | systemd.services = LUNs // { inherit tgtd; }; 84 | }; 85 | } 86 | -------------------------------------------------------------------------------- /util.nix: -------------------------------------------------------------------------------- 1 | { writeScriptBin, runCommand, xterm }: 2 | 3 | let 4 | nixposition = writeScriptBin "nix-position" '' 5 | nix-position () { 6 | usage () { 7 | echo "Usage: nix-position " 8 | echo "Shows the Nix source file for a given attribute path." 9 | } 10 | if [ $# -ne 1 ]; then usage; return -1; fi 11 | local EXPR="(import {}).pkgs.${1}.meta.position" 12 | nix-instantiate --eval -E "''${EXPR}" | sed 's:"$::g' | sed 's:^"::g' 13 | return 0 14 | } 15 | ''; 16 | in runCommand "util-1" {} '' 17 | mkdir -pv $out/bin 18 | 19 | cat << EOF > $out/bin/loginto 20 | #!$SHELL 21 | exec ${xterm}/bin/xterm -e ssh \$1 -t screen -xRRU 22 | EOF 23 | chmod +x $out/bin/loginto 24 | 25 | cat << EOF > $out/bin/showsize 26 | #!$SHELL 27 | nix-store --query --tree "\$1" | sed 's,[-+| ]*/,/,' | awk '{print \$1}' | sort | uniq | xargs nix-store --query --size | paste -sd+ | ( echo -n '( ';sed 's,+, + ,g';echo ' ) / 1024 / 1024' ) | xargs expr 28 | EOF 29 | chmod +x $out/bin/showsize 30 | 31 | cat << EOF > $out/bin/nix-lookup 32 | #!$SHELL 33 | local USAGE 34 | USAGE="$USAGE Usage: nix-lookup " 35 | USAGE="$USAGE Shows the directory for the given attribute path." 36 | if [ $# -ne 1 ]; then echo "$USAGE"; return -1; fi 37 | nix-instantiate --eval -E "\"\''${(import {}).pkgs.$1}\"" | sed 's:"::g' 38 | EOF 39 | chmod +x $out/bin/nix-lookup 40 | 41 | cat << EOF > $out/bin/nix-unpack 42 | nix-shell --run 'phases=unpackPhase genericBuild' "$@" 43 | EOF 44 | chmod +x $out/bin/nix-unpack 45 | '' 46 | -------------------------------------------------------------------------------- /vim.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ...}: 2 | 3 | with lib; 4 | 5 | let 6 | notPython = pkgs.writeScript "notPython" '' 7 | #!${pkgs.stdenv.shell} 8 | shift 9 | shift 10 | shift 11 | wakatime "$@" 12 | ''; 13 | myVim = (pkgs.vim_configurable.override { 14 | #python = pkgs.python3; 15 | }).customize { 16 | name = "vim"; 17 | vimrcConfig = { 18 | customRC = '' 19 | syntax on 20 | set nu 21 | set foldmethod=syntax 22 | set listchars=tab:->,trail:· 23 | set list 24 | set ruler 25 | set backspace=indent,eol,start 26 | set pastetoggle= 27 | nmap :!nix-build -A default 28 | map :tabp 29 | map :tabn 30 | set expandtab 31 | set softtabstop=2 32 | set shiftwidth=2 33 | set autoindent 34 | set hlsearch 35 | "set statusline+=col:\ %c, 36 | set ruler 37 | set background=dark 38 | 39 | " remove trailing whitespace upon save 40 | " au BufWritePre * %s/\s\+$//e 41 | 42 | " highlight all trailing whitespace 43 | highlight ExtraWhitespace ctermbg=red guibg=red 44 | au ColorScheme * highlight ExtraWhitespace guibg=red 45 | au BufEnter * match ExtraWhitespace /\s\+$/ 46 | au InsertEnter * match ExtraWhitespace /\s\+\%#\@