init
This commit is contained in:
commit
54bab918d7
260 changed files with 18544 additions and 0 deletions
7
.channelStable.json
Normal file
7
.channelStable.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"url": "https://github.com/NixOS/nixpkgs-channels.git",
|
||||
"rev": "0e0ee084d6dfc83b5b67b6cbcefe43664114808d",
|
||||
"date": "2019-10-07T15:48:50+02:00",
|
||||
"sha256": "1qk0ag4ihfjh9ay28hc9zf9vnrdw096driirv62picyn30j9y0l3",
|
||||
"fetchSubmodules": false
|
||||
}
|
7
.channelUnstable.json
Normal file
7
.channelUnstable.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"url": "https://github.com/NixOS/nixpkgs-channels.git",
|
||||
"rev": "2436c27541b2f52deea3a4c1691216a02152e729",
|
||||
"date": "2019-09-25T08:02:27+02:00",
|
||||
"sha256": "0p98dwy3rbvdp6np596sfqnwlra11pif3rbdh02pwdyjmdvkmbvd",
|
||||
"fetchSubmodules": false
|
||||
}
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
*.swp
|
||||
result
|
||||
result-*
|
||||
.history
|
||||
TAGS
|
||||
|
||||
*.tf.json
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
[submodule "assets/video-browser"]
|
||||
path = assets/video-browser
|
||||
url = ssh://gogs@git.ingolf-wagner.de:443/palo/video-browser.git
|
||||
[submodule "wetten"]
|
||||
path = wetten
|
||||
url = ssh://gogs@git.ingolf-wagner.de:443/palo/wetten.git
|
7
.krops.json
Normal file
7
.krops.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"url": "https://git.ingolf-wagner.de/krebs/krops.git",
|
||||
"rev": "2e93a93ac264a480b427acc2684993476732539d",
|
||||
"date": "2018-09-19T19:57:26+02:00",
|
||||
"sha256": "1s6b2cs60xa270ynhr32qj1rcy3prvf9pidap0qbbvgg008iafxk",
|
||||
"fetchSubmodules": false
|
||||
}
|
7
.nix-writers.json
Normal file
7
.nix-writers.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"url": "https://cgit.krebsco.de/nix-writers/",
|
||||
"rev": "fc8a3802a0777a5f43a9a2fe0f5848ecaeb555a1",
|
||||
"date": "2018-10-27T14:45:48+02:00",
|
||||
"sha256": "1iy207rcbz9nv9bf64025ypy38x8mwzl6snbmbrq347h6vvs0ksc",
|
||||
"fetchSubmodules": false
|
||||
}
|
7
.nixos-generators.json
Normal file
7
.nixos-generators.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"url": "https://github.com/nix-community/nixos-generators.git",
|
||||
"rev": "ef1e4480cf8af45cfdeac597b2f1b1af33923e93",
|
||||
"date": "2019-01-18T10:41:01+01:00",
|
||||
"sha256": "0ymzp4pmpkjjjg5h8d45gv8avy4wh1dj0v238i2cz3jp3j489ik9",
|
||||
"fetchSubmodules": false
|
||||
}
|
35
README.md
Normal file
35
README.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# My NixOS configuration
|
||||
|
||||
## Folder Structure
|
||||
|
||||
### configs
|
||||
|
||||
This should container system specific configurations
|
||||
|
||||
### system
|
||||
|
||||
Holds system type information like `server` and `desktop`.
|
||||
|
||||
### modules
|
||||
|
||||
This should container scripts that can be copied across different sources.
|
||||
|
||||
### pkgs
|
||||
|
||||
My overlay is in here.
|
||||
|
||||
### assets
|
||||
|
||||
assets, like scripts which I dont want to write in nix-lang.
|
||||
|
||||
### terranix
|
||||
|
||||
some terranix scripts
|
||||
|
||||
### library
|
||||
|
||||
some nix-lang functions and tools I use.
|
||||
|
||||
### images
|
||||
|
||||
some images I use and build via nixos-generators.
|
105
assets/jack.sh
Executable file
105
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
|
56
assets/shrink_exports
Executable file
56
assets/shrink_exports
Executable file
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
PROJECTS_FOLDER=~/music-projects/Rendered-Projects
|
||||
|
||||
# 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 "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
assets/sprueche-axel
Normal file
3
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
assets/sprueche-siw
Normal file
18
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
assets/ssh/card_rsa.pub
Normal file
1
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
assets/tinc/pepe_host_file
Normal file
14
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
assets/tinc/porani_host_file
Normal file
14
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
assets/tinc/retiolum/host_file
Normal file
14
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
assets/tinc/sputnik_host_file
Normal file
14
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
assets/tinc/sterni_host_file
Normal file
14
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
assets/tinc/workhorse_host_file
Normal file
14
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
assets/tinc/workout_host_file
Normal file
14
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-----
|
10
collect-network-connections.sh
Normal file
10
collect-network-connections.sh
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# collect all network configurations and save them in the store
|
||||
|
||||
sudo ls /etc/NetworkManager/system-connections \
|
||||
| while read file
|
||||
do
|
||||
sudo cat /etc/NetworkManager/system-connections/$file \
|
||||
| pass insert -m desktop/network-manager/system-connections/$file
|
||||
done
|
64
configs/pepe/configuration.nix
Normal file
64
configs/pepe/configuration.nix
Normal file
|
@ -0,0 +1,64 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
|
||||
imports = [
|
||||
|
||||
<system/desktop>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./encfs.nix
|
||||
#./samba.nix
|
||||
./syncthing.nix
|
||||
./tinc.nix
|
||||
#./wifi-access-point.nix
|
||||
|
||||
];
|
||||
|
||||
custom.samba-share.folders = {
|
||||
enable = false;
|
||||
public = "/home/palo/movies";
|
||||
};
|
||||
|
||||
system.custom.wifi.interfaces = ["wlp3s0"];
|
||||
|
||||
networking.hostName = "pepe";
|
||||
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount}/bin/pumount";
|
||||
};
|
||||
|
||||
# keybase
|
||||
services.keybase.enable = true;
|
||||
services.kbfs.enable = true;
|
||||
|
||||
programs.custom.steam.enable = false;
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
8
configs/pepe/encfs.nix
Normal file
8
configs/pepe/encfs.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
module.backup.services.encfs = {
|
||||
"fotos".enable = true;
|
||||
"desktop".enable = true;
|
||||
"finance".enable = true;
|
||||
};
|
||||
}
|
86
configs/pepe/hardware-configuration.nix
Normal file
86
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>
|
||||
];
|
||||
|
||||
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";
|
||||
fsType = "tmpfs";
|
||||
};
|
||||
|
||||
fileSystems."/browsers/" = {
|
||||
#device = "/dev/ram2";
|
||||
#fsType = "tmpfs";
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/secure_vg/browser";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
nix.maxJobs = lib.mkDefault 4;
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
|
||||
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = [
|
||||
{
|
||||
name = "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";
|
||||
};
|
||||
|
||||
# /home/palo/private/.fotos.ct
|
||||
# ----------------------------
|
||||
fileSystems."/home/palo/private/.fotos.ct" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/secure_vg/fotos";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
# boot
|
||||
# ----
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
|
||||
}
|
5
configs/pepe/samba.nix
Normal file
5
configs/pepe/samba.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
|
||||
|
||||
}
|
32
configs/pepe/syncthing.nix
Normal file
32
configs/pepe/syncthing.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
test.services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = false;
|
||||
user = "palo";
|
||||
dataDir = "/home/palo/.syncthing";
|
||||
configDir = "/home/palo/.syncthing";
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
|
||||
book.path = "/home/palo/books";
|
||||
desktop-encrypted.path = "/home/palo/.desktop.ct";
|
||||
finance-encrypted.path = "/home/palo/.finance.ct";
|
||||
fotos-encrypted.path = "/home/palo/private/.fotos.ct";
|
||||
kruck-pepe.path = "/home/palo/pepe-kruck";
|
||||
music-library.path = "/home/palo/music-library";
|
||||
music-projects.path = "/home/palo/music-projects";
|
||||
porani-pepe.path = "/home/palo/pepe-porani";
|
||||
schasch-pepe.path = "/home/palo/pepe-schasch";
|
||||
smartphone-fotos.path = "/home/palo/smartphone-fotos";
|
||||
workout-pepe.path = "/home/palo/pepe-workout";
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
18
configs/pepe/tinc.nix
Normal file
18
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;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
77
configs/pepe/wifi-access-point.nix
Normal file
77
configs/pepe/wifi-access-point.nix
Normal file
|
@ -0,0 +1,77 @@
|
|||
{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}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
58
configs/porani/configuration.nix
Normal file
58
configs/porani/configuration.nix
Normal file
|
@ -0,0 +1,58 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
imports = [
|
||||
|
||||
<system/server>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./tinc.nix
|
||||
./syncthing.nix
|
||||
#./packages.nix
|
||||
#./home-assistant.nix
|
||||
#./wifi-access-point.nix
|
||||
#./kodi.nix
|
||||
#./mpd.nix
|
||||
|
||||
];
|
||||
|
||||
networking.hostName = "porani";
|
||||
|
||||
# enable initrd ssh
|
||||
configuration.init-ssh = {
|
||||
enable = "enabled";
|
||||
kernelModules = [ "e1000e" ];
|
||||
authorizedKeys = config.users.users.root.openssh.authorizedKeys.keyFiles;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
77
configs/porani/hardware-configuration.nix
Normal file
77
configs/porani/hardware-configuration.nix
Normal file
|
@ -0,0 +1,77 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
imports =
|
||||
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# grub configuration
|
||||
# ------------------
|
||||
boot.loader.grub = {
|
||||
device = "/dev/sda";
|
||||
enable = true;
|
||||
version = 2;
|
||||
};
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = [
|
||||
{
|
||||
name = "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";
|
||||
};
|
||||
|
||||
# automount
|
||||
# ---------
|
||||
fileSystems."/media" = {
|
||||
device = "/dev/disk/by-uuid/162c2f9e-8baa-4433-99fd-bb7e7b69472f";
|
||||
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/162c2f9e-8baa-4433-99fd-bb7e7b69472f";
|
||||
where = "/media";
|
||||
}
|
||||
];
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nix.maxJobs = lib.mkDefault 4;
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
}
|
228
configs/porani/home-assistant.nix
Normal file
228
configs/porani/home-assistant.nix
Normal file
|
@ -0,0 +1,228 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
unstablePkgs = import <nixpkgs-unstable> {};
|
||||
in {
|
||||
|
||||
imports = [
|
||||
./home-assistant/chaospott.nix
|
||||
./home-assistant/holiday.nix
|
||||
./home-assistant/mpd.nix
|
||||
./home-assistant/sonoff.nix
|
||||
./home-assistant/mqtt.nix
|
||||
./home-assistant/dayOfWeek.nix
|
||||
./home-assistant/timer.nix
|
||||
./home-assistant/kodi.nix
|
||||
./home-assistant/zigbee2mqtt.nix
|
||||
];
|
||||
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# turn on to edit GUI
|
||||
# lovelace = {};
|
||||
|
||||
homeassistant = {
|
||||
latitude = 51.444847;
|
||||
longitude = 6.967006;
|
||||
elevation = 116;
|
||||
|
||||
|
||||
auth_providers = [
|
||||
{
|
||||
type = "trusted_networks";
|
||||
trusted_networks = [
|
||||
config.module.cluster.services.tinc."private".networkSubnet
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
prometheus.namespace = "hass";
|
||||
|
||||
automation = [
|
||||
|
||||
# todo when ich weis ich bin zuhause
|
||||
#{
|
||||
# alias = "Licht and wenn Dunkel";
|
||||
# trigger = {
|
||||
# platform = "state";
|
||||
# entity_id = [ "binary_sensor.night" ];
|
||||
# from = "off";
|
||||
# to = "on";
|
||||
# };
|
||||
# action = [
|
||||
# {
|
||||
# service = "switch.turn_on";
|
||||
# entity_id = "group.kitchen";
|
||||
# }
|
||||
# {
|
||||
# service = "switch.turn_on";
|
||||
# entity_id = "group.living_room";
|
||||
# }
|
||||
# ];
|
||||
#}
|
||||
|
||||
#{
|
||||
# alias = "Küchen Sensor An";
|
||||
# trigger = {
|
||||
# platform = "state";
|
||||
# entity_id = [ "binary_sensor.motion_1" ];
|
||||
# to = "on";
|
||||
# };
|
||||
# action = {
|
||||
# service = "switch.turn_on";
|
||||
# entity_id = "group.kitchen";
|
||||
# };
|
||||
#}
|
||||
|
||||
#{
|
||||
# alias = "Küchen Sensor aus";
|
||||
# trigger = {
|
||||
# platform = "state";
|
||||
# entity_id = [ "binary_sensor.motion_1" ];
|
||||
# to = "off";
|
||||
# for = "00:00:25";
|
||||
# };
|
||||
# action = {
|
||||
# service = "switch.turn_off";
|
||||
# entity_id = "group.kitchen";
|
||||
# };
|
||||
#}
|
||||
];
|
||||
|
||||
group = {
|
||||
bed_room = {
|
||||
name = "Schlafzimmer";
|
||||
view = false;
|
||||
};
|
||||
tv = {
|
||||
name = "TV";
|
||||
view = false;
|
||||
};
|
||||
living_room = {
|
||||
name = "Wohnzimmer";
|
||||
view = false;
|
||||
};
|
||||
kitchen = {
|
||||
name = "Küche";
|
||||
view = false;
|
||||
};
|
||||
today = {
|
||||
control = "hidden";
|
||||
name = "Today";
|
||||
view = false;
|
||||
entities = [
|
||||
"sensor.weather_temperature"
|
||||
"sun.sun"
|
||||
];
|
||||
};
|
||||
all_lights = {
|
||||
name = "All Lights";
|
||||
view = false;
|
||||
};
|
||||
unknown = {
|
||||
control = "hidden";
|
||||
name = "Not Used";
|
||||
view = false;
|
||||
};
|
||||
|
||||
view_rooms = {
|
||||
name = "Räume";
|
||||
view = true;
|
||||
entities = [
|
||||
"group.all_lights"
|
||||
"group.bed_room"
|
||||
"group.living_room"
|
||||
"group.kitchen"
|
||||
"group.tv"
|
||||
];
|
||||
};
|
||||
|
||||
view_overview = {
|
||||
name = "Übersicht";
|
||||
view = true;
|
||||
entities = [ "group.today" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
sun = {};
|
||||
|
||||
script.turn_all_off.sequence = [ ];
|
||||
|
||||
script.turn_all_on.sequence = [ ];
|
||||
|
||||
sensor = [
|
||||
# Weather prediction
|
||||
{ platform = "zamg";
|
||||
name = "Weather";
|
||||
}
|
||||
];
|
||||
|
||||
# todo: add holidays package to home-assiatnt
|
||||
binary_sensor = [
|
||||
{
|
||||
name = "before_workday";
|
||||
platform = "workday";
|
||||
country = "DE";
|
||||
province = "NW";
|
||||
workdays = [ "mon" "tue" "wed" "thu" "fri" ];
|
||||
days_offset = 1;
|
||||
}
|
||||
{
|
||||
name = "workday";
|
||||
platform = "workday";
|
||||
country = "DE";
|
||||
province = "NW";
|
||||
workdays = [ "mon" "tue" "wed" "thu" "fri" ];
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
package = unstablePkgs.home-assistant.override{
|
||||
python3 = unstablePkgs.python36;
|
||||
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 ];
|
||||
};
|
||||
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
85
configs/porani/home-assistant/chaospott.nix
Normal file
85
configs/porani/home-assistant/chaospott.nix
Normal file
|
@ -0,0 +1,85 @@
|
|||
{ 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)";
|
||||
control = "hidden";
|
||||
entities = [
|
||||
"sensor.${name}_aerie"
|
||||
"sensor.${name}_cellar"
|
||||
];
|
||||
};
|
||||
view_overview.entities = [ "group.${name}" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
systemd.services."${name}" = {
|
||||
enable = true;
|
||||
before = [ "home-assistant.service" ];
|
||||
wantedBy = [ "home-assistant.service" ];
|
||||
serviceConfig = {
|
||||
User = "hass";
|
||||
Type = "oneshot";
|
||||
};
|
||||
description = "set ${name} for homeassistant";
|
||||
script = /* sh */ ''
|
||||
${pkgs.curl}/bin/curl -Ls 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";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
57
configs/porani/home-assistant/dayOfWeek.nix
Normal file
57
configs/porani/home-assistant/dayOfWeek.nix
Normal file
|
@ -0,0 +1,57 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
|
||||
folderPath = config.services.home-assistant.configDir;
|
||||
filePath = "${folderPath}/dayOfWeek.json";
|
||||
|
||||
in {
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
sensor = [
|
||||
{ platform = "file";
|
||||
name = "day_of_week";
|
||||
file_path = filePath;
|
||||
value_template = "{{ value_json.dayOfWeek }}";
|
||||
}
|
||||
];
|
||||
|
||||
homeassistant = {
|
||||
whitelist_external_dirs = [ folderPath ];
|
||||
customize."sensor.day_of_week" = {
|
||||
icon = "mdi:calendar-today";
|
||||
friendly_name = "Wochen Tag";
|
||||
};
|
||||
};
|
||||
|
||||
group = {
|
||||
overview.entities = [
|
||||
"sensor.day_of_week"
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
systemd.services.dayOfWeek = {
|
||||
enable = true;
|
||||
before = [ "home-assistant.service" ];
|
||||
wantedBy = [ "home-assistant.service" ];
|
||||
serviceConfig = {
|
||||
User = "hass";
|
||||
Type = "oneshot";
|
||||
};
|
||||
description = "set day of wek for homeassistant";
|
||||
script = /* sh */ ''
|
||||
date +'{"dayOfWeek":"%A"}' >> ${filePath}
|
||||
'';
|
||||
};
|
||||
systemd.timers.dayOfWeek = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "00:01:00";
|
||||
Persistent = "true";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
93
configs/porani/home-assistant/holiday.nix
Normal file
93
configs/porani/home-assistant/holiday.nix
Normal file
|
@ -0,0 +1,93 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
|
||||
state = "NW"; # NRW
|
||||
# state = "BE"; # Berlin
|
||||
|
||||
name = "holiday";
|
||||
folderPath = config.services.home-assistant.configDir;
|
||||
filePath = "${folderPath}/${name}.json";
|
||||
|
||||
in {
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# todo : use the python tool
|
||||
sensor = [
|
||||
{ platform = "file";
|
||||
name = "${name}_date";
|
||||
file_path = filePath;
|
||||
value_template = "{{ value_json.date }}";
|
||||
}
|
||||
{ platform = "file";
|
||||
name = "${name}_name";
|
||||
file_path = filePath;
|
||||
value_template = "{{ value_json.name }}";
|
||||
}
|
||||
];
|
||||
|
||||
homeassistant = {
|
||||
whitelist_external_dirs = [ folderPath ];
|
||||
customize = {
|
||||
"sensor.${name}_date" = {
|
||||
icon = "mdi:calendar";
|
||||
friendly_name = "Nächster Feiertag";
|
||||
};
|
||||
"sensor.${name}_name" = {
|
||||
icon = "mdi:calendar";
|
||||
friendly_name = "Nächster Feiertag";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
group = {
|
||||
|
||||
holidays = {
|
||||
name = "Feiertage";
|
||||
view = false;
|
||||
control = "hidden";
|
||||
entities = [
|
||||
"sensor.${name}_date"
|
||||
"sensor.${name}_name"
|
||||
];
|
||||
};
|
||||
|
||||
view_overview.entities = [ "group.holidays" ];
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
systemd.services."${name}" = {
|
||||
enable = true;
|
||||
before = [ "home-assistant.service" ];
|
||||
wantedBy = [ "home-assistant.service" ];
|
||||
serviceConfig = {
|
||||
User = "hass";
|
||||
Type = "oneshot";
|
||||
};
|
||||
description = "set ${name} for homeassistant";
|
||||
script = /* sh */ ''
|
||||
${pkgs.curl}/bin/curl \
|
||||
-Ls "https://feiertage-api.de/api/?jahr=$( date +%Y )&nur_land=${state}" \
|
||||
| ${pkgs.jq}/bin/jq --compact-output '
|
||||
map_values( .datum ) |
|
||||
to_entries |
|
||||
map( { date: .value, name : .key } ) |
|
||||
sort_by( .date ) |
|
||||
map(select ( .date >= "'`date +%Y-%m-%d`'" )) |
|
||||
.[0]' \
|
||||
>> ${filePath}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers."${name}" = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = "true";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
85
configs/porani/home-assistant/kodi.nix
Normal file
85
configs/porani/home-assistant/kodi.nix
Normal file
|
@ -0,0 +1,85 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
group.view_overview.entities = [
|
||||
"media_player.kodi"
|
||||
];
|
||||
|
||||
media_player = [
|
||||
{
|
||||
platform = "kodi";
|
||||
host = "127.0.0.1";
|
||||
turn_on_action.service = "script.watch_tv";
|
||||
turn_off_action.service = "script.stop_watch_tv";
|
||||
}
|
||||
];
|
||||
|
||||
shell_command = {
|
||||
start_display = "sudo ${pkgs.systemd}/bin/systemctl start display-manager";
|
||||
stop_display = "sudo ${pkgs.systemd}/bin/systemctl stop display-manager";
|
||||
};
|
||||
|
||||
script = {
|
||||
|
||||
turn_all_off.sequence = [
|
||||
# todo : use the shell_command here
|
||||
{
|
||||
alias = "turn off tv";
|
||||
service = "switch.turn_off";
|
||||
data.entity_id = "group.tv";
|
||||
}
|
||||
{
|
||||
alias = "stop kodi";
|
||||
service = "shell_command.stop_display";
|
||||
}
|
||||
];
|
||||
|
||||
test_display.sequence = [
|
||||
{ service = "shell_command.start_display"; }
|
||||
{ delay.seconds = 20; }
|
||||
{ service = "shell_command.stop_display"; }
|
||||
];
|
||||
|
||||
watch_tv = {
|
||||
alias = "Watch TV";
|
||||
sequence = [
|
||||
{
|
||||
alias = "turn on tv";
|
||||
service = "switch.turn_on";
|
||||
data.entity_id = "group.tv";
|
||||
}
|
||||
{ delay.minutes = 1;}
|
||||
{
|
||||
alias = "start kodi";
|
||||
service = "shell_command.start_display";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
stop_watch_tv = {
|
||||
alias = "Stop TV";
|
||||
sequence = [
|
||||
{
|
||||
alias = "turn off tv";
|
||||
service = "switch.turn_off";
|
||||
data.entity_id = "group.tv";
|
||||
}
|
||||
{
|
||||
alias = "stop kodi";
|
||||
service = "shell_command.stop_display";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
group.tv.entities = [ "script.watch_tv" "script.stop_watch_tv" ];
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
'';
|
||||
}
|
43
configs/porani/home-assistant/mpd.nix
Normal file
43
configs/porani/home-assistant/mpd.nix
Normal file
|
@ -0,0 +1,43 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
group.view_overview.entities = [
|
||||
"media_player.mpd"
|
||||
];
|
||||
|
||||
media_player = [
|
||||
{
|
||||
platform = "mpd";
|
||||
host = "localhost";
|
||||
}
|
||||
];
|
||||
|
||||
script.turn_all_off.sequence = [
|
||||
{
|
||||
alias = "turn mpd off";
|
||||
service = "media_player.turn_off";
|
||||
data.entity_id = "media_player.mpd";
|
||||
}
|
||||
];
|
||||
|
||||
script.turn_all_on.sequence = [
|
||||
{
|
||||
alias = "turn mpd on";
|
||||
service = "media_player.turn_on";
|
||||
data.entity_id = "media_player.mpd";
|
||||
}
|
||||
{
|
||||
alias = "Adjust volume";
|
||||
service = "media_player.volume_set";
|
||||
data = {
|
||||
entity_id = "media_player.mpd";
|
||||
volume_level = "0.90";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
}
|
27
configs/porani/home-assistant/mqtt.nix
Normal file
27
configs/porani/home-assistant/mqtt.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
services.homeAssistantConfig.mqtt = {
|
||||
# discovery = false;
|
||||
|
||||
# for mosquitto
|
||||
broker = "127.0.0.1";
|
||||
username = fileContents <secrets/home-assistant/mqtt-user>;
|
||||
password = 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 #" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
118
configs/porani/home-assistant/sonoff.nix
Normal file
118
configs/porani/home-assistant/sonoff.nix
Normal file
|
@ -0,0 +1,118 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
unstablePkgs = import <nixpkgs-unstable> {};
|
||||
in {
|
||||
|
||||
services.homeAssistantConfig =
|
||||
let
|
||||
|
||||
sonoffSwitches = {
|
||||
"pal01" = { label = "Bett"; icon = "mdi:lightbulb-on"; };
|
||||
"pal02" = { label = "Lampe"; icon = "mdi:lightbulb-on"; };
|
||||
"pal03" = { label = "Couche"; icon = "mdi:lightbulb-on"; };
|
||||
"pal06" = { label = "Küche"; icon = "mdi:lightbulb-on"; };
|
||||
"pal05" = { label = "TV"; icon = "mdi:television"; };
|
||||
|
||||
"pal04" = { label = "Nummer 4"; icon = "mdi:power-plug-off"; };
|
||||
"pal07" = { label = "Nummer 7"; icon = "mdi:power-plug-off"; };
|
||||
"pal08" = { label = "Nummer 8"; icon = "mdi:power-plug-off"; };
|
||||
};
|
||||
|
||||
toSwitch = name: "switch.${name}";
|
||||
|
||||
in {
|
||||
|
||||
homeassistant = {
|
||||
customize = lib.mapAttrs' (
|
||||
entity: value:
|
||||
{
|
||||
name = toSwitch entity;
|
||||
value = {
|
||||
friendly_name = value.label;
|
||||
icon = value.icon;
|
||||
};
|
||||
}
|
||||
) sonoffSwitches;
|
||||
};
|
||||
|
||||
script.turn_all_off.sequence = [
|
||||
{
|
||||
alias = "turn off sonoff";
|
||||
service = "switch.turn_off";
|
||||
data.entity_id = "group.all_lights";
|
||||
}
|
||||
{
|
||||
alias = "turn off sonoff";
|
||||
service = "switch.turn_off";
|
||||
data.entity_id = "group.tv";
|
||||
}
|
||||
];
|
||||
|
||||
script.turn_all_on.sequence = [
|
||||
{
|
||||
alias = "turn on all lights";
|
||||
service = "switch.turn_on";
|
||||
data.entity_id = "group.all_lights";
|
||||
}
|
||||
];
|
||||
|
||||
group = {
|
||||
bed_room = {
|
||||
entities = builtins.map toSwitch [ "pal01" ];
|
||||
};
|
||||
living_room = {
|
||||
entities = builtins.map toSwitch [ "pal03" "pal02" ];
|
||||
};
|
||||
tv = {
|
||||
entities = builtins.map toSwitch [ "pal05" ];
|
||||
};
|
||||
kitchen = {
|
||||
entities = builtins.map toSwitch [ "pal06" ];
|
||||
};
|
||||
unknown = {
|
||||
entities = builtins.map toSwitch [ "pal04" "pal07" "pal08" ];
|
||||
};
|
||||
all_lights = {
|
||||
entities = builtins.map toSwitch [ "pal01" "pal02" "pal03" "pal06" ];
|
||||
};
|
||||
};
|
||||
|
||||
switch =
|
||||
let
|
||||
sonoffConfigurations = builtins.map (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";
|
||||
}) (builtins.attrNames sonoffSwitches) ;
|
||||
in
|
||||
sonoffConfigurations;
|
||||
|
||||
# discover state on init
|
||||
automation = [
|
||||
{
|
||||
alias = "Sonoff initial Power state";
|
||||
trigger = {
|
||||
platform = "homeassistant";
|
||||
event = "start";
|
||||
};
|
||||
action = builtins.map ( name:
|
||||
{
|
||||
service = "mqtt.publish";
|
||||
data = {
|
||||
topic = "cmnd/${lib.toUpper name}/power";
|
||||
payload = "";
|
||||
};
|
||||
})
|
||||
(builtins.attrNames sonoffSwitches);
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
}
|
274
configs/porani/home-assistant/timer.nix
Normal file
274
configs/porani/home-assistant/timer.nix
Normal file
|
@ -0,0 +1,274 @@
|
|||
{ 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 = {
|
||||
view = false;
|
||||
name = "Arbeits Aufwachen";
|
||||
control = "hidden";
|
||||
entities = [
|
||||
"input_boolean.wakeup"
|
||||
"input_datetime.wakeup"
|
||||
"input_select.wakeup"
|
||||
];
|
||||
};
|
||||
|
||||
timer_leave = {
|
||||
view = false;
|
||||
name = "Leave Time";
|
||||
control = "hidden";
|
||||
entities = [
|
||||
"input_boolean.leave"
|
||||
"input_datetime.leave"
|
||||
];
|
||||
};
|
||||
|
||||
timer_return = {
|
||||
view = false;
|
||||
name = "Nach Hause kommen";
|
||||
control = "hidden";
|
||||
entities = [
|
||||
"input_boolean.return"
|
||||
"input_datetime.return"
|
||||
];
|
||||
};
|
||||
|
||||
timer_sleep = {
|
||||
view = false;
|
||||
name = "Einschlafen";
|
||||
control = "hidden";
|
||||
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"
|
||||
];
|
||||
|
||||
view_overview.entities = [
|
||||
"group.timer_wakeup"
|
||||
"group.timer_leave"
|
||||
"group.timer_return"
|
||||
"group.timer_sleep"
|
||||
];
|
||||
};
|
||||
|
||||
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";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
];
|
||||
};
|
||||
|
||||
}
|
304
configs/porani/home-assistant/zigbee2mqtt.nix
Normal file
304
configs/porani/home-assistant/zigbee2mqtt.nix
Normal file
|
@ -0,0 +1,304 @@
|
|||
{ pkgs, lib, config , ... }:
|
||||
let
|
||||
|
||||
# allow new devices to join
|
||||
enablePairing = true;
|
||||
|
||||
device = "/dev/ttyACM0";
|
||||
dataFolder = "/srv/zigbee/data";
|
||||
|
||||
sensors = {
|
||||
buttons = {
|
||||
"button_1".id = "0x00158d0002b04f65";
|
||||
"button_2".id = "0x00158d0002b04f09";
|
||||
"button_3".id = "0x00158d0002b00e04";
|
||||
};
|
||||
temperature = {
|
||||
"temperature_sensor_1".id = "0x00158d0002d79220";
|
||||
"temperature_sensor_2".id = "0x00158d0002d7913d";
|
||||
};
|
||||
motion = {
|
||||
"motion_sensor_1".id = "0x00158d0002fbd451";
|
||||
};
|
||||
};
|
||||
|
||||
# todo : rename with allSensors
|
||||
allSensors = with sensors; buttons // temperature // motion;
|
||||
|
||||
zigBee2MqttConfig = {
|
||||
|
||||
# Home Assistant integration (MQTT discovery)
|
||||
homeassistant = false;
|
||||
# homeassistant = true;
|
||||
|
||||
# allow new devices to join
|
||||
permit_join = enablePairing;
|
||||
|
||||
# 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";
|
||||
# Optional: disable LED of CC2531 USB sniffer
|
||||
disable_led = true;
|
||||
};
|
||||
|
||||
devices = lib.mapAttrs' (
|
||||
name: { id , ... }:
|
||||
{
|
||||
name = id;
|
||||
value = {
|
||||
retain = false;
|
||||
friendly_name = name;
|
||||
};
|
||||
}
|
||||
) allSensors;
|
||||
};
|
||||
|
||||
configurationYaml = pkgs.writeText "configuration.yml" (builtins.toJSON zigBee2MqttConfig);
|
||||
in
|
||||
{
|
||||
imports = [ ./mqtt.nix ];
|
||||
|
||||
services.homeAssistantConfig = {
|
||||
|
||||
# group.unknown.entities = [ "sensor.button_1" ];
|
||||
|
||||
sensor = let
|
||||
buttons = with 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 }}";
|
||||
}
|
||||
) sensors.buttons;
|
||||
|
||||
|
||||
temperature = with 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 }}";
|
||||
}
|
||||
]
|
||||
) sensors.temperature;
|
||||
|
||||
informations = lib.mapAttrsToList (
|
||||
name: {...}:
|
||||
[
|
||||
{
|
||||
platform = "mqtt";
|
||||
name = "battery_${name}";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "%";
|
||||
device_class = "battery";
|
||||
value_template = "{{ value_json.battery }}";
|
||||
}
|
||||
{
|
||||
name = "link_${name}";
|
||||
platform = "mqtt";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
unit_of_measurement = "-";
|
||||
value_template = "{{ value_json.linkquality }}";
|
||||
}
|
||||
]
|
||||
) allSensors;
|
||||
|
||||
in
|
||||
lib.flatten ( buttons ++ temperature ++ informations );
|
||||
|
||||
binary_sensor = let
|
||||
|
||||
motion = lib.mapAttrsToList (
|
||||
name: { ... }:
|
||||
{
|
||||
name = name;
|
||||
platform = "mqtt";
|
||||
device_class = "motion";
|
||||
#icon = "mdi:motion-sensor";
|
||||
state_topic = "zigbee2mqtt/${name}";
|
||||
availability_topic = "zigbee2mqtt/bridge/state";
|
||||
payload_on = true;
|
||||
payload_off = false;
|
||||
value_template = "{{ value_json.occupancy }}";
|
||||
}
|
||||
) sensors.motion;
|
||||
in
|
||||
lib.flatten ( motion );
|
||||
|
||||
|
||||
|
||||
group = let
|
||||
|
||||
information = name: [ "sensor.battery_${name}" "sensor.link_${name}" ];
|
||||
|
||||
sensor = lib.mapAttrs' (
|
||||
name: {...}:
|
||||
{
|
||||
name = name;
|
||||
value = {
|
||||
control = "hidden";
|
||||
entities = ["sensor.${name}"] ++ (information name);
|
||||
};
|
||||
}
|
||||
) (sensors.buttons);
|
||||
|
||||
sensorTemperature = lib.mapAttrs' (
|
||||
name: { ... }:
|
||||
{
|
||||
name = name;
|
||||
value = {
|
||||
control = "hidden";
|
||||
entities = [
|
||||
"sensor.${name}"
|
||||
"sensor.humidity_${name}"
|
||||
"sensor.pressure_${name}"
|
||||
] ++ (information name);
|
||||
};
|
||||
}
|
||||
) (sensors.temperature);
|
||||
|
||||
binarySensor = lib.mapAttrs' (
|
||||
name: { ... }:
|
||||
{
|
||||
name = name;
|
||||
value = {
|
||||
control = "hidden";
|
||||
entities = [ "binary_sensor.${name}" ] ++ (information name);
|
||||
};
|
||||
}
|
||||
) (sensors.motion);
|
||||
|
||||
views = {
|
||||
view_sensors = {
|
||||
name = "Sensoren";
|
||||
control = "hidden";
|
||||
view = true;
|
||||
entities = lib.mapAttrsToList (name: { ... }: "group.${name}") allSensors;
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
views // sensor // binarySensor // sensorTemperature ;
|
||||
|
||||
automation =
|
||||
let
|
||||
lights = map (button:
|
||||
{
|
||||
alias = "Toggle all lights, on click";
|
||||
trigger = {
|
||||
platform = "mqtt";
|
||||
topic = "zigbee2mqtt/${button}";
|
||||
};
|
||||
condition = {
|
||||
condition = "template";
|
||||
value_template = ''{{ "single" == trigger.payload_json.click }}'';
|
||||
};
|
||||
action = {
|
||||
service = "switch.toggle";
|
||||
entity_id = "group.all_lights";
|
||||
};
|
||||
}) ["button_1" "button_2" "button_3"];
|
||||
mpd = map (button:
|
||||
{
|
||||
alias = "Toggle mpd, on double click";
|
||||
trigger = {
|
||||
platform = "mqtt";
|
||||
topic = "zigbee2mqtt/${button}";
|
||||
};
|
||||
condition = {
|
||||
condition = "template";
|
||||
value_template = ''{{ "double" == trigger.payload_json.click }}'';
|
||||
};
|
||||
action = {
|
||||
service = "media_player.toggle";
|
||||
# todo use a group here
|
||||
entity_id = "media_player.mpd";
|
||||
};
|
||||
}) ["button_1" "button_2" "button_3"];
|
||||
in
|
||||
lights ++ mpd;
|
||||
|
||||
# click = double => music an aus
|
||||
|
||||
# click = hold => film an aus
|
||||
|
||||
};
|
||||
|
||||
virtualisation.docker.enable = true;
|
||||
|
||||
# todo : einen eigenen container bauen mit dockerTool : https://nixos.wiki/wiki/Docker
|
||||
|
||||
systemd.services."zigbee2mqtt" = {
|
||||
enable = true;
|
||||
description = "Allows you to use your Zigbee devices without the vendors bridge/gateway.";
|
||||
after = [ "docker.service" ];
|
||||
requires = [ "docker.service" ];
|
||||
# todo : udev rule erstellen, die diesen service erst startet, dieses wanted by ist labil
|
||||
wantedBy = [ "home-assistant.service" ];
|
||||
|
||||
preStart = ''
|
||||
if [ -f ${dataFolder}/configuration.yaml ]
|
||||
then
|
||||
rm ${dataFolder}/configuration.yaml
|
||||
fi
|
||||
mkdir -p ${dataFolder}
|
||||
cat ${configurationYaml} | ${pkgs.yq}/bin/yq --yaml-output '.' > ${dataFolder}/configuration.yaml
|
||||
'';
|
||||
|
||||
restartTriggers = [ configurationYaml ];
|
||||
|
||||
script = ''
|
||||
# delete old instance to ensure update
|
||||
${pkgs.docker}/bin/docker stop zigbee2mqtt || true && ${pkgs.docker}/bin/docker rm -f zigbee2mqtt || true
|
||||
# start instance
|
||||
${pkgs.docker}/bin/docker run \
|
||||
--network="host" \
|
||||
--name zigbee2mqtt \
|
||||
-v ${dataFolder}:/app/data \
|
||||
--device=${device} \
|
||||
koenkk/zigbee2mqtt
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
}
|
30
configs/porani/kodi.nix
Normal file
30
configs/porani/kodi.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
autorun = false;
|
||||
desktopManager = {
|
||||
kodi.enable = true;
|
||||
default = "kodi";
|
||||
xterm.enable = false;
|
||||
};
|
||||
displayManager.lightdm = {
|
||||
enable = true;
|
||||
autoLogin.enable = true;
|
||||
autoLogin.user = config.users.users.kodi.name;
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
# mutableUsers = true;
|
||||
users.kodi= {
|
||||
isNormalUser = true;
|
||||
name = "kodi";
|
||||
uid = 1338;
|
||||
initialPassword = lib.fileContents <secrets/kodi/password>;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
12
configs/porani/mpd.nix
Normal file
12
configs/porani/mpd.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
|
||||
sound.enable = true;
|
||||
|
||||
services.mpd = {
|
||||
enable = true;
|
||||
network.listenAddress = "any";
|
||||
musicDirectory = "/media/music-library";
|
||||
};
|
||||
|
||||
}
|
7
configs/porani/packages.nix
Normal file
7
configs/porani/packages.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
|
||||
environment.systemPackages = [
|
||||
];
|
||||
|
||||
}
|
38
configs/porani/syncthing.nix
Normal file
38
configs/porani/syncthing.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
test.services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = true;
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
movies.path = "/media/movies";
|
||||
music-library.path = "/media/music-library";
|
||||
podcasts.path = "/media/podcasts";
|
||||
series.path = "/media/series";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."permown._media" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
system.permown."/media" = {
|
||||
owner = "syncthing";
|
||||
group = "syncthing";
|
||||
umask = "0007";
|
||||
};
|
||||
systemd.services."syncthing" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
|
||||
users.groups."syncthing".members = [ "mpd" "syncthing" "kodi" "palo" ];
|
||||
|
||||
|
||||
|
||||
}
|
12
configs/porani/tinc.nix
Normal file
12
configs/porani/tinc.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
67
configs/porani/wifi-access-point.nix
Normal file
67
configs/porani/wifi-access-point.nix
Normal file
|
@ -0,0 +1,67 @@
|
|||
{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
configs/porani/wifi-networking.nix
Normal file
4
configs/porani/wifi-networking.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
|
||||
}
|
41
configs/sputnik/configuration.nix
Normal file
41
configs/sputnik/configuration.nix
Normal file
|
@ -0,0 +1,41 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
|
||||
<system/proxy>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./nginx.nix
|
||||
./tinc.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
|
||||
'';
|
||||
|
||||
}
|
||||
|
||||
|
23
configs/sputnik/hardware-configuration.nix
Normal file
23
configs/sputnik/hardware-configuration.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
# 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;
|
||||
}
|
146
configs/sputnik/nginx.nix
Normal file
146
configs/sputnik/nginx.nix
Normal file
|
@ -0,0 +1,146 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
|
||||
"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;
|
||||
locations."/" = {
|
||||
proxyPass = "http://workhorse.private:3000";
|
||||
};
|
||||
};
|
||||
|
||||
"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;
|
||||
locations."/" = {
|
||||
proxyPass = "http://workhorse.private:8000";
|
||||
};
|
||||
};
|
||||
|
||||
#"landing.ingolf-wagner.de" = {
|
||||
# default = true;
|
||||
# listen = [
|
||||
# { addr = "0.0.0.0"; port = 4443; ssl = true; }
|
||||
# { addr = "0.0.0.0"; port = 80; ssl = false; }
|
||||
# ];
|
||||
# forceSSL = true;
|
||||
# enableACME = true;
|
||||
# locations."/" = {
|
||||
# root = "/srv/www/ingolf-wagner.de";
|
||||
# };
|
||||
#};
|
||||
|
||||
"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;
|
||||
locations."/" = {
|
||||
root = "/srv/www/tech";
|
||||
extraConfig = ''
|
||||
if (-d $request_filename) {
|
||||
rewrite [^/]$ $scheme://$http_host$uri/ permanent;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
"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;
|
||||
locations."/" = {
|
||||
root = "/srv/www/terranix";
|
||||
extraConfig = ''
|
||||
if (-d $request_filename) {
|
||||
rewrite [^/]$ $scheme://$http_host$uri/ permanent;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
"seafile.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;
|
||||
locations."/" = {
|
||||
proxyPass = "http://workhorse.private:3030";
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
|
||||
sub_filter "http://seafile.gaykraft.com" "https://seafile.gaykraft.com";
|
||||
|
||||
# used for view/edit office file via Office Online Server
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
"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;
|
||||
locations."/" = {
|
||||
root = "/srv/www/gaykraft";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
services.sslh = {
|
||||
enable = true;
|
||||
listenAddress = "0.0.0.0";
|
||||
port = 443;
|
||||
verbose = false;
|
||||
transparent = true;
|
||||
appendConfig = /* json */ ''
|
||||
protocols:
|
||||
(
|
||||
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "2222"; probe: "builtin"; },
|
||||
{ name: "ssl"; host: "localhost"; port: "4443"; probe: "builtin"; },
|
||||
{ name: "tinc"; host: "localhost"; port: "655"; probe: "builtin"; }
|
||||
);
|
||||
'';
|
||||
};
|
||||
|
||||
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
|
||||
'';
|
||||
#serviceConfig.User = "sslh";
|
||||
};
|
||||
|
||||
}
|
10
configs/sputnik/tinc.nix
Normal file
10
configs/sputnik/tinc.nix
Normal file
|
@ -0,0 +1,10 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
65
configs/sterni/configuration.nix
Normal file
65
configs/sterni/configuration.nix
Normal file
|
@ -0,0 +1,65 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
|
||||
imports = [
|
||||
|
||||
<system/desktop>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./encfs.nix
|
||||
./packages.nix
|
||||
./syncthing.nix
|
||||
./tinc.nix
|
||||
|
||||
#./wifi-access-point.nix
|
||||
|
||||
];
|
||||
|
||||
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 = true;
|
||||
services.kbfs.enable = true;
|
||||
|
||||
programs.custom.steam.enable = false;
|
||||
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;
|
||||
};
|
||||
|
||||
custom.samba-share.folders = {
|
||||
enable = false;
|
||||
public = "/home/palo/movies";
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
8
configs/sterni/encfs.nix
Normal file
8
configs/sterni/encfs.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
module.backup.services.encfs = {
|
||||
"fotos".enable = true;
|
||||
"desktop".enable = true;
|
||||
"finance".enable = true;
|
||||
};
|
||||
}
|
92
configs/sterni/hardware-configuration.nix
Normal file
92
configs/sterni/hardware-configuration.nix
Normal file
|
@ -0,0 +1,92 @@
|
|||
# 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.
|
||||
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;
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = [
|
||||
{
|
||||
name = "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";
|
||||
};
|
||||
|
||||
|
||||
}
|
8
configs/sterni/packages.nix
Normal file
8
configs/sterni/packages.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
environment.systemPackages = with pkgs ; [
|
||||
bitwig-studio
|
||||
];
|
||||
|
||||
}
|
27
configs/sterni/syncthing.nix
Normal file
27
configs/sterni/syncthing.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
test.services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = false;
|
||||
user = "palo";
|
||||
dataDir = "/home/palo/.syncthing";
|
||||
configDir = "/home/palo/.syncthing";
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
|
||||
book.path = "/home/palo/books";
|
||||
desktop-encrypted.path = "/home/palo/.desktop.ct";
|
||||
finance-encrypted.path = "/home/palo/.finance.ct";
|
||||
fotos-encrypted.path = "/home/palo/private/.fotos.ct";
|
||||
music-library.path = "/home/palo/music-library";
|
||||
music-projects.path = "/home/palo/music-projects";
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
18
configs/sterni/tinc.nix
Normal file
18
configs/sterni/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;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
77
configs/sterni/wifi-access-point.nix
Normal file
77
configs/sterni/wifi-access-point.nix
Normal file
|
@ -0,0 +1,77 @@
|
|||
{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}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
56
configs/workhorse/bepasty.nix
Normal file
56
configs/workhorse/bepasty.nix
Normal file
|
@ -0,0 +1,56 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
port = 8000;
|
||||
in {
|
||||
|
||||
# configure nginx
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"paste.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://paste.workhorse.private/;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
krops.userKeys."bepasty" = {
|
||||
user = "bepasty";
|
||||
source = toString <secrets/bepasty-secret-key>;
|
||||
requiredBy = [ "bepasty-server-ingolf-wagner.de-gunicorn.service" ];
|
||||
};
|
||||
|
||||
services.bepasty = {
|
||||
enable = true;
|
||||
servers."ingolf-wagner.de" = {
|
||||
bind = "0.0.0.0:${toString port}";
|
||||
secretKeyFile = config.krops.userKeys."bepasty".target;
|
||||
extraConfig = ''
|
||||
PERMISSIONS = {
|
||||
'${lib.fileContents <common_secrets/bepasty/admin-password>}': 'admin,list,create,read,delete',
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
/* fix bepasty service */
|
||||
nixpkgs.overlays = let
|
||||
overlay = self: super:
|
||||
{
|
||||
bepasty = super.bepasty.override { python3Packages = pkgs.python27Packages; };
|
||||
};
|
||||
in
|
||||
[ overlay ];
|
||||
|
||||
}
|
25
configs/workhorse/castget.nix
Normal file
25
configs/workhorse/castget.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{ 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";
|
||||
};
|
||||
LORA_radio = {
|
||||
url = "https://www.freie-radios.net/portal/podcast.php?radio=19&rss";
|
||||
spool = "${home}/lora_radio";
|
||||
};
|
||||
gegenstandpunkt = {
|
||||
url = "https://pc.argudiss.de/";
|
||||
spool = "${home}/GegenStandpunkt";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
80
configs/workhorse/configuration.nix
Normal file
80
configs/workhorse/configuration.nix
Normal file
|
@ -0,0 +1,80 @@
|
|||
{ lib, config, pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
|
||||
<system/server>
|
||||
./hardware-configuration.nix
|
||||
|
||||
./bepasty.nix
|
||||
./castget.nix
|
||||
./gogs.nix
|
||||
./grafana.nix
|
||||
./graylog.nix
|
||||
./jenkins.nix
|
||||
./kibana.nix
|
||||
./lektor-gaykraft.nix
|
||||
./lektor-techblog.nix
|
||||
./lektor-terranix.nix
|
||||
./mail-fetcher.nix
|
||||
./packages.nix
|
||||
./prometheus.nix
|
||||
./restic.nix
|
||||
./seafile.nix
|
||||
./syncthing.nix
|
||||
./taskserver.nix
|
||||
./tinc.nix
|
||||
./transmission.nix
|
||||
./weechat.nix
|
||||
./wetten.nix
|
||||
|
||||
];
|
||||
|
||||
networking.hostName = "workhorse";
|
||||
|
||||
# enable initrd ssh
|
||||
configuration.init-ssh = {
|
||||
enable = "enabled";
|
||||
kernelModules = [ "r8169" ];
|
||||
authorizedKeys = config.users.users.root.openssh.authorizedKeys.keyFiles;
|
||||
hostECDSAKey = <secrets/init-ssh/host_ecdsa_key>;
|
||||
};
|
||||
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
configuration.fireqos = {
|
||||
enable = true;
|
||||
interface = "eth0";
|
||||
input = 30000;
|
||||
output = 2000;
|
||||
balance = false;
|
||||
};
|
||||
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount}/bin/pumount";
|
||||
};
|
||||
|
||||
services.logind.lidSwitch = lib.mkForce "ignore";
|
||||
system.custom.x11.enable = lib.mkForce false;
|
||||
programs.custom.steam.enable = false;
|
||||
programs.custom.video.enable = false;
|
||||
|
||||
# font
|
||||
# ----
|
||||
programs.custom.urxvt.fontSize = 17;
|
||||
programs.custom.xterm.fontSize = 17;
|
||||
system.custom.fonts.dpi = 140;
|
||||
|
||||
services.printing.enable = true;
|
||||
nix.useSandbox = true;
|
||||
|
||||
virtualisation = {
|
||||
docker.enable = true;
|
||||
virtualbox = {
|
||||
host.enable = true;
|
||||
guest.x11 = true;
|
||||
guest.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
8
configs/workhorse/encfs.nix
Normal file
8
configs/workhorse/encfs.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
module.backup.services.encfs = {
|
||||
"fotos".enable = true;
|
||||
"desktop".enable = true;
|
||||
"finance".enable = true;
|
||||
};
|
||||
}
|
39
configs/workhorse/gogs.nix
Normal file
39
configs/workhorse/gogs.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"gogs.${config.networking.hostName}.private" = {
|
||||
serverAliases = ["git.${config.networking.hostName}.private"];
|
||||
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
|
||||
'';
|
||||
};
|
||||
|
||||
backup.all.restic.dirs = [ config.services.gogs.repositoryRoot ];
|
||||
|
||||
}
|
38
configs/workhorse/grafana.nix
Normal file
38
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";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
100
configs/workhorse/graylog.nix
Normal file
100
configs/workhorse/graylog.nix
Normal file
|
@ -0,0 +1,100 @@
|
|||
{ 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.elasticsearch.enable = true;
|
||||
services.mongodb.enable = 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>;
|
||||
|
||||
environment.etc."graylog/server/GeoLite2-City.mmdb" = {
|
||||
enable = true;
|
||||
source = "${pkgs.geodatabase}/GeoLite2-City.mmdb";
|
||||
};
|
||||
|
||||
# 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
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
98
configs/workhorse/hardware-configuration.nix
Normal file
98
configs/workhorse/hardware-configuration.nix
Normal file
|
@ -0,0 +1,98 @@
|
|||
{ 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 = [
|
||||
{
|
||||
name = "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/docker" = {
|
||||
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";
|
||||
};
|
||||
};
|
||||
|
||||
# automount
|
||||
# ---------
|
||||
fileSystems."/media" = {
|
||||
device = "/dev/disk/by-uuid/f7fa1c0e-ac9f-4955-b4bd-644c1ddb0d89";
|
||||
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/f7fa1c0e-ac9f-4955-b4bd-644c1ddb0d89";
|
||||
where = "/media";
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
|
239
configs/workhorse/jenkins.nix
Normal file
239
configs/workhorse/jenkins.nix
Normal file
|
@ -0,0 +1,239 @@
|
|||
{ 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
|
||||
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 "deploy-gaykraft"
|
||||
{ url = "ssh://gogs@workhorse.private:2222/palo/gaykraft.git";
|
||||
credentialsId = gogs-id; }
|
||||
[
|
||||
{ "build" = [
|
||||
"nix-shell --run build"
|
||||
];
|
||||
}
|
||||
{ "publish" = [
|
||||
{
|
||||
script = "nix-shell --run publish";
|
||||
credentialsId = sshSputnik;
|
||||
}
|
||||
];
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
(job "deploy-techblock"
|
||||
{ url = "ssh://gogs@workhorse.private:2222/palo/tech.ingolf-wagner.de.git";
|
||||
credentialsId = gogs-id; }
|
||||
[
|
||||
{ "build" = ["nix-shell --run build"];}
|
||||
{ "publish" = [
|
||||
{
|
||||
script = "nix-shell --run publish";
|
||||
credentialsId = sshSputnik;
|
||||
}
|
||||
];}
|
||||
])
|
||||
|
||||
(job "deploy-terranix"
|
||||
{ url = "ssh://gogs@workhorse.private:2222/terranix/terranix.org.git";
|
||||
credentialsId = gogs-id; }
|
||||
[
|
||||
{ "build" = ["nix-shell --run build"];}
|
||||
{ "publish" = [
|
||||
{
|
||||
script = "nix-shell --run publish";
|
||||
credentialsId = sshSputnik;
|
||||
}
|
||||
];}
|
||||
])
|
||||
|
||||
(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-terranix"
|
||||
{ url = "ssh://gogs@workhorse.private:2222/terranix/terranix.git";
|
||||
credentialsId = github-id;
|
||||
branch = "develop";}
|
||||
[
|
||||
{ "run Tests" = [
|
||||
''nix-shell tests/shell.nix --run "test-terranix"''
|
||||
];}
|
||||
])
|
||||
|
||||
(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 me
|
||||
# ----------
|
||||
(sync-to-github "sync-nixwriters"
|
||||
"https://cgit.krebsco.de/nix-writers/"
|
||||
"ssh://gogs@workhorse.private:2222/krebs/nix-writers.git")
|
||||
|
||||
(sync-to-github "sync-krops"
|
||||
"https://cgit.krebsco.de/krops/"
|
||||
"ssh://gogs@workhorse.private:2222/krebs/krops.git")
|
||||
|
||||
|
||||
# sync to github
|
||||
# --------------
|
||||
(sync-to-github "sync-radiodj"
|
||||
"ssh://gogs@workhorse.private:2222/crashburn_radio/radio_dj.git"
|
||||
"git@github.com:crashburn-radio/radio-dj.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-terranix"
|
||||
"ssh://gogs@workhorse.private:2222/terranix/terranix.git"
|
||||
"git@github.com:mrVanDalo/terranix.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-generator.git"
|
||||
"git@github.com:mrVanDalo/image-generator.git")
|
||||
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
}
|
24
configs/workhorse/kibana.nix
Normal file
24
configs/workhorse/kibana.nix
Normal file
|
@ -0,0 +1,24 @@
|
|||
{ 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;
|
||||
|
||||
}
|
54
configs/workhorse/lektor-gaykraft.nix
Normal file
54
configs/workhorse/lektor-gaykraft.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
|
||||
containerName = "gaykraft";
|
||||
port = 5001;
|
||||
repository = "ssh://gogs@git.ingolf-wagner.de:443/palo/gaykraft.git";
|
||||
sshKey = toString <secrets/lektor/gaykraft>;
|
||||
|
||||
in {
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"${containerName}.${config.networking.hostName}.private" = {
|
||||
serverAliases = [];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${toString port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
containers.${containerName} = {
|
||||
|
||||
bindMounts = {
|
||||
"/var/src" = {
|
||||
hostPath = toString "/var/src/";
|
||||
isReadOnly = true;
|
||||
};
|
||||
};
|
||||
|
||||
autoStart = true;
|
||||
config =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [ <system/all> ];
|
||||
services.lektor = {
|
||||
enable = true;
|
||||
host = "git.ingolf-wagner.de";
|
||||
sshKey = sshKey;
|
||||
repository = repository;
|
||||
port = port;
|
||||
additionalScript = pkgs.writeScript "build" "${pkgs.nix}/bin/nix-shell --run build";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
# it might take some time will this thing is up
|
||||
systemd.services."container@${containerName}".serviceConfig.TimeoutStartSec = lib.mkForce "infinity";
|
||||
|
||||
}
|
54
configs/workhorse/lektor-techblog.nix
Normal file
54
configs/workhorse/lektor-techblog.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
|
||||
containerName = "techblog";
|
||||
port = 5002;
|
||||
repository = "ssh://gogs@git.ingolf-wagner.de:443/palo/tech.ingolf-wagner.de.git";
|
||||
sshKey = toString <secrets/lektor/techblog>;
|
||||
|
||||
in {
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"${containerName}.${config.networking.hostName}.private" = {
|
||||
serverAliases = [];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${toString port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
containers.${containerName} = {
|
||||
|
||||
bindMounts = {
|
||||
"/var/src" = {
|
||||
hostPath = toString "/var/src/";
|
||||
isReadOnly = true;
|
||||
};
|
||||
};
|
||||
|
||||
autoStart = true;
|
||||
config =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [ <system/all> ];
|
||||
services.lektor = {
|
||||
enable = true;
|
||||
host = "git.ingolf-wagner.de";
|
||||
sshKey = sshKey;
|
||||
repository = repository;
|
||||
port = port;
|
||||
additionalScript = pkgs.writeScript "build" "${pkgs.nix}/bin/nix-shell --run build";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
# it might take some time will this thing is up
|
||||
systemd.services."container@${containerName}".serviceConfig.TimeoutStartSec = lib.mkForce "infinity";
|
||||
|
||||
}
|
54
configs/workhorse/lektor-terranix.nix
Normal file
54
configs/workhorse/lektor-terranix.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
|
||||
containerName = "terranix";
|
||||
port = 5003;
|
||||
repository = "ssh://gogs@git.ingolf-wagner.de:443/terranix/terranix.org.git";
|
||||
sshKey = toString <secrets/lektor/terranix>;
|
||||
|
||||
in {
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"${containerName}.${config.networking.hostName}.private" = {
|
||||
serverAliases = [];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${toString port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
containers.${containerName} = {
|
||||
|
||||
bindMounts = {
|
||||
"/var/src" = {
|
||||
hostPath = toString "/var/src/";
|
||||
isReadOnly = true;
|
||||
};
|
||||
};
|
||||
|
||||
autoStart = true;
|
||||
config =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [ <system/all> ];
|
||||
services.lektor = {
|
||||
enable = true;
|
||||
host = "git.ingolf-wagner.de";
|
||||
sshKey = sshKey;
|
||||
repository = repository;
|
||||
port = port;
|
||||
additionalScript = pkgs.writeScript "build" "${pkgs.nix}/bin/nix-shell --run build";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
# it might take some time will this thing is up
|
||||
systemd.services."container@${containerName}".serviceConfig.TimeoutStartSec = lib.mkForce "infinity";
|
||||
|
||||
}
|
292
configs/workhorse/mail-fetcher.nix
Normal file
292
configs/workhorse/mail-fetcher.nix
Normal file
|
@ -0,0 +1,292 @@
|
|||
# fetches mails for me
|
||||
{ lib, pkgs, config, ... }:
|
||||
{
|
||||
users.users.mailUser = {
|
||||
isNormalUser = true;
|
||||
description = "collects mails for me";
|
||||
hashedPassword = "!";
|
||||
name = "mailfetcher";
|
||||
openssh.authorizedKeys.keyFiles = config.users.users.root.openssh.authorizedKeys.keyFiles;
|
||||
};
|
||||
|
||||
|
||||
# configure passwords
|
||||
krops.userKeys = {
|
||||
"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"];
|
||||
};
|
||||
};
|
||||
|
||||
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";
|
||||
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";
|
||||
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";
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
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";
|
||||
port = 993;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
ingolf-wagner = {
|
||||
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 = 143;
|
||||
tls.useStartTls = true;
|
||||
};
|
||||
mbsync = {
|
||||
enable = true;
|
||||
create = "both";
|
||||
};
|
||||
notmuch.enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# configure mbsync
|
||||
home-manager.users.mailUser.programs.mbsync.enable = true;
|
||||
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 \
|
||||
--verbose \
|
||||
--all
|
||||
echo "run notmuch"
|
||||
${pkgs.notmuch}/bin/notmuch new
|
||||
echo "run afew"
|
||||
${pkgs.afew}/bin/afew --new --tag -v
|
||||
'';
|
||||
};
|
||||
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";
|
||||
};
|
||||
|
||||
# a few config
|
||||
home-manager.users.mailUser.programs.afew = {
|
||||
enable = true;
|
||||
extraConfig = with lib; let
|
||||
|
||||
template = index: { tags, query, message ? "generic", ... }: ''
|
||||
[Filter.${toString index}]
|
||||
query = ${query}
|
||||
tags = ${concatStringsSep ";" tags}
|
||||
message = ${message}
|
||||
'';
|
||||
|
||||
filters = [
|
||||
|
||||
{query = "from:no-reply@backtrace.io"; tags = ["+sononym" "-inbox" "-unread"];}
|
||||
{query = "from:linkedin.com"; tags = [ "+linked" "+jobs" "-inbox" ];}
|
||||
{query = "from:computerfutures.com OR from:computerfutures.de"; tags = [ "+jobs" "-inbox" ];}
|
||||
{query = "from:xing.com"; tags = [ "+jobs" "-inbox" ];}
|
||||
{query = "from:ebay.com OR from:ebay.de OR from:ebay.net"; tags = [ "+ebay" "+shop" "+billing"];}
|
||||
{query = "from:seek.com.au"; tags = [ "+jobs" "-inbox" ];}
|
||||
{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:circleci.com OR (from:noreply@github.com AND to:audio-overlay@googlegroups.com)"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:getdigital.de"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:digitalo.de"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:puppet.com"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:mixcloudmail.com AND subject:Weekly Update"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:facebook.com OR from:facebookmail.com"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:getpocket.com"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:oknotify2.com"; tags = [ "+okcupid" ];}
|
||||
{query = "from:oknotify2.com AND NOT subject:New message"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:paulaschoice.com"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:samplemagic.com OR from:wavealchemy.co.uk OR from:creators.gumroad.com"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:immobilienscout24.de"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:magix.net"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:booking.com"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:hackster.io"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:trade4less.de"; tags = [ "-inbox" "-unread" "+junk" ];}
|
||||
{query = "from:taxback.de OR to:taxback.de"; tags = ["+steuer"] ;}
|
||||
{query = "from:campact.de"; tags = ["+campact" "+politics"] ;}
|
||||
{query = "from:menospese.com"; tags = ["+junk" "-unread" "-inbox"] ;}
|
||||
{query = "from:aliexpress.com"; tags = ["+shop" "+aliexpress"] ;}
|
||||
{query = "from:congstar.de"; tags = ["+billing" "+congstar" "-inbox" "-unread"] ;}
|
||||
{query = "from:congstarnews.de"; tags = ["+congstar" "-inbox" "-unread" "+junk"] ;}
|
||||
{query = "from:fitnessfirst.de"; tags = ["-inbox" "-unread" "+junk"] ;}
|
||||
{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:drive-now.com"; tags = ["+billing" "+drivenow" "-inbox" "-unread"] ;}
|
||||
{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:ghostinspector.com"; tags = ["-unread" "-inbox" "+junk"] ;}
|
||||
{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 = "tag:lists AND from:nixos1@discoursemail.com"; tags = ["+nixos" "+discourse"] ;}
|
||||
{query = "from:limebike.com AND (subject:Funds OR subject:Receipt)" ; tags = ["-inbox" "-unread" "+billing" "+limebike"] ;}
|
||||
{query = "from:hetzner.com OR from:hetzner.de" ; tags = ["+hetzner"] ;}
|
||||
{query = "from:freemusicarchive.org" ; tags = ["+FMA"] ;}
|
||||
{query = "from:namecheap.com" ; tags = ["+namecheap" "+billing"] ;}
|
||||
{query = "from:nintendo.com" ; tags = ["+nintendo" "+billing"] ;}
|
||||
{query = "from:oculus.com AND subject:receipt" ; tags = ["+oculus" "+billing"] ;}
|
||||
{query = "from:vstbuzz.com" ; tags = ["+junk" "-inbox" ] ;}
|
||||
{query = "from:runtastic.com" ; tags = ["+junk" "-inbox" ] ;}
|
||||
{query = "from:letterboxd.com" ; tags = ["+junk" "-inbox" ] ;}
|
||||
{query = "from::microsoftstoreemail.com" ; tags = ["+junk" "-inbox" ] ;}
|
||||
{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:tumblr.com" ; tags = ["+junk" "-inbox" "-unread"];}
|
||||
{query = "from:jobs2web.com" ; tags = ["+newzealand" "+jobs" "-inbox" ];}
|
||||
{query = "from:mailings.gmx.net" ; tags = ["+junk" "-inbox" "-unread"];}
|
||||
{query = "from:paypal.de AND subject:Bestätigung"; tags = ["-unread" "+paypal" "+billing"] ;}
|
||||
|
||||
{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 = "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" ];
|
||||
}
|
||||
|
||||
# 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" ;}
|
||||
|
||||
# remove new tag at the end
|
||||
{ query = "tag:new"; tags = ["-new"]; message = "remove new tag at the end" ;}
|
||||
|
||||
];
|
||||
|
||||
in
|
||||
''
|
||||
# Tag mails which are mailing lists
|
||||
[ListMailsFilter]
|
||||
|
||||
# Tag mails as killed if the thread has been marked as "killed"
|
||||
[KillThreadsFilter]
|
||||
|
||||
${concatStringsSep "\n" (imap0 template filters)}
|
||||
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
7
configs/workhorse/packages.nix
Normal file
7
configs/workhorse/packages.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
unstable = import <nixpkgs-unstable> {};
|
||||
in {
|
||||
environment.systemPackages = with pkgs ; [
|
||||
];
|
||||
}
|
107
configs/workhorse/prometheus.nix
Normal file
107
configs/workhorse/prometheus.nix
Normal file
|
@ -0,0 +1,107 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"prometheus.workhorse.private" = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://workhorse.private:9090";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.prometheus2 = {
|
||||
enable = true;
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "nginx";
|
||||
scrape_interval = "8s";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["sputnik.private:9113"];
|
||||
labels = {
|
||||
service = "nginx";
|
||||
server = "sputnik";
|
||||
};
|
||||
}
|
||||
{
|
||||
targets = ["sputnik.private:9113"];
|
||||
labels = {
|
||||
service = "nginx";
|
||||
server = "sputnik";
|
||||
};
|
||||
}
|
||||
{
|
||||
targets = ["workhorse.private:9113"];
|
||||
labels = {
|
||||
service = "nginx";
|
||||
server = "sputnik";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "netdata";
|
||||
metrics_path = "/api/v1/allmetrics";
|
||||
params.format = [ "prometheus" ];
|
||||
scrape_interval = "5s";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["porani.private:19999"];
|
||||
labels = {
|
||||
service = "netdata";
|
||||
server = "porani";
|
||||
};
|
||||
}
|
||||
{
|
||||
targets = ["sputnik.private:19999"];
|
||||
labels = {
|
||||
service = "netdata";
|
||||
server = "sputnik";
|
||||
};
|
||||
}
|
||||
{
|
||||
targets = ["workhorse.private:19999"];
|
||||
labels = {
|
||||
service = "netdata";
|
||||
server = "workhorse";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "gogs";
|
||||
metrics_path = "/-/metrics";
|
||||
params.format = [ "prometheus" ];
|
||||
scrape_interval = "10s";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["workhorse.private:3000"];
|
||||
labels = {
|
||||
service = "gogs";
|
||||
server = "kruck";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "home-assistant";
|
||||
scrape_interval = "60s";
|
||||
metrics_path = "/api/prometheus";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["porani.private:8123"];
|
||||
labels = {
|
||||
service = "hass";
|
||||
server = "porani";
|
||||
city = "essen";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
9
configs/workhorse/restic.nix
Normal file
9
configs/workhorse/restic.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{config, ... }:
|
||||
{
|
||||
|
||||
backup.services.restic = {
|
||||
"on-porani".enable = false;
|
||||
"on-workhorse".enable = true;
|
||||
};
|
||||
|
||||
}
|
26
configs/workhorse/seafile.nix
Normal file
26
configs/workhorse/seafile.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"seafile.${config.networking.hostName}.private" = {
|
||||
serverAliases = [];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${toString config.custom.services.seafile.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
custom.services.seafile = {
|
||||
enable = true;
|
||||
hostname = "seafile.gaykraft.com";
|
||||
port = 3030;
|
||||
home = "/home/seafile";
|
||||
};
|
||||
|
||||
virtualisation.docker.enable = lib.mkDefault true;
|
||||
|
||||
}
|
53
configs/workhorse/syncthing.nix
Normal file
53
configs/workhorse/syncthing.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
test.services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = false;
|
||||
dataDir = "/home/syncthing";
|
||||
configDir = "/home/syncthing";
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
overrideFolders = true;
|
||||
|
||||
folders = {
|
||||
|
||||
# todo add podcast here
|
||||
|
||||
# on encrypted hard drive
|
||||
# -----------------------
|
||||
desktop-encrypted.path = "/home/syncthing/.desktop.ct";
|
||||
finance-encrypted.path = "/home/syncthing/.finance.ct";
|
||||
fotos-encrypted.path = "/home/syncthing/private/.fotos.ct";
|
||||
music-projects.path = "/home/syncthing/music-projects";
|
||||
video-material.path = "/home/syncthing/video-material";
|
||||
|
||||
# on media hard drive (not encrypted)
|
||||
# -----------------------------------
|
||||
music-library-free.path = "/media/syncthing/music-library-free";
|
||||
samples.path = "/media/syncthing/samples";
|
||||
movies.path = "/media/syncthing/movies";
|
||||
music-library.path = "/media/syncthing/music-library";
|
||||
podcasts.path = "/media/syncthing/podcasts";
|
||||
series.path = "/media/syncthing/series";
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."permown._media_syncthing" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
system.permown."/media/syncthing" = {
|
||||
owner = "syncthing";
|
||||
group = "syncthing";
|
||||
umask = "0007";
|
||||
};
|
||||
systemd.services."syncthing" = {
|
||||
bindsTo = [ "media.mount" ];
|
||||
after = [ "media.mount" ];
|
||||
};
|
||||
|
||||
}
|
14
configs/workhorse/taskserver.nix
Normal file
14
configs/workhorse/taskserver.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
services.taskserver = {
|
||||
enable = true;
|
||||
fqdn = "workhorse.private";
|
||||
listenHost = "0.0.0.0";
|
||||
requestLimit = 104857600;
|
||||
trust = "allow all";
|
||||
dataDir = "/var/lib/taskserver";
|
||||
organisations."orgie".users = ["palo"];
|
||||
};
|
||||
|
||||
}
|
16
configs/workhorse/tinc.nix
Normal file
16
configs/workhorse/tinc.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
"retiolum" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
45
configs/workhorse/transmission.nix
Normal file
45
configs/workhorse/transmission.nix
Normal file
|
@ -0,0 +1,45 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
allTincNetworks =
|
||||
builtins.attrNames config.module.cluster.services.tinc;
|
||||
|
||||
ipAddresses =
|
||||
flatten (mapAttrsToList (_: data:
|
||||
mapAttrsToList (_: hostConfig: hostConfig.tincIp) data.hosts)
|
||||
config.module.cluster.services.tinc);
|
||||
|
||||
in {
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
statusPage = true;
|
||||
virtualHosts = {
|
||||
"transmission.${config.networking.hostName}.private" = {
|
||||
serverAliases = ["torrent.${config.networking.hostName}.private"];
|
||||
locations."/" = {
|
||||
proxyPass = "http://${config.networking.hostName}.private:${toString config.services.transmission.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ config.services.custom.transmission.port ];
|
||||
allowedUDPPorts = [ config.services.custom.transmission.port ];
|
||||
};
|
||||
|
||||
services.custom.transmission = {
|
||||
enable = true;
|
||||
home = "/home/torrent";
|
||||
store = "/home/torrent";
|
||||
hosts = concatStringsSep "," (map (name: "${config.networking.hostName}.${name}") allTincNetworks);
|
||||
whitelist = concatStringsSep "," ipAddresses;
|
||||
user = "palo";
|
||||
password = lib.fileContents <secrets/transmission/password>;
|
||||
};
|
||||
|
||||
}
|
20
configs/workhorse/weechat.nix
Normal file
20
configs/workhorse/weechat.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
# how to setup a relay
|
||||
# * ssh on the maching
|
||||
# * sudo -u weechat screen -r
|
||||
# /set relay.network.password "mypassword"
|
||||
# /relay add weechat 10000
|
||||
|
||||
{
|
||||
|
||||
services.weechat = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# otherwise xterm is the only thing that works
|
||||
environment.systemPackages = [ pkgs.rxvt_unicode ];
|
||||
|
||||
backup.all.restic.dirs = [ config.services.weechat.root ];
|
||||
|
||||
}
|
40
configs/workhorse/wetten.nix
Normal file
40
configs/workhorse/wetten.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
{ config, lib, pkgs , ... }:
|
||||
{
|
||||
imports = [
|
||||
<wetten/nixos>
|
||||
];
|
||||
|
||||
krops.userKeys."wetten_appkey" = {
|
||||
user = "wetten";
|
||||
source = toString <secrets/betfair/appkey>;
|
||||
requiredBy = [ "wetten.service" ];
|
||||
};
|
||||
|
||||
krops.userKeys."wetten_key" = {
|
||||
user = "wetten";
|
||||
source = <secrets/betfair/key>;
|
||||
requiredBy = [ "wetten.service" ];
|
||||
};
|
||||
|
||||
krops.userKeys."wetten_cert" = {
|
||||
user = "wetten";
|
||||
source = toString <secrets/betfair/cert>;
|
||||
requiredBy = [ "wetten.service" ];
|
||||
};
|
||||
|
||||
krops.userKeys."wetten_password" = {
|
||||
user = "wetten";
|
||||
source = toString <secrets/betfair/password>;
|
||||
requiredBy = [ "wetten.service" ];
|
||||
};
|
||||
|
||||
services.wetten = {
|
||||
enable = true;
|
||||
username = "palipalo9@googlemail.com";
|
||||
passwordFile = config.krops.userKeys."wetten_password".target;
|
||||
appKeyFile = config.krops.userKeys."wetten_appkey".target;
|
||||
clientCert = config.krops.userKeys."wetten_cert".target;
|
||||
clientCertKey = config.krops.userKeys."wetten_key".target;
|
||||
};
|
||||
|
||||
}
|
62
configs/workout/configuration.nix
Normal file
62
configs/workout/configuration.nix
Normal file
|
@ -0,0 +1,62 @@
|
|||
{ lib, config, pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
|
||||
<system/desktop>
|
||||
./hardware-configuration.nix
|
||||
|
||||
#<system/server/netdata.nix>
|
||||
./encfs.nix
|
||||
./kibana.nix
|
||||
./packages.nix
|
||||
./slack.nix
|
||||
./syncthing.nix
|
||||
./tinc.nix
|
||||
|
||||
];
|
||||
|
||||
networking.hostName = "workout";
|
||||
|
||||
services.logind.lidSwitch = lib.mkForce "ignore";
|
||||
|
||||
security.wrappers = {
|
||||
pmount.source = "${pkgs.pmount}/bin/pmount";
|
||||
pumount.source = "${pkgs.pmount}/bin/pumount";
|
||||
};
|
||||
|
||||
# nix-shell -p speedtest_cli --run speedtest
|
||||
configuration.fireqos = {
|
||||
enable = true;
|
||||
interface = "wlp1s0";
|
||||
input = 4200;
|
||||
output = 1200;
|
||||
balance = false;
|
||||
};
|
||||
|
||||
programs.custom.steam.enable = true;
|
||||
programs.custom.video.enable = true;
|
||||
|
||||
# font
|
||||
# ----
|
||||
programs.custom.urxvt.fontSize = 17;
|
||||
programs.custom.xterm.fontSize = 17;
|
||||
system.custom.fonts.dpi = 140;
|
||||
|
||||
services.printing.enable = true;
|
||||
|
||||
virtualisation = {
|
||||
docker.enable = true;
|
||||
virtualbox = {
|
||||
host.enable = true;
|
||||
guest.x11 = true;
|
||||
guest.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
configuration.desktop = {
|
||||
width = 2560;
|
||||
height = 1440;
|
||||
};
|
||||
|
||||
}
|
||||
|
8
configs/workout/encfs.nix
Normal file
8
configs/workout/encfs.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
module.backup.services.encfs = {
|
||||
"fotos".enable = true;
|
||||
"desktop".enable = true;
|
||||
"finance".enable = true;
|
||||
};
|
||||
}
|
61
configs/workout/hardware-configuration.nix
Normal file
61
configs/workout/hardware-configuration.nix
Normal file
|
@ -0,0 +1,61 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
mainUserHome = "/home/palo";
|
||||
in
|
||||
{
|
||||
# fix fileSystems.<name>.encrypted - false overwrite
|
||||
# --------------------------------------------------
|
||||
boot.initrd.luks.cryptoModules = [ "aes" "aes_generic" "blowfish" "twofish" "serpent" "cbc" "xts" "lrw" "sha1" "sha256" "sha512" "aes_x86_64" ];
|
||||
|
||||
# todo : why should I use this here
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
nix.maxJobs = lib.mkDefault 8;
|
||||
|
||||
# lvm volume group
|
||||
# ----------------
|
||||
boot.initrd.luks.devices = [
|
||||
{
|
||||
name = "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";
|
||||
};
|
||||
boot.loader.grub = {
|
||||
device = "/dev/sda";
|
||||
enable = true;
|
||||
version = 2;
|
||||
};
|
||||
|
||||
# home
|
||||
# ----
|
||||
fileSystems."/home" = {
|
||||
options = [ "noatime" "nodiratime" "discard" ];
|
||||
device = "/dev/vg/home";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
}
|
||||
|
23
configs/workout/kibana.nix
Normal file
23
configs/workout/kibana.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{ 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 = "${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;
|
||||
|
||||
}
|
22
configs/workout/packages.nix
Normal file
22
configs/workout/packages.nix
Normal file
|
@ -0,0 +1,22 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
unstable = import <nixpkgs-unstable> {};
|
||||
in {
|
||||
|
||||
nixpkgs.config.packageOverrides = pkgs: {
|
||||
nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
|
||||
inherit pkgs;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs ; [
|
||||
bitwig-studio
|
||||
#unstable.pypi2nix
|
||||
#nur.repos.mic92.nixos-shell
|
||||
];
|
||||
|
||||
programs.custom.q = {
|
||||
enableIntelBacklight = false;
|
||||
enableBattery = false;
|
||||
};
|
||||
}
|
14
configs/workout/slack.nix
Normal file
14
configs/workout/slack.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
|
||||
programs.custom.slack = {
|
||||
enable = true;
|
||||
homeBackup = "~/desktop/slack";
|
||||
};
|
||||
|
||||
programs.custom.browser.configList.google-chrome = {
|
||||
inherit (config.programs.custom.browser.configList.development) home homeBackup user;
|
||||
sudoUsers = [ "slack" ];
|
||||
};
|
||||
|
||||
}
|
40
configs/workout/syncthing.nix
Normal file
40
configs/workout/syncthing.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
test.services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = false;
|
||||
user = "palo";
|
||||
dataDir = "/home/palo/.syncthing";
|
||||
configDir = "/home/palo/.syncthing";
|
||||
declarative = {
|
||||
cert = toString <secrets/syncthing/cert.pem>;
|
||||
key = toString <secrets/syncthing/key.pem>;
|
||||
|
||||
overrideFolders = true;
|
||||
folders = {
|
||||
|
||||
book.path = "/home/palo/books";
|
||||
desktop-encrypted.path = "/home/palo/.desktop.ct";
|
||||
finance-encrypted.path = "/home/palo/.finance.ct";
|
||||
fotos-encrypted.path = "/home/palo/private/.fotos.ct";
|
||||
kruck-workout.path = "/home/palo/workout-kruck";
|
||||
music-library-free.path = "/home/palo/music-library-free";
|
||||
music-library.path = "/home/palo/music-library";
|
||||
music-projects.path = "/home/palo/music-projects";
|
||||
porani-workout.path = "/home/palo/workout-porani";
|
||||
samples.path = "/home/palo/samples";
|
||||
schasch-workout.path = "/home/palo/workout-schasch";
|
||||
smartphone-fotos.path = "/home/palo/smartphone-fotos";
|
||||
smartphone-music.path = "/home/palo/smartphone-music";
|
||||
video-material.path = "/home/palo/video-material";
|
||||
workout-pepe.path = "/home/palo/workout-pepe";
|
||||
windows-sync.path = "/home/palo/windows-sync";
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
15
configs/workout/tinc.nix
Normal file
15
configs/workout/tinc.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
module.cluster.services.tinc = {
|
||||
"private" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
connectTo = [ "sputnik" ];
|
||||
};
|
||||
"retiolum" = {
|
||||
enable = true;
|
||||
openPort = true;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
19
images/remote-install/README.md
Normal file
19
images/remote-install/README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# remote installation iso
|
||||
|
||||
* `./config.nix` : to generate the installation image
|
||||
* `./remote-service.nix` : tor configuration you have to start on your machine.
|
||||
|
||||
|
||||
## Steps
|
||||
|
||||
* import `./remote-service.nix` in your `/etc/nixos/configuration.nix`
|
||||
* `nixos-rebuild switch`
|
||||
* run `remote-install-get-hiddenReceiver` and enter the result in `./config.nix` as `hiddenReceiver`
|
||||
* set the public key in `./config.nix`
|
||||
* run `nixos-generate -f install-iso -c ./config.nix`
|
||||
* prepare the usb stick : `sudo if=<path of the iso> of=/dev/<device> bs=4096`
|
||||
* boot the usb-stick at the new machine
|
||||
* run `remote-install-start-service`
|
||||
* after some time you will see a you can use to login to the new machine.
|
||||
|
||||
Now you can do the normal installations procedure.
|
142
images/remote-install/config.nix
Normal file
142
images/remote-install/config.nix
Normal file
|
@ -0,0 +1,142 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
|
||||
# cat ~/.ssh/id_rsa.pub
|
||||
publicSshKey = "";
|
||||
|
||||
# remote-install-get-hiddenReceiver
|
||||
hiddenReceiver = "";
|
||||
|
||||
in {
|
||||
|
||||
imports = [
|
||||
{ # system setup
|
||||
networking.hostName = "liveos";
|
||||
|
||||
users.extraUsers = {
|
||||
root = {
|
||||
password = "lolhack";
|
||||
openssh.authorizedKeys.keys = [
|
||||
publicSshKey
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.extraInit = ''
|
||||
EDITOR=vim
|
||||
'';
|
||||
}
|
||||
{ # installed packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
environment.systemPackages = with pkgs; [
|
||||
#style
|
||||
most
|
||||
rxvt_unicode.terminfo
|
||||
|
||||
#monitoring tools
|
||||
htop
|
||||
iotop
|
||||
|
||||
#network
|
||||
iptables
|
||||
iftop
|
||||
nmap
|
||||
|
||||
#stuff for dl
|
||||
aria2
|
||||
|
||||
#neat utils
|
||||
pciutils
|
||||
psmisc
|
||||
tmux
|
||||
usbutils
|
||||
git
|
||||
|
||||
#unpack stuff
|
||||
p7zip
|
||||
unzip
|
||||
unrar
|
||||
|
||||
#data recovery
|
||||
ddrescue
|
||||
ntfs3g
|
||||
dosfstools
|
||||
];
|
||||
}
|
||||
{ # bash configuration
|
||||
programs.bash = {
|
||||
enableCompletion = true;
|
||||
interactiveShellInit = ''
|
||||
HISTCONTROL='erasedups:ignorespace'
|
||||
HISTSIZE=65536
|
||||
HISTFILESIZE=$HISTSIZE
|
||||
|
||||
shopt -s checkhash
|
||||
shopt -s histappend histreedit histverify
|
||||
shopt -s no_empty_cmd_completion
|
||||
complete -d cd
|
||||
'';
|
||||
promptInit = ''
|
||||
if test $UID = 0; then
|
||||
PS1='\[\033[1;31m\]\w\[\033[0m\] '
|
||||
PROMPT_COMMAND='echo -ne "\033]0;$$ $USER@$PWD\007"'
|
||||
elif test $UID = 1337; then
|
||||
PS1='\[\033[1;32m\]\w\[\033[0m\] '
|
||||
PROMPT_COMMAND='echo -ne "\033]0;$$ $PWD\007"'
|
||||
else
|
||||
PS1='\[\033[1;33m\]\u@\w\[\033[0m\] '
|
||||
PROMPT_COMMAND='echo -ne "\033]0;$$ $USER@$PWD\007"'
|
||||
fi
|
||||
if test -n "$SSH_CLIENT"; then
|
||||
PS1='\[\033[35m\]\h'" $PS1"
|
||||
PROMPT_COMMAND='echo -ne "\033]0;$$ $HOSTNAME $USER@$PWD\007"'
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
{ # ssh configuration
|
||||
services.openssh.enable = true;
|
||||
services.openssh.passwordAuthentication = false;
|
||||
systemd.services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ];
|
||||
}
|
||||
{ # network configuration
|
||||
networking.networkmanager.enable = true;
|
||||
networking.wireless.enable = lib.mkForce false;
|
||||
}
|
||||
{ # hidden ssh announce
|
||||
config = let
|
||||
torDirectory = "/var/lib/tor";
|
||||
hiddenServiceDir = torDirectory + "/liveos";
|
||||
in {
|
||||
services.tor = {
|
||||
enable = true;
|
||||
client.enable = true;
|
||||
extraConfig = ''
|
||||
HiddenServiceDir ${hiddenServiceDir}
|
||||
HiddenServicePort 22 127.0.0.1:22
|
||||
'';
|
||||
};
|
||||
systemd.services.hidden-ssh-announce = {
|
||||
description = "irc announce hidden ssh";
|
||||
after = [ "tor.service" "network-online.target" ];
|
||||
wants = [ "tor.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = pkgs.writers.writeDash "irc-announce-ssh" ''
|
||||
set -efu
|
||||
until test -e ${hiddenServiceDir}/hostname; do
|
||||
echo "still waiting for ${hiddenServiceDir}/hostname"
|
||||
sleep 1
|
||||
done
|
||||
until ${pkgs.tor}/bin/torify ${pkgs.netcat-openbsd}/bin/nc -z ${hiddenReceiver} 1337; do sleep 1; done && \
|
||||
echo "torify ssh root@$(cat ${hiddenServiceDir}/hostname) -i ~/.ssh/id_rsa" | ${pkgs.tor}/bin/torify ${pkgs.nmap}/bin/ncat ${hiddenReceiver} 1337
|
||||
'';
|
||||
PrivateTmp = "true";
|
||||
User = "tor";
|
||||
Type = "oneshot";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
20
images/remote-install/remote-install.nix
Normal file
20
images/remote-install/remote-install.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
# installs scripts and tor to provide an announcement service for nixos-remote installation.
|
||||
{
|
||||
services.tor = {
|
||||
enable = true;
|
||||
client.enable = true;
|
||||
hiddenServices.liveos.map = [
|
||||
{ port = 1337; }
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "remote-install-start-service" ''
|
||||
echo "starting announcment server to receive remote-install iso onion id"
|
||||
${pkgs.nmap}/bin/ncat -k -l -p 1337
|
||||
'')
|
||||
(pkgs.writeShellScriptBin "remote-install-get-hiddenReceiver" ''
|
||||
sudo cat /var/lib/tor/onion/liveos/hostname
|
||||
'')
|
||||
];
|
||||
}
|
64
images/yubikey-image.nix
Normal file
64
images/yubikey-image.nix
Normal file
|
@ -0,0 +1,64 @@
|
|||
# NixOS livesystem to generate yubikeys in an air-gapped manner
|
||||
# screenshot: https://dl.thalheim.io/wmxIqucOEo2xuLk0Ut45fQ/yubikey-live-system.png
|
||||
# $ nixos-generator -f iso -c yubikey-image.nix
|
||||
{ pkgs, ... }: {
|
||||
environment.interactiveShellInit = ''
|
||||
export GNUPGHOME=/run/user/$(id -u)/gnupghome
|
||||
if [ ! -d $GNUPGHOME ]; then
|
||||
mkdir $GNUPGHOME
|
||||
fi
|
||||
cp ${pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/drduh/config/662c16404eef04f506a6a208f1253fee2f4895d9/gpg.conf";
|
||||
sha256 = "118fmrsn28fz629y7wwwcx7r1wfn59h3mqz1snyhf8b5yh0sb8la";
|
||||
}} "$GNUPGHOME/gpg.conf"
|
||||
echo "\$GNUPGHOME has been set up for you. Generated keys will be in $GNUPGHOME."
|
||||
'';
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
yubikey-personalization
|
||||
cryptsetup
|
||||
pwgen
|
||||
midori
|
||||
paperkey
|
||||
gnupg
|
||||
haskellPackages.hopenpgp-tools
|
||||
ctmg
|
||||
];
|
||||
|
||||
services.udev.packages = with pkgs; [ yubikey-personalization ];
|
||||
services.pcscd.enable = true;
|
||||
users.extraUsers.root.initialHashedPassword = "";
|
||||
|
||||
# make sure we are air-gapped
|
||||
networking.wireless.enable = false;
|
||||
networking.dhcpcd.enable = false;
|
||||
|
||||
services.mingetty.helpLine = "The 'root' account has an empty password.";
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
displayManager.auto.enable = true;
|
||||
|
||||
desktopManager = let
|
||||
guide = pkgs.stdenv.mkDerivation {
|
||||
name = "yubikey-guide-2019-01-21.html";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "drduh";
|
||||
repo = "YubiKey-Guide";
|
||||
rev = "035d98ebbed54a0218ccbf23905054d32f97508e";
|
||||
sha256 = "0rzy06a5xgfjpaklxdgrxml24d0vhk78lb577l3z4x7a2p32dbyq";
|
||||
};
|
||||
buildInputs = [ pkgs.pandoc ];
|
||||
installPhase = "pandoc --highlight-style pygments -s --toc README.md -o $out";
|
||||
};
|
||||
in {
|
||||
default = "xfce";
|
||||
xterm.enable = false;
|
||||
xfce.enable = true;
|
||||
xfce.extraSessionCommands = ''
|
||||
${pkgs.midori}/bin/midori ${guide} &
|
||||
${pkgs.xfce.terminal}/bin/xfce4-terminal &
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
21
library/default.nix
Normal file
21
library/default.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{ pkgs, lib, ... }:
|
||||
{
|
||||
desktopFile = bin: { longName ? "Script", command ? "${bin}/bin/${bin.name}", ... }:
|
||||
pkgs.writeTextFile {
|
||||
name = "${bin.name}.desktop" ;
|
||||
destination = "/share/applications/${bin.name}.desktop";
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Exec=${bin}/bin/${command} %U
|
||||
Comment=An open source web browser from Google
|
||||
Terminal=false
|
||||
Name=${bin.name}
|
||||
GenericName=${longName}
|
||||
StartupWMClass=${bin.name}
|
||||
'';
|
||||
};
|
||||
|
||||
jenkins = import ./jenkins.nix { inherit lib; };
|
||||
|
||||
}
|
135
library/jenkins.nix
Normal file
135
library/jenkins.nix
Normal file
|
@ -0,0 +1,135 @@
|
|||
{ lib, ... }:
|
||||
|
||||
with builtins;
|
||||
|
||||
{
|
||||
# source container url and credentialsId
|
||||
job = name: {
|
||||
url,
|
||||
credentialsId,
|
||||
branch ? "master",
|
||||
# https://docs.openstack.org/infra/jenkins-job-builder/triggers.html
|
||||
triggers ? [
|
||||
{ pollscm = {
|
||||
cron = "H/30 * * * *";
|
||||
ignore-post-commit-hooks = true;
|
||||
};}
|
||||
], ... }: config: { job = {
|
||||
inherit name triggers;
|
||||
sandbox = true;
|
||||
project-type = "pipeline";
|
||||
dsl = let
|
||||
stage = elem:
|
||||
let
|
||||
stageName = head ( attrNames elem );
|
||||
stateScripts = map ( stage :
|
||||
lib.getAttr (typeOf stage) {
|
||||
string = ''
|
||||
withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) {
|
||||
sh '${toString stage}'
|
||||
}'';
|
||||
set =
|
||||
let
|
||||
script = ''
|
||||
withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) {
|
||||
sh '${toString stage.script}'
|
||||
}
|
||||
'';
|
||||
in
|
||||
if (stage.credentialsId != null)
|
||||
then ''
|
||||
sshagent(['${stage.credentialsId}']) { ${script} }
|
||||
''
|
||||
else script;
|
||||
}
|
||||
)( getAttr stageName elem );
|
||||
in ''
|
||||
stage('${stageName}') {
|
||||
steps {
|
||||
${concatStringsSep "\n" stateScripts}
|
||||
}
|
||||
}
|
||||
'';
|
||||
stages = map stage config;
|
||||
in ''
|
||||
pipeline {
|
||||
agent any
|
||||
stages{
|
||||
stage('Pull') {
|
||||
steps {
|
||||
checkout(
|
||||
[$class: 'GitSCM'
|
||||
, branches: [[name: '*/${branch}']]
|
||||
, doGenerateSubmoduleConfigurations: false
|
||||
, extensions: [[$class: 'LocalBranch', localBranch: 'master']]
|
||||
, submoduleCfg: []
|
||||
, userRemoteConfigs:
|
||||
[[ credentialsId: '${credentialsId}'
|
||||
, url: '${url}']]
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
${concatStringsSep "\n" stages}
|
||||
}
|
||||
}
|
||||
'';
|
||||
};};
|
||||
|
||||
# creates a sync job
|
||||
# source and target container url and credentialsId
|
||||
syncJob = name: source: target: {
|
||||
job = {
|
||||
name = name;
|
||||
sandbox = true;
|
||||
project-type = "pipeline";
|
||||
triggers = [ {
|
||||
pollscm = {
|
||||
cron = "H/30 * * * *";
|
||||
ignore-post-commit-hooks = true;
|
||||
};
|
||||
} ];
|
||||
dsl = ''
|
||||
pipeline {
|
||||
agent any
|
||||
stages{
|
||||
stage('Pull') {
|
||||
steps {
|
||||
checkout(
|
||||
[$class: 'GitSCM'
|
||||
, branches: [[name: '*/master']]
|
||||
, doGenerateSubmoduleConfigurations: false
|
||||
, extensions: [[$class: 'LocalBranch', localBranch: 'master']]
|
||||
, submoduleCfg: []
|
||||
, userRemoteConfigs:
|
||||
[[ credentialsId: '${source.credentialsId}'
|
||||
, url: '${source.url}']]
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
stage('Push') {
|
||||
steps {
|
||||
sshagent(['${target.credentialsId}']) {
|
||||
withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) {
|
||||
sh "git push -f ${target.url}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Push Tags') {
|
||||
steps {
|
||||
sshagent(['${target.credentialsId}']) {
|
||||
withEnv(['PATH=/run/current-system/sw/bin/']) {
|
||||
sh "git push -f ${target.url} --tags"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
}
|
45
modules/default.nix
Normal file
45
modules/default.nix
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
|
||||
imports = [
|
||||
|
||||
./later/syncthing.nix
|
||||
|
||||
./services/castget.nix
|
||||
./services/home-assistant.nix
|
||||
./services/lektor.nix
|
||||
./services/samba-share.nix
|
||||
./services/seafile.nix
|
||||
./services/sshd.nix
|
||||
./services/transmission.nix
|
||||
./services/videoencoder.nix
|
||||
|
||||
./programs/browser.nix
|
||||
./programs/citate.nix
|
||||
./programs/curl-scripts.nix
|
||||
./programs/easytag.nix
|
||||
./programs/elm.nix
|
||||
./programs/espeak.nix
|
||||
./programs/ffmpeg.nix
|
||||
./programs/git.nix
|
||||
./programs/q.nix
|
||||
./programs/shell-bash.nix
|
||||
./programs/shell-tools.nix
|
||||
./programs/shell-zsh.nix
|
||||
./programs/slack.nix
|
||||
./programs/steam.nix
|
||||
./programs/taskwarrior.nix
|
||||
./programs/urxvt.nix
|
||||
./programs/video.nix
|
||||
./programs/vim.nix
|
||||
./programs/xterm.nix
|
||||
|
||||
./system/audio.nix
|
||||
./system/bluetooth.nix
|
||||
./system/font.nix
|
||||
./system/mainUser.nix
|
||||
./system/permown.nix
|
||||
./system/wifi.nix
|
||||
./system/x11.nix
|
||||
|
||||
];
|
||||
}
|
434
modules/later/syncthing.nix
Normal file
434
modules/later/syncthing.nix
Normal file
|
@ -0,0 +1,434 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.test.services.syncthing;
|
||||
defaultUser = "syncthing";
|
||||
|
||||
|
||||
|
||||
devices = mapAttrsToList (name: device: {
|
||||
deviceID = device.id;
|
||||
inherit (device) name addresses introducer;
|
||||
}) cfg.declarative.devices;
|
||||
|
||||
|
||||
folders = mapAttrsToList ( _: folder: {
|
||||
inherit (folder) path id label type;
|
||||
devices = map (device: { deviceId = cfg.declarative.devices.${device}.id; }) folder.devices;
|
||||
rescanIntervalS = folder.rescanInterval;
|
||||
fsWatcherEnabled = folder.watch;
|
||||
fsWatcherDelayS = folder.watchDelay;
|
||||
ignorePerms = folder.ignorePerms;
|
||||
}) (filterAttrs (
|
||||
_: value:
|
||||
(value.path != null) && (value.devices != [])
|
||||
) cfg.declarative.folders);
|
||||
|
||||
# get the api key by parsing the config.xml
|
||||
getApiKey = pkgs.writers.writeDash "getAPIKey" ''
|
||||
${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)'\
|
||||
${cfg.configDir}/config.xml
|
||||
'';
|
||||
|
||||
updateConfig = pkgs.writers.writeDash "merge-syncthing-config" ''
|
||||
set -efu
|
||||
# wait for syncthing port to open
|
||||
until ${pkgs.curl}/bin/curl -Ss ${cfg.guiAddress} -o /dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
API_KEY=$(${getApiKey})
|
||||
OLD_CFG=$(${pkgs.curl}/bin/curl -Ss \
|
||||
-H "X-API-Key: $API_KEY" \
|
||||
${cfg.guiAddress}/rest/system/config)
|
||||
|
||||
# generate the new config by merging with the nixos config options
|
||||
NEW_CFG=$(echo "$OLD_CFG" | ${pkgs.jq}/bin/jq -s '.[] as $in | $in * {
|
||||
"devices": (${builtins.toJSON devices}${optionalString (! cfg.declarative.overrideDevices) " + $in.devices"}),
|
||||
"folders": (${builtins.toJSON folders}${optionalString (! cfg.declarative.overrideFolders) " + $in.folders"})
|
||||
}')
|
||||
|
||||
# POST the new config to syncthing
|
||||
echo "$NEW_CFG" | ${pkgs.curl}/bin/curl -Ss \
|
||||
-H "X-API-Key: $API_KEY" \
|
||||
${cfg.guiAddress}/rest/system/config -d @-
|
||||
|
||||
# restart syncthing after sending the new config
|
||||
${pkgs.curl}/bin/curl -Ss \
|
||||
-H "X-API-Key: $API_KEY" \
|
||||
-X POST \
|
||||
${cfg.guiAddress}/rest/system/restart
|
||||
'';
|
||||
in {
|
||||
###### interface
|
||||
options = {
|
||||
test.services.syncthing = {
|
||||
|
||||
enable = mkEnableOption ''
|
||||
Syncthing - the self-hosted open-source alternative
|
||||
to Dropbox and Bittorrent Sync. Initial interface will be
|
||||
available on http://127.0.0.1:8384/.
|
||||
'';
|
||||
|
||||
declarative = {
|
||||
cert = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to users cert.pem file, will be copied into the syncthing's
|
||||
<literal>configDir</literal>
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to users key.pem file, will be copied into the syncthing's
|
||||
<literal>configDir</literal>
|
||||
'';
|
||||
};
|
||||
|
||||
overrideDevices = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the devices which are not configured via the
|
||||
<literal>declarative.devices</literal> option.
|
||||
If set to false, devices added via the webinterface will
|
||||
persist but will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
Peers/devices which syncthing should communicate with.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
name = "bigbox";
|
||||
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
||||
addresses = [ "tcp://192.168.0.10:51820" ];
|
||||
}
|
||||
];
|
||||
type = types.attrsOf (types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = config._module.args.name;
|
||||
description = ''
|
||||
Name of the device
|
||||
'';
|
||||
};
|
||||
|
||||
addresses = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The addresses used to connect to the device.
|
||||
If this is let empty, dynamic configuration is attempted
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The id of the other peer, this is mandatory. It's documented at
|
||||
https://docs.syncthing.net/dev/device-ids.html
|
||||
'';
|
||||
};
|
||||
|
||||
introducer = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If the device should act as an introducer and be allowed
|
||||
to add folders on this computer.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
overrideFolders = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to delete the folders which are not configured via the
|
||||
<literal>declarative.folders</literal> option.
|
||||
If set to false, folders added via the webinterface will persist
|
||||
but will have to be deleted manually.
|
||||
'';
|
||||
};
|
||||
|
||||
folders = mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
folders which should be shared by syncthing.
|
||||
'';
|
||||
type = types.attrsOf (types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
|
||||
path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The path to the folder which should be shared.
|
||||
'';
|
||||
};
|
||||
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
default = config._module.args.name;
|
||||
description = ''
|
||||
The id of the folder. Must be the same on all devices.
|
||||
'';
|
||||
};
|
||||
|
||||
label = mkOption {
|
||||
type = types.str;
|
||||
default = config._module.args.name;
|
||||
description = ''
|
||||
The label of the folder.
|
||||
'';
|
||||
};
|
||||
|
||||
devices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
The devices this folder should be shared with. Must be defined
|
||||
in the <literal>declarative.devices</literal> attribute.
|
||||
'';
|
||||
};
|
||||
|
||||
rescanInterval = mkOption {
|
||||
type = types.int;
|
||||
default = 3600;
|
||||
description = ''
|
||||
How often the folders should be rescaned for changes.
|
||||
'';
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
|
||||
default = "sendreceive";
|
||||
description = ''
|
||||
Whether to send only changes from this folder, only receive them
|
||||
or propagate both.
|
||||
'';
|
||||
};
|
||||
|
||||
watch = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the folder should be watched for changes by inotify.
|
||||
'';
|
||||
};
|
||||
|
||||
watchDelay = mkOption {
|
||||
type = types.int;
|
||||
default = 10;
|
||||
description = ''
|
||||
The delay after an inotify event is triggered.
|
||||
'';
|
||||
};
|
||||
|
||||
ignorePerms = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to propagate permission changes.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
guiAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1:8384";
|
||||
description = ''
|
||||
Address to serve the GUI.
|
||||
'';
|
||||
};
|
||||
|
||||
systemService = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Auto launch Syncthing as a system service.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = defaultUser;
|
||||
description = ''
|
||||
Syncthing will be run under this user (user will be created if it doesn't exist.
|
||||
This can be your user name).
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "nogroup";
|
||||
description = ''
|
||||
Syncthing will be run under this group (group will not be created if it doesn't exist.
|
||||
This can be your user name).
|
||||
'';
|
||||
};
|
||||
|
||||
all_proxy = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "socks5://address.com:1234";
|
||||
description = ''
|
||||
Overwrites all_proxy environment variable for the syncthing process to
|
||||
the given value. This is normaly used to let relay client connect
|
||||
through SOCKS5 proxy server.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/syncthing";
|
||||
description = ''
|
||||
Path where synced directories will exist.
|
||||
'';
|
||||
};
|
||||
|
||||
configDir = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path where the settings and keys will exist.
|
||||
'';
|
||||
default =
|
||||
let
|
||||
nixos = config.system.stateVersion;
|
||||
cond = versionAtLeast nixos "19.03";
|
||||
in cfg.dataDir + (optionalString cond "/.config/syncthing");
|
||||
};
|
||||
|
||||
openDefaultPorts = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
example = literalExample "true";
|
||||
description = ''
|
||||
Open the default ports in the firewall:
|
||||
- TCP 22000 for transfers
|
||||
- UDP 21027 for discovery
|
||||
If multiple users are running syncthing on this machine, you will need to manually open a set of ports for each instance and leave this disabled.
|
||||
Alternatively, if are running only a single instance on this machine using the default ports, enable this.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.syncthing;
|
||||
defaultText = "pkgs.syncthing";
|
||||
example = literalExample "pkgs.syncthing";
|
||||
description = ''
|
||||
Syncthing package to use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule ["services" "syncthing" "useInotify"] ''
|
||||
This option was removed because syncthing now has the inotify functionality included under the name "fswatcher".
|
||||
It can be enabled on a per-folder basis through the webinterface.
|
||||
'')
|
||||
];
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
networking.firewall = mkIf cfg.openDefaultPorts {
|
||||
allowedTCPPorts = [ 22000 ];
|
||||
allowedUDPPorts = [ 21027 ];
|
||||
};
|
||||
|
||||
systemd.packages = [ pkgs.syncthing ];
|
||||
|
||||
users = mkIf (cfg.systemService && cfg.user == defaultUser) {
|
||||
users."${defaultUser}" =
|
||||
{ group = cfg.group;
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
uid = config.ids.uids.syncthing;
|
||||
description = "Syncthing daemon user";
|
||||
};
|
||||
|
||||
groups."${defaultUser}".gid =
|
||||
config.ids.gids.syncthing;
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
syncthing = mkIf cfg.systemService {
|
||||
description = "Syncthing service";
|
||||
after = [ "network.target" ];
|
||||
environment = {
|
||||
STNORESTART = "yes";
|
||||
STNOUPGRADE = "yes";
|
||||
inherit (cfg) all_proxy;
|
||||
} // config.networking.proxy.envVars;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Restart = "on-failure";
|
||||
SuccessExitStatus = "2 3 4";
|
||||
RestartForceExitStatus="3 4";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStartPre = mkIf (cfg.declarative.cert != null || cfg.declarative.key != null)
|
||||
"+${pkgs.writers.writeBash "syncthing-copy-keys" ''
|
||||
mkdir -p ${cfg.configDir}
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.configDir}
|
||||
chmod 700 ${cfg.configDir}
|
||||
${optionalString (cfg.declarative.cert != null) ''
|
||||
cp ${toString cfg.declarative.cert} ${cfg.configDir}/cert.pem
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.configDir}/cert.pem
|
||||
chmod 400 ${cfg.configDir}/cert.pem
|
||||
''}
|
||||
${optionalString (cfg.declarative.key != null) ''
|
||||
cp ${toString cfg.declarative.key} ${cfg.configDir}/key.pem
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.configDir}/key.pem
|
||||
chmod 400 ${cfg.configDir}/key.pem
|
||||
''}
|
||||
''}"
|
||||
;
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/syncthing \
|
||||
-no-browser \
|
||||
-gui-address=${cfg.guiAddress} \
|
||||
-home=${cfg.configDir}
|
||||
'';
|
||||
};
|
||||
};
|
||||
syncthing-init = {
|
||||
after = [ "syncthing.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
RemainAfterExit = true;
|
||||
Type = "oneshot";
|
||||
ExecStart = updateConfig;
|
||||
};
|
||||
};
|
||||
|
||||
syncthing-resume = {
|
||||
wantedBy = [ "suspend.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
247
modules/programs/browser.nix
Normal file
247
modules/programs/browser.nix
Normal file
|
@ -0,0 +1,247 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
# todo : this needs to be cleaned up
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.custom.browser;
|
||||
library = import <library> { inherit pkgs lib; };
|
||||
|
||||
chromiumBin = "${pkgs.chromium}/bin/chromium";
|
||||
chromeBin = "${pkgs.google-chrome}/bin/google-chrome-stable";
|
||||
firefoxBin = "${pkgs.firefox}/bin/firefox";
|
||||
tarBin = "${pkgs.gnutar}/bin/tar";
|
||||
|
||||
|
||||
# desktop file
|
||||
# ------------
|
||||
# makes it possible to be used by other programs
|
||||
desktopFile = bin: let
|
||||
browserName = bin.name;
|
||||
in pkgs.writeTextFile {
|
||||
name = "${browserName}.desktop" ;
|
||||
destination = "/share/applications/${browserName}.desktop";
|
||||
text = ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Exec=${bin}/bin/${browserName} %U
|
||||
Icon=chromium
|
||||
Comment=An open source web browser from Google
|
||||
Terminal=false
|
||||
Name=${browserName}
|
||||
GenericName=Web browser
|
||||
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;x-scheme-handler/webcal;x-scheme-handler/about
|
||||
Categories=Network;WebBrowser
|
||||
StartupWMClass=${browserName}
|
||||
'';
|
||||
};
|
||||
|
||||
cleanBrowser = name: browser: home: homeBackup:
|
||||
let
|
||||
backupFile = "${homeBackup}.tar.lzma";
|
||||
rolloutFile = "${home}.tar.lzma";
|
||||
lockFile = "${home}-lock";
|
||||
in
|
||||
pkgs.writeShellScriptBin "${name}-clean" /* sh */ ''
|
||||
sudo killall -9 -u ${name}
|
||||
sudo rm ${lockFile}
|
||||
sudo rm -rf ${home}
|
||||
'';
|
||||
|
||||
createBrowser = name: user: browser: home: homeBackup:
|
||||
let
|
||||
backupFile = "${homeBackup}.tar.lzma";
|
||||
rolloutFile = "${home}.tar.lzma";
|
||||
lockFile = "${home}-lock";
|
||||
in
|
||||
pkgs.writeShellScriptBin "${name}" /* sh */ ''
|
||||
# set -x
|
||||
if [[ ! -e ${lockFile} ]]
|
||||
then
|
||||
# rollout backup
|
||||
if [[ -e ${backupFile} ]]
|
||||
then
|
||||
if [[ ! -d ${home} ]]
|
||||
then
|
||||
# todo : use make user
|
||||
sudo mkdir -p ${home}
|
||||
sudo chown -R ${user}:users ${home}
|
||||
fi
|
||||
cp ${backupFile} ${rolloutFile}
|
||||
sudo -u ${user} ${tarBin} xf ${rolloutFile} --directory ${home}
|
||||
rm ${rolloutFile}
|
||||
touch ${lockFile}
|
||||
fi
|
||||
fi
|
||||
|
||||
sudo -u ${user} ${browser}
|
||||
'';
|
||||
|
||||
browserExecutableList =
|
||||
let
|
||||
allBrowser = flip mapAttrsToList cfg.configList (
|
||||
name: config:
|
||||
let
|
||||
browser = if config.browserType == "chrome"
|
||||
then "${chromiumBin} \"$@\""
|
||||
else if config.browserType == "google"
|
||||
then "${chromeBin} \"$@\""
|
||||
else "${firefoxBin} \"$@\"";
|
||||
in
|
||||
createBrowser name config.user browser config.home config.homeBackup
|
||||
);
|
||||
xclipBrowser = [
|
||||
(pkgs.writeShellScriptBin "copy-to-xclip" /* sh */''
|
||||
echo "$*" | ${pkgs.xclip}/bin/xclip
|
||||
'')
|
||||
];
|
||||
in
|
||||
allBrowser ++ xclipBrowser;
|
||||
|
||||
createBackupScript = name: home: backupHome:
|
||||
pkgs.writeShellScriptBin "${name}-backup" /* sh */ ''
|
||||
sudo -u ${name} \
|
||||
${tarBin} \
|
||||
--exclude=.cache \
|
||||
--exclude=Downloads \
|
||||
--create \
|
||||
--verbos \
|
||||
--lzma \
|
||||
--file ${home}.tar.lzma \
|
||||
--directory ${home} \
|
||||
.
|
||||
|
||||
cp ${home}.tar.lzma ${backupHome}.tar.lzma
|
||||
'';
|
||||
|
||||
allBackupScripts =
|
||||
let
|
||||
filteredConfigs =
|
||||
filterAttrs
|
||||
(name: browserConfig: browserConfig.homeBackup != null)
|
||||
cfg.configList;
|
||||
in
|
||||
mapAttrsToList
|
||||
(name: browserConfig: createBackupScript name browserConfig.home browserConfig.homeBackup)
|
||||
filteredConfigs;
|
||||
|
||||
allCleanScripts =
|
||||
let
|
||||
filteredConfigs =
|
||||
filterAttrs
|
||||
(name: browserConfig: browserConfig.homeBackup != null)
|
||||
cfg.configList;
|
||||
in
|
||||
mapAttrsToList
|
||||
(name: browserConfig: cleanBrowser name name browserConfig.home browserConfig.homeBackup)
|
||||
filteredConfigs;
|
||||
|
||||
|
||||
# browser chooser
|
||||
# ---------------
|
||||
browserSelect = pkgs.writeScriptBin "browser-select" ''
|
||||
# select a browser using dmenu
|
||||
# ----------------------------
|
||||
BROWSER=$( echo -e "${lib.concatMapStringsSep "\\n" (bin: bin.name) browserExecutableList}" \
|
||||
| ${pkgs.rofi}/bin/rofi -dmenu )
|
||||
|
||||
# start selected browser
|
||||
# ----------------------
|
||||
case $BROWSER in
|
||||
${lib.concatStringsSep "\n"
|
||||
(flip map browserExecutableList (bin: "${bin.name}) export BIN=${bin}/bin/${bin.name} ;;"))
|
||||
}
|
||||
esac
|
||||
$BIN "$@"
|
||||
'';
|
||||
|
||||
|
||||
in {
|
||||
|
||||
options.programs.custom.browser = {
|
||||
enable = mkEnableOption "enable browsers";
|
||||
configList = mkOption {
|
||||
type = with types; attrsOf (submodule ({ name , ... }: {
|
||||
options = {
|
||||
browserType = mkOption {
|
||||
type = with types; enum ["firefox" "chrome" "google"];
|
||||
default = "chrome";
|
||||
description = ''
|
||||
the type of browser which is simulated
|
||||
'';
|
||||
};
|
||||
home = mkOption {
|
||||
type = with types; str;
|
||||
description = ''
|
||||
Home of the browser.
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
default = name;
|
||||
type = with types; str;
|
||||
description = ''
|
||||
user to run the browser as
|
||||
'';
|
||||
};
|
||||
sudoUsers = mkOption {
|
||||
default = [ config.users.users.mainUser.name ];
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
user allowed to run sudo without password to start the browser
|
||||
'';
|
||||
};
|
||||
homeBackup = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
example = "~/.my-browser-backup";
|
||||
description = ''
|
||||
backup of the home, which gets rolled out if the
|
||||
home does not exists. usefull for homes in tmpfs.
|
||||
dont use file endings!
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
# add sudo rights
|
||||
security.sudo.extraConfig =
|
||||
let
|
||||
extraRules = flip mapAttrsToList cfg.configList (name: values:
|
||||
concatStringsSep "\n" (map (sudoUser: "${sudoUser} ALL=(${values.user}) NOPASSWD: ALL") values.sudoUsers)) ;
|
||||
in
|
||||
lib.concatStringsSep "\n" extraRules;
|
||||
|
||||
# create users
|
||||
users.users = flip mapAttrs cfg.configList (name: config:
|
||||
{
|
||||
home = config.home;
|
||||
createHome = true;
|
||||
initialPassword = "${name}-browser";
|
||||
shell = pkgs.bashInteractive;
|
||||
isNormalUser = true;
|
||||
group = "users";
|
||||
# enable video usage
|
||||
extraGroups = [ "video" "audio" ];
|
||||
}
|
||||
);
|
||||
|
||||
# add groups to mainUser
|
||||
system.custom.mainUser.extraGroups = builtins.attrNames cfg.configList;
|
||||
|
||||
environment.systemPackages = [
|
||||
browserSelect
|
||||
( desktopFile browserSelect )
|
||||
]
|
||||
++ browserExecutableList
|
||||
++ (map (bin: desktopFile bin) browserExecutableList)
|
||||
++ allBackupScripts
|
||||
++ allCleanScripts;
|
||||
|
||||
};
|
||||
}
|
35
modules/programs/citate.nix
Normal file
35
modules/programs/citate.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.custom.citate;
|
||||
|
||||
library = import <library> { inherit pkgs lib; };
|
||||
|
||||
xdotool = "${pkgs.xdotool}/bin/xdotool";
|
||||
dmenu = "${pkgs.dmenu}/bin/dmenu";
|
||||
|
||||
citateScript = file: suffix: pkgs.writeShellScriptBin "citate-${suffix}" ''
|
||||
${xdotool} - <<<"type -- $( cat ${file} | ${dmenu} -l 10 -i | sed -e "s/\(.*\)/'\1'/" )"
|
||||
'';
|
||||
|
||||
scriptAxel = citateScript (toString <assets/sprueche-axel>) "axel";
|
||||
scriptSiw = citateScript (toString <assets/sprueche-siw>) "siw";
|
||||
|
||||
in {
|
||||
|
||||
options.programs.custom.citate = {
|
||||
enable = mkEnableOption "enable programs.custom.citate";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
scriptAxel
|
||||
(library.desktopFile scriptAxel { longName = "Citate Axel"; command = "citate-axel"; })
|
||||
scriptSiw
|
||||
(library.desktopFile scriptSiw { longName = "Citate Sinnlos im Weltall"; command = "citate-siw"; })
|
||||
];
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue