Compare commits

..

2 commits

Author SHA1 Message Date
905d086e4f odroidh2p-0: manual installation 2020-12-13 23:29:56 +01:00
284b5859a9 Justfile: don't run just with sudo 2020-12-13 21:39:27 +01:00
309 changed files with 5547 additions and 16575 deletions

6
.envrc
View file

@ -1,5 +1 @@
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then eval "$(lorri direnv)"
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
fi
use flake .#develop

7
.gitignore vendored
View file

@ -2,10 +2,3 @@
*.qcow2 *.qcow2
.*.log .*.log
.env .env
**/result
.direnv/
# nixago: ignore-linked-files
/treefmt.toml
/debug-logs

10
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,10 @@
stages:
- build
build:
stage: build
tags:
- nix
script:
# Test the nix-shell
- just run-with-channels 'nix-shell --run "echo OK"'

View file

@ -1,129 +0,0 @@
# This example uses YAML anchors which allows reuse of multiple keys
# without having to repeat yourself.
# Also see https://github.com/Mic92/dotfiles/blob/master/nixos/.sops.yaml
# for a more complex example.
# use `ssh-keyscan <IP> | ssh-to-age` to get the age key for a remote machine
# use `for file in $(grep -lr "sops:") secrets; do sops updatekeys -y $file; done` for updating
keys:
- &steveej 6F7069FE6B96E894E60EC45C6EEFA706CB17E89B
- &steveej-age age1tkvtkw62xy90xc5xdcq836wgyrwlwmdslh76cete5g98vvvhj34qvwdw0g
- &steveej-t14 age17jxphuql70wjkd84azn62ltx9ky69hyvkac23lm8f2j92lznf9hseqq0vl
- &steveej-x13s age1y9urllccdcemlv7g5z4peuzeh5ah0a8nu6cnkvym8v2vfhqjd5jql483c6
- &elias-e525 age1pmznn2tjpelpmxjxqef48rse5ujggf9kcr8x5vewuadqcw03aavqwy54zm
- &justyna-p300 age1ye4fa0v37shz8q4e5uf9cp2avygcp9jtetmnj2sv9y9mqc7gjyksq2cjy8
- &sj-vps-htz0 age18dmqd7r7fanrfmdxsvwgv9psvhs3hw5ydpvw0na0dv3dlrg4rs3q2wpvgv
- &sj-srv1 age18dmqd7r7fanrfmdxsvwgv9psvhs3hw5ydpvw0na0dv3dlrg4rs3q2wpvgv
- &router0-dmz0 age1qju6ms625tlgcjwc9p447seu2p8gu0cr63e5gv5y0wx9mvgmre9slxzzs0
- &router0-ifog age1dktk5glcuu34u9t6kp3g2vqyj7dy0elray38t8n75mwa6l0s0vdst2cy00
- &router0-hosthatch age1v458x2q70yt0a6m6cq5ehemphtrzfzyhmeg3r872vsyyf65asgwstmqqk4
- &hstk0 age10xwq7a4y256yhv02j0u80te0vt4krgfjc68r0uw07t96z7ggmpwqtv38a0
creation_rules:
- path_regex: ^(.+/|)secrets/[^/]+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *steveej-x13s
- *elias-e525
- *router0-dmz0
- *sj-srv1
- *hstk0
- *router0-ifog
- *router0-hosthatch
- path_regex: ^secrets/steveej-t14/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *steveej-t14
- path_regex: ^secrets/desktop/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *steveej-t14
- *steveej-x13s
- path_regex: ^secrets/servers/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *sj-srv1
- path_regex: ^nix/os/containers/.+_secrets.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *sj-srv1
- path_regex: ^secrets/holochain-infra/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- path_regex: ^secrets/router0-dmz0/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *router0-dmz0
- path_regex: ^secrets/router0-ifog/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *router0-ifog
- path_regex: ^secrets/router0-hosthatch/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *router0-hosthatch
- path_regex: ^secrets/sj-vps-htz0/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *sj-vps-htz0
- path_regex: ^secrets/sj-srv1/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *sj-srv1
- path_regex: ^secrets/hstk0/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *hstk0
- path_regex: ^secrets/steveej-x13s/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *steveej-x13s
- path_regex: ^secrets/work-holo/.+$
key_groups:
- pgp:
- *steveej
age:
- *steveej-age
- *steveej-x13s

20
.vscode/settings.json vendored
View file

@ -1,20 +0,0 @@
{
"editor.defaultFormatter": "ibecker.treefmt-vscode",
"editor.formatOnSave": true,
"nix.enableLanguageServer": true,
"nix.serverPath": "nil",
"nix.serverSettings": {
// settings for 'nil' LSP
"nil": {
"autoArchive": true,
"diagnostics": {
"ignored": ["unused_binding", "unused_with"]
},
"formatting": {
"command": ["treefmt", "--stdin", ".nil.nix"]
}
}
},
"treefmt.command": "treefmt",
"treefmt.config": ""
}

485
Justfile
View file

@ -1,321 +1,318 @@
# _DEFAULT_VERSION_TMPL: _DEFAULT_VERSION_TMPL:
# echo "{{invocation_directory()}}/nix/variables/versions.tmpl.nix" echo "{{invocation_directory()}}/nix/variables/versions.tmpl.nix"
_DEFAULT_VERSION:
echo "{{invocation_directory()}}/nix/variables/versions.nix"
_usage: _usage:
just -l just -l
# Re-render the default versions # Re-render the default versions
update-default-versions: update-default-versions:
nix flake update #!/usr/bin/env bash
template="$(just _DEFAULT_VERSION_TMPL)"
outfile="$(just _DEFAULT_VERSION)"
esh -o ${outfile} ${template}
_get_nix_path versionsPath: _get_nix_path versionsPath:
echo $(set -x; nix-build --no-link --show-trace {{ invocation_directory() }}/nix/default.nix -A channelSources --argstr versionsPath {{ versionsPath }}) echo $(set -x; nix-build --no-link --show-trace {{invocation_directory()}}/nix/default.nix -A channelSources --argstr versionsPath {{versionsPath}})
_device recipe dir +moreargs="": _device recipe dir +moreargs="":
#!/usr/bin/env bash #!/usr/bin/env bash
set -ex set -ex
unset NIX_PATH source $(just -v _get_nix_path {{invocation_directory()}}/{{dir}}/versions.nix)
source $(just -v _get_nix_path {{ invocation_directory() }}/{{ dir }}/versions.nix) $(set -x; nix-build --no-link --show-trace $(dirname {{dir}})/default.nix -A recipes.{{recipe}} --argstr dir {{dir}} {{moreargs}})
$(set -x; nix-build --no-link --show-trace $(dirname {{ dir }})/default.nix -A recipes.{{ recipe }} --argstr dir {{ dir }} {{ moreargs }})
_render_templates: _render_templates:
#!/usr/bin/env bash #!/usr/bin/env bash
set -ex set -ex
if ! ip route get 1.1.1.1; then if ! ip route get 1.1.1.1; then
echo No route to WAN. Skipping template rendering... echo No route to WAN. Skipping template rendering...
else else
source $(just -v _get_nix_path {{ invocation_directory() }}/nix/variables/versions.nix) source $(just -v _get_nix_path {{invocation_directory()}}/nix/variables/versions.nix)
# nix/scripts/pre-eval-fixed.sh nix/home-manager/profiles/dotfiles/vcsh{.tmpl,}.nix nix/scripts/pre-eval-fixed.sh nix/home-manager/profiles/dotfiles/vcsh{.tmpl,}.nix
fi fi
rebuild-remote-device device +rebuildargs="dry-activate": _rebuild-device dir rebuildarg="dry-activate" +moreargs="": _render_templates
#!/usr/bin/env bash #!/usr/bin/env bash
set -ex set -ex
nix run .#colmena -- apply --impure --on {{ device }} {{ rebuildargs }} just -v _device rebuild {{dir}} --argstr rebuildarg {{rebuildarg}} {{moreargs}}
rebuild-remote-device device target rebuildarg="dry-activate" :
#!/usr/bin/env bash
set -ex
just -v _rebuild-device nix/os/devices/{{device}} {{rebuildarg}} --argstr moreargs "'--target-host\ {{target}}'"
# Rebuild this device's NixOS # Rebuild this device's NixOS
rebuild-this-device +rebuildargs="dry-activate": rebuild-this-device rebuildarg="dry-activate":
nix run .#colmena -- apply-local --impure --sudo {{ rebuildargs }} #!/usr/bin/env bash
set -e
function parse_hm_rebuildarg() {
case $1 in
switch)
echo switch
;;
*)
echo build
;;
esac
}
export SYSREBUILD_LOG=.$(hostname -s)_sysrebuild.log
export HOMEREBUILD_LOG=.$(hostname -s)_homerebuild.log
echo Rebuilding system in {{rebuildarg}}-mode...
if just -v _rebuild-device nix/os/devices/$(hostname -s) {{rebuildarg}} > ${SYSREBUILD_LOG} 2>&1 ; then
echo System rebuild successful
else
cat ${SYSREBUILD_LOG}
echo ERROR: system rebuild failed
exit 1
fi
if type home-manager > /dev/null 2>&1; then
echo Rebuilding home in $(parse_hm_rebuildarg {{rebuildarg}})-mode...
source $(just -v _get_nix_path {{invocation_directory()}}/nix/os/devices/$(hostname -s)/versions.nix)
if home-manager -v $(parse_hm_rebuildarg {{rebuildarg}}) > ${HOMEREBUILD_LOG} 2>&1 ; then
echo Home rebuild successful
else
cat ${HOMEREBUILD_LOG}
echo ERROR: home rebuild failed
exit 1
fi
fi
# Re-render the versions of a remote device and rebuild its environment # Re-render the versions of a remote device and rebuild its environment
update-remote-device devicename +rebuildargs='build': update-remote-device device target rebuildmode='switch':
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
( template=nix/os/devices/{{device}}/versions.tmpl.nix
set -xe outfile=nix/os/devices/{{device}}/versions.nix
cd nix/os/devices/{{ devicename }}
nix flake update if ! test -e ${template}; then
) template="$(just _DEFAULT_VERSION_TMPL)"
fi
just -v rebuild-remote-device {{ devicename }} {{ rebuildargs }} esh -o ${outfile} ${template}
if ! test "$(git diff ${outfile})"; then
echo Already on latest versions
exit 0
fi
git commit -v nix/os/devices/{{ devicename }}/flake.{nix,lock} -m "nix/os/devices/{{ devicename }}: bump versions" just -v rebuild-remote-device {{device}} {{target}} dry-activate || {
echo ERROR: rebuild in mode 'dry-active' failed after updating ${outfile}
exit 1
}
just -v rebuild-remote-device {{ device }} {{ target }} {{ rebuildmode }} || {
echo ERROR: rebuild in mode '{{ rebuildmode }}' failed after updating ${outfile}
exit 1
}
git commit -v ${outfile} -m "nix/os/devices/{{ device }}: bump versions"
# Re-render the versions of the current device and rebuild its environment # Re-render the versions of the current device and rebuild its environment
update-this-device rebuild-mode='switch' +moreargs='': update-this-device rebuild-mode='switch':
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
( template=nix/os/devices/$(hostname -s)/versions.tmpl.nix
set -xe outfile=nix/os/devices/$(hostname -s)/versions.nix
cd nix/os/devices/$(hostname -s)
nix flake update
)
just -v rebuild-this-device {{ rebuild-mode }} {{ moreargs }} if ! test -e ${template}; then
template="$(just _DEFAULT_VERSION_TMPL)"
fi
git commit -v nix/os/devices/$(hostname -s)/flake.{nix,lock} -m "nix/os/devices/$(hostname -s): bump versions" esh -o ${outfile} ${template}
if ! test "$(git diff ${outfile})"; then
echo Already on latest versions
exit 0
fi
export SYSREBUILD_LOG=.$(hostname -s)_sysrebuild.log
just -v rebuild-this-device dry-activate || {
echo ERROR: Update failed, reverting ${outfile}...
exit 1
}
just -v rebuild-this-device {{rebuild-mode}} || {
echo ERROR: Rebuilding in {{rebuild-mode}}-mode failed
exit 1
}
git commit -v ${outfile} -m "nix/os/devices/$(hostname -s): bump versions"
# Rebuild an offline system # Rebuild an offline system
rebuild-disk device: rebuild-disk device:
#!/usr/bin/env bash #!/usr/bin/env bash
set -xe set -xe
just -v disk-mount {{ device }} just -v disk-mount {{device}}
trap "set +e; just -v disk-umount {{ device }}" EXIT trap "set +e; just -v disk-umount {{device}}" EXIT
just -v disk-install {{ device }} just -v disk-install {{device}}
# Re-render the versions of the given offline system and reinstall it in offline-mode # Re-render the versions of the given offline system and reinstall it in offline-mode
update-disk dir: update-disk dir:
#!/usr/bin/env bash #!/usr/bin/env bash
set -exuo pipefail set -exuo pipefail
dir={{ dir }} dir={{dir}}
template={{ dir }}/versions.tmpl.nix template={{dir}}/versions.tmpl.nix
outfile={{ dir }}/versions.nix outfile={{dir}}/versions.nix
if ! test -e ${template}; then if ! test -e ${template}; then
template="$(just _DEFAULT_VERSION_TMPL)" template="$(just _DEFAULT_VERSION_TMPL)"
fi fi
esh -o ${outfile} ${template} esh -o ${outfile} ${template}
if ! test "$(git diff ${outfile})"; then if ! test "$(git diff ${outfile})"; then
echo Already on latest versions echo Already on latest versions
exit 0 exit 0
fi fi
export SYSREBUILD_LOG=.{{ dir }}_sysrebuild.log export SYSREBUILD_LOG=.{{dir}}_sysrebuild.log
just -v rebuild-disk {{ dir }} || { just -v rebuild-disk {{dir}} || {
echo ERROR: Update of {{ dir }} failed, reverting ${outfile}... echo ERROR: Update of {{dir}} failed, reverting ${outfile}...
exit 1 exit 1
} }
git commit -v ${outfile} -m "${dir}: bump versions" git commit -v ${outfile} -m "${dir}: bump versions"
# Iterate on a qtile config by running it inside Xephyr. (un-/grab the mouse with Ctrl + Shift-L) # Iterate on a qtile config by running it inside Xephyr. (un-/grab the mouse with Ctrl + Shift-L)
hm-iterate-qtile: hm-iterate-qtile:
#!/usr/bin/env bash #!/usr/bin/env bash
set -xe set -xe
home-manager switch || just -v rebuild-this-device switch home-manager switch || just -v rebuild-this-device switch
Xephyr -ac -br -resizeable :1 & Xephyr -ac -br -resizeable :1 &
XEPHYR_PID=$! XEPHYR_PID=$!
echo ${XEPHYR_PID} echo ${XEPHYR_PID}
DISPLAY=:1 $(grep qtile ~/.xsession) & DISPLAY=:1 $(grep qtile ~/.xsession) &
echo "Xephyr started. un-/grab the mouse with Ctrl + Shift-L" echo "Xephyr started. un-/grab the mouse with Ctrl + Shift-L"
wait $! wait $!
kill ${XEPHYR_PID} kill ${XEPHYR_PID}
# !!! DANGERIOUS !!! This wipes the disk which is configured for the given device. # !!! DANGERIOUS !!! This wipes the disk which is configured for the given device.
disk-prepare dir: disk-prepare dir:
just -v _device diskPrepare {{ dir }} just -v _device diskPrepare {{dir}} --argstr rebuildarg "dummy"
disk-relabel dir previous: disk-relabel dir previous:
just -v _device diskRelabel {{ dir }} --argstr previousDiskId {{ previous }} just -v _device diskRelabel {{dir}} --argstr rebuildarg "dummy" --argstr previousDiskId {{previous}}
# Mount the target disk specified by device configuration directory. The 'dir' argument points to a device configuration, e.g. 'nix/os/devices/steveej-live-mmc-SL32G_0x259093f6' # Mount the target disk specified by device configuration directory. The 'dir' argument points to a device configuration, e.g. 'nix/os/devices/steveej-live-mmc-SL32G_0x259093f6'
disk-mount dir: disk-mount dir:
just -v _device diskMount {{ dir }} just -v _device diskMount {{dir}} --argstr rebuildarg "dummy"
# Unmount target disk, specified by device configuration directory # Unmount target disk, specified by device configuration directory
disk-umount dir: disk-umount dir:
just -v _device diskUmount {{ dir }} just -v _device diskUmount {{dir}} --argstr rebuildarg "dummy"
# Perform an offline installation on the mounted target disk, specified by device configuration directory # Perform an offline installation on the mounted target disk, specified by device configuration directory
disk-install dir: _render_templates disk-install dir: _render_templates
just -v _device diskInstall {{ dir }} just -v _device diskInstall {{dir}} --argstr rebuildarg "dummy"
verify-n-unlock sshserver attempts="10": verify-n-unlock sshserver attempts="10":
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
env \ : ${VNCSOCK:?VNCSOCK must be set}
GETPW="just _get_pass_entry Infrastructure/VPS/{{ sshserver }} DRIVE_PW" \ : ${VNCPW:?VNCPW must be set}
SSHOPTS="$(just _get_pass_entry Infrastructure/VPS/{{ sshserver }} SSHOPTS)" \
VNCSOCK="$(just _get_pass_entry Infrastructure/VPS/{{ sshserver }} VNCSOCK)" \
VNCPW="$(just _get_pass_entry Infrastructure/VPS/{{ sshserver }} VNCPW)" \
\
just _verify-n-unlock {{ sshserver }} {{ attempts }}
_verify-n-unlock sshserver attempts: export MAGICK_ARGS="-filter Catrom -density 72 -resample 300 -contrast -normalize -despeckle -type grayscale -sharpen 1 -posterize 3 -negate -gamma 100 -blur 1x65535"
#!/usr/bin/env bash export TESS_ARGS="-c debug_file=/dev/null --psm 4"
set -e
: ${VNCSOCK:?VNCSOCK must be set}
: ${VNCPW:?VNCPW must be set}
export MAGICK_ARGS="-filter Catrom -density 72 -resample 300 -contrast -normalize -despeckle -type grayscale -sharpen 1 -posterize 3 -negate -gamma 100 -blur 1x65535" function send() {
export TESS_ARGS="-c debug_file=/dev/null --psm 4" local what="${1:?need something to send}"
ssh -4 ${SSHOPTS:?need sshopts} root@{{sshserver}} "echo -e ${what}>> /dev/tty0" &>/dev/null
}
function send() { function expect() {
local what="${1:?need something to send}" local what="${1:?need something to expect}"
ssh -4 ${SSHOPTS:?need sshopts} root@{{ sshserver }} "echo -e ${what}>> /dev/tty0" &>/dev/null vncdo --server=${VNCSOCK} --password=${VNCPW} --disable-desktop-resizing --nocursor capture $PWD/screenshot.bmp
} convert ${MAGICK_ARGS} screenshot.bmp screenshot.tiff
tesseract ${TESS_ARGS} screenshot.tiff screenshot
grep --quiet "${what}" screenshot.txt
}
function expect() { function send_and_expect() {
local what="${1:?need something to expect}" local send="${1:?need something to send}"
vncdo --server=${VNCSOCK} --password=${VNCPW} --disable-desktop-resizing --nocursor capture $PWD/screenshot.bmp local expect="${2:?need something to expect}"
convert ${MAGICK_ARGS} screenshot.bmp screenshot.tiff if ! send "${send}"; then
tesseract ${TESS_ARGS} screenshot.tiff screenshot echo warning: cannot send > /dev/stderr
grep --quiet "${what}" screenshot.txt return -1
} fi
expect "${expect}"
}
function send_and_expect() { trap 'E=$?; set +e; rm screenshot.*; echo Exiting...; kill $(jobs -p | cut -d " " -f 4); exit $E' EXIT
local send="${1:?need something to send}"
local expect="${2:?need something to expect}"
if ! send "${send}"; then
echo warning: cannot send > /dev/stderr
return -1
fi
expect "${expect}"
}
trap 'E=$?; set +e; rm screenshot.*; echo Exiting...; kill $(jobs -p | cut -d " " -f 4); exit $E' EXIT for i in `seq 1 {{attempts}}`; do
echo Attempt $i...
expect="$(pwgen -0 12)"
send="'\0033\0143'${expect}"
if send_and_expect "${send}" "${expect}"; then
pipe=$(mktemp -u)
mkfifo ${pipe}
exec 3<>${pipe}
rm ${pipe}
for i in `seq 1 {{ attempts }}`; do echo Verification succeeded at attempt $i. Unlocking remote drive...
echo Attempt $i... ssh -4 ${SSHOPTS} root@{{sshserver}} "cryptsetup-askpass" <&3 &>/dev/null &
expect="$(pwgen -0 12)" eval ${GETPW} | head -n1 >&3
send="'\0033\0143'${expect}"
if send_and_expect "${send}" "${expect}"; then
pipe=$(mktemp -u)
mkfifo ${pipe}
exec 3<>${pipe}
rm ${pipe}
echo Verification succeeded at attempt $i. Unlocking remote drive... for j in `seq 1 120`; do
ssh -4 ${SSHOPTS} root@{{ sshserver }} "cryptsetup-askpass" <&3 &>/dev/null & sleep 0.5
eval ${GETPW} | head -n1 >&3 if expect '— success'; then
echo Unlock successful.
exit 0
fi
done
for j in `seq 1 120`; do echo Unlock failed...
sleep 0.5 exit 1
if expect '— success'; then fi
echo Unlock successful. done
exit 0 echo Verification failed {{attempts}} times. Giving up...
fi exit 1
done
echo Unlock failed...
exit 1
fi
done
echo Verification failed {{ attempts }} times. Giving up...
exit 1
_get_pass_entry path key: _get_pass_entry path key:
pass show {{ path }}| grep -E "^{{ key }}:" | sed -E 's/^[^:]+: *//g' pass show {{path}}| grep -E "^{{key}}:" | awk '{ print $2 }'
# jq -sR 'split("\n") | map(split(":"))' <(pass show Infrastructure/VPS/CFB4ED74 | grep -E "^[A-Za-z_]+:")
run-with-channels +cmds: run-with-channels +cmds:
#!/usr/bin/env bash #!/usr/bin/env bash
source $(just -v _get_nix_path {{ invocation_directory() }}/nix/variables/versions.nix) set -x
{{ cmds }} source $(just -v _get_nix_path {{invocation_directory()}}/nix/variables/versions.nix)
{{cmds}}
install-config config root: install-config config root:
sudo just run-with-channels nixos-install -I nixos-config={{ invocation_directory() }}/{{ config }} --root {{ root }} --no-root-passwd just run-with-channels sudo -E nixos-install -I nixos-config={{invocation_directory()}}/{{config}} --root {{root}} --no-root-passwd
# Switch between gpg-card capable devices which have a copy of the same key # Switch between gpg-card capable devices which have a copy of the same key
switch-gpg-card key-id="6EEFA706CB17E89B": switch-gpg-card:
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# Derived from https://github.com/drduh/YubiKey-Guide/issues/19. # Derived from https://github.com/drduh/YubiKey-Guide/issues/19.
# #
# Connect the new device and then run this script to make it known to gnupg. # Connect the new device and then run this script to make it known to gnupg.
# #
set -xe set -xe
if [[ -n "{{ key-id }}" ]]; then KEY_ID=$(gpg --card-status | rg sec | rg -o '[0-9A-Z]{16}')
KEY_ID="{{ key-id }}"
else
KEY_ID=$(gpg --card-status | rg sec | rg -o '[0-9A-Z]{16}')
fi
# export pubkey and ownertrust # export pubkey and ownertrust
gpg2 --output "${KEY_ID}".pubkey --export "${KEY_ID}" gpg2 --output "${KEY_ID}".pubkey --export "${KEY_ID}"
# if this fails the trust in the key is missing and can be fixed with `gpg --edit-key ${KEY_ID}` # if this fails the trust in the key is missing and can be fixed with `gpg --edit-key ${KEY_ID}`
gpg2 --export-ownertrust | rg "${KEY_ID}" > "${KEY_ID}".ownertrust gpg2 --export-ownertrust | rg "${KEY_ID}" > "${KEY_ID}".ownertrust
# delete the key # delete the key
gpg --yes --delete-secret-and-public-keys "${KEY_ID}" gpg --yes --delete-secret-and-public-keys "${KEY_ID}"
# import pubkey and ownertrust back and cleanup # import pubkey and ownertrust back and cleanup
gpg2 --import "${KEY_ID}".pubkey gpg2 --import "${KEY_ID}".pubkey
gpg2 --import-ownertrust < "${KEY_ID}".ownertrust gpg2 --import-ownertrust < "${KEY_ID}".ownertrust
rm "${KEY_ID}".{pubkey,ownertrust} rm "${KEY_ID}".{pubkey,ownertrust}
# refresh the gpg agent # refresh the gpg agent
gpg-connect-agent "scd serialno" "learn --force" /bye gpg-connect-agent "scd serialno" "learn --force" /bye
gpg --card-status gpg --card-status
# Connect to `remote` UUID, and turn it into a short name
uuid-to-device-name remote:
#!/usr/bin/env bash
set -e -o pipefail
ssh {{ remote }} 'nix run nixpkgs.dmidecode -c dmidecode -s system-uuid' | xxhsum --quiet -H1 | awk '{print $1}'
test-connection:
#! /usr/bin/env nix-shell
#! nix-shell -p curl zsh
#! nix-shell -i zsh
#! nix-shell --pure
while true; do
FAILURE="false"
output=$(
echo "$(date)\n---"
for url in \
"https://172.16.0.1:65443/0.7/gui/#/login/" \
"https://192.168.0.1" \
"http://172.172.171.9" \
"https://172.172.171.10:65443" \
"https://172.172.171.11:65443" \
"https://172.172.171.13:443" \
"https://172.172.171.14:443" \
"http://172.172.171.15:22" \
"http://172.172.171.16:22" \
"https://crates.io" \
"https://holo.host" \
; \
do
print "trying ${url}": $(
curl_output=$(curl --http0.9 -k --head --connect-timeout 0.5 ${url} 2>&1)
# if [ $? -ne 0 ]; then
if [[ "$curl_output" == *timeout* ]]; then
echo failure: $(echo ${curl_output} | tail -n1)
# BUG: outer FAILURE is not set by this
FAILURE="true"
else
echo success
fi
)
done
)
clear
echo ${output}
if [[ ${FAILURE} == "true" ]]; then
echo something failed
tracepath -m5 -n1 172.16.0.1
tracepath -m5 -n1 192.168.0.1
fi
sleep 5
done
cachix-use name:
nix run nixpkgs/nixos-unstable#cachix -- use {{ name }} -m nixos -d nix/os/
update-sops-keys:
for file in $(egrep -lr '"?sops"?:') secrets; do sops updatekeys -y $file; done
deploy-router0-dmz0:
NIX_SSHOPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o CheckHostIP=no" nixos-rebuild switch --impure --flake .\#router0-dmz0 --target-host root@192.168.20.1
ttyusb:
screen -fa /dev/ttyUSB0 115200

View file

@ -1,5 +1,4 @@
# steveej's infra # steveej's infra
This repository helps me to manage all computer infrastructure. This repository helps me to manage all computer infrastructure.
This is mostly achieved with the help of [Nix](https://nixos.org). This is mostly achieved with the help of [Nix](https://nixos.org).
@ -20,7 +19,7 @@ In the unlikely case that you actually read this and have any questions please d
- [ ] development environments - [ ] development environments
- [x] (Semi-) automatic synchronization of important repositories - [x] (Semi-) automatic synchronization of important repositories
- [x] Modification strategy - [x] Modification strategy
The approach is to use vcsh for the dotfiles The approach is to use vcsh for the dotfiles
- [x] dotfiles - [x] dotfiles
- [x] Toplevel Justfile for simple actions - [x] Toplevel Justfile for simple actions
- [x] mount/umount disks - [x] mount/umount disks
@ -30,56 +29,19 @@ In the unlikely case that you actually read this and have any questions please d
- [x] annotate recipes with some documentation - [x] annotate recipes with some documentation
- [x] declare shell.nix with runtime deps - [x] declare shell.nix with runtime deps
- [x] partition/encrypt/format disks - [x] partition/encrypt/format disks
- [x] Maybe make this a nix-overlay - [ ] Document bootstrap process
- [x] refactor as a nix flake and adopt an existing framework
- [x] devShell version
- [x] ~~version templating~~ obsolete due to the usage of flakes
- [x] elias-e525
- [x] steveej-t14
- [x] contabo vps
- [x] sj-pve0
- [x] use an existing secret management framework
- [x] adapt (or abandon?) _just_ recipes
- [x] `rebuild-this-device`
- [x] `update-this-device`
- [x] `rebuild-remote-device`
- [x] `update-remote-device`
evaluate, and understand a path to using these tools in a pull-based fashion:
- [x] [colmena](https://github.com/zhaofengli/colmena)
- bootstrapping: https://github.com/zhaofengli/colmena/issues/68
- [ ] deploy-rs
- [x] 🚧 find a better alternative for the qtile-desktop
current issues:
- floating windows often get lost in the background
- plugging in-/out- screen crashes the desktop
evaluate:
- [x] ~~🚧 gnome3 + pop-shell~~
- [x] ~~leftwm + eww (+ wayland?)~~
- [ ] (Re-)document bootstrap process
- [ ] `apt install sudo cryptsetup` as a requirements on a deb admin machine
- [ ] a new machine - [ ] a new machine
- [ ] an install media - [ ] an install media
- [ ] Design disaster recovery - [ ] Design disaster recovery
- [ ] Automatic synchronization of other state files - see https://gitlab.com/steveeJ/nix-expressions/issues/2 - [ ] Automatic synchronization of other state files - see https://gitlab.com/steveeJ/nix-expressions/issues/2
- [ ] Recycle _\_archived_ - [ ] Recycle *\_archived*
- [ ] container migrations - [x] Maybe make this a nix-overlay
- [ ] ensure DDNS is updated _before_ the containers are started
## Bugs ## Bugs
- [ ] home-manager leaves ~/.gnupg at 0755 - [ ] home-manager leaves ~/.gnupg at 0755
## Usage ## Usage
*(These are reminders for my future self)*
_(These are reminders for my future self)_
``` ```
just --list just --list
@ -88,37 +50,9 @@ just --list
## Bootstrap ## Bootstrap
### A new machine ### A new machine
* ensure the dotfiles repo has a branch with the new machine's hostname
- ensure the dotfiles repo has a branch with the new machine's hostname * boot with an install media and go through setup
- boot with an install media and go through setup
#### Post-Install Setup #### Post-Install Setup
* `gpg2 --edit-card; fetch`
- `chmod --recursive g-rwx,o-rwx ~/.gnupg`
- `gpg2 --edit-card; fetch`
- clone password-manager and infra repositories
- gpg2: ultimately trust my own key
## Swapping out a disk
1. offline-bitwise copy of drive
2. disconnect remove the previous drive
3. replace the driveId in the device's hw.nix
4. run the `just disk-relabel nix/os/devices/<deviceName> <prevDiskId>` command to rename the filesystem and volume group
## Rebuilding an offline system
```
(
sudo cryptsetup open /dev/sdb3 steveej-t14s-cryptroot
sleep 5
sudo mkdir -p /mnt/root
sudo mount /dev/mapper/nvme--WD_BLACK_SN850X_4000GB_2227DT443901-root /mnt/root -o subvol=nixos
sudo mount /dev/sdb2 /mnt/root/boot
sudo mount /dev/mapper/nvme--WD_BLACK_SN850X_4000GB_2227DT443901-root /mnt/root/home -o subvol=home
sudo nixos-install -v --flake .#steveej-t14 --root /mnt/root/ --no-root-password
)
```

View file

@ -0,0 +1,89 @@
import /home/steveej/src/github/NixOS/nixpkgs/default.nix {
crossSystem = rec {
config = "armv7l-unknown-linux-gnueabi";
bigEndian = false;
arch = "arm";
float = "hard";
fpu = "vfpv3-d16";
withTLS = true;
libc = "glibc";
platform = {
name = "armv7l-hf-multiplatform";
gcc = {
arch = "armv7-a";
fpu = "neon";
float = "hard";
};
kernelMajor = "2.6"; # Using "2.6" enables 2.6 kernel syscalls in glibc.
kernelHeadersBaseConfig = "multi_v7_defconfig";
kernelBaseConfig = "multi_v7_defconfig";
kernelArch = "arm";
kernelDTB = true;
kernelAutoModules = false;
kernelExtraConfig = ''
NAMESPACES y
BTRFS_FS y
BTRFS_FS_POSIX_ACL y
OVERLAY_FS y
FUSE_FS y
'';
kernelTarget = "zImage";
uboot = null;
};
openssl.system = "linux-generic32";
gcc = {
arch = "armv7-a";
fpu = "neon";
float = "hard";
};
};
}
# pkgs.config = {
# packageOverrides = super: let self = super.pkgs; in {
# linux_4_0 = super.linux_3_18.override {
# kernelPatches = super.linux_3_18.kernelPatches ++ [
# # we'll also add one of our own patches
# { patch = ./dts.patch; name = "dts-fix"; }
# ];
#
# # add "CONFIG_PPP_FILTER y" option to the set of kernel options
# extraConfig = ''
# HAVE_IMX_ANATOP y
# HAVE_IMX_GPC y
# HAVE_IMX_MMDC y
# HAVE_IMX_SRC y
# SOC_IMX6 y
# SOC_IMX6Q y
# SOC_IMX6SL y
# PCI_IMX6 y
# ARM_IMX6Q_CPUFREQ y
# IMX_WEIM y
# AHCI_IMX y
# SERIAL_IMX y
# SERIAL_IMX_CONSOLE y
# I2C_IMX y
# SPI_IMX y
# PINCTRL_IMX y
# PINCTRL_IMX6Q y
# PINCTRL_IMX6SL y
# POWER_RESET_IMX y
# IMX_THERMAL y
# IMX2_WDT y
# IMX_IPUV3_CORE y
# DRM_IMX y
# DRM_IMX_FB_HELPER y
# DRM_IMX_PARALLEL_DISPLAY y
# DRM_IMX_TVE y
# DRM_IMX_LDB y
# DRM_IMX_IPUV3 y
# DRM_IMX_HDMI y
# MMC_SDHCI_ESDHC_IMX y
# IMX_SDMA y
# PWM_IMX y
# DEBUG_IMX6Q_UART y
#
# PPP_FILTER y
# '';
# };
# };
# };

View file

@ -0,0 +1,89 @@
{ gitpkgs ? import /home/steveej/src/github/NixOS/nixpkgs {}
, pkgs ? gitpkgs
, name ? "generic"
, version
, extraBuildInputs ? []
, extraShellHook ? ""
}:
let
go = builtins.getAttr "go_${version}" pkgs;
commonVimRC = ''
let g:tagbar_type_go = {
\ 'ctagstype' : 'go',
\ 'kinds' : [
\ 'p:package',
\ 'i:imports:1',
\ 'c:constants',
\ 'v:variables',
\ 't:types',
\ 'n:interfaces',
\ 'w:fields',
\ 'e:embedded',
\ 'm:methods',
\ 'r:constructor',
\ 'f:functions'
\ ],
\ 'sro' : '.',
\ 'kind2scope' : {
\ 't' : 'ctype',
\ 'n' : 'ntype'
\ },
\ 'scope2kind' : {
\ 'ctype' : 't',
\ 'ntype' : 'n'
\ },
\ 'ctagsbin' : 'gotags',
\ 'ctagsargs' : '-sort -silent'
\ }
" vim-go {
let g:go_highlight_functions = 1
let g:go_highlight_methods = 1
let g:go_highlight_structs = 1
let g:go_highlight_interfaces = 1
let g:go_highlight_operators = 1
let g:go_highlight_build_constraints = 1
let g:go_fmt_command = 'gofmt'
let g:go_fmt_options= '-s'
let g:go_def_mode = 'godef'
let g:go_def_reuse_buffer = 0
au FileType go nmap <Leader>gds <Plug>(go-def-split)
au FileType go nmap <Leader>gdv <Plug>(go-def-vertical)
au FileType go nmap <Leader>gdt <Plug>(go-def-tab)
au FileType go nmap <Leader>gi <Plug>(go-imports)
" }
'';
buildInputs = with pkgs; [
glibc.out
glibc.static
go
gotools
#gotools.bin
#gocode.bin
#godef godef.bin
godep
#godep.bin
gox.bin
#ginkgo ginkgo.bin
#gomega
# ( import ./vim-go.nix { pkgs=gitpkgs; commonRC=commonVimRC; } )
# ( import ./neovim-go.nix { pkgs=gitpkgs; commonRC=commonVimRC; } )
];
in pkgs.stdenv.mkDerivation {
inherit name;
buildInputs = extraBuildInputs ++ buildInputs;
shellHook = ''
goname=${go.version}_$name
# FIXME: setPS1 $goname
export GOROOT=${go}/share/go
export GOPATH="$HOME/.gopath_$goname"
export PATH="$HOME/.gopath_$goname/bin:$PATH"
unset name
unset SSL_CERT_FILE
${extraShellHook}
'';
}

View file

@ -0,0 +1,15 @@
{ commonRC, ... } @ args :
(import ../../pkg-configuration/vim-derivates/neovim.nix args // {
additionalRC = commonRC + ''
" deoplete {
let g:deoplete#enable_at_startup = 1
let g:deoplete#enable_smart_case = 1
" }
'';
additionalPlugins = [
"deoplete-go"
"deoplete-nvim"
"vim-go"
];
})

View file

@ -0,0 +1,26 @@
{ gitpkgs ? import /home/steveej/src/github/NixOS/nixpkgs {}
, pkgs ? gitpkgs
, name ? "generic"
, version ? "Stable"
, extraBuildInputs ? []
}:
let
commonVimRC = ''
'';
in pkgs.stdenv.mkDerivation {
inherit name;
buildInputs = with pkgs; [
( import ./vim-pandoc.nix { pkgs=gitpkgs; commonRC=commonVimRC; })
pandoc
texlive.combined.scheme-medium
python27Packages.pandocfilters
python27Packages.htmltreediff
python27Packages.html5lib
python27Packages.dbus-python
] ++ extraBuildInputs;
shellHook = ''
pandocname=pandoc_${pkgs.pandoc.version}
setPS1 $pandocname
unset name
'';
}

View file

@ -0,0 +1,72 @@
{
pkgs ? import /home/steveej/src/github/NixOS/nixpkgs {},
mkGoEnv ? import ./go.nix,
rktPath,
}:
let
rktBasebuildInputs = with pkgs; [
glibc.out
glibc.static
autoreconfHook
gnupg1
squashfsTools
cpio
tree
intltool
libtool
pkgconfig
libgcrypt
gperf
libcap
libseccomp
libzip
eject
iptables
bc
acl
trousers
systemd
];
extraShellHook = ''
TARGET=$GOPATH/src/github.com/coreos/rkt
if [[ -e ${rktPath}/rkt/rkt.go ]]; then
pushd ${rktPath}
else
echo rktPath must be run the rkt repository clone, but got '${rktPath}'
exit 1
fi
if ! [[ -e $TARGET/rkt/rkt.go ]]; then
mkdir -p $TARGET
echo $PWD
sudo -E mount -o bind $PWD $TARGET
fi
pushd $TARGET
'';
in {
go15 = mkGoEnv {
inherit pkgs;
name = "rktGo15";
version = "1_5";
extraBuildInputs = rktBasebuildInputs;
inherit extraShellHook;
};
go16 = mkGoEnv {
inherit pkgs;
name = "rktGo16";
version = "1_6";
extraBuildInputs = rktBasebuildInputs;
inherit extraShellHook;
};
go17 = mkGoEnv {
inherit pkgs;
name = "rktGo17";
version = "1_7";
extraBuildInputs = rktBasebuildInputs;
inherit extraShellHook;
};
}

View file

@ -0,0 +1 @@
eval "$(lorri direnv)"

View file

@ -0,0 +1,32 @@
{ gitpkgs ? import /home/steveej/src/github/NixOS/nixpkgs {}
, pkgs ? gitpkgs
, name ? "generic"
, version ? "Stable"
, extraBuildInputs ? []
}:
let
rustPackages = builtins.getAttr "rust${version}" pkgs;
rustc = rustPackages.rustc;
rustShellHook = { rustc, name }: ''
rustname=rust_${rustc.version}_${name}
setPS1 $rustname
unset name
'';
commonVimRC = ''
'';
in pkgs.stdenv.mkDerivation {
inherit name;
buildInputs = with rustPackages;[
( import ./vim-rust.nix { pkgs=gitpkgs; commonRC=commonVimRC;
inherit rustc;
racerd=pkgs.rustracerd;
})
rustc cargo
] ++ [
pkgs.rustfmt
] ++ extraBuildInputs;
shellHook = (rustShellHook){
inherit name;
inherit rustc;
};
}

View file

@ -0,0 +1,20 @@
{ commonRC, ... } @ args :
import ../../pkg-configuration/vim-derivates/vim.nix (args // {
name = "vim-for-go";
additionalRC = commonRC + ''
" Disable AutoComplPop.
let g:acp_enableAtStartup = 0
" Use neocomplete.
let g:neocomplete#enable_at_startup = 1
" Use smartcase.
let g:neocomplete#enable_smart_case = 1
if !exists('g:neocomplete#sources#omni#input_patterns')
let g:neocomplete#sources#omni#input_patterns = {}
endif
'';
additionalPlugins = [
"neocomplete"
"vim-go"
];
})

View file

@ -0,0 +1,22 @@
{ commonRC
,
... } @ args :
import ../../pkg-configuration/vim-derivates/vim.nix (args // {
name = "vim-for-pandoc";
additionalRC = commonRC + ''
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0
'';
additionalPlugins = [
"vim-pandoc"
"vim-pandoc-syntax"
"vimpreviewpandoc"
];
})

View file

@ -0,0 +1,46 @@
{ commonRC
, rustc
, racerd,
... } @ args :
import ../../pkg-configuration/vim-derivates/vim.nix (args // {
name = "vim-for-rust";
additionalRC = commonRC + ''
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0
" tagbar
let g:tagbar_type_rust = {
\ 'ctagstype' : 'rust',
\ 'kinds' : [
\'T:types,type definitions',
\'f:functions,function definitions',
\'g:enum,enumeration names',
\'s:structure names',
\'m:modules,module names',
\'c:consts,static constants',
\'t:traits,traits',
\'i:impls,trait implementations',
\]
\}
let g:syntastic_rust_checkers = ["rustc"]
"rustfmt
let g:rustfmt_autosave = 1
let g:ycm_auto_trigger = 1
let g:ycm_rust_src_path = '${rustc.src}/src'
let g:ycm_racerd_binary_path = '${racerd.out}/bin/racerd'
'';
additionalPlugins = [
"rust-vim"
];
})

View file

@ -0,0 +1,42 @@
{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
name = "devfhs";
multiPkgs = pkgs: (with pkgs; [
android-udev-rules
sudo
gawk
bzip2
file
gcc
getopt
git
gnumake
ncurses
openssl
patch
perl
pkgconfig
python
openssh
subversion
unzip
wget
which
vim
zlib
libusb
libusb1
systemd
strace
swt
xorg.libXtst
glib
gtk2
gnome.gtk
]);
profile = ''
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/lib64:/lib32:/usr/lib32:/usr/lib64:${pkgs.xorg.libXtst}/lib:${pkgs.glib}/lib:${pkgs.gtk2}/lib
'';
runScript = "bash";
}).env

View file

@ -0,0 +1,38 @@
{ pkgs ? import <nixpkgs> {} }:
(pkgs.buildFHSUserEnv {
name = "everydayFHS";
targetPkgs = pkgs: (with pkgs;
[ which
gitFull
zsh
file
direnv
xdg_utils
xsel
vscode
# vscode live share
gnome3.gcr
libgnome_keyring3
liburcu
libunwind
lttng-ust
curl
openssl
libkrb5
libuuid
icu
zlib
libsecret
]);
multiPkgs = pkgs: (with pkgs;
[
]);
profile = ''
export SHELL=/bin/zsh
'';
# FIXME runScript = "$SHELL";
}).env

View file

@ -0,0 +1,10 @@
{ config
, pkgs
, ... } @ args:
{
environment.systemPackages = [
pkgs.xsel
(import ../../../pkg-configuration/vim-derivates/neovim.nix args)
];
}

View file

@ -0,0 +1,9 @@
{ pkgs
, ... } @ args:
{
environment.systemPackages = [
pkgs.xsel
(import ../../../pkg-configuration/vim-derivates/vim.nix (args // { name = "vim"; }))
];
}

View file

@ -0,0 +1,20 @@
{ config
, pkgs
, ... }:
let
passwords = import ../passwords.crypt.nix;
keys = import ../keys.nix;
inherit (import ../lib) mkUser;
in {
users.mutableUsers = false;
users.defaultUserShell = pkgs.zsh;
users.extraUsers.steveej = mkUser {
uid = 1000;
hashedPassword = passwords.users.steveej;
};
security.pam.enableU2F = true;
security.pam.services.steveej.u2fAuth = true;
}

View file

@ -0,0 +1,98 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
d0:17:d1:86:81:d4:f1:28
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=North Carolina, L=Raleigh, O=Katello, OU=SomeOrgUnit, CN=sat-r220-02.lab.eng.rdu2.redhat.com
Validity
Not Before: Nov 2 15:37:13 2018 GMT
Not After : Jan 17 15:37:13 2038 GMT
Subject: C=US, ST=North Carolina, L=Raleigh, O=Katello, OU=SomeOrgUnit, CN=sat-r220-02.lab.eng.rdu2.redhat.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ba:03:39:e3:af:3e:c7:89:bd:d0:07:66:83:18:
9c:c0:da:56:e8:bb:37:fe:03:67:94:9a:1c:9d:47:
da:6a:a7:6e:56:6d:0a:73:05:79:0e:44:61:71:78:
33:33:79:b1:ce:a6:9d:87:d0:01:81:10:d5:e3:21:
0f:d0:e9:ef:86:dc:13:34:62:42:47:81:f6:ce:d8:
78:de:00:0c:a6:5d:25:d8:cc:72:6a:c4:7c:e1:5b:
84:2b:e2:3c:b6:51:7e:8e:e6:e1:55:7d:b4:c8:e7:
98:76:eb:20:15:48:6f:2e:91:ca:b7:17:d4:d9:76:
5b:40:1c:7e:4c:0b:6f:2c:63:fa:78:c5:8b:b5:36:
b6:01:d9:da:58:a9:06:76:32:18:ca:b2:7c:2d:aa:
4f:4e:f5:67:30:4c:a6:a3:e3:ef:7c:1d:d3:67:de:
da:a5:b9:57:0d:74:01:c3:24:a9:03:61:98:91:c2:
1f:1d:a4:36:d2:a6:f4:95:6f:01:6a:99:41:ea:f0:
8c:7a:7d:a0:0d:34:93:a3:80:cb:19:fb:1a:e1:c4:
0b:60:5c:8d:33:ea:90:ed:98:d2:2a:06:6e:a2:02:
1f:f8:2c:1e:d4:d0:d4:8f:93:8d:c9:fe:21:39:6a:
5b:7b:60:5d:2a:9c:1e:3f:51:31:b1:be:56:28:cb:
4d:cd
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Key Usage:
Digital Signature, Key Encipherment, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Netscape Cert Type:
SSL Server, SSL CA
Netscape Comment:
Katello SSL Tool Generated Certificate
X509v3 Subject Key Identifier:
72:CD:88:06:03:FE:5D:A2:D0:B3:20:C7:37:74:06:84:A8:A8:13:DF
X509v3 Authority Key Identifier:
keyid:72:CD:88:06:03:FE:5D:A2:D0:B3:20:C7:37:74:06:84:A8:A8:13:DF
DirName:/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=sat-r220-02.lab.eng.rdu2.redhat.com
serial:D0:17:D1:86:81:D4:F1:28
Signature Algorithm: sha256WithRSAEncryption
70:fe:c6:9f:1a:62:e8:b0:a6:25:df:e8:51:6c:e9:08:48:00:
72:2b:d8:a2:95:6e:57:01:8e:2a:9c:a0:14:f8:c9:8a:e3:5d:
48:64:f9:0f:81:e7:3e:b1:c2:cb:a0:ec:55:d6:e4:7f:c0:46:
7b:bc:66:15:88:61:73:3b:ea:9e:ea:cb:32:79:35:bc:dc:eb:
6f:d8:d0:89:c2:ae:fd:02:43:cd:e0:38:d6:9c:16:d7:6d:bb:
2c:73:53:3c:82:56:51:d8:96:71:e1:28:49:31:be:fb:ed:23:
08:e5:8d:eb:48:c7:25:5d:ef:0e:30:22:d3:93:7f:f1:66:b8:
7f:8f:5c:d2:97:e7:13:0e:5b:06:1d:fd:97:1d:a5:24:93:d9:
8a:d2:ba:51:00:b3:71:c8:61:da:79:31:64:75:96:d0:b8:d8:
45:57:24:40:2f:11:d6:63:70:f5:bf:8d:fc:7f:1b:b9:ad:e0:
16:6a:89:9b:6a:0c:d3:e3:b5:14:b4:5c:36:8a:b0:dd:15:4d:
4e:77:e9:9b:29:df:e9:e3:27:dc:87:f8:6e:5d:a9:14:42:5c:
8b:7b:13:9d:8b:c7:7a:4d:6d:52:7e:5f:02:9f:21:15:de:98:
5d:f5:25:30:d3:fa:b4:34:f3:ff:8d:36:c7:e3:1c:d3:b1:f7:
b6:7b:ad:40
-----BEGIN CERTIFICATE-----
MIIFEDCCA/igAwIBAgIJANAX0YaB1PEoMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD
VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVp
Z2gxEDAOBgNVBAoMB0thdGVsbG8xFDASBgNVBAsMC1NvbWVPcmdVbml0MSwwKgYD
VQQDDCNzYXQtcjIyMC0wMi5sYWIuZW5nLnJkdTIucmVkaGF0LmNvbTAeFw0xODEx
MDIxNTM3MTNaFw0zODAxMTcxNTM3MTNaMIGOMQswCQYDVQQGEwJVUzEXMBUGA1UE
CAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVpZ2gxEDAOBgNVBAoMB0th
dGVsbG8xFDASBgNVBAsMC1NvbWVPcmdVbml0MSwwKgYDVQQDDCNzYXQtcjIyMC0w
Mi5sYWIuZW5nLnJkdTIucmVkaGF0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALoDOeOvPseJvdAHZoMYnMDaVui7N/4DZ5SaHJ1H2mqnblZtCnMF
eQ5EYXF4MzN5sc6mnYfQAYEQ1eMhD9Dp74bcEzRiQkeB9s7YeN4ADKZdJdjMcmrE
fOFbhCviPLZRfo7m4VV9tMjnmHbrIBVIby6RyrcX1Nl2W0AcfkwLbyxj+njFi7U2
tgHZ2lipBnYyGMqyfC2qT071ZzBMpqPj73wd02fe2qW5Vw10AcMkqQNhmJHCHx2k
NtKm9JVvAWqZQerwjHp9oA00k6OAyxn7GuHEC2BcjTPqkO2Y0ioGbqICH/gsHtTQ
1I+Tjcn+ITlqW3tgXSqcHj9RMbG+VijLTc0CAwEAAaOCAW0wggFpMAwGA1UdEwQF
MAMBAf8wCwYDVR0PBAQDAgGmMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjARBglghkgBhvhCAQEEBAMCAkQwNQYJYIZIAYb4QgENBCgWJkthdGVsbG8gU1NM
IFRvb2wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRyzYgGA/5dotCz
IMc3dAaEqKgT3zCBwwYDVR0jBIG7MIG4gBRyzYgGA/5dotCzIMc3dAaEqKgT36GB
lKSBkTCBjjELMAkGA1UEBhMCVVMxFzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRAw
DgYDVQQHDAdSYWxlaWdoMRAwDgYDVQQKDAdLYXRlbGxvMRQwEgYDVQQLDAtTb21l
T3JnVW5pdDEsMCoGA1UEAwwjc2F0LXIyMjAtMDIubGFiLmVuZy5yZHUyLnJlZGhh
dC5jb22CCQDQF9GGgdTxKDANBgkqhkiG9w0BAQsFAAOCAQEAcP7Gnxpi6LCmJd/o
UWzpCEgAcivYopVuVwGOKpygFPjJiuNdSGT5D4HnPrHCy6DsVdbkf8BGe7xmFYhh
czvqnurLMnk1vNzrb9jQicKu/QJDzeA41pwW1227LHNTPIJWUdiWceEoSTG+++0j
COWN60jHJV3vDjAi05N/8Wa4f49c0pfnEw5bBh39lx2lJJPZitK6UQCzcchh2nkx
ZHWW0LjYRVckQC8R1mNw9b+N/H8bua3gFmqJm2oM0+O1FLRcNoqw3RVNTnfpmynf
6eMn3If4bl2pFEJci3sTnYvHek1tUn5fAp8hFd6YXfUlMNP6tDTz/402x+Mc07H3
tnutQA==
-----END CERTIFICATE-----

View file

@ -4,9 +4,11 @@
# Having pkgs default to <nixpkgs> is fine though, and it lets you use short # Having pkgs default to <nixpkgs> is fine though, and it lets you use short
# commands such as: # commands such as:
# nix-build -A mypackage # nix-build -A mypackage
{ pkgs ? import <nixpkgs> {} }:
{ {
pkgs ? import <nixpkgs> { }, overlays = import ./nix/overlays;
}:
{
pkgs = import ./nix/pkgs { inherit pkgs; }; pkgs = import ./nix/pkgs { inherit pkgs; };
} }

1491
flake.lock generated

File diff suppressed because it is too large Load diff

388
flake.nix
View file

@ -1,388 +0,0 @@
# flake.nix
{
inputs = {
# TODO: where has this been used?
# dotfiles = {
# url = "git+https://forgejo.www.stefanjunker.de/steveej/dotfiles.git";
# flake = false;
# };
# flake and infra basics
nixpkgs-2211.url = "github:nixos/nixpkgs/nixos-22.11";
radicalePkgs.follows = "nixpkgs-2211";
nixpkgs-2411.url = "github:nixos/nixpkgs/nixos-24.11";
nixpkgs-2505.url = "github:nixos/nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs.follows = "nixpkgs-2505";
flake-parts.url = "github:hercules-ci/flake-parts";
get-flake.url = "github:ursi/get-flake";
srvos.url = "github:numtide/srvos";
srvos.inputs.nixpkgs.follows = "nixpkgs";
nixos-anywhere.url = "github:numtide/nixos-anywhere/main";
nixos-anywhere.inputs.nixpkgs.follows = "nixpkgs";
disko.follows = "nixos-anywhere/disko";
nixpkgs-wayland.url = "github:nix-community/nixpkgs-wayland";
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
nixpkgs-vscodium.url = "github:nixos/nixpkgs/nixos-unstable";
# needs to be in sync with `vscodium --version` from `nixpkgs-vscodium`
openvscode-server.url = "github:gitpod-io/openvscode-server/openvscode-server-v1.88.1";
openvscode-server.flake = false;
colmena = {
url = "github:zhaofengli/colmena";
inputs.nixpkgs.follows = "nixpkgs";
};
# libraries for building applications
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
crane.url = "github:ipetkov/crane";
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# applications
aphorme_launcher = {
url = "github:Iaphetes/aphorme_launcher/main";
flake = false;
};
yofi = {
url = "github:l4l/yofi/master";
flake = true;
inputs.nixpkgs.follows = "nixpkgs";
};
ofi-pass = {
url = "github:sereinity/ofi-pass";
flake = false;
};
jay = {
url = "github:mahkoh/jay";
flake = false;
};
prs = {
# url = "gitlab:timvisee/prs/v0.5.2";
url = "gitlab:timvisee/prs/07f17a93d19fb6bc92c9c7f3ae3f5cc750b1f973";
flake = false;
};
rperf = {
url = "github:steveej-forks/rperf";
flake = false;
};
# nixpkgs-logseq.url = "github:steveej-forks/nixpkgs/logseq-linux-arm64-selfbuilt-appimage";
espanso = {
flake = false;
url = "github:espanso/espanso/db97658d1d80697a635b57801696c594eacf057b";
};
nix4vscode = {
url = "github:nix-community/nix4vscode";
# inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
# TODO: pin to nixos-24.11 once available
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs";
};
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nixago = {
url = "github:jmgilman/nixago";
inputs.nixpkgs.follows = "nixpkgs";
};
nur = {
url = "github:nix-community/NUR";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs-gimp.url = "github:jtojnar/nixpkgs/gimp-meson";
};
outputs =
inputs@{
self,
flake-parts,
nixpkgs,
...
}:
let
inherit (nixpkgs) lib;
systems = [
"x86_64-linux"
"aarch64-linux"
];
in
flake-parts.lib.mkFlake { inherit inputs; } (
{ withSystem, ... }:
{
flake.colmenaHive = inputs.colmena.lib.makeHive (
lib.lists.foldl (sum: cur: lib.attrsets.recursiveUpdate sum cur)
{ meta.nixpkgs = import inputs.nixpkgs.outPath { system = builtins.elemAt systems 0; }; }
# FIXME: this doesn't seem to work to apply overlays into a node's nixpkgs import
# try this instead: https://github.com/zhaofengli/colmena/issues/60#issuecomment-1510496861
(
builtins.map
(
nodeName:
import ./nix/os/devices/${nodeName} {
inherit nodeName;
repoFlake = self;
repoFlakeWithSystem = withSystem;
nodeFlake = self.inputs.get-flake (self + "/nix/os/devices/${nodeName}");
}
)
[
"steveej-t14"
"steveej-x13s"
"steveej-x13s-rmvbl"
"elias-e525"
# "justyna-p300"
# "srv0-dmz0"
# "router0-dmz0"
"router0-ifog"
"router0-hosthatch"
"sj-srv1"
]
)
);
flake.lib = {
inherit withSystem;
prsFn =
{
lib,
prs,
skim,
rustPlatform,
makeWrapper,
}:
prs.overrideAttrs (attrs: rec {
pname = "prs";
src = self.inputs.prs;
version = self.inputs.prs.shortRev;
nativeBuildInputs = attrs.nativeBuildInputs ++ [
makeWrapper
];
cargoDeps = rustPlatform.fetchCargoVendor {
inherit src;
hash = "sha256-6kCqrwcHFy7cEl2JM+CzTWDM9abepumzdcJLq1ChzUk=";
};
postFixup = ''
wrapProgram $out/bin/prs \
--prefix PATH : ${lib.makeBinPath [ skim ]}
'';
});
};
# this makes nixos-anywhere work
flake.nixosConfigurations =
let
colmenaHiveNodes = self.outputs.colmenaHive.nodes;
router0-dmz0 = (inputs.get-flake (self + "/nix/os/devices/router0-dmz0")).nixosConfigurations;
in
colmenaHiveNodes
// {
router0-dmz0 = router0-dmz0.native;
# for now deploy directly with:
# nixos-rebuild switch --flake .\#router0-dmz0_cross --build-host localhost --target-host root@192.168.10.1
router0-dmz0_cross = router0-dmz0.cross;
steveej-x13s_cross =
(inputs.get-flake (self + "./nix/os/devices/steveej-x13s")).nixosConfigurations.cross;
steveej-x13s-rmvbl_cross =
(inputs.get-flake ./nix/os/devices/steveej-x13s-rmvbl).nixosConfigurations.cross;
};
inherit systems;
perSystem =
{
self',
inputs',
system,
config,
lib,
pkgs,
...
}:
{
imports = [ ./nix/modules/flake-parts/perSystem/default.nix ];
packages =
let
dcpj4110dw = pkgs.callPackage (self + /nix/pkgs/dcpj4110dw) { };
craneLibFn = (inputs.crane.mkLib inputs.nixpkgs.legacyPackages.${system}).overrideToolchain;
craneLib = craneLibFn inputs'.fenix.packages.stable.toolchain;
local-xwayland = pkgs.writeShellScriptBin "local-xwayland" ''
set -x
${pkgs.wayland-proxy-virtwl}/bin/wayland-proxy-virtwl \
--wayland-display=wayland-3 \
--xwayland-binary=${pkgs.xwayland}/bin/Xwayland \
--x-display=0 \
# --x-unscale=3 \
--verbose
'';
in
{
dcpj4110dwDriver = dcpj4110dw.driver;
dcpj4110dwCupswrapper = dcpj4110dw.cupswrapper;
inherit (inputs'.colmena.packages) colmena;
nomad = inputs'.nixpkgs-unstable.legacyPackages.nomad_1_6;
ledger-live-desktop-wrapped = pkgs.writeShellScriptBin "ledger-live-desktop-wrapped" ''
set -x
pkill -9 wayland-proxy-v
export NIXOS_OZONE_WL=""
${pkgs.wayland-proxy-virtwl}/bin/wayland-proxy-virtwl \
--wayland-display=wayland-3 \
--xwayland-binary=${pkgs.xwayland}/bin/Xwayland \
--x-display=3 \
&
# --x-unscale=3 \
#--verbose \
export PROXYPID="$!"
trap "kill -9 \$PROXYPID" EXIT
# trap "pkill -9 wayland-proxy-v" EXIT
env \
WAYLAND_DISPLAY=wayland-3 \
DISPLAY=:3 \
ledger-live-desktop
'';
syncthing-container-webui = pkgs.writeShellScriptBin "reverse-port-forward-syncthing-container" ''
ssh root@${self.colmena.sj-vps-htz0.deployment.targetHost} -L 8385:syncthing.containers:8384
'';
rperf = craneLib.buildPackage {
src = inputs.rperf;
nativeBuildInputs = [ pkgs.pkg-config ];
buildInputs = [ ];
};
inherit local-xwayland;
inherit (inputs'.nixpkgs-gimp.legacyPackages) gimp;
};
formatter =
let
settingsNix = {
projectRootFile = ".git/config";
package = inputs'.nixpkgs-unstable.legacyPackages.treefmt2;
programs = {
nixfmt.enable = true;
deadnix.enable = true;
statix.enable = true;
shfmt.enable = true;
shellcheck.enable = true;
prettier.enable = true;
just = {
enable = true;
includes = [
"*/Justfile"
"Justfile"
];
};
} // pkgs.lib.optionalAttrs (pkgs.system != "riscv64-linux") { shellcheck.enable = true; };
settings = {
global.excludes = [
"LICENSE"
"secrets/"
".git-crypt/"
# unsupported extensions
"*.{enc,gif,png,svg,tape,mts,lock,mod,sum,toml,env,envrc,gitignore}"
];
formatter = {
deadnix = {
priority = 1;
options = [ "--no-underscore" ];
};
nixfmt = {
priority = 2;
};
statix = {
priority = 3;
};
prettier = {
options = [
"--tab-width"
"2"
];
includes = [ "*.{css,html,js,json,jsx,md,mdx,scss,ts,yaml}" ];
};
};
};
};
eval = inputs.treefmt-nix.lib.evalModule pkgs settingsNix;
in
eval.config.build.wrapper.overrideAttrs (_: {
passthru = {
inherit (eval.config) package settings;
};
});
devShells =
let
all = import ./nix/devShells.nix {
inherit
self
self'
inputs'
pkgs
;
};
in
all
// {
default = all.develop;
};
};
}
);
}

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -xe set -xe
[ -n "$NAME" ] [ ! -z "$NAME" ]
nix-build . --show-trace -A "$NAME" nix-build . --show-trace -A "$NAME"
docker image rm "$NAME":latest --force docker image rm "$NAME":latest --force
docker load -i result docker load -i result

View file

@ -1,10 +1,14 @@
{ { pkgs ? import <nixpkgs> {}
pkgs ? import <nixpkgs> { },
}: }:
let let
baseEnv = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; baseEnv = [
in "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
rec { ];
in rec {
base = pkgs.dockerTools.buildImage rec { base = pkgs.dockerTools.buildImage rec {
name = "base"; name = "base";
@ -37,52 +41,50 @@ rec {
}; };
}; };
s3ql = s3ql = let
let entrypoint = pkgs.writeScript "entrypoint" ''
entrypoint = pkgs.writeScript "entrypoint" '' #!${pkgs.stdenv.shell}
#!${pkgs.stdenv.shell}
if [ -z "$S3QL_BUCKET" ]; then if [ -z "$S3QL_BUCKET" ]; then
echo S3QL_BUCKET not set echo S3QL_BUCKET not set
exit 1 exit 1
fi fi
if [ -z "$S3QL_STORAGE_URL" ]; then if [ -z "$S3QL_STORAGE_URL" ]; then
echo S3QL_STORAGE_URL not set echo S3QL_STORAGE_URL not set
exit 1 exit 1
fi fi
if [ -z "$S3QL_CACHESIZE" ]; then if [ -z "$S3QL_CACHESIZE" ]; then
echo S3QL_CACHESIZE not set echo S3QL_CACHESIZE not set
exit 1 exit 1
fi fi
set -x set -x
if [ "$S3QL_SKIP_FSCK" != "1" ]; then if [ "$S3QL_SKIP_FSCK" != "1" ]; then
fsck.s3ql \ fsck.s3ql \
--authfile $S3QL_AUTHINFO2 \ --authfile $S3QL_AUTHINFO2 \
--log none \
--cachedir $S3QL_CACHE_DIR \
$S3QL_STORAGE_URL
fi
exec mount.s3ql \
--cachedir "$S3QL_CACHE_DIR" \
--authfile "$S3QL_AUTHINFO2" \
--cachesize "$S3QL_CACHESIZE" \
--fg \
--compress lzma-6 \
--threads 4 \
--log none \ --log none \
--allow-root \ --cachedir $S3QL_CACHE_DIR \
"$S3QL_STORAGE_URL" \ $S3QL_STORAGE_URL
/bucket fi
# FIXME: touch .isbucket after mount exec mount.s3ql \
''; --cachedir "$S3QL_CACHE_DIR" \
in --authfile "$S3QL_AUTHINFO2" \
pkgs.dockerTools.buildImage { --cachesize "$S3QL_CACHESIZE" \
--fg \
--compress lzma-6 \
--threads 4 \
--log none \
--allow-root \
"$S3QL_STORAGE_URL" \
/bucket
# FIXME: touch .isbucket after mount
'';
in pkgs.dockerTools.buildImage {
name = "s3ql"; name = "s3ql";
fromImage = interactive_base; fromImage = interactive_base;
contents = [ contents = [
@ -93,11 +95,11 @@ rec {
runAsRoot = '' runAsRoot = ''
#!${pkgs.stdenv.shell} #!${pkgs.stdenv.shell}
mkdir -p /usr/bin mkdir -p /usr/bin
cp -a ${pkgs.fuse}/bin/fusermount /usr/bin cp -a ${pkgs.fuse}/bin/fusermount /usr/bin
chmod +s /usr/bin/fusermount chmod +s /usr/bin/fusermount
echo user_allow_other >> /etc/fuse.conf echo user_allow_other >> /etc/fuse.conf
''; '';
config = { config = {
Env = baseEnv ++ [ Env = baseEnv ++ [
"HOME=/home/s3ql" "HOME=/home/s3ql"
@ -107,49 +109,49 @@ rec {
]; ];
Cmd = [ entrypoint ]; Cmd = [ entrypoint ];
Volumes = { Volumes = {
"/var/cache/s3ql" = { }; "/var/cache/s3ql" = {};
"/etc/s3ql/authinfo2" = { }; "/etc/s3ql/authinfo2" = {};
"/buckets" = { }; "/buckets" = {};
"/tmp" = { }; "/tmp" = {};
};
}; };
}; };
};
syncthing = syncthing = let
let entrypoint = pkgs.writeScript "entrypoint" ''
entrypoint = pkgs.writeScript "entrypoint" '' #!${pkgs.stdenv.shell}
#!${pkgs.stdenv.shell} set -x
set -x if [ ! -e /data/.isbucket ]; then
if [ ! -e /data/.isbucket ]; then echo ERROR: Bucket not mounted at /data
echo ERROR: Bucket not mounted at /data exit 1
exit 1 fi
fi
if [ -z "$SYNCTHING_GUI_ADDRESS" ]; then if [ -z "$SYNCTHING_GUI_ADDRESS" ]; then
echo ERROR: SYNCTHING_GUI_ADDRESS is not set echo ERROR: SYNCTHING_GUI_ADDRESS is not set
exit 1 exit 1
fi fi
if [ ! -w "$SYNCTHING_HOME" ]; then if [ ! -w "$SYNCTHING_HOME" ]; then
echo ERROR : SYNCTHING_HOME is not writable echo ERROR : SYNCTHING_HOME is not writable
fi fi
exec syncthing \ exec syncthing \
-home $SYNCTHING_HOME \ -home $SYNCTHING_HOME \
-gui-address=$SYNCTHING_GUI_ADDRESS \ -gui-address=$SYNCTHING_GUI_ADDRESS \
-no-browser -no-browser
''; '';
in in pkgs.dockerTools.buildImage {
pkgs.dockerTools.buildImage {
name = "syncthing"; name = "syncthing";
fromImage = interactive_base; fromImage = interactive_base;
contents = pkgs.syncthing; contents = pkgs.syncthing;
config = { config = {
Env = baseEnv ++ [ "SYNCTHING_HOME=/home/syncthing" ]; Env = baseEnv ++ [
"SYNCTHING_HOME=/home/syncthing"
];
Cmd = [ entrypoint ]; Cmd = [ entrypoint ];
Volumes = { Volumes = {
"/data" = { }; "/data" = {};
}; };
}; };
}; };

View file

@ -1,33 +1,26 @@
{ versionsPath }: { versionsPath }:
let let
channelVersions = import versionsPath; channelVersions = (import versionsPath);
mkChannelSource = mkChannelSource = name:
name:
let let
channelVersion = builtins.getAttr name channelVersions; channelVersion = builtins.getAttr name channelVersions;
in in builtins.fetchGit {
builtins.fetchGit {
# Descriptive name to make the store path easier to identify # Descriptive name to make the store path easier to identify
inherit name; inherit name;
inherit (channelVersion) url ref rev; inherit (channelVersion) url ref rev;
}; };
nixPath = builtins.concatStringsSep ":" ( nixPath = builtins.foldl' (path: elemName:
builtins.map ( let
elemName: elem = builtins.getAttr elemName channelVersions;
let elemPath = (mkChannelSource elemName);
elem = builtins.getAttr elemName channelVersions; suffix = if builtins.hasAttr "suffix" elem then elem.suffix else "";
elemPath = mkChannelSource elemName; in
suffix = if builtins.hasAttr "suffix" elem then elem.suffix else ""; path + ":" + builtins.concatStringsSep "=" [ elemName elemPath ] + suffix
in ) "" (builtins.attrNames channelVersions);
builtins.concatStringsSep "=" [ pkgs = import (mkChannelSource "nixpkgs") {};
elemName
elemPath
]
+ suffix
) (builtins.attrNames channelVersions)
);
pkgs = import (mkChannelSource "nixpkgs") { };
in in
{ {
inherit nixPath; inherit nixPath;
channelSources = pkgs.writeText "channels.rc" '' channelSources = pkgs.writeText "channels.rc" ''

View file

@ -1,105 +0,0 @@
{
self,
self',
inputs',
pkgs,
}:
{
install = pkgs.mkShell {
name = "infra-install";
packages = with pkgs; [
nixos-install-tools
inputs'.disko.packages.disko
just
git
git-crypt
gnupg
];
};
develop = pkgs.mkShell {
name = "infra-develop";
inputsFrom = [ self'.devShells.install ];
packages = with pkgs; [
self'.formatter # .package
inputs'.colmena.packages.colmena
dconf2nix
inputs'.nixos-anywhere.packages.nixos-anywhere
nurl
vcsh
ripgrep
# pass
age
age-plugin-yubikey
ssh-to-age
yubico-piv-tool
inputs'.sops-nix.packages.default
sops
nil
nix-index
apacheHttpd
# vncdo
# tesseract
# imagemagick
# lm_sensors
# nmap
# sysstat
# lshw
# xxHash
# linssid
# wavemon
# wirelesstools
# zathura
# xorg.xwininfo
# glxinfo
# autorandr
# arandr
# playerctl
# x11docker
# fwupd
# ntfy
# hedgedoc-cli
xwayland
pulsemixer
(pkgs.writeShellScriptBin "rflk" ''
exec nix run nixpkgs#$@
'')
(pkgs.writeShellScriptBin "r11" ''
exec env NIXOS_OZONE_WL="" WAYLAND_DISPLAY="" $@
'')
jq
yq
wireguard-tools
screen
inputs'.nixpkgs-unstable.legacyPackages.kanidm
(flameshot.override { enableWlrSupport = true; })
];
# Set Environment Variables
RUST_BACKTRACE = 1;
KANIDM_URL =
self.nixosConfigurations.sj-srv1.config.containers.webserver.config.services.kanidm.serverSettings.origin;
shellHook = builtins.concatStringsSep "\n" [
# (self.inputs.nixago.lib.${pkgs.system}.make {
# data = self'.formatter.settings;
# output = "treefmt.toml";
# format = "toml";
# }).shellHook
];
};
}

View file

@ -1,102 +1,89 @@
{ { pkgs }:
pkgs,
lib,
config,
# these come in via home-manager.extraSpecialArgs and are specific to each node
nodeFlake,
repoFlake,
...
}:
let let
pkgsUnstable = zshCurried = import ../programs/zsh.nix { inherit pkgs; };
pkgs.pkgsUnstable
or (import nodeFlake.inputs.nixpkgs-unstable { inherit (pkgs) system config overlays; });
in in
{
{ pkgs
, config
, ... }:
let
# gitpkgs = import /home/steveej/src/github/NixOS/nixpkgs {};
unstablepkgs = import <channels-nixos-unstable> { config = config.nixpkgs.config; };
masterpkgs = import <nixpkgs-master> { config = config.nixpkgs.config; };
in {
imports = [ imports = [
../profiles/common.nix ../profiles/common.nix
# ../profiles/dotfiles.nix ../profiles/qtile-desktop.nix
# FIXME: fix homeshick when no WAN connection is available ../profiles/dotfiles.nix
# ../programs/homeshick.nix
# ../profiles/gnome-desktop.nix
# ../profiles/experimental-desktop.nix
../programs/redshift.nix
../programs/gpg-agent.nix
../programs/pass.nix
../programs/espanso.nix
../programs/firefox.nix ../programs/firefox.nix
../programs/chromium.nix ../programs/chromium.nix
# FIXME: fix homeshick when no WAN connection is available
# ../programs/homeshick.nix
../programs/libreoffice.nix ../programs/libreoffice.nix
../programs/neovim.nix ../programs/neovim.nix
../programs/pass.nix
zshCurried
../programs/podman.nix
../programs/vscode ../programs/vscode
{ home.packages = [ pkgsUnstable.markdown-oxide ]; }
]; ];
home.sessionVariables.HM_CONFIG = "graphical-fullblown"; nixpkgs.config = {
home.sessionVariables.GOPATH = "$HOME/src/go"; pidgin = {
home.sessionVariables.PATH = pkgs.lib.concatStringsSep ":" [ openssl = true;
"$HOME/.local/bin" gnutls = true;
"$PATH" };
];
nixpkgs.config.allowInsecurePredicate = packageOverrides = pkgs: with pkgs; {
pkg: };
builtins.elem (lib.getName pkg) [ };
"electron-28.3.3"
"electron-27.3.11" home.sessionVariables = {
# TODO: find a way to prevent using a store path for the current file
# HM_CONFIG_PATH=builtins.toString "${./.}";
HM_CONFIG="graphical-fullblown";
GOPATH="$HOME/src/go";
PATH=pkgs.lib.concatStringsSep ":" [
"$HOME/.local/bin"
"$PATH"
]; ];
};
nixpkgs.config.permittedInsecurePackages = [ home.packages = []
"electron-28.3.3" ++ (with pkgs; [
"electron-27.3.11"
];
nixpkgs.config.allowUnfree = [
"electron-28.3.3"
"electron-27.3.11"
];
# nixpkgs.config.allowUnfreePredicate = pkg:
# builtins.elem (lib.getName pkg) [
# "smartgithg"
# "electron-27.3.11"
# ];
home.packages =
(with pkgs; [
# Authentication # Authentication
# cacert cacert
# fprintd fprintd
# openssl openssl
# mkpasswd mkpasswd
# Nix package related tools # Nix package related tools
patchelf patchelf
# nix-index nix-index
nox
nix-prefetch-scripts nix-prefetch-scripts
nix-tree nix-prefetch-github
# Version Control Systems # Version Control Systems
gitFull pijul
# gitless gitless
gitRepo gitRepo
git-lfs git-lfs
# Process/System Administration # Process/System Administration
htop htop
# gnome.gnome-tweaks gnome3.gnome-tweak-tool
xorg.xhost xorg.xhost
dmidecode dmidecode
evtest evtest
# Archive Managers # Archive Managers
sshfs-fuse sshfsFuse
xarchive
p7zip p7zip
zip zip
unzip unzip
@ -106,74 +93,98 @@ in
# Password Management # Password Management
gnupg gnupg
yubikey-manager yubikey-manager
yubikey-neo-manager
yubikey-personalization yubikey-personalization
yubikey-personalization-gui yubikey-personalization-gui
gnome3.gnome_keyring
# gnome.gnome-keyring gnome3.seahorse
gcr
seahorse
# Language Support # Language Support
hunspellDicts.en-us hunspellDicts.en-us
hunspellDicts.de-de hunspellDicts.de-de
# Messaging/Communication # Messaging/Communication
# pidgin signal-desktop
# hexchat pidgin
pkgsUnstable.element-desktop hexchat
aspellDicts.en aspellDicts.en
aspellDicts.de aspellDicts.de
# skypeforlinux skype
# pkgsUnstable.jitsi-meet-electron unstablepkgs.jitsi-meet-electron
thunderbird-128 zoom-us # broken as of 2019-10-30
# betterbird bluejeans-gui
thunderbird
# FIXME: depends on insecure openssl 1.1.1t gnome3.evolution # gnome4.glib_networking
# kotatogram-desktop # telegram
pkgsUnstable.tdesktop unstablepkgs.tdesktop
pkgsUnstable.signal-desktop gnome3.cheese
# Virtualization # Virtualization
virt-manager virtmanager
# (pkgs.lib.hiPrio qemu)
# virtualbox
# vagrant
# docker_compose
# unstablepkgs.kubernetes
# unstablepkgs.minikube
# unstablepkgs.openshift
# (unstablepkgs.minikube.overrideAttrs (oldAttrs: {
# patches = oldAttrs.patches ++ [
# (builtins.fetchurl { url ="https://patch-diff.githubusercontent.com/raw/kubernetes/minikube/pull/2517.diff"; })
# ];
# }))
appimage-run
# Remote Control Tools # Remote Control Tools
remmina remmina
# freerdp freerdp
teamviewer
# Audio/Video Players # Audio/Video Players
# ffmpeg ffmpeg
vlc vlc
# v4l-utils audacity
# audacity spotify
# spotify python38Packages.youtube-dl-light
yt-dlp
(writeShellScriptBin "youtube-dl-audio" "${yt-dlp}/bin/yt-dlp --extract-audio --audio-format best --audio-quality 9 \${@:?}")
libwebcam libwebcam
libcamera
snapshot
# Network Tools # Network Tools
openvpn
tcpdump tcpdump
iftop iftop
iperf iperf
bind bind
socat socat
nethogs # 2019-03-05: broken on 19.03 linssid
iptraf-ng
ipmitool
# Code Editing and Programming # samba
# TODO(remove or use): pkgsUnstable.lapce iptables
# TODO(remve or use): pkgsUnstable.helix nftables
wireshark
# Code Editors
# unstablepkgs.atom
xclip
xsel
# Image/Graphic/Design Tools # Image/Graphic/Design Tools
eog gnome3.eog
# gimp gimp
# imagemagick imagemagick
# exiv2 exiv2
# graphviz graphviz
# inkscape inkscape
# qrencode # barcode
qrencode
zbar
feh
# digikam
# TODO: remove or move these: Modelling Tools
# Modelling Tools
# plantuml # plantuml
# umlet # umlet
# staruml # staruml
@ -182,46 +193,99 @@ in
# astah-community # astah-community
# Misc Development Tools # Misc Development Tools
# qrcode qrcode
# jq # travis
# cdrtools jq
# prometheus
cdrtools
# Document Processing and Management # Document Processing and Management
nautilus # zathura
pcmanfm mendeley
# mendeley # zotero
evince pandoc
xournalpp
# LaTeX
perlPackages.YAMLTiny
perlPackages.FileHomeDir
perlPackages.UnicodeLineBreak
(texlive.combine {
inherit (texlive)
scheme-small
texlive-de
texlive-en
texlive-scripts
collection-langgerman
latexindent
latexmk
algorithms
cm-super
preprint
enumitem
draftwatermark
everypage
ulem
placeins
minted ifplatform fvextra xstring framed
;
})
pdftk
masterpdfeditor
# File Synchronzation # File Synchronzation
maestral seafile-client
grive2
dropbox
rsync rsync
# Filesystem Tools # Filesystem Tools
# ntfs3g ntfs3g
# ddrescue ddrescue
# ncdu ncdu
# hdparm woeusb
# binwalk unetbootin
# gptfdisk pcmanfm
# gparted hdparm
# smartmontools testdisk
python38Packages.binwalk
gptfdisk
gparted
smartmontools
## Android
androidenv.androidPkgs_9_0.platform-tools
## Python ## Python
# packages'.myPython myPython
# Code generators
# unstablepkgs.swagger-codegen
# Misc Desktop Tools # Misc Desktop Tools
# ltunify # TODO: this may be required if brightness control isn't working
# dex # brightnessctl
ltunify
# solaar # TODO: conflicts with solar over udev rules
dex
# kitty
busyboxStatic
xorg.xbacklight
coreutils coreutils
lsof lsof
xdg-utils x11_ssh_askpass
xdotool
xdg_utils
xdg-user-dirs xdg-user-dirs
dconf gnome3.dconf
picocom picocom
glib.dev # contains gdbus tool glib.dev # contains gdbus tool
alacritty alacritty
# wally-cli roxterm
unstablepkgs.wally-cli
man-pages man-pages
# Screen recording # Screen recording
@ -231,58 +295,11 @@ in
# shutter # shutter
# kazam # doesn't start # kazam # doesn't start
# xvidcap # doesn't keep the recording rectangle # xvidcap # doesn't keep the recording rectangle
obs-studio
screenkey
# shotcut # shotcut
# openshot-qt # openshot-qt
# introduces python: screenkey
# avidemux # broken ledger-live-desktop
# handbrake ]);
# snes9x
# snes9x-gtk
# this is a displaymanager!
# libretro.snes9x2010
# retroarchFull
# pkgs.logseq-bin
pkgs.logseq
# (pkgs.callPackage "${repoFlake.inputs.nixpkgs-logseq}/pkgs/by-name/lo/logseq-bin/package.nix" { })
])
++ (with repoFlake.packages.${pkgs.system}; [ gimp ])
++ (lib.lists.optionals (!pkgs.stdenv.targetPlatform.isAarch64) [
pkgsUnstable.ledger-live-desktop
# unsupported on aarch64-linux
pkgs.androidenv.androidPkgs_9_0.platform-tools
pkgs.teamviewer
pkgs.discord
pkgsUnstable.session-desktop
pkgsUnstable.rustdesk
]);
systemd.user.startServices = true;
services.syncthing.enable = true;
services.udiskie = {
enable = true;
automount = false;
notify = true;
};
# TODO: uncomment this when it's in stable home-manger
# programs.joshuto = {
# enable = true;
# };
# systemd.user.services.maestral = {
# Unit.Description = "Maestral daemon";
# Install.WantedBy = ["default.target"];
# Service = {
# ExecStart = "${pkgs.maestral}/bin/maestral start -f";
# ExecStop = "${pkgs.maestral}/bin/maestral stop";
# Restart = "on-failure";
# Nice = 10;
# };
# };
} }

View file

@ -1,8 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
gnome-tweaks
gnome-keyring
seahorse
];
}

View file

@ -1,5 +1,17 @@
{ pkgs, ... }: { pkgs }:
{
let
zshCurried = import ../programs/zsh.nix { inherit pkgs; };
in
{ pkgs
, config,
... }:
let
unstablepkgs = import <channels-nixos-unstable> { config = config.nixpkgs.config; };
in {
imports = [ imports = [
../profiles/common.nix ../profiles/common.nix
../profiles/qtile-desktop.nix ../profiles/qtile-desktop.nix
@ -11,89 +23,109 @@
../programs/libreoffice.nix ../programs/libreoffice.nix
../programs/neovim.nix ../programs/neovim.nix
../programs/pass.nix ../programs/pass.nix
zshCurried
]; ];
home.packages = with pkgs; [ nixpkgs.config = {
# Nix package related tools pidgin = {
patchelf openssl = true;
nix-index gnutls = true;
nix-prefetch-scripts };
# Version Control Systems packageOverrides = pkgs: with pkgs; {
gitless };
};
# Process/System Administration home.sessionVariables = {
htop };
gnome-tweaks
xorg.xhost
dmidecode
evtest
# Archive Managers
sshfs-fuse
xarchive
p7zip
zip
unzip
gzip
lzop
# Password Management home.packages =
gnome-keyring [] ++ (with pkgs; [
seahorse # Nix package related tools
patchelf
nix-index
nix-prefetch-scripts
# Remote Control Tools # Version Control Systems
remmina gitless
freerdp
# Network Tools # Process/System Administration
openvpn htop
tcpdump gnome3.gnome-tweak-tool
iftop xorg.xhost
iperf dmidecode
bind evtest
socat
# samba # Archive Managers
iptables sshfsFuse
nftables xarchive
wireshark p7zip
zip
unzip
gzip
lzop
# Code Editors # Password Management
xclip gnome3.gnome_keyring
xsel gnome3.seahorse
# Image/Graphic/Design Tools # Remote Control Tools
gnome.eog remmina
gimp freerdp
inkscape
# Misc Development Tools # Network Tools
qrcode openvpn
jq tcpdump
cdrtools iftop
iperf
bind
socat
# Document Processing and Management # samba
zathura iptables
nftables
wireshark
# File Synchronzation # Code Editors
rsync xclip
xsel
unstablepkgs.vscode
# Filesystem Tools # Image/Graphic/Design Tools
ntfs3g gnome3.eog
ddrescue gimp
ncdu inkscape
woeusb
unetbootin
pcmanfm
hdparm
testdisk
binwalk
gptfdisk
packages'.myPython # Misc Development Tools
qrcode
jq
cdrtools
# Virtualization # Document Processing and Management
virtmanager zathura
];
# File Synchronzation
rsync
# Filesystem Tools
ntfs3g
ddrescue
ncdu
unstablepkgs.woeusb
unetbootin
pcmanfm
hdparm
testdisk
python38Packages.binwalk
gptfdisk
## Python
myPython
busyboxStatic
# Virtualization
virtmanager
]);
} }

View file

@ -0,0 +1,35 @@
{ pkgs, extraPackages ? [] }:
let
zshCurried = import ../programs/zsh.nix { inherit pkgs; };
in
{ pkgs
, config
, ... }:
let
in {
imports = [
../profiles/common.nix
../profiles/nix-channels.nix
../programs/neovim.nix
zshCurried
];
nixpkgs.config = {
packageOverrides = pkgs: with pkgs; {
};
};
home.sessionVariables = {
};
home.packages = extraPackages
++ (with pkgs; [
iperf3
telnet
speedtest-cli
]);
}

View file

@ -1,19 +1,22 @@
_: { {
mkSimpleTrayService = }:
{ execStart }:
{
Unit = {
Description = "";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = { let
WantedBy = [ "graphical-session.target" ];
};
Service = { in {
ExecStart = execStart; mkSimpleTrayService = { execStart }: {
}; Unit = {
Description = "pasystray applet";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
}; };
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
ExecStart = execStart;
};
};
} }

View file

@ -1,97 +1,54 @@
{ pkgs, lib, ... }: { pkgs
{ , ...
home.stateVersion = lib.mkDefault "23.11"; }:
# TODO: re-enable this with the appropriate version? let
in {
# TODO: re-enable this with the appropriate version
# programs.home-manager.enable = true; # programs.home-manager.enable = true;
# programs.home-manager.path = https://github.com/rycee/home-manager/archive/445c0b1482c38172a9f8294ee16a7ca7462388e5.tar.gz; # programs.home-manager.path = https://github.com/rycee/home-manager/archive/445c0b1482c38172a9f8294ee16a7ca7462388e5.tar.gz;
# TODO: move this to an OS snippet? nixpkgs.overlays = builtins.attrValues (import ../../overlays);
nixpkgs.config = { nixpkgs.config = {
allowBroken = false; allowBroken = true;
allowUnfree = true; allowUnfree = true;
allowUnsupportedSystem = true;
allowInsecurePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"electron-32.3.3"
"electron"
];
permittedInsecurePackages = [
"electron-32.3.3"
"electron"
];
allowUnfreePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"obsidian"
"vivaldi"
"aspell-dict-en-science"
];
}; };
home.keyboard = { home.keyboard = {
layout = "us"; layout = "us";
variant = "altgr-intl"; variant = "altgr-intl";
options = [ options = [
# nodeadkeys doesn't make sense with us layout: see https://man.archlinux.org/man/xkeyboard-config.7 for valid options "nodeadkeys"
# "nodeadkeys" # "caps:swapescape"
# "caps:swapescape"
]; ];
}; };
xdg.enable = true;
programs.direnv.enable = true; programs.direnv.enable = true;
services.lorri.enable = true;
# Don't create .pyc files. home.sessionVariables = {
home.sessionVariables.PYTHONDONTWRITEBYTECODE = "1"; NIXPKGS_ALLOW_UNFREE = "1";
# Don't create .pyc files.
PYTHONDONTWRITEBYTECODE = "1";
};
programs.command-not-found.enable = true; programs.command-not-found.enable = true;
programs.fzf.enable = true; programs.fzf.enable = true;
home.packages = with pkgs; [ home.packages =
coreutils [] ++ (with pkgs; [
# git helpers
git-crypt
vcsh vcsh
# Authentication
cacert
openssl
mkpasswd
htop just
iperf3 ripgrep
nethogs du-dust
]);
# Authentication
cacert
openssl
mkpasswd
just
ripgrep
du-dust
elfutils
exfat
file
tree
pwgen
proot
parted
pv
tmux
wget
curl
# git helpers
git-crypt
gitFull
pastebinit
gist
mr
usbutils
pciutils
];
} }

View file

@ -1,6 +1,13 @@
_: { { pkgs
# TODO: fix the dotfiles , config
# home.activation.vcsh = config.lib.dag.entryAfter["linkGeneration"] '' , ...
# $DRY_RUN_CMD ${vcshActivationScript} }:
# '';
let
vcshActivationScript = pkgs.callPackage ./dotfiles/vcsh.nix {};
in {
home.activation.vcsh = config.lib.dag.entryAfter["linkGeneration"] ''
$DRY_RUN_CMD ${vcshActivationScript}
'';
} }

View file

@ -1,42 +1,39 @@
{ { pkgs
pkgs, , repoHttps ? "https://gitlab.com/steveeJ/dotfiles.git"
repoHttps ? "https://gitlab.com/steveeJ/dotfiles.git", , repoSsh ? "git@gitlab.com:/steveeJ/dotfiles.git"
repoSsh ? "git@gitlab.com:/steveeJ/dotfiles.git", , ...
...
}: }:
let let
repoBareLocal = repoBareLocal = pkgs.runCommand "fetchbare" {
pkgs.runCommand "fetchbare" outputHashMode = "recursive";
{ outputHashAlgo = "sha256";
outputHashMode = "recursive"; outputHash = "0000000000000000000000000000000000000000000000000000";
outputHashAlgo = "sha256"; } ''
outputHash = "0000000000000000000000000000000000000000000000000000"; (
} set -xe
'' export GIT_SSL_CAINFO=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
( export SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
set -xe ${pkgs.git}/bin/git clone --mirror ${repoHttps} $out
export GIT_SSL_CAINFO=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt )
export SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt '';
${pkgs.git}/bin/git clone --mirror ${repoHttps} $out
)
'';
in
pkgs.writeScript "activation-script" ''
export HOST=$(hostname -s)
function set_remotes { in pkgs.writeScript "activation-script" ''
${pkgs.vcsh}/bin/vcsh dotfiles remote set-url origin $1 export HOST=$(hostname -s)
${pkgs.vcsh}/bin/vcsh dotfiles remote set-url --push origin $2
}
if ! test -d $HOME/.config/vcsh/repo.d/dotfiles.git; then function set_remotes {
echo Cloning dotfiles for $HOST... ${pkgs.vcsh}/bin/vcsh dotfiles remote set-url origin $1
${pkgs.vcsh}/bin/vcsh clone -b $HOST ${repoBareLocal} dotfiles ${pkgs.vcsh}/bin/vcsh dotfiles remote set-url --push origin $2
set_remotes ${repoHttps} ${repoSsh} }
else
set_remotes ${repoBareLocal} ${repoSsh} if ! test -d $HOME/.config/vcsh/repo.d/dotfiles.git; then
echo Updating dotfiles for $HOST... echo Cloning dotfiles for $HOST...
${pkgs.vcsh}/bin/vcsh pull $HOST || true ${pkgs.vcsh}/bin/vcsh clone -b $HOST ${repoBareLocal} dotfiles
set_remotes ${repoHttps} ${repoSsh} set_remotes ${repoHttps} ${repoSsh}
fi else
'' set_remotes ${repoBareLocal} ${repoSsh}
echo Updating dotfiles for $HOST...
${pkgs.vcsh}/bin/vcsh pull $HOST || true
set_remotes ${repoHttps} ${repoSsh}
fi
''

View file

@ -1,10 +0,0 @@
{ packages', ... }:
{
imports = [ ../profiles/wayland-desktop.nix ];
home.packages = [
# experimental WMs
packages'.jay
packages'.magmawm
];
}

View file

@ -1,100 +0,0 @@
{ pkgs, ... }:
{
imports = [ ../profiles/wayland-desktop.nix ];
services = {
gnome-keyring.enable = false;
blueman-applet.enable = true;
flameshot.enable = true;
pasystray.enable = true;
};
# TODO: remove this comment once i'm sure everything works
# xdg.configFile."autostart/gnome-keyring-ssh.desktop".text = ''
# [Desktop Entry]
# Type=Application
# Hidden=true
# '';
services.gpg-agent.pinentry.package = pkgs.pinentry-gnome3;
dconf.settings =
let
manualKeybindings = [
{
binding = "Print";
command = "flameshot gui";
name = "flameshot";
}
{
binding = "<Super>t";
command = "alacritty";
name = "alacritty";
}
];
numWorkspaces = 10;
customKeybindingBaseName = "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom";
customKeybindingsNames = builtins.genList (i: "/${customKeybindingBaseName}${toString i}/") (
(builtins.length manualKeybindings) + numWorkspaces # for sending to the workspace
);
workspacesKeyBindingsOffset = builtins.length manualKeybindings;
# with this we can make use of all number keys [0-9]
mapToNumber =
i:
if i < 10 then
i
else if i == 10 then
0
else
throw "i exceeds 10: ${i}";
in
{
"org/gnome/settings-daemon/plugins/media-keys" = {
custom-keybindings = customKeybindingsNames;
screenreader = "@as []";
screensaver = [ "<Alt><Super>l" ];
};
# disable the builtin <Super>[1-9] functionality
"org/gnome/shell/keybindings" = builtins.listToAttrs (
(builtins.genList (i: {
name = "switch-to-application-${toString (i + 1)}";
value = [ ];
}) numWorkspaces)
++ [
{
name = "toggle-overview";
value = [ ];
}
]
);
# remap it to switching to the workspaces
"org/gnome/desktop/wm/keybindings" = builtins.listToAttrs (
builtins.genList (i: {
name = "switch-to-workspace-${toString (i + 1)}";
value = [ "<Super>${toString (mapToNumber (i + 1))}" ];
}) numWorkspaces
);
}
// builtins.listToAttrs (
builtins.genList (i: {
name = "${customKeybindingBaseName}${toString i}";
value = builtins.elemAt manualKeybindings i;
}) (builtins.length manualKeybindings)
)
// builtins.listToAttrs (
builtins.genList (i: {
name = "${customKeybindingBaseName}${toString (workspacesKeyBindingsOffset + i)}";
value = {
binding = "<Control><Super>${toString (mapToNumber (i + 1))}";
command = "wmctrl -r :ACTIVE: -t ${toString i}";
name = "Send to workspace ${toString (i + 1)}";
};
}) numWorkspaces
);
}

View file

@ -1,22 +1,26 @@
{ pkgs, config, ... }: { pkgs
{ , config
home.file.".nix-channels".text = ""; , ...
}:
home.activation.removeExistingNixChannels = config.lib.dag.entryBefore [ "checkLinkTargets" ] '' let
in {
home.file.".nix-channels".text = ''
'';
home.activation.removeExistingNixChannels = config.lib.dag.entryBefore ["checkLinkTargets"] ''
$DRY_RUN_CMD ${pkgs.writeScript "activation-script" '' $DRY_RUN_CMD ${pkgs.writeScript "activation-script" ''
set -ex set -ex
if test -f $HOME/.nix-channels; then if test -f $HOME/.nix-channels; then
echo Uninstalling available channels... echo Uninstalling available channels...
if test -f $HOME/.nix-channel; then while read url channel; do
while read url channel; do nix-channel --remove $channel
nix-channel --remove $channel done < $HOME/.nix-channel
done < $HOME/.nix-channel echo Moving existing file away...
fi touch $HOME/.nix-channels.dummy
echo Moving existing file away... mv --backup=numbered $HOME/.nix-channels.dummy $HOME/.nix-channels
touch $HOME/.nix-channels.dummy rm $HOME/.nix-channels
mv --backup=numbered $HOME/.nix-channels.dummy $HOME/.nix-channels fi
rm $HOME/.nix-channels
fi
''}; ''};
''; '';
} }

View file

@ -1,15 +1,17 @@
{ pkgs, ... }: { pkgs
let , ...
}:
audio = pkgs.writeShellScript "audio" '' let
export PATH=${ inherit (import ../lib.nix { })
with pkgs; mkSimpleTrayService
lib.makeBinPath [ ;
pulseaudio
findutils audio = pkgs.writeScript "audio" ''
gnugrep #!${pkgs.bash}/bin/bash
] export PATH=${with pkgs; lib.makeBinPath [
}:$PATH pulseaudio findutils gnugrep
]}:$PATH
export MUTEFILE=''${TEMPDIR:-/tmp}/.qtilemute export MUTEFILE=''${TEMPDIR:-/tmp}/.qtilemute
case $1 in case $1 in
@ -31,9 +33,13 @@ let
esac esac
''; '';
terminalCommand = "${pkgs.alacritty}/bin/alacritty"; terminalCommand = "${pkgs.alacritty}/bin/alacritty";
# terminalCommand = "${pkgs.roxterm}/bin/roxterm";
dpmsScript = pkgs.writeShellScript "dpmsScript" '' dpmsScript = pkgs.writeScript "dpmsScript" ''
export PATH=${with pkgs; lib.makeBinPath [ xorg.xset ]}:$PATH #!${pkgs.bash}/bin/bash
export PATH=${with pkgs; lib.makeBinPath [
xlibs.xset
]}:$PATH
set -xe set -xe
@ -55,8 +61,11 @@ let
esac esac
''; '';
screenLockCommand = pkgs.writeShellScript "screenLock" '' screenLockCommand = pkgs.writeScript "screenLock" ''
export PATH=${with pkgs; lib.makeBinPath [ i3lock ]}:$PATH #!${pkgs.bash}/bin/bash
export PATH=${with pkgs; lib.makeBinPath [
i3lock
]}:$PATH
revert() { revert() {
${dpmsScript} default ${dpmsScript} default
@ -69,190 +78,229 @@ let
revert revert
''; '';
initScreen = pkgs.writeShellScript "initScreen" ''
# ${pkgs.xorg.xinput}/bin/xinput set-prop "ZSA Moonlander Mark I Mouse" "libinput Natural Scrolling Enabled" 1
${pkgs.autorandr}/bin/autorandr -c
${pkgs.feh}/bin/feh --bg-scale ${pkgs.nixos-artwork.wallpapers.simple-blue}/share/artwork/gnome/nix-wallpaper-simple-blue.png
${dpmsScript} default
'';
qtileConfig = pkgs.writeScript "qtile_config.py" '' qtileConfig = pkgs.writeScript "qtile_config.py" ''
from libqtile.config import Key, Screen, Group, Drag, Click from libqtile.config import Key, Screen, Group, Drag, Click
from libqtile.command import lazy from libqtile.command import lazy
from libqtile import layout, bar, widget from libqtile import layout, bar, widget
from libqtile import hook from libqtile import hook
import logging, os import logging, os
logger = logging.getLogger() logger = logging.getLogger()
logger.setLevel(logging.WARN) logger.setLevel(logging.WARN)
handler = logging.handlers.RotatingFileHandler( handler = logging.handlers.RotatingFileHandler(
os.path.join(os.getenv('TEMPDIR', default="/tmp"), '.qtilelog'), maxBytes=10240000, os.path.join(os.getenv('TEMPDIR', default="/tmp"), '.qtilelog'), maxBytes=10240000,
backupCount=7 backupCount=7
) )
handler.setLevel(logging.WARN) handler.setLevel(logging.WARN)
logger.addHandler(handler) logger.addHandler(handler)
key_super = "mod4" # @hook.subscribe.screen_change
key_alt = "mod1" # def restart_on_randr(qtile, ev):
key_control = "control" # import time
#
# with open(os.path.join(os.environ['TEMPDIR', default="/tmp"], ".qtilelastrestart"), "w"):
# pass
#
# lastRestart = 0
# with open(os.path.join(os.environ['TEMPDIR', default="/tmp"], ".qtilelastrestart"), "r+") as lastRestartFile:
# lastRestartStr = lastRestartFile.read()
# if len(lastRestartStr) > 0:
# lastRestart = float(lastRestartStr)
#
# print("screen changed. (last change: %s)" % lastRestart)
#
# delta=time.time()-lastRestart
# if delta > 3:
# import subprocess
# lastRestartFile.seek(0)
# lastRestartFile.write("%s" % time.time())
# lastRestartFile.truncate()
#
# subprocess.call(["autorandr","-c"])
# qtile.cmd_restart()
# else:
# print("screen is changing too fast: %s" % delta)
#
# active_screen = 0
# @hook.subscribe.client_focus
# def focus_changed(window):
# global active_screen
# pass
# active_screen = window.group.screen.index
#
# @hook.subscribe.current_screen_change
# def move_widget():
# global active_screen
# systray = widget.Systray()
# logging.warn("Screen changed to %i" % active_screen)
keys = [ key_super = "mod4"
# https://github.com/qtile/qtile/blob/master/libqtile/backend/x11/xkeysyms.py key_alt = "mod1"
Key([key_super], "Return", lazy.spawn("${terminalCommand}")), key_control = "control"
Key([key_super], "r", lazy.spawncmd()),
Key([key_super], "w", lazy.window.kill()),
Key([key_alt, key_super], "l", lazy.spawn('${pkgs.bash}/bin/sh -c "loginctl lock-session $XDG_SESSION_ID"')), keys = [
Key([key_alt, key_super], "s", lazy.spawn("${pkgs.systemd}/bin/systemctl suspend")), # https://github.com/qtile/qtile/blob/develop/libqtile/xkeysyms.py
Key([key_super], "Return", lazy.spawn("${terminalCommand}")),
Key([key_super], "backslash", lazy.spawn("${terminalCommand}")),
Key([key_super], "apostrophe", lazy.spawn("${terminalCommand}")),
Key([key_super], "r", lazy.spawncmd()),
Key([key_super], "w", lazy.window.kill()),
Key([key_super, key_control], "r", lazy.spawn("${initScreen}")), Key([key_alt, key_super], "l", lazy.spawn('${pkgs.bash}/bin/sh -c "loginctl lock-session $XDG_SESSION_ID"')),
Key([key_super, key_control], "q", lazy.shutdown()), Key([key_alt, key_super], "s", lazy.spawn("${pkgs.systemd}/bin/systemctl suspend")),
# Toggle between different layouts as defined below # Key([key_super, key_control], "r", lazy.restart()),
Key([key_super], "Tab", lazy.next_layout()), Key([key_super, key_control], "r", lazy.spawn("${pkgs.autorandr}/bin/autorandr -c && ${dpmsScript} default"), lazy.restart()),
Key([key_super, key_control], "q", lazy.shutdown()),
# this is usefull when floating windows get buried # Toggle between different layouts as defined below
Key([key_super], "Escape", lazy.window.bring_to_front()), Key([key_super], "Tab", lazy.next_layout()),
# common to all layouts # MonadTall keybindings
Key([key_control, key_alt], "h", lazy.layout.grow_left()), Key([key_super], "h", lazy.layout.left()),
Key([key_control, key_alt], "j", lazy.layout.grow_down()), Key([key_super], "l", lazy.layout.right()),
Key([key_control, key_alt], "k", lazy.layout.grow_up()), Key([key_super], "j", lazy.layout.down()),
Key([key_control, key_alt], "l", lazy.layout.grow_right()), Key([key_super], "k", lazy.layout.up()),
Key([key_super], "n", lazy.layout.normalize()), Key([key_super, key_control], "h", lazy.layout.shuffle_left()),
Key([key_super], "o", lazy.layout.maximize()), Key([key_super, key_control], "l", lazy.layout.shuffle_right()),
Key([key_super, key_control], "j", lazy.layout.shuffle_down()),
Key([key_super, key_control], "k", lazy.layout.shuffle_up()),
Key([key_super, key_control], "space", lazy.layout.toggle_split()),
Key([key_control, key_alt], "h", lazy.layout.grow_left()),
Key([key_control, key_alt], "j", lazy.layout.grow_down()),
Key([key_control, key_alt], "k", lazy.layout.grow_up()),
Key([key_control, key_alt], "l", lazy.layout.grow_right()),
Key([key_super], "n", lazy.layout.normalize()),
Key([key_super], "o", lazy.layout.maximize()),
# MonadTall keybindings # Stack
Key([key_super], "h", lazy.layout.left().when(layout="monad")), Key([key_super], "h", lazy.layout.previous().when('stack')),
Key([key_super], "l", lazy.layout.right().when(layout="monad")), Key([key_super], "l", lazy.layout.next().when('stack')),
Key([key_super], "j", lazy.layout.down().when(layout="monad")), Key([key_super], "j", lazy.layout.up().when('stack')),
Key([key_super], "k", lazy.layout.up().when(layout="monad")), Key([key_super], "k", lazy.layout.down().when('stack')),
Key([key_super, key_control], "h", lazy.layout.shuffle_left().when(layout="monad")), Key([key_super, key_control], "j", lazy.layout.shuffle_up().when('stack')),
Key([key_super, key_control], "l", lazy.layout.shuffle_right().when(layout="monad")), Key([key_super, key_control], "k", lazy.layout.shuffle_down().when('stack')),
Key([key_super, key_control], "j", lazy.layout.shuffle_down().when(layout="monad")), Key([key_super, key_control], "h", lazy.layout.client_to_previous().when('stack')),
Key([key_super, key_control], "k", lazy.layout.shuffle_up().when(layout="monad")), Key([key_super, key_control], "l", lazy.layout.client_to_next().when('stack')),
Key([key_super, key_control], "space", lazy.layout.toggle_split().when(layout="monad")),
# Stack # Columns
Key([key_super], "h", lazy.layout.previous().when(layout='stack')), Key([key_super], "h", lazy.layout.left().when('columns')),
Key([key_super], "l", lazy.layout.next().when(layout='stack')), Key([key_super], "l", lazy.layout.right().when('columns')),
Key([key_super], "j", lazy.layout.up().when(layout='stack')), Key([key_super], "j", lazy.layout.down().when('columns')),
Key([key_super], "k", lazy.layout.down().when(layout='stack')), Key([key_super], "k", lazy.layout.up().when('columns')),
Key([key_super, key_control], "j", lazy.layout.shuffle_up().when(layout='stack')), Key([key_super, key_control], "j", lazy.layout.shuffle_down().when('columns')),
Key([key_super, key_control], "k", lazy.layout.shuffle_down().when(layout='stack')), Key([key_super, key_control], "k", lazy.layout.shuffle_up().when('columns')),
Key([key_super, key_control], "h", lazy.layout.client_to_previous().when(layout='stack')), Key([key_super, key_control], "h", lazy.layout.shuffle_left().when('columns')),
Key([key_super, key_control], "l", lazy.layout.client_to_next().when(layout='stack')), Key([key_super, key_control], "l", lazy.layout.shuffle_right().when('columns')),
# Columns # Max
Key([key_super], "h", lazy.layout.left().when(layout="columns")), Key([key_super], "j", lazy.layout.next()),
Key([key_super], "l", lazy.layout.right().when(layout="columns")), Key([key_super], "k", lazy.layout.previous()),
Key([key_super], "j", lazy.layout.next().when(layout="columns")),
Key([key_super], "k", lazy.layout.previous().when(layout="columns")),
Key([key_super, key_control], "j", lazy.layout.shuffle_down().when(layout="columns")),
Key([key_super, key_control], "k", lazy.layout.shuffle_up().when(layout="columns")),
Key([key_super, key_control], "h", lazy.layout.shuffle_left().when(layout="columns")),
Key([key_super, key_control], "l", lazy.layout.shuffle_right().when(layout="columns")),
Key([key_super, key_control], "space", lazy.layout.toggle_split().when(layout="columns")),
# Max # Multimedia Keys
Key([key_super], "j", lazy.layout.down().when(layout="max")), Key([], "XF86AudioPlay", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause")),
Key([key_super], "k", lazy.layout.up().when(layout="max")), Key([], "XF86AudioPrev", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous")),
Key([], "XF86AudioNext", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next")),
## Microsoft Comfort Curve specific
Key([key_super, "shift"], "XF86TouchpadToggle", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous")),
Key([key_alt, key_super], "XF86TouchpadToggle", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next")),
Key([], "XF86AudioMute", lazy.spawn("${audio} mute")),
Key([], "XF86AudioLowerVolume", lazy.spawn("${audio} lower")),
Key([], "XF86AudioRaiseVolume", lazy.spawn("${audio} raise")),
Key([], "Print", lazy.spawn("${pkgs.flameshot}/bin/flameshot gui")),
]
groups = [Group(i) for i in "1234567890"]
# TODO: these are required to make the 'columns' layout work, but why? for i in groups:
Key([key_super], "j", lazy.layout.next()), # super + letter of group = switch to group
Key([key_super], "k", lazy.layout.previous()), keys.append(
Key([key_super], i.name, lazy.group[i.name].toscreen())
# Multimedia Keys
Key([], "XF86AudioPlay", lazy.spawn("${pkgs.playerctl}/bin/playerctl play-pause")),
Key([], "XF86AudioPrev", lazy.spawn("${pkgs.playerctl}/bin/playerctl previous")),
Key([], "XF86AudioNext", lazy.spawn("${pkgs.playerctl}/bin/playerctl next")),
# TODO: the next two don't work yet
Key([], "XF86AudioRewind", lazy.spawn("${pkgs.playerctl}/bin/playerctl offset 10-")),
Key([], "XF86BackForward", lazy.spawn("${pkgs.playerctl}/bin/playerctl offset 10+")),
Key([], "XF86AudioMute", lazy.spawn("${audio} mute")),
Key([], "XF86AudioLowerVolume", lazy.spawn("${audio} lower")),
Key([], "XF86AudioRaiseVolume", lazy.spawn("${audio} raise")),
Key([], "Print", lazy.spawn("${pkgs.flameshot}/bin/flameshot gui")),
]
groups = [Group(i) for i in "1234567890"]
for i in groups:
# super + letter of group = switch to group
keys.append(
Key([key_super], i.name, lazy.group[i.name].toscreen())
)
# super + shift + letter of group = switch to & move focused window to group
keys.append(
Key([key_super, key_control], i.name, lazy.window.togroup(i.name))
)
layouts = [
layout.Columns(num_columns=3, border_focus='#00ff00', border_width=2),
layout.Max(),
# layout.Stack(num_stacks=3, border_focus='#00ff00', border_width=2, autosplit=True, previous_on_rm=True),
# layout.Wmii(border_focus='#00ff00'),
# layout.MonadTall(ratio=0.6, border_focus='#00ff00'),
]
widget_defaults = dict(
font='Arial',
fontsize=16,
padding=3,
) )
screens_count = 4 # super + shift + letter of group = switch to & move focused window to group
screens = [] keys.append(
for i in range(0, screens_count+1): Key([key_super, key_control], i.name, lazy.window.togroup(i.name))
j = i+1 )
widgets = [
widget.TextBox("Screen %i" % j, name="Screen %i" % j),
widget.GroupBox(),
widget.WindowName(),
widget.Prompt(),
widget.CPUGraph(),
widget.ThermalSensor(tag_sensor = "CPU"),
widget.Memory(),
# widget.Net(interface='eth0'),
widget.Net(interface='wlan0'),
widget.Clock(format='%Y-%m-%d %a %I:%M %p'),
]
if i is 0:
widgets.insert(-1, widget.Systray())
screens.append(Screen(bottom=bar.Bar(widgets, 30))) layouts = [
layout.Columns(num_columns=3, border_focus='#00ff00', border_width=2),
layout.Max(),
# layout.Stack(num_stacks=3, border_focus='#00ff00', border_width=2, autosplit=True, previous_on_rm=True),
# layout.Wmii(border_focus='#00ff00'),
# layout.MonadTall(ratio=0.6, border_focus='#00ff00'),
]
keys.append(Key([key_super, "shift"], "%i" % (i+1), lazy.to_screen(i))) widget_defaults = dict(
font='Arial',
fontsize=16,
padding=3,
)
dgroups_key_binder = None screens_count = 4
dgroups_app_rules = [] screens = []
follow_mouse_focus = False for i in range(0, screens_count+1):
bring_front_click = False j = i+1
cursor_warp = False widgets = [
auto_fullscreen = True widget.TextBox("Screen %i" % j, name="Screen %i" % j),
auto_minimize = False widget.GroupBox(),
# focus_on_window_activation = "urgent" widget.WindowName(),
widget.Prompt(),
widget.CPUGraph(),
# Drag floating layouts. widget.ThermalSensor(),
mouse = [ widget.Memory(),
# Drag([key_super,key_control], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()), widget.Net(interface='eth0'),
# Drag([key_super,key_control], "Button2", lazy.window.set_size_floating(), start=lazy.window.get_size()), widget.Net(interface='wlan0'),
Click([key_super,key_control], "Button3", lazy.window.disable_floating()) widget.Clock(format='%Y-%m-%d %a %I:%M %p'),
] ]
if i is 0:
widgets.insert(-1, widget.Systray())
# disable any floating screens.append(Screen(bottom=bar.Bar(widgets, 30)))
@hook.subscribe.client_new
def disable_floating_for_all_new_windows(window):
window.floating = False
@hook.subscribe.client_new keys.append(Key([key_super, "shift"], "%i" % (i+1), lazy.to_screen(i)))
def print_new_window(window):
print("new window: ", window) # subscribe.current_screen_change(func)
dgroups_key_binder = None
dgroups_app_rules = []
main = None
follow_mouse_focus = False
bring_front_click = True
cursor_warp = False
auto_fullscreen = True
focus_on_window_activation = "urgent"
# Drag floating layouts.
mouse = [
Drag([key_super,key_control], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
Drag([key_super,key_control], "Button2", lazy.window.set_size_floating(), start=lazy.window.get_size()),
Click([key_super,key_control], "Button3", lazy.window.disable_floating())
]
floating_layout = layout.Floating()
wmname = "LG3D"
''; '';
in in {
{ systemd.user = {
startServices = true;
services = {
redshift-gtk = mkSimpleTrayService {
execStart = "${pkgs.redshift}/bin/redshift-gtk -v -l 47.6691:9.1698 -t 7000:4500 -m randr";
};
pasystray = mkSimpleTrayService {
execStart = "${pkgs.pasystray}/bin/pasystray";
};
cbatticon = mkSimpleTrayService {
execStart = "${pkgs.cbatticon}/bin/cbatticon";
};
};
};
services = { services = {
gnome-keyring.enable = true; gnome-keyring.enable = true;
blueman-applet.enable = true; blueman-applet.enable = true;
@ -262,32 +310,43 @@ in
lockCmd = "${screenLockCommand}"; lockCmd = "${screenLockCommand}";
}; };
network-manager-applet.enable = true; network-manager-applet.enable = true;
syncthing.enable = true;
gpg-agent = {
enable = true;
enableScDaemon = true;
enableSshSupport = true;
grabKeyboardAndMouse = true;
extraConfig = "pinentry-program ${pkgs.pinentry-gtk2}/bin/pinentry";
};
flameshot.enable = true; flameshot.enable = true;
pasystray.enable = true;
cbatticon.enable = true;
};
home.pointerCursor = {
name = "Vanilla-DMZ";
package = pkgs.vanilla-dmz;
size = 32;
x11.enable = true;
gtk.enable = true;
}; };
xsession = { xsession = {
enable = false; enable = true;
windowManager.command = "${pkgs.qtile}/bin/qtile start -c ${qtileConfig}"; windowManager.command = "${pkgs.qtile}/bin/qtile -c ${qtileConfig}";
initExtra = "${initScreen}"; initExtra = ''
# ${pkgs.xorg.xinput}/bin/xinput set-prop "ErgoDox EZ ErgoDox EZ Mouse" "libinput Natural Scrolling Enabled"
${pkgs.autorandr}/bin/autorandr -c
${pkgs.feh}/bin/feh --bg-scale ${pkgs.nixos-artwork.wallpapers.simple-blue}/share/artwork/gnome/nix-wallpaper-simple-blue.png
${dpmsScript} default
'';
pointerCursor = {
name = "Vanilla-DMZ-AA";
package = pkgs.vanilla-dmz;
size = 32;
};
}; };
home.packages = with pkgs; [ home.packages = with pkgs; [
# X Tools/Libraries # X Tools/Libraries
lightdm lightdm
networkmanagerapplet qtile
gnome-icon-theme gnome3.networkmanagerapplet
gnome.gnome-themes-extra autorandr
adwaita-icon-theme arandr
gnome3.gnome_themes_standard
gnome3.adwaita-icon-theme
lxappearance lxappearance
xorg.xcursorthemes xorg.xcursorthemes
pavucontrol pavucontrol

View file

@ -1,262 +0,0 @@
/*
TODO: create helper scripts for sharing of a screen portion
```
# this will create a new output named HEADLESS-<n>. <n> increments by 1 with each invocation even if the output is `unplug`ged.
swaymsg create_output
# find the name and the workspace number
swaymsg -t get_outputs | jq '.[] | select(.name | test("HEADLESS-.*")) | (.name, .current_workspace)'
swaymsg output HEADLESS-1 mode 1920@108060Hz
# mirror the headless workspace on the current one
nix run nixpkgs\#wl-mirror -- HEADLESS-1
# shift windows to the workspace and switch the focus to it
*/
{
pkgs,
config,
lib,
# packages',
...
}:
let
lockCmd = "${pkgs.swaylock}/bin/swaylock -efF --color '#000000'";
displayOffCmd = "${pkgs.sway}/bin/swaymsg 'output * power off'";
displayOnCmd = "${pkgs.sway}/bin/swaymsg 'output * power on'";
swapOutputWorkspaces = ../../../scripts/sway-swapoutputworkspaces.sh;
in
{
imports = [
../profiles/wayland-desktop.nix
../programs/waybar.nix
];
services.dunst = {
enable = true;
};
services.gpg-agent.pinentry.package = pkgs.pinentry-gnome3;
home.packages = [
pkgs.swayidle
pkgs.swaylock
## themes
pkgs.adwaita-icon-theme
pkgs.hicolor-icon-theme
pkgs.gnome-icon-theme
## fonts
# pkgs.nerd-fonts # TODO: reinstall selected ones
pkgs.dejavu_fonts # just a basic good fond
pkgs.font-awesome_5 # needed by i3status-rust
pkgs.font-awesome
pkgs.roboto
pkgs.ttf_bitstream_vera
pkgs.noto-fonts
pkgs.noto-fonts-cjk-sans
pkgs.noto-fonts-cjk-serif
pkgs.noto-fonts-emoji
pkgs.noto-fonts-emoji-blob-bin
pkgs.noto-fonts-extra
pkgs.noto-fonts-lgc-plus
pkgs.liberation_ttf
pkgs.fira-code
pkgs.fira-code-symbols
pkgs.mplus-outline-fonts.githubRelease
pkgs.dina-font
pkgs.monoid
pkgs.hermit
### found on colemickens' repo
pkgs.gelasio # metric-compatible with Georgia
pkgs.powerline-symbols
pkgs.iosevka-comfy.comfy-fixed
## experimental stuff
pkgs.fuzzel
];
# TODO: configure kanshi to always set the 5K resolution
# DP-1 "Philips Consumer Electronics Company PHL 499P9 AU02419010010 (DP-1 via DP)"
# Make: Philips Consumer Electronics Company
# Model: PHL 499P9
# Serial: AU02419010010
# Physical size: 1190x340 mm
# Enabled: yes
# Modes:
# 3840x1080 px, 59.967999 Hz (preferred)
# 5120x1440 px, 59.977001 Hz (current)
wayland.windowManager.sway = {
enable = true;
systemd.enable = true;
xwayland = false;
config =
let
modifier = "Mod4";
inherit (config.wayland.windowManager.sway.config)
left
right
up
down
;
in
{
inherit modifier;
bars = [ ];
input = {
"type:keyboard" =
{
xkb_layout = config.home.keyboard.layout;
xkb_variant = config.home.keyboard.variant;
}
// lib.attrsets.optionalAttrs (builtins.length (config.home.keyboard.options or [ ]) > 0) {
xkb_options = builtins.concatStringsSep "," config.home.keyboard.options;
};
"type:touchpad" = {
natural_scroll = "enabled";
};
# alternatively run this command
# swaymsg input "1386:914:Wacom_Intuos_Pro_S_Pen" tool_mode "* relative"
# and then switch to a different VT (alt+ctrl+f2) and back
"1386:914:Wacom_Intuos_Pro_S_Pen" = {
tool_mode = "* relative";
};
};
keybindings = lib.mkOptionDefault {
# as of 2023-05-21 the `!!` arg parsing mode was broken for me on yofi
# "${modifier}+d" = "exec ${packages'.yofi}/bin/yofi binapps";
"${modifier}+d" = "exec ${pkgs.fuzzel}/bin/fuzzel --show-actions";
# only 1-9 exist on the default config
"${modifier}+0" = "workspace number 0";
"${modifier}+Shift+0" = "move container to workspace number 0";
# disable splitting for now as i sometimes trigger it accidentally and then get stuck with it
"${modifier}+b" = "nop";
"${modifier}+v" = "nop";
# move workspace to output
"${modifier}+Control+Shift+${left}" = "move workspace to output left";
"${modifier}+Control+Shift+${right}" = "move workspace to output right";
"${modifier}+Control+Shift+${up}" = "move workspace to output up";
"${modifier}+Control+Shift+${down}" = "move workspace to output down";
# move workspace to output with arrow keys
"${modifier}+Control+Shift+Left" = "move workspace to output left";
"${modifier}+Control+Shift+Right" = "move workspace to output right";
"${modifier}+Control+Shift+Up" = "move workspace to output up";
"${modifier}+Control+Shift+Down" = "move workspace to output down";
# TODO: i've been hitting this one accidentally way too often. find a better place.
# "${modifier}+Shift+e" = "exec ${pkgs.sway}/bin/swaymsg exit";
"${modifier}+q" = "kill";
"${modifier}+Shift+q" =
"exec ${pkgs.sway}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq 'recurse(.nodes[], .floating_nodes[]) | select(.focused).pid' | ${pkgs.findutils}/bin/xargs -L1 kill -9";
"${modifier}+x" = "exec ${swapOutputWorkspaces}";
"${modifier}+Ctrl+l" = "exec ${lockCmd}";
"--locked XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl previous";
"XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next";
"XF86AudioRaiseVolume" = "exec ${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5";
"XF86AudioLowerVolume" = "exec ${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5";
"--locked XF86AudioMute" = "exec ${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute";
"Print" = "exec ${pkgs.shotman}/bin/shotman --capture region";
};
terminal = "alacritty";
startup =
[
{
command = builtins.toString (
pkgs.writeShellScript "ensure-graphical-session" ''
(
${pkgs.coreutils}/bin/sleep 0.2
${pkgs.systemd}/bin/systemctl --user restart graphical-session.target
) &
''
);
}
]
++ lib.optionals config.services.swayidle.enable [
{
command = builtins.toString (
pkgs.writeShellScript "ensure-graphical-session" ''
(
${pkgs.coreutils}/bin/sleep 0.2
${pkgs.systemd}/bin/systemctl --user restart swayidle
) &
''
);
}
];
colors.focused = lib.mkOptionDefault { childBorder = lib.mkForce "#ffa500"; };
window.titlebar = false;
window.border = 4;
# this maps to focus_on_window_activation
focus.newWindow = "urgent";
window.commands = [
{
command = "border pixel 0, floating enable, fullscreen disable, move absolute position 0 0";
criteria.app_id = "flameshot";
}
];
};
};
services.swayidle = {
enable = true;
timeouts = [
{
timeout = 10;
command = "if ${pkgs.procps}/bin/pgrep -x swaylock; then ${displayOffCmd}; fi";
resumeCommand = displayOnCmd;
}
{
timeout = 60 * 5;
command = lockCmd;
}
{
timeout = 60 * 6;
command = displayOffCmd;
resumeCommand = displayOnCmd;
}
];
events = [
{
event = "before-sleep";
command = builtins.concatStringsSep "; " [
lockCmd
"${pkgs.playerctl}/bin/playerctl pause"
];
}
{
event = "after-resume";
command = displayOnCmd;
}
{
event = "lock";
command = lockCmd;
}
];
};
}

View file

@ -1,87 +0,0 @@
{
pkgs,
lib,
repoFlake,
...
}:
let
nixpkgs-wayland' = repoFlake.inputs.nixpkgs-wayland.packages.${pkgs.system};
in
{
fonts.fontconfig.enable = true;
# services.gpg-agent.pinentryFlavor = lib.mkForce null;
# services.gpg-agent.extraConfig = ''
# pinentry-program "${wayprompt}/bin/pinentry-wayprompt"
# '';
services = {
blueman-applet.enable = true;
network-manager-applet.enable = true;
};
systemd.user.targets.tray = {
Unit = {
Description = "Home Manager System Tray";
Requires = [ "graphical-session-pre.target" ];
};
};
home.packages =
with pkgs;
[
# required by network-manager-applet
networkmanagerapplet
wlr-randr
wayout
wl-clipboard
wmctrl
nixpkgs-wayland'.shotman
# identifies key input syms
wev
# TODO: whwat's this for?
# wltype
qt5.qtwayland
qt6.qtwayland
# libsForQt5.qt5.qtwayland
# libsForQt6.qt6.qtwayland
# audio
playerctl
helvum
pasystray
sonusmix
pwvucontrol
# probably required by flameshot
# xdg-desktop-portal xdg-desktop-portal-wlr
# grim
waypipe
]
++ (lib.lists.optionals (!pkgs.stdenv.isAarch64)
# TODO: broken on aarch64
[ ]
);
home.sessionVariables = {
XDG_SESSION_TYPE = "wayland";
NIXOS_OZONE_WL = "1";
MOZ_ENABLE_WAYLAND = "1";
WLR_NO_HARDWARE_CURSORS = "1";
};
home.pointerCursor = {
name = "Vanilla-DMZ";
package = pkgs.vanilla-dmz;
size = 32;
x11.enable = true;
gtk.enable = true;
};
}

View file

@ -1,81 +1,23 @@
{ {
name, ...
lib,
pkgs,
...
}: }:
let
extensions =
[
#undetectable adblocker
{ id = "gcfcpohokifjldeandkfjoboemihipmb"; }
# ublock origin
{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; }
# # YT ad block
# {id = "cmedhionkhpnakcndndgjdbohmhepckk";}
# # Adblock Plus
# {id = "cfhdojbkjhnklbpkdaibdccddilifddb";}
# Cookie Notice Blocker
{ id = "odhmfmnoejhihkmfebnolljiibpnednn"; }
# i don't care about cookies
{ id = "fihnjjcciajhdojfnbdddfaoknhalnja"; }
# NopeCHA
{ id = "dknlfmjaanfblgfdfebhijalfmhmjjjo"; }
# h264ify
{ id = "aleakchihdccplidncghkekgioiakgal"; }
# clippy
# {id = "honbeilkanbghjimjoniipnnehlmhggk"}
{
id = "dcpihecpambacapedldabdbpakmachpb";
updateUrl = "https://raw.githubusercontent.com/iamadamdev/bypass-paywalls-chrome/master/updates.xml";
}
# cookie autodelete
{ id = "fhcgjolkccmbidfldomjliifgaodjagh"; }
# unhook
{ id = "khncfooichmfjbepaaaebmommgaepoid"; }
]
++ (lib.lists.optionals ((builtins.match "^steveej.*" name) != null) [
# polkadotjs
{ id = "mopnmbcafieddcagagdcbnhejhlodfdd"; }
# rabby wallet
{ id = "acmacodkjbdgmoleebolmdjonilkdbch"; }
# phantom wallet
{ id = "bfnaelmomeimhlpmgjnjophhpkkoljpa"; }
# Vimium C
{ id = "hfjbmagddngcpeloejdejnfgbamkjaeg"; }
# TODO: this causes scrolling the tab bar all the way to the end. look for a different one or report
# always right
{ id = "npjpaghfnndnnmjiliibnkmdfgbojokj"; }
# shazam music
{ id = "mmioliijnhnoblpgimnlajmefafdfilb"; }
]);
in
{ {
programs.chromium = { programs.chromium = {
enable = true; enable = true;
inherit extensions;
# TODO: extensions currently don't work with ungoogled-chromium
package = pkgs.chromium;
}; };
programs.brave = { nixpkgs.config = {
# TODO: enable this on aarch64-linux chromium = {
enable = true && !pkgs.stdenv.targetPlatform.isAarch64; # 2019-03-05: missing on 19.03 enablePepperPDF = true;
inherit extensions; enablePepperFlash = false;
};
};
programs.browserpass = {
browsers = [
"chromium"
];
}; };
} }

View file

@ -0,0 +1,24 @@
{ pkgs,
...
}:
{
programs.emacs = {
enable = true;
extraPackages = epkgs: (with epkgs; [
nix-mode
magit # ; Integrate git <C-x g>
zerodark-theme # ; Nicolas' theme
undo-tree # ; <C-x u> to show the undo tree
# zoom-frm # ; increase/decrease font size for all buffers %lt;C-x C-+>
]) ++ (with epkgs.melpaPackages; [
evil
]) ++ (with epkgs.elpaPackages; [
auctex # ; LaTeX mode
beacon # ; highlight my cursor when scrolling
nameless # ; hide current package name everywhere in elisp code
]) ++ (with pkgs; [
pkgs.notmuch # From main packages set
]);
};
}

View file

@ -1,82 +0,0 @@
{ pkgs, ... }:
{
services.espanso = {
package = pkgs.espanso-wayland;
# package = pkgs.espanso-wayland.overrideAttrs (_: {
# src = repoFlake.inputs.espanso;
# cargoLock = {
# # lockFile = "${repoFlake.inputs.espanso.outPath}/Cargo.lock";
# lockFile = repoFlake.inputs.espanso + "/Cargo.lock";
# outputHashes = {
# "yaml-rust-0.4.6" = "sha256-wXFy0/s4y6wB3UO19jsLwBdzMy7CGX4JoUt5V6cU7LU=";
# };
# };
# });
enable = false;
configs = {
default = {
# backend = "Inject";
# backend = "Clipboard";
};
};
matches =
let
playerctl = ''${pkgs.coreutils}/bin/env DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(${pkgs.coreutils}/bin/id -u)/bus" ${pkgs.playerctl}/bin/playerctl'';
in
{
default = {
matches = [
{
trigger = ":vpos";
replace = "{{output}}";
vars = [
{
name = "output";
type = "script";
params = {
args = [
(pkgs.writeScript "espanso" ''
#! ${pkgs.python3}/bin/python
import subprocess, os, math, datetime
id=str(os.getuid())
result=subprocess.run(args=["${pkgs.playerctl}/bin/playerctl", "position"], env={"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/"+id+"/bus"},capture_output=True)
result.check_returncode()
position_secs = math.trunc(float(result.stdout))
position_human = datetime.timedelta(seconds=position_secs)
print("%s - %s" % (position_human, position_secs))
'')
];
};
}
];
}
{
trigger = ":vtit";
replace = "{{output}}";
vars = [
{
name = "output";
type = "script";
params = {
args = [ (pkgs.writeShellScript "espanso" "${playerctl} metadata title") ];
};
}
];
}
{
trigger = ":dunno";
replace = "¯\\_()_/¯";
}
{
trigger = ":shrug";
replace = "¯\\_()_/¯";
}
];
};
};
};
}

View file

@ -1,451 +1,19 @@
{ { pkgs
repoFlake, , ...
pkgs,
config,
lib,
...
}: }:
let
# Search extension names with below command:
# nix flake show --json "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons" --all-systems | jq -r '.packages."x86_64-linux" | keys[]' | rg QUERY
ryceeAddons = with pkgs.nur.repos.rycee.firefox-addons; [
ublock-origin
# bypass-paywalls-clean (can't use, was creating popups)
consent-o-matic
terms-of-service-didnt-read
auto-tab-discard
# redirector # For nixos wiki
# darkreader
facebook-container
control-panel-for-twitter
# containerise
facebook-tracking-removal
vimium
cookie-autodelete
auto-tab-discard
istilldontcareaboutcookies
youtube-recommended-videos
display-_anchors
];
customAddons = [
];
search = {
force = true;
default = "ddg";
privateDefault = "ddg";
order = [
"ddg"
"ecosia"
"google"
];
};
mkProfile =
override:
lib.recursiveUpdate {
extensions.packages = ryceeAddons ++ customAddons;
inherit search;
settings = {
# automatically enable extensions
"extensions.autoDisableScopes" = 0;
"middlemouse.paste" = false;
"browser.download.useDownloadDir" = false;
"browser.tabs.insertAfterCurrent" = true;
"browser.tabs.warnOnClose" = true;
"browser.toolbars.bookmarks.visibility" = "never";
"browser.quitShortcut.disabled" = false;
# restore the previous session automatically
"browser.startup.page" = 3;
"browser.sessionstore.resume_from_crash" = true;
"browser.sessionstore.restore_pinned_tabs_on_demand" = true;
"browser.sessionstore.restore_on_demand" = true;
"browser.urlbar.suggest.bookmark" = true;
"browser.urlbar.suggest.engines" = true;
"browser.urlbar.suggest.history" = true;
"browser.urlbar.suggest.openpage" = true;
"browser.urlbar.suggest.topsites" = false;
"browser.urlbar.trimHttps" = true;
"sidebar.position_start" = false;
"findbar.highlightAll" = true;
"browser.tabs.hoverPreview.enabled" = true;
# Disable fx accounts
"identity.fxaccounts.enabled" = false;
# Disable "save password" prompt
"signon.rememberSignons" = false;
# Harden
"privacy.trackingprotection.enabled" = true;
"dom.security.https_only_mode" = true;
# Disable irritating first-run stuff
"browser.disableResetPrompt" = true;
"browser.download.panel.shown" = true;
"browser.feeds.showFirstRunUI" = false;
"browser.messaging-system.whatsNewPanel.enabled" = false;
"browser.rights.3.shown" = true;
"browser.shell.checkDefaultBrowser" = false;
"browser.shell.defaultBrowserCheckCount" = 1;
"browser.startup.homepage_override.mstone" = "ignore";
"browser.uitour.enabled" = false;
"startup.homepage_override_url" = "";
"trailhead.firstrun.didSeeAboutWelcome" = true;
"browser.bookmarks.restore_default_bookmarks" = false;
"browser.bookmarks.addedImportButton" = true;
# Disable "Save to Pocket" or Pocket entirely
"extensions.pocket.enabled" = false;
# Disable telemetry
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.archive.enabled" = false;
"datareporting.healthreport.uploadEnabled" = false;
"app.shield.optoutstudies.enabled" = false;
"browser.discovery.enabled" = false;
"browser.newtabpage.activity-stream.feeds.telemetry" = false;
"browser.newtabpage.activity-stream.telemetry" = false;
"browser.ping-centre.telemetry" = false;
"datareporting.healthreport.service.enabled" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.sessions.current.clean" = true;
"devtools.onboarding.telemetry.logged" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.hybridContent.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.prompted" = 2;
"toolkit.telemetry.rejected" = true;
"toolkit.telemetry.reportingpolicy.firstRun" = false;
"toolkit.telemetry.server" = "";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.unifiedIsOptIn" = false;
"toolkit.telemetry.updatePing.enabled" = false;
# Disable any feeds on the new tab page
"browser.newtabpage.activity-stream.showTopSites" = false;
"browser.newtabpage.activity-stream.default.sites" = lib.mkForce [ ];
"browser.newtabpage.activity-stream.discoverystream.enabled" = false;
"browser.newtabpage.activity-stream.feeds.topsites" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts" = false;
"browser.newtabpage.blocked" = lib.genAttrs [
# Youtube
"26UbzFJ7qT9/4DhodHKA1Q=="
# Facebook
"4gPpjkxgZzXPVtuEoAL9Ig=="
# Wikipedia
"eV8/WsSLxHadrTL1gAxhug=="
# Reddit
"gLv0ja2RYVgxKdp0I5qwvA=="
# Amazon
"K00ILysCaEq8+bEqV/3nuw=="
# Twitter
"T9nJot5PurhJSy8n038xGA=="
] (_: 1);
"browser.topsites.blockedSponsors" = [
"adidas"
"temuaffiliateprogram.pxf"
"s.click.aliexpress"
];
# enable userChrome
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"devtools.chrome.enabled" = true;
"devtools.debugger.remote-enabled" = true;
# disable translations for some languages
"browser.translations.neverTranslateLanguages" = [
"en"
"de"
];
"browser.translations.automaticallyPopup" = false;
# enable pipewire (and libcamera) sources
"media.webrtc.camera.allow-pipewire" = true;
};
userChrome =
let
name = override.color or colors.grey;
value = colorValues."${name}".normal;
valueBright = colorValues."${name}".highlight;
valueDark = colorValues."${name}".inactive;
in
''
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* only needed once */
#nav-bar {
background-color: ${value} !important;
color: black !important;
}
/* don't show close button on background tabs */
#tabbrowser-tabs[closebuttons="activetab"] .tabbrowser-tab:not([selected]):not([pinned]):not([hover]) .tab-close-button {
display: none !important;
}
/* show close button on hover */
#tabbrowser-tabs[closebuttons="activetab"] .tabbrowser-tab:not([selected]):not([pinned]):hover .tab-close-button {
display: -moz-inline-box !important;
}
/* default */
#TabsToolbar {
background: ${valueDark} !important;
}
/* default tab */
#TabsToolbar #tabbrowser-tabs .tabbrowser-tab .tab-content {
background: ${value} !important;
opacity: 0.8
}
/* selected tab */
#TabsToolbar #tabbrowser-tabs .tabbrowser-tab[selected] .tab-content {
background: ${valueBright} !important;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
}
/* hovered tab */
#TabsToolbar #tabbrowser-tabs .tabbrowser-tab:hover:not([selected]) .tab-content {
background: ${valueBright} !important;
}
/* unloaded/pending tab */
#TabsToolbar #tabbrowser-tabs .tabbrowser-tab[pending] .tab-content {
background: ${valueDark} !important;
}
'';
# /* new tab */
# #TabsToolbar #tabbrowser-tabs #tabs-newtab-button .toolbarbutton-icon {
# background: unset !important;
# }
# #TabsToolbar #tabbrowser-tabs #tabs-newtab-button {
# /* background: var(--default_tabs_bg_newtab) !important;
# }
# /* hovered new tab */
# #TabsToolbar #tabbrowser-tabs #tabs-newtab-button:hover {
# background: var(--default_tabs_bg_newtab_hovered) !important;
# }
} (builtins.removeAttrs override [ "color" ]);
# TODO: insert the id automatically
mkProfiles = attrs: builtins.mapAttrs (_k: v: v) attrs;
colors = builtins.mapAttrs (name: _: name) colorValues;
colorValues = {
blue = {
normal = "#49b1fc";
highlight = "#05a9fc"; # Brighter blue
inactive = "#1f81c6"; # Darker blue
};
green = {
normal = "#51cd00";
highlight = "#5ae200"; # Brighter green
inactive = "#45ad00"; # Darker green
};
orange = {
normal = "#ff9800";
highlight = "#ffb74d"; # Brighter orange
inactive = "#c76a00"; # Darker orange
};
red = {
normal = "#f6685e";
highlight = "#ff4336"; # Brighter red
inactive = "#aa463f"; # Darker red
};
yellow = {
normal = "#fced4b";
highlight = "#fce705"; # Brighter yellow
inactive = "#dbbe00"; # Darker yellow
};
purple = {
normal = "#9c27b0";
highlight = "#ab47bc"; # Brighter purple
inactive = "#7b1fa2"; # Darker purple
};
pink = {
normal = "#e91e63";
highlight = "#ff6090"; # Brighter pink
inactive = "#c2185b"; # Darker pink
};
brown = {
normal = "#795548";
highlight = "#a88b6f"; # Brighter brown
inactive = "#4e3b30"; # Darker brown
};
grey = {
normal = "#9e9e9e";
highlight = "#bdbdbd"; # Brighter grey
inactive = "#757575"; # Darker grey
};
teal = {
normal = "#009688";
highlight = "#26c6da"; # Brighter teal
inactive = "#00796b"; # Darker teal
};
};
in
{ {
nixpkgs.overlays = [
repoFlake.inputs.nur.overlays.default
];
nixpkgs.config.allowUnfreePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"youtube-recommended-videos"
];
programs.librewolf = {
enable = false;
};
programs.firefox = { programs.firefox = {
enable = true; enable = true;
package = pkgs.firefox; enableAdobeFlash = false;
profiles =
lib.filterAttrs (_: v: config.home.username == "steveej" || (v.isDefault or false))
(mkProfiles {
"personal" = mkProfile {
id = 0;
isDefault = true;
color = colors.blue;
};
"comms" = mkProfile {
id = 1;
color = colors.blue;
};
"admin" = mkProfile {
id = 2;
color = colors.blue;
};
"infra" = mkProfile {
id = 3;
color = colors.blue;
};
"finance" = mkProfile {
id = 4;
color = colors.yellow;
};
"business-admin" = mkProfile {
id = 5;
color = colors.teal;
};
"business-comms" = mkProfile {
id = 6;
color = colors.teal;
};
"business-dev" = mkProfile {
id = 7;
color = colors.teal;
};
"holo-dev" = mkProfile {
id = 8;
color = colors.green;
};
"holo-infra" = mkProfile {
id = 9;
color = colors.green;
};
"holo-comms" = mkProfile {
id = 10;
color = colors.green;
};
"justyna" = mkProfile {
id = 11;
color = colors.pink;
};
"justyna-office" = mkProfile {
id = 12;
color = colors.pink;
};
"tech-research" = mkProfile {
id = 13;
color = colors.purple;
};
});
# policies = {
# # search via policy. the other one doesn't always work because of schema version mismatch
# SearchEngines = {
# Default = "Qwant";
# PreventInstalls = true;
# Add = [
# {
# Method = "GET";
# Alias = "qwant";
# Description = "Description";
# # PostData= "name=value&q={searchTerms}";
# Name = "Qwant";
# SuggestURLTemplate = "https://api.qwant.com/api/suggest/?q={searchTerms}";
# URLTemplate = "https://www.qwant.com/?q={searchTerms}";
# }
# ];
# };
# };
}; };
# create one desktop entry for each profile programs.browserpass = {
xdg.desktopEntries = lib.mapAttrs' ( browsers = [
k: _v: "firefox"
lib.nameValuePair "firefox-profile-${k}" { ];
categories = [ };
"Network"
"WebBrowser" home.file.".mozilla/native-messaging-hosts/passff.json".source = "${pkgs.passff-host}/share/passff-host/passff.json";
];
exec = "${lib.getExe config.programs.firefox.package} -P ${k}";
genericName = "Web Browser";
icon =
builtins.replaceStrings [ ".desktop" ] [ "" ]
config.programs.firefox.package.desktopItem.name;
mimeType = [
"text/html"
"text/xml"
"application/xhtml+xml"
"application/vnd.mozilla.xul+xml"
"x-scheme-handler/http"
"x-scheme-handler/https"
];
name = "Firefox: ${k}";
startupNotify = true;
settings.StartupWMClass =
# To group windows of different profiles.
# Set WM_CLASS on Xorg using --class, set app-id on Wayland using --name.
#if profile.name == "default"
#then "firefox"
#else "firefox-${profile.name}";
"firefox";
terminal = false;
type = "Application";
}
) config.programs.firefox.profiles;
} }

View file

@ -1,24 +0,0 @@
{
lib,
pkgs,
osConfig,
...
}:
{
home.packages = [ pkgs.gcr ];
programs.gpg.enable = true;
services.gpg-agent = {
enable = true;
enableScDaemon = !osConfig.services.pcscd.enable;
enableSshSupport = true;
grabKeyboardAndMouse = true;
pinentry.package = lib.mkDefault pkgs.pinentry-gtk2;
extraConfig = ''
no-allow-external-cache
'';
defaultCacheTtl = 0;
maxCacheTtl = 0;
};
}

View file

@ -1,29 +1,38 @@
{ pkgs, config, ... }: { pkgs
{ , config
home.sessionVariables.HOMESHICK_DIR = "${pkgs.homeshick}"; , ...
}:
home.activation.bootstrapRepos = config.lib.dag.entryAfter [ "writeBoundary" ] '' let
# TODO: clean up the impurity in here
in {
home.sessionVariables = {
HOMESHICK_DIR="${pkgs.homeshick}";
};
home.activation.bootstrapRepos = config.lib.dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD ${pkgs.writeScript "activation-script" '' $DRY_RUN_CMD ${pkgs.writeScript "activation-script" ''
set -e set -e
echo home-manager path is ${config.home.path} echo home-manager path is ${config.home.path}
echo home is $HOME echo home is $HOME
source ${pkgs.homeshick}/homeshick.sh source ${pkgs.homeshick}/homeshick.sh
type homeshick type homeshick
# echo Updating homeshick # echo Updating homeshick
# ln -sfT ${pkgs.homeshick} "$HOMESICK_REPOS"/.homeshick # ln -sfT ${pkgs.homeshick} "$HOMESICK_REPOS"/.homeshick
# mv -Tf "$HOMESICK_REPOS"/{.,}homeshick # mv -Tf "$HOMESICK_REPOS"/{.,}homeshick
''}; ''};
''; '';
nixpkgs.config = { nixpkgs.config = {
packageOverrides =
pkgs: with pkgs; { packageOverrides = pkgs: with pkgs; {
homeshick = builtins.fetchGit { homeshick = builtins.fetchGit {
url = "https://github.com/andsens/homeshick.git"; url = "https://github.com/andsens/homeshick.git";
ref = "master"; ref = "master";
};
}; };
};
}; };
} }

View file

@ -1,8 +1,14 @@
{ pkgs, nodeFlake, ... }: { pkgs,
...
}:
let
pkgsStable = nodeFlake.inputs.nixpkgs-stable.legacyPackages.${pkgs.system};
in
{ {
home.packages = [ pkgsStable.libreoffice ]; home.sessionVariables = {
# Workaround for Libreoffice to force gtk3
SAL_USE_VCLPLUGIN = "gtk3";
};
home.packages = with pkgs; [
libreoffice-fresh
];
} }

View file

@ -1,163 +1,166 @@
{ repoFlake, pkgs, ... }: { pkgs,
{ ...
imports = [ repoFlake.inputs.nixvim.homeManagerModules.nixvim ]; }:
programs.nixvim = { let
enable = true; unstablepkgs = import <channels-nixos-unstable> {};
defaultEditor = true;
vimdiffAlias = true;
vimAlias = true;
extraPython3Packages = ps: with ps; [ ]; in {
home.sessionVariables = {
EDITOR = "nvim";
};
# extraConfigVim = builtins.readFile ./neovim/vimrc; nixpkgs.config = {
pidgin = {
clipboard = { openssl = true;
register = "unnamedplus"; gnutls = true;
providers.wl-copy.enable = true;
}; };
plugins = { packageOverrides = pkgs: with pkgs; {
airline = { neovim = unstablepkgs.neovim;
enable = true; vimPlugins = unstablepkgs.vimPlugins;
settings = { };
powerline_fonts = 1; };
skip_empty_sections = 1;
theme = "papercolor"; programs.neovim = {
enable = true;
extraPythonPackages = (ps: with ps; [ ]);
extraPython3Packages = (ps: with ps; [ ]);
configure = {
customRC = builtins.readFile ./neovim/vimrc;
vam = {
knownPlugins = with pkgs; vimPlugins // {
delimitMate = vimUtils.buildVimPlugin {
name = "delimitMate-vim";
src = fetchFromGitHub {
owner = "Raimondi";
repo = "delimitMate";
rev = "728b57a6564c1d2bdfb9b9e0f2f8c5ba3d7e0c5c";
sha256 = "0fskm9gz81dk8arcidrm71mv72a7isng1clssqkqn5wnygbiimsn";
};
buildInputs = [ zip vim ];
};
yaml-folds = vimUtils.buildVimPlugin {
name = "vim-yaml-folds";
src = fetchFromGitHub {
owner = "pedrohdz";
repo = "vim-yaml-folds";
rev = "0672d9a3b685b51b4c49d8716c2ad4e27cfa5abd";
sha256 = "0yp2jgaqiria79lh75fkrs77rw7nk518bq63w9bvyy814i7s4scn";
};
buildInputs = [ zip vim ];
};
vim-yaml = vimUtils.buildVimPlugin {
name = "vim-yaml";
src = fetchFromGitHub {
owner = "stephpy";
repo = "vim-yaml";
rev = "e97e063b16eba4e593d620676a0a15fa98613979";
sha256 = "0vqahbrnr43lxanpziyrmzaqqb3cmyny8ry1xvmy2xyd1larzfrk";
};
};
vim-markdown-toc = vimUtils.buildVimPlugin {
name = "vim-markdown-toc";
src = fetchFromGitHub {
owner = "mzlogin";
repo = "vim-markdown-toc";
rev = "a6e227023f405a7c39590a8aaf0d54dde5614a2e";
sha256 = "1vpsnjzc7hvrkp6mq68myxl3k1x363iif58rrd17njcsa4jh1zwy";
};
};
vim-perl = vimUtils.buildVimPlugin {
name = "vim-perl";
src = fetchFromGitHub {
owner = "vim-perl";
repo = "vim-perl";
rev = "21d0a0d795336acf8a9306da35f379c32cfc5e08";
sha256 = "0f2sa0v3djd89k16n4saji9n7grziyhkljq75dskcbv8r19m8i1j";
};
};
git-blame = vimUtils.buildVimPlugin {
name = "git-blame";
src = fetchFromGitHub {
"owner" = "zivyangll";
"repo" = "git-blame.vim";
"rev" = "a5b666840eead1b1ea1c351038da6ce026716bb6";
"sha256" = "181siphb87yzln9433159ssa6vmm1h2dd0kqhlx7bgsi51gng4rv";
};
};
tlib = vimPlugins.tlib_vim;
}; };
};
fugitive.enable = true;
gitblame.enable = true;
lsp = {
enable = true;
};
nix.enable = true; pluginDictionaries = let
default = [
"delimitMate"
"vim-airline"
"vim-airline-themes"
"ctrlp"
"vim-css-color"
"rainbow_parentheses"
"vim-colorschemes"
"vim-colorstepper"
"vim-signify"
"fugitive"
"vim-indent-guides"
"UltiSnips"
"fzfWrapper"
# TODO: enable in next release "ncm2"
# numbertoggle.enable = true; "ncm2-bufword"
"ncm2-path"
"ncm2-tmux"
"ncm2-ultisnips"
"nvim-yarp"
# successfor to ctrlp and fzf "LanguageClient-neovim"
telescope.enable = true;
todo-comments.enable = true; "Improved-AnsiEsc"
"tabular"
"git-blame"
toggleterm.enable = true; # Nix
"vim-addon-nix" "tlib"
"vim-addon-vim2nix"
treesitter = { # LaTeX
enable = true; "vim-latex-live-preview"
"vimtex"
grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [ # YAML
bash "yaml-folds"
json "vim-yaml"
lua
make # Perl
markdown # "vim-perl"
nix
regex
toml # markdown
vim "vim-markdown"
vimdoc "vim-markdown-toc"
xml
yaml # misc syntax support
"vim-bazel" "maktaba"
];
in [
{ names = default; }
{ names = default ++ [
];
filename_regex = ".*\.nix\$";
}
{ names = default ++ [
];
filename_regex = ".*\.tex\$";
}
]; ];
}; };
treesitter-context.enable = true;
treesitter-refactor.enable = true;
# This plugin trims trailing whitespace and lines.
trim.enable = true;
web-devicons.enable = true;
}; };
# plugins = with pkgs;
# [
# # yaml-folds
# {
# plugin = vimUtils.buildVimPlugin {
# name = "vim-yaml-folds";
# src = fetchFromGitHub {
# owner = "pedrohdz";
# repo = "vim-yaml-folds";
# rev = "890ccd8e5370808d569e96dbb06cbeca2cf5993a";
# sha256 = "018z6xcwrq58q6lj6gwhrifjaxkmrlkkg0n86s6mjjlwkbs2qa4m";
# };
# buildInputs = [zip vim];
# };
# }
# {
# plugin = vimUtils.buildVimPlugin {
# name = "vim-yaml";
# src = fetchFromGitHub {
# owner = "stephpy";
# repo = "vim-yaml";
# rev = "e97e063b16eba4e593d620676a0a15fa98613979";
# sha256 = "0vqahbrnr43lxanpziyrmzaqqb3cmyny8ry1xvmy2xyd1larzfrk";
# };
# };
# }
# {
# plugin = vimUtils.buildVimPlugin {
# name = "git-blame";
# src = fetchFromGitHub {
# "owner" = "zivyangll";
# "repo" = "git-blame.vim";
# "rev" = "9d144b7bed5d8f1c9259551768b7f3b3d1294917";
# "sha256" = "06zb5xcc59k25rpwl46j82fcqckiznmj97v6i0mwlb8jhqqrhy9j";
# };
# };
# }
# ]
# ++ (with pkgs.vimPlugins; [
# delimitMate
# vim-airline
# vim-airline-themes
# ctrlp
# vim-css-color
# rainbow_parentheses
# vim-colorschemes
# vim-colorstepper
# vim-signify
# fugitive
# vim-indent-guides
# UltiSnips
# fzfWrapper
# ncm2
# ncm2-bufword
# ncm2-path
# ncm2-tmux
# ncm2-ultisnips
# nvim-yarp
# LanguageClient-neovim
# Improved-AnsiEsc
# tabular
# # Nix
# vim-addon-nix
# tlib
# vim-addon-vim2nix
# # LaTeX
# vim-latex-live-preview
# vimtex
# # YAML
# vim-yaml
# # markdown
# vim-markdown
# vim-markdown-toc
# # misc syntax support
# vim-bazel
# maktaba
# ]);
}; };
} }

View file

@ -46,11 +46,9 @@ noremap <C-p> :tabp<CR>
let g:ctrlp_map = '<tab>' let g:ctrlp_map = '<tab>'
set wildignore+=*/site/*,*.so,*.swp,*.zip set wildignore+=*/site/*,*.so,*.swp,*.zip
let g:ctrlp_custom_ignore = { let g:ctrlp_custom_ignore = {
\ 'dir': '\v[\/]\.(git|hg|svn)$$', \ 'dir': '\v[\/]\.(git|hg|svn|)$$',
\ 'file': '\v\.(exe|so|dll)$$', \ 'file': '\v\.(exe|so|dll)$$',
\ } \ }
"let g:ctrlp_max_files=0
"let g:ctrlp_max_depth=1000
"let g:ctrlp_match_func = { 'match': 'pymatcher#PyMatch' } "let g:ctrlp_match_func = { 'match': 'pymatcher#PyMatch' }
"let g:pydiction_location = '~/.vim/bundle/pydiction/complete-dict' "let g:pydiction_location = '~/.vim/bundle/pydiction/complete-dict'

View file

@ -1,25 +0,0 @@
{ pkgs, lib, ... }:
{
programs.obs-studio = {
enable = true;
plugins =
builtins.map
(
plugin:
(plugin.overrideAttrs (attrs: {
meta = lib.mkMerge [
{ inherit (attrs) meta; }
{ meta.platforms = [ pkgs.stdenv.system ]; }
];
}))
)
(
with pkgs.obs-studio-plugins;
[
# wlrobs
obs-backgroundremoval
obs-pipewire-audio-capture
]
);
};
}

View file

@ -1,37 +0,0 @@
{ pkgs, repoFlake, ... }:
let
pkgsVscodium = import repoFlake.inputs.nixpkgs-vscodium { inherit (pkgs) system config; };
in
{
home.packages = [
pkgs.nil
pkgs.nixd
pkgs.nixfmt-rfc-style
# TODO: automate linking this
# 1. get the commit with: `codium --version`
# 2. create the binary directory: `mkdir -p /home/steveej/.vscodium-server/bin/c8ce3ba4bc6b30b3b10edc61481cb85b1d2396bc/bin/`
# 3. link the binary. this relies on the client-side setting `"remote.SSH.experimental.serverBinaryName": "openvscode-server"` : ln -s $(which openvscode-server) /home/steveej/.vscodium-server/bin/c8ce3ba4bc6b30b3b10edc61481cb85b1d2396bc/bin/
/*
e.g.:
```
(
set -e
export COMMIT=$(codium --version | rg '^[0-9a-f]{40}$')
ssh bm-hostkey0 "pkill -9 openvscode; rm -rf /home/steveej/.vscodium-server/bin/$COMMIT; mkdir -p /home/steveej/.vscodium-server/bin/$COMMIT/bin/; ln -s \$(which openvscode-server) /home/steveej/.vscodium-server/bin/$COMMIT/bin/"
)
```
*/
(pkgsVscodium.openvscode-server.overrideAttrs (attrs: {
src = repoFlake.inputs.openvscode-server;
version = "1.94.2";
yarnCache = attrs.yarnCache.overrideAttrs (_: {
outputHash = "sha256-89c6GYLT2RzHqwxBKegYqB6g5rEJ6/nH53cnfV7b0Tt=";
});
}))
pkgs.waypipe
];
}

View file

@ -1,17 +1,23 @@
{ repoFlake, pkgs, ... }: { pkgs
, ...
}:
{ {
# required by pass-otp home.sessionVariables = {
# home.sessionVariables.PASSWORD_STORE_EXTENSIONS_DIR = "$HOME/.nix-profile/lib/password-store/extensions"; # required by pass-otp
# home.sessionVariables.PASSWORD_STORE_ENABLE_EXTENSIONS = "true"; PASSWORD_STORE_EXTENSIONS_DIR = "$HOME/.nix-profile/lib/password-store/extensions";
# programs.browserpass.enable = true; PASSWORD_STORE_ENABLE_EXTENSIONS = "true";
};
programs.browserpass = {
enable = true;
};
home.packages = [ home.packages = with pkgs; [
pkgs.gnupg pass-otp
qtpass
# broken on wayland rofi-pass
# rofi-pass gnupg
(pkgs.callPackage repoFlake.lib.prsFn {
})
]; ];
} }

View file

@ -0,0 +1,160 @@
{ pkgs
, ...
}:
let
cniConfigDir = let
loopback = pkgs.writeText "00-loopback.conf" ''
{
"cniVersion": "0.3.0",
"type": "loopback"
}
'';
podman-bridge = pkgs.writeText "87-podman-bridge.conflist" ''
{
"cniVersion": "0.3.0",
"name": "podman",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"subnet": "10.88.0.0/16",
"routes": [
{ "dst": "0.0.0.0/0" }
]
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
'';
in pkgs.runCommand "cniConfig" {} ''
set -x
mkdir $out;
ln -s ${loopback} $out/${loopback.name}
ln -s ${podman-bridge} $out/${podman-bridge.name}
'';
containersConf = pkgs.writeText "containers.conf" ''
# containers.conf is the default configuration file for all tools using libpod to
# manage containers
# Default transport method for pulling and pushing for images
image_default_transport = "docker://"
# Paths to search for the conmon container manager binary. If the paths are empty or no valid path was found, then the $PATH environment variable will be used as the fallback.
conmon_path = [
"${pkgs.conmon}/bin/conmon"
]
# --runtime ${pkgs.crun}/bin/crun \
runtime = "crun"
# Environment variables to pass into conmon
conmon_env_vars = [
]
# CGroup Manager - valid values are "systemd" and "cgroupfs"
# cgroup_manager = "systemd"
cgroup_manager = "cgroupfs"
# Maximum size of log files (in bytes)
# -1 is unlimited
max_log_size = -1
# Whether to use chroot instead of pivot_root in the runtime
no_pivot_root = false
# Directory containing CNI plugin configuration files
cni_config_dir = "${cniConfigDir}"
# Directories where the CNI plugin binaries may be located
cni_plugin_dir = [
"${pkgs.cni-plugins}/bin"
]
# Default CNI network for libpod.
# If multiple CNI network configs are present, libpod will use the network with
# the name given here for containers unless explicitly overridden.
# The default here is set to the name we set in the
# 87-podman-bridge.conflist included in the repository.
# Not setting this, or setting it to the empty string, will use normal CNI
# precedence rules for selecting between multiple networks.
cni_default_network = "podman"
# Default libpod namespace
# If libpod is joined to a namespace, it will see only containers and pods
# that were created in the same namespace, and will create new containers and
# pods in that namespace.
# The default namespace is "", which corresponds to no namespace. When no
# namespace is set, all containers and pods are visible.
#namespace = ""
# Default pause image name for pod pause containers
pause_image = "k8s.gcr.io/pause:3.1"
# Default command to run the pause container
pause_command = "/pause"
# Determines whether libpod will reserve ports on the host when they are
# forwarded to containers. When enabled, when ports are forwarded to containers,
# they are held open by conmon as long as the container is running, ensuring that
# they cannot be reused by other programs on the host. However, this can cause
# significant memory usage if a container has many ports forwarded to it.
# Disabling this can save memory.
enable_port_reservation = true
# Default libpod support for container labeling
# label=true
'';
in {
home.packages = with pkgs; [
podman
];
home.file.".config/containers/containers.conf".source = containersConf;
home.file.".config/containers/registries.conf".text = ''
[registries.search]
registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']
[registries.insecure]
registries = []
#blocked (docker only)
[registries.block]
registries = []
'';
home.file.".config/containers/storage.conf".text = ''
[storage]
driver = "btrfs"
'';
home.file.".config/containers/policy.json".text = ''
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports":
{
"docker-daemon":
{
"": [{"type":"insecureAcceptAnything"}]
}
}
}
'';
}

View file

@ -1,89 +0,0 @@
{
config,
lib,
pkgs,
osConfig,
...
}:
let
libdecsync = pkgs.python3Packages.buildPythonPackage rec {
pname = "libdecsync";
version = "2.2.1";
src = pkgs.python3Packages.fetchPypi {
inherit pname version;
hash = "sha256-Mukjzjumv9VL+A0maU0K/SliWrgeRjAeiEdN5a83G0I=";
};
propagatedBuildInputs = [
# pkgs.libxcrypt-legacy
];
};
radicale-storage-decsync = pkgs.python3Packages.buildPythonPackage rec {
pname = "radicale_storage_decsync";
version = "2.1.0";
src = pkgs.python3Packages.fetchPypi {
inherit pname version;
hash = "sha256-X+0MT5o2PjsKxca5EDI+rYyQDmUtbRoELDr6e4YXKCg=";
};
buildInputs = [
pkgs.radicale
# pkgs.libxcrypt-legacy
# pkgs.libxcrypt
];
nativeCheckInputs = [
# pkgs.libxcrypt-legacy
# pkgs.libxcrypt
];
propagatedBuildInputs = [
libdecsync
pkgs.python3Packages.setuptools
];
};
radicale-decsync = pkgs.radicale.overrideAttrs (old: {
propagatedBuildInputs = old.propagatedBuildInputs ++ [ radicale-storage-decsync ];
});
mkRadicaleService =
{ suffix, port }:
let
radicale-config = pkgs.writeText "radicale-config-${suffix}" ''
[server]
hosts = localhost:${builtins.toString port}
[auth]
type = htpasswd
htpasswd_filename = ${osConfig.sops.secrets.radicale_htpasswd.path}
htpasswd_encryption = bcrypt
[storage]
type = radicale_storage_decsync
filesystem_folder = ${config.xdg.dataHome}/radicale/radicale-${suffix}
decsync_dir = ${config.xdg.dataHome}/decsync/decsync-${suffix}
'';
in
{
systemd.user.services."radicale-${suffix}" = {
Unit.Description = "Radicale with DecSync (${suffix})";
Service = {
ExecStart = "${radicale-decsync}/bin/radicale -C ${radicale-config}";
Restart = "on-failure";
};
Install.WantedBy = [ "default.target" ];
};
};
in
builtins.foldl' (sum: cur: lib.recursiveUpdate sum (mkRadicaleService cur)) { } [
{
suffix = "personal";
port = 5232;
}
{
suffix = "family";
port = 5233;
}
]

View file

@ -1,28 +0,0 @@
_:
let
passwords = import ../../variables/passwords.crypt.nix;
in
{
services.gammastep = {
enable = true;
provider = "manual";
enableVerboseLogging = true;
inherit (passwords.location.stefan) longitude latitude;
temperature = {
# day = 6700;
day = 3000;
night = 3000;
};
tray = true;
settings = {
general = {
adjustment-method = "wayland";
};
gammastep = {
# brightness-day = 1.0;
brightness-day = 0.5;
brightness-night = 0.5;
};
};
};
}

View file

@ -1,31 +0,0 @@
{ pkgs, packages', ... }:
# useful testing command:
# for i in `seq 0 10`; do nix shell nixpkgs#libnotify --command notify-send notifiiiiiii "$i"; sleep 1; done
let
inherit (import ../lib.nix { }) mkSimpleTrayService;
in
{
home.packages = [ packages'.salut ];
xdg.configFile."salut/config.ini" = {
enable = true;
text = ''
[notifications]
timeout = 5000
[window]
auto-hide = true
anchor = bottom-right
transition = slidebottom
[mode]
single = true
[style]
preference = dark
'';
onChange = "${pkgs.systemd}/bin/systemctl --user restart salut";
};
systemd.user.services.salut = mkSimpleTrayService { execStart = "${packages'.salut}/bin/salut"; };
}

View file

@ -1,134 +1,483 @@
{ { pkgs, ... }:
config,
pkgs,
repoFlake,
lib,
...
}:
let let
pkgsVscodium = import repoFlake.inputs.nixpkgs-vscodium { inherit (pkgs) system config; }; packagedExtensions = with pkgs.vscode-extensions; [
bbenoist.Nix
ms-vscode-remote.remote-ssh
];
marketPlaceExtensions = pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "vim";
publisher = "vscodevim";
version = "1.17.1";
sha256 = "10f8jz52gr6k2553awa66m006wszj9z2rnshsic6h2aawxiz3zq1";
}
{
name = "remote-ssh-edit";
publisher = "ms-vscode-remote";
version = "0.56.0";
sha256 = "1gy03ff2xqg7q3y4j47z2l94x5gbw0mjd5h4cl3n0q3iaswk1c1r";
}
{
name = "Theme-NaturalContrast-With-HC";
publisher = "74th";
version = "1.0.0";
sha256 = "1wxwk059znkflip0c8hyqdfq0h15n4idmff4bnnfdggiqjwhr5rm";
}
{
name = "markdown-toc";
publisher = "AlanWalk";
version = "1.5.6";
sha256 = "0hh38i2dpmrm2akcd4jkxchp6b374m5jzcqm1jqqmkqjmlig7qm5";
}
{
name = "Paper-tmTheme";
publisher = "DiryoX";
version = "0.4.0";
sha256 = "0l8hgbwwg87ysfb22rvwgmkk91i4vjd0kgi30c1bn26bm2pd1gw0";
}
{
name = "Monokai-Polished";
publisher = "Mit";
version = "0.3.1";
sha256 = "11h7sfwp9ikwc8z6bkyxk1678ymfpff8i2p876b208yrq8dy2kr1";
}
{
name = "dot";
publisher = "Stephanvs";
version = "0.0.1";
sha256 = "0rq0wvnbcggg4zb4swxym77knfjma0v9lwf3x45p22qsqx2crvgf";
}
{
name = "rust-snippets";
publisher = "ZakCodes";
version = "0.0.1";
sha256 = "152i23mh8j2l26zpwid3hllxc2abkhr3g939rvxk8bry137vryy2";
}
{
name = "better-comments";
publisher = "aaron-bond";
version = "2.1.0";
sha256 = "0kmmk6bpsdrvbb7dqf0d3annpg41n9g6ljzc1dh0akjzpbchdcwp";
}
{
name = "vscode-icalendar";
publisher = "af4jm";
version = "1.0.1";
sha256 = "0g15f2595ayy9ch4f2ccd8prc51q1mwslilk8sk2ldsmdksaya79";
}
{
name = "hugofy";
publisher = "akmittal";
version = "0.1.1";
sha256 = "02rjwmy7z4qfxws8lgdki53q4b2hjklxn2nlxx3w04kahr759dlg";
}
{
name = "asciidoctor-vscode";
publisher = "asciidoctor";
version = "2.8.4";
sha256 = "0j019vwmd83mbc75kfcqzmpvqzsp3s595cgh6n9978k9q0zjrqad";
}
{
name = "markdown-preview-github-styles";
publisher = "bierner";
version = "0.1.6";
sha256 = "1plj6a1hgbhb740zbw4pbnk7919cx1s6agf5xiiqbb9485x2pqiw";
}
{
name = "made-of-code";
publisher = "brian-yu";
version = "0.0.5";
sha256 = "1cmw63vrpzxv8vkgq674xa2wqqag0a8spr623ngi87925f17p965";
}
{
name = "better-toml";
publisher = "bungcip";
version = "0.3.2";
sha256 = "08lhzhrn6p0xwi0hcyp6lj9bvpfj87vr99klzsiy8ji7621dzql3";
}
{
name = "tabulous";
publisher = "bwildeman";
version = "1.2.0";
sha256 = "0hbp345i19ncvn1v792nr257gmw0nz09nhjniiypnzvz9wszw2j9";
}
{
name = "bracket-pair-colorizer";
publisher = "CoenraadS";
version = "1.0.61";
sha256 = "0r3bfp8kvhf9zpbiil7acx7zain26grk133f0r0syxqgml12i652";
}
{
name = "mustache";
publisher = "dawhite";
version = "1.1.1";
sha256 = "1j8qn5grg8v3n3v66d8c77slwpdr130xzpv06z1wp2bmxhqsck1y";
}
{
name = "vscode-nomnoml";
publisher = "doctorrustynelson";
version = "0.3.0";
sha256 = "07nr6n5ai8m6rap8av47mqi3vv6zchymiqfw8jlbl4hsryszyr43";
}
{
name = "gitlens";
publisher = "eamodio";
version = "11.0.5";
sha256 = "1fi8j5r6cd82a50hv2lwzqnvyvhxf9waamkviyh0wyqi5i1k4q88";
}
{
name = "monokai-light";
publisher = "ethansugar";
version = "0.2.1";
sha256 = "1xn74arpv58hwdywaxvv9xhljl23wsqdpyfrgn9nvd29gsiz71w0";
}
{
name = "Theme-Monokai-Contrast";
publisher = "gerane";
version = "0.0.5";
sha256 = "1m1n1izdjgng0q3yljccwjxj0s60p5nfw3hlw7hb467a1wz479pm";
}
{
name = "Theme-snappy-light";
publisher = "gerane";
version = "0.0.5";
sha256 = "0syrm921l4lka6dmg258c2zi0a758acvcs8y0qm0kjim7h7xxf0w";
}
{
name = "vscode-pull-request-github";
publisher = "GitHub";
version = "0.21.3";
sha256 = "0p03v6y1gh62jby74vkhi897mzj8dg9xb561v0b99x81r9zhwqw0";
}
{
name = "go";
publisher = "golang";
version = "0.19.0";
sha256 = "1xr2c4xn0w68fdcbm8d2wqfb9dxf03w38367ghycrzmz2p4syr98";
}
{
name = "terraform";
publisher = "hashicorp";
version = "2.3.0";
sha256 = "0696q8nr6kb5q08295zvbqwj7lr98z18gz1chf0adgrh476zm6qq";
}
{
name = "bonsai";
publisher = "hawkeyegold";
version = "1.4.0";
sha256 = "0r7bxx1lgbg6p97xwd2wr8j7slz720a1v6vzpd0fhcq83vqzkl89";
}
{
name = "live-html-previewer";
publisher = "hdg";
version = "0.3.0";
sha256 = "0hv5plh44q97355j5la83r8hjsxpv9d173mba34xr4p82a3pcq5p";
}
{
name = "yuml";
publisher = "JaimeOlivares";
version = "3.5.1";
sha256 = "01phwj8kn2zmzpjk97wacnc8iiby0szv40b1030fkcm3szafnya0";
}
{
name = "latex-workshop";
publisher = "James-Yu";
version = "8.14.0";
sha256 = "12bh2gpmak7vgzhjnvk2hw0yqm6wkd7vsm4ki4zbqa6lpriscjyi";
}
{
name = "plantuml";
publisher = "jebbs";
version = "2.13.16";
sha256 = "0672x0a1c9yk0g4vka40f4amgxir2bs25zg6qsims9plj0x2s4si";
}
{
name = "tasks-chooser";
publisher = "jeremyfa";
version = "0.3.0";
sha256 = "0bq80wv7zf94cgn94ll3jj68z35p13r0zw5by62dnlnj1sv7dghi";
}
{
name = "asciidoctor-vscode";
publisher = "joaompinto";
version = "2.8.0";
sha256 = "06nx627fik3c3x4gsq01rj0v59ckd4byvxffwmmigy3q2ljzsp0x";
}
{
name = "contrast-theme";
publisher = "johndugan";
version = "1.1.10";
sha256 = "0hib85318940ajfbzqrpgqh4jr39w18aq6babargbf64yxg94mbw";
}
{
name = "theme-dark-plus-contrast";
publisher = "k3a";
version = "0.1.101";
sha256 = "137kq6i6xn394msjrhj7v6c8shrvw9yf8i01mf4yl4aan2bw3419";
}
{
name = "vscode-gist";
publisher = "kenhowardpdx";
version = "3.0.3";
sha256 = "033iry115hbd5jbdr04frbrcgfpfnsc2z551nlfsaczbg4j9dydw";
}
{
name = "quick-open";
publisher = "leizongmin";
version = "1.1.0";
sha256 = "03avjgkvl2w51f0lvvfksa6lxqb4i9jgz2c74hw686yaydj8mfsp";
}
{
name = "rainbow-csv";
publisher = "mechatroner";
version = "1.7.1";
sha256 = "0w5mijs4ll5qjkpyw7qpn1k40pq8spm0b3q72x150ydbcini5hxw";
}
{
name = "openapi-lint";
publisher = "mermade";
version = "1.2.0";
sha256 = "0q81ifgr211apymbs21y0l3x8n324k6mh7p8kykz2xz38cslyq49";
}
{
name = "swagger-doc-viewer";
publisher = "mimarec";
version = "1.0.4";
sha256 = "1vvqwmfav6c2r1xkyfczm564bi2cpa9nklj35w3h3hrp4f6dnvpx";
}
{
name = "vscode-clang";
publisher = "mitaki28";
version = "0.2.3";
sha256 = "0xbg2frb4dxv7zl43gi25w2mkkh4xq2aidcf5i8b4imys9h720yr";
}
{
name = "prettify-json";
publisher = "mohsen1";
version = "0.0.3";
sha256 = "1spj01dpfggfchwly3iyfm2ak618q2wqd90qx5ndvkj3a7x6rxwn";
}
{
name = "vscode-docker";
publisher = "ms-azuretools";
version = "1.8.1";
sha256 = "08691mwb3kgmk5fnjpw1g3a5i7qwalw1yrv2skm519wh62w6nmw8";
}
{
name = "python";
publisher = "ms-python";
version = "2020.11.371526539";
sha256 = "0iavy4c209k53jkqsbhsvibzjj3fjxa500rv72fywgb2vxsi9fc3";
}
{
name = "jupyter";
publisher = "ms-toolsai";
version = "2020.11.372831992";
sha256 = "0r39xqrbkzcfkz6rca039s87ibx79a983y8lbiglhkmw3bp4p658";
}
# fails to download C/C++ tools
# {
# name = "cpptools";
# publisher = "ms-vscode";
# version = "1.1.2";
# sha256 = "09z1vrshvwimdrpsnfs4lyzca2qixp3h85xib8jf2fpxdjl3r5vg";
# }
{
name = "vscode-quick-open-create";
publisher = "nocksock";
version = "0.6.0";
sha256 = "0ipkjm74xpx44h130rmbnkjwsi63kcvq6fr0b0nxqqc9aa9jk22j";
}
{
name = "indent-rainbow";
publisher = "oderwat";
version = "7.4.0";
sha256 = "1xnsdwrcx24vlbpd2igjaqlk3ck5d6jzcfmxaisrgk7sac1aa81p";
}
{
name = "phantypist";
publisher = "paulofallon";
version = "1.0.3";
sha256 = "0rsaklwsd9i25p9j82ivblkbsk5cwjm22afzc2cq5klkbz9vxg62";
}
{
name = "swaggitor";
publisher = "qnsolutions";
version = "0.1.1";
sha256 = "0dhygxawxjhm0q1nmxwwcyhnk4hm1yzadnhc5ha7amdg7gddlrc1";
}
{
name = "vscode-yaml";
publisher = "redhat";
version = "0.13.0";
sha256 = "046kdk73a5xbrwq16ff0l64271c6q6ygjvxaph58z29gyiszfkig";
}
{
name = "papercolor-vscode";
publisher = "rozbo";
version = "0.4.0";
sha256 = "0fla4dfxm6ppqgfvp9rc2izhnv0909yk3r38xmh15ald84i1jhzm";
}
{
name = "iferrblocks";
publisher = "rstuven";
version = "1.1.1";
sha256 = "0ncj1g2dqa1wwqmj27w1356f4b9nlk2narvgyjn208axfwifz1lw";
}
{
name = "rust";
publisher = "rust-lang";
version = "0.7.8";
sha256 = "039ns854v1k4jb9xqknrjkj8lf62nfcpfn0716ancmjc4f0xlzb3";
}
{
name = "bracket-jumper";
publisher = "sashaweiss";
version = "1.1.8";
sha256 = "11sj7h13yjcpd94x07wlmck7cmidk1kla00kjq7wfw2xc1143rqs";
}
{
name = "just";
publisher = "skellock";
version = "2.0.0";
sha256 = "1ph869zl757a11f8iq643f79h8gry7650a9i03mlxyxlqmspzshl";
}
{
name = "line-endings";
publisher = "steditor";
version = "1.0.3";
sha256 = "1mdybbhs771w8r9xqy1n7x2is2vhh6axkssarb2yy7gps3v81ik7";
}
{
name = "code-spell-checker";
publisher = "streetsidesoftware";
version = "1.10.0";
sha256 = "1172wcw1a1mbx8nrlnh1hyizs9abzvqmhwgc6bmp8wvxk8hk4x3i";
}
{
name = "code-spell-checker-german";
publisher = "streetsidesoftware";
version = "0.1.8";
sha256 = "117ba1m427d7nqh2p4djjswbksz1nvy2zkgdnm2iis17gzxscbmz";
}
{
name = "code-spell-checker-german";
publisher = "streetsidesoftware";
version = "0.1.8";
sha256 = "117ba1m427d7nqh2p4djjswbksz1nvy2zkgdnm2iis17gzxscbmz";
}
{
name = "code-spell-checker";
publisher = "streetsidesoftware";
version = "1.10.0";
sha256 = "1172wcw1a1mbx8nrlnh1hyizs9abzvqmhwgc6bmp8wvxk8hk4x3i";
}
{
name = "vscode-open-in-github";
publisher = "sysoev";
version = "1.14.0";
sha256 = "1whyrsckx0gikgjj1812dlsykck7cs696wz9fn4fhcishp9479hp";
}
{
name = "html-preview-vscode";
publisher = "tht13";
version = "0.2.5";
sha256 = "0k75ivigzjfq8y4xwwrgs2iy913plkwp2a68f0i4bkz9kx39wq6v";
}
{
name = "scrolloff";
publisher = "tickleforce";
version = "0.0.4";
sha256 = "1n5xcbcwdj54c9dlscd5igdbga6v9wv5j1qbhjb7p2mf7sbps3cq";
}
{
name = "shellcheck";
publisher = "timonwong";
version = "0.12.1";
sha256 = "0apvbs90mdjk5y6vy2v4azwxhdjqfypqp5d5hh9rlgxyq4m0azz2";
}
{
name = "sort-lines";
publisher = "Tyriar";
version = "1.9.0";
sha256 = "0l4wibsjnlbzbrl1wcj18vnm1q4ygvxmh347jvzziv8f1l790qjl";
}
# slow and currently not needed
# {
# name = "vscode-lldb";
# publisher = "vadimcn";
# version = "1.6.0";
# sha256 = "15m0idk75bvbzfxipdxwz2vpdklr15zv92h4mxxpr8db9jjr32vi";
# }
{
name = "vim";
publisher = "vscodevim";
version = "1.17.1";
sha256 = "10f8jz52gr6k2553awa66m006wszj9z2rnshsic6h2aawxiz3zq1";
}
{
name = "prettify-selected-json";
publisher = "vthiery";
version = "1.0.3";
sha256 = "0g2svrls7x4w75fj6rr839mrwd3sn912vn6ysiy0sasnnc55rpgb";
}
{
name = "debug";
publisher = "webfreak";
version = "0.25.0";
sha256 = "0qm2jgkj17a0ca5z21xbqzfjpi0hzxw4h8y2hm8c4kk2bnw02sh1";
}
{
name = "clang-format";
publisher = "xaver";
version = "1.9.0";
sha256 = "0bwc4lpcjq1x73kwd6kxr674v3rb0d2cjj65g3r69y7gfs8yzl5b";
}
{
name = "vscode-capnp";
publisher = "xmonader";
version = "1.0.0";
sha256 = "0z2shl6qvr3y3m5y63v69x94rzyb2cmf5046afx2yswnll6j52fc";
}
{
name = "plsql-language";
publisher = "xyz";
version = "1.8.2";
sha256 = "16xxa6w03wzd95v1cycmjvw9hfg3chvpclrn28v0qsa3lir1mxrr";
}
{
name = "markdown-pdf";
publisher = "yzane";
version = "1.4.4";
sha256 = "00cjwjwzsv3wx2qy0faqxryirr2hp60yhkrlzsk0avmvb0bm9paf";
}
{
name = "vscode-proto3";
publisher = "zxh404";
version = "0.5.2";
sha256 = "1jmmbz3i0hxq5ka4rsk07mynxh3pkh5g736d9ryv1czhnrb06lwf";
}
];
in in
{ {
programs.vscode = { programs.vscode = {
enable = true; enable = true;
package = pkgsVscodium.vscodium; extensions = []
profiles.default.extensions = ++ packagedExtensions
with pkgsVscodium.vscode-extensions; ++ marketPlaceExtensions
[ ;
eamodio.gitlens
mkhl.direnv
tomoki1207.pdf
vscodevim.vim
# bbenoist.nix
jnoortheen.nix-ide
ms-vscode.theme-tomorrowkit
nonylene.dark-molokai-theme
ms-python.vscode-pylance
# TODO: these are not in nixpkgs
# fredwangwang.vscode-hcl-format
# hashicorp.hcl
# mindaro-dev.file-downloader
# ms-vscode.remote-explorer
# TODO: not compatible with vscodium
# ms-vscode-remote.remote-ssh
]
++ (
let
extensions = repoFlake.inputs.nix-vscode-extensions.extensions.${pkgs.system};
in
with extensions.vscode-marketplace;
with extensions.vscode-marketplace-release;
[
serayuzgur.crates
rust-lang.rust-analyzer
swellaby.vscode-rust-test-adapter
tamasfe.even-better-toml
golang.go
jeff-hykin.better-go-syntax
blueglassblock.better-json5
nefrob.vscode-just-syntax
# fabianlauer.vs-code-xml-format
bierner.emojisense
]
)
++ (
let
nix4vscodeToml = pkgs.writeText "nix4vscode.toml" ''
vscode_version = "${config.programs.vscode.package.version}"
[[extensions]]
publisher_name = "FelixZeller"
extension_name = "markdown-oxide"
[[extensions]]
publisher_name = "ibecker"
extension_name = "treefmt-vscode"
[[extensions]]
publisher_name = "AntiAntiSepticeye"
extension_name = "vscode-color-picker"
# [[extensions]]
# publisher_name = "nefrob"
# extension_name = "vscode-just-syntax"
[[extensions]]
publisher_name = "fabianlauer"
extension_name = "vs-code-xml-format"
'';
nix4vscodeNix =
pkgs.runCommand "nix4vscode.nix"
{
# nix4vscode needs internet access
__noChroot = true;
requiredSystemFeatures = [ "recursive-nix" ];
buildInputs = [
pkgs.nix
pkgs.cacert
(pkgs.callPackage "${repoFlake.inputs.nix4vscode.outPath}/nix/package.nix" { })
# pkgs.strace
];
# outputHashAlgo = "sha256";
# outputHashMode = "recursive";
# outputHash = lib.fakeSha256;
}
''
# set -x
# export RUST_BACKTRACE=full
# export RUST_LOG=trace
export HOME=$(mktemp -d)
# strace -ffZyyY
nix4vscode ${nix4vscodeToml} > $out
'';
nix4vscodeExtensions = builtins.removeAttrs (pkgs.callPackage nix4vscodeNix { }) [
"override"
"overrideDerivation"
];
nix4vscodeExtensions' = lib.attrsets.mapAttrsToList (
_: v: builtins.head (builtins.attrValues v)
) nix4vscodeExtensions;
in
nix4vscodeExtensions'
);
mutableExtensionsDir = true;
}; };
home.packages = [
pkgs.nil
pkgs.nixfmt-rfc-style
];
} }
# TODO: automate # TODO: automate
# rustup install stable
# rustup component add rust-analysis --toolchain stable
# rustup component add rust-src --toolchain stable
# rustup component add rls --toolchain stable
### original list: ### original list:
# 74th.Theme-NaturalContrast-With-HC # 74th.Theme-NaturalContrast-With-HC
# AlanWalk.markdown-toc # AlanWalk.markdown-toc

View file

@ -1,5 +0,0 @@
#custom-cputemp {
padding: 0 10px;
background-color: #f0932b;
color: #ffffff;
}

View file

@ -1,86 +0,0 @@
{ pkgs, repoFlake, ... }:
{
home.packages = [
# required by any bar that has a tray plugin
pkgs.libappindicator-gtk3
pkgs.libdbusmenu-gtk3
];
programs.waybar = {
enable = true;
package =
repoFlake.inputs.nixpkgs-wayland.outputs.packages.${pkgs.stdenv.hostPlatform.system}.waybar;
style = pkgs.lib.readFile "${pkgs.waybar.src}/resources/style.css" + pkgs.lib.readFile ./waybar.css;
systemd.enable = true;
settings = {
mainBar = {
layer = "top";
position = "bottom";
height = 30;
output =
# hide the bar on HEADDLESS displays as i use them only for screensharing
(builtins.genList (i: "!HEADLESS-${builtins.toString i}") 99) ++ [ "*" ];
# output = [
# "eDP-1"
# "DP-*"
# ];
modules-left = [
"sway/workspaces"
"sway/mode"
# "wlr/taskbar"
];
"sway/workspaces" = {
disable-scroll = true;
all-outputs = false;
};
modules-center = [
"sway/window"
# "custom/hello-from-waybar"
];
modules-right = [
"tray"
"cpu"
"memory"
"custom/cputemp"
"custom/fan"
"battery"
"pulseaudio"
"clock"
"clock#date"
];
tray.spacing = 10;
cpu.format = " {usage}%";
memory.format = " {}%";
"temperature" = {
hwmon-path = "/sys/class/hwmon/hwmon3/temp1_input";
format = " {temperatureC} °C";
};
"custom/cputemp" = {
format = " {}";
exec = "${pkgs.lm_sensors}/bin/sensors | ${pkgs.gawk}/bin/awk '/CPU:/ {print $2}'";
interval = 2;
};
"custom/fan" = {
format = " {} rpm ";
exec = "${pkgs.lm_sensors}/bin/sensors | ${pkgs.gawk}/bin/awk '/fan1:/ {print $2}'";
interval = 2;
};
battery.format = "🔋 {}%";
pulseaudio = {
format = "🔉 {volume}%";
# on-click-middle = ''${pkgs.sway}/bin/swaymsg exec "${pkgs.pavucontrol}/bin/pavucontrol"'';
};
clock.format = "{:%H:%M %p}";
"clock#date".format = "{:%a, %d %b '%y}";
};
};
};
}

View file

@ -1,9 +1,7 @@
{ { pkgs }:
config,
lib, { ... }:
pkgs,
...
}:
let let
just-plugin = just-plugin =
let let
@ -25,8 +23,8 @@ let
_describe 'command' subcmds _describe 'command' subcmds
''; '';
in
pkgs.stdenv.mkDerivation { in pkgs.stdenv.mkDerivation {
name = "just-completions"; name = "just-completions";
version = "0.1.0"; version = "0.1.0";
phases = "installPhase"; phases = "installPhase";
@ -36,77 +34,60 @@ let
cp ${plugin_file} $PLUGIN_PATH/_just cp ${plugin_file} $PLUGIN_PATH/_just
chmod --recursive a-w $out chmod --recursive a-w $out
''; '';
}; };
in
{ in {
programs.zsh = { programs.zsh = {
enable = true; enable = true;
profileExtra = ''
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
'';
# will be called again by oh-my-zsh # will be called again by oh-my-zsh
enableCompletion = false; enableCompletion = false;
autosuggestion.enable = true; enableAutosuggestions = true;
initContent = initExtra = ''
let PROMPT='%F{%(!.red.green)}%n%f@%m %(?.%F{green}%f.%F{red} ($?%))%f %F{blue}%~%f %F{magenta}$(git_prompt_info)%f$prompt_newline%_%F{%(!.red.green)}$(prompt_char)%f '
inNixShell = ''$([[ -n "$IN_NIX_SHELL" ]] && printf " 🐚")''; RPROMPT=""
in
''
if test ! -n "$TMPDIR" -a -z "$TMPDIR"; then
unset TMPDIR
fi
if test ! -n "$TMP" -a -z "$TMP"; then # Automatic rehash
unset TMP zstyle ':completion:*' rehash true
fi
if [ -f $HOME/.shrc.d/sh_aliases ]; then
. $HOME/.shrc.d/sh_aliases
fi
PROMPT='%F{%(!.red.green)}%n%f@%m %(?.%F{green}%f.%F{red} ($?%))%f %F{blue}%~%f${inNixShell}%F{magenta}$(git_prompt_info)%f$prompt_newline%_%F{%(!.red.green)}$(prompt_char)%f ' ${if builtins.hasAttr "homeshick" pkgs then ''
RPROMPT="" source ${pkgs.homeshick}/homeshick.sh
fpath=(${pkgs.homeshick}/completions $fpath)
'' else ''
''}
# Automatic rehash # Disable intercepting of ctrl-s and ctrl-q as flow control.
zstyle ':completion:*' rehash true stty stop ''' -ixoff -ixon
if [ -f $HOME/.shrc.d/sh_aliases ]; then # don't cd into directories when executed
. $HOME/.shrc.d/sh_aliases unsetopt AUTO_CD
fi
${ export NIX_PATH="${pkgs.nixPath}"
if builtins.hasAttr "homeshick" pkgs then
''
source ${pkgs.homeshick}/homeshick.sh
fpath=(${pkgs.homeshick}/completions $fpath)
''
else
""
}
# Disable intercepting of ctrl-s and ctrl-q as flow control. # print lines without termination
stty stop ''' -ixoff -ixon setopt PROMPT_CR
setopt PROMPT_SP
export PROMPT_EOL_MARK=""
'';
# don't cd into directories when executed sessionVariables = {
unsetopt AUTO_CD # Add more envrionment variables here
};
# print lines without termination
setopt PROMPT_CR
setopt PROMPT_SP
export PROMPT_EOL_MARK=""
${lib.optionalString config.services.gpg-agent.enable ''
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gnupg/S.gpg-agent.ssh"
''}
${lib.optionalString config.programs.neovim.enable ''
export EDITOR="nvim"
''}
'';
plugins = [ plugins = [
{ {
# will source zsh-autosuggestions.plugin.zsh
name = "zsh-autosuggestions"; name = "zsh-autosuggestions";
src = pkgs.zsh-autosuggestions; src = pkgs.fetchFromGitHub {
owner = "zsh-users";
repo = "zsh-autosuggestions";
rev = "v0.6.3";
sha256 = "1h8h2mz9wpjpymgl2p7pc146c1jgb3dggpvzwm9ln3in336wl95c";
};
} }
{ {
name = "enhancd"; name = "enhancd";
@ -114,8 +95,8 @@ in
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "b4b4r07"; owner = "b4b4r07";
repo = "enhancd"; repo = "enhancd";
rev = "v2.5.1"; rev = "v2.2.4";
sha256 = "sha256-kaintLXSfLH7zdLtcoZfVNobCJCap0S/Ldq85wd3krI="; sha256 = "1smskx9vkx78yhwspjq2c5r5swh9fc5xxa40ib4753f00wk4dwpp";
}; };
} }
{ {

View file

@ -1,8 +0,0 @@
{ lib, ... }:
{
options.flake.colmena = lib.mkOption {
# type = lib.types.attrsOf lib.types.unspecified;
type = lib.types.raw;
default = { };
};
}

View file

@ -1,37 +0,0 @@
{ pkgs, ... }:
{
packages = {
myPython = pkgs.python310.withPackages (
ps:
with ps;
[
pep8
yapf
flake8
# autopep8 (broken)
# pylint (broken)
ipython
llfuse
dugong
defusedxml
wheel
pip
virtualenv
cffi
# pyopenssl
urllib3
# mistune (insecure)
sympy
flask
pyaml
requests
]
++ [
pkgs.pypi2nix
pkgs.libffi
]
);
};
}

View file

@ -0,0 +1,65 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ n, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
# Define on which hard drive you want to install Grub.
boot.loader.grub.device = "/dev/sdb";
networking.hostName = "nano${toString n}"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Select internationalisation properties.
# i18n = {
# consoleFont = "Lat2-Terminus16";
# consoleKeyMap = "us";
# defaultLocale = "en_US.UTF-8";
# };
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# List packages installed in system profile. To search by name, run:
# $ nix-env -qaP | grep wget
# environment.systemPackages = with pkgs; [
# wget
# ];
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
services.openssh.permitRootLogin = "yes";
# Enable CUPS to print documents.
services.printing.enable = false;
# Enable the X11 windowing system.
services.xserver.enable = false;
# services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
# Enable the KDE Desktop Environment.
# services.xserver.displayManager.kdm.enable = true;
# services.xserver.desktopManager.kde4.enable = true;
# Define a user account. Don't forget to set a password with passwd.
# users.extraUsers.guest = {
# isNormalUser = true;
# uid = 1000;
# };
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "16.03";
}

View 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/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/e02a410e-5044-440f-90e9-b573e51f1315";
fsType = "ext4";
};
swapDevices = [ ];
nix.maxJobs = 2;
}

26
nix/ops/nanos@kn.nix Normal file
View file

@ -0,0 +1,26 @@
{ nixpkgs ? import <nixpkgs> {}
, nrNanos ? 1 # Number of nanos
}:
let
pkgs = nixpkgs;
webserver = { services.httpd.enable = true;
services.httpd.adminAddr = "mail@stefanjunker.de";
services.httpd.documentRoot = "${pkgs.nixops}/share/doc/nixops/";
networking.firewall.allowedTCPPorts = [ 80 ];
};
mkNano = { n }: {
imports = [
(import ./nano/configuration.nix {inherit pkgs n;})
../configuration/common/user/root.nix
];
deployment.targetEnv = "none";
deployment.targetHost = "nano${toString n}";
};
mkNanos = n: nixpkgs.lib.nameValuePair "nano${toString n}" (
mkNano { inherit n; }
);
in nixpkgs.lib.listToAttrs (map mkNanos (nixpkgs.lib.range 0 (nrNanos - 1)))

View file

@ -1,12 +0,0 @@
# WARN: this file will get overwritten by $ cachix use <name>
{ lib, ... }:
let
folder = ./cachix;
toImport = name: _value: folder + ("/" + name);
filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key;
imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder));
in
{
inherit imports;
nix.settings.substituters = [ "https://cache.nixos.org/" ];
}

View file

@ -1,8 +0,0 @@
{
nix = {
settings.substituters = [ "https://nixpkgs-wayland.cachix.org" ];
settings.trusted-public-keys = [
"nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
];
};
}

View file

@ -1,125 +1,185 @@
{ { config
config, , hostAddress
hostAddress, , localAddress
localAddress,
subvolumes,
targetPathSuffix ? "",
autoStart ? false,
}: }:
let let
unstablepkgs = import <channels-nixos-unstable> { config = config.nixpkgs.config; };
passwords = import ../../variables/passwords.crypt.nix; passwords = import ../../variables/passwords.crypt.nix;
subvolumeParentDir = "/var/lib/container-volumes"; bucket = "bkp";
in subvolumeParentDir = "/var/lib";
{
config =
{ pkgs, ... }:
{
system.stateVersion = "20.03"; # Did you read the comment?
imports = [ ../profiles/containers/configuration.nix ]; subvolumeDir = "/var/lib/container-volumes";
subvolumeSnapshot = "/var/lib/container-volumes.snapshot";
environment.systemPackages = with pkgs; [ bkpSource = subvolumeSnapshot;
btrfs-progs bkpDestination = "/container/backup";
btrbk cacheDir = "/var/lib/rclone-cachedir";
];
networking.firewall.enable = true; wasabiRc = pkgs: pkgs.writeText "rc" ''
[wasabi-${bucket}]
type = s3
provider = Wasabi
env_auth = false
systemd.services."bkp-sync" = { #bkp user
enable = true; access_key_id = ${passwords.storage.wasabi.bkp.key}
description = "bkp-sync service"; secret_access_key = ${passwords.storage.wasabi.bkp.secret}
serviceConfig = { region = us-east-1
Type = "oneshot"; endpoint = s3.wasabisys.com
}; location_constraint =
acl =
server_side_encryption =
storage_class =
'';
after = [ "bkp-run.service" ];
requires = [ "bkp-run.service" ]; bkp-mount-rclone-manual = pkgs: {
enable = true;
path = with pkgs; [ utillinux ]; description = "bkp-mount-rclone-manual service";
script = '' path = with pkgs; [ unstablepkgs.rclone utillinux ];
set -x serviceConfig = {
true Type = "notify";
'';
}; };
script = ''
export PATH="$PATH:/run/wrappers/bin"
exec rclone --config ${wasabiRc pkgs} mount wasabi-${bucket}:${bucket} ${bkpDestination} \
--stats=50m --stats-log-level=NOTICE \
--cache-dir=${cacheDir} \
--vfs-cache-mode=full
systemd.services."bkp-run" = { '';
enable = true; preStart = ''
description = "bkp-run"; mkdir -p ${bkpDestination}
mkdir -p ${cacheDir}
'';
postStop = ''
sync
umount ${bkpDestination} \
|| umount -l ${bkpDestination} \
|| :
serviceConfig = { rmdir ${bkpDestination}
Type = "oneshot"; '';
};
partOf = [ "bkp-sync.service" ];
path = with pkgs; [
btrfs-progs
btrbk
coreutils
];
script =
let
btrbkConf = pkgs.writeText "cfg" ''
timestamp_format long
ssh_identity ${passwords.storage.backupTarget.keyPath}
ssh_user ${passwords.storage.backupTarget.user}
ssh_compression no
backend_remote btrfs-progs-sudo
compat_remote busybox
btrfs_commit_delete each
snapshot_create onchange
snapshot_preserve_min latest
snapshot_preserve 7d 4w
target_preserve_min latest
target_preserve 7d 4w 12m *y
volume ${subvolumeParentDir}
target ${passwords.storage.backupTarget.target}/container-volumes/${targetPathSuffix}
${builtins.foldl' (sum: elem: sum + " subvolume " + elem + "\n") "" subvolumes}
'';
in
''
#! ${pkgs.bash}/bin/bash
set -Eeuxo pipefail
btrbk -c ${btrbkConf} --progress ''${@:-run}
'';
};
systemd.timers."bkp" = {
description = "Timer to trigger bkp periodically";
enable = true;
wantedBy = [
"timer.target"
"multi-user.target"
];
timerConfig = {
# Obtained using `systemd-analyze calendar "Wed 23:00"`
# OnCalendar = "Wed *-*-* 23:00:00";
OnStartupSec = "1m";
Unit = "bkp-sync.service";
OnUnitInactiveSec = "2h";
Persistent = "true";
};
};
}; };
inherit autoStart;
in {
config = { pkgs, ... }: {
imports = [
../profiles/containers/configuration.nix
];
environment.systemPackages = with pkgs; [
btrfs-progs
rdup rdedup
iptraf-ng nethogs
rclone
];
networking.firewall.enable = true;
systemd.services."bkp-mount-rclone-manual" = bkp-mount-rclone-manual pkgs;
systemd.services."bkp-sync-rclone" = {
enable = true;
description = "bkp-sync-rclone service";
serviceConfig = {
Type = "oneshot";
};
after = [
"bkp-run.service"
];
requires = [
"bkp-run.service"
];
path = with pkgs; [ unstablepkgs.rclone utillinux ];
script = ''
set -x
echo Starting rclone sync...
rclone --config ${wasabiRc pkgs} sync \
${bkpDestination}/rdedup/ wasabi-${bucket}:${bucket}/rdedup/ \
--stats=50m --stats-log-level=WARNING
echo Finished rclone sync...
'';
};
systemd.services."bkp-run" = {
enable = true;
description = "bkp-run";
serviceConfig = {
Type = "oneshot";
};
partOf = [
"bkp-sync-rclone.service"
];
path = with pkgs; [ btrfs-progs rdup rdedup coreutils ];
preStart = ''
echo Creating new btrfs snapshot of ${subvolumeDir} at ${subvolumeSnapshot}
btrfs subvolume snapshot -r ${subvolumeDir} ${subvolumeSnapshot}
'';
script = ''
#! ${pkgs.bash}/bin/bash
set -Eeuxo pipefail
export RUST_BACKTRACE=1
export TIMESTAMP=$(date +"%Y%m%d.%H%M%S")
echo Starting rdup/rdedup backup...
for d in `ls -1 ${bkpSource}`; do
echo Determining backup source size ${bkpSource}/$d...
du -hs ${bkpSource}/$d
rdup -x /dev/null ${bkpSource}/$d | rdedup -v -ttt --dir=${bkpDestination}/rdedup store $d-''${TIMESTAMP}
done
sync
echo Finished rdup/rdedup backup...
echo Removing all previous backups...
rdedup --dir=${bkpDestination}/rdedup list | grep -v ''${TIMESTAMP} | xargs echo rdedup --dir=${bkpDestination}/rdedup remove
echo Running rdedup garbage-collector...
time rdedup -v -ttt --dir=${bkpDestination}/rdedup gc
echo Determining backup destination size ${bkpDestination}/rdedup...
du -hs ${bkpDestination}/rdedup
'';
postStop = ''
btrfs subvolume delete ${subvolumeSnapshot}
'';
};
systemd.timers."bkp" = {
description = "Timer to trigger bkp periodically";
enable = true;
wantedBy = [ "timer.target" "multi-user.target" ];
timerConfig = {
# Obtained using `systemd-analyze calendar "Wed 23:00"`
# OnCalendar = "Wed *-*-* 23:00:00";
OnStartupSec="2d";
Unit = "bkp-sync-rclone.service";
OnUnitInactiveSec="2d";
Persistent="true";
};
};
};
autoStart = true;
bindMounts = { bindMounts = {
"${subvolumeParentDir}" = { "${subvolumeParentDir}" = {
hostPath = subvolumeParentDir; hostPath = "/var/lib/";
isReadOnly = false; isReadOnly = false;
}; };
"/etc/secrets/" = {
hostPath = "/var/lib/container-volumes/backup/etc-secrets";
isReadOnly = true;
};
"/dev/fuse" = { "/dev/fuse" = {
hostPath = "/dev/fuse"; hostPath = "/dev/fuse";
isReadOnly = false; isReadOnly = false;
@ -127,16 +187,12 @@ in
}; };
allowedDevices = [ allowedDevices = [
{ { node = "/dev/fuse"; modifier = "rw"; }
node = "/dev/fuse";
modifier = "rw";
}
]; ];
extraFlags = [ "--resolv-conf=bind-host" ];
privateNetwork = true; privateNetwork = true;
forwardPorts = [ ]; forwardPorts = [
];
inherit hostAddress localAddress; inherit hostAddress localAddress;
} }

View file

@ -1,228 +1,149 @@
{ { hostAddress
specialArgs, , localAddress
hostBridge, , imapsPort ? 993
hostAddress, , sievePort ? 4190
localAddress,
imapsPort ? 993,
sievePort ? 4190,
autoStart ? false,
}: }:
{
inherit specialArgs;
config =
{
pkgs,
config,
repoFlake,
...
}:
{
system.stateVersion = "22.05"; # Did you read the comment?
imports = [ let
../profiles/containers/configuration.nix passwords = import ../../variables/passwords.crypt.nix;
repoFlake.inputs.sops-nix.nixosModules.sops in {
../profiles/common/user.nix
];
networking.firewall.allowedTCPPorts = [ config = { pkgs, ... }: {
imapsPort imports = [
sievePort ../profiles/containers/configuration.nix
]; ../profiles/common/user.nix
];
# FIXME: find out how to use the `defaultSopsFile` so i don't have to specify each secret separately networking.firewall.enable = false;
# sops.defaultSopsFile = ./mailserver_secrets.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; services.ddclientovh = {
sops.secrets.email_mailStefanjunkerDe = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.steveej.name;
};
sops.secrets.email_mailStefanjunkerDeHetzner = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.steveej.name;
};
sops.secrets.email_schtifATwebDe = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.steveej.name;
};
sops.secrets.email_dovecot_steveej = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.dovecot2.name;
};
# TODO: switch to something other than ddclient as it's no longer maintained
# TODO: switch to a let's encrypt certificate
sops.secrets.dovecotSslServerCert = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.dovecot2.name;
};
sops.secrets.dovecotSslServerKey = {
sopsFile = ./mailserver_secrets.yaml;
owner = config.users.users.dovecot2.name;
};
services.dovecot2 = {
enable = true; enable = true;
domain = "mailserver.svc.stefanjunker.de";
};
protocols = [ "sieve" ]; services.dovecot2 = {
enable = true;
enableImap = true; modules = [ pkgs.dovecot_pigeonhole ];
enableLmtp = true; protocols = [ "sieve" ];
enablePAM = true;
showPAMFailure = true;
mailLocation = "maildir:~/.maildir";
sslServerCert = config.sops.secrets.dovecotSslServerCert.path;
sslServerKey = config.sops.secrets.dovecotSslServerKey.path;
#configFile = "/etc/dovecot/dovecot2_manual.conf"; enableImap = true;
extraConfig = '' enableLmtp = true;
auth_mechanisms = cram-md5 digest-md5 enablePAM = true;
auth_verbose = yes showPAMFailure = true;
mailLocation = "maildir:~/.maildir";
sslServerCert = "/etc/secrets/server.pem";
sslServerKey = "/etc/secrets/server.key";
passdb { #configFile = "/etc/dovecot/dovecot2_manual.conf";
driver = passwd-file extraConfig = ''
args = scheme=CRYPT username_format=%u /etc/dovecot/users auth_mechanisms = cram-md5 digest-md5
} auth_verbose = yes
passdb {
driver = passwd-file
args = scheme=CRYPT username_format=%u /etc/dovecot/users
}
protocol lda { protocol lda {
postmaster_address = "mail@stefanjunker.de" postmaster_address = "mail@stefanjunker.de"
mail_plugins = $mail_plugins sieve mail_plugins = $mail_plugins sieve
} }
protocol imap { protocol imap {
mail_max_userip_connections = 64 mail_max_userip_connections = 64
} }
''; '';
};
environment.systemPackages = [ };
pkgs.dovecot_pigeonhole
];
environment.etc."dovecot/users".source = config.sops.secrets.email_dovecot_steveej.path; environment.etc."dovecot/users".text = ''
steveej:${passwords.email.steveej}
'';
systemd.services.steveej-getmail-stefanjunker = { systemd.services.steveej-getmail-stefanjunker = {
enable = true; enable = true;
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig.User = "steveej"; serviceConfig.User = "steveej";
serviceConfig.Group = "dovecot2"; serviceConfig.Group = "dovecot2";
serviceConfig.RestartSec = 600; serviceConfig.RestartSec = 600;
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
description = "Getmail service"; description = "Getmail service";
path = [ pkgs.getmail6 ]; path = [ ];
script = script = let
let rc = pkgs.writeText "mailATstefanjunker.de.getmail.rc" ''
rc = pkgs.writeText "mailATstefanjunker.de.getmail.rc" '' [options]
[options] verbose = 1
verbose = 1 read_all = 0
read_all = 0 delete_after = 30
delete_after = 30
[retriever] [retriever]
type = SimpleIMAPSSLRetriever type = SimpleIMAPSSLRetriever
server = ssl0.ovh.net server = ssl0.ovh.net
port = 993 port = 993
username = mail@stefanjunker.de username = mail@stefanjunker.de
password_command = ("${pkgs.coreutils}/bin/cat", "${config.sops.secrets.email_mailStefanjunkerDe.path}") password = ${passwords.email.mailStefanjunkerDe}
mailboxes = ('INBOX',) mailboxes = ('INBOX',)
[destination] [destination]
type = MDA_external type = MDA_external
path = ${pkgs.dovecot}/libexec/dovecot/dovecot-lda path = ${pkgs.dovecot}/libexec/dovecot/dovecot-lda
'';
in
''
getmail --idle=INBOX --rcfile=${rc}
''; '';
}; in ''
${pkgs.getmail}/bin/getmail --rcfile=${rc} --idle=INBOX
'';
};
systemd.services.steveej-getmail-stefanjunker-hetzner = { systemd.services.steveej-getmail-webde = {
enable = true; enable = true;
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig.User = "steveej"; serviceConfig.User = "steveej";
serviceConfig.Group = "dovecot2"; serviceConfig.Group = "dovecot2";
serviceConfig.RestartSec = 60; description = "Getmail service";
serviceConfig.Restart = "always"; path = [ pkgs.getmail ];
description = "Getmail service"; serviceConfig.RestartSec = 1000;
path = [ pkgs.getmail6 ]; serviceConfig.Restart = "always";
script = script = let
let rc = pkgs.writeText "schtifATweb.de.getmail.rc" ''
rc = pkgs.writeText "mailATstefanjunker.de.getmail.rc" '' [options]
[options] verbose = 1
verbose = 2 read_all = 0
read_all = 0 delete_after = 30
delete_after = 30
[retriever] [retriever]
type = SimpleIMAPSSLRetriever type = SimpleIMAPSSLRetriever
server = mail.your-server.de server = imap.web.de
port = 993 port = 993
username = mail@stefanjunker.de username = schtif
password_command = ("${pkgs.coreutils}/bin/cat", "${config.sops.secrets.email_mailStefanjunkerDeHetzner.path}") password = ${passwords.email.schtifATwebDe}
mailboxes = ('INBOX',) mailboxes = ('INBOX',)
[destination] [destination]
type = MDA_external type = Maildir
path = ${pkgs.dovecot}/libexec/dovecot/dovecot-lda path = ~/.maildir/
'';
in
''
getmail --rcfile=${rc} --idle=INBOX
'';
};
systemd.services.steveej-getmail-webde = {
enable = true;
wantedBy = [ "multi-user.target" ];
serviceConfig.User = "steveej";
serviceConfig.Group = "dovecot2";
description = "Getmail service";
path = [ pkgs.getmail6 ];
serviceConfig.RestartSec = 1000;
serviceConfig.Restart = "always";
script =
let
rc = pkgs.writeText "schtifATweb.de.getmail.rc" ''
[options]
verbose = 1
read_all = 0
delete_after = 30
[retriever]
type = SimpleIMAPSSLRetriever
server = imap.web.de
port = 993
username = schtif
password_command = ("${pkgs.coreutils}/bin/cat", "${config.sops.secrets.email_schtifATwebDe.path}")
mailboxes = ('INBOX',)
[destination]
type = Maildir
path = ~/.maildir/
'';
in
''
getmail --rcfile=${rc} --idle=INBOX
''; '';
in ''
getmail --rcfile=${rc}
'';
}; };
}; };
inherit autoStart; autoStart = true;
bindMounts = { bindMounts = {
# FIXME/REMINDER: this is used so that the container can decrypt the secrets that are deployed to the host "/etc/secrets/" = {
"/etc/ssh/ssh_host_ed25519_key".isReadOnly = true; hostPath = "/var/lib/container-volumes/mailserver/etc-secrets";
"/etc/ssh/ssh_host_ed25519_key.pub".isReadOnly = true; isReadOnly = false;
};
"/home" = { "/home" = {
hostPath = "/var/lib/container-volumes/mailserver/home"; hostPath = "/var/lib/container-volumes/mailserver/home";
isReadOnly = false; isReadOnly = false;
}; };
}; };
privateNetwork = true; privateNetwork = true ;
forwardPorts = [ forwardPorts = [
{ {
# imaps # imaps
@ -239,5 +160,5 @@
} }
]; ];
inherit hostBridge hostAddress localAddress; inherit hostAddress localAddress;
} }

View file

@ -1,53 +0,0 @@
email_mailStefanjunkerDe: ENC[AES256_GCM,data:sSBunuv4wipvl720vBrObPVlwMqf8MCWPA==,iv:57SPbRgdO1OtCunFbRJ9rLadWfrCF072lv27ond6qQ0=,tag:DpTeij/rGCK2NQMre5xBsw==,type:str]
email_mailStefanjunkerDeHetzner: ENC[AES256_GCM,data:HvPU/tV2uwutE8q6BzMjkw==,iv:sxERmGojxJhTre2XhslD/B3hesJaP8Cn6TJ7G2WygQw=,tag:JeRI3a2oc/cMJWqyiICgYw==,type:str]
email_schtifATwebDe: ENC[AES256_GCM,data:OOmxkHcM25A+rSmPE1lmvUylv0TT2qWWeA==,iv:ysnRyv4WwbnovgEZcwmk1Rdo6U7gBWDFvGIxgF/m/5A=,tag:9b7q+mceiDx5y8qVVHjBhw==,type:str]
email_dovecot_steveej: ENC[AES256_GCM,data:nZJX2ZIe2pJTzBIU/XRZaiiy9NmUtJydaOvSAQT3icCEeLTvgah48mgrz14eGPuOEupVqKII5jpHw3Xid+QWzdIels0B9M4+GgVT85yVAaPQKw==,iv:vb2bKtgeJI4fvRfKoR8AoBpv9WOkAAKQ3DzMInGF4SA=,tag:p6q0rfyG0g1hF8PR476TZQ==,type:str]
email_postmasterStefanjunkerDe: ENC[AES256_GCM,data:mUe2SbT1aj6yCav0X0lZ04rxYjJjQfKOqw==,iv:ZtOca09m2ne36cmLem/dNnmrsTV6fWaluuoPS85HdGc=,tag:2Z8RwuKJteXUKyuzpFzyfg==,type:str]
dovecotSslServerCert: ENC[AES256_GCM,data:ylK0IIj2vdY0mXOqSgA5zYmFYGote/uMtDWy2rwHhuSoirnADu+k6pYrH4UUTB9BQsDpCzuU4vb4Rz2pQuB0PJ9iZ3XI2fTxft+UxZI4wwAkvHXeJWxLnEvySQW3mnk2uJBaeAxhkXZ55SrKA0h1u/luiXlCoLD197yqJsaR7ldlTImfiIwZPoSRJvo33/UsEIfxlmNMrJk6kgWp9Ay1pT+K3ymWTzBaxzMypUM+Wb4BulgR62qCBxoVjXPP4tVsBwRN6LREeKpP6zIZSjNNU5SWkf2GVDuRl6AMfh8UUq5aRQqNrorRm0p9FR5CXvJZH6gOxh1jSaXGFRbyfEwlaBrzU3NYqXA4tVTh6jKeRy6tmkw3KHhV3kOeJhJ5YQy4IM4Tv03zp5M/rCCIDoZLZsmNKYpLHYKfKORBYt/XlOfnXFVW/dp+q7lMiy2vPPNaVzH6aFrlzIEUyQBfawbHPBnIN09rmW9cIzZC5n3owzq8jj8aWDILqgun7RFOnBWBaG2JE9imXoS66cKAvzGf1wpjN2pELQOpSI1dVuENxMC+K8dTu/2RN2Xe0t6x6FlHK7PHB+JNGsGOHjrga+Z2rWTqcOtY30XZpBSqoZ4XxhcFtp+gxwBuW6zjzS4hEBz1/BJTYLD0dolTp3Vzo93bsezAr+iUfNrfzESTfg8fRH89tdPCeSPv4lfi+Bo4un41x6+x14Kf66Sz5AR7dBQzypNC3ChGCKtp29ZBBee+5oQWvrYBVybbOdD+uaS6pRC/Uydubx+cDGyU1vn50Iq4XTkmiy0m8joHa7gwgOggSeDoZK8lSnwCEwssWZaxzWfO8/8gxEDJD74ki+0GzkGCSIW7EIDiEEBSuL971bqgmKOgKmzqeHYxMpO3DbrFSQVIBUzlcPMoL9GuMHnF9UWT8u3Oo4eIh8rgwJQ4tbIdIbOop1LKLSKjtt/ny4+fGjrF1gzYWHu6RDMHkl9h/AplsHH6r8x3L3rM40O8mOG/SVgqA2GTN+0pviLAPzvQ+Xb0xRQH3vfXXMkufpQtb2o0xlh4pgJw+6a4QrjSq6ZJ3saA8TeC3F6BzIEr6nAwljBMSY4v8wBQivquENBCbqo4St5h+eleKpqbpyLJQYgCyvrUST8kNa014eZjNMLnJ1XBmPO9vpUk/2FJkSpaPAPQ7thqhRBEhe+GsnkScqqrq7gLpNIX4o/HR2b70T/8/4G7uZ3KPScW25TX9D9cI7LFON3Sfprn5LK6hm2nxTmjhaD0rWNnDCkfqDfzRJeQV9kW5Hfn0rBOIsmUoQEcgeCqNKenr/lalRRiifsHDdTUwzSJLgHm09RJI4CVZ+ovPHENRW02VPP9YBupemrZazN3ttj3pin8QRRcOM0w7jeGjfSyih0E4JfiC8NzLWhBpFtBSSxi79QD2vkz17ububf37p5XMg0KfClubQgnNKxlbQ/Me7xxp1X0JlmyxpwIhaaLoz9f+268/9n4RKBGDjAY9D0jZ2zcNm+MpkoG1IIWzPBtBiGTfs+HZPH3GKiEcnkEVcUbDZis9zERamYKDMMPqfAm3KsQLXxUVyuy3cuikGxg7ab+41b1s4MtyoeoUIeRruc60Gg+rSv+d0Jl/YP9Lb5/WBGwNKzm/1R70hJnbTWRt/kKZRKsVY2rcb+FH6vXBjFAHgiszFns5oXS0Q3jhVHH4i3IUn+M6HsbqDIaJ4t4Jvtcx+ESNC2NHKCSxKe4UePng8xJ+91jB04DxdJFlTrZ7RBgjmmiMR8DPF6XiYi+awZtUaTKjZev8SPl4vSobu5aqnct0F5O6aPGB/T8nHlXevdkuQ//7BXc0RwN1ZBZzGqzc8+NzIBa9aB96XnlXPDek1C5Cc9/yVWelM9dWwTzUECBWanTRFt1uz7hpoeemGI0X7IV4DXe26yZot2PlRLFBGL/5lnoSZcjfjym1yyjd5guLdRSHOihPoDDV0JR88BDzDSS/Fx4tRCxKCuaQos+QiMlZ+yJnY9v/K88NtX9X+cRr1ZFS9Li1+uBhbJamWgtWpSJireAGZkLFSEu5GpmfcofuzDsuSYsG6wDLMpJGgRvGJeDuZ4pJTMz1dhjjWUw3blpoJW99zHVDwuSMUNEOFnFgu9BNsoq2caoDcNcm7yA0dsNl1sS3ECsBAg18KsMHA5bL6gXhAkCGOzUVBzW0NRUm8SvHloB73LvfBiFHkpqkqS8KsQZkGts+vBcVAjfDYHYy+TvcaiO0I7xEOUZMdkjuZFOkh2Q0x7pQzCarYs=,iv:6zMCqVVdsbJmEr9YDQ5FqYhRcV36aM585YZz/Dd+b3c=,tag:LCDn6L/VJvW8St1CHXcObw==,type:str]
dovecotSslServerKey: ENC[AES256_GCM,data:KYpQZbioLGrp/6R6j/c4uJhBpoDT2aj7UffQQug8Otzr/0rk51tavsjg4YRQGIv+ZpFYpWAuHbhW4O8AsRgpi0AX3hKsZICEdNubfK5zfd+SInXveaVFbHHjOuzcqftraUrqx9APu+omk4LlpxpWTbj/bAcRnRBn0C093AeJNi1giaCZd4NxmmkYqwYzrjUc6LYHvICEnjA87ZVpeOKE/6B2Ng5QWDKhZNmjy7YDXAk4DS+P2grLmoGvnz6ubtaypSzaKXYTFz/uxEvtCCPlIaJHm3Nz0i0j1rjX3S/w3c26zuIFtwCmAQzGnHyQwbx7ILwCXfnyQnpM7+R5+fxcYvcK2GEJyTGzg/JFa++TI1YO+wpknjzxK3Sa8aX0pUbx/TEjnY3+tRnx7YNuih2ZNZrPHy8uJJtO9Aef84Sq5vLQG5n1/ya0pVhjCbs1pgpeK/qT3ikLbkcJg6NxAq3hqqQdR4TTkZBwKLVfzcMXLDZB0GphhVvtO0W7afRCE+nA/FPDT2NN6WLD15cN5F8w6USi0iQlwFb+TE8nt1ghhoGmwCMx+lX1Bk/jdIlYtJ62T8+T3nRVJ6ZRlUa1rkbAADaWZVvLR2/ylaEkeYFo/CC6lUg4DWPCVoGFxaWaU+ZaIDjbiYcqGQFBwq8JZ44hAOyJQpb7N1zgDVyPh/xr+ukmjutFuu97FY55VTn+8eipRiR4TZpPRH+KvB/FmlLNaim76YZCRH9Dv2ENbz9fXpWv7P+yh06+ci9HKvjNAzR6NRr368tK2srEEhWzFv+nAsRetzc2VcfwNMcg5/mvlWHVZSmONXC5adEo/W5XgJgUnH/fkz5IRPY/1iteq8PTCPUkubzF+qT2+suzEDnvgXlaKsqHkrk+n8YySl+GRABnasmnBYdb8vboDM41ptw3PXDoL+l07o6KxTwPOWWl9BVNMT8VzL7gAl+dlxjkEUSqn53OrsYDluxefBa3c0rfvk8CCvOMjgLkagK9O+VavqJEo00zd3f0ZzMcIoRebuDzYILw3DTrG/qyLXGsRoybBr+qcuSVBzM5RnjcToFJO4W/0EIdH1drZmqHdNgSNwPPRSNCivrhV25syUCrTee/xkDVUr47z67pK/5Mh0ewlwq0hcl/dBoA0YP/PptntK0CHfistD8chNtdMk3PyzqSiFaDPQ3T4wdc3zTNUjXeQ5643k5weJXFPg4tUuCCa8HxUJHd5sLnNY0OaRBwh2SLkQlcXYFQDzVHSoVscR3tf+57L7aF2hVQT2QtJKdZQjOyMg5YK0UlVc3tkyPZzyjOVaP7eTCRKwXI1NminHmmy1ZzZ+w+8+oX8cfvE9HdbqDoDp0MnkicS0+5S0lZwkRWrjUx/gS4aMWLbCHUQHY8wm+fmyDLJ/oI4ukdUI5YLOutlCsIY+aotnVMoORgdd/EPeZVYJmci/pvMjPF9Eard0aD4rLA7z/HwGgc3VEGmNluE+20BXO3bFIqwa9tzMqzOJB0qglP35MjVGiUe6Svq13DAmSOnzN+WqcVbTMJG8J1bwKqvmaN8AEpO0zU94ZhHspUtGyQQ0D6sMsw9jqJ1WyLE7aXeFR6OHrpw3DC2mCpr/qX8QFsveeyB83Za2+CuVVi2sqGAKYzkwlUPkeuaxfBak0apwJsF2trT1uMvPOuIda8k4XhtYLxah2BDJZIoMqUVz2xcN4OuW8bdSX/lepsyZZO34VEQDLBa2dxCCHJmCKf6io/0YlswNKGDQh+DI935KTdqBnHSJ9IjvADQuu+K37aS0L9V0ZLXiM5SBQtbB7kQpHjvivq97ru7QpFqJf8HCl1vDs4gJ/NV+J0+CX6dQTQOtHvwxD2CPGiiSv40ycoJAcwiqTh5T+hRPtca6bSes/jGN5iQjfLCRbwvL/ItLLAK3F2cEIdKZnfhJkdEAIwWFLvR4R5I7ZcCK5GgKz5dPROup8BAONA8XxcJWXaXV0YkfEmCDbZYMFC7pcx4NAnGp881RyAaG/HlstBHHVagpP2fwZ8K0J/2KPillOq/Die+vNc2++hx4EuftvNkZhSd+7zIYNKHQd0M4Ea74flgmmW5lG73bE1BkhVd2DsgEDihH19/vJjFH4PxKINKp0ij4jMyq9w+WsGiUqSDaQz/MZJ8wjzaSjvmSj4qlOAitr/s3f041e77rMb0W2ieCtYEy7IsebIqIWgKn/crm5FhyUtBCPEqFZgAKS313bXUio8LktqXCrZjZ0ZG8DmQG6hnK4PstKlIUQoNuFnb8Bp1zDgY4i2hb6Zmu7NnqnOaJJTjSGwaZOav0oMousn67BuFtwoMaGp+OjCopZ3HPfg19usnjvWpOgccXWYlQc0HOlGXUq+otKlXtQwAjUvz50GmV+lY3t4rpCgqk+pj9iH62xuzDQ01FOXl+v3Ehnw97mNJk9YarueG0Hl/1f6dhwXnjeEv35LLyWUjQolOoYgycEkgQ/cCCOSm7zgK1VT0oTLFISai8IG0qDP9HCszteHZhp+y4bsXQfAJTY11QLr7hx9/nQmVlHksDN5Wsno4wbkT+D2xb5EaDU2RBqZfTVcbRBWRtAhQcRPxdaUXyI7oKEaFg8fvQZ8wK/Ae+L18ub+Latb5W69dUVT6I13tPleXDl1oen9BXzaX7sygSpY4lJoXlu+SCKyNTMrC36PrB39QUWosw03ZsiKT5xjgN5+1m32yv4cg8lAwNCR4xxShrnhSbZ328yifaAuTnSawZmUGBVxPx4glVcvNUOXW2UvVtmeKU0SG1E+UGBAq7/UfaadMM7BsjyaaKpBa/tXZTm0rn8UiFqujvgNjQ3F/3ybRdlO5d6eMI9Na+1gqg6qxYSGR0H0wAdPhtyGRxpumehAQGeMKd49Sg6jspaf3NAjjuZ0Yp+eJV9652WqVZ7xtCNqRURV353h+XPGR+ZZ9siHRDQ+NcbxPkfbHw0/RTvZvEIdaDi5+DLh6tgIxMEtOpwTlfFrOUDaIcmWvzk92VtBFuafvoGzTipryTnMszjCsUTvyEPN8jPd6r8UmOFGXF2aVNksmn/bI97i4s1kYLgY8XsEOyx+Q9pUTkTEMn2JWgnEcSOAtaX1ZskHnfueKzUPb+/YWb+z8SNCgnUqHqa42qBqwlhdshzYhhfKhEisUptirzzp1kcbyHrug5PzHxh8Qri2pjHxSHYQ5sjig6K6B1YEuHP6uo19fL6BdgGlhKroiOF/6TMAcE9V3+yqvDdsW/IC0QXLHIBKC7wlDgLc25ltGogD/76P6tViDAb6+HNSSXJO056Ovq0z2BrXhnq1AmWa99mVnOLJwafRWPZC,iv:XxnAsh6yx9gICi3N6oTttpGXvguGZImWNIMp9srDJLM=,tag:M9gFSD5PNIfoCLet6Vy6QA==,type:str]
hetznerDnsApiToken: ENC[AES256_GCM,data:JfL4Xg9TZu4Og35g0SwfrI1uxiqgdFa7p5AQcfiPwLY=,iv:yOak3uXX7CNglu8O2UW/1sOI7BGZxpRQAFJCvRbzU0Y=,tag:6orkQIy7BxACziLWpYoS5Q==,type:str]
sops:
age:
- recipient: age1tkvtkw62xy90xc5xdcq836wgyrwlwmdslh76cete5g98vvvhj34qvwdw0g
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArQjVya2RyY1MxQUxtTHdX
MGlZRWdxZ3VXb01KbCtTSkJMR3dkZkZ0UGw0CitXcldZT3NJWExYZG50QnowMVhV
WDBpc0VFYjZnZDJDSWhUcHFHTzBiYkUKLS0tIFlrMmlxUkNVZExSNGN4VlMxcUw1
VW8rSVdDcGZKcHpocjdqZldiaFpqRlUKfQNcKrI6PuyeFv06Es8NsHm8I7NzxJ1k
ir088kx66xcXeEiyA4DnIcAWG9O6HEVXXnSahAIE2jcupSSouDF3ug==
-----END AGE ENCRYPTED FILE-----
- recipient: age18dmqd7r7fanrfmdxsvwgv9psvhs3hw5ydpvw0na0dv3dlrg4rs3q2wpvgv
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0OGlqTEhtaGR2Yi8vTVcv
NUtvd0ptS3h5Rnd1RGNuYlY2bHMrUmpKWHhRCkJpYjloQWhSM0FsNlNYSVcvWktV
VkkvblAyRXBadUJjK3h3c2JJbDZHc0kKLS0tIEhMbVZsekM5VDRhbDB0KzdyK1li
dWdhSGtFN1oybGpIb294ZE0zcDFUaEkK/AyEXeVmiYk1/IZdkyNGN4bccMFx5+JE
BazBF2NkztUWnyhqRvyp0cBucx7h/HhRSzqxwSr20lvv8XpRPGh8Iw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-07-17T12:01:21Z"
mac: ENC[AES256_GCM,data:003nzaNWdXLscJy9XZcwAb93M9Eo3Bdg9s5MHHiv4/TitaaZE7VghWHKv5DrcoA0GGdN9SnIVqHd+o6OPVER91XLVxoiX7ixtlu1RIRfqdama3RRPtSki5wP5wPz6qF4vRBIKfrTpZK7thXLYs2NhCB9HJYljNhcgLtzEG5bWgY=,iv:tEP530Pij3bt3hc5PCYGjFFyPiKgo34dHm23Xtmrxt8=,tag:macr/U8R5+wktTBJ9OqI/w==,type:str]
pgp:
- created_at: "2025-06-05T09:49:08Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMAw+OdhfgD3wfAQ/8DFSjoJYmO4+yvi4WT6mgrlzmAIvX0Ozch9XY+6DDOwiN
746QgI6FI5NpmayTbhddhL1J3tiWkzOyAMhxd8JVNDdZHDJ9lDMCq5s/6yYJZvst
qpoU2pjeYFc+ag+H7m8d5dIaR352aBlKw+MMGOvBinM+5qAWNWo1Vams/9HV3BAV
vsFKLSj3eo3/MjjzY3bPlfBwhkDnudzfVJXcY7GhbVVzaQKXosoGjMfCKvSQNMWr
z52P40pfkXx1nWUt79G4xcH/G+lCUlz93RmS89sLS+YrrjKGQc4xcYpqpNjy5Xdw
rz+nGuOsMKXqLuxYJVuiTcxN0agVily9BTifUYiJZfS9cpbMvLwTyUOcc64EVCKH
Gg0b5l5DhyUKKk3klzgeXTlj2zPhKjGVT2MnZShZRspfGfV6T7iP761YD4ucaExd
1+/cegyfeCNAykt4lD6ACeQXRLDs8rU2hUjpN3J6AemLW+Aj/ZnRVZWzgIvnDEEY
pyz/rAk5J6m7Q7909TcMuFg3j9ENeJZuRSwxwF0MRUYLZByKCH3QY9CE3mCh7Xni
p5znHpYaYqNIoiTmbBcxEx4mYRXUkorLTJXt4AO7zQB24ZReLDRsSzvrnQqyLIdA
b4pK2k2/L0Hagu2SZFvfhgw4qWZpIlgcoOVbe2dkmbIXMbjb8SuF/2jFwushALjS
XAG+iXYORCrvsuJoNjnQtSW0OGqYwuNNvWo2Ymyg2sA6CW+O6gsCZpZE0FKHcbl/
FxgecFBl+P6Dk4OOewie+E4cZWIq2uXQch8QPSk5huuyUms6VZI2fre83dMv
=mHmB
-----END PGP MESSAGE-----
fp: 6F7069FE6B96E894E60EC45C6EEFA706CB17E89B
unencrypted_suffix: _unencrypted
version: 3.7.3

View file

@ -1,124 +0,0 @@
{
"nodes": {
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nix-snapshotter",
"nixpkgs"
]
},
"locked": {
"lastModified": 1704152458,
"narHash": "sha256-DS+dGw7SKygIWf9w4eNBUZsK+4Ug27NwEWmn2tnbycg=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "88a2cd8166694ba0b6cb374700799cec53aef527",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nix-snapshotter": {
"inputs": {
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1723875769,
"narHash": "sha256-66GofByLJ+S4ZZphIC+vJKeL9VJ2bzH2VbcJ3OqteMM=",
"owner": "pdtpartners",
"repo": "nix-snapshotter",
"rev": "6eaadfd8f89e5e7d79b2013626bbd36e388159da",
"type": "github"
},
"original": {
"owner": "pdtpartners",
"repo": "nix-snapshotter",
"type": "github"
}
},
"nixlib": {
"locked": {
"lastModified": 1728781282,
"narHash": "sha256-hUP9oxmnOmNnKcDOf5Y55HQ+NnoT0+bLWHLQWLLw9Ks=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "16340f605f4e8e5cf07fd74dcbe692eee2d4f51b",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixos-generators": {
"inputs": {
"nixlib": "nixlib",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1728867876,
"narHash": "sha256-NCyOA8WZNoojmXH+kBDrQj3LwvakYNzSc0h+LTXkmPE=",
"owner": "nix-community",
"repo": "nixos-generators",
"rev": "fdf142111597f6c6283cf5ffe092b6293a3911d0",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-generators",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1728897630,
"narHash": "sha256-0utJPs4o2Mody8GDwo4hnGuxc8dJqju4u9lLJY4d/Lw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c9f0b4a395289ce18727e2a8e43cae6796693ccc",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nix-snapshotter": "nix-snapshotter",
"nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,371 +0,0 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small";
# nixpkgs-systemd256.url = "github:NixOS/nixpkgs/962cf03fb8c782c5e00f465397e03dc84284acc9";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-snapshotter = {
url = "github:pdtpartners/nix-snapshotter";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{ self, nixpkgs, ... }:
let
systems = [
"aarch64-linux"
"x86_64-linux"
];
forAllSystems = nixpkgs.lib.genAttrs systems;
in
{
nixosConfigurations.default = nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
specialArgs = { };
modules = [
(
{
config,
modulesPath,
pkgs,
lib,
...
}:
{
nixpkgs.overlays = [
(_final: _previous: {
# inherit (self.inputs.nixpkgs-systemd256.legacyPackages.${pkgs.system}) systemd systemdMinimal;
# systemd =
# self.inputs.nixpkgs-systemd256.legacyPackages.${pkgs.system}.systemd.overrideAttrs (prevAttrs: {
# src = /home/steveej/src/others/systemd;
# withAppArmor = false;
# withRepart = false;
# withHomed = false;
# withAcl = false;
# withEfi = false;
# withBootloader = false;
# withCryptsetup = false;
# withLibBPF = false;
# withOomd = false;
# withFido2 = false;
# withApparmor = false;
# withDocumentation = false;
# withUtmp = false;
# withQrencode = false;
# withVmspawn = false;
# withMachined = false;
# withLogTrace = true;
# withArchive = false;
# # don't need these but cause errors for exampel files not found
# # withLogind = false;
# })
# pkgs.systemdMinimal.override {
# # getting errors with these disabled
# withCoredump = true;
# withCompression = true;
# withLogind = true;
# withSysusers = true;
# withUserDb = true;
# }
# pkgs.systemdMinimal
# pkgs.systemd.override {
# withRepart = false;
# withHomed = false;
# withAcl = false;
# withEfi = false;
# withBootloader = false;
# withCryptsetup = false;
# withLibBPF = false;
# withOomd = false;
# withFido2 = false;
# withApparmor = false;
# withDocumentation = false;
# withUtmp = false;
# withQrencode = false;
# withVmspawn = false;
# withMachined = false;
# withLogTrace = true;
# # don't need these but cause errors for exampel files not found
# # withLogind = false;
# }
# ;
})
];
imports = [ (modulesPath + "/profiles/minimal.nix") ];
system.stateVersion = "24.11";
# https://github.com/hercules-ci/arion/blob/c24c185e67f093298a081900b49ca18716077dec/src/nix/modules/nixos/container-systemd.nix
boot.isContainer = true;
# boot.tmp.useTmpfs = true;
boot.loader.grub.enable = lib.mkForce false;
boot.loader.systemd-boot.enable = lib.mkForce false;
services.journald.console = "/dev/console";
services.journald.storage = "none";
# boot.specialFileSystems = lib.mkForce {};
services.nscd.enable = false;
system.nssModules = lib.mkForce [ ];
systemd.services.systemd-logind.enable = false;
systemd.services.console-getty.enable = false;
systemd.sockets.nix-daemon.enable = false;
systemd.services.nix-daemon.enable = false;
systemd.oomd.enable = false;
networking.useDHCP = false;
networking.firewall.enable = false;
# system.build.earlyMountScript =
# lib.mkForce ''
# '';
# system.activationScripts.specialfs =
# lib.mkForce ''
# '';
boot.postBootCommands = ''
ls -lha /run
mkdir -p /run/wrappers
'';
boot.kernelParams = [ "systemd.log_level=debug" ];
# services.udev.enable = false;
# TODO: this is only needed because `/run/current-system` is missing
# environment.variables.PATH = "${lib.makeBinPath config.environment.systemPackages}:$PATH";
systemd.mounts = lib.mkForce [ ];
fileSystems = lib.mkForce { };
services.mycelium.enable = false;
services.mycelium.keyFile = "/var/lib/secrets/mycelium-keyfile";
systemd.services.mycelium.serviceConfig.DynamicUser = lib.mkForce false;
systemd.services.mycelium.serviceConfig.User = lib.mkForce "root";
systemd.services.mycelium.serviceConfig.ExecStart = lib.mkForce (
pkgs.writeShellScript "mycelium" ''
while true; do
ls -lha $CREDENTIALS_DIRECTORY
sleep 5
done
''
);
systemd.services.testing-credentials = {
wantedBy = [ "multi-user.target" ];
path = [ pkgs.coreutils ];
serviceConfig = {
# SyslogIdentifier = "testing-credentials";
# StateDirectory = "testing-credentials";
# DynamicUser = true;
# User = "tc";
# ProtectHome = true;
# ProtectSystem = true;
# LoadCredential = [
# "mycelium-keyfile:${self.nixosConfigurations.default.config.services.mycelium.keyFile}"
# "hosts:/etc/hosts"
# ];
SetCredential = "mycelium-keyfile:not secret string";
ExecStart = lib.mkForce (
pkgs.writeShellScript "mycelium" ''
cd $STATE_DIRECTORY
pwd
env
while true; do
ls -lha $CREDENTIALS_DIRECTORY
sleep 5
done
''
);
};
};
services.caddy = {
enable = true;
globalConfig = ''
auto_https off
'';
virtualHosts.":80" = {
extraConfig = ''
respond "hello from ${config.networking.hostName}"
'';
};
};
}
)
];
};
packages = forAllSystems (
system:
let
name = "mycelium";
inherit (self.inputs) nix-snapshotter;
config = {
entrypoint = "${self.nixosConfigurations.default.config.system.build.toplevel}/init";
# port = 2379;
args = [ ];
# nodePort = 30001;
};
myceliumPorts = {
tcp = [ 9651 ];
udp = [
9650
9651
];
};
inherit (config)
entrypoint
# port
args
# nodePort
;
pkgs = import nixpkgs { overlays = [ nix-snapshotter.overlays.default ]; };
image = pkgs.nix-snapshotter.buildImage {
inherit name;
resolvedByNix = true;
config = {
entrypoint = [ entrypoint ];
env = [
# this is read by the `/init` script and prevents various incompatible commands like mount, etc.
# the value of this doesn't seem to matter as long as it's not an empty string.
"container=nerd"
"SYSTEMD_LOG_LEVEL=debug"
];
volumes = {
# "/var/lib/private/mycelium/key.bin" = {};
# "/run" = {};
# "/tmp" = {};
# "/etc" = {};
};
copyToRoot = [
# self.nixosConfigurations.default.config.system.build.toplevel
];
};
};
in
{
k8s =
let
pod = pkgs.writeText "${name}-pod.json" (
builtins.toJSON {
apiVersion = "v1";
kind = "Pod";
metadata = {
inherit name;
labels = {
inherit name;
};
};
spec.containers = [
{
inherit name args;
image = "nix:0${image}";
ports = [
{
name = "mycelium-tcp-0";
containerPort = builtins.elemAt myceliumPorts.tcp 0;
}
{
name = "mycelium-udp-0";
protocol = "UDP";
containerPort = builtins.elemAt myceliumPorts.udp 0;
}
{
name = "mycelium-udp-1";
protocol = "UDP";
containerPort = builtins.elemAt myceliumPorts.udp 1;
}
];
}
];
}
);
service = pkgs.writeText "${name}-service.json" (
builtins.toJSON {
apiVersion = "v1";
kind = "Service";
metadata.name = "${name}-service";
spec = {
type = "NodePort";
selector = {
inherit name;
};
ports = [
{
name = "mycelium-tcp-0";
port = builtins.elemAt myceliumPorts.tcp 0 + 50000;
targetPort = "mycelium-tcp-0";
}
{
name = "mycelium-udp-0";
protocol = "UDP";
port = builtins.elemAt myceliumPorts.udp 0 + 50000;
targetPort = "mycelium-udp-0";
}
{
name = "mycelium-udp-1";
protocol = "UDP";
port = builtins.elemAt myceliumPorts.udp 1 + 50000;
targetPort = "mycelium-udp-1";
}
];
};
}
);
in
pkgs.runCommand "declarative-k8s" { } ''
mkdir -p $out/share/k8s
cp ${pod} $out/share/k8s/
cp ${service} $out/share/k8s/
'';
inherit image;
start = pkgs.writeShellApplication {
name = "start";
text = ''
set -x
rm -rf ./result
nix build --impure .#image
sudo nix2container load ./result
sudo -E nerdctl run --name ${name} --privileged -dt \
--cgroup-manager cgroupfs \
--volume "$PWD/key.bin.crypt:${self.nixosConfigurations.default.config.services.mycelium.keyFile}:ro" \
"nix:0$(readlink result):latest"
'';
};
stop = pkgs.writeShellApplication {
name = "stop";
text = ''
set +e
sudo -E nerdctl stop -t 60 ${name}
sudo -E nerdctl rm --force ${name}
sudo -E nerdctl system prune --all --force
sudo systemctl stop nix-snapshotter
sudo systemctl stop containerd
mount | rg -No '(/var/lib/container|/tmp/initial)[^ ]+' | tac | xargs sudo umount -l
sudo systemctl start containerd
sudo systemctl start nix-snapshotter
'';
# tmpfs on /run/credentials/mycelium.service type tmpfs (ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,noswap)
# mount -t tmpfs tmpfs /run/credentials/mycelium.service -o ro,nosuid,nodev,noexec,relatime,nosymfollow,size=1024k,nr_inodes=1024,mode=700,noswap
};
}
);
};
}

View file

@ -1,82 +1,29 @@
{ { hostAddress
specialArgs, , localAddress
hostBridge, , syncthingPort ? 22000
hostAddress,
localAddress,
syncthingPort ? 22000,
syncthingLocalAnnouncePort ? 21027,
smbTcpPort ? 445,
autoStart ? false,
}: }:
{ {
inherit specialArgs;
config =
{ ... }:
{
system.stateVersion = "20.05"; # Did you read the comment?
imports = [ ../profiles/containers/configuration.nix ]; config = { config, pkgs, ... }: {
imports = [
../profiles/containers/configuration.nix
];
networking.firewall.allowedTCPPorts = [ networking.firewall.enable = true;
# syncthing gui networking.firewall.allowedTCPPorts = [
8384 # syncthing gui
]; 8384
];
services.syncthing = { services.syncthing = {
enable = true; enable = true;
openDefaultPorts = true; openDefaultPorts = true;
guiAddress = "0.0.0.0:8384"; guiAddress = "0.0.0.0:8384";
};
services.samba = {
enable = true;
securityType = "user";
openFirewall = true;
settings = {
global = {
"workgroup" = "DMZ";
"server string" = "syncthing";
"netbios name" = "syncthing";
"security" = "user";
#"use sendfile" = "yes";
#"max protocol" = "smb2";
# note: localhost is the ipv6 localhost ::1
"hosts allow" = "192.168.23. 127.0.0.1 localhost";
"hosts deny" = "0.0.0.0/0";
"guest account" = "nobody";
"map to guest" = "bad user";
};
"scan-stefan" = {
"path" = "/var/lib/syncthing/Sync/Home::Scan::Stefan";
"browseable" = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = "syncthing";
"force group" = "syncthing";
};
"scan-justyna" = {
"path" = "/var/lib/syncthing/Sync/Home::Scan::Justyna";
"browseable" = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = "syncthing";
"force group" = "syncthing";
};
};
};
# TODO: find out if smbpasswd file is still used and set it here. or find an alternative
# sops.secrets.smbpasswd = {
# };
# environment.etc."samba/smbpasswd".source = config.sops.secrets.smbpasswd.text;
}; };
};
inherit autoStart; autoStart = true;
bindMounts = { bindMounts = {
"/var/lib/syncthing/" = { "/var/lib/syncthing/" = {
@ -92,22 +39,7 @@
hostPort = syncthingPort; hostPort = syncthingPort;
protocol = "tcp"; protocol = "tcp";
} }
{
containerPort = 22000;
hostPort = syncthingPort;
protocol = "udp";
}
{
containerPort = 21027;
hostPort = syncthingLocalAnnouncePort;
protocol = "udp";
}
{
containerPort = 445;
hostPort = smbTcpPort;
protocol = "tcp";
}
]; ];
inherit hostBridge hostAddress localAddress; inherit hostAddress localAddress;
} }

View file

@ -1,436 +1,76 @@
{ { hostAddress
specialArgs, , localAddress
hostBridge, , httpsPort ? 443
hostAddress, }: {
localAddress, config = { config, pkgs, lib, ... }: {
httpPort, imports = [
httpsPort, ../profiles/containers/configuration.nix
forgejoSshPort, ];
autoStart ? false,
}:
let
domain = "www.stefanjunker.de";
in
{
inherit specialArgs;
config =
{
config,
pkgs,
lib,
repoFlake,
nodeFlake,
system,
...
}:
let
nixpkgs-kanidm = nodeFlake.inputs.nixpkgs-unstable;
in
{
system.stateVersion = "22.05"; # Did you read the comment?
disabledModules = [ networking.firewall.enable = false;
"services/misc/forgejo.nix"
"services/security/kanidm.nix"
];
imports = [ services.ddclientovh = {
"${nodeFlake.inputs.nixpkgs-unstable}/nixos/modules/services/misc/forgejo.nix"
"${nixpkgs-kanidm}/nixos/modules/services/security/kanidm.nix"
../profiles/containers/configuration.nix
repoFlake.inputs.sops-nix.nixosModules.sops
];
sops.defaultSopsFile = ./webserver_secrets.yaml;
networking.firewall.allowedTCPPorts = [
httpPort
httpsPort
forgejoSshPort
];
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.hedgedoc_environment_file = {
sopsFile = ./webserver_secrets.yaml;
owner = config.users.users.hedgedoc.name;
};
services.caddy = {
enable = true; enable = true;
logFormat = '' domain = "www.stefanjunker.de";
level ERROR
'';
virtualHosts."${domain}" = {
extraConfig = ''
redir /hedgedoc* https://hedgedoc.${domain}
basic_auth /justyna/202505_prt_teil1* {
prt $2a$14$y7tZYZxTlJ2JFsBtRM.D8Ok0oHhWt53mGXk.xJMLXc/JF.bTtOWaq
}
file_server /* {
browse
root /var/www/stefanjunker.de/htdocs/caddy
pass_thru
}
# respond "Hi"
# respond (not /*/*) "Hi"
'';
};
virtualHosts."hedgedoc.${domain}" = {
extraConfig = ''
reverse_proxy http://[::1]:3000
'';
};
virtualHosts."authelia.${domain}" = {
extraConfig = ''
reverse_proxy http://127.0.0.1:${builtins.toString config.services.authelia.instances.default.settings.server.port}
'';
};
virtualHosts."lldap.${domain}" = {
extraConfig = ''
reverse_proxy http://127.0.0.1:${builtins.toString config.services.lldap.settings.http_port}
'';
};
virtualHosts."forgejo.${domain}" = {
extraConfig = ''
reverse_proxy http://127.0.0.1:${builtins.toString config.services.forgejo.settings.server.HTTP_PORT}
'';
};
virtualHosts."kanidm.${domain}" = {
extraConfig = ''
reverse_proxy https://${builtins.toString config.services.kanidm.serverSettings.bindaddress} {
transport http {
tls_server_name ${config.services.kanidm.serverSettings.domain}
}
}
'';
};
};
services.hedgedoc = {
enable = true;
settings = {
domain = "hedgedoc.${domain}";
urlPath = "";
protocolUseSSL = true;
db = {
dialect = "sqlite";
storage = "/var/lib/hedgedoc/db.hedgedoc.sqlite";
};
allowAnonymous = false;
allowAnonymousEdits = false;
allowGravatar = false;
allowFreeURL = false;
defaultPermission = "private";
allowEmailRegister = false;
email = false;
ldap = {
url = "ldap://127.0.0.1:${builtins.toString config.services.lldap.settings.ldap_port}";
bindDn = "uid=admin,ou=people,dc=stefanjunker,dc=de";
# these are set via the `environmentFile`
# bindCredentials = "$LDAP_ADMIN_PASSWORD";
searchBase = "ou=people,dc=stefanjunker,dc=de";
searchFilter = "(&(memberOf=cn=hedgedoc,ou=groups,dc=stefanjunker,dc=de)(uid={{username}}))";
useridField = "uid";
};
oauth2 =
let
originURL = config.services.kanidm.serverSettings.origin;
in
{
providerName = "kanidm (${originURL})";
authorizationURL = "${originURL}/ui/oauth2";
tokenURL = "${originURL}/oauth2/token";
userProfileURL = "${originURL}/oauth2/openid/hedgedoc/userinfo";
scope = "openid email profile";
# rolesClaim = "roles";
# accessRole = "role/hedgedoc";
userProfileUsernameAttr = "name";
userProfileDisplayNameAttr = "displayname";
userProfileEmailAttr = "email";
clientID = "hedgedoc";
# set via the `environmentFile`
# clientSecret = "$CMD_OAUTH2_CLIENT_SECRET";
};
uploadsPath = "/var/lib/hedgedoc/uploads";
};
environmentFile = config.sops.secrets.hedgedoc_environment_file.path;
};
services.jitsi-meet = {
enable = false;
hostName = "meet.${domain}";
config = {
prejoinPageEnabled = true;
};
caddy.enable = true;
nginx.enable = false;
};
sops.secrets.authelia_storageEncryptionKey = {
sopsFile = ./webserver_secrets.yaml;
owner = config.users.users.authelia-default.name;
};
sops.secrets.authelia_jwtSecret = {
sopsFile = ./webserver_secrets.yaml;
owner = config.users.users.authelia-default.name;
};
services.authelia.instances.default =
let
baseDir = "/var/lib/authelia-default";
in
{
enable = true;
secrets.storageEncryptionKeyFile = config.sops.secrets.authelia_storageEncryptionKey.path;
secrets.jwtSecretFile = config.sops.secrets.authelia_jwtSecret.path;
settings = {
theme = "auto";
default_2fa_method = "totp";
log.level = "debug";
server = {
disable_healthcheck = true;
host = "127.0.0.1";
port = 9091;
# path = "authelia";
};
storage = {
local.path = "${baseDir}/authelia.sqlite";
};
authentication_backend = {
file.path = "${baseDir}/first_factor.yaml";
file.search.email = true;
file.search.case_insensitive = false;
};
access_control = {
default_policy = "one_factor";
};
session.domain = "stefanjunker.de";
notifier = {
disable_startup_check = true;
filesystem.filename = "${baseDir}/notification.txt";
};
};
};
users.groups.lldap = { };
users.users.lldap = {
isSystemUser = true;
group = "lldap";
};
sops.secrets.lldap_jwtSecret = {
sopsFile = ./webserver_secrets.yaml;
owner = config.users.users.lldap.name;
};
sops.secrets.lldap_adminPassword = {
sopsFile = ./webserver_secrets.yaml;
owner = config.users.users.lldap.name;
};
sops.secrets.lldap_environmentFile = {
sopsFile = ./webserver_secrets.yaml;
owner = config.users.users.lldap.name;
};
services.lldap = {
enable = true;
environment = {
LLDAP_JWT_SECRET_FILE = config.sops.secrets.lldap_jwtSecret.path;
LLDAP_LDAP_USER_PASS_FILE = config.sops.secrets.lldap_adminPassword.path;
};
environmentFile = config.sops.secrets.lldap_environmentFile.path;
settings = {
verbose = true;
ldap_base_dn = "dc=stefanjunker,dc=de";
http_url = "https://lldap.${domain}";
## Options to configure SMTP parameters, to send password reset emails.
## To set these options from environment variables, use the following format
## (example with "password"): LLDAP_SMTP_OPTIONS__PASSWORD
smtp_options = {
## Whether to enabled password reset via email, from LLDAP.
enable_password_reset = true;
# port = 465;
## How the connection is encrypted, either "NONE" (no encryption), "TLS" or "STARTTLS".
# smtp_encryption = "TLS";
};
# database_url = "sqlite:///var/lib/lldap/users.db?mode=rwc";
};
};
sops.secrets.FORGEJO_JWT_SECRET = { };
sops.secrets.FORGEJO_INTERNAL_TOKEN = { };
sops.secrets.FORGEJO_SECRET_KEY = { };
services.forgejo = {
enable = true;
package = nodeFlake.inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.forgejo;
settings = {
service.DISABLE_REGISTRATION = true;
server.HTTP_ADDR = "127.0.0.1";
server.START_SSH_SERVER = true;
server.SSH_PORT = forgejoSshPort;
server.ROOT_URL = "https://forgejo.${domain}";
server.HTTP_PORT = 3001;
# TODO: how do i get a 3072 length SSH key with the yubikey?
"ssh.minimum_key_sizes".RSA = 2048;
};
secrets = {
oauth2.JWT_SECRET = lib.mkForce config.sops.secrets.FORGEJO_JWT_SECRET.path;
security.INTERNAL_TOKEN = lib.mkForce config.sops.secrets.FORGEJO_INTERNAL_TOKEN.path;
security.SECRET_KEY = lib.mkForce config.sops.secrets.FORGEJO_SECRET_KEY.path;
};
};
systemd.services.lldap.serviceConfig.User = config.users.users.lldap.name;
systemd.services.lldap.serviceConfig.Group = config.users.groups.lldap.name;
systemd.services.lldap.serviceConfig.DynamicUser = lib.mkForce false;
# combine a path watcher with a service that transfers the certs by caddy to kanidm
# TODO: had an issue where the certificate in kanidm was expired, despite caddy having a refreshed certificate
systemd.paths.kanidm-tls-watch = {
enable = true;
requiredBy = [ "kanidm.service" ];
pathConfig = {
PathChanged = [
"${config.services.caddy.dataDir}/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${config.services.kanidm.serverSettings.domain}/${config.services.kanidm.serverSettings.domain}.key"
"${config.services.caddy.dataDir}/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${config.services.kanidm.serverSettings.domain}/${config.services.kanidm.serverSettings.domain}.crt"
];
Unit = "kanidm-tls-update.service";
};
};
systemd.services.kanidm-tls-update =
let
dbDir = builtins.dirOf config.services.kanidm.serverSettings.db_path;
in
{
enable = true;
requiredBy = [ "kanidm.service" ];
unitConfig = {
# ConditionPathExists = [
# "${config.services.caddy.dataDir}/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${config.services.kanidm.serverSettings.domain}/${config.services.kanidm.serverSettings.domain}.key"
# "${config.services.caddy.dataDir}/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${config.services.kanidm.serverSettings.domain}/${config.services.kanidm.serverSettings.domain}.crt"
# ];
};
serviceConfig.Type = "oneshot";
script =
let
tlsDir = builtins.dirOf config.services.kanidm.serverSettings.tls_key;
in
''
set -xe
cat "${config.services.caddy.dataDir}/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${config.services.kanidm.serverSettings.domain}/${config.services.kanidm.serverSettings.domain}.key" > tls.key
cat "${config.services.caddy.dataDir}/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${config.services.kanidm.serverSettings.domain}/${config.services.kanidm.serverSettings.domain}.crt" > tls.chain
chown ${config.systemd.services.kanidm.serviceConfig.User}:${config.systemd.services.kanidm.serviceConfig.Group} tls.{key,chain}
chmod 400 tls.{key,chain}
# create the kanidm directory in case it's missing
if [[ ! -d ${tlsDir} ]]; then
mkdir -p ${tlsDir}
chown -R ${config.systemd.services.kanidm.serviceConfig.User}:${config.systemd.services.kanidm.serviceConfig.Group} ${tlsDir}
chmod 700 ${tlsDir}
fi
mv tls.key ${config.services.kanidm.serverSettings.tls_key}
mv tls.chain ${config.services.kanidm.serverSettings.tls_chain}
if [[ ! -d ${dbDir} ]]; then
mkdir -p ${dbDir}
chown -R ${config.systemd.services.kanidm.serviceConfig.User}:${config.systemd.services.kanidm.serviceConfig.Group} ${dbDir}
chmod 700 ${dbDir}
fi
'';
};
systemd.services.kanidm.serviceConfig =
let
dbDir = builtins.dirOf config.services.kanidm.serverSettings.db_path;
in
# stateDir = "/var/lib/${config.systemd.services.kanidm.serviceConfig.StateDirectory}";
{
# ExecStartPre = ''
# mkdir -p ${dbDir}
# '';
BindPaths = [
dbDir
# stateDir
];
};
services.kanidm =
let
dataDir = "/var/lib/kanidm";
in
{
package = nixpkgs-kanidm.legacyPackages.${pkgs.system}.kanidm;
enablePam = false;
enableClient = false;
enableServer = true;
serverSettings = {
role = "WriteReplica";
log_level = "debug";
domain = "kanidm.${domain}";
origin = "https://kanidm.${domain}";
bindaddress = "127.0.0.1:8444";
# don't expose ldap
# ldapbindaddress = "[::1]:6636";
tls_key = "${dataDir}/tls/tls.key";
tls_chain = "${dataDir}/tls/tls.chain";
online_backup = {
schedule = "00 06 * * *";
};
};
};
}; };
inherit autoStart; services.nginx.enable = true;
services.nginx.virtualHosts."stefanjunker.de" = {
default = true;
onlySSL = true;
root = "/var/www/stefanjunker.de/htdocs";
sslCertificate = "/etc/secrets/stefanjunker.de/nginx/nginx.crt";
sslCertificateKey = "/etc/secrets/stefanjunker.de/nginx/nginx.key";
locations."/fi" = {
index = "index.php";
};
locations."~ ^(.+\.php)(.*)$".extraConfig = ''
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass unix:${config.services.phpfpm.pools.mypool.socket};
fastcgi_index index.php;
'';
};
services.phpfpm.pools.mypool = {
user = "nobody";
phpPackage = pkgs.php5;
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 5;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 1;
"pm.max_spare_servers" = 3;
"pm.max_requests" = 500;
"php_admin_value[error_reporting]" = "E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED";
};
};
# the custom php5 we're using here has no fpm-systemd, so the default `Type = "notify"` won't work
systemd.services."phpfpm-mypool" = {
serviceConfig = {
Type = lib.mkForce "simple";
};
};
services.mysql = {
enable = true;
package = pkgs.mariadb;
};
};
autoStart = true;
bindMounts = { bindMounts = {
# FIXME/REMINDER: this is used so that the container can decrypt the secrets that are deployed to the host "/etc/secrets/" = {
"/etc/ssh/ssh_host_ed25519_key".isReadOnly = true; hostPath = "/var/lib/container-volumes/webserver/etc-secrets";
"/etc/ssh/ssh_host_ed25519_key.pub".isReadOnly = true; isReadOnly = true;
};
"/var/www" = { "/var/www" = {
hostPath = "/var/lib/container-volumes/webserver/var-www"; hostPath = "/var/lib/container-volumes/webserver/var-www";
@ -441,55 +81,17 @@ in
hostPath = "/var/lib/container-volumes/webserver/var-lib-mysql"; hostPath = "/var/lib/container-volumes/webserver/var-lib-mysql";
isReadOnly = false; isReadOnly = false;
}; };
"/var/lib/hedgedoc" = {
hostPath = "/var/lib/container-volumes/webserver/var-lib-hedgedoc";
isReadOnly = false;
};
"/var/lib/authelia-default" = {
hostPath = "/var/lib/container-volumes/webserver/var-lib-authelia-default";
isReadOnly = false;
};
"/var/lib/lldap" = {
hostPath = "/var/lib/container-volumes/webserver/var-lib-lldap";
isReadOnly = false;
};
"/var/lib/forgejo" = {
hostPath = "/var/lib/container-volumes/webserver/var-lib-forgejo";
isReadOnly = false;
};
"/var/lib/kanidm" = {
hostPath = "/var/lib/container-volumes/webserver/var-lib-kanidm";
isReadOnly = false;
};
}; };
privateNetwork = true; privateNetwork = true;
forwardPorts = [ forwardPorts = [
{
# http
containerPort = 80;
hostPort = httpPort;
protocol = "tcp";
}
{ {
# https # https
containerPort = 443; containerPort = 443;
hostPort = httpsPort; hostPort = httpsPort;
protocol = "tcp"; protocol = "tcp";
} }
{
# forgejo ssh
containerPort = forgejoSshPort;
hostPort = forgejoSshPort;
protocol = "tcp";
}
]; ];
inherit hostBridge hostAddress localAddress; inherit hostAddress localAddress;
} }

View file

@ -1,55 +0,0 @@
hedgedoc_environment_file: ENC[AES256_GCM,data:gPTokPMGBAN/lGGeUs95vg45yVrrSmFCKWTjlMV4V+YnflcqiaZvifX9+0fe3DELwNL4kY4st4N0MadhLkTiSieyp46fP8Dujk4Prhi7JWweBDsN4WtxcwJfAdowgh5LTzqM3zggC/J9NGR/zgJGLYraOqsFueXycxDxntE+8MlepYFGsND4WbFHNRvsVd7xUWerZZD+JFhws2sjwC9DqoJ+mBX4u9J2faSrL3okBGwRpEZlJhe6/8pT0l1aVxI0b/9UsLUL/him/vVqY8ygMP8O95gzuDEaCtwSXw08ylhb3g3YHdMh9ZOe9dPNVocVFrB15HfxeY4KzRCVfvgmBsSiUrgUAZQ8aav2ZWHPKQ==,iv:AVtx/43MK5KVxP59olEmbkUzLhd0cBjPpVeiAJGELfM=,tag:Hd3edeUzLgHnwAwPiMGp4A==,type:str]
authelia_storageEncryptionKey: ENC[AES256_GCM,data:BLj2+w0jUOiiqljd4WcYt90I1Y/tm6vYRn9IPvv7k+ykjeWeafDcb9LpAbYZ82iAbCDZ6cDnTIJSH50TYFM1Bw==,iv:DfrFuTMS6rzWS1F7hIloD7Eb9N6LV6MDsPGEidTCIkM=,tag:4TxiUuWj8LLCAe+3SQWthA==,type:str]
authelia_jwtSecret: ENC[AES256_GCM,data:CtvhPJDlM8kZDh3MWI6jBEIK5P/Rc0ZY3JfQ/1qn2FyZ0kOE9CMznRQdzi125Mlh+LgfhS00aeY/esuSJ1YKnw==,iv:o29+Ja4E4USpxD5Bgg4nGpj1WdK+uJJeuyqa3c92Pys=,tag:Ko/6PqIM7FyvqMJAepTNKw==,type:str]
lldap_jwtSecret: ENC[AES256_GCM,data:Jd05K5zZZcdFY9P+PM1ycpl4eKr7THXzlEC2gxhfq0kZ0c7NrmqpnxLFyMOoq0oZwFXQ3aE29N+dYYCbWgEs0g==,iv:k9Y4XZcFSUaaOvooMzH1AlHaI/RiZZ0cpSqTU6jzsUU=,tag:EHwIMQ00Z+IrXAKgugMbmQ==,type:str]
lldap_adminPassword: ENC[AES256_GCM,data:qZviC+/V25iHWS2d5KKrMfCLmmWKAkXoiLW3NJyZWIvMRbFPtfJGv/5e++idcKNLdPHRgvGpdeTpOdZNK7ETSQ==,iv:jX8bzgYVXZfMQ8Qxa7WaUiQFE/mBmQWZ3o000njeEC8=,tag:4Rd3WVGIw1rBLKND4xPbMg==,type:str]
lldap_environmentFile: ENC[AES256_GCM,data:TpdO1N2MgHWI4TipvlwfVjnKppzpluI9WA3ejbgT8jrRXXTCA94PS734wDHLtEAIwKdIQd/JGDS+1kbdvgDL3F3HIOX5HLz9h7CtkDBYT6qOy0Zb0tNHjmJco6dL/iMwuzglXxu2460nadO+lHoTs3DA3lesghzpJzm41hgElzcxXS2sa/hsV+kjmbyfu6Xi94kbqcHBLA/mppWmLSgJN6wu/bO07XfaSB1ghHnAR7BL9XZDjoNDzljZAXDpDBw3WD6mwoZeIjGbkEuL4nUnkS6CkA+y7IORA24XGGAczRxZp4vLfUOnnlFCPGIHBsRTbrTB4bcEDBK4+5gHfNhXxvD5VlNMb4TPqYdcEIxkgMxZNLV5U2LTlzn18HNOCvsPb9XOOtY21j6qHMMQDXZREmn5NsW0HXM4gNZ0fC9UEe1MYBhyE3gGEGDzzDUrrQCGLm7/1OC7NRlzuI7M/5DlgcREwK1PkjPDmfRCAq86l0N5lMP/A7MMq2SJWcZvf+ot3fInugq485773vgWWl2Rodl08SZ8YHnzj0L6anPu856v2BsIotE0iRJSCpzA2ZgOJ9RViBfoq6F3beJKLnGN7oGb8XBviRTnXrTN6BTuFyv3dIZ7qcuTGTY+ucjRXfGJ1TVlVQBbiqhQDz5c9D5e0RVnRe3AkMXeDMOd4GlWW5gsJSuZtlYq1aMEf/Bx+4WMyY/Wh+Jk1xxf30bth5L1dW82p6fNFhEuKabtkBALOg/CQzYczMeGP9ai6BWgZL8QPlQoEUpHh59Vz91V6unQSOJ2PNr5wzC6j75IKInVjcp4d1S9K2UAxg+HETn5p9T1sBRdAAVz0YgO5902FwDTsA+2x6Q=,iv:U94CNFxQ8kyIYdH0EyqQIJ3s7QKaLlMa+5coO0dQnto=,tag:KZEizL99W5BtcaXSnYXFhg==,type:str]
#ENC[AES256_GCM,data:uNqahO8WF6QFNkbPnQq2UDKn/gFt0H56keUb,iv:CDVKC3ER5rsKoMmBi2g5g+F3ZfKc3+Rs8bjxFhgSPZ4=,tag:oGPl6TB/nghGwWvVBLFlGQ==,type:comment]
FORGEJO_JWT_SECRET: ENC[AES256_GCM,data:nVz9x7+K+rBIZxuQP7o0WNFHUz89eR9cwBjfSAx9/WH5PF+/aWazZOJpVg==,iv:4qpHo143fe/sVhKfYDwxr+YiBZ2q/WWViYSwoxz0i/k=,tag:smSsJsqa6uZKarcoOMUjwQ==,type:str]
FORGEJO_INTERNAL_TOKEN: ENC[AES256_GCM,data:EIono9HSyvp1nQM0ij3ln3IUXO4moFbRgVddeV0BZBXmZG05jdjZ1SIXo/BxoSmRKnjllR7P00CpajNM5zORldlsBId5oAYL5GZtY3/nmxeXucJidknuow22G7Z8wRJJGBdishbgQhmc,iv:1D93gTUF1+DUR8qLJgML+oUhvSslhxEjGnbBC/PWHXw=,tag:NZB+mwba4TzLcUANZLDRTw==,type:str]
FORGEJO_SECRET_KEY: ENC[AES256_GCM,data:CewYFZtcXKUD5/oSM0Q32rhw+urdA0eQhdYp8EFHUXxEtL6f5NWK6IOwIlMuEv1/FjtTWlqxWekOZpmxBRzwnw==,iv:qLyVB7Nc+rDbBoO5g82/vPdykwOATHCSDLhvS+fK9PM=,tag:4NMhUvKmrRd6qrcQq3R8wA==,type:str]
sops:
age:
- recipient: age1tkvtkw62xy90xc5xdcq836wgyrwlwmdslh76cete5g98vvvhj34qvwdw0g
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuTitidDZpWVJsZWxmWDFa
emdyTSszczVNbDhZSlVjeWRDMDdXQmg4QmpBCmNLZ0tob2hsRHhlTXY5VHZEY01T
MUtRdUxBM0lmeEo2OVBMdElrYVVvY1EKLS0tIHIwWllkQU9RRjF1U0F0OWdCKzlq
Y3ZxSWI3MUxQNEljNXlUSnlTdlpxazAKKjJYqcDsBzo6yOYDkgtBZntxhsHjqOyZ
yg5G8vtuOiDvPLvODzI/I9VupGyLwEkxaFc67bpg4u/1Cql7oaAADQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age18dmqd7r7fanrfmdxsvwgv9psvhs3hw5ydpvw0na0dv3dlrg4rs3q2wpvgv
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsdFg1cm9JTFFyUmYxb1ZP
WWtKTDE4bDBya3pWakJ0bFVkSnZvdExGMlNVCmo0N1BvNnV4MERUTjU2blUzbngv
VDduRWd2K1VlK1k2OWp6L0JhTERnOUEKLS0tIGV0aFZMTGRHNW5HUUhGRkYxNGMz
dHJwN0R1eHkyWXpiVDlRcldHT0gvV28KRiwauYvF4CCu5LeW7+kR3GSkZ+rpIbsC
JF9vV3rxbE9SdJ3nP6CyYQX7tQ6rbXtOKawq3k+z4zV/Dw7gYSNn5Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-10-16T12:28:51Z"
mac: ENC[AES256_GCM,data:nrd2czzJlBcFfwn6lzh4qqco+/XsU2J6BqvQqMtskh3mL4Xx25IAzxiCno0KlNGr6o4YsuZP5anOX9RvrDq76Us3JQ7pDi3iQGPhmg+SE9u3Rwqn1/3YConvdfPV2DNB+tuyG3UVoRqpA4d+HdcYjN9n1UKk54R6UdSm9UrA+zc=,iv:Juupyet09zUAMu7bmVxq+/Q0bXJAzR0wAyt6vKNns3w=,tag:owdUWuXrQcDdiWi+1geY9A==,type:str]
pgp:
- created_at: "2025-06-05T09:49:08Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMAw+OdhfgD3wfAQ/8DIuNUO6tpyuG0j4Ros6MjHs1USkfY+2ntzqyugGe4OpA
cXLzXWGT7pCxE6bcd7FepG/Nln17219siP9PX1WqEl324GnKXjbAbczjnu/9ggeF
bUWBhKFwGivVXDfO8VusG0MN41tJMoDwAelaJdgnXnbAwHISJ20UzFtnTBx67ALs
5pqHzOf7uuY7eZbl79iEiBJ8Ecj/Y3yrcANbVXQtET7X5629nTMHuizFsym9fy0p
6elwdrJSGPlncWA/+wsec5WIxwOsrLoEz8rvFpZJo/YI4/5heiL6RmgqKODzAhFp
+PD/VoksJQ0lynzH2jBUKNte7UU5fyMAn9CEu0eY7sNRHpEKWjj/uPoWPkaV3JQ/
Au2YN9VV0qkyqYZ/6mU1L+Ukaci3kG/hJKM9MxXZ6rVEsuOnbuHPgW9jW/xogo38
/522CAF+NThKPWbiS/VDHyUsH+h2ubh9jGyFuesP/dNhXbc+6vkcIIBgfsb2IWt1
Fc2fvUlX9tpJYobk3PmyR88DHv4pXPkgIIEqW6JUHmkjdH+q82sGsRtni58eWUj6
DXn09tSpM3gu02wlqobca1qrOIKVsQJ/bHB4p6PRFoeqx6Yzfdy8h4WvT75PONGD
DGW7uLYo/ISb/SDgbclNw6vlYsI7ZFtYDTWxtCjrYXFBqRSMftgreRwhi8gU0rTS
XAFXAkIp4B0y8cfxofqJyDsZmil0gJraJpkz/Y0JA+jXlQ2jHlC03xoMZIn60RKn
XI91UY65PAyoQ0LROa/TRBFCLJarLFcCSeth4MhDq06f4spXYtCV9i+2HNBj
=bUJ6
-----END PGP MESSAGE-----
fp: 6F7069FE6B96E894E60EC45C6EEFA706CB17E89B
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,4 +1,7 @@
{ lib, ... }: { lib
, ...
}:
{ {
boot.loader.grub.efiSupport = lib.mkForce false; boot.loader.grub.efiSupport = lib.mkForce false;
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];

View file

@ -1,12 +1,14 @@
{ ... }: { ... }:
{ {
disabledModules = [
];
imports = [ imports = [
../../profiles/common/configuration.nix ../../profiles/common/configuration.nix
../../modules/opinionatedDisk.nix
./system.nix ./system.nix
./hw.nix ./hw.nix
./pkg.nix ./pkg.nix
./user.nix ./boot.nix
]; ];
} }

View file

@ -0,0 +1,56 @@
{ ... }:
let
stage1Modules = [
# "aesni_intel"
# "kvm-intel"
"aes_x86_64"
"virtio_balloon"
"virtio_scsi"
"virtio_net"
"virtio_pci"
"virtio_ring"
"virtio"
"scsi_mod"
"virtio_blk"
"virtio_ring"
"bochs_drm"
"ata_piix"
"pata_acpi"
"ata_generic"
];
in
{
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/354fb107-2f4a-42ad-80dd-9dddb61bfd02";
fsType = "ext4";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/993cce35-cc1f-40cc-b07a-5ea58b99fb5b";
fsType = "btrfs";
options = [ "subvol=root" ];
neededForBoot = true;
};
fileSystems."/home" = {
device = "/dev/disk/by-uuid/993cce35-cc1f-40cc-b07a-5ea58b99fb5b";
fsType = "btrfs";
options = [ "subvol=home" ];
neededForBoot = true;
};
swapDevices = [ { device = "/dev/disk/by-uuid/d16b5f4a-f38c-41c6-8aae-1625be815f9d"; } ];
boot.loader.grub = {
device = "/dev/vda";
};
boot.initrd.availableKernelModules = stage1Modules;
boot.initrd.kernelModules = stage1Modules;
boot.extraModprobeConfig = ''
'';
}

View file

@ -0,0 +1,30 @@
{ config
, pkgs
, lib
, ...
}:
{
nixpkgs.config.packageOverrides = pkgs: with pkgs; {
nixPath = (import ../../../default.nix { versionsPath = ./versions.nix; }).nixPath;
};
home-manager.users.steveej = import ../../../home-manager/configuration/text-minimal.nix {
inherit pkgs;
extraPackages = [
# required by vscode's remote-ssh plugin
pkgs.nodejs
# allow clipboard exchanges
pkgs.xsel
pkgs.xclip
];
};
nix.buildMachines = [
{ hostName = "localhost";
system = "x86_64-linux";
supportedFeatures = ["kvm" "nixos-test" "big-parallel" "benchmark"];
maxJobs = 4;
}
];
}

View file

@ -0,0 +1,104 @@
{ pkgs
, lib
, config
, ... }:
let
keys = import ../../../variables/keys.nix;
in {
# TASK: new device
networking.hostName = "sj-pvehtz-0"; # Define your hostname.
# networking.domain = "";
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [
# iperf3
5201
];
networking.firewall.logRefusedConnections = false;
networking.usePredictableInterfaceNames = false;
networking.interfaces.eth0 = {
mtu = 1400;
useDHCP = false;
ipv4.addresses = [
{ "address" = "167.233.1.14"; "prefixLength" = 29; }
];
ipv6.addresses = [
];
};
networking.defaultGateway = {
address = "167.233.1.9";
interface = "eth0";
};
networking.defaultGateway6 = {
address = "fe80::1";
interface = "eth0";
};
networking.nameservers = [
"1.1.1.1"
];
networking.nat = {
enable = true;
internalInterfaces = [ "ve-+" ];
externalInterface = "eth0";
};
# Kubernetes
# services.kubernetes.roles = ["master" "node"];
# virtualization
virtualisation = {
docker.enable = true;
};
services.spice-vdagentd.enable = true;
services.qemuGuest.enable = true;
systemd.services."sshd-status" = {
enable = true;
description = "sshd-status service";
path = [ pkgs.systemd ];
script = ''
systemctl status sshd | grep -i tasks
'';
};
systemd.services.sshd.serviceConfig = {
TasksMax = 32;
};
systemd.timers."sshd-status" = {
description = "Timer to trigger sshd-status periodically";
enable = true;
wantedBy = [ "timer.target" "multi-user.target" ];
timerConfig = {
OnActiveSec="360s";
OnUnitActiveSec="360s";
AccuracySec="1s";
Unit = "sshd-status.service";
};
};
nix.gc = {
automatic = true;
};
networking.useHostResolvConf = true;
services.openssh.forwardX11 = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "20.09"; # Did you read the comment?
}

View file

@ -0,0 +1,37 @@
let
nixpkgs = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-20.09";
rev = "51aaa3fa1b69559456f9bd4968bd5b179a784f67";
};
in
{
inherit nixpkgs;
"channels-nixos-stable" = nixpkgs;
"channels-nixos-20.03" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-20.03";
rev = "ff6fda61600cc60404bab5cb6b18b8636785b7bc";
};
"channels-nixos-19.09" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-19.09";
rev = "75f4ba05c63be3f147bcc2f7bd4ba1f029cedcb1";
};
"channels-nixos-unstable" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-unstable";
rev = "24c9b05ac53e422f1af81a156f1fd58499eb27fb";
};
"nixpkgs-master" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "master";
rev = "9b3e35d991ea6a43f256069dcb2e006006730d05";
};
"home-manager-module" = {
url = "https://github.com/nix-community/home-manager";
ref = "release-20.09";
rev = "7339784e07217ed0232e08d1ea33b610c94657d8";
};
}

View file

@ -0,0 +1,37 @@
let
nixpkgs = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-20.09";
rev = "<% git ls-remote https://github.com/nixos/nixpkgs nixos-20.09 | awk '{ print $1 }' | tr -d '\n' -%>";
};
in
{
inherit nixpkgs;
"channels-nixos-stable" = nixpkgs;
"channels-nixos-20.03" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-20.03";
rev = "<% git ls-remote https://github.com/nixos/nixpkgs nixos-20.03 | awk '{ print $1 }' | tr -d '\n' -%>";
};
"channels-nixos-19.09" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-19.09";
rev = "<% git ls-remote https://github.com/nixos/nixpkgs nixos-19.09 | awk '{ print $1 }' | tr -d '\n' -%>";
};
"channels-nixos-unstable" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "nixos-unstable";
rev = "<% git ls-remote https://github.com/nixos/nixpkgs nixos-unstable | awk '{ print $1 }' | tr -d '\n' -%>";
};
"nixpkgs-master" = {
url = "https://github.com/NixOS/nixpkgs/";
ref = "master";
rev = "<% git ls-remote https://github.com/NixOS/nixpkgs.git master | head -n1 | awk '{ print $1 }' | tr -d '\n' -%>";
};
"home-manager-module" = {
url = "https://github.com/nix-community/home-manager";
ref = "release-20.09";
rev = "<% git ls-remote https://github.com/nix-community/home-manager.git release-20.09 | awk '{ print $1 }' | tr -d '\n' -%>";
};
}

View file

@ -1,58 +1,40 @@
{ { pkgs ? import <channels-nixos-stable> {}
dir, , ownLib ? import ../lib/default.nix { }
pkgs ? import <channels-nixos-stable> { }, , dir
ownLib ? import ../lib/default.nix { inherit (pkgs) lib; }, , rebuildarg
gitRoot ? "$(git rev-parse --show-toplevel)", , moreargs ? ""
# FIXME: why do these need explicit mentioning? , diskId ? (import ((builtins.getEnv "PWD")+"/${dir}/hw.nix") {}).hardware.encryptedDisk.diskId
moreargs ? "", , gitRoot ? "$(git rev-parse --show-toplevel)"
rebuildarg ? "", , previousDiskId ? ""
... }:
}@args:
let let
rebuildargsSudo = [ rebuildargsSudo = [ "switch" "boot" ];
"switch" rebuild = pkgs.writeScript "script" ''
"boot" #!/usr/bin/env bash
]; set -xe
rebuild =
{
gitRoot,
rebuildarg ? "dry-activate",
moreargs ? "",
...
}:
pkgs.writeScript "script" ''
#!/usr/bin/env bash
set -xe
pushd ${gitRoot}/${dir} pushd ${gitRoot}/${dir}
export NIXOS_CONFIG="$PWD"/configuration.nix export NIXOS_CONFIG="$PWD"/configuration.nix
[[ -e "''${NIXOS_CONFIG}" ]] [[ -e "''${NIXOS_CONFIG}" ]]
if test -L result; then ${if (builtins.elem rebuildarg rebuildargsSudo)
rm result && builtins.match ".*--target-host.*" moreargs == null
fi then
"sudo -E \\"
${ else
if ""
(builtins.elem rebuildarg rebuildargsSudo) && (builtins.match ".*--target-host.*" moreargs) == null
then
"sudo -E \\"
else
""
}
nixos-rebuild --show-trace -I nixos-config=''${NIXOS_CONFIG} ${rebuildarg} ${moreargs}
'';
in
{
recipes = {
rebuild = rebuild {
inherit gitRoot;
inherit moreargs;
inherit rebuildarg;
} }
# // pkgs.lib.attrsets.optionalAttrs (moreargs != "") { inherit moreargs; } nixos-rebuild --show-trace -I nixos-config=''${NIXOS_CONFIG} ${rebuildarg} ${moreargs}
# // pkgs.lib.attrsets.optionalAttrs (rebuildarg != "") { inherit rebuildarg; } if test -L result; then
; rm result
} // (import ./disk.nix (args // { inherit pkgs ownLib gitRoot; })); fi
'';
in {
recipes = {
inherit rebuild;
} // (import ./disk.nix { inherit pkgs ownLib dir rebuildarg moreargs diskId gitRoot previousDiskId; });
} }

View file

@ -1,25 +1,22 @@
{ { pkgs
pkgs, , ownLib
ownLib, , dir
dir, , rebuildarg
gitRoot, , moreargs
diskId ? (import ((builtins.getEnv "PWD") + "/${dir}/hw.nix") { }).hardware.opinionatedDisk.diskId, , diskId
encrypted ? , gitRoot
(import ((builtins.getEnv "PWD") + "/${dir}/hw.nix") { }).hardware.opinionatedDisk.encrypted, , previousDiskId ? ""
previousDiskId ? "",
...
}: }:
let let
mntRootVol = "/mnt/${diskId}-root"; mntRootVol="/mnt/${diskId}-root";
in
rec { in rec {
diskMount = pkgs.writeScript "script" '' diskMount = pkgs.writeScript "script" ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -xe set -xe
echo Mounting ${diskId} echo Mounting ${diskId}
${pkgs.lib.strings.optionalString encrypted '' sudo cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
sudo cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
''}
sleep 1 sleep 1
sudo vgchange -ay ${ownLib.disk.volumeGroup diskId} sudo vgchange -ay ${ownLib.disk.volumeGroup diskId}
sudo mkdir -p /mnt sudo mkdir -p /mnt
@ -35,9 +32,7 @@ rec {
sudo umount -Rl ${mntRootVol} sudo umount -Rl ${mntRootVol}
sudo rmdir ${mntRootVol} sudo rmdir ${mntRootVol}
sudo vgchange -an ${ownLib.disk.volumeGroup diskId} sudo vgchange -an ${ownLib.disk.volumeGroup diskId}
${pkgs.lib.strings.optionalString encrypted '' sudo cryptsetup close ${ownLib.disk.luksName diskId}
sudo cryptsetup close ${ownLib.disk.luksName diskId}
''}
sync sync
''; '';
@ -50,10 +45,9 @@ rec {
[[ -e "''${NIXOS_CONFIG}" ]] [[ -e "''${NIXOS_CONFIG}" ]]
[[ -e "${mntRootVol}/nixos" ]] [[ -e "${mntRootVol}/nixos" ]]
sudo --preserve-env=PATH -E $SHELL <<EOF sudo -E $SHELL <<EOF
# 'having $system set breaks nixos-install' # 'having $system set breaks nixos-install'
unset system unset system
echo $NIX_PATH
nixos-install --max-jobs 5 --cores 4 --no-root-passwd --root ${mntRootVol}/nixos nixos-install --max-jobs 5 --cores 4 --no-root-passwd --root ${mntRootVol}/nixos
EOF EOF
''; '';
@ -62,7 +56,7 @@ rec {
#!/usr/bin/env bash #!/usr/bin/env bash
set -xe set -xe
read -p "Continue to format ${ownLib.disk.bootGrubDevice diskId} (YES/n)? " choice read -p "Continue to format ${ownLib.disk.bootGrubDevice diskId} (YES/n)?" choice
case "$choice" in case "$choice" in
YES ) echo "Continuing in 3 seconds..."; sleep 3;; YES ) echo "Continuing in 3 seconds..."; sleep 3;;
n|N ) echo "Exiting..."; exit 0;; n|N ) echo "Exiting..."; exit 0;;
@ -76,16 +70,16 @@ rec {
g g
n n
1 1
+1M +1M
n n
2 2
+512M +512M
n n
3 3
t t
1 1
4 4
@ -106,14 +100,12 @@ rec {
sleep 1 sleep 1
${pkgs.lib.strings.optionalString encrypted '' # Encrypt
# Encrypt sudo cryptsetup luksFormat ${ownLib.disk.bootLuksDevice diskId} -
sudo cryptsetup luksFormat ${ownLib.disk.bootLuksDevice diskId} - sudo cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
sudo cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
''}
# LVM # LVM
sudo vgcreate ${ownLib.disk.volumeGroup diskId} ${ownLib.disk.lvmPv diskId encrypted} sudo vgcreate ${ownLib.disk.volumeGroup diskId} ${ownLib.disk.luksPhysicalVolume diskId}
sudo lvcreate ${ownLib.disk.volumeGroup diskId} -L 2G -n swap sudo lvcreate ${ownLib.disk.volumeGroup diskId} -L 2G -n swap
sudo lvcreate ${ownLib.disk.volumeGroup diskId} -l 100%FREE -n root sudo lvcreate ${ownLib.disk.volumeGroup diskId} -l 100%FREE -n root
@ -128,7 +120,7 @@ rec {
sudo mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol} sudo mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol}
sudo btrfs subvolume create ${mntRootVol}/nixos sudo btrfs subvolume create ${mntRootVol}/nixos
sudo btrfs subvolume create ${mntRootVol}/home sudo btrfs subvolume create ${mntRootVol}/home
sudo mkdir ${mntRootVol}/nixos/{boot,home,tmp} sudo mkdir ${mntRootVol}/nixos/{boot,home}
${diskUmount} ${diskUmount}
''; '';
@ -168,9 +160,7 @@ rec {
if test "${previousDiskId}"; then if test "${previousDiskId}"; then
${pkgs.lib.strings.optionalString encrypted '' sudo cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
sudo cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
''}
sync sync
sleep 1 sleep 1
if sudo vgs ${previousDiskId}; then if sudo vgs ${previousDiskId}; then
@ -178,8 +168,6 @@ rec {
sudo vgscan sudo vgscan
fi fi
fi fi
${pkgs.lib.strings.optionalString encrypted '' sudo cryptsetup close ${ownLib.disk.luksName diskId}
sudo cryptsetup close ${ownLib.disk.luksName diskId}
''}
''; '';
} }

View file

@ -1,5 +0,0 @@
{ lib, ... }:
{
boot.loader.grub.efiSupport = lib.mkForce false;
boot.loader.efi.canTouchEfiVariables = lib.mkForce false;
}

View file

@ -1,29 +0,0 @@
{
nodeName,
repoFlake,
nodeFlake,
...
}:
let
system = "x86_64-linux";
in
{
meta.nodeSpecialArgs.${nodeName} = {
inherit repoFlake nodeName nodeFlake;
packages' = repoFlake.packages.${system};
};
meta.nodeNixpkgs.${nodeName} = import nodeFlake.inputs.nixpkgs.outPath { inherit system; };
${nodeName} = {
deployment.targetHost = "elias-e525";
deployment.replaceUnknownProfiles = true;
# deployment.allowLocalDeployment = true;
imports = [
nodeFlake.inputs.home-manager.nixosModules.home-manager
./configuration.nix
];
};
}

View file

@ -1,52 +0,0 @@
{
"nodes": {
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1748665073,
"narHash": "sha256-RMhjnPKWtCoIIHiuR9QKD7xfsKb3agxzMfJY8V9MOew=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "282e1e029cb6ab4811114fc85110613d72771dea",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.05",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1749024892,
"narHash": "sha256-OGcDEz60TXQC+gVz5sdtgGJdKVYr6rwdzQKuZAJQpCA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "8f1b52b04f2cb6e5ead50bd28d76528a2f0380ef",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs-stable"
],
"nixpkgs-stable": "nixpkgs-stable"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,11 +0,0 @@
{
inputs.nixpkgs.follows = "nixpkgs-stable";
inputs.nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05";
inputs.home-manager = {
url = "github:nix-community/home-manager/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
outputs = _: { };
}

View file

@ -1,11 +0,0 @@
_: {
# TASK: new device
hardware.opinionatedDisk = {
enable = true;
encrypted = false;
diskId = "ata-KINGSTON_SV100S2128G_08BAB0020855";
};
# boot.initrd.availableKernelModules = stage1Modules;
boot.extraModprobeConfig = "";
}

View file

@ -1,47 +0,0 @@
{ pkgs, lib, ... }:
let
homeEnv = keyboard: {
imports = [
../../../home-manager/profiles/common.nix
../../../home-manager/configuration/graphical-gnome3.nix
../../../home-manager/programs/firefox.nix
../../../home-manager/programs/libreoffice.nix
../../../home-manager/programs/neovim.nix
];
home.keyboard = keyboard;
home.packages = with pkgs; [
dia
rustdesk
];
};
in
{
services.gnome = builtins.mapAttrs (_attr: value: lib.mkForce value) {
gnome-remote-desktop.enable = true;
};
home-manager.users.steveej = homeEnv {
layout = "en";
options = [ "nodeadkey" ];
variant = "altgr-intl";
};
home-manager.users.elias = homeEnv {
layout = "de";
options = [ ];
variant = "";
};
home-manager.users.justyna = homeEnv {
layout = "de";
options = [ ];
variant = "";
};
system.stateVersion = "21.11";
}

View file

@ -1,47 +0,0 @@
{ pkgs, lib, ... }:
{
# TASK: new device
networking.hostName = "elias-e525"; # Define your hostname.
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [
# iperf3
5201
];
networking.firewall.logRefusedConnections = false;
networking.usePredictableInterfaceNames = false;
services.fprintd.enable = true;
security.pam.services = {
# conflicts with nixpkgs' gdm.nix
# login.fprintAuth = true;
sudo.fprintAuth = true;
};
services = {
xserver = {
xkb.layout = lib.mkForce "de";
xkb.variant = lib.mkForce "";
xkb.options = lib.mkForce "";
displayManager.gdm.enable = lib.mkForce true;
displayManager.lightdm.enable = lib.mkForce false;
desktopManager.gnome.enable = true;
};
displayManager.autoLogin.enable = lib.mkForce false;
# dbus.packages = [ pkgs.gnome3.dconf ];
# udev.packages = [ pkgs.gnome3.gnome-settings-daemon ];
};
security.pki.certificateFiles = [ "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ];
services.xserver.videoDrivers = [ "modesetting" ];
# boot.kernelPackages = lib.mkForce pkgs.linuxPackages_latest;
nix.gc = {
automatic = true;
};
}

View file

@ -1,36 +0,0 @@
{ config, lib, ... }:
let
keys = import ../../../variables/keys.nix;
inherit (import ../../lib/default.nix { inherit lib config; }) mkUser deepMergeAttrsets;
in
deepMergeAttrsets [
{
sops.secrets.sharedUsers-elias = {
sopsFile = ../../../../secrets/shared-users.yaml;
neededForUsers = true;
format = "yaml";
};
sops.secrets.sharedUsers-justyna = {
sopsFile = ../../../../secrets/shared-users.yaml;
neededForUsers = true;
format = "yaml";
};
}
(mkUser {
username = "elias";
uid = 1001;
openssh.authorizedKeys.keys = keys.users.steveej.openssh;
hashedPasswordFile = config.sops.secrets.sharedUsers-elias.path;
})
(mkUser {
username = "justyna";
uid = 1002;
openssh.authorizedKeys.keys = keys.users.steveej.openssh;
hashedPasswordFile = config.sops.secrets.sharedUsers-justyna.path;
})
]

View file

@ -1,5 +0,0 @@
{ lib, ... }:
{
boot.loader.grub.efiInstallAsRemovable = lib.mkForce true;
boot.loader.efi.canTouchEfiVariables = lib.mkForce false;
}

View file

@ -1,11 +0,0 @@
_: {
# TASK: new device
hardware.opinionatedDisk = {
enable = true;
encrypted = false;
diskId = "ata-INTEL_SSDSC2BW240A4_PHDA435602332403GN";
};
hardware.enableRedistributableFirmware = true;
boot.extraModprobeConfig = "";
}

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