From 32f4cb5cbba313b7af2fce46139c04d9469cb72a Mon Sep 17 00:00:00 2001 From: Kleidi Bujari Date: Fri, 24 Jan 2025 12:14:23 -0500 Subject: 25-jan sprint --- flake.lock | 21 + flake.nix | 6 + machines/iridium/default.nix | 19 +- machines/radon/default.nix | 50 + machines/radon/jellyfin.nix | 34 + machines/radon/pxeboot.nix | 48 + machines/t1/default.nix | 16 +- machines/xnet/default.nix | 3 +- machines/xnet/gitserver/gitweb.nix | 7 +- machines/xnet/monitoring/22604_rev2.json | 1565 ++++++++++++++++++++++++++++++ machines/xnet/monitoring/default.nix | 76 +- machines/xnet/monitoring/grafana.nix | 105 +- machines/xnet/monitoring/prometheus.nix | 15 - machines/xnet/net/default.nix | 125 ++- machines/xnet/net/sshd.nix | 4 +- machines/xnet/persist.nix | 61 ++ machines/xnet/users.nix | 18 +- mod/code/cses/.envrc | 1 + mod/code/cses/default.nix | 13 + mod/code/cses/problems/1068.cpp | 17 + mod/code/cses/problems/1069.cpp | 23 + mod/code/cses/problems/1070.cpp | 15 + mod/code/cses/problems/1083.cpp | 20 + mod/code/cses/problems/1094.cpp | 27 + mod/tools/perf-flamegraph.nix | 12 + mod/tools/typst/default.nix | 2 +- 26 files changed, 2182 insertions(+), 121 deletions(-) create mode 100644 machines/radon/default.nix create mode 100644 machines/radon/jellyfin.nix create mode 100644 machines/radon/pxeboot.nix create mode 100644 machines/xnet/monitoring/22604_rev2.json delete mode 100644 machines/xnet/monitoring/prometheus.nix create mode 100644 machines/xnet/persist.nix create mode 100644 mod/code/cses/.envrc create mode 100644 mod/code/cses/default.nix create mode 100644 mod/code/cses/problems/1068.cpp create mode 100644 mod/code/cses/problems/1069.cpp create mode 100644 mod/code/cses/problems/1070.cpp create mode 100644 mod/code/cses/problems/1083.cpp create mode 100644 mod/code/cses/problems/1094.cpp create mode 100644 mod/tools/perf-flamegraph.nix diff --git a/flake.lock b/flake.lock index 01ad159..93e38cf 100644 --- a/flake.lock +++ b/flake.lock @@ -21,6 +21,26 @@ "type": "github" } }, + "naersk": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1736429655, + "narHash": "sha256-BwMekRuVlSB9C0QgwKMICiJ5EVbLGjfe4qyueyNQyGI=", + "owner": "nix-community", + "repo": "naersk", + "rev": "0621e47bd95542b8e1ce2ee2d65d6a1f887a13ce", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "naersk", + "type": "github" + } + }, "nixos-hardware": { "locked": { "lastModified": 1735388221, @@ -56,6 +76,7 @@ "root": { "inputs": { "disko": "disko", + "naersk": "naersk", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs", "sops-nix": "sops-nix" diff --git a/flake.nix b/flake.nix index ecb7b72..1afc072 100644 --- a/flake.nix +++ b/flake.nix @@ -11,6 +11,10 @@ sops-nix.inputs.nixpkgs.follows = "nixpkgs"; nixos-hardware.url = "github:nixos/nixos-hardware/master"; + + # Rust projects + naersk.url = "github:nix-community/naersk"; + naersk.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, ... } @ inputs: @@ -41,6 +45,8 @@ depot = readTree.fix (self: readDepot { depot = self; + inherit inputs; + # x86_64-linux is hardcoded as the package arch only for the # mod directory. This workaround keeps the flake pure, # at the expense of only supporting one system. This can diff --git a/machines/iridium/default.nix b/machines/iridium/default.nix index caf55fa..4f755dd 100644 --- a/machines/iridium/default.nix +++ b/machines/iridium/default.nix @@ -1,20 +1,35 @@ -{ lib, ... }: +{ lib, inputs, depot, ... }: let gitKeys = builtins.fetchurl { url = "https://github.com/kbujari.keys"; sha256 = "0fpa679zkrpx77vangzf3gnidwvmky8ifivn8411xx6albrikaqx"; }; + + inherit (inputs.nixos-hardware.nixosModules) + common-cpu-intel + common-gpu-intel + ; in { system.stateVersion = "24.11"; + networking.hostName = "iridium"; + + users.users.root.initialPassword = "hello"; + + imports = [ common-cpu-intel common-gpu-intel ]; xnet = { disk = { enable = true; device = "/dev/nvme0n1"; }; - net.sshd.enable = true; + net = { + sshd.enable = true; + interface = "enp1s0"; + join = [ "plaza" "kubenet" ]; + }; nginx.enable = true; + monitoring.hostGrafana = true; gitServer = { enable = true; gitweb.enable = true; diff --git a/machines/radon/default.nix b/machines/radon/default.nix new file mode 100644 index 0000000..839ee6d --- /dev/null +++ b/machines/radon/default.nix @@ -0,0 +1,50 @@ +{ lib, inputs, ... }: +let + gitKeys = builtins.fetchurl { + url = "https://github.com/kbujari.keys"; + sha256 = "0fpa679zkrpx77vangzf3gnidwvmky8ifivn8411xx6albrikaqx"; + }; + + inherit (inputs.nixos-hardware.nixosModules) + common-cpu-intel + common-gpu-intel + ; +in +{ + imports = [ + common-cpu-intel + common-gpu-intel + ./jellyfin.nix + ./pxeboot.nix + ]; + + system.stateVersion = "24.11"; + networking.hostName = "radon"; + + users.users.root.initialPassword = "hello"; + + users.groups.media.gid = 2000; + + boot.zfs.pools.radon.devNodes = "/dev/disk/by-id/"; + boot.zfs.extraPools = [ "radon" ]; + + services.nfs.server.enable = true; + + xnet = { + disk = { + enable = true; + device = "/dev/nvme0n1"; + }; + net = { + join = [ "plaza" ]; + interface = "enp1s0"; + sshd.enable = true; + }; + nginx.enable = true; + gitServer = { + enable = true; + gitweb.enable = true; + keys = lib.splitString "\n" (builtins.readFile gitKeys); + }; + }; +} diff --git a/machines/radon/jellyfin.nix b/machines/radon/jellyfin.nix new file mode 100644 index 0000000..7d3a96a --- /dev/null +++ b/machines/radon/jellyfin.nix @@ -0,0 +1,34 @@ +{ config, ... }: +let + inherit (config.services) jellyfin; +in +{ + services.jellyfin.enable = true; + + users.groups.media.members = [ jellyfin.user ]; + + xnet.persist = [ + { + path = jellyfin.cacheDir; + user = jellyfin.user; + group = jellyfin.group; + mode = "0750"; + } + { + path = jellyfin.dataDir; + user = jellyfin.user; + group = jellyfin.group; + mode = "0750"; + } + { + path = jellyfin.configDir; + user = jellyfin.user; + group = jellyfin.group; + mode = "0750"; + } + ]; + + services.nginx.virtualHosts."mov.4kb.net" = { + locations."/".proxyPass = "http://localhost:8096"; + }; +} diff --git a/machines/radon/pxeboot.nix b/machines/radon/pxeboot.nix new file mode 100644 index 0000000..4d897c3 --- /dev/null +++ b/machines/radon/pxeboot.nix @@ -0,0 +1,48 @@ +{ pkgs, lib, ... }: +let + installer = lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ({ config, pkgs, lib, modulesPath, ... }: { + imports = [ + (modulesPath + "/installer/netboot/netboot-minimal.nix") + (modulesPath + "/installer/cd-dvd/channel.nix") + ]; + + services.openssh = { + enable = true; + openFirewall = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; + }; + + nix.settings = { + experimental-features = [ "nix-command" "flakes" ]; + }; + + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP7T2uWJFUu8aFZZgQusGKyEMocb2pKbHLDad2eIJus9" + ]; + }) + ]; + }; + + inherit (installer.config.system) build; +in +{ + services.pixiecore = { + enable = true; + openFirewall = true; + kernel = "${build.kernel}/bzImage"; + initrd = "${build.netbootRamdisk}/initrd"; + cmdLine = "init=${build.toplevel}/init loglevel=4"; + mode = "boot"; + port = 8001; + statusPort = 8001; + + # Piggyback on existing network DHCP + dhcpNoBind = true; + }; +} diff --git a/machines/t1/default.nix b/machines/t1/default.nix index 31a652e..d95926b 100644 --- a/machines/t1/default.nix +++ b/machines/t1/default.nix @@ -1,9 +1,23 @@ -{ ... }: { +{ inputs, ... }: + +let + inherit (inputs.nixos-hardware.nixosModules) + common-cpu-amd + common-gpu-amd + ; +in +{ + imports = [ + common-cpu-amd + common-gpu-amd + ]; + system.stateVersion = "24.11"; xnet = { desktop.enable = true; users.enable = [ "kle" ]; + net.join = [ "plaza" ]; disk = { enable = true; device = "/dev/nvme0n1"; diff --git a/machines/xnet/default.nix b/machines/xnet/default.nix index 006dd1c..578db03 100644 --- a/machines/xnet/default.nix +++ b/machines/xnet/default.nix @@ -7,10 +7,11 @@ in ./disk.nix ./users.nix ./nginx.nix + ./persist.nix ./net ./desktop ./gitserver - # ./monitoring + ./monitoring ]; i18n.defaultLocale = mkDefault "en_US.UTF-8"; diff --git a/machines/xnet/gitserver/gitweb.nix b/machines/xnet/gitserver/gitweb.nix index bfd593d..da9a5ee 100644 --- a/machines/xnet/gitserver/gitweb.nix +++ b/machines/xnet/gitserver/gitweb.nix @@ -47,6 +47,7 @@ in ''; settings = { about-filter = "${pkgs.cgit-pink}/lib/cgit/filters/about-formatting.sh"; + source-filter = "${pkgs.cgit-pink}/lib/cgit/filters/syntax-highlighting.py"; clone-url = "https://${cfg.hostName}/$CGIT_REPO_URL git@${cfg.hostName}:$CGIT_REPO_URL"; enable-commit-graph = true; enable-http-clone = false; @@ -61,12 +62,6 @@ in }; }; - # required for rendering markdown readme - environment.systemPackages = with pkgs; [ - python312 - python312Packages.markdown - ]; - # services.nginx.virtualHosts."${cfg.gitweb.hostName}" = { # useACMEHost = "4kb.net"; # addSSL = true; diff --git a/machines/xnet/monitoring/22604_rev2.json b/machines/xnet/monitoring/22604_rev2.json new file mode 100644 index 0000000..0adeb22 --- /dev/null +++ b/machines/xnet/monitoring/22604_rev2.json @@ -0,0 +1,1565 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "11.4.0" + }, + { + "type": "panel", + "id": "piechart", + "name": "Pie chart", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Extended smartctl-exporter Dashboard", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "links": [], + "mappings": [], + "min": 20, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "celsius" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 13, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": ["mean", "lastNotNull", "max"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "avg(smartctl_device_temperature{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"}) by (instance,device,model_name)", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "1m", + "intervalFactor": 1, + "legendFormat": "{{instance}} {{device}} {{model_name}}", + "refId": "B" + } + ], + "title": "Disk Temperature", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 2, + "x": 13, + "y": 0 + }, + "id": 13, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(smartctl_device{instance=~\"$node\", device=~\"$disk\", interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"})", + "instant": false, + "range": true, + "refId": "A" + } + ], + "title": "Devices", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "fieldMinMax": false, + "mappings": [], + "min": 0, + "noValue": "0", + "unit": "none" + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": ["Value"], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 2, + "x": 15, + "y": 0 + }, + "id": 16, + "options": { + "displayLabels": ["percent"], + "legend": { + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "values": ["value"] + }, + "pieType": "pie", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "/^Value$/", + "values": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(smartctl_device) by (interface)", + "format": "table", + "instant": true, + "intervalFactor": 1, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "piechart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 7, + "x": 17, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": ["lastNotNull"], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "smartctl_device_media_errors{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"} > 0", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}} {{device}} {{model_name}}", + "range": true, + "refId": "A" + } + ], + "title": "Media Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "fieldMinMax": false, + "mappings": [], + "min": 0, + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 2, + "x": 13, + "y": 4 + }, + "id": 12, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "count((smartctl_device_smart_status{instance=~\"$node\",device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device) == 0)", + "format": "table", + "instant": true, + "intervalFactor": 1, + "legendFormat": "__auto", + "refId": "A" + } + ], + "title": "Unhealthy", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "bars", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "stepAfter", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "links": [], + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + }, + "unit": "short" + }, + "overrides": [ + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsZero", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + } + ] + }, + "gridPos": { + "h": 4, + "w": 7, + "x": 17, + "y": 4 + }, + "id": 5, + "options": { + "legend": { + "calcs": ["lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "smartctl_device_critical_warning{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"} > 0", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Critical Warnings {{device}}", + "range": true, + "refId": "A" + } + ], + "title": "Critical Warnings", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 0 + }, + { + "color": "green", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 15, + "y": 6 + }, + "id": 15, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "count(count(smartctl_device) by (instance))", + "instant": true, + "legendFormat": "nodes", + "range": false, + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": false, + "inspect": false, + "minWidth": 150 + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "unit", + "value": "dateTimeFromNow" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "custom.align" + }, + { + "id": "displayName", + "value": "Last Checked" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value #A" + }, + "properties": [ + { + "id": "displayName", + "value": "Power On Time" + }, + { + "id": "unit", + "value": "s" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "custom.align" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "model_name" + }, + "properties": [ + { + "id": "displayName", + "value": "Device Model" + }, + { + "id": "custom.align" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "device" + }, + "properties": [ + { + "id": "displayName", + "value": "Device" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Value #B" + }, + "properties": [ + { + "id": "displayName", + "value": "Power Cycles" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "instance" + }, + "properties": [ + { + "id": "displayName", + "value": "Node" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Node" + }, + "properties": [ + { + "id": "custom.width", + "value": 80 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Device" + }, + "properties": [ + { + "id": "custom.width", + "value": 107 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Last Checked" + }, + "properties": [ + { + "id": "custom.width", + "value": 142 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Device Model" + }, + "properties": [ + { + "id": "custom.width", + "value": 291 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Power On Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 162 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Power Cycles" + }, + "properties": [ + { + "id": "custom.width", + "value": 117 + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 13, + "x": 0, + "y": 8 + }, + "id": 10, + "interval": "1h", + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Power On Time" + } + ] + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "max(smartctl_device_power_on_seconds{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"}) by (instance, device, model_name)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "__auto", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "max(smartctl_device_power_cycle_count{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"}) by (instance, device, model_name)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Power Cycles", + "refId": "B" + } + ], + "title": "Disk Lifetime", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Total Written" + }, + "properties": [ + { + "id": "displayName", + "value": "Total Written" + }, + { + "id": "unit", + "value": "bytes" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "custom.align" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "unit", + "value": "dateTimeFromNow" + }, + { + "id": "custom.align" + }, + { + "id": "displayName", + "value": "Last Checked" + }, + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "model_name" + }, + "properties": [ + { + "id": "displayName", + "value": "Device Model" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "device" + }, + "properties": [ + { + "id": "displayName", + "value": "Device" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "instance" + }, + "properties": [ + { + "id": "displayName", + "value": "Node" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "serial_number" + }, + "properties": [ + { + "id": "displayName", + "value": "Serial Number" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Device" + }, + "properties": [ + { + "id": "custom.width", + "value": 115 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "instance" + }, + "properties": [ + { + "id": "custom.width", + "value": 77 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Serial Number" + }, + "properties": [ + { + "id": "custom.width", + "value": 177 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "model_name" + }, + "properties": [ + { + "id": "custom.width", + "value": 277 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Total Written" + }, + "properties": [ + { + "id": "custom.width", + "value": 123 + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 11, + "x": 13, + "y": 8 + }, + "id": 3, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Total Written" + } + ] + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "max(smartctl_device_bytes_written{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"}) by (device, instance, model_name, serial_number)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "__auto", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max((smartctl_device_attribute{instance=~\"$node\", device=~\"$disk\", attribute_name=\"Total_LBAs_Written\", attribute_value_type=\"raw\"} * on (instance,device) smartctl_device_block_size{instance=~\"$node\", device=~\"$disk\",blocks_type=\"physical\"}) * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"$type\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"}) by (device, instance, model_name, serial_number)\n", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Total Data Written on SSDs", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + }, + { + "id": "calculateField", + "options": { + "alias": "Total Written", + "binary": { + "left": { + "fixed": "" + }, + "right": { + "fixed": "" + } + }, + "mode": "reduceRow", + "reduce": { + "include": ["Value #B", "Value #A"], + "reducer": "sum" + }, + "replaceFields": false, + "window": { + "reducer": "mean", + "windowAlignment": "trailing", + "windowSize": 0.1, + "windowSizeMode": "percentage" + } + } + }, + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": [ + "Time", + "device", + "instance", + "model_name", + "serial_number", + "Total Written" + ] + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "", + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 75 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 13, + "x": 0, + "y": 18 + }, + "id": 8, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": ["last"], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "sort_desc(100 - smartctl_device_attribute{instance=~\"$node\", device=~\"$disk\", attribute_name=\"Wear_Leveling_Count\",attribute_value_type=\"value\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"sat\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"})", + "format": "time_series", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}:{{device}}", + "refId": "A" + } + ], + "title": "Wear Level on SATA Devices", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "", + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 75 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 11, + "x": 13, + "y": 18 + }, + "id": 14, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": ["last"], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "editorMode": "code", + "expr": "sort_desc(smartctl_device_percentage_used{instance=~\"$node\", device=~\"$disk\"} * on(instance, device) group_left(interface,serial_number,model_family,model_name) smartctl_device{interface=~\"nvme\",serial_number=~\"$serial_number\",model_name=~\"$device_model\"})\n", + "format": "time_series", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}:{{device}}", + "refId": "A" + } + ], + "title": "Wear Level on NVMe Devices", + "type": "gauge" + } + ], + "refresh": "1m", + "schemaVersion": 40, + "tags": ["prometheus", "node_exporter", "smartmon"], + "templating": { + "list": [ + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "definition": "label_values(smartctl_version,instance)", + "includeAll": true, + "multi": true, + "name": "node", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(smartctl_version,instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "definition": "label_values(smartctl_device,device)", + "includeAll": true, + "multi": true, + "name": "disk", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(smartctl_device,device)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "definition": "label_values(smartctl_device,interface)", + "includeAll": true, + "multi": true, + "name": "type", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(smartctl_device,interface)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "definition": "label_values(smartctl_device,model_name)", + "includeAll": true, + "multi": true, + "name": "device_model", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(smartctl_device,model_name)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "Prometheus" + }, + "definition": "label_values(smartctl_device,serial_number)", + "includeAll": true, + "multi": true, + "name": "serial_number", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(smartctl_device,serial_number)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["1m", "5m", "15m", "30m", "1h", "2h", "1d"] + }, + "timezone": "browser", + "title": "SMARTctl Exporter Dashboard", + "uid": "ce8j0dmrrej9cc", + "version": 47, + "weekStart": "", + "gnetId": 22604 +} diff --git a/machines/xnet/monitoring/default.nix b/machines/xnet/monitoring/default.nix index 87ae724..eed4963 100644 --- a/machines/xnet/monitoring/default.nix +++ b/machines/xnet/monitoring/default.nix @@ -1,38 +1,58 @@ { config, ... }: let - inherit (config.networking) hostName; + inherit (builtins) + map + ; + inherit (config.services.prometheus) exporters; in { - imports = [ ./grafana.nix ./prometheus.nix ]; + imports = [ ./grafana.nix ]; - exporters = { - node = { - enable = true; - enabledCollectors = [ "processes" "systemd" ]; - }; - systemd = { - enable = true; - extraFlags = [ - "--systemd.collector.enable-ip-accounting" - "--systemd.collector.enable-restart-count" - ]; + config = { + services.prometheus = { + enable = config.xnet.monitoring.hostGrafana; + globalConfig.scrape_interval = "1m"; + + exporters = { + node = { + enable = true; + openFirewall = true; + enabledCollectors = [ "processes" "systemd" ]; + }; + + # systemd = { + # enable = true; + # openFirewall = true; + # extraFlags = [ + # "--systemd.collector.enable-ip-accounting" + # "--systemd.collector.enable-restart-count" + # ]; + # }; + + smartctl = { + enable = true; + openFirewall = true; + }; + }; + + scrapeConfigs = + let + hosts = [ "iridium" "radon" ]; + in + [{ + job_name = "node"; + static_configs = [{ + targets = map (h: "${h}:${toString exporters.node.port}") hosts; + }]; + } + { + job_name = "smartctl"; + static_configs = [{ + targets = map (h: "${h}:${toString exporters.smartctl.port}") hosts; + }]; + }]; }; }; - - services.prometheus.scrapeConfigs = [ - { - job_name = "node"; - static_configs = [{ - targets = [ "${hostName}:${toString exporters.node.port}" ]; - }]; - } - { - job_name = "systemd"; - static_configs = [{ - targets = [ "${hostName}:${toString exporters.systemd.port}" ]; - }]; - } - ]; } diff --git a/machines/xnet/monitoring/grafana.nix b/machines/xnet/monitoring/grafana.nix index 6a37ce1..e95318d 100644 --- a/machines/xnet/monitoring/grafana.nix +++ b/machines/xnet/monitoring/grafana.nix @@ -1,51 +1,78 @@ -{ config, pkgs, ... }: { - services.grafana.provision = { - enable = true; - datasources.settings.datasources = [{ - name = "Prometheus"; - type = "prometheus"; - url = "http://localhost:9090"; - access = "proxy"; - editable = false; - }]; +{ config, pkgs, lib, ... }: +let + inherit (lib) mkOption mkIf types; - dashboards.settings.providers = [{ - name = "Fetched Dashboards"; - options.path = "/etc/grafana/dashboards"; - }]; + inherit (config.xnet.monitoring) + hostGrafana + ; +in +{ + options.xnet.monitoring = { + hostGrafana = mkOption { + type = types.bool; + default = false; + description = "Scrape hosts and host the data."; + }; }; - environment.etc = { - "grafana/dashboards/node-exporter.json" = { - user = "grafana"; - group = "grafana"; - source = pkgs.fetchurl { - url = "https://grafana.com/api/dashboards/1860/revisions/37/download"; - hash = "sha256-1DE1aaanRHHeCOMWDGdOS1wBXxOF84UXAjJzT5Ek6mM="; - }; + config = mkIf hostGrafana { + services.grafana.provision = { + enable = true; + datasources.settings.datasources = [{ + name = "Prometheus"; + type = "prometheus"; + url = "http://localhost:9090"; + access = "proxy"; + editable = false; + }]; + + dashboards.settings.providers = [{ + name = "Fetched Dashboards"; + options.path = "/etc/grafana/dashboards"; + }]; }; - }; - services.grafana = { - enable = true; - settings.server = { - domain = "grafana.web.4kb.net"; - protocol = "socket"; + environment.etc = { + "grafana/dashboards/node-exporter.json" = { + user = "grafana"; + group = "grafana"; + source = pkgs.fetchurl { + url = "https://grafana.com/api/dashboards/1860/revisions/37/download"; + hash = "sha256-1DE1aaanRHHeCOMWDGdOS1wBXxOF84UXAjJzT5Ek6mM="; + }; + }; + "grafana/dashboards/smartctl-exporter.json" = { + user = "grafana"; + group = "grafana"; + source = ./grafana.nix; + # source = pkgs.fetchurl { + # url = "https://grafana.com/api/dashboards/22604/revisions/2/download"; + # hash = "sha256-ci8WE23fZ+ltEKFoUdNNVXsUIV0jqtas79ia2lYIo88="; + # }; + }; }; - settings."auth.anonymous" = { - enabled = true; - org_role = "Admin"; + + services.grafana = { + enable = true; + settings.server = { + domain = "grafana.plaza.4kb.net"; + protocol = "socket"; + }; + settings."auth.anonymous" = { + enabled = true; + org_role = "Admin"; + }; }; - }; - users.groups.grafana.members = [ "nginx" ]; - systemd.services.nginx.serviceConfig.ProtectHome = false; + users.groups.grafana.members = [ "nginx" ]; + systemd.services.nginx.serviceConfig.ProtectHome = false; - services.nginx.virtualHosts."${config.services.grafana.settings.server.domain}" = { - useACMEHost = "4kb.net"; - addSSL = true; - locations."/" = { - proxyPass = "http://unix:/${toString config.services.grafana.settings.server.socket}"; + services.nginx.virtualHosts."${config.services.grafana.settings.server.domain}" = { + # useACMEHost = "4kb.net"; + # addSSL = true; + locations."/" = { + proxyPass = "http://unix:/${toString config.services.grafana.settings.server.socket}"; + }; }; }; } diff --git a/machines/xnet/monitoring/prometheus.nix b/machines/xnet/monitoring/prometheus.nix deleted file mode 100644 index e32e078..0000000 --- a/machines/xnet/monitoring/prometheus.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ config, ... }: { - services.prometheus = { - enable = true; - globalConfig.scrape_interval = "1m"; - # scrapeConfigs = [{ - # job_name = "node"; - # relabel_configs = [{ - # source_labels = [ "__address__" ]; - # regex = "(.*):[0-9]+"; - # target_label = "instance"; - # replacement = "$1"; - # }]; - # }]; - }; -} diff --git a/machines/xnet/net/default.nix b/machines/xnet/net/default.nix index 2255f53..9673792 100644 --- a/machines/xnet/net/default.nix +++ b/machines/xnet/net/default.nix @@ -1,8 +1,60 @@ { config, lib, ... }: let cfg = config.xnet.net; - inherit (lib) mkOption mkIf types; - prefix = "10.26.4"; + + inherit (builtins) + attrNames + attrValues + map + length + ; + + inherit (lib) + concatLines + genAttrs + mapAttrsToList + mergeAttrsList + mkOption + mkIf + types + ; + + # Networks are logical groupings of hosts wired together. This is + # accomplished using VLANS on the same layer 2 network. + # + # Hosts can hard code their spot on a network here. This module aims + # to generate network information for a host using this set of facts. + # The module should gracefully fall back to defaults if a given fact + # is not specified for the host consuming the module. + # + # A host will have it's /etc/hosts populated with all other hosts in + # a network to avoid a dynamic DNS server. + networks = { + + # Open network for xnet hosts + plaza = { + mask = 24; + vlan = 88; + hosts = { + t1 = "10.88.88.1"; + radon = "10.88.88.2"; + iridium = "10.88.88.3"; + }; + }; + + # Reserved network for kubernetes related nodes. A distinct network + # is created here for hosts that provide resources to workers. + # Generally, nodes on this network are spawned dynamically and are + # not a part of this NixOS config directly, although they may boot + # from assets served from a node here. + kubenet = { + mask = 24; + vlan = 42; + hosts = { + iridium = "10.88.42.254"; + }; + }; + }; in { imports = [ @@ -10,35 +62,60 @@ in ]; options.xnet.net = { + join = mkOption { + type = types.listOf (types.enum (attrNames networks)); + default = [ ]; + description = "Available networks."; + }; + interface = mkOption { type = types.str; default = ""; description = "Network interface connecting to xnet."; }; - - addr = mkOption { - type = types.ints.between 0 255; - description = "Final octet for xnet address."; - example = 4; - }; }; - # TODO: - # - Add assertion that each address is only used once across config - # - Add each host to each other hosts dns configuration - config = mkIf (builtins.stringLength cfg.interface > 0) { - networking.vlans = { - "${cfg.interface}.4" = { - inherit (cfg) interface; - id = 4; - }; - }; + config = mkIf ((length cfg.join) > 0) { + systemd.network = + let + name = config.networking.hostName; - networking.interfaces = { - "${cfg.interface}.4".ipv4.addresses = [{ - address = "${prefix}.${toString cfg.addr}"; - prefixLength = 24; - }]; - }; + genConfig = net: { + netdevs."${toString networks.${net}.vlan}-${net}" = { + netdevConfig.Kind = "vlan"; + netdevConfig.Name = net; + vlanConfig.Id = networks.${net}.vlan; + }; + + networks."10-${cfg.interface}" = { + matchConfig.Name = cfg.interface; + vlan = cfg.join; + + # Accept DHCP on physical interface + DHCP = "ipv4"; + + # Network is up when xnet physical interface gets carrier + linkConfig.RequiredForOnline = "carrier"; + }; + + networks."${toString networks.${net}.vlan}-${net}" = { + matchConfig.Name = net; + + # Set up address for known host + address = [ "${networks.${net}.hosts.${name}}/${toString networks.${net}.mask}" ]; + }; + }; + + values = attrValues (genAttrs cfg.join genConfig); + in + { enable = true; } // mergeAttrsList values; + + networking.extraHosts = + let + genHosts = net: concatLines + (mapAttrsToList (name: value: "${value} ${name} ${name}.${net}.4kb.net") + networks.${net}.hosts); + in + concatLines (map (net: genHosts net) cfg.join); }; } diff --git a/machines/xnet/net/sshd.nix b/machines/xnet/net/sshd.nix index ef225db..b7cacc2 100644 --- a/machines/xnet/net/sshd.nix +++ b/machines/xnet/net/sshd.nix @@ -24,8 +24,8 @@ in settings = { UsePAM = true; X11Forwarding = false; - PermitRootLogin = "no"; - PasswordAuthentication = false; + PermitRootLogin = "yes"; + # PasswordAuthentication = false; Ciphers = [ "chacha20-poly1305@openssh.com" ]; Macs = [ "hmac-sha2-512-etm@openssh.com" ]; KexAlgorithms = [ "curve25519-sha256@libssh.org" ]; diff --git a/machines/xnet/persist.nix b/machines/xnet/persist.nix new file mode 100644 index 0000000..0ace84f --- /dev/null +++ b/machines/xnet/persist.nix @@ -0,0 +1,61 @@ +{ config, lib, ... }: +let + inherit (lib) + concatLists + isString + mkOption + types + ; + +in +{ + options.xnet.persist = mkOption { + type = types.listOf (types.either + types.str + (types.submodule { + options = { + path = mkOption { + type = types.str; + description = "Path to persist"; + }; + user = mkOption { + type = types.nullOr types.str; + default = null; + description = "User ID to set on the persisted directory"; + }; + group = mkOption { + type = types.nullOr types.str; + default = null; + description = "Group ID to set on the persisted directory"; + }; + + mode = mkOption { + type = types.nullOr types.str; + default = null; + description = "Permissions to set"; + }; + }; + })); + default = [ ]; + description = "Automatically persisted state."; + }; + + config.systemd.tmpfiles.rules = + let + mkEntry = entry: + let + path = if isString entry then entry else entry.path; + user = if isString entry then "-" else entry.user; + group = if isString entry then "-" else entry.group; + mode = if isString entry then "-" else entry.mode; + + dent = "d /persist${path} ${mode} ${user} ${group} - -"; + link = "L ${path} - - - - /persist${path}"; + perm = "Z ${mode} ${user} ${group} - -"; + in + [ dent link perm ]; + + entries = map mkEntry config.xnet.persist; + in + concatLists entries; +} diff --git a/machines/xnet/users.nix b/machines/xnet/users.nix index 384cb8c..7995b94 100644 --- a/machines/xnet/users.nix +++ b/machines/xnet/users.nix @@ -1,12 +1,24 @@ { pkgs, lib, config, ... }: let + inherit (builtins) + elem + ; + + inherit (lib) + mkOption + mkIf + types + ; + cfg = config.xnet.users; - inherit (lib) mkOption mkIf types; + + userEn = user: elem user cfg.enable; gitKeys = builtins.fetchurl { url = "https://github.com/kbujari.keys"; sha256 = "0fpa679zkrpx77vangzf3gnidwvmky8ifivn8411xx6albrikaqx"; }; + in { @@ -25,7 +37,7 @@ in initialHashedPassword = "$y$j9T$eGwGb5tZwhk/.K0Lezsx4/$dJ4AODPBo0RBkVoCh1MVZTtkkDRn/C6A/XQIKt2YBNA"; openssh.authorizedKeys.keys = lib.splitString "\n" (builtins.readFile gitKeys); }; - users.kle = mkIf (builtins.elem "kle" cfg.enable) { + users.kle = mkIf (userEn "kle") { initialHashedPassword = "$6$R4dDhaftX.vapGMd$.An36hlp3DXfkIC7bPZ0MDPo6Zvpk8JRrhy2LES.lZZj6JDa74oJkcMW3DCsIySvLJxOPXSShos0TpgJ/w0fH/"; isNormalUser = true; shell = pkgs.fish; @@ -50,6 +62,8 @@ in }; }; + disko.devices.zpool.zroot.datasets = { }; + security.sudo = { execWheelOnly = true; extraConfig = "Defaults lecture = never"; diff --git a/mod/code/cses/.envrc b/mod/code/cses/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/mod/code/cses/.envrc @@ -0,0 +1 @@ +use nix diff --git a/mod/code/cses/default.nix b/mod/code/cses/default.nix new file mode 100644 index 0000000..6538eb8 --- /dev/null +++ b/mod/code/cses/default.nix @@ -0,0 +1,13 @@ +{ pkgs ? import { }, ... }: + +pkgs.mkShell { + packages = with pkgs; [ + clang-tools + (writeShellScriptBin "cpprun" '' + TEMP=".tmp.cpp" + g++ -std=c++20 -O3 ./problems/"$1.cpp" -o $TEMP + ./$TEMP + rm $TEMP + '') + ]; +} diff --git a/mod/code/cses/problems/1068.cpp b/mod/code/cses/problems/1068.cpp new file mode 100644 index 0000000..8d05936 --- /dev/null +++ b/mod/code/cses/problems/1068.cpp @@ -0,0 +1,17 @@ +#include + +int main(int argc, char *argv[]) { + unsigned long long n; + std::cin >> n; + + while (n != 1) { + std::cout << n << " "; + + if (n % 2 == 0) + n /= 2; + else + n = (n * 3) + 1; + } + + std::cout << 1; +} diff --git a/mod/code/cses/problems/1069.cpp b/mod/code/cses/problems/1069.cpp new file mode 100644 index 0000000..232d2f7 --- /dev/null +++ b/mod/code/cses/problems/1069.cpp @@ -0,0 +1,23 @@ +#include + +int main() { + std::string input; + std::cin >> input; + + auto max = 0; + auto curr = '-'; + auto count = 0; + + for (auto const ch : input) { + if (curr != ch) { + curr = ch; + count = 0; + } + + count += 1; + max = std::max(max, count); + } + + std::cout << max; + return 0; +} diff --git a/mod/code/cses/problems/1070.cpp b/mod/code/cses/problems/1070.cpp new file mode 100644 index 0000000..131a644 --- /dev/null +++ b/mod/code/cses/problems/1070.cpp @@ -0,0 +1,15 @@ +#include + +int main() { + int n; + std::cin >> n; + + if (n == 1) + std::cout << 1; + else if (n < 4) + std::cout << "NO SOLUTION"; + else { + for (auto i = 2; i <= n; i += 2) std::cout << i << " "; + for (auto i = 1; i <= n; i += 2) std::cout << i << " "; + } +} diff --git a/mod/code/cses/problems/1083.cpp b/mod/code/cses/problems/1083.cpp new file mode 100644 index 0000000..a3cd253 --- /dev/null +++ b/mod/code/cses/problems/1083.cpp @@ -0,0 +1,20 @@ +#include +#include + +using ull = unsigned long long; + +int main(int argc, char *argv[]) { + ull n; + std::cin >> n; + + auto set = std::set{}; + + std::string numstr; + while (std::getline(std::cin, numstr, ' ')) set.insert(std::stoi(numstr)); + + for (auto i = 1; i <= n; i++) { + if (set.contains(i)) continue; + std::cout << i; + break; + } +} diff --git a/mod/code/cses/problems/1094.cpp b/mod/code/cses/problems/1094.cpp new file mode 100644 index 0000000..56f3886 --- /dev/null +++ b/mod/code/cses/problems/1094.cpp @@ -0,0 +1,27 @@ +#include +#include + +using ull = unsigned long long; + +int main() { + ull n; + auto arr = std::vector{}; + + std::cin >> n; + + std::string type; + while (std::cin >> type) arr.push_back(std::stoi(type)); + + ull count = 0; + auto last = arr[0]; + + for (auto const num : arr) { + if (num > last) { + last = num; + continue; + } + count += last - num; + } + + std::cout << count; +} diff --git a/mod/tools/perf-flamegraph.nix b/mod/tools/perf-flamegraph.nix new file mode 100644 index 0000000..b472b74 --- /dev/null +++ b/mod/tools/perf-flamegraph.nix @@ -0,0 +1,12 @@ +# Script that collects perf timing for the execution of a command and writes a +# flamegraph to stdout +{ pkgs, ... }: + +pkgs.writeShellScriptBin "perf-flamegraph" '' + set -euo pipefail + + ${pkgs.linuxPackages.perf}/bin/perf record -g --call-graph dwarf -F max "$@" + ${pkgs.linuxPackages.perf}/bin/perf script \ + | ${pkgs.flamegraph}/bin/stackcollapse-perf.pl \ + | ${pkgs.flamegraph}/bin/flamegraph.pl +'' diff --git a/mod/tools/typst/default.nix b/mod/tools/typst/default.nix index 3f81658..5f809d6 100644 --- a/mod/tools/typst/default.nix +++ b/mod/tools/typst/default.nix @@ -28,6 +28,6 @@ in depotPackages ]; - shellHook = "export XDG_DATA_HOME=${depotPackages}/share:$XDG_DATA_HOME"; + shellHook = "alias typst='export XDG_DATA_HOME=${depotPackages}/share:$XDG_DATA_HOME'"; }; } -- cgit v1.3.1