1
0
mirror of https://github.com/kmein/niveum synced 2026-03-29 08:41:07 +02:00

7 Commits

Author SHA1 Message Date
c15f5375e2 format 2025-12-28 13:39:42 +01:00
51533efeda use treefmt-nix 2025-12-28 13:39:36 +01:00
977e733ace vim-typewriter: fix 2025-12-28 13:29:27 +01:00
29571bce10 remove specialArgs inputs 2025-12-28 13:23:49 +01:00
ab895d9f7b systems -> machines 2025-12-28 12:49:10 +01:00
2d6294e44b ditch nixinate 2025-12-28 12:40:45 +01:00
c33cbe3817 update old system code 2025-12-28 12:05:59 +01:00
47 changed files with 896 additions and 1022 deletions

View File

@@ -2,7 +2,7 @@ name: Update flake.lock
on: on:
workflow_dispatch: # allows manual triggering workflow_dispatch: # allows manual triggering
schedule: schedule:
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00 - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00
jobs: jobs:
lockfile: lockfile:

View File

@@ -7,33 +7,33 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
system: [makanek,manakish,kabsa,zaatar,ful,fatteh] system: [makanek, manakish, kabsa, zaatar, ful, fatteh]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Install QEMU (ARM) - name: Install QEMU (ARM)
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y qemu-user-static sudo apt-get install -y qemu-user-static
if: ${{ matrix.system == 'ful' }} if: ${{ matrix.system == 'ful' }}
- name: Install Nix (ARM) - name: Install Nix (ARM)
uses: cachix/install-nix-action@v16 uses: cachix/install-nix-action@v16
if: ${{ matrix.system == 'ful' }} if: ${{ matrix.system == 'ful' }}
with: with:
extra_nix_config: | extra_nix_config: |
system = aarch64-linux system = aarch64-linux
- name: Install Nix (x86_64) - name: Install Nix (x86_64)
uses: cachix/install-nix-action@v16 uses: cachix/install-nix-action@v16
if: ${{ matrix.system != 'ful' }} if: ${{ matrix.system != 'ful' }}
- name: nixos-rebuild dry-build - name: nixos-rebuild dry-build
run: | run: |
# remove secrets: ref https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/36593218 # remove secrets: ref https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/36593218
git submodule deinit -f secrets git submodule deinit -f secrets
rm -rf .git/modules/secrets rm -rf .git/modules/secrets
git rm -f secrets git rm -f secrets
# recreate secrets # recreate secrets
mkdir secrets mkdir secrets
cat secrets.txt | while read -r path; do touch $path; done cat secrets.txt | while read -r path; do touch $path; done
git add secrets git add secrets
nix run nixpkgs#nixos-rebuild -- dry-build --flake $GITHUB_WORKSPACE#${{matrix.system}} nix run nixpkgs#nixos-rebuild -- dry-build --flake $GITHUB_WORKSPACE#${{matrix.system}}

View File

@@ -5,13 +5,14 @@
> [nĭvĕus](https://logeion.uchicago.edu/niveus), a, um, adj. [nix], _of_ or _from snow, snowy, snow-_ (poet.) > [nĭvĕus](https://logeion.uchicago.edu/niveus), a, um, adj. [nix], _of_ or _from snow, snowy, snow-_ (poet.)
> >
> 1. Lit.: aggeribus niveis informis, Verg. G. 3, 354: aqua, _cooled with snow_, Mart. 12, 17, 6; cf. id. 14, 104 and 117: mons, _covered with snow_, Cat. 64, 240.— > 1. Lit.: aggeribus niveis informis, Verg. G. 3, 354: aqua, _cooled with snow_, Mart. 12, 17, 6; cf. id. 14, 104 and 117: mons, _covered with snow_, Cat. 64, 240.—
>
> 2. Transf., _snow-white, snowy_ (mostly poet.): a similitudine sic: Corpore niveum candorem, aspectu igneum ardorem assequebatur, Auct. Her. 4, 33, 44: lacerti, Verg. A. 8, 387: lac, id. E. 2, 20: hanc si capite niveae agnae exorari judicas, Sen. Q. N. 2, 36: Briseis niveo colore, Hor. C. 2, 4, 3: vestis, Ov. M. 10, 432: candidior nivei folio, Galatea, ligustri, id. ib. 13, 789: dens, id. H. 18, 18: quā notam duxit niveus videri, Hor. C. 4, 2, 59: panis, Juv. 5, 70: flumen, _clear, pellucid_, Sen. Hippol. 504: undae, Mart. 7, 32, 11: tribuni, _clothed in white togas_, Calp. Ecl. 7, 29; so, Quirites, Juv. 10, 45. > 2. Transf., _snow-white, snowy_ (mostly poet.): a similitudine sic: Corpore niveum candorem, aspectu igneum ardorem assequebatur, Auct. Her. 4, 33, 44: lacerti, Verg. A. 8, 387: lac, id. E. 2, 20: hanc si capite niveae agnae exorari judicas, Sen. Q. N. 2, 36: Briseis niveo colore, Hor. C. 2, 4, 3: vestis, Ov. M. 10, 432: candidior nivei folio, Galatea, ligustri, id. ib. 13, 789: dens, id. H. 18, 18: quā notam duxit niveus videri, Hor. C. 4, 2, 59: panis, Juv. 5, 70: flumen, _clear, pellucid_, Sen. Hippol. 504: undae, Mart. 7, 32, 11: tribuni, _clothed in white togas_, Calp. Ecl. 7, 29; so, Quirites, Juv. 10, 45.
## Pressestimmen ## Pressestimmen
> das ist ja pure poesie —[riotbib](https://github.com/riotbib/) > das ist ja pure poesie —[riotbib](https://github.com/riotbib/)
> Deine Configs sind wunderschön <3 —[flxai](https://github.com/flxai/) > Deine Configs sind wunderschön <3 —[flxai](https://github.com/flxai/)
## To do ## To do
- [ ] get rid of `nixinate`
🦗

View File

@@ -1,11 +1,8 @@
{ {
config, config,
inputs, pkgs,
... ...
}: }:
let
autorenkalender = inputs.autorenkalender.packages.x86_64-linux.default;
in
{ {
niveum.bots.autorenkalender = { niveum.bots.autorenkalender = {
enable = true; enable = true;
@@ -16,7 +13,7 @@ in
chatIds = [ "@autorenkalender" ]; chatIds = [ "@autorenkalender" ];
parseMode = "Markdown"; parseMode = "Markdown";
}; };
command = "${autorenkalender}/bin/autorenkalender"; command = "${pkgs.autorenkalender}/bin/autorenkalender";
}; };
niveum.passport.services = [ niveum.passport.services = [

View File

@@ -1,12 +1,9 @@
{ {
config, config,
pkgs, pkgs,
lib,
inputs,
... ...
}: }:
let let
telebots = inputs.telebots.defaultPackage.x86_64-linux;
reverseDirectory = "/run/telegram-reverse"; reverseDirectory = "/run/telegram-reverse";
proverbDirectory = "/run/telegram-proverb"; proverbDirectory = "/run/telegram-proverb";
in in
@@ -74,7 +71,7 @@ in
path = [ pkgs.ffmpeg ]; path = [ pkgs.ffmpeg ];
enable = true; enable = true;
script = '' script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-reverse TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-reverse
''; '';
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
serviceConfig.WorkingDirectory = reverseDirectory; serviceConfig.WorkingDirectory = reverseDirectory;
@@ -86,7 +83,7 @@ in
description = "Telegram bot converting YouTube Music <-> Spotify"; description = "Telegram bot converting YouTube Music <-> Spotify";
enable = true; enable = true;
script = '' script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-streaming-link TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-streaming-link
''; '';
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
serviceConfig.LoadCredential = "token:${config.age.secrets.telegram-token-streaming-link.path}"; serviceConfig.LoadCredential = "token:${config.age.secrets.telegram-token-streaming-link.path}";
@@ -97,7 +94,7 @@ in
description = "Telegram beta code bot"; description = "Telegram beta code bot";
enable = true; enable = true;
script = '' script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-betacode TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-betacode
''; '';
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
serviceConfig.LoadCredential = "token:${config.age.secrets.telegram-token-betacode.path}"; serviceConfig.LoadCredential = "token:${config.age.secrets.telegram-token-betacode.path}";
@@ -108,7 +105,7 @@ in
description = "Telegram proverb bot"; description = "Telegram proverb bot";
enable = true; enable = true;
script = '' script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-proverb TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-proverb
''; '';
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
serviceConfig.WorkingDirectory = proverbDirectory; serviceConfig.WorkingDirectory = proverbDirectory;

View File

@@ -1,13 +1,8 @@
{ {
pkgs, pkgs,
config, config,
inputs,
lib,
... ...
}: }:
let
hesychius = inputs.scripts.outPath + "/hesychius/hesychius.txt";
in
{ {
niveum.bots.hesychius = { niveum.bots.hesychius = {
enable = true; enable = true;
@@ -22,7 +17,7 @@ in
tokenFile = config.age.secrets.telegram-token-kmein.path; tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = [ "@HesychiosAlexandreus" ]; chatIds = [ "@HesychiosAlexandreus" ];
}; };
command = "${pkgs.coreutils}/bin/shuf -n1 ${hesychius}"; command = "${pkgs.coreutils}/bin/shuf -n1 ${pkgs.hesychius}";
}; };
systemd.timers.bot-hesychius.timerConfig.RandomizedDelaySec = "10h"; systemd.timers.bot-hesychius.timerConfig.RandomizedDelaySec = "10h";

View File

@@ -2,7 +2,6 @@
pkgs, pkgs,
lib, lib,
config, config,
inputs,
... ...
}: }:
let let
@@ -10,8 +9,6 @@ let
in in
{ {
imports = [ imports = [
inputs.self.nixosModules.system-dependent
inputs.self.nixosModules.power-action
{ {
boot.supportedFilesystems = [ "ntfs" ]; boot.supportedFilesystems = [ "ntfs" ];
} }

View File

@@ -1,6 +1,5 @@
{ {
pkgs, pkgs,
inputs,
... ...
}: }:
{ {
@@ -10,6 +9,5 @@
nix = { nix = {
package = pkgs.nixVersions.stable; package = pkgs.nixVersions.stable;
extraOptions = "experimental-features = nix-command flakes"; extraOptions = "experimental-features = nix-command flakes";
nixPath = [ "nixpkgs=${inputs.nixpkgs}" ];
}; };
} }

View File

@@ -1,8 +1,6 @@
{ {
config, config,
pkgs, pkgs,
lib,
inputs,
... ...
}: }:
let let
@@ -123,7 +121,7 @@ in
zoom-us # video conferencing zoom-us # video conferencing
(pkgs.writers.writeDashBin "im" '' (pkgs.writers.writeDashBin "im" ''
weechat_password=$(${pkgs.pass}/bin/pass weechat) weechat_password=$(${pkgs.pass}/bin/pass weechat)
exec ${weechat}/bin/weechat -t -r '/mouse enable; /remote add makanek http://${pkgs.lib.niveum.systems.makanek.externalIp}:8002 -password='"$weechat_password"'; /remote connect makanek' exec ${weechat}/bin/weechat -t -r '/mouse enable; /remote add makanek http://${pkgs.lib.niveum.machines.makanek.externalIp}:8002 -password='"$weechat_password"'; /remote connect makanek'
'') '')
alejandra # nix formatter alejandra # nix formatter
pdfgrep # search in pdf pdfgrep # search in pdf
@@ -190,22 +188,18 @@ in
par par
qrencode qrencode
# inputs.menstruation-backend.defaultPackage.x86_64-linux pkgs.agenix
inputs.agenix.packages.x86_64-linux.default pkgs.alarm
inputs.recht.defaultPackage.x86_64-linux
(pkgs.writers.writeDashBin "worldradio" '' (pkgs.writers.writeDashBin "worldradio" ''
shuf ${worldradio} | ${pkgs.findutils}/bin/xargs ${pkgs.mpv}/bin/mpv --no-video shuf ${worldradio} | ${pkgs.findutils}/bin/xargs ${pkgs.mpv}/bin/mpv --no-video
'') '')
(pkgs.writers.writeDashBin "chats" '' (pkgs.writers.writeDashBin "chats" ''
${pkgs.openssh}/bin/ssh makanek "cd /var/lib/weechat/logs && grep --ignore-case --color=always --recursive $@" | ${pkgs.less}/bin/less --raw-control-chars ${pkgs.openssh}/bin/ssh -p ${toString pkgs.lib.niveum.machines.makanek.sshPort} ${pkgs.lib.niveum.machines.makanek.externalIp} "cd /var/lib/weechat/logs && grep --ignore-case --color=always --recursive $@" | ${pkgs.less}/bin/less --raw-control-chars
'') '')
inputs.scripts.packages.x86_64-linux.alarm
spotify spotify
ncspot
playerctl playerctl
#krebs #krebs

View File

@@ -8,7 +8,7 @@
services.openssh = { services.openssh = {
enable = true; enable = true;
ports = [ pkgs.lib.niveum.sshPort ]; ports = [ pkgs.lib.niveum.machines.${config.networking.hostName}.sshPort ];
settings = { settings = {
PasswordAuthentication = false; PasswordAuthentication = false;
X11Forwarding = true; X11Forwarding = true;

View File

@@ -1,7 +1,6 @@
{ {
pkgs, pkgs,
lib, lib,
inputs,
... ...
}: }:
let let
@@ -153,7 +152,7 @@ let
}; };
}; };
coptic = { coptic = {
dictionary = inputs.coptic-dictionary.packages.x86_64-linux.coptic-stardict; dictionary = pkgs.coptic-stardict;
Crum = pkgs.fetchzip { Crum = pkgs.fetchzip {
url = locker "stardict-Coptic-English_all_dialects-2.4.2.tar.bz2"; url = locker "stardict-Coptic-English_all_dialects-2.4.2.tar.bz2";
sha256 = "1fi281mb9yzv40wjsdapi8fzpa7x2yscz582lv2qnss9g8zzzzr9"; sha256 = "1fi281mb9yzv40wjsdapi8fzpa7x2yscz582lv2qnss9g8zzzzr9";

View File

@@ -2,12 +2,11 @@
pkgs, pkgs,
config, config,
lib, lib,
inputs,
... ...
}: }:
let let
generatedWallpaper = pkgs.runCommand "wallpaper.png" { } '' generatedWallpaper = pkgs.runCommand "wallpaper.png" { } ''
${inputs.wallpaper-generator.packages.x86_64-linux.wp-gen}/bin/wallpaper-generator lines \ ${pkgs.wp-gen}/bin/wallpaper-generator lines \
--output $out \ --output $out \
${lib.concatMapStringsSep " " ( ${lib.concatMapStringsSep " " (
n: "--base0${lib.toHexString n}=${config.lib.stylix.colors.withHashtag."base0${lib.toHexString n}"}" n: "--base0${lib.toHexString n}=${config.lib.stylix.colors.withHashtag."base0${lib.toHexString n}"}"
@@ -16,7 +15,6 @@ let
in in
{ {
# https://danth.github.io/stylix/tricks.html # https://danth.github.io/stylix/tricks.html
# stylix.image = inputs.wallpapers.outPath + "/meteora/rodrigo-soares-250630.jpg";
stylix.enable = true; stylix.enable = true;
stylix.image = generatedWallpaper; stylix.image = generatedWallpaper;

156
flake.lock generated
View File

@@ -455,6 +455,21 @@
} }
}, },
"flake-utils_3": { "flake-utils_3": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_4": {
"inputs": { "inputs": {
"systems": "systems_4" "systems": "systems_4"
}, },
@@ -885,24 +900,6 @@
"type": "github" "type": "github"
} }
}, },
"nixinate_2": {
"inputs": {
"nixpkgs": "nixpkgs_6"
},
"locked": {
"lastModified": 1742737607,
"narHash": "sha256-rXR5zT+/ivE5JTi6m5tCvqN4obQPIT0mgmrBHkdjwEs=",
"owner": "matthewcroughan",
"repo": "nixinate",
"rev": "617b9bb5297147e35cbb24c93e2f30129f31bb9d",
"type": "github"
},
"original": {
"owner": "matthewcroughan",
"repo": "nixinate",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1693636127, "lastModified": 1693636127,
@@ -1000,22 +997,6 @@
} }
}, },
"nixpkgs_10": { "nixpkgs_10": {
"locked": {
"lastModified": 1760878510,
"narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_11": {
"locked": { "locked": {
"lastModified": 1659446231, "lastModified": 1659446231,
"narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=", "narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=",
@@ -1031,7 +1012,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_12": { "nixpkgs_11": {
"locked": { "locked": {
"lastModified": 1744536153, "lastModified": 1744536153,
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
@@ -1047,6 +1028,22 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_12": {
"locked": {
"lastModified": 1761236834,
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_13": { "nixpkgs_13": {
"locked": { "locked": {
"lastModified": 1615532953, "lastModified": 1615532953,
@@ -1122,22 +1119,6 @@
} }
}, },
"nixpkgs_6": { "nixpkgs_6": {
"locked": {
"lastModified": 1653060744,
"narHash": "sha256-kfRusllRumpt33J1hPV+CeCCylCXEU7e0gn2/cIM7cY=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "dfd82985c273aac6eced03625f454b334daae2e8",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_7": {
"locked": { "locked": {
"lastModified": 1764983851, "lastModified": 1764983851,
"narHash": "sha256-y7RPKl/jJ/KAP/VKLMghMgXTlvNIJMHKskl8/Uuar7o=", "narHash": "sha256-y7RPKl/jJ/KAP/VKLMghMgXTlvNIJMHKskl8/Uuar7o=",
@@ -1153,7 +1134,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_8": { "nixpkgs_7": {
"locked": { "locked": {
"lastModified": 1765186076, "lastModified": 1765186076,
"narHash": "sha256-hM20uyap1a0M9d344I692r+ik4gTMyj60cQWO+hAYP8=", "narHash": "sha256-hM20uyap1a0M9d344I692r+ik4gTMyj60cQWO+hAYP8=",
@@ -1169,13 +1150,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_9": { "nixpkgs_8": {
"locked": { "locked": {
"lastModified": 1744536153, "lastModified": 1665296151,
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", "narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", "rev": "14ccaaedd95a488dd7ae142757884d8e125b3363",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1185,6 +1166,22 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_9": {
"locked": {
"lastModified": 1760878510,
"narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nmd": { "nmd": {
"flake": false, "flake": false,
"locked": { "locked": {
@@ -1251,7 +1248,7 @@
"nur_2": { "nur_2": {
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_8" "nixpkgs": "nixpkgs_7"
}, },
"locked": { "locked": {
"lastModified": 1765367248, "lastModified": 1765367248,
@@ -1380,8 +1377,7 @@
"menstruation-backend": "menstruation-backend_2", "menstruation-backend": "menstruation-backend_2",
"menstruation-telegram": "menstruation-telegram_2", "menstruation-telegram": "menstruation-telegram_2",
"nix-index-database": "nix-index-database", "nix-index-database": "nix-index-database",
"nixinate": "nixinate_2", "nixpkgs": "nixpkgs_6",
"nixpkgs": "nixpkgs_7",
"nixpkgs-old": "nixpkgs-old_2", "nixpkgs-old": "nixpkgs-old_2",
"nixpkgs-unstable": "nixpkgs-unstable_2", "nixpkgs-unstable": "nixpkgs-unstable_2",
"nur": "nur_2", "nur": "nur_2",
@@ -1392,6 +1388,7 @@
"stylix": "stylix_2", "stylix": "stylix_2",
"telebots": "telebots_2", "telebots": "telebots_2",
"tinc-graph": "tinc-graph_2", "tinc-graph": "tinc-graph_2",
"treefmt-nix": "treefmt-nix_2",
"voidrice": "voidrice_2", "voidrice": "voidrice_2",
"wallpaper-generator": "wallpaper-generator_2", "wallpaper-generator": "wallpaper-generator_2",
"wallpapers": "wallpapers_2" "wallpapers": "wallpapers_2"
@@ -1443,14 +1440,15 @@
}, },
"rust-overlay_2": { "rust-overlay_2": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_9" "flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_8"
}, },
"locked": { "locked": {
"lastModified": 1765593578, "lastModified": 1677119371,
"narHash": "sha256-qbl874bCIy9+OLImdfBfZ9ITUDDjjTAB04Dk4PlZFV0=", "narHash": "sha256-L0Da4eKzDZrsy8ysOS1lhgDjAgEqGvYGf/lXaRd5/YQ=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "348b94ed9ddffccdf1a65582a2dcff0a4a3eeeb4", "rev": "c67c79ea25664d66e74ae91a6fa0d6c65d12d3a7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1461,7 +1459,7 @@
}, },
"rust-overlay_3": { "rust-overlay_3": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_12" "nixpkgs": "nixpkgs_11"
}, },
"locked": { "locked": {
"lastModified": 1765593578, "lastModified": 1765593578,
@@ -1517,11 +1515,11 @@
"rust-overlay": "rust-overlay_2" "rust-overlay": "rust-overlay_2"
}, },
"locked": { "locked": {
"lastModified": 1765657698, "lastModified": 1766923069,
"narHash": "sha256-Ic5lcBZQKw9kOU6BUl3w+r1zCj9hveHyaHsOAYB7Yhg=", "narHash": "sha256-RTW7ZlqnTue6o6yr2rzIT9MhfQPucDFnx4RgE7e4fNo=",
"owner": "kmein", "owner": "kmein",
"repo": "scripts", "repo": "scripts",
"rev": "aeea5b4cdaf39169ab469a7c31269c8360b9c403", "rev": "8c8acef0d204ebd606d240ea829478f664f588fd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1534,7 +1532,7 @@
"inputs": { "inputs": {
"buildbot-nix": "buildbot-nix", "buildbot-nix": "buildbot-nix",
"nix-writers": "nix-writers", "nix-writers": "nix-writers",
"nixpkgs": "nixpkgs_10" "nixpkgs": "nixpkgs_9"
}, },
"locked": { "locked": {
"lastModified": 1763891069, "lastModified": 1763891069,
@@ -1696,7 +1694,7 @@
}, },
"telebots_2": { "telebots_2": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_11" "nixpkgs": "nixpkgs_10"
}, },
"locked": { "locked": {
"lastModified": 1765657917, "lastModified": 1765657917,
@@ -1868,6 +1866,24 @@
"type": "github" "type": "github"
} }
}, },
"treefmt-nix_2": {
"inputs": {
"nixpkgs": "nixpkgs_12"
},
"locked": {
"lastModified": 1766000401,
"narHash": "sha256-+cqN4PJz9y0JQXfAK5J1drd0U05D5fcAGhzhfVrDlsI=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "42d96e75aa56a3f70cab7e7dc4a32868db28e8fd",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"voidrice": { "voidrice": {
"flake": false, "flake": false,
"locked": { "locked": {
@@ -1926,7 +1942,7 @@
}, },
"wallpaper-generator_2": { "wallpaper-generator_2": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_3", "flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_13" "nixpkgs": "nixpkgs_13"
}, },
"locked": { "locked": {

334
flake.nix
View File

@@ -11,7 +11,6 @@
menstruation-backend.url = "github:kmein/menstruation.rs"; menstruation-backend.url = "github:kmein/menstruation.rs";
menstruation-telegram.url = "github:kmein/menstruation-telegram"; menstruation-telegram.url = "github:kmein/menstruation-telegram";
nix-index-database.url = "github:nix-community/nix-index-database"; nix-index-database.url = "github:nix-community/nix-index-database";
nixinate.url = "github:matthewcroughan/nixinate";
nixpkgs-old.url = "github:NixOS/nixpkgs/50fc86b75d2744e1ab3837ef74b53f103a9b55a0"; nixpkgs-old.url = "github:NixOS/nixpkgs/50fc86b75d2744e1ab3837ef74b53f103a9b55a0";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/master"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/master";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
@@ -23,6 +22,7 @@
stylix.url = "github:danth/stylix/release-25.11"; stylix.url = "github:danth/stylix/release-25.11";
telebots.url = "github:kmein/telebots"; telebots.url = "github:kmein/telebots";
tinc-graph.url = "github:kmein/tinc-graph"; tinc-graph.url = "github:kmein/tinc-graph";
treefmt-nix.url = "github:numtide/treefmt-nix";
voidrice.url = "github:Lukesmithxyz/voidrice"; voidrice.url = "github:Lukesmithxyz/voidrice";
wallpaper-generator.url = "github:pinpox/wallpaper-generator/v1.1"; wallpaper-generator.url = "github:pinpox/wallpaper-generator/v1.1";
wallpapers.url = "github:kmein/wallpapers"; wallpapers.url = "github:kmein/wallpapers";
@@ -52,13 +52,13 @@
home-manager, home-manager,
agenix, agenix,
retiolum, retiolum,
nixinate,
coptic-dictionary, coptic-dictionary,
menstruation-backend, menstruation-backend,
menstruation-telegram, menstruation-telegram,
scripts, scripts,
tinc-graph, tinc-graph,
recht, recht,
treefmt-nix,
autorenkalender, autorenkalender,
wallpaper-generator, wallpaper-generator,
telebots, telebots,
@@ -71,72 +71,98 @@
let let
lib = nixpkgs.lib; lib = nixpkgs.lib;
eachSupportedSystem = lib.genAttrs lib.systems.flakeExposed; eachSupportedSystem = lib.genAttrs lib.systems.flakeExposed;
treefmtEval = eachSupportedSystem (
system:
treefmt-nix.lib.evalModule nixpkgs.legacyPackages.${system} (
{ pkgs, ... }:
{
projectRootFile = "flake.nix";
programs.nixfmt.enable = true;
programs.ormolu.enable = true;
programs.black.enable = true;
programs.prettier.enable = true;
programs.stylua.enable = true;
}
)
);
in in
{ {
apps = { apps =
x86_64-linux = let
let localSystem = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.x86_64-linux; in
lib = nixpkgs.lib; {
in ${localSystem} =
lib.mergeAttrsList [ let
(nixinate.nixinate.x86_64-linux self) pkgs = nixpkgs.legacyPackages.${localSystem};
{ lib = nixpkgs.lib;
mock-secrets = { in
type = "app"; lib.mergeAttrsList [
program = toString ( {
pkgs.writers.writeDash "mock-secrets" '' mock-secrets = {
${pkgs.findutils}/bin/find secrets -not -path '*/.*' -type f | ${pkgs.coreutils}/bin/sort > secrets.txt
''
);
};
}
# the following error prevents remote building of ful: https://github.com/NixOS/nixpkgs/issues/177873
(builtins.listToAttrs (
map (
hostname:
let
targets = {
ful = "root@ful";
zaatar = "root@zaatar";
makanek = "root@makanek";
manakish = "root@manakish";
tahina = "root@tahina";
tabula = "root@tabula";
kabsa = "root@kabsa";
fatteh = "root@fatteh";
kibbeh = "root@kibbeh";
};
in
lib.attrsets.nameValuePair "deploy-${hostname}" {
type = "app"; type = "app";
program = toString ( program = toString (
pkgs.writers.writeDash "deploy-${hostname}" '' pkgs.writers.writeDash "mock-secrets" ''
exec ${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \ ${pkgs.findutils}/bin/find secrets -not -path '*/.*' -type f | ${pkgs.coreutils}/bin/sort > secrets.txt
''
);
};
}
(builtins.listToAttrs (
map (
hostname:
let
machines = import lib/machines.nix;
systemAddresses =
system:
lib.optionals (system ? "internalIp") [ system.internalIp ]
++ lib.optionals (system ? "externalIp") [ system.externalIp ]
++ lib.optionals (system ? "retiolum") [
system.retiolum.ipv6
system.retiolum.ipv4
]
++ lib.optionals (system ? "mycelium") [ system.mycelium.ipv6 ];
addresses = lib.listToAttrs (
map (name: {
inherit name;
value = systemAddresses (machines.${hostname});
}) (builtins.attrNames self.nixosConfigurations)
);
deployScript = pkgs.writers.writeBash "deploy-${hostname}" ''
# try to connect to any of the known addresses
targets=(
${lib.concatStringsSep " " (map (addr: "\"root@${addr}\"") addresses.${hostname})}
)
for target in "''${targets[@]}"; do
nc -z -w 2 "$(echo $target | cut -d'@' -f2)" ${
toString machines.${hostname}.sshPort
} && reachable_target=$target && break
done
if [ -z "$reachable_target" ]; then
echo "No reachable target found for ${hostname}" >&2
exit 1
fi
echo "Deploying to ${hostname} via $reachable_target"
export NIX_SSHOPTS='-p ${toString machines.${hostname}.sshPort}'
${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \
--max-jobs 2 \ --max-jobs 2 \
--log-format internal-json \ --log-format internal-json \
--flake .#${hostname} \ --flake .#${hostname} \
--target-host ${targets.${hostname}} 2>&1 \ --target-host "$reachable_target" \
| ${pkgs.nix-output-monitor}/bin/nom --json ${
'' lib.optionalString (localSystem != machines.${hostname}.system) "--build-host $reachable_target"
); } \
} |& ${pkgs.nix-output-monitor}/bin/nom --json
) (builtins.attrNames self.nixosConfigurations) '';
)) in
{ lib.attrsets.nameValuePair "deploy-${hostname}" {
deploy-ful = { type = "app";
type = "app"; program = toString deployScript;
program = toString ( }
pkgs.writers.writeDash "deploy-ful" '' ) (builtins.attrNames self.nixosConfigurations)
exec ${pkgs.nix}/bin/nix run .#nixinate.ful \ ))
--log-format internal-json 2>&1 \ ];
| ${pkgs.nix-output-monitor}/bin/nom --json };
''
);
};
}
];
};
# TODO overlay for packages # TODO overlay for packages
# TODO remove flake-utils dependency from my own repos # TODO remove flake-utils dependency from my own repos
@@ -227,6 +253,21 @@
vim-reason-plus = prev.callPackage packages/vimPlugins/vim-reason-plus.nix { }; # TODO upstream vim-reason-plus = prev.callPackage packages/vimPlugins/vim-reason-plus.nix { }; # TODO upstream
}; };
# packaged from inputs
agenix = agenix.packages.${prev.stdenv.hostPlatform.system}.default;
alarm = scripts.packages.${prev.stdenv.hostPlatform.system}.alarm;
menstruation-telegram =
menstruation-telegram.packages.${prev.stdenv.hostPlatform.system}.menstruation-telegram;
menstruation-backend =
menstruation-backend.packages.${prev.stdenv.hostPlatform.system}.menstruation-backend;
telebots = telebots.packages.${prev.stdenv.hostPlatform.system}.telebots;
hesychius = scripts.packages.${prev.stdenv.hostPlatform.system}.hesychius;
autorenkalender = autorenkalender.packages.${prev.stdenv.hostPlatform.system}.default;
coptic-stardict = coptic-dictionary.packages.${prev.stdenv.hostPlatform.system}.coptic-stardict;
onomap = scripts.packages.${prev.stdenv.hostPlatform.system}.onomap;
tinc-graph = tinc-graph.packages.${prev.stdenv.hostPlatform.system}.tinc-graph;
wp-gen = wallpaper-generator.packages.${prev.stdenv.hostPlatform.system}.wp-gen;
# krebs # krebs
brainmelter = prev.callPackage packages/brainmelter.nix { }; brainmelter = prev.callPackage packages/brainmelter.nix { };
cyberlocker-tools = prev.callPackage packages/cyberlocker-tools.nix { }; cyberlocker-tools = prev.callPackage packages/cyberlocker-tools.nix { };
@@ -298,161 +339,103 @@
nixosConfigurations = nixosConfigurations =
let let
niveumSpecialArgs = system: { defaultModules = [
unstablePackages = import nixpkgs-unstable { { nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; }
inherit system; { nixpkgs.overlays = [ self.overlays.default ]; }
overlays = [ ]; agenix.nixosModules.default
config.allowUnfreePredicate = retiolum.nixosModules.retiolum
pkg: ];
builtins.elem (nixpkgs-unstable.lib.getName pkg) [ desktopModules = [
"obsidian" home-manager.nixosModules.home-manager
"zoom" nix-index-database.nixosModules.default
]; nur.modules.nixos.default
}; stylix.nixosModules.stylix
inputs = { self.nixosModules.system-dependent
inherit self.nixosModules.power-action
tinc-graph ];
self
telebots
menstruation-telegram
menstruation-backend
scripts
coptic-dictionary
agenix
recht
autorenkalender
nixpkgs
wallpaper-generator
;
};
};
in in
{ {
ful = nixpkgs.lib.nixosSystem rec { ful = nixpkgs.lib.nixosSystem {
system = "aarch64-linux"; system = "aarch64-linux";
specialArgs = niveumSpecialArgs system; modules = defaultModules ++ [
modules = [
{ nixpkgs.overlays = [ self.overlays.default ]; }
systems/ful/configuration.nix systems/ful/configuration.nix
agenix.nixosModules.default
self.nixosModules.passport self.nixosModules.passport
self.nixosModules.panoptikon self.nixosModules.panoptikon
self.nixosModules.go-webring self.nixosModules.go-webring
stockholm.nixosModules.reaktor2 stockholm.nixosModules.reaktor2
retiolum.nixosModules.retiolum
nur.modules.nixos.default nur.modules.nixos.default
{ nixpkgs.overlays = [ stockholm.overlays.default ]; } { nixpkgs.overlays = [ stockholm.overlays.default ]; }
{
_module.args.nixinate = {
host = "ful";
sshUser = "root";
buildOn = "remote";
substituteOnTarget = true;
hermetic = false;
};
}
]; ];
}; };
zaatar = nixpkgs.lib.nixosSystem rec { zaatar = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules = defaultModules ++ [
modules = [
{ nixpkgs.overlays = [ self.overlays.default ]; }
systems/zaatar/configuration.nix systems/zaatar/configuration.nix
agenix.nixosModules.default
retiolum.nixosModules.retiolum
]; ];
}; };
kibbeh = nixpkgs.lib.nixosSystem rec { kibbeh = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules =
modules = [ defaultModules
{ nixpkgs.overlays = [ self.overlays.default ]; } ++ desktopModules
systems/kibbeh/configuration.nix ++ [
agenix.nixosModules.default systems/kibbeh/configuration.nix
retiolum.nixosModules.retiolum ];
home-manager.nixosModules.home-manager
];
}; };
makanek = nixpkgs.lib.nixosSystem rec { makanek = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
# for using inputs in other config files modules = defaultModules ++ [
specialArgs = niveumSpecialArgs system;
modules = [
{ nixpkgs.overlays = [ self.overlays.default ]; }
systems/makanek/configuration.nix systems/makanek/configuration.nix
self.nixosModules.telegram-bot self.nixosModules.telegram-bot
self.nixosModules.passport self.nixosModules.passport
agenix.nixosModules.default
retiolum.nixosModules.retiolum
nur.modules.nixos.default nur.modules.nixos.default
]; ];
}; };
tahina = nixpkgs.lib.nixosSystem rec { tahina = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules = defaultModules ++ [
modules = [
{ nixpkgs.overlays = [ self.overlays.default ]; }
systems/tahina/configuration.nix systems/tahina/configuration.nix
agenix.nixosModules.default
retiolum.nixosModules.retiolum
]; ];
}; };
tabula = nixpkgs.lib.nixosSystem rec { tabula = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules = defaultModules ++ [
modules = [
{ nixpkgs.overlays = [ self.overlays.default ]; }
systems/tabula/configuration.nix systems/tabula/configuration.nix
agenix.nixosModules.default
retiolum.nixosModules.retiolum
]; ];
}; };
manakish = nixpkgs.lib.nixosSystem rec { manakish = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules =
modules = [ defaultModules
{ nixpkgs.overlays = [ self.overlays.default ]; } ++ desktopModules
systems/manakish/configuration.nix ++ [
agenix.nixosModules.default systems/manakish/configuration.nix
retiolum.nixosModules.retiolum ];
home-manager.nixosModules.home-manager
nix-index-database.nixosModules.default
nur.modules.nixos.default
stylix.nixosModules.stylix
];
}; };
kabsa = nixpkgs.lib.nixosSystem rec { kabsa = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules =
modules = [ defaultModules
{ nixpkgs.overlays = [ self.overlays.default ]; } ++ desktopModules
systems/kabsa/configuration.nix ++ [
agenix.nixosModules.default systems/kabsa/configuration.nix
retiolum.nixosModules.retiolum ];
home-manager.nixosModules.home-manager
nur.modules.nixos.default
nix-index-database.nixosModules.default
stylix.nixosModules.stylix
];
}; };
fatteh = nixpkgs.lib.nixosSystem rec { fatteh = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = niveumSpecialArgs system; modules =
modules = [ defaultModules
{ nixpkgs.overlays = [ self.overlays.default ]; } ++ desktopModules
systems/fatteh/configuration.nix ++ [
agenix.nixosModules.default systems/fatteh/configuration.nix
retiolum.nixosModules.retiolum ];
home-manager.nixosModules.home-manager
nur.modules.nixos.default
nix-index-database.nixosModules.default
stylix.nixosModules.stylix
];
}; };
}; };
formatter = eachSupportedSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-tree); formatter = eachSupportedSystem (system: treefmtEval.${system}.config.build.wrapper);
checks = eachSupportedSystem (system: {
formatting = treefmtEval.${system}.config.build.check self;
});
packages = eachSupportedSystem ( packages = eachSupportedSystem (
system: system:
@@ -517,7 +500,6 @@
q q
qrpaste qrpaste
radio-news radio-news
radioStreams
random-zeno random-zeno
rfc rfc
scanned scanned

View File

@@ -1,6 +1,6 @@
{ lib, pkgs }: { lib, pkgs }:
let let
systems = import ./systems.nix; machines = import ./machines.nix;
in in
{ {
tmpfilesConfig = tmpfilesConfig =
@@ -70,19 +70,19 @@ in
}; };
retiolumAddresses = lib.mapAttrs (_: v: { inherit (v.retiolum) ipv4 ipv6; }) ( retiolumAddresses = lib.mapAttrs (_: v: { inherit (v.retiolum) ipv4 ipv6; }) (
lib.filterAttrs (_: v: v ? "retiolum") systems lib.filterAttrs (_: v: v ? "retiolum") machines
); );
externalNetwork = lib.mapAttrs (_: v: v.externalIp) ( externalNetwork = lib.mapAttrs (_: v: v.externalIp) (
lib.filterAttrs (_: v: v ? "externalIp") systems lib.filterAttrs (_: v: v ? "externalIp") machines
); );
localAddresses = lib.mapAttrs (_: v: v.internalIp) ( localAddresses = lib.mapAttrs (_: v: v.internalIp) (
lib.filterAttrs (_: v: v ? "internalIp") systems lib.filterAttrs (_: v: v ? "internalIp") machines
); );
myceliumAddresses = lib.mapAttrs (_: v: v.mycelium.ipv6) ( myceliumAddresses = lib.mapAttrs (_: v: v.mycelium.ipv6) (
lib.filterAttrs (_: v: v ? "mycelium") systems lib.filterAttrs (_: v: v ? "mycelium") machines
); );
syncthingIds = lib.mapAttrs (_: v: { id = v.syncthingId; }) ( syncthingIds = lib.mapAttrs (_: v: { id = v.syncthingId; }) (
lib.filterAttrs (_: v: v ? "syncthingId") systems lib.filterAttrs (_: v: v ? "syncthingId") machines
); );
email = email =
@@ -102,7 +102,7 @@ in
}; };
}; };
systems = systems; machines = machines;
kieran = { kieran = {
github = "kmein"; github = "kmein";
@@ -120,9 +120,9 @@ in
"" ""
]; ];
sshKeys = [ sshKeys = [
systems.fatteh.sshKey machines.fatteh.sshKey
systems.manakish.sshKey machines.manakish.sshKey
systems.kabsa.sshKey machines.kabsa.sshKey
]; ];
}; };

View File

@@ -1,3 +1,6 @@
let
sshPort = 22022;
in
{ {
kabsa = { kabsa = {
sshKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDyTnGhFq0Q+vghNhrqNrAyY+CsN7nNz8bPfiwIwNpjk"; sshKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDyTnGhFq0Q+vghNhrqNrAyY+CsN7nNz8bPfiwIwNpjk";
@@ -7,6 +10,8 @@
ipv6 = "42:0:3c46:861f:a118:8e9a:82c9:3d"; ipv6 = "42:0:3c46:861f:a118:8e9a:82c9:3d";
}; };
mycelium.ipv6 = "432:e30:d5d8:9311:e34b:6587:96ee:3fcb"; mycelium.ipv6 = "432:e30:d5d8:9311:e34b:6587:96ee:3fcb";
inherit sshPort;
system = "x86_64-linux";
}; };
manakish = { manakish = {
sshKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOiQEc8rTr7C7xVLYV7tQ99BDDBLrJsy5hslxtCEatkB"; sshKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOiQEc8rTr7C7xVLYV7tQ99BDDBLrJsy5hslxtCEatkB";
@@ -16,6 +21,8 @@
ipv6 = "42:0:3c46:ac99:ae36:cb8:c551:ba27"; ipv6 = "42:0:3c46:ac99:ae36:cb8:c551:ba27";
}; };
mycelium.ipv6 = "512:d3bd:3cd9:fcc8:ae34:81fa:385f:8c21"; mycelium.ipv6 = "512:d3bd:3cd9:fcc8:ae34:81fa:385f:8c21";
inherit sshPort;
system = "x86_64-linux";
}; };
fatteh = { fatteh = {
sshKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIByreBjBEMJKjgpKLd5XZHIUUwIhNafVqN6OUOQpJa3y"; sshKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIByreBjBEMJKjgpKLd5XZHIUUwIhNafVqN6OUOQpJa3y";
@@ -25,6 +32,8 @@
ipv4 = "10.243.2.77"; ipv4 = "10.243.2.77";
}; };
mycelium.ipv6 = "463:a0d4:daa3:aa8d:a9b1:744a:46a5:7a80"; mycelium.ipv6 = "463:a0d4:daa3:aa8d:a9b1:744a:46a5:7a80";
inherit sshPort;
system = "x86_64-linux";
}; };
kibbeh = { kibbeh = {
syncthingId = "HLQSG3D-WSKLA6S-MEYQ3EU-GDBGABE-PY53RQ6-SWQAP2I-Z5MVBVX-MYPJXAM"; syncthingId = "HLQSG3D-WSKLA6S-MEYQ3EU-GDBGABE-PY53RQ6-SWQAP2I-Z5MVBVX-MYPJXAM";
@@ -36,6 +45,8 @@
ipv6 = "42:0:3c46:2c8b:a564:1213:9fb4:1bc4"; ipv6 = "42:0:3c46:2c8b:a564:1213:9fb4:1bc4";
}; };
mycelium.ipv6 = "5bf:d60e:bebf:5163:f495:8787:880c:6d41"; mycelium.ipv6 = "5bf:d60e:bebf:5163:f495:8787:880c:6d41";
inherit sshPort;
system = "aarch64-linux";
}; };
zaatar = { zaatar = {
retiolum = { retiolum = {
@@ -43,6 +54,8 @@
ipv6 = "42:0:3c46:156e:10b6:3bd6:6e82:b2cd"; ipv6 = "42:0:3c46:156e:10b6:3bd6:6e82:b2cd";
}; };
mycelium.ipv6 = "5c5:49e0:7793:f017:59e1:1715:9e0e:3fc8"; mycelium.ipv6 = "5c5:49e0:7793:f017:59e1:1715:9e0e:3fc8";
inherit sshPort;
system = "x86_64-linux";
}; };
makanek = { makanek = {
externalIp = "88.99.83.173"; externalIp = "88.99.83.173";
@@ -51,6 +64,8 @@
ipv6 = "42:0:3c46:f7a9:1f0a:1b2b:822a:6050"; ipv6 = "42:0:3c46:f7a9:1f0a:1b2b:822a:6050";
}; };
mycelium.ipv6 = "43f:ad4f:fa67:d9f7:8a56:713c:7418:164b"; mycelium.ipv6 = "43f:ad4f:fa67:d9f7:8a56:713c:7418:164b";
inherit sshPort;
system = "x86_64-linux";
}; };
officejet = { officejet = {
internalIp = "192.168.0.251"; internalIp = "192.168.0.251";
@@ -63,11 +78,15 @@
ipv4 = "10.243.2.78"; ipv4 = "10.243.2.78";
ipv6 = ""; ipv6 = "";
}; };
inherit sshPort;
system = "x86_64-linux";
}; };
tahina = { tahina = {
retiolum = { retiolum = {
ipv4 = "10.243.2.74"; ipv4 = "10.243.2.74";
ipv6 = "42:0:3c46:2923:1c90:872:edd6:306"; ipv6 = "42:0:3c46:2923:1c90:872:edd6:306";
}; };
inherit sshPort;
system = "x86_64-linux";
}; };
} }

View File

@@ -1,17 +1,18 @@
{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RecordWildCards #-}
import Control.Arrow ((&&&)) import Control.Arrow ((&&&))
import Control.Monad (forM_) import Control.Monad (forM_)
import Control.Parallel.Strategies (using, parList, rdeepseq) import Control.Parallel.Strategies (parList, rdeepseq, using)
import Data.Char (toLower) import Data.Char (toLower)
import Data.List (sortOn) import Data.List (sortOn)
import Options.Applicative import Options.Applicative
import Text.EditDistance (levenshteinDistance, defaultEditCosts) import Text.EditDistance (defaultEditCosts, levenshteinDistance)
data Options = Options data Options = Options
{ limit :: Int { limit :: Int,
, word :: String word :: String,
, dictionary :: FilePath dictionary :: FilePath
} }
optionsParser :: Parser Options optionsParser :: Parser Options

View File

@@ -12,6 +12,6 @@ rl.on("line", (line) => {
console.log( console.log(
Sanscript.t(line, "hk", "devanagari") Sanscript.t(line, "hk", "devanagari")
.replace(/\.\./g, "॥") .replace(/\.\./g, "॥")
.replace(/[,.]/g, "।") .replace(/[,.]/g, "।"),
); );
}); });

View File

@@ -4,150 +4,150 @@ import sys
# https://www.phon.ucl.ac.uk/home/sampa/ipasam-x.pdf TODO # https://www.phon.ucl.ac.uk/home/sampa/ipasam-x.pdf TODO
XSAMPA_TO_IPA = { XSAMPA_TO_IPA = {
"!": "\uA71C", "!": "\ua71c",
"!\\": "\u01C3", "!\\": "\u01c3",
"%": "\u02CC", "%": "\u02cc",
"&": "\u0276", "&": "\u0276",
"'": "\u02B2", "'": "\u02b2",
"-\\": "\u203F", "-\\": "\u203f",
"1": "\u0268", "1": "\u0268",
"2": "\u00f8", "2": "\u00f8",
"3": "\u025C", "3": "\u025c",
"3\\": "\u025E", "3\\": "\u025e",
"4": "\u027E", "4": "\u027e",
"5": "\u026b", "5": "\u026b",
"6": "\u0250", "6": "\u0250",
"7": "\u0264", "7": "\u0264",
"8": "\u0275", "8": "\u0275",
"9": "\u0153", "9": "\u0153",
":": "\u02D0", ":": "\u02d0",
":\\": "\u02D1", ":\\": "\u02d1",
"<B>": "\u02E9", "<B>": "\u02e9",
"<F>": "\u2198", "<F>": "\u2198",
"<H>": "\u02E6", "<H>": "\u02e6",
"<L>": "\u02E8", "<L>": "\u02e8",
"<M>": "\u02E7", "<M>": "\u02e7",
"<R>": "\u2197", "<R>": "\u2197",
"<T>": "\u02E5", "<T>": "\u02e5",
"<\\": "\u02A2", "<\\": "\u02a2",
"=": "\u0329", "=": "\u0329",
"=\\": "\u01C2", "=\\": "\u01c2",
">\\": "\u02A1", ">\\": "\u02a1",
"?": "\u0294", "?": "\u0294",
"?\\": "\u0295", "?\\": "\u0295",
"@": "\u0259", "@": "\u0259",
"@\\": "\u0258", "@\\": "\u0258",
"A": "\u0251", "A": "\u0251",
"B": "\u03B2", "B": "\u03b2",
"B\\": "\u0299", "B\\": "\u0299",
"C": "\u00E7", "C": "\u00e7",
"D": "\u00F0", "D": "\u00f0",
"E": "\u025B", "E": "\u025b",
"F": "\u0271", "F": "\u0271",
"G": "\u0263", "G": "\u0263",
"G\\": "\u0262", "G\\": "\u0262",
"G\\_<": "\u029B", "G\\_<": "\u029b",
"H": "\u0265", "H": "\u0265",
"H\\": "\u029C", "H\\": "\u029c",
"I": "\u026A", "I": "\u026a",
"J": "\u0272", "J": "\u0272",
"J\\": "\u025F", "J\\": "\u025f",
"J\\_<": "\u0284", "J\\_<": "\u0284",
"K": "\u026C", "K": "\u026c",
"K\\": "\u026E", "K\\": "\u026e",
"L": "\u028E", "L": "\u028e",
"L\\": "\u029F", "L\\": "\u029f",
"M": "\u026F", "M": "\u026f",
"M\\": "\u0270", "M\\": "\u0270",
"N": "\u014B", "N": "\u014b",
"N\\": "\u0274", "N\\": "\u0274",
"O": "\u0254", "O": "\u0254",
"O\\": "\u0298", "O\\": "\u0298",
"P": "\u028B", "P": "\u028b",
"Q": "\u0252", "Q": "\u0252",
"R": "\u0281", "R": "\u0281",
"R\\": "\u0280", "R\\": "\u0280",
"S": "\u0283", "S": "\u0283",
"T": "\u03B8", "T": "\u03b8",
"U": "\u028A", "U": "\u028a",
"V": "\u028C", "V": "\u028c",
"W": "\u028D", "W": "\u028d",
"X": "\u03C7", "X": "\u03c7",
"X\\": "\u0127", "X\\": "\u0127",
"Y": "\u028F", "Y": "\u028f",
"Z": "\u0292", "Z": "\u0292",
"^": "\uA71B", "^": "\ua71b",
"_": "\u0361", "_": "\u0361",
"_+": "\u031F", "_+": "\u031f",
"_-": "\u0320", "_-": "\u0320",
"_0": "\u0325", "_0": "\u0325",
"_=": "\u0329", "_=": "\u0329",
"_>": "\u02BC", "_>": "\u02bc",
"_?\\": "\u02E4", "_?\\": "\u02e4",
"_A": "\u0318", "_A": "\u0318",
"_B": "\u030F", "_B": "\u030f",
"_B_L": "\u1DC5", "_B_L": "\u1dc5",
"_F": "\u0302", "_F": "\u0302",
"_F_R": "\u1dc9", "_F_R": "\u1dc9",
"_G": "\u02E0", "_G": "\u02e0",
"_H": "\u0341", "_H": "\u0341",
"_H_T": "\u1DC4", "_H_T": "\u1dc4",
"_L": "\u0340", "_L": "\u0340",
"_M": "\u0304", "_M": "\u0304",
"_N": "\u033C", "_N": "\u033c",
"_O": "\u0339", "_O": "\u0339",
"_R": "\u030C", "_R": "\u030c",
"_R_F": "\u1dc8", "_R_F": "\u1dc8",
"_T": "\u030B", "_T": "\u030b",
"_X": "\u0306", "_X": "\u0306",
"_^": "\u032F", "_^": "\u032f",
"_a": "\u033A", "_a": "\u033a",
"_c": "\u031C", "_c": "\u031c",
"_d": "\u032A", "_d": "\u032a",
"_e": "\u0334", "_e": "\u0334",
"_h": "\u02B0", "_h": "\u02b0",
"_j": "\u02B2", "_j": "\u02b2",
"_k": "\u0330", "_k": "\u0330",
"_l": "\u02E1", "_l": "\u02e1",
"_m": "\u033B", "_m": "\u033b",
"_n": "\u207F", "_n": "\u207f",
"_o": "\u031E", "_o": "\u031e",
"_q": "\u0319", "_q": "\u0319",
"_r": "\u031D", "_r": "\u031d",
"_t": "\u0324", "_t": "\u0324",
"_v": "\u032C", "_v": "\u032c",
"_w": "\u02B7", "_w": "\u02b7",
"_x": "\u033D", "_x": "\u033d",
"_}": "\u031A", "_}": "\u031a",
"_~": "\u0303", "_~": "\u0303",
"`": "\u02DE", "`": "\u02de",
"b_<": "\u0253", "b_<": "\u0253",
"d_<": "\u0257", "d_<": "\u0257",
"d`": "\u0256", "d`": "\u0256",
"d`_<": "\u1D91", "d`_<": "\u1d91",
"g_<": "\u0260", "g_<": "\u0260",
"h\\": "\u0266", "h\\": "\u0266",
"j\\": "\u029D", "j\\": "\u029d",
"l\\": "\u027A", "l\\": "\u027a",
"l`": "\u026D", "l`": "\u026d",
"n`": "\u0273", "n`": "\u0273",
"p\\": "\u0278", "p\\": "\u0278",
"r\\": "\u0279", "r\\": "\u0279",
"r\\`": "\u027B", "r\\`": "\u027b",
"r` ": "\u027D", "r` ": "\u027d",
"s\\": "\u0255", "s\\": "\u0255",
"s`": "\u0282", "s`": "\u0282",
"t`": "\u0288", "t`": "\u0288",
"v\\": "\u028B", "v\\": "\u028b",
"x\\": "\u0267", "x\\": "\u0267",
"z\\": "\u0291", "z\\": "\u0291",
"z`": "\u0290", "z`": "\u0290",
"{": "\u00E6", "{": "\u00e6",
"|\\": "\u01C0", "|\\": "\u01c0",
"|\\|\\": "\u01C1", "|\\|\\": "\u01c1",
"}": "\u0289", "}": "\u0289",
"~": "\u0303", "~": "\u0303",
'"': "\u02C8", '"': "\u02c8",
'_"': "\u0308", '_"': "\u0308",
} }

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
@@ -78,7 +78,7 @@
startDate.title = isoString(start); startDate.title = isoString(start);
startDate.setAttribute("datetime", isoString(start)); startDate.setAttribute("datetime", isoString(start));
startDate.appendChild( startDate.appendChild(
document.createTextNode(start.toLocaleString()) document.createTextNode(start.toLocaleString()),
); );
const endDate = document.createElement("time"); const endDate = document.createElement("time");
@@ -86,7 +86,7 @@
endDate.title = isoString(end); endDate.title = isoString(end);
endDate.setAttribute("datetime", isoString(end)); endDate.setAttribute("datetime", isoString(end));
endDate.appendChild( endDate.appendChild(
document.createTextNode(end.toLocaleString()) document.createTextNode(end.toLocaleString()),
); );
li.appendChild(document.createTextNode(newsItem.text)); li.appendChild(document.createTextNode(newsItem.text));
@@ -110,7 +110,7 @@
from: isoString(new Date(formData.get("from"))), from: isoString(new Date(formData.get("from"))),
to: isoString(new Date(formData.get("to"))), to: isoString(new Date(formData.get("to"))),
text: formData.get("text"), text: formData.get("text"),
}) }),
); );
location.reload(); location.reload();
} }
@@ -119,7 +119,7 @@
const localIsoString = (date) => const localIsoString = (date) =>
`${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2( `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(
date.getDate() date.getDate(),
)}T${pad2(date.getHours())}:${pad2(date.getMinutes())}`; )}T${pad2(date.getHours())}:${pad2(date.getMinutes())}`;
function setDate() { function setDate() {

View File

@@ -3,14 +3,14 @@ local luasnip = require("luasnip")
if vim.g.snippet_directory then if vim.g.snippet_directory then
require("luasnip.loaders.from_vscode").lazy_load({ require("luasnip.loaders.from_vscode").lazy_load({
paths = { vim.g.snippet_directory } paths = { vim.g.snippet_directory },
}) })
end end
luasnip.config.set_config({ luasnip.config.set_config({
history = true, history = true,
updateevents = "TextChanged,TextChangedI", updateevents = "TextChanged,TextChangedI",
enable_autosnippets = true enable_autosnippets = true,
}) })
cmp.setup({ cmp.setup({
@@ -21,7 +21,7 @@ cmp.setup({
}, },
mapping = { mapping = {
-- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#super-tab-like-mapping -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#super-tab-like-mapping
['<Tab>'] = cmp.mapping(function(fallback) ["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then if cmp.visible() then
cmp.select_next_item() cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then elseif luasnip.expand_or_jumpable() then
@@ -29,7 +29,7 @@ cmp.setup({
else else
fallback() fallback()
end end
end, {"i", "s"}), end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback) ["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then if cmp.visible() then
cmp.select_prev_item() cmp.select_prev_item()
@@ -41,18 +41,18 @@ cmp.setup({
end, { "i", "s" }), end, { "i", "s" }),
}, },
sources = cmp.config.sources({ sources = cmp.config.sources({
{ name = 'nvim_lsp' }, { name = "nvim_lsp" },
{ name = 'luasnip' }, { name = "luasnip" },
}) }),
}) })
local capabilities = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities()) local capabilities = require("cmp_nvim_lsp").default_capabilities(vim.lsp.protocol.make_client_capabilities())
local opts = { noremap=true, silent=true } local opts = { noremap = true, silent = true }
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts) vim.keymap.set("n", "<space>e", vim.diagnostic.open_float, opts)
vim.keymap.set('n', '<space>dn', vim.diagnostic.goto_prev, opts) vim.keymap.set("n", "<space>dn", vim.diagnostic.goto_prev, opts)
vim.keymap.set('n', '<space>dp', vim.diagnostic.goto_next, opts) vim.keymap.set("n", "<space>dp", vim.diagnostic.goto_next, opts)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts) vim.keymap.set("n", "<space>q", vim.diagnostic.setloclist, opts)
-- Use an on_attach function to only map the following keys -- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer -- after the language server attaches to the current buffer
@@ -61,23 +61,25 @@ local on_attach = function(client, bufnr)
-- vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') -- vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
-- Mappings. -- Mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions -- See `:help vim.lsp.*` for documentation on any of the below functions
local bufopts = { noremap=true, silent=true, buffer=bufnr } local bufopts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) vim.keymap.set("n", "gD", vim.lsp.buf.declaration, bufopts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) vim.keymap.set("n", "gd", vim.lsp.buf.definition, bufopts)
vim.keymap.set('n', 'gt', vim.lsp.buf.type_definition, bufopts) vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, bufopts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts) vim.keymap.set("n", "K", vim.lsp.buf.hover, bufopts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) vim.keymap.set("n", "gi", vim.lsp.buf.implementation, bufopts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts) vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, bufopts)
vim.keymap.set('n', '<space>f', vim.lsp.buf.format, bufopts) vim.keymap.set("n", "<space>f", vim.lsp.buf.format, bufopts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts) vim.keymap.set("n", "<space>wa", vim.lsp.buf.add_workspace_folder, bufopts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts) vim.keymap.set("n", "<space>wr", vim.lsp.buf.remove_workspace_folder, bufopts)
vim.keymap.set('n', '<space>wl', function() vim.keymap.set("n", "<space>wl", function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders())) print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, bufopts) end, bufopts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts) vim.keymap.set("n", "<space>rn", vim.lsp.buf.rename, bufopts)
vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts) vim.keymap.set("n", "<space>ca", vim.lsp.buf.code_action, bufopts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) vim.keymap.set("n", "gr", vim.lsp.buf.references, bufopts)
vim.keymap.set('n', '<space>f', function() vim.lsp.buf.format { async = true } end, bufopts) vim.keymap.set("n", "<space>f", function()
vim.lsp.buf.format({ async = true })
end, bufopts)
end end
local lsp_flags = { local lsp_flags = {
@@ -97,17 +99,17 @@ local language_servers = {
lua_ls = { lua_ls = {
Lua = { Lua = {
runtime = { runtime = {
version = 'LuaJIT', version = "LuaJIT",
}, },
diagnostics = { diagnostics = {
globals = {'vim'}, globals = { "vim" },
}, },
workspace = { workspace = {
library = vim.api.nvim_get_runtime_file("", true) library = vim.api.nvim_get_runtime_file("", true),
}, },
telemetry = { telemetry = {
enable = false, enable = false,
} },
}, },
}, },
hls = {}, -- haskell-language-server hls = {}, -- haskell-language-server
@@ -115,7 +117,7 @@ local language_servers = {
jsonls = {}, -- vscode-langservers-extracted jsonls = {}, -- vscode-langservers-extracted
lemminx = {}, -- lemminx (for xml) lemminx = {}, -- lemminx (for xml)
nil_ls = { nil_ls = {
['nil'] = { ["nil"] = {
formatting = { formatting = {
command = { "nixfmt" }, command = { "nixfmt" },
}, },
@@ -135,23 +137,23 @@ local language_servers = {
args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" }, args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" },
executable = "latexmk", executable = "latexmk",
forwardSearchAfter = false, forwardSearchAfter = false,
onSave = false onSave = false,
}, },
chktex = { chktex = {
onEdit = false, onEdit = false,
onOpenAndSave = false onOpenAndSave = false,
}, },
diagnosticsDelay = 300, diagnosticsDelay = 300,
formatterLineLength = 80, formatterLineLength = 80,
forwardSearch = { forwardSearch = {
args = {} args = {},
}, },
latexFormatter = "latexindent", latexFormatter = "latexindent",
latexindent = { latexindent = {
modifyLineBreaks = false modifyLineBreaks = false,
} },
} },
} },
} }
for server, settings in pairs(language_servers) do for server, settings in pairs(language_servers) do
@@ -159,7 +161,7 @@ for server, settings in pairs(language_servers) do
on_attach = on_attach, on_attach = on_attach,
flags = lsp_flags, flags = lsp_flags,
settings = settings, settings = settings,
capabilities = capabilities capabilities = capabilities,
}) })
vim.lsp.enable(server) vim.lsp.enable(server)
end end

View File

@@ -55,5 +55,5 @@ in
writers.writeDashBin "vim-typewriter" '' writers.writeDashBin "vim-typewriter" ''
# tell the window manager to fullscreen the nvim window # tell the window manager to fullscreen the nvim window
${wmctrl}/bin/wmctrl -r :ACTIVE: -b add,fullscreen ${wmctrl}/bin/wmctrl -r :ACTIVE: -b add,fullscreen
${vim-typewriter}/bin/nvim "$@ ${vim-typewriter}/bin/nvim "$@"
'' ''

View File

@@ -1,7 +1,6 @@
{ {
pkgs, pkgs,
config, config,
inputs,
... ...
}: }:
let let

View File

@@ -49,10 +49,12 @@
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.lightdm.enable = true; services.xserver.displayManager.lightdm.enable = true;
services.xserver.desktopManager.pantheon.enable = true; services.desktopManager.pantheon.enable = true;
# services.displayManager.autoLogin.enable = true; # services.displayManager.autoLogin.enable = true;
# services.displayManager.autoLogin.user = config.users.users.me.name; # services.displayManager.autoLogin.user = config.users.users.me.name;
home-manager.users.me.home.stateVersion = "24.11";
age.secrets = { age.secrets = {
di-fm-key.file = ../../secrets/di-fm-key.age; di-fm-key.file = ../../secrets/di-fm-key.age;
}; };
@@ -68,13 +70,12 @@
firefox firefox
thunderbird thunderbird
alacritty alacritty
tor-browser-bundle-bin tor-browser
zathura zathura
okular kdePackages.okular
anki-bin anki-bin
libreoffice libreoffice
xournalpp xournalpp
jellyfin-media-player
mpv-tv mpv-tv
telegram-desktop telegram-desktop
(mpv-radio.override { di-fm-key-file = config.age.secrets.di-fm-key.path; }) (mpv-radio.override { di-fm-key-file = config.age.secrets.di-fm-key.path; })

View File

@@ -2,7 +2,6 @@
config, config,
pkgs, pkgs,
lib, lib,
inputs,
... ...
}: }:
let let
@@ -38,7 +37,7 @@ in
script = '' script = ''
set -efu set -efu
export MENSTRUATION_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/menstruation-token")" export MENSTRUATION_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/menstruation-token")"
${inputs.menstruation-telegram.defaultPackage.x86_64-linux}/bin/menstruation-telegram ${pkgs.menstruation-telegram}/bin/menstruation-telegram
''; '';
serviceConfig = { serviceConfig = {
Restart = "always"; Restart = "always";
@@ -57,7 +56,7 @@ in
serviceConfig = { serviceConfig = {
Restart = "always"; Restart = "always";
DynamicUser = true; DynamicUser = true;
ExecStart = "${inputs.menstruation-backend.defaultPackage.x86_64-linux}/bin/menstruation_server"; ExecStart = "${pkgs.menstruation-backend}/bin/menstruation_server";
}; };
}; };
} }

View File

@@ -180,9 +180,7 @@
"justifyMode": "auto", "justifyMode": "auto",
"orientation": "auto", "orientation": "auto",
"reduceOptions": { "reduceOptions": {
"calcs": [ "calcs": ["lastNotNull"],
"lastNotNull"
],
"fields": "", "fields": "",
"values": false "values": false
}, },
@@ -246,9 +244,7 @@
"justifyMode": "auto", "justifyMode": "auto",
"orientation": "auto", "orientation": "auto",
"reduceOptions": { "reduceOptions": {
"calcs": [ "calcs": ["lastNotNull"],
"lastNotNull"
],
"fields": "", "fields": "",
"values": false "values": false
}, },
@@ -429,9 +425,7 @@
"justifyMode": "auto", "justifyMode": "auto",
"orientation": "auto", "orientation": "auto",
"reduceOptions": { "reduceOptions": {
"calcs": [ "calcs": ["lastNotNull"],
"lastNotNull"
],
"fields": "", "fields": "",
"values": false "values": false
}, },
@@ -497,9 +491,7 @@
"justifyMode": "auto", "justifyMode": "auto",
"orientation": "auto", "orientation": "auto",
"reduceOptions": { "reduceOptions": {
"calcs": [ "calcs": ["lastNotNull"],
"lastNotNull"
],
"fields": "", "fields": "",
"values": false "values": false
}, },
@@ -562,9 +554,7 @@
"justifyMode": "auto", "justifyMode": "auto",
"orientation": "auto", "orientation": "auto",
"reduceOptions": { "reduceOptions": {
"calcs": [ "calcs": ["lastNotNull"],
"lastNotNull"
],
"fields": "", "fields": "",
"values": false "values": false
}, },

View File

@@ -1,18 +1,18 @@
{ {
pkgs, pkgs,
lib,
inputs,
... ...
}: let }:
let
port = 5703; port = 5703;
in { in
{
systemd.services.names = { systemd.services.names = {
wants = ["network-online.target"]; wants = [ "network-online.target" ];
wantedBy = ["multi-user.target"]; wantedBy = [ "multi-user.target" ];
description = "Better clone of geogen.stoepel.net"; description = "Better clone of geogen.stoepel.net";
serviceConfig = { serviceConfig = {
DynamicUser = true; DynamicUser = true;
ExecStart = "${inputs.scripts.packages.x86_64-linux.onomap}/bin/onomap-web"; ExecStart = "${pkgs.onomap}/bin/onomap-web";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "15s"; RestartSec = "15s";
}; };

View File

@@ -2,9 +2,11 @@
pkgs, pkgs,
config, config,
... ...
}: let }:
let
storageBoxMountPoint = "/mnt/storagebox"; storageBoxMountPoint = "/mnt/storagebox";
in { in
{
# https://docs.hetzner.com/de/robot/storage-box/access/access-samba-cifs/ # https://docs.hetzner.com/de/robot/storage-box/access/access-samba-cifs/
fileSystems.${storageBoxMountPoint} = { fileSystems.${storageBoxMountPoint} = {
device = "//u359050.your-storagebox.de/backup"; device = "//u359050.your-storagebox.de/backup";
@@ -23,8 +25,14 @@ in {
}; };
systemd.services.nextcloud-setup = { systemd.services.nextcloud-setup = {
wants = ["mnt-storagebox.mount" "postgresql.service"]; wants = [
after = ["mnt-storagebox.mount" "postgresql.service"]; "mnt-storagebox.mount"
"postgresql.service"
];
after = [
"mnt-storagebox.mount"
"postgresql.service"
];
}; };
age.secrets = { age.secrets = {
@@ -73,7 +81,6 @@ in {
# extraTrustedDomains = [ "toum.r" ]; # extraTrustedDomains = [ "toum.r" ];
}; };
settings = { settings = {
defaultapp = "files"; defaultapp = "files";
overwriteprotocol = "https"; overwriteprotocol = "https";
@@ -92,12 +99,12 @@ in {
services.postgresqlBackup = { services.postgresqlBackup = {
enable = true; enable = true;
databases = [config.services.nextcloud.config.dbname]; databases = [ config.services.nextcloud.config.dbname ];
}; };
services.postgresql = { services.postgresql = {
enable = true; enable = true;
ensureDatabases = [config.services.nextcloud.config.dbname]; ensureDatabases = [ config.services.nextcloud.config.dbname ];
ensureUsers = [ ensureUsers = [
{ {
name = "nextcloud"; name = "nextcloud";

View File

@@ -1,4 +1,5 @@
{config, ...}: { { config, ... }:
{
services.onlyoffice = { services.onlyoffice = {
enable = true; enable = true;
port = 8111; port = 8111;

View File

@@ -2,32 +2,35 @@
config, config,
pkgs, pkgs,
lib, lib,
inputs,
... ...
}: let }:
let
network = "retiolum"; network = "retiolum";
stateDirectory = "retiolum-map"; stateDirectory = "retiolum-map";
geo-ip-database = "${lib.head config.services.geoipupdate.settings.EditionIDs}.mmdb"; geo-ip-database = "${lib.head config.services.geoipupdate.settings.EditionIDs}.mmdb";
geo-ip-database-path = "${config.services.geoipupdate.settings.DatabaseDirectory}/${geo-ip-database}"; geo-ip-database-path = "${config.services.geoipupdate.settings.DatabaseDirectory}/${geo-ip-database}";
in
tinc-graph = inputs.tinc-graph.defaultPackage.x86_64-linux; {
in {
systemd.services.retiolum-index = { systemd.services.retiolum-index = {
description = "Retiolum indexing service"; description = "Retiolum indexing service";
wants = ["tinc.${network}.service"]; wants = [ "tinc.${network}.service" ];
script = '' script = ''
${tinc-graph}/bin/tinc-graph --geoip-file ${geo-ip-database-path} --network ${network} \ ${pkgs.tinc-graph}/bin/tinc-graph --geoip-file ${geo-ip-database-path} --network ${network} \
| ${pkgs.coreutils}/bin/tee network.json \ | ${pkgs.coreutils}/bin/tee network.json \
| ${tinc-graph}/bin/tinc-midpoint > midpoint.json | ${pkgs.tinc-graph}/bin/tinc-midpoint > midpoint.json
cp ${tinc-graph}/static/map.html map.html cp ${pkgs.tinc-graph}/static/map.html map.html
cp ${tinc-graph}/static/map.html index.html cp ${pkgs.tinc-graph}/static/map.html index.html
cp ${tinc-graph}/static/graph.html graph.html cp ${pkgs.tinc-graph}/static/graph.html graph.html
''; '';
startAt = "hourly"; startAt = "hourly";
path = [pkgs.coreutils pkgs.jq pkgs.tinc_pre]; path = [
pkgs.coreutils
pkgs.jq
pkgs.tinc_pre
];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
User = "root"; User = "root";
@@ -41,7 +44,7 @@ in {
settings = { settings = {
AccountID = 608777; AccountID = 608777;
LicenseKey._secret = config.age.secrets.maxmind-license-key.path; LicenseKey._secret = config.age.secrets.maxmind-license-key.path;
EditionIDs = ["GeoLite2-City"]; EditionIDs = [ "GeoLite2-City" ];
}; };
}; };
@@ -72,8 +75,8 @@ in {
}; };
systemd.services.geoip-share = { systemd.services.geoip-share = {
after = ["geoipupdate.service"]; after = [ "geoipupdate.service" ];
wantedBy = ["geoipupdate.service"]; wantedBy = [ "geoipupdate.service" ];
script = "${pkgs.curl}/bin/curl -fSs --data-binary @${geo-ip-database-path} http://c.r/${geo-ip-database} "; script = "${pkgs.curl}/bin/curl -fSs --data-binary @${geo-ip-database-path} http://c.r/${geo-ip-database} ";
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";

View File

@@ -10,22 +10,24 @@ in
home = scrabbleDirectory; home = scrabbleDirectory;
createHome = true; createHome = true;
}; };
users.extraGroups.scrabble = {}; users.extraGroups.scrabble = { };
systemd.services.scrabble = { systemd.services.scrabble = {
wantedBy = ["multi-user.target"]; wantedBy = [ "multi-user.target" ];
enable = true; enable = true;
preStart = "npm install @cdot/xanado"; preStart = "npm install @cdot/xanado";
path = [ pkgs.nodejs ]; path = [ pkgs.nodejs ];
script = '' script = ''
${scrabbleDirectory}/node_modules/.bin/xanado --config ${(pkgs.formats.json {}).generate "config.json" { ${scrabbleDirectory}/node_modules/.bin/xanado --config ${
port = port; (pkgs.formats.json { }).generate "config.json" {
host = "localhost"; port = port;
game_defaults = { host = "localhost";
edition = "Deutsch_Scrabble"; game_defaults = {
dictionary = "German"; edition = "Deutsch_Scrabble";
}; dictionary = "German";
}} };
}
}
''; '';
serviceConfig = { serviceConfig = {
User = "scrabble"; User = "scrabble";
@@ -34,7 +36,6 @@ in
}; };
}; };
services.nginx.virtualHosts."scrabble.kmein.de" = { services.nginx.virtualHosts."scrabble.kmein.de" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
@@ -43,10 +44,10 @@ in
systemd.services.scrabble-fix = { systemd.services.scrabble-fix = {
startAt = "hourly"; startAt = "hourly";
wantedBy = ["multi-user.target"]; wantedBy = [ "multi-user.target" ];
enable = false; enable = false;
script = '' script = ''
${pkgs.gnused}/bin/sed -i s/encadefrit/en/ sessions/*.json passwd.json" ${pkgs.gnused}/bin/sed -i s/encadefrit/en/ sessions/*.json passwd.json"
''; '';
serviceConfig = { serviceConfig = {
User = "scrabble"; User = "scrabble";

View File

@@ -3,10 +3,12 @@
lib, lib,
config, config,
... ...
}: let }:
let
domain = "feed.kmein.de"; domain = "feed.kmein.de";
port = 8181; port = 8181;
in { in
{
services.miniflux = { services.miniflux = {
enable = true; enable = true;
adminCredentialsFile = config.age.secrets.miniflux-credentials.path; adminCredentialsFile = config.age.secrets.miniflux-credentials.path;
@@ -23,7 +25,7 @@ in {
services.postgresqlBackup = { services.postgresqlBackup = {
enable = true; enable = true;
databases = ["miniflux"]; databases = [ "miniflux" ];
}; };
services.nginx.virtualHosts.${domain} = { services.nginx.virtualHosts.${domain} = {

View File

@@ -2,13 +2,15 @@
lib, lib,
pkgs, pkgs,
... ...
}: let }:
let
weechatHome = "/var/lib/weechat"; weechatHome = "/var/lib/weechat";
in { in
systemd.services.weechat = let {
tmux = pkgs.writers.writeDash "tmux" '' systemd.services.weechat =
exec ${pkgs.tmux}/bin/tmux -f ${ let
pkgs.writeText "tmux.conf" '' tmux = pkgs.writers.writeDash "tmux" ''
exec ${pkgs.tmux}/bin/tmux -f ${pkgs.writeText "tmux.conf" ''
set-option -g prefix ` set-option -g prefix `
unbind-key C-b unbind-key C-b
bind ` send-prefix bind ` send-prefix
@@ -21,174 +23,195 @@ in {
bind-key p switch-client -p bind-key p switch-client -p
bind-key n switch-client -n bind-key n switch-client -n
bind-key C-s switch-client -l bind-key C-s switch-client -l
'' ''} "$@"
} "$@" '';
''; weechat = pkgs.weechat-declarative.override {
weechat = pkgs.weechat-declarative.override { config = {
config = { scripts = [
scripts = [ pkgs.weechatScripts.weechat-autosort
pkgs.weechatScripts.weechat-autosort pkgs.weechatScripts.colorize_nicks
pkgs.weechatScripts.colorize_nicks pkgs.weechatScripts.hotlist2extern
pkgs.weechatScripts.hotlist2extern # pkgs.weechatScripts.weechat-matrix
# pkgs.weechatScripts.weechat-matrix ];
]; settings =
settings = let let
nick = "kmein"; nick = "kmein";
in { in
weechat = { {
look.mouse = true; weechat = {
look.prefix_align_max = 15; look.mouse = true;
color.chat_nick_colors = lib.lists.subtractLists (lib.range 52 69 ++ lib.range 231 248) (lib.range 31 254); look.prefix_align_max = 15;
}; color.chat_nick_colors = lib.lists.subtractLists (lib.range 52 69 ++ lib.range 231 248) (
irc = { lib.range 31 254
look = { );
server_buffer = "independent";
color_nicks_in_nicklist = true;
};
server_default = {
nicks = nick;
msg_part = "tschö mit ö";
msg_quit = "ciao kakao";
msg_kick = "warum machst du diese?";
realname = lib.head (lib.strings.split " " pkgs.lib.niveum.kieran.name);
};
server = {
hackint = {
autoconnect = true;
addresses = "irc.hackint.org/6697";
ipv6 = true;
tls = true;
autojoin = ["#eloop" "#krebs" "#the_playlist"];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.hackint_sasl}";
}; };
libera = { irc = {
autoconnect = true; look = {
addresses = "irc.libera.chat/6697"; server_buffer = "independent";
tls = true; color_nicks_in_nicklist = true;
autojoin = ["#haskell" "#fysi" "#binaergewitter" "#vim"]; };
sasl_mechanism = "plain"; server_default = {
sasl_username = nick; nicks = nick;
sasl_password = "\${sec.data.libera_sasl}"; msg_part = "tschö mit ö";
msg_quit = "ciao kakao";
msg_kick = "warum machst du diese?";
realname = lib.head (lib.strings.split " " pkgs.lib.niveum.kieran.name);
};
server = {
hackint = {
autoconnect = true;
addresses = "irc.hackint.org/6697";
ipv6 = true;
tls = true;
autojoin = [
"#eloop"
"#krebs"
"#the_playlist"
];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.hackint_sasl}";
};
libera = {
autoconnect = true;
addresses = "irc.libera.chat/6697";
tls = true;
autojoin = [
"#haskell"
"#fysi"
"#binaergewitter"
"#vim"
];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.libera_sasl}";
};
retiolum = {
autoconnect = true;
addresses = "irc.r";
tls = false;
autojoin = [
"#xxx"
"#brockman"
"#flix"
];
command = lib.concatStringsSep "\\;" [
"/oper admin aidsballs"
"/msg nickserv always-on true"
"/msg nickserv autoreplay-missed on"
"/msg nickserv auto-away"
];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.retiolum_sasl}";
};
brockman = {
autoconnect = true;
addresses = "brockman.news";
tls = false;
autojoin = [
"#cook"
"#kmeinung"
];
sasl_username = nick;
sasl_password = "\${sec.data.brockman_sasl}";
sasl_mechanism = "plain";
};
};
}; };
retiolum = { logger.level.irc.news = 0;
autoconnect = true; plugins.var.perl.hotlist2extern = {
addresses = "irc.r"; external_command_hotlist = "echo %X > ${weechatHome}/hotlist.txt";
tls = false; external_command_hotlist_empty = "echo -n %X > ${weechatHome}/hotlist.txt";
autojoin = ["#xxx" "#brockman" "#flix"]; lowest_priority = "2";
command = lib.concatStringsSep "\\;" [ use_title = "off";
"/oper admin aidsballs" delimiter = ",";
"/msg nickserv always-on true"
"/msg nickserv autoreplay-missed on"
"/msg nickserv auto-away"
];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.retiolum_sasl}";
}; };
brockman = { matrix.look.server_buffer = "merge_without_core";
matrix.server.nibbana = {
address = "nibbana.jp";
username = nick;
password = "\${sec.data.nibbana_account}";
autoconnect = true; autoconnect = true;
addresses = "brockman.news"; };
tls = false; alias.cmd.mod = "/quote omode $channel +o $nick";
autojoin = ["#cook" "#kmeinung"]; relay = {
sasl_username = nick; port.weechat = 9000;
sasl_password = "\${sec.data.brockman_sasl}"; network.password = "\${sec.data.relay_password}";
sasl_mechanism = "plain"; };
filters = {
zerocovid = {
buffer = "irc.news.*";
tags = "*";
regex = "[kc]orona|💉|🤒|😷|[kc]ovid|virus|lockdown|va[kc][sc]in|vaxx|mutante|mutation|impf|pandemi|κορ[ωο]ν[αο]ϊό|корона|expert|infe[ck]t|infizi|in[cz]iden[cz]|sars-cov|drosten|virolog|lauterbach|delta|omi[ck]ron|epidemi|booster|r-wert";
};
smart = {
buffer = "*";
tags = "irc_smart_filter";
regex = "*";
};
playlist_topic = {
buffer = "irc.*.#the_playlist";
tags = "irc_topic";
regex = "*";
};
brockman_notice = {
buffer = "irc.news.*";
tags = "irc_notice";
regex = "*";
};
bots = {
buffer = "irc.retiolum.*";
tags = [
"nick_gitlab"
"nick_prometheus"
];
regex = "*";
};
people = {
buffer = "irc.*.*";
tags = map (name: "nick_${name}") [ "mod_p[matrix-fli" ];
regex = "*";
};
}; };
}; };
}; extraCommands = ''
logger.level.irc.news = 0; /save
plugins.var.perl.hotlist2extern = { /connect -all
external_command_hotlist = "echo %X > ${weechatHome}/hotlist.txt"; '';
external_command_hotlist_empty = "echo -n %X > ${weechatHome}/hotlist.txt"; # /matrix connect nibbana
lowest_priority = "2";
use_title = "off";
delimiter = ",";
};
matrix.look.server_buffer = "merge_without_core";
matrix.server.nibbana = {
address = "nibbana.jp";
username = nick;
password = "\${sec.data.nibbana_account}";
autoconnect = true;
};
alias.cmd.mod = "/quote omode $channel +o $nick";
relay = {
port.weechat = 9000;
network.password = "\${sec.data.relay_password}";
};
filters = {
zerocovid = {
buffer = "irc.news.*";
tags = "*";
regex = "[kc]orona|💉|🤒|😷|[kc]ovid|virus|lockdown|va[kc][sc]in|vaxx|mutante|mutation|impf|pandemi|κορ[ωο]ν[αο]ϊό|корона|expert|infe[ck]t|infizi|in[cz]iden[cz]|sars-cov|drosten|virolog|lauterbach|delta|omi[ck]ron|epidemi|booster|r-wert";
};
smart = {
buffer = "*";
tags = "irc_smart_filter";
regex = "*";
};
playlist_topic = {
buffer = "irc.*.#the_playlist";
tags = "irc_topic";
regex = "*";
};
brockman_notice = {
buffer = "irc.news.*";
tags = "irc_notice";
regex = "*";
};
bots = {
buffer = "irc.retiolum.*";
tags = ["nick_gitlab" "nick_prometheus"];
regex = "*";
};
people = {
buffer = "irc.*.*";
tags = map (name: "nick_${name}") ["mod_p[matrix-fli"];
regex = "*";
};
};
}; };
extraCommands = '' };
/save in
/connect -all {
''; description = "Weechat bouncer";
# /matrix connect nibbana after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
restartIfChanged = true;
path = [ pkgs.alacritty.terminfo ];
environment.WEECHAT_HOME = weechatHome;
# preStart = "${pkgs.coreutils}/bin/rm $WEECHAT_HOME/*.conf";
script = "${tmux} -2 new-session -d -s IM ${weechat}/bin/weechat";
preStop = "${tmux} kill-session -t IM";
serviceConfig = {
User = "weechat";
Group = "weechat";
RemainAfterExit = true;
Type = "oneshot";
}; };
}; };
in {
description = "Weechat bouncer";
after = ["network.target"];
wantedBy = ["multi-user.target"];
restartIfChanged = true;
path = [pkgs.alacritty.terminfo];
environment.WEECHAT_HOME = weechatHome;
# preStart = "${pkgs.coreutils}/bin/rm $WEECHAT_HOME/*.conf";
script = "${tmux} -2 new-session -d -s IM ${weechat}/bin/weechat";
preStop = "${tmux} kill-session -t IM";
serviceConfig = {
User = "weechat";
Group = "weechat";
RemainAfterExit = true;
Type = "oneshot";
};
};
users.groups.weechat = {}; users.groups.weechat = { };
users.extraUsers.weechat = { users.extraUsers.weechat = {
useDefaultShell = true; useDefaultShell = true;
openssh.authorizedKeys.keys = openssh.authorizedKeys.keys = pkgs.lib.niveum.kieran.sshKeys ++ [
pkgs.lib.niveum.kieran.sshKeys "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC+KVDmYYH7mA8v81e9O3swXm3ZVYY9t4HP65ud61uXy weechat_android@kibbeh"
++ [ ];
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC+KVDmYYH7mA8v81e9O3swXm3ZVYY9t4HP65ud61uXy weechat_android@kibbeh"
];
createHome = true; createHome = true;
group = "weechat"; group = "weechat";
home = "/var/lib/weechat"; home = "/var/lib/weechat";
isSystemUser = true; isSystemUser = true;
packages = [pkgs.tmux]; packages = [ pkgs.tmux ];
}; };
age.secrets.weechat-sec = { age.secrets.weechat-sec = {

View File

@@ -1,209 +0,0 @@
{ lib, pkgs, config, unstablePackages, ... }:
let
weechatHome = "/var/lib/weechat";
weechat-declarative =
pkgs.callPackage ../../packages/weechat-declarative.nix {
inherit unstablePackages;
};
in {
systemd.services.weechat = let
tmux = pkgs.writers.writeDash "tmux" ''
exec ${pkgs.tmux}/bin/tmux -f ${
pkgs.writeText "tmux.conf" ''
set-option -g prefix `
unbind-key C-b
bind ` send-prefix
set-option -g status off
set-option -g default-terminal screen-256color
#use session instead of windows
bind-key c new-session
bind-key p switch-client -p
bind-key n switch-client -n
bind-key C-s switch-client -l
''
} "$@"
'';
weechat = weechat-declarative.override {
config = {
scripts = [
pkgs.weechatScripts.weechat-autosort
pkgs.weechatScripts.colorize_nicks
# pkgs.weechatScripts.weechat-matrix
(pkgs.callPackage ../../packages/weechatScripts/hotlist2extern.nix
{ })
];
settings = let nick = "kmein";
in {
weechat = {
look.mouse = true;
look.prefix_align_max = 15;
color.chat_nick_colors =
lib.lists.subtractLists (lib.range 52 69 ++ lib.range 231 248)
(lib.range 31 254);
};
irc = {
look = {
server_buffer = "independent";
color_nicks_in_nicklist = true;
};
server_default = {
nicks = nick;
msg_part = "tschö mit ö";
msg_quit = "ciao kakao";
msg_kick = "warum machst du diese?";
realname = lib.head (lib.strings.split " " pkgs.lib.niveum.kieran.name);
};
server = {
hackint = {
autoconnect = true;
addresses = "irc.hackint.org/6697";
ipv6 = true;
tls = true;
autojoin = [ "#eloop" "#krebs" "#the_playlist" ];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.hackint_sasl}";
};
libera = {
autoconnect = true;
addresses = "irc.libera.chat/6697";
tls = true;
autojoin = [ "#haskell" "#fysi" "#binaergewitter" "#vim" ];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.libera_sasl}";
};
retiolum = {
autoconnect = true;
addresses = "irc.r";
tls = false;
autojoin = [ "#xxx" "#brockman" "#flix" ];
command = lib.concatStringsSep "\\;" [
"/oper admin aidsballs"
"/msg nickserv always-on true"
"/msg nickserv autoreplay-missed on"
"/msg nickserv auto-away"
];
sasl_mechanism = "plain";
sasl_username = nick;
sasl_password = "\${sec.data.retiolum_sasl}";
};
brockman = {
autoconnect = true;
addresses = "brockman.news/6667";
tls = false;
autojoin = [ "#cook" "#kmeinung" ];
sasl_username = nick;
sasl_password = "\${sec.data.brockman_sasl}";
sasl_mechanism = "plain";
};
};
};
logger.level.irc.news = 0;
plugins.var.perl.hotlist2extern = {
external_command_hotlist = "echo %X > ${weechatHome}/hotlist.txt";
external_command_hotlist_empty =
"echo -n %X > ${weechatHome}/hotlist.txt";
lowest_priority = "2";
use_title = "off";
delimiter = ",";
};
matrix.look.server_buffer = "merge_without_core";
matrix.server.nibbana = {
address = "nibbana.jp";
username = nick;
password = "\${sec.data.nibbana_account}";
autoconnect = true;
};
alias.cmd.mod = "/quote omode $channel +o $nick";
relay = {
port.weechat = 9000;
network.password = "\${sec.data.relay_password}";
};
filters = {
zerocovid = {
buffer = "irc.news.*";
tags = "*";
regex =
"[kc]orona|💉|🤒|😷|[kc]ovid|virus|lockdown|va[kc][sc]in|vaxx|mutante|mutation|impf|pandemi|κορ[ωο]ν[αο]ϊό|корона|expert|infe[ck]t|infizi|in[cz]iden[cz]|sars-cov|drosten|virolog|lauterbach|delta|omi[ck]ron|epidemi|booster|r-wert";
};
smart = {
buffer = "*";
tags = "irc_smart_filter";
regex = "*";
};
playlist_topic = {
buffer = "irc.*.#the_playlist";
tags = "irc_topic";
regex = "*";
};
brockman_notice = {
buffer = "irc.news.*";
tags = "irc_notice";
regex = "*";
};
bots = {
buffer = "irc.retiolum.*";
tags = [ "nick_gitlab" "nick_prometheus" ];
regex = "*";
};
people = {
buffer = "irc.*.*";
tags = map (name: "nick_${name}") [ "mod_p[matrix-fli" ];
regex = "*";
};
};
};
extraCommands = ''
/save
/connect -all
'';
# /matrix connect nibbana
};
};
in {
description = "Weechat bouncer";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
restartIfChanged = true;
path = [ pkgs.alacritty.terminfo ];
environment.WEECHAT_HOME = weechatHome;
# preStart = "${pkgs.coreutils}/bin/rm $WEECHAT_HOME/*.conf";
script = "${tmux} -2 new-session -d -s IM ${weechat}/bin/weechat";
preStop = "${tmux} kill-session -t IM";
serviceConfig = {
User = "weechat";
Group = "weechat";
RemainAfterExit = true;
Type = "oneshot";
};
};
users.groups.weechat = { };
users.extraUsers.weechat = {
useDefaultShell = true;
openssh.authorizedKeys.keys = pkgs.lib.niveum.kieran.sshKeys ++ [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC+KVDmYYH7mA8v81e9O3swXm3ZVYY9t4HP65ud61uXy weechat_android@kibbeh"
];
createHome = true;
group = "weechat";
home = "/var/lib/weechat";
isSystemUser = true;
packages = [ pkgs.tmux ];
};
age.secrets.weechat-sec = {
file = ../../secrets/weechat-sec.conf.age;
path = "/var/lib/weechat/sec.conf";
owner = "weechat";
group = "weechat";
mode = "440";
};
niveum.passport.services = [{
title = "weechat bouncer";
description = "keeps me logged in on IRC.";
}];
}

View File

@@ -3,7 +3,8 @@
pkgs, pkgs,
lib, lib,
... ...
}: { }:
{
imports = [ imports = [
# Include the results of the hardware scan. # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
@@ -47,7 +48,7 @@
wlp3s0.useDHCP = true; wlp3s0.useDHCP = true;
wwp0s20u4i6.useDHCP = true; wwp0s20u4i6.useDHCP = true;
}; };
wireless.interfaces = ["wlp3s0"]; wireless.interfaces = [ "wlp3s0" ];
retiolum = pkgs.lib.niveum.retiolumAddresses.manakish; retiolum = pkgs.lib.niveum.retiolumAddresses.manakish;
hostName = "manakish"; hostName = "manakish";
}; };

View File

@@ -4,17 +4,25 @@
pkgs, pkgs,
modulesPath, modulesPath,
... ...
}: { }:
imports = [(modulesPath + "/installer/scan/not-detected.nix")]; {
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = { boot = {
initrd = { initrd = {
availableKernelModules = ["xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci"]; availableKernelModules = [
kernelModules = []; "xhci_pci"
"ehci_pci"
"ahci"
"usb_storage"
"sd_mod"
"sdhci_pci"
];
kernelModules = [ ];
luks.devices."crypted".device = "/dev/disk/by-uuid/493cb228-c292-4f71-9f38-dcb3e96dec47"; luks.devices."crypted".device = "/dev/disk/by-uuid/493cb228-c292-4f71-9f38-dcb3e96dec47";
}; };
kernelModules = ["kvm-intel"]; kernelModules = [ "kvm-intel" ];
extraModulePackages = []; extraModulePackages = [ ];
loader.grub = { loader.grub = {
enable = true; enable = true;
efiSupport = true; efiSupport = true;
@@ -36,11 +44,11 @@
"/mnt/sd-card" = { "/mnt/sd-card" = {
device = "/dev/disk/by-id/mmc-5E4S5_0x4c585d15-part1"; device = "/dev/disk/by-id/mmc-5E4S5_0x4c585d15-part1";
fsType = "ext4"; fsType = "ext4";
options = ["nofail"]; options = [ "nofail" ];
}; };
}; };
swapDevices = []; swapDevices = [ ];
zramSwap.enable = true; zramSwap.enable = true;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";

View File

@@ -1,13 +1,17 @@
{pkgs, ...}: { { pkgs, ... }:
services.xserver.displayManager.sessionCommands = let {
intern = "LVDS-1"; services.xserver.displayManager.sessionCommands =
extern = "HDMI-1"; let
pulseaudioCard = "alsa_card.pci-0000_00_1b.0"; intern = "LVDS-1";
# pulseaudioProfile = "output:hdmi-stereo-extra2+input:analog-stereo"; extern = "HDMI-1";
pulseaudioProfile = "alsa_output.pci-0000_00_1b.0.analog-stereo"; pulseaudioCard = "alsa_card.pci-0000_00_1b.0";
in # pulseaudioProfile = "output:hdmi-stereo-extra2+input:analog-stereo";
toString (pkgs.writers.writeDash "hdmi-on" '' pulseaudioProfile = "alsa_output.pci-0000_00_1b.0.analog-stereo";
${pkgs.xorg.xrandr}/bin/xrandr --output ${intern} --primary --auto --output ${extern} --above ${intern} --auto in
${pkgs.pulseaudio}/bin/pactl set-card-profile ${pulseaudioCard} ${pulseaudioProfile} toString (
''); pkgs.writers.writeDash "hdmi-on" ''
${pkgs.xorg.xrandr}/bin/xrandr --output ${intern} --primary --auto --output ${extern} --above ${intern} --auto
${pkgs.pulseaudio}/bin/pactl set-card-profile ${pulseaudioCard} ${pulseaudioProfile}
''
);
} }

View File

@@ -3,7 +3,8 @@
lib, lib,
pkgs, pkgs,
... ...
}: { }:
{
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../../configs/spacetime.nix ../../configs/spacetime.nix
@@ -28,26 +29,25 @@
}; };
}; };
services.xserver = { services.libinput.enable = true;
libinput.enable = true;
};
users.users.xenos = { users.users.xenos = {
name = "xenos"; name = "xenos";
password = "xenos"; password = "xenos";
isNormalUser = true; isNormalUser = true;
extraGroups = ["networkmanager"]; extraGroups = [ "networkmanager" ];
};
services.displayManager = {
autoLogin = {
enable = true;
user = "xenos";
};
}; };
services.xserver = { services.xserver = {
enable = true; enable = true;
desktopManager.lxqt.enable = true; desktopManager.lxqt.enable = true;
displayManager = {
autoLogin = {
enable = true;
user = "xenos";
};
};
}; };
environment.systemPackages = [ environment.systemPackages = [
@@ -70,7 +70,6 @@
hostName = "tabula"; hostName = "tabula";
}; };
hardware.pulseaudio.enable = true;
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
system.stateVersion = "21.11"; system.stateVersion = "21.11";

View File

@@ -4,7 +4,8 @@
pkgs, pkgs,
modulesPath, modulesPath,
... ...
}: { }:
{
imports = [ imports = [
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
@@ -12,15 +13,22 @@
boot = { boot = {
loader.grub = { loader.grub = {
enable = true; enable = true;
version = 2;
device = "/dev/sda"; device = "/dev/sda";
}; };
initrd = { initrd = {
availableKernelModules = ["pata_sis" "ohci_pci" "ehci_pci" "sata_sis" "usb_storage" "sd_mod" "sr_mod"]; availableKernelModules = [
kernelModules = []; "pata_sis"
"ohci_pci"
"ehci_pci"
"sata_sis"
"usb_storage"
"sd_mod"
"sr_mod"
];
kernelModules = [ ];
}; };
kernelModules = []; kernelModules = [ ];
extraModulePackages = []; extraModulePackages = [ ];
}; };
fileSystems."/" = { fileSystems."/" = {
@@ -29,7 +37,7 @@
}; };
swapDevices = [ swapDevices = [
{device = "/dev/disk/by-uuid/874256aa-5bae-44a4-8933-c65f8600fe78";} { device = "/dev/disk/by-uuid/874256aa-5bae-44a4-8933-c65f8600fe78"; }
]; ];
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;

View File

@@ -3,7 +3,8 @@
lib, lib,
pkgs, pkgs,
... ...
}: { }:
{
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../../configs/spacetime.nix ../../configs/spacetime.nix
@@ -30,30 +31,28 @@
console.keyMap = "de"; console.keyMap = "de";
i18n.defaultLocale = "de_DE.UTF-8"; i18n.defaultLocale = "de_DE.UTF-8";
services.xserver = { services.libinput.enable = true;
layout = "de"; services.xserver.xkb.layout = "de";
libinput.enable = true;
};
users.users.xenos = { users.users.xenos = {
name = "xenos"; name = "xenos";
password = "xenos"; password = "xenos";
isNormalUser = true; isNormalUser = true;
extraGroups = ["networkmanager"]; extraGroups = [ "networkmanager" ];
}; };
services.desktopManager.pantheon.enable = true;
services.displayManager.autoLogin = {
enable = true;
user = "xenos";
};
services.xserver = { services.xserver = {
enable = true; enable = true;
desktopManager.pantheon.enable = true;
displayManager = { displayManager = {
lightdm = { lightdm = {
enable = true; enable = true;
greeters.pantheon.enable = true; greeters.pantheon.enable = true;
}; };
autoLogin = {
enable = true;
user = "xenos";
};
}; };
}; };
boot.plymouth.enable = true; boot.plymouth.enable = true;

View File

@@ -4,7 +4,8 @@
pkgs, pkgs,
modulesPath, modulesPath,
... ...
}: { }:
{
imports = [ imports = [
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
@@ -18,12 +19,21 @@
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;
}; };
initrd = { initrd = {
availableKernelModules = ["xhci_pci" "ehci_pci" "ahci" "firewire_ohci" "usb_storage" "sd_mod" "sr_mod" "sdhci_pci"]; availableKernelModules = [
kernelModules = ["dm-snapshot"]; "xhci_pci"
"ehci_pci"
"ahci"
"firewire_ohci"
"usb_storage"
"sd_mod"
"sr_mod"
"sdhci_pci"
];
kernelModules = [ "dm-snapshot" ];
luks.devices.luksmap.device = "/dev/disk/by-uuid/b7d66981-8cb7-4aad-a595-ee6574b312cf"; luks.devices.luksmap.device = "/dev/disk/by-uuid/b7d66981-8cb7-4aad-a595-ee6574b312cf";
}; };
kernelModules = ["kvm-intel"]; kernelModules = [ "kvm-intel" ];
extraModulePackages = []; extraModulePackages = [ ];
}; };
fileSystems = { fileSystems = {

View File

@@ -3,15 +3,17 @@
pkgs, pkgs,
lib, lib,
... ...
}: let }:
let
dataDir = "/backup/restic"; dataDir = "/backup/restic";
in { in
{
services.restic.server = { services.restic.server = {
enable = true; enable = true;
appendOnly = true; appendOnly = true;
inherit dataDir; inherit dataDir;
prometheus = true; prometheus = true;
extraFlags = ["--no-auth"]; # auth is done via firewall extraFlags = [ "--no-auth" ]; # auth is done via firewall
listenAddress = toString pkgs.lib.niveum.restic.port; listenAddress = toString pkgs.lib.niveum.restic.port;
}; };
@@ -26,33 +28,35 @@ in {
fsType = "ext4"; fsType = "ext4";
}; };
networking.firewall = let networking.firewall =
dport = pkgs.lib.niveum.restic.port; let
protocol = "tcp"; dport = pkgs.lib.niveum.restic.port;
rules = [ protocol = "tcp";
(pkgs.lib.niveum.firewall.accept { rules = [
inherit dport protocol; (pkgs.lib.niveum.firewall.accept {
source = pkgs.lib.niveum.retiolumAddresses.kabsa.ipv4; inherit dport protocol;
}) source = pkgs.lib.niveum.retiolumAddresses.kabsa.ipv4;
(pkgs.lib.niveum.firewall.accept { })
inherit dport protocol; (pkgs.lib.niveum.firewall.accept {
source = pkgs.lib.niveum.retiolumAddresses.manakish.ipv4; inherit dport protocol;
}) source = pkgs.lib.niveum.retiolumAddresses.manakish.ipv4;
(pkgs.lib.niveum.firewall.accept { })
inherit dport protocol; (pkgs.lib.niveum.firewall.accept {
source = pkgs.lib.niveum.retiolumAddresses.makanek.ipv4; inherit dport protocol;
}) source = pkgs.lib.niveum.retiolumAddresses.makanek.ipv4;
(pkgs.lib.niveum.firewall.accept { })
inherit dport protocol; (pkgs.lib.niveum.firewall.accept {
source = pkgs.lib.niveum.retiolumAddresses.fatteh.ipv4; inherit dport protocol;
}) source = pkgs.lib.niveum.retiolumAddresses.fatteh.ipv4;
(pkgs.lib.niveum.firewall.accept { })
inherit dport protocol; (pkgs.lib.niveum.firewall.accept {
source = pkgs.lib.niveum.retiolumAddresses.ful.ipv4; inherit dport protocol;
}) source = pkgs.lib.niveum.retiolumAddresses.ful.ipv4;
]; })
in { ];
extraCommands = pkgs.lib.niveum.firewall.addRules rules; in
extraStopCommands = pkgs.lib.niveum.firewall.removeRules rules; {
}; extraCommands = pkgs.lib.niveum.firewall.addRules rules;
extraStopCommands = pkgs.lib.niveum.firewall.removeRules rules;
};
} }

View File

@@ -1,4 +1,5 @@
{pkgs, ...}: { { pkgs, ... }:
{
environment.systemPackages = [ environment.systemPackages = [
(pkgs.writers.writeDashBin "gaslight-stream" '' (pkgs.writers.writeDashBin "gaslight-stream" ''
${pkgs.ffmpeg}/bin/ffmpeg -r 14 -s 640x480 -f video4linux2 -i /dev/video0 -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac -f avi - ${pkgs.ffmpeg}/bin/ffmpeg -r 14 -s 640x480 -f video4linux2 -i /dev/video0 -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac -f avi -
@@ -16,8 +17,6 @@
]; ];
} }
/* /*
ssh machine gaslight-stream | mpv -
ssh machine gaslight-stream | mpv - ssh machine gaslight-say "blablabla"
ssh machine gaslight-say "blablabla"
*/ */

View File

@@ -4,14 +4,22 @@
pkgs, pkgs,
modulesPath, modulesPath,
... ...
}: { }:
imports = [(modulesPath + "/installer/scan/not-detected.nix")]; {
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = { boot = {
initrd.availableKernelModules = ["ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_acpi" "rtsx_usb_sdmmc"]; initrd.availableKernelModules = [
kernelModules = ["kvm-intel"]; "ahci"
extraModulePackages = []; "xhci_pci"
supportedFilesystems = ["ntfs"]; "usb_storage"
"sd_mod"
"sdhci_acpi"
"rtsx_usb_sdmmc"
];
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
supportedFilesystems = [ "ntfs" ];
loader = { loader = {
systemd-boot = { systemd-boot = {
enable = true; enable = true;
@@ -32,9 +40,9 @@
}; };
}; };
swapDevices = swapDevices = [
[ { device = "/dev/disk/by-uuid/7b2a3e4c-e53f-4c53-b599-b6d6cff49f1f"; } { device = "/dev/disk/by-uuid/7b2a3e4c-e53f-4c53-b599-b6d6cff49f1f"; }
]; ];
nix.settings.max-jobs = lib.mkDefault 4; nix.settings.max-jobs = lib.mkDefault 4;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";

View File

@@ -1,8 +1,15 @@
{config, pkgs, lib, ...}: let {
config,
pkgs,
lib,
...
}:
let
port = 8123; port = 8123;
volumeName = "home-assistant"; volumeName = "home-assistant";
in { in
networking.firewall.allowedTCPPorts = [port]; {
networking.firewall.allowedTCPPorts = [ port ];
services.nginx.virtualHosts."home.kmein.r" = { services.nginx.virtualHosts."home.kmein.r" = {
locations."/" = { locations."/" = {
@@ -59,7 +66,7 @@ in {
enable = true; enable = true;
autoPrune = { autoPrune = {
enable = true; enable = true;
flags = ["--all"]; flags = [ "--all" ];
}; };
}; };

View File

@@ -3,20 +3,25 @@
pkgs, pkgs,
lib, lib,
... ...
}: { }:
{
users.extraUsers.kiosk = { users.extraUsers.kiosk = {
isNormalUser = true; isNormalUser = true;
password = ""; password = "";
extraGroups = ["audio" "pipewire"]; extraGroups = [
"audio"
"pipewire"
];
}; };
# TODO https://github.com/cage-kiosk/cage/issues/138 # TODO https://github.com/cage-kiosk/cage/issues/138
services.cage = { services.cage = {
enable = true; enable = true;
user = config.users.extraUsers.kiosk.name; user = config.users.extraUsers.kiosk.name;
extraArguments = ["-s"]; # allow vt switching extraArguments = [ "-s" ]; # allow vt switching
program = let program =
startUrls = []; let
in startUrls = [ ];
in
pkgs.writers.writeDash "kiosk-browser" '' pkgs.writers.writeDash "kiosk-browser" ''
while true; do while true; do
${pkgs.brave}/bin/brave \ ${pkgs.brave}/bin/brave \

View File

@@ -3,21 +3,25 @@
pkgs, pkgs,
lib, lib,
... ...
}: let }:
moodle-dl-package = pkgs.moodle-dl.overrideAttrs (old: let
moodle-dl-package = pkgs.moodle-dl.overrideAttrs (
old:
old old
// { // {
# patches = [../../packages/moodle-dl/telegram-format.patch]; TODO? # patches = [../../packages/moodle-dl/telegram-format.patch]; TODO?
}); }
in { );
in
{
age.secrets = { age.secrets = {
/* /*
moodle-dl-tokens = { moodle-dl-tokens = {
file = ../../secrets/zaatar-moodle-dl-tokens.json.age; file = ../../secrets/zaatar-moodle-dl-tokens.json.age;
owner = "moodle-dl"; owner = "moodle-dl";
group = "moodle-dl"; group = "moodle-dl";
mode = "400"; mode = "400";
}; };
*/ */
moodle-dl-basicAuth = { moodle-dl-basicAuth = {
file = ../../secrets/zaatar-moodle-dl-basicAuth.age; file = ../../secrets/zaatar-moodle-dl-basicAuth.age;
@@ -120,10 +124,10 @@ in {
fileSystems."/export/moodle" = { fileSystems."/export/moodle" = {
device = config.services.moodle-dl.directory; device = config.services.moodle-dl.directory;
options = ["bind"]; options = [ "bind" ];
}; };
networking.firewall.allowedTCPPorts = [2049]; networking.firewall.allowedTCPPorts = [ 2049 ];
services.nginx.enable = true; services.nginx.enable = true;
@@ -140,11 +144,16 @@ in {
services.nfs.server = { services.nfs.server = {
enable = true; enable = true;
exports = let exports =
machines = with pkgs.lib.niveum.retiolumAddresses; [kabsa manakish]; let
in '' machines = with pkgs.lib.niveum.retiolumAddresses; [
/export ${lib.concatMapStringsSep " " (machine: "${machine.ipv4}(fsid=0)") machines} kabsa
/export/moodle ${lib.concatMapStringsSep " " (machine: "${machine.ipv4}(insecure,rw)") machines} manakish
''; ];
in
''
/export ${lib.concatMapStringsSep " " (machine: "${machine.ipv4}(fsid=0)") machines}
/export/moodle ${lib.concatMapStringsSep " " (machine: "${machine.ipv4}(insecure,rw)") machines}
'';
}; };
} }