Compare commits

..

2 Commits

Author SHA1 Message Date
fab83a3034 kartei/mic92: update ryan's key 2023-07-01 17:38:45 +02:00
lassulus
b76bd892a0 reaktor2: use new bing api 2023-06-11 15:00:02 +00:00
237 changed files with 2843 additions and 3000 deletions

17
flake.lock generated
View File

@ -1,21 +1,5 @@
{
"nodes": {
"nix-writers": {
"flake": false,
"locked": {
"lastModified": 1677612737,
"narHash": "sha256-UaCKZ4PbMZU6UZH7XNFcjRtd5jheswl66rjZDBfQgp8=",
"ref": "refs/heads/master",
"rev": "66a1f6833464bbb121b6d94247ad769f277351f8",
"revCount": 39,
"type": "git",
"url": "https://cgit.krebsco.de/nix-writers"
},
"original": {
"type": "git",
"url": "https://cgit.krebsco.de/nix-writers"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1686135559,
@ -34,7 +18,6 @@
},
"root": {
"inputs": {
"nix-writers": "nix-writers",
"nixpkgs": "nixpkgs"
}
}

View File

@ -1,41 +0,0 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-writers = {
url = "git+https://cgit.krebsco.de/nix-writers";
flake = false;
};
# disko.url = "github:nix-community/disko";
# disko.inputs.nixpkgs.follows = "nixpkgs";
};
description = "stockholm";
outputs = { self, nixpkgs, nix-writers }: {
nixosConfigurations.hotdog = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs.stockholm = self;
specialArgs.nix-writers = nix-writers;
specialArgs.secrets = toString ./krebs/0tests/data/secrets;
modules = [
./krebs/1systems/hotdog/config.nix
];
};
nixosModules =
let
inherit (nixpkgs) lib;
in builtins.listToAttrs
(map
(name: {name = lib.removeSuffix ".nix" name; value = import (./krebs/3modules + "/${name}");})
(lib.filter
(name: name != "default.nix" && !lib.hasPrefix "." name)
(lib.attrNames (builtins.readDir ./krebs/3modules))));
kartei = {
hosts = self.nixosConfigurations.hotdog.config.krebs.hosts;
users = self.nixosConfigurations.hotdog.config.krebs.users;
};
lib = import (self.outPath + "/lib/pure.nix") { lib = nixpkgs.lib; };
};
}

View File

@ -1,13 +1,12 @@
{ config, lib, ... }: let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
external = true;
monitoring = false;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
});
in {
users = {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
{ config, ... }: let
lib = import ../../lib;
in {
users.dave = {
mail = "hsngrmpf@gmail.com";
@ -8,7 +8,7 @@ in {
owner = config.krebs.users.dave;
nets.retiolum = {
aliases = [ "dave.r" ];
ip6.addr = (slib.krebs.genipv6 "retiolum" "dave" { hostName = "dave"; }).address;
ip6.addr = (lib.krebs.genipv6 "retiolum" "dave" { hostName = "dave"; }).address;
ip4.addr = "10.243.0.6";
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----

View File

@ -1,7 +1,6 @@
{ config, lib, ... }:
with import ../../lib;
{ config, ... }:
let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
external = true;
@ -9,11 +8,11 @@ let
owner = config.krebs.users.dbalan;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
};
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
};
});
in

View File

@ -9,7 +9,7 @@ in {
(name: _type: let
path = ./. + "/${name}";
in {
krebs = import path { inherit config lib; };
krebs = import path { inherit config; };
})
(removeTemplate
(lib.filterAttrs

View File

@ -1,6 +1,5 @@
{ config, lib, ... }: let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: flip recursiveUpdate host ({
owner = config.krebs.users.feliks;
ci = false;
@ -8,10 +7,10 @@
monitoring = false;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill.ip6.addr =
(slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
(krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
});
in {
users.feliks = {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
{ config, ... }: let
lib = import ../../lib;
in {
users.jan = {
@ -39,7 +39,6 @@ in {
nets = {
retiolum = {
ip4.addr = "10.243.143.11";
ip6.addr = (slib.krebs.genipv6 "retiolum" "jan" { hostName = "petrosilia"; }).address;
aliases = [
"petrosilia.r"
];
@ -68,7 +67,7 @@ in {
nets.retiolum = {
aliases = [ "grill.r" ];
ip4.addr = "10.243.217.217";
ip6.addr = (slib.krebs.genipv6 "retiolum" "jan" { hostName = "grill"; }).address;
ip6.addr = (lib.krebs.genipv6 "retiolum" "jan" { hostName = "grill"; }).address;
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAs4P6CfRcwFGCqkfv1tyTbbk2eHh08kEqxPNQ655sMKWxMhgRnRII

View File

@ -1,12 +1,12 @@
{ config, lib, ... }: let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = true;
owner = config.krebs.users.jeschli;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "jeschli" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "jeschli" { inherit hostName; }).address;
});
in {

View File

@ -1,7 +1,6 @@
{ config, lib, ... }:
with import ../../lib;
{ config, ... }:
let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
maybeEmpty = attrset: key: if (attrset?key) then attrset.${key} else [];
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
@ -10,11 +9,11 @@ let
owner = config.krebs.users.kmein;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
};
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
};
});
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");

View File

@ -1,12 +1,11 @@
{ config, lib, ... }: let
inherit (lib) flip genAttrs mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: flip recursiveUpdate host ({
owner = config.krebs.users.krebs;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "krebs" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "krebs" { inherit hostName; }).address;
});
testHosts = genAttrs [
@ -67,6 +66,7 @@ in {
tinc.pubkey_ed25519 = "D5TYSZW9OAkdnvQ/NL98UgheRC2Zg4SMNZ8M4/KwdeL";
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKRpjW68lSlTL8jBQcXKOTdGa+olQw5ghaU5df2yAE64";
};
hotdog = {
@ -100,6 +100,7 @@ in {
tinc.pubkey_ed25519 = "ugy/sGReVro3YzjDuroV/5hdeBdqD18no9dMhTy9DYL";
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxFkBln23wUxt4RhIHE3GvdKeBpJbjn++6maupHqUHp";
};
news = {
@ -132,6 +133,7 @@ in {
'';
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHl5cDF9QheXyMlNYIX17ILbgd94K50fZy7w0fDLvZlo ";
};
onebutton = {
@ -159,6 +161,7 @@ in {
'';
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAcZg+iLaPZ0SpLM+nANxIjZC/RIsansjyutK0+gPhIe ";
};
ponte = {
@ -205,6 +208,7 @@ in {
};
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEw9fo8Qtb/DTLacdrJP7Ti7c4UXTm6wUUX+iRFweEo ";
};
puyak = {
@ -230,6 +234,7 @@ in {
'';
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPpVwKv9mQGfcn5oFwuitq+b6Dz4jBG9sGhVoCYFw5RY";
syncthing.id = "DK5CEE2-PNUXYCE-Q42H2HP-623GART-B7KS4VK-HU2RBGQ-EK6QPUP-HUL3PAR";
};
@ -254,6 +259,7 @@ in {
'';
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOu6EVN3928qWiWszqBUzOjeQJRvFozTBl4xAhBP/Ymc";
};
wolf = {
@ -290,6 +296,7 @@ in {
'';
};
};
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKYMXMWZIK0jjnZDM9INiYAKcwjXs2241vew54K8veCR";
};
} // testHosts);

View File

@ -1,8 +1,8 @@
{ config, lib, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
r6 = ip: (slib.krebs.genipv6 "retiolum" "lass" ip).address;
w6 = ip: (slib.krebs.genipv6 "wiregrill" "lass" ip).address;
r6 = ip: (krebs.genipv6 "retiolum" "lass" ip).address;
w6 = ip: (krebs.genipv6 "wiregrill" "lass" ip).address;
hostFiles =
builtins.map (lib.removeSuffix ".nix") (
builtins.filter
@ -14,17 +14,14 @@ in {
dns.providers = {
"lassul.us" = "zones";
};
hosts = lib.mapAttrs (_: lib.recursiveUpdate {
hosts = mapAttrs (_: recursiveUpdate {
owner = config.krebs.users.lass;
consul = true;
ci = true;
monitoring = true;
ssh.privkey.path = <secrets/ssh.id_ed25519>;
}) (
lib.genAttrs hostFiles (host: import (./. + "/${host}.nix") {
inherit config lib r6 w6;
inherit (slib) krebs;
})
lib.genAttrs hostFiles (host: import (./. + "/${host}.nix") { inherit config krebs lib r6 w6; })
);
users = rec {
lass = lass-yubikey;

View File

@ -2,10 +2,8 @@
# tinc generate-keys
# ssh-keygen -f ssh.id_ed25519 -t ed25519 -C host
{ config, lib, ... }: let
inherit (builtins) foldl' mapAttrs pathExists readFile;
inherit (lib) optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: foldl' recursiveUpdate {} [
{
@ -21,7 +19,7 @@
"${hostName}.r"
];
ip6.addr =
(slib.krebs.genipv6 "retiolum" "makefu" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "makefu" { inherit hostName; }).address;
};
})
# Retiolum ed25519 keys
@ -39,7 +37,7 @@
"${hostName}.w"
];
ip6.addr =
(slib.krebs.genipv6 "wiregrill" "makefu" { inherit hostName; }).address;
(krebs.genipv6 "wiregrill" "makefu" { inherit hostName; }).address;
wireguard.pubkey = readFile pubkey-path;
};
})
@ -56,7 +54,7 @@
];
pub-for = name: builtins.readFile (./ssh + "/${name}.pub");
w6 = ip: (slib.krebs.genipv6 "wiregrill" "makefu" ip).address;
w6 = ip: (krebs.genipv6 "wiregrill" "makefu" ip).address;
in {
hosts = mapAttrs hostDefaults {
cake = rec {
@ -106,8 +104,7 @@ in {
nets = {
retiolum.ip4.addr = "10.243.0.91";
wiregrill = {
ip4.addr = "10.243.245.6";
aliases = [ "x.w" ];
# defaults
};
};
@ -123,12 +120,6 @@ in {
ci = true;
syncthing.id = "Y5OTK3S-JOJLAUU-KTBXKUW-M7S5UEQ-MMQPUK2-7CXO5V6-NOUDLKP-PRGAFAK";
nets = {
wiregrill = {
aliases = ["omo.w" "hass.omo.w" "jelly.omo.w" "jelly.makefu.w" ];
ip6.addr = (slib.krebs.genipv6 "wiregrill" "makefu" { hostName = "omo"; }).address;
ip4.addr = "10.244.245.5";
};
retiolum = {
ip4.addr = "10.243.0.89";
aliases = [
@ -158,7 +149,7 @@ in {
# pixel3a
telex.nets.wiregrill = {
aliases = ["telex.w"];
ip6.addr = (slib.krebs.genipv6 "wiregrill" "makefu" { hostName = "telex"; }).address;
ip6.addr = (krebs.genipv6 "wiregrill" "makefu" { hostName = "telex"; }).address;
ip4.addr = "10.244.245.4";
};
@ -248,7 +239,6 @@ in {
play.work.euer IN A ${nets.internet.ip4.addr}
ul.work.euer IN A ${nets.internet.ip4.addr}
music.euer IN A ${nets.internet.ip4.addr}
ntfy.euer IN A ${nets.internet.ip4.addr}
'';
};
nets = rec {
@ -265,7 +255,7 @@ in {
ip6.addr = w6 "1";
wireguard.port = 51821;
wireguard.subnets = [
(slib.krebs.genipv6 "wiregrill" "makefu" 0).subnetCIDR
(krebs.genipv6 "wiregrill" "makefu" 0).subnetCIDR
"10.244.245.0/24" # required for routing directly to gum via rockit
];
};

View File

@ -1 +1 @@
lKMWnuEVjcSoSEUWrj+51pwDQrQj2TqloL3aBKVWBbO
Ed25519PublicKey = lKMWnuEVjcSoSEUWrj+51pwDQrQj2TqloL3aBKVWBbO

View File

@ -1 +0,0 @@
JmcpzkwgKymVecZqaV0ODQactoVwGGlEHcfYIOCkx3A=

View File

@ -1,13 +1,12 @@
{ config, lib, ... }: let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
external = true;
monitoring = false;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
});
in {
hosts = mapAttrs hostDefaults {

View File

@ -1,6 +1,5 @@
{ config, lib, ... }: let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
with import ../../lib;
{ config, ... }: let
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
@ -8,10 +7,10 @@
monitoring = false;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill.ip6.addr =
(slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
(krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
});
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");
tinc-for = name: builtins.readFile (./tinc + "/${name}.pub");

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
{ config, ... }: let
lib = import ../../lib;
in {
users.oxzi = {
mail = "post@0x21.biz";
@ -13,7 +13,7 @@ in {
"gosh.r"
];
ip4.addr = "10.243.32.1";
ip6.addr = (slib.krebs.genipv6 "retiolum" "oxzi" { hostName = "ancha"; }).address;
ip6.addr = (lib.krebs.genipv6 "retiolum" "oxzi" { hostName = "ancha"; }).address;
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEA5RSP7nWZ1c04kvQBxoHqcdRKpJuRDzD3f0Nl2KhS7QsAqHJGdK7T
@ -39,7 +39,7 @@ in {
"marohu.oxzi.r"
];
ip4.addr = "10.243.32.2";
ip6.addr = (slib.krebs.genipv6 "retiolum" "oxzi" { hostName = "marohu"; }).address;
ip6.addr = (lib.krebs.genipv6 "retiolum" "oxzi" { hostName = "marohu"; }).address;
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAxHLkvuH9JMXay/fEmoWTEqLHg9A50EzkxPVBn4nyezgp5vxsUqJz

View File

@ -1,7 +1,6 @@
{ config, lib, ... }:
with import ../../lib;
{ config, ... }:
let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
@ -9,10 +8,10 @@ let
monitoring = false;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill.ip6.addr =
(slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
(krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
});
in

View File

@ -1,8 +1,6 @@
{ config, lib, ... }:
with import ../../lib;
{ config, ... }:
let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
external = true;
@ -10,11 +8,11 @@ let
owner = config.krebs.users.rtunreal;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
};
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
};
});
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");

View File

@ -1,12 +1,13 @@
{ config, lib, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
{ config, ... }: let
lib = import ../../lib;
hostDefaults = hostName: host: lib.flip lib.recursiveUpdate host ({
ci = false;
external = true;
monitoring = false;
} // lib.optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
(lib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
});
in {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
{ config, ... }: let
lib = import ../../lib;
in {
users.DUMMYUSER = {
mail = "DUMMYUSER@example.ork";
@ -8,7 +8,7 @@ in {
owner = config.krebs.users.DUMMYUSER;
nets.retiolum = {
aliases = [ "DUMMYHOST.DUMMYUSER.r" ];
ip6.addr = (slib.krebs.genipv6 "retiolum" "DUMMYUSER" { hostName = "DUMMYHOST"; }).address;
ip6.addr = (lib.krebs.genipv6 "retiolum" "DUMMYUSER" { hostName = "DUMMYHOST"; }).address;
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
DUMMYTINCPUBKEYRSA

View File

@ -1,11 +1,5 @@
{ config, lib, ... }@attrs: let
inherit (builtins)
getAttr head mapAttrs match pathExists readDir readFile typeOf;
inherit (lib)
const hasAttrByPath mapAttrs' mkDefault mkIf optionalAttrs removeSuffix
toList;
slib = import ../../lib/pure.nix { inherit lib; };
in {
with import ../../lib;
{ config, ... }: {
dns.providers = {
"viljetic.de" = "regfish";
};
@ -14,10 +8,10 @@ in {
(hostName: hostFile: let
hostSource = import hostFile;
hostConfig = getAttr (typeOf hostSource) {
lambda = hostSource attrs;
lambda = hostSource { inherit config lib; };
set = hostSource;
};
in slib.evalSubmodule slib.types.host [
in evalSubmodule types.host [
hostConfig
{
name = hostName;
@ -26,7 +20,7 @@ in {
(optionalAttrs (hasAttrByPath ["nets" "retiolum"] hostConfig) {
nets.retiolum = {
ip6.addr =
(slib.krebs.genipv6 "retiolum" "tv" { inherit hostName; }).address;
(krebs.genipv6 "retiolum" "tv" { inherit hostName; }).address;
};
})
(let
@ -37,14 +31,14 @@ in {
"${hostName}.w"
];
ip6.addr =
(slib.krebs.genipv6 "wiregrill" "tv" { inherit hostName; }).address;
(krebs.genipv6 "wiregrill" "tv" { inherit hostName; }).address;
wireguard.pubkey = readFile pubkey-path;
};
})
(host: mkIf (host.config.ssh.pubkey != null) {
ssh.privkey = mapAttrs (const mkDefault) {
path = config.krebs.secret.file "ssh.id_${host.config.ssh.privkey.type}";
type = head (toList (builtins.match "ssh-([^ ]+) .*" host.config.ssh.pubkey));
type = head (toList (match "ssh-([^ ]+) .*" host.config.ssh.pubkey));
};
})
])

View File

@ -1,6 +1,4 @@
{ config, lib, ... }: let
slib = import ../../../lib/pure.nix { inherit lib; };
in {
{ config, lib, ... }: {
extraZones = {
"krebsco.de" = ''
ni 60 IN A ${config.krebs.hosts.ni.nets.internet.ip4.addr}
@ -62,7 +60,7 @@ in {
via = config.krebs.hosts.ni.nets.internet;
ip4.addr = "10.244.3.1";
wireguard.subnets = [
(slib.krebs.genipv6 "wiregrill" "tv" 0).subnetCIDR
(lib.krebs.genipv6 "wiregrill" "tv" 0).subnetCIDR
];
};
};

View File

@ -1,7 +1,6 @@
{ config, lib, ... }:
with import ../../lib;
{ config, ... }:
let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
maybeEmpty = attrset: key: if (attrset?key) then attrset.${key} else [];
hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false;
@ -10,11 +9,11 @@ let
owner = config.krebs.users.xkey;
} // optionalAttrs (host.nets?retiolum) {
nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
};
} // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
};
});
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");

View File

@ -1,6 +1,6 @@
{ config, lib, ... }:
{ config, ... }:
let
slib = import ../../lib/pure.nix { inherit lib; };
lib = import ../../lib;
in
{
users.ynnel = {
@ -10,7 +10,7 @@ in
owner = config.krebs.users.ynnel;
nets.retiolum = {
aliases = [ "mokemoke.ynnel.r" ];
ip6.addr = (slib.krebs.genipv6 "retiolum" "ynnel" { hostName = "mokemoke"; }).address;
ip6.addr = (lib.krebs.genipv6 "retiolum" "ynnel" { hostName = "mokemoke"; }).address;
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEA7rS560SZEPcSekW30dRF6ZTHOnb8WvuVgt3BFLRWhTgV5DqLqFa8

View File

@ -9,15 +9,15 @@ in
{
imports = [
./hw.nix
../../../krebs
../../../krebs/2configs
<stockholm/krebs>
<stockholm/krebs/2configs>
#../../../krebs/2configs/binary-cache/nixos.nix
#../../../krebs/2configs/binary-cache/prism.nix
#<stockholm/krebs/2configs/binary-cache/nixos.nix>
#<stockholm/krebs/2configs/binary-cache/prism.nix>
../../../krebs/2configs/shack/ssh-keys.nix
../../../krebs/2configs/save-diskspace.nix
../../../krebs/2configs/shack/prometheus/node.nix
<stockholm/krebs/2configs/shack/ssh-keys.nix>
<stockholm/krebs/2configs/save-diskspace.nix>
<stockholm/krebs/2configs/shack/prometheus/node.nix>
];
# use your own binary cache, fallback use cache.nixos.org (which is used by

View File

@ -5,16 +5,16 @@ in
{
imports = [
./hardware-configuration.nix
../../../krebs
../../../krebs/2configs
# ../../../krebs/2configs/secret-passwords.nix
<stockholm/krebs>
<stockholm/krebs/2configs>
# <stockholm/krebs/2configs/secret-passwords.nix>
# ../../../krebs/2configs/binary-cache/nixos.nix
# ../../../krebs/2configs/binary-cache/prism.nix
../../../krebs/2configs/shack/ssh-keys.nix
../../../krebs/2configs/shack/prometheus/node.nix
# <stockholm/krebs/2configs/binary-cache/nixos.nix>
# <stockholm/krebs/2configs/binary-cache/prism.nix>
<stockholm/krebs/2configs/shack/ssh-keys.nix>
<stockholm/krebs/2configs/shack/prometheus/node.nix>
# provides access to /home/share for smbuser via smb
../../../krebs/2configs/shack/share.nix
<stockholm/krebs/2configs/shack/share.nix>
{
fileSystems."/home/share" =
{ device = "/serve";
@ -23,8 +23,8 @@ in
}
## Collect local statistics via collectd and send to collectd
# ../../../krebs/2configs/stats/shack-client.nix
# ../../../krebs/2configs/stats/shack-debugging.nix
# <stockholm/krebs/2configs/stats/shack-client.nix>
# <stockholm/krebs/2configs/stats/shack-debugging.nix>
];
krebs.build.host = config.krebs.hosts.filebitch;
@ -35,13 +35,12 @@ in
'';
networking = {
firewall.enable = true;
interfaces.et0.useDHCP = true;
#interfaces.et0.ipv4.addresses = [
# {
# address = shack-ip;
# prefixLength = 20;
# }
#];
interfaces.et0.ipv4.addresses = [
{
address = shack-ip;
prefixLength = 20;
}
];
defaultGateway = "10.42.0.1";
nameservers = [ "10.42.0.100" "10.42.0.200" ];

View File

@ -2,23 +2,23 @@
{
imports = [
../../../krebs
../../../krebs/2configs
<stockholm/krebs>
<stockholm/krebs/2configs>
../../../krebs/2configs/buildbot-stockholm.nix
../../../krebs/2configs/binary-cache/nixos.nix
../../../krebs/2configs/ircd.nix
../../../krebs/2configs/reaktor2.nix
../../../krebs/2configs/wiki.nix
../../../krebs/2configs/acme.nix
../../../krebs/2configs/mud.nix
../../../krebs/2configs/repo-sync.nix
<stockholm/krebs/2configs/buildbot-stockholm.nix>
<stockholm/krebs/2configs/binary-cache/nixos.nix>
<stockholm/krebs/2configs/ircd.nix>
<stockholm/krebs/2configs/reaktor2.nix>
<stockholm/krebs/2configs/wiki.nix>
<stockholm/krebs/2configs/acme.nix>
<stockholm/krebs/2configs/mud.nix>
<stockholm/krebs/2configs/repo-sync.nix>
../../../krebs/2configs/cal.nix
../../../krebs/2configs/mastodon.nix
<stockholm/krebs/2configs/cal.nix>
<stockholm/krebs/2configs/mastodon.nix>
## (shackie irc bot
../../../krebs/2configs/shack/reaktor.nix
## shackie irc bot
<stockholm/krebs/2configs/shack/reaktor.nix>
];
krebs.build.host = config.krebs.hosts.hotdog;

View File

@ -2,15 +2,15 @@
{
imports = [
../../../krebs
../../../krebs/2configs
<stockholm/krebs>
<stockholm/krebs/2configs>
../../../krebs/2configs/ircd.nix
../../../krebs/2configs/go.nix
<stockholm/krebs/2configs/ircd.nix>
<stockholm/krebs/2configs/go.nix>
#### NEWS ####
../../../krebs/2configs/ircd.nix
../../../krebs/2configs/news.nix
<stockholm/krebs/2configs/ircd.nix>
<stockholm/krebs/2configs/news.nix>
];
krebs.build.host = config.krebs.hosts.news;

View File

@ -46,8 +46,10 @@
# light.shack web-ui
<stockholm/krebs/2configs/shack/light.shack.nix> #light.shack
# fetch the u300 power stats
<stockholm/krebs/2configs/shack/power/u300-power.nix>
# powerraw usb serial to mqtt and raw socket
<stockholm/krebs/2configs/shack/powerraw.nix> # powerraw.shack standby.shack
# send power stats to s3
<stockholm/krebs/2configs/shack/s3-power.nix> # powerraw.shack must be available
{ # do not log to /var/spool/log

View File

@ -7,7 +7,6 @@ in {
SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0"
SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="${ext-if}"
'';
networking.wireless.enable = true;
networking = {
firewall.enable = true;
firewall.allowedTCPPorts = [ 80 443 8088 8086 8083 5901 ];

View File

@ -1,5 +1,5 @@
{ config, lib, ... }:
with lib;
with import <stockholm/lib>;
{
krebs.backup.plans = {
} // mapAttrs (_: recursiveUpdate {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }:
with import ../../lib/pure.nix { inherit lib; };
{ config, ... }: with import <stockholm/lib>;
{
networking.firewall.allowedTCPPorts = [ 80 ];
services.nginx = {

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
setupGit = ''
export PATH=${lib.makeBinPath [
@ -24,13 +23,13 @@
git add .gitignore
'';
pushCal = pkgs.writers.writeDash "push_cal" ''
pushCal = pkgs.writeDash "push_cal" ''
${setupGit}
git fetch origin
git merge --ff-only origin/master || :
'';
pushCgit = pkgs.writers.writeDash "push_cgit" ''
pushCgit = pkgs.writeDash "push_cgit" ''
${setupGit}
git push origin master
'';
@ -74,7 +73,7 @@ in {
cgit.settings = {
root-title = "krebs repos";
};
rules = with slib.git; [
rules = with pkgs.stockholm.lib.git; [
{
user = [
{

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
{
imports = [
./backup.nix

View File

@ -1,6 +1,5 @@
{ config, lib, ... }:
with import ../../lib/pure.nix { inherit lib; };
let
with import <stockholm/lib>;
{ config, ... }: let
format = from: to: {
inherit from;

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }:
with import <stockholm/lib>;
{
krebs.go = {
enable = true;

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }:
with import <stockholm/lib>;
{
networking.wireless.enable = lib.mkDefault true;

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
{ config, pkgs, ... }:
let
#for shared state directory
@ -22,7 +22,7 @@ let
# TODO; get state as argument
state_file = "${stateDir}/ledger";
};
filename = pkgs.writers.writeDash "bedger-add" ''
filename = pkgs.writeDash "bedger-add" ''
set -x
tonick=$1
amt=$2
@ -42,7 +42,7 @@ let
env = {
state_file = "${stateDir}/ledger";
};
filename = pkgs.writers.writeDash "bedger-balance" ''
filename = pkgs.writeDash "bedger-balance" ''
${pkgs.hledger}/bin/hledger -f $state_file bal -N -O csv \
| ${pkgs.coreutils}/bin/tail +2 \
| ${pkgs.miller}/bin/mlr --icsv --opprint cat \
@ -57,7 +57,7 @@ let
arguments = [1];
timeoutSec = 1337;
command = {
filename = pkgs.writers.writeDash "bing" ''
filename = pkgs.writeDash "bing" ''
set -efu
report_error() {
printf '%s' "$*" |
@ -97,7 +97,7 @@ let
arguments = [1];
timeoutSec = 1337;
command = {
filename = pkgs.writers.writeDash "bing-img" ''
filename = pkgs.writeDash "bing-img" ''
set -efu
report_error() {
printf '%s' "$*" |
@ -142,7 +142,7 @@ let
activate = "match";
arguments = [1];
command = {
filename = pkgs.writers.writeDash "confuse" ''
filename = pkgs.writeDash "confuse" ''
set -efux
export PATH=${makeBinPath [
@ -164,7 +164,7 @@ let
activate = "match";
arguments = [1];
command = {
filename = pkgs.writers.writeDash "interrogate" ''
filename = pkgs.writeDash "interrogate" ''
set -efux
export PATH=${makeBinPath [
@ -181,7 +181,7 @@ let
activate = "match";
arguments = [1];
command = {
filename = pkgs.writers.writeDash "confuse" ''
filename = pkgs.writeDash "confuse" ''
set -efu
export PATH=${makeBinPath [
pkgs.coreutils
@ -204,7 +204,7 @@ let
activate = "match";
arguments = [1];
command = {
filename = pkgs.writers.writeDash "say" ''
filename = pkgs.writeDash "say" ''
set -efu
export PATH=${makeBinPath [
@ -234,20 +234,20 @@ let
arguments = [2];
env.TASKDATA = "${stateDir}/${name}";
commands = rec {
add.filename = pkgs.writers.writeDash "${name}-task-add" ''
add.filename = pkgs.writeDash "${name}-task-add" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} add "$1"
'';
list.filename = pkgs.writers.writeDash "${name}-task-list" ''
list.filename = pkgs.writeDash "${name}-task-list" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} export \
| ${pkgs.jq}/bin/jq -r '
.[] | select(.id != 0) | "\(.id) \(.description)"
'
'';
delete.filename = pkgs.writers.writeDash "${name}-task-delete" ''
delete.filename = pkgs.writeDash "${name}-task-delete" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} delete "$1"
'';
del = delete;
done.filename = pkgs.writers.writeDash "${name}-task-done" ''
done.filename = pkgs.writeDash "${name}-task-done" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} done "$1"
'';
};
@ -293,7 +293,8 @@ let
{
activate = "always";
command = {
filename = ../5pkgs/simple/Reaktor/scripts/tell-on_join.sh;
filename =
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_join.sh>;
env = {
PATH = makeBinPath [
pkgs.coreutils # XXX env, touch
@ -310,7 +311,7 @@ let
pattern = "^list-locations";
activate = "match";
command = {
filename = pkgs.writers.writeDash "list-locations" ''
filename = pkgs.writeDash "list-locations" ''
export PATH=${makeBinPath [
pkgs.curl
pkgs.jq
@ -327,7 +328,7 @@ let
activate = "match";
arguments = [1 2 3];
command = {
filename = pkgs.writers.writeDash "add-location" ''
filename = pkgs.writeDash "add-location" ''
export PATH=${makeBinPath [
pkgs.curl
pkgs.jq
@ -344,7 +345,7 @@ let
activate = "match";
arguments = [1];
command = {
filename = pkgs.writers.writeDash "add-location" ''
filename = pkgs.writeDash "add-location" ''
export PATH=${makeBinPath [
pkgs.curl
pkgs.jq
@ -373,7 +374,7 @@ let
sha256 = "sha256-J7jGWZeAULDA1EkO50qx+hjl+5IsUj389pUUMreKeNE=";
};
osm-restaurants = pkgs.callPackage "${osm-restaurants-src}/osm-restaurants" {};
in pkgs.writers.writeDash "krebsfood" ''
in pkgs.writeDash "krebsfood" ''
set -efu
export PATH=${makeBinPath [
osm-restaurants
@ -416,7 +417,8 @@ let
(generators.command_hook {
inherit (commands) dance random-emoji nixos-version;
tell = {
filename = ../5pkgs/simple/Reaktor/scripts/tell-on_privmsg.sh;
filename =
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_privmsg.sh>;
env = {
PATH = makeBinPath [
pkgs.coreutils # XXX date, env
@ -450,7 +452,7 @@ in {
name = "reaktor2";
home = stateDir;
};
script = ''. ${pkgs.writers.writeDash "agenda" ''
script = ''. ${pkgs.writeDash "agenda" ''
echo "$Method $Request_URI" >&2
case "$Method" in
"GET")

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
konsens-user = {

View File

@ -1,5 +1,4 @@
{ lib, ... }:
with lib;
{ ... }: with import <stockholm/lib>;
{
users.extraUsers =
mapAttrs (_: h: { hashedPassword = h; })

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
{ config, pkgs, ... }:
with import <stockholm/lib>;
let
root = "/var/srv/drivedroid";
in

View File

@ -0,0 +1,23 @@
# needs:
# binary_sensor.lounge_ampel_status
# light.lounge_ampel_licht_rot
let
glados = import ../lib;
in
{
services.home-assistant.config.automation =
[
{
alias = "Ampel Rotes Licht";
initial_state = true;
trigger = {
platform = "state";
entity_id = "binary_sensor.lounge_ampel_status";
};
action = { service = "light.turn_on";
data.entity_id = "light.lounge_ampel_licht_rot";
};
}
];
}

View File

@ -0,0 +1,28 @@
Willkommen werter Keyholder {{ states("sensor.keyholder") }} in deinem Lieblingshackerspace.
Es ist {{states("sensor.fablab_feinstaub_temperature") | round(1) | replace('.',' Komma ')}} Grad {% if states("sensor.fablab_feinstaub_temperature")|float > 25 %}heiss{%elif states("sensor.fablab_feinstaub_temperature")|float > 15%}warm{%else%}kalt{%endif%} bei {% if states(" sensor.rz_feinstaub_humidity") | int <45 %}trockenen{% elif states(" sensor.rz_feinstaub_humidity") | int <65 %}angenehmen{%else%}feuchten{%endif%} {{states(" sensor.rz_feinstaub_humidity") | int }} Prozent Luftfeuchtigkeit.
{% if (states("sensor.fullstand_mate_1")|int == 0) and
states("sensor.fullstand_mate_2")|int == 0 %}ES IST MAHTECALYPSE, BEIDE MAHTESCHÄCHTE SIND LEER! {%if states("sensor.fullstand_mate_cola")| int == 0%} UND SOGAR DIE COLA IST ALLE. Ihr seid sowas von am Arsch!{%else%}Zum Glück gibt es noch Cola, Phew!{%endif%}
{% elif (states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int) < 5 %}
Der Mahtestand im Automaten ist mit {{states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int }} verbleibenden Flaschen kritisch!
{% else %}
Im Automaten sind noch {{states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int }} Flaschen Mahte und {{states("sensor.fullstand_mate_cola")}} Flaschen Cola.
{%endif%}
Die Wettervorhersage: {{states("sensor.dark_sky_hourly_summary")}} Aktuell {{states("sensor.dark_sky_summary")}} bei {{states("sensor.dark_sky_temperature") | round(1) | replace('.',' Komma ')}} Grad.
Der Stromverbrauch liegt bei {{ (( states("sensor.l1_power")|int + states("sensor.l2_power")|int + states("sensor.l3_power")|int ) / 1000 )| round(1) | replace('.',' Komma ')}} Kilowatt.
Im Fablab ist die Feinstaubbelastung {% if states("sensor.fablab_particulate_matter_2_5um_concentration") | float > 50 %}hoch!{%elif states("sensor.fablab_particulate_matter_2_5um_concentration") | float > 25 %}mäßig.{% else %}gering.{%endif%}
{% if is_state("binary_sensor.door_rzl",'on') and is_state("binary_sensor.door_entropia",'on') %}
Das Raumzeitlabor und Entropia haben geöffnet.
{% elif is_state("binary_sensor.door_rzl",'off') and is_state("binary_sensor.door_entropia",'off') %}
Das Raumzeitlabor und Entropia haben geschlossen.
{% elif is_state("binary_sensor.door_rzl",'on') and is_state("binary_sensor.door_entropia",'off') %}
Das Raumzeitlabor hat geöffnet und Entropia hat geschlossen.
{% elif is_state("binary_sensor.door_rzl",'off') and is_state("binary_sensor.door_entropia",'on') %}
Das Raumzeitlabor hat geschlossen und Entropia hat geöffnet.
{%endif%}
Die Glados Hackerspace Automation wünscht dir und allen Anwesenden einen produktiven und angenehmen Aufenthalt!

View File

@ -0,0 +1,24 @@
# needs:
# light.fablab_led
{
services.home-assistant.config.automation =
[
{ alias = "State on HA start-up";
trigger = {
platform = "homeassistant";
event = "start";
};
# trigger good/bad air
action = [
{ service = "light.turn_on";
data = {
entity_id = "light.fablab_led";
effect = "Rainbow";
color_name = "purple";
};
}
];
}
];
}

View File

@ -0,0 +1,32 @@
# Needs:
# sun.sunset
# switch.lounge_diskoschalter_relay
let
glados = import ../lib;
disko_schalter = "switch.lounge_diskoschalter_relay";
player = "media_player.lounge";
in
{
services.home-assistant.config.automation =
[
{ alias = "Party um 21 Uhr";
trigger = {
platform = "sun";
event = "sunset";
};
action =
( glados.say.kiosk "Die Sonne geht unter. Und jetzt geht die Party im shack erst richtig los. Partybeleuchtung, aktiviert!" )
++
[
{
service = "homeassistant.turn_on";
entity_id = disko_schalter;
}
{
service = "media_player.turn_on";
data.entity_id = player;
} # TODO: also start playlist if nothing is running?
];
}
];
}

View File

@ -0,0 +1,100 @@
# needs:
# binary_sensor.portal_lock
# sensor.keyholder
# media_player.lounge
# additional state required on:
# mpd.shack:
# playlist "ansage"
# playlist "lassulus"
# lounge.kiosk.shack:
# playlist "ansage"
let
glados = import ../lib;
in
{
services.home-assistant.config.automation =
[
{
alias = "Bedanken bei Übernahme von Key";
initial_state = true;
trigger = {
platform = "state";
entity_id = "sensor.keyholder";
};
condition = {
condition = "template";
value_template = "{{ (trigger.from_state.state != 'No Keyholder') and (trigger.from_state.state != 'No Keyholder') }}";
};
action = glados.say.kiosk "Danke {{ trigger.to_state.state }} für das Übernehmen des Keys von {{ trigger.from_state.state }}";
}
{
alias = "Keyholder Begrüßen wenn MPD hoch fährt";
initial_state = true;
trigger = {
platform = "state";
from = "unavailable";
entity_id = "media_player.kiosk";
};
action = glados.say.kiosk (builtins.readFile ./announcement.j2);
}
{
alias = "Start Music on portal lock on";
trigger = {
platform = "state";
entity_id = "binary_sensor.portal_lock";
to = "on";
for.seconds = 30;
};
condition = {
condition = "and";
conditions =
[
{ # only start if a keyholder opened the door and if the lounge mpd is currently not playing anything
condition = "template";
value_template = "{{ state('sensor.keyholder') != 'No Keyholder' }}";
}
{
condition = "state";
entity_id = "media_player.lounge";
state = "idle";
}
];
};
action = [
{
service = "media_player.volume_set";
data = {
entity_id = "media_player.lounge";
volume_level = 1.0;
};
}
{
service = "media_player.play_media";
data = {
entity_id = "media_player.lounge";
media_content_type = "playlist";
media_content_id = "ansage";
};
}
{ delay.seconds = 8.5; }
{
service = "media_player.volume_set";
data = {
entity_id = "media_player.lounge";
volume_level = 0.6;
};
}
{
service = "media_player.play_media";
data = {
entity_id = "media_player.lounge";
media_content_type = "playlist";
media_content_id = "lassulus";
};
}
];
}
];
}

View File

@ -1,33 +1,12 @@
{ config, pkgs, lib, ... }:
let
kodi-host = "192.168.8.11";
confdir = "/var/lib/homeassistant-docker";
unstable = import (pkgs.fetchFromGitHub {
owner = "nixos";
repo = "nixpkgs";
rev = (lib.importJSON ../../../nixpkgs-unstable.json).rev;
sha256 = (lib.importJSON ../../../nixpkgs-unstable.json).sha256;
}) {};
in {
imports = [
];
# networking.firewall.allowedTCPPorts = [ 8123 ];
virtualisation.oci-containers.containers.hass = {
image = "homeassistant/home-assistant:latest";
environment = {
TZ = "Europe/Berlin";
# TODO create unique users
PUID = toString config.users.users.news_container.uid;
PGID = toString config.users.groups.news_container.gid;
UMASK = "007";
};
extraOptions = ["--net=host" ];
volumes = [
"${confdir}:/config"
#"${confdir}/docker-run:/etc/services.d/home-assistant/run:"
];
};
systemd.tmpfiles.rules = [
#"f ${confdir}/docker-run 0770 kiosk kiosk - -"
# TODO:
"d ${confdir} 0770 news_container news_container - -"
];
services.nginx.virtualHosts."hass.shack" = {
serverAliases = [ "glados.shack" ];
locations."/" = {
@ -44,4 +23,127 @@ in {
'';
};
};
imports = [
./multi/shackopen.nix
./multi/wasser.nix
./multi/schlechte_luft.nix
./multi/rollos.nix
./switch/power.nix
./sensors/power.nix
./sensors/mate.nix
./sensors/darksky.nix
./sensors/spaceapi.nix
./sensors/sensemap.nix
./automation/shack-startup.nix
./automation/party-time.nix
./automation/hass-restart.nix
./automation/ampel.nix
];
services.home-assistant =
{
enable = true;
package = unstable.home-assistant.overrideAttrs (old: {
doInstallCheck = false;
});
config = {
homeassistant = {
name = "Glados";
time_zone = "Europe/Berlin";
latitude = "48.8265";
longitude = "9.0676";
elevation = 303;
auth_providers = [
{ type = "homeassistant";}
{ type = "trusted_networks";
trusted_networks = [
"127.0.0.1/32"
"10.42.0.0/16"
"::1/128"
"fd00::/8"
];
}
];
};
# https://www.home-assistant.io/components/influxdb/
influxdb = {
database = "glados";
host = "influx.shack";
component_config_glob = {
"sensor.*particulate_matter_2_5um_concentration".override_measurement = "2_5um particles";
"sensor.*particulate_matter_10_0um_concentration".override_measurement ="10um particles";
};
tags = {
instance = "wolf";
source = "glados";
};
};
esphome = {};
api = {};
mqtt = {
broker = "localhost";
port = 1883;
client_id = "home-assistant";
keepalive = 60;
protocol = 3.1;
discovery = true; #enable esphome discovery
discovery_prefix = "homeassistant";
birth_message = {
topic = "glados/hass/status/LWT";
payload = "Online";
qos = 1;
retain = true;
};
will_message = {
topic = "glados/hass/status/LWT";
payload = "Offline";
qos = 1;
retain = true;
};
};
light = [];
media_player = [
{ platform = "mpd";
name = "lounge";
host = "lounge.mpd.shack";
}
{ platform = "mpd";
name = "kiosk";
#host = "lounge.kiosk.shack";
host = "kiosk.shack";
}
];
camera = [];
frontend = { };
config = { };
sun = {};
http = {
base_url = "http://hass.shack";
use_x_forwarded_for = true;
trusted_proxies = [ "127.0.0.1" "::1" ];
};
#conversation = {};
history = {};
logbook = {};
#recorder = {};
logger.default = "info";
tts = [
{ platform = "google_translate";
service_name = "say";
language = "de";
cache = true;
time_memory = 57600;
base_url = "http://hass.shack";
}
];
device_tracker = [];
};
};
}

View File

@ -0,0 +1,27 @@
{ lib
, buildPythonPackage
, fetchPypi
, requests
}:
buildPythonPackage rec {
pname = "gtts-token";
version = "1.1.3";
src = fetchPypi {
pname = "gTTS-token";
inherit version;
sha256 = "9d6819a85b813f235397ef931ad4b680f03d843c9b2a9e74dd95175a4bc012c5";
};
propagatedBuildInputs = [
requests
];
meta = with lib; {
description = "Calculates a token to run the Google Translate text to speech";
homepage = https://github.com/boudewijn26/gTTS-token;
license = licenses.mit;
# maintainers = [ maintainers. ];
};
}

View File

@ -0,0 +1,33 @@
{ lib
, buildPythonPackage
, fetchpatch
, fetchPypi
, aiohttp
, async-timeout
}:
buildPythonPackage rec {
pname = "pyhaversion";
version = "2.2.1";
src = fetchPypi {
inherit pname version;
sha256 = "72b65aa25d7b2dbb839a4d0218df2005c2335e93526035904d365bb668030b9f";
};
patches = [
(fetchpatch { url = "https://github.com/makefu/pyhaversion/commit/f3bdc38970272cd345c2cfbde3037ea492ca27c4.patch";
sha256 =
"1rhq4z7mdgnwhwpf5fmarnbc1ba3qysk1wqjdr0hvbzi8vmvbfcc";})
];
doCheck = false;
propagatedBuildInputs = [
aiohttp
async-timeout
];
meta = with lib; {
description = "";
homepage = https://github.com/ludeeus/pyhaversion;
# maintainers = [ maintainers. ];
};
}

View File

@ -0,0 +1,66 @@
let
prefix = "glados";
in
{
say = let
# returns a list of actions to be performed on an mpd to say something
tts = { message, entity }:
[
{
service = "media_player.turn_on";
data.entity_id = "media_player.${entity}";
}
{ service = "media_player.play_media";
data = {
entity_id = "media_player.${entity}";
media_content_type = "playlist";
media_content_id = "ansage";
};
}
{
service = "media_player.turn_on";
data.entity_id = "media_player.${entity}";
}
{ delay.seconds = 4.5; }
{ service = "tts.say";
entity_id = "media_player.${entity}";
data_template = {
inherit message;
language = "de";
};
}
];
in
{
lounge = message: tts {
inherit message;
entity = "lounge";
};
herrenklo = message: tts {
inherit message;
entity = "herrenklo";
};
kiosk = message: tts {
inherit message;
entity = "kiosk";
};
};
tasmota =
{
plug = {host, name ? host, topic ? host}:
{
platform = "mqtt";
inherit name;
state_topic = "sonoff/stat/${topic}/POWER1";
command_topic = "sonoff/cmnd/${topic}/POWER1";
availability_topic = "sonoff/tele/${topic}/LWT";
payload_on= "ON";
payload_off= "OFF";
payload_available= "Online";
payload_not_available= "Offline";
retain = false;
qos = 1;
};
};
}

View File

@ -0,0 +1,59 @@
#
let
glados = import ../lib;
tempsensor = "sensor.dark_sky_temperature";
all_covers = [
"cover.crafting_rollo"
"cover.elab_rollo"
"cover.or2_rollo"
"cover.retroraum_rollo"
];
in
{
services.home-assistant.config =
{
automation =
[
{ alias = "Rollos fahren Runter";
trigger = [
{
platform = "numeric_state";
entity_id = tempsensor;
above = 25;
for = "00:30:00";
}
];
condition =
[
{
condition = "state";
entity_id = "sun.sun";
state = "above_horizon";
}
];
action =
[
{ service = "cover.close_cover";
entity_id = all_covers;
}
];
}
{ alias = "Rollos fahren Hoch";
trigger = [
{
platform = "sun";
event = "sunset";
}
];
condition = [ ];
action =
[
{ service = "cover.open_cover";
entity_id = all_covers;
}
];
}
];
};
}

View File

@ -0,0 +1,109 @@
let
glados = import ../lib;
feinstaub_sensor = "sensor.fablab_particulate_matter_2_5um_concentration";
ledring = "light.fablab_led_ring";
in
{
services.home-assistant.config =
{
automation =
[
{ alias = "Gute Luft Fablab";
trigger = [
{
platform = "numeric_state";
entity_id = feinstaub_sensor;
below = 3;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Twinkle";
color_name = "green";
};
}
];
}
{ alias = "mäßige Luft Fablab";
trigger = [
{
platform = "numeric_state";
above = 3;
below = 10;
entity_id = feinstaub_sensor;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Twinkle";
color_name = "yellow";
};
}
];
}
{ alias = "schlechte Luft Fablab";
trigger = [
{
platform = "numeric_state";
above = 10;
entity_id = feinstaub_sensor;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Fireworks";
color_name = "red";
};
}
];
}
{ alias = "Luft Sensor nicht verfügbar";
trigger = [
{
platform = "state";
to = "unavailable";
entity_id = feinstaub_sensor;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Rainbow";
color_name = "blue";
};
}
];
}
{ alias = "Fablab Licht Reboot";
trigger = [
{
platform = "state";
from = "unavailable";
entity_id = ledring;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Rainbow";
color_name = "orange";
};
}
];
}
];
};
}

View File

@ -0,0 +1,26 @@
{
services.home-assistant.config =
{
binary_sensor = [
{ platform = "mqtt";
name = "Portal Lock";
device_class = "door";
state_topic = "portal/gateway/status";
availability_topic = "portal/gateway/lwt";
payload_on = "open";
payload_off = "closed";
payload_available = "online";
payload_not_available = "offline";
}
];
sensor = [
{ platform = "mqtt";
name = "Keyholder";
state_topic = "portal/gateway/keyholder";
availability_topic = "portal/gateway/lwt";
payload_available = "online";
payload_not_available = "offline";
}
];
};
}

View File

@ -0,0 +1,113 @@
# uses:
# switch.crafting_giesskanne_relay
let
glados = import ../lib;
seconds = 20;
wasser = "switch.crafting_giesskanne_relay";
brotbox = {
minutes = 10;
pump = "switch.crafting_brotbox_pumpe";
sensor = "sensor.statistics_for_sensor_crafting_brotbox_soil_moisture";
};
in
{
services.home-assistant.config =
{
sensor = map ( entity_id: {
platform = "statistics";
name = "Statistics for ${entity_id}";
inherit entity_id;
max_age.minutes = "60";
sampling_size = 1000;
}) ["sensor.crafting_brotbox_soil_moisture"];
automation =
[
### Brotbox #####
#{ alias = "Brotbox: water for ${toString brotbox.minutes} minutes every hour";
# trigger =
# { # Trigger once every hour at :42
# platform = "time_pattern";
# minutes = 42;
# };
# condition = {
# condition = "numeric_state";
# entity_id = brotbox.sensor;
# value_template = "{{ state_attr('${brotbox.sensor}', 'median') }}";
# below = 75;
# };
# action =
# [
# {
# service = "homeassistant.turn_on";
# entity_id = brotbox.pump;
# }
# { delay.minutes = brotbox.minutes; }
# {
# service = "homeassistant.turn_off";
# entity_id = brotbox.pump ;
# }
# ];
#}
{ alias = "Brotbox: Always turn off water after ${toString (brotbox.minutes * 2)} minutes";
trigger =
{
platform = "state";
entity_id = brotbox.pump;
to = "on";
for.minutes = brotbox.minutes*2;
};
action =
{
service = "homeassistant.turn_off";
entity_id = brotbox.pump;
};
}
##### Kaffeemaschine
{ alias = "Water the plant for ${toString seconds} seconds";
trigger = [
{ # trigger at 20:00 no matter what
# TODO: retry or run only if switch.wasser is available
platform = "time";
at = "20:00:00";
}
];
action =
[
{
service = "homeassistant.turn_on";
entity_id = [
wasser
];
}
{ delay.seconds = seconds; }
{
service = "homeassistant.turn_off";
entity_id = [
wasser
];
}
];
}
{ alias = "Always turn off water after ${toString (seconds * 2)}seconds";
trigger = [
{
platform = "state";
entity_id = wasser;
to = "on";
for.seconds = seconds*2;
}
];
action =
[
{
service = "homeassistant.turn_off";
entity_id = [ wasser ];
}
];
}
];
};
}

View File

@ -0,0 +1,24 @@
{lib,...}:
{
services.home-assistant.config.sensor =
[
{ platform = "darksky";
api_key = lib.removeSuffix "\n"
(builtins.readFile <secrets/hass/darksky.apikey>);
language = "de";
monitored_conditions = [
"summary" "icon"
"nearest_storm_distance" "precip_probability"
"precip_intensity"
"temperature" # "temperature_high" "temperature_low"
"apparent_temperature"
"hourly_summary" # next 24 hours text
"humidity"
"pressure"
"uv_index"
];
units = "si" ;
scan_interval = "00:15:00";
}
];
}

View File

@ -0,0 +1,20 @@
let
fuellstand = name: id: {
platform = "rest";
resource = "https://ora5.tutschonwieder.net/ords/lick_prod/v1/get/fuellstand/1/${toString id}";
method = "GET";
name = "Füllstand ${name}";
value_template = "{{ value_json.fuellstand }}";
};
in
{
services.home-assistant.config.sensor =
[
(fuellstand "Wasser" 1)
(fuellstand "Mate Cola" 2)
(fuellstand "Apfelschorle" 3)
(fuellstand "Zitronensprudel" 4)
(fuellstand "Mate 1" 26)
(fuellstand "Mate 2" 27)
];
}

View File

@ -0,0 +1,29 @@
let
power_x = name: phase:
{ platform = "mqtt";
name = "${phase} ${name}";
state_topic = "/power/total/${phase}/${name}";
availability_topic = "/power/lwt";
payload_available = "Online";
payload_not_available = "Offline";
};
power_consumed =
{ platform = "mqtt";
name = "Power Consumed";
device_class = "power";
state_topic = "/power/total/consumed";
availability_topic = "/power/lwt";
payload_available = "Online";
payload_not_available = "Offline";
};
power_volt = power_x "Voltage";
power_watt = (power_x "Power") ;
power_curr = power_x "Current";
in
{
services.home-assistant.config.sensor =
(map power_volt [ "L1" "L2" "L3" ])
++ (map (x: ((power_watt x) // { device_class = "power"; })) [ "L1" "L2" "L3" ])
++ (map power_curr [ "L1" "L2" "L3" ])
++ [ power_consumed ];
}

View File

@ -0,0 +1,9 @@
{
services.home-assistant.config.air_quality =
[
{
platform = "opensensemap";
station_id = "56a0de932cb6e1e41040a68b";
}
];
}

View File

@ -0,0 +1,55 @@
{
services.home-assistant.config.binary_sensor =
[
{
platform = "rest";
resource = "https://spaceapi.afra-berlin.de/v1/status.json";
method = "GET";
name = "Door AFRA Berlin";
device_class = "door";
value_template = "{{ value_json.open }}";
}
{
platform = "rest";
resource = "http://club.entropia.de/spaceapi";
method = "GET";
name = "Door Entropia";
device_class = "door";
value_template = "{{ value_json.open }}";
}
{
platform = "rest";
resource = "http://www.c-base.org/status.json";
method = "GET";
name = "Door C-Base Berlin";
device_class = "door";
value_template = "{{ value_json.open }}";
}
{
platform = "rest";
resource = "https://status.raumzeitlabor.de/api/full.json";
method = "GET";
name = "Door RZL";
device_class = "door";
value_template = "{{ value_json.status }}";
}
{
platform = "rest";
resource = "https://datenobservatorium.de/";
method = "GET";
name = "Door Datenobservatorium";
device_class = "door";
value_template = "false";
scan_interval = 2592000;
}
{
platform = "rest";
resource = "https://infuanfu.de/";
method = "GET";
name = "Door Infuanfu";
device_class = "door";
value_template = "false";
scan_interval = 2592000;
}
];
}

View File

@ -0,0 +1,6 @@
{
controllers = {
host = "unifi.shack";
site = "shackspace";
};
}

View File

@ -0,0 +1,44 @@
# 1 - haupt
# 2 - dusche
# 3 - warmwasser
# 4 - or
# 5 - kueche
let
nodelight = type: ident: name: {
platform = "mqtt";
name = "${type} ${name}";
command_topic = "${type}/${toString ident}/command";
state_topic = "${type}/${toString ident}/state";
payload_on = "on";
payload_off = "off";
};
power = nodelight "power";
light = ident: name: { icon = "mdi:lightbulb";} // nodelight "light" ident name;
in
{
services.home-assistant.config.switch =
[
# These commands we see with a shutdown:
# power/143/state on
# power/142/state on
# power/141/state on
# power/142/state off
# power/141/state off
# power/10/state off
# power/main/state off
(power "10" "Hauptschalter")
(power 1 "Dusche") # ???
(power 2 "Warmwasser") # ???
(power 3 "Optionsräume") # ???
(power 4 "Küche") # ???
(light 1 "Decke Lounge 1")
(light 2 "Decke Lounge 2")
(light 3 "Decke Lounge 3")
(light 4 "Decke Lounge 4")
(light 5 "Decke Lounge 5")
(light 6 "Decke Lounge 6")
(light 7 "Decke Lounge 7")
(light 8 "Decke Lounge 8")
];
}

View File

@ -4,18 +4,7 @@ in {
networking.firewall.allowedTCPPorts = [ port ]; # legacy
services.nginx.virtualHosts."grafana.shack" = {
locations."/" = {
proxyPass = "http://localhost:${toString port}";
extraConfig =''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
locations."/".proxyPass = "http://localhost:${toString port}";
};
services.grafana = {
enable = true;

View File

@ -15,16 +15,6 @@ in
'';
locations."/" = {
proxyPass = "http://localhost:${toString port}/";
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
'';
};
};
nixpkgs.overlays = [

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
pkg = pkgs.stdenv.mkDerivation {
name = "mqtt2graphite-2017-05-29";

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
pkg = pkgs.stdenv.mkDerivation {
name = "muell_caller-2017-06-01";

View File

@ -1,5 +1,5 @@
{ config, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
cfg = config.krebs.apt-cacher-ng;
in

View File

@ -1,29 +0,0 @@
{ pkgs, ... }:
let
src = pkgs.fetchFromGitHub {
repo = "shackstrom";
owner = "samularity";
rev = "adfbdc7d12000fbc9fd9367c8ef0a53b7d0a9fad";
hash = "sha256-77vSX2+1XXaBVgLka+tSEK/XYZASEk9iq+uEuO1aOUQ=";
};
pkg = pkgs.writers.writePython3 "test_python3" {
libraries = [ pkgs.python3Packages.requests pkgs.python3Packages.paho-mqtt ];
} (builtins.readFile "${src}/shackstrom.py");
in
{
systemd.services = {
u300-power = {
enable = true;
environment = {
DATA_URL = "http://10.42.20.255/csv.html";
BROKER = "mqtt.shack";
};
serviceConfig = {
Restart = "always";
ExecStart = pkg;
RestartSec = "15s";
};
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@ -1,12 +1,28 @@
{ lib,... }:
let
disk_free_threshold = "5"; # at least this much free disk percentage
disk_free_threshold = "10"; # at least this much free disk percentage
in {
services.prometheus.rules = [(builtins.toJSON
{
groups = [
{ name = "shack-env";
rules = [
{
alert = "Wolf RootPartitionFull";
for = "30m";
expr = ''(node_filesystem_avail_bytes{alias="wolf.shack",mountpoint="/"} * 100) / node_filesystem_size_bytes{alias="wolf.shack",mountpoint="/"} < ${disk_free_threshold}'';
labels.severity = "warning";
annotations.summary = "{{ $labels.alias }} root disk full";
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=wolf";
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%). CI for deploying new configuration will seize working. Log in to the system and try to clean up the obsolete files on the machine. There are a couple of things you can do:
1. `nix-collect-garbage -d`
2. clean up the shack share folder in `/home/share`
3. check `du -hs /var/ | sort -h`.
4. run `docker system prune`
5. `find /var/lib/containers/news/var/lib/htgen-go/items -mtime +7 -delete;` to clean up the link shortener data
5. If you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete
6. as a last resort the root disk can be expanded via `lvresize -L +10G /dev/pool/root && btrfs filesystem resize max /` '';
}
{
alert = "Puyak RootPartitionFull";
for = "30m";
@ -16,8 +32,9 @@ in {
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=puyak";
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%).Prometheus will not be able to create new alerts and CI for deploying new configuration will also seize working. Log in to the system and run `nix-collect-garbage -d` and if this does not help you can check `du -hs /var/ | sort -h`, run `docker system prune` or if you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete'';
}
# wolf.shack is not worth supervising anymore
{
alert = "Infra01 down";
alert = "HostDown";
expr = ''up{alias="infra01.shack"} == 0'';
for = "5m";
labels.severity = "page";

View File

@ -1,207 +0,0 @@
import base64
import cgi
import json
import os
import re
import socket
import ssl
import sys
from http.server import BaseHTTPRequestHandler
from typing import List, Optional, Tuple
from urllib.parse import urlparse
DEBUG = os.environ.get("DEBUG") is not None
def _irc_send(
server: str,
nick: str,
channel: str,
sasl_password: Optional[str] = None,
server_password: Optional[str] = None,
tls: bool = True,
port: int = 6697,
messages: List[str] = [],
) -> None:
if not messages:
return
sock = socket.socket()
if tls:
sock = ssl.wrap_socket(
sock, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1_2
)
def _send(command: str) -> int:
if DEBUG:
print(command)
return sock.send((f"{command}\r\n").encode())
def _pong(ping: str):
if ping.startswith("PING"):
sock.send(ping.replace("PING", "PONG").encode("ascii"))
recv_file = sock.makefile(mode="r")
print(f"connect {server}:{port}")
sock.connect((server, port))
if server_password:
_send(f"PASS {server_password}")
_send(f"USER {nick} 0 * :{nick}")
_send(f"NICK {nick}")
for line in recv_file.readline():
if re.match(r"^:[^ ]* (MODE|221|376|422) ", line):
break
else:
_pong(line)
if sasl_password:
_send("CAP REQ :sasl")
_send("AUTHENTICATE PLAIN")
auth = base64.encodebytes(f"{nick}\0{nick}\0{sasl_password}".encode("utf-8"))
_send(f"AUTHENTICATE {auth.decode('ascii')}")
_send("CAP END")
_send(f"JOIN :{channel}")
for m in messages:
_send(f"PRIVMSG {channel} :{m}")
_send("INFO")
for line in recv_file:
if DEBUG:
print(line, end="")
# Assume INFO reply means we are done
if "End of /INFO" in line:
break
else:
_pong(line)
sock.send(b"QUIT")
print("disconnect")
sock.close()
def irc_send(
url: str, notifications: List[str], password: Optional[str] = None
) -> None:
parsed = urlparse(f"{url}")
username = parsed.username or "prometheus"
server = parsed.hostname or "chat.freenode.net"
if parsed.fragment != "":
channel = f"#{parsed.fragment}"
else:
channel = "#krebs-announce"
port = parsed.port or 6697
if not password:
password = parsed.password
if len(notifications) == 0:
return
_irc_send(
server=server,
nick=username,
sasl_password=password,
channel=channel,
port=port,
messages=notifications,
tls=parsed.scheme == "irc+tls",
)
class PrometheusWebHook(BaseHTTPRequestHandler):
def __init__(
self,
irc_url: str,
conn: socket.socket,
addr: Tuple[str, int],
password: Optional[str] = None,
) -> None:
self.irc_url = irc_url
self.password = password
self.rfile = conn.makefile("rb")
self.wfile = conn.makefile("wb")
self.client_address = addr
self.handle()
# for testing
def do_GET(self) -> None:
if DEBUG:
print("GET: Request Received")
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write(b"ok")
def do_POST(self) -> None:
if DEBUG:
print("POST: Request Received")
content_type, _ = cgi.parse_header(self.headers.get("content-type"))
# refuse to receive non-json content
if content_type != "application/json":
if DEBUG:
print(f"POST: wrong content type {content_type}")
self.send_response(400)
self.end_headers()
return
length = int(self.headers.get("content-length"))
payload = json.loads(self.rfile.read(length))
messages = []
for alert in payload["alerts"]:
description = alert["annotations"]["description"]
messages.append(f"{alert['status']}: {description}")
irc_send(self.irc_url, messages, password=self.password)
self.do_GET()
def systemd_socket_response() -> None:
irc_url = os.environ.get("IRC_URL", None)
if irc_url is None:
print(
"IRC_URL environment variable not set: i.e. IRC_URL=irc+tls://mic92-prometheus@chat.freenode.net/#krebs-announce",
file=sys.stderr,
)
sys.exit(1)
password = None
irc_password_file = os.environ.get("IRC_PASSWORD_FILE", None)
if irc_password_file:
with open(irc_password_file) as f:
password = f.read()
msgs = sys.argv[1:]
if msgs != []:
irc_send(irc_url, msgs, password=password)
return
nfds = os.environ.get("LISTEN_FDS", None)
if nfds is None:
print(
"LISTEN_FDS not set. Run me with systemd(TM) socket activation?",
file=sys.stderr,
)
sys.exit(1)
fds = range(3, 3 + int(nfds))
for fd in fds:
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0)
try:
while True:
PrometheusWebHook(irc_url, *sock.accept(), password=password)
except BlockingIOError:
# no more connections
pass
if __name__ == "__main__":
if DEBUG:
print("Starting in DEBUG mode")
if len(sys.argv) == 3:
print(f"{sys.argv[1]} {sys.argv[2]}")
irc_send(sys.argv[1], [sys.argv[2]])
else:
systemd_socket_response()

View File

@ -1,59 +0,0 @@
{ config
, lib
, pkgs
, ...
}:
let
irc-alerts = pkgs.writers.writePython3 "irc-alerts" {
flakeIgnore = [ "E501" ];
} (builtins.readFile ./irc-alerts.py);
endpoints = {
binaergewitter = {
url = "irc+tls://puyak-alerts@irc.libera.chat:6697/#binaergewitter-alerts";
port = 9223;
};
};
in
{
systemd.sockets =
lib.mapAttrs'
(name: opts:
lib.nameValuePair "irc-alerts-${name}" {
description = "Receive http hook and send irc message for ${name}";
wantedBy = [ "sockets.target" ];
listenStreams = [ "[::]:${builtins.toString opts.port}" ];
}) endpoints;
systemd.services =
lib.mapAttrs'
(name: opts:
let
serviceName = "irc-alerts-${name}";
hasPassword = opts.passwordFile or null != null;
in
lib.nameValuePair serviceName {
description = "Receive http hook and send irc message for ${name}";
requires = [ "irc-alerts-${name}.socket" ];
serviceConfig =
{
Environment =
[
"IRC_URL=${opts.url}"
"DEBUG=y"
]
++ lib.optional hasPassword "IRC_PASSWORD_FILE=/run/${serviceName}/password";
DynamicUser = true;
User = serviceName;
ExecStart = irc-alerts;
}
// lib.optionalAttrs hasPassword {
PermissionsStartOnly = true;
ExecStartPre =
"${pkgs.coreutils}/bin/install -m400 "
+ "-o ${serviceName} -g ${serviceName} "
+ "${config.sops.secrets.prometheus-irc-password.path} "
+ "/run/${serviceName}/password";
RuntimeDirectory = serviceName;
};
}) endpoints;
}

View File

@ -3,7 +3,6 @@
{
imports = [
./alert-rules.nix
./irc-hooks.nix
];
networking = {
firewall.allowedTCPPorts = [
@ -130,11 +129,11 @@
"group_wait" = "30s";
"group_interval" = "2m";
"repeat_interval" = "4h";
"receiver" = "shack-admins";
"receiver" = "team-admins";
};
"receivers" = [
{
"name" = "shack-admins";
"name" = "team-admins";
"email_configs" = [ ];
"webhook_configs" = [
{

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
pkg = pkgs.stdenv.mkDerivation {
name = "radioactive-2017-06-01";

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
pkg = pkgs.stdenv.mkDerivation {
name = "worlddomination-2020-12-01";

View File

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }:
# TODO: krebs.collectd.plugins
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
connect-time-cfg = with pkgs; writeText "collectd-connect-time.conf" ''
LoadPlugin python

View File

@ -1,6 +1,4 @@
{ config, lib, options, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
let
{ options, config, pkgs, ... }: with import <stockholm/lib>; let
mk_peers = mapAttrs (n: v: { id = v.syncthing.id; });
all_peers = filterAttrs (n: v: v.syncthing.id != null) config.krebs.hosts;

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
{ config, pkgs, ... }:
with import <stockholm/lib>;
let
setupGit = ''
@ -14,13 +14,13 @@ let
fi
'';
pushGollum = pkgs.writers.writeDash "push_gollum" ''
pushGollum = pkgs.writeDash "push_gollum" ''
${setupGit}
git fetch origin
git merge --ff-only origin/master
'';
pushCgit = pkgs.writers.writeDash "push_cgit" ''
pushCgit = pkgs.writeDash "push_cgit" ''
${setupGit}
git push origin master
'';

View File

@ -1,7 +1,6 @@
{ config, lib, pkgs, ... }:
with lib;
with import <stockholm/lib>; #genid
let
slib = import ../../lib/pure.nix { inherit lib; };
cfg = config.krebs.airdcpp;
out = {
@ -266,14 +265,14 @@ let
};
users = lib.mkIf (cfg.user == "airdcpp") {
users.airdcpp = {
uid = slib.genid "airdcpp";
uid = genid "airdcpp";
home = cfg.stateDir;
createHome = true;
isSystemUser = true;
group = "airdcpp";
inherit (cfg) extraGroups;
};
groups.airdcpp.gid = slib.genid "airdcpp";
groups.airdcpp.gid = genid "airdcpp";
};
};
in

View File

@ -1,21 +1,20 @@
{ config, pkgs, lib, ... }:
let
slib = import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
{ config, pkgs, ... }: let
cfg = config.krebs.announce-activation;
announce-activation = pkgs.writeDash "announce-activation" ''
set -efu
message=$(${cfg.get-message})
exec ${pkgs.irc-announce}/bin/irc-announce \
${slib.shell.escape cfg.irc.server} \
${slib.shell.escape (toString cfg.irc.port)} \
${slib.shell.escape cfg.irc.nick} \
${slib.shell.escape cfg.irc.channel} \
${lib.escapeShellArg cfg.irc.tls} \
${shell.escape cfg.irc.server} \
${shell.escape (toString cfg.irc.port)} \
${shell.escape cfg.irc.nick} \
${shell.escape cfg.irc.channel} \
${escapeShellArg cfg.irc.tls} \
"$message"
'';
default-get-message = pkgs.writeDash "announce-activation-get-message" ''
set -efu
PATH=${lib.makeBinPath [
PATH=${makeBinPath [
pkgs.coreutils
pkgs.gawk
pkgs.gnused
@ -29,37 +28,37 @@ let
'';
in {
options.krebs.announce-activation = {
enable = lib.mkEnableOption "announce-activation";
get-message = lib.mkOption {
enable = mkEnableOption "announce-activation";
get-message = mkOption {
default = default-get-message;
type = lib.types.package;
type = types.package;
};
irc = {
# TODO rename channel to target?
channel = lib.mkOption {
channel = mkOption {
default = "#xxx";
type = lib.types.str; # TODO types.irc-channel
type = types.str; # TODO types.irc-channel
};
nick = lib.mkOption {
nick = mkOption {
default = config.krebs.build.host.name;
type = slib.types.label;
type = types.label;
};
port = lib.mkOption {
port = mkOption {
default = 6667;
type = lib.types.int;
type = types.int;
};
server = lib.mkOption {
server = mkOption {
default = "irc.r";
type = slib.types.hostname;
type = types.hostname;
};
tls = lib.mkOption {
tls = mkOption {
default = false;
type = lib.types.bool;
type = types.bool;
};
};
};
config = lib.mkIf cfg.enable {
system.activationScripts.announce-activation = lib.stringAfter [ "etc" ] ''
config = mkIf cfg.enable {
system.activationScripts.announce-activation = stringAfter [ "etc" ] ''
${announce-activation}
'';
};

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }:
with lib;
with import <stockholm/lib>;
let
acng-config = pkgs.writeTextFile {
name = "acng-configuration";

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
out = {
options.krebs.backup = api;

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with lib;
with import <stockholm/lib>;
let
gunicorn = pkgs.python3Packages.gunicorn;
bepasty = pkgs.bepasty;

View File

@ -1,5 +1,5 @@
{ config, pkgs, lib, ... }:
with lib;
with import <stockholm/lib>;
{ config, pkgs, ... }:
let
cfg = config.krebs.bindfs;
in {

View File

@ -1,7 +1,6 @@
{ pkgs, config, lib, ... }:
with lib;
{ pkgs, config, ... }:
with import <stockholm/lib>;
let
slib = import ../../lib/pure.nix { inherit lib; };
cfg = config.krebs.brockman;
in {
options.krebs.brockman = {
@ -15,7 +14,7 @@ in {
group = "brockman";
createHome = true;
isSystemUser = true;
uid = slib.genid_uint31 "brockman";
uid = genid_uint31 "brockman";
};
users.groups.brockman = {};

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
{ config, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
{
options.krebs.build = {

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
cfg = config.krebs.ci;
@ -24,7 +25,7 @@ let
};
hostname = config.networking.hostName;
getJobs = pkgs.writers.writeDash "get_jobs" ''
getJobs = pkgs.writeDash "get_jobs" ''
set -efu
${pkgs.nix}/bin/nix-build --no-out-link --quiet --show-trace -Q ./ci.nix >&2
json="$(${pkgs.nix}/bin/nix-instantiate --quiet -Q --eval --strict --json ./ci.nix)"
@ -115,7 +116,7 @@ let
build_script = stages[stage],
),
timeout = 3600,
command="${pkgs.writers.writeDash "build.sh" ''
command="${pkgs.writeDash "build.sh" ''
set -xefu
profile=${shell.escape profileRoot}/$build_name
result=$("$build_script")

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }:
with lib;
with import <stockholm/lib>;
let
cfg = config.krebs.current;

View File

@ -1,62 +1,170 @@
{ config, lib, ... }:
{
imports = [
../../kartei
./acl.nix
./airdcpp.nix
./announce-activation.nix
./apt-cacher-ng.nix
./backup.nix
./bepasty-server.nix
./bindfs.nix
./brockman.nix
./build.nix
./cachecache.nix
./ci
./current.nix
./dns.nix
./exim-retiolum.nix
./exim-smarthost.nix
./exim.nix
./fetchWallpaper.nix
./git.nix
./github
./go.nix
./hidden-ssh.nix
./hosts.nix
./htgen.nix
./iana-etc.nix
./iptables.nix
./kapacitor.nix
./konsens.nix
./krebs.nix
./krebs-pages.nix
./monit.nix
./nixpkgs.nix
./on-failure.nix
./os-release.nix
./per-user.nix
./permown.nix
./power-action.nix
./reaktor2.nix
./realwallpaper.nix
./repo-sync.nix
./retiolum-bootstrap.nix
./secret.nix
./setuid.nix
./shadow.nix
./ssh.nix
./sitemap.nix
./ssl.nix
./sync-containers.nix
./sync-containers3.nix
./systemd.nix
./tinc.nix
./tinc_graphs.nix
./upstream
./urlwatch.nix
./users.nix
./xresources.nix
./zones.nix
with import <stockholm/lib>;
let
cfg = config.krebs;
out = {
imports = [
../../kartei
../../submodules/disko/module.nix
./acl.nix
./airdcpp.nix
./announce-activation.nix
./apt-cacher-ng.nix
./backup.nix
./bepasty-server.nix
./bindfs.nix
./brockman.nix
./build.nix
./cachecache.nix
./ci
./current.nix
./dns.nix
./exim-retiolum.nix
./exim-smarthost.nix
./exim.nix
./fetchWallpaper.nix
./git.nix
./github
./go.nix
./hidden-ssh.nix
./hosts.nix
./htgen.nix
./iana-etc.nix
./iptables.nix
./kapacitor.nix
./konsens.nix
./krebs-pages.nix
./monit.nix
./nixpkgs.nix
./on-failure.nix
./os-release.nix
./per-user.nix
./permown.nix
./power-action.nix
./reaktor2.nix
./realwallpaper.nix
./repo-sync.nix
./retiolum-bootstrap.nix
./secret.nix
./setuid.nix
./shadow.nix
./sitemap.nix
./ssl.nix
./sync-containers.nix
./sync-containers3.nix
./systemd.nix
./tinc.nix
./tinc_graphs.nix
./upstream
./urlwatch.nix
./users.nix
./xresources.nix
./zones.nix
];
options.krebs = api;
config = lib.mkIf cfg.enable imp;
};
api = {
enable = mkEnableOption "krebs";
zone-head-config = mkOption {
type = with types; attrsOf str;
description = ''
The zone configuration head which is being used to create the
zone files. The string for each key is pre-pended to the zone file.
'';
# TODO: configure the default somewhere else,
# maybe use krebs.dns.providers
default = {
# github.io -> 192.30.252.154
"krebsco.de" = ''
$TTL 86400
@ IN SOA dns19.ovh.net. tech.ovh.net. (2015052000 86400 3600 3600000 86400)
IN NS ns19.ovh.net.
IN NS dns19.ovh.net.
'';
};
};
};
imp = lib.mkMerge [
{
services.openssh.hostKeys =
let inherit (config.krebs.build.host.ssh) privkey; in
mkIf (privkey != null) [privkey];
services.openssh.knownHosts =
filterAttrs
(knownHostName: knownHost:
knownHost.publicKey != null &&
knownHost.hostNames != []
)
(mapAttrs
(hostName: host: {
hostNames =
concatLists
(mapAttrsToList
(netName: net:
let
aliases =
concatLists [
shortAliases
net.aliases
net.addrs
];
shortAliases =
optionals
(cfg.dns.search-domain != null)
(map (removeSuffix ".${cfg.dns.search-domain}")
(filter (hasSuffix ".${cfg.dns.search-domain}")
net.aliases));
addPort = alias:
if net.ssh.port != 22
then "[${alias}]:${toString net.ssh.port}"
else alias;
in
map addPort aliases
)
host.nets);
publicKey = host.ssh.pubkey;
})
(foldl' mergeAttrs {} [
cfg.hosts
{
localhost = {
nets.local = {
addrs = [ "127.0.0.1" "::1" ];
aliases = [ "localhost" ];
ssh.port = 22;
};
ssh.pubkey = config.krebs.build.host.ssh.pubkey;
};
}
]));
programs.ssh.extraConfig = concatMapStrings
(net: ''
Host ${toString (net.aliases ++ net.addrs)}
Port ${toString net.ssh.port}
'')
(filter
(net: net.ssh.port != 22)
(concatMap (host: attrValues host.nets)
(mapAttrsToList
(_: host: recursiveUpdate host
(optionalAttrs (cfg.dns.search-domain != null &&
hasAttr cfg.dns.search-domain host.nets) {
nets."" = host.nets.${cfg.dns.search-domain} // {
aliases = [host.name];
addrs = [];
};
}))
config.krebs.hosts)));
}
];
}
in out

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; }; {
with import <stockholm/lib>;
{ config, ... }: {
options = {
krebs.dns.providers = mkOption {
type = types.attrsOf types.str;
@ -8,7 +8,7 @@ with import ../../lib/pure.nix { inherit lib; }; {
type = types.nullOr types.hostname;
};
};
config = lib.mkIf config.krebs.enable {
config = mkIf config.krebs.enable {
krebs.dns.providers = {
"krebsco.de" = "zones";
shack = "hosts";

View File

@ -1,5 +1,5 @@
{ config, pkgs, lib, ... }:
with import ../../lib/pure.nix { inherit lib; }; let
with import <stockholm/lib>;
{ config, pkgs, lib, ... }: let
cfg = config.krebs.exim-retiolum;
# Due to improvements to the JSON notation, braces around top-level objects

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
cfg = config.krebs.exim-smarthost;

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }: with import ../../lib/pure.nix { inherit lib; }; let
{ config, lib, pkgs, ... }: with import <stockholm/lib>; let
cfg = config.krebs.exim;
in {
options.krebs.exim = {

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
cfg = config.krebs.fetchWallpaper;

View File

@ -6,14 +6,14 @@
# TODO when authorized_keys changes, then restart ssh
# (or kill already connected users somehow)
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let
cfg = config.krebs.git;
out = {
options.krebs.git = api;
config = with lib; lib.mkIf cfg.enable (mkMerge [
(lib.mkIf cfg.cgit.enable cgit-imp)
config = with lib; mkIf cfg.enable (mkMerge [
(mkIf cfg.cgit.enable cgit-imp)
git-imp
]);
};
@ -446,7 +446,7 @@ let
];
locations."/".extraConfig = ''
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME ${pkgs.writers.writeDash "cgit-wrapper" ''
fastcgi_param SCRIPT_FILENAME ${pkgs.writeDash "cgit-wrapper" ''
set -efu
exec 3>&1
${pkgs.cgit}/cgit/cgit.cgi "$@" 2>&1 >&3 3>&- \

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with lib;
with import <stockholm/lib>;
let
cfg = config.krebs.github-hosts-sync;

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with lib;
with import <stockholm/lib>;
let
cfg = config.krebs.go;

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
with lib;
with import <stockholm/lib>;
let
cfg = config.krebs.hidden-ssh;

View File

@ -1,19 +1,17 @@
{ config, lib, pkgs, ... }:
with lib; let
with import <stockholm/lib>;
{ config, ... }: let
check = hostname: any (domain: hasSuffix ".${domain}" hostname) domains;
domains = attrNames (filterAttrs (_: slib.eq "hosts") config.krebs.dns.providers);
# we need this import because we have infinite recursion otherwise
slib = import ../../lib/pure.nix { inherit lib; };
domains = attrNames (filterAttrs (_: eq "hosts") config.krebs.dns.providers);
in {
options = {
krebs.hosts = mkOption {
default = {};
type = types.attrsOf slib.types.host;
type = types.attrsOf types.host;
};
};
config = lib.mkIf config.krebs.enable {
config = mkIf config.krebs.enable {
networking.hosts =
filterAttrs
(_name: value: value != [])
@ -93,7 +91,7 @@ in {
(concatLists (attrValues netAliases));
}
//
slib.genAttrs' (attrNames netAliases) (netname: rec {
genAttrs' (attrNames netAliases) (netname: rec {
name = "krebs-hosts-${netname}";
value = writeHosts name netAliases.${netname};
});

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