Compare commits
337 commits
Author | SHA1 | Date | |
---|---|---|---|
Natsu Kagami | baa3d1cd0d | ||
Natsu Kagami | cd4a9807cb | ||
Natsu Kagami | f98b48a5e3 | ||
Natsu Kagami | fc57e77340 | ||
Natsu Kagami | dc49540f8d | ||
Natsu Kagami | c36f5f66b1 | ||
Natsu Kagami | 8702656b24 | ||
Natsu Kagami | 02ea7e95b7 | ||
Natsu Kagami | 22d1dbebe6 | ||
Natsu Kagami | c14aab4a8f | ||
Natsu Kagami | d99d57f53e | ||
Natsu Kagami | 267f135972 | ||
Natsu Kagami | 600ba660c9 | ||
Natsu Kagami | 55397974b4 | ||
Natsu Kagami | 2f7179e7d5 | ||
Natsu Kagami | 2c54a0a9a1 | ||
Natsu Kagami | 21947fd510 | ||
Natsu Kagami | 097a0efd90 | ||
Natsu Kagami | 5cc543c9db | ||
Natsu Kagami | 6a1deaae36 | ||
Natsu Kagami | 5af862a4ad | ||
Natsu Kagami | a1bd5600a9 | ||
Natsu Kagami | a59fa31628 | ||
Natsu Kagami | 81b549a670 | ||
Natsu Kagami | 17e66e339c | ||
Natsu Kagami | 63c2616c0f | ||
Natsu Kagami | bc5de8bc77 | ||
Natsu Kagami | 177f0f686e | ||
Natsu Kagami | 4fe33b7e80 | ||
Natsu Kagami | 5ecad94dcb | ||
Natsu Kagami | 84fa06937c | ||
Natsu Kagami | 08d0c7aea3 | ||
Natsu Kagami | 5b85a94be7 | ||
Natsu Kagami | 40d325218f | ||
Natsu Kagami | db7e115863 | ||
Natsu Kagami | 59f9ae8d5b | ||
Natsu Kagami | fbe19bac34 | ||
Natsu Kagami | bc4cfe7c69 | ||
Natsu Kagami | 70ab3aa5b3 | ||
Natsu Kagami | 41f717c5be | ||
Natsu Kagami | 9fecd353f8 | ||
Natsu Kagami | f0807443fd | ||
Natsu Kagami | b1db7229cd | ||
Natsu Kagami | f4c514baa6 | ||
Natsu Kagami | 58a49a71a8 | ||
Natsu Kagami | e8424a0d21 | ||
Natsu Kagami | 81d3c1dcd1 | ||
Natsu Kagami | 08111c8f13 | ||
Natsu Kagami | 5d2f127bcc | ||
Natsu Kagami | a490d5a5ef | ||
Natsu Kagami | a5df4c0b58 | ||
Natsu Kagami | 73d9b5fb4e | ||
Natsu Kagami | e772814eed | ||
Natsu Kagami | 7b53f1d945 | ||
Natsu Kagami | 167d1dddb8 | ||
Natsu Kagami | 472daa8e59 | ||
Natsu Kagami | d18a5ca503 | ||
Natsu Kagami | f164a27290 | ||
Natsu Kagami | 0887487c29 | ||
Natsu Kagami | 0b2e4feebb | ||
Natsu Kagami | 8ec79eac11 | ||
Natsu Kagami | 07478138d9 | ||
Natsu Kagami | 45e90570b7 | ||
Natsu Kagami | 28080d31c0 | ||
Natsu Kagami | e82627e317 | ||
Natsu Kagami | 228db93202 | ||
Natsu Kagami | fec7f40440 | ||
Natsu Kagami | 38c7afa96f | ||
Natsu Kagami | 581093ff78 | ||
Natsu Kagami | 9a11fd1b38 | ||
Natsu Kagami | 530a746260 | ||
Natsu Kagami | 8bd64fbe79 | ||
Natsu Kagami | 0f2686f9a7 | ||
Natsu Kagami | af7e118298 | ||
Natsu Kagami | 7018b23522 | ||
Natsu Kagami | bd2af0670d | ||
Natsu Kagami | a3d59d71ec | ||
Natsu Kagami | 58b72cbb8c | ||
Natsu Kagami | c488e5e05d | ||
Natsu Kagami | 59c25c883a | ||
Natsu Kagami | 567542d665 | ||
Natsu Kagami | 30ba277d46 | ||
Natsu Kagami | 2657e7f3fc | ||
Natsu Kagami | 527c6ba4e5 | ||
Natsu Kagami | 3b9f2d3dec | ||
Natsu Kagami | 7f1f963d5e | ||
Natsu Kagami | 9c64c4dca9 | ||
Natsu Kagami | c397c143e1 | ||
Natsu Kagami | 27e1fcf99b | ||
Natsu Kagami | edf38dc4e1 | ||
Natsu Kagami | 3affdb3174 | ||
Natsu Kagami | 41106623e8 | ||
Natsu Kagami | 47b96aee71 | ||
Natsu Kagami | 5426a7c526 | ||
Natsu Kagami | c16efcf256 | ||
Natsu Kagami | c59b47c1ce | ||
Natsu Kagami | ea7e32973a | ||
Natsu Kagami | 99b653229e | ||
Natsu Kagami | 5f61631957 | ||
Natsu Kagami | 54264260ed | ||
Natsu Kagami | 15a74c324f | ||
Natsu Kagami | e7be048163 | ||
Natsu Kagami | 3bae764ff5 | ||
Natsu Kagami | f323e92b48 | ||
Natsu Kagami | 506bcfb5e3 | ||
Natsu Kagami | 690f939c71 | ||
Natsu Kagami | 1c87a689e6 | ||
Natsu Kagami | 69200a098f | ||
Natsu Kagami | 89fa620591 | ||
Natsu Kagami | 40bc313429 | ||
Natsu Kagami | f2dfe30ff3 | ||
Natsu Kagami | 0d4bf856c3 | ||
Natsu Kagami | 5acc4d91a0 | ||
Natsu Kagami | 6e88c391f9 | ||
Natsu Kagami | 2326c903c0 | ||
Natsu Kagami | cc7d62745c | ||
Natsu Kagami | 23c2436ab6 | ||
Natsu Kagami | cbb496cb47 | ||
Natsu Kagami | c02946aba3 | ||
Natsu Kagami | d0943fd8b4 | ||
Natsu Kagami | 7a3f3e1b8c | ||
Natsu Kagami | a42ca31aed | ||
Natsu Kagami | f4c8297a55 | ||
Natsu Kagami | c7cdc4ff5e | ||
Natsu Kagami | 97a162786f | ||
Natsu Kagami | a6b28f8c05 | ||
Natsu Kagami | 37a712e117 | ||
Natsu Kagami | b46da01895 | ||
Natsu Kagami | 3be0332f7c | ||
Natsu Kagami | 989c7e64c6 | ||
Natsu Kagami | 0efe7f556a | ||
Natsu Kagami | 1f14b6b02a | ||
Natsu Kagami | aa3524840c | ||
Natsu Kagami | fc9898a5ec | ||
Natsu Kagami | 9f9c76d0d2 | ||
Natsu Kagami | 5d5609e5a9 | ||
Natsu Kagami | 2bbbf47ce2 | ||
Natsu Kagami | 3b78843f34 | ||
Natsu Kagami | 7d8d80c6a3 | ||
Natsu Kagami | 3ebdd014b8 | ||
Natsu Kagami | b1316346b9 | ||
Natsu Kagami | 37d8642ed9 | ||
Natsu Kagami | 74ad74af1f | ||
Natsu Kagami | db64c71a2a | ||
Natsu Kagami | f6044a11ba | ||
Natsu Kagami | 2fe1f71699 | ||
Natsu Kagami | eed4c25127 | ||
Natsu Kagami | 4ab9afd9c3 | ||
Natsu Kagami | 445c3fcc4c | ||
Natsu Kagami | 8eca740ad3 | ||
Natsu Kagami | 666478ad36 | ||
Natsu Kagami | 381520a013 | ||
Natsu Kagami | 07179e77e8 | ||
Natsu Kagami | 5681d080e5 | ||
Natsu Kagami | fff8f3042a | ||
Natsu Kagami | 1cba13a2e8 | ||
Natsu Kagami | 7d19c95472 | ||
Natsu Kagami | ef5af56cb6 | ||
Natsu Kagami | 08a7b1edb7 | ||
Natsu Kagami | 1624eacdf0 | ||
Natsu Kagami | 51f06ac76c | ||
Natsu Kagami | 6ae7ccf045 | ||
Natsu Kagami | c9a33982de | ||
Natsu Kagami | 9d0116cc7d | ||
Natsu Kagami | 5c9cde7f87 | ||
Natsu Kagami | 5e8f6081f0 | ||
Natsu Kagami | feb61f5f41 | ||
Natsu Kagami | e17341a42f | ||
Natsu Kagami | c7cc8f9516 | ||
Natsu Kagami | c0dca78a74 | ||
Natsu Kagami | dd3063e6f1 | ||
Natsu Kagami | b2263d1fe5 | ||
Natsu Kagami | 98d935e2d5 | ||
Natsu Kagami | ee6bf03506 | ||
Natsu Kagami | 580601ddd5 | ||
Natsu Kagami | e9e5a00308 | ||
Natsu Kagami | 9d924cc9a9 | ||
Natsu Kagami | 8e3f767dd9 | ||
Natsu Kagami | fbcc19fc97 | ||
Natsu Kagami | 3e3a433bca | ||
Natsu Kagami | 94ce7860bb | ||
Natsu Kagami | c834fd0ef7 | ||
Natsu Kagami | ea5aacd63d | ||
Natsu Kagami | 244cecb3ba | ||
Natsu Kagami | fb1652d82b | ||
Natsu Kagami | 91603a500d | ||
Natsu Kagami | 526ed059db | ||
Natsu Kagami | 99e7ec3143 | ||
Natsu Kagami | c74fe98853 | ||
Natsu Kagami | 6f2dc57089 | ||
Natsu Kagami | d9db52e92a | ||
Natsu Kagami | 9ac5fedc75 | ||
Natsu Kagami | 53dec713ec | ||
Natsu Kagami | 908f74f121 | ||
Natsu Kagami | 9c376e38bc | ||
Natsu Kagami | be5237eeeb | ||
Natsu Kagami | 662be5e96d | ||
Natsu Kagami | ef304742ce | ||
Natsu Kagami | a688ce8cef | ||
Natsu Kagami | 36eebe0174 | ||
Natsu Kagami | b6b12df069 | ||
Natsu Kagami | 45a27e64bc | ||
Natsu Kagami | 857b7fc98a | ||
Natsu Kagami | 7285080198 | ||
Natsu Kagami | 483c34e501 | ||
Natsu Kagami | b836868109 | ||
Natsu Kagami | 641fc6a51c | ||
Natsu Kagami | 9319833752 | ||
Natsu Kagami | ed5245630f | ||
Natsu Kagami | 9d01f43bb0 | ||
Natsu Kagami | edeca6408b | ||
Natsu Kagami | 0fc02235e1 | ||
Natsu Kagami | 3ccaa71de6 | ||
Natsu Kagami | d1a37d19d7 | ||
Natsu Kagami | eafa4af3cf | ||
Natsu Kagami | 5f5b966c76 | ||
Natsu Kagami | 70107fbe4d | ||
Natsu Kagami | a722647f27 | ||
Natsu Kagami | 9a51746ac2 | ||
Natsu Kagami | 151f5838b2 | ||
Natsu Kagami | 6a35224cd8 | ||
Natsu Kagami | 052f372f67 | ||
Natsu Kagami | 1247233c36 | ||
Natsu Kagami | 16f735f25b | ||
Natsu Kagami | 20c30726bb | ||
Natsu Kagami | c64a76b6b3 | ||
Natsu Kagami | 65aca5a3f5 | ||
Natsu Kagami | 91f4e896a5 | ||
Natsu Kagami | 2d3ebab8dd | ||
Natsu Kagami | 2bbe9db98b | ||
Natsu Kagami | db3c1acb2c | ||
Natsu Kagami | 224974dd77 | ||
Natsu Kagami | d90650116e | ||
Natsu Kagami | 0c8a5e1368 | ||
Natsu Kagami | 77baad5311 | ||
Natsu Kagami | c1badc0580 | ||
Natsu Kagami | efdad6975d | ||
Natsu Kagami | 23d22a3171 | ||
Natsu Kagami | cf2d7b0271 | ||
Natsu Kagami | f4e00a834b | ||
Natsu Kagami | aa7f5ba285 | ||
Natsu Kagami | 2888c0a300 | ||
Natsu Kagami | cec9dd4d85 | ||
Natsu Kagami | ea8a3fd15a | ||
Natsu Kagami | 955e63b1e8 | ||
Natsu Kagami | 6c302bf948 | ||
Natsu Kagami | d6c218859c | ||
Natsu Kagami | 9879ab0048 | ||
Natsu Kagami | 65686fdf16 | ||
Natsu Kagami | dccc3802d7 | ||
Natsu Kagami | 43e97d65c4 | ||
Natsu Kagami | 3cd23cce00 | ||
Natsu Kagami | 97c065231b | ||
Natsu Kagami | 9c2dfd483b | ||
Natsu Kagami | 38390db87c | ||
Natsu Kagami | 1f38c3c29f | ||
Natsu Kagami | 5cf73ba503 | ||
Natsu Kagami | bc0cea6575 | ||
Natsu Kagami | 08792154ed | ||
Natsu Kagami | ec89cef3a2 | ||
Natsu Kagami | 62c14ffd0d | ||
Natsu Kagami | 25ab9e9b70 | ||
Natsu Kagami | 099b6ffa28 | ||
Natsu Kagami | df3b2e7b00 | ||
Natsu Kagami | 0c0b3fb83d | ||
Natsu Kagami | 8f82978e8d | ||
Natsu Kagami | b79855b9b9 | ||
Natsu Kagami | ae97651a64 | ||
Natsu Kagami | cfce2aaecb | ||
Natsu Kagami | 6109922b19 | ||
Natsu Kagami | d4b9c4edfc | ||
Natsu Kagami | 308e4412ad | ||
Natsu Kagami | 49a4c49e08 | ||
Natsu Kagami | d1ce95aa08 | ||
Natsu Kagami | 4c491f359c | ||
Natsu Kagami | 61c02e0a02 | ||
Natsu Kagami | 91a5ee5df5 | ||
Natsu Kagami | adf3aeadfa | ||
Natsu Kagami | ef1c71b462 | ||
Natsu Kagami | c89832abab | ||
Natsu Kagami | 3e40481ddd | ||
Natsu Kagami | 44305d6805 | ||
Natsu Kagami | 2d726f8c04 | ||
Natsu Kagami | 32c9474e7e | ||
Natsu Kagami | fb9d120c37 | ||
Natsu Kagami | 058e62f921 | ||
Natsu Kagami | ea0180e420 | ||
Natsu Kagami | f0a983c52d | ||
Natsu Kagami | 58034eb5b0 | ||
Natsu Kagami | 947be2b7c7 | ||
Natsu Kagami | 31c59ca13d | ||
Natsu Kagami | dd88bf11c8 | ||
Natsu Kagami | 01903f3547 | ||
Natsu Kagami | 1e822b9fe9 | ||
Natsu Kagami | 35d27c09c2 | ||
Natsu Kagami | f96e48e3b4 | ||
Natsu Kagami | feca54585c | ||
Natsu Kagami | cedbbeafb5 | ||
Natsu Kagami | a7104c6197 | ||
Natsu Kagami | 066344ec2f | ||
Natsu Kagami | 0ce6c530cd | ||
Natsu Kagami | 7f0d5b0da1 | ||
Natsu Kagami | c6518aae2f | ||
Natsu Kagami | 37b780ba72 | ||
Natsu Kagami | 4f32f04d6b | ||
Natsu Kagami | a268436f68 | ||
Natsu Kagami | 536eec198a | ||
Natsu Kagami | 93d9e820db | ||
Natsu Kagami | 237e6afa33 | ||
Natsu Kagami | 33cf7ed435 | ||
Natsu Kagami | caf6677f71 | ||
Natsu Kagami | 7a100e241b | ||
Natsu Kagami | fde3ba411d | ||
Natsu Kagami | 2693126dca | ||
Natsu Kagami | 7d71caa8db | ||
Natsu Kagami | 1f10e0e943 | ||
Natsu Kagami | 0233a84edc | ||
Natsu Kagami | f155382789 | ||
Natsu Kagami | cfc752a3db | ||
Natsu Kagami | b33f843d42 | ||
Natsu Kagami | 43bcb4721b | ||
Natsu Kagami | 92cc5096cb | ||
Natsu Kagami | d89a084d56 | ||
Natsu Kagami | a32c24a376 | ||
Natsu Kagami | b173c6a874 | ||
Natsu Kagami | c92779eb96 | ||
Natsu Kagami | 3fe1a12813 | ||
Natsu Kagami | 54c30642bc | ||
Natsu Kagami | 872528ed1f | ||
Natsu Kagami | 5d2ea18b48 | ||
Natsu Kagami | 8a430a1399 | ||
Natsu Kagami | 6a67d1b8ae | ||
Natsu Kagami | 9a84dde328 | ||
Natsu Kagami | a9bba20428 | ||
Natsu Kagami | a7cf162fe3 | ||
Natsu Kagami | 6e11b80b40 | ||
Natsu Kagami | 69af06d78a |
144
.github/workflows/deploy.yml
vendored
144
.github/workflows/deploy.yml
vendored
|
@ -32,76 +32,76 @@ jobs:
|
||||||
git status
|
git status
|
||||||
false
|
false
|
||||||
fi
|
fi
|
||||||
deploy:
|
# deploy:
|
||||||
if: "github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Deploy')"
|
# if: "github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Deploy')"
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
name: Deploy
|
# name: Deploy
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v2.3.4
|
# - uses: actions/checkout@v2.3.4
|
||||||
- name: Notify deployment starting
|
# - name: Notify deployment starting
|
||||||
run: |
|
# run: |
|
||||||
git show --no-patch | curl \
|
# git show --no-patch | curl \
|
||||||
--fail-with-body \
|
# --fail-with-body \
|
||||||
-u "${{ secrets.NTFY_CREDS }}" \
|
# -u "${{ secrets.NTFY_CREDS }}" \
|
||||||
-H "X-Title: Deployment to nki-personal-do started" \
|
# -H "X-Title: Deployment to nki-personal-do started" \
|
||||||
-H "X-Priority: 1" \
|
# -H "X-Priority: 1" \
|
||||||
-H "X-Tags: cloud" \
|
# -H "X-Tags: cloud" \
|
||||||
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||||
-d "Commit info:
|
# -d "Commit info:
|
||||||
" \
|
# " \
|
||||||
-d @- \
|
# -d @- \
|
||||||
https://ntfy.nkagami.me/nki-personal-do
|
# https://ntfy.nkagami.me/nki-personal-do
|
||||||
- name: Add SSH key
|
# - name: Add SSH key
|
||||||
env:
|
# env:
|
||||||
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
run: |
|
# run: |
|
||||||
mkdir -p /home/runner/.ssh
|
# mkdir -p /home/runner/.ssh
|
||||||
echo "${{ secrets.NIX_SECRETS_SSH_KEY }}" > /home/runner/.ssh/nix_secrets_key
|
# echo "${{ secrets.NIX_SECRETS_SSH_KEY }}" > /home/runner/.ssh/nix_secrets_key
|
||||||
echo "${{ secrets.NIX_DEPLOY_SSH_KEY }}" > /home/runner/.ssh/nix_deploy_key
|
# echo "${{ secrets.NIX_DEPLOY_SSH_KEY }}" > /home/runner/.ssh/nix_deploy_key
|
||||||
chmod 600 /home/runner/.ssh/*
|
# chmod 600 /home/runner/.ssh/*
|
||||||
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
# ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
||||||
ssh-add /home/runner/.ssh/*
|
# ssh-add /home/runner/.ssh/*
|
||||||
ssh-keyscan ${{ secrets.INSTANCE_IP }} >> /home/runner/.ssh/known_hosts
|
# ssh-keyscan ${{ secrets.INSTANCE_IP }} >> /home/runner/.ssh/known_hosts
|
||||||
ssh-keyscan git.dtth.ch >> /home/runner/.ssh/known_hosts
|
# ssh-keyscan git.dtth.ch >> /home/runner/.ssh/known_hosts
|
||||||
- uses: cachix/install-nix-action@v20
|
# - uses: cachix/install-nix-action@v20
|
||||||
with:
|
# with:
|
||||||
extra_nix_config: |
|
# extra_nix_config: |
|
||||||
# Enable flakes
|
# # Enable flakes
|
||||||
experimental-features = nix-command flakes
|
# experimental-features = nix-command flakes
|
||||||
# Deploy tokens
|
# # Deploy tokens
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
# access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
# Import my substituters
|
# # Import my substituters
|
||||||
extra-substituters = https://natsukagami.cachix.org
|
# extra-substituters = https://natsukagami.cachix.org
|
||||||
extra-trusted-public-keys = natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ=
|
# extra-trusted-public-keys = natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ=
|
||||||
- name: Deploy with deploy-rs
|
# - name: Deploy with deploy-rs
|
||||||
env:
|
# env:
|
||||||
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
run: |
|
# run: |
|
||||||
nix run .#deploy-rs -- . --hostname ${{ secrets.INSTANCE_IP }} -s -- -L
|
# nix run .#deploy-rs -- . --hostname ${{ secrets.INSTANCE_IP }} -s -- -L
|
||||||
- name: Notify deployment succeeding
|
# - name: Notify deployment succeeding
|
||||||
run: |
|
# run: |
|
||||||
git show --no-patch | curl \
|
# git show --no-patch | curl \
|
||||||
--fail-with-body \
|
# --fail-with-body \
|
||||||
-u "${{ secrets.NTFY_CREDS }}" \
|
# -u "${{ secrets.NTFY_CREDS }}" \
|
||||||
-H "X-Title: Deployment to nki-personal-do succeeded" \
|
# -H "X-Title: Deployment to nki-personal-do succeeded" \
|
||||||
-H "X-Tags: tada,cloud" \
|
# -H "X-Tags: tada,cloud" \
|
||||||
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||||
-d "Commit info:
|
# -d "Commit info:
|
||||||
" \
|
# " \
|
||||||
-d @- \
|
# -d @- \
|
||||||
https://ntfy.nkagami.me/nki-personal-do
|
# https://ntfy.nkagami.me/nki-personal-do
|
||||||
- name: Notify deployment failing
|
# - name: Notify deployment failing
|
||||||
if: ${{ failure() }}
|
# if: ${{ failure() }}
|
||||||
run: |
|
# run: |
|
||||||
git show --no-patch | curl \
|
# git show --no-patch | curl \
|
||||||
--fail-with-body \
|
# --fail-with-body \
|
||||||
-u "${{ secrets.NTFY_CREDS }}" \
|
# -u "${{ secrets.NTFY_CREDS }}" \
|
||||||
-H "X-Title: Deployment to nki-personal-do failed" \
|
# -H "X-Title: Deployment to nki-personal-do failed" \
|
||||||
-H "X-Priority: 4" \
|
# -H "X-Priority: 4" \
|
||||||
-H "X-Tags: warning,cloud" \
|
# -H "X-Tags: warning,cloud" \
|
||||||
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||||
-d "Commit info:
|
# -d "Commit info:
|
||||||
" \
|
# " \
|
||||||
-d @- \
|
# -d @- \
|
||||||
https://ntfy.nkagami.me/nki-personal-do
|
# https://ntfy.nkagami.me/nki-personal-do
|
||||||
|
|
||||||
|
|
15
.sops.yaml
15
.sops.yaml
|
@ -4,6 +4,8 @@ keys:
|
||||||
- &nki_pc age1tt0peqg8zdfh74m5sdgwsczcqh036nhgmwvkqnvywll88uvmm9xs433rhm
|
- &nki_pc age1tt0peqg8zdfh74m5sdgwsczcqh036nhgmwvkqnvywll88uvmm9xs433rhm
|
||||||
- &nkagami_main age1n8tnmmgredzltzwkspag7aufhrn6034ny8ysjeulhkwdnf7vqqaqec4mg5
|
- &nkagami_main age1n8tnmmgredzltzwkspag7aufhrn6034ny8ysjeulhkwdnf7vqqaqec4mg5
|
||||||
- &nkagami_do age1z2h24mjt80fryqupajkh3kg5r4sjgw65uqy489xeqxhqj8u2a9fsm3ff36
|
- &nkagami_do age1z2h24mjt80fryqupajkh3kg5r4sjgw65uqy489xeqxhqj8u2a9fsm3ff36
|
||||||
|
- &nki_yoga age1vhjhmxura35apu5zdwg5ur5r40xay45ld9szh07dy0ph9chgsu7shfm4h9
|
||||||
|
- &nki_framework age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: kagami-air-m1/secrets\.yaml$
|
- path_regex: kagami-air-m1/secrets\.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
|
@ -16,9 +18,20 @@ creation_rules:
|
||||||
- *nki_pc
|
- *nki_pc
|
||||||
- *nkagami_main
|
- *nkagami_main
|
||||||
- *nkagami_do
|
- *nkagami_do
|
||||||
- path_regex: nki-home/secrets/secrets\.yaml$
|
- *nki_framework
|
||||||
|
- path_regex: nki-home/secrets\.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *nki_pc
|
- *nki_pc
|
||||||
- *nkagami_main
|
- *nkagami_main
|
||||||
- *nkagami_do
|
- *nkagami_do
|
||||||
|
- path_regex: nki-yoga-g8/secrets\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *nki_yoga
|
||||||
|
- age1axvjllyv2gutngwmp3pvp4xtq2gqneldaq2c4nrzmaye0uwmk9lqsealdv # The machine itself
|
||||||
|
- path_regex: nki-framework/secrets\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *nki_framework
|
||||||
|
- age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27 # The machine itself
|
||||||
|
|
|
@ -12,7 +12,9 @@ in
|
||||||
{ lib, pkgs, config, ... }:
|
{ lib, pkgs, config, ... }:
|
||||||
with lib; {
|
with lib; {
|
||||||
imports = [
|
imports = [
|
||||||
defaultShell
|
# defaultShell
|
||||||
|
./modules/services/nix-cache
|
||||||
|
./modules/services/nix-build-farm
|
||||||
];
|
];
|
||||||
|
|
||||||
## Packages
|
## Packages
|
||||||
|
|
920
flake.lock
920
flake.lock
File diff suppressed because it is too large
Load diff
177
flake.nix
177
flake.nix
|
@ -2,17 +2,19 @@
|
||||||
description = "nki's systems";
|
description = "nki's systems";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
|
||||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
nixos-hardware.url = "github:nixos/nixos-hardware";
|
||||||
darwin.url = "github:lnl7/nix-darwin/master";
|
darwin.url = "github:lnl7/nix-darwin/master";
|
||||||
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
home-manager.url = "github:nix-community/home-manager/release-23.05";
|
home-manager.url = "github:nix-community/home-manager/release-24.05";
|
||||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
home-manager-unstable.url = "github:nix-community/home-manager";
|
||||||
|
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
sops-nix.url = "github:Mic92/sops-nix";
|
sops-nix.url = "github:Mic92/sops-nix";
|
||||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
|
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
|
||||||
deploy-rs.url = "github:Serokell/deploy-rs";
|
deploy-rs.url = "github:Serokell/deploy-rs";
|
||||||
nur.url = "github:nix-community/NUR";
|
|
||||||
|
|
||||||
# --- Secure boot
|
# --- Secure boot
|
||||||
lanzaboote = {
|
lanzaboote = {
|
||||||
|
@ -23,33 +25,35 @@
|
||||||
# --- Build tools
|
# --- Build tools
|
||||||
flake-utils.url = github:numtide/flake-utils;
|
flake-utils.url = github:numtide/flake-utils;
|
||||||
crane.url = github:ipetkov/crane;
|
crane.url = github:ipetkov/crane;
|
||||||
|
rust-overlay = {
|
||||||
|
url = "github:oxalica/rust-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
arion.url = github:hercules-ci/arion;
|
arion.url = github:hercules-ci/arion;
|
||||||
|
lix-module = {
|
||||||
|
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-1.tar.gz";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
# Imported apps
|
# Imported apps
|
||||||
rnix-lsp.url = "github:nix-community/rnix-lsp";
|
|
||||||
youmubot.url = "github:natsukagami/youmubot";
|
youmubot.url = "github:natsukagami/youmubot";
|
||||||
swayfx = {
|
# swayfx = {
|
||||||
url = github:WillPower3309/swayfx;
|
# url = github:WillPower3309/swayfx;
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
# inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
# };
|
||||||
mpd-mpris = {
|
mpd-mpris = {
|
||||||
url = github:natsukagami/mpd-mpris;
|
url = github:natsukagami/mpd-mpris;
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki/phanpy";
|
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki/phanpy?ref=dtth-fork";
|
||||||
conduit = {
|
conduit.url = "gitlab:famedly/conduit/v0.9.0";
|
||||||
url = gitlab:famedly/conduit/v0.6.0;
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
|
||||||
};
|
|
||||||
eza.url = github:eza-community/eza/v0.12.0;
|
|
||||||
eza.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
nix-gaming.url = github:fufexan/nix-gaming;
|
nix-gaming.url = github:fufexan/nix-gaming;
|
||||||
|
|
||||||
# --- Sources
|
# --- Sources
|
||||||
kakoune.url = github:mawww/kakoune;
|
kakoune.url = github:mawww/kakoune;
|
||||||
kakoune.flake = false;
|
kakoune.flake = false;
|
||||||
kak-lsp.url = github:natsukagami/kak-lsp/metals-support;
|
kak-lsp.url = github:kakoune-lsp/kakoune-lsp;
|
||||||
kak-lsp.flake = false;
|
kak-lsp.flake = false;
|
||||||
nixos-m1.url = github:tpwrules/nixos-apple-silicon;
|
nixos-m1.url = github:tpwrules/nixos-apple-silicon;
|
||||||
nixos-m1.inputs.nixpkgs.follows = "nixpkgs";
|
nixos-m1.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
@ -59,7 +63,7 @@
|
||||||
secrets.url = "git+ssh://git@github.com/natsukagami/nix-deploy-secrets";
|
secrets.url = "git+ssh://git@github.com/natsukagami/nix-deploy-secrets";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, darwin, nixpkgs, nixpkgs-unstable, home-manager, deploy-rs, sops-nix, nur, ... }@inputs:
|
outputs = { self, darwin, nixpkgs, nixpkgs-unstable, home-manager, deploy-rs, sops-nix, ... }@inputs:
|
||||||
let
|
let
|
||||||
overlays = import ./overlay.nix inputs;
|
overlays = import ./overlay.nix inputs;
|
||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
|
@ -71,23 +75,12 @@
|
||||||
nixpkgsAsRegistry_ = stable: { lib, ... }: {
|
nixpkgsAsRegistry_ = stable: { lib, ... }: {
|
||||||
imports = [ applyOverlays ];
|
imports = [ applyOverlays ];
|
||||||
nix.registry.current-system.flake = self;
|
nix.registry.current-system.flake = self;
|
||||||
nix.registry.nixpkgs.flake = stable;
|
|
||||||
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
|
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
nix.nixPath = [
|
nix.nixPath = lib.mkDefault [
|
||||||
"nixpkgs=${nixpkgs}"
|
|
||||||
"nixpkgs-unstable=${nixpkgs-unstable}"
|
"nixpkgs-unstable=${nixpkgs-unstable}"
|
||||||
"/nix/var/nix/profiles/per-user/root/channels"
|
|
||||||
];
|
|
||||||
# Binary Cache for Haskell.nix
|
|
||||||
nix.settings.trusted-public-keys = [
|
|
||||||
# "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
|
|
||||||
];
|
|
||||||
nix.settings.substituters = [
|
|
||||||
# "https://cache.iog.io"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
nixpkgsAsRegistry = nixpkgsAsRegistry_ nixpkgs;
|
|
||||||
|
|
||||||
osuStable = { pkgs, ... }: {
|
osuStable = { pkgs, ... }: {
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
|
@ -95,6 +88,20 @@
|
||||||
trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" ];
|
trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" ];
|
||||||
};
|
};
|
||||||
environment.systemPackages = [ inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-stable ];
|
environment.systemPackages = [ inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-stable ];
|
||||||
|
programs.gamemode = {
|
||||||
|
enable = true;
|
||||||
|
enableRenice = true;
|
||||||
|
settings = {
|
||||||
|
general = {
|
||||||
|
renice = 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
custom = {
|
||||||
|
start = "${pkgs.libnotify}/bin/notify-send 'GameMode started'";
|
||||||
|
end = "${pkgs.libnotify}/bin/notify-send 'GameMode ended'";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Common Nix modules
|
# Common Nix modules
|
||||||
|
@ -103,6 +110,7 @@
|
||||||
(nixpkgsAsRegistry_ stable)
|
(nixpkgsAsRegistry_ stable)
|
||||||
./common.nix
|
./common.nix
|
||||||
sops-nix.nixosModules.sops
|
sops-nix.nixosModules.sops
|
||||||
|
inputs.lix-module.nixosModules.default
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
common-nixos = stable: { ... }: {
|
common-nixos = stable: { ... }: {
|
||||||
|
@ -111,9 +119,39 @@
|
||||||
./modules/common/linux
|
./modules/common/linux
|
||||||
(common-nix stable)
|
(common-nix stable)
|
||||||
inputs.secrets.nixosModules.common
|
inputs.secrets.nixosModules.common
|
||||||
|
inputs.nix-gaming.nixosModules.pipewireLowLatency
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mkPersonalSystem = nixpkgs-module: system: { configuration
|
||||||
|
, homeManagerUsers ? { }
|
||||||
|
, extraModules ? [ ]
|
||||||
|
, includeCommonModules ? true
|
||||||
|
,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
home-manager-module =
|
||||||
|
if nixpkgs-module == inputs.nixpkgs then inputs.home-manager
|
||||||
|
else if nixpkgs-module == inputs.nixpkgs-unstable then inputs.home-manager-unstable
|
||||||
|
else builtins.abort "Unknown nixpkgs module, use `nixpkgs` or `nixpkgs-unstable`";
|
||||||
|
in
|
||||||
|
nixpkgs-module.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules =
|
||||||
|
(if includeCommonModules then [
|
||||||
|
(common-nixos nixpkgs-module)
|
||||||
|
] else [ ]) ++ [
|
||||||
|
configuration
|
||||||
|
# Home Manager
|
||||||
|
home-manager-module.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
home-manager.users = homeManagerUsers;
|
||||||
|
}
|
||||||
|
] ++ extraModules;
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
overlays.default = lib.composeManyExtensions overlays;
|
overlays.default = lib.composeManyExtensions overlays;
|
||||||
|
@ -137,29 +175,16 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
# Home configuration
|
# Home configuration
|
||||||
nixosConfigurations."nki-home" = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations."kagamiPC" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
|
||||||
system = "x86_64-linux";
|
configuration = ./nki-home/configuration.nix;
|
||||||
modules = [
|
homeManagerUsers.nki = import ./home/kagami-pc-home.nix;
|
||||||
(common-nixos nixpkgs)
|
extraModules = [ osuStable ];
|
||||||
./nki-home/configuration.nix
|
|
||||||
osuStable
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
home-manager.users.nki = { ... }: {
|
|
||||||
imports = [
|
|
||||||
./home/kagami-pc-home.nix
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
# yoga g8 configuration
|
# yoga g8 configuration
|
||||||
nixosConfigurations."nki-yoga-g8" = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations."nki-yoga-g8" = mkPersonalSystem nixpkgs "x86_64-linux" {
|
||||||
system = "x86_64-linux";
|
configuration = ./nki-yoga-g8/configuration.nix;
|
||||||
modules = [
|
homeManagerUsers.nki = import ./home/nki-x1c1.nix;
|
||||||
(common-nixos nixpkgs)
|
extraModules = [
|
||||||
inputs.lanzaboote.nixosModules.lanzaboote
|
inputs.lanzaboote.nixosModules.lanzaboote
|
||||||
({ ... }: {
|
({ ... }: {
|
||||||
# Sets up secure boot
|
# Sets up secure boot
|
||||||
|
@ -169,40 +194,38 @@
|
||||||
pkiBundle = "/etc/secureboot";
|
pkiBundle = "/etc/secureboot";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
./nki-yoga-g8/configuration.nix
|
];
|
||||||
home-manager.nixosModules.home-manager
|
};
|
||||||
{
|
# framework configuration
|
||||||
home-manager.useGlobalPkgs = true;
|
nixosConfigurations."nki-framework" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
|
||||||
home-manager.useUserPackages = true;
|
configuration = ./nki-framework/configuration.nix;
|
||||||
home-manager.users.nki = import ./home/nki-x1c1.nix;
|
homeManagerUsers.nki = import ./home/nki-framework.nix;
|
||||||
}
|
extraModules = [
|
||||||
|
inputs.lanzaboote.nixosModules.lanzaboote
|
||||||
|
inputs.nixos-hardware.nixosModules.framework-13-7040-amd
|
||||||
|
({ ... }: {
|
||||||
|
# Sets up secure boot
|
||||||
|
boot.loader.systemd-boot.enable = lib.mkForce false;
|
||||||
|
boot.lanzaboote = {
|
||||||
|
enable = true;
|
||||||
|
pkiBundle = "/etc/secureboot";
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
# macbook nixos
|
# macbook nixos
|
||||||
nixosConfigurations."kagami-air-m1" = inputs.nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations."kagami-air-m1" = mkPersonalSystem nixpkgs "aarch64-linux" {
|
||||||
system = "aarch64-linux";
|
configuration = ./kagami-air-m1/configuration.nix;
|
||||||
modules = [
|
homeManagerUsers.nki = import ./home/macbook-nixos.nix;
|
||||||
(common-nixos inputs.nixpkgs)
|
extraModules = [ inputs.nixos-m1.nixosModules.apple-silicon-support ];
|
||||||
inputs.nixos-m1.nixosModules.apple-silicon-support
|
|
||||||
./kagami-air-m1/configuration.nix
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
home-manager.users.nki = import ./home/macbook-nixos.nix;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# DigitalOcean node
|
# DigitalOcean node
|
||||||
nixosConfigurations."nki-personal-do" = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations."nki-personal-do" = mkPersonalSystem nixpkgs "x86_64-linux" {
|
||||||
system = "x86_64-linux";
|
configuration = ./nki-personal-do/configuration.nix;
|
||||||
modules = [
|
extraModules = [
|
||||||
(common-nixos nixpkgs)
|
|
||||||
inputs.arion.nixosModules.arion
|
inputs.arion.nixosModules.arion
|
||||||
./modules/my-tinc
|
|
||||||
inputs.youmubot.nixosModules.default
|
inputs.youmubot.nixosModules.default
|
||||||
./nki-personal-do/configuration.nix
|
|
||||||
inputs.secrets.nixosModules.nki-personal-do
|
inputs.secrets.nixosModules.nki-personal-do
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -217,8 +240,8 @@
|
||||||
|
|
||||||
# This is highly advised, and will prevent many possible mistakes
|
# This is highly advised, and will prevent many possible mistakes
|
||||||
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
|
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
|
||||||
|
|
||||||
} // (inputs.flake-utils.lib.eachDefaultSystem (system: {
|
} // (inputs.flake-utils.lib.eachDefaultSystem (system: {
|
||||||
formatter = nixpkgs.legacyPackages.${system}.nixpkgs-fmt;
|
formatter = nixpkgs.legacyPackages.${system}.nixpkgs-fmt;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,51 +1,54 @@
|
||||||
{ pkgs, config, lib, ... }:
|
{ pkgs, config, lib, ... }:
|
||||||
with lib; {
|
with lib;
|
||||||
|
let
|
||||||
|
kwallet = { pkgs, lib, ... }: {
|
||||||
|
home.packages = with pkgs; [ kdePackages.kwallet kdePackages.ksshaskpass ];
|
||||||
|
home.sessionVariables = {
|
||||||
|
# https://wiki.archlinux.org/title/KDE_Wallet#Using_the_KDE_Wallet_to_store_ssh_key_passphrases
|
||||||
|
SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
|
||||||
|
SSH_ASKPASS_REQUIRE = "prefer";
|
||||||
|
};
|
||||||
|
# Enable this for sway
|
||||||
|
wayland.windowManager.sway.config.startup = [
|
||||||
|
{ command = "${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init"; }
|
||||||
|
];
|
||||||
|
# Automatic dbus activation
|
||||||
|
xdg.dataFile."dbus-1/services/org.freedesktop.secrets.service".text = ''
|
||||||
|
[D-BUS Service]
|
||||||
|
Name=org.freedesktop.secrets
|
||||||
|
Exec=${pkgs.kdePackages.kwallet}/bin/kwalletd6
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./modules/monitors.nix
|
./modules/monitors.nix
|
||||||
./modules/linux/graphical
|
./modules/linux/graphical
|
||||||
./modules/X11/xfce4-notifyd.nix
|
./modules/X11/xfce4-notifyd.nix
|
||||||
./modules/programs/discord.nix
|
./modules/programs/discord.nix
|
||||||
|
kwallet
|
||||||
];
|
];
|
||||||
config = (mkIf pkgs.stdenv.isLinux {
|
config = (mkIf pkgs.stdenv.isLinux {
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
psmisc # killall and friends
|
psmisc # killall and friends
|
||||||
file # Query file type
|
file # Query file type
|
||||||
|
|
||||||
pinentry-gnome
|
pinentry-gnome3 # until pinentry-qt introduces caching
|
||||||
] ++ (
|
|
||||||
if pkgs.stdenv.isx86_64
|
|
||||||
then [
|
|
||||||
vivaldi
|
|
||||||
mpv # for anki
|
|
||||||
pkgs.unstable.anki-bin
|
|
||||||
|
|
||||||
tdesktop
|
|
||||||
whatsapp-for-linux
|
|
||||||
]
|
|
||||||
else [ ]
|
|
||||||
);
|
|
||||||
|
|
||||||
## Gnome-keyring
|
|
||||||
services.gnome-keyring = {
|
|
||||||
enable = true;
|
|
||||||
components = [ "pkcs11" "secrets" "ssh" ];
|
|
||||||
};
|
|
||||||
# services.gpg-agent.enable = true;
|
|
||||||
# services.gpg-agent.pinentryFlavor = "curses";
|
|
||||||
# services.gpg-agent.enableSshSupport = true;
|
|
||||||
|
|
||||||
# Git "safe-directory"
|
|
||||||
programs.git.extraConfig.safe.directory = [
|
|
||||||
"${config.home.homeDirectory}/.config/nixpkgs"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.user.startServices = "sd-switch";
|
systemd.user.startServices = "sd-switch";
|
||||||
|
|
||||||
|
# Audio stuff!
|
||||||
|
services.easyeffects.enable = true;
|
||||||
|
|
||||||
# Bluetooth controls
|
# Bluetooth controls
|
||||||
services.mpris-proxy.enable = true;
|
# services.mpris-proxy.enable = true;
|
||||||
|
|
||||||
# Owncloud
|
# Owncloud
|
||||||
services.owncloud-client.enable = true;
|
services.owncloud-client.enable = true;
|
||||||
|
services.owncloud-client.package = pkgs.owncloud-client.overrideAttrs (attrs: {
|
||||||
|
buildInputs = attrs.buildInputs ++ [ pkgs.qt6.qtwayland ];
|
||||||
|
});
|
||||||
|
|
||||||
# UDisks automounter
|
# UDisks automounter
|
||||||
services.udiskie.enable = true;
|
services.udiskie.enable = true;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
let
|
|
||||||
texlab = pkgs.unstable.texlab;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./kakoune/kak.nix
|
./kakoune/kak.nix
|
||||||
|
@ -12,13 +9,6 @@ in
|
||||||
./modules/programs/my-kitty
|
./modules/programs/my-kitty
|
||||||
./modules/programs/openconnect-epfl.nix
|
./modules/programs/openconnect-epfl.nix
|
||||||
./common-linux.nix
|
./common-linux.nix
|
||||||
|
|
||||||
# PATH Overrides
|
|
||||||
({ config, lib, ... }: {
|
|
||||||
home.sessionPath = lib.mkBefore [
|
|
||||||
"${config.home.homeDirectory}/.bin/overrides"
|
|
||||||
];
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
# Let Home Manager install and manage itself.
|
||||||
|
@ -29,46 +19,16 @@ in
|
||||||
|
|
||||||
# Packages that are not in programs section
|
# Packages that are not in programs section
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
# Build Tools
|
|
||||||
## C++
|
|
||||||
autoconf
|
|
||||||
automake
|
|
||||||
## SQL
|
|
||||||
flyway
|
|
||||||
## Go
|
|
||||||
go # to be configured later
|
|
||||||
## Rust
|
|
||||||
rust-analyzer
|
|
||||||
## JavaScript
|
|
||||||
yarn
|
|
||||||
## Nix
|
|
||||||
cachix
|
|
||||||
rnix-lsp
|
|
||||||
## Latex
|
|
||||||
tectonic
|
|
||||||
texlab
|
|
||||||
## Typst
|
|
||||||
typst
|
|
||||||
## Python
|
|
||||||
python3
|
|
||||||
## Scala
|
|
||||||
pkgs.unstable.scala-cli
|
|
||||||
|
|
||||||
# Fonts
|
|
||||||
fantasque-sans-mono
|
|
||||||
## Get the nerd font symbols
|
|
||||||
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
|
|
||||||
|
|
||||||
# CLI tools
|
# CLI tools
|
||||||
fd
|
fd
|
||||||
|
sd
|
||||||
ripgrep
|
ripgrep
|
||||||
fossil
|
|
||||||
openssh
|
openssh
|
||||||
tea # gitea CLI (gh-like)
|
tea # gitea CLI (gh-like)
|
||||||
fx # JSON viewer
|
fx # JSON viewer
|
||||||
glow # Markdown viewer
|
glow # Markdown viewer
|
||||||
## File Manager
|
nix-output-monitor # Nice nix output formatting
|
||||||
nnn
|
unstable.scala-next
|
||||||
## PDF Processors
|
## PDF Processors
|
||||||
poppler_utils
|
poppler_utils
|
||||||
## htop replacement
|
## htop replacement
|
||||||
|
@ -80,13 +40,6 @@ in
|
||||||
unzip
|
unzip
|
||||||
zstd
|
zstd
|
||||||
atool
|
atool
|
||||||
|
|
||||||
## To do tunneling with cloudflare
|
|
||||||
pkgs.cloudflared
|
|
||||||
|
|
||||||
# Databases
|
|
||||||
postgresql
|
|
||||||
mariadb
|
|
||||||
];
|
];
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
|
@ -116,9 +69,9 @@ in
|
||||||
direnv.nix-direnv.enable = true;
|
direnv.nix-direnv.enable = true;
|
||||||
direnv.config.global.load_dotenv = true;
|
direnv.config.global.load_dotenv = true;
|
||||||
|
|
||||||
exa = {
|
eza = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableAliases = true;
|
enableFishIntegration = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fzf = {
|
fzf = {
|
||||||
|
@ -150,6 +103,8 @@ in
|
||||||
.envrc
|
.envrc
|
||||||
.kakrc
|
.kakrc
|
||||||
''}";
|
''}";
|
||||||
|
safe.directory = "*";
|
||||||
|
merge.conflictstyle = "diff3";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
{
|
{
|
||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
packageOverrides = pkgs: {
|
|
||||||
nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
|
|
||||||
inherit pkgs;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,37 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, options, pkgs, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
let
|
||||||
|
bootDesktop = pkgs.writeScript "boot-desktop" ''
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
|
set -a PATH ${pkgs.gum}/bin
|
||||||
|
|
||||||
|
set -x GUM_CHOOSE_HEADER "Select the Desktop to boot into:"
|
||||||
|
set CHOICES
|
||||||
|
|
||||||
|
if which sway &>/dev/null
|
||||||
|
set -a CHOICES "sway"
|
||||||
|
end
|
||||||
|
if which startplasma-wayland &>/dev/null
|
||||||
|
set -a CHOICES "KDE Plasma"
|
||||||
|
end
|
||||||
|
set -a CHOICES "None: continue to shell"
|
||||||
|
|
||||||
|
switch (gum choose $CHOICES)
|
||||||
|
case "sway"
|
||||||
|
systemctl --user unset-environment NIXOS_OZONE_WL
|
||||||
|
exec sway
|
||||||
|
case "KDE Plasma"
|
||||||
|
exec ${pkgs.kdePackages.plasma-workspace}/libexec/plasma-dbus-run-session-if-needed startplasma-wayland
|
||||||
|
case '*'
|
||||||
|
exec fish -i
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./tide/nix-shell.nix
|
./tide
|
||||||
];
|
];
|
||||||
|
|
||||||
options.programs.fish.everywhereAbbrs = mkOption {
|
options.programs.fish.everywhereAbbrs = mkOption {
|
||||||
|
@ -23,22 +51,28 @@ with lib;
|
||||||
config.programs.fish = {
|
config.programs.fish = {
|
||||||
enable = true;
|
enable = true;
|
||||||
functions = {
|
functions = {
|
||||||
|
rebuild = {
|
||||||
|
body = ''
|
||||||
|
pls nixos-rebuild --flake ~/.config/nixpkgs -L --log-format internal-json -v $argv \
|
||||||
|
&| ${pkgs.nix-output-monitor}/bin/nom --json
|
||||||
|
'';
|
||||||
|
wraps = "nixos-rebuild";
|
||||||
|
};
|
||||||
# Simplify nix usage!
|
# Simplify nix usage!
|
||||||
nx = {
|
nx = {
|
||||||
body = ''
|
body = ''
|
||||||
set impure
|
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
|
||||||
if test $argv[1] = "--impure"
|
if set -q _flag_help || test (count $argv) -eq 0
|
||||||
set impure "--impure"
|
echo "nx [--impure] [-u/--unstable/-g/--git] {package} [args...]"
|
||||||
set argv $argv[2..]
|
|
||||||
end
|
|
||||||
if test (count $argv) -gt 0
|
|
||||||
nix run $impure nixpkgs#$argv[1] -- $argv[2..]
|
|
||||||
else
|
|
||||||
echo "nx [--impure] {package} [args...]"
|
|
||||||
return 1
|
return 1
|
||||||
|
else
|
||||||
|
set -q _flag_impure && set impure "--impure"
|
||||||
|
set nixpkgs "nixpkgs"
|
||||||
|
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
|
||||||
|
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
|
||||||
|
nix run $impure $nixpkgs"#"$argv[1] -- $argv[2..]
|
||||||
end
|
end
|
||||||
'';
|
'';
|
||||||
wraps = "nix run";
|
|
||||||
description = "Runs an app from the nixpkgs store.";
|
description = "Runs an app from the nixpkgs store.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,25 +80,35 @@ with lib;
|
||||||
description = "Spawns a shell from the given nixpkgs packages";
|
description = "Spawns a shell from the given nixpkgs packages";
|
||||||
wraps = "nix shell";
|
wraps = "nix shell";
|
||||||
body = ''
|
body = ''
|
||||||
set impure
|
function help
|
||||||
if test $argv[1] = "--impure"
|
echo "nsh [--impure] [--impure] [-u/--unstable/-g/--git] {package}* [-c command args...]"
|
||||||
set impure "--impure"
|
|
||||||
set argv $argv[2..]
|
|
||||||
end
|
end
|
||||||
if test (count $argv) -gt 0
|
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
|
||||||
set minusc (contains -i -- "-c" $argv)
|
if set -q _flag_help || test (count $argv) -eq 0
|
||||||
if test -z $minusc
|
help
|
||||||
nix shell $impure nixpkgs#$argv -c fish
|
return 0
|
||||||
else if test $minusc -eq (count $argv)
|
end
|
||||||
echo "nsh [--impure] {packages} [-c command args...]"
|
set packages $argv
|
||||||
|
set minusc (contains -i -- "-c" $argv)
|
||||||
|
if test -n "$minusc"
|
||||||
|
if test $minusc -eq 1
|
||||||
|
help
|
||||||
return 1
|
return 1
|
||||||
else
|
|
||||||
nix shell $impure nixpkgs#$argv[..(math $minusc - 1)] $argv[$minusc..]
|
|
||||||
end
|
end
|
||||||
|
set packages $argv[..(math $minusc - 1)]
|
||||||
|
set argv $argv[(math $minusc + 1)..]
|
||||||
else
|
else
|
||||||
echo "nsh [--impure] {packages} [-c command args...]"
|
set argv "fish" "-i"
|
||||||
|
end
|
||||||
|
if test (count $packages) -eq 0
|
||||||
|
help
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
set -q _flag_impure && set impure "--impure"
|
||||||
|
set nixpkgs "nixpkgs"
|
||||||
|
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
|
||||||
|
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
|
||||||
|
nix shell $impure $nixpkgs"#"$packages --command $argv
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
# Grep stuff
|
# Grep stuff
|
||||||
|
@ -82,17 +126,44 @@ with lib;
|
||||||
};
|
};
|
||||||
echo-today = "date +%F";
|
echo-today = "date +%F";
|
||||||
newfile = "mkdir -p (dirname $argv[-1]) && touch $argv";
|
newfile = "mkdir -p (dirname $argv[-1]) && touch $argv";
|
||||||
|
|
||||||
|
# pls
|
||||||
|
pls = {
|
||||||
|
wraps = "sudo";
|
||||||
|
body = ''
|
||||||
|
set -l cmd "`"(string join " " -- $argv)"`"
|
||||||
|
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
|
||||||
|
# Send a notification on password prompt
|
||||||
|
if command sudo -vn 2>/dev/null
|
||||||
|
# nothing to do, user already authenticated
|
||||||
|
else
|
||||||
|
# throw a notification
|
||||||
|
set notif_id (kitten notify -P \
|
||||||
|
-p ${./haruka.png} \
|
||||||
|
-a "pls" \
|
||||||
|
-u critical \
|
||||||
|
"A-a command requires your p-password" \
|
||||||
|
(printf "I-I need your p-password to r-run the following c-command:\n\n%s" $cmd))
|
||||||
|
command sudo -v -p "P-password please: "
|
||||||
|
kitten notify -i $notif_id ""
|
||||||
|
end
|
||||||
|
command sudo $argv
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
tide = {
|
tide = {
|
||||||
nix-shell.enable = true;
|
enable = true;
|
||||||
|
leftItems = options.programs.fish.tide.leftItems.default;
|
||||||
|
rightItems = options.programs.fish.tide.rightItems.default;
|
||||||
};
|
};
|
||||||
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
cat = "bat --theme=GitHub ";
|
cat = "bat --theme=GitHub ";
|
||||||
catp = "bat --theme=GitHub -p ";
|
catp = "bat --theme=GitHub -p ";
|
||||||
l = "exa -l --color=always ";
|
l = "exa -l --color=always ";
|
||||||
|
"cp+" = "rsync -avzP";
|
||||||
};
|
};
|
||||||
|
|
||||||
everywhereAbbrs = {
|
everywhereAbbrs = {
|
||||||
|
@ -107,9 +178,17 @@ with lib;
|
||||||
if test -e /opt/homebrew/bin/brew
|
if test -e /opt/homebrew/bin/brew
|
||||||
/opt/homebrew/bin/brew shellenv | source
|
/opt/homebrew/bin/brew shellenv | source
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Override PATH
|
||||||
|
set --export --prepend PATH ~/.bin/overrides ~/.local/bin
|
||||||
'';
|
'';
|
||||||
|
|
||||||
interactiveShellInit = ''
|
interactiveShellInit = ''
|
||||||
|
# Sway!
|
||||||
|
if status --is-login; and test -z $DISPLAY; and test (tty) = "/dev/tty1"
|
||||||
|
exec ${bootDesktop}
|
||||||
|
end
|
||||||
|
|
||||||
function fish_greeting
|
function fish_greeting
|
||||||
${pkgs.timg}/bin/timg ${./arona.jpg}
|
${pkgs.timg}/bin/timg ${./arona.jpg}
|
||||||
printf (env LANG=ja_JP.UTF-8 date +"ご主人様、お帰りなさい!\n今日は%A、%Y年%m月%d日ですねー!今の時間って、%H時%M分です〜 \n言って言ってご主人様、コンピュターちゃんと何がするつもりでしょーか?〜エヘヘっ\n")
|
printf (env LANG=ja_JP.UTF-8 date +"ご主人様、お帰りなさい!\n今日は%A、%Y年%m月%d日ですねー!今の時間って、%H時%M分です〜 \n言って言ってご主人様、コンピュターちゃんと何がするつもりでしょーか?〜エヘヘっ\n")
|
||||||
|
@ -176,23 +255,8 @@ with lib;
|
||||||
set -q PERL_LOCAL_LIB_ROOT; or set -x PERL_LOCAL_LIB_ROOT ${config.home.homeDirectory}/perl5;
|
set -q PERL_LOCAL_LIB_ROOT; or set -x PERL_LOCAL_LIB_ROOT ${config.home.homeDirectory}/perl5;
|
||||||
set -x PERL_MB_OPT --install_base\ \"${config.home.homeDirectory}/perl5\";
|
set -x PERL_MB_OPT --install_base\ \"${config.home.homeDirectory}/perl5\";
|
||||||
set -x PERL_MM_OPT INSTALL_BASE=${config.home.homeDirectory}/perl5;
|
set -x PERL_MM_OPT INSTALL_BASE=${config.home.homeDirectory}/perl5;
|
||||||
|
|
||||||
# Sway!
|
|
||||||
if status --is-login; and which sway >/dev/null; and test -z $DISPLAY; and test (tty) = "/dev/tty1"
|
|
||||||
read -P "Press enter to start sway..."; and exec sway
|
|
||||||
end
|
|
||||||
'';
|
'';
|
||||||
plugins = [
|
plugins = [
|
||||||
{
|
|
||||||
name = "tide";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "IlanCosman";
|
|
||||||
repo = "tide";
|
|
||||||
rev = "447945d2cff8f70d5c791dd4eec8b322d37798dd";
|
|
||||||
# sha256 = lib.fakeSha256;
|
|
||||||
sha256 = "sha256-1c2E3UC3r9hPfijAQoZ/+4yXieFxC4+hkk7wUyr30NM=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "fzf";
|
name = "fzf";
|
||||||
src = pkgs.fetchFromGitHub {
|
src = pkgs.fetchFromGitHub {
|
||||||
|
@ -221,8 +285,8 @@ with lib;
|
||||||
target = ".config/fish/conf.d/change_cmd.fish";
|
target = ".config/fish/conf.d/change_cmd.fish";
|
||||||
};
|
};
|
||||||
"fish/pls.fish" = {
|
"fish/pls.fish" = {
|
||||||
source = ./. + "/pls.fish";
|
source = ./pls_extra.fish;
|
||||||
target = ".config/fish/conf.d/pls.fish";
|
target = ".config/fish/conf.d/pls_extra.fish";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
BIN
home/fish/haruka.png
Normal file
BIN
home/fish/haruka.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -1,155 +0,0 @@
|
||||||
alias sue="pls -e"
|
|
||||||
|
|
||||||
function pls
|
|
||||||
set -l cmd "`"(string join " " -- $argv)"`"
|
|
||||||
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
|
|
||||||
# Send a notification on password prompt
|
|
||||||
if command sudo -vn 2>/dev/null
|
|
||||||
# nothing to do, user already authenticated
|
|
||||||
else
|
|
||||||
# throw a notification
|
|
||||||
# notify-send -t 3000 -u critical -i ~/Downloads/harukablush.jpg -h "STRING:command:"$cmd "A-a command requires your p-password" (printf "I-I need your p-password to r-run the following c-command: %s" $cmd)
|
|
||||||
end
|
|
||||||
command sudo $argv
|
|
||||||
end
|
|
||||||
|
|
||||||
function sudo
|
|
||||||
echo "Not polite enough."
|
|
||||||
end
|
|
||||||
|
|
||||||
function __fish_prepend_pls -d "Prepend 'pls ' to the beginning of the current commandline"
|
|
||||||
# If there is no commandline, insert the last item from history
|
|
||||||
# and *then* toggle
|
|
||||||
if not commandline | string length -q
|
|
||||||
commandline -r "$history[1]"
|
|
||||||
end
|
|
||||||
|
|
||||||
set -l cmd (commandline -po)
|
|
||||||
set -l cursor (commandline -C)
|
|
||||||
|
|
||||||
if test "$cmd[1]" = e
|
|
||||||
commandline -C 0
|
|
||||||
commandline -i "su"
|
|
||||||
commandline -C (math $cursor + 2)
|
|
||||||
else if test "$cmd[1]" = sue
|
|
||||||
commandline -r (string sub --start=3 (commandline -p))
|
|
||||||
commandline -C -- (math $cursor - 2)
|
|
||||||
else if test "$cmd[1]" != pls
|
|
||||||
commandline -C 0
|
|
||||||
commandline -i "pls "
|
|
||||||
commandline -C (math $cursor + 4)
|
|
||||||
else
|
|
||||||
commandline -r (string sub --start=5 (commandline -p))
|
|
||||||
commandline -C -- (math $cursor - 4)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
bind --preset -e -M insert \es
|
|
||||||
bind -M insert \es __fish_prepend_pls
|
|
||||||
|
|
||||||
function __fish_man_page
|
|
||||||
# Get all commandline tokens not starting with "-"
|
|
||||||
set -l args (commandline -po | string match -rv '^-')
|
|
||||||
|
|
||||||
# If commandline is empty, exit.
|
|
||||||
if not set -q args[1]
|
|
||||||
printf \a
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
#Skip `pls` and display then manpage of following command
|
|
||||||
while set -q args[2]
|
|
||||||
and string match -qr -- '^(pls|.*=.*)$' $args[1]
|
|
||||||
set -e args[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
|
|
||||||
# Try "man first-second" and fall back to "man first" if that doesn't work out.
|
|
||||||
set -l maincmd (basename $args[1])
|
|
||||||
if set -q args[2]
|
|
||||||
# HACK: If stderr is not attached to a terminal `less` (the default pager)
|
|
||||||
# wouldn't use the alternate screen.
|
|
||||||
# But since we don't know what pager it is, and because `man` is totally underspecified,
|
|
||||||
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
|
|
||||||
# See #7863.
|
|
||||||
if man "$maincmd-$args[2]" &>/dev/null
|
|
||||||
man "$maincmd-$args[2]"
|
|
||||||
else if man "$maincmd" &>/dev/null
|
|
||||||
man "$maincmd"
|
|
||||||
else
|
|
||||||
printf \a
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if man "$maincmd" &>/dev/null
|
|
||||||
man "$maincmd"
|
|
||||||
else
|
|
||||||
printf \a
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
commandline -f repaint
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Completion for pls
|
|
||||||
#
|
|
||||||
|
|
||||||
function __fish_pls_print_remaining_args
|
|
||||||
set -l tokens (commandline -opc) (commandline -ct)
|
|
||||||
set -e tokens[1]
|
|
||||||
# These are all the options mentioned in the man page for Todd Miller's "pls.ws" pls (in that order).
|
|
||||||
# If any other implementation has different options, this should be harmless, since they shouldn't be used anyway.
|
|
||||||
set -l opts A/askpass b/background C/close-from= E/preserve-env='?'
|
|
||||||
# Note that "-h" is both "--host" (which takes an option) and "--help" (which doesn't).
|
|
||||||
# But `-h` as `--help` only counts when it's the only argument (`pls -h`),
|
|
||||||
# so any argument completion after that should take it as "--host".
|
|
||||||
set -a opts e/edit g/group= H/set-home h/host= 1-help
|
|
||||||
set -a opts i/login K/remove-timestamp k/reset-timestamp l/list n/non-interactive
|
|
||||||
set -a opts P/preserve-groups p/prompt= S/stdin s/shell U/other-user=
|
|
||||||
set -a opts u/user= T/command-timeout= V/version v/validate
|
|
||||||
argparse -s $opts -- $tokens 2>/dev/null
|
|
||||||
# The remaining argv is the subcommand with all its options, which is what
|
|
||||||
# we want.
|
|
||||||
if test -n "$argv"
|
|
||||||
and not string match -qr '^-' $argv[1]
|
|
||||||
string join0 -- $argv
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function __fish_pls_no_subcommand
|
|
||||||
not __fish_pls_print_remaining_args >/dev/null
|
|
||||||
end
|
|
||||||
|
|
||||||
function __fish_complete_pls_subcommand
|
|
||||||
set -l args (__fish_pls_print_remaining_args | string split0)
|
|
||||||
set -lx -a PATH /usr/local/sbin /sbin /usr/sbin
|
|
||||||
__fish_complete_subcommand --commandline $args
|
|
||||||
end
|
|
||||||
|
|
||||||
# All these options should be valid for GNU and OSX pls
|
|
||||||
complete -c pls -n __fish_no_arguments -s h -d "Display help and exit"
|
|
||||||
complete -c pls -n __fish_no_arguments -s V -d "Display version information and exit"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s A -d "Ask for password via the askpass or \$SSH_ASKPASS program"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s C -d "Close all file descriptors greater or equal to the given number" -xa "0 1 2 255"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s E -d "Preserve environment"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s H -d "Set home"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s K -d "Remove the credential timestamp entirely"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s P -d "Preserve group vector"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s S -d "Read password from stdin"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s b -d "Run command in the background"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s e -rF -d Edit
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s g -a "(__fish_complete_groups)" -x -d "Run command as group"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s i -d "Run a login shell"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s k -d "Reset or ignore the credential timestamp"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s l -d "List the allowed and forbidden commands for the given user"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s n -d "Do not prompt for a password - if one is needed, fail"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s p -d "Specify a custom password prompt"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s s -d "Run the given command in a shell"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s u -a "(__fish_complete_users)" -x -d "Run command as user"
|
|
||||||
complete -c pls -n __fish_pls_no_subcommand -s v -n __fish_no_arguments -d "Validate the credentials, extending timeout"
|
|
||||||
|
|
||||||
# Complete the command we are executed under pls
|
|
||||||
complete -c pls -x -n 'not __fish_seen_argument -s e' -a "(__fish_complete_pls_subcommand)"
|
|
47
home/fish/pls_extra.fish
Normal file
47
home/fish/pls_extra.fish
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
alias sue="pls -e"
|
||||||
|
|
||||||
|
function sudo
|
||||||
|
echo "Not polite enough."
|
||||||
|
end
|
||||||
|
|
||||||
|
bind --preset -M visual \es 'fish_commandline_prepend pls'
|
||||||
|
bind -M insert \es 'fish_commandline_prepend pls'
|
||||||
|
|
||||||
|
function __fish_man_page
|
||||||
|
# Get all commandline tokens not starting with "-", up to and including the cursor's
|
||||||
|
set -l args (string match -rv '^-|^$' -- (commandline -cpx && commandline -t))
|
||||||
|
|
||||||
|
# If commandline is empty, exit.
|
||||||
|
if not set -q args[1]
|
||||||
|
printf \a
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# Skip leading commands and display the manpage of following command
|
||||||
|
while set -q args[2]
|
||||||
|
and string match -qr -- '^(and|begin|builtin|caffeinate|command|doas|entr|env|exec|if|mosh|nice|not|or|pipenv|prime-run|setsid|sudo|pls|systemd-nspawn|time|watch|while|xargs|.*=.*)$' $args[1]
|
||||||
|
set -e args[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
|
||||||
|
# Try "man first-second" and fall back to "man first" if that doesn't work out.
|
||||||
|
set -l maincmd (path basename $args[1])
|
||||||
|
# HACK: If stderr is not attached to a terminal `less` (the default pager)
|
||||||
|
# wouldn't use the alternate screen.
|
||||||
|
# But since we don't know what pager it is, and because `man` is totally underspecified,
|
||||||
|
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
|
||||||
|
# See #7863.
|
||||||
|
if set -q args[2]
|
||||||
|
and not string match -q -- '*/*' $args[2]
|
||||||
|
and man "$maincmd-$args[2]" &>/dev/null
|
||||||
|
man "$maincmd-$args[2]"
|
||||||
|
else
|
||||||
|
if man "$maincmd" &>/dev/null
|
||||||
|
man "$maincmd"
|
||||||
|
else
|
||||||
|
printf \a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
commandline -f repaint
|
||||||
|
end
|
87
home/fish/tide/default.nix
Normal file
87
home/fish/tide/default.nix
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.programs.fish.tide;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.fish.tide = {
|
||||||
|
enable = mkEnableOption "Enable tide integrations for fish";
|
||||||
|
items = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
description = "Additional item definitions to create";
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
rightItems = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "The list of right-items, note that `time` is not included here and will always appear last";
|
||||||
|
default = [
|
||||||
|
"status"
|
||||||
|
"cmd_duration"
|
||||||
|
"jobs"
|
||||||
|
"direnv"
|
||||||
|
"node"
|
||||||
|
"python"
|
||||||
|
"rustc"
|
||||||
|
"java"
|
||||||
|
"php"
|
||||||
|
"pulumi"
|
||||||
|
"ruby"
|
||||||
|
"go"
|
||||||
|
"gcloud"
|
||||||
|
"kubectl"
|
||||||
|
"distrobox"
|
||||||
|
"toolbox"
|
||||||
|
"terraform"
|
||||||
|
"aws"
|
||||||
|
"crystal"
|
||||||
|
"elixir"
|
||||||
|
"nix_shell"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
leftItems = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "The list of left-items. Note that `newline` and `character` is not included here and will always appear last";
|
||||||
|
default = [ "os" "context" "pwd" "git" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config.programs.fish =
|
||||||
|
let
|
||||||
|
tideItems = attrsets.mapAttrs' (name: def: { name = "_tide_item_${name}"; value = def; });
|
||||||
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
functions = tideItems ({
|
||||||
|
nix_shell = ''
|
||||||
|
# In a Nix Shell
|
||||||
|
if set -qx DIRENV_FILE && test -f $DIRENV_FILE && rg -q "^use flake" $DIRENV_FILE
|
||||||
|
set -U tide_nix_shell_color "FFA500"
|
||||||
|
set -U tide_nix_shell_bg_color normal
|
||||||
|
_tide_print_item nix_shell "❄"
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
} // cfg.items);
|
||||||
|
plugins = [
|
||||||
|
{
|
||||||
|
name = "tide";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "IlanCosman";
|
||||||
|
repo = "tide";
|
||||||
|
rev = "v6.0.1";
|
||||||
|
# sha256 = lib.fakeSha256;
|
||||||
|
sha256 = "sha256-oLD7gYFCIeIzBeAW1j62z5FnzWAp3xSfxxe7kBtTLgA=";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
config.xdg.configFile."fish/tide/init.fish" = {
|
||||||
|
text = ''
|
||||||
|
# Configure tide items
|
||||||
|
set -U tide_left_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.leftItems} newline character
|
||||||
|
set -U tide_right_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.rightItems} time
|
||||||
|
'';
|
||||||
|
|
||||||
|
onChange = "fish ~/.config/fish/tide/init.fish";
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.programs.fish.tide.nix-shell;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.programs.fish.tide.nix-shell = {
|
|
||||||
enable = mkEnableOption "An indicator of having a `nix shell` environment";
|
|
||||||
};
|
|
||||||
|
|
||||||
config.programs.fish = mkIf cfg.enable {
|
|
||||||
functions._tide_item_nix_shell = ''
|
|
||||||
# In a Nix Shell
|
|
||||||
if string match -q "/nix/store/*" $PATH
|
|
||||||
set -U tide_nix_shell_color (set -q DIRENV_DIR && echo "FFA500" || echo "blue")
|
|
||||||
set -U tide_nix_shell_bg_color normal
|
|
||||||
_tide_print_item nix_shell "❄"
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -21,9 +21,12 @@
|
||||||
texlive.combined.scheme-full
|
texlive.combined.scheme-full
|
||||||
inkscape # for TeX svg
|
inkscape # for TeX svg
|
||||||
|
|
||||||
# Java & sbt
|
# Gaming stuff
|
||||||
openjdk11
|
wineWowPackages.full
|
||||||
sbt
|
# wine-lol
|
||||||
|
winetricks
|
||||||
|
lutris
|
||||||
|
steam
|
||||||
|
|
||||||
# Manage tlmc
|
# Manage tlmc
|
||||||
flacon
|
flacon
|
||||||
|
@ -34,6 +37,7 @@
|
||||||
# Enable X11 configuration
|
# Enable X11 configuration
|
||||||
linux.graphical.type = "wayland";
|
linux.graphical.type = "wayland";
|
||||||
linux.graphical.wallpaper = ./images/pixiv_18776904.png;
|
linux.graphical.wallpaper = ./images/pixiv_18776904.png;
|
||||||
|
linux.graphical.defaults.webBrowser = "librewolf.desktop";
|
||||||
programs.my-sway.enable = true;
|
programs.my-sway.enable = true;
|
||||||
programs.my-sway.fontSize = 15.0;
|
programs.my-sway.fontSize = 15.0;
|
||||||
programs.my-sway.enableLaptopBars = false;
|
programs.my-sway.enableLaptopBars = false;
|
||||||
|
|
79
home/kakoune/catppuccin-latte.kak
Normal file
79
home/kakoune/catppuccin-latte.kak
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# Catppuccin theme for Kakoune
|
||||||
|
|
||||||
|
declare-option str rosewater "rgb:dc8a78"
|
||||||
|
declare-option str flamingo "rgb:dd7878"
|
||||||
|
declare-option str pink "rgb:ea76cb"
|
||||||
|
declare-option str mauve "rgb:8839ef"
|
||||||
|
declare-option str red "rgb:d20f39"
|
||||||
|
declare-option str maroon "rgb:e64553"
|
||||||
|
declare-option str peach "rgb:fe640b"
|
||||||
|
declare-option str yellow "rgb:df8e1d"
|
||||||
|
declare-option str green "rgb:40a02b"
|
||||||
|
declare-option str teal "rgb:179299"
|
||||||
|
declare-option str sky "rgb:04a5e5"
|
||||||
|
declare-option str sapphire "rgb:209fb5"
|
||||||
|
declare-option str blue "rgb:1e66f5"
|
||||||
|
declare-option str lavender "rgb:7287fd"
|
||||||
|
declare-option str text "rgb:4c4f69"
|
||||||
|
declare-option str subtext1 "rgb:5c5f77"
|
||||||
|
declare-option str subtext0 "rgb:6c6f85"
|
||||||
|
declare-option str overlay2 "rgb:7c7f93"
|
||||||
|
declare-option str overlay1 "rgb:8c8fa1"
|
||||||
|
declare-option str overlay0 "rgb:9ca0b0"
|
||||||
|
declare-option str surface2 "rgb:acb0be"
|
||||||
|
declare-option str surface1 "rgb:bcc0cc"
|
||||||
|
declare-option str surface0 "rgb:ccd0da"
|
||||||
|
declare-option str base "rgb:eff1f5"
|
||||||
|
declare-option str mantle "rgb:e6e9ef"
|
||||||
|
declare-option str crust "rgb:dce0e8"
|
||||||
|
|
||||||
|
|
||||||
|
set-face global title "%opt{text}+b"
|
||||||
|
set-face global header "%opt{subtext0}+b"
|
||||||
|
set-face global bold "%opt{maroon}+b"
|
||||||
|
set-face global italic "%opt{maroon}+i"
|
||||||
|
set-face global mono "%opt{green}"
|
||||||
|
set-face global block "%opt{sapphire}"
|
||||||
|
set-face global link "%opt{blue}"
|
||||||
|
set-face global bullet "%opt{peach}"
|
||||||
|
set-face global list "%opt{peach}"
|
||||||
|
|
||||||
|
set-face global Default "%opt{text},%opt{base}"
|
||||||
|
set-face global PrimarySelection "%opt{text},%opt{surface2}"
|
||||||
|
set-face global SecondarySelection "%opt{text},%opt{surface2}"
|
||||||
|
set-face global PrimaryCursor "%opt{crust},%opt{rosewater}"
|
||||||
|
set-face global SecondaryCursor "%opt{text},%opt{overlay0}"
|
||||||
|
set-face global PrimaryCursorEol "%opt{surface2},%opt{lavender}"
|
||||||
|
set-face global SecondaryCursorEol "%opt{surface2},%opt{overlay1}"
|
||||||
|
set-face global LineNumbers "%opt{overlay1},%opt{base}"
|
||||||
|
set-face global LineNumberCursor "%opt{rosewater},%opt{surface2}+b"
|
||||||
|
set-face global LineNumbersWrapped "%opt{rosewater},%opt{surface2}+i"
|
||||||
|
set-face global MenuForeground "%opt{text},%opt{surface1}+b"
|
||||||
|
set-face global MenuBackground "%opt{text},%opt{surface0}"
|
||||||
|
set-face global MenuInfo "%opt{crust},%opt{teal}"
|
||||||
|
set-face global Information "%opt{crust},%opt{teal}"
|
||||||
|
set-face global Error "%opt{crust},%opt{red}"
|
||||||
|
set-face global StatusLine "%opt{text},%opt{mantle}"
|
||||||
|
set-face global StatusLineMode "%opt{crust},%opt{yellow}"
|
||||||
|
set-face global StatusLineInfo "%opt{crust},%opt{teal}"
|
||||||
|
set-face global StatusLineValue "%opt{crust},%opt{yellow}"
|
||||||
|
set-face global StatusCursor "%opt{crust},%opt{rosewater}"
|
||||||
|
set-face global Prompt "%opt{teal},%opt{base}+b"
|
||||||
|
set-face global MatchingChar "%opt{maroon},%opt{base}"
|
||||||
|
set-face global Whitespace "%opt{overlay1},%opt{base}+f"
|
||||||
|
set-face global WrapMarker "Whitespace"
|
||||||
|
set-face global BufferPadding "%opt{base},%opt{base}"
|
||||||
|
|
||||||
|
set-face global value "%opt{peach}"
|
||||||
|
set-face global type "%opt{blue}"
|
||||||
|
set-face global variable "%opt{text}"
|
||||||
|
set-face global module "%opt{maroon}"
|
||||||
|
set-face global function "%opt{blue}"
|
||||||
|
set-face global string "%opt{green}"
|
||||||
|
set-face global keyword "%opt{mauve}"
|
||||||
|
set-face global operator "%opt{sky}"
|
||||||
|
set-face global attribute "%opt{green}"
|
||||||
|
set-face global comment "%opt{overlay0}"
|
||||||
|
set-face global documentation "comment"
|
||||||
|
set-face global meta "%opt{yellow}"
|
||||||
|
set-face global builtin "%opt{red}"
|
|
@ -1,59 +1,67 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
kakounePkg =
|
|
||||||
pkgs.kakoune.override {
|
|
||||||
kakoune = with lib; pkgs.stdenv.mkDerivation rec {
|
|
||||||
pname = "kakoune-unwrapped";
|
|
||||||
version = "r${builtins.substring 0 6 pkgs.sources.kakoune.rev}";
|
|
||||||
src = pkgs.sources.kakoune;
|
|
||||||
makeFlags = [ "debug=no" "PREFIX=${placeholder "out"}" ];
|
|
||||||
|
|
||||||
preConfigure = ''
|
|
||||||
export version="v${version}";
|
|
||||||
'';
|
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
|
||||||
|
|
||||||
doInstallCheck = true;
|
|
||||||
installCheckPhase = ''
|
|
||||||
$out/bin/kak -ui json -e "kill 0"
|
|
||||||
'';
|
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
# make share/kak/autoload a directory
|
|
||||||
cd "$out/share/kak"
|
|
||||||
autoload_target=$(readlink autoload)
|
|
||||||
rm autoload
|
|
||||||
mkdir autoload
|
|
||||||
ln -s --relative "$autoload_target" autoload
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
kak-lsp = pkgs.libs.crane.buildPackage {
|
|
||||||
src = pkgs.sources.kak-lsp;
|
|
||||||
buildInputs = (with pkgs;
|
|
||||||
lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security SystemConfiguration CoreServices ])
|
|
||||||
) ++ (with pkgs; [ libiconv ]);
|
|
||||||
};
|
|
||||||
|
|
||||||
kak-lsp-frontend = { pkgs, lib, ... }:
|
kak-lsp-frontend = { pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
langserver = name: {
|
langserver = name: {
|
||||||
args = [ "--stdio" ];
|
name = "vscode-${name}-language-server";
|
||||||
command = "${pkgs.nodePackages.vscode-langservers-extracted}/bin/vscode-${name}-language-server";
|
value = {
|
||||||
filetypes = [ name ];
|
args = [ "--stdio" ];
|
||||||
roots = [ "package.json" ".git" ];
|
command = "vscode-${name}-language-server";
|
||||||
|
filetypes = [ name ];
|
||||||
|
roots = [ "package.json" ".git" ];
|
||||||
|
};
|
||||||
|
package = pkgs.nodePackages.vscode-langservers-extracted;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tailwind = {
|
||||||
|
command = "tailwindcss-language-server";
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
filetypes = [ "html" "css" "javascript" "typescript" "templ" ];
|
||||||
|
roots = [ "tailwind.config.{js,cjs,mjs,ts}" "package.json" ".git" ];
|
||||||
|
settings_section = "tailwindCSS";
|
||||||
|
settings.tailwindCSS = {
|
||||||
|
validate = "warning";
|
||||||
|
userLanguages.templ = "html";
|
||||||
|
};
|
||||||
|
package = pkgs.tailwindcss-language-server;
|
||||||
|
};
|
||||||
|
|
||||||
|
templModule = { pkgs, lib, ... }: {
|
||||||
|
programs.kak-lsp.languageServers."vscode-html-language-server".filetypes = [ "templ" ];
|
||||||
|
programs.kak-lsp.languageServers."tailwindcss-language-server".filetypes = [ "templ" ];
|
||||||
|
programs.kak-lsp.languageServers.templ = {
|
||||||
|
command = "templ";
|
||||||
|
args = [ "lsp" ];
|
||||||
|
filetypes = [ "templ" ];
|
||||||
|
roots = [ "go.mod" ".git" ];
|
||||||
|
package = pkgs.unstable.templ;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
programs.kak-lsp.languages = lib.attrsets.genAttrs [ "html" "css" "json" ] langserver;
|
imports = [ templModule ];
|
||||||
|
|
||||||
|
programs.kak-lsp.languageServers = (builtins.listToAttrs (map langserver [ "html" "css" "json" ])) // {
|
||||||
|
tailwindcss-language-server = tailwind;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ltexLsp = { pkgs, lib, ... }: {
|
||||||
|
programs.kak-lsp.languageServers.ltex-ls = {
|
||||||
|
command = "ltex-ls";
|
||||||
|
args = [ "--log-file=/tmp" ];
|
||||||
|
filetypes = [ "latex" "typst" ];
|
||||||
|
roots = [ "main.tex" "main.typ" ".git" ];
|
||||||
|
package = pkgs.ltex-ls;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ../modules/programs/my-kakoune ./kaktex.nix kak-lsp-frontend ];
|
imports = [ ../modules/programs/my-kakoune ./kaktex.nix kak-lsp-frontend ltexLsp ];
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
# ctags for peneira
|
# ctags for peneira
|
||||||
|
@ -68,7 +76,6 @@ in
|
||||||
programs.my-kakoune.enable = true;
|
programs.my-kakoune.enable = true;
|
||||||
programs.my-kakoune.enable-fish-session = true;
|
programs.my-kakoune.enable-fish-session = true;
|
||||||
programs.kak-lsp.enable = true;
|
programs.kak-lsp.enable = true;
|
||||||
programs.kak-lsp.package = kak-lsp;
|
|
||||||
programs.kak-lsp.semanticTokens.additionalFaces = [
|
programs.kak-lsp.semanticTokens.additionalFaces = [
|
||||||
# Typst
|
# Typst
|
||||||
{ face = "header"; token = "heading"; }
|
{ face = "header"; token = "heading"; }
|
||||||
|
@ -84,13 +91,20 @@ in
|
||||||
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
|
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.kak-lsp.languages.typescript = {
|
programs.kak-lsp.languageServers.elixir-ls = {
|
||||||
|
args = [ ];
|
||||||
|
command = "elixir-ls";
|
||||||
|
filetypes = [ "elixir" ];
|
||||||
|
roots = [ "mix.exs" ];
|
||||||
|
};
|
||||||
|
programs.kak-lsp.languageServers.typescript-language-server = {
|
||||||
args = [ "--stdio" ];
|
args = [ "--stdio" ];
|
||||||
command = "typescript-language-server";
|
command = "typescript-language-server";
|
||||||
filetypes = [ "typescript" ];
|
filetypes = [ "typescript" "javascript" ];
|
||||||
roots = [ "package.json" ];
|
roots = [ "package.json" ];
|
||||||
|
package = pkgs.nodePackages.typescript-language-server;
|
||||||
};
|
};
|
||||||
programs.kak-lsp.languages.fsharp = {
|
programs.kak-lsp.languageServers.fsautocomplete = {
|
||||||
args = [ "--adaptive-lsp-server-enabled" "--project-graph-enabled" "--source-text-factory" "RoslynSourceText" ];
|
args = [ "--adaptive-lsp-server-enabled" "--project-graph-enabled" "--source-text-factory" "RoslynSourceText" ];
|
||||||
command = "fsautocomplete";
|
command = "fsautocomplete";
|
||||||
filetypes = [ "fsharp" ];
|
filetypes = [ "fsharp" ];
|
||||||
|
@ -100,7 +114,7 @@ in
|
||||||
AutomaticWorkspaceInit = true;
|
AutomaticWorkspaceInit = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
programs.kak-lsp.languages.scala = {
|
programs.kak-lsp.languageServers.metals = {
|
||||||
command = "metals";
|
command = "metals";
|
||||||
filetypes = [ "scala" ];
|
filetypes = [ "scala" ];
|
||||||
roots = [ "build.sbt" "build.sc" ];
|
roots = [ "build.sbt" "build.sc" ];
|
||||||
|
@ -110,12 +124,18 @@ in
|
||||||
showInferredType = true;
|
showInferredType = true;
|
||||||
decorationProvider = true;
|
decorationProvider = true;
|
||||||
inlineDecorationProvider = true;
|
inlineDecorationProvider = true;
|
||||||
|
# From kakoune-lsp's own options
|
||||||
|
icons = "unicode";
|
||||||
|
isHttpEnabled = true;
|
||||||
|
statusBarProvider = "log-message";
|
||||||
|
compilerOptions = { overrideDefFormat = "unicode"; };
|
||||||
};
|
};
|
||||||
|
package = pkgs.metals;
|
||||||
};
|
};
|
||||||
programs.kak-lsp.languages.latex = {
|
programs.kak-lsp.languageServers.texlab = {
|
||||||
command = "texlab";
|
command = "texlab";
|
||||||
filetypes = [ "latex" ];
|
filetypes = [ "latex" ];
|
||||||
roots = [ ".git" "main.tex" "all.tex" ];
|
roots = [ "main.tex" "all.tex" ".git" ];
|
||||||
settings_section = "texlab";
|
settings_section = "texlab";
|
||||||
settings.texlab = {
|
settings.texlab = {
|
||||||
build.executable = "latexmk";
|
build.executable = "latexmk";
|
||||||
|
@ -131,16 +151,32 @@ in
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
executable = "${pkgs.zathura}/bin/zathura";
|
executable = "${pkgs.zathura}/bin/zathura";
|
||||||
args = [ "--synctex-forward" "%l:1:%f" "%p" "-x" "/home/nki/.bin/kaktex jump %{input} %{line}" ];
|
args = [ "--synctex-forward" "%l:1:%f" "%p" "-x" "${./kaktex} jump %%{input} %%{line} %%{column}" ];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
package = pkgs.texlab;
|
||||||
};
|
};
|
||||||
programs.kak-lsp.languages.typst = {
|
programs.kak-lsp.languageServers.typst-lsp = {
|
||||||
command = "${pkgs.typst-lsp}/bin/typst-lsp";
|
command = "typst-lsp";
|
||||||
filetypes = [ "typst" ];
|
filetypes = [ "typst" ];
|
||||||
roots = [ ".git" "main.typ" ];
|
roots = [ "main.typ" ".git" ];
|
||||||
settings_section = "typst-lsp";
|
settings_section = "typst-lsp";
|
||||||
settings.typst-lsp = { };
|
settings.typst-lsp = {
|
||||||
|
experimentalFormatterMode = "on";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs.kak-lsp.languageServers.marksman = {
|
||||||
|
command = "marksman";
|
||||||
|
filetypes = [ "markdown" ];
|
||||||
|
roots = [ ".marksman.toml" ".git" ];
|
||||||
|
package = pkgs.marksman;
|
||||||
|
};
|
||||||
|
programs.kak-lsp.languageServers.rust-analyzer = {
|
||||||
|
args = [ ];
|
||||||
|
command = "rust-analyzer";
|
||||||
|
filetypes = [ "rust" ];
|
||||||
|
roots = [ "Cargo.toml" ];
|
||||||
|
package = pkgs.rust-analyzer;
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.my-kakoune.tree-sitter.extraAliases = {
|
programs.my-kakoune.tree-sitter.extraAliases = {
|
||||||
|
@ -159,47 +195,113 @@ in
|
||||||
conditional = "keyword_conditional";
|
conditional = "keyword_conditional";
|
||||||
include = "keyword_control_import";
|
include = "keyword_control_import";
|
||||||
};
|
};
|
||||||
programs.my-kakoune.tree-sitter.languages = {
|
programs.my-kakoune.tree-sitter.languages =
|
||||||
scala =
|
let
|
||||||
let
|
tree-sitter-go = pkgs.fetchFromGitHub {
|
||||||
src = pkgs.fetchFromGitHub {
|
owner = "tree-sitter";
|
||||||
owner = "tree-sitter";
|
repo = "tree-sitter-go";
|
||||||
repo = "tree-sitter-scala";
|
rev = "v0.20.0";
|
||||||
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
|
hash = "sha256-G7d8CHCyKDAb9j6ijRfHk/HlgPqSI+uvkuRIRRvjkHI=";
|
||||||
hash =
|
|
||||||
if pkgs.stdenv.isDarwin
|
|
||||||
then lib.fakeHash
|
|
||||||
else "sha256-xr43ejHGCH4mcjOqxTJpO11LWKcHKAEETt6ZWUG9vo4=";
|
|
||||||
leaveDotGit = true;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
grammar.src = src;
|
|
||||||
queries.src = src;
|
|
||||||
queries.path = "queries/scala";
|
|
||||||
};
|
};
|
||||||
haskell =
|
in
|
||||||
let
|
{
|
||||||
src = pkgs.fetchFromGitHub {
|
scala =
|
||||||
owner = "tree-sitter";
|
let
|
||||||
repo = "tree-sitter-haskell";
|
src = pkgs.fetchFromGitHub {
|
||||||
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
|
owner = "tree-sitter";
|
||||||
sha256 =
|
repo = "tree-sitter-scala";
|
||||||
if pkgs.stdenv.isDarwin
|
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
|
||||||
then "sha256-lW3E4gSZV/m2RfofUqeiCu8KDz06YEvXbYKs8smXFi4="
|
hash = "sha256-bi0Lqo/Zs2Uaz1efuKAARpEDg5Hm59oUe7eSXgL1Wow=";
|
||||||
else "sha256-nocX9L8vD655nzky4PQulygWAjKGC1rh3SYDr7t4wBQ=";
|
};
|
||||||
leaveDotGit = true;
|
in
|
||||||
|
{
|
||||||
|
grammar.src = src;
|
||||||
|
queries.src = src;
|
||||||
|
queries.path = "queries/scala";
|
||||||
};
|
};
|
||||||
in
|
haskell =
|
||||||
{
|
let
|
||||||
grammar.src = src;
|
src = pkgs.fetchFromGitHub {
|
||||||
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "../scanner.c" "../unicode.h" "-I" ".." ];
|
owner = "tree-sitter";
|
||||||
queries.src = src;
|
repo = "tree-sitter-haskell";
|
||||||
|
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
|
||||||
|
hash = "sha256-ZSOF0CLOn82GwU3xgvFefmh/AD2j5zz8I0t5YPwfan0=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
grammar.src = src;
|
||||||
|
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "../scanner.c" "../unicode.h" "-I" ".." ];
|
||||||
|
queries.src = src;
|
||||||
|
queries.path = "queries";
|
||||||
|
};
|
||||||
|
yaml = {
|
||||||
|
grammar.src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "ikatyang";
|
||||||
|
repo = "tree-sitter-yaml";
|
||||||
|
rev = "0e36bed171768908f331ff7dff9d956bae016efb";
|
||||||
|
hash = "sha256-bpiT3FraOZhJaoiFWAoVJX1O+plnIi8aXOW2LwyU23M=";
|
||||||
|
};
|
||||||
|
grammar.compile.args = [ "-c" "-fpic" "../scanner.cc" "../parser.c" "-I" ".." ];
|
||||||
|
grammar.link.args = [ "-shared" "-fpic" "scanner.o" "parser.o" ];
|
||||||
|
grammar.link.flags = [ "-O3" "-lstdc++" ];
|
||||||
|
|
||||||
|
queries.src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "helix-editor";
|
||||||
|
repo = "helix";
|
||||||
|
rev = "dbd248fdfa680373d94fbc10094a160aafa0f7a7";
|
||||||
|
hash = "sha256-wk8qVUDFXhAOi1Ibc6iBMzDCXb6t+YiWZcTd0IJybqc=";
|
||||||
|
};
|
||||||
|
queries.path = "runtime/queries/yaml";
|
||||||
|
};
|
||||||
|
|
||||||
|
templ =
|
||||||
|
let
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "vrischmann";
|
||||||
|
repo = "tree-sitter-templ";
|
||||||
|
rev = "044ad200092170727650fa6d368df66a8da98f9d";
|
||||||
|
hash = "sha256-hJuB3h5pp+LLfP0/7bAYH0uLVo+OQk5jpzJb3J9BNkY=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
grammar.src = src;
|
||||||
|
queries.src = pkgs.runCommandLocal "templ-tree-sitter-queries" { } ''
|
||||||
|
mkdir -p $out/queries
|
||||||
|
# copy most stuff from tree-sitter-templ
|
||||||
|
install -m644 ${src}/queries/templ/* $out/queries
|
||||||
|
# override inherited files
|
||||||
|
cat ${tree-sitter-go}/queries/highlights.scm ${src}/queries/templ/highlights.scm > $out/queries/highlights.scm
|
||||||
|
'';
|
||||||
|
queries.path = "queries";
|
||||||
|
};
|
||||||
|
|
||||||
|
go = {
|
||||||
|
grammar.src = tree-sitter-go;
|
||||||
|
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "-I" ".." ];
|
||||||
|
grammar.link.args = [ "-shared" "-fpic" "parser.o" ];
|
||||||
|
queries.src = tree-sitter-go;
|
||||||
queries.path = "queries";
|
queries.path = "queries";
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
programs.my-kakoune.package = kakounePkg;
|
hylo =
|
||||||
|
let
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "natsukagami";
|
||||||
|
repo = "tree-sitter-hylo";
|
||||||
|
rev = "494cbdff0d13cbc67348316af2efa0286dbddf6f";
|
||||||
|
hash = "sha256-R5UeoglCTl0do3VDJ/liCTeqbxU9slvmVKNRA/el2VY=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
grammar.src = src;
|
||||||
|
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "-I" ".." ];
|
||||||
|
grammar.link.args = [ "-shared" "-fpic" "parser.o" ];
|
||||||
|
queries.src = src;
|
||||||
|
queries.path = "queries";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.my-kakoune.package = pkgs.kakoune;
|
||||||
programs.my-kakoune.rc =
|
programs.my-kakoune.rc =
|
||||||
builtins.readFile ./kakrc + ''
|
builtins.readFile ./kakrc + ''
|
||||||
|
|
||||||
|
@ -211,11 +313,11 @@ in
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.my-kakoune.extraFaces = {
|
programs.my-kakoune.extraFaces = {
|
||||||
Default = "%opt{white},%opt{background}";
|
Default = "%opt{text},%opt{base}";
|
||||||
BufferPadding = "%opt{background},%opt{background}";
|
BufferPadding = "%opt{base},%opt{base}";
|
||||||
MenuForeground = "blue,white+bF";
|
MenuForeground = "%opt{blue},white+bF";
|
||||||
MenuBackground = "bright-blue,white+F";
|
MenuBackground = "%opt{sky},white+F";
|
||||||
Information = "bright-blue,white";
|
Information = "%opt{sky},white";
|
||||||
# Markdown help color scheme
|
# Markdown help color scheme
|
||||||
InfoDefault = "Information";
|
InfoDefault = "Information";
|
||||||
InfoBlock = "@block";
|
InfoBlock = "@block";
|
||||||
|
@ -407,10 +509,7 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
programs.my-kakoune.themes = {
|
programs.my-kakoune.themes = {
|
||||||
catppuccin-latte = builtins.fetchurl {
|
catppuccin-latte = ./catppuccin-latte.kak;
|
||||||
url = "https://raw.githubusercontent.com/catppuccin/kakoune/f6d43770609433c45046632f1bb68d1395305dbb/colors/catppuccin_latte.kak";
|
|
||||||
sha256 = "sha256:0ycvxs8hmsvd0zrpxiby16wzmapvmz6p34b6j343pc1girw6fi4i";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,34 @@
|
||||||
# Enable kak-tree-sitter
|
# Enable kak-tree-sitter
|
||||||
eval %sh{ kak-tree-sitter --kakoune -d --server }
|
eval %sh{test -z "$WE_STARTED_KAK" && kak-tree-sitter --kakoune -d --server --init $kak_session}
|
||||||
## Set some color overrides
|
map global normal <c-t> ": enter-user-mode tree-sitter<ret>"
|
||||||
set global kts_yellow "rgb:e2b75e"
|
# ## Set some color overrides
|
||||||
set global kts_teal "rgb:008080"
|
# set global kts_yellow "rgb:e2b75e"
|
||||||
set global kts_mauve "rgb:c264ff"
|
# set global kts_teal "rgb:008080"
|
||||||
set global kts_sky "rgb:6aa622"
|
# set global kts_mauve "rgb:c264ff"
|
||||||
|
# set global kts_sky "rgb:6aa622"
|
||||||
# Color scheme
|
# Color scheme
|
||||||
colorscheme catppuccin-latte
|
colorscheme catppuccin-latte
|
||||||
set global background default
|
set global base "default"
|
||||||
|
|
||||||
|
# Set indentation guides
|
||||||
|
add-highlighter global/indent-guides show-whitespaces -tab " " -spc " " -lf " " -nbsp " "
|
||||||
|
set-face global Whitespace default,default
|
||||||
|
set-face global WhitespaceIndent +d@comment
|
||||||
|
|
||||||
# Assistant
|
# Assistant
|
||||||
set global ui_options terminal_assistant=cat
|
set global ui_options terminal_assistant=cat
|
||||||
|
|
||||||
# Enable line numbers
|
# Enable line numbers
|
||||||
addhl global/ number-lines
|
hook global WinCreate .* %{
|
||||||
|
addhl window/number-lines number-lines
|
||||||
|
}
|
||||||
|
|
||||||
set global grepcmd "rg --line-number --no-column --no-heading --color=never "
|
set global grepcmd "rg --line-number --no-column --no-heading --color=never "
|
||||||
|
|
||||||
# Floating terminal
|
# Kitty-specific options
|
||||||
# define-command floating-terminal -params 1 -docstring "Open a floating terminal running the given command" %{
|
hook -group windowing global KakBegin .* %{
|
||||||
# evaluate-commands -save-regs 'a' %{
|
set global kitty_window_type os-window
|
||||||
# set-register a %arg{@}
|
}
|
||||||
# evaluate-commands %sh{
|
|
||||||
# alacritty \
|
|
||||||
# --class=alacritty,floating \
|
|
||||||
# -o window.dimensions.lines=24 \
|
|
||||||
# -o window.dimensions.columns=120 \
|
|
||||||
# -e sh -c "$kak_quoted_reg_a" < /dev/null > /dev/null 2>&1 &
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# map global user t -docstring "Open a side terminal on the current directory" ' :iterm-terminal-horizontal fish<ret>'
|
|
||||||
|
|
||||||
# Comment line and block
|
# Comment line and block
|
||||||
map global normal <#> ': comment-line<ret>'
|
map global normal <#> ': comment-line<ret>'
|
||||||
|
@ -43,9 +41,9 @@ map global goto f -docstring "current grep-jump match" '<esc>: grep-jump<ret>'
|
||||||
hook global RegisterModified '"' %{ nop %sh{
|
hook global RegisterModified '"' %{ nop %sh{
|
||||||
printf "%s" "$kak_main_reg_dquote" | pbcopy >/dev/null 2>/dev/null &
|
printf "%s" "$kak_main_reg_dquote" | pbcopy >/dev/null 2>/dev/null &
|
||||||
}}
|
}}
|
||||||
map global user P -docstring "Paste before cursor from clipboard" '! pbpaste<ret>'
|
map global user P -docstring "Paste before cursor from clipboard" '! pbpaste -n | cat<ret>'
|
||||||
map global user p -docstring "Paste after cursor from clipboard" '<a-!> pbpaste<ret>'
|
map global user p -docstring "Paste after cursor from clipboard" '<a-!> pbpaste -n | cat<ret>'
|
||||||
map global user R -docstring "Replace selection with text from clipboard" '<a-d>! pbpaste<ret>'
|
map global user R -docstring "Replace selection with text from clipboard" '<a-d>! pbpaste -n | cat<ret>'
|
||||||
define-command -params 0 -docstring "Copy line down" copyline %{
|
define-command -params 0 -docstring "Copy line down" copyline %{
|
||||||
execute-keys -draft 'xy'%val{count}'P'
|
execute-keys -draft 'xy'%val{count}'P'
|
||||||
}
|
}
|
||||||
|
@ -63,11 +61,13 @@ map global normal D ": delete-current-brackets<ret>"
|
||||||
|
|
||||||
# Tab sizes
|
# Tab sizes
|
||||||
hook global InsertChar \t %{ exec -draft -itersel h@ }
|
hook global InsertChar \t %{ exec -draft -itersel h@ }
|
||||||
set global tabstop 4
|
set global tabstop 2
|
||||||
set global indentwidth 4
|
set global indentwidth 2
|
||||||
hook global WinSetOption filetype=(c|cpp|haskell|nix|yaml) %{
|
|
||||||
set global tabstop 2
|
# Language-specific tabstop with override
|
||||||
set global indentwidth 2
|
hook global WinSetOption filetype=(rust) %{
|
||||||
|
set window tabstop 4
|
||||||
|
set window indentwidth 4
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ctrl + a in insert mode = esc
|
# Ctrl + a in insert mode = esc
|
||||||
|
@ -93,8 +93,9 @@ hook global InsertCompletionHide .* %{
|
||||||
# Enable LSP
|
# Enable LSP
|
||||||
try %{
|
try %{
|
||||||
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
|
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
|
||||||
|
set-option global lsp_cmd "kak-lsp -s %val{session}"
|
||||||
}
|
}
|
||||||
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json) %{
|
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json|markdown|templ|elixir) %{
|
||||||
lsp-enable-window
|
lsp-enable-window
|
||||||
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
|
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
|
||||||
map window normal <c-l> ": enter-user-mode lsp<ret>"
|
map window normal <c-l> ": enter-user-mode lsp<ret>"
|
||||||
|
@ -102,9 +103,16 @@ hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c
|
||||||
map window normal <c-s-h> ": lsp-hover-buffer<ret>"
|
map window normal <c-s-h> ": lsp-hover-buffer<ret>"
|
||||||
# lsp-auto-hover-insert-mode-enable
|
# lsp-auto-hover-insert-mode-enable
|
||||||
set window lsp_hover_anchor true
|
set window lsp_hover_anchor true
|
||||||
|
map global insert <tab> '<a-;>:try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks <lt>tab> }<ret>' -docstring 'Select next snippet placeholder'
|
||||||
|
map global object a '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
|
||||||
|
map global object <a-a> '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
|
||||||
|
map global object f '<a-semicolon>lsp-object Function Method<ret>' -docstring 'LSP function or method'
|
||||||
|
map global object t '<a-semicolon>lsp-object Class Interface Struct<ret>' -docstring 'LSP class interface or struct'
|
||||||
|
map global object d '<a-semicolon>lsp-diagnostic-object --include-warnings<ret>' -docstring 'LSP errors and warnings'
|
||||||
|
map global object D '<a-semicolon>lsp-diagnostic-object<ret>' -docstring 'LSP errors'
|
||||||
}
|
}
|
||||||
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|haskell|nix|fsharp) %{
|
|
||||||
|
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|haskell|nix|fsharp|templ) %{
|
||||||
# Format the document if possible
|
# Format the document if possible
|
||||||
hook window BufWritePre .* %{ lsp-formatting-sync }
|
hook window BufWritePre .* %{ lsp-formatting-sync }
|
||||||
}
|
}
|
||||||
|
@ -150,9 +158,6 @@ hook global WinSetOption filetype=(rust) %{
|
||||||
hook global WinSetOption filetype=(scala) %{
|
hook global WinSetOption filetype=(scala) %{
|
||||||
# Format the document if possible
|
# Format the document if possible
|
||||||
hook -group scala-fmt window BufWritePre .* %{ lsp-formatting-sync }
|
hook -group scala-fmt window BufWritePre .* %{ lsp-formatting-sync }
|
||||||
|
|
||||||
set window tabstop 2
|
|
||||||
set window indentwidth 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hook global WinSetOption filetype=(typst) %{
|
hook global WinSetOption filetype=(typst) %{
|
||||||
|
@ -210,6 +215,16 @@ hook global BufCreate .*[.]typ %{
|
||||||
add-highlighter buffer/ wrap
|
add-highlighter buffer/ wrap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hook global BufCreate .*[.]templ %{
|
||||||
|
set-option buffer filetype templ
|
||||||
|
set-option buffer comment_line "//"
|
||||||
|
}
|
||||||
|
|
||||||
|
hook global BufCreate .*[.]hylo %{
|
||||||
|
set-option buffer filetype hylo
|
||||||
|
set-option buffer comment_line "//"
|
||||||
|
}
|
||||||
|
|
||||||
hook global BufOpenFile .* %{
|
hook global BufOpenFile .* %{
|
||||||
modeline-parse
|
modeline-parse
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
function usage
|
function usage
|
||||||
echo "Usage: "
|
echo "Usage: "
|
||||||
echo " kaktex set [client] [session]"
|
echo " kaktex set [client] [session]"
|
||||||
echo " kaktex jump [file] [line]"
|
echo " kaktex jump [file] [line] [column]"
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if test (count $argv) -ne 3
|
if test (count $argv) -lt 3
|
||||||
usage
|
usage
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ switch $argv[1]
|
||||||
echo "
|
echo "
|
||||||
evaluate-commands -client $_kaktex_client %{
|
evaluate-commands -client $_kaktex_client %{
|
||||||
evaluate-commands -try-client $_kaktex_client %{
|
evaluate-commands -try-client $_kaktex_client %{
|
||||||
edit -- $argv[2] $argv[3]
|
edit -existing -- $argv[2] $(math $argv[3] + 1) $(math $argv[4] + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
" | kak -p $_kaktex_session
|
" | kak -p $_kaktex_session
|
||||||
|
|
|
@ -1,22 +1,12 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
|
||||||
kaktexScript = ./kaktex;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
# Create kak-tex executable
|
|
||||||
home.file.kaktex = {
|
|
||||||
source = kaktexScript;
|
|
||||||
executable = true;
|
|
||||||
target = ".bin/kaktex";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Source kaktex whenever we have a tex file
|
# Source kaktex whenever we have a tex file
|
||||||
programs.my-kakoune.rc = ''
|
programs.my-kakoune.rc = ''
|
||||||
hook global WinSetOption filetype=(tex|latex) %{
|
hook global WinSetOption filetype=(tex|latex) %{
|
||||||
hook window WinDisplay '.*' %{
|
hook window WinDisplay '.*' %{
|
||||||
eval %sh{
|
eval %sh{
|
||||||
${kaktexScript} set $kak_client $kak_session
|
${./kaktex} set $kak_client $kak_session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
{ pkgs, config, lib, ... }:
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
discord =
|
discord = pkgs.armcord.override { nss = pkgs.nss_latest; };
|
||||||
(pkgs.armcord.override { nss = pkgs.nss_latest; }).overrideAttrs (attrs: {
|
|
||||||
postInstall = ''
|
|
||||||
# Wrap the startup command
|
|
||||||
makeWrapper $out/opt/ArmCord/armcord $out/bin/armcord \
|
|
||||||
"''${gappsWrapperArgs[@]}" \
|
|
||||||
--prefix XDG_DATA_DIRS : "${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}/" \
|
|
||||||
--add-flags "--ozone-platform=x11 --enable-features=UseOzonePlatform --enable-features=WebRTCPipeWireCapturer" \
|
|
||||||
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath attrs.buildInputs}" \
|
|
||||||
--suffix PATH : ${lib.makeBinPath [ pkgs.xdg-utils ]}
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -30,7 +19,7 @@ in
|
||||||
home.homeDirectory = "/home/nki";
|
home.homeDirectory = "/home/nki";
|
||||||
|
|
||||||
nki.programs.kitty.enable = true;
|
nki.programs.kitty.enable = true;
|
||||||
nki.programs.kitty.fontSize = 18;
|
nki.programs.kitty.fontSize = 16;
|
||||||
programs.fish.shellInit = lib.mkAfter ''
|
programs.fish.shellInit = lib.mkAfter ''
|
||||||
set -eg MESA_GL_VERSION_OVERRIDE
|
set -eg MESA_GL_VERSION_OVERRIDE
|
||||||
set -eg MESA_GLSL_VERSION_OVERRIDE
|
set -eg MESA_GLSL_VERSION_OVERRIDE
|
||||||
|
@ -53,10 +42,6 @@ in
|
||||||
discord
|
discord
|
||||||
|
|
||||||
typora
|
typora
|
||||||
|
|
||||||
# Java & sbt
|
|
||||||
openjdk11
|
|
||||||
sbt
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# Graphical set up
|
# Graphical set up
|
||||||
|
@ -64,7 +49,7 @@ in
|
||||||
linux.graphical.wallpaper = ./images/wallpaper-macbook.jpg;
|
linux.graphical.wallpaper = ./images/wallpaper-macbook.jpg;
|
||||||
# Enable sway
|
# Enable sway
|
||||||
programs.my-sway.enable = true;
|
programs.my-sway.enable = true;
|
||||||
programs.my-sway.fontSize = 12.0;
|
programs.my-sway.fontSize = 14.0;
|
||||||
programs.my-sway.enableLaptopBars = true;
|
programs.my-sway.enableLaptopBars = true;
|
||||||
programs.my-sway.enableMpd = false;
|
programs.my-sway.enableMpd = false;
|
||||||
programs.my-sway.discord = "${discord}/bin/armcord";
|
programs.my-sway.discord = "${discord}/bin/armcord";
|
||||||
|
@ -72,7 +57,7 @@ in
|
||||||
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
|
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
|
||||||
wayland.windowManager.sway.config.output."eDP-1" = {
|
wayland.windowManager.sway.config.output."eDP-1" = {
|
||||||
mode = "2560x1600@60Hz";
|
mode = "2560x1600@60Hz";
|
||||||
scale = "1.5";
|
scale = "1.25";
|
||||||
subpixel = "vrgb";
|
subpixel = "vrgb";
|
||||||
};
|
};
|
||||||
wayland.windowManager.sway.config.input."1452:641:Apple_Internal_Keyboard_/_Trackpad" = {
|
wayland.windowManager.sway.config.input."1452:641:Apple_Internal_Keyboard_/_Trackpad" = {
|
||||||
|
@ -112,7 +97,7 @@ in
|
||||||
|
|
||||||
home.file.".gnupg/gpg-agent.conf" = {
|
home.file.".gnupg/gpg-agent.conf" = {
|
||||||
text = ''
|
text = ''
|
||||||
pinentry-program ${pkgs.pinentry-gnome}/bin/pinentry-gnome3
|
pinentry-program ${pkgs.pinentry-gnome3}/bin/pinentry-gnome3
|
||||||
'';
|
'';
|
||||||
onChange = ''
|
onChange = ''
|
||||||
echo "Reloading gpg-agent"
|
echo "Reloading gpg-agent"
|
||||||
|
@ -121,10 +106,6 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# Autostart
|
# Autostart
|
||||||
xdg.configFile."autostart/polkit.desktop".text = ''
|
|
||||||
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
|
|
||||||
OnlyShowIn=sway;
|
|
||||||
'';
|
|
||||||
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
||||||
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,20 @@ with lib;
|
||||||
let
|
let
|
||||||
cfg = config.linux.graphical;
|
cfg = config.linux.graphical;
|
||||||
|
|
||||||
|
thunderbird = pkgs.thunderbird-128;
|
||||||
vscode = with pkgs; if stdenv.isAarch64 then unstable.vscode else unstable.vscode-fhs;
|
vscode = with pkgs; if stdenv.isAarch64 then unstable.vscode else unstable.vscode-fhs;
|
||||||
|
|
||||||
alwaysStartup = with pkgs; [ ];
|
wifi-indicator = pkgs.writeScriptBin "wifi-indicator" ''
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
|
set wifi_output (${lib.getExe pkgs.iw} wlan0 link | rg "SSID: (.+)" --replace '🛜 $1' | string trim)
|
||||||
|
|
||||||
|
if test -z $wifi_output
|
||||||
|
echo "❌ not connected"
|
||||||
|
else
|
||||||
|
echo $wifi_output
|
||||||
|
end
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./x11.nix ./wayland.nix ./alacritty.nix ];
|
imports = [ ./x11.nix ./wayland.nix ./alacritty.nix ];
|
||||||
|
@ -23,11 +34,16 @@ in
|
||||||
startup = mkOption {
|
startup = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
description = "List of packages to include in ~/.config/autostart";
|
description = "List of packages to include in ~/.config/autostart";
|
||||||
default = [ ];
|
default = with pkgs; [
|
||||||
|
librewolf
|
||||||
|
thunderbird
|
||||||
|
vesktop
|
||||||
|
premid
|
||||||
|
];
|
||||||
};
|
};
|
||||||
defaults.webBrowser = mkOption {
|
defaults.webBrowser = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "firefox.desktop";
|
default = "librewolf.desktop";
|
||||||
description = "Desktop file of the default web browser";
|
description = "Desktop file of the default web browser";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -42,29 +58,47 @@ in
|
||||||
feh # For images?
|
feh # For images?
|
||||||
deluge # Torrent client
|
deluge # Torrent client
|
||||||
pavucontrol # PulseAudio control panel
|
pavucontrol # PulseAudio control panel
|
||||||
firefox
|
|
||||||
librewolf
|
|
||||||
cinnamon.nemo # File manager
|
|
||||||
thunderbird # Email
|
thunderbird # Email
|
||||||
sublime-music # For navidrome
|
sublime-music # For navidrome
|
||||||
# Note taking
|
# cinny-desktop
|
||||||
obsidian
|
gajim
|
||||||
(logseq.override { electron = pkgs.electron_24; })
|
vivaldi
|
||||||
|
# Audio
|
||||||
|
qpwgraph # Pipewire graph
|
||||||
|
|
||||||
zotero
|
unstable.zotero
|
||||||
libreoffice
|
libreoffice
|
||||||
|
|
||||||
|
mpv # for anki
|
||||||
|
anki-bin
|
||||||
|
|
||||||
|
# Chat stuff
|
||||||
|
tdesktop
|
||||||
|
whatsapp-for-linux
|
||||||
|
slack
|
||||||
|
zoom-us
|
||||||
|
|
||||||
|
librewolf
|
||||||
|
|
||||||
## CLI stuff
|
## CLI stuff
|
||||||
dex # .desktop file management, startup
|
dex # .desktop file management, startup
|
||||||
# sct # Display color temperature
|
# sct # Display color temperature
|
||||||
xdg-utils # Open stuff
|
xdg-utils # Open stuff
|
||||||
] ++ (if pkgs.stdenv.isAarch64 then [ ] else [
|
wifi-indicator
|
||||||
gnome.cheese # Webcam check, expensive
|
]);
|
||||||
# Chat stuff
|
|
||||||
unstable.slack
|
|
||||||
]));
|
|
||||||
|
|
||||||
nki.programs.discord.enable = pkgs.stdenv.isx86_64;
|
nki.programs.discord.enable = pkgs.stdenv.isx86_64;
|
||||||
|
nki.programs.discord.package = pkgs.vesktop;
|
||||||
|
|
||||||
|
# OBS
|
||||||
|
programs.obs-studio = {
|
||||||
|
enable = true;
|
||||||
|
plugins = with pkgs.obs-studio-plugins; [
|
||||||
|
wlrobs
|
||||||
|
input-overlay
|
||||||
|
obs-pipewire-audio-capture
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# Yellow light!
|
# Yellow light!
|
||||||
services.wlsunset = {
|
services.wlsunset = {
|
||||||
|
@ -88,13 +122,33 @@ in
|
||||||
xdg.mimeApps.enable = true;
|
xdg.mimeApps.enable = true;
|
||||||
|
|
||||||
xdg.mimeApps.associations.added = {
|
xdg.mimeApps.associations.added = {
|
||||||
"x-scheme-handler/mailto" = [ "org.gnome.Evolution.desktop" ];
|
"x-scheme-handler/mailto" = [ "thunderbird.desktop" "org.gnome.Evolution.desktop" ];
|
||||||
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
||||||
"text/plain" = [ "kakoune.desktop" ];
|
"text/plain" = [ "kakoune.desktop" ];
|
||||||
|
|
||||||
|
# Other Thunderbird stuff
|
||||||
|
"x-scheme-handler/mid" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/news" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/snews" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/nntp" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
|
||||||
|
"application/rss+xml" = [ "thunderbird.desktop" ];
|
||||||
|
"application/x-extension-rss" = [ "thunderbird.desktop" ];
|
||||||
};
|
};
|
||||||
xdg.mimeApps.defaultApplications = {
|
xdg.mimeApps.defaultApplications = {
|
||||||
# Email
|
# Email
|
||||||
"x-scheme-handler/mailto" = [ "org.gnome.Evolution.desktop" ];
|
"x-scheme-handler/mailto" = [ "thunderbird.desktop" "org.gnome.Evolution.desktop" ];
|
||||||
|
"x-scheme-handler/webcal" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/webcals" = [ "thunderbird.desktop" ];
|
||||||
|
|
||||||
|
# Other Thunderbird stuff
|
||||||
|
"x-scheme-handler/mid" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/news" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/snews" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/nntp" = [ "thunderbird.desktop" ];
|
||||||
|
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
|
||||||
|
"application/rss+xml" = [ "thunderbird.desktop" ];
|
||||||
|
"application/x-extension-rss" = [ "thunderbird.desktop" ];
|
||||||
|
|
||||||
# Default web browser stuff
|
# Default web browser stuff
|
||||||
"text/html" = [ cfg.defaults.webBrowser ];
|
"text/html" = [ cfg.defaults.webBrowser ];
|
||||||
|
@ -104,6 +158,7 @@ in
|
||||||
"x-scheme-handler/https" = [ cfg.defaults.webBrowser ];
|
"x-scheme-handler/https" = [ cfg.defaults.webBrowser ];
|
||||||
"x-scheme-handler/ftp" = [ cfg.defaults.webBrowser ];
|
"x-scheme-handler/ftp" = [ cfg.defaults.webBrowser ];
|
||||||
"x-scheme-handler/ftps" = [ cfg.defaults.webBrowser ];
|
"x-scheme-handler/ftps" = [ cfg.defaults.webBrowser ];
|
||||||
|
"x-scheme-handler/file" = [ cfg.defaults.webBrowser ];
|
||||||
|
|
||||||
# Torrent
|
# Torrent
|
||||||
"application/x-bittorrent" = [ "deluge.desktop" ];
|
"application/x-bittorrent" = [ "deluge.desktop" ];
|
||||||
|
@ -111,10 +166,10 @@ in
|
||||||
|
|
||||||
# Text
|
# Text
|
||||||
"text/plain" = [ "kakoune.desktop" ];
|
"text/plain" = [ "kakoune.desktop" ];
|
||||||
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
"application/pdf" = [ "okularApplication_pdf.desktop" ];
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
"inode/directory" = [ "nemo.desktop" ];
|
"inode/directory" = [ "dolphin.desktop" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Add one for kakoune
|
# Add one for kakoune
|
||||||
|
@ -133,26 +188,37 @@ in
|
||||||
## GTK
|
## GTK
|
||||||
gtk.enable = true;
|
gtk.enable = true;
|
||||||
gtk.cursorTheme = { inherit (config.home.pointerCursor) package name size; };
|
gtk.cursorTheme = { inherit (config.home.pointerCursor) package name size; };
|
||||||
gtk.font.name = "system-ui";
|
gtk.font.name = "IBM Plex Sans JP";
|
||||||
gtk.font.size = 10;
|
gtk.font.size = 10;
|
||||||
gtk.iconTheme = {
|
gtk.iconTheme = {
|
||||||
package = pkgs.numix-icon-theme;
|
package = pkgs.kdePackages.breeze-icons;
|
||||||
name = "Numix";
|
name = "breeze";
|
||||||
};
|
};
|
||||||
gtk.theme = {
|
gtk.theme = {
|
||||||
package = pkgs.numix-gtk-theme;
|
package = pkgs.kdePackages.breeze-gtk;
|
||||||
name = "Numix";
|
name = "Breeze";
|
||||||
};
|
};
|
||||||
|
gtk.gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
|
||||||
|
gtk.gtk2.extraConfig = ''
|
||||||
|
gtk-enable-animations=1
|
||||||
|
gtk-im-module="fcitx"
|
||||||
|
gtk-theme-name="Numix"
|
||||||
|
gtk-primary-button-warps-slider=1
|
||||||
|
gtk-toolbar-style=3
|
||||||
|
gtk-menu-images=1
|
||||||
|
gtk-button-images=1
|
||||||
|
gtk-sound-theme-name="ocean"
|
||||||
|
gtk-icon-theme-name="breeze"
|
||||||
|
'';
|
||||||
|
gtk.gtk3.extraConfig.gtk-im-module = "fcitx";
|
||||||
|
gtk.gtk4.extraConfig.gtk-im-module = "fcitx";
|
||||||
## Qt
|
## Qt
|
||||||
qt.enable = true;
|
qt.enable = true;
|
||||||
qt.platformTheme = "gnome";
|
qt.platformTheme.name = "kde";
|
||||||
qt.style.package = pkgs.adwaita-qt;
|
qt.platformTheme.package = with pkgs.kdePackages; [ plasma-integration systemsettings ];
|
||||||
qt.style.name = "adwaita";
|
qt.style.package = [ pkgs.kdePackages.breeze ];
|
||||||
|
qt.style.name = "Breeze";
|
||||||
|
|
||||||
home.sessionVariables = {
|
|
||||||
# Set up Java font style
|
|
||||||
_JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=lcd";
|
|
||||||
};
|
|
||||||
|
|
||||||
xdg.configFile =
|
xdg.configFile =
|
||||||
let
|
let
|
||||||
|
@ -162,17 +228,22 @@ in
|
||||||
source =
|
source =
|
||||||
let
|
let
|
||||||
srcFile = pkgs.runCommand "${pkg.name}-startup" { } ''
|
srcFile = pkgs.runCommand "${pkg.name}-startup" { } ''
|
||||||
mkdir - p $out
|
mkdir -p $out
|
||||||
cp $
|
cp $(ls -d ${pkg}/share/applications/*.desktop | head -n 1) $out/${pkg.name}.desktop
|
||||||
(ls - d ${
|
|
||||||
pkg}/share/applications/*.desktop | head -n 1) $out/${pkg.name}.desktop
|
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
"${srcFile}/${pkg.name}.desktop";
|
"${srcFile}/${pkg.name}.desktop";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
autoStartup = listToAttrs (map f cfg.startup);
|
||||||
in
|
in
|
||||||
listToAttrs (map f (cfg.startup ++ alwaysStartup));
|
autoStartup // {
|
||||||
|
## Polkit UI
|
||||||
|
"autostart/polkit.desktop".text = ''
|
||||||
|
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
|
||||||
|
OnlyShowIn=sway;
|
||||||
|
'';
|
||||||
|
};
|
||||||
# IBus configuration
|
# IBus configuration
|
||||||
# dconf.settings."desktop/ibus/general" = {
|
# dconf.settings."desktop/ibus/general" = {
|
||||||
# engines-order = hm.gvariant.mkArray hm.gvariant.type.string [ "xkb:jp::jpn" "mozc-jp" "Bamboo" ];
|
# engines-order = hm.gvariant.mkArray hm.gvariant.type.string [ "xkb:jp::jpn" "mozc-jp" "Bamboo" ];
|
||||||
|
|
|
@ -2,31 +2,19 @@
|
||||||
let
|
let
|
||||||
notificationModule = { config, pkgs, lib, ... }:
|
notificationModule = { config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
swaync = pkgs.unstable.swaynotificationcenter;
|
swaync = pkgs.swaynotificationcenter;
|
||||||
in
|
in
|
||||||
with lib; mkIf (config.linux.graphical.type == "wayland") {
|
with lib; mkIf (config.linux.graphical.type == "wayland") {
|
||||||
home.packages = [ swaync ];
|
services.swaync = {
|
||||||
wayland.windowManager.sway.config = {
|
enable = true;
|
||||||
startup = [
|
settings.widgets = [ "inhibitors" "title" "dnd" "mpris" "notifications" ];
|
||||||
{ command = "swaync"; }
|
style = ./swaync.css;
|
||||||
];
|
|
||||||
};
|
|
||||||
xdg.configFile = {
|
|
||||||
"swaync/config.json" = {
|
|
||||||
text = builtins.toJSON {
|
|
||||||
widgets = [ "inhibitors" "title" "dnd" "mpris" "notifications" ];
|
|
||||||
scripts = { };
|
|
||||||
};
|
|
||||||
onChange = "swaync-client -R";
|
|
||||||
};
|
|
||||||
"swaync/style.css" = {
|
|
||||||
source = ./swaync.css;
|
|
||||||
onChange = "swaync-client -rs";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
systemd.user.services.swaync.Install.WantedBy = lib.mkForce [ "sway-session.target" ];
|
||||||
|
systemd.user.services.swaync.Unit.PartOf = lib.mkForce [ "sway-session.target" ];
|
||||||
|
|
||||||
programs.my-sway.waybar = {
|
programs.my-sway.waybar = {
|
||||||
extraSettings = {
|
extraSettings = [{
|
||||||
modules-right = mkAfter [ "custom/swaync" ];
|
modules-right = mkAfter [ "custom/swaync" ];
|
||||||
modules."custom/swaync" = {
|
modules."custom/swaync" = {
|
||||||
tooltip = false;
|
tooltip = false;
|
||||||
|
@ -48,21 +36,35 @@ let
|
||||||
on-click-right = "${swaync}/bin/swaync-client -d -sw";
|
on-click-right = "${swaync}/bin/swaync-client -d -sw";
|
||||||
escape = true;
|
escape = true;
|
||||||
};
|
};
|
||||||
};
|
}];
|
||||||
extraStyle = mkAfter ''
|
extraStyle = mkAfter ''
|
||||||
#custom-swaync {
|
#custom-swaync {
|
||||||
padding: 0 10px;
|
|
||||||
margin: 0 5px;
|
|
||||||
background: #F0FFFF;
|
background: #F0FFFF;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
plasmaModule = { pkgs, ... }: {
|
||||||
|
home.packages = with pkgs.kdePackages; [
|
||||||
|
discover
|
||||||
|
kmail
|
||||||
|
kontact
|
||||||
|
akonadi
|
||||||
|
kdepim-runtime
|
||||||
|
kmail-account-wizard
|
||||||
|
akonadi-import-wizard
|
||||||
|
];
|
||||||
|
xdg.configFile."plasma-workspace/env/wayland.sh".source = pkgs.writeScript "plasma-wayland-env.sh" ''
|
||||||
|
export NIXOS_OZONE_WL=1
|
||||||
|
'';
|
||||||
|
xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source = "${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service";
|
||||||
|
};
|
||||||
in
|
in
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
imports = [ notificationModule ];
|
imports = [ notificationModule plasmaModule ];
|
||||||
config = mkIf (config.linux.graphical.type == "wayland") {
|
config = mkIf (config.linux.graphical.type == "wayland") {
|
||||||
# Additional packages
|
# Additional packages
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
|
@ -70,13 +72,17 @@ with lib;
|
||||||
|
|
||||||
# Mimic the clipboard stuff in MacOS
|
# Mimic the clipboard stuff in MacOS
|
||||||
(pkgs.writeShellScriptBin "pbcopy" ''
|
(pkgs.writeShellScriptBin "pbcopy" ''
|
||||||
exec ${pkgs.wl-clipboard}/bin/wl-copy
|
exec ${pkgs.wl-clipboard}/bin/wl-copy "$@"
|
||||||
'')
|
'')
|
||||||
(pkgs.writeShellScriptBin "pbpaste" ''
|
(pkgs.writeShellScriptBin "pbpaste" ''
|
||||||
exec ${pkgs.wl-clipboard}/bin/wl-paste -n
|
exec ${pkgs.wl-clipboard}/bin/wl-paste "$@"
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
ANKI_WAYLAND = "1";
|
||||||
|
};
|
||||||
|
|
||||||
# Notification system
|
# Notification system
|
||||||
# services.dunst = {
|
# services.dunst = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
let
|
let
|
||||||
monitors = {
|
monitors = {
|
||||||
# Internal
|
# Internal
|
||||||
|
"framework" = {
|
||||||
|
name = "BOE 0x0BCA Unknown";
|
||||||
|
mode = "2256x1504@60Hz";
|
||||||
|
scale = 1.25;
|
||||||
|
};
|
||||||
# External
|
# External
|
||||||
## Work @ EPFL
|
## Work @ EPFL
|
||||||
"work" = {
|
"work" = {
|
||||||
|
|
|
@ -44,14 +44,16 @@ in
|
||||||
set -gx EDITOR "kak"
|
set -gx EDITOR "kak"
|
||||||
alias e="kak"
|
alias e="kak"
|
||||||
'';
|
'';
|
||||||
|
};
|
||||||
_tide_item_kakoune = ''
|
programs.fish.tide = {
|
||||||
|
items.kakoune = ''
|
||||||
if set -q kak_session
|
if set -q kak_session
|
||||||
set -U tide_kakoune_color FFA500
|
set -U tide_kakoune_color FFA500
|
||||||
set -U tide_kakoune_bg_color normal
|
set -U tide_kakoune_bg_color normal
|
||||||
_tide_print_item kakoune " " "e[$kak_session]"
|
_tide_print_item kakoune " " "e[$kak_session]"
|
||||||
end
|
end
|
||||||
'';
|
'';
|
||||||
|
rightItems = mkAfter [ "kakoune" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,52 +4,23 @@ with lib;
|
||||||
let
|
let
|
||||||
lspConfig =
|
lspConfig =
|
||||||
{
|
{
|
||||||
language = {
|
language_ids = {
|
||||||
bash = {
|
c = "c_cpp";
|
||||||
args = [ "start" ];
|
cpp = "c_cpp";
|
||||||
command = "bash-language-server";
|
javascript = "javascriptreact";
|
||||||
filetypes = [ "sh" ];
|
typescript = "typescriptreact";
|
||||||
roots = [ ".git" ".hg" ];
|
protobuf = "proto";
|
||||||
};
|
sh = "shellscript";
|
||||||
c_cpp = {
|
};
|
||||||
|
|
||||||
|
language_servers = {
|
||||||
|
ccls = {
|
||||||
args = [ "-v=2" "-log-file=/tmp/ccls.log" ];
|
args = [ "-v=2" "-log-file=/tmp/ccls.log" ];
|
||||||
command = "ccls";
|
command = "ccls";
|
||||||
filetypes = [ "c" "cpp" ];
|
filetypes = [ "c" "cpp" ];
|
||||||
roots = [ "compile_commands.json" ".cquery" ".git" ];
|
roots = [ "compile_commands.json" ".cquery" ".git" ];
|
||||||
};
|
};
|
||||||
crystal = {
|
gopls = {
|
||||||
command = "scry";
|
|
||||||
filetypes = [ "crystal" ];
|
|
||||||
roots = [ "shard.yml" ];
|
|
||||||
};
|
|
||||||
css = {
|
|
||||||
args = [ "--stdio" ];
|
|
||||||
command = "css-languageserver";
|
|
||||||
filetypes = [ "css" ];
|
|
||||||
roots = [ "package.json" ];
|
|
||||||
};
|
|
||||||
d = {
|
|
||||||
command = "dls";
|
|
||||||
filetypes = [ "d" "di" ];
|
|
||||||
roots = [ ".git" "dub.sdl" "dub.json" ];
|
|
||||||
};
|
|
||||||
dart = {
|
|
||||||
command = "dart_language_server";
|
|
||||||
filetypes = [ "dart" ];
|
|
||||||
roots = [ "pubspec.yaml" ".git" ];
|
|
||||||
};
|
|
||||||
elm = {
|
|
||||||
args = [ "--stdio" ];
|
|
||||||
command = "elm-language-server";
|
|
||||||
filetypes = [ "elm" ];
|
|
||||||
roots = [ "elm.json" ];
|
|
||||||
};
|
|
||||||
fsharp = {
|
|
||||||
command = "FSharpLanguageServer";
|
|
||||||
filetypes = [ "fsharp" ];
|
|
||||||
roots = [ ".git" "*.fsx" ];
|
|
||||||
};
|
|
||||||
go = {
|
|
||||||
command = "gopls";
|
command = "gopls";
|
||||||
filetypes = [ "go" ];
|
filetypes = [ "go" ];
|
||||||
offset_encoding = "utf-8";
|
offset_encoding = "utf-8";
|
||||||
|
@ -57,101 +28,27 @@ let
|
||||||
settings = { gopls = { hoverKind = "SynopsisDocumentation"; semanticTokens = true; }; };
|
settings = { gopls = { hoverKind = "SynopsisDocumentation"; semanticTokens = true; }; };
|
||||||
settings_section = "gopls";
|
settings_section = "gopls";
|
||||||
};
|
};
|
||||||
haskell = {
|
haskell-language-server = {
|
||||||
args = [ "--lsp" ];
|
args = [ "--lsp" ];
|
||||||
command = "haskell-language-server-wrapper";
|
command = "haskell-language-server-wrapper";
|
||||||
filetypes = [ "haskell" ];
|
filetypes = [ "haskell" ];
|
||||||
roots = [ "Setup.hs" "stack.yaml" "*.cabal" "package.yaml" ];
|
roots = [ "Setup.hs" "stack.yaml" "*.cabal" "package.yaml" ];
|
||||||
settings_section = "haskell";
|
settings_section = "haskell";
|
||||||
};
|
};
|
||||||
html = {
|
nil = {
|
||||||
args = [ "--stdio" ];
|
command = "${pkgs.nil}/bin/nil";
|
||||||
command = "html-languageserver";
|
|
||||||
filetypes = [ "html" ];
|
|
||||||
roots = [ "package.json" ];
|
|
||||||
};
|
|
||||||
javascript = {
|
|
||||||
args = [ "lsp" ];
|
|
||||||
command = "flow";
|
|
||||||
filetypes = [ "javascript" ];
|
|
||||||
roots = [ ".flowconfig" ];
|
|
||||||
};
|
|
||||||
json = {
|
|
||||||
args = [ "--stdio" ];
|
|
||||||
command = "json-languageserver";
|
|
||||||
filetypes = [ "json" ];
|
|
||||||
roots = [ "package.json" ];
|
|
||||||
};
|
|
||||||
latex = {
|
|
||||||
command = "texlab";
|
|
||||||
filetypes = [ "latex" ];
|
|
||||||
roots = [ ".git" "main.tex" "all.tex" ];
|
|
||||||
settings_section = "texlab";
|
|
||||||
settings.texlab = {
|
|
||||||
build.executable = "latexmk";
|
|
||||||
build.args = [ "-pdf" "-shell-escape" "-interaction=nonstopmode" "-synctex=1" "%f" ];
|
|
||||||
|
|
||||||
build.forwardSearchAfter = true;
|
|
||||||
build.onSave = true;
|
|
||||||
|
|
||||||
forwardSearch = {
|
|
||||||
executable = "/Applications/Skim.app/Contents/SharedSupport/displayline";
|
|
||||||
args = [ "-r" "-g" "%l" "%p" "%f" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
nim = {
|
|
||||||
command = "nimlsp";
|
|
||||||
filetypes = [ "nim" ];
|
|
||||||
roots = [ "*.nimble" ".git" ];
|
|
||||||
};
|
|
||||||
nix = {
|
|
||||||
command = "rnix-lsp";
|
|
||||||
filetypes = [ "nix" ];
|
filetypes = [ "nix" ];
|
||||||
roots = [ "flake.nix" "shell.nix" ".git" ];
|
roots = [ "flake.nix" "shell.nix" ".git" ];
|
||||||
|
settings.nil = {
|
||||||
|
formatting.command = [ "${getExe pkgs.nixpkgs-fmt}" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
ocaml = {
|
pyls = {
|
||||||
args = [ ];
|
|
||||||
command = "ocamllsp";
|
|
||||||
filetypes = [ "ocaml" ];
|
|
||||||
roots = [ "Makefile" "opam" "*.opam" "dune" ".merlin" ".ocamlformat" ];
|
|
||||||
};
|
|
||||||
php = {
|
|
||||||
args = [ "--stdio" ];
|
|
||||||
command = "intelephense";
|
|
||||||
filetypes = [ "php" ];
|
|
||||||
roots = [ ".htaccess" "composer.json" ];
|
|
||||||
};
|
|
||||||
python = {
|
|
||||||
command = "pyls";
|
command = "pyls";
|
||||||
filetypes = [ "python" ];
|
filetypes = [ "python" ];
|
||||||
offset_encoding = "utf-8";
|
offset_encoding = "utf-8";
|
||||||
roots = [ "requirements.txt" "setup.py" ".git" ".hg" ];
|
roots = [ "requirements.txt" "setup.py" ".git" ".hg" ];
|
||||||
};
|
};
|
||||||
racket = {
|
|
||||||
args = [ "-l" "racket-langserver" ];
|
|
||||||
command = "racket";
|
|
||||||
filetypes = [ "racket" ];
|
|
||||||
roots = [ ".git" ];
|
|
||||||
};
|
|
||||||
reason = {
|
|
||||||
args = [ "--stdio" ];
|
|
||||||
command = "ocaml-language-server";
|
|
||||||
filetypes = [ "reason" ];
|
|
||||||
roots = [ "package.json" "Makefile" ".git" ".hg" ];
|
|
||||||
};
|
|
||||||
ruby = {
|
|
||||||
args = [ "stdio" ];
|
|
||||||
command = "solargraph";
|
|
||||||
filetypes = [ "ruby" ];
|
|
||||||
roots = [ "Gemfile" ];
|
|
||||||
};
|
|
||||||
rust = {
|
|
||||||
args = [ ];
|
|
||||||
command = "rust-analyzer";
|
|
||||||
filetypes = [ "rust" ];
|
|
||||||
roots = [ "Cargo.toml" ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
semantic_tokens.faces = [
|
semantic_tokens.faces = [
|
||||||
## Items
|
## Items
|
||||||
|
@ -188,7 +85,7 @@ let
|
||||||
verbosity = 255;
|
verbosity = 255;
|
||||||
};
|
};
|
||||||
|
|
||||||
languageOption = types.submodule {
|
languageServerOption = types.submodule {
|
||||||
options = {
|
options = {
|
||||||
filetypes = mkOption {
|
filetypes = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
|
@ -222,10 +119,28 @@ let
|
||||||
default = null;
|
default = null;
|
||||||
description = "Additional settings to be passed to the LSP server.";
|
description = "Additional settings to be passed to the LSP server.";
|
||||||
};
|
};
|
||||||
|
package = mkOption {
|
||||||
|
type = types.nullOr types.package;
|
||||||
|
default = null;
|
||||||
|
description = "The default package of the language server. Will be appended as the ending segments of the PATH to kak-lsp";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg = config.programs.kak-lsp;
|
cfg = config.programs.kak-lsp;
|
||||||
|
|
||||||
|
serverPackages =
|
||||||
|
filter (v: v != null)
|
||||||
|
(lib.mapAttrsToList (_: serv: serv.package) cfg.languageServers);
|
||||||
|
|
||||||
|
wrappedPackage = pkgs.symlinkJoin {
|
||||||
|
name = "kak-lsp-wrapped";
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
paths = [ cfg.package ];
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram $out/bin/kak-lsp --suffix PATH ":" ${lib.makeBinPath serverPackages}
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.programs.kak-lsp = {
|
options.programs.kak-lsp = {
|
||||||
|
@ -259,35 +174,40 @@ in
|
||||||
description = "Server timeout";
|
description = "Server timeout";
|
||||||
};
|
};
|
||||||
|
|
||||||
languages = mkOption {
|
languageServers = mkOption {
|
||||||
type = types.attrsOf languageOption;
|
type = types.attrsOf languageServerOption;
|
||||||
default = { };
|
default = { };
|
||||||
description = "The language options";
|
description = "The language options";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
languageIds = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Language IDs to be sent to the LSP";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable
|
||||||
home.packages = [ cfg.package ];
|
{
|
||||||
|
home.packages = [ wrappedPackage ];
|
||||||
|
|
||||||
# Configurations
|
# Configurations
|
||||||
xdg.configFile."kak-lsp/kak-lsp.toml" = {
|
xdg.configFile."kak-lsp/kak-lsp.toml" =
|
||||||
source = pkgs.runCommand "config.toml"
|
let
|
||||||
|
toml = pkgs.formats.toml { };
|
||||||
|
toLspConfig = lib.filterAttrsRecursive (n: v: n != "package" && v != null);
|
||||||
|
in
|
||||||
{
|
{
|
||||||
buildInputs = [ pkgs.yj ];
|
source = toml.generate "config.toml"
|
||||||
preferLocalBuild = true;
|
{
|
||||||
} ''
|
|
||||||
yj -jt -i \
|
|
||||||
< ${
|
|
||||||
pkgs.writeText "config.json" (builtins.toJSON {
|
|
||||||
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
|
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
|
||||||
server.timeout = cfg.serverTimeout;
|
server.timeout = cfg.serverTimeout;
|
||||||
snippet_support = cfg.enableSnippets;
|
snippet_support = cfg.enableSnippets;
|
||||||
verbosity = 255;
|
verbosity = 255;
|
||||||
language = lspConfig.language // cfg.languages;
|
language_server = toLspConfig (lspConfig.language_servers // cfg.languageServers);
|
||||||
})
|
language_ids = lspConfig.language_ids // cfg.languageIds;
|
||||||
} \
|
};
|
||||||
> $out
|
};
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,83 +43,96 @@ in
|
||||||
};
|
};
|
||||||
package = mkPackageOption pkgs "kak-tree-sitter" { };
|
package = mkPackageOption pkgs "kak-tree-sitter" { };
|
||||||
|
|
||||||
|
features = {
|
||||||
|
highlighting = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Enable highlighting";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
text_objects = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Enable text objects";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
highlighterGroups = mkOption {
|
highlighterGroups = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = {
|
default = {
|
||||||
attribute = "@attribute";
|
attribute = "@attribute";
|
||||||
comment = "@comment";
|
comment = "@comment";
|
||||||
conceal = "%opt{kts_mauve}+i";
|
conceal = "%opt{mauve}+i";
|
||||||
constant = "%opt{kts_peach}";
|
constant = "%opt{peach}";
|
||||||
constant_builtin_boolean = "%opt{kts_sky}";
|
constant_builtin_boolean = "%opt{sky}";
|
||||||
constant_character = "%opt{kts_yellow}";
|
constant_character = "%opt{yellow}";
|
||||||
constant_macro = "%opt{kts_mauve}";
|
constant_macro = "%opt{mauve}";
|
||||||
constant_numeric = "%opt{kts_peach}";
|
constant_numeric = "%opt{peach}";
|
||||||
constructor = "%opt{kts_sapphire}";
|
constructor = "%opt{sapphire}";
|
||||||
diff_plus = "%opt{kts_green}";
|
diff_plus = "%opt{green}";
|
||||||
diff_minus = "%opt{kts_red}";
|
diff_minus = "%opt{red}";
|
||||||
diff_delta = "%opt{kts_blue}";
|
diff_delta = "%opt{blue}";
|
||||||
diff_delta_moved = "%opt{kts_mauve}";
|
diff_delta_moved = "%opt{mauve}";
|
||||||
error = "%opt{kts_red}+b";
|
error = "%opt{red}+b";
|
||||||
function = "@function";
|
function = "@function";
|
||||||
function_builtin = "@builtin";
|
function_builtin = "@builtin";
|
||||||
function_macro = "+i@ts_function";
|
function_macro = "+i@ts_function";
|
||||||
hint = "%opt{kts_blue}+b";
|
hint = "%opt{blue}+b";
|
||||||
info = "%opt{kts_green}+b";
|
info = "%opt{green}+b";
|
||||||
keyword = "keyword";
|
keyword = "keyword";
|
||||||
keyword_conditional = "+i@ts_keyword";
|
keyword_conditional = "+i@ts_keyword";
|
||||||
keyword_control_conditional = "+i@ts_keyword";
|
keyword_control_conditional = "+i@ts_keyword";
|
||||||
keyword_control_directive = "+i@ts_keyword";
|
keyword_control_directive = "+i@ts_keyword";
|
||||||
keyword_control_import = "+i@ts_keyword";
|
keyword_control_import = "+i@ts_keyword";
|
||||||
keyword_directive = "+i@ts_keyword";
|
keyword_directive = "+i@ts_keyword";
|
||||||
label = "%opt{kts_sapphire}+i";
|
label = "%opt{sapphire}+i";
|
||||||
markup_bold = "%opt{kts_peach}+b";
|
markup_bold = "%opt{peach}+b";
|
||||||
markup_heading = "%opt{kts_red}";
|
markup_heading = "%opt{red}";
|
||||||
markup_heading_1 = "%opt{kts_red}";
|
markup_heading_1 = "%opt{red}";
|
||||||
markup_heading_2 = "%opt{kts_mauve}";
|
markup_heading_2 = "%opt{mauve}";
|
||||||
markup_heading_3 = "%opt{kts_green}";
|
markup_heading_3 = "%opt{green}";
|
||||||
markup_heading_4 = "%opt{kts_yellow}";
|
markup_heading_4 = "%opt{yellow}";
|
||||||
markup_heading_5 = "%opt{kts_pink}";
|
markup_heading_5 = "%opt{pink}";
|
||||||
markup_heading_6 = "%opt{kts_teal}";
|
markup_heading_6 = "%opt{teal}";
|
||||||
markup_heading_marker = "%opt{kts_peach}+b";
|
markup_heading_marker = "%opt{peach}+b";
|
||||||
markup_italic = "%opt{kts_pink}+i";
|
markup_italic = "%opt{pink}+i";
|
||||||
markup_list_checked = "%opt{kts_green}";
|
markup_list_checked = "%opt{green}";
|
||||||
markup_list_numbered = "%opt{kts_blue}+i";
|
markup_list_numbered = "%opt{blue}+i";
|
||||||
markup_list_unchecked = "%opt{kts_teal}";
|
markup_list_unchecked = "%opt{teal}";
|
||||||
markup_list_unnumbered = "%opt{kts_mauve}";
|
markup_list_unnumbered = "%opt{mauve}";
|
||||||
markup_link_label = "%opt{kts_blue}";
|
markup_link_label = "%opt{blue}";
|
||||||
markup_link_url = "%opt{kts_teal}+u";
|
markup_link_url = "%opt{teal}+u";
|
||||||
markup_link_uri = "%opt{kts_teal}+u";
|
markup_link_uri = "%opt{teal}+u";
|
||||||
markup_link_text = "%opt{kts_blue}";
|
markup_link_text = "%opt{blue}";
|
||||||
markup_quote = "%opt{kts_gray1}";
|
markup_quote = "%opt{crust}";
|
||||||
markup_raw = "%opt{kts_sky}";
|
markup_raw = "%opt{sky}";
|
||||||
markup_raw_block = "%opt{kts_sky}";
|
markup_raw_block = "%opt{sky}";
|
||||||
markup_raw_inline = "%opt{kts_green}";
|
markup_raw_inline = "%opt{green}";
|
||||||
markup_strikethrough = "%opt{kts_gray1}+s";
|
markup_strikethrough = "%opt{crust}+s";
|
||||||
namespace = "@module";
|
namespace = "@module";
|
||||||
operator = "@operator";
|
operator = "@operator";
|
||||||
property = "%opt{kts_sky}";
|
property = "%opt{sky}";
|
||||||
punctuation = "%opt{kts_overlay2}";
|
punctuation = "%opt{overlay2}";
|
||||||
punctuation_special = "%opt{kts_sky}";
|
punctuation_special = "%opt{sky}";
|
||||||
special = "%opt{kts_blue}";
|
special = "%opt{blue}";
|
||||||
spell = "%opt{kts_mauve}";
|
spell = "%opt{mauve}";
|
||||||
string = "%opt{kts_green}";
|
string = "%opt{green}";
|
||||||
string_regex = "%opt{kts_peach}";
|
string_regex = "%opt{peach}";
|
||||||
string_regexp = "%opt{kts_peach}";
|
string_regexp = "%opt{peach}";
|
||||||
string_escape = "%opt{kts_mauve}";
|
string_escape = "%opt{mauve}";
|
||||||
string_special = "%opt{kts_blue}";
|
string_special = "%opt{blue}";
|
||||||
string_special_path = "%opt{kts_green}";
|
string_special_path = "%opt{green}";
|
||||||
string_special_symbol = "%opt{kts_mauve}";
|
string_special_symbol = "%opt{mauve}";
|
||||||
string_symbol = "%opt{kts_red}";
|
string_symbol = "%opt{red}";
|
||||||
tag = "%opt{kts_teal}";
|
tag = "%opt{teal}";
|
||||||
tag_error = "%opt{kts_red}";
|
tag_error = "%opt{red}";
|
||||||
text_title = "%opt{kts_mauve}";
|
text_title = "%opt{mauve}";
|
||||||
type = "%opt{kts_yellow}";
|
type = "@type";
|
||||||
type_enum_variant = "%opt{kts_flamingo}";
|
type_enum_variant = "+i@ts_type";
|
||||||
variable = "@variable";
|
variable = "@variable";
|
||||||
variable_builtin = "@builtin";
|
variable_builtin = "@builtin";
|
||||||
variable_other_member = "%opt{kts_teal}";
|
variable_other_member = "%opt{teal}";
|
||||||
variable_parameter = "%opt{kts_maroon}+i";
|
variable_parameter = "+i@variable";
|
||||||
warning = "%opt{kts_peach}+b";
|
warning = "%opt{peach}+b";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,8 +187,6 @@ in
|
||||||
|
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
aliasedOnce = name: values: if asserts.assertMsg (builtins.length values 1) "face ${name} was aliased more than once: ${toString values}" then (builtins.head values) else [ ];
|
|
||||||
|
|
||||||
allGroups = attrsets.recursiveUpdate cfg.highlighterGroups cfg.extraHighlighterGroups;
|
allGroups = attrsets.recursiveUpdate cfg.highlighterGroups cfg.extraHighlighterGroups;
|
||||||
|
|
||||||
aliases = attrsets.recursiveUpdate cfg.aliases cfg.extraAliases;
|
aliases = attrsets.recursiveUpdate cfg.aliases cfg.extraAliases;
|
||||||
|
@ -189,10 +200,24 @@ in
|
||||||
|
|
||||||
toml = pkgs.formats.toml { };
|
toml = pkgs.formats.toml { };
|
||||||
|
|
||||||
|
srcName = src: lib.removePrefix "/nix/store/" src.outPath;
|
||||||
|
mkGitRepo = src: pkgs.runCommandLocal "${src.name}-git" { } ''
|
||||||
|
cp -r --no-preserve=all ${src} $out
|
||||||
|
cd $out
|
||||||
|
if ! test -d $out/.git; then
|
||||||
|
${lib.getExe pkgs.git} init -b ${srcName src}
|
||||||
|
${lib.getExe pkgs.git} config user.email "a@b.com"
|
||||||
|
${lib.getExe pkgs.git} config user.name "a"
|
||||||
|
${lib.getExe pkgs.git} add .
|
||||||
|
${lib.getExe pkgs.git} commit -m "Just making a git commit"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
toLanguageConf = name: lang: with lang; {
|
toLanguageConf = name: lang: with lang; {
|
||||||
grammar = {
|
grammar = {
|
||||||
inherit (grammar) path;
|
inherit (grammar) path;
|
||||||
url = "${grammar.src}";
|
source.git.url = "${mkGitRepo grammar.src}";
|
||||||
|
source.git.pin = "${srcName grammar.src}";
|
||||||
compile = grammar.compile.command;
|
compile = grammar.compile.command;
|
||||||
compile_args = grammar.compile.args;
|
compile_args = grammar.compile.args;
|
||||||
compile_flags = grammar.compile.flags;
|
compile_flags = grammar.compile.flags;
|
||||||
|
@ -201,7 +226,8 @@ in
|
||||||
link_flags = grammar.link.flags;
|
link_flags = grammar.link.flags;
|
||||||
};
|
};
|
||||||
queries = {
|
queries = {
|
||||||
url = "${queries.src}";
|
source.git.url = "${mkGitRepo queries.src}";
|
||||||
|
source.git.pin = "${srcName queries.src}";
|
||||||
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
|
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -220,19 +246,14 @@ in
|
||||||
xdg.configFile."kak-tree-sitter/config.toml" = {
|
xdg.configFile."kak-tree-sitter/config.toml" = {
|
||||||
source = toml.generate "config.toml" {
|
source = toml.generate "config.toml" {
|
||||||
highlight.groups = builtins.map toScm (builtins.attrNames allGroups ++ builtins.attrNames aliases);
|
highlight.groups = builtins.map toScm (builtins.attrNames allGroups ++ builtins.attrNames aliases);
|
||||||
|
features = cfg.features;
|
||||||
language = builtins.mapAttrs toLanguageConf cfg.languages;
|
language = builtins.mapAttrs toLanguageConf cfg.languages;
|
||||||
};
|
};
|
||||||
|
|
||||||
onChange =
|
onChange = ''
|
||||||
let
|
export PATH=$PATH:${lib.getBin pkgs.gcc}
|
||||||
buildCmd = lang: "ktsctl -fci ${lang}";
|
${cfg.package}/bin/ktsctl sync -a
|
||||||
buildAll = strings.concatMapStringsSep "\n" buildCmd (builtins.attrNames cfg.languages);
|
'';
|
||||||
in
|
|
||||||
''
|
|
||||||
# Rebuild languages
|
|
||||||
${buildAll}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.my-kakoune.extraFaces = faces;
|
programs.my-kakoune.extraFaces = faces;
|
||||||
|
|
|
@ -2,11 +2,20 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.nki.programs.kitty;
|
cfg = config.nki.programs.kitty;
|
||||||
cmd = if pkgs.stdenv.isDarwin then "cmd" else "ctrl";
|
|
||||||
|
theme = { lib, options, config, ... }: {
|
||||||
|
programs.kitty = lib.mkIf config.nki.programs.kitty.enable (
|
||||||
|
if builtins.hasAttr "themeFile" options.programs.kitty then {
|
||||||
|
themeFile = "ayu_light";
|
||||||
|
} else {
|
||||||
|
theme = "Ayu Light";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
in
|
in
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
imports = [ ./darwin.nix ./linux.nix ./tabs.nix ];
|
imports = [ theme ./darwin.nix ./linux.nix ./tabs.nix ];
|
||||||
|
|
||||||
options.nki.programs.kitty = {
|
options.nki.programs.kitty = {
|
||||||
enable = mkEnableOption "Enable kitty";
|
enable = mkEnableOption "Enable kitty";
|
||||||
|
@ -51,8 +60,6 @@ with lib;
|
||||||
font.name = "Fantasque Sans Mono";
|
font.name = "Fantasque Sans Mono";
|
||||||
font.size = cfg.fontSize;
|
font.size = cfg.fontSize;
|
||||||
|
|
||||||
theme = "Ayu Light";
|
|
||||||
|
|
||||||
settings =
|
settings =
|
||||||
let
|
let
|
||||||
# Background color and transparency
|
# Background color and transparency
|
||||||
|
@ -93,6 +100,18 @@ with lib;
|
||||||
## Hints
|
## Hints
|
||||||
"${cfg.cmd}+shift+p>n" = "kitten hints --type=linenum --linenum-action=tab kak {path} +{line}";
|
"${cfg.cmd}+shift+p>n" = "kitten hints --type=linenum --linenum-action=tab kak {path} +{line}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraConfig =
|
||||||
|
let
|
||||||
|
# Nerd Fonts glyph map
|
||||||
|
glyphMap = pkgs.fetchurl {
|
||||||
|
url = "https://raw.githubusercontent.com/Sharparam/dotfiles/main/kitty/.config/kitty/font-nerd-symbols.conf";
|
||||||
|
hash = "sha256-1OaDWLC3y8ASD2ttRWWgPEpRnfKXu6H6vS3cFVpzT0o=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
''
|
||||||
|
include ${glyphMap}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, lib, config, ... }:
|
{ pkgs, lib, options, config, osConfig, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.programs.my-sway;
|
cfg = config.programs.my-sway;
|
||||||
|
@ -18,6 +18,9 @@ let
|
||||||
"9:🔨 9"
|
"9:🔨 9"
|
||||||
"10:🎲 misc"
|
"10:🎲 misc"
|
||||||
];
|
];
|
||||||
|
extraWorkspaces = {
|
||||||
|
mail = "📧 Email";
|
||||||
|
};
|
||||||
wsAttrs = builtins.listToAttrs (
|
wsAttrs = builtins.listToAttrs (
|
||||||
map
|
map
|
||||||
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
|
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
|
||||||
|
@ -42,6 +45,12 @@ let
|
||||||
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f -
|
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f -
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
rofi-rbw-script = pkgs.writeShellApplication {
|
||||||
|
name = "rofi-rbw-script";
|
||||||
|
runtimeInputs = with pkgs; [ rofi wtype rofi-rbw ];
|
||||||
|
text = "rofi-rbw";
|
||||||
|
};
|
||||||
|
|
||||||
ignored-devices = [ "Surface_Headphones" ];
|
ignored-devices = [ "Surface_Headphones" ];
|
||||||
playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}";
|
playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}";
|
||||||
|
|
||||||
|
@ -75,11 +84,6 @@ in
|
||||||
description = "The command for the browser";
|
description = "The command for the browser";
|
||||||
default = "${pkgs.firefox-wayland}/bin/firefox";
|
default = "${pkgs.firefox-wayland}/bin/firefox";
|
||||||
};
|
};
|
||||||
discord = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
description = "The command for discord";
|
|
||||||
default = "${config.nki.programs.discord.package}/bin/discord";
|
|
||||||
};
|
|
||||||
|
|
||||||
lockCmd = mkOption {
|
lockCmd = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -106,12 +110,12 @@ in
|
||||||
default = barWith: [ (barWith { }) ];
|
default = barWith: [ (barWith { }) ];
|
||||||
};
|
};
|
||||||
extraSettings = mkOption {
|
extraSettings = mkOption {
|
||||||
type = types.raw;
|
type = types.listOf types.raw;
|
||||||
description = "Extra settings to be included with every default bar";
|
description = "Extra settings to be included with every default bar";
|
||||||
default = { };
|
default = [ ];
|
||||||
};
|
};
|
||||||
extraStyle = mkOption {
|
extraStyle = mkOption {
|
||||||
type = types.str;
|
type = types.lines;
|
||||||
description = "Additional style for the default waybar";
|
description = "Additional style for the default waybar";
|
||||||
default = "";
|
default = "";
|
||||||
};
|
};
|
||||||
|
@ -120,8 +124,20 @@ in
|
||||||
|
|
||||||
config.wayland.windowManager.sway = mkIf cfg.enable {
|
config.wayland.windowManager.sway = mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemdIntegration = true;
|
systemd.enable = true;
|
||||||
|
systemd.variables = options.wayland.windowManager.sway.systemd.variables.default ++ [
|
||||||
|
"PATH" # for portals
|
||||||
|
"XDG_DATA_DIRS" # For extra icons
|
||||||
|
"XDG_DATA_HOME" # For extra icons
|
||||||
|
] ++ lib.optionals osConfig.services.desktopManager.plasma6.enable [
|
||||||
|
"XDG_MENU_PREFIX"
|
||||||
|
];
|
||||||
|
systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default
|
||||||
|
++ [
|
||||||
|
"systemctl --user restart xdg-desktop-portal.service"
|
||||||
|
];
|
||||||
|
|
||||||
|
checkConfig = false; # Not working atm
|
||||||
config = {
|
config = {
|
||||||
### Inputs
|
### Inputs
|
||||||
#
|
#
|
||||||
|
@ -152,16 +168,9 @@ in
|
||||||
{ command = "${pkgs.dex}/bin/dex -ae sway"; }
|
{ command = "${pkgs.dex}/bin/dex -ae sway"; }
|
||||||
# Waybar
|
# Waybar
|
||||||
{ command = "systemctl --user restart waybar"; always = true; }
|
{ command = "systemctl --user restart waybar"; always = true; }
|
||||||
# Startup programs
|
# IME
|
||||||
{ command = "${cfg.browser}"; }
|
{ command = "fcitx5"; }
|
||||||
{ command = "thunderbird"; } # Rely on system package with plugins
|
];
|
||||||
] ++ (if cfg.discord != null then [
|
|
||||||
{ command = "${cfg.discord}"; }
|
|
||||||
] ++ lib.lists.optional
|
|
||||||
(!pkgs.stdenv.isAarch64)
|
|
||||||
(
|
|
||||||
{ command = "${pkgs.premid}/bin/premid"; }
|
|
||||||
) else [ ]);
|
|
||||||
|
|
||||||
### Keybindings
|
### Keybindings
|
||||||
#
|
#
|
||||||
|
@ -214,6 +223,7 @@ in
|
||||||
# Launcher
|
# Launcher
|
||||||
"${mod}+space" = "exec rofi -show drun";
|
"${mod}+space" = "exec rofi -show drun";
|
||||||
"${mod}+tab" = "exec ${./rofi-window.py}";
|
"${mod}+tab" = "exec ${./rofi-window.py}";
|
||||||
|
"${mod}+shift+p" = "exec ${lib.getExe rofi-rbw-script}";
|
||||||
} // {
|
} // {
|
||||||
## Splits
|
## Splits
|
||||||
"${mod}+v" = "split v";
|
"${mod}+v" = "split v";
|
||||||
|
@ -255,6 +265,11 @@ in
|
||||||
])
|
])
|
||||||
(builtins.attrNames wsAttrs))
|
(builtins.attrNames wsAttrs))
|
||||||
)) //
|
)) //
|
||||||
|
{
|
||||||
|
# Extra workspaces
|
||||||
|
"${mod}+asciicircum" = "workspace ${extraWorkspaces.mail}";
|
||||||
|
"${mod}+shift+asciicircum" = "move to workspace ${extraWorkspaces.mail}";
|
||||||
|
} //
|
||||||
# Move workspaces between outputs
|
# Move workspaces between outputs
|
||||||
{
|
{
|
||||||
"${mod}+ctrl+h" = "move workspace to output left";
|
"${mod}+ctrl+h" = "move workspace to output left";
|
||||||
|
@ -286,17 +301,32 @@ in
|
||||||
];
|
];
|
||||||
"${builtins.elemAt workspaces 1}" = [
|
"${builtins.elemAt workspaces 1}" = [
|
||||||
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
|
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
|
||||||
|
{ class = "VencordDesktop"; }
|
||||||
|
{ app_id = "VencordDesktop"; }
|
||||||
|
{ class = "vesktop"; }
|
||||||
|
{ app_id = "vesktop"; }
|
||||||
];
|
];
|
||||||
"📧 Email" = [
|
${extraWorkspaces.mail} = [
|
||||||
{ app_id = "thunderbird"; }
|
{ app_id = "thunderbird"; }
|
||||||
|
{ app_id = "evolution"; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
# Commands
|
# Commands
|
||||||
window.commands = [
|
window.commands = [
|
||||||
{ criteria = { title = ".*"; }; command = "inhibit_idle fullscreen"; }
|
{ criteria = { title = ".*"; }; command = "inhibit_idle fullscreen"; }
|
||||||
{ criteria = { app_id = ".*float.*"; }; command = "floating enable"; }
|
] ++ (
|
||||||
{ criteria = { class = ".*float.*"; }; command = "floating enable"; }
|
# Floating assignments
|
||||||
];
|
let
|
||||||
|
criterias = [
|
||||||
|
{ app_id = ".*float.*"; }
|
||||||
|
{ app_id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
|
||||||
|
{ class = ".*float.*"; }
|
||||||
|
{ title = "Extension: .*Bitwarden.*"; }
|
||||||
|
];
|
||||||
|
toCommand = criteria: { inherit criteria; command = "floating enable"; };
|
||||||
|
in
|
||||||
|
map toCommand criterias
|
||||||
|
);
|
||||||
# Focus
|
# Focus
|
||||||
focus.followMouse = true;
|
focus.followMouse = true;
|
||||||
focus.mouseWarping = true;
|
focus.mouseWarping = true;
|
||||||
|
@ -319,16 +349,21 @@ in
|
||||||
swaynag.enable = true;
|
swaynag.enable = true;
|
||||||
# Environment Variables
|
# Environment Variables
|
||||||
extraSessionCommands = ''
|
extraSessionCommands = ''
|
||||||
export MOZ_ENABLE_WAYLAND=1
|
|
||||||
export SDL_VIDEODRIVER=wayland
|
|
||||||
export QT_QPA_PLATFORM=wayland
|
export QT_QPA_PLATFORM=wayland
|
||||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
|
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
|
||||||
|
export QT_IM_MODULE=fcitx
|
||||||
|
export GTK_IM_MODULE=fcitx # Til text-input is merged
|
||||||
|
# export NIXOS_OZONE_WL=1 # Until text-input is merged
|
||||||
|
|
||||||
'' + (if config.services.gnome-keyring.enable then ''
|
'' + (if config.services.gnome-keyring.enable then ''
|
||||||
# gnome-keyring
|
# gnome-keyring
|
||||||
eval `gnome-keyring-daemon`
|
if type gnome-keyring-daemon >/dev/null; then
|
||||||
export SSH_AUTH_SOCK
|
eval `gnome-keyring-daemon`
|
||||||
'' else "");
|
export SSH_AUTH_SOCK
|
||||||
|
fi
|
||||||
|
'' else "") + lib.optionalString osConfig.services.desktopManager.plasma6.enable ''
|
||||||
|
export XDG_MENU_PREFIX=plasma-
|
||||||
|
'';
|
||||||
# Extra
|
# Extra
|
||||||
wrapperFeatures.base = true;
|
wrapperFeatures.base = true;
|
||||||
wrapperFeatures.gtk = true;
|
wrapperFeatures.gtk = true;
|
||||||
|
@ -360,27 +395,26 @@ in
|
||||||
'' + ''
|
'' + ''
|
||||||
# Enable portal stuff
|
# Enable portal stuff
|
||||||
exec ${pkgs.writeShellScript "start-portals.sh" ''
|
exec ${pkgs.writeShellScript "start-portals.sh" ''
|
||||||
# Import the WAYLAND_DISPLAY env var from sway into the systemd user session.
|
|
||||||
dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
|
|
||||||
|
|
||||||
# Stop any services that are running, so that they receive the new env var when they restart.
|
|
||||||
systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
|
|
||||||
systemctl --user start pipewire-media-session
|
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
config.services.swayidle = mkIf cfg.enable {
|
config.services.swayidle = mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
systemdTarget = "sway-session.target";
|
||||||
timeouts = [
|
timeouts = [
|
||||||
# Lock after 15 minutes of idle
|
# Lock after 15 minutes of idle
|
||||||
{ timeout = 15 * 60; command = cfg.lockCmd; }
|
# { timeout = 15 * 60; command = cfg.lockCmd; }
|
||||||
|
];
|
||||||
|
events = [
|
||||||
|
{ event = "lock"; command = cfg.lockCmd; }
|
||||||
|
{ event = "before-sleep"; command = cfg.lockCmd; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
config.programs.waybar =
|
config.programs.waybar =
|
||||||
let
|
let
|
||||||
barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: (mkMerge [{
|
barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: mkMerge ([{
|
||||||
position = "top";
|
position = "top";
|
||||||
modules-left = [
|
modules-left = [
|
||||||
"sway/workspaces"
|
"sway/workspaces"
|
||||||
|
@ -391,7 +425,7 @@ in
|
||||||
];
|
];
|
||||||
modules-right =
|
modules-right =
|
||||||
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
|
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
|
||||||
++ [
|
++ [
|
||||||
"tray"
|
"tray"
|
||||||
"pulseaudio"
|
"pulseaudio"
|
||||||
] ++ lib.optionals showConnectivity [
|
] ++ lib.optionals showConnectivity [
|
||||||
|
@ -402,7 +436,7 @@ in
|
||||||
"memory"
|
"memory"
|
||||||
"temperature"
|
"temperature"
|
||||||
] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ]
|
] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ]
|
||||||
++ [
|
++ [
|
||||||
"clock"
|
"clock"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -432,8 +466,35 @@ in
|
||||||
spacing = 10;
|
spacing = 10;
|
||||||
};
|
};
|
||||||
"clock" = {
|
"clock" = {
|
||||||
tooltip-format = "{:%Y-%m-%d | %H:%M}";
|
# format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}";
|
||||||
format-alt = "{:%Y-%m-%d}";
|
format = "📅 {0:%Y-%m-%d} |️ 🕰️ {0:%H:%M [%Z]}";
|
||||||
|
tooltip-format = "\n<span size='9pt' font_family='Noto Sans Mono CJK JP'>{calendar}</span>";
|
||||||
|
timezones = [
|
||||||
|
"Europe/Zurich"
|
||||||
|
"America/Toronto"
|
||||||
|
"Asia/Tokyo"
|
||||||
|
"Asia/Ho_Chi_Minh"
|
||||||
|
];
|
||||||
|
calendar = {
|
||||||
|
mode = "year";
|
||||||
|
mode-mon-col = 3;
|
||||||
|
weeks-pos = "right";
|
||||||
|
on-scroll = 1;
|
||||||
|
on-click-right = "mode";
|
||||||
|
format = {
|
||||||
|
months = "<span color='#ffead3'><b>{}</b></span>";
|
||||||
|
days = "<span color='#ecc6d9'><b>{}</b></span>";
|
||||||
|
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
|
||||||
|
weekdays = "<span color='#ffcc66'><b>日 月 火 水 木 金 土</b></span>"; # See https://github.com/Alexays/Waybar/issues/3132
|
||||||
|
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
on-click-middle = "mode";
|
||||||
|
on-click-right = "tz_up";
|
||||||
|
on-scroll-up = "shift_up";
|
||||||
|
on-scroll-down = "shift_down";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"cpu" = {
|
"cpu" = {
|
||||||
format = "{usage}% ";
|
format = "{usage}% ";
|
||||||
|
@ -542,13 +603,14 @@ in
|
||||||
"on-click" = "${playerctl} play-pause";
|
"on-click" = "${playerctl} play-pause";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}] ++
|
||||||
cfg.waybar.extraSettings
|
cfg.waybar.extraSettings
|
||||||
extraSettings]);
|
++ [ extraSettings ]);
|
||||||
in
|
in
|
||||||
mkIf cfg.enable {
|
mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemd.enable = true;
|
systemd.enable = true;
|
||||||
|
systemd.target = "sway-session.target";
|
||||||
settings = cfg.waybar.makeBars barWith;
|
settings = cfg.waybar.makeBars barWith;
|
||||||
style = ''
|
style = ''
|
||||||
* {
|
* {
|
||||||
|
@ -586,7 +648,8 @@ in
|
||||||
}
|
}
|
||||||
|
|
||||||
#window, #sway, #sway-window {
|
#window, #sway, #sway-window {
|
||||||
padding: 0 10px;
|
padding-left: 1em;
|
||||||
|
margin-bottom: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mode {
|
#mode {
|
||||||
|
@ -594,9 +657,16 @@ in
|
||||||
border-bottom: 3px solid #ffffff;
|
border-bottom: 3px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd {
|
/* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */
|
||||||
padding: 0 10px;
|
.modules-right > * > * {
|
||||||
margin: 0 5px;
|
margin: 0.2em 0 0.4em 0;
|
||||||
|
padding: 0.2em 0.5em;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||||
|
border-radius: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modules-right > *:not(:last-child) > * {
|
||||||
|
margin-right: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#clock {
|
#clock {
|
||||||
|
@ -707,7 +777,7 @@ in
|
||||||
};
|
};
|
||||||
config.home.packages = mkIf cfg.enable (with pkgs; [
|
config.home.packages = mkIf cfg.enable (with pkgs; [
|
||||||
# Needed for QT_QPA_PLATFORM
|
# Needed for QT_QPA_PLATFORM
|
||||||
qt5.qtwayland
|
kdePackages.qtwayland
|
||||||
# For waybar
|
# For waybar
|
||||||
font-awesome
|
font-awesome
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -4,12 +4,15 @@ let
|
||||||
name = "openconnect-epfl";
|
name = "openconnect-epfl";
|
||||||
runtimeInputs = with pkgs; [ openconnect rbw ];
|
runtimeInputs = with pkgs; [ openconnect rbw ];
|
||||||
text = ''
|
text = ''
|
||||||
GASPAR_PASSWORD=$(rbw get gaspar)
|
METHOD="Microsoft Entra ID"
|
||||||
GASPAR_TOKEN=$(rbw code gaspar)
|
RBW_ENTRY="EPFL Microsoft Auth"
|
||||||
|
GASPAR_PASSWORD=$(rbw get "$RBW_ENTRY")
|
||||||
|
GASPAR_TOKEN=$(rbw code "$RBW_ENTRY")
|
||||||
|
|
||||||
printf "%s\n%s" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | sudo openconnect \
|
printf "\n%s\n%s\n%s\n" "$METHOD" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | command sudo openconnect \
|
||||||
--passwd-on-stdin \
|
--passwd-on-stdin \
|
||||||
-u pham \
|
-u "pham" \
|
||||||
|
--useragent='AnyConnect' \
|
||||||
"https://vpn.epfl.ch"
|
"https://vpn.epfl.ch"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
118
home/nki-framework.nix
Normal file
118
home/nki-framework.nix
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# Common configuration
|
||||||
|
./common.nix
|
||||||
|
# We use our own firefox
|
||||||
|
# ./firefox.nix
|
||||||
|
# osu!
|
||||||
|
./osu.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# Home Manager needs a bit of information about you and the
|
||||||
|
# paths it should manage.
|
||||||
|
home.username = "nki";
|
||||||
|
home.homeDirectory = "/home/nki";
|
||||||
|
|
||||||
|
# More packages
|
||||||
|
home.packages = (with pkgs; [
|
||||||
|
# CLI stuff
|
||||||
|
python3
|
||||||
|
zip
|
||||||
|
# TeX
|
||||||
|
texlive.combined.scheme-full
|
||||||
|
# Note-taking
|
||||||
|
rnote
|
||||||
|
]);
|
||||||
|
|
||||||
|
# Graphical set up
|
||||||
|
linux.graphical.type = "wayland";
|
||||||
|
linux.graphical.wallpaper = ./images/wallpaper_0.png;
|
||||||
|
linux.graphical.defaults.webBrowser = "librewolf.desktop";
|
||||||
|
# Enable sway
|
||||||
|
programs.my-sway.enable = true;
|
||||||
|
programs.my-sway.fontSize = 14.0;
|
||||||
|
programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty";
|
||||||
|
programs.my-sway.browser = "librewolf";
|
||||||
|
wayland.windowManager.sway.config = {
|
||||||
|
# Keyboard support
|
||||||
|
input."*".xkb_layout = "jp";
|
||||||
|
input."1278:34:HHKB-Hybrid_3_Keyboard".xkb_layout = "jp";
|
||||||
|
input."1:1:AT_Translated_Set_2_keyboard" = {
|
||||||
|
xkb_options = "ctrl:swapcaps";
|
||||||
|
};
|
||||||
|
input."2362:628:PIXA3854:00_093A:0274_Touchpad" = {
|
||||||
|
drag = "enabled";
|
||||||
|
natural_scroll = "enabled";
|
||||||
|
tap = "enabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs.my-sway.waybar.extraSettings =
|
||||||
|
let
|
||||||
|
change-mode = pkgs.writeScript "change-mode" ''
|
||||||
|
#!/usr/bin/env ${lib.getExe pkgs.fish}
|
||||||
|
set -ax PATH ${lib.getBin pkgs.power-profiles-daemon} ${lib.getBin pkgs.rofi} ${lib.getBin pkgs.ripgrep}
|
||||||
|
|
||||||
|
set profiles (powerprofilesctl list | rg "^[ *] (\S+):" -r '$1')
|
||||||
|
set selected_index (math (contains -i (powerprofilesctl get) $profiles) - 1)
|
||||||
|
set new_profile (printf "%s\n" $profiles | rofi -dmenu -p "Switch to power profile" -a $selected_index)
|
||||||
|
powerprofilesctl set $new_profile
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
[{
|
||||||
|
modules."battery"."on-click" = change-mode;
|
||||||
|
}];
|
||||||
|
|
||||||
|
# input-remapping
|
||||||
|
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
||||||
|
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
||||||
|
# Kitty
|
||||||
|
nki.programs.kitty = {
|
||||||
|
enable = true;
|
||||||
|
fontSize = 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Multiple screen setup
|
||||||
|
services.kanshi = with config.common.monitors; {
|
||||||
|
enable = true;
|
||||||
|
settings = [
|
||||||
|
{
|
||||||
|
profile.name = "undocked";
|
||||||
|
profile.outputs = [{ criteria = "eDP-1"; }];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
profile.name = "work-both";
|
||||||
|
profile.outputs = [
|
||||||
|
{
|
||||||
|
criteria = "eDP-1";
|
||||||
|
position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}";
|
||||||
|
status = "enable";
|
||||||
|
}
|
||||||
|
{ criteria = work.name; position = "1920,0"; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
profile.name = "work-one";
|
||||||
|
profile.outputs = [
|
||||||
|
{
|
||||||
|
criteria = "eDP-1";
|
||||||
|
status = "disable";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{ output.criteria = config.common.monitors.work.name; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# This value determines the Home Manager release that your
|
||||||
|
# configuration is compatible with. This helps avoid breakage
|
||||||
|
# when a new Home Manager release introduces backwards
|
||||||
|
# incompatible changes.
|
||||||
|
#
|
||||||
|
# You can update Home Manager without changing this value. See
|
||||||
|
# the Home Manager release notes for a list of state version
|
||||||
|
# changes in each release.
|
||||||
|
home.stateVersion = "21.05";
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# We use our own firefox
|
# We use our own firefox
|
||||||
# ./firefox.nix
|
# ./firefox.nix
|
||||||
# osu!
|
# osu!
|
||||||
# ./osu.nix
|
./osu.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Home Manager needs a bit of information about you and the
|
# Home Manager needs a bit of information about you and the
|
||||||
|
@ -24,10 +24,6 @@
|
||||||
texlive.combined.scheme-full
|
texlive.combined.scheme-full
|
||||||
# Note-taking
|
# Note-taking
|
||||||
rnote
|
rnote
|
||||||
|
|
||||||
# Java & sbt
|
|
||||||
openjdk11
|
|
||||||
sbt
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# Graphical set up
|
# Graphical set up
|
||||||
|
|
49
home/osu.nix
49
home/osu.nix
|
@ -1,33 +1,32 @@
|
||||||
{ pkgs, config, lib, ... }:
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
osu-pkg = pkgs.unstable.osu-lazer-bin;
|
# osu-pkg = pkgs.unstable.osu-lazer-bin;
|
||||||
# with pkgs; with lib;
|
osu-pkg = with pkgs; with lib;
|
||||||
# appimageTools.wrapType2 rec {
|
appimageTools.wrapType2 rec {
|
||||||
# pname = "osu-lazer-bin";
|
pname = "osu-lazer-bin";
|
||||||
# version = "2023.914.0";
|
version = "2024.1009.1";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
|
||||||
|
sha256 = "sha256-2H2SPcUm/H/0D9BqBiTFvaCwd0c14/r+oWhyeZdNpoU=";
|
||||||
|
};
|
||||||
|
extraPkgs = pkgs: with pkgs; [ icu ];
|
||||||
|
|
||||||
# src = fetchurl {
|
extraInstallCommands =
|
||||||
# url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
|
let contents = appimageTools.extract { inherit pname version src; };
|
||||||
# # sha256 = "sha256-edu93pvTEM5/s0kW55U1xfYGDl0eUpGXypvuYIwsM3w=";
|
in
|
||||||
# hash = lib.fakeHash;
|
''
|
||||||
# };
|
mv -v $out/bin/${pname} $out/bin/osu\!
|
||||||
|
install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
|
||||||
# extraPkgs = pkgs: with pkgs; [ icu ];
|
for i in 16 32 48 64 96 128 256 512 1024; do
|
||||||
|
install -D ${contents}/osu\!.png $out/share/icons/hicolor/''${i}x$i/apps/osu\!.png
|
||||||
# extraInstallCommands =
|
done
|
||||||
# let contents = appimageTools.extract { inherit pname version src; };
|
'';
|
||||||
# in
|
};
|
||||||
# ''
|
|
||||||
# mv -v $out/bin/${pname}-${version} $out/bin/osu\!
|
|
||||||
# install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
|
|
||||||
# for i in 16 32 48 64 96 128 256 512 1024; do
|
|
||||||
# install -D ${contents}/osu\!.png $out/share/icons/hicolor/''${i}x$i/apps/osu\!.png
|
|
||||||
# done
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = [ osu-pkg ];
|
home.packages = [ osu-pkg ];
|
||||||
|
xdg.mimeApps.defaultApplications."x-scheme-handler/osu" = "osu!.desktop";
|
||||||
# home.packages = [ pkgs.osu-lazer ];
|
# home.packages = [ pkgs.osu-lazer ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
../modules/personal/fonts
|
../modules/personal/fonts
|
||||||
# Encrypted DNS
|
# Encrypted DNS
|
||||||
../modules/services/edns
|
../modules/services/edns
|
||||||
|
# Override base mesa
|
||||||
|
({ ... }: { nixpkgs.overlays = lib.mkBefore [ (final: prev: { mesa = prev.mesa.override { enableOpenCL = true; meson = final.unstable.meson; }; }) ]; })
|
||||||
];
|
];
|
||||||
|
|
||||||
# time.timeZone = lib.mkForce "Asia/Ho_Chi_Minh";
|
# time.timeZone = lib.mkForce "Asia/Ho_Chi_Minh";
|
||||||
|
@ -28,6 +30,30 @@
|
||||||
useExperimentalGPUDriver = true;
|
useExperimentalGPUDriver = true;
|
||||||
experimentalGPUInstallMode = "overlay";
|
experimentalGPUInstallMode = "overlay";
|
||||||
};
|
};
|
||||||
|
# Override mesa
|
||||||
|
nixpkgs.overlays = lib.mkAfter [
|
||||||
|
(final: prev: {
|
||||||
|
mesa-asahi-edge = prev.mesa-asahi-edge.overrideAttrs (attrs: {
|
||||||
|
version = "24.0.0";
|
||||||
|
# buildInputs = attrs.buildInputs ++ (with pkgslw; [ libclc cmake (spirv-llvm-translator.override { inherit (llvmPackages_15) llvm; }) ]);
|
||||||
|
# nativeBuildInputs = attrs.nativeBuildInputs ++ (with pkgs; [ pkgs.unstable.spirv-llvm-translator ]);
|
||||||
|
src = final.fetchFromGitLab {
|
||||||
|
# latest release
|
||||||
|
domain = "gitlab.freedesktop.org";
|
||||||
|
owner = "asahi";
|
||||||
|
repo = "mesa";
|
||||||
|
rev = "asahi-20231121";
|
||||||
|
hash = "sha256-IcKKe1RA8sCaUfWK71ELzF15YaBS3DjoYhNMIWiQ5Jw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
patches = lib.forEach attrs.patches (p:
|
||||||
|
if lib.hasSuffix "opencl.patch" p
|
||||||
|
then ./mesa-asahi-edge/opencl.patch else p);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
];
|
||||||
|
## Additional mesa-related packages
|
||||||
|
environment.systemPackages = with pkgs; [ SDL2 ];
|
||||||
|
|
||||||
# Power Management
|
# Power Management
|
||||||
services.upower = {
|
services.upower = {
|
||||||
|
@ -44,7 +70,7 @@
|
||||||
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
|
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
|
||||||
|
|
||||||
# Enable touchpad support (enabled default in most desktopManager).
|
# Enable touchpad support (enabled default in most desktopManager).
|
||||||
services.xserver.libinput.enable = true;
|
services.libinput.enable = true;
|
||||||
# Keyboard
|
# Keyboard
|
||||||
services.input-remapper.enable = true;
|
services.input-remapper.enable = true;
|
||||||
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
|
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
|
||||||
|
|
66
kagami-air-m1/mesa-asahi-edge/opencl.patch
Normal file
66
kagami-air-m1/mesa-asahi-edge/opencl.patch
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 04d89987311..babfe440973 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -1812,7 +1812,7 @@ endif
|
||||||
|
|
||||||
|
dep_clang = null_dep
|
||||||
|
if with_clc
|
||||||
|
- llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir')
|
||||||
|
+ llvm_libdir = get_option('clang-libdir')
|
||||||
|
|
||||||
|
dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
|
||||||
|
|
||||||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||||||
|
index e885ba61a8a..29ce0270479 100644
|
||||||
|
--- a/meson_options.txt
|
||||||
|
+++ b/meson_options.txt
|
||||||
|
@@ -1,6 +1,12 @@
|
||||||
|
# Copyright © 2017-2019 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
+option(
|
||||||
|
+ 'clang-libdir',
|
||||||
|
+ type : 'string',
|
||||||
|
+ value : '',
|
||||||
|
+ description : 'Locations to search for clang libraries.'
|
||||||
|
+)
|
||||||
|
option(
|
||||||
|
'platforms',
|
||||||
|
type : 'array',
|
||||||
|
diff --git a/src/gallium/targets/opencl/meson.build b/src/gallium/targets/opencl/meson.build
|
||||||
|
index 7c14135898e..74dc6850603 100644
|
||||||
|
--- a/src/gallium/targets/opencl/meson.build
|
||||||
|
+++ b/src/gallium/targets/opencl/meson.build
|
||||||
|
@@ -39,7 +39,8 @@ if dep_llvm.version().version_compare('>=10.0.0')
|
||||||
|
polly_isl_dep = cpp.find_library('PollyISL', dirs : llvm_libdir, required : false)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
|
||||||
|
+clang_libdir = get_option('clang-libdir')
|
||||||
|
+dep_clang = cpp.find_library('clang-cpp', dirs : clang_libdir, required : false)
|
||||||
|
|
||||||
|
# meson will return clang-cpp from system dirs if it's not found in llvm_libdir
|
||||||
|
linker_rpath_arg = '-Wl,--rpath=@0@'.format(llvm_libdir)
|
||||||
|
@@ -123,7 +124,7 @@ if with_opencl_icd
|
||||||
|
configuration : _config,
|
||||||
|
input : 'mesa.icd.in',
|
||||||
|
output : 'mesa.icd',
|
||||||
|
- install : true,
|
||||||
|
+ install : false,
|
||||||
|
install_tag : 'runtime',
|
||||||
|
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
|
||||||
|
)
|
||||||
|
diff --git a/src/gallium/targets/rusticl/meson.build b/src/gallium/targets/rusticl/meson.build
|
||||||
|
index b2963fe6dfa..99d6d801b94 100644
|
||||||
|
--- a/src/gallium/targets/rusticl/meson.build
|
||||||
|
+++ b/src/gallium/targets/rusticl/meson.build
|
||||||
|
@@ -76,7 +76,7 @@ configure_file(
|
||||||
|
configuration : _config,
|
||||||
|
input : 'rusticl.icd.in',
|
||||||
|
output : 'rusticl.icd',
|
||||||
|
- install : true,
|
||||||
|
+ install : false,
|
||||||
|
install_tag : 'runtime',
|
||||||
|
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
|
||||||
|
)
|
|
@ -12,8 +12,8 @@ let
|
||||||
images = {
|
images = {
|
||||||
postgresql = mkImage {
|
postgresql = mkImage {
|
||||||
imageName = "postgres";
|
imageName = "postgres";
|
||||||
finalImageTag = "12-alpine";
|
finalImageTag = "16-alpine";
|
||||||
imageDigest = "sha256:f52ffee699232c84d820c35c28656363f4fda6a3e3e934b83f4e5e1898e2bdfa";
|
imageDigest = "sha256:b40547ea0c7bcb401d8f11c6a233ebe65e2067e5966e54ccf9b03c5f01c2957c";
|
||||||
};
|
};
|
||||||
redis = mkImage {
|
redis = mkImage {
|
||||||
imageName = "redis";
|
imageName = "redis";
|
||||||
|
@ -22,8 +22,8 @@ let
|
||||||
};
|
};
|
||||||
authentik = mkImage {
|
authentik = mkImage {
|
||||||
imageName = "ghcr.io/goauthentik/server";
|
imageName = "ghcr.io/goauthentik/server";
|
||||||
finalImageTag = "2023.8.3";
|
finalImageTag = "2024.8.2";
|
||||||
imageDigest = "sha256:82a07af063e8f93d0f174b6b058fcb6d54cd31ca2a271d23173cb149e19e8116";
|
imageDigest = "sha256:71984fdbb7a9414f5172bb446104d3fe4ab1ab412c8b3343bb97b04449dd53eb";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
authentikEnv = pkgs.writeText "authentik.env" ''
|
authentikEnv = pkgs.writeText "authentik.env" ''
|
||||||
|
@ -48,7 +48,14 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.arion-authentik.serviceConfig.EnvironmentFile = cfg.envFile;
|
systemd.services.arion-authentik = {
|
||||||
|
serviceConfig.EnvironmentFile = cfg.envFile;
|
||||||
|
serviceConfig.Type = "notify";
|
||||||
|
serviceConfig.NotifyAccess = "all";
|
||||||
|
script = lib.mkBefore ''
|
||||||
|
${lib.getExe pkgs.wait4x} http http://127.0.0.1:${toString cfg.port} --expect-status-code 200 -t 0 -q -- systemd-notify --ready &
|
||||||
|
'';
|
||||||
|
};
|
||||||
virtualisation.arion.projects.authentik.settings = {
|
virtualisation.arion.projects.authentik.settings = {
|
||||||
services.postgresql.service = {
|
services.postgresql.service = {
|
||||||
image = images.postgresql;
|
image = images.postgresql;
|
||||||
|
|
|
@ -10,9 +10,10 @@ let
|
||||||
user = "bitwarden";
|
user = "bitwarden";
|
||||||
|
|
||||||
port = 8001;
|
port = 8001;
|
||||||
notificationsPort = 8002;
|
|
||||||
|
|
||||||
host = "bw.nkagami.me";
|
host = "bw.nkagami.me";
|
||||||
|
|
||||||
|
package = pkgs.vaultwarden-postgresql;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.cloud.bitwarden = {
|
options.cloud.bitwarden = {
|
||||||
|
@ -37,12 +38,6 @@ in
|
||||||
inherit port host;
|
inherit port host;
|
||||||
noCloudflare = true;
|
noCloudflare = true;
|
||||||
};
|
};
|
||||||
cloud.traefik.hosts.bitwarden-notifications = {
|
|
||||||
inherit host;
|
|
||||||
port = notificationsPort;
|
|
||||||
path = "/notifications/hub";
|
|
||||||
noCloudflare = true;
|
|
||||||
};
|
|
||||||
# systemd unit
|
# systemd unit
|
||||||
systemd.services.bitwarden-server = {
|
systemd.services.bitwarden-server = {
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
|
@ -52,12 +47,11 @@ in
|
||||||
DATABASE_URL = databaseUrl;
|
DATABASE_URL = databaseUrl;
|
||||||
|
|
||||||
DATA_FOLDER = "/var/lib/bitwarden-server";
|
DATA_FOLDER = "/var/lib/bitwarden-server";
|
||||||
WEB_VAULT_FOLDER = "${pkgs.unstable.vaultwarden-vault}/share/vaultwarden/vault";
|
WEB_VAULT_FOLDER = "${pkgs.vaultwarden-vault}/share/vaultwarden/vault";
|
||||||
|
|
||||||
ROCKET_PORT = toString port;
|
ROCKET_PORT = toString port;
|
||||||
|
|
||||||
WEBSOCKET_ENABLED = "true";
|
PUSH_ENABLED = "true";
|
||||||
WEBSOCKET_PORT = toString notificationsPort;
|
|
||||||
|
|
||||||
DOMAIN = "https://${host}";
|
DOMAIN = "https://${host}";
|
||||||
};
|
};
|
||||||
|
@ -65,7 +59,7 @@ in
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = user;
|
User = user;
|
||||||
Group = user;
|
Group = user;
|
||||||
ExecStart = "${pkgs.unstable.vaultwarden-postgresql}/bin/vaultwarden";
|
ExecStart = "${package}/bin/vaultwarden";
|
||||||
EnvironmentFile = lists.optional (cfg.envFile != null) cfg.envFile;
|
EnvironmentFile = lists.optional (cfg.envFile != null) cfg.envFile;
|
||||||
LimitNOFILE = "1048576";
|
LimitNOFILE = "1048576";
|
||||||
PrivateTmp = "true";
|
PrivateTmp = "true";
|
||||||
|
|
|
@ -73,7 +73,9 @@ with lib;
|
||||||
global.server_name = server_name;
|
global.server_name = server_name;
|
||||||
global.port = instance.port;
|
global.port = instance.port;
|
||||||
global.allow_registration = instance.allow_registration;
|
global.allow_registration = instance.allow_registration;
|
||||||
global.database_path = "/var/lib/${srvName}/";
|
global.database_path = "/mnt/data/${srvName}/";
|
||||||
|
global.well_known_client = "https://${instance.host}";
|
||||||
|
global.well_known_server = "${instance.host}:443";
|
||||||
});
|
});
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -103,7 +105,8 @@ with lib;
|
||||||
"@system-service"
|
"@system-service"
|
||||||
"~@privileged"
|
"~@privileged"
|
||||||
];
|
];
|
||||||
StateDirectory = "${srvName}";
|
# StateDirectory = "/mnt/data/${srvName}";
|
||||||
|
BindPaths = [ "/mnt/data/${srvName}" ];
|
||||||
ExecStart = "${cfg.package}/bin/conduit";
|
ExecStart = "${cfg.package}/bin/conduit";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = 10;
|
RestartSec = 10;
|
||||||
|
@ -113,56 +116,12 @@ with lib;
|
||||||
))
|
))
|
||||||
cfg.instances);
|
cfg.instances);
|
||||||
|
|
||||||
# Serving .well-known files
|
|
||||||
# This is a single .well-known/matrix/server file that points to the server,
|
|
||||||
# which is NOT on port 8448 since Cloudflare doesn't allow us to route HTTPS
|
|
||||||
# through that port.
|
|
||||||
config.services.nginx = mkIf cfg.enable
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
virtualHosts = lib.attrsets.mapAttrs'
|
|
||||||
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" {
|
|
||||||
listen = [{ addr = "127.0.0.1"; port = instance.well-known_port; }];
|
|
||||||
# Check https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md
|
|
||||||
# for the file structure.
|
|
||||||
root = pkgs.symlinkJoin
|
|
||||||
{
|
|
||||||
name = "well-known-files-for-conduit-${name}";
|
|
||||||
paths = [
|
|
||||||
(pkgs.writeTextDir ".well-known/matrix/client" (builtins.toJSON {
|
|
||||||
"m.homeserver".base_url = "https://${instance.host}";
|
|
||||||
"org.matrix.msc3575.proxy".url = "https://${instance.host}";
|
|
||||||
}))
|
|
||||||
(pkgs.writeTextDir ".well-known/matrix/server" (builtins.toJSON {
|
|
||||||
"m.server" = "${instance.host}:443";
|
|
||||||
}))
|
|
||||||
];
|
|
||||||
};
|
|
||||||
# Enable CORS from anywhere since we want all clients to find us out
|
|
||||||
extraConfig = ''
|
|
||||||
add_header 'Access-Control-Allow-Origin' "*";
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
cfg.instances;
|
|
||||||
};
|
|
||||||
|
|
||||||
config.cloud.traefik.hosts = mkIf cfg.enable (
|
config.cloud.traefik.hosts = mkIf cfg.enable (
|
||||||
(lib.attrsets.mapAttrs'
|
(lib.attrsets.mapAttrs'
|
||||||
(name: instance: lib.attrsets.nameValuePair "conduit-${name}" ({
|
(name: instance: lib.attrsets.nameValuePair "conduit-${name}" ({
|
||||||
inherit (instance) host port noCloudflare;
|
inherit (instance) host port noCloudflare;
|
||||||
}))
|
}))
|
||||||
cfg.instances)
|
cfg.instances)
|
||||||
// (lib.attrsets.mapAttrs'
|
|
||||||
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" (
|
|
||||||
let
|
|
||||||
server_name = if instance.server_name == "" then instance.host else instance.server_name;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
port = instance.well-known_port;
|
|
||||||
filter = "Host(`${server_name}`) && PathPrefix(`/.well-known`)";
|
|
||||||
}
|
|
||||||
))
|
|
||||||
cfg.instances)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ with lib; {
|
||||||
{
|
{
|
||||||
systemd.services.heisenbridge = {
|
systemd.services.heisenbridge = {
|
||||||
description = "Matrix<->IRC bridge";
|
description = "Matrix<->IRC bridge";
|
||||||
requires = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse
|
requires = [ "matrix-conduit-nkagami.service" "matrix-synapse.service" ]; # So the registration file can be used by Synapse
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
serviceConfig = rec {
|
serviceConfig = rec {
|
||||||
|
|
|
@ -4,35 +4,12 @@ let
|
||||||
cfg = config.cloud.gotosocial;
|
cfg = config.cloud.gotosocial;
|
||||||
|
|
||||||
dbUser = "gotosocial";
|
dbUser = "gotosocial";
|
||||||
|
storageLocation = "/mnt/data/gotosocial";
|
||||||
configFile = pkgs.writeText "config.yml" (generators.toYAML { } {
|
|
||||||
# General
|
|
||||||
host = cfg.host;
|
|
||||||
account-domain = cfg.accountDomain;
|
|
||||||
bind-address = "localhost";
|
|
||||||
port = cfg.port;
|
|
||||||
# Database
|
|
||||||
db-port = 0; # Use socket
|
|
||||||
db-user = dbUser;
|
|
||||||
db-database = dbUser;
|
|
||||||
# Web
|
|
||||||
web-template-base-dir = "${cfg.package}/share/web/template";
|
|
||||||
web-asset-base-dir = "${cfg.package}/share/web/assets";
|
|
||||||
# OIDC
|
|
||||||
oidc-enabled = true;
|
|
||||||
oidc-idp-name = "DTTH";
|
|
||||||
oidc-scopes = [ "openid" "email" "profile" ];
|
|
||||||
# HTTP Client
|
|
||||||
http-client.block-ips = [ "11.0.0.0/24" ];
|
|
||||||
# Advanced
|
|
||||||
advanced-rate-limit-requests = 0;
|
|
||||||
# instance-inject-mastodon-version = true;
|
|
||||||
});
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.cloud.gotosocial = {
|
options.cloud.gotosocial = {
|
||||||
enable = mkEnableOption "Enable our local GtS server";
|
enable = mkEnableOption "Enable our local GtS server";
|
||||||
package = mkPackageOption pkgs "gotosocial-bin" { };
|
package = mkPackageOption pkgs "gotosocial" { };
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The GtS host";
|
description = "The GtS host";
|
||||||
|
@ -72,49 +49,59 @@ in
|
||||||
};
|
};
|
||||||
} else { });
|
} else { });
|
||||||
# The service itself
|
# The service itself
|
||||||
systemd.services.gotosocial = {
|
services.gotosocial = {
|
||||||
after = [ "network.target" ];
|
enable = true;
|
||||||
serviceConfig = {
|
package = cfg.package;
|
||||||
User = dbUser;
|
environmentFile = cfg.envFile;
|
||||||
Group = dbUser;
|
settings = {
|
||||||
ExecStart = "${cfg.package}/bin/gotosocial --config-path ${configFile} server start";
|
# General
|
||||||
EnvironmentFile = cfg.envFile;
|
host = cfg.host;
|
||||||
# Sandboxing options to harden security
|
account-domain = cfg.accountDomain;
|
||||||
# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
|
bind-address = "localhost";
|
||||||
NoNewPrivileges = "yes";
|
port = cfg.port;
|
||||||
PrivateTmp = "yes";
|
# Instance
|
||||||
PrivateDevices = "yes";
|
instance-languages = [ "en-ca" "vi" ];
|
||||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
# Accounts
|
||||||
RestrictNamespaces = "yes";
|
accounts-registration-open = false;
|
||||||
RestrictRealtime = "yes";
|
accounts-allow-custom-css = true;
|
||||||
DevicePolicy = "closed";
|
# Database
|
||||||
ProtectSystem = "full";
|
db-type = "postgres";
|
||||||
ProtectControlGroups = "yes";
|
db-address = "/run/postgresql"; # Use socket
|
||||||
ProtectKernelModules = "yes";
|
db-user = dbUser;
|
||||||
ProtectKernelTunables = "yes";
|
db-database = dbUser;
|
||||||
LockPersonality = "yes";
|
# Web
|
||||||
SystemCallFilter = "~@clock @debug @module @mount @obsolete @reboot @setuid @swap";
|
web-template-base-dir = "${cfg.package}/share/gotosocial/web/template";
|
||||||
|
web-asset-base-dir = "${cfg.package}/share/gotosocial/web/assets";
|
||||||
# Denying access to capabilities that should not be relevant
|
# Media
|
||||||
# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html
|
media-emoji-remote-max-size = 256 * 1024 /* bytes */;
|
||||||
CapabilityBoundingSet = strings.concatStringsSep " " [
|
media-emoji-local-max-size = 256 * 1024 /* bytes */;
|
||||||
"CAP_RAWIO CAP_MKNOD"
|
media-remote-cache-days = 7;
|
||||||
"CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE"
|
media-cleanup-from = "00:00";
|
||||||
"CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT"
|
media-cleanup-every = "24h";
|
||||||
"CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK"
|
# OIDC
|
||||||
"CAP_BLOCK_SUSPEND CAP_WAKE_ALARM"
|
oidc-enabled = true;
|
||||||
"CAP_SYS_TTY_CONFIG"
|
oidc-idp-name = "DTTH";
|
||||||
"CAP_MAC_ADMIN CAP_MAC_OVERRIDE"
|
oidc-scopes = [ "openid" "email" "profile" ];
|
||||||
"CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW"
|
# HTTP Client
|
||||||
"CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG "
|
http-client.block-ips = [ "11.0.0.0/24" ];
|
||||||
];
|
# Advanced
|
||||||
# You might need this if you are running as non-root on a privileged port (below 1024)
|
advanced-rate-limit-requests = 0;
|
||||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
# Storage
|
||||||
StateDirectory = "gotosocial";
|
storage-backend = "local";
|
||||||
WorkingDirectory = "/var/lib/gotosocial";
|
storage-local-base-path = "${storageLocation}/storage";
|
||||||
|
# instance-inject-mastodon-version = true;
|
||||||
};
|
};
|
||||||
wantedBy = [ "multi-user.target" ];
|
};
|
||||||
requires = [ "minio.service" "postgresql.service" ];
|
systemd.services.gotosocial.requires = mkAfter [ "postgresql.service" "arion-authentik.service" ];
|
||||||
|
systemd.services.gotosocial.after = mkAfter [ "postgresql.service" "arion-authentik.service" ];
|
||||||
|
systemd.services.gotosocial.unitConfig = {
|
||||||
|
RequiresMountsFor = [ storageLocation ];
|
||||||
|
ReadWritePaths = [ storageLocation ];
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.settings."10-gotosocial".${storageLocation}.d = {
|
||||||
|
user = dbUser;
|
||||||
|
group = dbUser;
|
||||||
|
mode = "0700";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,788 +0,0 @@
|
||||||
# Stub until 0.69.2 lands in stable
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
defaultUser = "outline";
|
|
||||||
cfg = config.cloud.services.outline;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# See here for a reference of all the options:
|
|
||||||
# https://github.com/outline/outline/blob/v0.67.0/.env.sample
|
|
||||||
# https://github.com/outline/outline/blob/v0.67.0/app.json
|
|
||||||
# https://github.com/outline/outline/blob/v0.67.0/server/env.ts
|
|
||||||
# https://github.com/outline/outline/blob/v0.67.0/shared/types.ts
|
|
||||||
# The order is kept the same here to make updating easier.
|
|
||||||
options.cloud.services.outline = {
|
|
||||||
enable = lib.mkEnableOption (lib.mdDoc "outline");
|
|
||||||
|
|
||||||
package = lib.mkOption {
|
|
||||||
default = pkgs.unstable.outline;
|
|
||||||
defaultText = lib.literalExpression "pkgs.unstable.outline";
|
|
||||||
type = lib.types.package;
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
pkgs.outline.overrideAttrs (super: {
|
|
||||||
# Ignore the domain part in emails that come from OIDC. This is might
|
|
||||||
# be helpful if you want multiple users with different email providers
|
|
||||||
# to still land in the same team. Note that this effectively makes
|
|
||||||
# Outline a single-team instance.
|
|
||||||
patchPhase = ${"''"}
|
|
||||||
sed -i 's/const domain = parts\.length && parts\[1\];/const domain = "example.com";/g' server/routes/auth/providers/oidc.ts
|
|
||||||
${"''"};
|
|
||||||
})
|
|
||||||
'';
|
|
||||||
description = lib.mdDoc "Outline package to use.";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = defaultUser;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
User under which the service should run. If this is the default value,
|
|
||||||
the user will be created, with the specified group as the primary
|
|
||||||
group.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = defaultUser;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Group under which the service should run. If this is the default value,
|
|
||||||
the group will be created.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sequelizeArguments = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "";
|
|
||||||
example = "--env=production-ssl-disabled";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Optional arguments to pass to `sequelize` calls.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
#
|
|
||||||
# Required options
|
|
||||||
#
|
|
||||||
|
|
||||||
secretKeyFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/outline/secret_key";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File path that contains the application secret key. It must be 32
|
|
||||||
bytes long and hex-encoded. If the file does not exist, a new key will
|
|
||||||
be generated and saved here.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
utilsSecretFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/var/lib/outline/utils_secret";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File path that contains the utility secret key. If the file does not
|
|
||||||
exist, a new key will be generated and saved here.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
databaseUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "local";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
URI to use for the main PostgreSQL database. If this needs to include
|
|
||||||
credentials that shouldn't be world-readable in the Nix store, set an
|
|
||||||
environment file on the systemd service and override the
|
|
||||||
`DATABASE_URL` entry. Pass the string
|
|
||||||
`local` to setup a database on the local server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
redisUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "local";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Connection to a redis server. If this needs to include credentials
|
|
||||||
that shouldn't be world-readable in the Nix store, set an environment
|
|
||||||
file on the systemd service and override the
|
|
||||||
`REDIS_URL` entry. Pass the string
|
|
||||||
`local` to setup a local Redis database.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
publicUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "http://localhost:3000";
|
|
||||||
description = lib.mdDoc "The fully qualified, publicly accessible URL";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 3000;
|
|
||||||
description = lib.mdDoc "Listening port.";
|
|
||||||
};
|
|
||||||
|
|
||||||
storage = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
To support uploading of images for avatars and document attachments an
|
|
||||||
s3-compatible storage must be provided. AWS S3 is recommended for
|
|
||||||
redundancy however if you want to keep all file storage local an
|
|
||||||
alternative such as [minio](https://github.com/minio/minio)
|
|
||||||
can be used.
|
|
||||||
|
|
||||||
A more detailed guide on setting up S3 is available
|
|
||||||
[here](https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f).
|
|
||||||
'';
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
{
|
|
||||||
accessKey = "...";
|
|
||||||
secretKeyFile = "/somewhere";
|
|
||||||
uploadBucketUrl = "https://minio.example.com";
|
|
||||||
uploadBucketName = "outline";
|
|
||||||
region = "us-east-1";
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
type = lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
accessKey = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "S3 access key.";
|
|
||||||
};
|
|
||||||
secretKeyFile = lib.mkOption {
|
|
||||||
type = lib.types.path;
|
|
||||||
description = lib.mdDoc "File path that contains the S3 secret key.";
|
|
||||||
};
|
|
||||||
region = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "xx-xxxx-x";
|
|
||||||
description = lib.mdDoc "AWS S3 region name.";
|
|
||||||
};
|
|
||||||
uploadBucketUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
URL endpoint of an S3-compatible API where uploads should be
|
|
||||||
stored.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
uploadBucketName = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Name of the bucket where uploads should be stored.";
|
|
||||||
};
|
|
||||||
uploadMaxSize = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 26214400;
|
|
||||||
description = lib.mdDoc "Maxmium file size for uploads.";
|
|
||||||
};
|
|
||||||
forcePathStyle = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc "Force S3 path style.";
|
|
||||||
};
|
|
||||||
acl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "private";
|
|
||||||
description = lib.mdDoc "ACL setting.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#
|
|
||||||
# Authentication
|
|
||||||
#
|
|
||||||
|
|
||||||
slackAuthentication = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
To configure Slack auth, you'll need to create an Application at
|
|
||||||
https://api.slack.com/apps
|
|
||||||
|
|
||||||
When configuring the Client ID, add a redirect URL under "OAuth & Permissions"
|
|
||||||
to `https://[publicUrl]/auth/slack.callback`.
|
|
||||||
'';
|
|
||||||
default = null;
|
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
clientId = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Authentication key.";
|
|
||||||
};
|
|
||||||
secretFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "File path containing the authentication secret.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
googleAuthentication = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
To configure Google auth, you'll need to create an OAuth Client ID at
|
|
||||||
https://console.cloud.google.com/apis/credentials
|
|
||||||
|
|
||||||
When configuring the Client ID, add an Authorized redirect URI to
|
|
||||||
`https://[publicUrl]/auth/google.callback`.
|
|
||||||
'';
|
|
||||||
default = null;
|
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
clientId = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Authentication client identifier.";
|
|
||||||
};
|
|
||||||
clientSecretFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "File path containing the authentication secret.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
azureAuthentication = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
To configure Microsoft/Azure auth, you'll need to create an OAuth
|
|
||||||
Client. See
|
|
||||||
[the guide](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4)
|
|
||||||
for details on setting up your Azure App.
|
|
||||||
'';
|
|
||||||
default = null;
|
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
clientId = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Authentication client identifier.";
|
|
||||||
};
|
|
||||||
clientSecretFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "File path containing the authentication secret.";
|
|
||||||
};
|
|
||||||
resourceAppId = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Authentication application resource ID.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
oidcAuthentication = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
To configure generic OIDC auth, you'll need some kind of identity
|
|
||||||
provider. See the documentation for whichever IdP you use to fill out
|
|
||||||
all the fields. The redirect URL is
|
|
||||||
`https://[publicUrl]/auth/oidc.callback`.
|
|
||||||
'';
|
|
||||||
default = null;
|
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
clientId = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Authentication client identifier.";
|
|
||||||
};
|
|
||||||
clientSecretFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "File path containing the authentication secret.";
|
|
||||||
};
|
|
||||||
authUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "OIDC authentication URL endpoint.";
|
|
||||||
};
|
|
||||||
tokenUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "OIDC token URL endpoint.";
|
|
||||||
};
|
|
||||||
userinfoUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "OIDC userinfo URL endpoint.";
|
|
||||||
};
|
|
||||||
usernameClaim = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Specify which claims to derive user information from. Supports any
|
|
||||||
valid JSON path with the JWT payload
|
|
||||||
'';
|
|
||||||
default = "preferred_username";
|
|
||||||
};
|
|
||||||
displayName = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Display name for OIDC authentication.";
|
|
||||||
default = "OpenID";
|
|
||||||
};
|
|
||||||
scopes = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
description = lib.mdDoc "OpenID authentication scopes.";
|
|
||||||
default = [ "openid" "profile" "email" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
#
|
|
||||||
# Optional configuration
|
|
||||||
#
|
|
||||||
|
|
||||||
sslKeyFile = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File path that contains the Base64-encoded private key for HTTPS
|
|
||||||
termination. This is only required if you do not use an external reverse
|
|
||||||
proxy. See
|
|
||||||
[the documentation](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
sslCertFile = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File path that contains the Base64-encoded certificate for HTTPS
|
|
||||||
termination. This is only required if you do not use an external reverse
|
|
||||||
proxy. See
|
|
||||||
[the documentation](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
cdnUrl = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
If using a Cloudfront/Cloudflare distribution or similar it can be set
|
|
||||||
using this option. This will cause paths to JavaScript files,
|
|
||||||
stylesheets and images to be updated to the hostname defined here. In
|
|
||||||
your CDN configuration the origin server should be set to public URL.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
forceHttps = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Auto-redirect to HTTPS in production. The default is
|
|
||||||
`true` but you may set this to `false`
|
|
||||||
if you can be sure that SSL is terminated at an external loadbalancer.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
enableUpdateCheck = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Have the installation check for updates by sending anonymized statistics
|
|
||||||
to the maintainers.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
concurrency = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 1;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
How many processes should be spawned. For a rough estimate, divide your
|
|
||||||
server's available memory by 512.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
maximumImportSize = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 5120000;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The maximum size of document imports. Overriding this could be required
|
|
||||||
if you have especially large Word documents with embedded imagery.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
debugOutput = lib.mkOption {
|
|
||||||
type = lib.types.nullOr (lib.types.enum [ "http" ]);
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc "Set this to `http` log HTTP requests.";
|
|
||||||
};
|
|
||||||
|
|
||||||
slackIntegration = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
For a complete Slack integration with search and posting to channels
|
|
||||||
this configuration is also needed. See here for details:
|
|
||||||
https://wiki.generaloutline.com/share/be25efd1-b3ef-4450-b8e5-c4a4fc11e02a
|
|
||||||
'';
|
|
||||||
default = null;
|
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
verificationTokenFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "File path containing the verification token.";
|
|
||||||
};
|
|
||||||
appId = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Application ID.";
|
|
||||||
};
|
|
||||||
messageActions = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc "Whether to enable message actions.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
googleAnalyticsId = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Optionally enable Google Analytics to track page views in the knowledge
|
|
||||||
base.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sentryDsn = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Optionally enable [Sentry](https://sentry.io/) to
|
|
||||||
track errors and performance.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sentryTunnel = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Optionally add a
|
|
||||||
[Sentry proxy tunnel](https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option)
|
|
||||||
for bypassing ad blockers in the UI.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
logo = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Custom logo displayed on the authentication screen. This will be scaled
|
|
||||||
to a height of 60px.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtp = lib.mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
To support sending outgoing transactional emails such as
|
|
||||||
"document updated" or "you've been invited" you'll need to provide
|
|
||||||
authentication for an SMTP server.
|
|
||||||
'';
|
|
||||||
default = null;
|
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
host = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Host name or IP address of the SMTP server.";
|
|
||||||
};
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
description = lib.mdDoc "TCP port of the SMTP server.";
|
|
||||||
};
|
|
||||||
username = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Username to authenticate with.";
|
|
||||||
};
|
|
||||||
passwordFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File path containing the password to authenticate with.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
fromEmail = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Sender email in outgoing mail.";
|
|
||||||
};
|
|
||||||
replyEmail = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = lib.mdDoc "Reply address in outgoing mail.";
|
|
||||||
};
|
|
||||||
tlsCiphers = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "";
|
|
||||||
description = lib.mdDoc "Override SMTP cipher configuration.";
|
|
||||||
};
|
|
||||||
secure = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc "Use a secure SMTP connection.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultLanguage = lib.mkOption {
|
|
||||||
type = lib.types.enum [
|
|
||||||
"da_DK"
|
|
||||||
"de_DE"
|
|
||||||
"en_US"
|
|
||||||
"es_ES"
|
|
||||||
"fa_IR"
|
|
||||||
"fr_FR"
|
|
||||||
"it_IT"
|
|
||||||
"ja_JP"
|
|
||||||
"ko_KR"
|
|
||||||
"nl_NL"
|
|
||||||
"pl_PL"
|
|
||||||
"pt_BR"
|
|
||||||
"pt_PT"
|
|
||||||
"ru_RU"
|
|
||||||
"sv_SE"
|
|
||||||
"th_TH"
|
|
||||||
"vi_VN"
|
|
||||||
"zh_CN"
|
|
||||||
"zh_TW"
|
|
||||||
];
|
|
||||||
default = "en_US";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The default interface language. See
|
|
||||||
[translate.getoutline.com](https://translate.getoutline.com/)
|
|
||||||
for a list of available language codes and their rough percentage
|
|
||||||
translated.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
rateLimiter.enable = lib.mkEnableOption (lib.mdDoc "rate limiter for the application web server");
|
|
||||||
rateLimiter.requests = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 5000;
|
|
||||||
description = lib.mdDoc "Maximum number of requests in a throttling window.";
|
|
||||||
};
|
|
||||||
rateLimiter.durationWindow = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 60;
|
|
||||||
description = lib.mdDoc "Length of a throttling window.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
assertions = [
|
|
||||||
{ assertion = pkgs.outline.version == "0.68.1"; message = "Please use the nixpkgs module for outline > 0.68.1"; }
|
|
||||||
];
|
|
||||||
users.users = lib.optionalAttrs (cfg.user == defaultUser) {
|
|
||||||
${defaultUser} = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = cfg.group;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups = lib.optionalAttrs (cfg.group == defaultUser) {
|
|
||||||
${defaultUser} = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"f ${cfg.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
|
|
||||||
"f ${cfg.utilsSecretFile} 0600 ${cfg.user} ${cfg.group} -"
|
|
||||||
"f ${cfg.storage.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.postgresql = lib.mkIf (cfg.databaseUrl == "local") {
|
|
||||||
enable = true;
|
|
||||||
ensureUsers = [{
|
|
||||||
name = "outline";
|
|
||||||
ensurePermissions."DATABASE outline" = "ALL PRIVILEGES";
|
|
||||||
}];
|
|
||||||
ensureDatabases = [ "outline" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.redis.servers.outline = lib.mkIf (cfg.redisUrl == "local") {
|
|
||||||
enable = true;
|
|
||||||
user = config.services.outline.user;
|
|
||||||
port = 0; # Disable the TCP listener
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.outline =
|
|
||||||
let
|
|
||||||
localRedisUrl = "redis+unix:///run/redis-outline/redis.sock";
|
|
||||||
localPostgresqlUrl = "postgres://localhost/outline?host=/run/postgresql";
|
|
||||||
|
|
||||||
# Create an outline-sequalize wrapper (a wrapper around the wrapper) that
|
|
||||||
# has the config file's path baked in. This is necessary because there is
|
|
||||||
# at least two occurrences of outline calling this from its own code.
|
|
||||||
sequelize = pkgs.writeShellScriptBin "outline-sequelize" ''
|
|
||||||
exec ${cfg.package}/bin/outline-sequelize \
|
|
||||||
--config $RUNTIME_DIRECTORY/database.json \
|
|
||||||
${cfg.sequelizeArguments} \
|
|
||||||
"$@"
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
description = "Outline wiki and knowledge base";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "networking.target" ]
|
|
||||||
++ lib.optional (cfg.databaseUrl == "local") "postgresql.service"
|
|
||||||
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
|
|
||||||
requires = lib.optional (cfg.databaseUrl == "local") "postgresql.service"
|
|
||||||
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
|
|
||||||
path = [
|
|
||||||
pkgs.openssl # Required by the preStart script
|
|
||||||
sequelize
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
environment = lib.mkMerge [
|
|
||||||
{
|
|
||||||
NODE_ENV = "production";
|
|
||||||
|
|
||||||
REDIS_URL = if cfg.redisUrl == "local" then localRedisUrl else cfg.redisUrl;
|
|
||||||
URL = cfg.publicUrl;
|
|
||||||
PORT = builtins.toString cfg.port;
|
|
||||||
|
|
||||||
AWS_ACCESS_KEY_ID = cfg.storage.accessKey;
|
|
||||||
AWS_REGION = cfg.storage.region;
|
|
||||||
AWS_S3_UPLOAD_BUCKET_URL = cfg.storage.uploadBucketUrl;
|
|
||||||
AWS_S3_UPLOAD_BUCKET_NAME = cfg.storage.uploadBucketName;
|
|
||||||
AWS_S3_UPLOAD_MAX_SIZE = builtins.toString cfg.storage.uploadMaxSize;
|
|
||||||
AWS_S3_FORCE_PATH_STYLE = builtins.toString cfg.storage.forcePathStyle;
|
|
||||||
AWS_S3_ACL = cfg.storage.acl;
|
|
||||||
|
|
||||||
CDN_URL = cfg.cdnUrl;
|
|
||||||
FORCE_HTTPS = builtins.toString cfg.forceHttps;
|
|
||||||
ENABLE_UPDATES = builtins.toString cfg.enableUpdateCheck;
|
|
||||||
WEB_CONCURRENCY = builtins.toString cfg.concurrency;
|
|
||||||
MAXIMUM_IMPORT_SIZE = builtins.toString cfg.maximumImportSize;
|
|
||||||
DEBUG = cfg.debugOutput;
|
|
||||||
GOOGLE_ANALYTICS_ID = lib.optionalString (cfg.googleAnalyticsId != null) cfg.googleAnalyticsId;
|
|
||||||
SENTRY_DSN = lib.optionalString (cfg.sentryDsn != null) cfg.sentryDsn;
|
|
||||||
SENTRY_TUNNEL = lib.optionalString (cfg.sentryTunnel != null) cfg.sentryTunnel;
|
|
||||||
TEAM_LOGO = lib.optionalString (cfg.logo != null) cfg.logo;
|
|
||||||
DEFAULT_LANGUAGE = cfg.defaultLanguage;
|
|
||||||
|
|
||||||
RATE_LIMITER_ENABLED = builtins.toString cfg.rateLimiter.enable;
|
|
||||||
RATE_LIMITER_REQUESTS = builtins.toString cfg.rateLimiter.requests;
|
|
||||||
RATE_LIMITER_DURATION_WINDOW = builtins.toString cfg.rateLimiter.durationWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.slackAuthentication != null) {
|
|
||||||
SLACK_CLIENT_ID = cfg.slackAuthentication.clientId;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.googleAuthentication != null) {
|
|
||||||
GOOGLE_CLIENT_ID = cfg.googleAuthentication.clientId;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.azureAuthentication != null) {
|
|
||||||
AZURE_CLIENT_ID = cfg.azureAuthentication.clientId;
|
|
||||||
AZURE_RESOURCE_APP_ID = cfg.azureAuthentication.resourceAppId;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.oidcAuthentication != null) {
|
|
||||||
OIDC_CLIENT_ID = cfg.oidcAuthentication.clientId;
|
|
||||||
OIDC_AUTH_URI = cfg.oidcAuthentication.authUrl;
|
|
||||||
OIDC_TOKEN_URI = cfg.oidcAuthentication.tokenUrl;
|
|
||||||
OIDC_USERINFO_URI = cfg.oidcAuthentication.userinfoUrl;
|
|
||||||
OIDC_USERNAME_CLAIM = cfg.oidcAuthentication.usernameClaim;
|
|
||||||
OIDC_DISPLAY_NAME = cfg.oidcAuthentication.displayName;
|
|
||||||
OIDC_SCOPES = lib.concatStringsSep " " cfg.oidcAuthentication.scopes;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.slackIntegration != null) {
|
|
||||||
SLACK_APP_ID = cfg.slackIntegration.appId;
|
|
||||||
SLACK_MESSAGE_ACTIONS = builtins.toString cfg.slackIntegration.messageActions;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf (cfg.smtp != null) {
|
|
||||||
SMTP_HOST = cfg.smtp.host;
|
|
||||||
SMTP_PORT = builtins.toString cfg.smtp.port;
|
|
||||||
SMTP_USERNAME = cfg.smtp.username;
|
|
||||||
SMTP_FROM_EMAIL = cfg.smtp.fromEmail;
|
|
||||||
SMTP_REPLY_EMAIL = cfg.smtp.replyEmail;
|
|
||||||
SMTP_TLS_CIPHERS = cfg.smtp.tlsCiphers;
|
|
||||||
SMTP_SECURE = builtins.toString cfg.smtp.secure;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
preStart = ''
|
|
||||||
if [ ! -s ${lib.escapeShellArg cfg.secretKeyFile} ]; then
|
|
||||||
openssl rand -hex 32 > ${lib.escapeShellArg cfg.secretKeyFile}
|
|
||||||
fi
|
|
||||||
if [ ! -s ${lib.escapeShellArg cfg.utilsSecretFile} ]; then
|
|
||||||
openssl rand -hex 32 > ${lib.escapeShellArg cfg.utilsSecretFile}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# The config file is required for the sequelize CLI.
|
|
||||||
${if (cfg.databaseUrl == "local") then ''
|
|
||||||
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
|
||||||
{
|
|
||||||
"production-ssl-disabled": {
|
|
||||||
"host": "/run/postgresql",
|
|
||||||
"username": null,
|
|
||||||
"password": null,
|
|
||||||
"dialect": "postgres"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
'' else ''
|
|
||||||
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
|
||||||
{
|
|
||||||
"production": {
|
|
||||||
"use_env_variable": "DATABASE_URL",
|
|
||||||
"dialect": "postgres",
|
|
||||||
"dialectOptions": {
|
|
||||||
"ssl": {
|
|
||||||
"rejectUnauthorized": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"production-ssl-disabled": {
|
|
||||||
"use_env_variable": "DATABASE_URL",
|
|
||||||
"dialect": "postgres"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
|
|
||||||
script = ''
|
|
||||||
export SECRET_KEY="$(head -n1 ${lib.escapeShellArg cfg.secretKeyFile})"
|
|
||||||
export UTILS_SECRET="$(head -n1 ${lib.escapeShellArg cfg.utilsSecretFile})"
|
|
||||||
export AWS_SECRET_ACCESS_KEY="$(head -n1 ${lib.escapeShellArg cfg.storage.secretKeyFile})"
|
|
||||||
${lib.optionalString (cfg.slackAuthentication != null) ''
|
|
||||||
export SLACK_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.slackAuthentication.secretFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.googleAuthentication != null) ''
|
|
||||||
export GOOGLE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.googleAuthentication.clientSecretFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.azureAuthentication != null) ''
|
|
||||||
export AZURE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.azureAuthentication.clientSecretFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.oidcAuthentication != null) ''
|
|
||||||
export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.sslKeyFile != null) ''
|
|
||||||
export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.sslCertFile != null) ''
|
|
||||||
export SSL_CERT="$(head -n1 ${lib.escapeShellArg cfg.sslCertFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.slackIntegration != null) ''
|
|
||||||
export SLACK_VERIFICATION_TOKEN="$(head -n1 ${lib.escapeShellArg cfg.slackIntegration.verificationTokenFile})"
|
|
||||||
''}
|
|
||||||
${lib.optionalString (cfg.smtp != null) ''
|
|
||||||
export SMTP_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.smtp.passwordFile})"
|
|
||||||
''}
|
|
||||||
|
|
||||||
${if (cfg.databaseUrl == "local") then ''
|
|
||||||
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
|
|
||||||
export PGSSLMODE=disable
|
|
||||||
'' else ''
|
|
||||||
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
|
|
||||||
''}
|
|
||||||
|
|
||||||
${cfg.package}/bin/outline-server
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
Restart = "always";
|
|
||||||
ProtectSystem = "strict";
|
|
||||||
PrivateHome = true;
|
|
||||||
PrivateTmp = true;
|
|
||||||
UMask = "0007";
|
|
||||||
|
|
||||||
StateDirectory = "outline";
|
|
||||||
StateDirectoryMode = "0750";
|
|
||||||
RuntimeDirectory = "outline";
|
|
||||||
RuntimeDirectoryMode = "0750";
|
|
||||||
# This working directory is required to find stuff like the set of
|
|
||||||
# onboarding files:
|
|
||||||
WorkingDirectory = "${cfg.package}/share/outline";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ index d218dbc1f..24c0505e3 100644
|
||||||
/**
|
/**
|
||||||
* The product name
|
* The product name
|
||||||
*/
|
*/
|
||||||
|
@Public
|
||||||
- public APP_NAME = "Outline";
|
- public APP_NAME = "Outline";
|
||||||
+ public APP_NAME = "DTTH Wiki";
|
+ public APP_NAME = "DTTH Wiki";
|
||||||
|
|
||||||
|
|
183
modules/cloud/outline/r2.patch
Normal file
183
modules/cloud/outline/r2.patch
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
commit 8c7f8c28fabc174a71499a4737579b24b5c4b244
|
||||||
|
Author: Natsu Kagami <nki@nkagami.me>
|
||||||
|
Date: Mon Oct 21 02:17:36 2024 +0200
|
||||||
|
|
||||||
|
Support R2
|
||||||
|
|
||||||
|
diff --git a/.env.sample b/.env.sample
|
||||||
|
index eb57ad85c..94ffcee07 100644
|
||||||
|
--- a/.env.sample
|
||||||
|
+++ b/.env.sample
|
||||||
|
@@ -66,6 +66,8 @@ AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
|
||||||
|
AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
|
||||||
|
AWS_S3_FORCE_PATH_STYLE=true
|
||||||
|
AWS_S3_ACL=private
|
||||||
|
+AWS_S3_R2=true
|
||||||
|
+AWS_S3_R2_PUBLIC_URL=http://s3:4569
|
||||||
|
|
||||||
|
# –––––––––––––– AUTHENTICATION ––––––––––––––
|
||||||
|
|
||||||
|
diff --git a/app/utils/files.ts b/app/utils/files.ts
|
||||||
|
index 6607a6b12..5138f68ad 100644
|
||||||
|
--- a/app/utils/files.ts
|
||||||
|
+++ b/app/utils/files.ts
|
||||||
|
@@ -63,8 +63,13 @@ export const uploadFile = async (
|
||||||
|
xhr.addEventListener("loadend", () => {
|
||||||
|
resolve(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400);
|
||||||
|
});
|
||||||
|
- xhr.open("POST", data.uploadUrl, true);
|
||||||
|
- xhr.send(formData);
|
||||||
|
+ xhr.open(data.method, data.uploadUrl, true);
|
||||||
|
+ xhr.setRequestHeader("Content-Type", file.type);
|
||||||
|
+ if (data.method === "POST") {
|
||||||
|
+ xhr.send(formData);
|
||||||
|
+ } else {
|
||||||
|
+ xhr.send(file);
|
||||||
|
+ }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
diff --git a/server/env.ts b/server/env.ts
|
||||||
|
index 5b420f2e1..4ea1e8d3c 100644
|
||||||
|
--- a/server/env.ts
|
||||||
|
+++ b/server/env.ts
|
||||||
|
@@ -519,6 +519,14 @@ export class Environment {
|
||||||
|
environment.AWS_S3_UPLOAD_BUCKET_NAME
|
||||||
|
);
|
||||||
|
|
||||||
|
+ @IsOptional()
|
||||||
|
+ public AWS_S3_R2 = this.toBoolean(environment.AWS_S3_R2 ?? "false");
|
||||||
|
+
|
||||||
|
+ @IsOptional()
|
||||||
|
+ public AWS_S3_R2_PUBLIC_URL = this.toOptionalString(
|
||||||
|
+ environment.AWS_S3_R2_PUBLIC_URL
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Whether to force path style URLs for S3 objects, this is required for some
|
||||||
|
* S3-compatible storage providers.
|
||||||
|
diff --git a/server/routes/api/attachments/attachments.ts b/server/routes/api/attachments/attachments.ts
|
||||||
|
index 5e6c27594..b7620f440 100644
|
||||||
|
--- a/server/routes/api/attachments/attachments.ts
|
||||||
|
+++ b/server/routes/api/attachments/attachments.ts
|
||||||
|
@@ -3,6 +3,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { AttachmentPreset } from "@shared/types";
|
||||||
|
import { bytesToHumanReadable } from "@shared/utils/files";
|
||||||
|
import { AttachmentValidation } from "@shared/validations";
|
||||||
|
+import env from "@server/env";
|
||||||
|
import { AuthorizationError, ValidationError } from "@server/errors";
|
||||||
|
import auth from "@server/middlewares/authentication";
|
||||||
|
import { rateLimiter } from "@server/middlewares/rateLimiter";
|
||||||
|
@@ -90,16 +91,30 @@ router.post(
|
||||||
|
{ transaction }
|
||||||
|
);
|
||||||
|
|
||||||
|
- const presignedPost = await FileStorage.getPresignedPost(
|
||||||
|
- key,
|
||||||
|
- acl,
|
||||||
|
- maxUploadSize,
|
||||||
|
- contentType
|
||||||
|
- );
|
||||||
|
+ let uploadUrl;
|
||||||
|
+ let method;
|
||||||
|
+ let presignedPost = {
|
||||||
|
+ fields: {},
|
||||||
|
+ };
|
||||||
|
+ if (env.AWS_S3_R2) {
|
||||||
|
+ uploadUrl = await FileStorage.getPresignedPut(key);
|
||||||
|
+ method = "PUT";
|
||||||
|
+ } else {
|
||||||
|
+ uploadUrl = FileStorage.getUploadUrl();
|
||||||
|
+ method = "POST";
|
||||||
|
+
|
||||||
|
+ presignedPost = await FileStorage.getPresignedPost(
|
||||||
|
+ key,
|
||||||
|
+ acl,
|
||||||
|
+ maxUploadSize,
|
||||||
|
+ contentType
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ctx.body = {
|
||||||
|
data: {
|
||||||
|
- uploadUrl: FileStorage.getUploadUrl(),
|
||||||
|
+ uploadUrl,
|
||||||
|
+ method,
|
||||||
|
form: {
|
||||||
|
"Cache-Control": "max-age=31557600",
|
||||||
|
"Content-Type": contentType,
|
||||||
|
diff --git a/server/storage/files/BaseStorage.ts b/server/storage/files/BaseStorage.ts
|
||||||
|
index ce0287ebc..a1931c83d 100644
|
||||||
|
--- a/server/storage/files/BaseStorage.ts
|
||||||
|
+++ b/server/storage/files/BaseStorage.ts
|
||||||
|
@@ -26,6 +26,8 @@ export default abstract class BaseStorage {
|
||||||
|
contentType: string
|
||||||
|
): Promise<Partial<PresignedPost>>;
|
||||||
|
|
||||||
|
+ public abstract getPresignedPut(key: string): Promise<string>;
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Returns a promise that resolves with a stream for reading a file from the storage provider.
|
||||||
|
*
|
||||||
|
diff --git a/server/storage/files/LocalStorage.ts b/server/storage/files/LocalStorage.ts
|
||||||
|
index 83cf98c50..324e60dd9 100644
|
||||||
|
--- a/server/storage/files/LocalStorage.ts
|
||||||
|
+++ b/server/storage/files/LocalStorage.ts
|
||||||
|
@@ -30,6 +30,10 @@ export default class LocalStorage extends BaseStorage {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public async getPresignedPut(key: string) {
|
||||||
|
+ return this.getUrlForKey(key);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
public getUploadUrl() {
|
||||||
|
return "/api/files.create";
|
||||||
|
}
|
||||||
|
diff --git a/server/storage/files/S3Storage.ts b/server/storage/files/S3Storage.ts
|
||||||
|
index a42442e0c..d55ef5472 100644
|
||||||
|
--- a/server/storage/files/S3Storage.ts
|
||||||
|
+++ b/server/storage/files/S3Storage.ts
|
||||||
|
@@ -4,6 +4,7 @@ import {
|
||||||
|
S3Client,
|
||||||
|
DeleteObjectCommand,
|
||||||
|
GetObjectCommand,
|
||||||
|
+ PutObjectCommand,
|
||||||
|
ObjectCannedACL,
|
||||||
|
} from "@aws-sdk/client-s3";
|
||||||
|
import { Upload } from "@aws-sdk/lib-storage";
|
||||||
|
@@ -58,6 +59,16 @@ export default class S3Storage extends BaseStorage {
|
||||||
|
return createPresignedPost(this.client, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public async getPresignedPut(key: string) {
|
||||||
|
+ const params = {
|
||||||
|
+ Bucket: env.AWS_S3_UPLOAD_BUCKET_NAME,
|
||||||
|
+ Key: key,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ const command = new PutObjectCommand(params);
|
||||||
|
+ return await getSignedUrl(this.client, command, { expiresIn: 3600 });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private getPublicEndpoint(isServerUpload?: boolean) {
|
||||||
|
if (env.AWS_S3_ACCELERATE_URL) {
|
||||||
|
return env.AWS_S3_ACCELERATE_URL;
|
||||||
|
@@ -137,10 +148,17 @@ export default class S3Storage extends BaseStorage {
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public getR2ObjectUrl = async (key: string) =>
|
||||||
|
+ env.AWS_S3_R2_PUBLIC_URL + "/" + key;
|
||||||
|
+
|
||||||
|
public getSignedUrl = async (
|
||||||
|
key: string,
|
||||||
|
expiresIn = S3Storage.defaultSignedUrlExpires
|
||||||
|
) => {
|
||||||
|
+ if (env.AWS_S3_R2) {
|
||||||
|
+ return this.getR2ObjectUrl(key);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
const isDocker = env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
|
||||||
|
const params = {
|
||||||
|
Bucket: this.getBucket(),
|
|
@ -9,9 +9,7 @@ let
|
||||||
# to that database.
|
# to that database.
|
||||||
userFromDatabase = databaseName: {
|
userFromDatabase = databaseName: {
|
||||||
name = databaseName;
|
name = databaseName;
|
||||||
ensurePermissions = {
|
ensureDBOwnership = true;
|
||||||
"DATABASE \"${databaseName}\"" = "ALL PRIVILEGES";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -32,10 +30,14 @@ in
|
||||||
|
|
||||||
ensureDatabases = cfg.databases;
|
ensureDatabases = cfg.databases;
|
||||||
|
|
||||||
ensureUsers = (map userFromDatabase cfg.databases) ++ [{
|
ensureUsers = (map userFromDatabase cfg.databases);
|
||||||
name = "root";
|
|
||||||
ensurePermissions = { "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES"; };
|
dataDir = "/mnt/data/postgresql/${config.services.postgresql.package.psqlSchema}";
|
||||||
}];
|
};
|
||||||
|
|
||||||
|
config.systemd.services.postgresql.serviceConfig = {
|
||||||
|
StateDirectory = "postgresql postgresql ${config.services.postgresql.dataDir}";
|
||||||
|
StateDirectoryMode = "0750";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Backup settings
|
# Backup settings
|
||||||
|
|
|
@ -20,6 +20,24 @@ let
|
||||||
in
|
in
|
||||||
valueType;
|
valueType;
|
||||||
|
|
||||||
|
# https://www.cloudflare.com/ips/
|
||||||
|
trustedIPs =
|
||||||
|
let
|
||||||
|
files = [
|
||||||
|
(pkgs.fetchurl {
|
||||||
|
url = "https://www.cloudflare.com/ips-v4";
|
||||||
|
hash = "sha256-8Cxtg7wBqwroV3Fg4DbXAMdFU1m84FTfiE5dfZ5Onns=";
|
||||||
|
})
|
||||||
|
(pkgs.fetchurl {
|
||||||
|
url = "https://www.cloudflare.com/ips-v6";
|
||||||
|
hash = "sha256-np054+g7rQDE3sr9U8Y/piAp89ldto3pN9K+KCNMoKk=";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
readLines = path: lib.splitString "\n" (builtins.readFile path);
|
||||||
|
in
|
||||||
|
lib.concatMap readLines files;
|
||||||
|
|
||||||
cfg = config.cloud.traefik;
|
cfg = config.cloud.traefik;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -57,6 +75,7 @@ in
|
||||||
};
|
};
|
||||||
## HTTPS entrypoint: ok!
|
## HTTPS entrypoint: ok!
|
||||||
entrypoints.https.address = ":443";
|
entrypoints.https.address = ":443";
|
||||||
|
entrypoints.https.forwardedHeaders.trustedIPs = trustedIPs;
|
||||||
## IMAP and SMTP
|
## IMAP and SMTP
|
||||||
entrypoints.imap.address = ":993";
|
entrypoints.imap.address = ":993";
|
||||||
entrypoints.smtp-submission.address = ":587";
|
entrypoints.smtp-submission.address = ":587";
|
||||||
|
|
|
@ -26,14 +26,25 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
accounts = { pkgs, ... }: mkIf config.common.linux.enable {
|
graphics = { config, ... }: {
|
||||||
environment.systemPackages = with pkgs.gnome; [ pkgs.glib gnome-control-center ];
|
hardware =
|
||||||
|
if config.system.nixos.release == "24.05" then {
|
||||||
|
opengl.enable = true;
|
||||||
|
opengl.driSupport32Bit = true;
|
||||||
|
} else {
|
||||||
|
graphics.enable = true;
|
||||||
|
graphics.enable32Bit = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts = { pkgs, ... }: mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
|
||||||
|
environment.systemPackages = [ pkgs.glib (pkgs.gnome-control-center or pkgs.gnome.gnome-control-center) ];
|
||||||
services.accounts-daemon.enable = true;
|
services.accounts-daemon.enable = true;
|
||||||
services.gnome.gnome-online-accounts.enable = true;
|
services.gnome.gnome-online-accounts.enable = true;
|
||||||
programs.evolution.enable = true;
|
# programs.evolution.enable = true;
|
||||||
programs.evolution.plugins = with pkgs; [ evolution-ews ];
|
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
|
||||||
services.gnome.evolution-data-server.enable = true;
|
# services.gnome.evolution-data-server.enable = true;
|
||||||
services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
|
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr = { ... }: mkIf config.common.linux.enable {
|
wlr = { ... }: mkIf config.common.linux.enable {
|
||||||
|
@ -49,6 +60,14 @@ let
|
||||||
environment.systemPackages = with pkgs; [ piper ];
|
environment.systemPackages = with pkgs; [ piper ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kwallet = { pkgs, lib, ... }: mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
|
||||||
|
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
|
||||||
|
xdg.portal = {
|
||||||
|
extraPortals = [ pkgs.kdePackages.kwallet ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
virtualisation = { pkgs, ... }: mkIf cfg.enable {
|
virtualisation = { pkgs, ... }: mkIf cfg.enable {
|
||||||
virtualisation.podman = {
|
virtualisation.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -58,13 +77,56 @@ let
|
||||||
|
|
||||||
virtualisation.oci-containers.backend = "podman";
|
virtualisation.oci-containers.backend = "podman";
|
||||||
|
|
||||||
virtualisation.virtualbox.host.enable = true;
|
virtualisation.virtualbox.host.enable = false;
|
||||||
users.extraGroups.vboxusers.members = [ cfg.username ];
|
users.extraGroups.vboxusers.members = [ cfg.username ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rt-audio = { pkgs, ... }: mkIf cfg.enable {
|
||||||
|
services.pipewire.lowLatency = {
|
||||||
|
# enable this module
|
||||||
|
enable = true;
|
||||||
|
# defaults (no need to be set unless modified)
|
||||||
|
quantum = 32;
|
||||||
|
rate = 48000;
|
||||||
|
};
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
|
||||||
|
# Real time configurations
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
"vm.swappiness" = 10;
|
||||||
|
"fs.inotify.max_user_watches" = 524288;
|
||||||
|
};
|
||||||
|
security.pam.loginLimits = [
|
||||||
|
{
|
||||||
|
domain = "@audio";
|
||||||
|
item = "rtprio";
|
||||||
|
type = "-";
|
||||||
|
value = "90";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "@audio";
|
||||||
|
item = "memlock";
|
||||||
|
type = "-";
|
||||||
|
value = "unlimited";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = with modules; [ adb ios wlr logitech virtualisation accounts ];
|
imports = with modules; [
|
||||||
|
./sops.nix
|
||||||
|
|
||||||
|
adb
|
||||||
|
ios
|
||||||
|
graphics
|
||||||
|
wlr
|
||||||
|
logitech
|
||||||
|
kwallet
|
||||||
|
virtualisation
|
||||||
|
accounts
|
||||||
|
rt-audio
|
||||||
|
];
|
||||||
|
|
||||||
options.common.linux = {
|
options.common.linux = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
|
@ -87,7 +149,7 @@ in
|
||||||
dnsServers = mkOption {
|
dnsServers = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = "DNS server list";
|
description = "DNS server list";
|
||||||
default = [ "8.8.8.8" "8.8.4.4" ];
|
default = [ "1.1.1.1" "2606:4700:4700:1111" ];
|
||||||
};
|
};
|
||||||
networks = mkOption {
|
networks = mkOption {
|
||||||
type = types.attrsOf (types.submodule {
|
type = types.attrsOf (types.submodule {
|
||||||
|
@ -121,11 +183,10 @@ in
|
||||||
boot.kernelPackages = mkDefault pkgs.linuxPackages_latest;
|
boot.kernelPackages = mkDefault pkgs.linuxPackages_latest;
|
||||||
# Use the systemd-boot EFI boot loader.
|
# Use the systemd-boot EFI boot loader.
|
||||||
boot = {
|
boot = {
|
||||||
plymouth.enable = true;
|
|
||||||
loader.timeout = 60;
|
loader.timeout = 60;
|
||||||
loader.systemd-boot.enable = true;
|
loader.systemd-boot.enable = true;
|
||||||
loader.efi.canTouchEfiVariables = true;
|
loader.efi.canTouchEfiVariables = true;
|
||||||
supportedFilesystems = [ "ntfs" ];
|
supportedFilesystems.ntfs = true;
|
||||||
};
|
};
|
||||||
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
|
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
|
||||||
# LUKS devices
|
# LUKS devices
|
||||||
|
@ -143,8 +204,11 @@ in
|
||||||
cfg.luksDevices;
|
cfg.luksDevices;
|
||||||
|
|
||||||
## Hardware-related
|
## Hardware-related
|
||||||
|
|
||||||
|
# Firmware stuff
|
||||||
|
services.fwupd.enable = true;
|
||||||
|
|
||||||
# Enable sound.
|
# Enable sound.
|
||||||
sound.enable = true;
|
|
||||||
services.pipewire = {
|
services.pipewire = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# alsa is optional
|
# alsa is optional
|
||||||
|
@ -153,6 +217,7 @@ in
|
||||||
|
|
||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# udev configurations
|
# udev configurations
|
||||||
services.udev.packages = with pkgs; [
|
services.udev.packages = with pkgs; [
|
||||||
qmk-udev-rules # For keyboards
|
qmk-udev-rules # For keyboards
|
||||||
|
@ -174,12 +239,17 @@ in
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"wheel" # Enable ‘sudo’ for the user.
|
"wheel" # Enable ‘sudo’ for the user.
|
||||||
"plugdev" # Enable openrazer-daemon privileges
|
"plugdev" # Enable openrazer-daemon privileges
|
||||||
|
"audio"
|
||||||
];
|
];
|
||||||
|
shell = pkgs.fish;
|
||||||
};
|
};
|
||||||
|
nix.settings.trusted-users = [ "root" cfg.username ];
|
||||||
|
|
||||||
## Network configuration
|
## Network configuration
|
||||||
systemd.network.enable = true;
|
systemd.network.enable = true;
|
||||||
networking.dhcpcd.enable = lib.mkForce false;
|
networking.dhcpcd.enable = lib.mkForce false;
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.useNetworkd = true;
|
||||||
systemd.network.wait-online.enable = false;
|
systemd.network.wait-online.enable = false;
|
||||||
networking.hostName = cfg.networking.hostname;
|
networking.hostName = cfg.networking.hostname;
|
||||||
networking.wireless.iwd.enable = true;
|
networking.wireless.iwd.enable = true;
|
||||||
|
@ -202,38 +272,44 @@ in
|
||||||
services.tailscale.enable = true;
|
services.tailscale.enable = true;
|
||||||
|
|
||||||
## Time and Region
|
## Time and Region
|
||||||
time.timeZone = "Europe/Zurich";
|
time.timeZone = lib.mkDefault "Europe/Zurich";
|
||||||
# Select internationalisation properties.
|
# Select internationalisation properties.
|
||||||
console.keyMap = "jp106"; # Console key layout
|
console.keyMap = "jp106"; # Console key layout
|
||||||
i18n.defaultLocale = "ja_JP.UTF-8";
|
i18n.defaultLocale = "ja_JP.UTF-8";
|
||||||
# Input methods (only fcitx5 works reliably on Wayland)
|
# Input methods (only fcitx5 works reliably on Wayland)
|
||||||
i18n.inputMethod = {
|
i18n.inputMethod = {
|
||||||
enabled = "fcitx5";
|
fcitx5.waylandFrontend = true;
|
||||||
fcitx5.addons = with pkgs; [
|
fcitx5.addons = with pkgs; [
|
||||||
fcitx5-mozc
|
fcitx5-mozc
|
||||||
fcitx5-unikey
|
fcitx5-unikey
|
||||||
fcitx5-gtk
|
fcitx5-gtk
|
||||||
];
|
];
|
||||||
};
|
} // (if config.system.nixos.release == "24.05" then {
|
||||||
|
enabled = "fcitx5";
|
||||||
|
} else {
|
||||||
|
enable = true;
|
||||||
|
type = "fcitx5";
|
||||||
|
});
|
||||||
|
|
||||||
# Default packages
|
# Default packages
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
kakoune # An editor
|
kakoune # An editor
|
||||||
wget # A simple fetcher
|
wget # A simple fetcher
|
||||||
fish # Good shell
|
|
||||||
|
|
||||||
## System monitoring tools
|
## System monitoring tools
|
||||||
usbutils # lsusb and friends
|
usbutils # lsusb and friends
|
||||||
pciutils # lspci and friends
|
pciutils # lspci and friends
|
||||||
psmisc # killall, pstree, ...
|
psmisc # killall, pstree, ...
|
||||||
|
lm_sensors # sensors
|
||||||
|
|
||||||
## Security stuff
|
## Security stuff
|
||||||
libsForQt5.qtkeychain
|
libsForQt5.qtkeychain
|
||||||
|
|
||||||
## Wayland
|
## Wayland
|
||||||
qt5.qtwayland
|
kdePackages.qtwayland
|
||||||
];
|
];
|
||||||
# Add a reliable terminal
|
# Add a reliable terminal
|
||||||
|
programs.fish.enable = true;
|
||||||
# programs.gnome-terminal.enable = true;
|
# programs.gnome-terminal.enable = true;
|
||||||
# KDEConnect is just based
|
# KDEConnect is just based
|
||||||
programs.kdeconnect.enable = true;
|
programs.kdeconnect.enable = true;
|
||||||
|
@ -243,20 +319,13 @@ in
|
||||||
programs.dconf.enable = true;
|
programs.dconf.enable = true;
|
||||||
# Gaming! (not for ARM64)
|
# Gaming! (not for ARM64)
|
||||||
programs.steam.enable = !pkgs.stdenv.isAarch64;
|
programs.steam.enable = !pkgs.stdenv.isAarch64;
|
||||||
hardware.opengl.enable = true;
|
|
||||||
hardware.opengl.driSupport = true;
|
|
||||||
hardware.opengl.driSupport32Bit = !pkgs.stdenv.isAarch64; # For 32 bit applications
|
|
||||||
|
|
||||||
## Services
|
## Services
|
||||||
# gnome-keyring for storing keys
|
|
||||||
services.gnome.gnome-keyring.enable = true;
|
|
||||||
# OpenSSH so you can SSH to me
|
# OpenSSH so you can SSH to me
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
# PAM
|
# PAM
|
||||||
security.pam.services.login.enableKwallet = true;
|
security.pam.services.login.enableKwallet = true;
|
||||||
security.pam.services.login.enableGnomeKeyring = true;
|
|
||||||
security.pam.services.lightdm.enableKwallet = true;
|
security.pam.services.lightdm.enableKwallet = true;
|
||||||
security.pam.services.lightdm.enableGnomeKeyring = true;
|
|
||||||
security.pam.services.swaylock = { };
|
security.pam.services.swaylock = { };
|
||||||
# Printers
|
# Printers
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
|
@ -264,8 +333,11 @@ in
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wlr.enable = true;
|
wlr.enable = true;
|
||||||
|
xdgOpenUsePortal = true;
|
||||||
# gtk portal needed to make gtk apps happy
|
# gtk portal needed to make gtk apps happy
|
||||||
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
|
extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde pkgs.xdg-desktop-portal-gtk ];
|
||||||
|
|
||||||
|
config.sway.default = [ "wlr" "kde" "kwallet" ];
|
||||||
};
|
};
|
||||||
# D-Bus
|
# D-Bus
|
||||||
services.dbus.packages = with pkgs; [ gcr ];
|
services.dbus.packages = with pkgs; [ gcr ];
|
||||||
|
|
18
modules/common/linux/sops.nix
Normal file
18
modules/common/linux/sops.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
with { inherit (lib) types mkOption mkEnableOption; };
|
||||||
|
let
|
||||||
|
cfg = config.common.linux.sops;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.common.linux.sops = {
|
||||||
|
enable = mkEnableOption "Enable sops configuration";
|
||||||
|
file = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Path to the default sops file";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
sops.defaultSopsFile = cfg.file;
|
||||||
|
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
|
};
|
||||||
|
}
|
|
@ -34,11 +34,6 @@ in
|
||||||
default = 655;
|
default = 655;
|
||||||
description = "The port to listen on";
|
description = "The port to listen on";
|
||||||
};
|
};
|
||||||
|
|
||||||
meshIp = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "The mesh ip to be assigned by hostname";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (builtins.seq
|
config = mkIf cfg.enable (builtins.seq
|
||||||
|
@ -51,7 +46,6 @@ in
|
||||||
myMeshIp = myHost.subnetAddr;
|
myMeshIp = myHost.subnetAddr;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
services.my-tinc.meshIp = myMeshIp;
|
|
||||||
# Scripts that set up the tinc services
|
# Scripts that set up the tinc services
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
|
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
|
||||||
|
@ -84,6 +78,11 @@ in
|
||||||
# firewall
|
# firewall
|
||||||
networking.firewall.allowedUDPPorts = [ 655 ];
|
networking.firewall.allowedUDPPorts = [ 655 ];
|
||||||
networking.firewall.allowedTCPPorts = [ 655 ];
|
networking.firewall.allowedTCPPorts = [ 655 ];
|
||||||
|
networking.firewall.interfaces."tinc.${networkName}" = {
|
||||||
|
allowedUDPPortRanges = [{ from = 0; to = 65535; }];
|
||||||
|
allowedTCPPortRanges = [{ from = 0; to = 65535; }];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
# configure tinc service
|
# configure tinc service
|
||||||
# ----------------------
|
# ----------------------
|
||||||
|
|
|
@ -23,10 +23,13 @@ in
|
||||||
hosts;
|
hosts;
|
||||||
|
|
||||||
# Add all of them to host
|
# Add all of them to host
|
||||||
networking.extraHosts = lib.strings.concatStringsSep
|
nki.services.edns = {
|
||||||
"\n"
|
enable = true;
|
||||||
(lib.attrsets.mapAttrsToList
|
cloaking-rules =
|
||||||
(name: host: "${host.subnetAddr} ${name}.tinc")
|
(lib.attrsets.mapAttrs'
|
||||||
hosts);
|
(name: host: { name = "${name}.tinc"; value = host.subnetAddr; })
|
||||||
|
hosts)
|
||||||
|
;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,14 @@
|
||||||
subnetAddr = "11.0.0.4";
|
subnetAddr = "11.0.0.4";
|
||||||
ed25519PublicKey = "6MN5LVE4juavv8qJW2dTN4t/haKCADWquAQj/ADF7iN";
|
ed25519PublicKey = "6MN5LVE4juavv8qJW2dTN4t/haKCADWquAQj/ADF7iN";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
yoga = {
|
||||||
|
subnetAddr = "11.0.0.5";
|
||||||
|
ed25519PublicKey = "n+gIZjuuTPxi0OBqw2oOcmXd3loOHG+GQHBMXNlgyqI";
|
||||||
|
};
|
||||||
|
|
||||||
|
framework = {
|
||||||
|
subnetAddr = "11.0.0.6";
|
||||||
|
ed25519PublicKey = "YL7NA6Ydv/3FBfSzOPvyHlGweAViPvsG3b0Zh8L0NzF";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,29 @@
|
||||||
{ pkgs, lib, config, ... }:
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
|
||||||
noto-fonts-emoji-blob-bin =
|
|
||||||
let
|
|
||||||
pname = "noto-fonts-emoji-blob-bin";
|
|
||||||
version = "15.0";
|
|
||||||
in
|
|
||||||
pkgs.fetchurl {
|
|
||||||
name = "${pname}-${version}";
|
|
||||||
url = "https://github.com/C1710/blobmoji/releases/download/v${version}/Blobmoji.ttf";
|
|
||||||
sha256 = "sha256-n5yVk2w9x7UVrMe0Ho6nwu1Z9E/ktjo1UHdHKStoJWc=";
|
|
||||||
|
|
||||||
downloadToTemp = true;
|
|
||||||
recursiveHash = true;
|
|
||||||
postFetch = ''
|
|
||||||
install -Dm 444 $downloadedFile $out/share/fonts/blobmoji/Blobmoji.ttf
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
|
imports = [ ./mounting.nix ];
|
||||||
# Fonts
|
# Fonts
|
||||||
config.fonts = {
|
config.fonts = {
|
||||||
fonts = with pkgs; [
|
packages = with pkgs; mkForce [
|
||||||
noto-fonts-emoji-blob-bin
|
noto-fonts-emoji-blob-bin
|
||||||
ibm-plex
|
ibm-plex
|
||||||
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
|
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
|
||||||
noto-fonts
|
noto-fonts
|
||||||
noto-fonts-cjk
|
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk)
|
||||||
merriweather
|
merriweather
|
||||||
|
corefonts
|
||||||
|
font-awesome
|
||||||
|
hack-font # for Plasma
|
||||||
];
|
];
|
||||||
} // (if pkgs.stdenv.isLinux then {
|
} // (if pkgs.stdenv.isLinux then {
|
||||||
enableDefaultFonts = false;
|
enableDefaultPackages = false;
|
||||||
fontconfig = {
|
fontconfig = {
|
||||||
defaultFonts = {
|
defaultFonts = {
|
||||||
emoji = lib.mkBefore [ "Blobmoji" ];
|
emoji = lib.mkBefore [ "Blobmoji" ];
|
||||||
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" ];
|
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
|
||||||
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" ];
|
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
|
||||||
monospace = lib.mkBefore [ "IBM Plex Mono" ];
|
monospace = lib.mkBefore [ "IBM Plex Mono" "Font Awesome 6 Free" "Symbols Nerd Font" "Blobmoji" "IBM Plex Sans JP" ];
|
||||||
};
|
};
|
||||||
localConf = ''
|
localConf = ''
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
|
@ -49,6 +35,7 @@ in
|
||||||
<family>IBM Plex Sans</family>
|
<family>IBM Plex Sans</family>
|
||||||
<family>IBM Plex Sans JP</family>
|
<family>IBM Plex Sans JP</family>
|
||||||
<family>IBM Plex Sans KR</family>
|
<family>IBM Plex Sans KR</family>
|
||||||
|
<family>Blobmoji</family>
|
||||||
</prefer>
|
</prefer>
|
||||||
</alias>
|
</alias>
|
||||||
</fontconfig>
|
</fontconfig>
|
||||||
|
|
29
modules/personal/fonts/mounting.nix
Normal file
29
modules/personal/fonts/mounting.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
lib.mkIf pkgs.stdenv.isLinux {
|
||||||
|
system.fsPackages = [ pkgs.bindfs ];
|
||||||
|
fileSystems =
|
||||||
|
let
|
||||||
|
mkRoSymBind = path: {
|
||||||
|
device = path;
|
||||||
|
fsType = "fuse.bindfs";
|
||||||
|
options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ];
|
||||||
|
};
|
||||||
|
aggregatedIcons = pkgs.buildEnv {
|
||||||
|
name = "system-icons";
|
||||||
|
paths = with pkgs; [
|
||||||
|
#libsForQt5.breeze-qt5 # for plasma
|
||||||
|
(pkgs.gnome-themes-extra or gnome.gnome-themes-extra) # Until 24.11
|
||||||
|
];
|
||||||
|
pathsToLink = [ "/share/icons" ];
|
||||||
|
};
|
||||||
|
aggregatedFonts = pkgs.buildEnv {
|
||||||
|
name = "system-fonts";
|
||||||
|
paths = config.fonts.packages;
|
||||||
|
pathsToLink = [ "/share/fonts" ];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"/usr/share/icons" = mkRoSymBind "${aggregatedIcons}/share/icons";
|
||||||
|
"/usr/local/share/fonts" = mkRoSymBind "${aggregatedFonts}/share/fonts";
|
||||||
|
};
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ in
|
||||||
security.pam = mkIf pkgs.stdenv.isLinux {
|
security.pam = mkIf pkgs.stdenv.isLinux {
|
||||||
u2f = {
|
u2f = {
|
||||||
enable = true;
|
enable = true;
|
||||||
cue = true;
|
settings.cue = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Services
|
# Services
|
||||||
|
|
|
@ -8,6 +8,11 @@ in
|
||||||
options.nki.services.edns = {
|
options.nki.services.edns = {
|
||||||
enable = mkEnableOption "Enable encrypted DNS";
|
enable = mkEnableOption "Enable encrypted DNS";
|
||||||
ipv6 = mkEnableOption "Enable ipv6";
|
ipv6 = mkEnableOption "Enable ipv6";
|
||||||
|
cloaking-rules = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "A set of domain -> ip mapping for cloaking_rules";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -42,6 +47,11 @@ in
|
||||||
{ server_name = "*"; via = [ "anon-plan9-dns" "anon-v.dnscrypt.up-ipv4" ]; }
|
{ server_name = "*"; via = [ "anon-plan9-dns" "anon-v.dnscrypt.up-ipv4" ]; }
|
||||||
];
|
];
|
||||||
anonymized_dns.skip_incompatible = true;
|
anonymized_dns.skip_incompatible = true;
|
||||||
|
|
||||||
|
# Cloaking rules
|
||||||
|
cloaking_rules = pkgs.writeText "cloaking_rules.txt" (lib.strings.concatStringsSep
|
||||||
|
"\n"
|
||||||
|
(lib.attrsets.mapAttrsToList (name: ip: "${name} ${ip}") cfg.cloaking-rules));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
66
modules/services/nix-build-farm/default.nix
Normal file
66
modules/services/nix-build-farm/default.nix
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
with { inherit (lib) mkOption types mkIf; };
|
||||||
|
let
|
||||||
|
cfg = config.services.nix-build-farm;
|
||||||
|
hosts = import ./hosts.nix;
|
||||||
|
|
||||||
|
build-user = "nix-builder";
|
||||||
|
|
||||||
|
isBuilder = host: host ? "builder";
|
||||||
|
allBuilders = lib.filterAttrs (_: isBuilder) hosts;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.nix-build-farm = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to enable nix-build-farm as a client";
|
||||||
|
};
|
||||||
|
hostname = mkOption {
|
||||||
|
type = types.enum (builtins.attrNames hosts);
|
||||||
|
description = "The hostname as listed in ./hosts.nix file";
|
||||||
|
};
|
||||||
|
privateKeyFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "The path to the private SSH key file";
|
||||||
|
};
|
||||||
|
|
||||||
|
ipAddrs = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The ip addresses to limit access to";
|
||||||
|
default = "11.0.0.*";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (
|
||||||
|
let
|
||||||
|
host = hosts.${cfg.hostname};
|
||||||
|
otherHosts = lib.filterAttrs (name: _: name != cfg.hostname) hosts;
|
||||||
|
otherBuilders = lib.filterAttrs (name: _: name != cfg.hostname) allBuilders;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nix.distributedBuilds = true;
|
||||||
|
nix.buildMachines = lib.mapAttrsToList
|
||||||
|
(name: host: {
|
||||||
|
hostName = host.host;
|
||||||
|
sshUser = build-user;
|
||||||
|
sshKey = cfg.privateKeyFile;
|
||||||
|
} // host.builder)
|
||||||
|
otherBuilders;
|
||||||
|
|
||||||
|
users = mkIf (isBuilder host) {
|
||||||
|
users.${build-user} = {
|
||||||
|
description = "Nix build farm user";
|
||||||
|
group = build-user;
|
||||||
|
isNormalUser = true;
|
||||||
|
openssh.authorizedKeys.keys = lib.mapAttrsToList (_: host: ''from="${cfg.ipAddrs}" ${host.pubKey}'') otherHosts;
|
||||||
|
};
|
||||||
|
groups.${build-user} = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
nix.settings.trusted-users = mkIf (isBuilder host) [ build-user ];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
37
modules/services/nix-build-farm/hosts.nix
Normal file
37
modules/services/nix-build-farm/hosts.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
cloud = {
|
||||||
|
host = "cloud.tinc";
|
||||||
|
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE87ddj0fTH0NuvJz0dT5ln7v7zbafXqDVdM2A4ddOb0 root@nki-personal-do";
|
||||||
|
};
|
||||||
|
|
||||||
|
home = {
|
||||||
|
host = "home.tinc";
|
||||||
|
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6N1uTxnbo73tyzD9X7d7OgPeoOpY7JmQaHASjSWFPI nki@kagamiPC";
|
||||||
|
|
||||||
|
builder = {
|
||||||
|
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUhiVTh2NlNBa0kyOTBCc1QzVG1IRVVJQWdXcVFyNm9jRmpjakRRczRoT2ggcm9vdEBrYWdhbWlQQwo=";
|
||||||
|
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||||
|
maxJobs = 16;
|
||||||
|
speedFactor = 2;
|
||||||
|
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
yoga = {
|
||||||
|
host = "yoga.tinc";
|
||||||
|
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6ZrO/xIdmwBCUx80cscBSpJBBTp55OHGrXYBGRXKAw nki@nki-yoga-g8";
|
||||||
|
};
|
||||||
|
|
||||||
|
framework = {
|
||||||
|
host = "framework.tinc";
|
||||||
|
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH/g472MaT7YySUhBjxClfmMjpn98qYnKXDKlzWHYwuO nki@nki-framework";
|
||||||
|
|
||||||
|
builder = {
|
||||||
|
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUdOUlBCVFRkNTVVMXY1U1Jac0FjYVdhS3JGZTY0ZjIxOVViODVTQ2NWd28gcm9vdEBua2ktZnJhbWV3b3JrCg==";
|
||||||
|
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||||
|
maxJobs = 16;
|
||||||
|
speedFactor = 3;
|
||||||
|
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
1
modules/services/nix-cache/cache-pub-key.pem
Normal file
1
modules/services/nix-cache/cache-pub-key.pem
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nix.home.tinc:zG2uDy0MbLY0wLuoVH/qKzTD6hTfKZufA2cWDSTCZMA=
|
60
modules/services/nix-cache/default.nix
Normal file
60
modules/services/nix-cache/default.nix
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with { inherit (lib) mkEnableOption mkOption types mkIf; };
|
||||||
|
let
|
||||||
|
cfg = config.nki.services.nix-cache;
|
||||||
|
|
||||||
|
bindAddr = "127.0.0.1:5000";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.nki.services.nix-cache = {
|
||||||
|
enableClient = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = !cfg.enableServer;
|
||||||
|
description = "Enable nix-cache client";
|
||||||
|
};
|
||||||
|
enableServer = mkEnableOption "Enable nix-cache server";
|
||||||
|
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "nix.home.tinc";
|
||||||
|
};
|
||||||
|
|
||||||
|
publicKey = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = builtins.readFile ./cache-pub-key.pem;
|
||||||
|
};
|
||||||
|
|
||||||
|
privateKeyFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Path to the private key .pem file";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
nix.settings = mkIf cfg.enableClient {
|
||||||
|
substituters = lib.mkAfter [ "http://${cfg.host}" ];
|
||||||
|
trusted-public-keys = [ cfg.publicKey ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.harmonia = mkIf cfg.enableServer {
|
||||||
|
enable = true;
|
||||||
|
signKeyPath = cfg.privateKeyFile;
|
||||||
|
settings = {
|
||||||
|
bind = bindAddr;
|
||||||
|
priority = 45;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = mkIf cfg.enableServer {
|
||||||
|
enable = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
virtualHosts = {
|
||||||
|
# ... existing hosts config etc. ...
|
||||||
|
"${cfg.host}" = {
|
||||||
|
locations."/".proxyPass = "http://${bindAddr}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
{ pkgs, config, lib, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.nki.services.pam;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.nki.services.pam.enableGnomeKeyring = mkEnableOption "Enable gnome-keyring on login";
|
|
||||||
config = mkIf cfg.enableGnomeKeyring {
|
|
||||||
security.pam.services.login.enableGnomeKeyring = true;
|
|
||||||
# security.pam.services.login.gnupg.enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
132
nki-framework/configuration.nix
Normal file
132
nki-framework/configuration.nix
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
# 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’).
|
||||||
|
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
# Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
# Fonts
|
||||||
|
../modules/personal/fonts
|
||||||
|
# Encrypted DNS
|
||||||
|
../modules/services/edns
|
||||||
|
# Wireless card
|
||||||
|
./wireless.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# Sops
|
||||||
|
common.linux.sops.enable = true;
|
||||||
|
common.linux.sops.file = ./secrets.yaml;
|
||||||
|
|
||||||
|
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
|
||||||
|
services.nix-build-farm.hostname = "framework";
|
||||||
|
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
|
||||||
|
|
||||||
|
# services.xserver.enable = true;
|
||||||
|
# services.xserver.displayManager.sddm.enable = true;
|
||||||
|
# services.xserver.displayManager.sddm.wayland.enable = true;
|
||||||
|
services.desktopManager.plasma6.enable = true;
|
||||||
|
|
||||||
|
# Power Management
|
||||||
|
services.upower = {
|
||||||
|
enable = true;
|
||||||
|
criticalPowerAction = "Hibernate";
|
||||||
|
|
||||||
|
usePercentageForPolicy = true;
|
||||||
|
percentageCritical = 3;
|
||||||
|
percentageLow = 10;
|
||||||
|
};
|
||||||
|
services.power-profiles-daemon.enable = true;
|
||||||
|
# powerManagement.enable = true;
|
||||||
|
# powerManagement.powertop.enable = true;
|
||||||
|
services.logind.lidSwitch = "suspend-then-hibernate";
|
||||||
|
|
||||||
|
# Printing
|
||||||
|
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
|
||||||
|
|
||||||
|
# Enable touchpad support (enabled default in most desktopManager).
|
||||||
|
services.libinput.enable = true;
|
||||||
|
# Keyboard
|
||||||
|
services.input-remapper.enable = true;
|
||||||
|
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
|
||||||
|
hardware.uinput.enable = true;
|
||||||
|
|
||||||
|
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||||
|
common.linux.username = "nki";
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
common.linux.networking = {
|
||||||
|
hostname = "nki-framework";
|
||||||
|
networks."10-wired".match = "enp*";
|
||||||
|
networks."20-wireless".match = "wlan*";
|
||||||
|
dnsServers = [ "127.0.0.1" ];
|
||||||
|
};
|
||||||
|
nki.services.edns.enable = true;
|
||||||
|
nki.services.edns.ipv6 = true;
|
||||||
|
|
||||||
|
# Backup home
|
||||||
|
services.btrbk.extraPackages = with pkgs; [ sudo ];
|
||||||
|
services.btrbk.instances.home = {
|
||||||
|
onCalendar = "hourly";
|
||||||
|
settings = {
|
||||||
|
snapshot_preserve = "24h 30d 6m 1y";
|
||||||
|
snapshot_preserve_min = "7d";
|
||||||
|
volume."/" = {
|
||||||
|
subvolume.home.snapshot_name = ".backups-home";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable fingerprint auth for some stuff
|
||||||
|
security.pam.services.sudo.fprintAuth = true;
|
||||||
|
security.pam.services.swaylock.fprintAuth = true;
|
||||||
|
security.pam.services.login.fprintAuth = true;
|
||||||
|
|
||||||
|
# tinc network
|
||||||
|
sops.secrets."tinc-private-key" = { };
|
||||||
|
services.my-tinc = {
|
||||||
|
enable = true;
|
||||||
|
hostName = "framework";
|
||||||
|
ed25519PrivateKey = config.sops.secrets."tinc-private-key".path;
|
||||||
|
bindPort = 6565;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
# sops.defaultSopsFile = ./secrets.yaml;
|
||||||
|
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
|
|
||||||
|
## tinc
|
||||||
|
# sops.secrets."tinc/ed25519-private-key" = { };
|
||||||
|
# services.my-tinc = {
|
||||||
|
# enable = true;
|
||||||
|
# hostName = "macbooknix";
|
||||||
|
# ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
|
||||||
|
# bindPort = 6565;
|
||||||
|
# };
|
||||||
|
|
||||||
|
services.dbus.packages = with pkgs; [ gcr ];
|
||||||
|
|
||||||
|
# Open ports in the firewall.
|
||||||
|
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||||
|
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||||
|
# Or disable the firewall altogether.
|
||||||
|
# networking.firewall.enable = false;
|
||||||
|
|
||||||
|
# Copy the NixOS configuration file and link it from the resulting system
|
||||||
|
# (/run/current-system/configuration.nix). This is useful in case you
|
||||||
|
# accidentally delete configuration.nix.
|
||||||
|
# system.copySystemConfiguration = 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. It‘s 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 = "22.05"; # Did you read the comment?
|
||||||
|
}
|
||||||
|
|
74
nki-framework/hardware-configuration.nix
Normal file
74
nki-framework/hardware-configuration.nix
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages; # until mesa fixed
|
||||||
|
boot.kernelParams = [
|
||||||
|
# Hibernation
|
||||||
|
"resume=UUID=fa8aaf51-b99f-4fb4-9230-8c0957d8af3f"
|
||||||
|
"resume_offset=5776640" # btrfs inspect-internal map-swapfile -r /var/swapfile
|
||||||
|
];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=root" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
services.btrfs.autoScrub = {
|
||||||
|
enable = true;
|
||||||
|
interval = "monthly";
|
||||||
|
};
|
||||||
|
|
||||||
|
common.linux.luksDevices."cryptroot" = "/dev/disk/by-uuid/94226aae-6d1c-401a-bfad-3aa5f371a365";
|
||||||
|
|
||||||
|
fileSystems."/home" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=home" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "subvol=nix" "compress=zstd" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/6A0E-4D23";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [
|
||||||
|
{ device = "/var/swapfile"; size = 32 * 1024; priority = 10; }
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
environment.systemPackages = with pkgs; [ vulkan-validation-layers ];
|
||||||
|
|
||||||
|
# Fingerprint
|
||||||
|
services.fprintd.enable = true;
|
||||||
|
|
||||||
|
hardware.sensor.iio.enable = true; # Orientaion and ambient light sensors
|
||||||
|
}
|
32
nki-framework/secrets.yaml
Normal file
32
nki-framework/secrets.yaml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
tinc-private-key: ENC[AES256_GCM,data:cKtOFrF5FRSHWxe/QxH5O9GAba1WcWeCwW1IOzmbgdtFufRoWbCtYeaLP+WQhQ70z6xobiY9DN8Jrh7mDptKSsfKrrx2SH5JrdpsoINhLMbetXq7E29+q6CkS8NlLgE/KyV8eFjQySNsYiA/+Efq9xj9e1wOmHBDsND/jgiJDkA1qsEIFZg/vuv8LdoRY3TV/oKJ4pao9+70G4H+8Ef1sMZHGNe9qJ94Wa71nNX2fTSjKH5YBbRijMAePWr/IeCpZ9Phs7RqjBs=,iv:l0iB136X7nLVblQjFi7K4f42JKSxdsiLIRy5GPzK1nc=,tag:HAgkvWkl0Rx62ejGZckdKA==,type:str]
|
||||||
|
nix-build-farm:
|
||||||
|
private-key: ENC[AES256_GCM,data:w56sobHrhvVcKbuK15Yj20EqgFrR/5pNy/rcQjlZCiFEfgPC6ZrbsxziIdMTOX+Q4DyllKCKo+g/MIKm5S+s+nIff509ODlILhTtXlZvZlnT9+wvm5oN3WQCdkkqOr1gNnErPupfMxA6V35tNvNBCeomYuM8Xb7TuH4I1fXa5GFeT0Tnp5A2WqWoS1MzXz34CxlKXvoL6i4w7nUngt5zaGr9oMZbSa0pHxEzIhXk6h/lE864QlJid7q/mDok9gh2R80WvArGtNNj9PrT6cNKYIFuXo7vITkSkT3vo9BLflg5sgRxy4+7rBaRla0ziihQvZLtworwo6aNDvEqPqYfiX0TMYPpEWvJpp/HGDJy+Po7b0ZZkwSza+tB0J79vFH2h11Px1XSwXdq757Bn9G4OTb5oKWS5ycBU4xTnnHQBjYTSooFxYyTAvfKNEsB8AHKSuQRZgtVhWoOSPpJ6YL94ClUIT+DTaNmQjwouqNatf/nif+N/FCar8JWZDE+FX1TBu0yLmJie/f0LCdCQx+6IVdyXg7oVCoNiGg0,iv:TeSxlVc0WlOMMUtv/uq3f7JvW/kNCM7LjguhZxL51a4=,tag:m1iuk4pAX/yugM0ObzkJHQ==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmL2Z1RzBWaTI1TDl6WDNa
|
||||||
|
NTNVdEhTSFU5enNlTGVNWTI5anBZb1BtaVhjCm1BRnJDSXl1cWdBRUs1VnREVjBU
|
||||||
|
QWZxdkgzdm9JL0k5WmhDL1RCNTltdm8KLS0tIFhvQTlKMDZiVklTRWd4TzVmc2ll
|
||||||
|
bmpjcWdBV1doZml2NjlzQzdQczJ3alEKBMRP3POxtPIqBWnrvxY/++5jtVE70Uxa
|
||||||
|
EVfhsUO76A/hzyxfzpLEy1QGFE+DB/zlU0CK7HkNGPD2TrBHbzkPJA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2MUxQU0dZOGRaekF4MWdo
|
||||||
|
T0krcERtRTJndFR1RHZmL0t6MjBxMW5PSENNCkR6SUhxQ0FoaEhuaWpiUzJ0MnJE
|
||||||
|
RXRERzVhL0lRVW1iRUlac0c5OHZsckEKLS0tIC9VM1dNZTNzdkFnMWk2YUwvcDNB
|
||||||
|
TDZnVjBaVzZBem5lZDB1MW4xQ0RmZ28K6d7mF+f3ZyilXlSIQGT2pBrTWuYLccE1
|
||||||
|
rYIJjHjFft/2wPX2gAW9VTiwfMT3lKJhJRqNdoie5phV5BZhkb3D9w==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-08-17T14:58:10Z"
|
||||||
|
mac: ENC[AES256_GCM,data:ZCrzXDttLxYUvdLiqM5I17Ys6O3zoOVKq8xP78VaLb3AAoV4RGGQxixKVQ6K9h84e8bFymh512BR7xKa9fqebxTyL1XCqPkRaSZy0aWjbc6QCaK+JD4yqivgO/x5x2xgMpX/ZhPFzKNLpMga61bnm6plvF8ocG+wOqYvj3vL0Ss=,iv:QZ8YJD7h2QD2jqVKo4bg0rwpZSTyyNw6zZDcBfClKPo=,tag:PH2XnTqxV2irymg2+Z+Egg==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.9.0
|
13
nki-framework/wireless.nix
Normal file
13
nki-framework/wireless.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{ pkgs, lib, ... }: {
|
||||||
|
environment.systemPackages = with pkgs; [ iw ];
|
||||||
|
# Disable power_save on boot
|
||||||
|
services.udev.packages = [
|
||||||
|
(pkgs.writeTextFile {
|
||||||
|
name = "udev_disable_wifi_power_save";
|
||||||
|
destination = "/etc/udev/rules.d/10-wifi-power_save.rules";
|
||||||
|
text = ''
|
||||||
|
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wl*", RUN+="${lib.getExe pkgs.iw} dev $name set power_save off"
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
5
nki-home/audio/default.nix
Normal file
5
nki-home/audio/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ config, pkgs, lib, ... }: {
|
||||||
|
environment.etc = {
|
||||||
|
"wireplumber/main.lua.d/51-sdac.lua".source = ./sdac.lua;
|
||||||
|
};
|
||||||
|
}
|
16
nki-home/audio/sdac.lua
Normal file
16
nki-home/audio/sdac.lua
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
rule = {
|
||||||
|
matches = {
|
||||||
|
{
|
||||||
|
{ "node.name", "matches", "alsa_output.usb-Grace_Design_SDAC-00.*" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apply_properties = {
|
||||||
|
["audio.format"] = "S24_3LE",
|
||||||
|
["audio.rate"] = 96000,
|
||||||
|
["api.alsa.period-size"] = 2,
|
||||||
|
["api.alsa.headroom"] = 0,
|
||||||
|
["api.alsa.disable-batch"] = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
table.insert(alsa_monitor.rules, rule)
|
|
@ -10,19 +10,37 @@ with lib;
|
||||||
[
|
[
|
||||||
# Include the results of the hardware scan.
|
# Include the results of the hardware scan.
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
# secret management
|
|
||||||
./secrets
|
|
||||||
# Fonts
|
# Fonts
|
||||||
../modules/personal/fonts
|
../modules/personal/fonts
|
||||||
# Encrypted DNS
|
# Encrypted DNS
|
||||||
../modules/services/edns
|
../modules/services/edns
|
||||||
# Other services
|
# Other services
|
||||||
../modules/personal/u2f.nix
|
../modules/personal/u2f.nix
|
||||||
|
./peertube-runner.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Kernel
|
||||||
|
boot.kernelPackages = pkgs.linuxKernel.packages.linux_xanmod_stable;
|
||||||
|
|
||||||
|
# Plasma!
|
||||||
|
services.desktopManager.plasma6.enable = true;
|
||||||
|
|
||||||
## Encryption
|
## Encryption
|
||||||
# Kernel modules needed for mounting USB VFAT devices in initrd stage
|
# Kernel modules needed for mounting USB VFAT devices in initrd stage
|
||||||
common.linux.luksDevices.root = "/dev/disk/by-uuid/7c6e40a8-900b-4f85-9712-2b872caf1892";
|
common.linux.luksDevices.root = "/dev/disk/by-uuid/7c6e40a8-900b-4f85-9712-2b872caf1892";
|
||||||
|
common.linux.sops.enable = true;
|
||||||
|
common.linux.sops.file = ./secrets.yaml;
|
||||||
|
|
||||||
|
# Nix cache server
|
||||||
|
sops.secrets."nix-cache/private-key" = { owner = "harmonia"; group = "harmonia"; mode = "0600"; };
|
||||||
|
nki.services.nix-cache = {
|
||||||
|
enableServer = true;
|
||||||
|
privateKeyFile = config.sops.secrets."nix-cache/private-key".path;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
|
||||||
|
services.nix-build-farm.hostname = "home";
|
||||||
|
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
|
||||||
|
|
||||||
# Networking
|
# Networking
|
||||||
common.linux.networking =
|
common.linux.networking =
|
||||||
|
@ -53,13 +71,11 @@ with lib;
|
||||||
PrivateKeyFile = config.sops.secrets."dtth-wg/private-key".path;
|
PrivateKeyFile = config.sops.secrets."dtth-wg/private-key".path;
|
||||||
};
|
};
|
||||||
wireguardPeers = [{
|
wireguardPeers = [{
|
||||||
wireguardPeerConfig = {
|
PublicKey = "+7iI4jwmM1Qr+/DKB1Hv8JgFkGu7lSV0PAoo+O5d3yQ=";
|
||||||
PublicKey = "+7iI4jwmM1Qr+/DKB1Hv8JgFkGu7lSV0PAoo+O5d3yQ=";
|
PresharedKeyFile = config.sops.secrets."dtth-wg/preshared-key".path;
|
||||||
PresharedKeyFile = config.sops.secrets."dtth-wg/preshared-key".path;
|
AllowedIPs = [ "100.64.0.0/10" "fd00::/106" ];
|
||||||
AllowedIPs = [ "100.64.0.0/10" "fd00::/106" ];
|
Endpoint = "vpn.dtth.ch:51820";
|
||||||
Endpoint = "vpn.dtth.ch:51820";
|
PersistentKeepalive = 25;
|
||||||
PersistentKeepalive = 25;
|
|
||||||
};
|
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
systemd.network.networks."dtth-wg" = {
|
systemd.network.networks."dtth-wg" = {
|
||||||
|
@ -67,8 +83,8 @@ with lib;
|
||||||
address = [ "100.73.146.80/32" "fd00::33:105b/128" ];
|
address = [ "100.73.146.80/32" "fd00::33:105b/128" ];
|
||||||
DHCP = "no";
|
DHCP = "no";
|
||||||
routes = [
|
routes = [
|
||||||
{ routeConfig = { Destination = "100.64.0.0/10"; Scope = "link"; }; }
|
{ Destination = "100.64.0.0/10"; Scope = "link"; }
|
||||||
{ routeConfig.Destination = "fd00::/106"; }
|
{ Destination = "fd00::/106"; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,6 +113,7 @@ with lib;
|
||||||
"/mnt/Data" = ntfsMount "/dev/disk/by-uuid/A90680F8BBE62FE3";
|
"/mnt/Data" = ntfsMount "/dev/disk/by-uuid/A90680F8BBE62FE3";
|
||||||
"/mnt/Stuff" = ntfsMount "/dev/disk/by-uuid/717BF2EE20BB8A62";
|
"/mnt/Stuff" = ntfsMount "/dev/disk/by-uuid/717BF2EE20BB8A62";
|
||||||
"/mnt/Shared" = ntfsMount "/dev/disk/by-uuid/76AC086BAC0827E7";
|
"/mnt/Shared" = ntfsMount "/dev/disk/by-uuid/76AC086BAC0827E7";
|
||||||
|
"/mnt/osu" = ntfsMount "/dev/disk/by-uuid/530D3E1648CD1C26";
|
||||||
};
|
};
|
||||||
|
|
||||||
# PAM
|
# PAM
|
||||||
|
@ -129,7 +146,7 @@ with lib;
|
||||||
MusicFolder = "/mnt/Stuff/Music";
|
MusicFolder = "/mnt/Stuff/Music";
|
||||||
};
|
};
|
||||||
systemd.services.navidrome.serviceConfig.BindReadOnlyPaths = lib.mkAfter [ "/etc" ];
|
systemd.services.navidrome.serviceConfig.BindReadOnlyPaths = lib.mkAfter [ "/etc" ];
|
||||||
networking.firewall.allowedTCPPorts = [ 4533 ];
|
networking.firewall.allowedTCPPorts = [ 4533 8000 ];
|
||||||
|
|
||||||
# Printers
|
# Printers
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
imports =
|
imports =
|
||||||
[
|
[
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
./audio
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||||
|
@ -19,6 +20,12 @@
|
||||||
device = "/dev/disk/by-uuid/32a74827-4624-43ef-b066-b52e1f11793d";
|
device = "/dev/disk/by-uuid/32a74827-4624-43ef-b066-b52e1f11793d";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
fileSystems."/home/nki/Projects" =
|
||||||
|
{
|
||||||
|
device = "/dev/disk/by-uuid/025cb533-e21b-47f2-b7d5-322b7b95b831";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "compress=zstd" ];
|
||||||
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" =
|
||||||
{
|
{
|
||||||
|
@ -29,10 +36,6 @@
|
||||||
swapDevices =
|
swapDevices =
|
||||||
[{ device = "/dev/disk/by-uuid/561f6441-1915-4059-a5e1-76a449b0c9bf"; }];
|
[{ device = "/dev/disk/by-uuid/561f6441-1915-4059-a5e1-76a449b0c9bf"; }];
|
||||||
|
|
||||||
# GPU options
|
|
||||||
services.xserver.videoDrivers = [ "amdgpu" ];
|
|
||||||
hardware.opengl.enable = true;
|
|
||||||
|
|
||||||
# bluetooth usb
|
# bluetooth usb
|
||||||
hardware.firmware = [ pkgs.rtl8761b-firmware ];
|
hardware.firmware = [ pkgs.rtl8761b-firmware ];
|
||||||
}
|
}
|
||||||
|
|
67
nki-home/peertube-runner.nix
Normal file
67
nki-home/peertube-runner.nix
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
user = "peertube-runner-nodejs";
|
||||||
|
instance = "systemd-instance";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets."peertube/dtth-key" = {
|
||||||
|
restartUnits = [ "peertube-runner.service" ];
|
||||||
|
};
|
||||||
|
users.groups.${user} = { };
|
||||||
|
users.users.${user} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = user;
|
||||||
|
};
|
||||||
|
sops.templates."peertube-config.toml".owner = user;
|
||||||
|
sops.templates."peertube-config.toml".content = ''
|
||||||
|
[jobs]
|
||||||
|
concurrency = 2
|
||||||
|
|
||||||
|
[ffmpeg]
|
||||||
|
threads = 12
|
||||||
|
nice = 20
|
||||||
|
|
||||||
|
[[registeredInstances]]
|
||||||
|
url = "https://peertube.dtth.ch"
|
||||||
|
runnerToken = "${config.sops.placeholder."peertube/dtth-key"}"
|
||||||
|
runnerName = "kagamipc"
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.etc."${user}/${instance}/config.toml".source = config.sops.templates."peertube-config.toml".path;
|
||||||
|
|
||||||
|
|
||||||
|
systemd.services.peertube-runner = {
|
||||||
|
description = "PeerTube runner daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
requires = [ ];
|
||||||
|
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
ExecStart = "${lib.getExe' pkgs.peertube.runner "peertube-runner"} server --id ${instance}";
|
||||||
|
User = user;
|
||||||
|
RuntimeDirectory = user;
|
||||||
|
StateDirectory = user;
|
||||||
|
CacheDirectory = user;
|
||||||
|
# Hardening
|
||||||
|
ProtectSystem = "full";
|
||||||
|
PrivateDevices = false;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
NODE_ENV = "production";
|
||||||
|
# Override XDG values to fit env-path
|
||||||
|
# https://github.com/sindresorhus/env-paths/blob/main/index.js
|
||||||
|
XDG_DATA_HOME = "/run";
|
||||||
|
XDG_CONFIG_HOME = "/etc";
|
||||||
|
XDG_CACHE_HOME = "/var/cache";
|
||||||
|
XDG_STATE_HOME = "/var/lib";
|
||||||
|
};
|
||||||
|
|
||||||
|
path = with pkgs; [ nodejs ffmpeg ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,12 @@ scrobble:
|
||||||
dtth-wg:
|
dtth-wg:
|
||||||
private-key: ENC[AES256_GCM,data:ySxPGzOplKwNLxRnPNw7If7xzxMwRkwTasT7FaQE9n5YB04R+gaQVjDqPqg=,iv:f5t94bUoo9sCGGwWytiuhg5jcKjzRjbR3Q0OIM28VDU=,tag:fJos9Hb9XytQbfGaPMa1/A==,type:str]
|
private-key: ENC[AES256_GCM,data:ySxPGzOplKwNLxRnPNw7If7xzxMwRkwTasT7FaQE9n5YB04R+gaQVjDqPqg=,iv:f5t94bUoo9sCGGwWytiuhg5jcKjzRjbR3Q0OIM28VDU=,tag:fJos9Hb9XytQbfGaPMa1/A==,type:str]
|
||||||
preshared-key: ENC[AES256_GCM,data:96q0ZfvPz4pb53XvTGameVkcETamYH8Xbv69672RBdacH6QjRCCVvPnBTfA=,iv:Q2Yonb07/Uu6KidhMgRX4zJuNU1ZySNC7g/5TwpMU80=,tag:1qQQdk20yIQlGZmX+/25RA==,type:str]
|
preshared-key: ENC[AES256_GCM,data:96q0ZfvPz4pb53XvTGameVkcETamYH8Xbv69672RBdacH6QjRCCVvPnBTfA=,iv:Q2Yonb07/Uu6KidhMgRX4zJuNU1ZySNC7g/5TwpMU80=,tag:1qQQdk20yIQlGZmX+/25RA==,type:str]
|
||||||
|
peertube:
|
||||||
|
dtth-key: ENC[AES256_GCM,data:Gu7qOisVBZrFXKBr51165FJ7Ej4hV+lIf3AMC02R3UFNXOnTHF2xC8E=,iv:F83FuD1VjZEJFMcx3gkQuKCpJmYdHtO15fRHkYdMxJM=,tag:ScH42Tr5ZsIo9JMnXhylSw==,type:str]
|
||||||
|
nix-cache:
|
||||||
|
private-key: ENC[AES256_GCM,data:4sbfIQb10Y50CrZbgjN+1iXEbXTpDqMbIB/yA3WlaAqhLtb8HKib5aZX3DLoxFbVihJcztQsvBBgEAhT9iMijoksaT9qzBQ5yIn4NGCfFem1DK8DQdjhTLMCVTyMFCT7hQHu/2Sd7w==,iv:zTSxuKOtOLekOBKBvl9MScD/Bo1Hviqq/n8Saa+1Cgo=,tag:fx73fCDPY9d07V3KKMw3DA==,type:str]
|
||||||
|
nix-build-farm:
|
||||||
|
private-key: ENC[AES256_GCM,data:m5neeWCEdaZ1MRhNwTptfDIgv3ABNlYyNil3oTD81Jbe/6WxWaS5Q++CRlHCjc2hOoHsWsZixw8iGZVTA+QXgH6B9C6A4oOAhgR9m92EGTEfFw0qxQbdzs7U98Yonx/N8SApUycZZB/EU81+MrDNY4GGzCiO6s00/vZLkDTYnqRFgbo+8KTG0BQTl4q+VYP2q3l0wy+Ivz5CWPmbz42Xdin/sBnjeFHKDuof4iZZnN3i8gUJ/mMw3lbdiHd6A8DL0G5Ut46ljzMC2aMsZOATCID3mPOPgI0xIetDofPJLDqVsNqptRHo8WB+KwDidvl222f5F7JqdSqgAMOJYPscrX0odufApiJfg5bbXBygvrDfAlPSruW7GsWGoKAhw0qC4NC/j+qYCwhS0qdorCLnIy3zzMtA6HkHtE675hy7/7oLj7k9Y8MhE4PxztjXTmDazaVCtKhnA/DpaxP2mH84gfCkJFD1YF9jtPm+P3e+46FwkW+WnHaA2L+H7Evava30DLEBhh5y9Gd1A3JN4isn,iv:7KUWg7+GWgmGJkbIvsy9gtccZBb+1Y5uDWhXQFk0obk=,tag:qJdM684XPHxecLVxVb5pgw==,type:str]
|
||||||
sops:
|
sops:
|
||||||
kms: []
|
kms: []
|
||||||
gcp_kms: []
|
gcp_kms: []
|
||||||
|
@ -44,8 +50,8 @@ sops:
|
||||||
bUhIT0Z2b1dVWGNyS1hRVFRyZTA4d00KchP7EhSOMwBl5vFuuskzosRoi8jUu1sw
|
bUhIT0Z2b1dVWGNyS1hRVFRyZTA4d00KchP7EhSOMwBl5vFuuskzosRoi8jUu1sw
|
||||||
hVjJNF2a40ewgkQgVAoWEzirHbknbQORzmepDDRth7Bve3UQU64+GA==
|
hVjJNF2a40ewgkQgVAoWEzirHbknbQORzmepDDRth7Bve3UQU64+GA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2023-04-29T13:03:22Z"
|
lastmodified: "2024-08-16T13:59:20Z"
|
||||||
mac: ENC[AES256_GCM,data:ZNDRS6LLy89TZoW27c57RMnjs6M/GBH0XfKKlrhys8gL7+I0V/++ry59VDbLxvqS4nPR4C5hk777+B5dqnseyYW2xRT3NKYxocCQu5kO6A8L/wB00j3bm3SSIGwLcKJPibEqi7ymU53K0bmZdjRMChkBwv3CnDNkM3Dc6rvZ2DM=,iv:Z1ZjnYW1Yk+oEzNknQDytTengjKxcud95LZTFfKMnpw=,tag:pnZ+UGQWuRCKoTll00oUKA==,type:str]
|
mac: ENC[AES256_GCM,data:ncT8fbtEb9ZcLcftXwgAKJRPPSG4TRHFMArtVgWNmIjDRcCNNT7ICa+9Dl8DAYKRJ+8pgelV9StIg2f7rvypHYlckontEP5nwSFzEApLItG3AZXewTC8VPoDYb4T8/OWKDoa5kBMvGrDr1bFP/CZz7H8No+k5TV7fVExsw0PHpg=,iv:vxbkeJtHkOAq7NcaZEIOMV3qGEqBUg/vpJYumBBfY70=,tag:T0yw2x1O5Tp0UllLpcFryg==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.7.3
|
version: 3.9.0
|
|
@ -1,6 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
sops.defaultSopsFile = ./secrets.yaml;
|
|
||||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
|
||||||
}
|
|
|
@ -10,9 +10,10 @@
|
||||||
../modules/cloud/bitwarden
|
../modules/cloud/bitwarden
|
||||||
../modules/cloud/mail
|
../modules/cloud/mail
|
||||||
../modules/cloud/conduit
|
../modules/cloud/conduit
|
||||||
../modules/cloud/writefreely
|
|
||||||
../modules/cloud/gotosocial
|
../modules/cloud/gotosocial
|
||||||
../modules/cloud/outline.nix
|
|
||||||
|
# Encrypted DNS
|
||||||
|
../modules/services/edns
|
||||||
|
|
||||||
./headscale.nix
|
./headscale.nix
|
||||||
./gitea.nix
|
./gitea.nix
|
||||||
|
@ -21,8 +22,13 @@
|
||||||
./synapse.nix
|
./synapse.nix
|
||||||
./phanpy.nix
|
./phanpy.nix
|
||||||
./invidious.nix
|
./invidious.nix
|
||||||
|
./owncast.nix
|
||||||
|
./peertube.nix
|
||||||
|
./outline.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
system.stateVersion = "21.11";
|
||||||
|
|
||||||
common.linux.enable = false; # Don't enable the "common linux" module, this is a special machine.
|
common.linux.enable = false; # Don't enable the "common linux" module, this is a special machine.
|
||||||
|
|
||||||
# Personal user
|
# Personal user
|
||||||
|
@ -48,6 +54,7 @@
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
git
|
git
|
||||||
htop-vim
|
htop-vim
|
||||||
|
kakoune
|
||||||
|
|
||||||
docker-compose
|
docker-compose
|
||||||
];
|
];
|
||||||
|
@ -56,19 +63,15 @@
|
||||||
|
|
||||||
services.do-agent.enable = true;
|
services.do-agent.enable = true;
|
||||||
|
|
||||||
system.autoUpgrade = {
|
|
||||||
enable = true;
|
|
||||||
allowReboot = true;
|
|
||||||
flake = "github:natsukagami/nix-home#nki-personal-do";
|
|
||||||
};
|
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
package = pkgs.nixUnstable;
|
|
||||||
extraOptions = ''
|
extraOptions = ''
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nki.services.edns.enable = true;
|
||||||
|
nki.services.edns.ipv6 = true;
|
||||||
|
|
||||||
# Secret management
|
# Secret management
|
||||||
sops.defaultSopsFile = ./secrets/secrets.yaml;
|
sops.defaultSopsFile = ./secrets/secrets.yaml;
|
||||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
|
@ -81,6 +84,10 @@
|
||||||
services.my-tinc.rsaPrivateKey = config.sops.secrets."tinc/rsa-private-key".path;
|
services.my-tinc.rsaPrivateKey = config.sops.secrets."tinc/rsa-private-key".path;
|
||||||
services.my-tinc.ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
|
services.my-tinc.ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
|
||||||
|
|
||||||
|
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
|
||||||
|
services.nix-build-farm.hostname = "home";
|
||||||
|
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
|
||||||
|
|
||||||
# Set up traefik
|
# Set up traefik
|
||||||
sops.secrets.cloudflare-dns-api-token = { owner = "traefik"; };
|
sops.secrets.cloudflare-dns-api-token = { owner = "traefik"; };
|
||||||
sops.secrets.traefik-dashboard-users = { owner = "traefik"; };
|
sops.secrets.traefik-dashboard-users = { owner = "traefik"; };
|
||||||
|
@ -185,75 +192,13 @@
|
||||||
protocol = "udp";
|
protocol = "udp";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# Outline
|
|
||||||
sops.secrets.minio-secret-key = { owner = "root"; mode = "0444"; };
|
|
||||||
sops.secrets.authentik-oidc-client-secret = { owner = "outline"; };
|
|
||||||
sops.secrets."outline/smtp-password" = { owner = "outline"; };
|
|
||||||
cloud.services.outline = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.unstable.outline.overrideAttrs (attrs: {
|
|
||||||
patches = if builtins.hasAttr "patches" attrs then attrs.patches else [ ] ++ [ ../modules/cloud/outline/dtth-wiki.patch ];
|
|
||||||
});
|
|
||||||
databaseUrl = "postgres://outline:outline@localhost/outline?sslmode=disable";
|
|
||||||
sequelizeArguments = "--env=production-ssl-disabled";
|
|
||||||
redisUrl = "local";
|
|
||||||
publicUrl = "https://wiki.dtth.ch";
|
|
||||||
port = 18729;
|
|
||||||
storage = {
|
|
||||||
accessKey = "minio";
|
|
||||||
secretKeyFile = config.sops.secrets.minio-secret-key.path;
|
|
||||||
region = config.services.minio.region;
|
|
||||||
uploadBucketUrl = "https://s3.dtth.ch";
|
|
||||||
uploadBucketName = "dtth-outline";
|
|
||||||
uploadMaxSize = 50 * 1024 * 1000;
|
|
||||||
};
|
|
||||||
maximumImportSize = 50 * 1024 * 1000;
|
|
||||||
|
|
||||||
oidcAuthentication = {
|
|
||||||
clientId = "3a0c10e00cdcb4a1194315577fa208a747c1a5f7";
|
|
||||||
clientSecretFile = config.sops.secrets.authentik-oidc-client-secret.path;
|
|
||||||
authUrl = "https://auth.dtth.ch/application/o/authorize/";
|
|
||||||
tokenUrl = "https://auth.dtth.ch/application/o/token/";
|
|
||||||
userinfoUrl = "https://auth.dtth.ch/application/o/userinfo/";
|
|
||||||
displayName = "DTTH Account";
|
|
||||||
};
|
|
||||||
|
|
||||||
smtp = {
|
|
||||||
fromEmail = "DTTH Wiki <dtth.wiki@nkagami.me>";
|
|
||||||
replyEmail = "";
|
|
||||||
host = "mx1.nkagami.me";
|
|
||||||
username = "dtth.wiki@nkagami.me";
|
|
||||||
passwordFile = config.sops.secrets."outline/smtp-password".path;
|
|
||||||
port = 465;
|
|
||||||
secure = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
forceHttps = false;
|
|
||||||
};
|
|
||||||
cloud.postgresql.databases = [ "outline" ];
|
|
||||||
systemd.services.outline.requires = [ "postgresql.service" ];
|
|
||||||
cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; };
|
|
||||||
|
|
||||||
# GoToSocial
|
# GoToSocial
|
||||||
sops.secrets.gts-env = { };
|
sops.secrets.gts-env = { restartUnits = [ "gotosocial.service" ]; };
|
||||||
cloud.gotosocial = {
|
cloud.gotosocial = {
|
||||||
enable = true;
|
enable = true;
|
||||||
envFile = config.sops.secrets.gts-env.path;
|
envFile = config.sops.secrets.gts-env.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Minio
|
|
||||||
sops.secrets.minio-credentials = { };
|
|
||||||
services.minio = {
|
|
||||||
enable = true;
|
|
||||||
listenAddress = ":61929";
|
|
||||||
consoleAddress = ":62929";
|
|
||||||
rootCredentialsFile = config.sops.secrets.minio-credentials.path;
|
|
||||||
dataDir = lib.mkForce [ "/mnt/data/minio" ];
|
|
||||||
};
|
|
||||||
cloud.traefik.hosts.minio = { host = "s3.dtth.ch"; port = 61929; };
|
|
||||||
system.stateVersion = "21.11";
|
|
||||||
|
|
||||||
# ntfy
|
# ntfy
|
||||||
cloud.traefik.hosts.ntfy-sh = { host = "ntfy.nkagami.me"; port = 11161; noCloudflare = true; };
|
cloud.traefik.hosts.ntfy-sh = { host = "ntfy.nkagami.me"; port = 11161; noCloudflare = true; };
|
||||||
services.ntfy-sh = {
|
services.ntfy-sh = {
|
||||||
|
|
|
@ -9,11 +9,28 @@ let
|
||||||
|
|
||||||
signingKey = "0x3681E15E5C14A241";
|
signingKey = "0x3681E15E5C14A241";
|
||||||
|
|
||||||
catppuccinThemes = builtins.fetchurl {
|
catppuccinThemes = pkgs.fetchurl {
|
||||||
url = "https://github.com/catppuccin/gitea/releases/download/v0.2.1/catppuccin-gitea.tar.gz";
|
url = "https://github.com/catppuccin/gitea/releases/download/v0.4.1/catppuccin-gitea.tar.gz";
|
||||||
sha256 = "sha256:18l67whffayrgylsf5j6g7sj95anjcjl0cy7fzqn1wrm0gg2xns0";
|
hash = "sha256-/P4fLvswitlfeaKaUykrEKvjbNpw5Q/nzGQ/GZaLyUI=";
|
||||||
};
|
};
|
||||||
themes = strings.concatStringsSep "," [
|
staticDir = pkgs.runCommandLocal "forgejo-static" { } ''
|
||||||
|
mkdir -p $out
|
||||||
|
tmp=$(mktemp -d)
|
||||||
|
cp -r ${config.services.forgejo.package.data}/* $tmp
|
||||||
|
chmod -R +w $tmp
|
||||||
|
|
||||||
|
# Copy icons
|
||||||
|
install -m 0644 ${./gitea/img}/* $tmp/public/assets/img
|
||||||
|
|
||||||
|
# Copy the themes
|
||||||
|
env PATH=${pkgs.gzip}/bin:${pkgs.gnutar}/bin:$PATH \
|
||||||
|
tar -xvf ${catppuccinThemes} -C $tmp/public/assets/css
|
||||||
|
|
||||||
|
cp -r $tmp/* $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
default-themes = "forgejo-auto, forgejo-light, forgejo-dark, gitea-auto, gitea-light, gitea-dark, forgejo-auto-deuteranopia-protanopia, forgejo-light-deuteranopia-protanopia, forgejo-dark-deuteranopia-protanopia, forgejo-auto-tritanopia, forgejo-light-tritanopia, forgejo-dark-tritanopia";
|
||||||
|
themes = strings.concatStringsSep ", " [
|
||||||
"catppuccin-macchiato-green"
|
"catppuccin-macchiato-green"
|
||||||
"catppuccin-mocha-teal"
|
"catppuccin-mocha-teal"
|
||||||
"catppuccin-macchiato-sky"
|
"catppuccin-macchiato-sky"
|
||||||
|
@ -73,7 +90,15 @@ let
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
users.users.${user} = {
|
||||||
|
home = config.services.forgejo.stateDir;
|
||||||
|
useDefaultShell = true;
|
||||||
|
isSystemUser = true;
|
||||||
|
group = user;
|
||||||
|
};
|
||||||
|
users.groups.${user} = { };
|
||||||
sops.secrets."gitea/signing-key".owner = user;
|
sops.secrets."gitea/signing-key".owner = user;
|
||||||
|
sops.secrets."gitea/minio-secret-key".owner = user;
|
||||||
sops.secrets."gitea/mailer-password".owner = user;
|
sops.secrets."gitea/mailer-password".owner = user;
|
||||||
# database
|
# database
|
||||||
cloud.postgresql.databases = [ user ];
|
cloud.postgresql.databases = [ user ];
|
||||||
|
@ -83,21 +108,20 @@ in
|
||||||
noCloudflare = true;
|
noCloudflare = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.gitea.requires = [ "postgresql.service" ];
|
systemd.services.forgejo.requires = [ "postgresql.service" ];
|
||||||
|
|
||||||
services.gitea = {
|
services.forgejo = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
inherit user;
|
inherit user;
|
||||||
|
|
||||||
appName = "DTTHgit";
|
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
server = {
|
server = {
|
||||||
DOMAIN = host;
|
DOMAIN = host;
|
||||||
ROOT_URL = "https://${host}/";
|
ROOT_URL = "https://${host}/";
|
||||||
HTTP_ADDRESS = "127.0.0.1";
|
HTTP_ADDRESS = "127.0.0.1";
|
||||||
HTTP_PORT = port;
|
HTTP_PORT = port;
|
||||||
|
STATIC_ROOT_PATH = staticDir;
|
||||||
};
|
};
|
||||||
repository = {
|
repository = {
|
||||||
DEFAULT_PRIVATE = "private";
|
DEFAULT_PRIVATE = "private";
|
||||||
|
@ -111,10 +135,10 @@ in
|
||||||
};
|
};
|
||||||
"repository.signing" = {
|
"repository.signing" = {
|
||||||
SIGNING_KEY = signingKey;
|
SIGNING_KEY = signingKey;
|
||||||
SIGNING_NAME = "DTTHGit";
|
SIGNING_NAME = "DTTHgit";
|
||||||
SIGNING_EMAIL = "dtth-gitea@nkagami.me";
|
SIGNING_EMAIL = "dtth-gitea@nkagami.me";
|
||||||
};
|
};
|
||||||
ui.THEMES = "auto,gitea,arc-green," + themes;
|
ui.THEMES = default-themes + "," + themes;
|
||||||
"ui.meta" = {
|
"ui.meta" = {
|
||||||
AUTHOR = "DTTHgit - Gitea instance for GTTH";
|
AUTHOR = "DTTHgit - Gitea instance for GTTH";
|
||||||
DESCRIPTION = "DTTHGit is a custom Gitea instance hosted for DTTH members only.";
|
DESCRIPTION = "DTTHGit is a custom Gitea instance hosted for DTTH members only.";
|
||||||
|
@ -151,9 +175,23 @@ in
|
||||||
PATH = "${pkgs.git}/bin/git";
|
PATH = "${pkgs.git}/bin/git";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
storage = {
|
||||||
|
STORAGE_TYPE = "minio";
|
||||||
|
MINIO_USE_SSL = "true";
|
||||||
|
MINIO_ENDPOINT = "60c0807121eb35ef52cdcd4a33735fa6.r2.cloudflarestorage.com";
|
||||||
|
MINIO_ACCESS_KEY_ID = "704c29ade7a8b438b77ab520da2799ca";
|
||||||
|
MINIO_SECRET_ACCESS_KEY = "#miniosecretkey#";
|
||||||
|
MINIO_BUCKET = "dtth-gitea";
|
||||||
|
MINIO_LOCATION = "auto";
|
||||||
|
MINIO_CHECKSUM_ALGORITHM = "md5"; # R2 moment
|
||||||
|
};
|
||||||
|
|
||||||
federation.ENABLED = true;
|
federation.ENABLED = true;
|
||||||
|
DEFAULT.APP_NAME = "DTTHGit";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
stateDir = "/mnt/data/gitea";
|
||||||
|
|
||||||
mailerPasswordFile = secrets."gitea/mailer-password".path;
|
mailerPasswordFile = secrets."gitea/mailer-password".path;
|
||||||
|
|
||||||
database = {
|
database = {
|
||||||
|
@ -172,31 +210,30 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# Set up gpg signing key
|
# Set up gpg signing key
|
||||||
systemd.services.gitea = {
|
systemd.services.forgejo = {
|
||||||
path = with pkgs; [ gnupg ];
|
path = with pkgs; [ gnupg ];
|
||||||
environment.GNUPGHOME = "${config.services.gitea.stateDir}/.gnupg";
|
environment.GNUPGHOME = "${config.services.gitea.stateDir}/.gnupg";
|
||||||
# https://github.com/NixOS/nixpkgs/commit/93c1d370db28ad4573fb9890c90164ba55391ce7
|
# https://github.com/NixOS/nixpkgs/commit/93c1d370db28ad4573fb9890c90164ba55391ce7
|
||||||
serviceConfig.SystemCallFilter = mkForce "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
|
serviceConfig.SystemCallFilter = mkForce "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
|
||||||
preStart = ''
|
preStart =
|
||||||
# Import the signing subkey
|
let
|
||||||
if cat ${config.services.gitea.stateDir}/.gnupg/gpg.conf | grep -q ${signingKey}; then
|
configFile = "${config.services.forgejo.customDir}/conf/app.ini";
|
||||||
echo "Keys already imported"
|
in
|
||||||
# imported
|
''
|
||||||
else
|
# Update minio secret key
|
||||||
echo "Import your keys!"
|
chmod u+w ${configFile} && \
|
||||||
${pkgs.gnupg}/bin/gpg --quiet --import ${secrets."gitea/signing-key".path}
|
${lib.getExe pkgs.replace-secret} '#miniosecretkey#' '${config.sops.secrets."gitea/minio-secret-key".path}' '${configFile}' && \
|
||||||
echo "trusted-key ${signingKey}" >> ${config.services.gitea.stateDir}/.gnupg/gpg.conf
|
chmod u-w ${configFile}
|
||||||
exit 1
|
# Import the signing subkey
|
||||||
fi
|
if cat ${config.services.forgejo.stateDir}/.gnupg/gpg.conf | grep -q ${signingKey}; then
|
||||||
|
echo "Keys already imported"
|
||||||
# Copy icons
|
# imported
|
||||||
mkdir -p ${config.services.gitea.stateDir}/custom/public/img
|
else
|
||||||
install -m 0644 ${./gitea/img}/* ${config.services.gitea.stateDir}/custom/public/img
|
echo "Import your keys!"
|
||||||
|
${pkgs.gnupg}/bin/gpg --quiet --import ${secrets."gitea/signing-key".path}
|
||||||
# Copy the themes
|
echo "trusted-key ${signingKey}" >> ${config.services.forgejo.stateDir}/.gnupg/gpg.conf
|
||||||
mkdir -p ${config.services.gitea.stateDir}/custom/public/css
|
exit 1
|
||||||
env PATH=${pkgs.gzip}/bin:${pkgs.gnutar}/bin:$PATH \
|
fi
|
||||||
tar -xvf ${catppuccinThemes} -C ${config.services.gitea.stateDir}/custom/public/css/
|
'';
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
swapDevices = [{ device = "/var/swapfile"; size = 4 * 1024; priority = 1024; }];
|
swapDevices = [{ device = "/var/swapfile"; size = 4 * 1024; priority = 1024; }];
|
||||||
zramSwap.enable = true;
|
zramSwap.enable = true;
|
||||||
# volumes
|
# volumes
|
||||||
|
services.btrfs.autoScrub.enable = true;
|
||||||
fileSystems.data = {
|
fileSystems.data = {
|
||||||
device = "/dev/disk/by-id/scsi-0HC_Volume_31812942";
|
device = "/dev/disk/by-id/scsi-0HC_Volume_101470796";
|
||||||
fsType = "ext4";
|
fsType = "btrfs";
|
||||||
mountPoint = "/mnt/data";
|
mountPoint = "/mnt/data";
|
||||||
|
options = [ "compress=zstd" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ in
|
||||||
cloud.traefik.hosts.invidious = { host = "invi.dtth.ch"; port = 61191; };
|
cloud.traefik.hosts.invidious = { host = "invi.dtth.ch"; port = 61191; };
|
||||||
services.invidious = {
|
services.invidious = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.unstable.invidious;
|
|
||||||
domain = "invi.dtth.ch";
|
domain = "invi.dtth.ch";
|
||||||
port = 61191;
|
port = 61191;
|
||||||
extraSettingsFile = config.sops.secrets.invidious.path;
|
extraSettingsFile = config.sops.secrets.invidious.path;
|
||||||
|
@ -56,7 +55,7 @@ in
|
||||||
systemd.timers.smart-ipv6-rotator = {
|
systemd.timers.smart-ipv6-rotator = {
|
||||||
description = "Rotate ipv6 routes to Google";
|
description = "Rotate ipv6 routes to Google";
|
||||||
timerConfig = { OnCalendar = "*-*-* 00,06,12,18:00:00"; };
|
timerConfig = { OnCalendar = "*-*-* 00,06,12,18:00:00"; };
|
||||||
wantedBy = [ "invidious.service" ];
|
wantedBy = [ "invidious.service" "timers.target" ];
|
||||||
unitConfig = { };
|
unitConfig = { };
|
||||||
};
|
};
|
||||||
systemd.services.smart-ipv6-rotator = {
|
systemd.services.smart-ipv6-rotator = {
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
{ lib, pkgs, config, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
user = "nextcloud";
|
|
||||||
host = "cloud.dtth.ch";
|
|
||||||
port = 61155;
|
|
||||||
|
|
||||||
secrets = config.sops.secrets;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets."nextcloud/admin-password" = { owner = user; };
|
|
||||||
sops.secrets."nextcloud/minio-secret-key" = { owner = user; key = "minio-secret-key"; };
|
|
||||||
# database
|
|
||||||
cloud.postgresql.databases = [ user ];
|
|
||||||
# traefik
|
|
||||||
cloud.traefik.hosts.nextcloud = {
|
|
||||||
inherit port host;
|
|
||||||
};
|
|
||||||
systemd.services.nextcloud.requires = [ "postgresql.service" ];
|
|
||||||
services.nextcloud = {
|
|
||||||
enable = true;
|
|
||||||
hostName = host;
|
|
||||||
package = pkgs.nextcloud26;
|
|
||||||
enableBrokenCiphersForSSE = false;
|
|
||||||
|
|
||||||
home = "/mnt/data/nextcloud";
|
|
||||||
https = true;
|
|
||||||
database.createLocally = false;
|
|
||||||
|
|
||||||
extraApps = with pkgs.nextcloud26Packages.apps; {
|
|
||||||
inherit calendar contacts deck forms groupfolders news tasks;
|
|
||||||
sociallogin = pkgs.fetchNextcloudApp rec {
|
|
||||||
url = "https://github.com/zorn-v/nextcloud-social-login/releases/download/v5.4.3/release.tar.gz";
|
|
||||||
sha256 = "sha256-ZKwtF9j9WFIk3MZgng9DmN00A73S2Rb4qbehL9adaZo=";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
# Database
|
|
||||||
dbtype = "pgsql";
|
|
||||||
dbname = user;
|
|
||||||
dbuser = user;
|
|
||||||
dbhost = "/run/postgresql";
|
|
||||||
# User
|
|
||||||
adminuser = "nki";
|
|
||||||
adminpassFile = secrets."nextcloud/admin-password".path;
|
|
||||||
# General
|
|
||||||
overwriteProtocol = "https";
|
|
||||||
defaultPhoneRegion = "VN";
|
|
||||||
|
|
||||||
objectstore.s3 = {
|
|
||||||
enable = true;
|
|
||||||
bucket = "nextcloud-dtth";
|
|
||||||
autocreate = true;
|
|
||||||
key = "minio";
|
|
||||||
secretFile = config.sops.secrets."nextcloud/minio-secret-key".path;
|
|
||||||
hostname = "s3.dtth.ch";
|
|
||||||
port = 443;
|
|
||||||
useSsl = true;
|
|
||||||
usePathStyle = true;
|
|
||||||
region = "us-east-1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services.nginx.virtualHosts.${host}.listen = [{ inherit port; addr = "127.0.0.1"; }];
|
|
||||||
}
|
|
||||||
|
|
56
nki-personal-do/outline.nix
Normal file
56
nki-personal-do/outline.nix
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{ config, pkgs, ... }: {
|
||||||
|
sops.secrets.authentik-oidc-client-secret = { owner = "outline"; };
|
||||||
|
sops.secrets."outline/smtp-password" = { owner = "outline"; };
|
||||||
|
sops.secrets."outline/s3-secret-key" = { owner = "outline"; };
|
||||||
|
|
||||||
|
services.outline = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.outline.overrideAttrs (attrs: {
|
||||||
|
patches = attrs.patches or [ ] ++ [
|
||||||
|
../modules/cloud/outline/dtth-wiki.patch
|
||||||
|
../modules/cloud/outline/r2.patch
|
||||||
|
];
|
||||||
|
});
|
||||||
|
databaseUrl = "postgres://outline:outline@localhost/outline?sslmode=disable";
|
||||||
|
redisUrl = "local";
|
||||||
|
publicUrl = "https://wiki.dtth.ch";
|
||||||
|
port = 18729;
|
||||||
|
storage = {
|
||||||
|
accessKey = "6ef730e13f172d2ed6ed77f0b5b9bad9";
|
||||||
|
secretKeyFile = config.sops.secrets."outline/s3-secret-key".path;
|
||||||
|
region = "auto";
|
||||||
|
uploadBucketUrl = "https://60c0807121eb35ef52cdcd4a33735fa6.r2.cloudflarestorage.com";
|
||||||
|
uploadBucketName = "dtth-outline";
|
||||||
|
uploadMaxSize = 50 * 1024 * 1000;
|
||||||
|
};
|
||||||
|
maximumImportSize = 50 * 1024 * 1000;
|
||||||
|
|
||||||
|
oidcAuthentication = {
|
||||||
|
clientId = "3a0c10e00cdcb4a1194315577fa208a747c1a5f7";
|
||||||
|
clientSecretFile = config.sops.secrets.authentik-oidc-client-secret.path;
|
||||||
|
authUrl = "https://auth.dtth.ch/application/o/authorize/";
|
||||||
|
tokenUrl = "https://auth.dtth.ch/application/o/token/";
|
||||||
|
userinfoUrl = "https://auth.dtth.ch/application/o/userinfo/";
|
||||||
|
displayName = "DTTH Account";
|
||||||
|
};
|
||||||
|
|
||||||
|
smtp = {
|
||||||
|
fromEmail = "DTTH Wiki <dtth.wiki@nkagami.me>";
|
||||||
|
replyEmail = "";
|
||||||
|
host = "mx1.nkagami.me";
|
||||||
|
username = "dtth.wiki@nkagami.me";
|
||||||
|
passwordFile = config.sops.secrets."outline/smtp-password".path;
|
||||||
|
port = 465;
|
||||||
|
secure = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
forceHttps = false;
|
||||||
|
};
|
||||||
|
cloud.postgresql.databases = [ "outline" ];
|
||||||
|
systemd.services.outline.requires = [ "postgresql.service" ];
|
||||||
|
systemd.services.outline.environment = {
|
||||||
|
AWS_S3_R2 = "true";
|
||||||
|
AWS_S3_R2_PUBLIC_URL = "https://s3.wiki.dtth.ch";
|
||||||
|
};
|
||||||
|
cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; };
|
||||||
|
}
|
19
nki-personal-do/owncast.nix
Normal file
19
nki-personal-do/owncast.nix
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
let
|
||||||
|
host = "owncast.nkagami.me";
|
||||||
|
port = 61347;
|
||||||
|
user = "owncast";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# traefik
|
||||||
|
cloud.traefik.hosts.owncast = {
|
||||||
|
inherit port host;
|
||||||
|
};
|
||||||
|
services.owncast = {
|
||||||
|
inherit user port;
|
||||||
|
listen = "0.0.0.0"; # Listen to direct IP requests too
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
dataDir = "${config.fileSystems.data.mountPoint}/owncast";
|
||||||
|
};
|
||||||
|
}
|
80
nki-personal-do/peertube.nix
Normal file
80
nki-personal-do/peertube.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
secrets = config.sops.secrets;
|
||||||
|
cfg = config.services.peertube;
|
||||||
|
|
||||||
|
host = "peertube.dtth.ch";
|
||||||
|
port = 19878;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets."peertube" = { owner = cfg.user; restartUnits = [ "peertube.service" ]; };
|
||||||
|
sops.secrets."peertube-env" = { owner = cfg.user; restartUnits = [ "peertube.service" ]; };
|
||||||
|
# database
|
||||||
|
cloud.postgresql.databases = [ "peertube" ];
|
||||||
|
# traefik
|
||||||
|
cloud.traefik.hosts.peertube = {
|
||||||
|
inherit port host;
|
||||||
|
noCloudflare = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.peertube = {
|
||||||
|
enable = true;
|
||||||
|
enableWebHttps = true;
|
||||||
|
listenWeb = 443;
|
||||||
|
listenHttp = port;
|
||||||
|
localDomain = host;
|
||||||
|
|
||||||
|
secrets.secretsFile = secrets."peertube".path;
|
||||||
|
serviceEnvironmentFile = secrets."peertube-env".path;
|
||||||
|
|
||||||
|
# Databases
|
||||||
|
redis.createLocally = true;
|
||||||
|
database = {
|
||||||
|
host = "/run/postgresql";
|
||||||
|
};
|
||||||
|
|
||||||
|
# S3
|
||||||
|
settings.object_storage = {
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
region = "auto";
|
||||||
|
|
||||||
|
proxy.proxify_private_files = false;
|
||||||
|
|
||||||
|
web_videos = {
|
||||||
|
bucket_name = "dtthtube";
|
||||||
|
prefix = "web-videos/";
|
||||||
|
base_url = "https://content.peertube.dtth.ch";
|
||||||
|
};
|
||||||
|
streaming_playlists = {
|
||||||
|
bucket_name = "dtthtube";
|
||||||
|
prefix = "hls-playlists/";
|
||||||
|
base_url = "https://content.peertube.dtth.ch";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Storage
|
||||||
|
settings.client.videos = {
|
||||||
|
resumable_upload.max_chunk_size = "90MB";
|
||||||
|
};
|
||||||
|
settings.storage = {
|
||||||
|
storyboards = "/var/lib/peertube/storage/storyboards/";
|
||||||
|
tmp = "/mnt/data/peertube/tmp/";
|
||||||
|
tmp_persistent = "/mnt/data/peertube/tmp_persistent/";
|
||||||
|
web_videos = "/mnt/data/peertube/web-videos/";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Trust proxy
|
||||||
|
settings.trust_proxy = [ "loopback" ] ++ config.services.traefik.staticConfigOptions.entrypoints.https.forwardedHeaders.trustedIPs;
|
||||||
|
|
||||||
|
# Federation
|
||||||
|
settings.federation = {
|
||||||
|
sign_federated_fetches = true;
|
||||||
|
videos.federate_unlisted = true;
|
||||||
|
videos.cleanup_remote_interactions = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDirs = [ "/var/lib/peertube" "/mnt/data/peertube" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -29,6 +29,7 @@ in
|
||||||
enable = true;
|
enable = true;
|
||||||
withJemalloc = true;
|
withJemalloc = true;
|
||||||
dataDir = "${config.fileSystems.data.mountPoint}/matrix-synapse-dtth";
|
dataDir = "${config.fileSystems.data.mountPoint}/matrix-synapse-dtth";
|
||||||
|
extras = [ "systemd" "url-preview" "oidc" "postgres" ];
|
||||||
settings = {
|
settings = {
|
||||||
server_name = "dtth.ch";
|
server_name = "dtth.ch";
|
||||||
enable_registration = false;
|
enable_registration = false;
|
||||||
|
@ -75,6 +76,10 @@ in
|
||||||
"fec0::/10"
|
"fec0::/10"
|
||||||
];
|
];
|
||||||
app_service_config_files = app_services;
|
app_service_config_files = app_services;
|
||||||
|
|
||||||
|
auto_join_rooms = [
|
||||||
|
"#join-dtth-matrix:dtth.ch"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
extraConfigFiles = [
|
extraConfigFiles = [
|
||||||
(config.sops.secrets."matrix-synapse-dtth/oidc-config".path)
|
(config.sops.secrets."matrix-synapse-dtth/oidc-config".path)
|
||||||
|
|
|
@ -11,7 +11,7 @@ in
|
||||||
# traefik
|
# traefik
|
||||||
cloud.traefik.hosts.writefreely-dtth = { inherit host port; };
|
cloud.traefik.hosts.writefreely-dtth = { inherit host port; };
|
||||||
|
|
||||||
sops.secrets."writefreely-dtth" = { owner = user; };
|
sops.secrets."writefreely-oauth-secret" = { owner = user; };
|
||||||
|
|
||||||
users.users.${user} = {
|
users.users.${user} = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
|
@ -53,22 +53,24 @@ in
|
||||||
monetization = false;
|
monetization = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
"oauth.generic" = {
|
"oauth.generic" = { };
|
||||||
client_id = "rpoTTr2Wz0h4EgOSCHe0G85O8DCQDMup7JW9U9fV";
|
};
|
||||||
host = "https://auth.dtth.ch";
|
|
||||||
display_name = "DTTH";
|
oauth = {
|
||||||
token_endpoint = "/application/o/token/";
|
enable = true;
|
||||||
inspect_endpoint = "/application/o/userinfo/";
|
clientId = "rpoTTr2Wz0h4EgOSCHe0G85O8DCQDMup7JW9U9fV";
|
||||||
auth_endpoint = "/application/o/authorize/";
|
clientSecretFile = config.sops.secrets."writefreely-oauth-secret".path;
|
||||||
scope = "email openid profile";
|
host = "https://auth.dtth.ch";
|
||||||
map_user_id = "nickname";
|
displayName = "DTTH";
|
||||||
map_username = "preferred_username";
|
tokenEndpoint = "/application/o/token/";
|
||||||
map_display_name = "name";
|
inspectEndpoint = "/application/o/userinfo/";
|
||||||
allow_registration = true;
|
authEndpoint = "/application/o/authorize/";
|
||||||
};
|
scopes = [ "email" "openid" "profile" ];
|
||||||
|
mapUserId = "nickname";
|
||||||
|
mapUsername = "preferred_username";
|
||||||
|
mapDisplayName = "name";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraSettingsFile = config.sops.secrets."writefreely-dtth".path;
|
|
||||||
|
|
||||||
database.type = "sqlite3";
|
database.type = "sqlite3";
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@ let
|
||||||
if value == true then "true" else "false"
|
if value == true then "true" else "false"
|
||||||
else
|
else
|
||||||
toString value);
|
toString value);
|
||||||
in
|
in "${key} = ${value'}";
|
||||||
"${key} = ${value'}";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg = config.nki.services.writefreely;
|
cfg = config.nki.services.writefreely;
|
||||||
|
@ -32,20 +31,19 @@ let
|
||||||
host = cfg.settings.app.host or "${hostProtocol}://${cfg.host}";
|
host = cfg.settings.app.host or "${hostProtocol}://${cfg.host}";
|
||||||
};
|
};
|
||||||
|
|
||||||
database =
|
database = if cfg.database.type == "sqlite3" then {
|
||||||
if cfg.database.type == "sqlite3" then {
|
type = "sqlite3";
|
||||||
type = "sqlite3";
|
filename = cfg.settings.database.filename or "writefreely.db";
|
||||||
filename = cfg.settings.database.filename or "writefreely.db";
|
database = cfg.database.name;
|
||||||
database = cfg.database.name;
|
} else {
|
||||||
} else {
|
type = "mysql";
|
||||||
type = "mysql";
|
username = cfg.database.user;
|
||||||
username = cfg.database.user;
|
password = "#dbpass#";
|
||||||
password = "#dbpass#";
|
database = cfg.database.name;
|
||||||
database = cfg.database.name;
|
host = cfg.database.host;
|
||||||
host = cfg.database.host;
|
port = cfg.database.port;
|
||||||
port = cfg.database.port;
|
tls = cfg.database.tls;
|
||||||
tls = cfg.database.tls;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
server = cfg.settings.server or { } // {
|
server = cfg.settings.server or { } // {
|
||||||
bind = cfg.settings.server.bind or "localhost";
|
bind = cfg.settings.server.bind or "localhost";
|
||||||
|
@ -58,6 +56,24 @@ let
|
||||||
cfg.settings.server.pages_parent_dir or cfg.package.src;
|
cfg.settings.server.pages_parent_dir or cfg.package.src;
|
||||||
keys_parent_dir = cfg.settings.server.keys_parent_dir or cfg.stateDir;
|
keys_parent_dir = cfg.settings.server.keys_parent_dir or cfg.stateDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"oauth.generic" = cfg.settings."oauth.generic" or { } // (if cfg.oauth.enable then {
|
||||||
|
client_id = cfg.oauth.clientId;
|
||||||
|
client_secret = "#oauth_client_secret#";
|
||||||
|
host = cfg.oauth.host;
|
||||||
|
display_name = cfg.oauth.displayName;
|
||||||
|
callback_proxy = cfg.oauth.callbackProxy;
|
||||||
|
callback_proxy_api = cfg.oauth.callbackProxyApi;
|
||||||
|
token_endpoint = cfg.oauth.tokenEndpoint;
|
||||||
|
inspect_endpoint = cfg.oauth.inspectEndpoint;
|
||||||
|
auth_endpoint = cfg.oauth.authEndpoint;
|
||||||
|
scope = lib.concatStringsSep " " cfg.oauth.scopes;
|
||||||
|
allow_disconnect = cfg.oauth.allowDisconnect;
|
||||||
|
map_user_id = cfg.oauth.mapUserId;
|
||||||
|
map_username = cfg.oauth.mapUsername;
|
||||||
|
map_display_name = cfg.oauth.mapDisplayName;
|
||||||
|
map_email = cfg.oauth.mapEmail;
|
||||||
|
} else { });
|
||||||
};
|
};
|
||||||
|
|
||||||
configFile = format.generate "config.ini" settings;
|
configFile = format.generate "config.ini" settings;
|
||||||
|
@ -91,10 +107,14 @@ let
|
||||||
optionalString (cfg.database.passwordFile != null)
|
optionalString (cfg.database.passwordFile != null)
|
||||||
"$(head -n1 ${cfg.database.passwordFile})"
|
"$(head -n1 ${cfg.database.passwordFile})"
|
||||||
}
|
}
|
||||||
|
oauth_client_secret=${
|
||||||
|
optionalString cfg.oauth.enable
|
||||||
|
"$(head -n1 ${cfg.oauth.clientSecretFile})"
|
||||||
|
}
|
||||||
|
|
||||||
install -m 0660 ${configFile} '${cfg.stateDir}/config.ini'
|
cp -f ${configFile} '${cfg.stateDir}/config.ini'
|
||||||
sed -e "s,#dbpass#,$db_pass,g" -i '${cfg.stateDir}/config.ini'
|
sed -e "s,#dbpass#,$db_pass,g" -i '${cfg.stateDir}/config.ini'
|
||||||
${if cfg.extraSettingsFile != null then "cat ${cfg.extraSettingsFile} >> ${cfg.stateDir}/config.ini" else ""}
|
sed -e "s,#oauth_client_secret#,$oauth_client_secret,g" -i '${cfg.stateDir}/config.ini'
|
||||||
chmod 440 '${cfg.stateDir}/config.ini'
|
chmod 440 '${cfg.stateDir}/config.ini'
|
||||||
|
|
||||||
${text}
|
${text}
|
||||||
|
@ -123,7 +143,7 @@ let
|
||||||
withConfigFile ''
|
withConfigFile ''
|
||||||
query () {
|
query () {
|
||||||
local result=$(${sqlite}/bin/sqlite3 \
|
local result=$(${sqlite}/bin/sqlite3 \
|
||||||
'${cfg.stateDir}/${settings.database.filename}'
|
'${cfg.stateDir}/${settings.database.filename}' \
|
||||||
"$1" \
|
"$1" \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -132,53 +152,46 @@ let
|
||||||
|
|
||||||
${text}
|
${text}
|
||||||
'';
|
'';
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
options.nki.services.writefreely = {
|
options.nki.services.writefreely = {
|
||||||
enable =
|
enable =
|
||||||
lib.mkEnableOption (lib.mdDoc "Writefreely, build a digital writing community");
|
lib.mkEnableOption "Writefreely, build a digital writing community";
|
||||||
|
|
||||||
package = lib.mkOption {
|
package = lib.mkOption {
|
||||||
type = lib.types.package;
|
type = lib.types.package;
|
||||||
default = pkgs.writefreely;
|
default = pkgs.writefreely;
|
||||||
defaultText = lib.literalExpression "pkgs.writefreely";
|
defaultText = lib.literalExpression "pkgs.writefreely";
|
||||||
description = lib.mdDoc "Writefreely package to use.";
|
description = "Writefreely package to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
stateDir = mkOption {
|
stateDir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "/var/lib/writefreely";
|
default = "/var/lib/writefreely";
|
||||||
description = lib.mdDoc "The state directory where keys and data are stored.";
|
description = "The state directory where keys and data are stored.";
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "writefreely";
|
default = "writefreely";
|
||||||
description = lib.mdDoc "User under which Writefreely is ran.";
|
description = "User under which Writefreely is ran.";
|
||||||
};
|
};
|
||||||
|
|
||||||
group = mkOption {
|
group = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "writefreely";
|
default = "writefreely";
|
||||||
description = lib.mdDoc "Group under which Writefreely is ran.";
|
description = "Group under which Writefreely is ran.";
|
||||||
};
|
};
|
||||||
|
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
description = lib.mdDoc "The public host name to serve.";
|
description = "The public host name to serve.";
|
||||||
example = "example.com";
|
example = "example.com";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraSettingsFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc "Additional configs to be appended to the config file";
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
default = { };
|
default = { };
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
Writefreely configuration ({file}`config.ini`). Refer to
|
Writefreely configuration ({file}`config.ini`). Refer to
|
||||||
<https://writefreely.org/docs/latest/admin/config>
|
<https://writefreely.org/docs/latest/admin/config>
|
||||||
for details.
|
for details.
|
||||||
|
@ -192,7 +205,7 @@ in
|
||||||
theme = mkOption {
|
theme = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "write";
|
default = "write";
|
||||||
description = lib.mdDoc "The theme to apply.";
|
description = "The theme to apply.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -201,7 +214,7 @@ in
|
||||||
type = types.port;
|
type = types.port;
|
||||||
default = if cfg.nginx.enable then 18080 else 80;
|
default = if cfg.nginx.enable then 18080 else 80;
|
||||||
defaultText = "80";
|
defaultText = "80";
|
||||||
description = lib.mdDoc "The port WriteFreely should listen on.";
|
description = "The port WriteFreely should listen on.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -212,74 +225,158 @@ in
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.enum [ "sqlite3" "mysql" ];
|
type = types.enum [ "sqlite3" "mysql" ];
|
||||||
default = "sqlite3";
|
default = "sqlite3";
|
||||||
description = lib.mdDoc "The database provider to use.";
|
description = "The database provider to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "writefreely";
|
default = "writefreely";
|
||||||
description = lib.mdDoc "The name of the database to store data in.";
|
description = "The name of the database to store data in.";
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = if cfg.database.type == "mysql" then "writefreely" else null;
|
default = if cfg.database.type == "mysql" then "writefreely" else null;
|
||||||
defaultText = "writefreely";
|
defaultText = "writefreely";
|
||||||
description = lib.mdDoc "The database user to connect as.";
|
description = "The database user to connect as.";
|
||||||
};
|
};
|
||||||
|
|
||||||
passwordFile = mkOption {
|
passwordFile = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
description = lib.mdDoc "The file to load the database password from.";
|
description = "The file to load the database password from.";
|
||||||
};
|
};
|
||||||
|
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "localhost";
|
default = "localhost";
|
||||||
description = lib.mdDoc "The database host to connect to.";
|
description = "The database host to connect to.";
|
||||||
};
|
};
|
||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = types.port;
|
type = types.port;
|
||||||
default = 3306;
|
default = 3306;
|
||||||
description = lib.mdDoc "The port used when connecting to the database host.";
|
description = "The port used when connecting to the database host.";
|
||||||
};
|
};
|
||||||
|
|
||||||
tls = mkOption {
|
tls = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = "Whether or not TLS should be used for the database connection.";
|
||||||
lib.mdDoc "Whether or not TLS should be used for the database connection.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
migrate = mkOption {
|
migrate = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description =
|
description = "Whether or not to automatically run migrations on startup.";
|
||||||
lib.mdDoc "Whether or not to automatically run migrations on startup.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
createLocally = mkOption {
|
createLocally = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
When {option}`services.writefreely.database.type` is set to
|
When {option}`services.writefreely.database.type` is set to
|
||||||
`"mysql"`, this option will enable the MySQL service locally.
|
`"mysql"`, this option will enable the MySQL service locally.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
oauth = {
|
||||||
|
enable = lib.mkEnableOption "Enable generic OAuth authentication";
|
||||||
|
clientId = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The client ID associated with WriteFreely in the OAuth provider application.";
|
||||||
|
};
|
||||||
|
clientSecretFile = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The file to load the OAuth client secret from.";
|
||||||
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The base url of the OAuth provider application, including the protocol.";
|
||||||
|
example = "https://example.com";
|
||||||
|
};
|
||||||
|
displayName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The human-readable name of the OAuth service that appears on the login button, will appear as `Log in with [display_name]`.";
|
||||||
|
};
|
||||||
|
|
||||||
|
callbackProxy = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "The url of an inbound proxy that sits in front of the default `/oauth/callback/generic` endpoint. Use if you want the OAuth callback to be somewhere other than that generic location. Default is blank.";
|
||||||
|
example = "https://example.com/whatever/path";
|
||||||
|
};
|
||||||
|
callbackProxyApi = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "The url of an outbound proxy to send your OAuth requests through. Default is blank.";
|
||||||
|
example = "https://my-proxy.example.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenEndpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The API endpoint of the OAuth provider implementation to obtain an access token by presenting an authorization grant or refresh token. This is a fragment of a url, appended to host as described above.";
|
||||||
|
example = "/oauth/token";
|
||||||
|
};
|
||||||
|
inspectEndpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The API endpoint of the OAuth provider that returns basic user info given their authentication information. This is a fragment of a url, appended to host as described above.";
|
||||||
|
example = "/oauth/userinfo";
|
||||||
|
};
|
||||||
|
authEndpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The API endpoint of the OAuth provider that returns an authorization grant. This is a fragment of a url, appended to host as described above.";
|
||||||
|
example = "public";
|
||||||
|
};
|
||||||
|
|
||||||
|
scopes = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "read_user" ];
|
||||||
|
description = "A scope or set of scopes required by some OAuth providers. This will usually be blank in this config file, and is set to `read_user` by default.";
|
||||||
|
};
|
||||||
|
allowDisconnect = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether or not an individual user is allowed to disconnect this OAuth provider from their account.";
|
||||||
|
};
|
||||||
|
|
||||||
|
mapUserId = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this User ID key in the provider's user info, instead of the default key (user_id).";
|
||||||
|
};
|
||||||
|
mapUsername = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this Username key in the provider's user info, instead of the default key (username)";
|
||||||
|
};
|
||||||
|
mapDisplayName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this Display Name key in the provider's user info, instead of the default key (*none*)";
|
||||||
|
};
|
||||||
|
mapEmail = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this Email key in the provider's user info, instead of the default key (email)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
admin = {
|
admin = {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
description = lib.mdDoc "The name of the first admin user.";
|
description = "The name of the first admin user.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
initialPasswordFile = mkOption {
|
initialPasswordFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
Path to a file containing the initial password for the admin user.
|
Path to a file containing the initial password for the admin user.
|
||||||
If not provided, the default password will be set to `nixos`.
|
If not provided, the default password will be set to `nixos`.
|
||||||
'';
|
'';
|
||||||
|
@ -292,14 +389,13 @@ in
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = "Whether or not to enable and configure nginx as a proxy for WriteFreely.";
|
||||||
lib.mdDoc "Whether or not to enable and configure nginx as a proxy for WriteFreely.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
forceSSL = mkOption {
|
forceSSL = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = lib.mdDoc "Whether or not to force the use of SSL.";
|
description = "Whether or not to force the use of SSL.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -307,8 +403,7 @@ in
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = "Whether or not to automatically fetch and configure SSL certs.";
|
||||||
lib.mdDoc "Whether or not to automatically fetch and configure SSL certs.";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -344,11 +439,12 @@ in
|
||||||
optionalAttrs (cfg.group == "writefreely") { writefreely = { }; };
|
optionalAttrs (cfg.group == "writefreely") { writefreely = { }; };
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
systemd.tmpfiles.settings."10-writefreely".${cfg.stateDir}.d = {
|
||||||
[ "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" ];
|
inherit (cfg) user group;
|
||||||
|
mode = "0750";
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.writefreely = {
|
systemd.services.writefreely = {
|
||||||
path = with pkgs; [ openssl ];
|
|
||||||
after = [ "network.target" ]
|
after = [ "network.target" ]
|
||||||
++ optional isSqlite "writefreely-sqlite-init.service"
|
++ optional isSqlite "writefreely-sqlite-init.service"
|
||||||
++ optional isMysql "writefreely-mysql-init.service"
|
++ optional isMysql "writefreely-mysql-init.service"
|
||||||
|
@ -393,29 +489,27 @@ in
|
||||||
cfg.admin.initialPasswordFile;
|
cfg.admin.initialPasswordFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
script =
|
script = let
|
||||||
let
|
migrateDatabase = optionalString cfg.database.migrate ''
|
||||||
migrateDatabase = optionalString cfg.database.migrate ''
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
|
|
||||||
'';
|
|
||||||
|
|
||||||
createAdmin = optionalString (cfg.admin.name != null) ''
|
|
||||||
if [[ $(query "SELECT COUNT(*) FROM users") == 0 ]]; then
|
|
||||||
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
|
|
||||||
|
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
withSqlite ''
|
|
||||||
if ! test -f '${settings.database.filename}'; then
|
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
|
|
||||||
fi
|
|
||||||
|
|
||||||
${migrateDatabase}
|
|
||||||
|
|
||||||
${createAdmin}
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
createAdmin = optionalString (cfg.admin.name != null) ''
|
||||||
|
if [[ $(query "SELECT COUNT(*) FROM users") == 0 ]]; then
|
||||||
|
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
|
||||||
|
|
||||||
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in withSqlite ''
|
||||||
|
if ! test -f '${settings.database.filename}'; then
|
||||||
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
|
||||||
|
fi
|
||||||
|
|
||||||
|
${migrateDatabase}
|
||||||
|
|
||||||
|
${createAdmin}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.writefreely-mysql-init = mkIf isMysql {
|
systemd.services.writefreely-mysql-init = mkIf isMysql {
|
||||||
|
@ -432,38 +526,36 @@ in
|
||||||
cfg.admin.initialPasswordFile;
|
cfg.admin.initialPasswordFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
script =
|
script = let
|
||||||
let
|
updateUser = optionalString isMysqlLocal ''
|
||||||
updateUser = optionalString isMysqlLocal ''
|
# WriteFreely currently *requires* a password for authentication, so we
|
||||||
# WriteFreely currently *requires* a password for authentication, so we
|
# need to update the user in MySQL accordingly. By default MySQL users
|
||||||
# need to update the user in MySQL accordingly. By default MySQL users
|
# authenticate with auth_socket or unix_socket.
|
||||||
# authenticate with auth_socket or unix_socket.
|
# See: https://github.com/writefreely/writefreely/issues/568
|
||||||
# See: https://github.com/writefreely/writefreely/issues/568
|
${config.services.mysql.package}/bin/mysql --skip-column-names --execute "ALTER USER '${cfg.database.user}'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('$db_pass'); FLUSH PRIVILEGES;"
|
||||||
${config.services.mysql.package}/bin/mysql --skip-column-names --execute "ALTER USER '${cfg.database.user}'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('$db_pass'); FLUSH PRIVILEGES;"
|
|
||||||
'';
|
|
||||||
|
|
||||||
migrateDatabase = optionalString cfg.database.migrate ''
|
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
|
|
||||||
'';
|
|
||||||
|
|
||||||
createAdmin = optionalString (cfg.admin.name != null) ''
|
|
||||||
if [[ $(query 'SELECT COUNT(*) FROM users') == 0 ]]; then
|
|
||||||
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
|
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
withMysql ''
|
|
||||||
${updateUser}
|
|
||||||
|
|
||||||
if [[ $(query "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${cfg.database.name}'") == 0 ]]; then
|
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
|
|
||||||
fi
|
|
||||||
|
|
||||||
${migrateDatabase}
|
|
||||||
|
|
||||||
${createAdmin}
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
migrateDatabase = optionalString cfg.database.migrate ''
|
||||||
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
|
||||||
|
'';
|
||||||
|
|
||||||
|
createAdmin = optionalString (cfg.admin.name != null) ''
|
||||||
|
if [[ $(query 'SELECT COUNT(*) FROM users') == 0 ]]; then
|
||||||
|
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
|
||||||
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in withMysql ''
|
||||||
|
${updateUser}
|
||||||
|
|
||||||
|
if [[ $(query "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${cfg.database.name}'") == 0 ]]; then
|
||||||
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
|
||||||
|
fi
|
||||||
|
|
||||||
|
${migrateDatabase}
|
||||||
|
|
||||||
|
${createAdmin}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
services.mysql = mkIf isMysqlLocal {
|
services.mysql = mkIf isMysqlLocal {
|
||||||
|
@ -497,4 +589,3 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
# Fonts
|
# Fonts
|
||||||
../modules/personal/fonts
|
../modules/personal/fonts
|
||||||
# Some PAM stuff
|
# Some PAM stuff
|
||||||
../modules/services/pam/gnome-keyring.nix
|
|
||||||
../modules/services/swaylock.nix
|
../modules/services/swaylock.nix
|
||||||
];
|
];
|
||||||
# Use the latest kernel
|
# Use the latest kernel
|
||||||
|
@ -116,9 +115,6 @@
|
||||||
pciutils
|
pciutils
|
||||||
];
|
];
|
||||||
|
|
||||||
# Gnome-keyring is useful
|
|
||||||
services.gnome.gnome-keyring.enable = true;
|
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
environment.variables = {
|
environment.variables = {
|
||||||
# Input method overrides
|
# Input method overrides
|
||||||
|
@ -145,7 +141,6 @@
|
||||||
# };
|
# };
|
||||||
|
|
||||||
# List services that you want to enable:
|
# List services that you want to enable:
|
||||||
nki.services.pam.enableGnomeKeyring = true;
|
|
||||||
services.input-remapper.enable = true;
|
services.input-remapper.enable = true;
|
||||||
services.swaylock.enable = true;
|
services.swaylock.enable = true;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,4 @@
|
||||||
[{ device = "/dev/disk/by-uuid/2694d189-2ff6-4719-a449-367c52ed3ad6"; }];
|
[{ device = "/dev/disk/by-uuid/2694d189-2ff6-4719-a449-367c52ed3ad6"; }];
|
||||||
|
|
||||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|
||||||
hardware.opengl.enable = true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,24 @@
|
||||||
../modules/services/edns
|
../modules/services/edns
|
||||||
];
|
];
|
||||||
|
|
||||||
services.xserver.desktopManager.plasma5.enable = true;
|
# Secrets
|
||||||
|
common.linux.sops.enable = true;
|
||||||
|
common.linux.sops.file = ./secrets.yaml;
|
||||||
|
|
||||||
|
# Build farm
|
||||||
|
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
|
||||||
|
services.nix-build-farm.hostname = "yoga";
|
||||||
|
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
|
||||||
|
|
||||||
|
## tinc
|
||||||
|
sops.secrets."tinc-private-key" = { };
|
||||||
|
services.my-tinc = {
|
||||||
|
enable = true;
|
||||||
|
hostName = "yoga";
|
||||||
|
ed25519PrivateKey = config.sops.secrets."tinc-private-key".path;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.desktopManager.plasma6.enable = true;
|
||||||
|
|
||||||
# Power Management
|
# Power Management
|
||||||
services.upower = {
|
services.upower = {
|
||||||
|
@ -85,6 +102,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Enable fingerprint auth for some stuff
|
||||||
|
security.pam.services.sudo.fprintAuth = true;
|
||||||
|
security.pam.services.swaylock.fprintAuth = true;
|
||||||
|
security.pam.services.login.fprintAuth = true;
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
# sops.defaultSopsFile = ./secrets.yaml;
|
# sops.defaultSopsFile = ./secrets.yaml;
|
||||||
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
boot.kernelParams = [
|
||||||
|
# Hibernation
|
||||||
|
"resume=UUID=b32d27bf-9df6-43c1-8b93-c0693811bf5b"
|
||||||
|
"resume_offset=9731998" # btrfs inspect-internal map-swapfile -r /var/swapfile
|
||||||
|
];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{
|
{
|
||||||
|
@ -41,6 +46,9 @@
|
||||||
"mtk_t7xx"
|
"mtk_t7xx"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Fingerprint
|
||||||
|
services.fprintd.enable = true;
|
||||||
|
|
||||||
hardware.sensor.iio.enable = true; # Orientaion and ambient light sensors
|
hardware.sensor.iio.enable = true; # Orientaion and ambient light sensors
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
|
32
nki-yoga-g8/secrets.yaml
Normal file
32
nki-yoga-g8/secrets.yaml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
tinc-private-key: ENC[AES256_GCM,data:lzmisexQPfRlIMGqbmb+uqGtOPceQ3CJGlVOeOC6nbP/IDwkufSWtxugYmUwi9IJKwO0mldijiKWuG3p9005H++8567hhPy/bU7fA4vyVC+3UVGW6l0mE+yKQXTyI7kzxkXMCK5a4Q4rUJj544vU6pt75/mytfg+Cox2woGZAHZvJ/pRuHDe2t3R6w3EYYTu6x1w5azGnFvCOVdR6XPsGJA2p3oRnEpz64L7KD2QOdtm0YsfMnorH9FbvkZgNr927VbRnBRJ1QM=,iv:4K4w6ruQxtRGjmFnWszlXZKp36TuTTnrB0sDEE/tmrM=,tag:NBP897Sw84bvZTvo/+fVfA==,type:str]
|
||||||
|
nix-build-farm:
|
||||||
|
private-key: ENC[AES256_GCM,data:etqFl2T2atN2djxqktFRtrTGqsC61A+ZUd2yS0PLm5KPO2s2/k6XqQGac9rUWP86C1YGpTJhUMzYuOPGW4yNc0YmoeHVslxBR7nX8pubXabZNdB2YMm/yAgsdeeflo4slbxJ6+00eH0iCrtWcHtWbZafHnxojborZABOvCsODdx/ahJ4J9aHqf22cAqe9iJY3L0TgE+iazKS8OO+C/PTaQiV02NZjP8GajRMXzPVoYT7wz3u0t0q0m/t8FkhMIDl9QKL+kFUDeLEGoCBzR57JXLZiW1gJsRxbkP8hVIB3s4TQnhasxqQQlCJuqBSNFl/cGdBm/ADm/yi78VHQG7rUxUrFVDL4Aoidjp6GyoojLIEpdQjtlvC7RCLNpTibV6B71EB3obpjMmmIwfoDLT4jEWhXNx3b8DnMoa0Qh4ba+HBJf+XKA93B0qOJWwJzj4qH9uqBK3xPOGTkqQMmd9M1HYrStTcI/JUX0WvEMwk8xI8MZN/TsLij4w5i6NCwSqa8Dn2lyLK0BGp5C8RT8R4k6U2ieyY6lmxsGIe,iv:703rM/FQz65upd1JWTHNsjAXh2BeoknkALShKuHUsis=,tag:yAB6KJqpm1mOFT5GzKRPBw==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age1vhjhmxura35apu5zdwg5ur5r40xay45ld9szh07dy0ph9chgsu7shfm4h9
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBseVN3ODV1YkZnNms0Y09l
|
||||||
|
dUFBK1EyOTEydWg5KzAwcjZVSG8yYlRDWlhRCklLS2ZJNlBvSlEyOGF2ZFg2UGVW
|
||||||
|
UC9LN0hxdmtGN3JlOWJaTU5hbGwvc2MKLS0tIGM1NGZxd1NoTXNacEJqMVlsbTdi
|
||||||
|
MytuNUNydmJYWFYyQk9DaHVuVk85cjAKScucMPO8pyMlSxFw09NqzqVmDYVEh5xT
|
||||||
|
4fSTAsMwIiuOyV7jvHYORxKWNMLr5t6fnj8+OFq5qUc//jNWf9pVuA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1axvjllyv2gutngwmp3pvp4xtq2gqneldaq2c4nrzmaye0uwmk9lqsealdv
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYNXp6MWZGb2dGdW1ML2xq
|
||||||
|
ZWMvSVdWalQ5Z2NzTWd3Z1AweXlXZnRwUWtRCkY1VFhPS0NtbFZKU0VCMlAvSmhG
|
||||||
|
N2NmdWxTUEpMb05Ld3p6MzhhRkdBc3cKLS0tIGQ0TmFxdk1GV205azRzZ0hUWitj
|
||||||
|
eitNc1E2SzY5bkUxNWtNczRsWWJaU2MKUIu9GT7zu0MvvnXxiQfLW9pQcxFKOwPm
|
||||||
|
VRU2k3XQkYjSDZX29DxrOzaPS/L3OYNyBYMyOW8GyMa2V12lMH6lPQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-08-16T14:17:07Z"
|
||||||
|
mac: ENC[AES256_GCM,data:qrMyVDLhtK4URqrHFBx+08PMrFyfib4iH0y7iAeVB/oFGazjm3O5MeS9fNYJeONghuelux69nh2FRfSJHG/moEBcWlL68R4xbCb4he528P+n7mQnR54BNFJdT2oOra4bqO9n/4m2UA8jmA0veoqSrZUVjnmjftqOedjnRESY1L8=,iv:jql79ItwPcJg/nnbsUywOzWz/UJy0ZpY04pvEF290c4=,tag:XKrToym2dXdippnivoK1/Q==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
174
overlay.nix
174
overlay.nix
|
@ -1,101 +1,141 @@
|
||||||
{ nixpkgs, nixpkgs-unstable, nur, ... }@inputs:
|
{ nixpkgs, nixpkgs-unstable, ... }@inputs:
|
||||||
let
|
let
|
||||||
overlay-unstable = final: prev: {
|
overlay-unstable = final: prev: {
|
||||||
|
stable = import nixpkgs { config.allowUnfree = true; system = prev.system; };
|
||||||
unstable = import nixpkgs-unstable { config.allowUnfree = true; system = prev.system; };
|
unstable = import nixpkgs-unstable { config.allowUnfree = true; system = prev.system; };
|
||||||
x86 = import nixpkgs-unstable { system = prev.system; config.allowUnsupportedSystem = true; };
|
x86 = import nixpkgs-unstable { system = prev.system; config.allowUnsupportedSystem = true; };
|
||||||
};
|
};
|
||||||
overlay-needs-unstable = final: prev: {
|
overlay-needs-unstable = final: prev: {
|
||||||
# override some packages that needs unstable that cannot be changed in the setup.
|
|
||||||
nix-direnv = prev.unstable.nix-direnv;
|
|
||||||
|
|
||||||
# Typst updates really quickly.
|
# Typst updates really quickly.
|
||||||
typst = final.unstable.typst;
|
typst = final.unstable.typst;
|
||||||
typst-lsp = final.unstable.typst-lsp;
|
typst-lsp = final.unstable.typst-lsp;
|
||||||
|
|
||||||
# Sublime-music has a bug with playlists in 0.11.x
|
# Until 0.35 is in
|
||||||
sublime-music =
|
kitty = final.unstable.kitty;
|
||||||
if builtins.compareVersions prev.sublime-music.version "0.12" < 0
|
|
||||||
then final.unstable.sublime-music
|
|
||||||
else prev.sublime-music;
|
|
||||||
|
|
||||||
# New stuff in Kanshi 1.4.0
|
|
||||||
kanshi =
|
|
||||||
if builtins.compareVersions prev.kanshi.version "1.4.0" < 0
|
|
||||||
then final.callPackage final.unstable.kanshi.override { }
|
|
||||||
else prev.kanshi;
|
|
||||||
};
|
};
|
||||||
overlay-imported = final: prev: {
|
overlay-imported = final: prev: {
|
||||||
rnix-lsp = inputs.rnix-lsp.defaultPackage."${final.system}";
|
|
||||||
sway = prev.sway.override { sway-unwrapped = final.swayfx-unwrapped; };
|
sway = prev.sway.override { sway-unwrapped = final.swayfx-unwrapped; };
|
||||||
deploy-rs = inputs.deploy-rs.packages.default;
|
deploy-rs = inputs.deploy-rs.packages.default;
|
||||||
dtth-phanpy = inputs.dtth-phanpy.packages.${final.system}.default;
|
dtth-phanpy = inputs.dtth-phanpy.packages.${final.system}.default;
|
||||||
matrix-conduit = inputs.conduit.packages.${final.system}.default;
|
matrix-conduit = inputs.conduit.packages.${final.system}.default;
|
||||||
exa = inputs.eza.packages.${final.system}.default.overrideAttrs (attrs: {
|
|
||||||
postInstall = attrs.postInstall + ''
|
|
||||||
ln -sv $out/bin/eza $out/bin/exa
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
|
|
||||||
# A list of source-style inputs.
|
# A list of source-style inputs.
|
||||||
sources = final.lib.attrsets.filterAttrs (name: f: !(builtins.hasAttr "outputs" f)) inputs;
|
sources = final.lib.attrsets.filterAttrs (name: f: !(builtins.hasAttr "outputs" f)) inputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
overlay-versioning = final: prev: {
|
overlay-versioning = final: prev: {
|
||||||
input-remapper =
|
gotosocial = prev.gotosocial.overrideAttrs (attrs: rec {
|
||||||
prev.input-remapper.overrideAttrs (oldAttrs: rec {
|
version = "0.17.1";
|
||||||
version = "2.0.0";
|
ldflags = [
|
||||||
name = "input-remapper-${version}";
|
"-s"
|
||||||
src = final.fetchFromGitHub {
|
"-w"
|
||||||
owner = "sezanzeb";
|
"-X main.Version=${version}"
|
||||||
repo = "input-remapper";
|
];
|
||||||
rev = "${version}";
|
doCheck = false;
|
||||||
sha256 = "sha256-yQRUhezzI/rz7A+s5O7NGP8DjPzzXA80gIAhhV7mc3w=";
|
|
||||||
};
|
web-assets = final.fetchurl {
|
||||||
|
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_web-assets.tar.gz";
|
||||||
|
hash = "sha256-rGntLlIbgfCtdqpD7tnvAY8qwF+BpYbQWfAGMhdOTgY=";
|
||||||
|
};
|
||||||
|
src = final.fetchFromGitHub {
|
||||||
|
owner = "superseriousbusiness";
|
||||||
|
repo = "gotosocial";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-oWWsCs9jgd244yzWhgLkuHp7kY0BQ8+Ay6KpuBVG+U8=";
|
||||||
|
};
|
||||||
|
postInstall = ''
|
||||||
|
tar xf ${web-assets}
|
||||||
|
mkdir -p $out/share/gotosocial
|
||||||
|
mv web $out/share/gotosocial/
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
input-remapper = final.unstable.input-remapper;
|
||||||
|
|
||||||
|
kakoune-unwrapped =
|
||||||
|
prev.kakoune-unwrapped.overrideAttrs (attrs: {
|
||||||
|
version = "r${builtins.substring 0 6 inputs.kakoune.rev}";
|
||||||
|
src = inputs.kakoune;
|
||||||
|
patches = [
|
||||||
|
# patches in the original package was already applied
|
||||||
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
thunderbird = final.wrapThunderbird final.thunderbirdPackages.thunderbird-115 { };
|
swayfx-unwrapped = prev.swayfx-unwrapped.overrideAttrs (attrs: {
|
||||||
|
patches = (attrs.patches or [ ]) ++ [
|
||||||
|
(final.fetchurl {
|
||||||
|
url = "https://patch-diff.githubusercontent.com/raw/WillPower3309/swayfx/pull/315.patch";
|
||||||
|
hash = "sha256-zamOLHUjlzRs8PytPTAzEsdzgVtK+HVziHgrhwPcB+E=";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
librewolf = (prev.librewolf.override {
|
||||||
|
nativeMessagingHosts = with final; [ kdePackages.plasma-browser-integration ];
|
||||||
|
});
|
||||||
|
|
||||||
|
# Add desktop file to premid
|
||||||
|
premid = final.symlinkJoin {
|
||||||
|
name = prev.premid.name;
|
||||||
|
paths = [
|
||||||
|
prev.premid
|
||||||
|
(final.makeDesktopItem {
|
||||||
|
name = prev.premid.name;
|
||||||
|
desktopName = "PreMID";
|
||||||
|
exec = "${final.lib.getExe prev.premid} --no-sandbox %U";
|
||||||
|
icon = "premid";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/334822
|
||||||
|
vulkan-validation-layers = prev.vulkan-validation-layers.overrideAttrs (attrs: {
|
||||||
|
buildInputs = attrs.buildInputs ++ [
|
||||||
|
final.spirv-tools
|
||||||
|
];
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
overlay-libs = final: prev: {
|
overlay-libs = final: prev: {
|
||||||
libs.crane = inputs.crane.lib.${prev.system};
|
libs.crane = inputs.crane.mkLib final;
|
||||||
};
|
};
|
||||||
|
|
||||||
overlay-packages = final: prev: {
|
overlay-packages = final: prev: {
|
||||||
gotosocial-bin = final.callPackage ./packages/x86_64-linux/gotosocial-bin.nix { };
|
|
||||||
kak-tree-sitter = final.callPackage ./packages/common/kak-tree-sitter.nix { rustPlatform = final.unstable.rustPlatform; };
|
kak-tree-sitter = final.callPackage ./packages/common/kak-tree-sitter.nix { rustPlatform = final.unstable.rustPlatform; };
|
||||||
|
|
||||||
|
kak-lsp =
|
||||||
|
let
|
||||||
|
src = inputs.kak-lsp;
|
||||||
|
cargoArtifacts = final.libs.crane.buildDepsOnly { inherit src; };
|
||||||
|
in
|
||||||
|
final.libs.crane.buildPackage {
|
||||||
|
inherit src cargoArtifacts;
|
||||||
|
buildInputs = (with final;
|
||||||
|
lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security SystemConfiguration CoreServices ])
|
||||||
|
) ++ (with final; [ libiconv ]);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
overlay-aarch64-linux = final: prev:
|
overlay-rust-is-dumb = final: prev: {
|
||||||
let
|
# Use stable delta compiled with old Rust version
|
||||||
optionalOverride = pkg: alt:
|
delta = final.stable.delta;
|
||||||
if prev.stdenv.isLinux && prev.stdenv.isAarch64 then alt else pkg;
|
deepfilternet = final.stable.deepfilternet;
|
||||||
in
|
harmonia = final.callPackage
|
||||||
{
|
(import
|
||||||
# See https://github.com/sharkdp/fd/issues/1085
|
(builtins.fetchurl {
|
||||||
fd = optionalOverride prev.fd (prev.fd.overrideAttrs (attrs: {
|
url = "https://raw.githubusercontent.com/Mic92/nixpkgs/63f91202f5cd071187ede5e5ffc56003cb442876/pkgs/by-name/ha/harmonia/package.nix";
|
||||||
preBuild = ''
|
sha256 = "1mz211c0bxn116ix0j5xx4wlglpbkfg7d3npw1z8hg9gc0vbj2xb";
|
||||||
export JEMALLOC_SYS_WITH_LG_PAGE=16
|
}))
|
||||||
'';
|
{ };
|
||||||
}));
|
};
|
||||||
# See https://www.reddit.com/r/AsahiLinux/comments/zqejue/kitty_not_working_with_mesaasahiedge/
|
|
||||||
kitty = optionalOverride prev.kitty (final.writeShellApplication {
|
|
||||||
name = "kitty";
|
|
||||||
runtimeInputs = [ ];
|
|
||||||
text = ''
|
|
||||||
MESA_GL_VERSION_OVERRIDE=3.3 MESA_GLSL_VERSION_OVERRIDE=330 ${prev.kitty}/bin/kitty "$@"
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
# Zotero does not have their own aarch64-linux build
|
|
||||||
zotero = optionalOverride prev.zotero (final.callPackage ./packages/aarch64-linux/zotero.nix { });
|
|
||||||
# Typora for aarch64-linux only
|
|
||||||
typora = optionalOverride
|
|
||||||
(builtins.abort "no support for non-aarch64-linux")
|
|
||||||
(final.callPackage ./packages/aarch64-linux/typora.nix { });
|
|
||||||
};
|
|
||||||
|
|
||||||
overlay-asahi = inputs.nixos-m1.overlays.default;
|
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
|
# inputs.swayfx.inputs.scenefx.overlays.override
|
||||||
|
# inputs.swayfx.overlays.override
|
||||||
|
inputs.mpd-mpris.overlays.default
|
||||||
|
inputs.rust-overlay.overlays.default
|
||||||
|
inputs.youmubot.overlays.default
|
||||||
|
|
||||||
(import ./overlays/openrazer)
|
(import ./overlays/openrazer)
|
||||||
overlay-unstable
|
overlay-unstable
|
||||||
overlay-needs-unstable
|
overlay-needs-unstable
|
||||||
|
@ -103,16 +143,10 @@ in
|
||||||
overlay-imported
|
overlay-imported
|
||||||
overlay-versioning
|
overlay-versioning
|
||||||
overlay-libs
|
overlay-libs
|
||||||
overlay-asahi
|
overlay-rust-is-dumb
|
||||||
overlay-aarch64-linux
|
|
||||||
nur.overlay
|
|
||||||
|
|
||||||
(import ./packages/common)
|
(import ./packages/common)
|
||||||
|
|
||||||
inputs.mpd-mpris.overlays.default
|
|
||||||
inputs.swayfx.overlays.default
|
|
||||||
inputs.youmubot.overlays.default
|
|
||||||
|
|
||||||
# Bug fixes
|
# Bug fixes
|
||||||
] # we assign the overlay created before to the overlays of nixpkgs.
|
] # we assign the overlay created before to the overlays of nixpkgs.
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,41 @@
|
||||||
{ lib, rustPlatform, fetchFromGitHub, symlinkJoin, clang, git, ... }:
|
{ lib, rustPlatform, fetchFromSourcehut, symlinkJoin, clang, git, writeText, ... }:
|
||||||
let
|
let
|
||||||
src = fetchFromGitHub {
|
src = fetchFromSourcehut {
|
||||||
owner = "phaazon";
|
owner = "~hadronized";
|
||||||
repo = "kak-tree-sitter";
|
repo = "kak-tree-sitter";
|
||||||
rev = "3567f648bbf6a5d556c43bde5433dff45eabd693";
|
rev = "kak-tree-sitter-v1.1.2";
|
||||||
hash = "sha256-xr7CtOfMO4nRu2MOIQX3jR0wsKGsjYiF/TGXSAsidM4=";
|
hash = "sha256-wBWfSyR8LGtug/mCD0bJ4lbdN3trIA/03AnCxZoEOSA=";
|
||||||
};
|
};
|
||||||
|
|
||||||
kak-tree-sitter = rustPlatform.buildRustPackage rec {
|
kak-tree-sitter = rustPlatform.buildRustPackage {
|
||||||
inherit src;
|
inherit src;
|
||||||
pname = "kak-tree-sitter";
|
pname = "kak-tree-sitter";
|
||||||
version = "0.4.6";
|
version = "1.1.2";
|
||||||
cargoHash = "sha256-6HJxJTr4P1/6Yy3/dtfiaCFoHA4iKvmuwg51jTYU2eo=";
|
cargoHash = "sha256-OQPUWqJAts8DbFNSsC/CmMCbuZ9TVxRTR05O7oiodKI=";
|
||||||
cargoBuildOptions = [ "--package" "kak-tree-sitter" "--package" "ktsctl" ];
|
cargoBuildOptions = [ "--package" "kak-tree-sitter" "--package" "ktsctl" ];
|
||||||
|
|
||||||
nativeBuildInputs = [ clang git ];
|
nativeBuildInputs = [ clang git ];
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
# Allow absolute-path style repos
|
||||||
|
(writeText "resources.patch" ''
|
||||||
|
diff --git a/ktsctl/src/resources.rs b/ktsctl/src/resources.rs
|
||||||
|
index f1da3ff..ac89345 100644
|
||||||
|
--- a/ktsctl/src/resources.rs
|
||||||
|
+++ b/ktsctl/src/resources.rs
|
||||||
|
@@ -48,7 +48,8 @@ impl Resources {
|
||||||
|
url
|
||||||
|
.trim_start_matches("http")
|
||||||
|
.trim_start_matches('s')
|
||||||
|
- .trim_start_matches("://"),
|
||||||
|
+ .trim_start_matches(":/")
|
||||||
|
+ .trim_start_matches("/"),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.runtime_dir.join("sources").join(url_dir)
|
||||||
|
'')
|
||||||
|
];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
kak-tree-sitter
|
kak-tree-sitter
|
||||||
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
{ stdenv, lib, autoPatchelfHook }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "gotosocial-bin";
|
|
||||||
version = "0.11.1";
|
|
||||||
|
|
||||||
src = builtins.fetchurl {
|
|
||||||
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_linux_amd64.tar.gz";
|
|
||||||
sha256 = "sha256:01ylmsvlq86nf2hsj8mcgnhpgc7g0vyqs5sx3g2j79a4835sai2f";
|
|
||||||
# sha256 = fakeSha256;
|
|
||||||
};
|
|
||||||
|
|
||||||
nativeBuildInputs = [ autoPatchelfHook ];
|
|
||||||
|
|
||||||
sourceRoot = ".";
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
install -m755 -D gotosocial $out/bin/gotosocial
|
|
||||||
mkdir $out/share
|
|
||||||
cp -r web $out/share/web
|
|
||||||
cp -r example $out/share/example
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://docs.gotosocial.org";
|
|
||||||
description = "GoToSocial network";
|
|
||||||
platforms = platforms.linux;
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in a new issue