moved all to subfolder nixos
This commit is contained in:
parent
78d39395b7
commit
15c6866362
263 changed files with 638 additions and 762 deletions
nixos
assets
configs
dummy
mobi
pepe
borg.nixconfiguration.nixdms.nixhardware-configuration.nixhome-assistant.nix
home-assistant
chaospott.nixiot-control.nixkodi.nixlight-control.nixmpd.nixmqtt.nixsonoff.nixstocks.nixtimer.nixweather.nixworkday.nixzigbee2mqtt.nix
kodi.nixlan.nixsyncthing.nixtinc.nixwifi-access-point.nixzigbee2mqtt
porani
configuration.nixhardware-configuration.nixkodi.nixmpd.nixpackages.nixsyncthing.nixtinc.nixwifi-access-point.nixwifi-networking.nix
sputnik
bitwarden.nixcodimd.nixconfiguration.nixhardware-configuration.nixiodined.nixnginx.nixsyncplay.nixtinc.nix
sternchen
configuration.nixhardware-configuration.nixpackages.nixsyncthing.nixtinc.nixwifi-access-point.nixwireshark.nix
sterni
configuration.nixhardware-configuration.nixpackages.nixsyncthing.nixtinc.nixwifi-access-point.nixwireshark.nix
workhorse
105
nixos/assets/jack.sh
Executable file
105
nixos/assets/jack.sh
Executable file
|
|
@ -0,0 +1,105 @@
|
|||
set -e
|
||||
|
||||
defaultDevice=PCH
|
||||
|
||||
start_jack(){
|
||||
|
||||
internal_device_number=-1
|
||||
komplete_device_number=$(aplay -l | grep Vestax | cut -d":" -f1 | cut -d" " -f2)
|
||||
babyface_device_number=$(aplay -l | grep Babyface | cut -d":" -f1 | cut -d" " -f2)
|
||||
cmedia_device_number=$(aplay -l | grep C-Media | cut -d":" -f1 | cut -d" " -f2)
|
||||
h2n_device_number=$(aplay -l | grep H2n | cut -d":" -f1 | cut -d" " -f2)
|
||||
|
||||
# this should be more readable some day
|
||||
if [[ $babyface_device_number == "" ]]; then
|
||||
if [[ $komplete_device_number == "" ]]; then
|
||||
if [[ $cmedia_device_number == "" ]]; then
|
||||
if [[ $h2n_device_number == "" ]]; then
|
||||
echo "use : default device"
|
||||
device_number=$internal_device_number
|
||||
else
|
||||
echo "use : h2n"
|
||||
device_number=$h2n_device_number
|
||||
fi
|
||||
else
|
||||
echo "use : c-media"
|
||||
device_number=$cmedia_device_number
|
||||
fi
|
||||
else
|
||||
echo "use : komplete"
|
||||
device_number=$komplete_device_number
|
||||
fi
|
||||
else
|
||||
echo "use : babyface"
|
||||
device_number=$babyface_device_number
|
||||
fi
|
||||
|
||||
# device parameter configuration
|
||||
# ==============================
|
||||
#
|
||||
# to find configuration options do
|
||||
# jack_control dp
|
||||
if [[ $device_number -eq -1 ]]
|
||||
then
|
||||
# we use alsa in reality, but pulse opens up all the pulse
|
||||
# sink and source stuff
|
||||
# jack_control ds pulse # not working for some reason
|
||||
jack_control ds alsa
|
||||
jack_control dps device hw:$defaultDevice
|
||||
else
|
||||
jack_control ds alsa
|
||||
jack_control dps device hw:$device_number # use usb card
|
||||
fi
|
||||
|
||||
jack_control dps duplex True # record and playback ports
|
||||
jack_control dps hwmon False # no hardware monitoring
|
||||
jack_control dps rate 48000 # use cd sample rate
|
||||
|
||||
|
||||
# nperiods are the splitup of the
|
||||
# sound-ring-buffer. 2 are ok for internal cards
|
||||
# but for usb you should use 3 because
|
||||
# you can have to write in junks to the card
|
||||
# so there is one backup slice in the middle
|
||||
if [[ $internal_device_number -ne -1 ]]
|
||||
then
|
||||
jack_control dps nperiods 3
|
||||
fi
|
||||
|
||||
# engine parameter configuration
|
||||
# ==============================
|
||||
#
|
||||
# to find configuration options do
|
||||
# jack_control ep
|
||||
jack_control eps sync True
|
||||
|
||||
# realtime kernel
|
||||
# set True for using a realtime kernel
|
||||
jack_control eps realtime False
|
||||
# set priority if realtime kernel is set True
|
||||
# jack_control eps realtime-priority 10
|
||||
|
||||
jack_control start
|
||||
}
|
||||
|
||||
stop_jack(){
|
||||
jack_control exit
|
||||
}
|
||||
|
||||
status_jack() {
|
||||
jack_control dp
|
||||
jack_control ep
|
||||
jack_control status
|
||||
}
|
||||
|
||||
|
||||
case $1 in
|
||||
start) start_jack
|
||||
;;
|
||||
stop) stop_jack
|
||||
;;
|
||||
restart) stop_jack ; start_jack
|
||||
;;
|
||||
*) status_jack
|
||||
;;
|
||||
esac
|
||||
50
nixos/assets/music-making.sh
Normal file
50
nixos/assets/music-making.sh
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
function stop_program(){
|
||||
echo "stop $1"
|
||||
sudo systemctl stop $1
|
||||
}
|
||||
|
||||
function start_program(){
|
||||
echo "start $1"
|
||||
sudo systemctl stop $1
|
||||
}
|
||||
|
||||
|
||||
function start(){
|
||||
echo "starting programs again"
|
||||
echo "-----------------------"
|
||||
echo
|
||||
start_program backup.on-porani.insecure.timer
|
||||
start_program backup.on-workhorse.insecure.timer
|
||||
start_program backup.on-workout.insecure.timer
|
||||
start_program syncthing.service
|
||||
start_program tlp.service
|
||||
start_program tor.service
|
||||
}
|
||||
|
||||
function stop(){
|
||||
echo "stopping programs"
|
||||
echo "-----------------"
|
||||
echo
|
||||
stop_program backup.on-porani.insecure.timer
|
||||
stop_program backup.on-workhorse.insecure.timer
|
||||
stop_program backup.on-workout.insecure.timer
|
||||
stop_program syncthing.service
|
||||
stop_program tlp.service
|
||||
stop_program tor.service
|
||||
}
|
||||
|
||||
|
||||
# ----
|
||||
# main
|
||||
# ----
|
||||
|
||||
|
||||
stop
|
||||
|
||||
echo
|
||||
echo -n "wait to start again -> "
|
||||
read
|
||||
echo
|
||||
|
||||
start
|
||||
39
nixos/assets/nginx-show-config.sh
Normal file
39
nixos/assets/nginx-show-config.sh
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -p nginx-config-formatter python3 -i python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
|
||||
def nginx_config() -> str:
|
||||
reload_config ="/etc/nginx/nginx.conf"
|
||||
if os.path.exists(reload_config):
|
||||
return reload_config
|
||||
out = subprocess.check_output(["systemctl", "cat", "nginx"])
|
||||
match = re.search(r"-c '(\S+-nginx\.conf)", out.decode("utf-8"))
|
||||
if not match:
|
||||
print("Could not find nginx.conf in nginx.service", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def main():
|
||||
config_path = nginx_config()
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
temp_path = os.path.join(temp_dir, "nginx.conf")
|
||||
with open(temp_path, "wb+") as temp_file, \
|
||||
open(config_path, "rb") as config_file:
|
||||
shutil.copyfileobj(config_file, temp_file)
|
||||
temp_file.flush()
|
||||
subprocess.check_call(["nginxfmt", temp_file.name])
|
||||
editor = os.environ.get("EDITOR", "cat")
|
||||
subprocess.check_call([editor, temp_file.name] + sys.argv[1:])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
57
nixos/assets/shrink_exports
Executable file
57
nixos/assets/shrink_exports
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
PROJECTS_FOLDER=~/music-projects/Rendered-Projects
|
||||
GARBADGE_FOLDER=/share
|
||||
|
||||
# file separator (needed to handle files with spaces)
|
||||
IFS="
|
||||
"
|
||||
|
||||
function info_log(){
|
||||
echo -n ">>> [ "
|
||||
echo -n $@
|
||||
echo " ]"
|
||||
}
|
||||
|
||||
function run_ffmpeg(){
|
||||
local input=$1
|
||||
local output=$2
|
||||
|
||||
info_log "ffmpeg : ${output}"
|
||||
ffmpeg \
|
||||
-i "${input}" \
|
||||
-f mp3 \
|
||||
-codec:a libmp3lame \
|
||||
-qscale:a 5 \
|
||||
-ar 44100 \
|
||||
-loglevel error \
|
||||
-af loudnorm \
|
||||
"${output}"
|
||||
}
|
||||
|
||||
function delete(){
|
||||
local input=$1
|
||||
|
||||
if [[ -e "${input}" ]]
|
||||
then
|
||||
info_log "move : ${input} to ${GARBADGE_FOLDER}"
|
||||
mv "${input}" "${GARBADGE_FOLDER}/$(basename ${input})"
|
||||
#info_log "delete : ${input}"
|
||||
#rm "${input}"
|
||||
fi
|
||||
}
|
||||
|
||||
for file in `ls ${PROJECTS_FOLDER} | grep wav$`
|
||||
do
|
||||
filename=`basename ${file} .wav`
|
||||
mp3="${filename}.mp3"
|
||||
|
||||
info_log ${filename}
|
||||
|
||||
delete "${PROJECTS_FOLDER}/${mp3}"
|
||||
run_ffmpeg "${PROJECTS_FOLDER}/${file}" "${PROJECTS_FOLDER}/${mp3}"
|
||||
delete "${PROJECTS_FOLDER}/${file}"
|
||||
|
||||
done
|
||||
3
nixos/assets/sprueche-axel
Normal file
3
nixos/assets/sprueche-axel
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
"Fernsehen ist für mich der Elektro-Jude" - Dr Axel Stoll
|
||||
"Der Zellkern ist gleich pures Licht" - Dr Axel Stoll
|
||||
"Die Sonne ist Kalt!" - Dr Axel Stoll
|
||||
18
nixos/assets/sprueche-siw
Normal file
18
nixos/assets/sprueche-siw
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
"Also Attracktiv oder net, ich seh hier immer noch am Besten aus" - Reiker
|
||||
"Hör mal auf dich selber zu bemitleiden, sonst baft das aber echt jetzt! Dummer Lutscher" - Käpten Pika
|
||||
"Komm Junge is besser du gibs dat jetzt zu, dann haste wenigsten noch ein paar Jahre wat von deinen Zähnen" - Käpten Pika
|
||||
"Ich sauf doch net mit euch Pennern, echt Ey" - Käpten Pika
|
||||
"Ja toll dann hab ich ja schon wieder verloren" - Deiter
|
||||
"Komisch! Mein Vater heißt auch Vater, aber sieht ganz anders aus!" - Reiker
|
||||
"Sag noch einmal Junge, Junge!" - Käpten Pika
|
||||
"Häää? Worte, was sind Worte?" - Reiker
|
||||
"Ich hau dir gleich die Zähne aus deiner fiesen Schnauze!" - Käpten Pika
|
||||
"Ihr glaubt wohl ich kann keine schlauen Sachen sagen, wa? Schlaue Sachen!!" - Reiker
|
||||
"Jetzt... also ich raff das jetzt echt net. Ist das so kompliziert?" - Reiker
|
||||
"Dat is hier die Molekularsymplexion über trivial-komplexive Plasmakonvergenzen, wie? Wat?" - Jordi
|
||||
"Äh, äh, Junge? Ey, Junge, echt jetz! Weißte?" - Käpten Pika
|
||||
"Deine Dummheit unterscheidet meinen Datentransfer" - Computer
|
||||
"Ähh, komisch mein Vadder sieht ganz anders aus, obwohl der auch Vadder heißt." - Reiker
|
||||
"Aaaaaah, ich kann nimmer" - Reiker
|
||||
"Also ich hab keine Gummipuppe. Nur Gummibärchen." - Reiker
|
||||
"Richtig heisser, kochend heisser Kaffee" - Käpten Pika
|
||||
1
nixos/assets/ssh/borg_access.pub
Normal file
1
nixos/assets/ssh/borg_access.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC/WCoJ9zSL85R1mNJHUGRofyigeg2+g4+bwWVysHxWroPMIpP2hJrMRPoP13SAOaLOjl6X112jjoQ2wpJ/qptjtojrsF8bpFgoMqCQFsQDD4zuG4V/AaIt0nAF4B5tDBGFN3Hj6vpbwVAidv+8Kr41r5JOG/8Z/UiJDGrIMab3kDwyOklrMPLWr7IBYC0O8Jwyz3lAl18ukMSEZvoPaJhPJyyqRhSagX59U7AQiNrnq18kzi7Pszy3e1d7x3vWSXemJGZaUJ+cFbl1LrvFHwUa55sSUVUVBRxgABc906YoiUcr31aw98zUX4W+2+AqDzIIquV5frIc/+nnfsmDrsnMl81cLglxuRxqib0AuSYqkNQimWrR61M7TaLvGZomMk8Vheew/QlxvHvhbHwnu7/tgNll2i+Zi1T7VZ5Hcy4quYDZQA7NDrvu0dEm+dTlOfuJJZdMLWws20ao8xtv8IxxCN31CBCbCSETpsSuvT7joHKGpJoOf3eilLLqOKjrbo5E6s6S1w1WRoZ6LuXQo2l5uvMVSzUZ+4CG+FX+Q73bpQ5SWUvz2o5HovX8RbcneuG7mfZMe80F5IyaqSmi0r+kFOqK4NKz/InHhSJjrFYJWl2PP+30MfsHx5NMOVhfKdRZje5oTds6L2o9+3vhiE7CmgZVR+RqMHMUtRrERODwPQ==
|
||||
1
nixos/assets/ssh/card_rsa.pub
Normal file
1
nixos/assets/ssh/card_rsa.pub
Normal file
|
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6uza62+Go9sBFs3XZE2OkugBv9PJ7Yv8ebCskE5WYPcahMZIKkQw+zkGI8EGzOPJhQEv2xk+XBf2VOzj0Fto4nh8X5+Llb1nM+YxQPk1SVlwbNAlhh24L1w2vKtBtMy277MF4EP+caGceYP6gki5+DzlPUSdFSAEFFWgN1WPkiyUii15Xi3QuCMR8F18dbwVUYbT11vwNhdiAXWphrQG+yPguALBGR+21JM6fffOln3BhoDUp2poVc5Qe2EBuUbRUV3/fOU4HwWVKZ7KCFvLZBSVFutXCj5HuNWJ5T3RuuxJSmY5lYuFZx9gD+n+DAEJt30iXWcaJlmUqQB5awcB1S2d9pJ141V4vjiCMKUJHIdspFrI23rFNYD9k2ZXDA8VOnQE33BzmgF9xOVh6qr4G0oEpsNqJoKybVTUeSyl4+ifzdQANouvySgLJV/pcqaxX1srSDIUlcM2vDMWAs3ryCa0aAlmAVZIHgRhh6wa+IXW8gIYt+5biPWUuihJ4zGBEwkyVXXf2xsecMWCAGPWPDL0/fBfY9krNfC5M2sqxey2ShFIq+R/wMdaI7yVjUCF2QIUNiIdFbJL6bDrDyHnEXJJN+rAo23jUoTZZRv7Jq3DB/A5H7a73VCcblZyUmwMSlpg3wos7pdw5Ctta3zQPoxoAKGS1uZ+yTeZbPMmdbw== cardno:000611343142
|
||||
14
nixos/assets/tinc/mobi_host_file
Normal file
14
nixos/assets/tinc/mobi_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = 94CccmfAuNtQzopd5NiVYjTjZvSgabMh66BI/iyVmnJ
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA8m9cBRv+9K8ywH19CZKDidwmzEa+2j3rkFjek+uPLVCHX5FlVQv+
|
||||
flX5fY06DuaPzWKf4MoXHxmVa9T/WOcKZJUmhSJC2AVorhuPihOx0FNrQr69bamy
|
||||
x03fiH0pHmDXumNdGMUcNf+06Zu2Nr9yze8rE1B97zb0RPBf+XC1uHw4E4PrWC/F
|
||||
swibj9U45bp07wFvJrkAsngw4c6+TFERW6TK5DPKDQs7KfgdsqFGLvg2cY5phwC1
|
||||
08HBC7eTf2xG6paaS7gEbhDMQ/K47Lbhbv2srnYfaBw5iyc8f29ZwEuNfE4V15B3
|
||||
foz/kGAhceTuBKNCVvKvqSIL2yEsibFVyl7zlgGp3EKWuR5ETQAspJViGILwiyq6
|
||||
iRYQ1AxxyroqS146CUAB8/68w0PwroKt8lXMEtx58S7/OAW0KnXGxwqSfocH+iE4
|
||||
qry9pPuSs7RR6lXBB0nvSfTbaZDMUXtiyV24+pyZgl5Q31kDgUWgFpzGRBc/CTO2
|
||||
h8OmUcvEyLxh3bruu0SQGXa35G1Igsumuh/uLifgHB/odLYY00PhEdpp52BswgXe
|
||||
yz88nfXMOyvm7ROEyA7r2qruM1kEHDSQ8IRuxhd8YebyI7k6mYVE8CR5T89QfVl3
|
||||
mrNk+f6Q/cpFiNBxr7+UBCiHix3/GDAD4NEgvu5nfqinTA34FuscTS8CAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/pepe_host_file
Normal file
14
nixos/assets/tinc/pepe_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = LnE+w6ZfNCky4Kad3TBxpFKRJ2PJshkSpW6mC3pcsPI
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEAmAyz71GoQq2Mn4XeUVcN9yfgxeWT57li7i6Te9lq7OVAXQ+CBtD3
|
||||
puTMrW3/LXOIS678E2iMYPmdQzMZLmADi8+ZrXOqX98uceNv5bPrTJF0z/RA9Tif
|
||||
kfh78GcJCGHmZz+GGWu1ExtSa5ekBdamEtehW6vAGbrPM6Umu9B2UCn8zaSx+RGe
|
||||
Y7Z81wO21+ywUorMPTbHeuPYZW+Z8L+QKHO9NdYhzZ9zMPeVMi0x/mwIZqXJ57Wz
|
||||
57nx0rrPh+e+5cj3Jh+i4HC76mxPGCyCdvf+60d7W87UZxPqRiTLt2SwgltEKf56
|
||||
jBsVeOb5Fjzb6LcNGWfF8zNh0w6rAQsG4W7l93VlerTd46GtG2XW42JkGhuKb8JJ
|
||||
L1olPUmbcDbxlQGGUNaI7thAzubszAzinqyat3oU8NjgDJJIueHLmo752RW+yHUY
|
||||
giyRSBYtDRM9cE3s848WsToO5BtjXLkg/rC4WIWX2MNJFsAZXzfHWDmae+ajpoVy
|
||||
Gl6tGYbLhjd8KtSWB9kB0OWsV56f4KmWeRxHwTgylMO30l6v+XRdnoRUAp9wj8dV
|
||||
c6HJHnn5b2q4dk+qwWOYgwvpRFnSixbCCT4PoedEU9xVOzLmzxRtGmkzPsOXEOj5
|
||||
6r4Jvk0jw2LTkhEVX1CPblTrGpms9NO02SXNHkF/Akw7PGuJu+w3HZUCAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/porani_host_file
Normal file
14
nixos/assets/tinc/porani_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = 9JI8y56NWiKMRS6g/k2H3VgTEw0q+8UEDDJdiCjOl8O
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA4Ff6XRvf83XSuWUkb70Yz+cWo1/dq4LBh5ZG7SJypdIXYnWQpQJc
|
||||
sLRfAS6nJZ6VixNADx7A03c8TdADVaAgl591rLd4CSzM22EgaOFstU2VO/MfMKHf
|
||||
v+WUQsrTE6CQ48SW+MDbSZZ7M7FRa/A6hwqZc5qygxdG/tgTei9pmTfqW+ZdQBWl
|
||||
IeCCINiNSA/fD+FjWXslZIFRZ5sQ7AYZJgL2nFAueY+cKtRZy3tcDL1v6mhDdIrE
|
||||
h8JjEUiayQDGnWmBlflLqE3ODqEsEKoL6W7epqK6PcwvZQxSNwrZe/wzH3oTC43m
|
||||
Yg7TQGr0v3SnSziXv3cJvcHfwr9+huo37wTbUJNmozGpI8nLszfUTEIfhbu2ODQv
|
||||
R2iM7FJcE4wV48y9aybEnESKA0vsjgI23RIQfxkN0oii7L6NAZVHgl/JJBOtCMXf
|
||||
V5uXAdOtkv9UvfofrrV0uahncvbz5efPTSPF8fS5EiwzWfDUW6KHrp/9+gDcnirn
|
||||
H8HvmmNVeOGWA1xlrKgi8kiBHv5BxCXfurD0aD6ZIlxdLjJCvGfnLnJZ6gr//GAf
|
||||
1BJJVei98uZzihNe4VbRF6Iaphns1KezsdygMsEV9gDIJw3IIqTukcUK7AcBXhb4
|
||||
IJ792j2iRwUOyiAcUYLeVYzAt3xFN6wPNcC/Opdo6TVbdMZu2uS1ZN8CAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/retiolum/host_file
Normal file
14
nixos/assets/tinc/retiolum/host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = kc1SACqsoYjk5GimZfP+eszfJmUzZkMQhWeW42UKjfL
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA2ACttoosnRZ99o+OyMrxBdUWPqsT5btzSIQ5dU1XWqGjO4nRchCE
|
||||
8tO0b/4jqVgJVTRZVIUJQESZRlSmclsCAjdM8tsGj74CJrm7tBvgbBn2IObSs5+4
|
||||
oJWe57VsQaeHPuI2JZuGqv8Z3Esw+B07bQS5VTaC1ISo7vnLG/q5XLCbKHB9JZc/
|
||||
ztYbk4bEQHwbulfoPjD9FY3heLnTzqPw9Xr3ixao5gbAXfWNJM+iCluMq+Q2g1BD
|
||||
ozSnyYvaGLQ6h4yksDp+xuK8YCqiRj174EkXySI8Jee1CBMuI8ciX/5Q7yzvzscQ
|
||||
ZQ/MLVdx3MRW+VeT0ctaRzoA9E09ILqPe+56DjpsKzt4Ne8qeMG5HdpzO9UdNzTu
|
||||
MuibsCL7CJy5Ytl38PK+LAXHQr3Os1Z4OHjeTZ38vTAZcOUJZEkl6w9nO1XjcyBL
|
||||
rIaG+20Nx0ZU79MlJZFiG7ovlUiDfIEKNygng8v/yoTMaqMYLxQZ/leQwLMNLujo
|
||||
sku8+oV4Jvx4SyUjuAS6jgG9CnejLCnHP/yyDGdaMQSzmlzYXacLMfnPZE3r7bj1
|
||||
EjA6yQbkPixm7xLCyMm5u2leWtqtbg1oRA6Mw3UyYkNy3hiTU+jTvztEI3SCliDH
|
||||
yjGlESH4/edryKjLNjmYP77VFbM9ZSQ+QGlbMGPvjcn6XCdJGdxm3PUCAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/sputnik_host_file
Normal file
14
nixos/assets/tinc/sputnik_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = ZK9iznseTpMqjaMgDJ7MdjYaq62QlEOFquLfVxlLpFK
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEAzBU8x9aB7F3sPJlcg9avJiSrsAoTHsMkfk6uRKFVjUjuNJgb3rjW
|
||||
gyQ7krftLAyxLkTYJzpD+4D+qWiudEgju7W+BU65/hudMIvBmbRYqXmcQlD9B9Pv
|
||||
0bVAazHJ80wN8GJD060Wq6XTtkrtAJhPmQSyMt0xU4WmWw/39QBX9rWtOTy75813
|
||||
qrfuv1I11YcVQ3jegPLUIzlZqz6LeouCXiP7IRIa+WUXIwAdAYtO/RJC+tty6zyI
|
||||
BXNd0Mkvpf0Qaw5joQJRXkdb1sWHOZYh75JW1QWqFMWCclkGG7/Dve4KzuO9N5XZ
|
||||
ZMs/MCtDkJQpweNDT3aaiqZa8Oj29OXs4HR4FFrvYkY+qqmKCUqS70FYLo45uNx1
|
||||
sRb7GKX8/dsPyOGHfXDuFTSXsKLh9gNLMlF/kuTQ2yJMfeMKdC5jDClL145Fm0ux
|
||||
akH/PWSS9DENxSu0GH1sTQnLyhc4mVzOehu1XfR9EALjYY0BNBUir7aAaiLTCbq9
|
||||
LKwMaF/D467W3j3Zp5xEAsf8xYC2CyMl1Df43zxcxLY+3K8/kUM2rkU7ocl2VT3o
|
||||
7yNC+JqQz41n4SDOXBZc6cfxUXj2MqqEw9Ywgs+aXZiSCaVOulhyXj0TSE1mX1NI
|
||||
woDHEzyx7q4AryQOWQsLq5JimI0v2/xN2yz+cNXoetDypjEWnws4e/ECAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/sternchen_host_file
Normal file
14
nixos/assets/tinc/sternchen_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = Z567IKl00Kw5JFBNwMvjL33QYe2hRoNtQcNIDFRPReB
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA1vhCFsFK0QSYDlXSS6ngpZbilplYtaPBzbxWYGAxa5vNtwoaO2Tz
|
||||
BZ4ptvE26TR2+Jygvlk5xdoNYAL/yhNI9p86vs/pA+sJmBlsYAWOA5qAnXoIL2u4
|
||||
1CBB9t+uMnQKhyPoBoDq6QXmM1HlFhxtkKVlLyEHxARxu7g/inFtghPqYD/HyjVJ
|
||||
V6h9OdKEgY+wcn6GGLXGjrSMAsIZP2w8fPQfS45UAtjK+cFODFKElxGZrjqgJP1w
|
||||
/Jw6nB03yKMGsMHNkiwC2BJbK3+pT92JfyqXRg3REw0hVMZghcsoNtWfBoNYLvFY
|
||||
qwk+bvf5bVdLxLMEv33+B3F8SScXuwMUpBwCeMi58ltt+OuOVhh8PLA9ncA6tGa9
|
||||
tzyUo7i8qjGTremSilWIdRYqOexriPKCdnYcJcw/L9Vl2H3QbIj7uVxbszQbqDGS
|
||||
KM43U5cXgpMIYI9CwxnWB8np7n/IXZFG5E+9afd4kYTLShzaObzu2I1yom0O4Ks7
|
||||
HsdvlsBgv4iT6ctquHtU6IFsa/Wfm4ntDiAcczoQEXs0F2v839FH62TPTY70xzyd
|
||||
wQhAdCegb6MYVmVmQL9jv8QDfxwUxtsohbW3ncBDYrdy2rmeiZDGaRJVEbyf6MKI
|
||||
OfaobRGXY0NnOURX9/fkXSydDKd3rIhOMubfUq0+Smm3YrsHWeZVvNMCAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/sterni_host_file
Normal file
14
nixos/assets/tinc/sterni_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = Hm+YwSe6XiRNQD4HfJPgTB8UFVMyVi0vy+3ofMnW6jD
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEAu7Ajx9+mEaDK/ASZ5hoVj3X3IkWl+8MAhmj7dwnhqc4YrPrvwKE4
|
||||
cOnVcEUp4K4pyIHUG8zhsesstfpu/0owLQaz8Cekr4CyQWsjDfi7K/QiAN+v2O2m
|
||||
DQOjrYzDvRyBa20A2MnO1kZU/aFHE9qcIHefZhQUZyv97j+QcsE/FDuIH/RAua6/
|
||||
p+br2tfecePGH6f0fMk8dp+YbxcjjVyhJkjyaYF2r+n+YflDl5y3ngxUFJ0UnNE0
|
||||
RfYJf2NE1wzt4rIdnYobFP3vifDIeYj6M0LGHnURPsT6zP+zStZ81MYZKrNlTJ37
|
||||
sbZhorVmO6x46xEWaDUd7UqcKJBpb7u8iSAE4S3tHLFRxBs60dPS+3UEraiTvTHr
|
||||
FvWTq1Q+t/FivTxXEkVt74N5auOKbT5AAkztak21Izx6enspdx6da2aLuJD5I0OU
|
||||
3F4kd8lW5PqEZubkYziDwcVoNsx88hQzHi5l2aRdzY57o82+ltWw4xXmAFR2o605
|
||||
SwVJ4AUmORHuIoDYSR+UgbtKHguxVaTLVggdfvHzlDQ1VERwEU58awMwPLU1k+jP
|
||||
3QW7ehPLKRN+StB6LBlnmRD1ltkaPY5iy+NMXj17hJx0trpz3qoCuv+5TRvsGvQ7
|
||||
Je/G7c6suIGd4HbA9TvCinW6/JLbJQlDiG7MD2oCOPS1pdayUuB9Jw0CAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/workhorse_host_file
Normal file
14
nixos/assets/tinc/workhorse_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = sPs48jzCdtTv0Viy2Of3HlXipfxH5Y8bA+KYVkOrSiK
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA01HJ49zxmnixWC9YMP0c3UFxZc4Hl5UK9nJvhMRBOuxm75kpzZsz
|
||||
3v6mSy1YrVE9rrGXYjZ76wKrRhchMpvrMKKD8/DRjVqTkuFwtGgUEigzpSFoSLtC
|
||||
u2Wis7Z6GW3nLgAS79NU9IUUEoeevND1zzglDb0HdERuiImiZVg3I+VXLyA31X3L
|
||||
Z/B7T4QLmZGIRvFw0y1TawMjFMJZmDBtzMqfO7behkms2O1ORAciGhGxmZ9gd7yk
|
||||
n/NKCpSSzeC6sJ28i33LRrWF3hRUXAEJFgq8YRxm6mjRoPLsJVsw2S98DvTcxmjN
|
||||
eyVnqPVQi7JuKrOQsewQvwV2KiqI9ibEYH1zZNXwy+l05b3QSaAcyRtDpwRW7FCY
|
||||
H4B3S0vjte75D4bEuYTFgT3wCzlAjdB7fPZ4jyZXdrP8G3IfbMmgsdECz5uIMwam
|
||||
UaSZISlHkSJv+erA8TMJLBnqAO7ERKYI7PRIDdIun0VtX2QjRJpWIdVpxEcL4fZU
|
||||
w6gzX8lOQe5NnoH/MFUfU0LyBuUH1k6WX7xdwrynUVS087vwaQN+H/VTp0QSX6PQ
|
||||
oCLYPCGKS2B/St954uaPanzeG7QZQpWbvttaFVmUSkilx78xqqu3zDm9pSofFKCX
|
||||
08TGlluy8JAwUqAxekQVKey2PdLmKjlMCcoUeNYbJybGplc9gv2hYhsCAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
14
nixos/assets/tinc/workout_host_file
Normal file
14
nixos/assets/tinc/workout_host_file
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Ed25519PublicKey = r6mRDc814z2YtyG9ev/XXV2SgquqWR8n53V13xNXb7O
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA7/bur2JIXzNrsgjQ7kfoaLUVCC9S7HNNdDrlnSdum0sWvN9urdxS
|
||||
1OfzqG+kjDhQ0sS4fEeYyLMU8W3/aHkSbMjfKBiZS70bg5yHRepUEPZNqDqR3+rO
|
||||
LTAGWMi/IQQQmnfcN5SjaNY/ZyXoaPd1emlpV2UXBvXo/bQTl+pmOt7AIAh7Z7M6
|
||||
X5KAwU23kUwrfn/7zFCw98euNEPcCKpdF5oD4+G+S0PGfFvBmE6Xoi2blM1rcjJ4
|
||||
39IGVCsKAlW1Vg48yj7FypSSjaFvIW+kyRcNNTEZ4V5p50Vm7DfylfW96NqAOeuz
|
||||
2aSVaLhvmu8fU9z+g95MdGZOJYd57jFt76GbkwcLCF8KBCP9NhMfOQu0i1glk+AP
|
||||
CcJcDa/Oj7lLQVB2+holJhw5fkHH2Yi+L+UsjIF0iLiOSTjGJp4yRT9Al9pgMCj2
|
||||
O1JUMYxQ490mSFHBomNv1fq+f5VJnytEwAkJH6AgH+RIcAC5/r+sowfLv+Gy0ga8
|
||||
jKG6t9d/x6lRNv0x5sUhYkiUD9Naq0NncaZz1GtkBAyu+hUZx2+zg3r8He4XoiXx
|
||||
zWAQEgcW3X1/9VC7IBvaK9cdLG5pbeGCBaDv8S0Ue332mM0XNDlffjdC7Sg9f/TG
|
||||
YV8MHpR3RwwUqdi6WFPQqVz5Hv1pE02v/Uw6tby1UgAnzskrufPh+m8CAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
||||
61
nixos/configs/dummy/configuration.nix
Normal file
61
nixos/configs/dummy/configuration.nix
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{ lib, config, pkgs, ... }: {
|
||||
imports = [
|
||||
|
||||
<modules>
|
||||
<system/server/initssh.nix>
|
||||
<system/all/sshd.nix>
|
||||
|
||||
./hardware-configuration.nix
|
||||
|
||||
];
|
||||
|
||||
# enable initrd ssh
|
||||
configuration.init-ssh = {
|
||||
enable = "enabled";
|
||||
kernelModules = [ "virtio_pci" ];
|
||||
hostECDSAKey = <secrets/init-ssh/host_ecdsa_key>;
|
||||
};
|
||||
|
||||
networking.hostName = "dummy";
|
||||
|
||||
# font
|
||||
# ----
|
||||
programs.custom.urxvt.fontSize = 17;
|
||||
programs.custom.xterm.fontSize = 17;
|
||||
system.custom.fonts.dpi = 140;
|
||||
|
||||
# allow un-free
|
||||
# -------------
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
environment.variables.NIXPKGS_ALLOW_UNFREE = "1";
|
||||
|
||||
# some system stuff
|
||||
# -----------------
|
||||
time.timeZone = lib.mkDefault "Europe/Berlin";
|
||||
#time.timeZone = lib.mkDefault "Pacific/Auckland";
|
||||
#time.timeZone = lib.mkDefault "Asia/Singapore";
|
||||
#time.timeZone = lib.mkDefault "Asia/Makassar";
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
console.font = "Lat2-Terminus16";
|
||||
console.keyMap = "us";
|
||||
|
||||
# swappiness
|
||||
# ----------
|
||||
# 0 = only when running out of RAM
|
||||
# 100 = always swapp
|
||||
boot.kernel.sysctl."vm.swappiness" = 0;
|
||||
|
||||
# rewire NIX_PATH
|
||||
# ---------------
|
||||
environment.variables.NIX_PATH = lib.mkForce "/var/src";
|
||||
|
||||
environment.systemPackages = [ pkgs.git ];
|
||||
|
||||
boot.initrd.network.postCommands = lib.mkAfter ''
|
||||
echo "sleep engineering"
|
||||
sleep 120
|
||||
'';
|
||||
|
||||
}
|
||||
|
||||
9
nixos/configs/dummy/hardware-configuration.nix
Normal file
9
nixos/configs/dummy/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ ... }: {
|
||||
imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ];
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
fileSystems."/" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
};
|
||||
}
|
||||
|
||||
32
nixos/configs/mobi/configuration.nix
Normal file
32
nixos/configs/mobi/configuration.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
imports = [
|
||||
|
||||
<system/desktop>
|
||||
./hardware-configuration.nix
|
||||
./tinc.nix
|
||||
|
||||
];
|
||||
|
||||
system.custom.wifi.interfaces = [ ];
|
||||
|
||||
networking.hostName = "mobi";
|
||||
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount}/bin/pumount";
|
||||
};
|
||||
|
||||
# fonts
|
||||
# -----
|
||||
programs.custom.urxvt.fontSize = 12;
|
||||
programs.custom.xterm.fontSize = 12;
|
||||
system.custom.fonts.dpi = 100;
|
||||
|
||||
configuration.desktop = {
|
||||
width = 1366;
|
||||
height = 768;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
58
nixos/configs/mobi/hardware-configuration.nix
Normal file
58
nixos/configs/mobi/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ehci_pci" "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# efi boot loader configuration using grub
|
||||
boot.loader.efi.canTouchEfiVariables = false;
|
||||
boot.loader.grub = {
|
||||
device = "nodev";
|
||||
efiInstallAsRemovable = true;
|
||||
efiSupport = true;
|
||||
enable = true;
|
||||
version = 2;
|
||||
};
|
||||
|
||||
fileSystems."/share/" = {
|
||||
device = "/dev/ram1";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
|
||||
# NTFS support
|
||||
# ------------
|
||||
environment.systemPackages = [ pkgs.ntfs3g ];
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = {
|
||||
mobi = {
|
||||
device = "/dev/disk/by-uuid/e138095f-c703-4dea-bb1c-bf888b8e1b81";
|
||||
preLVM = true;
|
||||
};
|
||||
};
|
||||
|
||||
# root
|
||||
# ----
|
||||
fileSystems."/" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/mobi/root";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# boot
|
||||
# ----
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/064D-3144";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
}
|
||||
14
nixos/configs/mobi/tinc.nix
Normal file
14
nixos/configs/mobi/tinc.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
32
nixos/configs/pepe/borg.nix
Normal file
32
nixos/configs/pepe/borg.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{ lib, config, pkgs, ... }: {
|
||||
|
||||
# provide borg backup repository
|
||||
services.borgbackup.repos = {
|
||||
default = {
|
||||
quota = "100G";
|
||||
allowSubRepos = true;
|
||||
authorizedKeys = [
|
||||
# todo rename
|
||||
(lib.fileContents ../../assets/ssh/borg_access.pub)
|
||||
(lib.fileContents ../../assets/ssh/card_rsa.pub)
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# mirror backup folder to /media
|
||||
systemd.services.borg-mirror-to-media = {
|
||||
enable = true;
|
||||
script = ''
|
||||
${pkgs.rsync}/bin/rsync -a \
|
||||
/var/lib/borgbackup/ \
|
||||
/media/borg-backup-mirror \
|
||||
--delete-after
|
||||
'';
|
||||
};
|
||||
systemd.timers.borg-mirror-to-media = {
|
||||
enable = true;
|
||||
timerConfig.OnCalendar = "daily";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
}
|
||||
58
nixos/configs/pepe/configuration.nix
Normal file
58
nixos/configs/pepe/configuration.nix
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
imports = [
|
||||
|
||||
<system/server>
|
||||
./hardware-configuration.nix
|
||||
|
||||
#./home-assistant.nix
|
||||
#./kodi.nix
|
||||
./syncthing.nix
|
||||
./tinc.nix
|
||||
#./wifi-access-point.nix
|
||||
#./lan.nix
|
||||
./dms.nix
|
||||
./borg.nix
|
||||
|
||||
];
|
||||
|
||||
nixpkgs.config.permittedInsecurePackages = [ "homeassistant-0.114.4" ];
|
||||
|
||||
networking.hostName = "pepe";
|
||||
|
||||
# fonts
|
||||
# -----
|
||||
programs.custom.urxvt.fontSize = 12;
|
||||
programs.custom.xterm.fontSize = 12;
|
||||
system.custom.fonts.dpi = 100;
|
||||
|
||||
# networking
|
||||
# ----------
|
||||
#system.custom.wifi = {
|
||||
#enable = false;
|
||||
#interfaces = [ "wlp3s0" ];
|
||||
#configurationFile = <secrets/wpa_supplicant>;
|
||||
#};
|
||||
|
||||
configuration.init-ssh = {
|
||||
enable = "enabled";
|
||||
kernelModules = [ "e1000e" ];
|
||||
};
|
||||
|
||||
# just enable lan
|
||||
networking.dhcpcd.allowInterfaces = [ "enp0s25" ];
|
||||
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
configuration.fireqos = {
|
||||
enable = true;
|
||||
interface = "wlp3s0";
|
||||
input = 5000;
|
||||
output = 1200;
|
||||
balance = false;
|
||||
};
|
||||
|
||||
services.printing.enable = false;
|
||||
services.smartd.enable = true;
|
||||
|
||||
}
|
||||
|
||||
95
nixos/configs/pepe/dms.nix
Normal file
95
nixos/configs/pepe/dms.nix
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
{ lib, pkgs, config, ... }:
|
||||
|
||||
# a very simple dms setup which.
|
||||
# I have a brother ADS-1600W scanner, which is configured to send all
|
||||
# PDFs to this machine in /home/ftp-upload/input
|
||||
# from there the dms.py scans them and makes them searchable.
|
||||
|
||||
let
|
||||
dms = pkgs.fetchgit {
|
||||
url = "https://github.com/mrVanDalo/dms.git";
|
||||
rev = "2f5c44f017bdfd8abfe908d419ef26bac300f809";
|
||||
sha256 = "0dxhk1ah6wwbsxyk4hd32rz7886w7r5gfy16485gjbvky1qsi8gd";
|
||||
};
|
||||
in {
|
||||
|
||||
# setup ftp
|
||||
services.vsftpd = {
|
||||
enable = true;
|
||||
userlist = [ "ftp-upload" ];
|
||||
userlistEnable = true;
|
||||
localUsers = true;
|
||||
writeEnable = true;
|
||||
extraConfig = ''
|
||||
# additional ports for directory list and stuff
|
||||
pasv_min_port=4242
|
||||
pasv_max_port=4243
|
||||
'';
|
||||
};
|
||||
networking.firewall.allowedTCPPortRanges = [
|
||||
{
|
||||
# ftp: additional ports for directory list and stuff
|
||||
from = 4242;
|
||||
to = 4243;
|
||||
}
|
||||
{
|
||||
# ftp
|
||||
from = 20;
|
||||
to = 21;
|
||||
}
|
||||
];
|
||||
|
||||
# create user
|
||||
users.users.ftp-upload = {
|
||||
passwordFile = toString <secrets/ftp/password>;
|
||||
isNormalUser = true;
|
||||
};
|
||||
|
||||
# create dms service
|
||||
systemd.services.dms = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [
|
||||
(pkgs.python3.withPackages (ps: with ps; [ flask ]))
|
||||
pkgs.imagemagickBig
|
||||
(pkgs.pdfsandwich.override { imagemagick = pkgs.imagemagickBig; })
|
||||
pkgs.poppler_utils
|
||||
pkgs.which
|
||||
pkgs.netpbm
|
||||
pkgs.gawk
|
||||
pkgs.bash
|
||||
];
|
||||
serviceConfig = { User = "ftp-upload"; };
|
||||
preStart = ''
|
||||
if [[ ! -L /home/ftp-upload/db/SOURCE_DIR ]]
|
||||
then
|
||||
rm -rf /home/ftp-upload/db/SOURCE_DIR
|
||||
mkdir -p /home/ftp-upload/db
|
||||
mkdir -p /home/ftp-upload/input
|
||||
ln -s /home/ftp-upload/input /home/ftp-upload/db/SOURCE_DIR
|
||||
fi
|
||||
'';
|
||||
script = ''
|
||||
DMSDATA=/home/ftp-upload/db \
|
||||
FLASK_APP=${dms}/dms.py \
|
||||
flask run --host 0.0.0.0 \
|
||||
"$@"
|
||||
'';
|
||||
};
|
||||
|
||||
# host nginx setup
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"dms.pepe.private" = {
|
||||
serverAliases =
|
||||
[ "pdf.pepe.private" "docs.pepe.private" "dms.pepe.lan" ];
|
||||
locations."/" = { proxyPass = "http://localhost:5000"; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# add documents to backup
|
||||
backup.dirs = [ "/home/ftp-upload/db" ];
|
||||
|
||||
}
|
||||
86
nixos/configs/pepe/hardware-configuration.nix
Normal file
86
nixos/configs/pepe/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
||||
|
||||
(let mediaUUID = "29ebe5ba-7599-4dd3-99a3-37b9bf8e4d61";
|
||||
in {
|
||||
fileSystems."/media" = {
|
||||
device = "/dev/disk/by-uuid/${mediaUUID}";
|
||||
fsType = "ext4";
|
||||
options = [
|
||||
"nofail"
|
||||
"noauto"
|
||||
#"x-systemd.device-timeout=1ms"
|
||||
];
|
||||
};
|
||||
systemd.mounts = [{
|
||||
enable = true;
|
||||
options = "nofail,noauto";
|
||||
type = "ext4";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
what = "/dev/disk/by-uuid/${mediaUUID}";
|
||||
where = "/media";
|
||||
}];
|
||||
})
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
version = 2;
|
||||
device = "/dev/sda";
|
||||
};
|
||||
|
||||
zramSwap = {
|
||||
enable = true;
|
||||
numDevices = 2;
|
||||
swapDevices = 1;
|
||||
memoryPercent = 50;
|
||||
};
|
||||
|
||||
fileSystems."/share" = {
|
||||
#device = "/dev/ram1";
|
||||
device = "none";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
|
||||
nix.maxJobs = lib.mkDefault 2;
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = {
|
||||
"secure_vg" = {
|
||||
device = "/dev/sda2";
|
||||
preLVM = true;
|
||||
};
|
||||
};
|
||||
|
||||
# NTFS support
|
||||
# ------------
|
||||
environment.systemPackages = [ pkgs.ntfs3g ];
|
||||
|
||||
# root
|
||||
# ----
|
||||
fileSystems."/" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/secure_vg/root";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# boot
|
||||
# ----
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
}
|
||||
302
nixos/configs/pepe/home-assistant.nix
Normal file
302
nixos/configs/pepe/home-assistant.nix
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
{ pkgs, config, lib, ... }: {
|
||||
|
||||
imports = [
|
||||
#./home-assistant/mpd.nix
|
||||
#./home-assistant/timer.nix
|
||||
./home-assistant/light-control.nix
|
||||
./home-assistant/iot-control.nix
|
||||
./home-assistant/chaospott.nix
|
||||
./home-assistant/kodi.nix
|
||||
./home-assistant/mqtt.nix
|
||||
./home-assistant/sonoff.nix
|
||||
./home-assistant/stocks.nix
|
||||
./home-assistant/weather.nix
|
||||
./home-assistant/workday.nix
|
||||
./home-assistant/zigbee2mqtt.nix
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8123 ];
|
||||
networking.firewall.allowedUDPPorts = [ 8123 ];
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# turn on to edit GUI
|
||||
lovelace = { };
|
||||
|
||||
homeassistant = {
|
||||
|
||||
name = "Home";
|
||||
latitude = 51.444847;
|
||||
longitude = 6.967006;
|
||||
elevation = 116;
|
||||
unit_system = "metric";
|
||||
|
||||
time_zone = config.time.timeZone;
|
||||
auth_providers = [{
|
||||
type = "trusted_networks";
|
||||
trusted_networks = [
|
||||
config.module.cluster.services.tinc."private".networkSubnet
|
||||
"192.168.178.0/24"
|
||||
"127.0.0.1"
|
||||
];
|
||||
}];
|
||||
|
||||
};
|
||||
|
||||
# needed, don't know why
|
||||
default_config = { };
|
||||
config = { };
|
||||
|
||||
# to grab metrics via prometheus
|
||||
prometheus.namespace = "hass";
|
||||
|
||||
# manual state
|
||||
# ------------
|
||||
# all scenes
|
||||
input_select.scene = {
|
||||
icon = "mdi:brightness-auto";
|
||||
options = [ "up-bright" "up-dark" "half" "down" "night" "outside" ];
|
||||
};
|
||||
# scenes controlled by buttons
|
||||
input_select.scene_button = {
|
||||
icon = "mdi:brightness-auto";
|
||||
options = [ "up-dark" "night" ];
|
||||
};
|
||||
input_boolean.situation_toggle.icon = "mdi:toggle-switch";
|
||||
input_boolean.printer_toggle.icon = "mdi:toggle-switch";
|
||||
|
||||
input_boolean.windows_up.icon = "mdi:toggle-switch";
|
||||
|
||||
automation = [
|
||||
|
||||
{
|
||||
alias = "Hold Button -> Toggle Printer";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "input_boolean.printer_toggle";
|
||||
};
|
||||
action = {
|
||||
service = "switch.toggle";
|
||||
data.entity_id = "switch.pal02";
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
alias = "set light-control scene";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "input_select.scene";
|
||||
};
|
||||
action = {
|
||||
service = "mqtt.publish";
|
||||
data_template = {
|
||||
topic = "control/lights/set";
|
||||
payload_template =
|
||||
''{"scene":"{{ states('input_select.scene')}}"}'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
# control situation with buttons
|
||||
{
|
||||
alias = "Button -> Change Scene";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "input_boolean.situation_toggle";
|
||||
};
|
||||
action = {
|
||||
service = "input_select.select_next";
|
||||
data.entity_id = "input_select.scene_button";
|
||||
};
|
||||
}
|
||||
{
|
||||
alias = "Button Scene -> Scene";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "input_select.scene_button";
|
||||
};
|
||||
action = {
|
||||
service = "input_select.select_option";
|
||||
data_template = {
|
||||
entity_id = "input_select.scene";
|
||||
option = "{{ states('input_select.scene_button') }}";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
# outside and home
|
||||
{
|
||||
alias = "when opening door I'm outside";
|
||||
trigger = [
|
||||
{
|
||||
platform = "state";
|
||||
# todo : groups are not working right now
|
||||
entity_id = "binary_sensor.door_sensor_4";
|
||||
from = "off";
|
||||
to = "on";
|
||||
}
|
||||
{
|
||||
platform = "state";
|
||||
# todo : groups are not working right now
|
||||
entity_id = "binary_sensor.door_sensor_4";
|
||||
from = "on";
|
||||
to = "off";
|
||||
}
|
||||
];
|
||||
action = [{
|
||||
service = "input_select.select_option";
|
||||
data = {
|
||||
entity_id = "input_select.scene";
|
||||
option = "outside";
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
||||
{
|
||||
alias = "reset everything when back home";
|
||||
trigger = map (entity_id: {
|
||||
platform = "state";
|
||||
entity_id = entity_id;
|
||||
from = "off";
|
||||
to = "on";
|
||||
}) [
|
||||
"binary_sensor.motion_sensor_1"
|
||||
"binary_sensor.motion_sensor_2"
|
||||
"binary_sensor.motion_sensor_3"
|
||||
"binary_sensor.motion_sensor_4"
|
||||
"binary_sensor.motion_sensor_5"
|
||||
"binary_sensor.motion_sensor_6"
|
||||
"binary_sensor.motion_sensor_7"
|
||||
"binary_sensor.motion_sensor_8"
|
||||
];
|
||||
condition = {
|
||||
condition = "template";
|
||||
value_template =
|
||||
''{{ states.input_select.scene.state == "outside" }}'';
|
||||
};
|
||||
action = [{
|
||||
service = "input_select.select_option";
|
||||
data = {
|
||||
entity_id = "input_select.scene";
|
||||
option = "up-dark";
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
group = let
|
||||
create_room = { name, description }: {
|
||||
"${name}" = {
|
||||
name = "${description}";
|
||||
entities = [ ];
|
||||
};
|
||||
};
|
||||
create_rooms = rooms:
|
||||
lib.foldr (a: b: a // b) { } (map create_room rooms);
|
||||
# rooms
|
||||
# -----
|
||||
in (create_rooms [
|
||||
{
|
||||
name = "floor_room";
|
||||
description = "Flur";
|
||||
}
|
||||
{
|
||||
name = "bed_room";
|
||||
description = "Schlafzimmer";
|
||||
}
|
||||
{
|
||||
name = "living_room";
|
||||
description = "Wohnzimmer";
|
||||
}
|
||||
{
|
||||
name = "kitchen_room";
|
||||
description = "Küche";
|
||||
}
|
||||
{
|
||||
name = "bath_room";
|
||||
description = "Klo";
|
||||
}
|
||||
]) // {
|
||||
|
||||
# overview
|
||||
# --------
|
||||
all_sensors = { name = "Alle Sensoren"; };
|
||||
today = {
|
||||
name = "Today";
|
||||
entities = [ "input_select.scene" ];
|
||||
};
|
||||
# other stuff
|
||||
# -----------
|
||||
tv = { name = "TV"; };
|
||||
all_lights = { name = "Alle Lampen"; };
|
||||
unknown = {
|
||||
name = "Not Used";
|
||||
entities = [ ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
package = pkgs.unstable.home-assistant;
|
||||
#package = pkgs.unstable.home-assistant.override {
|
||||
# python3 = pkgs.unstable.python37;
|
||||
# extraPackages = python: [
|
||||
# # todo : check which is still needed
|
||||
# python.netdisco
|
||||
# python.xmltodict
|
||||
# python.mpd2
|
||||
# # for mqtt
|
||||
# python.hbmqtt
|
||||
# python.paho-mqtt
|
||||
# # needed for platform workday
|
||||
# #(python.buildPythonPackage rec {
|
||||
# # pname = "holidays";
|
||||
# # version = "0.9.10";
|
||||
# # src = python.fetchPypi {
|
||||
# # inherit pname version;
|
||||
# # sha256 =
|
||||
# # "9f06d143eb708e8732230260636938f2f57114e94defd8fa2082408e0d422d6f";
|
||||
# # };
|
||||
# # doCheck = false;
|
||||
# # buildInputs = [ pkgs.dateutils ];
|
||||
# # propagatedBuildInputs = [ python."python-dateutil" python."six" ];
|
||||
# # meta = with pkgs.stdenv.lib; {
|
||||
# # homepage = "https://github.com/dr-prodigy/python-holidays";
|
||||
# # license = licenses.mit;
|
||||
# # description = "Generate and work with holidays in Python";
|
||||
# # maintainers = with maintainers; [ mrVanDalo ];
|
||||
# # };
|
||||
# #})
|
||||
# ];
|
||||
#};
|
||||
|
||||
};
|
||||
|
||||
# host nginx setup
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts = {
|
||||
"iot.pepe.private" = {
|
||||
serverAliases = [ "hass.pepe.private" "home.pepe.private" ];
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8123";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
79
nixos/configs/pepe/home-assistant/chaospott.nix
Normal file
79
nixos/configs/pepe/home-assistant/chaospott.nix
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
|
||||
name = "chaospott";
|
||||
folderPath = config.services.home-assistant.configDir;
|
||||
filePath = "${folderPath}/${name}.json";
|
||||
|
||||
in {
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = [
|
||||
{
|
||||
platform = "file";
|
||||
name = "${name}_aerie";
|
||||
file_path = filePath;
|
||||
value_template = "{{ value_json.aerie }}";
|
||||
}
|
||||
{
|
||||
platform = "file";
|
||||
name = "${name}_cellar";
|
||||
file_path = filePath;
|
||||
value_template = "{{ value_json.cellar }}";
|
||||
}
|
||||
];
|
||||
|
||||
homeassistant = {
|
||||
whitelist_external_dirs = [ folderPath ];
|
||||
customize = {
|
||||
"sensor.${name}_aerie" = {
|
||||
icon = "mdi:store";
|
||||
entity_picture = "https://chaospott.de/images/logo.png";
|
||||
friendly_name = "ChaosPott Oben";
|
||||
};
|
||||
"sensor.${name}_cellar" = {
|
||||
icon = "mdi:store";
|
||||
entity_picture = "https://chaospott.de/images/logo.png";
|
||||
friendly_name = "ChaosPott Unten";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
group = {
|
||||
"${name}" = {
|
||||
name = "ChaosPott (Essen)";
|
||||
entities = [ "sensor.${name}_aerie" "sensor.${name}_cellar" ];
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
systemd.services."${name}" = {
|
||||
enable = true;
|
||||
before = [ "home-assistant.service" ];
|
||||
wantedBy = [ "home-assistant.service" ];
|
||||
serviceConfig = {
|
||||
User = "hass";
|
||||
Type = "oneshot";
|
||||
};
|
||||
description = "set ${name} for homeassistant";
|
||||
script = ''
|
||||
${pkgs.curl}/bin/curl --location --silent https://status.chaospott.de/api \
|
||||
| ${pkgs.jq}/bin/jq --compact-output \
|
||||
'.sensors.door_locked |
|
||||
[.[] | { "\(.location)" : (if .value then "closed" else "open" end) }] |
|
||||
reduce .[] as $item ({}; . + $item) ' \
|
||||
>> ${filePath}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers."${name}" = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
Persistent = "true";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
30
nixos/configs/pepe/home-assistant/iot-control.nix
Normal file
30
nixos/configs/pepe/home-assistant/iot-control.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{ lib, pkgs, config, ... }: {
|
||||
|
||||
users.users.heater-control = { };
|
||||
|
||||
#systemd.services.heater-control = {
|
||||
# enable = true;
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# serviceConfig = { User = "heater-control"; };
|
||||
# script =
|
||||
# let myPython = pkgs.python3.withPackages (ps: with ps; [ paho-mqtt ]);
|
||||
# in ''
|
||||
# cd ${<mqtt>}
|
||||
# ${myPython}/bin/python heater.py
|
||||
# '';
|
||||
#};
|
||||
|
||||
users.users.fyrtur-control = { };
|
||||
|
||||
systemd.services.fyrtur-control = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = { User = "fyrtur-control"; };
|
||||
script =
|
||||
let myPython = pkgs.python3.withPackages (ps: with ps; [ paho-mqtt ]);
|
||||
in ''
|
||||
cd ${<mqtt>}
|
||||
${myPython}/bin/python fyrtur.py
|
||||
'';
|
||||
};
|
||||
}
|
||||
45
nixos/configs/pepe/home-assistant/kodi.nix
Normal file
45
nixos/configs/pepe/home-assistant/kodi.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{ pkgs, config, lib, ... }: {
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
media_player = [{
|
||||
platform = "kodi";
|
||||
host = "127.0.0.1";
|
||||
}];
|
||||
|
||||
shell_command = {
|
||||
start_kodi = "sudo ${pkgs.systemd}/bin/systemctl start display-manager";
|
||||
stop_kodi = "sudo ${pkgs.systemd}/bin/systemctl stop display-manager";
|
||||
};
|
||||
|
||||
automation = [
|
||||
{
|
||||
alias = "turn kodi on once the tv is turned on";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "group.tv";
|
||||
from = "off";
|
||||
to = "on";
|
||||
for.seconds = 60;
|
||||
};
|
||||
action = [{ service = "shell_command.start_kodi"; }];
|
||||
}
|
||||
{
|
||||
alias = "turn off kodi on once the tv is turned off";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "group.tv";
|
||||
from = "on";
|
||||
to = "off";
|
||||
};
|
||||
action = [{ service = "shell_command.stop_kodi"; }];
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
security.sudo.extraConfig = ''
|
||||
hass ALL= (root) NOPASSWD: ${pkgs.systemd}/bin/systemctl start display-manager
|
||||
hass ALL= (root) NOPASSWD: ${pkgs.systemd}/bin/systemctl stop display-manager
|
||||
'';
|
||||
}
|
||||
228
nixos/configs/pepe/home-assistant/light-control.nix
Normal file
228
nixos/configs/pepe/home-assistant/light-control.nix
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
{ pkgs, lib, config, ... }: {
|
||||
|
||||
services.mqtt.light-control.enable = true;
|
||||
services.mqtt.light-control.loglevel = "debug";
|
||||
services.mqtt.light-control.config = {
|
||||
credentials = {
|
||||
host = "tcp://localhost:1883";
|
||||
user = "homeassistant";
|
||||
password = "hallo";
|
||||
};
|
||||
scenes = [
|
||||
{
|
||||
name = "up-dark";
|
||||
ignored_sensors = [
|
||||
"zigbee2mqtt/door_sensor_1"
|
||||
"zigbee2mqtt/door_sensor_4"
|
||||
"zigbee2mqtt/door_sensor_5"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "half";
|
||||
ignored_sensors = [
|
||||
"zigbee2mqtt/door_sensor_1"
|
||||
"zigbee2mqtt/door_sensor_4"
|
||||
"zigbee2mqtt/door_sensor_5"
|
||||
];
|
||||
disabled_switches = [
|
||||
"zigbee2mqtt/led_1"
|
||||
"zigbee2mqtt/led_2"
|
||||
"zigbee2mqtt/light_2"
|
||||
"zigbee2mqtt/light_4"
|
||||
"zigbee2mqtt/light_5"
|
||||
"zigbee2mqtt/light_7"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "down";
|
||||
ignored_sensors = [
|
||||
"zigbee2mqtt/door_sensor_1"
|
||||
"zigbee2mqtt/door_sensor_4"
|
||||
"zigbee2mqtt/door_sensor_5"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "up-bright";
|
||||
disabled_switches = [
|
||||
"zigbee2mqtt/led_1"
|
||||
"zigbee2mqtt/led_2"
|
||||
"zigbee2mqtt/light_2"
|
||||
"zigbee2mqtt/light_4"
|
||||
"zigbee2mqtt/light_5"
|
||||
"zigbee2mqtt/light_7"
|
||||
];
|
||||
ignored_sensors = [ "zigbee2mqtt/door_sensor_4" ];
|
||||
}
|
||||
{
|
||||
name = "outside";
|
||||
room_tracking_enabled = false;
|
||||
ignored_sensors = [ "zigbee2mqtt/door_sensor_4" ];
|
||||
}
|
||||
{
|
||||
name = "night";
|
||||
room_tracking_enabled = false;
|
||||
brightness = 25;
|
||||
ignored_sensors =
|
||||
[ "zigbee2mqtt/motion_sensor_7" "zigbee2mqtt/door_sensor_4" ];
|
||||
}
|
||||
];
|
||||
sensors = let
|
||||
door = { topic, room }: {
|
||||
topic = topic;
|
||||
key = "contact";
|
||||
room = room;
|
||||
invert_state = true;
|
||||
delay = 90;
|
||||
};
|
||||
motion = { topic, room }: {
|
||||
topic = topic;
|
||||
key = "occupancy";
|
||||
room = room;
|
||||
delay = 60;
|
||||
};
|
||||
in [
|
||||
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_1";
|
||||
room = "office_room";
|
||||
})
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_2";
|
||||
room = "office_room";
|
||||
})
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_6";
|
||||
room = "office_room";
|
||||
})
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_8";
|
||||
room = "office_room";
|
||||
})
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_7";
|
||||
room = "sleeping_room";
|
||||
})
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_5";
|
||||
room = "kitchen";
|
||||
})
|
||||
(motion {
|
||||
topic = "zigbee2mqtt/motion_sensor_4";
|
||||
room = "storage_room";
|
||||
})
|
||||
|
||||
(door {
|
||||
topic = "zigbee2mqtt/door_sensor_1";
|
||||
room = "storage_room";
|
||||
})
|
||||
(door {
|
||||
topic = "zigbee2mqtt/door_sensor_5";
|
||||
room = "sleeping_room";
|
||||
})
|
||||
(door {
|
||||
# house door
|
||||
topic = "zigbee2mqtt/door_sensor_4";
|
||||
room = "floor";
|
||||
})
|
||||
|
||||
];
|
||||
switches = let
|
||||
sonoff = { id, rooms, delay ? 0 }: {
|
||||
topic = "stat/${id}/RESULT";
|
||||
key = "POWER";
|
||||
rooms = rooms;
|
||||
delay = delay;
|
||||
command = {
|
||||
command = "{{state}}";
|
||||
init_command = "(null)";
|
||||
topic = "cmnd/${id}/POWER";
|
||||
on = "ON";
|
||||
off = "OFF";
|
||||
};
|
||||
};
|
||||
light = { topic, rooms, delay ? 0 }: {
|
||||
topic = topic;
|
||||
key = "state";
|
||||
rooms = rooms;
|
||||
delay = delay;
|
||||
command = {
|
||||
command = ''{"state":"{{state}}","brightness":{{brightness}}}'';
|
||||
topic = "${topic}/set";
|
||||
on = "ON";
|
||||
off = "OFF";
|
||||
};
|
||||
};
|
||||
led = { topic, rooms, delay ? 0 }: {
|
||||
topic = topic;
|
||||
key = "state";
|
||||
rooms = rooms;
|
||||
delay = delay;
|
||||
command = {
|
||||
# Configure it once to the color you like
|
||||
# {"state":"{{state}}","brightness":{{brightness}},"color":{"hex":"#FFFFFF},"color_temp":255","transition":0}
|
||||
command = ''
|
||||
{"state":"{{state}}","brightness":{{brightness}},"transition":0}'';
|
||||
topic = "${topic}/set";
|
||||
on = "ON";
|
||||
off = "OFF";
|
||||
};
|
||||
};
|
||||
in [
|
||||
|
||||
(light {
|
||||
topic = "zigbee2mqtt/light_2";
|
||||
rooms = [ "office_room" ];
|
||||
})
|
||||
(light {
|
||||
topic = "zigbee2mqtt/light_4";
|
||||
rooms = [ "office_room" ];
|
||||
})
|
||||
(light {
|
||||
topic = "zigbee2mqtt/light_5";
|
||||
rooms = [ "storage_room" ];
|
||||
})
|
||||
(light {
|
||||
topic = "zigbee2mqtt/light_7";
|
||||
rooms = [ "sleeping_room" ];
|
||||
})
|
||||
(led {
|
||||
topic = "zigbee2mqtt/led_1";
|
||||
rooms = [ "office_room" ];
|
||||
})
|
||||
(led {
|
||||
topic = "zigbee2mqtt/led_2";
|
||||
rooms = [ "kitchen" ];
|
||||
})
|
||||
|
||||
#(sonoff {
|
||||
# id = "PAL01";
|
||||
# rooms = [ "bed_room" ];
|
||||
#})
|
||||
#(sonoff {
|
||||
# id = "PAL03";
|
||||
# rooms = [ "living_room" ];
|
||||
#})
|
||||
#(sonoff {
|
||||
# id = "PAL04";
|
||||
# rooms = [ "bed_room" ];
|
||||
#})
|
||||
#(sonoff {
|
||||
# id = "PAL06";
|
||||
# rooms = [ "kitchen" ];
|
||||
#})
|
||||
## monitor and speakers
|
||||
#(sonoff {
|
||||
# id = "PAL07";
|
||||
# rooms = [ "bed_room" ];
|
||||
# delay = 180;
|
||||
#})
|
||||
#(sonoff {
|
||||
# id = "PAL08";
|
||||
# rooms = [ "bed_room" ];
|
||||
# delay = 180;
|
||||
#})
|
||||
|
||||
];
|
||||
};
|
||||
|
||||
}
|
||||
13
nixos/configs/pepe/home-assistant/mpd.nix
Normal file
13
nixos/configs/pepe/home-assistant/mpd.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
media_player = [{
|
||||
platform = "mpd";
|
||||
host = "localhost";
|
||||
}];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
31
nixos/configs/pepe/home-assistant/mqtt.nix
Normal file
31
nixos/configs/pepe/home-assistant/mqtt.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{ lib, ... }: {
|
||||
services.homeAssistantConfig.mqtt = {
|
||||
|
||||
# discovery = false;
|
||||
# for mosquitto
|
||||
broker = "127.0.0.1";
|
||||
username = lib.fileContents <secrets/home-assistant/mqtt-user>;
|
||||
password = lib.fileContents <secrets/home-assistant/mqtt-password>;
|
||||
|
||||
};
|
||||
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
host = "0.0.0.0";
|
||||
users = {
|
||||
homeassistant = {
|
||||
password = lib.fileContents <secrets/mosquitto/password>;
|
||||
acl = [ "topic readwrite #" ];
|
||||
};
|
||||
zigbee = {
|
||||
password = lib.fileContents <secrets/zigbee/password>;
|
||||
acl = [ "topic readwrite #" ];
|
||||
};
|
||||
lightcontrol = {
|
||||
password = "password";
|
||||
acl = [ "topic readwrite #" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
104
nixos/configs/pepe/home-assistant/sonoff.nix
Normal file
104
nixos/configs/pepe/home-assistant/sonoff.nix
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
|
||||
sonoffSwitches = {
|
||||
#"pal01" = {
|
||||
# label = "Schlafzimmer Lampe Links";
|
||||
# icon = "mdi:lightbulb";
|
||||
# groups = [ "bed_room" ];
|
||||
#};
|
||||
"pal02" = {
|
||||
label = "Drucker / Scanner";
|
||||
icon = "mdi:printer";
|
||||
groups = [ "bed_room" "today" ];
|
||||
};
|
||||
#"pal03" = {
|
||||
# label = "Wohnzimmer Lampe";
|
||||
# icon = "mdi:lightbulb";
|
||||
# groups = [ "living_room" ];
|
||||
#};
|
||||
#"pal04" = {
|
||||
# label = "Schlafzimmer Lampe Rechts";
|
||||
# icon = "mdi:lightbulb";
|
||||
# groups = [ "bed_room" ];
|
||||
#};
|
||||
"pal05" = {
|
||||
label = "TV";
|
||||
icon = "mdi:television";
|
||||
groups = [ "tv" ];
|
||||
device = "tv";
|
||||
};
|
||||
#"pal06" = {
|
||||
# label = "Küchen Lampe";
|
||||
# icon = "mdi:lightbulb";
|
||||
# groups = ["kitchen_room"];
|
||||
#};
|
||||
"pal07" = { label = "Nummer 7"; };
|
||||
"pal08" = { label = "Nummer 8"; };
|
||||
};
|
||||
|
||||
toSwitch = name: "switch.${name}";
|
||||
|
||||
in {
|
||||
|
||||
imports = [ ./mqtt.nix ];
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# nicer names
|
||||
# -----------
|
||||
homeassistant.customize = lib.mapAttrs' (entity:
|
||||
{ label, icon ? "mdi:power-plug-off", ... }: {
|
||||
name = toSwitch entity;
|
||||
value = {
|
||||
friendly_name = label;
|
||||
icon = icon;
|
||||
};
|
||||
}) sonoffSwitches;
|
||||
|
||||
# define switches
|
||||
# ---------------
|
||||
switch = lib.mapAttrsToList (name:
|
||||
{ ... }: {
|
||||
name = name;
|
||||
platform = "mqtt";
|
||||
command_topic = "cmnd/${lib.toUpper name}/POWER";
|
||||
state_topic = "stat/${lib.toUpper name}/POWER";
|
||||
payload_on = "ON";
|
||||
payload_off = "OFF";
|
||||
state_on = "ON";
|
||||
state_off = "OFF";
|
||||
}) sonoffSwitches;
|
||||
|
||||
# discover state on init
|
||||
# ----------------------
|
||||
automation = [{
|
||||
alias = "Sonoff initial Power state";
|
||||
trigger = {
|
||||
platform = "homeassistant";
|
||||
event = "start";
|
||||
};
|
||||
action = lib.mapAttrsToList (name:
|
||||
{ ... }: {
|
||||
service = "mqtt.publish";
|
||||
data = {
|
||||
topic = "cmnd/${lib.toUpper name}/power";
|
||||
payload = "";
|
||||
};
|
||||
}) sonoffSwitches;
|
||||
}];
|
||||
|
||||
# append to groups
|
||||
# ----------------
|
||||
group = let
|
||||
# sort lights into given groups.
|
||||
sortedInGroups = let
|
||||
groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name:
|
||||
{ groups ? [ ], ... }:
|
||||
map (groupName: { "${groupName}" = "switch.${name}"; }) groups)
|
||||
sonoffSwitches));
|
||||
in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
|
||||
in sortedInGroups;
|
||||
};
|
||||
|
||||
}
|
||||
173
nixos/configs/pepe/home-assistant/stocks.nix
Normal file
173
nixos/configs/pepe/home-assistant/stocks.nix
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
{ lib, config, pkgs, ... }:
|
||||
let
|
||||
|
||||
folderPath = config.services.home-assistant.configDir;
|
||||
|
||||
# find symbols with
|
||||
# https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords=<keywords>&apikey=<api_key>
|
||||
# as described here : https://www.alphavantage.co/documentation/#symbolsearch
|
||||
#
|
||||
# example:
|
||||
# --------
|
||||
# stocks = [
|
||||
# {
|
||||
# symbol = "GOOGL";
|
||||
# name = "google";
|
||||
# friendly_name = "Google";
|
||||
# currency = "$";
|
||||
# # I own 50 and bought at a price of 1000
|
||||
# own = {
|
||||
# pieces = 50;
|
||||
# price = 1000;
|
||||
# };
|
||||
# }
|
||||
# ];
|
||||
stocks = import <secrets/home-assistant/stocks>;
|
||||
filePath = name: "${folderPath}/stock_${name}.json";
|
||||
|
||||
cleanup_list = list: lib.filter (entry: entry != { }) (lib.flatten list);
|
||||
|
||||
in {
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = cleanup_list (map ({ name, currency, own ? { }, ... }: [
|
||||
{
|
||||
platform = "file";
|
||||
name = "stock_${name}";
|
||||
file_path = filePath name;
|
||||
value_template = "{{ value_json.price}} ${currency}";
|
||||
|
||||
}
|
||||
{
|
||||
platform = "file";
|
||||
name = "stock_${name}_change";
|
||||
file_path = filePath name;
|
||||
value_template = "{{ value_json.change}} ${currency}";
|
||||
|
||||
}
|
||||
{
|
||||
platform = "file";
|
||||
name = "stock_${name}_change_percent";
|
||||
file_path = filePath name;
|
||||
value_template = "{{ value_json.change_percent}} %";
|
||||
}
|
||||
(lib.optionalAttrs (own != { }) {
|
||||
platform = "file";
|
||||
name = "stock_${name}_profit";
|
||||
file_path = filePath name;
|
||||
value_template = ''
|
||||
{{ "{:,.2f}".format( value_json.price * ${toString own.pieces} - ${
|
||||
toString (own.pieces * own.price)
|
||||
} ) }} ${currency}'';
|
||||
})
|
||||
]) stocks);
|
||||
|
||||
homeassistant = {
|
||||
whitelist_external_dirs = [ folderPath ];
|
||||
customize = builtins.listToAttrs (cleanup_list (map
|
||||
({ name, own ? { }, ... }: [
|
||||
{
|
||||
name = "sensor.stock_${name}";
|
||||
value = {
|
||||
icon = "mdi:cash-usd-outline";
|
||||
friendly_name = "Price";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "sensor.stock_${name}_change";
|
||||
value = {
|
||||
icon = "mdi:radar";
|
||||
friendly_name = "Difference";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "sensor.stock_${name}_change_percent";
|
||||
value = {
|
||||
icon = "mdi:radar";
|
||||
friendly_name = "Percent";
|
||||
};
|
||||
}
|
||||
(lib.optionalAttrs (own != { }) {
|
||||
name = "sensor.stock_${name}_profit";
|
||||
value = {
|
||||
icon = "mdi:radar";
|
||||
friendly_name = "Profit";
|
||||
};
|
||||
})
|
||||
]) stocks));
|
||||
};
|
||||
|
||||
group = (builtins.listToAttrs (map
|
||||
({ name, friendly_name, own ? { }, ... }: {
|
||||
name = "stock_${name}";
|
||||
value = {
|
||||
name = "${friendly_name} Aktie";
|
||||
entities = [
|
||||
"sensor.stock_${name}"
|
||||
"sensor.stock_${name}_change"
|
||||
"sensor.stock_${name}_change_percent"
|
||||
] ++ (lib.optional (own != { }) "sensor.stock_${name}_profit");
|
||||
};
|
||||
}) stocks));
|
||||
|
||||
};
|
||||
|
||||
systemd.services = let
|
||||
pullService = { name, symbol, currency, ... }: {
|
||||
name = "pull_stock_${name}";
|
||||
value = {
|
||||
enable = true;
|
||||
before = [ "home-assistant.service" ];
|
||||
wantedBy = [ "home-assistant.service" ];
|
||||
serviceConfig = {
|
||||
User = "hass";
|
||||
Type = "oneshot";
|
||||
};
|
||||
description = "pull stock_${name} for homeassistant";
|
||||
script = ''
|
||||
SYMBOL="${symbol}"
|
||||
CURRENCY="${currency}"
|
||||
APIKEY=${
|
||||
lib.fileContents <secrets/home-assistant/alphavantage/apikey>
|
||||
}
|
||||
|
||||
${pkgs.curl}/bin/curl --location --silent \
|
||||
"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \
|
||||
| ${pkgs.jq}/bin/jq --compact-output \
|
||||
'.["Global Quote"] |
|
||||
{
|
||||
price: .["05. price"] | tonumber,
|
||||
currency: "'$CURRENCY'",
|
||||
change_percent: .["10. change percent"] | .[0:-1] | tonumber,
|
||||
change: .["09. change"] | tonumber,
|
||||
last_date: .["07. latest trading day"],
|
||||
}' \
|
||||
>> ${filePath name}
|
||||
|
||||
# old and stupid
|
||||
#${pkgs.curl}/bin/curl --location --silent \
|
||||
#"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=$SYMBOL&interval=5min&apikey=$APIKEY" \
|
||||
#| ${pkgs.jq}/bin/jq --compact-output \
|
||||
# '.["Time Series (5min)"] | to_entries | [ .[]
|
||||
# | { date : .key , value : .value["4. close"], currency: "'$CURRENCY'" } ]
|
||||
# | sort_by(.date) | reverse | .[0]' \
|
||||
'';
|
||||
};
|
||||
};
|
||||
in builtins.listToAttrs (map pullService stocks);
|
||||
|
||||
systemd.timers = let
|
||||
pullTimer = { name, ... }: {
|
||||
name = "pull_stock_${name}";
|
||||
value = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
Persistent = "true";
|
||||
};
|
||||
};
|
||||
};
|
||||
in builtins.listToAttrs (map pullTimer stocks);
|
||||
|
||||
}
|
||||
225
nixos/configs/pepe/home-assistant/timer.nix
Normal file
225
nixos/configs/pepe/home-assistant/timer.nix
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
{ config, ... }: {
|
||||
|
||||
imports = [ ./mpd.nix ];
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = [{
|
||||
platform = "time_date";
|
||||
display_options = [ "time" "date" ];
|
||||
}];
|
||||
|
||||
input_datetime = {
|
||||
wakeup = {
|
||||
name = "Arbeitswecker";
|
||||
has_time = true;
|
||||
has_date = false;
|
||||
icon = "mdi:alarm";
|
||||
};
|
||||
leave = {
|
||||
name = "Turn off Time";
|
||||
has_time = true;
|
||||
has_date = false;
|
||||
icon = "mdi:alarm";
|
||||
};
|
||||
return = {
|
||||
name = "Return home";
|
||||
has_time = true;
|
||||
has_date = false;
|
||||
icon = "mdi:alarm";
|
||||
};
|
||||
sleep = {
|
||||
name = "Turn off Time";
|
||||
has_time = true;
|
||||
has_date = false;
|
||||
icon = "mdi:alarm";
|
||||
};
|
||||
};
|
||||
|
||||
input_boolean = {
|
||||
wakeup = {
|
||||
name = "enable";
|
||||
icon = "mdi:toggle-switch";
|
||||
};
|
||||
leave = {
|
||||
name = "enable";
|
||||
icon = "mdi:toggle-switch";
|
||||
};
|
||||
return = {
|
||||
name = "enable";
|
||||
icon = "mdi:toggle-switch";
|
||||
};
|
||||
sleep = {
|
||||
name = "enable";
|
||||
icon = "mdi:toggle-switch";
|
||||
};
|
||||
};
|
||||
|
||||
input_select = {
|
||||
wakeup = {
|
||||
name = "Playlist";
|
||||
icon = "mdi:library-music";
|
||||
options = [ "wakeup" "wakeup1" "wakeup2" ];
|
||||
};
|
||||
};
|
||||
|
||||
binary_sensor = [
|
||||
{
|
||||
platform = "tod";
|
||||
name = "night";
|
||||
after = "sunset";
|
||||
before = "sunrise";
|
||||
}
|
||||
{
|
||||
platform = "tod";
|
||||
name = "daytime";
|
||||
after = "sunrise";
|
||||
before = "sunset";
|
||||
}
|
||||
];
|
||||
|
||||
group = {
|
||||
|
||||
timer_wakeup = {
|
||||
name = "Arbeits Aufwachen";
|
||||
entities = [
|
||||
"input_boolean.wakeup"
|
||||
"input_datetime.wakeup"
|
||||
"input_select.wakeup"
|
||||
];
|
||||
};
|
||||
|
||||
timer_leave = {
|
||||
name = "Leave Time";
|
||||
entities = [ "input_boolean.leave" "input_datetime.leave" ];
|
||||
};
|
||||
|
||||
timer_return = {
|
||||
name = "Nach Hause kommen";
|
||||
entities = [ "input_boolean.sleep" "input_datetime.sleep" ];
|
||||
};
|
||||
|
||||
timers.entities = [
|
||||
"group.timer_wakeup"
|
||||
"group.timer_leave"
|
||||
"group.timer_return"
|
||||
"group.timer_sleep"
|
||||
"binary_sensor.night"
|
||||
"binary_sensor.daytime"
|
||||
];
|
||||
|
||||
today.entities = [ "sensor.date" "sensor.time" ];
|
||||
|
||||
};
|
||||
|
||||
automation = [
|
||||
{
|
||||
alias = "Wecker Arbeiten";
|
||||
trigger = {
|
||||
platform = "template";
|
||||
value_template =
|
||||
"{{ states('sensor.time') == (states.input_datetime.wakeup.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
|
||||
};
|
||||
condition = {
|
||||
condition = "and";
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "input_boolean.wakeup";
|
||||
state = "on";
|
||||
}
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "binary_sensor.workday";
|
||||
state = "on";
|
||||
}
|
||||
];
|
||||
};
|
||||
action = [
|
||||
{
|
||||
alias = "Play wakeup list";
|
||||
service = "media_player.play_media";
|
||||
data_template = {
|
||||
entity_id = "media_player.mpd";
|
||||
media_content_type = "playlist";
|
||||
media_content_id = "{{ states('input_select.wakeup') }}";
|
||||
};
|
||||
}
|
||||
{
|
||||
alias = "turn all on";
|
||||
service = "script.turn_on";
|
||||
entity_id = "script.turn_all_on";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
{
|
||||
alias = "Leave Turn all off Timer";
|
||||
trigger = {
|
||||
platform = "template";
|
||||
value_template =
|
||||
"{{ states('sensor.time') == (states.input_datetime.leave.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
|
||||
};
|
||||
condition = {
|
||||
condition = "and";
|
||||
conditions = [{
|
||||
condition = "state";
|
||||
entity_id = "input_boolean.leave";
|
||||
state = "on";
|
||||
}];
|
||||
};
|
||||
action = [{
|
||||
alias = "turn all off";
|
||||
service = "script.turn_on";
|
||||
entity_id = "script.turn_all_off";
|
||||
}];
|
||||
}
|
||||
|
||||
{
|
||||
alias = "Return to Home";
|
||||
trigger = {
|
||||
platform = "template";
|
||||
value_template =
|
||||
"{{ states('sensor.time') == (states.input_datetime.return.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
|
||||
};
|
||||
condition = {
|
||||
condition = "and";
|
||||
conditions = [{
|
||||
condition = "state";
|
||||
entity_id = "input_boolean.return";
|
||||
state = "on";
|
||||
}];
|
||||
};
|
||||
action = [{
|
||||
alias = "turn all on";
|
||||
service = "script.turn_on";
|
||||
entity_id = "script.turn_all_on";
|
||||
}];
|
||||
}
|
||||
|
||||
{
|
||||
alias = "Sleep Turn all off Timer";
|
||||
trigger = {
|
||||
platform = "template";
|
||||
value_template =
|
||||
"{{ states('sensor.time') == (states.input_datetime.sleep.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}";
|
||||
};
|
||||
condition = {
|
||||
condition = "and";
|
||||
conditions = [{
|
||||
condition = "state";
|
||||
entity_id = "input_boolean.sleep";
|
||||
state = "on";
|
||||
}];
|
||||
};
|
||||
action = [{
|
||||
alias = "turn all off";
|
||||
service = "script.turn_on";
|
||||
entity_id = "script.turn_all_off";
|
||||
}];
|
||||
}
|
||||
|
||||
];
|
||||
};
|
||||
|
||||
}
|
||||
18
nixos/configs/pepe/home-assistant/weather.nix
Normal file
18
nixos/configs/pepe/home-assistant/weather.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{ config, ... }: {
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = [
|
||||
# Weather prediction
|
||||
{
|
||||
platform = "zamg";
|
||||
name = "weather";
|
||||
}
|
||||
];
|
||||
|
||||
sun = { };
|
||||
|
||||
group.today.entities = [ "sensor.weather_temperature" "sun.sun" ];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
55
nixos/configs/pepe/home-assistant/workday.nix
Normal file
55
nixos/configs/pepe/home-assistant/workday.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
holiday-range = month: dayA: dayB:
|
||||
map (day: "${month}-${toString day}")
|
||||
(map (lib.fixedWidthNumber 2) (lib.range dayA dayB));
|
||||
privateHolidays = import <secrets/home-assistant/holidays>;
|
||||
# for example :
|
||||
# holidays = lib.flatten [
|
||||
# (holiday-range "2020-06" 7 24)
|
||||
# (holiday-range "2020-10" 10 16)
|
||||
#];
|
||||
holidays = lib.flatten (privateHolidays holiday-range);
|
||||
|
||||
in {
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
binary_sensor = [
|
||||
{
|
||||
name = "before_workday";
|
||||
platform = "workday";
|
||||
country = "DE";
|
||||
province = "NW";
|
||||
workdays = [ "mon" "tue" "wed" "thu" "fri" ];
|
||||
days_offset = 1;
|
||||
add_holidays = holidays;
|
||||
}
|
||||
{
|
||||
name = "workday";
|
||||
platform = "workday";
|
||||
country = "DE";
|
||||
province = "NW";
|
||||
workdays = [ "mon" "tue" "wed" "thu" "fri" ];
|
||||
add_holidays = holidays;
|
||||
}
|
||||
];
|
||||
|
||||
homeassistant.customize = {
|
||||
"binary_sensor.workday" = {
|
||||
icon = "mdi:calendar";
|
||||
friendly_name = "Workday?";
|
||||
};
|
||||
"binary_sensor.before_workday" = {
|
||||
icon = "mdi:calendar";
|
||||
friendly_name = "Workday Tomorrow?";
|
||||
};
|
||||
};
|
||||
|
||||
group = {
|
||||
today.entities =
|
||||
[ "binary_sensor.before_workday" "binary_sensor.workday" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
100
nixos/configs/pepe/home-assistant/zigbee2mqtt.nix
Normal file
100
nixos/configs/pepe/home-assistant/zigbee2mqtt.nix
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
# no need to set ZIGBEE2MQTT_DATA anymore
|
||||
assert lib.versionOlder lib.version "21.03";
|
||||
|
||||
{
|
||||
imports = [
|
||||
./mqtt.nix
|
||||
./zigbee2mqtt/service.nix
|
||||
./zigbee2mqtt/buttons.nix
|
||||
./zigbee2mqtt/configurationHelper.nix
|
||||
./zigbee2mqtt/doors.nix
|
||||
./zigbee2mqtt/fyrtur.nix
|
||||
./zigbee2mqtt/heater.nix
|
||||
./zigbee2mqtt/leds.nix
|
||||
./zigbee2mqtt/lights.nix
|
||||
./zigbee2mqtt/motion.nix
|
||||
./zigbee2mqtt/repeater.nix
|
||||
./zigbee2mqtt/temperatur.nix
|
||||
];
|
||||
|
||||
custom.services.zigbee2mqtt = {
|
||||
enable = true;
|
||||
#package = pkgs.own_zigbee2mqtt;
|
||||
#package = unstable.zigbee2mqtt;
|
||||
package = pkgs.unstable.zigbee2mqtt.overrideAttrs (old: rec {
|
||||
version = "1.18.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "Koenkk";
|
||||
repo = "zigbee2mqtt";
|
||||
rev = version;
|
||||
sha256 = "1x73k346ayik5hv5axa3nvmd82mgwyrpxqv3dxnffi8aa1r8pf8x";
|
||||
};
|
||||
});
|
||||
config = {
|
||||
|
||||
# Home Assistant integration (MQTT discovery)
|
||||
homeassistant = false;
|
||||
|
||||
# allow new devices to join
|
||||
permit_join = false;
|
||||
|
||||
# MQTT settings
|
||||
mqtt = {
|
||||
# MQTT base topic for zigbee2mqtt MQTT messages
|
||||
base_topic = "zigbee2mqtt";
|
||||
# MQTT server URL
|
||||
server = "mqtt://127.0.0.1:1883";
|
||||
# MQTT server authentication, uncomment if required:
|
||||
user = "zigbee";
|
||||
password = lib.fileContents <secrets/zigbee/password>;
|
||||
};
|
||||
|
||||
# Serial settings
|
||||
serial = {
|
||||
#port = "/dev/ttyACM0";
|
||||
port = "/dev/ttyUSB0";
|
||||
# disable LED of CC2531 USB sniffer
|
||||
#disable_led = true;
|
||||
};
|
||||
|
||||
# you own network key,
|
||||
# 16 numbers between 0 and 255
|
||||
# see https://www.zigbee2mqtt.io/how_tos/how_to_secure_network.html
|
||||
advanced.network_key = import <secrets/home-assistant/zigbee/networkKey>;
|
||||
advanced.log_output = [ "console" ];
|
||||
|
||||
advanced.pan_id = 1337;
|
||||
|
||||
# add last seen information
|
||||
advanced.last_seen = "ISO_8601_local";
|
||||
|
||||
# configure web ui
|
||||
frontend.port = 9666;
|
||||
frontend.host = "0.0.0.0";
|
||||
experimental.new_api = true;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
#systemd.services.zigbee2mqtt.environment = {
|
||||
# ZIGBEE2MQTT_DATA = "/var/lib/zigbee2mqtt";
|
||||
#};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts = {
|
||||
"zigbee2mqtt.pepe.private" = {
|
||||
serverAliases = [ "zigbee.pepe.private" ];
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${
|
||||
toString config.custom.services.zigbee2mqtt.config.frontend.port
|
||||
}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
226
nixos/configs/pepe/home-assistant/zigbee2mqtt/buttons.nix
Normal file
226
nixos/configs/pepe/home-assistant/zigbee2mqtt/buttons.nix
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# we create 3 input_boolean which get toggled by the 3 types of buttons pressed.
|
||||
# input_boolean.single_${name} : single click
|
||||
# input_boolean.double_${name} : double click
|
||||
# input_boolean.hold_${name} : hold
|
||||
# if you override these input (via states) you have to create the input yourself
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/WXKG12LM.html
|
||||
allDevices = {
|
||||
"button_a1" = {
|
||||
id = "0x00158d0002b04f65";
|
||||
#groups = [ "living_room" ];
|
||||
states.single = "input_boolean.situation_toggle";
|
||||
states.hold = "input_boolean.printer_toggle";
|
||||
states.double = "input_boolean.windows_up";
|
||||
};
|
||||
"button_a2" = {
|
||||
id = "0x00158d0002b04f09";
|
||||
#groups = [ "bed_room" ];
|
||||
states.single = "input_boolean.situation_toggle";
|
||||
states.hold = "input_boolean.printer_toggle";
|
||||
states.double = "input_boolean.windows_up";
|
||||
};
|
||||
"button_a3" = {
|
||||
id = "0x00158d0002b00e04";
|
||||
#groups = [ "bed_room" ];
|
||||
states.single = "input_boolean.situation_toggle";
|
||||
states.hold = "input_boolean.printer_toggle";
|
||||
states.double = "input_boolean.windows_up";
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# define input_boolean
|
||||
# --------------------
|
||||
# which get toggled by the buttons
|
||||
input_boolean = let stripEmpty = lib.filter (a: a != { });
|
||||
in builtins.listToAttrs (stripEmpty (lib.flatten (lib.mapAttrsToList (name:
|
||||
{ states ? { }, ... }: [
|
||||
(lib.optionalAttrs (!lib.hasAttr "single" states) {
|
||||
name = "single_${name}";
|
||||
value = { icon = "mdi:toggle-switch"; };
|
||||
})
|
||||
(lib.optionalAttrs (!lib.hasAttr "double" states) {
|
||||
name = "double_${name}";
|
||||
value = { icon = "mdi:toggle-switch"; };
|
||||
})
|
||||
(lib.optionalAttrs (!lib.hasAttr "hold" states) {
|
||||
name = "hold_${name}";
|
||||
value = { icon = "mdi:toggle-switch"; };
|
||||
})
|
||||
]) allDevices)));
|
||||
|
||||
# define meta information sensors
|
||||
sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [
|
||||
{
|
||||
platform = "mqtt";
|
||||
name = name;
|
||||
icon = "mdi:toggle-switch";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
value_template = "{{ value_json.click }}";
|
||||
}
|
||||
{
|
||||
name = "battery_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
icon = "mdi:battery-10";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
icon = "mdi:signal";
|
||||
unit_of_measurement = "lqi";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
]) allDevices);
|
||||
|
||||
binary_sensor = lib.mapAttrsToList (name:
|
||||
{ ... }: {
|
||||
name = name;
|
||||
platform = "mqtt";
|
||||
device_class = "motion";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
payload_on = true;
|
||||
payload_off = false;
|
||||
value_template = "{{ value_json.occupancy }}";
|
||||
}) allDevices;
|
||||
|
||||
# create groups
|
||||
# -------------
|
||||
#group = let
|
||||
# # to have nice panels for every device
|
||||
# sensorGroups = lib.mapAttrs (name:
|
||||
# { states ? { }, ... }:
|
||||
# let
|
||||
# entityIds = { single ? "input_boolean.single_${name}"
|
||||
# , double ? "input_boolean.double_${name}"
|
||||
# , hold ? "input_boolean.hold_${name}", ... }: [
|
||||
# single
|
||||
# double
|
||||
# hold
|
||||
# ];
|
||||
# in {
|
||||
# entities = [ "sensor.${name}" ] ++ (entityIds states)
|
||||
# ++ [ "sensor.battery_${name}" "sensor.link_${name}" ];
|
||||
# }) allDevices;
|
||||
# # sort lights into given groups.
|
||||
# sortedInGroups = let
|
||||
# groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name:
|
||||
# { groups ? [ ], states ? { }, ... }:
|
||||
# map (groupName: {
|
||||
# "${groupName}" = if (lib.hasAttr "single" states) then
|
||||
# states.single
|
||||
# else
|
||||
# "input_boolean.single_${name}";
|
||||
# }) groups) allDevices));
|
||||
# in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
|
||||
#in sortedInGroups // sensorGroups // {
|
||||
# all_sensors.entities =
|
||||
# lib.mapAttrsToList (name: { ... }: "binary_sensor.${name}") allDevices;
|
||||
#};
|
||||
|
||||
# create automation
|
||||
# -----------------
|
||||
automation = let
|
||||
|
||||
# single click
|
||||
toggle_single_button_input = lib.mapAttrsToList (name:
|
||||
{ states ? { }, ... }:
|
||||
let
|
||||
entityId = if (lib.hasAttr "single" states) then
|
||||
states.single
|
||||
else
|
||||
"input_boolean.single_${name}";
|
||||
in {
|
||||
alias = "toggle single click ${name}";
|
||||
trigger = {
|
||||
platform = "mqtt";
|
||||
topic = "zigbee2mqtt/${name}";
|
||||
};
|
||||
condition = {
|
||||
condition = "template";
|
||||
value_template = ''{{ "single" == trigger.payload_json.click}}'';
|
||||
};
|
||||
action = {
|
||||
service = "input_boolean.toggle";
|
||||
data.entity_id = entityId;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
# double click
|
||||
toggle_double_button_input = lib.mapAttrsToList (name:
|
||||
{ states ? { }, ... }:
|
||||
let
|
||||
entityId = if (lib.hasAttr "double" states) then
|
||||
states.double
|
||||
else
|
||||
"input_boolean.double_${name}";
|
||||
in {
|
||||
alias = "toggle double click ${name}";
|
||||
trigger = {
|
||||
platform = "mqtt";
|
||||
topic = "zigbee2mqtt/${name}";
|
||||
};
|
||||
condition = {
|
||||
condition = "template";
|
||||
value_template = ''{{ "double" == trigger.payload_json.click}}'';
|
||||
};
|
||||
action = {
|
||||
service = "input_boolean.toggle";
|
||||
data.entity_id = entityId;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
# hold
|
||||
toggle_hold_button_input = lib.mapAttrsToList (name:
|
||||
{ states ? { }, ... }:
|
||||
let
|
||||
entityId = if (lib.hasAttr "hold" states) then
|
||||
states.hold
|
||||
else
|
||||
"input_boolean.hold_${name}";
|
||||
in {
|
||||
alias = "toggle hold ${name}";
|
||||
trigger = {
|
||||
platform = "mqtt";
|
||||
topic = "zigbee2mqtt/${name}";
|
||||
};
|
||||
condition = {
|
||||
condition = "template";
|
||||
value_template = ''{{ "hold" == trigger.payload_json.action}}'';
|
||||
};
|
||||
action = {
|
||||
service = "input_boolean.toggle";
|
||||
data.entity_id = entityId;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
in lib.flatten (toggle_single_button_input ++ toggle_double_button_input
|
||||
++ toggle_hold_button_input);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let cfg = config.services.zigbee2mqttConfiguration;
|
||||
in {
|
||||
options.services.zigbee2mqttConfiguration = mkOption {
|
||||
type = with types; attrs;
|
||||
description = ''
|
||||
device definitions
|
||||
'';
|
||||
};
|
||||
config = { services.zigbee2mqtt.config.devices = cfg; };
|
||||
}
|
||||
87
nixos/configs/pepe/home-assistant/zigbee2mqtt/doors.nix
Normal file
87
nixos/configs/pepe/home-assistant/zigbee2mqtt/doors.nix
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/MCCGQ11LM.html
|
||||
allDevices = {
|
||||
"door_sensor_1" = { id = "0x00158d000312dc52"; };
|
||||
"door_sensor_2" = { id = "0x00158d000316d5bf"; };
|
||||
"door_sensor_3" = { id = "0x00158d0002f9516f"; };
|
||||
"door_sensor_4" = { id = "0x00158d00031383b9"; };
|
||||
"door_sensor_5" = { id = "0x00158d0003120d3e"; };
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# define meta information sensors
|
||||
sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [
|
||||
{
|
||||
name = "battery_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
icon = "mdi:battery-10";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
icon = "mdi:signal";
|
||||
unit_of_measurement = "lqi";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
]) allDevices);
|
||||
|
||||
binary_sensor = lib.mapAttrsToList (name:
|
||||
{ ... }: {
|
||||
name = name;
|
||||
platform = "mqtt";
|
||||
device_class = "door";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
payload_on = false;
|
||||
payload_off = true;
|
||||
value_template = "{{ value_json.contact}}";
|
||||
}) allDevices;
|
||||
|
||||
# create groups
|
||||
# -------------
|
||||
group = let
|
||||
# to have nice panels for every device
|
||||
sensorGroups = lib.mapAttrs (name:
|
||||
{ ... }: {
|
||||
entities = [
|
||||
"binary_sensor.${name}"
|
||||
"sensor.battery_${name}"
|
||||
"sensor.link_${name}"
|
||||
];
|
||||
}) allDevices;
|
||||
# sort lights into given groups.
|
||||
sortedInGroups = let
|
||||
groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name:
|
||||
{ groups ? [ ], ... }:
|
||||
map (groupName: { "${groupName}" = "binary_sensor.${name}"; }) groups)
|
||||
allDevices));
|
||||
in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
|
||||
in sortedInGroups // sensorGroups // {
|
||||
all_sensors.entities =
|
||||
lib.mapAttrsToList (name: { ... }: "binary_sensor.${name}") allDevices;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
52
nixos/configs/pepe/home-assistant/zigbee2mqtt/fyrtur.nix
Normal file
52
nixos/configs/pepe/home-assistant/zigbee2mqtt/fyrtur.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/E1757.html
|
||||
allDevices = {
|
||||
"office_fyrtur_1" = { id = "0x680ae2fffe64fa40"; };
|
||||
"office_fyrtur_2" = { id = "0x680ae2fffe91d234"; };
|
||||
"bedroom_fyrtur_1" = { id = "0x680ae2fffe6e9f41"; };
|
||||
"broken_fyrtur_1" = { id = "0x680ae2fffe8f6411"; };
|
||||
};
|
||||
|
||||
# -t "zigbee2mqtt/fyrtur1/set" -m '{"position":100}'
|
||||
# -t "zigbee2mqtt/fyrtur1/set" -m '{"position":15}'
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
transition = 0.1;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [
|
||||
{
|
||||
name = "battery_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
icon = "mdi:battery-10";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
icon = "mdi:signal";
|
||||
unit_of_measurement = "lqi";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
]) allDevices);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
80
nixos/configs/pepe/home-assistant/zigbee2mqtt/heater.nix
Normal file
80
nixos/configs/pepe/home-assistant/zigbee2mqtt/heater.nix
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/SPZB0001.html
|
||||
allDevices = {
|
||||
"office_heater_1" = { id = "0x00158d00032f5ee4"; }; # office
|
||||
"office_heater_2" = { id = "0x00158d00032f5f9f"; }; # office (kitchen)
|
||||
"bedroom_heater_1" = { id = "0x00158d00032f6d1e"; }; # bed room
|
||||
"storage_heater_1" = { id = "0x00158d00032f604d"; }; # abstell raum
|
||||
};
|
||||
|
||||
# -t "zigbee2mqtt/heater3/set" -m '{"system_mode":"auto","current_heating_setpoint":23}'
|
||||
# -t "zigbee2mqtt/heater3/set" -m '{"system_mode":"off"}'
|
||||
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
legacy = false;
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
transition = 1;
|
||||
debounce = 0.5;
|
||||
filtered_attributes = [
|
||||
"battery_low"
|
||||
"eurotronic_host_flags"
|
||||
"eurotronic_system_mode"
|
||||
#"occupied_heating_setpoint"
|
||||
#"pi_heating_demand"
|
||||
#"unoccupied_heating_setpoint"
|
||||
];
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [
|
||||
{
|
||||
name = "battery_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
icon = "mdi:battery-10";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
icon = "mdi:signal";
|
||||
unit_of_measurement = "lqi";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
{
|
||||
platform = "mqtt";
|
||||
name = "temperature_${name}";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "°C";
|
||||
device_class = "temperature";
|
||||
value_template = "{{ value_json.local_temperature }}";
|
||||
}
|
||||
{
|
||||
platform = "mqtt";
|
||||
name = "pi_heating_demand_${name}";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
value_template = "{{ value_json.pi_heating_demand }}";
|
||||
}
|
||||
]) allDevices);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
43
nixos/configs/pepe/home-assistant/zigbee2mqtt/leds.nix
Normal file
43
nixos/configs/pepe/home-assistant/zigbee2mqtt/leds.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/GL-C-007-1ID.html
|
||||
allDevices = {
|
||||
"led_1" = { id = "0x00124b001f7a5be9"; };
|
||||
"led_2" = { id = "0x00124b001ee958b3"; };
|
||||
};
|
||||
|
||||
# -t "zigbee2mqtt/led_1/set" -m '{"state":"ON","transition":0, "color_temp":255}'
|
||||
# -t "zigbee2mqtt/led_1/set" -m '{"state":"OFF","transition":0, "color_temp":255}'
|
||||
# -t "zigbee2mqtt/led_1/set" -m '{"state":"ON","brightness":255,"color":{"hex":"#00FFFF"}}'
|
||||
# -t "zigbee2mqtt/led_1/set" -m '{"state":"OFF"}'
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
transition = 1;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
light = lib.mapAttrsToList (name:
|
||||
{ ... }: {
|
||||
platform = "mqtt";
|
||||
name = name;
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
command_topic = "zigbee2mqtt/${name}/set";
|
||||
value_template = "{{ value_json.click }}";
|
||||
brightness = true;
|
||||
color_temp = true;
|
||||
schema = "json";
|
||||
}) allDevices;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
94
nixos/configs/pepe/home-assistant/zigbee2mqtt/lights.nix
Normal file
94
nixos/configs/pepe/home-assistant/zigbee2mqtt/lights.nix
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/AC10787.html
|
||||
allDevices = {
|
||||
"light_1" = { id = "0x7cb03eaa0a0347b5"; };
|
||||
"light_2" = { id = "0x7cb03eaa0a0387b9"; };
|
||||
"light_3" = { id = "0x7cb03eaa0a033a86"; };
|
||||
"light_4" = { id = "0x7cb03eaa0a04aabf"; };
|
||||
"light_5" = { id = "0x7cb03eaa0a0346e4"; };
|
||||
"light_6" = { id = "0x7cb03eaa0a034b46"; };
|
||||
"light_7" = { id = "0x7cb03eaa0a033b4f"; };
|
||||
"light_8" = { id = "0x7cb03eaa0a0384d3"; };
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
osram_set_transition = 2; # time in seconds (integer or float)
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
light = lib.mapAttrsToList (name:
|
||||
{ ... }: {
|
||||
platform = "mqtt";
|
||||
name = name;
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
command_topic = "zigbee2mqtt/${name}/set";
|
||||
value_template = "{{ value_json.click }}";
|
||||
brightness = true;
|
||||
color_temp = true;
|
||||
schema = "json";
|
||||
}) allDevices;
|
||||
|
||||
# sensor = with lib;
|
||||
# mapAttrsToList (name:
|
||||
# { ... }: {
|
||||
# name = "link_${name}";
|
||||
# platform = "mqtt";
|
||||
# state_topic = "zigbee2mqtt/${name}";
|
||||
# availability_topic = "zigbee2mqtt/bridge/state";
|
||||
# icon = "mdi:signal";
|
||||
# value_template = "{{ value_json.linkquality}}";
|
||||
# }) allDevices;
|
||||
|
||||
# binary_sensor = lib.mapAttrsToList (name:
|
||||
# { ... }: {
|
||||
# name = "update_${name}";
|
||||
# platform = "mqtt";
|
||||
# state_topic = "zigbee2mqtt/${name}";
|
||||
# availability_topic = "zigbee2mqtt/bridge/state";
|
||||
# payload_on = true;
|
||||
# payload_off = false;
|
||||
# value_template = "{{ value_json.update_available }}";
|
||||
# }) allDevices;
|
||||
|
||||
# # create groups
|
||||
# # -------------
|
||||
# group = let
|
||||
|
||||
# # to have nice panels for every device
|
||||
# lightGroups = lib.mapAttrs (name:
|
||||
# { ... }: {
|
||||
# entities = [
|
||||
# "light.${name}"
|
||||
# "sensor.link_${name}"
|
||||
# "binary_sensor.update_${name}"
|
||||
# ];
|
||||
# }) allDevices;
|
||||
|
||||
# # sort lights into given groups.
|
||||
# sortedInGroups = let
|
||||
# groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name:
|
||||
# { groups ? [ ], ... }:
|
||||
# map (groupName: { "${groupName}" = "light.${name}"; }) groups)
|
||||
# allDevices));
|
||||
# in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
|
||||
|
||||
# in sortedInGroups // lightGroups // {
|
||||
# all_lights.entities =
|
||||
# lib.mapAttrsToList (name: { ... }: "light.${name}") allDevices;
|
||||
# };
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
69
nixos/configs/pepe/home-assistant/zigbee2mqtt/motion.nix
Normal file
69
nixos/configs/pepe/home-assistant/zigbee2mqtt/motion.nix
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/RTCGQ01LM.html
|
||||
allDevices = {
|
||||
|
||||
"motion_sensor_1" = { id = "0x00158d0002fbd451"; };
|
||||
"motion_sensor_2" = { id = "0x00158d0002f9a6b8"; };
|
||||
"motion_sensor_3" = { id = "0x00158d0002f04522"; };
|
||||
"motion_sensor_4" = { id = "0x00158d0002f9a558"; };
|
||||
"motion_sensor_5" = { id = "0x00158d0002f9a56f"; };
|
||||
"motion_sensor_6" = { id = "0x00158d0002f9a5cb"; };
|
||||
"motion_sensor_7" = { id = "0x00158d0002f9a6aa"; };
|
||||
"motion_sensor_8" = { id = "0x00158d0002f04637"; };
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, timeout ? 65, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
# should not be set below 60 seconds
|
||||
occupancy_timeout = timeout;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# define meta information sensors
|
||||
binary_sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [{
|
||||
name = "${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
value_template = "{{ value_json.occupancy }}";
|
||||
#icon = "mdi:battery-10";
|
||||
payload_on = true;
|
||||
payload_off = false;
|
||||
device_class = "motion";
|
||||
}]) allDevices);
|
||||
|
||||
# define meta information sensors
|
||||
sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [
|
||||
{
|
||||
name = "battery_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
icon = "mdi:battery-10";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
icon = "mdi:signal";
|
||||
unit_of_measurement = "lqi";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
]) allDevices);
|
||||
};
|
||||
}
|
||||
18
nixos/configs/pepe/home-assistant/zigbee2mqtt/repeater.nix
Normal file
18
nixos/configs/pepe/home-assistant/zigbee2mqtt/repeater.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/SPZB0001.html
|
||||
allDevices = {
|
||||
"repeater1" = { id = "0x680ae2fffe6e7dc1"; };
|
||||
"repeater2" = { id = "0x680ae2fffe8e240d"; };
|
||||
"repeater3" = { id = "0x680ae2fffe404f60"; };
|
||||
"repeater4" = { id = "0x680ae2fffe8e2e71"; };
|
||||
};
|
||||
|
||||
in {
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = { friendly_name = name; };
|
||||
}) allDevices;
|
||||
}
|
||||
118
nixos/configs/pepe/home-assistant/zigbee2mqtt/service.nix
Normal file
118
nixos/configs/pepe/home-assistant/zigbee2mqtt/service.nix
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.custom.services.zigbee2mqtt;
|
||||
|
||||
configJSON = pkgs.writeText "configuration.json" (builtins.toJSON
|
||||
(recursiveUpdate cfg.config config.services.zigbee2mqtt.config));
|
||||
configFile =
|
||||
pkgs.runCommand "configuration.yaml" { preferLocalBuild = true; } ''
|
||||
${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out
|
||||
'';
|
||||
|
||||
# the default config contains all required settings,
|
||||
# so the service starts up without crashing.
|
||||
defaultConfig = {
|
||||
homeassistant = false;
|
||||
permit_join = false;
|
||||
mqtt = {
|
||||
base_topic = "zigbee2mqtt";
|
||||
server = "mqtt://localhost:1883";
|
||||
};
|
||||
serial.port = "/dev/ttyACM0";
|
||||
# put device configuration into separate file because configuration.yaml
|
||||
# is copied from the store on startup
|
||||
devices = "devices.yaml";
|
||||
};
|
||||
in {
|
||||
options.custom.services.zigbee2mqtt = {
|
||||
enable = mkEnableOption "enable zigbee2mqtt service";
|
||||
|
||||
package = mkOption {
|
||||
description = "ignored";
|
||||
default = pkgs.zigbee2mqtt.override { dataDir = cfg.dataDir; };
|
||||
defaultText = "pkgs.zigbee2mqtt";
|
||||
type = types.package;
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
description = "Zigbee2mqtt data directory";
|
||||
default = "/var/lib/zigbee2mqtt";
|
||||
type = types.path;
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
default = { };
|
||||
type = with types; nullOr attrs;
|
||||
example = literalExample ''
|
||||
{
|
||||
homeassistant = config.services.home-assistant.enable;
|
||||
permit_join = true;
|
||||
serial = {
|
||||
port = "/dev/ttyACM1";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Your <filename>configuration.yaml</filename> as a Nix attribute set.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable) {
|
||||
|
||||
virtualisation.oci-containers.containers.zigbee2mqtt = {
|
||||
image = "koenkk/zigbee2mqtt:1.18.1";
|
||||
volumes = [
|
||||
"${cfg.dataDir}:/app/data"
|
||||
#"/run/udev:/run/udev:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
"--device=${cfg.config.serial.port}" # /dev/ttyUSB0
|
||||
"--network=host"
|
||||
#"--privileged=true"
|
||||
];
|
||||
environment = { TZ = "Europe/Amsterdam"; };
|
||||
#ports = [ "127.0.0.1:${toString frontPort}:80" ];
|
||||
};
|
||||
|
||||
# create config before staring container
|
||||
systemd.services.docker-zigbee2mqtt = {
|
||||
preStart = ''
|
||||
cp --no-preserve=mode ${configFile} "${cfg.dataDir}/configuration.yaml"
|
||||
'';
|
||||
};
|
||||
|
||||
#systemd.services.zigbee2mqtt = {
|
||||
# description = "Zigbee2mqtt Service";
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# after = [ "network.target" ];
|
||||
# environment.ZIGBEE2MQTT_DATA = cfg.dataDir;
|
||||
# serviceConfig = {
|
||||
# ExecStart = "${cfg.package}/bin/zigbee2mqtt";
|
||||
# User = "zigbee2mqtt";
|
||||
# WorkingDirectory = cfg.dataDir;
|
||||
# Restart = "on-failure";
|
||||
# ProtectSystem = "strict";
|
||||
# ReadWritePaths = cfg.dataDir;
|
||||
# PrivateTmp = true;
|
||||
# RemoveIPC = true;
|
||||
# };
|
||||
# preStart = ''
|
||||
# cp --no-preserve=mode ${configFile} "${cfg.dataDir}/configuration.yaml"
|
||||
# '';
|
||||
#};
|
||||
|
||||
#users.users.zigbee2mqtt = {
|
||||
# home = cfg.dataDir;
|
||||
# createHome = true;
|
||||
# group = "zigbee2mqtt";
|
||||
# extraGroups = [ "dialout" ];
|
||||
# uid = config.ids.uids.zigbee2mqtt;
|
||||
#};
|
||||
|
||||
#users.groups.zigbee2mqtt.gid = config.ids.gids.zigbee2mqtt;
|
||||
};
|
||||
}
|
||||
107
nixos/configs/pepe/home-assistant/zigbee2mqtt/temperatur.nix
Normal file
107
nixos/configs/pepe/home-assistant/zigbee2mqtt/temperatur.nix
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
{ pkgs, lib, ... }:
|
||||
let
|
||||
|
||||
# https://www.zigbee2mqtt.io/devices/WSDCGQ11LM.html
|
||||
allDevices = {
|
||||
"temperature_sensor_1" = {
|
||||
id = "0x00158d0002d79220";
|
||||
groups = [ "living_room" ];
|
||||
};
|
||||
"temperature_sensor_2" = {
|
||||
id = "0x00158d0002d7913d";
|
||||
groups = [ "living_room" ];
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.zigbee2mqttConfiguration = lib.mapAttrs' (name:
|
||||
{ id, ... }: {
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
};
|
||||
}) allDevices;
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# define meta information sensors
|
||||
sensor = lib.flatten (lib.mapAttrsToList (name:
|
||||
{ ... }: [
|
||||
{
|
||||
platform = "mqtt";
|
||||
name = name;
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "°C";
|
||||
device_class = "temperature";
|
||||
value_template = "{{ value_json.temperature }}";
|
||||
}
|
||||
{
|
||||
platform = "mqtt";
|
||||
name = "humidity_${name}";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
device_class = "humidity";
|
||||
value_template = "{{ value_json.humidity }}";
|
||||
}
|
||||
#{
|
||||
# platform = "mqtt";
|
||||
# name = "pressure_${name}";
|
||||
# state_topic = "zigbee2mqtt/${name}";
|
||||
# availability_topic = "zigbee2mqtt/bridge/state";
|
||||
# unit_of_measurement = "hPa";
|
||||
# device_class = "pressure";
|
||||
# value_template = "{{ value_json.pressure }}";
|
||||
#}
|
||||
{
|
||||
name = "battery_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
icon = "mdi:battery-10";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
icon = "mdi:signal";
|
||||
unit_of_measurement = "lqi";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
]) allDevices);
|
||||
|
||||
# create groups
|
||||
# -------------
|
||||
#group = let
|
||||
# # to have nice panels for every device
|
||||
# sensorGroups = lib.mapAttrs (name:
|
||||
# { ... }: {
|
||||
# entities = [
|
||||
# "sensor.${name}"
|
||||
# "sensor.humidity_${name}"
|
||||
# #"sensor.pressure_${name}"
|
||||
# "sensor.battery_${name}"
|
||||
# "sensor.link_${name}"
|
||||
# ];
|
||||
# }) allDevices;
|
||||
# # sort lights into given groups.
|
||||
# sortedInGroups = let
|
||||
# groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name:
|
||||
# { groups ? [ ], ... }:
|
||||
# map (groupName: { "${groupName}" = "sensor.${name}"; }) groups)
|
||||
# allDevices));
|
||||
# in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
|
||||
#in sortedInGroups // sensorGroups // {
|
||||
# all_sensors.entities =
|
||||
# lib.mapAttrsToList (name: { ... }: "sensor.${name}") allDevices;
|
||||
#};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
44
nixos/configs/pepe/kodi.nix
Normal file
44
nixos/configs/pepe/kodi.nix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
|
||||
services.xserver = {
|
||||
enable = false;
|
||||
autorun = false;
|
||||
videoDrivers = [ "intel" ];
|
||||
#deviceSection = ''
|
||||
# Option "DRI" "2"
|
||||
# Option "TearFree" "true"
|
||||
#'';
|
||||
desktopManager = {
|
||||
kodi.enable = true;
|
||||
default = "kodi";
|
||||
xterm.enable = false;
|
||||
};
|
||||
displayManager = {
|
||||
sddm = {
|
||||
enable = true;
|
||||
autoLogin = {
|
||||
enable = true;
|
||||
relogin = true;
|
||||
user = config.users.users.kodi.name;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
# mutableUsers = true;
|
||||
users.kodi = {
|
||||
isNormalUser = true;
|
||||
name = "kodi";
|
||||
uid = 1338;
|
||||
initialPassword = lib.fileContents <secrets/kodi/password>;
|
||||
};
|
||||
};
|
||||
|
||||
# allow everybody in the net to access the wifi
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 8080 ];
|
||||
allowedUDPPorts = [ 8080 ];
|
||||
};
|
||||
|
||||
}
|
||||
26
nixos/configs/pepe/lan.nix
Normal file
26
nixos/configs/pepe/lan.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{ lib, pkgs, ... }:
|
||||
let
|
||||
|
||||
interface = "enp0s25";
|
||||
ipAddress = "10.1.0.2";
|
||||
prefixLength = 24;
|
||||
|
||||
in {
|
||||
|
||||
networking.extraHosts = ''
|
||||
10.1.0.1 workout.lan
|
||||
10.1.0.2 pepe.lan
|
||||
'';
|
||||
|
||||
# todo only open needed ports
|
||||
networking.firewall.trustedInterfaces = [ interface ];
|
||||
|
||||
networking.networkmanager.unmanaged = [ interface ];
|
||||
networking.dhcpcd.denyInterfaces = [ interface ];
|
||||
|
||||
networking.interfaces."${interface}".ipv4.addresses = [{
|
||||
address = ipAddress;
|
||||
prefixLength = prefixLength;
|
||||
}];
|
||||
|
||||
}
|
||||
136
nixos/configs/pepe/syncthing.nix
Normal file
136
nixos/configs/pepe/syncthing.nix
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
users.groups."syncthing".members = [ "mpd" "syncthing" "kodi" ];
|
||||
|
||||
custom.samba-share = {
|
||||
enable = true;
|
||||
folders = {
|
||||
movies = config.services.syncthing.declarative.folders.movies.path;
|
||||
music = config.services.syncthing.declarative.folders.music-library.path;
|
||||
samples = config.services.syncthing.declarative.folders.samples.path;
|
||||
series = config.services.syncthing.declarative.folders.series.path;
|
||||
books = config.services.syncthing.declarative.folders.books.path;
|
||||
};
|
||||
#private.test = {
|
||||
# folder = ;
|
||||
# users = "kodi";
|
||||
#};
|
||||
};
|
||||
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = true;
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
|
||||
# on encrypted drive
|
||||
# ------------------
|
||||
private = {
|
||||
enable = true;
|
||||
path = "/home/syncthing/private";
|
||||
};
|
||||
desktop = {
|
||||
enable = true;
|
||||
path = "/home/syncthing/desktop";
|
||||
};
|
||||
finance = {
|
||||
enable = true;
|
||||
path = "/home/syncthing/finance";
|
||||
};
|
||||
lost-fotos = {
|
||||
enable = true;
|
||||
path = "/home/syncthing/lost-fotos.ct";
|
||||
};
|
||||
fotos = {
|
||||
enable = true;
|
||||
path = "/home/syncthing/fotos";
|
||||
};
|
||||
zettlr = {
|
||||
enable = true;
|
||||
path = "/home/syncthing/zettlr";
|
||||
};
|
||||
|
||||
# no need to be encrypted
|
||||
# -----------------------
|
||||
borg-mirror = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/borg";
|
||||
rescanInterval = 36 * 3600;
|
||||
type = "receiveonly";
|
||||
};
|
||||
books = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/books";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
movies = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/movies";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
music-projects = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/music-projects";
|
||||
};
|
||||
music-library = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/music-library";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
music-library-free = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/music-library-free";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
samples = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/samples";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
series = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/series";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
smartphone-folder = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/smartphone-folder";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
video-material = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/video-material";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
processing = {
|
||||
enable = true;
|
||||
path = "/media/syncthing/sketchbook";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
system.permown."/home/syncthing" = {
|
||||
owner = "syncthing";
|
||||
group = "syncthing";
|
||||
};
|
||||
system.permown."/media/syncthing" = {
|
||||
owner = "syncthing";
|
||||
group = "syncthing";
|
||||
};
|
||||
systemd.services."permown._media_syncthing" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
systemd.services."syncthing" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
|
||||
}
|
||||
18
nixos/configs/pepe/tinc.nix
Normal file
18
nixos/configs/pepe/tinc.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
"retiolum" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
78
nixos/configs/pepe/wifi-access-point.nix
Normal file
78
nixos/configs/pepe/wifi-access-point.nix
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# you find this device using `ifconfig -a` or `ip link`
|
||||
wifi = "wlp0s26u1u2";
|
||||
#wifi = "wlp3s0-ifb";
|
||||
ipAddress = "10.23.45.1";
|
||||
prefixLength = 24;
|
||||
servedAddressRange = "10.23.45.2,10.23.45.150,12h";
|
||||
ssid = "palosiot";
|
||||
wifiPassword = lib.fileContents <secrets/iot_wifi>;
|
||||
|
||||
in {
|
||||
|
||||
# todo only open needed ports
|
||||
networking.firewall.trustedInterfaces = [ wifi ];
|
||||
|
||||
networking.networkmanager.unmanaged = [ wifi ];
|
||||
networking.dhcpcd.denyInterfaces = [ wifi ];
|
||||
|
||||
networking.interfaces."${wifi}".ipv4.addresses = [{
|
||||
address = ipAddress;
|
||||
prefixLength = prefixLength;
|
||||
}];
|
||||
|
||||
systemd.services.hostapd = {
|
||||
description = "hostapd wireless AP";
|
||||
path = [ pkgs.hostapd ];
|
||||
wantedBy = [ "network.target" ];
|
||||
|
||||
after = [
|
||||
"${wifi}-cfg.service"
|
||||
"nat.service"
|
||||
"bind.service"
|
||||
"dhcpd.service"
|
||||
"sys-subsystem-net-devices-${wifi}.device"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.hostapd}/bin/hostapd ${
|
||||
pkgs.writeText "hostapd.conf" ''
|
||||
interface=${wifi}
|
||||
hw_mode=g
|
||||
channel=10
|
||||
ieee80211d=1
|
||||
country_code=DE
|
||||
ieee80211n=1
|
||||
wmm_enabled=1
|
||||
|
||||
ssid=${ssid}
|
||||
auth_algs=1
|
||||
wpa=2
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
rsn_pairwise=CCMP
|
||||
wpa_passphrase=${wifiPassword}
|
||||
''
|
||||
}";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
# Only listen to routers' LAN NIC. Doing so opens up tcp/udp port 53 to
|
||||
# localhost and udp port 67 to world:
|
||||
interface=${wifi}
|
||||
|
||||
# Explicitly specify the address to listen on
|
||||
listen-address=${ipAddress}
|
||||
|
||||
# Dynamic range of IPs to make available to LAN PC and the lease time.
|
||||
# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records.
|
||||
dhcp-range=${servedAddressRange}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
56
nixos/configs/porani/configuration.nix
Normal file
56
nixos/configs/porani/configuration.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{ pkgs, lib, config, ... }: {
|
||||
imports = [
|
||||
|
||||
<system/server>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./tinc.nix
|
||||
./syncthing.nix
|
||||
#./kodi.nix
|
||||
|
||||
];
|
||||
|
||||
networking.hostName = "porani";
|
||||
|
||||
# not needed because not encrypted
|
||||
# enable initrd ssh
|
||||
#configuration.init-ssh = {
|
||||
# enable = "enabled";
|
||||
# kernelModules = [ "e1000e" ];
|
||||
# hostECDSAKey = <secrets/init-ssh/host_ecdsa_key>;
|
||||
#};
|
||||
|
||||
# programs
|
||||
programs.custom.vim.enable = true;
|
||||
environment.systemPackages = [ pkgs.mosh ];
|
||||
|
||||
# wifi setup
|
||||
system.custom.wifi = {
|
||||
enable = true;
|
||||
configurationFile = <secrets/wpa_supplicant>;
|
||||
interfaces = [ "wlp3s0" ];
|
||||
};
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
configuration.fireqos = {
|
||||
enable = true;
|
||||
interface = "wlp3s0";
|
||||
input = 2500;
|
||||
output = 1200;
|
||||
balance = false;
|
||||
};
|
||||
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
#configuration.fireqos = {
|
||||
# enable = true;
|
||||
# interface = "eth0";
|
||||
# input = 2500;
|
||||
# output = 1200;
|
||||
# balance = false;
|
||||
#};
|
||||
|
||||
# new Zealand overwrites
|
||||
# services.netdata.enable = lib.mkForce false ;
|
||||
services.SystemdJournal2Gelf.enable = lib.mkForce false;
|
||||
|
||||
}
|
||||
|
||||
79
nixos/configs/porani/hardware-configuration.nix
Normal file
79
nixos/configs/porani/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
imports = [
|
||||
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
||||
|
||||
# boot loader
|
||||
# -----------
|
||||
{
|
||||
# Use the systemd-boot EFI boot loader, not grub
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
#boot.loader.grub = {
|
||||
# device = "/dev/sda";
|
||||
# enable = true;
|
||||
# version = 2;
|
||||
#};
|
||||
}
|
||||
|
||||
# kernel
|
||||
# ------
|
||||
{
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
}
|
||||
|
||||
# automount
|
||||
# ---------
|
||||
(let mediaUUID = "3d106f56-89e5-400d-9d6b-1dd957919548";
|
||||
in {
|
||||
fileSystems."/media" = {
|
||||
device = "/dev/disk/by-uuid/${mediaUUID}";
|
||||
fsType = "ext4";
|
||||
options = [
|
||||
"nofail"
|
||||
"noauto"
|
||||
#"x-systemd.device-timeout=1ms"
|
||||
];
|
||||
};
|
||||
systemd.mounts = [{
|
||||
enable = true;
|
||||
options = "nofail,noauto";
|
||||
type = "ext4";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
what = "/dev/disk/by-uuid/${mediaUUID}";
|
||||
where = "/media";
|
||||
}];
|
||||
})
|
||||
];
|
||||
|
||||
# NTFS support
|
||||
# ------------
|
||||
environment.systemPackages = [ pkgs.ntfs3g ];
|
||||
|
||||
# partitions
|
||||
# ----------
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/77a3e839-5a80-4777-93c3-31be7f0cb99d";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/FBFB-8DA5";
|
||||
fsType = "vfat";
|
||||
};
|
||||
fileSystems."/home" = {
|
||||
device = "/dev/disk/by-uuid/192a8bd6-e5f7-4e66-b69e-f3da701da343";
|
||||
fsType = "ext4";
|
||||
};
|
||||
fileSystems."/backup" = {
|
||||
device = "/dev/disk/by-uuid/ca895f0e-f932-4a9e-b2ff-a1a488b0953d";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nix.maxJobs = lib.mkDefault 4;
|
||||
|
||||
}
|
||||
38
nixos/configs/porani/kodi.nix
Normal file
38
nixos/configs/porani/kodi.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
autorun = true;
|
||||
desktopManager = {
|
||||
kodi.enable = true;
|
||||
default = "kodi";
|
||||
xterm.enable = false;
|
||||
};
|
||||
displayManager = {
|
||||
sddm = {
|
||||
enable = true;
|
||||
autoLogin = {
|
||||
enable = true;
|
||||
relogin = true;
|
||||
user = config.users.users.kodi.name;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
# mutableUsers = true;
|
||||
users.kodi = {
|
||||
isNormalUser = true;
|
||||
name = "kodi";
|
||||
uid = 1338;
|
||||
initialPassword = lib.fileContents <secrets/kodi/password>;
|
||||
};
|
||||
};
|
||||
|
||||
# allow everybody in the net to access the wifi
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 8080 ];
|
||||
allowedUDPPorts = [ 8080 ];
|
||||
};
|
||||
}
|
||||
11
nixos/configs/porani/mpd.nix
Normal file
11
nixos/configs/porani/mpd.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{ config, lib, ... }: {
|
||||
|
||||
sound.enable = true;
|
||||
|
||||
services.mpd = {
|
||||
enable = true;
|
||||
network.listenAddress = "any";
|
||||
musicDirectory = "/media/music-library";
|
||||
};
|
||||
|
||||
}
|
||||
5
nixos/configs/porani/packages.nix
Normal file
5
nixos/configs/porani/packages.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ pkgs, ... }: {
|
||||
|
||||
environment.systemPackages = [ ];
|
||||
|
||||
}
|
||||
62
nixos/configs/porani/syncthing.nix
Normal file
62
nixos/configs/porani/syncthing.nix
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
networking.firewall.interfaces."tinc.secure".allowedTCPPorts = [ 8384 ];
|
||||
|
||||
custom.samba-share = {
|
||||
enable = true;
|
||||
folders = {
|
||||
movies = config.services.syncthing.declarative.folders.movies.path;
|
||||
series = config.services.syncthing.declarative.folders.series.path;
|
||||
music = config.services.syncthing.declarative.folders.music-library.path;
|
||||
};
|
||||
};
|
||||
|
||||
services.syncthing = {
|
||||
guiAddress = lib.mkForce "${config.networking.hostName}.secret:8384";
|
||||
enable = true;
|
||||
openDefaultPorts = true;
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
# on media hard drive (not encrypted)
|
||||
# -----------------------------------
|
||||
movies = {
|
||||
enable = true;
|
||||
path = "/media/movies";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
music-library = {
|
||||
enable = true;
|
||||
path = "/media/music-library";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
series = {
|
||||
enable = true;
|
||||
path = "/media/series";
|
||||
rescanInterval = 8 * 3600;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
system.permown."/media" = {
|
||||
owner = "syncthing";
|
||||
group = "syncthing";
|
||||
};
|
||||
systemd.services."permown._media" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
systemd.services."syncthing" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
|
||||
users.groups."syncthing".members = [ "mpd" "syncthing" "kodi" "palo" ];
|
||||
|
||||
backup.dirs = [ "/var/lib/syncthing/finance" ];
|
||||
|
||||
}
|
||||
|
||||
16
nixos/configs/porani/tinc.nix
Normal file
16
nixos/configs/porani/tinc.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
|
||||
module.cluster.services.tinc = {
|
||||
#"private" = {
|
||||
# enable = true;
|
||||
# openPort = true;
|
||||
# connectTo = [ "sputnik" ];
|
||||
#};
|
||||
"secure" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
75
nixos/configs/porani/wifi-access-point.nix
Normal file
75
nixos/configs/porani/wifi-access-point.nix
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
wifi = "wlp0s29u1u2";
|
||||
ipAddress = "10.23.45.1";
|
||||
prefixLength = 24;
|
||||
servedAddressRange = "10.23.45.2,10.23.45.150,12h";
|
||||
ssid = "palosiot";
|
||||
wifiPassword = lib.fileContents <secrets/iot_wifi>;
|
||||
|
||||
in {
|
||||
# todo only open needed ports
|
||||
networking.firewall.trustedInterfaces = [ wifi ];
|
||||
|
||||
networking.networkmanager.unmanaged = [ wifi ];
|
||||
networking.dhcpcd.denyInterfaces = [ wifi ];
|
||||
|
||||
networking.interfaces."${wifi}".ipv4.addresses = [{
|
||||
address = ipAddress;
|
||||
prefixLength = prefixLength;
|
||||
}];
|
||||
|
||||
systemd.services.hostapd = {
|
||||
description = "hostapd wireless AP";
|
||||
path = [ pkgs.hostapd ];
|
||||
wantedBy = [ "network.target" ];
|
||||
|
||||
after = [
|
||||
"${wifi}-cfg.service"
|
||||
"nat.service"
|
||||
"bind.service"
|
||||
"dhcpd.service"
|
||||
"sys-subsystem-net-devices-${wifi}.device"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.hostapd}/bin/hostapd ${
|
||||
pkgs.writeText "hostapd.conf" ''
|
||||
interface=${wifi}
|
||||
hw_mode=g
|
||||
channel=10
|
||||
ieee80211d=1
|
||||
country_code=DE
|
||||
ieee80211n=1
|
||||
wmm_enabled=1
|
||||
|
||||
ssid=${ssid}
|
||||
auth_algs=1
|
||||
wpa=2
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
rsn_pairwise=CCMP
|
||||
wpa_passphrase=${wifiPassword}
|
||||
''
|
||||
}";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
# Only listen to routers' LAN NIC. Doing so opens up tcp/udp port 53 to
|
||||
# localhost and udp port 67 to world:
|
||||
interface=${wifi}
|
||||
|
||||
# Explicitly specify the address to listen on
|
||||
listen-address=${ipAddress}
|
||||
|
||||
# Dynamic range of IPs to make available to LAN PC and the lease time.
|
||||
# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records.
|
||||
dhcp-range=${servedAddressRange}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
4
nixos/configs/porani/wifi-networking.nix
Normal file
4
nixos/configs/porani/wifi-networking.nix
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
|
||||
}
|
||||
12
nixos/configs/sputnik/bitwarden.nix
Normal file
12
nixos/configs/sputnik/bitwarden.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
services.bitwarden_rs = {
|
||||
enable = true;
|
||||
config = {
|
||||
domain = "https://bitwarden.ingolf-wagner.de";
|
||||
signupsAllowed = false;
|
||||
rocketPort = 8222;
|
||||
rocketLog = "critical";
|
||||
};
|
||||
};
|
||||
backup.dirs = [ "/var/lib/bitwarden_rs" ];
|
||||
}
|
||||
41
nixos/configs/sputnik/codimd.nix
Normal file
41
nixos/configs/sputnik/codimd.nix
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts.hedgedoc = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
serverName = "md.ingolf-wagner.de";
|
||||
locations."/".extraConfig = ''
|
||||
client_max_body_size 4G;
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://localhost:3091;
|
||||
'';
|
||||
};
|
||||
|
||||
services.hedgedoc = {
|
||||
enable = true;
|
||||
configuration = {
|
||||
allowFreeURL = true;
|
||||
db = {
|
||||
dialect = "sqlite";
|
||||
storage = "/var/lib/hedgedoc/db.sqlite";
|
||||
useCDN = false;
|
||||
};
|
||||
port = 3091;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
54
nixos/configs/sputnik/configuration.nix
Normal file
54
nixos/configs/sputnik/configuration.nix
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
imports = [
|
||||
|
||||
<system/proxy>
|
||||
./hardware-configuration.nix
|
||||
|
||||
<system/server/packages.nix>
|
||||
./nginx.nix
|
||||
./tinc.nix
|
||||
./codimd.nix
|
||||
./bitwarden.nix
|
||||
#./syncplay.nix
|
||||
|
||||
];
|
||||
|
||||
networking.hostName = "sputnik";
|
||||
networking.useDHCP = true;
|
||||
|
||||
boot.kernelParams = [ "net.ifnames=0" ];
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
version = 2;
|
||||
device = "/dev/sda";
|
||||
};
|
||||
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
configuration.fireqos = {
|
||||
enable = true;
|
||||
interface = "eth0";
|
||||
input = 55000;
|
||||
output = 4000;
|
||||
balance = false;
|
||||
};
|
||||
|
||||
services.custom.ssh.sshd.rootKeyFiles =
|
||||
[ (toString <secrets/ssh/jenkins_rsa.pub>) ];
|
||||
|
||||
# make sure ssh is only available trough the tinc
|
||||
networking.firewall.extraCommands = ''
|
||||
iptables -t nat -A PREROUTING ! -i tinc.private -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 0
|
||||
'';
|
||||
|
||||
# enable all subdomains to be reached to make nginx rules easier
|
||||
services.dnsmasq = with lib; {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
${concatStringsSep "\n"
|
||||
(flip mapAttrsToList config.module.cluster.services.tinc."private".hosts
|
||||
(name: attrs: "address=/.${name}.private/${attrs.tincIp}"))}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
22
nixos/configs/sputnik/hardware-configuration.nix
Normal file
22
nixos/configs/sputnik/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ];
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ata_piix" "uhci_hcd" "virtio_pci" "sd_mod" "sr_mod" ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/8f2986a3-d2b0-4735-be98-9ec081b87984";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nix.maxJobs = lib.mkDefault 1;
|
||||
}
|
||||
19
nixos/configs/sputnik/iodined.nix
Normal file
19
nixos/configs/sputnik/iodined.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{ pkgs, config, ... }:
|
||||
let
|
||||
domain = "io.ingolf-wagner.de";
|
||||
publicIp = "195.201.134.247";
|
||||
pw = import <secrets/iodinepw.nix>;
|
||||
in {
|
||||
|
||||
services.iodine.server = {
|
||||
enable = true;
|
||||
domain = domain;
|
||||
ip = "172.16.10.1/24";
|
||||
extraConfig = "-c -P ${pw} -l ${publicIp}";
|
||||
};
|
||||
|
||||
#krebs.iptables.tables.filter.INPUT.rules = [
|
||||
#{ predicate = "-p udp --dport 53"; target = "ACCEPT";}
|
||||
#];
|
||||
|
||||
}
|
||||
470
nixos/configs/sputnik/nginx.nix
Normal file
470
nixos/configs/sputnik/nginx.nix
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
|
||||
errorPages = pkgs.fetchgit {
|
||||
url = "https://git.ingolf-wagner.de/palo/http-errors.git";
|
||||
rev = "74b8e4c1d9bbba3db6ad858b888e1867318af1f0";
|
||||
sha256 = "0czdzafx4k76q773lyf3vsjm74g1995iz542dhw15kpy5xbivsrg";
|
||||
};
|
||||
|
||||
error = {
|
||||
extraConfig = ''
|
||||
error_page 400 /errors/400.html;
|
||||
error_page 401 /errors/401.html;
|
||||
error_page 402 /errors/402.html;
|
||||
error_page 403 /errors/403.html;
|
||||
error_page 404 /errors/404.html;
|
||||
error_page 405 /errors/405.html;
|
||||
error_page 406 /errors/406.html;
|
||||
error_page 500 /errors/500.html;
|
||||
error_page 501 /errors/501.html;
|
||||
error_page 502 /errors/502.html;
|
||||
error_page 503 /errors/503.html;
|
||||
error_page 504 /errors/504.html;
|
||||
'';
|
||||
locations."^~ /errors/" = {
|
||||
extraConfig = "internal;";
|
||||
root = "${errorPages}/";
|
||||
};
|
||||
};
|
||||
in {
|
||||
|
||||
networking.firewall.allowedTCPPorts =
|
||||
[ 80 443 4443 config.services.taskserver.listenPort ];
|
||||
networking.firewall.allowedUDPPorts =
|
||||
[ 80 443 4443 config.services.taskserver.listenPort ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts = {
|
||||
|
||||
"bitwarden.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${
|
||||
toString config.services.bitwarden_rs.config.rocketPort
|
||||
}";
|
||||
};
|
||||
};
|
||||
|
||||
"git.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://workhorse.private:3000";
|
||||
extraConfig = ''
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
#
|
||||
# Custom headers and headers various browsers *should* be OK with but aren't
|
||||
#
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
#
|
||||
# Tell client that this pre-flight info is valid for 20 days
|
||||
#
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain; charset=utf-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
if ($request_method = 'POST') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
}
|
||||
if ($request_method = 'GET') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
}
|
||||
'';
|
||||
};
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
"paste.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = { proxyPass = "http://workhorse.private:8000"; };
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
"travel.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = {
|
||||
root = "/srv/www/travel";
|
||||
extraConfig = ''
|
||||
if (-d $request_filename) {
|
||||
rewrite [^/]$ $scheme://$http_host$request_uri/ permanent;
|
||||
}
|
||||
'';
|
||||
};
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
"tech.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = {
|
||||
root = "/srv/www/tech";
|
||||
extraConfig = ''
|
||||
if (-d $request_filename) {
|
||||
rewrite [^/]$ $scheme://$http_host$request_uri/ permanent;
|
||||
}
|
||||
'';
|
||||
};
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
"preview.tech.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = {
|
||||
basicAuth.moderator = "IwantitIwantitIwantit";
|
||||
root = "/srv/www/tech_preview";
|
||||
extraConfig = ''
|
||||
if (-d $request_filename) {
|
||||
rewrite [^/]$ $scheme://$http_host$request_uri/ permanent;
|
||||
}
|
||||
'';
|
||||
};
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
"terranix.org" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = {
|
||||
root = "/srv/www/terranix";
|
||||
extraConfig = ''
|
||||
if (-d $request_filename) {
|
||||
rewrite [^/]$ $scheme://$http_host$request_uri/ permanent;
|
||||
}
|
||||
'';
|
||||
};
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
#"chat.ingolf-wagner.de" = {
|
||||
# listen = [
|
||||
# {
|
||||
# addr = "0.0.0.0";
|
||||
# port = 4443;
|
||||
# ssl = true;
|
||||
# }
|
||||
# {
|
||||
# addr = "0.0.0.0";
|
||||
# port = 80;
|
||||
# ssl = false;
|
||||
# }
|
||||
# ];
|
||||
# forceSSL = true;
|
||||
# enableACME = true;
|
||||
# extraConfig = error.extraConfig;
|
||||
# locations = {
|
||||
# "/" = {
|
||||
# proxyPass = "http://chat.workhorse.private";
|
||||
# proxyWebsockets = true;
|
||||
# extraConfig = ''
|
||||
# sub_filter "http://chat.ingolf-wagner.de" "https://chat.ingolf-wagner.de";
|
||||
# sub_filter "chat.workhorse.private" "chat.ingolf-wagner.de";
|
||||
# '';
|
||||
# };
|
||||
# } // error.locations;
|
||||
#};
|
||||
|
||||
"nextcloud.ingolf-wagner.de" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://nextcloud.workhorse.private";
|
||||
extraConfig = ''
|
||||
sub_filter "http://nextcloud.ingolf-wagner.de" "https://nextcloud.ingolf-wagner.de";
|
||||
sub_filter "nextcloud.workhorse.private" "nextcloud.ingolf-wagner.de";
|
||||
# used for view/edit office file via Office Online Server
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
"= /.well-known/carddav" = {
|
||||
priority = 210;
|
||||
extraConfig = "return 301 $scheme://$host/remote.php/dav;";
|
||||
};
|
||||
"= /.well-known/caldav" = {
|
||||
priority = 210;
|
||||
extraConfig = "return 301 $scheme://$host/remote.php/dav;";
|
||||
};
|
||||
"~ .(?:css|js|svg|gif)$" = {
|
||||
proxyPass = "http://nextcloud.workhorse.private$request_uri";
|
||||
extraConfig = ''
|
||||
expires 6M; # Cache-Control policy borrowed from `.htaccess`
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
sub_filter "http://nextcloud.ingolf-wagner.de" "https://nextcloud.ingolf-wagner.de";
|
||||
sub_filter "nextcloud.workhorse.private" "nextcloud.ingolf-wagner.de";
|
||||
# used for view/edit office file via Office Online Server
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
"~ .woff2?$" = {
|
||||
proxyPass = "http://nextcloud.workhorse.private$request_uri";
|
||||
extraConfig = ''
|
||||
expires 7d; # Cache-Control policy borrowed from `.htaccess`
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
sub_filter "http://nextcloud.ingolf-wagner.de" "https://nextcloud.ingolf-wagner.de";
|
||||
sub_filter "nextcloud.workhorse.private" "nextcloud.ingolf-wagner.de";
|
||||
# used for view/edit office file via Office Online Server
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
"gaykraft.com" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 4443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = error.extraConfig;
|
||||
locations = {
|
||||
"/" = { root = "/srv/www/gaykraft"; };
|
||||
} // error.locations;
|
||||
};
|
||||
|
||||
#"home.ingolf-wagner.de" = {
|
||||
# listen = [
|
||||
# {
|
||||
# addr = "0.0.0.0";
|
||||
# port = 4443;
|
||||
# ssl = true;
|
||||
# }
|
||||
# {
|
||||
# addr = "0.0.0.0";
|
||||
# port = 80;
|
||||
# ssl = false;
|
||||
# }
|
||||
# ];
|
||||
# extraConfig = ''
|
||||
# proxy_buffering off;
|
||||
# # client certificate
|
||||
# ssl_client_certificate ${<secrets/client-cert/ca.crt>};
|
||||
# # make verification optional, so we can display a 403 message to those
|
||||
# # who fail authentication
|
||||
# ssl_verify_client optional;
|
||||
# '';
|
||||
# forceSSL = true;
|
||||
# enableACME = true;
|
||||
# locations."/" = {
|
||||
# proxyPass = "http://pepe.private:8123";
|
||||
# proxyWebsockets = true;
|
||||
# extraConfig = ''
|
||||
# # if the client-side certificate failed to authenticate, show a 403
|
||||
# # message to the client
|
||||
# if ($ssl_client_verify != SUCCESS) {
|
||||
# return 403;
|
||||
# }
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_set_header Upgrade $http_upgrade;
|
||||
# proxy_set_header Connection $connection_upgrade;
|
||||
# '';
|
||||
# };
|
||||
#};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
services.sslh = {
|
||||
enable = true;
|
||||
listenAddresses = [ "0.0.0.0" ];
|
||||
port = 443;
|
||||
verbose = true;
|
||||
transparent = true;
|
||||
# List of protocols
|
||||
#
|
||||
# Each protocol entry consists of:
|
||||
# name: name of the probe. These are listed on the command line (ssh -?), plus 'regex' and 'timeout'.
|
||||
# service: (optional) libwrap service name (see hosts_access(5))
|
||||
# host, port: where to connect when this probe succeeds
|
||||
# log_level: 0 to turn off logging
|
||||
# 1 to log each incoming connection
|
||||
# keepalive: Should TCP keepalive be on or off for that
|
||||
# connection (default is off)
|
||||
# fork: Should a new process be forked for this protocol?
|
||||
# (only useful for sslh-select)
|
||||
# tfo_ok: Set to true if the server supports TCP FAST OPEN
|
||||
#
|
||||
# Probe-specific options:
|
||||
# (sslh will try each probe in order they are declared, and
|
||||
# connect to the first that matches.)
|
||||
#
|
||||
# tls:
|
||||
# sni_hostnames: list of FQDN for that target
|
||||
# alpn_protocols: list of ALPN protocols for that target, see:
|
||||
# https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||
#
|
||||
# if both sni_hostnames AND alpn_protocols are specified, both must match
|
||||
#
|
||||
# if neither are set, it is just checked whether this is the TLS protocol or not
|
||||
#
|
||||
# Obviously set the most specific probes
|
||||
# first, and if you use TLS with no ALPN/SNI
|
||||
# set it as the last TLS probe
|
||||
# regex:
|
||||
# regex_patterns: list of patterns to match for
|
||||
# that target.
|
||||
#
|
||||
# You can specify several of 'regex' and 'tls'.
|
||||
appendConfig = ''
|
||||
protocols:
|
||||
(
|
||||
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "2222";},
|
||||
{ name: "tls"; host: "localhost"; port: "4443";},
|
||||
{ name: "tinc"; host: "localhost"; port: "655"; }
|
||||
);
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services."socat-proxy" = {
|
||||
wantedBy = [ "sslh.service" "multi-user.target" ];
|
||||
after = [ "sslh.service" ];
|
||||
script = ''
|
||||
${pkgs.socat}/bin/socat TCP-LISTEN:2222,fork TCP:workhorse.private:2222
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services."socat-taskd" = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = let port = toString config.services.taskserver.listenPort;
|
||||
in ''
|
||||
${pkgs.socat}/bin/socat TCP-LISTEN:${port},fork TCP:workhorse.private:${port}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
5
nixos/configs/sputnik/syncplay.nix
Normal file
5
nixos/configs/sputnik/syncplay.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ config, ... }: {
|
||||
services.syncplay.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [ config.services.syncplay.port ];
|
||||
networking.firewall.allowedUDPPorts = [ config.services.syncplay.port ];
|
||||
}
|
||||
13
nixos/configs/sputnik/tinc.nix
Normal file
13
nixos/configs/sputnik/tinc.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
"secret" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
104
nixos/configs/sternchen/configuration.nix
Normal file
104
nixos/configs/sternchen/configuration.nix
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
imports = [
|
||||
|
||||
<system/desktop>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./packages.nix
|
||||
./syncthing.nix
|
||||
./tinc.nix
|
||||
|
||||
];
|
||||
|
||||
networking.hostName = "sternchen";
|
||||
|
||||
system.custom.mainUser.userName = "tina";
|
||||
|
||||
system.custom.wifi.interfaces = [ "wlp3s0" ];
|
||||
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount}/bin/pumount";
|
||||
};
|
||||
|
||||
programs.custom.steam.enable = false;
|
||||
programs.custom.video.enable = true;
|
||||
|
||||
# keyboard fiddling
|
||||
i18n.defaultLocale = "de_DE.UTF-8";
|
||||
console.keyMap = "de";
|
||||
services.xserver.layout = "de,us";
|
||||
|
||||
system.custom.suspend.enable = false;
|
||||
services.printing.enable = true;
|
||||
|
||||
# fonts
|
||||
# -----
|
||||
programs.custom.urxvt.fontSize = 12;
|
||||
programs.custom.xterm.fontSize = 12;
|
||||
system.custom.fonts.dpi = 100;
|
||||
|
||||
# x11
|
||||
# ---
|
||||
configuration.desktop = {
|
||||
width = 1366;
|
||||
height = 768;
|
||||
};
|
||||
# for congress and streaming
|
||||
hardware.opengl = {
|
||||
enable = true;
|
||||
extraPackages = [ pkgs.vaapiIntel ];
|
||||
driSupport = true;
|
||||
driSupport32Bit = true;
|
||||
};
|
||||
nixpkgs.config.packageOverrides = pkgs: {
|
||||
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
|
||||
};
|
||||
|
||||
services.xserver.displayManager.defaultSession = "plasma5";
|
||||
|
||||
services.xserver.desktopManager.pantheon.enable = false;
|
||||
services.xserver.desktopManager.xfce.enable = false;
|
||||
services.xserver.desktopManager.gnome3.enable = false;
|
||||
|
||||
services.xserver.desktopManager.cinnamon.enable = true;
|
||||
services.xserver.desktopManager.lxqt.enable = true;
|
||||
services.xserver.desktopManager.mate.enable = true;
|
||||
|
||||
services.xserver.desktopManager.plasma5.enable = true;
|
||||
services.xserver.desktopManager.plasma5.phononBackend = "vlc";
|
||||
|
||||
# stuff
|
||||
# -----
|
||||
custom.samba-share = {
|
||||
enable = false;
|
||||
folders = {
|
||||
#public = "/home/palo/movies";
|
||||
share = "/home/share";
|
||||
#syncthing = "/mnt/syncthing";
|
||||
#movies = "/mnt/syncthing/movies";
|
||||
#series = "/mnt/syncthing/series";
|
||||
};
|
||||
};
|
||||
|
||||
# enable this to use sidequest
|
||||
programs.adb.enable = false;
|
||||
users.users.mainUser.extraGroups = [ "adbusers" "video" ];
|
||||
|
||||
virtualisation = {
|
||||
docker.enable = false;
|
||||
|
||||
virtualbox = {
|
||||
host.enable = false;
|
||||
guest.x11 = false;
|
||||
guest.enable = false;
|
||||
};
|
||||
};
|
||||
|
||||
# keybase
|
||||
services.keybase.enable = false;
|
||||
services.kbfs.enable = false;
|
||||
|
||||
}
|
||||
|
||||
79
nixos/configs/sternchen/hardware-configuration.nix
Normal file
79
nixos/configs/sternchen/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
|
||||
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ehci_pci" "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# Use the systemd-boot EFI boot loader, not grub
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
zramSwap = {
|
||||
enable = true;
|
||||
numDevices = 2;
|
||||
swapDevices = 1;
|
||||
memoryPercent = 50;
|
||||
};
|
||||
|
||||
#fileSystems."/share/" = {
|
||||
# device = "/dev/ram1";
|
||||
# fsType = "tmpfs";
|
||||
#};
|
||||
|
||||
#fileSystems."/browsers/" = {
|
||||
# #device = "/dev/ram2";
|
||||
# #fsType = "tmpfs";
|
||||
# options = [ "noatime" "nodiratime" "discard" ];
|
||||
# device = "/dev/vg/browser";
|
||||
# fsType = "ext4";
|
||||
#};
|
||||
|
||||
nix.maxJobs = lib.mkDefault 4;
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = {
|
||||
vg = {
|
||||
device = "/dev/sda2";
|
||||
preLVM = true;
|
||||
};
|
||||
};
|
||||
|
||||
# NTFS support
|
||||
# ------------
|
||||
environment.systemPackages = [ pkgs.ntfs3g ];
|
||||
|
||||
# root
|
||||
# ----
|
||||
fileSystems."/" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/root";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# home
|
||||
# ----
|
||||
fileSystems."/home" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/home";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# boot
|
||||
# ----
|
||||
fileSystems."/boot" = {
|
||||
#device = "/dev/sda1";
|
||||
device = "/dev/disk/by-uuid/EDD4-9795";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
}
|
||||
50
nixos/configs/sternchen/packages.nix
Normal file
50
nixos/configs/sternchen/packages.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
|
||||
# overlay included
|
||||
#nixpkgs.overlays = [ (import <mozilla-overlay/rust-overlay.nix>) ];
|
||||
|
||||
programs.custom.browser.enable = false;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
spotify
|
||||
sweethome3d.application
|
||||
nextcloud-client
|
||||
gimp
|
||||
inkscape
|
||||
darktable
|
||||
keepassxc
|
||||
firefox
|
||||
google-chrome
|
||||
skype
|
||||
tipp10
|
||||
zoom-us
|
||||
gnome3.gnome-todo
|
||||
gnome3.gnome-control-center
|
||||
|
||||
# graphic
|
||||
krita
|
||||
gthumb
|
||||
digikam
|
||||
shotwell
|
||||
#synfigstudio
|
||||
|
||||
# kde programs
|
||||
okular
|
||||
ark
|
||||
gwenview
|
||||
skanlite
|
||||
|
||||
#
|
||||
#tor-browser-bundle-bin
|
||||
(tor-browser-bundle-bin.overrideAttrs (old: rec {
|
||||
version = "10.5";
|
||||
name = "tor-browser-bundle-${version}";
|
||||
src = pkgs.fetchurl {
|
||||
url =
|
||||
"https://dist.torproject.org/torbrowser/10.5/tor-browser-linux64-10.5_en-US.tar.xz";
|
||||
sha256 = "1dq9jys60rn2w37dvb2a69gmqsi7278b782am14wci57kmajlpvm";
|
||||
};
|
||||
}))
|
||||
];
|
||||
|
||||
}
|
||||
12
nixos/configs/sternchen/syncthing.nix
Normal file
12
nixos/configs/sternchen/syncthing.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
services.syncthing = {
|
||||
guiAddress = "localhost:8384";
|
||||
enable = true;
|
||||
openDefaultPorts = true;
|
||||
user = "tina";
|
||||
dataDir = "/home/tina/.syncthing";
|
||||
configDir = "/home/tina/.syncthing";
|
||||
};
|
||||
|
||||
}
|
||||
24
nixos/configs/sternchen/tinc.nix
Normal file
24
nixos/configs/sternchen/tinc.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
module.cluster.services.tinc = {
|
||||
#"private" = {
|
||||
# enable = true;
|
||||
# openPort = true;
|
||||
# connectTo = [ "sputnik" ];
|
||||
#};
|
||||
#"retiolum" = {
|
||||
# enable = true;
|
||||
# openPort = true;
|
||||
#};
|
||||
"secret" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
84
nixos/configs/sternchen/wifi-access-point.nix
Normal file
84
nixos/configs/sternchen/wifi-access-point.nix
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
wifi = "wlp0s29u1u2";
|
||||
ipAddress = "10.123.145.1";
|
||||
prefixLength = 24;
|
||||
servedAddressRange = "10.123.145.2,10.123.145.150,12h";
|
||||
ssid = "bumbumbum";
|
||||
wifiPassword = lib.fileContents <secrets/wifi-access-point>;
|
||||
|
||||
in {
|
||||
# todo only open needed ports
|
||||
networking.firewall.trustedInterfaces = [ wifi ];
|
||||
|
||||
networking.networkmanager.unmanaged = [ wifi ];
|
||||
networking.dhcpcd.denyInterfaces = [ wifi ];
|
||||
|
||||
networking.interfaces."${wifi}".ipv4.addresses = [{
|
||||
address = ipAddress;
|
||||
prefixLength = prefixLength;
|
||||
}];
|
||||
|
||||
# forward traffic coming in trough the access point => provide internet and vpn network access
|
||||
# todo : forward to own servers
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.conf.${wifi}.forwarding" = true;
|
||||
"net.ipv6.conf.${wifi}.forwarding" = true;
|
||||
};
|
||||
|
||||
systemd.services.hostapd = {
|
||||
description = "hostapd wireless AP";
|
||||
path = [ pkgs.hostapd ];
|
||||
|
||||
# start manual
|
||||
# wantedBy = [ "network.target" ];
|
||||
|
||||
after = [
|
||||
"${wifi}-cfg.service"
|
||||
"nat.service"
|
||||
"bind.service"
|
||||
"dhcpd.service"
|
||||
"sys-subsystem-net-devices-${wifi}.device"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.hostapd}/bin/hostapd ${
|
||||
pkgs.writeText "hostapd.conf" ''
|
||||
interface=${wifi}
|
||||
hw_mode=g
|
||||
channel=10
|
||||
ieee80211d=1
|
||||
country_code=DE
|
||||
ieee80211n=1
|
||||
wmm_enabled=1
|
||||
|
||||
ssid=${ssid}
|
||||
auth_algs=1
|
||||
wpa=2
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
rsn_pairwise=CCMP
|
||||
wpa_passphrase=${wifiPassword}
|
||||
''
|
||||
}";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
# Only listen to routers' LAN NIC. Doing so opens up tcp/udp port 53 to
|
||||
# localhost and udp port 67 to world:
|
||||
interface=${wifi}
|
||||
|
||||
# Explicitly specify the address to listen on
|
||||
listen-address=${ipAddress}
|
||||
|
||||
# Dynamic range of IPs to make available to LAN PC and the lease time.
|
||||
# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records.
|
||||
dhcp-range=${servedAddressRange}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
45
nixos/configs/sternchen/wireshark.nix
Normal file
45
nixos/configs/sternchen/wireshark.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{ pkgs, config, ... }: {
|
||||
|
||||
users.users.mainUser.extraGroups = [ "wireshark" ];
|
||||
programs.wireshark.enable = true;
|
||||
|
||||
environment.systemPackages = [
|
||||
|
||||
pkgs.wireshark
|
||||
|
||||
# alternative packet analyzer (only works with elasticsearch)
|
||||
pkgs.packetbeat7
|
||||
];
|
||||
|
||||
# elastic search is good for analysing stuff
|
||||
# https://www.elastic.co/blog/analyzing-network-packets-with-wireshark-elasticsearch-and-kibana
|
||||
services.elasticsearch.enable = true;
|
||||
services.elasticsearch.listenAddress =
|
||||
"${config.networking.hostName}.private";
|
||||
services.kibana.enable = true;
|
||||
services.kibana.elasticsearch.hosts =
|
||||
[ "http://${config.networking.hostName}.private:9200" ];
|
||||
services.kibana.listenAddress = "${config.networking.hostName}.private";
|
||||
services.kibana.port = 5601;
|
||||
|
||||
# using tshark with elastic search
|
||||
# --------------------------------
|
||||
# tshark -r file.pcap -T ek > packages.json
|
||||
# curl -XPOST "sterni.private:9200/packets/doc/_bulk" -H 'Content-Type: application/json' --data-binary "@packets.json"
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"kibana.${config.networking.hostName}.private" = {
|
||||
serverAliases = [ ];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.kibana.port
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
86
nixos/configs/sterni/configuration.nix
Normal file
86
nixos/configs/sterni/configuration.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
imports = [
|
||||
|
||||
../../system/desktop
|
||||
|
||||
./hardware-configuration.nix
|
||||
./packages.nix
|
||||
./syncthing.nix
|
||||
./tinc.nix
|
||||
|
||||
#./wifi-access-point.nix
|
||||
#./wireshark.nix
|
||||
|
||||
];
|
||||
|
||||
sops.defaultSopsFile = ../../secrets/sterni.yaml;
|
||||
networking.hostName = "sterni";
|
||||
|
||||
system.custom.wifi.interfaces = [ "wlp3s0" ];
|
||||
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount}/bin/pumount";
|
||||
};
|
||||
|
||||
# keybase
|
||||
services.keybase.enable = false;
|
||||
services.kbfs.enable = false;
|
||||
|
||||
programs.custom.steam.enable = true;
|
||||
programs.custom.video.enable = false;
|
||||
|
||||
services.printing.enable = true;
|
||||
|
||||
# fonts
|
||||
# -----
|
||||
programs.custom.urxvt.fontSize = 12;
|
||||
programs.custom.xterm.fontSize = 12;
|
||||
system.custom.fonts.dpi = 100;
|
||||
|
||||
virtualisation = {
|
||||
docker.enable = false;
|
||||
|
||||
virtualbox = {
|
||||
host.enable = false;
|
||||
guest.x11 = false;
|
||||
guest.enable = false;
|
||||
};
|
||||
};
|
||||
|
||||
configuration.desktop = {
|
||||
width = 1366;
|
||||
height = 768;
|
||||
};
|
||||
|
||||
services.xserver.desktopManager.gnome.enable = true;
|
||||
|
||||
custom.samba-share = {
|
||||
enable = false;
|
||||
folders = {
|
||||
#public = "/home/palo/movies";
|
||||
share = "/home/share";
|
||||
#syncthing = "/mnt/syncthing";
|
||||
#movies = "/mnt/syncthing/movies";
|
||||
#series = "/mnt/syncthing/series";
|
||||
};
|
||||
};
|
||||
|
||||
# enable this to use sidequest
|
||||
programs.adb.enable = true;
|
||||
users.users.mainUser.extraGroups = [ "adbusers" "video" ];
|
||||
|
||||
# for congress and streaming
|
||||
hardware.opengl = {
|
||||
enable = true;
|
||||
extraPackages = [ pkgs.vaapiIntel ];
|
||||
driSupport = true;
|
||||
driSupport32Bit = true;
|
||||
};
|
||||
nixpkgs.config.packageOverrides = pkgs: {
|
||||
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
87
nixos/configs/sterni/hardware-configuration.nix
Normal file
87
nixos/configs/sterni/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
|
||||
imports = [ "${modulesPath}/installer/scan/not-detected.nix" ];
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ehci_pci" "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# Use the systemd-boot EFI boot loader, not grub
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
zramSwap = {
|
||||
enable = true;
|
||||
numDevices = 2;
|
||||
swapDevices = 1;
|
||||
memoryPercent = 50;
|
||||
};
|
||||
|
||||
fileSystems."/share" = {
|
||||
#device = "/dev/ram1";
|
||||
device = "none";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
|
||||
fileSystems."/browsers" = {
|
||||
#device = "/dev/ram2";
|
||||
#fsType = "tmpfs";
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/browser";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
nix.maxJobs = lib.mkDefault 4;
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = {
|
||||
vg = {
|
||||
device = "/dev/sda2";
|
||||
preLVM = true;
|
||||
};
|
||||
};
|
||||
|
||||
# NTFS support
|
||||
# ------------
|
||||
environment.systemPackages = [ pkgs.ntfs3g ];
|
||||
|
||||
# root
|
||||
# ----
|
||||
fileSystems."/" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/root";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# home
|
||||
# ----
|
||||
fileSystems."/home" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/home";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# /home/palo/private/.fotos.ct
|
||||
# --------------------
|
||||
#fileSystems."/home/palo/private/.fotos.ct" = {
|
||||
# options = [ "noatime" "nodiratime" "discard" ];
|
||||
# device = "/dev/vg/fotos";
|
||||
# fsType = "ext4";
|
||||
#};
|
||||
|
||||
# boot
|
||||
# ----
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
}
|
||||
74
nixos/configs/sterni/packages.nix
Normal file
74
nixos/configs/sterni/packages.nix
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
nextcloudSync = folder:
|
||||
pkgs.writers.writeBashBin "nextcloud-sync-${folder}" ''
|
||||
${pkgs.nextcloud-client}/bin/nextcloudcmd \
|
||||
--user palo \
|
||||
--password `pass show home/nextcloud/palo/nextcloudcmd-token` \
|
||||
~/Nextcloud/${folder} \
|
||||
https://nextcloud.ingolf-wagner.de/remote.php/webdav/${folder}
|
||||
'';
|
||||
|
||||
in {
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
|
||||
(nextcloudSync "InstantUpload")
|
||||
(nextcloudSync "Pictures")
|
||||
(nextcloudSync "Unterlagen")
|
||||
(nextcloudSync "Video")
|
||||
|
||||
(pkgs.writeShellScriptBin "nixFlakes" ''
|
||||
exec ${pkgs.nixUnstable}/bin/nix --experimental-features "nix-command flakes" "$@"
|
||||
'')
|
||||
|
||||
#zeal # offline documentation
|
||||
#keepassxc
|
||||
sweethome3d.application
|
||||
polygon-art
|
||||
|
||||
# bluetooth gui
|
||||
blueberry
|
||||
|
||||
nextcloud-client
|
||||
gimp
|
||||
inkscape
|
||||
imagemagick
|
||||
|
||||
bitwig-studio3
|
||||
sonic-pi
|
||||
jack2
|
||||
sononym-crawler
|
||||
darktable
|
||||
|
||||
# rust development environment
|
||||
#cargo
|
||||
#rustc
|
||||
rustup
|
||||
jetbrains.clion
|
||||
|
||||
# general
|
||||
jetbrains.idea-ultimate
|
||||
vscode
|
||||
|
||||
# python
|
||||
python3Full
|
||||
jetbrains.pycharm-professional
|
||||
jetbrains.datagrip
|
||||
|
||||
element-desktop
|
||||
|
||||
tor-browser-bundle-bin
|
||||
#(tor-browser-bundle-bin.overrideAttrs (old: rec {
|
||||
# version = "10.0.15";
|
||||
# name = "tor-browser-bundle-${version}";
|
||||
# src = pkgs.fetchurl {
|
||||
# url =
|
||||
# "https://dist.torproject.org/torbrowser/10.0.15/tor-browser-linux64-10.0.15_en-US.tar.xz";
|
||||
# sha256 = "1ah69jmfgik063f9gkvyv9d4k706pqihmzc4k7cc95zyd17v8wrs";
|
||||
# };
|
||||
#}))
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
80
nixos/configs/sterni/syncthing.nix
Normal file
80
nixos/configs/sterni/syncthing.nix
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
{ config, pkgs, lib, ... }: {
|
||||
|
||||
sops.secrets.syncthing_cert = { };
|
||||
sops.secrets.syncthing_key = { };
|
||||
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = false;
|
||||
user = "palo";
|
||||
dataDir = "/home/palo/.syncthing";
|
||||
configDir = "/home/palo/.syncthing";
|
||||
declarative = {
|
||||
cert = toString config.sops.secrets.syncthing_cert.path;
|
||||
key = toString config.sops.secrets.syncthing_key.path;
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
|
||||
# on encrypted drive
|
||||
# ------------------
|
||||
private = {
|
||||
enable = true;
|
||||
path = "/home/palo/private";
|
||||
};
|
||||
desktop = {
|
||||
enable = true;
|
||||
path = "/home/palo/desktop";
|
||||
};
|
||||
finance = {
|
||||
enable = true;
|
||||
path = "/home/palo/finance";
|
||||
};
|
||||
fotos = {
|
||||
enable = true;
|
||||
path = "/home/palo/fotos";
|
||||
};
|
||||
samples = {
|
||||
enable = true;
|
||||
path = "/home/palo/samples";
|
||||
};
|
||||
zettlr = {
|
||||
enable = true;
|
||||
path = "/home/palo/zettlr";
|
||||
};
|
||||
programs = {
|
||||
enable = true;
|
||||
path = "/home/palo/programs";
|
||||
};
|
||||
|
||||
# no need to be encrypted
|
||||
# -----------------------
|
||||
books = {
|
||||
enable = true;
|
||||
path = "/home/palo/books";
|
||||
};
|
||||
music-library = {
|
||||
enable = true;
|
||||
path = "/home/palo/music-library";
|
||||
};
|
||||
music-projects = {
|
||||
enable = true;
|
||||
path = "/home/palo/music-projects";
|
||||
};
|
||||
smartphone-folder = {
|
||||
enable = true;
|
||||
path = "/home/palo/smartphone-folder";
|
||||
};
|
||||
processing = {
|
||||
enable = true;
|
||||
path = "/home/palo/sketchbook";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
system.permown."/home/palo/music-library" = {
|
||||
owner = "palo";
|
||||
group = "users";
|
||||
};
|
||||
}
|
||||
24
nixos/configs/sterni/tinc.nix
Normal file
24
nixos/configs/sterni/tinc.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
"retiolum" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
"secret" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
84
nixos/configs/sterni/wifi-access-point.nix
Normal file
84
nixos/configs/sterni/wifi-access-point.nix
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
wifi = "wlp0s29u1u2";
|
||||
ipAddress = "10.123.145.1";
|
||||
prefixLength = 24;
|
||||
servedAddressRange = "10.123.145.2,10.123.145.150,12h";
|
||||
ssid = "bumbumbum";
|
||||
wifiPassword = lib.fileContents <secrets/wifi-access-point>;
|
||||
|
||||
in {
|
||||
# todo only open needed ports
|
||||
networking.firewall.trustedInterfaces = [ wifi ];
|
||||
|
||||
networking.networkmanager.unmanaged = [ wifi ];
|
||||
networking.dhcpcd.denyInterfaces = [ wifi ];
|
||||
|
||||
networking.interfaces."${wifi}".ipv4.addresses = [{
|
||||
address = ipAddress;
|
||||
prefixLength = prefixLength;
|
||||
}];
|
||||
|
||||
# forward traffic coming in trough the access point => provide internet and vpn network access
|
||||
# todo : forward to own servers
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.conf.${wifi}.forwarding" = true;
|
||||
"net.ipv6.conf.${wifi}.forwarding" = true;
|
||||
};
|
||||
|
||||
systemd.services.hostapd = {
|
||||
description = "hostapd wireless AP";
|
||||
path = [ pkgs.hostapd ];
|
||||
|
||||
# start manual
|
||||
# wantedBy = [ "network.target" ];
|
||||
|
||||
after = [
|
||||
"${wifi}-cfg.service"
|
||||
"nat.service"
|
||||
"bind.service"
|
||||
"dhcpd.service"
|
||||
"sys-subsystem-net-devices-${wifi}.device"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.hostapd}/bin/hostapd ${
|
||||
pkgs.writeText "hostapd.conf" ''
|
||||
interface=${wifi}
|
||||
hw_mode=g
|
||||
channel=10
|
||||
ieee80211d=1
|
||||
country_code=DE
|
||||
ieee80211n=1
|
||||
wmm_enabled=1
|
||||
|
||||
ssid=${ssid}
|
||||
auth_algs=1
|
||||
wpa=2
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
rsn_pairwise=CCMP
|
||||
wpa_passphrase=${wifiPassword}
|
||||
''
|
||||
}";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
# Only listen to routers' LAN NIC. Doing so opens up tcp/udp port 53 to
|
||||
# localhost and udp port 67 to world:
|
||||
interface=${wifi}
|
||||
|
||||
# Explicitly specify the address to listen on
|
||||
listen-address=${ipAddress}
|
||||
|
||||
# Dynamic range of IPs to make available to LAN PC and the lease time.
|
||||
# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records.
|
||||
dhcp-range=${servedAddressRange}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
45
nixos/configs/sterni/wireshark.nix
Normal file
45
nixos/configs/sterni/wireshark.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{ pkgs, config, ... }: {
|
||||
|
||||
users.users.mainUser.extraGroups = [ "wireshark" ];
|
||||
programs.wireshark.enable = true;
|
||||
|
||||
environment.systemPackages = [
|
||||
|
||||
pkgs.wireshark
|
||||
|
||||
# alternative packet analyzer (only works with elasticsearch)
|
||||
pkgs.packetbeat7
|
||||
];
|
||||
|
||||
# elastic search is good for analysing stuff
|
||||
# https://www.elastic.co/blog/analyzing-network-packets-with-wireshark-elasticsearch-and-kibana
|
||||
services.elasticsearch.enable = true;
|
||||
services.elasticsearch.listenAddress =
|
||||
"${config.networking.hostName}.private";
|
||||
services.kibana.enable = true;
|
||||
services.kibana.elasticsearch.hosts =
|
||||
[ "http://${config.networking.hostName}.private:9200" ];
|
||||
services.kibana.listenAddress = "${config.networking.hostName}.private";
|
||||
services.kibana.port = 5601;
|
||||
|
||||
# using tshark with elastic search
|
||||
# --------------------------------
|
||||
# tshark -r file.pcap -T ek > packages.json
|
||||
# curl -XPOST "sterni.private:9200/packets/doc/_bulk" -H 'Content-Type: application/json' --data-binary "@packets.json"
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"kibana.${config.networking.hostName}.private" = {
|
||||
serverAliases = [ ];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.kibana.port
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
30
nixos/configs/workhorse/borg.nix
Normal file
30
nixos/configs/workhorse/borg.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{ lib, config, pkgs, ... }: {
|
||||
|
||||
services.borgbackup.repos = {
|
||||
default = {
|
||||
quota = "100G";
|
||||
allowSubRepos = true;
|
||||
authorizedKeys = [
|
||||
(lib.fileContents ../../assets/ssh/borg_access.pub)
|
||||
(lib.fileContents ../../assets/ssh/card_rsa.pub)
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# mirror backup folder to /media
|
||||
systemd.services.borg-mirror-to-media = {
|
||||
enable = true;
|
||||
script = ''
|
||||
${pkgs.rsync}/bin/rsync -a \
|
||||
/var/lib/borgbackup/ \
|
||||
/media/borg-backup-mirror \
|
||||
--delete-after
|
||||
'';
|
||||
};
|
||||
systemd.timers.borg-mirror-to-media = {
|
||||
enable = true;
|
||||
timerConfig.OnCalendar = "daily";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
}
|
||||
21
nixos/configs/workhorse/castget.nix
Normal file
21
nixos/configs/workhorse/castget.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
|
||||
home = "/home/syncthing/podcasts";
|
||||
|
||||
in {
|
||||
custom.services.castget = {
|
||||
enable = true;
|
||||
user = "root";
|
||||
feeds = {
|
||||
Alternativlos = {
|
||||
url = "https://alternativlos.org/alternativlos.rss";
|
||||
spool = "${home}/alternativlos";
|
||||
};
|
||||
gegenstandpunkt = {
|
||||
url = "https://pc.argudiss.de/";
|
||||
spool = "${home}/GegenStandpunkt";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
75
nixos/configs/workhorse/configuration.nix
Normal file
75
nixos/configs/workhorse/configuration.nix
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
{ lib, config, pkgs, ... }: {
|
||||
imports = [
|
||||
|
||||
<system/server>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./gogs.nix
|
||||
./grafana.nix
|
||||
./graylog.nix
|
||||
./jenkins.nix
|
||||
./kibana.nix
|
||||
./mail-fetcher.nix
|
||||
./packages.nix
|
||||
./prometheus.nix
|
||||
./syncthing.nix
|
||||
./taskserver.nix
|
||||
./tinc.nix
|
||||
./transmission.nix
|
||||
./weechat.nix
|
||||
./nextcloud.nix
|
||||
./borg.nix
|
||||
#./metabase.nix
|
||||
#./jupyter.nix
|
||||
./mysql.nix
|
||||
#./property.nix flask sucks, find something else
|
||||
./finance.nix
|
||||
#./mining.nix
|
||||
];
|
||||
|
||||
nixpkgs.config.permittedInsecurePackages =
|
||||
[ "gogs-0.11.91" "nextcloud-19.0.6" ];
|
||||
|
||||
# todo: add this to each file instead summing that here
|
||||
on-failure.plans = {
|
||||
gogs.name = "gogs";
|
||||
jenkins.name = "jenkins";
|
||||
graylog.name = "graylog";
|
||||
prometheus.name = "prometheus";
|
||||
taskserver.name = "taskserver";
|
||||
weechat.name = "weechat";
|
||||
transmission.name = "transmission";
|
||||
mail-fetcher.name = "fetchmail";
|
||||
};
|
||||
|
||||
networking.hostName = "workhorse";
|
||||
|
||||
# font
|
||||
# ----
|
||||
programs.custom.urxvt.fontSize = 17;
|
||||
programs.custom.xterm.fontSize = 17;
|
||||
system.custom.fonts.dpi = 140;
|
||||
|
||||
# enable initrd ssh
|
||||
configuration.init-ssh = {
|
||||
enable = "enabled";
|
||||
kernelModules = [ "r8169" ];
|
||||
hostKey = "/etc/ssh/ssh_host_ed25519_key";
|
||||
};
|
||||
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
configuration.fireqos = {
|
||||
enable = true;
|
||||
interface = "enp2s0f1";
|
||||
input = 45000;
|
||||
output = 8000;
|
||||
balance = false;
|
||||
};
|
||||
|
||||
virtualisation = { docker.enable = false; };
|
||||
|
||||
services.printing.enable = false;
|
||||
services.smartd.enable = true;
|
||||
|
||||
}
|
||||
|
||||
55
nixos/configs/workhorse/finance.nix
Normal file
55
nixos/configs/workhorse/finance.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{ lib, config, pkgs, ... }:
|
||||
let
|
||||
|
||||
# find symbols with
|
||||
# https://www.alphavantage.co/query?function=SYMBOL_SEARCH&apikey=<api_key>&keywords=<keywords>
|
||||
# as described here : https://www.alphavantage.co/documentation/#symbolsearch
|
||||
#
|
||||
# example:
|
||||
# --------
|
||||
# stocks = [
|
||||
# {
|
||||
# friendly_name = "google";
|
||||
# symbol = "GOOGL.DEX";
|
||||
# name = "google";
|
||||
# currency = "$";
|
||||
# }
|
||||
# ];
|
||||
# results in
|
||||
# P 2020-01-30 GOOGL $123
|
||||
stocks = import <secrets/finance/stocks>;
|
||||
stocksFile = toString /home/syncthing/finance/hledger/stocks.journal;
|
||||
|
||||
in {
|
||||
|
||||
systemd.services.pull_stocks = {
|
||||
enable = true;
|
||||
description = "pull stocks for hledger";
|
||||
serviceConfig = {
|
||||
User = "syncthing";
|
||||
Type = "oneshot";
|
||||
};
|
||||
|
||||
script = let
|
||||
command = { symbol, name, currency, ... }: ''
|
||||
APIKEY=${lib.fileContents <secrets/finance/alphavantage/apikey>}
|
||||
SYMBOL="${symbol}"
|
||||
${pkgs.curl}/bin/curl --location --silent \
|
||||
"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \
|
||||
| ${pkgs.jq}/bin/jq --raw-output '.["Global Quote"]
|
||||
| "P \(.["07. latest trading day"]) ${name} ${currency}\(.["05. price"] | tonumber)"' \
|
||||
>> ${stocksFile}
|
||||
sleep 1
|
||||
'';
|
||||
in lib.concatStringsSep "\n" (map command stocks);
|
||||
};
|
||||
|
||||
systemd.timers.pull_stocks = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "weekly";
|
||||
Persistent = "true";
|
||||
};
|
||||
};
|
||||
}
|
||||
121
nixos/configs/workhorse/gogs.nix
Normal file
121
nixos/configs/workhorse/gogs.nix
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
|
||||
errorPages = pkgs.fetchgit {
|
||||
url = "https://git.ingolf-wagner.de/palo/http-errors.git";
|
||||
rev = "74b8e4c1d9bbba3db6ad858b888e1867318af1f0";
|
||||
sha256 = "0czdzafx4k76q773lyf3vsjm74g1995iz542dhw15kpy5xbivsrg";
|
||||
};
|
||||
|
||||
error = {
|
||||
extraConfig = ''
|
||||
error_page 400 /errors/400.html;
|
||||
error_page 401 /errors/401.html;
|
||||
error_page 402 /errors/402.html;
|
||||
error_page 403 /errors/403.html;
|
||||
error_page 404 /errors/404.html;
|
||||
error_page 405 /errors/405.html;
|
||||
error_page 406 /errors/406.html;
|
||||
error_page 500 /errors/500.html;
|
||||
error_page 501 /errors/501.html;
|
||||
error_page 502 /errors/502.html;
|
||||
error_page 503 /errors/503.html;
|
||||
error_page 504 /errors/504.html;
|
||||
'';
|
||||
locations."^~ /errors/" = {
|
||||
extraConfig = "internal;";
|
||||
root = "${errorPages}/";
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"git.${config.networking.hostName}.private" = {
|
||||
extraConfig = error.extraConfig;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.gogs.httpPort
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.gogs = {
|
||||
enable = true;
|
||||
appName = "Kruck GoGs";
|
||||
domain = "git.ingolf-wagner.de";
|
||||
httpPort = 3000;
|
||||
repositoryRoot = "/home/gogs/repositories";
|
||||
stateDir = "/home/gogs";
|
||||
rootUrl = "https://git.ingolf-wagner.de/";
|
||||
extraConfig = ''
|
||||
[service]
|
||||
DISABLE_REGISTRATION = true
|
||||
SHOW_REGISTRATION_BUTTON = false
|
||||
[server]
|
||||
SSH_DOMAIN = "git.ingolf-wagner.de"
|
||||
SSH_PORT = 443
|
||||
START_SSH_SERVER = true
|
||||
SSH_LISTEN_PORT = 2222
|
||||
|
||||
[log.file]
|
||||
LEVEL = Warn
|
||||
|
||||
[log.console]
|
||||
LEVEL = Warn
|
||||
|
||||
[log.sublogger.macaron]
|
||||
LEVEL = Warn
|
||||
'';
|
||||
};
|
||||
backup.dirs = [ config.services.gogs.repositoryRoot ];
|
||||
|
||||
# services.nginx = {
|
||||
# enable = true;
|
||||
# statusPage = true;
|
||||
# virtualHosts = {
|
||||
# "gitlab.${config.networking.hostName}.private" = {
|
||||
# extraConfig = error.extraConfig;
|
||||
# locations."/" = {
|
||||
# proxyPass = "http://${config.networking.hostName}.private:${
|
||||
# toString config.services.gitlab.port
|
||||
# }";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# services.gitlab = {
|
||||
# enable = true;
|
||||
# host = "gitlab.${config.networking.hostname}.private";
|
||||
# port = 9897;
|
||||
# #databasePasswordFile = "path/todo";
|
||||
# #initialRootPasswordFile = "path/todo";
|
||||
#
|
||||
# secrets = {
|
||||
# # Make sure the secret is at least 30 characters and all random,
|
||||
# # no regular words or you'll be exposed to dictionary attacks
|
||||
# dbFile = "path/todo";
|
||||
#
|
||||
# # openssl genrsa 2048
|
||||
# jwsFile = "path/todo";
|
||||
#
|
||||
# # Make sure the secret is at least 30 characters and all random,
|
||||
# # no regular words or you'll be exposed to dictionary attacks
|
||||
# otpFile = "path/todo";
|
||||
#
|
||||
# # Make sure the secret is at least 30 characters and all random,
|
||||
# # no regular words or you'll be exposed to dictionary attacks
|
||||
# secretFile = "path/todo";
|
||||
# };
|
||||
#
|
||||
# # smtp?
|
||||
#
|
||||
# # gitlab-runner?
|
||||
# };
|
||||
|
||||
}
|
||||
38
nixos/configs/workhorse/grafana.nix
Normal file
38
nixos/configs/workhorse/grafana.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{ config, ... }: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"grafana.${config.networking.hostName}.private" = {
|
||||
serverAliases = [ ];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.grafana.port
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
port = 5656;
|
||||
addr =
|
||||
config.module.cluster.services.tinc."private".hosts."${config.networking.hostName}".tincIp;
|
||||
auth.anonymous = {
|
||||
enable = true;
|
||||
org_role = "Editor";
|
||||
org_name = "AWESOME";
|
||||
};
|
||||
provision = {
|
||||
enable = true;
|
||||
datasources = [{
|
||||
type = "prometheus";
|
||||
isDefault = true;
|
||||
name = "Prometheus Workhorse";
|
||||
url = "http://workhorse.private:9090";
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
130
nixos/configs/workhorse/graylog.nix
Normal file
130
nixos/configs/workhorse/graylog.nix
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let port = 9000;
|
||||
in {
|
||||
# configure nginx
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"graylog.workhorse.private" = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString port}";
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host:$server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90;
|
||||
proxy_redirect http://localhost:${
|
||||
toString port
|
||||
} https://graylog.workhorse.private/;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.mongodb.enable = true;
|
||||
services.elasticsearch = {
|
||||
enable = true;
|
||||
listenAddress = "${config.networking.hostName}.private";
|
||||
extraJavaOptions = [ "-Des.http.cname_in_publish_address=true" ];
|
||||
};
|
||||
|
||||
services.graylog.enable = true;
|
||||
services.graylog.elasticsearchHosts =
|
||||
[ "http://${config.services.elasticsearch.listenAddress}:9200" ];
|
||||
|
||||
# https://docs.graylog.org/en/3.0/pages/configuration/server.conf.html
|
||||
services.graylog.extraConfig = ''
|
||||
http_bind_address = 0.0.0.0:${toString port}
|
||||
http_publish_uri = http://workhorse.private:${toString port}/
|
||||
'';
|
||||
|
||||
# other wise this does not work
|
||||
services.graylog.nodeIdFile = "/var/lib/graylog/node-id";
|
||||
|
||||
# pwgen -N 1 -s 96
|
||||
services.graylog.passwordSecret =
|
||||
lib.fileContents <secrets/graylog/password-secret>;
|
||||
|
||||
# echo -n yourpassword | shasum -a 256
|
||||
services.graylog.rootPasswordSha2 =
|
||||
lib.fileContents <secrets/graylog/root-password-hash>;
|
||||
|
||||
services.graylog.plugins = [ pkgs.graylogPlugins.slack ];
|
||||
|
||||
# not working at the moment
|
||||
#services.geoip-updater.enable = true;
|
||||
|
||||
# https://wiki.splunk.com/Http_status.csv
|
||||
environment.etc."graylog/server/httpCodes.csv" = {
|
||||
enable = true;
|
||||
text = ''
|
||||
status,status_description,status_type
|
||||
100,Continue,Informational
|
||||
101,Switching Protocols,Informational
|
||||
200,OK,Successful
|
||||
201,Created,Successful
|
||||
202,Accepted,Successful
|
||||
203,Non-Authoritative Information,Successful
|
||||
204,No Content,Successful
|
||||
205,Reset Content,Successful
|
||||
206,Partial Content,Successful
|
||||
300,Multiple Choices,Redirection
|
||||
301,Moved Permanently,Redirection
|
||||
302,Found,Redirection
|
||||
303,See Other,Redirection
|
||||
304,Not Modified,Redirection
|
||||
305,Use Proxy,Redirection
|
||||
307,Temporary Redirect,Redirection
|
||||
400,Bad Request,Client Error
|
||||
401,Unauthorized,Client Error
|
||||
402,Payment Required,Client Error
|
||||
403,Forbidden,Client Error
|
||||
404,Not Found,Client Error
|
||||
405,Method Not Allowed,Client Error
|
||||
406,Not Acceptable,Client Error
|
||||
407,Proxy Authentication Required,Client Error
|
||||
408,Request Timeout,Client Error
|
||||
409,Conflict,Client Error
|
||||
410,Gone,Client Error
|
||||
411,Length Required,Client Error
|
||||
412,Precondition Failed,Client Error
|
||||
413,Request Entity Too Large,Client Error
|
||||
414,Request-URI Too Long,Client Error
|
||||
415,Unsupported Media Type,Client Error
|
||||
416,Requested Range Not Satisfiable,Client Error
|
||||
417,Expectation Failed,Client Error
|
||||
500,Internal Server Error,Server Error
|
||||
501,Not Implemented,Server Error
|
||||
502,Bad Gateway,Server Error
|
||||
503,Service Unavailable,Server Error
|
||||
504,Gateway Timeout,Server Error
|
||||
505,HTTP Version Not Supported,Server Error
|
||||
'';
|
||||
};
|
||||
|
||||
environment.etc."graylog/server/known_servers.csv" = {
|
||||
enable = true;
|
||||
text = ''
|
||||
"ip","host_name"
|
||||
"95.216.1.150","lassul.us"
|
||||
'';
|
||||
};
|
||||
|
||||
environment.etc."graylog/systemd/loglevel.csv" = {
|
||||
enable = true;
|
||||
text = ''
|
||||
"value","Servity","Description"
|
||||
"0","emergency","System is unusable"
|
||||
"1","alert","Should be corrected immediately"
|
||||
"2","cirtical","Critical conditions"
|
||||
"3","error","Error Condition"
|
||||
"4","warning","May indicate that an error will occur if action is not taken."
|
||||
"5","notice","Events that are unusual, but not error conditions."
|
||||
"6","info","Normal operational messages that require no action."
|
||||
"7","debug","Information useful to developers for debugging the application."
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
117
nixos/configs/workhorse/hardware-configuration.nix
Normal file
117
nixos/configs/workhorse/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let mainUserHome = "/home/palo";
|
||||
in {
|
||||
|
||||
# grub configuration
|
||||
# ------------------
|
||||
boot.loader.grub = {
|
||||
device = "/dev/sda";
|
||||
enable = true;
|
||||
version = 2;
|
||||
};
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = {
|
||||
vg = {
|
||||
device = "/dev/sda2";
|
||||
preLVM = true;
|
||||
};
|
||||
};
|
||||
|
||||
# NTFS support
|
||||
# ------------
|
||||
environment.systemPackages = [ pkgs.ntfs3g ];
|
||||
|
||||
# root
|
||||
# ----
|
||||
fileSystems."/" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/root";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# boot
|
||||
# ----
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# home
|
||||
# ----
|
||||
fileSystems."/home" = {
|
||||
options = [ "noatime" "nodiratime" ];
|
||||
device = "/dev/mapper/decrypted_home";
|
||||
fsType = "ext4";
|
||||
encrypted = {
|
||||
enable = true;
|
||||
keyFile = "/mnt-root/root/keys/home.key";
|
||||
label = "decrypted_home";
|
||||
blkDev = "/dev/mapper/store-home";
|
||||
};
|
||||
};
|
||||
|
||||
# var/lib/docker
|
||||
# --------------
|
||||
fileSystems."/var/lib/borgbackup" = {
|
||||
options = [ "noatime" "nodiratime" ];
|
||||
device = "/dev/mapper/decrypted_docker";
|
||||
fsType = "ext4";
|
||||
encrypted = {
|
||||
enable = true;
|
||||
keyFile = "/mnt-root/root/keys/docker.key";
|
||||
label = "decrypted_docker";
|
||||
blkDev = "/dev/mapper/store-docker";
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
# automount
|
||||
# ---------
|
||||
(let mediaUUID = "b8ba192e-e2aa-47dd-85ec-dcf97ec9310a";
|
||||
in {
|
||||
fileSystems."/media" = {
|
||||
device = "/dev/disk/by-uuid/${mediaUUID}";
|
||||
fsType = "ext4";
|
||||
options = [
|
||||
"nofail"
|
||||
"noauto"
|
||||
#"x-systemd.device-timeout=1ms"
|
||||
];
|
||||
};
|
||||
systemd.mounts = [{
|
||||
enable = true;
|
||||
options = "nofail,noauto";
|
||||
type = "ext4";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
what = "/dev/disk/by-uuid/${mediaUUID}";
|
||||
where = "/media";
|
||||
}];
|
||||
})
|
||||
|
||||
(let backupUUID = "f7fa1c0e-ac9f-4955-b4bd-644c1ddb0d89";
|
||||
in {
|
||||
fileSystems."/backup" = {
|
||||
device = "/dev/disk/by-uuid/${backupUUID}";
|
||||
fsType = "ext4";
|
||||
options = [
|
||||
"nofail"
|
||||
"noauto"
|
||||
#"x-systemd.device-timeout=1ms"
|
||||
];
|
||||
};
|
||||
systemd.mounts = [{
|
||||
enable = true;
|
||||
options = "nofail,noauto";
|
||||
type = "ext4";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
what = "/dev/disk/by-uuid/${backupUUID}";
|
||||
where = "/backup";
|
||||
}];
|
||||
})
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
199
nixos/configs/workhorse/jenkins.nix
Normal file
199
nixos/configs/workhorse/jenkins.nix
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
library = import ../../library { inherit pkgs lib; };
|
||||
|
||||
sync-repo = library.jenkins.syncJob;
|
||||
job = library.jenkins.job;
|
||||
|
||||
in {
|
||||
|
||||
environment.systemPackages = [ pkgs.cabal-install ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"jenkins.${config.networking.hostName}.private" = {
|
||||
locations."/" = {
|
||||
proxyPass =
|
||||
"http://localhost:${toString config.services.jenkins.port}";
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host:$server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_read_timeout 90;
|
||||
proxy_redirect http://localhost:${
|
||||
toString config.services.jenkins.port
|
||||
} https://jenkins.${config.networking.hostName}.private/;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
krops.userKeys."accessToken" = {
|
||||
user = "jenkins";
|
||||
source = toString <secrets/jenkins/accessToken>;
|
||||
requiredBy = [ "jenkins-job-builder.service" ];
|
||||
};
|
||||
|
||||
services.jenkins = {
|
||||
enable = true;
|
||||
home = "/home/jenkins";
|
||||
port = 10420;
|
||||
|
||||
# Plugins to Install:
|
||||
# - all the plugins recommended at the setup
|
||||
# - Build pipeline
|
||||
# - SSH Agent
|
||||
# - mattermost plugin
|
||||
jobBuilder = {
|
||||
enable = true;
|
||||
|
||||
# create an access token in the admin users panel
|
||||
accessTokenFile = config.krops.userKeys."accessToken".target;
|
||||
accessUser = "admin";
|
||||
|
||||
# https://docs.openstack.org/infra/jenkins-job-builder/definition.html#modules
|
||||
nixJobs = let
|
||||
# ssh username + key
|
||||
gogs-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2";
|
||||
# ssh username + key
|
||||
github-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2";
|
||||
# ssh username + key
|
||||
sshSputnik = "d91eb57c-5bff-434c-b317-68aad46848d7";
|
||||
|
||||
sync-to-github = name: source: target:
|
||||
sync-repo name {
|
||||
url = source;
|
||||
credentialsId = gogs-id;
|
||||
} {
|
||||
url = target;
|
||||
credentialsId = github-id;
|
||||
};
|
||||
|
||||
in [
|
||||
|
||||
(job "sync-retiolum" {
|
||||
url = "git@github.com:krebs/retiolum.git";
|
||||
credentialsId = github-id;
|
||||
triggers = [{ timed = "H/30 * * * *"; }];
|
||||
} [
|
||||
{
|
||||
"Download Files" = [
|
||||
"chmod 755 hosts"
|
||||
"chmod 755 -R hosts"
|
||||
''
|
||||
nix-shell -p curl -p gnutar -p bzip2 --run "curl https://lassul.us/retiolum-hosts.tar.bz2 | tar xvjf - || true"''
|
||||
"chmod 755 -R etc.hosts"
|
||||
''
|
||||
nix-shell -p curl --run "curl https://lassul.us/retiolum.hosts > etc.hosts || true"''
|
||||
];
|
||||
}
|
||||
{
|
||||
"update repo" = [
|
||||
''nix-shell -p git --run "git add ."''
|
||||
''
|
||||
nix-shell -p git --run "git -c user.name=\'Ingolf Wagner\' -c user.email=\'contact@ingolf-wagner.de\' commit -m update-`date +%Y-%m-%dT%H:%M:%S` || exit 0"''
|
||||
];
|
||||
}
|
||||
{
|
||||
Push = [{
|
||||
script = ''nix-shell -p git --run "git push origin master"'';
|
||||
credentialsId = github-id;
|
||||
}];
|
||||
}
|
||||
])
|
||||
|
||||
(job "test-taskninja" {
|
||||
url = "ssh://gogs@workhorse.private:2222/palo/taskninja.git";
|
||||
credentialsId = gogs-id;
|
||||
} [
|
||||
{
|
||||
"Create Shell" = [
|
||||
''
|
||||
nix-shell -p cabal2nix --run "cabal2nix --shell file://. > jenkins.nix"''
|
||||
];
|
||||
}
|
||||
{ Update = [ ''nix-shell ./jenkins.nix --run "cabal update"'' ]; }
|
||||
{
|
||||
Configure = [
|
||||
''nix-shell ./jenkins.nix --run "cabal configure --enable-tests"''
|
||||
''
|
||||
nix-shell ./jenkins.nix --run "cabal install --only-dependencies"''
|
||||
];
|
||||
}
|
||||
{ Build = [ ''nix-shell ./jenkins.nix --run "cabal build"'' ]; }
|
||||
{ Test = [ ''nix-shell ./jenkins.nix --run "cabal test"'' ]; }
|
||||
])
|
||||
|
||||
# sync to github
|
||||
# --------------
|
||||
(sync-to-github "sync-radiodj"
|
||||
"ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj2.git"
|
||||
"git@github.com:crashburn-radio/radio-dj.git")
|
||||
(sync-to-github "sync-radiodj-tracks"
|
||||
"ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj-tracks.git"
|
||||
"git@github.com:crashburn-radio/radio-dj-tracks.git")
|
||||
|
||||
(sync-to-github "sync-krops-module"
|
||||
"ssh://gogs@workhorse.private:2222/nix-modules/krops.git"
|
||||
"git@github.com:mrVanDalo/module.krops.git")
|
||||
|
||||
(sync-to-github "sync-cluster-module"
|
||||
"ssh://gogs@workhorse.private:2222/nix-modules/cluster.git"
|
||||
"git@github.com:mrVanDalo/module.cluster.git")
|
||||
|
||||
(sync-to-github "sync-backup-module"
|
||||
"ssh://gogs@workhorse.private:2222/nix-modules/backup.git"
|
||||
"git@github.com:mrVanDalo/module.backup.git")
|
||||
|
||||
(sync-to-github "sync-module-tinc"
|
||||
"ssh://gogs@workhorse.private:2222/palo/nixos-tinc.git"
|
||||
"git@github.com:mrVanDalo/nixos-tinc.git")
|
||||
|
||||
(sync-to-github "sync-memo"
|
||||
"ssh://gogs@workhorse.private:2222/palo/memo.git"
|
||||
"git@github.com:mrVanDalo/memo.git")
|
||||
|
||||
(sync-to-github "sync-diagrams-template"
|
||||
"ssh://gogs@workhorse.private:2222/palo/diagrams-template.git"
|
||||
"git@github.com:mrVanDalo/diagrams.git")
|
||||
|
||||
(sync-to-github "sync-plops"
|
||||
"ssh://gogs@workhorse.private:2222/palo/plops.git"
|
||||
"git@github.com:mrVanDalo/plops.git")
|
||||
|
||||
(sync-to-github "sync-image-generator"
|
||||
"ssh://gogs@workhorse.private:2222/palo/image-generator2.git"
|
||||
"git@github.com:mrVanDalo/image-generator.git")
|
||||
|
||||
(sync-to-github "sync-image-generator-lib"
|
||||
"ssh://gogs@workhorse.private:2222/palo/image-generator-lib.git"
|
||||
"git@github.com:mrVanDalo/image-generator-examples.git")
|
||||
|
||||
(sync-to-github "sync-tech.ingolf-wagner.de"
|
||||
"ssh://gogs@workhorse.private:2222/palo/tech.ingolf-wagner.de.git"
|
||||
"git@github.com:mrVanDalo/tech.ingolf-wagner.de.git")
|
||||
|
||||
(sync-to-github "sync-LineageOS-build"
|
||||
"ssh://gogs@git.ingolf-wagner.de:443/palo/LineagoOS-build.git"
|
||||
"git@github.com:mrVanDalo/LineagoOS-build.git")
|
||||
|
||||
(sync-to-github "sync-http-errors"
|
||||
"ssh://gogs@git.ingolf-wagner.de:443/palo/http-errors.git"
|
||||
"git@github.com:mrVanDalo/http-errors.git")
|
||||
(sync-to-github "sync-light-control"
|
||||
"ssh://gogs@git.ingolf-wagner.de:443/palo/light-control.git"
|
||||
"git@github.com:mrVanDalo/light-control.git")
|
||||
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
69
nixos/configs/workhorse/jupyter.nix
Normal file
69
nixos/configs/workhorse/jupyter.nix
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{ pkgs, lib, config, ... }: {
|
||||
|
||||
services.jupyter = {
|
||||
enable = true;
|
||||
ip = "0.0.0.0";
|
||||
#In [1]: from notebook.auth import passwd
|
||||
#In [2]: passwd('test')
|
||||
#Out[2]: 'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'
|
||||
#NOTE: you need to keep the single quote inside nix string.
|
||||
password = "'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'";
|
||||
kernels = {
|
||||
python3 = let
|
||||
env = (pkgs.python3.withPackages (pythonPackages:
|
||||
with pythonPackages; [
|
||||
ipykernel
|
||||
pandas
|
||||
|
||||
# database stuff
|
||||
mysqlclient
|
||||
databases
|
||||
asyncpg
|
||||
psycopg2
|
||||
aiomysql
|
||||
pymysql
|
||||
aiosqlite
|
||||
#aiopg
|
||||
sqlalchemy
|
||||
|
||||
# pdf export
|
||||
nbconvert
|
||||
]));
|
||||
in {
|
||||
displayName = "Python 3";
|
||||
argv = [
|
||||
"${env.interpreter}"
|
||||
"-m"
|
||||
"ipykernel_launcher"
|
||||
"-f"
|
||||
"{connection_file}"
|
||||
];
|
||||
language = "python";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# to generate pdfs and such
|
||||
environment.systemPackages = [ pkgs.pandoc ];
|
||||
|
||||
backup.dirs = [ "/var/lib/jupyter" ];
|
||||
backup.exclude =
|
||||
[ "/var/lib/jupyter/.local" "/var/lib/jupyter/.ipynb_checkpoints" ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"python.${config.networking.hostName}.private" = {
|
||||
serverAliases = [ "jupyter.${config.networking.hostName}.private" ];
|
||||
locations."/" = {
|
||||
proxyWebsockets = true;
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.jupyter.port
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
25
nixos/configs/workhorse/kibana.nix
Normal file
25
nixos/configs/workhorse/kibana.nix
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{ config, ... }: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"kibana.${config.networking.hostName}.private" = {
|
||||
serverAliases = [ ];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.kibana.port
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.elasticsearch.enable = true;
|
||||
services.elasticsearch.listenAddress = "workhorse.private";
|
||||
|
||||
services.kibana.enable = true;
|
||||
services.kibana.elasticsearch.hosts = [ "http://workhorse.private:9200" ];
|
||||
services.kibana.listenAddress = "workhorse.private";
|
||||
services.kibana.port = 5601;
|
||||
|
||||
}
|
||||
716
nixos/configs/workhorse/mail-fetcher.nix
Normal file
716
nixos/configs/workhorse/mail-fetcher.nix
Normal file
|
|
@ -0,0 +1,716 @@
|
|||
# fetches mails for me
|
||||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
junk_filter = [
|
||||
"from:booking.com"
|
||||
"from:brompton.com"
|
||||
"from:circleci.com OR (from:noreply@github.com AND to:audio-overlay@googlegroups.com)"
|
||||
"from:codepen.io"
|
||||
"from:congstarnews.de"
|
||||
"from:cronullasurfingacademy.com"
|
||||
"from:cryptohopper.com"
|
||||
"from:digitalo.de"
|
||||
"from:facebook.com OR from:facebookmail.com"
|
||||
"from:fitnessfirst.de"
|
||||
"from:flixbus.de"
|
||||
"from:getdigital.de"
|
||||
"from:getpocket.com"
|
||||
"from:ghostinspector.com"
|
||||
"from:globetrotter.de"
|
||||
"from:hackster.io"
|
||||
"from:hostelworld.com"
|
||||
"from:immobilienscout24.de"
|
||||
"from:kvraudio.com"
|
||||
"from:letterboxd.com"
|
||||
"from:linkedin.com"
|
||||
"from:magix.net"
|
||||
"from:mailings.gmx.net"
|
||||
"from:mailings.web.de"
|
||||
"from:matrix.org"
|
||||
"from:menospese.com"
|
||||
"from:microsoftstoreemail.com"
|
||||
"from:mixcloudmail.com AND subject:Weekly Update"
|
||||
"from:oknotify2.com AND NOT subject:New message"
|
||||
"from:paulaschoice.com"
|
||||
"from:puppet.com"
|
||||
"from:runtastic.com"
|
||||
"from:samplemagic.com OR from:wavealchemy.co.uk OR from:creators.gumroad.com"
|
||||
"from:ticketmaster.de"
|
||||
"from:trade4less.de"
|
||||
"from:tumblr.com"
|
||||
"from:turners.co.nz"
|
||||
"from:twitch.tv"
|
||||
"from:vstbuzz.com"
|
||||
];
|
||||
filters = [
|
||||
{
|
||||
query = "from:hv-geelen.de";
|
||||
tags = [ "+wohnung" ];
|
||||
}
|
||||
{
|
||||
query = "from:computerfutures.com OR from:computerfutures.de";
|
||||
tags = [ "+jobs" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query = "from:seek.com.au or from:seek.co.nz";
|
||||
tags = [ "+jobs" ];
|
||||
}
|
||||
{
|
||||
query = "from:xing.com";
|
||||
tags = [ "+jobs" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query = "from:no-reply@backtrace.io OR to:sononym@noreply.github.com";
|
||||
tags = [ "+sononym" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query = "from:ebay.com OR from:ebay.de OR from:ebay.net";
|
||||
tags = [ "+ebay" "+shop" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:bahn.de";
|
||||
tags = [ "+billing" "+bahn" ];
|
||||
}
|
||||
{
|
||||
query =
|
||||
"from:fysitech.atlassian.net OR to:engiadina-pwa@noreply.github.com";
|
||||
tags = [ "+mia" "+work" "-unread" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query =
|
||||
"from:space-left.org OR to:space-left.org OR subject:/\\[space-left\\]/";
|
||||
tags = [ "+spaceleft" "+space-left" ];
|
||||
}
|
||||
{
|
||||
query = "from:landr.com";
|
||||
tags = [ "+landr" "+music" ];
|
||||
}
|
||||
{
|
||||
query = "tag:landr and tag:billing";
|
||||
tags = [ "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:oknotify2.com";
|
||||
tags = [ "+okcupid" ];
|
||||
}
|
||||
{
|
||||
query = "from:taxback.de OR to:taxback.de";
|
||||
tags = [ "+steuer" ];
|
||||
}
|
||||
{
|
||||
query = "from:campact.de";
|
||||
tags = [ "+campact" "+politics" ];
|
||||
}
|
||||
{
|
||||
query = "from:aliexpress.com";
|
||||
tags = [ "+shop" "+aliexpress" ];
|
||||
}
|
||||
{
|
||||
query = "from:congstar.de";
|
||||
tags = [ "+billing" "+congstar" "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query =
|
||||
"from:steampowered.com AND NOT ( subject:purchase OR subject:received )";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query =
|
||||
"from:steampowered.com AND ( subject:purchase OR subject:received )";
|
||||
tags = [ "+billing" "+steam" ];
|
||||
}
|
||||
{
|
||||
query = "from:gog.com AND NOT subject:Bestellung";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:gog.com AND subject:Bestellung";
|
||||
tags = [ "+billing" "+gog" ];
|
||||
}
|
||||
{
|
||||
query = "from:stadtmobil.de";
|
||||
tags = [ "+billing" "+stadtmobil" "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:drive-now.com";
|
||||
tags = [ "+billing" "+drivenow" "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:data-treuhand.de";
|
||||
tags = [ "+mindcurv" "+work" "-inbox" "-unread" "-junk" ];
|
||||
}
|
||||
{
|
||||
query = "from:immocation.de";
|
||||
tags = [ "+immobilien" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query = "from:tinc-vpn.org";
|
||||
tags = [ "+tinc" ];
|
||||
}
|
||||
{
|
||||
query = "from:mindfactory.de";
|
||||
tags = [ "+shop" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:zalando.de";
|
||||
tags = [ "+shop" "+billing" "+zalando" ];
|
||||
}
|
||||
{
|
||||
query = "from:ing.de";
|
||||
tags = [ "+bank" "+ingdiba" ];
|
||||
}
|
||||
{
|
||||
query = "from:nab.com.au";
|
||||
tags = [ "+bank" "+nab" "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:dkb.de";
|
||||
tags = [ "+bank" "+dkb" ];
|
||||
}
|
||||
{
|
||||
query = "from:o2online.de";
|
||||
tags = [ "+billing" "+o2" ];
|
||||
}
|
||||
{
|
||||
query = "from:betfair.com";
|
||||
tags = [ "+work" "+betfair" ];
|
||||
}
|
||||
{
|
||||
query = "from:notifications@github.com";
|
||||
tags = [ "+github" ];
|
||||
}
|
||||
{
|
||||
query = "to:NUR@noreply.github.com";
|
||||
tags = [ "+nur" "+nixos" "+list" ];
|
||||
}
|
||||
{
|
||||
query = "to:nixpkgs@noreply.github.com";
|
||||
tags = [ "+nixpkgs" "+nixos" "+list" ];
|
||||
}
|
||||
{
|
||||
query = "from:travis-ci.org AND subject:mrVanDalo/navi";
|
||||
tags = [ "+development" "+navi" ];
|
||||
}
|
||||
{
|
||||
query = "from:travis-ci.org AND subject:nur-packages";
|
||||
tags = [ "+development" "+nixos" "+nur-packages" ];
|
||||
}
|
||||
{
|
||||
query = "from:travis-ci.org AND subject:csv-to-qif";
|
||||
tags = [ "+development" "+csv-to-qif" ];
|
||||
}
|
||||
{
|
||||
query = "to:proaudio@lists.tuxfamily.org";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com";
|
||||
tags = [ "+nixos" "+discourse" "+list" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Development";
|
||||
tags = [ "+nixos" "+discourse" "+development" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Français";
|
||||
tags = [ "+nixos" "+discourse" "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Announcements";
|
||||
tags = [ "+nixos" "+discourse" "+announcements" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Links";
|
||||
tags = [ "+nixos" "+discourse" "+links" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Games";
|
||||
tags = [ "+nixos" "+discourse" "+games" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Meta";
|
||||
tags = [ "+nixos" "+discourse" "+meta" ];
|
||||
}
|
||||
{
|
||||
query = "from:nixos1@discoursemail.com AND subject:Events";
|
||||
tags = [ "+nixos" "+discourse" "+events" ];
|
||||
}
|
||||
{
|
||||
query = "from:limebike.com AND (subject:Funds OR subject:Receipt)";
|
||||
tags = [ "-inbox" "-unread" "+billing" "+limebike" ];
|
||||
}
|
||||
{
|
||||
query = "from:freemusicarchive.org";
|
||||
tags = [ "+FMA" ];
|
||||
}
|
||||
{
|
||||
query = "from:namecheap.com and subject:auto-renewal";
|
||||
tags = [ "+namecheap" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:namecheap.com and subject:order";
|
||||
tags = [ "+namecheap" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "tag:namecheap.com and tag:billing and body:gaykraft.com";
|
||||
tags = [ "+namecheap" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:nintendo.com";
|
||||
tags = [ "+nintendo" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:oculus.com AND subject:receipt";
|
||||
tags = [ "+oculus" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:car2go.com";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:sixt.de";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
}
|
||||
{
|
||||
query = "from:meetup.com";
|
||||
tags = [ "-inbox" "-unread" "+meetup" ];
|
||||
}
|
||||
{
|
||||
query = "from:slack.com";
|
||||
tags = [ "+slack" ];
|
||||
}
|
||||
{
|
||||
query = "from:keybase.io";
|
||||
tags = [ "+keybase" ];
|
||||
}
|
||||
{
|
||||
query = "from:jobs2web.com";
|
||||
tags = [ "+newzealand" "+jobs" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query = "from:paypal.de AND subject:Bestätigung";
|
||||
tags = [ "-unread" "+paypal" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "to:c-base.org";
|
||||
tags = [ "+cbase" "+list" ];
|
||||
}
|
||||
{
|
||||
query = "to:c-base.org AND subject=[auto-report]";
|
||||
tags = [ "-unread" "-inbox" ];
|
||||
}
|
||||
{
|
||||
query = "from:browserstack.com";
|
||||
tags = [ "+browserstack" ];
|
||||
}
|
||||
{
|
||||
query =
|
||||
"to:renoise@ingolf-wagner.de OR to:root@renoise.com OR from:renoise.com OR to:admin@renoise.com";
|
||||
tags = [ "+renoise" ];
|
||||
}
|
||||
{
|
||||
query = "from:amazon.de OR from:amazon.com AND NOT to:renoise.com";
|
||||
tags = [ "+shop" "+amazon" "+billing" ];
|
||||
}
|
||||
{
|
||||
query = "from:hetzner.com OR from:hetzner.de";
|
||||
tags = [ "+hetzner" ];
|
||||
}
|
||||
{
|
||||
query =
|
||||
"to:renoise.com AND NOT ( from:renoise.com OR from:root OR from:hetzner.com OR from:hetzner.de OR from:amazon.com OR from:gmail.com )";
|
||||
tags = [ "-inbox" "-unread" "+junk" "+renoise" ];
|
||||
}
|
||||
{
|
||||
query = "tag:hetzner and subject:Invoice";
|
||||
tags = [ "+billing" ];
|
||||
}
|
||||
# final rules to make imap sync stuff easier
|
||||
# there can only be one output folder tag, and theses rules are prioritized
|
||||
{
|
||||
query = "tag:fraud";
|
||||
tags = [ "-inbox" "-archive" "-junk" "-unread" ];
|
||||
message = "clean up tag fraud";
|
||||
}
|
||||
{
|
||||
query = "tag:junk";
|
||||
tags = [ "-inbox" "-archive" "-fraud" "-unread" ];
|
||||
message = "clean up tag junk";
|
||||
}
|
||||
{
|
||||
query = "tag:archive";
|
||||
tags = [ "-inbox" "-junk" "-fraud" "-unread" ];
|
||||
message = "clean up tag archive";
|
||||
}
|
||||
{
|
||||
query = "tag:inbox";
|
||||
tags = [ "-archive" "-junk" "-fraud" ];
|
||||
message = "clean up inbox";
|
||||
}
|
||||
{
|
||||
query = "tag:killed";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
message = "clean up tag killed";
|
||||
}
|
||||
{
|
||||
query = "tag:muted";
|
||||
tags = [ "-inbox" "-unread" ];
|
||||
}
|
||||
# remove new tag at the end
|
||||
{
|
||||
query = "tag:new";
|
||||
tags = [ "-new" ];
|
||||
message = "remove new tag at the end";
|
||||
}
|
||||
];
|
||||
|
||||
notmuchTagging = let
|
||||
|
||||
template = index:
|
||||
{ tags, query, message ? "generic", ... }:
|
||||
let
|
||||
command = ''
|
||||
${pkgs.notmuch}/bin/notmuch tag ${
|
||||
lib.concatStringsSep " " tags
|
||||
} -- "${query}"
|
||||
'';
|
||||
in ''
|
||||
echo '${command}'
|
||||
${command}
|
||||
'';
|
||||
junk_template = index: query:
|
||||
template index {
|
||||
tags = [ "+junk" "-unread" "-inbox" ];
|
||||
query = query;
|
||||
message = "generic junk filter";
|
||||
};
|
||||
|
||||
in pkgs.writers.writeBash "notmuch-tagging" (lib.concatStringsSep "\n"
|
||||
((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters)));
|
||||
|
||||
notmuchTaggingNew = let
|
||||
|
||||
template = index:
|
||||
{ tags, query, message ? "generic", ... }:
|
||||
let
|
||||
command = ''
|
||||
${pkgs.notmuch}/bin/notmuch tag ${
|
||||
lib.concatStringsSep " " tags
|
||||
} -- "${query} AND tag:new"
|
||||
'';
|
||||
in ''
|
||||
echo '${command}'
|
||||
${command}
|
||||
'';
|
||||
|
||||
junk_template = index: query:
|
||||
template index {
|
||||
tags = [ "+junk" "-unread" "-inbox" ];
|
||||
query = query;
|
||||
message = "generic junk filter";
|
||||
};
|
||||
in pkgs.writers.writeBash "notmuch-tagging-new" (lib.concatStringsSep "\n"
|
||||
((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters)));
|
||||
|
||||
in {
|
||||
|
||||
backup.dirs = [ "/home/mailfetcher" ];
|
||||
|
||||
users.users.mailUser = {
|
||||
isNormalUser = true;
|
||||
description = "collects mails for me";
|
||||
hashedPassword = "!";
|
||||
name = "mailfetcher";
|
||||
home = "/home/mailfetcher";
|
||||
openssh.authorizedKeys.keyFiles =
|
||||
config.users.users.root.openssh.authorizedKeys.keyFiles;
|
||||
};
|
||||
|
||||
# configure passwords
|
||||
krops.userKeys = {
|
||||
"namecheap.terranix.org" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/namecheap/terranix.org>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
"gmail.palipalo9" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/gmail/palipalo9>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
"gmx.palo_van_dalo" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/gmx/palo_van_dalo>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
"gmx.ingolf_wagner" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/gmx/ingolf.wagner>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
"web.pali_palo" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/web.de/pali_palo>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
"siteground.contact" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/siteground/contact>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
"c-base.palo" = {
|
||||
user = config.users.users.mailUser.name;
|
||||
source = toString <secrets/mail/c-base/palo>;
|
||||
requiredBy = [ "fetchmail.service" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.muchsync ];
|
||||
|
||||
# configure accounts
|
||||
home-manager.users.mailUser.accounts.email = {
|
||||
accounts = {
|
||||
|
||||
palo_van_dalo-gmx = {
|
||||
primary = false;
|
||||
address = "palo_van_dalo@gmx.de";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "palo_van_dalo@gmx.de";
|
||||
passwordCommand =
|
||||
"cat ${toString config.krops.userKeys."gmx.palo_van_dalo".target}";
|
||||
imap = {
|
||||
host = "imap.gmx.net";
|
||||
tls.enable = true;
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
ingolf-wagner-gmx = {
|
||||
primary = false;
|
||||
address = "ingolf.wagner@gmx.de";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "ingolf.wagner@gmx.de";
|
||||
passwordCommand =
|
||||
"cat ${toString config.krops.userKeys."gmx.ingolf_wagner".target}";
|
||||
imap = {
|
||||
host = "imap.gmx.net";
|
||||
tls.enable = true;
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
pali_palo = {
|
||||
primary = false;
|
||||
address = "pali_palo@web.de";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "pali_palo@web.de";
|
||||
passwordCommand =
|
||||
"cat ${toString config.krops.userKeys."web.pali_palo".target}";
|
||||
imap = {
|
||||
host = "imap.web.de";
|
||||
tls.enable = true;
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
c-base = {
|
||||
primary = false;
|
||||
address = "palo@c-base.org";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "palo";
|
||||
passwordCommand =
|
||||
"cat ${toString config.krops.userKeys."c-base.palo".target}";
|
||||
imap = {
|
||||
host = "c-mail.c-base.org";
|
||||
port = 993;
|
||||
# fetched using : nix-shell -p openssl --run "openssl s_client -connect c-mail.c-base.org:993 -showcerts"
|
||||
tls.certificatesFile = pkgs.writeText "c-base.pem" ''
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFKDCCAxCgAwIBAgIDAtwrMA0GCSqGSIb3DQEBDQUAMFQxFDASBgNVBAoTC0NB
|
||||
Y2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5vcmcxHDAaBgNV
|
||||
BAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwHhcNMTkxMTA5MDgzMjUyWhcNMjExMTA4
|
||||
MDgzMjUyWjBhMQswCQYDVQQGEwJERTEPMA0GA1UECBMGQmVybGluMQ8wDQYDVQQH
|
||||
EwZCZXJsaW4xFDASBgNVBAoTC2MtYmFzZSBlLlYuMRowGAYDVQQDExFjLW1haWwu
|
||||
Yy1iYXNlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKR3XBxJ
|
||||
72MayCS0D5GCoHcY0TQLs1DQSohCCobRdSowFJzNQw/2lL6bb+Q2rmevZQXuM4vP
|
||||
YbFytvTDmY5y5MNXEqGLfi8D5TcaP/RdXWQU++yUunE6yMdqZNheeXPjM//PnoXG
|
||||
DyT236BovEi3YipUUsLXFiRj+cAjrQE7a2YUs3fjV3P6grMH0V06J6P6+JJvRgp2
|
||||
K33uhKhnKyb3s1tbdbu1KeGozx2ws9lg79XV+Py6PXxP6jTZ2PCsaxs3BThSdmsl
|
||||
vQyk/zoW7tA1m2ntRCoyFHZqfOHsN3UOS/HDRlXqgSf0ah8cPYPsl0ayXhgOv0Tu
|
||||
1PSMt4Ve2GajX8MCAwEAAaOB9TCB8jAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQE
|
||||
AwIDqDA0BgNVHSUELTArBggrBgEFBQcDAgYIKwYBBQUHAwEGCWCGSAGG+EIEAQYK
|
||||
KwYBBAGCNwoDAzAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9v
|
||||
Y3NwLmNhY2VydC5vcmcvMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9jcmwuY2Fj
|
||||
ZXJ0Lm9yZy9jbGFzczMtcmV2b2tlLmNybDAtBgNVHREEJjAkghFjLW1haWwuYy1i
|
||||
YXNlLm9yZ4IPbWFpbC5jLWJhc2Uub3JnMA0GCSqGSIb3DQEBDQUAA4ICAQBjTIa1
|
||||
xdhUYXJidv1U0qaqSV1DzumakFY20OM4QCV0Qvlq+SQUqroGBTIGodxhTnjG5o01
|
||||
4xBAnsTcMRNycXHu0j6XYqDS4QhaFcGdFmXP0EQfAFbvhwZdbvgiRHuUTSGEbcLp
|
||||
Vk8sP8dpzx+zMAZ6PL7XMwPFPTHm7vw40qmTyCuUcnhIwHgwGxu4yu0tdsU+VwRD
|
||||
RVsdZO4V2GhFTz8oRcHvmC2wmx+Zwx0RXWPXSN5yRDDZWwY4WbECa2MvojH1HlJG
|
||||
YJkokq7nbYJix/RipSkAXgurcgppVmM5cf7uYgSrltW8pm3IMMPrlaFrlzMMMtdq
|
||||
SYFk+FDp296B7CDyWpQhDcVjnGQ70JfMWT5S3Lsi8DnI2pul9ljxPOt+Q8XFh1oz
|
||||
Ofr7y5Qjm72YToOX1j7N8ppCh0RJH4lOsouTPVdp859ch9FxZdceq+nC744wv+Nt
|
||||
TQPw15Gk3RY5mVYBE/Cw2T7j7qDmBaEUKxkfW7q8t287FXM4XX6C+cKYr6jYx6s1
|
||||
5/2p4gCuOALYqJ7kD2xjci0VTWu77H4J2QKEZF8AgdI36dIYr7GY0e/+xb/CScwr
|
||||
uvu2R9jfPOMVu6CiavPGUtcvju4A+qMUDqIyH9dNwkMQRffAtmsF6KR4nMYxhr45
|
||||
nKY1BaufWLD1UWrjaR1IF6L5qDHOXeMJEChYkg==
|
||||
-----END CERTIFICATE-----'';
|
||||
};
|
||||
mbsync = {
|
||||
enable = false;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
gmail = {
|
||||
# for google accounts you have to allow 'less secure apps' in accounts.google.com
|
||||
primary = true;
|
||||
address = "palipalo9@googlemail.com";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "palipalo9@googlemail.com";
|
||||
passwordCommand =
|
||||
"cat ${toString config.krops.userKeys."gmail.palipalo9".target}";
|
||||
imap = {
|
||||
host = "imap.gmail.com";
|
||||
tls.enable = true;
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
terranix_org = {
|
||||
primary = false;
|
||||
address = "palo@terranix.org";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "palo@terranix.org";
|
||||
passwordCommand = "cat ${
|
||||
toString config.krops.userKeys."namecheap.terranix.org".target
|
||||
}";
|
||||
imap = {
|
||||
host = "mail.privateemail.com";
|
||||
tls.enable = true;
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
ingolf-wagner-de = {
|
||||
primary = false;
|
||||
address = "contact@ingolf-wagner.de";
|
||||
aliases = [ ];
|
||||
realName = "Ingolf Wagner";
|
||||
userName = "contact@ingolf-wagner.de";
|
||||
passwordCommand =
|
||||
"cat ${toString config.krops.userKeys."siteground.contact".target}";
|
||||
imap = {
|
||||
host = "securees5.sgcpanel.com";
|
||||
port = 993;
|
||||
tls.enable = true;
|
||||
#tls.useStartTls = true;
|
||||
};
|
||||
# make sure the upstream mail is deleted
|
||||
getmail = {
|
||||
enable = true;
|
||||
delete = true;
|
||||
readAll = false;
|
||||
mailboxes = [ "ALL" ];
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
# configure mbsync
|
||||
home-manager.users.mailUser.programs.mbsync.enable = true;
|
||||
|
||||
# re-tag everything once a day
|
||||
systemd.services.retagmail = {
|
||||
enable = true;
|
||||
serviceConfig = { User = config.users.users.mailUser.name; };
|
||||
environment.NOTMUCH_CONFIG =
|
||||
"${config.users.users.mailUser.home}/.config/notmuch/notmuchrc";
|
||||
script = "${notmuchTagging}";
|
||||
};
|
||||
systemd.timers.retagmail = {
|
||||
enable = true;
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = "true";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
# fetch mails every 10 minutes
|
||||
systemd.services.fetchmail = {
|
||||
enable = true;
|
||||
serviceConfig = { User = config.users.users.mailUser.name; };
|
||||
environment.NOTMUCH_CONFIG =
|
||||
"${config.users.users.mailUser.home}/.config/notmuch/notmuchrc";
|
||||
script = ''
|
||||
echo "run mbsync"
|
||||
${pkgs.isync}/bin/mbsync \
|
||||
--all
|
||||
|
||||
echo "run getmail"
|
||||
${pkgs.getmail}/bin/getmail \
|
||||
--quiet \
|
||||
--rcfile getmailingolf-wagner-de
|
||||
|
||||
echo "run notmuch"
|
||||
${pkgs.notmuch}/bin/notmuch new
|
||||
${notmuchTaggingNew}
|
||||
echo "mute threads"
|
||||
${pkgs.notmuch}/bin/notmuch tag +muted $(${pkgs.notmuch}/bin/notmuch search --output=threads tag:muted)
|
||||
echo "delete threads"
|
||||
${pkgs.notmuch}/bin/notmuch tag +deleted $(${pkgs.notmuch}/bin/notmuch search --output=threads tag:deleted)
|
||||
'';
|
||||
};
|
||||
systemd.timers.fetchmail = {
|
||||
enable = true;
|
||||
# timerConfig.OnCalendar = " *-*-* *:00:00";
|
||||
timerConfig.OnCalendar = "*:0/10";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
# configure notmuch
|
||||
home-manager.users.mailUser.programs.notmuch = {
|
||||
enable = true;
|
||||
new.tags = [ "unread" "inbox" "new" ];
|
||||
};
|
||||
home-manager.users.mailUser.home.file."notmuch" = {
|
||||
source = "${config.users.users.mailUser.home}/.config/notmuch/notmuchrc";
|
||||
target = ".notmuch-config";
|
||||
};
|
||||
|
||||
}
|
||||
24
nixos/configs/workhorse/metabase.nix
Normal file
24
nixos/configs/workhorse/metabase.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{ pkgs, lib, config, ... }: {
|
||||
|
||||
services.metabase = {
|
||||
listen.port = 3040;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
backup.dirs = [ "/var/lib/metabase" ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"metabase.${config.networking.hostName}.private" = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${
|
||||
toString config.services.metabase.listen.port
|
||||
}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
51
nixos/configs/workhorse/mining.nix
Normal file
51
nixos/configs/workhorse/mining.nix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
{ pkgs, config, ... }:
|
||||
let
|
||||
maxPower = 90;
|
||||
pool = "eu1.ethermine.org";
|
||||
toolkit = "opencl";
|
||||
wallet = "";
|
||||
rig = config.networking.hostName;
|
||||
recheckInterval = 2000;
|
||||
package = pkgs.ethminer;
|
||||
in {
|
||||
|
||||
systemd.services.ethminer = {
|
||||
description = "ethminer ethereum mining service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
ExecStartPre = "${package}/bin/.ethminer-wrapped --list-devices";
|
||||
Restart = "always";
|
||||
};
|
||||
|
||||
script = ''
|
||||
${package}/bin/.ethminer-wrapped \
|
||||
--farm-recheck ${toString recheckInterval} \
|
||||
--report-hashrate \
|
||||
--${toolkit} \
|
||||
--pool stratum1+tcp://${wallet}.${rig}@${pool}:4444
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
# https://wiki.archlinux.org/title/GPGPU#Intel
|
||||
hardware.opengl = {
|
||||
enable = true;
|
||||
extraPackages = with pkgs; [ intel-ocl intel-compute-runtime beignet ];
|
||||
driSupport = true;
|
||||
driSupport32Bit = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
package
|
||||
# go-ethereum
|
||||
go-ethereum
|
||||
# to check opencl config
|
||||
clinfo
|
||||
# check temperature
|
||||
i7z
|
||||
];
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue