mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-05-28 18:39:31 +02:00
Compare commits
283 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf3f364f89 | |||
| 3247e4a8e6 | |||
| 54c2240be6 | |||
| 2b8d059ecc | |||
| 52d04c1cb1 | |||
| 5ed77b764f | |||
| 7c91ffb251 | |||
| f12e5a4293 | |||
| fb9f757519 | |||
| 606b1d3412 | |||
| 4d0741c841 | |||
| efcee11839 | |||
| 310ac5c3e7 | |||
| 5a56d4808c | |||
| 9385c5dba5 | |||
| ab414236ce | |||
| b997697aed | |||
| d59061e526 | |||
| 2c8d0f629c | |||
| 2072da67a5 | |||
| 77bd038f32 | |||
| b4015c2189 | |||
| 69a64b209a | |||
| c7c771804a | |||
| f933146a42 | |||
| d20760cd61 | |||
| 5811a41aca | |||
| b7845ef85e | |||
| 996a27965f | |||
| d3ddf34267 | |||
| f141b49dc3 | |||
| 9914644189 | |||
| 7d56db3e47 | |||
| dbc5fcbd01 | |||
| b8e580ee5a | |||
| fa5b1b2752 | |||
| eb75f1fa49 | |||
| 8542fef152 | |||
| 4cf92e7199 | |||
| 4d24c74c16 | |||
| 1a7e4d52aa | |||
| fcde4b8e83 | |||
| 3c5f0751f5 | |||
| f4ee1a0685 | |||
| a6499f3cb9 | |||
| 8deb3f809b | |||
| bff316ab7e | |||
| 985beb8bd4 | |||
| 629ef6e451 | |||
| fa492e0b26 | |||
| 9f0570d367 | |||
| bbe0f29435 | |||
| b047c064d6 | |||
| 3b346c4dd9 | |||
| ed1b4775eb | |||
| 0286a84f23 | |||
| c31525e667 | |||
| b50c59d60e | |||
| 7a229f6e79 | |||
| 2cbf8df0fa | |||
| 533fcb6144 | |||
| f0217c68f5 | |||
| e2f9c59cb6 | |||
| 5a57d97d36 | |||
| 3a470f1b1f | |||
| 37fff317ef | |||
| 1ead059695 | |||
| 9a61f3c889 | |||
| f800d96673 | |||
| 64205a79fd | |||
| 2ec9eed885 | |||
| 9a71920fd4 | |||
| 0a9dee2aee | |||
| f6b34b042f | |||
| 6d1bdd2b40 | |||
| 010f3ece90 | |||
| 5f8f5c79d5 | |||
| 2390ece70b | |||
| 36f5367a5d | |||
| a73ebc7726 | |||
| c19184a6be | |||
| 1a3b02a062 | |||
| 996b1dd077 | |||
| 0c60bc495f | |||
| 96ee6f2c01 | |||
| 517949b78f | |||
| cb43947e32 | |||
| f1c79bbb70 | |||
| 5fe647c0d3 | |||
| a321d2c803 | |||
| e5fa57c660 | |||
| e5b0545dfd | |||
| ef1fb417ad | |||
| b75e9d6abe | |||
| 05028b84d4 | |||
| b6e51e1950 | |||
| 9626986524 | |||
| 279b1b69eb | |||
| 88092aba5b | |||
| 4c00a430d6 | |||
| 4d23a5eb19 | |||
| 9c07aa1113 | |||
| 34ca7615b4 | |||
| fd4f1f9086 | |||
| fe6caebe2e | |||
| 0da119a5e8 | |||
| a2af4728f3 | |||
| ae238d401d | |||
| 7cbff9ef3b | |||
| fa5aaf4f97 | |||
| 45c6d0f604 | |||
| 47225fffbc | |||
| d022fc3fa9 | |||
| f034011f96 | |||
| a5bb4a471a | |||
| 2b781b030c | |||
| 32e0131620 | |||
| 339e1ddb76 | |||
| 2db93b7b01 | |||
| 7fcafe3d04 | |||
| 28ea82df03 | |||
| 18a40b49e3 | |||
| 140b84df2b | |||
| 9b3a431942 | |||
| e7d5ad707f | |||
| fb55262f39 | |||
| 6c80d9907b | |||
| a541754381 | |||
| e88f42182f | |||
| 6dacc92ba3 | |||
| 36ac1b51da | |||
| f4c39598ec | |||
| f765fcd633 | |||
| 54c797396c | |||
| 036d5c7fba | |||
| af225f2271 | |||
| 1126e8c6a7 | |||
| 3f505194b5 | |||
| 819463aa20 | |||
| 7e674669d3 | |||
| fa6dd68818 | |||
| 6367c91f7a | |||
| 3f9d23dbad | |||
| aa95ad60b7 | |||
| f91d4a26fc | |||
| 5c92c0e0ac | |||
| 0695229e9d | |||
| d8901e3169 | |||
| 544ec79aff | |||
| c70f9de97c | |||
| 45a149f05a | |||
| f3b233330b | |||
| 9a09854c59 | |||
| b8f61f2946 | |||
| b0f259253b | |||
| 22066db41b | |||
| a2814f326c | |||
| ad861dcc59 | |||
| 3eec2a1837 | |||
| 40ff86d6d7 | |||
| e6aa017562 | |||
| 266a190b19 | |||
| 0504d0503b | |||
| 63d686ad3a | |||
| 3302f44178 | |||
| b231111d93 | |||
| dce701146c | |||
| 62ce9eb8cb | |||
| 6b183a0220 | |||
| 90cd503219 | |||
| a0e00c5453 | |||
| 27f1d54a79 | |||
| 05682dbac9 | |||
| b9b9a55ede | |||
| b75195d339 | |||
| 7f72a0612b | |||
| d1cdddc9ca | |||
| c02590c07a | |||
| 8646c1a4ff | |||
| 0b8a50b6d9 | |||
| 66276562b9 | |||
| b9a206054a | |||
| 7cc94146b8 | |||
| 0645a593e6 | |||
| ecc335b07e | |||
| ec5ef05983 | |||
| fd438f74c6 | |||
| 7e36360550 | |||
| 86bdd6539c | |||
| 9a2fa01711 | |||
| 3992de319c | |||
| be6e0a9882 | |||
| 15eb7f5a0f | |||
| 501b2397d8 | |||
| 2c08b2f1fa | |||
| d8aeb36b27 | |||
| aa3c26d907 | |||
| f0e0b18c5f | |||
| 55139cd4fe | |||
| 533758d5da | |||
| 62505e4488 | |||
| 1d8452f232 | |||
| e4eb232d8f | |||
| 360c218344 | |||
| e3b0eca505 | |||
| 8d69b2907f | |||
| d869e7d5ce | |||
| 4345509218 | |||
| a6587cfd79 | |||
| b1fac0dce5 | |||
| f47f24cf34 | |||
| 05caa0c33a | |||
| 40921d4199 | |||
| 9843ea9db5 | |||
| f51242ae08 | |||
| 4f1c138a01 | |||
| f7dd9cd6e2 | |||
| c90317a84b | |||
| 7f1d365f0b | |||
| 9d67e03f97 | |||
| d559655e26 | |||
| 03d822da3f | |||
| 02e040d294 | |||
| cba3212896 | |||
| 68e5d860d8 | |||
| a76daab3ce | |||
| 489f82f24b | |||
| 94aec4440e | |||
| 9cbffaf841 | |||
| 3f2049ab02 | |||
| 95bdf1d091 | |||
| fe73f73adb | |||
| 0148834e15 | |||
| 4ca27063e2 | |||
| f3f74cfd70 | |||
| 4d53f559b1 | |||
| cf2c1a4437 | |||
| 29afd7f670 | |||
| 16b75e90b6 | |||
| 11bbedcde7 | |||
| 1ec9c22fd0 | |||
| c4a28eb062 | |||
| 8c8a9105e4 | |||
| 04a689c5d1 | |||
| 36b44128a0 | |||
| 6fe2d2f002 | |||
| 9b96ff35d6 | |||
| 471661239f | |||
| 00b4997a74 | |||
| 1d2bdc1beb | |||
| ca5388740f | |||
| 1812510e0d | |||
| 161fd0db6a | |||
| f166761af7 | |||
| 228a7099d0 | |||
| 8c9a212e64 | |||
| 343ebacdcf | |||
| b6f46da403 | |||
| 2f58484b4c | |||
| 7da2c3dd93 | |||
| 95fc029194 | |||
| 40be9f8a55 | |||
| e42fda1d43 | |||
| 70f5b26fd2 | |||
| 3b796515d4 | |||
| e809caa9fd | |||
| 919527d6fc | |||
| 31ac4f1439 | |||
| 1581992b8d | |||
| abac10ac49 | |||
| 06d7e9f7d5 | |||
| c3ba586954 | |||
| 4eb5af38e3 | |||
| e629ece0eb | |||
| b774bb99c8 | |||
| 49e3b91e7e | |||
| 0cac1559b8 | |||
| 8ad6be56a5 | |||
| 2d08fd3cb7 | |||
| ede2763756 | |||
| 474bd8ebf4 | |||
| d66c4316aa | |||
| 7d9abf1a01 |
@@ -0,0 +1,3 @@
|
||||
# https://github.com/github-linguist/linguist/blob/master/docs/overrides.md
|
||||
|
||||
home/linux/desktop/i3/conf/polybar/** linguist-vendored
|
||||
@@ -51,6 +51,10 @@ gc:
|
||||
sudo nix store gc --debug
|
||||
sudo nix-collect-garbage --delete-old
|
||||
|
||||
gitgc:
|
||||
git reflog expire --expire-unreachable=now --all
|
||||
git gc --prune=now
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# Darwin related commands, harmonica is my macbook pro's hostname
|
||||
@@ -75,42 +79,103 @@ fe mode="default": darwin-set-proxy
|
||||
darwin-build "fern" {{mode}}; \
|
||||
darwin-switch "fern" {{mode}}
|
||||
|
||||
yabai-reload:
|
||||
launchctl kickstart -k "gui/502/org.nixos.yabai";
|
||||
launchctl kickstart -k "gui/502/org.nixos.skhd";
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# Idols, Commands related to my remote distributed building cluster
|
||||
# Homelab - NixOS servers running on bare metal
|
||||
#
|
||||
############################################################################
|
||||
|
||||
idols-ssh-key:
|
||||
ssh-add ~/.ssh/ai-idols
|
||||
virt:
|
||||
colmena apply --on '@virt-*' --verbose --show-trace
|
||||
|
||||
idols: idols-ssh-key
|
||||
colmena apply --on '@dist-build'
|
||||
shoryu:
|
||||
colmena apply --on '@shoryu' --verbose --show-trace
|
||||
|
||||
shushou:
|
||||
colmena apply --on '@shushou' --verbose --show-trace
|
||||
|
||||
youko:
|
||||
colmena apply --on '@youko' --verbose --show-trace
|
||||
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# Homelab - Virtual Machines running on Kubevirt
|
||||
#
|
||||
############################################################################
|
||||
|
||||
lab:
|
||||
colmena apply --on '@homelab-*' --verbose --show-trace
|
||||
|
||||
aqua:
|
||||
colmena apply --on '@aqua'
|
||||
colmena apply --on '@aqua' --verbose --show-trace
|
||||
# some config changes require a restart of the dae service
|
||||
ssh root@aquamarine "sudo systemctl stop dae; sleep 1; sudo systemctl start dae"
|
||||
|
||||
ruby:
|
||||
colmena apply --on '@ruby'
|
||||
colmena apply --on '@ruby' --verbose --show-trace
|
||||
|
||||
kana:
|
||||
colmena apply --on '@kana'
|
||||
colmena apply --on '@kana' --verbose --show-trace
|
||||
|
||||
idols-debug: idols-ssh-key
|
||||
colmena apply --on '@dist-build' --verbose --show-trace
|
||||
tsgw:
|
||||
colmena apply --on '@tailscale-gw' --verbose --show-trace
|
||||
|
||||
# only used once to setup the virtual machines
|
||||
idols-image:
|
||||
# take image for idols, and upload the image to proxmox nodes.
|
||||
nom build .#aquamarine
|
||||
scp result root@gtr5:/var/lib/vz/dump/vzdump-qemu-aquamarine.vma.zst
|
||||
# pve-aqua:
|
||||
# nom build .#aquamarine
|
||||
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-aquamarine.vma.zst
|
||||
#
|
||||
# pve-ruby:
|
||||
# nom build .#ruby
|
||||
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-ruby.vma.zst
|
||||
#
|
||||
# pve-kana:
|
||||
# nom build .#kana
|
||||
# rsync -avz --progress --copy-links result root@gtr5:/var/lib/vz/dump/vzdump-qemu-kana.vma.zst
|
||||
#
|
||||
# pve-tsgw:
|
||||
# nom build .#tailscale_gw
|
||||
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-tailscale_gw.vma.zst
|
||||
#
|
||||
|
||||
nom build .#ruby
|
||||
scp result root@s500plus:/var/lib/vz/dump/vzdump-qemu-ruby.vma.zst
|
||||
############################################################################
|
||||
#
|
||||
# Kubernetes related commands
|
||||
#
|
||||
############################################################################
|
||||
|
||||
nom build .#kana
|
||||
scp result root@um560:/var/lib/vz/dump/vzdump-qemu-kana.vma.zst
|
||||
k8s:
|
||||
colmena apply --on '@k8s-*' --verbose --show-trace
|
||||
|
||||
master:
|
||||
colmena apply --on '@k8s-prod-master-*' --verbose --show-trace
|
||||
|
||||
worker:
|
||||
colmena apply --on '@k8s-prod-worker-*' --verbose --show-trace
|
||||
|
||||
# pve-k8s:
|
||||
# nom build .#k3s_prod_1_master_1
|
||||
# rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-k3s_prod_1_master_1.vma.zst
|
||||
#
|
||||
# nom build .#k3s_prod_1_master_2
|
||||
# rsync -avz --progress --copy-links result root@gtr5:/var/lib/vz/dump/vzdump-qemu-k3s_prod_1_master_2.vma.zst
|
||||
#
|
||||
# nom build .#k3s_prod_1_master_3
|
||||
# rsync -avz --progress --copy-links result root@s500plus:/var/lib/vz/dump/vzdump-qemu-k3s_prod_1_master_3.vma.zst
|
||||
#
|
||||
# nom build .#k3s_prod_1_worker_1
|
||||
# rsync -avz --progress --copy-links result root@gtr5:/var/lib/vz/dump/vzdump-qemu-k3s_prod_1_worker_1.vma.zst
|
||||
#
|
||||
# nom build .#k3s_prod_1_worker_2
|
||||
# rsync -avz --progress --copy-links result root@s500plus:/var/lib/vz/dump/vzdump-qemu-k3s_prod_1_worker_2.vma.zst
|
||||
#
|
||||
# nom build .#k3s_prod_1_worker_3
|
||||
# rsync -avz --progress --copy-links result root@s500plus:/var/lib/vz/dump/vzdump-qemu-k3s_prod_1_worker_3.vma.zst
|
||||
#
|
||||
|
||||
############################################################################
|
||||
#
|
||||
@@ -118,17 +183,14 @@ idols-image:
|
||||
#
|
||||
############################################################################
|
||||
|
||||
roll: idols-ssh-key
|
||||
colmena apply --on '@riscv'
|
||||
|
||||
roll-debug: idols-ssh-key
|
||||
colmena apply --on '@dist-build' --verbose --show-trace
|
||||
riscv:
|
||||
colmena apply --on '@riscv' --verbose --show-trace
|
||||
|
||||
nozomi:
|
||||
colmena apply --on '@nozomi'
|
||||
colmena apply --on '@nozomi' --verbose --show-trace
|
||||
|
||||
yukina:
|
||||
colmena apply --on '@yukina'
|
||||
colmena apply --on '@yukina' --verbose --show-trace
|
||||
|
||||
############################################################################
|
||||
#
|
||||
@@ -137,13 +199,21 @@ yukina:
|
||||
############################################################################
|
||||
|
||||
aarch:
|
||||
colmena apply --on '@aarch'
|
||||
colmena apply --on '@aarch' --verbose --show-trace
|
||||
|
||||
suzu:
|
||||
colmena apply --on '@suzu'
|
||||
colmena apply --on '@suzu' --build-on-target --verbose --show-trace
|
||||
|
||||
suzu-debug:
|
||||
colmena apply --on '@suzu' --verbose --show-trace
|
||||
suzu-local mode="default":
|
||||
use utils.nu *; \
|
||||
nixos-switch suzu {{mode}}
|
||||
|
||||
rakushun:
|
||||
colmena apply --on '@rakushun' --build-on-target --verbose --show-trace
|
||||
|
||||
rakushun-local mode="default":
|
||||
use utils.nu *; \
|
||||
nixos-switch rakushun {{mode}}
|
||||
|
||||
############################################################################
|
||||
#
|
||||
@@ -155,6 +225,9 @@ fmt:
|
||||
# format the nix files in this repo
|
||||
nix fmt
|
||||
|
||||
path:
|
||||
$env.PATH | split row ":"
|
||||
|
||||
nvim-test:
|
||||
rm -rf $"($env.HOME)/.config/astronvim/lua/user"
|
||||
rsync -avz --copy-links --chmod=D2755,F744 home/base/desktop/editors/neovim/astronvim_user/ $"($env.HOME)/.config/astronvim/lua/user"
|
||||
@@ -197,3 +270,14 @@ emacs-purge:
|
||||
emacs-reload:
|
||||
doom sync
|
||||
{{reload-emacs-cmd}}
|
||||
|
||||
|
||||
# =================================================
|
||||
#
|
||||
# Kubernetes related commands
|
||||
#
|
||||
# =================================================
|
||||
|
||||
|
||||
del-failed:
|
||||
kubectl delete pod --all-namespaces --field-selector="status.phase==Failed"
|
||||
|
||||
@@ -8,13 +8,22 @@
|
||||
<a href="https://github.com/ryan4yin/nix-config/stargazers">
|
||||
<img alt="Stargazers" src="https://img.shields.io/github/stars/ryan4yin/nix-config?style=for-the-badge&logo=starship&color=C9CBFF&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||
<a href="https://nixos.org/">
|
||||
<img src="https://img.shields.io/badge/NixOS-23.05-informational.svg?style=for-the-badge&logo=nixos&color=F2CDCD&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||
<img src="https://img.shields.io/badge/NixOS-23.11-informational.svg?style=for-the-badge&logo=nixos&color=F2CDCD&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||
<a href="https://github.com/ryan4yin/nixos-and-flakes-book">
|
||||
<img src="https://img.shields.io/static/v1?label=Nix Flakes&message=learning&style=for-the-badge&logo=nixos&color=DDB6F2&logoColor=D9E0EE&labelColor=302D41"></a>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
This repository is home to the nix code that builds my systems.
|
||||
> My configuration is becoming more and more complex, and it may be difficult for beginners to read it.
|
||||
> If you are new to NixOS and want to know how I use NixOS, I would recommend you to take a look at the [ryan4yin/nix-config/releases](https://github.com/ryan4yin/nix-config/releases) first, **checkout to some simpler older versions**, which will be much easier to understand.
|
||||
|
||||
This repository is home to the nix code that builds my systems:
|
||||
|
||||
1. NixOS Desktops: NixOS with home-manager, i3, hyprland, agenix, etc.
|
||||
2. macOS Desktops: nix-darwin with home-manager, share the same home-manager configuration with NixOS Desktops.
|
||||
3. NixOS Servers: virtual machines running on Proxmox, with various services, such as kubernetes, homepage, prometheus, grafana, etc.
|
||||
|
||||
See [./hosts](./hosts) for details of each host.
|
||||
|
||||
## Why NixOS & Flakes?
|
||||
|
||||
@@ -47,19 +56,21 @@ As for Flakes, refer to [Introduction to Flakes - NixOS & Nix Flakes Book](https
|
||||
| **Text Editor** | [Neovim][Neovim] + [DoomEmacs][DoomEmacs] | [Neovim][Neovim] + [DoomEmacs][DoomEmacs] |
|
||||
| **Fonts** | [Nerd fonts][Nerd fonts] | [Nerd fonts][Nerd fonts] |
|
||||
| **Image Viewer** | [imv][imv] | [imv][imv] |
|
||||
| **Screenshot Software** | [grim][grim] | [flameshot](https://github.com/flameshot-org/flameshot) |
|
||||
| **Screenshot Software** | [flameshot][flameshot] + [grim][grim] | [flameshot][flameshot] |
|
||||
| **Screen Recording** | [OBS][OBS] | [OBS][OBS] |
|
||||
| **Filesystem & Encryption** | tmpfs on `/`, [Btrfs][Btrfs] subvolumes on a [LUKS][LUKS] crypted partition for persistent, unlock via passphrase | tmpfs on `/`, [Btrfs][Btrfs] subvolumes on a [LUKS][LUKS] crypted partition for persistent, unlock via passphrase |
|
||||
| **Secure Boot** | [lanzaboote][lanzaboote] | [lanzaboote][lanzaboote] |
|
||||
|
||||
Wallpapers: https://github.com/ryan4yin/wallpapers
|
||||
|
||||
## Hyprland + AstroNvim
|
||||
## Hyprland + AstroNvim + DoomEmacs
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## I3 + AstroNvim
|
||||
|
||||

|
||||
@@ -73,17 +84,16 @@ See [./home/base/desktop/editors/neovim/](./home/base/desktop/editors/neovim/) f
|
||||
|
||||
See [./home/base/desktop/editors/emacs/](./home/base/desktop/editors/emacs/) for details.
|
||||
|
||||
## Hosts
|
||||
|
||||
See [./hosts](./hosts) for details.
|
||||
|
||||
## Secrets Management
|
||||
|
||||
See [./secrets](./secrets) for details.
|
||||
|
||||
## How to Deploy this Flake?
|
||||
|
||||
> :red_circle: **IMPORTANT**: **You should NOT deploy this flake directly on your machine:exclamation: It will not succeed.** this flake contains my hardware configuration(such as [hardware-configuration.nix](hosts/idols/ai/hardware-configuration.nix), [cifs-mount.nix](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols/ai/cifs-mount.nix), [Nvidia Support](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols/ai/default.nix#L77-L91), etc.) which is not suitable for your hardware, and my private secrets repository [ryan4yin/nix-secrets](https://github.com/ryan4yin/nix-config/tree/main/secrets) that only I have access to. You may use this repo as a reference to build your own configuration.
|
||||
> :red_circle: **IMPORTANT**: **You should NOT deploy this flake directly on your machine :exclamation: It will not succeed.**
|
||||
> This flake contains my hardware configuration(such as [hardware-configuration.nix](hosts/idols_ai/hardware-configuration.nix), [cifs-mount.nix](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols_ai/cifs-mount.nix), [Nvidia Support](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols_ai/default.nix#L77-L91), etc.) which is not suitable for your hardwares,
|
||||
> and requires my private secrets repository [ryan4yin/nix-secrets](https://github.com/ryan4yin/nix-config/tree/main/secrets) to deploy.
|
||||
> You may use this repo as a reference to build your own configuration.
|
||||
|
||||
For NixOS:
|
||||
|
||||
@@ -108,7 +118,14 @@ just i3 debug
|
||||
For macOS:
|
||||
|
||||
```bash
|
||||
# deploy harmonicia's configuration(macOS Intel)
|
||||
# If you are deploying for the first time,
|
||||
# 1. install nix & homebrew manually.
|
||||
# 2. prepare the deployment environment with essential packages available
|
||||
nix-shell -p just nushell
|
||||
# 3. comment home-manager's code in lib/macosSystem.nix to speed up the first deplyment.
|
||||
# 4. comment out the proxy settings in scripts/darwin_set_proxy.py if the proxy is not ready yet.
|
||||
|
||||
# 4. deploy harmonica's configuration(macOS Intel)
|
||||
just ha
|
||||
|
||||
# deploy fern's configuration(Apple Silicon)
|
||||
@@ -131,7 +148,7 @@ nom build .#aquamarine # `nom`(nix-output-monitor) can be replaced by the stand
|
||||
|
||||
# 2. upload the genereated image to proxmox server's backup directory `/var/lib/vz/dump`
|
||||
# please replace the vma file name with the one you generated in step 1.
|
||||
scp result/vzdump-qemu-aquamarine-nixos-23.11.20230603.dd49825.vma.zst root@192.168.5.174:/var/lib/vz/dump
|
||||
rsync -avz --progress --copy-links result root@um560:/var/lib/vz/dump/vzdump-qemu-aquamarine.vma.zst
|
||||
|
||||
# 3. the image we uploaded will be listed in proxmox web ui's this page: [storage 'local'] -> [backups], we can restore a vm from it via the web ui now.
|
||||
```
|
||||
@@ -140,7 +157,7 @@ Once the virtual machine `aquamarine` is created, we can deploy updates to it wi
|
||||
|
||||
```shell
|
||||
# 1. add the ssh key to ssh-agent
|
||||
ssh-add ~/.ssh/ai-idols
|
||||
ssh-add /etc/agenix/ssh-key-romantic
|
||||
|
||||
# 2. deploy the configuration to all the remote host with tag `@dist-build`
|
||||
# using the ssh key we added in step 1
|
||||
@@ -163,6 +180,7 @@ Other dotfiles that inspired me:
|
||||
- [gvolpe/nix-config](https://github.com/gvolpe/nix-config)
|
||||
- [Ruixi-rebirth/flakes](https://github.com/Ruixi-rebirth/flakes)
|
||||
- [fufexan/dotfiles](https://github.com/fufexan/dotfiles): gtk theme, xdg, git, media, anyrun, etc.
|
||||
- [nix-community/srvos](https://github.com/nix-community/srvos): a collection of opinionated and sharable NixOS configurations for servers
|
||||
- Modularized NixOS Configuration
|
||||
- [hlissner/dotfiles](https://github.com/hlissner/dotfiles)
|
||||
- [viperML/dotfiles](https://github.com/viperML/dotfiles)
|
||||
@@ -197,6 +215,7 @@ Other dotfiles that inspired me:
|
||||
[DoomEmacs]: https://github.com/doomemacs/doomemacs
|
||||
[flameshot]: https://github.com/flameshot-org/flameshot
|
||||
[grim]: https://github.com/emersion/grim
|
||||
[flameshot]: https://github.com/flameshot-org/flameshot
|
||||
[imv]: https://sr.ht/~exec64/imv/
|
||||
[OBS]: https://obsproject.com
|
||||
[Mako]: https://github.com/emersion/mako
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 253 KiB |
Generated
+642
-182
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
description = "NixOS & macOS configuration of Ryan Yin";
|
||||
description = "Ryan Yin's nix configuration for both NixOS & macOS";
|
||||
|
||||
##################################################################################################################
|
||||
#
|
||||
@@ -42,21 +42,25 @@
|
||||
hooks = {
|
||||
alejandra.enable = true; # formatter
|
||||
# deadnix.enable = true; # detect unused variable bindings in `*.nix`
|
||||
statix.enable = true; # lints and suggestions for Nix code(auto suggestions)
|
||||
prettier = {
|
||||
enable = true;
|
||||
excludes = [".js" ".md" ".ts"];
|
||||
};
|
||||
# statix.enable = true; # lints and suggestions for Nix code(auto suggestions)
|
||||
# prettier = {
|
||||
# enable = true;
|
||||
# excludes = [".js" ".md" ".ts"];
|
||||
# };
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
devShells = forEachSystem (
|
||||
system: {
|
||||
default = nixpkgs.legacyPackages.${system}.mkShell {
|
||||
packages = [
|
||||
system: let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
# fix https://discourse.nixos.org/t/non-interactive-bash-errors-from-flake-nix-mkshell/33310
|
||||
nixpkgs.legacyPackages.${system}.bashInteractive
|
||||
bashInteractive
|
||||
# fix `cc` replaced by clang, which causes nvim-treesitter compilation error
|
||||
gcc
|
||||
];
|
||||
name = "dots";
|
||||
shellHook = ''
|
||||
@@ -75,11 +79,13 @@
|
||||
extra-substituters = [
|
||||
"https://anyrun.cachix.org"
|
||||
"https://hyprland.cachix.org"
|
||||
"https://nix-gaming.cachix.org"
|
||||
# "https://nixpkgs-wayland.cachix.org"
|
||||
];
|
||||
extra-trusted-public-keys = [
|
||||
"anyrun.cachix.org-1:pqBobmOjI7nKlsUMV25u9QHa9btJK65/C8vnO3p346s="
|
||||
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||
"nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
|
||||
# "nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
|
||||
];
|
||||
};
|
||||
@@ -90,10 +96,10 @@
|
||||
# There are many ways to reference flake inputs. The most widely used is github:owner/name/reference,
|
||||
# which represents the GitHub repository URL + branch/commit-id/tag.
|
||||
|
||||
# Official NixOS package source, using nixos's stable branch by default
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||
# nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
# Official NixOS package source, using nixos's unstable branch by default
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||
|
||||
# for macos
|
||||
nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-23.11-darwin";
|
||||
@@ -105,8 +111,8 @@
|
||||
|
||||
# home-manager, used for managing user configuration
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-23.11";
|
||||
# url = "github:nix-community/home-manager/master";
|
||||
# url = "github:nix-community/home-manager/release-23.11";
|
||||
url = "github:nix-community/home-manager/master";
|
||||
|
||||
# The `follows` keyword in inputs is used for inheritance.
|
||||
# Here, `inputs.nixpkgs` of home-manager is kept consistent with the `inputs.nixpkgs` of the current flake,
|
||||
@@ -141,13 +147,20 @@
|
||||
};
|
||||
# secrets management
|
||||
agenix = {
|
||||
# lock with git commit at 0.14.0
|
||||
url = "github:ryantm/agenix/54693c91d923fecb4cf04c4535e3d84f8dec7919";
|
||||
# lock with git commit at 0.15.0
|
||||
url = "github:ryantm/agenix/564595d0ad4be7277e07fa63b5a991b3c645655d";
|
||||
# replaced with a type-safe reimplementation to get a better error message and less bugs.
|
||||
# url = "github:ryan4yin/ragenix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nix-gaming.url = "github:fufexan/nix-gaming";
|
||||
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# add git hooks to format nix code before commit
|
||||
pre-commit-hooks = {
|
||||
url = "github:cachix/pre-commit-hooks.nix";
|
||||
@@ -156,11 +169,16 @@
|
||||
|
||||
nuenv.url = "github:DeterminateSystems/nuenv";
|
||||
|
||||
# daeuniverse.url = "github:daeuniverse/flake.nix/unstable";
|
||||
daeuniverse.url = "github:daeuniverse/flake.nix/exp";
|
||||
|
||||
attic.url = "github:zhaofengli/attic";
|
||||
|
||||
######################## Some non-flake repositories #########################################
|
||||
|
||||
# AstroNvim is an aesthetic and feature-rich neovim config.
|
||||
astronvim = {
|
||||
url = "github:AstroNvim/AstroNvim/v3.40.3";
|
||||
url = "github:AstroNvim/AstroNvim/v3.41.2";
|
||||
flake = false;
|
||||
};
|
||||
# doom-emacs is a configuration framework for GNU Emacs.
|
||||
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
|
||||
1. `server`: Configuration which is suitable for both servers and desktops.
|
||||
1. `desktop`: Configuration for desktop environments, such as Hyprland, I3, etc.
|
||||
1. `base.nix`: Common configuration for both servers and desktops.
|
||||
1. `core.nix`: Minimal home-manager's config
|
||||
|
||||
|
||||
@@ -1,28 +1,39 @@
|
||||
{pkgs, ...}: {
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs;
|
||||
[
|
||||
# general tools
|
||||
packer # machine image builder
|
||||
|
||||
# infrastructure as code
|
||||
pulumi
|
||||
pulumictl
|
||||
packer # machine image builder
|
||||
tf2pulumi
|
||||
crd2pulumi
|
||||
pulumiPackages.pulumi-random
|
||||
pulumiPackages.pulumi-command
|
||||
pulumiPackages.pulumi-aws-native
|
||||
pulumiPackages.pulumi-language-go
|
||||
pulumiPackages.pulumi-language-python
|
||||
pulumiPackages.pulumi-language-nodejs
|
||||
|
||||
# aws
|
||||
awscli2
|
||||
ssm-session-manager-plugin # Amazon SSM Session Manager Plugin
|
||||
aws-iam-authenticator
|
||||
eksctl
|
||||
istioctl
|
||||
|
||||
# aliyun
|
||||
aliyun-cli
|
||||
]
|
||||
++ (
|
||||
if pkgs.stdenv.isLinux
|
||||
then [
|
||||
lib.optionals pkgs.stdenv.isLinux [
|
||||
# cloud tools that nix do not have cache for.
|
||||
terraform
|
||||
terraformer # generate terraform configs from existing cloud resources
|
||||
]
|
||||
else []
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
pkgs-unstable,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs; [
|
||||
skopeo
|
||||
docker-compose
|
||||
dive # explore docker layers
|
||||
];
|
||||
|
||||
programs = {
|
||||
};
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
home.packages = with pkgs;
|
||||
[
|
||||
colmena # nixos's remote deployment tool
|
||||
|
||||
# db related
|
||||
dbeaver
|
||||
mycli
|
||||
@@ -31,17 +33,15 @@
|
||||
|
||||
# misc
|
||||
pkgs-unstable.devbox
|
||||
glow # markdown previewer
|
||||
fzf
|
||||
gdu # disk usage analyzer, required by AstroNvim
|
||||
bfg-repo-cleaner # remove large files from git history
|
||||
k6 # load testing tool
|
||||
protobuf # protocol buffer compiler
|
||||
nix-init # generate nix package from url
|
||||
|
||||
# solve coding extercises - learn by doing
|
||||
exercism
|
||||
]
|
||||
++ (
|
||||
if pkgs.stdenv.isLinux
|
||||
then [
|
||||
lib.optionals pkgs.stdenv.isLinux [
|
||||
# Automatically trims your branches whose tracking remote refs are merged or gone
|
||||
# It's really useful when you work on a project for a long time.
|
||||
git-trim
|
||||
@@ -54,8 +54,8 @@
|
||||
mitmproxy # http/https proxy tool
|
||||
insomnia # REST client
|
||||
wireshark # network analyzer
|
||||
ventoy # create bootable usb
|
||||
]
|
||||
else []
|
||||
);
|
||||
|
||||
programs = {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
The Language Server Protocol (LSP) is an open, JSON-RPC-based protocol for use between source code editors or integrated development environments (IDEs) and servers that provide programming language-specific features like:
|
||||
|
||||
- motions such as go-to-definition, find-references, hover.
|
||||
- **code completion**
|
||||
- **marking of warnings and errors**
|
||||
- **refactoring routines**
|
||||
|
||||
@@ -8,13 +8,26 @@ My editors:
|
||||
|
||||
And `Zellij` for a smooth and stable terminal experience.
|
||||
|
||||
## Tips
|
||||
|
||||
1. Many useful keys are already provided by vim, check vim/neovim's docs before you install a new plugin / reinvent the wheel.
|
||||
1. After using Emacs/Neovim more skillfully, I strongly recommend that you read the official documentation of Neovim/vim:
|
||||
1. <https://vimhelp.org/>: The official vim documentation.
|
||||
1. <https://neovim.io/doc/user/>: Neovim's official user documentation.
|
||||
1. Use Zellij for terminal related operations, and use Neovim/Helix for editing.
|
||||
1. As for Emacs, Use its GUI version & terminal emulator `vterm` for terminal related operations.
|
||||
1. Two powerful file search & jump tools:
|
||||
1. Tree-view plugins are beginner-friendly and intuitive, but they're not very efficient.
|
||||
1. **Search by the file path**: Useful when you're familiar with the project structure, especially on a large project.
|
||||
1. **Search by the content**: Useful when you're familiar with the code.
|
||||
|
||||
## Tutorial
|
||||
|
||||
Type `:tutor`(`:Tutor` in Neovim) to learn the basics usage of vim/neovim.
|
||||
|
||||
## VIM's Cheetsheet
|
||||
|
||||
> Here only record my commonly used keyboard keys, to see **a more comprehensive cheetsheet**: <https://github.com/rtorr/vim-cheat-sheet>
|
||||
> Here only record my commonly used keys, to see **a more comprehensive cheetsheet**: <https://vimhelp.org/quickref.txt.html>
|
||||
|
||||
Both Emacs-Evil & Neovim are compatible with vim, sothe key-bindings described here are common in both Emacs-Evil, Neovim & vim.
|
||||
|
||||
@@ -27,36 +40,66 @@ I mainly use Zellij for terminal related operations, here is its terminal shortc
|
||||
| Floating Terminal | `Ctrl + p + w` |
|
||||
| Horizontal Split Terminal | `Ctrl + p + d` |
|
||||
| Vertical Split Terminal | `Ctrl + p + n` |
|
||||
| Execute a command | `!xxx` |
|
||||
|
||||
### File Management
|
||||
|
||||
| Action | |
|
||||
| --------------------------------- | -------------------------------------------- |
|
||||
| Save selected text to a file | `:w filename` (Will show `:'<,'>w filename`) |
|
||||
| Save and close the current buffer | `:wq` |
|
||||
| Save all buffers | `:wa` |
|
||||
| Save and close all buffers | `:wqa` |
|
||||
> <https://neovim.io/doc/user/usr_22.html>
|
||||
|
||||
> <https://vimhelp.org/editing.txt.html>
|
||||
|
||||
| Action | |
|
||||
| ----------------------------------- | ------------------------------------------------ |
|
||||
| Save selected text to a file | `:w filename` (Will show `:'<,'>w filename`) |
|
||||
| Save and close the current buffer | `:wq` |
|
||||
| Save all buffers | `:wa` |
|
||||
| Save and close all buffers | `:wqa` |
|
||||
| Edit a file | `:e filename`(or `:e <TAB>` to show a file list) |
|
||||
| Browse the file list | `:Ex` or `:e .` |
|
||||
| Discard changes and reread the file | `:e!` |
|
||||
|
||||
### Motion
|
||||
|
||||
> https://vimhelp.org/motion.txt.html
|
||||
|
||||
| Action | Command |
|
||||
| --------------------------------------------------- | -------------------------------------------------- |
|
||||
| Move to the start/end of the buffer | `gg`/`G` |
|
||||
| Move the line number 5 | `5gg` / `5G` |
|
||||
| Move left/down/up/right | h/j/k/l or `5h`/`5j`/`5k`/`5l` or `Ctr-n`/`Ctrl-p` |
|
||||
| Move to the matchpairs, default to `()`, `{}`, `[]` | `%` |
|
||||
| Move to the start/end of the line | `0` / `$` |
|
||||
| Move a sentence forward/backward | `(` / `)` |
|
||||
| Move a paragraph forward/backward | `{` / `}` |
|
||||
| Move a section forward/backward | `[[` / `]]` |
|
||||
| Jump to various positions | `'` + some other keys(neovim has prompt) |
|
||||
|
||||
Text Objects:
|
||||
|
||||
- **sentence**: text ending at a '.', '!' or '?' followed by either the end of a line, or by a space or tab.
|
||||
- **paragraph**: text ending at a blank line.
|
||||
- **section**: text starting with a section header and ending at the start of the next section header (or at the end of the file). - The "`]]`" and "`[[`" commands stop at the '`{`' in the first column. This is
|
||||
useful to find the start of a function in a C/Go/Java/... program.
|
||||
|
||||
### Text Manipulation
|
||||
|
||||
Basics:
|
||||
|
||||
| Action | |
|
||||
| --------------------------------------------------- | ------------------------------ |
|
||||
| Move to the start/end of the buffer | `gg`/`G` |
|
||||
| Move the line number 5 | `5gg` / `5G` |
|
||||
| Move left/down/up/right | h/j/k/l or `5h`/`5j`/`5k`/`5l` |
|
||||
| Move to the matchpairs, default to `()`, `{}`, `[]` | `%` |
|
||||
| Delete the current character | `x` |
|
||||
| Delete the selection | `d` |
|
||||
| Undo the last change | `u` |
|
||||
| Redo the last change | `Ctrl + r` |
|
||||
|
||||
Convert Text Cases:
|
||||
|
||||
| Toggle text's case | `~` |
|
||||
| Convert to uppercase | `U` |
|
||||
| Convert to lowercase | `u` |
|
||||
| Action | |
|
||||
| --------------------------------------- | -------------------------- |
|
||||
| Delete the current character | `x` |
|
||||
| Paste the copied text | `p` |
|
||||
| Delete the selection | `d` |
|
||||
| Undo the last word | `CTRL-w`(in insert mode) |
|
||||
| Undo the last line | `CTRL-u`(in insert mode) |
|
||||
| Undo the last change | `u` |
|
||||
| Redo the last change | `Ctrl + r` |
|
||||
| Inserts the text of the previous insert | `Ctrl + a` |
|
||||
| Repeat the last command | `.` |
|
||||
| Toggle text's case | `~` |
|
||||
| Convert to uppercase | `U` (visual mode) |
|
||||
| Convert to lowercase | `u` (visual mode) |
|
||||
| Align the selected conent | `:center`/`:left`/`:right` |
|
||||
|
||||
Misc:
|
||||
|
||||
@@ -73,9 +116,9 @@ Misc:
|
||||
|
||||
| Action | |
|
||||
| ------------------------------------------------------------------------- | -------------- |
|
||||
| Sort tye selected lines | `:sort` |
|
||||
| Join Selection of Lines With Space | `:join` or `J` |
|
||||
| Join without spaces | `:join!` |
|
||||
| Move to the start/end of the line | `0` / `$` |
|
||||
| Enter Insert mode at the start/end of the line | `I` / `A` |
|
||||
| Delete from the cursor to the end of the line | `D` |
|
||||
| Delete from the cursor to the end of the line, and then enter insert mode | `C` |
|
||||
@@ -111,12 +154,12 @@ Advance Techs:
|
||||
|
||||
### Find and Replace
|
||||
|
||||
| Action | Command |
|
||||
| ------------------------ | ----------------------------------- |
|
||||
| Replace in selected area | `:s/old/new/g` |
|
||||
| Replace in current line | Same as above |
|
||||
| Replace in whole file | `:% s/old/new/g` |
|
||||
| Replace with regex | `:% s@\vhttp://(\w+)@https://\1@gc` |
|
||||
| Action | Command |
|
||||
| -------------------------------- | ----------------------------------- |
|
||||
| Replace in selected area | `:s/old/new/g` |
|
||||
| Replace in current line | Same as above |
|
||||
| Replace all the lines | `:% s/old/new/g` |
|
||||
| Replace all the lines with regex | `:% s@\vhttp://(\w+)@https://\1@gc` |
|
||||
|
||||
1. `\v` means means that in the regex pattern after it can be used without backslash escaping(similar to python's raw string).
|
||||
2. `\1` means the first matched group in the pattern.
|
||||
@@ -127,6 +170,7 @@ Advance Techs:
|
||||
| ----------------------------------------- | -------------------------------------- |
|
||||
| From the 10th line to the end of the file | `:10,$ s/old/new/g` or `:10,$ s@^@#@g` |
|
||||
| From the 10th line to the 20th line | `:10,20 s/old/new/g` |
|
||||
| Remove the trailing spaces | `:% s/\s\+$//g` |
|
||||
|
||||
The postfix(flags) in the above commands:
|
||||
|
||||
@@ -136,15 +180,27 @@ The postfix(flags) in the above commands:
|
||||
|
||||
### Buffers, Windows and Tabs
|
||||
|
||||
> <https://neovim.io/doc/user/usr_08.html>
|
||||
|
||||
> <https://vimhelp.org/windows.txt.html>
|
||||
|
||||
- A buffer is the in-memory text of a file.
|
||||
- A window is a viewport on a buffer.
|
||||
- A tab page is a collection of windows.
|
||||
|
||||
| Action | Command |
|
||||
| ----------------------------------- | ----------------------------------- |
|
||||
| Split the window horizontally | `:sp[lit]` or `:sp filename` |
|
||||
| Split the window horizontally | `:vs[plit]` or `:vs filename` |
|
||||
| Switch to the next/previous window | `Ctrl-w + w` or `Ctrl-w + h/j/k/l` |
|
||||
| Show all buffers | `:ls` |
|
||||
| show next/previous buffer | `]b`/`[b` or `:bn[ext]` / `bp[rev]` |
|
||||
| Split the window horizontally | `:sp[lit]` |
|
||||
| Split the window horizontally | `:vs[plit]` |
|
||||
| New Tab(New Workspace in DoomEmacs) | `:tabnew` |
|
||||
| Next/Previews Tab | `gt`/`gT` |
|
||||
|
||||
### History
|
||||
|
||||
| Action | Command |
|
||||
| ------------------------ | ------- |
|
||||
| Show the command history | `q:` |
|
||||
| Show the search history | `q/` |
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
Some plugins:
|
||||
|
||||
- Emacs
|
||||
- [parinfer-rust-mode](https://github.com/justinbarclay/parinfer-rust-mode)
|
||||
- [parinfer-rusT-mode](https://github.com/justinbarclay/parinfer-rust-mode)
|
||||
- Neovim
|
||||
- [parinfer-rust](https://github.com/eraserhd/parinfer-rust)
|
||||
- <https://github.com/Olical/conjure>
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
# Emacs Editor
|
||||
|
||||
- Framework: <https://github.com/doomemacs/doomemacs>
|
||||
- key bindings:
|
||||
- source code: <https://github.com/doomemacs/doomemacs/blob/master/modules/config/default/%2Bevil-bindings.el>
|
||||
- docs: <https://github.com/doomemacs/doomemacs/blob/master/modules/editor/evil/README.org>
|
||||
- module index: <https://github.com/doomemacs/doomemacs/blob/master/docs/modules.org>
|
||||
- Chinese(rime) support: <https://github.com/DogLooksGood/emacs-rime>
|
||||
- modal editing:
|
||||
- <https://github.com/emacs-evil/evil>: evil mode, enabled by default in doom-emacs.
|
||||
- <https://github.com/meow-edit/meow>
|
||||
- LSP Client: <https://github.com/manateelazycat/lsp-bridge>
|
||||
- Emacs Wiki: <https://www.emacswiki.org/emacs/SiteMap>
|
||||
- Awesome Emacs: <https://github.com/emacs-tw/awesome-emacs#lsp-client>
|
||||
|
||||
## Why emacs?
|
||||
|
||||
1. Explore the unknown, just for fun!
|
||||
2. Org Mode
|
||||
3. Lisp Coding
|
||||
4. A top-level tutorial for Emacs(Chinese): <https://nyk.ma/tags/emacs/>
|
||||
5. A Beginner's Guide to Emacs(Chinese): <https://github.com/emacs-tw/emacs-101-beginner-survival-guide>
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
||||
## Usefull Links
|
||||
|
||||
- Framework: <https://github.com/doomemacs/doomemacs>
|
||||
- key bindings:
|
||||
- source code: <https://github.com/doomemacs/doomemacs/blob/master/modules/config/default/%2Bevil-bindings.el>
|
||||
- docs: <https://github.com/doomemacs/doomemacs/blob/master/modules/editor/evil/README.org>
|
||||
- module index: <https://github.com/doomemacs/doomemacs/blob/master/docs/modules.org>
|
||||
- LSP Client: <https://github.com/manateelazycat/lsp-bridge>
|
||||
- Emacs Wiki: <https://www.emacswiki.org/emacs/SiteMap>
|
||||
- Awesome Emacs: <https://github.com/emacs-tw/awesome-emacs#lsp-client>
|
||||
- Chinese(rime) support: <https://github.com/DogLooksGood/emacs-rime>
|
||||
- modal editing:
|
||||
- <https://github.com/emacs-evil/evil>: evil mode, enabled by default in doom-emacs.
|
||||
- <https://github.com/meow-edit/meow>
|
||||
|
||||
## Install or Update
|
||||
|
||||
@@ -40,9 +48,22 @@ jsut emacs-purge
|
||||
just emacs-reload
|
||||
|
||||
# clear test data
|
||||
just emacs-clear
|
||||
just emacs-clean
|
||||
```
|
||||
|
||||
## Limits
|
||||
|
||||
- It's too slow to start up and install(compile/build) packages.
|
||||
- I have to use emacs in daemon/client mode to avoid this issue.
|
||||
- It's too large in size, not suitable for servers.
|
||||
- So vim/neovim is still the best choice for servers.
|
||||
- Emacs's markdown-mode works not well with tables, see:
|
||||
- https://github.com/jrblevin/markdown-mode/issues/380
|
||||
- I use git command frequently, but doomemacs only autoupdates status of git diff / treemacs when using magit.
|
||||
- I have to learn magit to avoid this issue...
|
||||
- GitHub's orgmode support is not well, Markdown is better for GitHub.
|
||||
- Use markdown for repo's README.md, and use orgmode for my personal notes and docs only.
|
||||
|
||||
## Cheetsheet
|
||||
|
||||
Here is the cheetsheet related to my DoomEmacs configs. Please read vim's common cheetsheet at [../README.md](../README.md) before reading the following.
|
||||
@@ -51,14 +72,15 @@ Here is the cheetsheet related to my DoomEmacs configs. Please read vim's common
|
||||
|
||||
> Terminal(vterm) is useful in GUI mode, I use Zellij instead in terminal mode.
|
||||
|
||||
> We can run any emacs command via `M-x`(Alt + x).
|
||||
|
||||
| Action | Shortcut |
|
||||
| ---------------------- | ------------- |
|
||||
| Popup Terminal(vterm) | `SPC + o + t` |
|
||||
| Open Terminal | `SPC + o + T` |
|
||||
| Open file tree sidebar | `SPC + o + p` |
|
||||
| Exit | `M-x C-c` |
|
||||
| Action | Shortcut |
|
||||
| ---------------------- | ------------------------------------------------- |
|
||||
| Popup Terminal(vterm) | `SPC + o + t` |
|
||||
| Open Terminal | `SPC + o + T` |
|
||||
| Open file tree sidebar | `SPC + o + p` |
|
||||
| Frame fullscreen | `SPC + t + F` |
|
||||
| Exit | `M-x C-c` |
|
||||
| Execute Command | `M-x`(hold on `Alt`/`option`, and then press `x`) |
|
||||
| Eval Lisp Code | `M-:`(hold on `Alt`/`option`, and then press `:`) |
|
||||
|
||||
### Window Navigation
|
||||
|
||||
@@ -145,7 +167,7 @@ SPC s p foo C-; E C-c C-p :%s/foo/bar/g RET Z Z
|
||||
|
||||
> easily switch between projects without exit emacs!
|
||||
|
||||
| Action | |
|
||||
| Action | Shortcut |
|
||||
| -------------------------- | ------------- |
|
||||
| Switch between projects | `SPC + p + p` |
|
||||
| Browse the current project | `SPC + p + .` |
|
||||
@@ -155,10 +177,47 @@ SPC s p foo C-; E C-c C-p :%s/foo/bar/g RET Z Z
|
||||
|
||||
> Very useful when run emacs in daemon/client modes
|
||||
|
||||
| Action | |
|
||||
| Action | Shortcut |
|
||||
| --------------------------- | --------------------------- |
|
||||
| Switch between workspaces | `M-1/2/3/...`(Alt-1/2/3/..) |
|
||||
| New Workspace | `SPC + TAB + n` |
|
||||
| New Named Workspace | `SPC + TAB + N` |
|
||||
| Delete Workspace | `SPC + TAB + d` |
|
||||
| Display Workspaces bar blow | `SPC + TAB + TAB` |
|
||||
|
||||
### Magit
|
||||
|
||||
> https://github.com/magit/magit
|
||||
|
||||
Magit is a powerful tool that make git operations easy and intuitive.
|
||||
|
||||
| Action | Shortcut |
|
||||
| ------------------------ | ------------------------ |
|
||||
| Open Magit | `C-x g` or `SPC + g + g` |
|
||||
| Switch branch | `SPC + g + b` |
|
||||
| Show buffer's commit log | `SPC + g + L` |
|
||||
|
||||
Shortcuts in magit's pane:
|
||||
|
||||
> When run `git commit` / `git add` / `git push` /... via magit, multiple Arguments can be set.
|
||||
> Set arguments won't trigger a git command immediately. Magit will try to run a git command only after an Action key is pressed.
|
||||
|
||||
| Action | Shortcut |
|
||||
| -------------------------------------------------- | --------------------------------------------- |
|
||||
| Quit the current Magit pane | `q` |
|
||||
| Show log | `l` |
|
||||
| Show current branch's log | `l + l` |
|
||||
| Show current reflog | `l + r` |
|
||||
| Commit | `c` |
|
||||
| Stage | `s` |
|
||||
| Unstage | `u` |
|
||||
| Push | `p` |
|
||||
| Pull | `f` |
|
||||
| Rebase | `r` |
|
||||
| Rebase Interactively | `r + i`, select on a commit, then `C-c + C-c` |
|
||||
| Stash | `z` |
|
||||
| Merge | `m` |
|
||||
| Fold/Unfold | `TAB` |
|
||||
| Show details of the current unit(commit/stage/...) | `<ENTER>` |
|
||||
|
||||
KeyBinding full list: <https://github.com/emacs-evil/evil-collection/tree/master/modes/magit#key-bindings>
|
||||
|
||||
@@ -24,6 +24,9 @@ with lib; let
|
||||
};
|
||||
librime-dir = "${config.xdg.dataHome}/emacs/librime";
|
||||
parinfer-rust-lib-dir = "${config.xdg.dataHome}/emacs/parinfer-rust";
|
||||
myEmacsPackagesFor = emacs: ((pkgs.emacsPackagesFor emacs).emacsWithPackages (epkgs: [
|
||||
epkgs.vterm
|
||||
]));
|
||||
in {
|
||||
options.modules.editors.emacs = {
|
||||
enable = mkEnableOption "Emacs Editor";
|
||||
@@ -40,10 +43,11 @@ in {
|
||||
## Optional dependencies
|
||||
fd # faster projectile indexing
|
||||
imagemagick # for image-dired
|
||||
fd # faster projectile indexing
|
||||
zstd # for undo-fu-session/undo-tree compression
|
||||
|
||||
# go-mode
|
||||
gocode
|
||||
# gocode # project archived, use gopls instead
|
||||
|
||||
## Module dependencies
|
||||
# :checkers spell
|
||||
@@ -61,19 +65,11 @@ in {
|
||||
home.shellAliases = shellAliases;
|
||||
programs.nushell.shellAliases = shellAliases;
|
||||
|
||||
# allow fontconfig to discover fonts and configurations installed through `home.packages`
|
||||
fonts.fontconfig.enable = true;
|
||||
|
||||
xdg.configFile."doom" = {
|
||||
source = ./doom;
|
||||
force = true;
|
||||
};
|
||||
|
||||
xdg.configFile."emacs/lsp-bridge-user-langserver" = {
|
||||
source = ./lsp-bridge-user-langserver;
|
||||
force = true;
|
||||
};
|
||||
|
||||
home.activation.installDoomEmacs = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||
${pkgs.rsync}/bin/rsync -avz --chmod=D2755,F744 ${doomemacs}/ ${config.xdg.configHome}/emacs/
|
||||
|
||||
@@ -92,7 +88,7 @@ in {
|
||||
# Do not use emacs-nox here, which makes the mouse wheel work abnormally in terminal mode.
|
||||
# pgtk (pure gtk) build add native support for wayland.
|
||||
# https://www.gnu.org/savannah-checkouts/gnu/emacs/emacs.html#Releases
|
||||
emacsPkg = (pkgs.emacsPackagesFor pkgs.emacs29-pgtk).emacsWithPackages (epkgs: [epkgs.vterm]);
|
||||
emacsPkg = myEmacsPackagesFor pkgs.emacs29-pgtk;
|
||||
in {
|
||||
home.packages = [emacsPkg];
|
||||
services.emacs = {
|
||||
@@ -111,7 +107,7 @@ in {
|
||||
let
|
||||
# macport adds some native features based on GNU Emacs 29
|
||||
# https://bitbucket.org/mituharu/emacs-mac/src/master/README-mac
|
||||
emacsPkg = (pkgs.emacsPackagesFor pkgs.emacs29-macport).emacsWithPackages (epkgs: [epkgs.vterm]);
|
||||
emacsPkg = myEmacsPackagesFor pkgs.emacs29;
|
||||
in {
|
||||
home.packages = [emacsPkg];
|
||||
launchd.enable = true;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
;; See 'C-h v doom-font' for documentation and more examples of what they
|
||||
;; accept. For example:
|
||||
;;
|
||||
(setq doom-font (font-spec :family "JetBrainsMono Nerd Font" :size 18 :weight 'normal)
|
||||
(setq doom-font (font-spec :family "JetBrainsMono Nerd Font" :size 18)
|
||||
doom-variable-pitch-font (font-spec :family "DejaVu Sans")
|
||||
doom-symbol-font (font-spec :family "Symbols Nerd Font Mono")
|
||||
doom-big-font (font-spec :family "JetBrainsMono Nerd Font" :size 28))
|
||||
@@ -46,9 +46,17 @@
|
||||
;; other doom's official themes:
|
||||
;; https://github.com/doomemacs/themes
|
||||
(setq doom-theme 'doom-dracula) ;; doom-one doom-dracula doom-nord
|
||||
;; Transparent Background
|
||||
(set-frame-parameter nil 'alpha-background 93) ; For current frame
|
||||
(add-to-list 'default-frame-alist '(alpha-background . 93)); For all new frames henceforth
|
||||
(if (eq system-type 'darwin)
|
||||
;; Transparent Backgroud - for macOS
|
||||
;;(set-frame-parameter (selected-frame) 'alpha '(<active> . <inactive>))
|
||||
;;(set-frame-parameter (selected-frame) 'alpha <both>)
|
||||
(progn
|
||||
(set-frame-parameter (selected-frame) 'alpha '(85 . 70))
|
||||
(add-to-list 'default-frame-alist '(alpha . (85 . 70))))
|
||||
;; Transparent Background - for Linux Xorg/Wayland
|
||||
(set-frame-parameter nil 'alpha-background 93) ; For current frame
|
||||
(add-to-list 'default-frame-alist '(alpha-background . 93))); For all new frames henceforth
|
||||
|
||||
;; This determines the style of line numbers in effect. If set to `nil', line
|
||||
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
||||
(setq display-line-numbers-type t)
|
||||
@@ -88,36 +96,21 @@
|
||||
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
|
||||
;; they are implemented.
|
||||
|
||||
(use-package! lsp-bridge
|
||||
:config
|
||||
(setq lsp-bridge-enable-log nil) ;; disabled for performance
|
||||
;; for user's custom langserver file
|
||||
(setq lsp-bridge-user-langserver-dir "~/.config/emacs/lsp-bridge-user-langserver")
|
||||
(setq lsp-bridge-enable-auto-format-code 1)
|
||||
(global-lsp-bridge-mode))
|
||||
|
||||
(use-package! wakatime-mode :ensure t)
|
||||
;; fully enable tree-sitter highlighting
|
||||
(after! tree-sitter
|
||||
(setq +tree-sitter-hl-enabled-modes t))
|
||||
;; fix: https://github.com/jrblevin/markdown-mode/issues/380
|
||||
;; even add this one, editing a large markdown table is still very slow.
|
||||
;; so avoid editing large markdown file in emacs, use neovim instead...
|
||||
(after! markdown-mode
|
||||
(global-font-lock-mode 0))
|
||||
|
||||
;; use alejandra to format nix files
|
||||
;; (use-package! lsp-nix
|
||||
;; :ensure lsp-mode
|
||||
;; :after
|
||||
;; (lsp-mode)
|
||||
;; :demand t
|
||||
;; :custom
|
||||
;; (lsp-nix-nil-formatter
|
||||
;; ["alejandra"]))
|
||||
(use-package! lsp-nix
|
||||
:ensure lsp-mode
|
||||
:after
|
||||
(lsp-mode)
|
||||
:demand t
|
||||
:custom
|
||||
(lsp-nix-nil-formatter
|
||||
["alejandra"]))
|
||||
|
||||
(use-package! nushell-mode
|
||||
:config
|
||||
(setq nushell-enable-auto-indent 1))
|
||||
(after! vterm
|
||||
(setq vterm-shell "nu")) ; use nushell by defualt
|
||||
|
||||
;; emacs-rime
|
||||
(use-package! rime
|
||||
@@ -155,3 +148,28 @@
|
||||
(add-hook 'fennel-mode-hook #'turn-off-smartparens-mode)
|
||||
(add-hook 'hy-mode-hook #'turn-off-smartparens-mode)
|
||||
|
||||
;; auto-save
|
||||
(use-package super-save
|
||||
:ensure t
|
||||
:config
|
||||
(super-save-mode +1)
|
||||
(setq super-save-auto-save-when-idle t)
|
||||
(setq auto-save-default nil))
|
||||
|
||||
;; save on find-file
|
||||
(add-to-list 'super-save-hook-triggers 'find-file-hook)
|
||||
|
||||
(use-package! copilot
|
||||
:hook
|
||||
(prog-mode . copilot-mode)
|
||||
:bind
|
||||
(:map copilot-completion-map
|
||||
("<tab>" . 'copilot-accept-completion)
|
||||
("TAB" . 'copilot-accept-completion)
|
||||
("C-TAB" . 'copilot-accept-completion-by-word)
|
||||
("C-<tab>" . 'copilot-accept-completion-by-word))
|
||||
:config
|
||||
(copilot-mode +1))
|
||||
|
||||
(use-package! wakatime-mode :ensure t)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
doom ; what makes DOOM look the way it does
|
||||
doom-dashboard ; a nifty splash screen for Emacs
|
||||
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||
(emoji +unicode)
|
||||
;; (emoji +unicode) ; Emacs 29 provides native support for inserting Unicode emojis.
|
||||
; 🙂
|
||||
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||||
indent-guides ; highlighted indent columns
|
||||
@@ -61,7 +61,7 @@
|
||||
(format +onsave)
|
||||
; automated prettiness
|
||||
;; multiple-cursors ; editing in many places at once
|
||||
;; objed ; text object editing for the innocent
|
||||
;; objed ; text object editing for the innocent, conflict with parinfer
|
||||
parinfer ; turn lisp into python, sort of, conflict with copilot/objed/smartparens
|
||||
;;rotate-text ; cycle region at point between text candidates
|
||||
snippets ; my elves. They type so I don't have to
|
||||
@@ -98,7 +98,7 @@
|
||||
(eval +overlay)
|
||||
; run code, run (also, repls)
|
||||
lookup ; navigate your code and its documentation
|
||||
;; lsp ; lsp-mode, conflict with lsp-bridge
|
||||
lsp ; lsp-mode, conflict with lsp-bridge
|
||||
magit ; a git porcelain for Emacs
|
||||
;;make ; run make tasks from Emacs
|
||||
;;pass ; password manager for nerds
|
||||
@@ -117,7 +117,7 @@
|
||||
:lang
|
||||
;;agda ; types of types of types of types...
|
||||
;;beancount ; mind the GAAP
|
||||
(cc +tree-sitter)
|
||||
(cc +lsp +tree-sitter)
|
||||
; C > C++ == 1
|
||||
;;clojure ; java with a lisp
|
||||
;;common-lisp ; if you've seen one lisp, you've seen them all
|
||||
@@ -138,17 +138,17 @@
|
||||
;;fsharp ; ML stands for Microsoft's Language
|
||||
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||||
;;gdscript ; the language you waited for
|
||||
(go +tree-sitter) ;; disable go-mode, use lsp-bridge instead
|
||||
(go +lsp +tree-sitter) ;; disable go-mode, use lsp-bridge instead
|
||||
; the hipster dialect
|
||||
;;(graphql) ; Give queries a REST
|
||||
;;(haskell) ; a language that's lazier than I am
|
||||
;;hy ; readability of scheme w/ speed of python
|
||||
;;idris ; a language you can depend on
|
||||
(json +tree-sitter)
|
||||
(json +lsp +tree-sitter)
|
||||
; At least it ain't XML
|
||||
(java +tree-sitter)
|
||||
(java +lsp +tree-sitter)
|
||||
; the poster child for carpal tunnel syndrome
|
||||
(javascript +tree-sitter)
|
||||
(javascript +lsp +tree-sitter)
|
||||
; all(hope(abandon(ye(who(enter(here))))))
|
||||
;;julia ; a better, faster MATLAB
|
||||
;;kotlin ; a better, slicker Java(Script)
|
||||
@@ -156,19 +156,19 @@
|
||||
; writing papers in Emacs has never been so fun
|
||||
;;lean ; for folks with too much to prove
|
||||
;;ledger ; be audit you can be
|
||||
(lua +tree-sitter)
|
||||
(lua +lsp +tree-sitter)
|
||||
; one-based indices? one-based indices
|
||||
(markdown +grip)
|
||||
; writing docs for people to ignore
|
||||
;;nim ; python + lisp at the speed of c
|
||||
(nix +tree-sitter)
|
||||
(nix +lsp +tree-sitter)
|
||||
; I hereby declare "nix geht mehr!"
|
||||
;;ocaml ; an objective camel
|
||||
org ; organize your plain life in plain text
|
||||
(org +pandoc +hugo +jupyter) ; organize your plain life in plain text
|
||||
;;php ; perl's insecure younger brother
|
||||
;;plantuml ; diagrams for confusing people more
|
||||
;;purescript ; javascript, but functional
|
||||
(python +tree-sitter +pyright)
|
||||
(python +lsp +tree-sitter +pyright)
|
||||
; beautiful is better than ugly
|
||||
;;qt ; the 'cutest' gui framework ever
|
||||
racket ; a DSL for DSLs
|
||||
@@ -176,20 +176,20 @@
|
||||
;;rest ; Emacs as a REST client
|
||||
;;rst ; ReST in peace
|
||||
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
(rust +tree-sitter)
|
||||
(rust +lsp +tree-sitter)
|
||||
; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
;;scala ; java, but good
|
||||
(scheme +guile)
|
||||
; a fully conniving family of lisps
|
||||
(sh +tree-sitter)
|
||||
(sh +lsp +tree-sitter)
|
||||
; she sells {ba,z,fi}sh shells on the C xor
|
||||
;;sml
|
||||
;;solidity ; do you need a blockchain? No.
|
||||
;;swift ; who asked for emoji variables?
|
||||
;;terra ; Earth and Moon in alignment for performance.
|
||||
(web +tree-sitter)
|
||||
(web +lsp +tree-sitter)
|
||||
; support for various web languages, including HTML5, CSS, SASS/SCSS, Pug/Jade/Slim, and more
|
||||
(yaml +tree-sitter)
|
||||
(yaml +lsp +tree-sitter)
|
||||
; JSON, but readable
|
||||
;;zig ; C, but simpler
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
;; on the command line, then restart Emacs for the changes to take effect -- or
|
||||
;; use 'M-x doom/reload'.
|
||||
|
||||
(package! nerd-icons)
|
||||
(package! super-save)
|
||||
(package! rime)
|
||||
(package! wakatime-mode
|
||||
:recipe
|
||||
@@ -15,15 +15,10 @@
|
||||
(package! nushell-mode :recipe
|
||||
(:host github :repo "mrkkrp/nushell-mode"))
|
||||
|
||||
(when (package! lsp-bridge
|
||||
:recipe (:host github
|
||||
:repo "manateelazycat/lsp-bridge"
|
||||
:branch "master"
|
||||
:files ("*.el" "*.py" "acm" "core" "langserver" "multiserver" "resources")
|
||||
;; do not perform byte compilation or native compilation for lsp-bridge
|
||||
:build (:not compile)))
|
||||
(package! markdown-mode)
|
||||
(package! yasnippet))
|
||||
(package! copilot
|
||||
:recipe
|
||||
(:host github :repo "copilot-emacs/copilot.el" :files
|
||||
("*.el" "dist")))
|
||||
|
||||
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
|
||||
;; (package! some-package)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "nil",
|
||||
"languageId": "nix",
|
||||
"command": ["nil"],
|
||||
"settings": {
|
||||
"nil": {
|
||||
"formatting": { "command": ["alejandra"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,20 @@ But its configuration is a bit complex, and finding the right plugins, writing c
|
||||
That's why I'm interested in Helix, Helix is similar to Neovim, but it's more opinionated, and it's batteries included.
|
||||
Whether I'll switch my main editor to Helix or not, it gives me a lot of ideas on how to improve my Neovim workflow.
|
||||
|
||||
## Tutorial
|
||||
|
||||
Use `:tutor` in helix to start the tutorial.
|
||||
|
||||
## Differences between Neovim and Helixer
|
||||
|
||||
1. Selecting first, then action.
|
||||
1. Helix: delete 2 word: `2w` then `x`. You can always see what you're selecting before you apply the action.
|
||||
2. Neovim: delete 2 word: `d`. then `2w`. No visual feedback before you apply the action.
|
||||
1. Helix - Morden builtin features: LSP, tree-sitter, fuzzy finder, multi cursors, surround and more.
|
||||
1. They're all available in Neovim too, but you need to find and use the right plugins manually, which takes time and effort.
|
||||
1. Helix is built in Rust from scratch. The result is a much smaller codebase and a modern set of defaults. No VimScript. No Lua.
|
||||
1. Neovim contains a lot of VimScript, and lua is too dynamic, it's hard to debug.
|
||||
1. Personally I'm glad to take a look at a Rust codebase, but not a VimScript/Lua codebase.
|
||||
1. Neovim have a very activate plugin ecosystem, and it's easy to find plugins for almost everything.
|
||||
1. Helix is still new, and it even do have a stable plugin system yet. A PR to add a plugin system is still envolving: <https://github.com/helix-editor/helix/pull/8675>
|
||||
2. Neovim has intergrated terminal, and it's very powerful. It's quite similar to VSCode's intergrated terminal. I use it a lot.
|
||||
@@ -19,9 +31,11 @@ Whether I'll switch my main editor to Helix or not, it gives me a lot of ideas o
|
||||
1. Helix do not have a tree-view panel, it's recommended to use Yazi/ranger/Broot instead, and open Helix in them.
|
||||
1. a tree-view plugin may be added after the plugin system is stable, but no one knows when it will be.
|
||||
2. and some Helix users stated that they don't need a tree-view plugin, Helix's file picker is useful and good enough.
|
||||
1. It seems Helix lacks a substitution command, you should run it in another window(via wm or Zellij).
|
||||
1. It seems Helix lacks a global substitution command, you should run it in another window(via wm or Zellij).
|
||||
1. <https://github.com/helix-editor/helix/issues/196>
|
||||
1. Neovim's substitution command allow you to preview the changes before you apply it, and it's very useful. if I switch to Helix, I'll need to find some other tools with similar feature(such as https://github.com/ms-jpq/sad).
|
||||
2. The downside of Neovim's substitution command is that it's unable to save the command we just typed. If I made some things wrong, I have to type the whole substitution command again.
|
||||
1. Complexity and Maintenance Costs vs Batteries Included: <https://github.com/helix-editor/helix/discussions/6356>
|
||||
|
||||
|
||||
I think Use Helix/Neovim within a terminal file manager(Yazi/ranger/Broot) and Zellij is a good idea.
|
||||
It's quite different from the workflow I migrated from VSCode/JetBrains before, I'm very interested in it.
|
||||
|
||||
@@ -132,7 +132,13 @@ Press `<Space> + D` to view available bindings and options.
|
||||
| Description | Shortcut |
|
||||
| ------------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||
| Open spectre.nvim search and replace panel | `<Space> + ss` |
|
||||
| Search and replace in command line(need install `sad` first) | `find -name "*.nix" \| sad '<pattern>' '<replacement>' \| delta` |
|
||||
|
||||
Search and replace via cli(fd + sad + delta):
|
||||
|
||||
```bash
|
||||
fd "\\.nix$" . | sad '<pattern>' '<replacement>' | delta
|
||||
```
|
||||
|
||||
|
||||
### Surrounding Characters
|
||||
|
||||
|
||||
@@ -32,12 +32,6 @@ in {
|
||||
home.shellAliases = shellAliases;
|
||||
programs.nushell.shellAliases = shellAliases;
|
||||
|
||||
nixpkgs.config = {
|
||||
programs.npm.npmrc = ''
|
||||
prefix = ''${HOME}/.npm-global
|
||||
'';
|
||||
};
|
||||
|
||||
programs = {
|
||||
neovim = {
|
||||
enable = true;
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
{pkgs, ...}: {
|
||||
nixpkgs.config = {
|
||||
programs.npm.npmrc = ''
|
||||
prefix = ''${HOME}/.npm-global
|
||||
'';
|
||||
};
|
||||
|
||||
home.packages = with pkgs;
|
||||
[
|
||||
#-- c/c++
|
||||
@@ -6,20 +12,22 @@
|
||||
cmake-language-server
|
||||
gnumake
|
||||
checkmake
|
||||
llvmPackages.clang-unwrapped # c/c++ tools with clang-tools such as clanvimPlugins.nvim-treesitter-parsers.vuegd
|
||||
lldb
|
||||
# c/c++ compiler, required by nvim-treesitter!
|
||||
# gcc has to be installed after clang, so that `cc` will be gcc instead of clang(on macOS)
|
||||
gcc
|
||||
# c/c++ tools with clang-tools, the unwrapped version won't
|
||||
# add alias like `cc` and `c++`, so that it won't conflict with gcc
|
||||
llvmPackages.clang-unwrapped
|
||||
lldb
|
||||
|
||||
#-- python
|
||||
nodePackages.pyright # python language server
|
||||
(python310.withPackages (
|
||||
(python311.withPackages (
|
||||
ps:
|
||||
with ps; [
|
||||
ruff-lsp
|
||||
black # python formatter
|
||||
|
||||
jupyter
|
||||
ipython
|
||||
pandas
|
||||
requests
|
||||
@@ -113,15 +121,15 @@
|
||||
marksman # language server for markdown
|
||||
glow # markdown previewer
|
||||
fzf
|
||||
pandoc # document converter
|
||||
hugo # static site generator
|
||||
|
||||
#-- Optional Requirements:
|
||||
gdu # disk usage analyzer, required by AstroNvim
|
||||
(ripgrep.override {withPCRE2 = true;}) # recursively searches directories for a regex pattern
|
||||
]
|
||||
++ (
|
||||
if pkgs.stdenv.isDarwin
|
||||
then []
|
||||
else [
|
||||
lib.optionals pkgs.stdenv.isLinux [
|
||||
#-- verilog / systemverilog
|
||||
verible
|
||||
gdb
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# Encryption
|
||||
|
||||
We have GnuPG & password-store installed by default, mainly for password management, authentication & communication encryption.
|
||||
|
||||
We also have LUKS2 for disk encryption on Linux, and [rclone](https://rclone.org/crypt/) for cross-platform data encryption & syncing.
|
||||
|
||||
[age](https://github.com/FiloSottile/age) may be more general for file encryption.
|
||||
|
||||
[Sops](https://github.com/getsops/sops/tree/main) can be used for file encryption too, if you prefer
|
||||
using a Cloud provider for key management.
|
||||
|
||||
|
||||
## Asymmetric Encryption
|
||||
|
||||
Both age, Sops & GnuPG provide asymmetric encryption, which is useful for encrypting files for a specific user.
|
||||
|
||||
For morden use, age is recommended, as it use [AEAD encryption function - ChaCha20-Poly1305][age Format v1],
|
||||
If you do not want to manage the keys by yourself, Sops is recommended, as it use KMS for key management.
|
||||
|
||||
## Symmetric Encryption
|
||||
|
||||
Both age & GnuPG provide symmetric encryption, which is useful for encrypting files for a specific user.
|
||||
|
||||
As described in [age Format v1][age Format v1], age use scrypt to encrypt and decrypt the file key with a provided passphrase,
|
||||
which is more secure than GnuPG's symmetric encryption.
|
||||
|
||||
|
||||
|
||||
[age Format v1]: https://age-encryption.org/v1
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{pkgs, ...}: {
|
||||
home.packages = with pkgs; [
|
||||
age
|
||||
sops
|
||||
rclone
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,660 @@
|
||||
# GNU Privacy Guard(GnuPG)
|
||||
|
||||
> Offical Website: https://www.gnupg.org/
|
||||
|
||||
The GNU Privacy Guard is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as **PGP**). GnuPG allows to encrypt and sign your data and communication, features a versatile key management system as well as access modules for all kind of public key directories.
|
||||
|
||||
> In the following content, we will use GPG to refer to GnuPG tool, and PGP to refer to various concepts defined in the OepnPGP standard(e.g. PGP key, PGP key server).
|
||||
|
||||
Key functions of GnuPG:
|
||||
|
||||
1. Keypair(keyring) management
|
||||
2. Sign and Verify your data
|
||||
3. Encrypt and Decrypt your data
|
||||
|
||||
Main usage scenarios of GnuPG:
|
||||
|
||||
1. Sign or encrypt your email
|
||||
1. Verify or decrypt the email you received
|
||||
2. Sign your git commit
|
||||
3. Manage your ssh key
|
||||
4. Encrypt your data and store it somewhere.
|
||||
|
||||
GnuPG/OpenPGP is complex, so while using it, I have been looking forward to finding an encryption tool that is simple enough, functional enough, and widely adopted.
|
||||
|
||||
Currently I use both age & GnuPG:
|
||||
|
||||
1. Age for secrets encryption(ssh key & other secret files), it's simple and easy to use.
|
||||
2. GnuPG for password-store and email encryption.
|
||||
|
||||
> At present, the safe and efficient use of GPG is probably combined with hardware keys such as yubikey. but I don't have one, so I won't talk about it here.
|
||||
|
||||
## Practical Cryptography for Developers
|
||||
|
||||
To use GnuGP without seamlessly, Some Practical Cryptography knowledge is required, here is dome tutorials:
|
||||
|
||||
- English version: <https://github.com/nakov/Practical-Cryptography-for-Developers-Book>
|
||||
- Chinese version: <https://thiscute.world/tags/cryptography/>
|
||||
|
||||
## Overview of GnuPG
|
||||
|
||||
> GnuPG's Official User Guides: <https://www.gnupg.org/documentation/guides.html>
|
||||
|
||||
> ArchWiki's GnuPG page: <https://wiki.archlinux.org/title/GnuPG>
|
||||
|
||||
### 0. How GnuGP generate & protect your keypair?
|
||||
|
||||
Related Docs:
|
||||
|
||||
- [2021年,用更现代的方法使用PGP(上)][2021年,用更现代的方法使用PGP(上)]
|
||||
- [Predictable, Passphrase-Derived PGP Keys][Predictable, Passphrase-Derived PGP Keys]
|
||||
- [OpenPGP - The almost perfect key pair][OpenPGP - The almost perfect key pair]
|
||||
|
||||
|
||||
GnuPG generate every secret key separately, and encrypt them with a symmetric key derived from your passphrase.
|
||||
OpenPGP standard defines [String-to-Key (S2K)](https://datatracker.ietf.org/doc/html/rfc4880#section-3.7)
|
||||
algorithm to derive a symmetric key from your passphrase.
|
||||
|
||||
GnuPG's [OpenPGP protocol specific options](https://gnupg.org/documentation/manuals/gnupg/OpenPGP-Options.html#OpenPGP-Options) shows that:
|
||||
|
||||
```
|
||||
--s2k-cipher-algo name
|
||||
|
||||
Use name as the cipher algorithm for symmetric encryption with a passphrase if --personal-cipher-preferences and --cipher-algo are not given. The default is AES-128.
|
||||
--s2k-digest-algo name
|
||||
|
||||
Use name as the digest algorithm used to mangle the passphrases for symmetric encryption. The default is SHA-1.
|
||||
--s2k-mode n
|
||||
|
||||
Selects how passphrases for symmetric encryption are mangled. If n is 0 a plain passphrase (which is in general not recommended) will be used, a 1 adds a salt (which should not be used) to the passphrase and a 3 (the default) iterates the whole process a number of times (see --s2k-count).
|
||||
--s2k-count n
|
||||
|
||||
Specify how many times the passphrases mangling for symmetric encryption is repeated. This value may range between 1024 and 65011712 inclusive. The default is inquired from gpg-agent. Note that not all values in the 1024-65011712 range are legal and if an illegal value is selected, GnuPG will round up to the nearest legal value. This option is only meaningful if --s2k-mode is set to the default of 3.
|
||||
```
|
||||
|
||||
The strongest options should be:
|
||||
|
||||
```
|
||||
gpg --s2k-mode 3 --s2k-count 65011712 --s2k-digest-algo SHA512 --s2k-cipher-algo AES256 ...
|
||||
```
|
||||
|
||||
To use the strongest options globally, you can specify these options in your `~/.gnupg/gpg.conf`.
|
||||
I've added them to my Home Manager's `programs.gpg.settings` option.
|
||||
|
||||
|
||||
### 1. PGP Key(Primary Key) generation
|
||||
|
||||
Key management is the core of OpenPGP standard / GnuPG.
|
||||
|
||||
GnuPG uses public-key cryptography so that users may communicate securely. In a public-key system, each user has a pair of keys consisting of a private key and a public key. **A user's private key is kept secret; it need **never be revealed. The public key may be given to anyone with whom the user wants to communicate**. GnuPG uses a somewhat more sophisticated scheme in which a user has a primary keypair and then zero or more additional subordinate keypairs. The primary and subordinate keypairs are bundled to facilitate key management and the bundle can often be considered simply as one keypair, or a keyring/keychain(which contains multiple sub key-pairs).
|
||||
|
||||
Let's generate a keypair interactively:
|
||||
|
||||
> Now in 2024, GnuPG 2.4.1 defaults to ECC algorithm (9) and Curve 25519 for ECC, which is morden and safe, I would recommend to use these defaults directly.
|
||||
|
||||
```bash
|
||||
gpg --full-gen-key
|
||||
```
|
||||
|
||||
This command will ask you for some algorithm related settings(ECC & Curve 25519), your personal info, and a strong passphrase to protect your PGP key. e.g.
|
||||
|
||||
``` bash
|
||||
› gpg --full-gen-key
|
||||
gpg (GnuPG) 2.4.1; Copyright (C) 2023 g10 Code GmbH
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
gpg: directory '/Users/ryan/.gnupg' created
|
||||
Please select what kind of key you want:
|
||||
(1) RSA and RSA
|
||||
(2) DSA and Elgamal
|
||||
(3) DSA (sign only)
|
||||
(4) RSA (sign only)
|
||||
(9) ECC (sign and encrypt) *default*
|
||||
(10) ECC (sign only)
|
||||
(14) Existing key from card
|
||||
Your selection? 9
|
||||
Please select which elliptic curve you want:
|
||||
(1) Curve 25519 *default*
|
||||
(4) NIST P-384
|
||||
(6) Brainpool P-256
|
||||
Your selection? 1
|
||||
Please specify how long the key should be valid.
|
||||
0 = key does not expire
|
||||
<n> = key expires in n days
|
||||
<n>w = key expires in n weeks
|
||||
<n>m = key expires in n months
|
||||
<n>y = key expires in n years
|
||||
Key is valid for? (0) 10y
|
||||
Key expires at 一 1/ 4 13:50:31 2044 CST
|
||||
Is this correct? (y/N) y
|
||||
|
||||
GnuPG needs to construct a user ID to identify your key.
|
||||
|
||||
Real name:
|
||||
Email address:
|
||||
Comment:
|
||||
You selected this USER-ID:
|
||||
"Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>"
|
||||
|
||||
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
|
||||
We need to generate a lot of random bytes. It is a good idea to perform
|
||||
some other action (type on the keyboard, move the mouse, utilize the
|
||||
disks) during the prime generation; this gives the random number
|
||||
generator a better chance to gain enough entropy.
|
||||
We need to generate a lot of random bytes. It is a good idea to perform
|
||||
some other action (type on the keyboard, move the mouse, utilize the
|
||||
disks) during the prime generation; this gives the random number
|
||||
generator a better chance to gain enough entropy.
|
||||
gpg: /Users/ryan/.gnupg/trustdb.gpg: trustdb created
|
||||
gpg: directory '/Users/ryan/.gnupg/openpgp-revocs.d' created
|
||||
gpg: revocation certificate stored as '/Users/ryan/.gnupg/openpgp-revocs.d/C8D84EBC5F82494F432ACEF042E49B284C30A0DA.rev'
|
||||
public and secret key created and signed.
|
||||
|
||||
pub ed25519 2024-01-09 [SC] [expires: 2034-01-04]
|
||||
C8D84EBC5F82494F432ACEF042E49B284C30A0DA
|
||||
uid Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||
sub cv25519 2024-01-09 [E] [expires: 2034-01-04]
|
||||
```
|
||||
|
||||
### 2. Configuration Files
|
||||
|
||||
> https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration.html
|
||||
|
||||
The generated keys are stored in `~/.gnupg` by default, the functions of each file are as follows:
|
||||
|
||||
``` bash
|
||||
› tree ~/.gnupg/
|
||||
/Users/ryan/.gnupg/
|
||||
|-- S.gpg-agent # socket file
|
||||
|-- S.gpg-agent.browser # socket file
|
||||
|-- S.gpg-agent.extra # socket file
|
||||
|-- S.gpg-agent.ssh # socket file
|
||||
|-- S.keyboxd # socket file
|
||||
|-- common.conf # config file
|
||||
|-- openpgp-revocs.d # Revocation certificates
|
||||
| `-- F680C6D7215674ADEA421CC5E22EC419FF93EA98.rev
|
||||
|-- private-keys-v1.d # private keys with user info & protect by passphrase
|
||||
| |-- 2083133619AB24DC32DA68F9FE83C58D375284E3.key
|
||||
| `-- 9350704F120643C504491E92CA97255223778C8A.key
|
||||
|-- public-keys.d # public keys
|
||||
| |-- pubring.db
|
||||
| `-- pubring.db.lock
|
||||
`-- trustdb.gpg # a trust database
|
||||
|
||||
4 directories, 12 files
|
||||
```
|
||||
|
||||
The functions of most files are quite clear at a glance, but the `trustdb.gpg` in them is a bit difficult to understand. Here are the details: <https://www.gnupg.org/gph/en/manual/x334.html>
|
||||
|
||||
Home Manager will manage all the things in `~/.gnupg/` EXCEPT `~/.gnupg/openpgp-revocs.d/` and `~/.gnupg/private-keys-v1.d/`, which is expected.
|
||||
|
||||
### 3. Sub Key Generation & Best Practice
|
||||
|
||||
In PGP, every keys has a **usage flag** to indicate its usage:
|
||||
|
||||
- `C` means this key can be used to **Certify** other keys, which means this key can be used to **create/delete/revoke/modify** other keys.
|
||||
- `S` means this key can be used to **Sign** data.
|
||||
- `E` means this key can be used to **Encrypt** data.
|
||||
- `A` means this key can be used to **Authenticate** data with various non-GnuPG programs. The key can be used as e.g. an **SSH key**.
|
||||
|
||||
The **best practice** is:
|
||||
|
||||
1. Generate a primary key with strong cryptography arguments(such as ECC + Curve 25519).
|
||||
2. Then generate 3 sub keys with `E`, `S` and `A` usage flag respectively.
|
||||
3. **The Primary Key is extremely important**, Backup the primary key to somewhere absolutely safe(such as two encryptd USB drivers, keep them in different places), and then **delete it from your computer immediately**.
|
||||
4. The sub key is also important, but you can generate a new one and replace it easily. You can backup it to somewhere else, and import it to another machine to use your keypair.
|
||||
5. Backup your Primary key's revocation certificate to somewhere safe, it's the last way to rescure your safety if your primary key is compromised!
|
||||
1. It's a big problem if your revocation certificate is compromised, but not the bigest one. because it's only used to revoke your keypair, your data is still safe. But you should generate a new keypair and revoke the old one immediately.
|
||||
1. It will be a big problem if your primary key is compromised, and you don't have a revocation certificate to revoke it. But since OpenPGP do not have a good way to distribute revocation certificate, even you have a revocation certificate, it's still hard to distribute it to others...
|
||||
|
||||
To keep your keypair safe, you should backup your keypair according to the following steps.
|
||||
|
||||
Now let's add the sub keys to the keypair we generated above:
|
||||
|
||||
> `E` sub key is already generated by default, so we only need to generate `S` and `A` sub keys.
|
||||
|
||||
> GnuPG will ask you to input your passphrase to unlock your primary key.
|
||||
|
||||
``` bash
|
||||
› gpg --expert --edit-key ryan4yin@linux.com
|
||||
gpg (GnuPG) 2.4.1; Copyright (C) 2023 g10 Code GmbH
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
Secret key is available.
|
||||
|
||||
sec ed25519/42E49B284C30A0DA
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/6CB4A81FFB3C99B6
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: E
|
||||
[ultimate] (1). Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||
|
||||
gpg> addkey
|
||||
Please select what kind of key you want:
|
||||
(3) DSA (sign only)
|
||||
(4) RSA (sign only)
|
||||
(5) Elgamal (encrypt only)
|
||||
(6) RSA (encrypt only)
|
||||
(7) DSA (set your own capabilities)
|
||||
(8) RSA (set your own capabilities)
|
||||
(10) ECC (sign only)
|
||||
(11) ECC (set your own capabilities)
|
||||
(12) ECC (encrypt only)
|
||||
(13) Existing key
|
||||
(14) Existing key from card
|
||||
Your selection? 10
|
||||
Please select which elliptic curve you want:
|
||||
(1) Curve 25519 *default*
|
||||
(2) Curve 448
|
||||
(3) NIST P-256
|
||||
(4) NIST P-384
|
||||
(5) NIST P-521
|
||||
(6) Brainpool P-256
|
||||
(7) Brainpool P-384
|
||||
(8) Brainpool P-512
|
||||
(9) secp256k1
|
||||
Your selection? 1
|
||||
Please specify how long the key should be valid.
|
||||
0 = key does not expire
|
||||
<n> = key expires in n days
|
||||
<n>w = key expires in n weeks
|
||||
<n>m = key expires in n months
|
||||
<n>y = key expires in n years
|
||||
Key is valid for? (0) 10y
|
||||
Key expires at Mon Jan 4 17:47:24 2044 CST
|
||||
Is this correct? (y/N) y
|
||||
Really create? (y/N) y
|
||||
We need to generate a lot of random bytes. It is a good idea to perform
|
||||
some other action (type on the keyboard, move the mouse, utilize the
|
||||
disks) during the prime generation; this gives the random number
|
||||
generator a better chance to gain enough entropy.
|
||||
|
||||
sec ed25519/42E49B284C30A0DA
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/6CB4A81FFB3C99B6
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: E
|
||||
ssb ed25519/A42813E03A10F504
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: S
|
||||
[ultimate] (1). Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||
|
||||
gpg> addkey
|
||||
Please select what kind of key you want:
|
||||
(3) DSA (sign only)
|
||||
(4) RSA (sign only)
|
||||
(5) Elgamal (encrypt only)
|
||||
(6) RSA (encrypt only)
|
||||
(7) DSA (set your own capabilities)
|
||||
(8) RSA (set your own capabilities)
|
||||
(10) ECC (sign only)
|
||||
(11) ECC (set your own capabilities)
|
||||
(12) ECC (encrypt only)
|
||||
(13) Existing key
|
||||
(14) Existing key from card
|
||||
Your selection? 11
|
||||
|
||||
Possible actions for this ECC key: Sign Authenticate
|
||||
Current allowed actions: Sign
|
||||
|
||||
(S) Toggle the sign capability
|
||||
(A) Toggle the authenticate capability
|
||||
(Q) Finished
|
||||
|
||||
Your selection? S
|
||||
|
||||
Possible actions for this ECC key: Sign Authenticate
|
||||
Current allowed actions:
|
||||
|
||||
(S) Toggle the sign capability
|
||||
(A) Toggle the authenticate capability
|
||||
(Q) Finished
|
||||
|
||||
Your selection? A
|
||||
|
||||
Possible actions for this ECC key: Sign Authenticate
|
||||
Current allowed actions: Authenticate
|
||||
|
||||
(S) Toggle the sign capability
|
||||
(A) Toggle the authenticate capability
|
||||
(Q) Finished
|
||||
|
||||
Your selection? Q
|
||||
Please select which elliptic curve you want:
|
||||
(1) Curve 25519 *default*
|
||||
(2) Curve 448
|
||||
(3) NIST P-256
|
||||
(4) NIST P-384
|
||||
(5) NIST P-521
|
||||
(6) Brainpool P-256
|
||||
(7) Brainpool P-384
|
||||
(8) Brainpool P-512
|
||||
(9) secp256k1
|
||||
Your selection? 1
|
||||
Please specify how long the key should be valid.
|
||||
0 = key does not expire
|
||||
<n> = key expires in n days
|
||||
<n>w = key expires in n weeks
|
||||
<n>m = key expires in n months
|
||||
<n>y = key expires in n years
|
||||
Key is valid for? (0) 10y
|
||||
Key expires at Mon Jan 4 17:48:27 2044 CST
|
||||
Is this correct? (y/N) y
|
||||
Really create? (y/N) y
|
||||
We need to generate a lot of random bytes. It is a good idea to perform
|
||||
some other action (type on the keyboard, move the mouse, utilize the
|
||||
disks) during the prime generation; this gives the random number
|
||||
generator a better chance to gain enough entropy.
|
||||
|
||||
sec ed25519/42E49B284C30A0DA
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/6CB4A81FFB3C99B6
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: E
|
||||
ssb ed25519/A42813E03A10F504
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: S
|
||||
ssb ed25519/5469C4FACC81B60F
|
||||
created: 2024-01-09 expires: 2034-01-04 usage: A
|
||||
[ultimate] (1). Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||
|
||||
gpg> save
|
||||
```
|
||||
|
||||
Check the secret keys and public keys we generated:
|
||||
|
||||
```bash
|
||||
› gpg --list-secret-keys --with-subkey-fingerprint
|
||||
[keyboxd]
|
||||
---------
|
||||
sec ed25519 2024-01-09 [SC] [expires: 2034-01-04]
|
||||
C8D84EBC5F82494F432ACEF042E49B284C30A0DA
|
||||
uid [ultimate] Ryan Yin (For pass For Work ssh only) <ryan4yin@linux.com>
|
||||
ssb cv25519 2024-01-09 [E] [expires: 2034-01-04]
|
||||
1146D48B93C2177C92D186026CB4A81FFB3C99B6
|
||||
ssb ed25519 2024-01-09 [S] [expires: 2034-01-04]
|
||||
DF64002A822948B17783BBB1A42813E03A10F504
|
||||
ssb ed25519 2024-01-09 [A] [expires: 2034-01-04]
|
||||
65E2C6C1C3559362ABB7047C5469C4FACC81B60F
|
||||
|
||||
› gpg --list-public-keys
|
||||
...
|
||||
```
|
||||
|
||||
### 4. Backup & Restore
|
||||
|
||||
Export Public Keys(Both Primary Key & Sub Keys):
|
||||
|
||||
```bash
|
||||
gpg --armor --export ryan4yin@linux.com > ryan4yin-gpg-keys.pub
|
||||
# check what we have exported, we should see 4 public keys
|
||||
nix run nixpkgs#pgpdump ryan4yin-gpg-keys.pub
|
||||
```
|
||||
|
||||
Export Primary Key(The exported key is still encrypted by your passphrase):
|
||||
|
||||
> the `!` at the end of the key ID is to force GnuPG to export only the specified key, not the subkeys.
|
||||
|
||||
> GnuPG will ask you to input your passphrase to unlock your keypair,
|
||||
> because GnuPG need to convert the secret key's format from its internal protection format to the one specified by the OpenPGP protocol.
|
||||
|
||||
```bash
|
||||
# replace the key ID with your own sec key's ID
|
||||
gpg --armor --export-secret-keys C8D84EBC5F82494F432ACEF042E49B284C30A0DA! > ryan4yin-primary-key.priv
|
||||
|
||||
# Check the exported primary key's detail info,
|
||||
nix run nixpkgs#pgpdump ryan4yin-primary-key.priv
|
||||
...
|
||||
Old: Secret Key Packet(tag 5)(134 bytes)
|
||||
Ver 4 - new
|
||||
Public key creation time - Sat Jan 27 14:13:13 CST 2024
|
||||
Pub alg - EdDSA Edwards-curve Digital Signature Algorithm(pub 22)
|
||||
Elliptic Curve - Ed25519 (0x2B 06 01 04 01 DA 47 0F 01)
|
||||
EdDSA Q(263 bits) - ...
|
||||
Sym alg - AES with 128-bit key(sym 7)
|
||||
Iterated and salted string-to-key(s2k 3):
|
||||
Hash alg - SHA1(hash 2)
|
||||
Salt - 8c 78 58 c0 87 83 8c 2c
|
||||
Count - 65011712(coded count 255)
|
||||
IV - xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
|
||||
Encrypted EdDSA x
|
||||
Encrypted SHA1 hash
|
||||
...
|
||||
```
|
||||
|
||||
As [Predictable, Passphrase-Derived PGP Keys][Predictable, Passphrase-Derived PGP Keys] says, we'll find that gpg ignored the `--s2k-count` option we specified when generating the keypair, and the `--s2k` related options we specified in `~/.gnupg/gpg.conf`,
|
||||
the exported primary key is protectd by `SHA1` and `AES128`, which is not secure enough!
|
||||
|
||||
So to increase the security of the exported primary key, we need to encrypt it again with a stronger algorithm, I choose `age` here(which use `scrypt` to encrypt the file key with a provided passphrase):
|
||||
|
||||
```bash
|
||||
# for simplicity, use the same passphrase as your gpg keypair here
|
||||
age --passphrase -o ryan4yin-primary-key.priv.age ryan4yin-primary-key.priv
|
||||
rm ryan4yin-primary-key.priv
|
||||
```
|
||||
|
||||
Export Sub Keys one by one(The exported keys is still encrypted by your passphrase):
|
||||
|
||||
```bash
|
||||
gpg --armor --export-secret-subkeys > ryan4yin-gpg-subkeys.priv
|
||||
|
||||
# Check the exported primary key's detail info,
|
||||
nix run nixpkgs#pgpdump ryan4yin-gpg-subkeys.priv
|
||||
|
||||
# encrypt it again with age(scrypt)
|
||||
age --passphrase -o ryan4yin-gpg-subkeys.priv.age ryan4yin-gpg-subkeys.priv
|
||||
rm ryan4yin-gpg-subkeys.priv
|
||||
```
|
||||
|
||||
Your can import the exported Private Key via `gpg --import <keyfile>` to restore it, but you need to decrypt it via age first.
|
||||
|
||||
As for Public Keys, please import your publicKeys via Home Manager's `programs.gpg.publicKeys` option, DO NOT import it manually(via `gpg --import <keyfile>`).
|
||||
|
||||
To ensure security, delete the master key and revoke the certificate immediately after the backup is completed:
|
||||
|
||||
```bash
|
||||
# delete the primary key and all its sub keys
|
||||
gpg --delete-secret-keys ryan4yin@linux.com
|
||||
|
||||
# delete the revocation certificate
|
||||
rm ~/.gnupg/openpgp-revocs.d/C8D84EBC5F82494F432ACEF042E49B284C30A0DA.rev
|
||||
|
||||
# import our subkeys back
|
||||
age --decrypt -o ryan4yin-primary-key.priv ryan4yin-primary-key.priv.age
|
||||
gpg --import ryan4yin-gpg-subkeys.priv
|
||||
```
|
||||
|
||||
Now check the secret keys and public keys again:
|
||||
|
||||
> A `#` at the end of the key ID means that the key is not available, because we have deleted it.
|
||||
|
||||
```bash
|
||||
› gpg --list-secret-keys --keyid-format=long
|
||||
/home/ryan/.gnupg/pubring.kbx
|
||||
-----------------------------
|
||||
sec# ed25519/D1C5FFA3118A41FC 2024-01-09 [SC] [expires: 2034-01-04]
|
||||
Key fingerprint = E267 943C 33AD C5AF 3D76 4D96 D1C5 FFA3 118A 41FC
|
||||
uid [ unknown] Ryan Yin (Personal) <ryan4yin@linux.com>
|
||||
ssb cv25519/62526A4A0CF43E33 2024-01-09 [E] [expires: 2034-01-04]
|
||||
ssb ed25519/433A66D63805BD1A 2024-01-09 [S] [expires: 2034-01-04]
|
||||
ssb ed25519/441E3D8FBD313BF2 2024-01-09 [A] [expires: 2034-01-04]
|
||||
|
||||
|
||||
› gpg --list-public-keys --keyid-format=long
|
||||
/home/ryan/.gnupg/pubring.kbx
|
||||
-----------------------------
|
||||
pub ed25519/D1C5FFA3118A41FC 2024-01-09 [SC] [expires: 2034-01-04]
|
||||
Key fingerprint = E267 943C 33AD C5AF 3D76 4D96 D1C5 FFA3 118A 41FC
|
||||
uid [ unknown] Ryan Yin (Personal) <ryan4yin@linux.com>
|
||||
sub cv25519/62526A4A0CF43E33 2024-01-09 [E] [expires: 2034-01-04]
|
||||
sub ed25519/433A66D63805BD1A 2024-01-09 [S] [expires: 2034-01-04]
|
||||
sub ed25519/441E3D8FBD313BF2 2024-01-09 [A] [expires: 2034-01-04]
|
||||
```
|
||||
|
||||
### 5. Signing & Verification
|
||||
|
||||
```bash
|
||||
# Make a cleartext signature.
|
||||
gpg --clearsign <file>
|
||||
|
||||
# Make a detached signature, with text output.
|
||||
gpg --armor --detach-sign <file>
|
||||
|
||||
# verify the file contains a valid signature.
|
||||
gpg --verify <file>
|
||||
|
||||
# verify the file with a detached signature.
|
||||
gpg --verify <file> <signature-file>
|
||||
```
|
||||
|
||||
### 6. Encryption & Decryption
|
||||
|
||||
```bash
|
||||
# Encrypt a file via recipient's public key, sign it via your private key for signing, and output cleartext.
|
||||
# so that the reciiptent can decrypt it via his/her private key.
|
||||
gpg --armor --sign --encrypt --recipient ryan4yin@linux.com <file>
|
||||
# or use this short version
|
||||
gpg -aser ryan4yin@linux.com <file>
|
||||
|
||||
# Descrypt a file via your private key, and verify the signature via the sender's public key.
|
||||
gpg --decrypt <file>
|
||||
# or
|
||||
gpg -d <file>
|
||||
```
|
||||
|
||||
If you just want to encrypt/decrypt a file quickly, you can use `age` with a passphrase, `gpg` can also do this, but it's not recommended(as age(scrypt)'s more secure):
|
||||
|
||||
```bash
|
||||
# Encrypt a file via symmetric encryption(AES256), and output cleartext.
|
||||
gpg --armor --symmetric --cipher-algo AES256 <file>
|
||||
# or
|
||||
gpg -ac <file>
|
||||
|
||||
# Decrypt a file via symmetric encryption.
|
||||
gpg --decrypt <file>
|
||||
# or
|
||||
gpg -d <file>
|
||||
```
|
||||
|
||||
### 7. Public Key Exchange & Revocation
|
||||
|
||||
In the case of many users, it is very difficult to exchange public keys securely and reliably with each other.
|
||||
In the Web world, There is a **Chain of Trust**** to resolve this problem:
|
||||
|
||||
- A Certificate Authority(CA) is responsible to verify & sign all the certificate signing request.
|
||||
- Web Server can safely transmit its Web Certificate to the client via TLS protocol.
|
||||
- Client can verify the recevied Web Certificate via the CA's root certificate(which is built in Browser/OS).
|
||||
|
||||
But in OpenPGP:
|
||||
|
||||
- There is key servers to distribute(exchange) public keys, but it **do not verify the identity of the key owner**, and any uploaded data is **not allowed to be deleted**. Which make it **insecure and dangerous**.
|
||||
- Why key server is dangerous?
|
||||
- Many PGP novices follow various tutorials to upload various key with personal privacy (such as real names) to the public key server, and then find that they can't delete them, which is very embarrassing.
|
||||
- Anyone can upload a key to the key server, and claim that it is the key of a certain person(such as Linus), which is very insecure.
|
||||
- **key server** is not recommend to use.
|
||||
- GnuPG will generate revocation certificate when generating keypair(`~/.gnupg/private-keys-v1.d/<Key-ID.rev>`), anyone can import this certificate to revoke the keypair. But OpenPGP standard **DO NOT provide a way to distribute this certificate to others**.
|
||||
- Not to mention some key status query protocol like OCSP in Web PKI.
|
||||
- Users has to pulish their revocation certificate to their blog, github profile or somewhere else, and others has to check it and run `gpg --import <revocation-certificate>` to revoke the keypair manually.
|
||||
|
||||
In summary, **there is no good way to distribute public keys and revoke them in OpenPGP**, which is a big problem.
|
||||
|
||||
Currently, You have to distribute your public key or revocation certificate via your blog, github profile, or somewhere else, and others has to check it and run `gpg --import` to import your public key or revocation certificate manually.
|
||||
|
||||
Anyway, let's try to revoke a keypair:
|
||||
|
||||
```bash
|
||||
› gpg --list-keys
|
||||
gpg: checking the trustdb
|
||||
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
|
||||
/home/ryan/.gnupg/pubring.kbx
|
||||
-----------------------------
|
||||
pub ed25519/0x55859965C2742B4B 2024-01-09 [SC]
|
||||
Key fingerprint = A2CD 07BD 9631 44CB 2725 5A6B 5585 9965 C274 2B4B
|
||||
uid [ultimate] test <test@test.t>
|
||||
sub cv25519/0x9E78E897B6490D6B 2024-01-09 [E]
|
||||
|
||||
# encrypt some file before revoke the keypair
|
||||
› gpg -aer test@test.t README.md > README.md.asc
|
||||
|
||||
# try to decrypt the file, it should works
|
||||
› gpg -d README.md.asc
|
||||
gpg: encrypted with cv25519 key, ID 0x9E78E897B6490D6B, created 2024-01-09
|
||||
"test <test@test.t>"
|
||||
# ......
|
||||
|
||||
# take a look at the revocation certificate
|
||||
› cat gpg-test-revoke.rev
|
||||
This is a revocation certificate for the OpenPGP key:
|
||||
|
||||
pub ed25519/0x55859965C2742B4B 2024-01-09 [S]
|
||||
Key fingerprint = A2CD 07BD 9631 44CB 2725 5A6B 5585 9965 C274 2B4B
|
||||
uid test <test@test.t>
|
||||
|
||||
A revocation certificate is a kind of "kill switch" to publicly
|
||||
declare that a key shall not anymore be used. It is not possible
|
||||
to retract such a revocation certificate once it has been published.
|
||||
|
||||
Use it to revoke this key in case of a compromise or loss of
|
||||
the secret key. However, if the secret key is still accessible,
|
||||
it is better to generate a new revocation certificate and give
|
||||
a reason for the revocation. For details see the description of
|
||||
of the gpg command "--generate-revocation" in the GnuPG manual.
|
||||
|
||||
To avoid an accidental use of this file, a colon has been inserted
|
||||
before the 5 dashes below. Remove this colon with a text editor
|
||||
before importing and publishing this revocation certificate.
|
||||
|
||||
:-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Comment: This is a revocation certificate
|
||||
|
||||
iHgEIBYKACAWIQSizQe9ljFEyyclWmtVhZllwnQrSwUCZZ1T9wIdAAAKCRBVhZll
|
||||
wnQrS2LVAQCegRF1qPqY/OCS5QCz8G0ra0XgPYlQYo9pSOjHgfY39AD+Psin2/6t
|
||||
STuJCp+gru6OtbTCu8Y2LugQeDh7UicM7Ak=
|
||||
=Xfs6
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
||||
|
||||
As the revocation certificate says, we need to remove the first colon(`:`) before the 5 dashes(`-----BEGIN PGP PUBLIC KEY BLOCK-----`), then import it:
|
||||
|
||||
```bash
|
||||
› gpg --import gpg-test-revoke.rev
|
||||
gpg: key 0x55859965C2742B4B: "test <test@test.t>" revocation certificate imported
|
||||
gpg: Total number processed: 1
|
||||
gpg: new key revocations: 1
|
||||
gpg: no ultimately trusted keys found
|
||||
|
||||
› gpg --list-secret-keys --keyid-format=long
|
||||
/home/ryan/.gnupg/pubring.kbx
|
||||
-----------------------------
|
||||
sec ed25519/55859965C2742B4B 2024-01-09 [SC] [revoked: 2024-01-09]
|
||||
Key fingerprint = A2CD 07BD 9631 44CB 2725 5A6B 5585 9965 C274 2B4B
|
||||
uid [ revoked] test <test@test.t>
|
||||
|
||||
|
||||
# try to decrypt the file, it still works, but will indicate that the key is revoked.
|
||||
› gpg -d README.md.asc
|
||||
gpg: encrypted with cv25519 key, ID 0x9E78E897B6490D6B, created 2024-01-09
|
||||
"test <test@test.t>"
|
||||
gpg: Note: key has been revoked
|
||||
gpg: reason for revocation: No reason specified
|
||||
# ......
|
||||
|
||||
# try to encrypt some file via the revoked key, it will fail.
|
||||
› gpg -aer 9E78E897B6490D6B README.md
|
||||
gpg: 9E78E897B6490D6B: skipped: Unusable public key
|
||||
gpg: README.md: encryption failed: Unusable public key
|
||||
```
|
||||
|
||||
But if you delete the `trustdb.gpg` and `pubring.kbx`, then import the revoked public key again, it will be valid and usable again... which is very dangerous.
|
||||
|
||||
## References
|
||||
|
||||
- [2021年,用更现代的方法使用PGP(上)][2021年,用更现代的方法使用PGP(上)]
|
||||
- [Predictable, Passphrase-Derived PGP Keys][Predictable, Passphrase-Derived PGP Keys]
|
||||
- [OpenPGP - The almost perfect key pair][OpenPGP - The almost perfect key pair]
|
||||
|
||||
[2021年,用更现代的方法使用PGP(上)]: https://ulyc.github.io/2021/01/13/2021%E5%B9%B4-%E7%94%A8%E6%9B%B4%E7%8E%B0%E4%BB%A3%E7%9A%84%E6%96%B9%E6%B3%95%E4%BD%BF%E7%94%A8PGP-%E4%B8%8A/
|
||||
[Predictable, Passphrase-Derived PGP Keys]: https://nullprogram.com/blog/2019/07/10/
|
||||
[OpenPGP - The almost perfect key pair]: https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1/
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
config,
|
||||
mysecrets,
|
||||
...
|
||||
}: {
|
||||
programs.gpg = {
|
||||
enable = true;
|
||||
homedir = "${config.home.homeDirectory}/.gnupg";
|
||||
# $GNUPGHOME/trustdb.gpg stores all the trust level you specified in `programs.gpg.publicKeys` option.
|
||||
#
|
||||
# If set `mutableTrust` to false, the path $GNUPGHOME/trustdb.gpg will be overwritten on each activation.
|
||||
# Thus we can only update trsutedb.gpg via home-manager.
|
||||
mutableTrust = false;
|
||||
|
||||
# $GNUPGHOME/pubring.kbx stores all the public keys you specified in `programs.gpg.publicKeys` option.
|
||||
#
|
||||
# If set `mutableKeys` to false, the path $GNUPGHOME/pubring.kbx will become an immutable link to the Nix store, denying modifications.
|
||||
# Thus we can only update pubring.kbx via home-manager
|
||||
mutableKeys = false;
|
||||
publicKeys = [
|
||||
# https://www.gnupg.org/gph/en/manual/x334.html
|
||||
{
|
||||
source = "${mysecrets}/public/ryan4yin-gpg-keys-2014-01-27.pub";
|
||||
trust = 5;
|
||||
} # ultimate trust, my own keys.
|
||||
];
|
||||
|
||||
# This configuration is based on the tutorial below, it allows for a robust setup
|
||||
# https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1
|
||||
# ~/.gnupg/gpg.conf
|
||||
settings = {
|
||||
# Get rid of the copyright notice
|
||||
no-greeting = true;
|
||||
|
||||
# Disable inclusion of the version string in ASCII armored output
|
||||
no-emit-version = true;
|
||||
# Do not write comment packets
|
||||
no-comments = false;
|
||||
# Export the smallest key possible
|
||||
# This removes all signatures except the most recent self-signature on each user ID
|
||||
export-options = "export-minimal";
|
||||
|
||||
# Display long key IDs
|
||||
keyid-format = "0xlong";
|
||||
# List all keys (or the specified ones) along with their fingerprints
|
||||
with-fingerprint = true;
|
||||
|
||||
# Display the calculated validity of user IDs during key listings
|
||||
list-options = "show-uid-validity";
|
||||
verify-options = "show-uid-validity show-keyserver-urls";
|
||||
|
||||
# Select the strongest cipher
|
||||
personal-cipher-preferences = "AES256";
|
||||
# Select the strongest digest
|
||||
personal-digest-preferences = "SHA512";
|
||||
# This preference list is used for new keys and becomes the default for "setpref" in the edit menu
|
||||
default-preference-list = "SHA512 SHA384 SHA256 RIPEMD160 AES256 TWOFISH BLOWFISH ZLIB BZIP2 ZIP Uncompressed";
|
||||
|
||||
# Use the strongest cipher algorithm
|
||||
cipher-algo = "AES256";
|
||||
# Use the strongest digest algorithm
|
||||
digest-algo = "SHA512";
|
||||
# Message digest algorithm used when signing a key
|
||||
cert-digest-algo = "SHA512";
|
||||
# Use RFC-1950 ZLIB compression
|
||||
compress-algo = "ZLIB";
|
||||
|
||||
# Disable weak algorithm
|
||||
disable-cipher-algo = "3DES";
|
||||
# Treat the specified digest algorithm as weak
|
||||
weak-digest = "SHA1";
|
||||
|
||||
# The cipher algorithm for symmetric encryption for symmetric encryption with a passphrase
|
||||
s2k-cipher-algo = "AES256";
|
||||
# The digest algorithm used to mangle the passphrases for symmetric encryption
|
||||
s2k-digest-algo = "SHA512";
|
||||
# Selects how passphrases for symmetric encryption are mangled
|
||||
s2k-mode = "3";
|
||||
# Specify how many times the passphrases mangling for symmetric encryption is repeated
|
||||
s2k-count = "65011712";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
# Password Manager
|
||||
|
||||
- https://www.passwordstore.org/
|
||||
- [awesome-password-store](https://github.com/tijn/awesome-password-store)
|
||||
- <https://github.com/gopasspw/gopass>: reimplement in go, with more features.
|
||||
- Clients
|
||||
- Android: <https://github.com/android-password-store/Android-Password-Store>
|
||||
- Brosers(Chrome/Firefox): <https://github.com/browserpass/browserpass-extension>
|
||||
|
||||
## How to change the gpg key of the pass password store?
|
||||
|
||||
To ensure security, we should change the GPG key every two or three years. Here is how to do this.
|
||||
|
||||
1. Create a new GPG key pair and backup it to a safe place.
|
||||
2. Ensure you can access both the old and new GPG keys.
|
||||
3. Update `./default.nix` to use the new GPG sub keys.
|
||||
4. Check which Key `pass` currently uses:
|
||||
|
||||
```bash
|
||||
cd ~/.local/share/password-store/
|
||||
# check which key is used by pass
|
||||
cat .gpg-id
|
||||
# check which key is really used to encrypt the password
|
||||
gpg --list-packets path/to/any/password.gpg
|
||||
```
|
||||
4. Change the key used by `pass`:
|
||||
```bash
|
||||
# change the key used by pass, see `man pass` for more details
|
||||
# you will be asked to enter the password of both the new and old keys
|
||||
# then pass will re-encrypt all the passwords with the new key
|
||||
pass init <new-key-id>
|
||||
```
|
||||
5. Check if the key is changed:
|
||||
```bash
|
||||
# check which key is used by pass
|
||||
cat .gpg-id
|
||||
# check which key is really used to encrypt the password
|
||||
gpg --list-packets path/to/any/password.gpg
|
||||
```
|
||||
6. Delete the old GPG key pair:
|
||||
```bash
|
||||
# delete the old key pair
|
||||
gpg --delete-secret-keys <old-key-id>
|
||||
gpg --delete-keys <old-key-id>
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
passwordStoreDir = "${config.xdg.dataHome}/password-store";
|
||||
in {
|
||||
programs.password-store = {
|
||||
enable = true;
|
||||
package = pkgs.pass.withExtensions (exts: [
|
||||
# support for one-time-password (OTP) tokens
|
||||
# NOTE: Saving the password and OTP together runs counter to the purpose of secondary verification!
|
||||
# exts.pass-otp
|
||||
|
||||
exts.pass-import # a generic importer tool from other password managers
|
||||
exts.pass-update # an easy flow for updating passwords
|
||||
]);
|
||||
# See the “Environment variables” section of pass(1) and the extension man pages for more information about the available keys.
|
||||
settings = {
|
||||
PASSWORD_STORE_DIR = passwordStoreDir;
|
||||
# Overrides the default gpg key identification set by init.
|
||||
# Hexadecimal key signature is recommended.
|
||||
# Multiple keys may be specified separated by spaces.
|
||||
PASSWORD_STORE_KEY = lib.strings.concatStringsSep " " [
|
||||
"EF824EB73CFD6CC7" # E - Ryan Yin (For pass & ssh only) <ryan4yin@linux.com>
|
||||
];
|
||||
# all .gpg-id files and non-system extension files must be signed using a detached signature using the GPG key specified by
|
||||
# the full 40 character upper-case fingerprint in this variable.
|
||||
# If multiple fingerprints are specified, each separated by a whitespace character, then signatures must match at least one.
|
||||
# The init command will keep signatures of .gpg-id files up to date.
|
||||
PASSWORD_STORE_SIGNING_KEY = lib.strings.concatStringsSep " " [
|
||||
"C2A313F98166C942" # S - Ryan Yin (For pass & ssh only) <ryan4yin@linux.com>
|
||||
];
|
||||
PASSWORD_STORE_CLIP_TIME = "60";
|
||||
PASSWORD_STORE_GENERATED_LENGTH = "15";
|
||||
PASSWORD_STORE_ENABLE_EXTENSIONS = "true";
|
||||
};
|
||||
};
|
||||
|
||||
# password-store extensions for browsers
|
||||
# you need to install the browser extension for this to work
|
||||
# https://github.com/browserpass/browserpass-extension
|
||||
programs.browserpass = {
|
||||
enable = true;
|
||||
browsers = [
|
||||
"chrome"
|
||||
"chromium"
|
||||
"firefox"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{pkgs-unstable, ...}: let
|
||||
nu_scripts = pkgs-unstable.nu_scripts;
|
||||
inherit (pkgs-unstable) nu_scripts;
|
||||
in {
|
||||
programs.bash = {
|
||||
# load the alias file for work
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
|
||||
# all my ssh private key are generated by `ssh-keygen -t ed25519 -C "ryan@nickname"`
|
||||
# the config's format:
|
||||
# All my ssh private key are generated by `ssh-keygen -t ed25519 -a 256 -C "xxx@xxx"`
|
||||
# Config format:
|
||||
# Host — given the pattern used to match against the host name given on the command line.
|
||||
# HostName — specify nickname or abbreviation for host
|
||||
# IdentityFile — the location of your SSH key authentication file for the account.
|
||||
# format in details:
|
||||
# Format in details:
|
||||
# https://www.ssh.com/academy/ssh/config
|
||||
extraConfig = ''
|
||||
# a private key that is used during authentication will be added to ssh-agent if it is running
|
||||
@@ -36,18 +36,6 @@
|
||||
Host s500plus
|
||||
HostName 192.168.5.174
|
||||
Port 22
|
||||
|
||||
Host k8s-main
|
||||
HostName 192.168.5.181
|
||||
ForwardAgent yes
|
||||
|
||||
Host k8s-data1
|
||||
HostName 192.168.5.182
|
||||
ForwardAgent yes
|
||||
|
||||
Host k8s-data2
|
||||
HostName 192.168.5.183
|
||||
ForwardAgent yes
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,93 +18,88 @@
|
||||
# we can add wezterm as a flake input once this PR is merged:
|
||||
# https://github.com/wez/wezterm/pull/3547
|
||||
|
||||
programs.wezterm =
|
||||
{
|
||||
enable = false; # disable
|
||||
programs.wezterm = {
|
||||
enable = true; # disable
|
||||
|
||||
# TODO: Fix: https://github.com/wez/wezterm/issues/4483
|
||||
# package = pkgs.wezterm.override { };
|
||||
# install wezterm via homebrew on macOS to avoid compilation, dummy package here.
|
||||
package =
|
||||
if pkgs.stdenv.isLinux
|
||||
then pkgs.wezterm
|
||||
else pkgs.hello;
|
||||
|
||||
extraConfig = let
|
||||
fontsize =
|
||||
if pkgs.stdenv.isDarwin
|
||||
then "14.0"
|
||||
else "13.0";
|
||||
in ''
|
||||
-- Pull in the wezterm API
|
||||
local wezterm = require 'wezterm'
|
||||
enableBashIntegration = pkgs.stdenv.isLinux;
|
||||
enableZshIntegration = pkgs.stdenv.isLinux;
|
||||
|
||||
-- This table will hold the configuration.
|
||||
local config = {}
|
||||
extraConfig = let
|
||||
fontsize =
|
||||
if pkgs.stdenv.isLinux
|
||||
then "13.0"
|
||||
else "14.0";
|
||||
in ''
|
||||
-- Pull in the wezterm API
|
||||
local wezterm = require 'wezterm'
|
||||
|
||||
-- In newer versions of wezterm, use the config_builder which will
|
||||
-- help provide clearer error messages
|
||||
if wezterm.config_builder then
|
||||
config = wezterm.config_builder()
|
||||
-- This table will hold the configuration.
|
||||
local config = {}
|
||||
|
||||
-- In newer versions of wezterm, use the config_builder which will
|
||||
-- help provide clearer error messages
|
||||
if wezterm.config_builder then
|
||||
config = wezterm.config_builder()
|
||||
end
|
||||
|
||||
wezterm.on('toggle-opacity', function(window, pane)
|
||||
local overrides = window:get_config_overrides() or {}
|
||||
if not overrides.window_background_opacity then
|
||||
overrides.window_background_opacity = 0.93
|
||||
else
|
||||
overrides.window_background_opacity = nil
|
||||
end
|
||||
window:set_config_overrides(overrides)
|
||||
end)
|
||||
|
||||
wezterm.on('toggle-opacity', function(window, pane)
|
||||
local overrides = window:get_config_overrides() or {}
|
||||
if not overrides.window_background_opacity then
|
||||
overrides.window_background_opacity = 0.93
|
||||
else
|
||||
overrides.window_background_opacity = nil
|
||||
end
|
||||
window:set_config_overrides(overrides)
|
||||
end)
|
||||
wezterm.on('toggle-maximize', function(window, pane)
|
||||
window:maximize()
|
||||
end)
|
||||
|
||||
wezterm.on('toggle-maximize', function(window, pane)
|
||||
window:maximize()
|
||||
end)
|
||||
-- This is where you actually apply your config choices
|
||||
config.color_scheme = "Catppuccin Mocha"
|
||||
config.font = wezterm.font_with_fallback {
|
||||
"JetBrainsMono Nerd Font",
|
||||
"FiraCode Nerd Font",
|
||||
|
||||
-- This is where you actually apply your config choices
|
||||
config.color_scheme = "Catppuccin Mocha"
|
||||
config.font = wezterm.font_with_fallback {
|
||||
"JetBrainsMono Nerd Font",
|
||||
"FiraCode Nerd Font",
|
||||
|
||||
-- To avoid 'Chinese characters displayed as variant (Japanese) glyphs'
|
||||
"Source Han Sans SC",
|
||||
"Source Han Sans TC"
|
||||
}
|
||||
|
||||
config.hide_tab_bar_if_only_one_tab = true
|
||||
config.scrollback_lines = 10000
|
||||
config.enable_scroll_bar = true
|
||||
config.term = 'wezterm'
|
||||
|
||||
config.keys = {
|
||||
-- toggle opacity(CTRL + SHIFT + B)
|
||||
{
|
||||
key = 'B',
|
||||
mods = 'CTRL',
|
||||
action = wezterm.action.EmitEvent 'toggle-opacity',
|
||||
},
|
||||
{
|
||||
key = 'M',
|
||||
mods = 'CTRL',
|
||||
action = wezterm.action.EmitEvent 'toggle-maximize',
|
||||
},
|
||||
}
|
||||
config.font_size = ${fontsize}
|
||||
|
||||
-- To resolve issues:
|
||||
-- 1. https://github.com/ryan4yin/nix-config/issues/26
|
||||
-- 2. https://github.com/ryan4yin/nix-config/issues/8
|
||||
-- Spawn a nushell in login mode via `bash`
|
||||
config.default_prog = { '${pkgs.bash}/bin/bash', '--login', '-c', 'nu --login --interactive' }
|
||||
|
||||
return config
|
||||
'';
|
||||
}
|
||||
// (
|
||||
if pkgs.stdenv.isDarwin
|
||||
then {
|
||||
# install wezterm via homebrew on macOS to avoid compilation, dummy package here.
|
||||
# package = pkgs.hello;
|
||||
enableBashIntegration = false;
|
||||
enableZshIntegration = false;
|
||||
-- To avoid 'Chinese characters displayed as variant (Japanese) glyphs'
|
||||
"Source Han Sans SC",
|
||||
"Source Han Sans TC"
|
||||
}
|
||||
else {}
|
||||
);
|
||||
|
||||
config.hide_tab_bar_if_only_one_tab = true
|
||||
config.scrollback_lines = 10000
|
||||
config.enable_scroll_bar = true
|
||||
config.term = 'wezterm'
|
||||
|
||||
config.keys = {
|
||||
-- toggle opacity(CTRL + SHIFT + B)
|
||||
{
|
||||
key = 'B',
|
||||
mods = 'CTRL',
|
||||
action = wezterm.action.EmitEvent 'toggle-opacity',
|
||||
},
|
||||
{
|
||||
key = 'M',
|
||||
mods = 'CTRL',
|
||||
action = wezterm.action.EmitEvent 'toggle-maximize',
|
||||
},
|
||||
}
|
||||
config.font_size = ${fontsize}
|
||||
|
||||
-- To resolve issues:
|
||||
-- 1. https://github.com/ryan4yin/nix-config/issues/26
|
||||
-- 2. https://github.com/ryan4yin/nix-config/issues/8
|
||||
-- Spawn a nushell in login mode via `bash`
|
||||
config.default_prog = { '${pkgs.bash}/bin/bash', '--login', '-c', 'nu --login --interactive' }
|
||||
|
||||
return config
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ in {
|
||||
# auto start zellij in nushell
|
||||
programs.nushell.extraConfig = ''
|
||||
# auto start zellij
|
||||
if not "ZELLIJ" in $env {
|
||||
# except when in emacs or zellij itself
|
||||
if (not ("ZELLIJ" in $env)) and (not ("INSIDE_EMACS" in $env)) {
|
||||
if "ZELLIJ_AUTO_ATTACH" in $env and $env.ZELLIJ_AUTO_ATTACH == "true" {
|
||||
^zellij attach -c
|
||||
} else {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
nur-ryan4yin,
|
||||
...
|
||||
}: {
|
||||
# a cat(1) clone with syntax highlighting and Git integration.
|
||||
programs.bat = {
|
||||
enable = true;
|
||||
config = {
|
||||
pager = "less -FR";
|
||||
theme = "catppuccin-mocha";
|
||||
};
|
||||
themes = {
|
||||
# https://raw.githubusercontent.com/catppuccin/bat/main/Catppuccin-mocha.tmTheme
|
||||
catppuccin-mocha = {
|
||||
src = nur-ryan4yin.packages.${pkgs.system}.catppuccin-bat;
|
||||
file = "Catppuccin-mocha.tmTheme";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,17 +1,32 @@
|
||||
{
|
||||
pkgs,
|
||||
pkgs-unstable,
|
||||
nur-ryan4yin,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs; [
|
||||
skopeo
|
||||
docker-compose
|
||||
dive # explore docker layers
|
||||
lazydocker # Docker terminal UI.
|
||||
|
||||
kubectl
|
||||
istioctl
|
||||
kubevirt # virtctl
|
||||
kubernetes-helm
|
||||
fluxcd
|
||||
argocd
|
||||
];
|
||||
|
||||
programs = {
|
||||
k9s = {
|
||||
enable = true;
|
||||
skin = let
|
||||
# https://k9scli.io/topics/aliases/
|
||||
# aliases = {};
|
||||
settings = {
|
||||
skin = "catppuccino-mocha";
|
||||
};
|
||||
skins.catppuccin-mocha = let
|
||||
skin_file = "${nur-ryan4yin.packages.${pkgs.system}.catppuccin-k9s}/dist/mocha.yml"; # theme - catppuccin mocha
|
||||
skin_attr = builtins.fromJSON (
|
||||
builtins.readFile
|
||||
+100
-55
@@ -1,61 +1,62 @@
|
||||
{pkgs, ...}: {
|
||||
home.packages = with pkgs; [
|
||||
neofetch
|
||||
{
|
||||
pkgs,
|
||||
attic,
|
||||
nur-ryan4yin,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs;
|
||||
[
|
||||
# Misc
|
||||
tldr
|
||||
cowsay
|
||||
gnupg
|
||||
gnumake
|
||||
|
||||
# archives
|
||||
zip
|
||||
xz
|
||||
unzip
|
||||
p7zip
|
||||
# Morden cli tools, replacement of grep/sed/...
|
||||
|
||||
# networking tools
|
||||
mtr # A network diagnostic tool
|
||||
iperf3
|
||||
dnsutils # `dig` + `nslookup`
|
||||
ldns # replacement of `dig`, it provide the command `drill`
|
||||
aria2 # A lightweight multi-protocol & multi-source command-line download utility
|
||||
socat # replacement of openbsd-netcat
|
||||
nmap # A utility for network discovery and security auditing
|
||||
ipcalc # it is a calculator for the IPv4/v6 addresses
|
||||
# Interactively filter its input using fuzzy searching, not limit to filenames.
|
||||
fzf
|
||||
# search for files by name, faster than find
|
||||
fd
|
||||
# search for files by its content, replacement of grep
|
||||
(ripgrep.override {withPCRE2 = true;})
|
||||
|
||||
# Text Processing
|
||||
# Docs: https://github.com/learnbyexample/Command-line-text-processing
|
||||
gnugrep # GNU grep, provides `grep`/`egrep`/`fgrep`
|
||||
gnused # GNU sed, very powerful(mainly for replacing text in files)
|
||||
gnumake
|
||||
just # a command runner like make, but simpler
|
||||
gawk # GNU awk, a pattern scanning and processing language
|
||||
sad # CLI search and replace, with diff preview, really useful!!!
|
||||
delta # A viewer for git and diff output
|
||||
# A fast and polyglot tool for code searching, linting, rewriting at large scale
|
||||
# supported languages: only some mainstream languages currently(do not support nix/nginx/yaml/toml/...)
|
||||
ast-grep
|
||||
jq # A lightweight and flexible command-line JSON processor
|
||||
yq-go # yaml processer https://github.com/mikefarah/yq
|
||||
# A fast and polyglot tool for code searching, linting, rewriting at large scale
|
||||
# supported languages: only some mainstream languages currently(do not support nix/nginx/yaml/toml/...)
|
||||
ast-grep
|
||||
|
||||
# misc
|
||||
tldr
|
||||
cowsay
|
||||
file
|
||||
which
|
||||
tree
|
||||
gnutar
|
||||
zstd
|
||||
caddy
|
||||
gnupg
|
||||
rsync
|
||||
sad # CLI search and replace, just like sed, but with diff preview.
|
||||
yq-go # yaml processer https://github.com/mikefarah/yq
|
||||
just # a command runner like make, but simpler
|
||||
delta # A viewer for git and diff output
|
||||
lazygit # Git terminal UI.
|
||||
hyperfine # command-line benchmarking tool
|
||||
gping # ping, but with a graph(TUI)
|
||||
doggo # DNS client for humans
|
||||
duf # Disk Usage/Free Utility - a better 'df' alternative
|
||||
du-dust # A more intuitive version of `du` in rust
|
||||
ncdu # analyzer your disk usage Interactively, via TUI(replacement of `du`)
|
||||
gdu # disk usage analyzer(replacement of `du`)
|
||||
|
||||
# nix related
|
||||
#
|
||||
# it provides the command `nom` works just like `nix
|
||||
# with more details log output
|
||||
nix-output-monitor
|
||||
nodePackages.node2nix
|
||||
# nix related
|
||||
#
|
||||
# it provides the command `nom` works just like `nix
|
||||
# with more details log output
|
||||
nix-output-monitor
|
||||
hydra-check # check hydra(nix's build farm) for the build status of a package
|
||||
nix-index # A small utility to index nix store paths
|
||||
nix-init # generate nix derivation from url
|
||||
# https://github.com/nix-community/nix-melt
|
||||
nix-melt # A TUI flake.lock viewer
|
||||
# https://github.com/utdemir/nix-tree
|
||||
nix-tree # A TUI to visualize the dependency graph of a nix derivation
|
||||
|
||||
# productivity
|
||||
hugo # static site generator
|
||||
glow # markdown previewer in terminal
|
||||
];
|
||||
# productivity
|
||||
caddy # A webserver with automatic HTTPS via Let's Encrypt(replacement of nginx)
|
||||
croc # File transfer between computers securely and easily
|
||||
]
|
||||
# self-hosted nix cache server
|
||||
++ lib.optionals pkgs.stdenv.isLinux [attic.packages.${pkgs.system}.attic-client];
|
||||
|
||||
programs = {
|
||||
# A modern replacement for ‘ls’
|
||||
@@ -67,6 +68,22 @@
|
||||
icons = true;
|
||||
};
|
||||
|
||||
# a cat(1) clone with syntax highlighting and Git integration.
|
||||
bat = {
|
||||
enable = true;
|
||||
config = {
|
||||
pager = "less -FR";
|
||||
theme = "catppuccin-mocha";
|
||||
};
|
||||
themes = {
|
||||
# https://raw.githubusercontent.com/catppuccin/bat/main/Catppuccin-mocha.tmTheme
|
||||
catppuccin-mocha = {
|
||||
src = nur-ryan4yin.packages.${pkgs.system}.catppuccin-bat;
|
||||
file = "Catppuccin-mocha.tmTheme";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# A command-line fuzzy finder
|
||||
fzf = {
|
||||
enable = true;
|
||||
@@ -88,11 +105,39 @@
|
||||
};
|
||||
};
|
||||
|
||||
# skim provides a single executable: sk.
|
||||
# Basically anywhere you would want to use grep, try sk instead.
|
||||
skim = {
|
||||
# zoxide is a smarter cd command, inspired by z and autojump.
|
||||
# It remembers which directories you use most frequently,
|
||||
# so you can "jump" to them in just a few keystrokes.
|
||||
# zoxide works on all major shells.
|
||||
#
|
||||
# z foo # cd into highest ranked directory matching foo
|
||||
# z foo bar # cd into highest ranked directory matching foo and bar
|
||||
# z foo / # cd into a subdirectory starting with foo
|
||||
#
|
||||
# z ~/foo # z also works like a regular cd command
|
||||
# z foo/ # cd into relative path
|
||||
# z .. # cd one level up
|
||||
# z - # cd into previous directory
|
||||
#
|
||||
# zi foo # cd with interactive selection (using fzf)
|
||||
#
|
||||
# z foo<SPACE><TAB> # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)
|
||||
zoxide = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
enableZshIntegration = true;
|
||||
enableNushellIntegration = true;
|
||||
};
|
||||
|
||||
# Atuin replaces your existing shell history with a SQLite database,
|
||||
# and records additional context for your commands.
|
||||
# Additionally, it provides optional and fully encrypted
|
||||
# synchronisation of your history between machines, via an Atuin server.
|
||||
atuin = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
enableZshIntegration = true;
|
||||
enableNushellIntegration = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
_: {
|
||||
# use mirror for pip install
|
||||
xdg.configFile."pip/pip.conf".text = ''
|
||||
[global]
|
||||
index-url = https://mirrors.ustc.edu.cn/pypi/web/simple
|
||||
format = columns
|
||||
'';
|
||||
|
||||
# xdg.configFile."pip/pip.conf".text = ''
|
||||
# [global]
|
||||
# index-url = https://mirrors.bfsu.edu.cn/pypi/web/simple
|
||||
# '';
|
||||
}
|
||||
@@ -12,7 +12,7 @@ in {
|
||||
programs.nushell = {
|
||||
enable = true;
|
||||
configFile.source = ./config.nu;
|
||||
shellAliases = shellAliases;
|
||||
inherit shellAliases;
|
||||
};
|
||||
|
||||
programs.bash = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Home Manager's Darwin Submodules
|
||||
|
||||
1. `core.nix`: some basic configuration.
|
||||
2. `shell.nix`: shell related.
|
||||
3. `rime-squirrel.nix`: [rime-squirrel](https://github.com/rime/squirrel)'s configuration.
|
||||
4. `default.nix`: the entrypoint of darwin's configuration, it import all the submodules above.
|
||||
|
||||
|
||||
+21
-3
@@ -1,6 +1,24 @@
|
||||
let
|
||||
envExtra = ''
|
||||
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
|
||||
export PATH="$PATH:/opt/homebrew/bin:/usr/local/bin"
|
||||
'';
|
||||
# copied from the content generated by `conda init bash`
|
||||
initExtra = ''
|
||||
arch=$(uname -m)
|
||||
|
||||
if [ "aarch64" = "$arch" ] || [ "arm64" = "$arch" ]; then
|
||||
# >>> (miniforge)conda initialize >>>
|
||||
# !! Contents within this block are managed by 'conda init' !!
|
||||
if [ -f "/opt/homebrew/Caskroom/miniforge/base/etc/profile.d/conda.sh" ]; then
|
||||
. "/opt/homebrew/Caskroom/miniforge/base/etc/profile.d/conda.sh"
|
||||
else
|
||||
export PATH="/opt/homebrew/Caskroom/miniforge/base/bin:$PATH"
|
||||
fi
|
||||
# <<< conda initialize <<<
|
||||
elif [[ "x86_64" = "$arch" ]]; then
|
||||
# do nothing
|
||||
true
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
# Homebrew's default install location:
|
||||
@@ -10,10 +28,10 @@ in {
|
||||
# in /opt/homebrew for Apple Silicon and /usr/local for Rosetta 2 to coexist and use bottles.
|
||||
programs.bash = {
|
||||
enable = true;
|
||||
bashrcExtra = envExtra;
|
||||
bashrcExtra = envExtra + initExtra;
|
||||
};
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
envExtra = envExtra;
|
||||
inherit envExtra initExtra;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{vars_networking, ...}: {
|
||||
programs.ssh.extraConfig = vars_networking.ssh.extraConfig;
|
||||
}
|
||||
@@ -1,37 +1,14 @@
|
||||
{pkgs, ...}: {
|
||||
# Linux Only Packages, not available on Darwin
|
||||
home.packages = with pkgs; [
|
||||
nmon
|
||||
iotop
|
||||
iftop
|
||||
|
||||
# misc
|
||||
libnotify
|
||||
wireguard-tools # manage wireguard vpn manually, via wg-quick
|
||||
|
||||
# system call monitoring
|
||||
strace # system call monitoring
|
||||
ltrace # library call monitoring
|
||||
bpftrace # powerful tracing tool
|
||||
tcpdump # network sniffer
|
||||
lsof # list open files
|
||||
|
||||
# system tools
|
||||
sysstat
|
||||
lm_sensors # for `sensors` command
|
||||
ethtool
|
||||
pciutils # lspci
|
||||
usbutils # lsusb
|
||||
hdparm # for disk performance, command
|
||||
dmidecode # a tool that reads information about your system's hardware from the BIOS according to the SMBIOS/DMI standard
|
||||
];
|
||||
|
||||
# auto mount usb drives
|
||||
services = {
|
||||
udiskie.enable = true;
|
||||
};
|
||||
|
||||
services = {
|
||||
# syncthing.enable = true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
## Why install I3/Hyprland in Home Manager instead of a NixOS Module?
|
||||
|
||||
1. I3 & Hyprland's configuration file is located in `~/.config`, which can be easily managed by Home Manager.
|
||||
2. There're other user-specific systemd servcies, such gammastep, wallpaper-switcher, etc. which can be easily managed by Home Manager, but if we start i3/hyprland in NixOS Module, they may failed to start automatically. With i3/hyprland installed via home-manager, we can control their systemd service's dependent order, to avoid issues like this.
|
||||
3. By install as less as possible in NixOS Module, we can:
|
||||
2. I have many user-specific systemd servcies, such gammastep, wallpaper-switcher, etc. Which can be easily managed by Home Manager, but if we add i3/hyprland in a NixOS Module, those user-level services may failed to start automatically. With i3/hyprland in a Home Manager Module, we can control their systemd service's dependent order more easily, so we can avoid issues like this.
|
||||
3. By install packages as less as possible in NixOS Module, we can:
|
||||
1. Make the NixOS system more secure and stable.
|
||||
2. Make this flake more portable to other non-NixOS systems, as home-manager can be installed on any Linux system.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
pkgs,
|
||||
pkgs-unstable,
|
||||
pkgs-stable,
|
||||
nur-ryan4yin,
|
||||
...
|
||||
}: {
|
||||
@@ -12,7 +13,7 @@
|
||||
krita # digital painting
|
||||
musescore # music notation
|
||||
# reaper # audio production
|
||||
pkgs-unstable.sonic-pi # music programming
|
||||
# sonic-pi # music programming
|
||||
|
||||
# this app consumes a lot of storage, so do not install it currently
|
||||
# kicad # 3d printing, eletrical engineering
|
||||
@@ -27,6 +28,34 @@
|
||||
|
||||
programs = {
|
||||
# live streaming
|
||||
obs-studio.enable = true;
|
||||
obs-studio = {
|
||||
enable = true;
|
||||
plugins = with pkgs-stable.obs-studio-plugins; [
|
||||
# screen capture
|
||||
wlrobs
|
||||
# obs-ndi
|
||||
obs-vaapi
|
||||
obs-nvfbc
|
||||
obs-teleport
|
||||
# obs-hyperion
|
||||
droidcam-obs
|
||||
obs-vkcapture
|
||||
obs-gstreamer
|
||||
obs-3d-effect
|
||||
input-overlay
|
||||
obs-multi-rtmp
|
||||
obs-source-clone
|
||||
obs-shaderfilter
|
||||
obs-source-record
|
||||
obs-livesplit-one
|
||||
looking-glass-obs
|
||||
obs-vintage-filter
|
||||
obs-command-source
|
||||
obs-move-transition
|
||||
obs-backgroundremoval
|
||||
advanced-scene-switcher
|
||||
obs-pipewire-audio-capture
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
pkgs,
|
||||
nix-gaming,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs; [
|
||||
# nix-gaming.packages.${pkgs.system}.osu-lazer-bin
|
||||
gamescope # SteamOS session compositing window manager
|
||||
prismlauncher # A free, open source launcher for Minecraft
|
||||
winetricks # A script to install DLLs needed to work around problems in Wine
|
||||
];
|
||||
}
|
||||
@@ -45,12 +45,12 @@
|
||||
|
||||
theme = {
|
||||
# https://github.com/catppuccin/gtk
|
||||
name = "Catppuccin-Macchiato-Compact-Pink-dark";
|
||||
name = "Catppuccin-Macchiato-Compact-Pink-Dark";
|
||||
package = pkgs.catppuccin-gtk.override {
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-23.05/pkgs/data/themes/catppuccin-gtk/default.nix
|
||||
accents = ["pink"];
|
||||
size = "compact";
|
||||
variant = "mocha";
|
||||
variant = "macchiato";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -27,4 +27,8 @@
|
||||
programs.gh = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# allow fontconfig to discover fonts and configurations installed through home.packages
|
||||
# Install fonts at system-level, not user-level
|
||||
fonts.fontconfig.enable = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{pkgs, ...}: {
|
||||
home.packages = with pkgs; [
|
||||
# https://joplinapp.org/help/
|
||||
joplin # joplin-cli
|
||||
joplin-desktop
|
||||
];
|
||||
}
|
||||
@@ -30,14 +30,17 @@
|
||||
# ls /etc/profiles/per-user/ryan/share/applications/
|
||||
mimeApps = {
|
||||
enable = true;
|
||||
# let `xdg-open` to open the url with the correct application.
|
||||
defaultApplications = let
|
||||
browser = ["firefox.desktop"];
|
||||
editor = ["nvim.desktop" "Helix.desktop" "code.desktop" "code-insiders.desktop"];
|
||||
in {
|
||||
"application/json" = browser;
|
||||
"application/pdf" = browser; # TODO: pdf viewer
|
||||
|
||||
"text/html" = browser;
|
||||
"text/xml" = browser;
|
||||
"text/plain" = editor;
|
||||
"application/xml" = browser;
|
||||
"application/xhtml+xml" = browser;
|
||||
"application/xhtml_xml" = browser;
|
||||
@@ -48,12 +51,18 @@
|
||||
"application/x-extension-shtml" = browser;
|
||||
"application/x-extension-xht" = browser;
|
||||
"application/x-extension-xhtml" = browser;
|
||||
"application/x-wine-extension-ini" = editor;
|
||||
|
||||
"x-scheme-handler/about" = browser;
|
||||
"x-scheme-handler/ftp" = browser;
|
||||
# define default applications for some url schemes.
|
||||
"x-scheme-handler/about" = browser; # open `about:` url with `browser`
|
||||
"x-scheme-handler/ftp" = browser; # open `ftp:` url with `browser`
|
||||
"x-scheme-handler/http" = browser;
|
||||
"x-scheme-handler/https" = browser;
|
||||
"x-scheme-handler/unknown" = browser;
|
||||
# https://github.com/microsoft/vscode/issues/146408
|
||||
"x-scheme-handler/vscode" = ["code-url-handler.desktop"]; # open `vscode://` url with `code-url-handler.desktop`
|
||||
"x-scheme-handler/vscode-insiders" = ["code-insiders-url-handler.desktop"]; # open `vscode-insiders://` url with `code-insiders-url-handler.desktop`
|
||||
# all other unknown schemes will be opened by this default application.
|
||||
# "x-scheme-handler/unknown" = editor;
|
||||
|
||||
"x-scheme-handler/discord" = ["discord.desktop"];
|
||||
"x-scheme-handler/tg" = ["org.telegram.desktop.desktop "];
|
||||
|
||||
@@ -6,7 +6,11 @@ input {
|
||||
kb_model=
|
||||
kb_options=
|
||||
kb_rules=
|
||||
|
||||
# mouse focus will not switch to the hovered window unless the mouse crosses a window boundary
|
||||
follow_mouse=1
|
||||
mouse_refocus=false
|
||||
|
||||
natural_scroll=0
|
||||
touchpad {
|
||||
natural_scroll = 1
|
||||
@@ -90,7 +94,6 @@ $term = kitty
|
||||
$app_launcher = ~/.config/hypr/scripts/menu
|
||||
$volume = ~/.config/hypr/scripts/volume
|
||||
$backlight = ~/.config/hypr/scripts/brightness
|
||||
$screenshot = ~/.config/hypr/scripts/screenshot
|
||||
$lockscreen = ~/.config/hypr/scripts/lockscreen
|
||||
$wlogout = ~/.config/hypr/scripts/wlogout
|
||||
$colorpicker = ~/.config/hypr/scripts/colorpicker
|
||||
@@ -133,9 +136,11 @@ bind=,XF86AudioPlay,exec,mpc toggle
|
||||
bind=,XF86AudioStop,exec,mpc stop
|
||||
|
||||
# -- Screenshots --
|
||||
bind=,Print,exec,$screenshot --now
|
||||
bind=SUPER,Print,exec,$screenshot --win
|
||||
bind=CTRL,Print,exec,$screenshot --area
|
||||
bind=,Print,exec,hyprshot -m output -o ~/Pictures/Screenshots -- imv
|
||||
bind=SUPER,Print,exec,hyprshot -m window -o ~/Pictures/Screenshots -- imv
|
||||
# flameshot do not recognize hyprland as a wayland compositor, so we set it to sway here
|
||||
bind=CTRL,Print,exec,XDG_CURRENT_DESKTOP=sway flameshot gui --raw -p ~/Pictures/Screenshots | wl-copy
|
||||
# bind=CTRL,Print,exec,hyprshot -m region -o ~/Pictures/Screenshots -- imv
|
||||
|
||||
# Focus
|
||||
bind=SUPER,left,movefocus,l
|
||||
@@ -191,8 +196,3 @@ exec-once=cp ~/.config/fcitx5/profile-bak ~/.config/fcitx5/profile # restore
|
||||
exec-once=fcitx5 -d --replace # start fcitx5 daemon
|
||||
bind=ALT,E,exec,pkill fcitx5 -9;sleep 1;fcitx5 -d --replace; sleep 1;fcitx5-remote -r
|
||||
|
||||
# fix xwayland apps
|
||||
windowrulev2 = rounding 0, xwayland:1, floating:1
|
||||
windowrulev2 = center, class:^(.*jetbrains.*)$, title:^(Confirm Exit|Open Project|win424|win201|splash)$
|
||||
windowrulev2 = size 640 400, class:^(.*jetbrains.*)$, title:^(splash)$
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
## Script to take screenshots with grim, slurp (in Wayland)
|
||||
|
||||
iDIR="$HOME/.config/hypr/mako/icons"
|
||||
|
||||
time=$(date +%Y-%m-%d-%H-%M-%S)
|
||||
dir="$(xdg-user-dir PICTURES)/Screenshots" # need
|
||||
file="Screenshot_${time}_${RANDOM}.png"
|
||||
|
||||
# notify and view screenshot
|
||||
notify_cmd_shot="notify-send -h string:x-canonical-private-synchronous:shot-notify -u low -i ${iDIR}/picture.png"
|
||||
notify_view () {
|
||||
${notify_cmd_shot} "Copied to clipboard."
|
||||
imv ${dir}/"$file"
|
||||
if [[ -e "$dir/$file" ]]; then
|
||||
${notify_cmd_shot} "Screenshot Saved."
|
||||
else
|
||||
${notify_cmd_shot} "Screenshot Deleted."
|
||||
fi
|
||||
}
|
||||
|
||||
# take shots
|
||||
shotnow () {
|
||||
cd ${dir} && grim - | tee "$file" | wl-copy
|
||||
notify_view
|
||||
}
|
||||
|
||||
shotwin () {
|
||||
w_pos=$(hyprctl activewindow | grep 'at:' | cut -d':' -f2 | tr -d ' ' | tail -n1)
|
||||
w_size=$(hyprctl activewindow | grep 'size:' | cut -d':' -f2 | tr -d ' ' | tail -n1 | sed s/,/x/g)
|
||||
cd ${dir} && grim -g "$w_pos $w_size" - | tee "$file" | wl-copy
|
||||
notify_view
|
||||
}
|
||||
|
||||
shotarea () {
|
||||
cd ${dir} && grim -g "$(slurp -b 1B1F28CC -c E06B74ff -s C778DD0D -w 2)" - | tee "$file" | wl-copy
|
||||
notify_view
|
||||
}
|
||||
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
mkdir -p "$dir"
|
||||
fi
|
||||
|
||||
if [[ "$1" == "--now" ]]; then
|
||||
shotnow
|
||||
elif [[ "$1" == "--area" ]]; then
|
||||
shotarea
|
||||
elif [[ "$1" == "--win" ]]; then
|
||||
shotwin
|
||||
else
|
||||
echo -e "Available Options : --now --win --area"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -6,7 +6,7 @@
|
||||
"custom/launcher",
|
||||
"temperature",
|
||||
"backlight",
|
||||
"wlr/workspaces"
|
||||
"hyprland/workspaces"
|
||||
],
|
||||
"modules-center": [
|
||||
"custom/playerctl"
|
||||
@@ -23,7 +23,7 @@
|
||||
"custom/powermenu",
|
||||
"tray"
|
||||
],
|
||||
"wlr/workspaces": {
|
||||
"hyprland/workspaces": {
|
||||
"format": "{icon}",
|
||||
"on-click": "activate",
|
||||
"format-icons": {
|
||||
|
||||
@@ -63,7 +63,4 @@
|
||||
recursive = true;
|
||||
};
|
||||
};
|
||||
|
||||
# allow fontconfig to discover fonts and configurations installed through home.packages
|
||||
fonts.fontconfig.enable = true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{pkgs, ...}: {
|
||||
{
|
||||
pkgs,
|
||||
pkgs-unstable,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs; [
|
||||
waybar # the status bar
|
||||
swaybg # the wallpaper
|
||||
@@ -8,10 +12,10 @@
|
||||
wl-clipboard # copying and pasting
|
||||
hyprpicker # color picker
|
||||
|
||||
wf-recorder # creen recording
|
||||
pkgs-unstable.hyprshot # screen shot
|
||||
grim # taking screenshots
|
||||
slurp # selecting a region to screenshot
|
||||
# TODO replace by `flameshot gui --raw | wl-copy`
|
||||
wf-recorder # creen recording
|
||||
|
||||
mako # the notification daemon, the same as dunst
|
||||
|
||||
|
||||
@@ -39,12 +39,13 @@
|
||||
google-chrome = {
|
||||
enable = true;
|
||||
|
||||
# https://wiki.archlinux.org/title/Chromium#Native_Wayland_support
|
||||
commandLineArgs = [
|
||||
"--ozone-platform-hint=auto"
|
||||
"--ozone-platform=wayland"
|
||||
# make it use GTK_IM_MODULE if it runs with Gtk4, so fcitx5 can work with it.
|
||||
# (only supported by chromium/chrome at this time, not electron)
|
||||
"--gtk-version=4"
|
||||
"--enable-features=UseOzonePlatform"
|
||||
"--ozone-platform=wayland"
|
||||
# make it use text-input-v1, which works for kwin 5.27 and weston
|
||||
"--enable-wayland-ime"
|
||||
|
||||
@@ -58,5 +59,38 @@
|
||||
enableGnomeExtensions = false;
|
||||
package = pkgs.firefox-wayland; # firefox with wayland support
|
||||
};
|
||||
|
||||
vscode = {
|
||||
enable = true;
|
||||
# let vscode sync and update its configuration & extensions across devices, using github account.
|
||||
userSettings = {};
|
||||
package =
|
||||
(pkgs.vscode.override
|
||||
{
|
||||
isInsiders = true;
|
||||
# https://wiki.archlinux.org/title/Wayland#Electron
|
||||
commandLineArgs = [
|
||||
"--ozone-platform-hint=auto"
|
||||
"--ozone-platform=wayland"
|
||||
# make it use GTK_IM_MODULE if it runs with Gtk4, so fcitx5 can work with it.
|
||||
# (only supported by chromium/chrome at this time, not electron)
|
||||
"--gtk-version=4"
|
||||
# make it use text-input-v1, which works for kwin 5.27 and weston
|
||||
"--enable-wayland-ime"
|
||||
|
||||
# TODO: fix https://github.com/microsoft/vscode/issues/187436
|
||||
# still not works...
|
||||
"--password-store=gnome" # use gnome-keyring as password store
|
||||
];
|
||||
})
|
||||
.overrideAttrs (oldAttrs: rec {
|
||||
# Use VSCode Insiders to fix crash: https://github.com/NixOS/nixpkgs/issues/246509
|
||||
src = builtins.fetchTarball {
|
||||
url = "https://update.code.visualstudio.com/latest/linux-x64/insider";
|
||||
sha256 = "0k2sh7rb6mrx9d6bkk2744ry4g17d13xpnhcisk4akl4x7dn6a83";
|
||||
};
|
||||
version = "latest";
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,7 +48,4 @@
|
||||
# xrandr - set primary screen
|
||||
".screenlayout/monitor.sh".source = ../conf/dual-monitor-4k-1080p.sh;
|
||||
};
|
||||
|
||||
# allow fontconfig to discover fonts and configurations installed through home.packages
|
||||
fonts.fontconfig.enable = true;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
{pkgs, ...}: {
|
||||
{
|
||||
pkgs,
|
||||
pkgs-unstable,
|
||||
...
|
||||
}: {
|
||||
home.packages = with pkgs; [
|
||||
firefox
|
||||
];
|
||||
|
||||
# TODO vscode & chrome both have wayland support, but they don't work with fcitx5, need to fix it.
|
||||
programs = {
|
||||
# source code: https://github.com/nix-community/home-manager/blob/master/modules/programs/chromium.nix
|
||||
google-chrome = {
|
||||
@@ -16,5 +19,11 @@
|
||||
# commandLineArgs = [
|
||||
# ];
|
||||
};
|
||||
vscode = {
|
||||
enable = true;
|
||||
package = pkgs-unstable.vscode;
|
||||
# let vscode sync and update its configuration & extensions across devices, using github account.
|
||||
# userSettings = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# Rakushun - Orange Pi 5 Plus
|
||||
|
||||
LUKS encrypted SSD for NixOS, on Orange Pi 5 Plus.
|
||||
|
||||
## Showcases
|
||||
|
||||

|
||||
|
||||
Disk layout:
|
||||
|
||||
```bash
|
||||
[ryan@rakushun:~]$ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
sda 8:0 1 58.6G 0 disk
|
||||
└─sda1 8:1 1 487M 0 part
|
||||
mtdblock0 31:0 0 16M 0 disk
|
||||
zram0 254:0 0 0B 0 disk
|
||||
nvme0n1 259:0 0 1.8T 0 disk
|
||||
├─nvme0n1p1 259:1 0 630M 0 part /boot
|
||||
└─nvme0n1p2 259:2 0 1.8T 0 part
|
||||
└─crypted 253:0 0 1.8T 0 crypt /tmp
|
||||
/swap
|
||||
/snapshots
|
||||
/home/ryan/tmp
|
||||
/home/ryan/nix-config
|
||||
/home/ryan/go
|
||||
/home/ryan/codes
|
||||
/home/ryan/.ssh
|
||||
/home/ryan/.local/state
|
||||
/home/ryan/.npm
|
||||
/home/ryan/.local/share
|
||||
/home/ryan/.conda
|
||||
/etc/ssh
|
||||
/etc/nix/inputs
|
||||
/etc/secureboot
|
||||
/etc/agenix
|
||||
/etc/NetworkManager/system-connections
|
||||
/etc/machine-id
|
||||
/nix/store
|
||||
/var/log
|
||||
/var/lib
|
||||
/nix
|
||||
/persistent
|
||||
|
||||
[ryan@rakushun:~]$ df -Th
|
||||
Filesystem Type Size Used Avail Use% Mounted on
|
||||
devtmpfs devtmpfs 785M 0 785M 0% /dev
|
||||
tmpfs tmpfs 7.7G 0 7.7G 0% /dev/shm
|
||||
tmpfs tmpfs 3.9G 6.8M 3.9G 1% /run
|
||||
tmpfs tmpfs 7.7G 1.9M 7.7G 1% /run/wrappers
|
||||
none tmpfs 4.0G 48K 4.0G 1% /
|
||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /persistent
|
||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /nix
|
||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /snapshots
|
||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /swap
|
||||
/dev/mapper/crypted btrfs 1.9T 19G 1.8T 2% /tmp
|
||||
/dev/nvme0n1p1 vfat 629M 96M 534M 16% /boot
|
||||
tmpfs tmpfs 1.6G 4.0K 1.6G 1% /run/user/1000
|
||||
```
|
||||
|
||||
CPU info:
|
||||
|
||||
```bash
|
||||
[ryan@rakushun:~]$ lscpu
|
||||
Architecture: aarch64
|
||||
CPU op-mode(s): 32-bit, 64-bit
|
||||
Byte Order: Little Endian
|
||||
CPU(s): 8
|
||||
On-line CPU(s) list: 0-7
|
||||
Vendor ID: ARM
|
||||
Model name: Cortex-A55
|
||||
Model: 0
|
||||
Thread(s) per core: 1
|
||||
Core(s) per socket: 4
|
||||
Socket(s): 1
|
||||
Stepping: r2p0
|
||||
CPU(s) scaling MHz: 67%
|
||||
CPU max MHz: 1800.0000
|
||||
CPU min MHz: 408.0000
|
||||
BogoMIPS: 48.00
|
||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
||||
Model name: Cortex-A76
|
||||
Model: 0
|
||||
Thread(s) per core: 1
|
||||
Core(s) per socket: 2
|
||||
Socket(s): 2
|
||||
Stepping: r4p0
|
||||
CPU(s) scaling MHz: 18%
|
||||
CPU max MHz: 2256.0000
|
||||
CPU min MHz: 408.0000
|
||||
BogoMIPS: 48.00
|
||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
||||
Caches (sum of all):
|
||||
L1d: 384 KiB (8 instances)
|
||||
L1i: 384 KiB (8 instances)
|
||||
L2: 2.5 MiB (8 instances)
|
||||
L3: 3 MiB (1 instance)
|
||||
```
|
||||
|
||||
## How to install NixOS on Orange Pi 5 Plus
|
||||
|
||||
### 1. Prepare a USB LUKS key
|
||||
|
||||
Generate LUKS keyfile to encrypt the root partition, it's used by disko.
|
||||
|
||||
```bash
|
||||
# partition the usb stick
|
||||
DEV=/dev/sdX
|
||||
parted ${DEV} -- mklabel gpt
|
||||
parted ${DEV} -- mkpart OPI5P_DSC fat32 0% 512MB
|
||||
mkfs.fat -F 32 -n OPI5P_DSC ${DEV}1
|
||||
|
||||
# Generate a keyfile from the true random number generator
|
||||
KEYFILE=./orangepi5plus-luks-keyfile
|
||||
dd bs=512 count=64 iflag=fullblock if=/dev/random of=$KEYFILE
|
||||
|
||||
# copy the keyfile and token to the usb stick
|
||||
KEYFILE=./orangepi5plus-luks-keyfile
|
||||
DEVICE=/dev/disk/by-label/OPI5P_DSC
|
||||
# seek=128 skip N obs-sized output blocks to avoid overwriting the filesystem header
|
||||
dd bs=512 count=64 iflag=fullblock seek=128 if=$KEYFILE of=$DEVICE
|
||||
```
|
||||
|
||||
### 2. Partition the SSD & install NixOS via disko
|
||||
|
||||
First, follow [UEFI - ryan4yin/nixos-rk3588](https://github.com/ryan4yin/nixos-rk3588/blob/main/UEFI.md) to install UEFI bootloader and boot into NixOS live environment via a USB stick.
|
||||
|
||||
Then, run the following commands:
|
||||
|
||||
```bash
|
||||
# transfer the nix-config to the target machine
|
||||
rsync -avzP ~/nix-config rk@<ip-addr>:/home/rk/
|
||||
|
||||
# login via ssh
|
||||
ssh rk@<ip-addr>
|
||||
|
||||
cd ~/nix-config/hosts/12kingdoms_rakushun
|
||||
# 1. change the disk device path in ./disko-fs.nix to the disk you want to use
|
||||
# 2. partition & format the disk via disko
|
||||
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko ./disko-fs.nix
|
||||
|
||||
|
||||
cd ~/nix-config
|
||||
# install nixos
|
||||
# NOTE: the root password you set here will be discarded when reboot
|
||||
sudo nixos-install --root /mnt --flake .#rakushun --no-root-password --show-trace --verbose
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
disko,
|
||||
nixos-rk3588,
|
||||
vars_networking,
|
||||
...
|
||||
}:
|
||||
#############################################################
|
||||
#
|
||||
# Suzu - Orange Pi 5 Plus, RK3588 + 16GB RAM
|
||||
#
|
||||
#############################################################
|
||||
let
|
||||
hostName = "rakushun"; # Define your hostname.
|
||||
hostAddress = vars_networking.hostAddress.${hostName};
|
||||
in {
|
||||
imports = [
|
||||
# import the rk3588 module, which contains the configuration for bootloader/kernel/firmware
|
||||
nixos-rk3588.nixosModules.orangepi5plus.core
|
||||
disko.nixosModules.default
|
||||
./hardware-configuration.nix
|
||||
./disko-fs.nix
|
||||
./impermanence.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
inherit hostName;
|
||||
inherit (vars_networking) defaultGateway nameservers;
|
||||
|
||||
networkmanager.enable = false;
|
||||
# RJ45 port 1
|
||||
interfaces.enP4p65s0 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [hostAddress];
|
||||
};
|
||||
# RJ45 port 2
|
||||
# interfaces.enP3p49s0 = {
|
||||
# useDHCP = false;
|
||||
# ipv4.addresses = [hostAddress];
|
||||
# };
|
||||
};
|
||||
|
||||
# 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 = "23.11"; # Did you read the comment?
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
{
|
||||
# required by impermanence
|
||||
fileSystems."/persistent".neededForBoot = true;
|
||||
|
||||
disko.devices = {
|
||||
nodev."/" = {
|
||||
fsType = "tmpfs";
|
||||
mountOptions = [
|
||||
"size=4G"
|
||||
"defaults"
|
||||
# set mode to 755, otherwise systemd will set it to 777, which cause problems.
|
||||
# relatime: Update inode access times relative to modify or change time.
|
||||
"mode=755"
|
||||
];
|
||||
};
|
||||
|
||||
# TODO: rename to main
|
||||
disk.sda = {
|
||||
type = "disk";
|
||||
# When using disko-install, we will overwrite this value from the commandline
|
||||
device = "/dev/nvme0n1"; # The device to partition
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
# The EFI & Boot partition
|
||||
ESP = {
|
||||
size = "630M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
];
|
||||
};
|
||||
};
|
||||
# The root partition
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted";
|
||||
settings = {
|
||||
keyFile = "/dev/disk/by-label/OPI5P_DSC"; # The keyfile is stored on a USB stick
|
||||
# The maxium size of the keyfile is 8192 bytes
|
||||
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
|
||||
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
|
||||
fallbackToPassword = true;
|
||||
allowDiscards = true;
|
||||
};
|
||||
# Whether to add a boot.initrd.luks.devices entry for the specified disk.
|
||||
initrdUnlock = true;
|
||||
|
||||
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
|
||||
# cryptsetup luksFormat
|
||||
extraFormatArgs = [
|
||||
"--type luks2"
|
||||
"--cipher aes-xts-plain64"
|
||||
"--hash sha512"
|
||||
"--iter-time 5000"
|
||||
"--key-size 256"
|
||||
"--pbkdf argon2id"
|
||||
# use true random data from /dev/random, will block until enough entropy is available
|
||||
"--use-random"
|
||||
];
|
||||
extraOpenArgs = [
|
||||
"--timeout 10"
|
||||
];
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = ["-f"];
|
||||
subvolumes = {
|
||||
"@nix" = {
|
||||
mountpoint = "/nix";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@persistent" = {
|
||||
mountpoint = "/persistent";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@tmp" = {
|
||||
mountpoint = "/tmp";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@snapshots" = {
|
||||
mountpoint = "/snapshots";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@swap" = {
|
||||
mountpoint = "/swap";
|
||||
swap.swapfile.size = "16384M";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.loader = {
|
||||
# depending on how you configured your disk mounts, change this to /boot or /boot/efi.
|
||||
efi.efiSysMountPoint = "/boot/";
|
||||
efi.canTouchEfiVariables = true;
|
||||
# do not use systemd-boot here, it has problems when running `nixos-install`
|
||||
grub = {
|
||||
device = "nodev";
|
||||
efiSupport = true;
|
||||
};
|
||||
};
|
||||
# clear /tmp on boot to get a stateless /tmp directory.
|
||||
boot.tmp.cleanOnBoot = true;
|
||||
|
||||
boot.initrd.availableKernelModules = ["nvme" "usbhid" "usb_storage"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = [];
|
||||
boot.extraModulePackages = [];
|
||||
|
||||
# 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.enP3p49s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enP4p65s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||
}
|
||||
+1
-44
@@ -41,11 +41,6 @@
|
||||
|
||||
"/var/log"
|
||||
"/var/lib"
|
||||
|
||||
# created by modules/nixos/misc/fhs-fonts.nix
|
||||
# for flatpak apps
|
||||
# "/usr/share/fonts"
|
||||
# "/usr/share/icons"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
@@ -58,44 +53,10 @@
|
||||
"nix-config"
|
||||
"tmp"
|
||||
|
||||
"Downloads"
|
||||
"Music"
|
||||
"Pictures"
|
||||
"Documents"
|
||||
"Videos"
|
||||
|
||||
{
|
||||
directory = ".gnupg";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".ssh";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".aws";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".docker";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".kube";
|
||||
mode = "0700";
|
||||
}
|
||||
|
||||
# misc
|
||||
".config/pulse"
|
||||
".pki"
|
||||
|
||||
# remote desktop
|
||||
".config/remmina"
|
||||
".config/freerdp"
|
||||
|
||||
# browsers
|
||||
".mozilla"
|
||||
".config/google-chrome"
|
||||
|
||||
# neovim / remmina / flatpak / ...
|
||||
".local/share"
|
||||
@@ -103,14 +64,10 @@
|
||||
|
||||
# language package managers
|
||||
".npm"
|
||||
".conda" # generated by `conda-shell`
|
||||
"go"
|
||||
|
||||
# neovim plugins(wakatime & copilot)
|
||||
".wakatime"
|
||||
".config/github-copilot"
|
||||
];
|
||||
files = [
|
||||
".wakatime.cfg"
|
||||
".config/nushell/history.txt"
|
||||
];
|
||||
};
|
||||
@@ -1,42 +1,35 @@
|
||||
{
|
||||
pkgs,
|
||||
nixos-hardware,
|
||||
vars_networking,
|
||||
...
|
||||
} @ args:
|
||||
}:
|
||||
#############################################################
|
||||
#
|
||||
# Shoukei - NixOS running on Macbook Pro 2020 I5 16G
|
||||
# https://github.com/NixOS/nixos-hardware/tree/master/apple/t2
|
||||
#
|
||||
#############################################################
|
||||
{
|
||||
let
|
||||
hostName = "shoukei"; # Define your hostname.
|
||||
in {
|
||||
imports = [
|
||||
nixos-hardware.nixosModules.apple-t2
|
||||
./apple-set-os-loader.nix
|
||||
{hardware.myapple-t2.enableAppleSetOsLoader = true;}
|
||||
|
||||
./hardware-configuration.nix
|
||||
./impermanence.nix
|
||||
../idols_ai/impermanence.nix
|
||||
];
|
||||
|
||||
boot.kernelModules = ["kvm-amd"];
|
||||
boot.extraModprobeConfig = "options kvm_amd nested=1"; # for amd cpu
|
||||
|
||||
networking = {
|
||||
hostName = "shoukei"; # Define your hostname.
|
||||
inherit hostName;
|
||||
inherit (vars_networking) defaultGateway nameservers;
|
||||
|
||||
# configures the network interface(include wireless) via `nmcli` & `nmtui`
|
||||
networkmanager.enable = true;
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# proxy.default = "http://user:password@proxy:port/";
|
||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# proxy.default = "http://user:password@proxy:port/";
|
||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
defaultGateway = "192.168.5.201";
|
||||
nameservers = [
|
||||
"119.29.29.29" # DNSPod
|
||||
"223.5.5.5" # AliDNS
|
||||
];
|
||||
};
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
+6
-1
@@ -29,7 +29,7 @@
|
||||
|
||||
# Enable binfmt emulation of aarch64-linux, this is required for cross compilation.
|
||||
boot.binfmt.emulatedSystems = ["aarch64-linux" "riscv64-linux"];
|
||||
# supported fil systems, so we can mount any removable disks with these filesystems
|
||||
# supported file systems, so we can mount any removable disks with these filesystems
|
||||
boot.supportedFilesystems = lib.mkForce [
|
||||
"ext4"
|
||||
"btrfs"
|
||||
@@ -53,6 +53,11 @@
|
||||
# whether to allow TRIM requests to the underlying device.
|
||||
# it's less secure, but faster.
|
||||
allowDiscards = true;
|
||||
# Whether to bypass dm-crypt’s internal read and write workqueues.
|
||||
# Enabling this should improve performance on SSDs;
|
||||
# https://wiki.archlinux.org/index.php/Dm-crypt/Specialties#Disable_workqueue_for_increased_solid_state_drive_(SSD)_performance
|
||||
bypassWorkqueues = true;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# Suzu - Orange Pi 5
|
||||
|
||||
LUKS encrypted SSD for NixOS, on Orange Pi 5.
|
||||
|
||||
|
||||
## Showcases
|
||||
|
||||

|
||||
|
||||
Disk layout:
|
||||
|
||||
```bash
|
||||
[ryan@suzu:~]$ lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
sda 8:0 1 58.6G 0 disk
|
||||
└─sda1 8:1 1 486M 0 part
|
||||
mtdblock0 31:0 0 16M 0 disk
|
||||
zram0 254:0 0 0B 0 disk
|
||||
nvme0n1 259:0 0 238.5G 0 disk
|
||||
├─nvme0n1p1 259:1 0 630M 0 part /boot
|
||||
└─nvme0n1p2 259:2 0 237.9G 0 part
|
||||
└─crypted 253:0 0 237.8G 0 crypt /tmp
|
||||
/snapshots
|
||||
/swap
|
||||
/home/ryan/tmp
|
||||
/home/ryan/nix-config
|
||||
/home/ryan/go
|
||||
/home/ryan/.local/state
|
||||
/home/ryan/codes
|
||||
/home/ryan/.npm
|
||||
/home/ryan/.ssh
|
||||
/home/ryan/.local/share
|
||||
/etc/ssh
|
||||
/home/ryan/.conda
|
||||
/etc/secureboot
|
||||
/etc/agenix
|
||||
/etc/nix/inputs
|
||||
/etc/NetworkManager/system-connections
|
||||
/nix/store
|
||||
/var/log
|
||||
/var/lib
|
||||
/nix
|
||||
/persistent
|
||||
|
||||
[ryan@suzu:~]$ df -Th
|
||||
Filesystem Type Size Used Avail Use% Mounted on
|
||||
devtmpfs devtmpfs 383M 0 383M 0% /dev
|
||||
tmpfs tmpfs 3.8G 0 3.8G 0% /dev/shm
|
||||
tmpfs tmpfs 1.9G 6.2M 1.9G 1% /run
|
||||
tmpfs tmpfs 3.8G 1.9M 3.8G 1% /run/wrappers
|
||||
none tmpfs 2.0G 48K 2.0G 1% /
|
||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /persistent
|
||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /nix
|
||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /swap
|
||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /snapshots
|
||||
/dev/mapper/crypted btrfs 238G 11G 226G 5% /tmp
|
||||
/dev/nvme0n1p1 vfat 629M 86M 543M 14% /boot
|
||||
tmpfs tmpfs 766M 4.0K 766M 1% /run/user/1000
|
||||
```
|
||||
|
||||
CPU info:
|
||||
|
||||
```bash
|
||||
[ryan@suzu:~]$ lscpu
|
||||
Architecture: aarch64
|
||||
CPU op-mode(s): 32-bit, 64-bit
|
||||
Byte Order: Little Endian
|
||||
CPU(s): 8
|
||||
On-line CPU(s) list: 0-7
|
||||
Vendor ID: ARM
|
||||
Model name: Cortex-A55
|
||||
Model: 0
|
||||
Thread(s) per core: 1
|
||||
Core(s) per socket: 4
|
||||
Socket(s): 1
|
||||
Stepping: r2p0
|
||||
CPU(s) scaling MHz: 56%
|
||||
CPU max MHz: 1800.0000
|
||||
CPU min MHz: 408.0000
|
||||
BogoMIPS: 48.00
|
||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
||||
Model name: Cortex-A76
|
||||
Model: 0
|
||||
Thread(s) per core: 1
|
||||
Core(s) per socket: 2
|
||||
Socket(s): 2
|
||||
Stepping: r4p0
|
||||
CPU(s) scaling MHz: 18%
|
||||
CPU max MHz: 2256.0000
|
||||
CPU min MHz: 408.0000
|
||||
BogoMIPS: 48.00
|
||||
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
|
||||
Caches (sum of all):
|
||||
L1d: 384 KiB (8 instances)
|
||||
L1i: 384 KiB (8 instances)
|
||||
L2: 2.5 MiB (8 instances)
|
||||
L3: 3 MiB (1 instance)
|
||||
```
|
||||
|
||||
## How to install NixOS on Orange Pi 5
|
||||
|
||||
### 1. Prepare a USB LUKS key
|
||||
|
||||
Generate LUKS keyfile to encrypt the root partition, it's used by disko.
|
||||
|
||||
```bash
|
||||
# partition the usb stick
|
||||
DEV=/dev/sdX
|
||||
parted ${DEV} -- mklabel gpt
|
||||
parted ${DEV} -- mkpart primary 2M 512MB
|
||||
mkfs.fat -F 32 -n OPI5_DSC ${DEV}1
|
||||
|
||||
|
||||
# Generate a keyfile from the true random number generator
|
||||
KEYFILE=./orangepi5-luks-keyfile
|
||||
dd bs=512 count=64 iflag=fullblock if=/dev/random of=$KEYFILE
|
||||
|
||||
# copy the keyfile and token to the usb stick
|
||||
KEYFILE=./orangepi5-luks-keyfile
|
||||
DEVICE=/dev/disk/by-label/OPI5_DSC
|
||||
# seek=128 skip N obs-sized output blocks to avoid overwriting the filesystem header
|
||||
dd bs=512 count=64 iflag=fullblock seek=128 if=$KEYFILE of=$DEVICE
|
||||
```
|
||||
|
||||
### 2. Partition the SSD & install NixOS via disko
|
||||
|
||||
First, follow [UEFI - ryan4yin/nixos-rk3588](https://github.com/ryan4yin/nixos-rk3588/blob/main/UEFI.md) to install UEFI bootloader and boot into NixOS live environment via a USB stick.
|
||||
|
||||
Then, run the following commands:
|
||||
|
||||
```bash
|
||||
# login via ssh
|
||||
ssh rk@<ip-addr>
|
||||
|
||||
git clone https://github.com/ryan4yin/nix-config.git
|
||||
|
||||
cd ~/nix-config/hosts/12kingdoms_suzu
|
||||
# 1. change the disk device path in ./disko-fs.nix to the disk you want to use
|
||||
# 2. partition & format the disk via disko
|
||||
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko ./disko-fs.nix
|
||||
|
||||
|
||||
cd ~/nix-config
|
||||
# install nixos
|
||||
# NOTE: the root password you set here will be discarded when reboot
|
||||
sudo nixos-install --root /mnt --flake .#suzu --no-root-password --show-trace --verbose
|
||||
```
|
||||
|
||||
|
||||
@@ -1,38 +1,36 @@
|
||||
{nixos-rk3588, ...}:
|
||||
#############################################################
|
||||
#
|
||||
# Aquamarine - A NixOS VM running on Proxmox
|
||||
#
|
||||
#############################################################
|
||||
{
|
||||
disko,
|
||||
nixos-rk3588,
|
||||
vars_networking,
|
||||
...
|
||||
}:
|
||||
#############################################################
|
||||
#
|
||||
# Suzu - Orange Pi 5 Plus, RK3588 + 16GB RAM
|
||||
#
|
||||
#############################################################
|
||||
let
|
||||
hostName = "suzu"; # Define your hostname.
|
||||
hostAddress = vars_networking.hostAddress.${hostName};
|
||||
in {
|
||||
imports = [
|
||||
# import the rk3588 module, which contains the configuration for bootloader/kernel/firmware
|
||||
nixos-rk3588.nixosModules.orangepi5
|
||||
nixos-rk3588.nixosModules.orangepi5plus.core
|
||||
disko.nixosModules.default
|
||||
./hardware-configuration.nix
|
||||
./disko-fs.nix
|
||||
./impermanence.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "suzu"; # Define your hostname.
|
||||
wireless.enable = false; # Enables wireless support via wpa_supplicant.
|
||||
inherit hostName;
|
||||
inherit (vars_networking) defaultGateway nameservers;
|
||||
|
||||
networkmanager.enable = false;
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# proxy.default = "http://user:password@proxy:port/";
|
||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
interfaces.end1 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "192.168.5.107";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv4.addresses = [hostAddress];
|
||||
};
|
||||
defaultGateway = "192.168.5.201";
|
||||
nameservers = [
|
||||
"119.29.29.29" # DNSPod
|
||||
"223.5.5.5" # AliDNS
|
||||
];
|
||||
};
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
@@ -0,0 +1,102 @@
|
||||
{
|
||||
# required by impermanence
|
||||
fileSystems."/persistent".neededForBoot = true;
|
||||
|
||||
disko.devices = {
|
||||
nodev."/" = {
|
||||
fsType = "tmpfs";
|
||||
mountOptions = [
|
||||
"size=2G"
|
||||
"defaults"
|
||||
# set mode to 755, otherwise systemd will set it to 777, which cause problems.
|
||||
# relatime: Update inode access times relative to modify or change time.
|
||||
"mode=755"
|
||||
];
|
||||
};
|
||||
|
||||
# TODO: rename to main
|
||||
disk.sda = {
|
||||
type = "disk";
|
||||
# When using disko-install, we will overwrite this value from the commandline
|
||||
device = "/dev/nvme0n1"; # The device to partition
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
# The EFI & Boot partition
|
||||
ESP = {
|
||||
size = "630M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
];
|
||||
};
|
||||
};
|
||||
# The root partition
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted";
|
||||
settings = {
|
||||
keyFile = "/dev/disk/by-label/OPI5_DSC"; # The keyfile is stored on a USB stick
|
||||
# The maxium size of the keyfile is 8192 bytes
|
||||
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
|
||||
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
|
||||
fallbackToPassword = true;
|
||||
allowDiscards = true;
|
||||
};
|
||||
# Whether to add a boot.initrd.luks.devices entry for the specified disk.
|
||||
initrdUnlock = true;
|
||||
|
||||
# encrypt the root partition with luks2 and argon2id, will prompt for a passphrase, which will be used to unlock the partition.
|
||||
# cryptsetup luksFormat
|
||||
extraFormatArgs = [
|
||||
"--type luks2"
|
||||
"--cipher aes-xts-plain64"
|
||||
"--hash sha512"
|
||||
"--iter-time 5000"
|
||||
"--key-size 256"
|
||||
"--pbkdf argon2id"
|
||||
# use true random data from /dev/random, will block until enough entropy is available
|
||||
"--use-random"
|
||||
];
|
||||
extraOpenArgs = [
|
||||
"--timeout 10"
|
||||
];
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = ["-f"];
|
||||
subvolumes = {
|
||||
"@nix" = {
|
||||
mountpoint = "/nix";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@persistent" = {
|
||||
mountpoint = "/persistent";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@tmp" = {
|
||||
mountpoint = "/tmp";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@snapshots" = {
|
||||
mountpoint = "/snapshots";
|
||||
mountOptions = ["compress-force=zstd:1" "noatime"];
|
||||
};
|
||||
"@swap" = {
|
||||
mountpoint = "/swap";
|
||||
swap.swapfile.size = "8192M";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.loader = {
|
||||
# depending on how you configured your disk mounts, change this to /boot or /boot/efi.
|
||||
efi.efiSysMountPoint = "/boot/";
|
||||
efi.canTouchEfiVariables = true;
|
||||
# do not use systemd-boot here, it has problems when running `nixos-install`
|
||||
grub = {
|
||||
device = "nodev";
|
||||
efiSupport = true;
|
||||
};
|
||||
};
|
||||
# clear /tmp on boot to get a stateless /tmp directory.
|
||||
boot.tmp.cleanOnBoot = true;
|
||||
|
||||
boot.initrd.availableKernelModules = ["nvme" "usbhid" "usb_storage"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = [];
|
||||
boot.extraModulePackages = [];
|
||||
|
||||
# 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.enP3p49s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enP4p65s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
impermanence,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
impermanence.nixosModules.impermanence
|
||||
];
|
||||
|
||||
environment.systemPackages = [
|
||||
# `sudo ncdu -x /`
|
||||
pkgs.ncdu
|
||||
];
|
||||
|
||||
# There are two ways to clear the root filesystem on every boot:
|
||||
## 1. use tmpfs for /
|
||||
## 2. (btrfs/zfs only)take a blank snapshot of the root filesystem and revert to it on every boot via:
|
||||
## boot.initrd.postDeviceCommands = ''
|
||||
## mkdir -p /run/mymount
|
||||
## mount -o subvol=/ /dev/disk/by-uuid/UUID /run/mymount
|
||||
## btrfs subvolume delete /run/mymount
|
||||
## btrfs subvolume snapshot / /run/mymount
|
||||
## '';
|
||||
#
|
||||
# See also https://grahamc.com/blog/erase-your-darlings/
|
||||
|
||||
# NOTE: impermanence only mounts the directory/file list below to /persistent
|
||||
# If the directory/file already exists in the root filesystem, you should
|
||||
# move those files/directories to /persistent first!
|
||||
environment.persistence."/persistent" = {
|
||||
# sets the mount option x-gvfs-hide on all the bind mounts
|
||||
# to hide them from the file manager
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
"/etc/NetworkManager/system-connections"
|
||||
"/etc/ssh"
|
||||
"/etc/nix/inputs"
|
||||
"/etc/secureboot" # lanzaboote - secure boot
|
||||
# my secrets
|
||||
"/etc/agenix/"
|
||||
|
||||
"/var/log"
|
||||
"/var/lib"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
];
|
||||
|
||||
# the following directories will be passed to /persistent/home/$USER
|
||||
users.ryan = {
|
||||
directories = [
|
||||
"codes"
|
||||
"nix-config"
|
||||
"tmp"
|
||||
|
||||
{
|
||||
directory = ".ssh";
|
||||
mode = "0700";
|
||||
}
|
||||
|
||||
# neovim / remmina / flatpak / ...
|
||||
".local/share"
|
||||
".local/state"
|
||||
|
||||
# language package managers
|
||||
".npm"
|
||||
".conda" # generated by `conda-shell`
|
||||
"go"
|
||||
];
|
||||
files = [
|
||||
".config/nushell/history.txt"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
+25
-17
@@ -1,32 +1,28 @@
|
||||
# Hosts
|
||||
|
||||
1. macOS
|
||||
1. `darwin`(macOS)
|
||||
1. `fern`: MacBook Pro 2022 13-inch M2 16G, mainly for business.
|
||||
1. `harmonica`: MacBook Pro 2020 13-inch i5 16G, for personal use.
|
||||
2. `idols`
|
||||
1. `ai`: My main computer, with NixOS + I5-13600KF + RTX 4090 GPU, for gaming & daily use.
|
||||
2. `aquamarine`: My NixOS virtual machine with R9-5900HX(8C16T), for distributed building & testing.
|
||||
3. `kana`: Yet another NixOS vm on another physical machine with R5-5625U(6C12T).
|
||||
4. `ruby`: Another NixOS vm on another physical machine with R7-5825U(8C16T).
|
||||
3. `rolling_girls`: My RISCV64 hosts.
|
||||
2. `aquamarine`: My NixOS virtual machine as a router(IPv4 only) with a tranparent proxy to bypass the G|F|W.
|
||||
3. `ruby`: Another NixOS VM running operation and maintenance related services, such as prometheus, grafana, restic, etc.
|
||||
4. `kana`: Yet another NixOS VM running some common applications, such as hompage, file browser, torrent downloader, etc.
|
||||
3. Homelab:
|
||||
1. `tailscale_gw`: A tailscale subnet router(gateway) for accessing my homelab remotely. NixOS VM running on Proxmox.
|
||||
4. `rolling_girls`: My RISCV64 hosts.
|
||||
1. `nozomi`: Lichee Pi 4A, TH1520(4xC910@2.0G), 8GB RAM + 32G eMMC + 64G SD Card.
|
||||
2. `yukina`: Lichee Pi 4A(Internal Test Version), TH1520(4xC910@2.0G), 8GB RAM + 8G eMMC + 128G SD Card.
|
||||
3. `chiaya`: Milk-V Mars, JH7110(4xU74@1.5 GHz), 4G RAM + No eMMC + 64G SD Card.
|
||||
4. `12kingdoms`:
|
||||
1. `shoukei`: NixOS on Macbook Pro 2022 Intel i5, 13.3-inch, 16G RAM + 512G SSD.
|
||||
5. `12kingdoms`:
|
||||
1. `shoukei`: NixOS on Macbook Pro 2020 Intel i5, 13.3-inch, 16G RAM + 512G SSD.
|
||||
1. `suzu`: Orange Pi 5, RK3588s(4xA76 + 4xA55), GPU(4Cores, Mail-G610), NPU(6Tops@int8), 8G RAM + 256G SSD.
|
||||
1. `rakushun`: Orange Pi 5 Plus, RK3588(4xA76 + 4xA55), GPU(4Cores, Mail-G610), NPU(6Tops@int8), 16G RAM + 2T SSD.
|
||||
6. `kubernetes`: My Kubernetes Cluster
|
||||
|
||||
## idols - Oshi no Ko
|
||||
|
||||
# idols - Oshi no Ko
|
||||
|
||||
These four servers are named after the four main characters of the mange/anime Oshi no Ko, they form a NixOS distributed building cluster,
|
||||
I usually run the build command on `Ai` and nix will distribute the build to other three machines, which is convenient and fast.
|
||||
|
||||
When building some packages for riscv64 or aarch64, I often have no cache available because of various changes under the hood, so I need to build much more packages than usual, which is one of the reasons why the cluster was originally built, and another reason is distributed building is cool!
|
||||
|
||||

|
||||
|
||||

|
||||
These four servers are named after the four main characters of the mange/anime Oshi no Ko.
|
||||
|
||||
## rolling girls
|
||||
|
||||
@@ -34,6 +30,16 @@ My All RISCV64 hosts.
|
||||
|
||||

|
||||
|
||||
## Distributed Building
|
||||
|
||||
I usually run the build command on `Ai` and nix will distribute the build to other NixOS machines, which is convenient and fast.
|
||||
|
||||
When building some packages for riscv64 or aarch64, I often have no cache available because of various changes under the hood, so I need to build much more packages than usual, which is one of the reasons why the cluster was originally built, and another reason is distributed building is cool!
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## References
|
||||
|
||||
[Oshi no Ko 【推しの子】 - Wikipedia](https://en.wikipedia.org/wiki/Oshi_no_Ko):
|
||||
@@ -49,3 +55,5 @@ My All RISCV64 hosts.
|
||||
|
||||

|
||||

|
||||
|
||||
[List of Frieren characters](https://en.wikipedia.org/wiki/List_of_Frieren_characters)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
{vars_networking, mylib, ...}:
|
||||
#############################################################
|
||||
#
|
||||
# Tailscale Gateway(homelab subnet router) - a NixOS VM running on Proxmox
|
||||
#
|
||||
#############################################################
|
||||
let
|
||||
hostName = "tailscale-gw"; # Define your hostname.
|
||||
hostAddress = vars_networking.hostAddress.${hostName};
|
||||
in {
|
||||
imports = mylib.scanPaths ./.;
|
||||
|
||||
# supported file systems, so we can mount any removable disks with these filesystems
|
||||
boot.supportedFilesystems = [
|
||||
"ext4"
|
||||
"btrfs"
|
||||
"xfs"
|
||||
"fat"
|
||||
"vfat"
|
||||
"exfat"
|
||||
];
|
||||
|
||||
networking = {
|
||||
inherit hostName;
|
||||
inherit (vars_networking) nameservers;
|
||||
|
||||
# Use mainGateway instead of defaultGateway to make NAT Traversal work
|
||||
defaultGateway = vars_networking.mainGateway;
|
||||
|
||||
networkmanager.enable = false;
|
||||
interfaces.ens18 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [hostAddress];
|
||||
};
|
||||
};
|
||||
|
||||
# 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 = "23.11"; # Did you read the comment?
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
# =============================================================
|
||||
#
|
||||
# Tailscale - your own private network(VPN) that uses WireGuard
|
||||
#
|
||||
# It's open souce and free for personal use,
|
||||
# and it's really easy to setup and use.
|
||||
# Tailscale has great client coverage for Linux, windows, Mac, android, and iOS.
|
||||
# Tailscale is more mature and stable compared to other alternatives such as netbird/netmaker.
|
||||
# Maybe I'll give netbird/netmaker a try when they are more mature, but for now, I'm sticking with Tailscale.
|
||||
#
|
||||
# How to use:
|
||||
# 1. Create a Tailscale account at https://login.tailscale.com
|
||||
# 2. Login via `tailscale login`
|
||||
# 3. join into your Tailscale network via `tailscale up --advertise-routes 192.168.5.0/24`
|
||||
# 4. If you prefer automatic connection to Tailscale, use the `authKeyFile` option` in the config below.
|
||||
#
|
||||
# Status Data:
|
||||
# `journalctl -u tailscaled` shows tailscaled's logs
|
||||
# logs indicate that tailscale store its data in /var/lib/tailscale
|
||||
# which is already persistent across reboots(via impermanence.nix)
|
||||
#
|
||||
# References:
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/services/networking/tailscale.nix
|
||||
#
|
||||
# =============================================================
|
||||
{
|
||||
# make the tailscale command usable to users
|
||||
environment.systemPackages = [pkgs.tailscale];
|
||||
|
||||
# enable the tailscale service
|
||||
services.tailscale = {
|
||||
enable = true;
|
||||
port = 41641;
|
||||
interfaceName = "tailscale0";
|
||||
# allow the Tailscale UDP port through the firewall
|
||||
openFirewall = true;
|
||||
useRoutingFeatures = "server";
|
||||
extraUpFlags = "--advertise-routes 192.168.5.0/24";
|
||||
# authKeyFile = "/var/lib/tailscale/authkey";
|
||||
};
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
config,
|
||||
username,
|
||||
...
|
||||
}: {
|
||||
# mount a smb/cifs share
|
||||
fileSystems."/home/${username}/SMB-Downloads" = {
|
||||
device = "//192.168.5.194/Downloads";
|
||||
fsType = "cifs";
|
||||
options = [
|
||||
"vers=3.0,uid=1000,gid=100,dir_mode=0755,file_mode=0755,mfsymlinks,credentials=${config.age.secrets.smb-credentials.path},nofail"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#############################################################
|
||||
#
|
||||
# Aquamarine - A NixOS VM running on Proxmox
|
||||
#
|
||||
#############################################################
|
||||
{
|
||||
# Enable binfmt emulation of aarch64-linux, this is required for cross compilation.
|
||||
boot.binfmt.emulatedSystems = ["aarch64-linux" "riscv64-linux"];
|
||||
# supported fil systems, so we can mount any removable disks with these filesystems
|
||||
boot.supportedFilesystems = [
|
||||
"ext4"
|
||||
"btrfs"
|
||||
"xfs"
|
||||
#"zfs"
|
||||
"ntfs"
|
||||
"fat"
|
||||
"vfat"
|
||||
"exfat"
|
||||
"cifs" # mount windows share
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "aquamarine"; # Define your hostname.
|
||||
wireless.enable = false; # Enables wireless support via wpa_supplicant.
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# proxy.default = "http://user:password@proxy:port/";
|
||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
networkmanager.enable = true;
|
||||
interfaces.ens18 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "192.168.5.101";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
};
|
||||
defaultGateway = "192.168.5.201";
|
||||
nameservers = [
|
||||
"119.29.29.29" # DNSPod
|
||||
"223.5.5.5" # AliDNS
|
||||
];
|
||||
};
|
||||
|
||||
# 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 = "23.11"; # Did you read the comment?
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
{
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
{
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
{
|
||||
}
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
Related:
|
||||
|
||||
- [/nixos-installer/README.shoukei.md](/nixos-installer/README.ai.md)
|
||||
- [/nixos-installer/README.md](/nixos-installer/README.md)
|
||||
|
||||
## TODOs
|
||||
|
||||
1. Install DCGM-Exporter on `ai` to monitor the GPU status.
|
||||
|
||||
## Info
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
config,
|
||||
username,
|
||||
...
|
||||
}: {
|
||||
# mount a smb/cifs share
|
||||
fileSystems."/home/${username}/SMB-Downloads" = {
|
||||
device = "//192.168.5.194/Downloads";
|
||||
fsType = "cifs";
|
||||
options = [
|
||||
# https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html
|
||||
"nofail,_netdev"
|
||||
"uid=1000,gid=100,dir_mode=0755,file_mode=0755"
|
||||
"vers=3.0,credentials=${config.age.secrets.smb-credentials.path}"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
{vars_networking, ...}:
|
||||
#############################################################
|
||||
#
|
||||
# Ai - my main computer, with NixOS + I5-13600KF + RTX 4090 GPU, for gaming & daily use.
|
||||
#
|
||||
#############################################################
|
||||
{
|
||||
let
|
||||
hostName = "ai"; # Define your hostname.
|
||||
hostAddress = vars_networking.hostAddress.${hostName};
|
||||
in {
|
||||
imports = [
|
||||
./cifs-mount.nix
|
||||
# Include the results of the hardware scan.
|
||||
@@ -14,30 +18,16 @@
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "ai";
|
||||
inherit hostName;
|
||||
inherit (vars_networking) defaultGateway nameservers;
|
||||
|
||||
wireless.enable = false; # Enables wireless support via wpa_supplicant.
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# proxy.default = "http://user:password@proxy:port/";
|
||||
# proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
networkmanager.enable = true;
|
||||
|
||||
enableIPv6 = false; # disable ipv6
|
||||
# configures the network interface(include wireless) via `nmcli` & `nmtui`
|
||||
networkmanager.enable = false;
|
||||
interfaces.enp5s0 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "192.168.5.100";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv4.addresses = [hostAddress];
|
||||
};
|
||||
defaultGateway = "192.168.5.201";
|
||||
nameservers = [
|
||||
"119.29.29.29" # DNSPod
|
||||
"223.5.5.5" # AliDNS
|
||||
];
|
||||
};
|
||||
|
||||
# conflict with feature: containerd-snapshotter
|
||||
+18
-4
@@ -23,7 +23,8 @@
|
||||
|
||||
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = ["kvm-intel"];
|
||||
boot.kernelModules = ["kvm-intel"]; # kvm virtualization support
|
||||
boot.extraModprobeConfig = "options kvm_intel nested=1"; # for intel cpu
|
||||
boot.kernelParams = ["nvidia.NVreg_PreserveVideoMemoryAllocations=1"];
|
||||
boot.extraModulePackages = [];
|
||||
# clear /tmp on boot to get a stateless /tmp directory.
|
||||
@@ -31,7 +32,7 @@
|
||||
|
||||
# Enable binfmt emulation of aarch64-linux, this is required for cross compilation.
|
||||
boot.binfmt.emulatedSystems = ["aarch64-linux" "riscv64-linux"];
|
||||
# supported fil systems, so we can mount any removable disks with these filesystems
|
||||
# supported file systems, so we can mount any removable disks with these filesystems
|
||||
boot.supportedFilesystems = [
|
||||
"ext4"
|
||||
"btrfs"
|
||||
@@ -45,7 +46,9 @@
|
||||
boot.initrd = {
|
||||
# unlocked luks devices via a keyfile or prompt a passphrase.
|
||||
luks.devices."crypted-nixos" = {
|
||||
device = "/dev/nvme0n1p2";
|
||||
# NOTE: DO NOT use device name here(like /dev/sda, /dev/nvme0n1p2, etc), use UUID instead.
|
||||
# https://github.com/ryan4yin/nix-config/issues/43
|
||||
device = "/dev/disk/by-uuid/a21ca82a-9ee6-4e5c-9d3f-a93e84e4e0f4";
|
||||
# the keyfile(or device partition) that should be used as the decryption key for the encrypted device.
|
||||
# if not specified, you will be prompted for a passphrase instead.
|
||||
#keyFile = "/root-part.key";
|
||||
@@ -53,6 +56,10 @@
|
||||
# whether to allow TRIM requests to the underlying device.
|
||||
# it's less secure, but faster.
|
||||
allowDiscards = true;
|
||||
# Whether to bypass dm-crypt’s internal read and write workqueues.
|
||||
# Enabling this should improve performance on SSDs;
|
||||
# https://wiki.archlinux.org/index.php/Dm-crypt/Specialties#Disable_workqueue_for_increased_solid_state_drive_(SSD)_performance
|
||||
bypassWorkqueues = true;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -71,6 +78,13 @@
|
||||
options = ["subvol=@nix" "noatime" "compress-force=zstd:1"];
|
||||
};
|
||||
|
||||
# for guix store, which use `/gnu/store` as its store directory.
|
||||
fileSystems."/gnu" = {
|
||||
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=@guix" "noatime" "compress-force=zstd:1"];
|
||||
};
|
||||
|
||||
fileSystems."/persistent" = {
|
||||
device = "/dev/disk/by-uuid/1167076c-dee1-486c-83c1-4b1af37555cd";
|
||||
fsType = "btrfs";
|
||||
@@ -109,7 +123,7 @@
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/nvme0n1p1";
|
||||
device = "/dev/disk/by-uuid/90FB-9F88";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
Host github.com
|
||||
# github is controlled by gluttony~
|
||||
IdentityFile ~/.ssh/gluttony
|
||||
IdentityFile ~/.ssh/idols-ai
|
||||
# Specifies that ssh should only use the identity file explicitly configured above
|
||||
# required to prevent sending default identity files first.
|
||||
IdentitiesOnly yes
|
||||
@@ -72,6 +72,19 @@
|
||||
directory = ".ssh";
|
||||
mode = "0700";
|
||||
}
|
||||
|
||||
# misc
|
||||
".config/pulse"
|
||||
".config/attic" # attic nix cache server
|
||||
".pki"
|
||||
".steam" # steam games
|
||||
|
||||
# cloud native
|
||||
{
|
||||
# pulumi - infrastructure as code
|
||||
directory = ".pulumi";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".aws";
|
||||
mode = "0700";
|
||||
@@ -85,10 +98,6 @@
|
||||
mode = "0700";
|
||||
}
|
||||
|
||||
# misc
|
||||
".config/pulse"
|
||||
".pki"
|
||||
|
||||
# remote desktop
|
||||
".config/remmina"
|
||||
".config/freerdp"
|
||||
@@ -97,6 +106,12 @@
|
||||
".config/emacs"
|
||||
"org" # org files
|
||||
|
||||
# vscode
|
||||
".vscode"
|
||||
".vscode-insiders"
|
||||
".config/Code/User"
|
||||
".config/Code - Insiders/User"
|
||||
|
||||
# browsers
|
||||
".mozilla"
|
||||
".config/google-chrome"
|
||||
@@ -107,6 +122,7 @@
|
||||
|
||||
# language package managers
|
||||
".npm"
|
||||
".conda" # generated by `conda-shell`
|
||||
"go"
|
||||
|
||||
# neovim plugins(wakatime & copilot)
|
||||
@@ -0,0 +1,42 @@
|
||||
# Idols - Aquamarine
|
||||
|
||||
A router(IPv4 only) with a tranparent proxy to bypass the G|F|W.
|
||||
|
||||
NOTE: dae(running on aquamarine) do not provides a http/socks5 proxy server, so a v2ray server is running on [idols_kana](../idols_kana/proxy.nix) to provides a http/socks5 proxy service.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Can not access the global internet
|
||||
|
||||
1. Check wether the subscription url is accessible.
|
||||
- If not, then you need to get a new subscription url and update the `dae`'s configuration.
|
||||
1. Check the `dae` service's log by `journalctl -u dae -n 1000`.
|
||||
|
||||
### DNS cannot be resolved
|
||||
|
||||
1. `sudo systemctl stop dae`, then try to resolve the domain name again.
|
||||
- If it works, the problem is caused by `dae` service.
|
||||
- check dae's log by `journalctl -u dae -n 1000`
|
||||
1. DNS & DHCP is provided by `dnsmasq` service, check the configuration of `dnsmasq`.
|
||||
|
||||
### DHCP cannot be obtained
|
||||
|
||||
1. `ss -tunlp`, check if `dnsmasq` is running and listening on udp port 67.
|
||||
1. `journalctl -u dnsmasq -n 1000` to check the log of `dnsmasq`.
|
||||
1. Request a new IP address by disconnect and reconnect one of your devices' wifi.
|
||||
1. `nix shell nixpkgs#dhcpdump` and then `sudo dhcpdump -i br-lan`, check if the DHCP request is received by `dnsmasq`.
|
||||
1. The server listens on UDP port number 67, and the client listens on UDP port number 68.
|
||||
1. DHCP operations fall into four phases:
|
||||
1. Server **discovery**: The DHCP client broadcasts a DHCPDISCOVER message on the network subnet using the destination address 255.255.255.255 (limited broadcast) or the specific subnet broadcast address (directed broadcast).
|
||||
1. IP lease **offer**: When a DHCP server receives a DHCPDISCOVER message from a client, which is an IP address lease request, the DHCP server reserves an IP address for the client and makes a lease offer by sending a DHCPOFFER message to the client.
|
||||
1. IP lease **request**: In response to the DHCP offer, the client replies with a DHCPREQUEST message, broadcast to the server,[a] requesting the offered address.
|
||||
1. IP lease **acknowledgement**: When the DHCP server receives the DHCPREQUEST message from the client, it sends a DHCPACK packet to the client, which includes the lease duration and any other configuration information that the client might have requested.
|
||||
1. So if you see only `DISCOVER` messages, the dhsmasq is not working properly.
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- <https://github.com/ghostbuster91/blogposts/blob/main/router2023-part2/main.md>
|
||||
- <https://github.com/ghostbuster91/nixos-router>
|
||||
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
# https://github.com/daeuniverse/dae/discussions/81
|
||||
# https://github.com/daeuniverse/dae/blob/main/example.dae
|
||||
|
||||
# load all dae files placed in ./config.d/
|
||||
include {
|
||||
config.d/*.dae
|
||||
}
|
||||
global {
|
||||
##### Software options.
|
||||
|
||||
# tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.
|
||||
# In normal case, you do not need to use it.
|
||||
tproxy_port: 12345
|
||||
|
||||
# Set it true to protect tproxy port from unsolicited traffic. Set it false to allow users to use self-managed
|
||||
# iptables tproxy rules.
|
||||
tproxy_port_protect: true
|
||||
|
||||
# If not zero, traffic sent from dae will be set SO_MARK. It is useful to avoid traffic loop with iptables tproxy
|
||||
# rules.
|
||||
so_mark_from_dae: 1
|
||||
|
||||
# Log level: error, warn, info, debug, trace.
|
||||
log_level: info
|
||||
|
||||
# Disable waiting for network before pulling subscriptions.
|
||||
disable_waiting_network: false
|
||||
|
||||
|
||||
##### Interface and kernel options.
|
||||
|
||||
# The LAN interface to bind. Use it if you want to proxy LAN.
|
||||
# Multiple interfaces split by ",".
|
||||
lan_interface: br-lan
|
||||
|
||||
# The WAN interface to bind. Use it if you want to proxy localhost.
|
||||
# Multiple interfaces split by ",". Use "auto" to auto detect.
|
||||
#
|
||||
# Disable this to avoid problems with the proxy server that prevent the subscription link from being updated
|
||||
# wan_interface: auto
|
||||
|
||||
# Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out
|
||||
# https://github.com/daeuniverse/dae/blob/main/docs/en/user-guide/kernel-parameters.md to see what will dae do.
|
||||
auto_config_kernel_parameter: false
|
||||
|
||||
##### Node connectivity check.
|
||||
|
||||
# Host of URL should have both IPv4 and IPv6 if you have double stack in local.
|
||||
# First is URL, others are IP addresses if given.
|
||||
# Considering traffic consumption, it is recommended to choose a site with anycast IP and less response.
|
||||
#tcp_check_url: 'http://cp.cloudflare.com'
|
||||
tcp_check_url: 'http://cp.cloudflare.com,1.1.1.1,2606:4700:4700::1111'
|
||||
|
||||
# The HTTP request method to `tcp_check_url`. Use 'HEAD' by default because some server implementations bypass
|
||||
# accounting for this kind of traffic.
|
||||
tcp_check_http_method: HEAD
|
||||
|
||||
# This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check
|
||||
# TCP DNS connectivity of nodes.
|
||||
# First is URL, others are IP addresses if given.
|
||||
# This DNS should have both IPv4 and IPv6 if you have double stack in local.
|
||||
#udp_check_dns: 'dns.google.com:53'
|
||||
udp_check_dns: 'dns.google.com:53,8.8.8.8,2001:4860:4860::8888'
|
||||
|
||||
check_interval: 30s
|
||||
|
||||
# Group will switch node only when new_latency <= old_latency - tolerance.
|
||||
check_tolerance: 50ms
|
||||
|
||||
|
||||
##### Connecting options.
|
||||
|
||||
# Optional values of dial_mode are:
|
||||
# 1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path
|
||||
# respectively, and makes the IP version requested by the application meet expectations. For example, if you
|
||||
# use curl -4 ip.sb, you will request IPv4 via proxy and get a IPv4 echo. And curl -6 ip.sb will request IPv6.
|
||||
# This may solve some wierd full-cone problem if your are be your node support that. Sniffing will be disabled
|
||||
# in this mode.
|
||||
# 2. "domain". Dial proxy using the domain from sniffing. This will relieve DNS pollution problem to a great extent
|
||||
# if have impure DNS environment. Generally, this mode brings faster proxy response time because proxy will
|
||||
# re-resolve the domain in remote, thus get better IP result to connect. This policy does not impact routing.
|
||||
# That is to say, domain rewrite will be after traffic split of routing and dae will not re-route it.
|
||||
# 3. "domain+". Based on domain mode but do not check the reality of sniffed domain. It is useful for users whose
|
||||
# DNS requests do not go through dae but want faster proxy response time. Notice that, if DNS requests do not
|
||||
# go through dae, dae cannot split traffic by domain.
|
||||
# 4. "domain++". Based on domain+ mode but force to re-route traffic using sniffed domain to partially recover
|
||||
# domain based traffic split ability. It doesn't work for direct traffic and consumes more CPU resources.
|
||||
dial_mode: domain
|
||||
|
||||
# Allow insecure TLS certificates. It is not recommended to turn it on unless you have to.
|
||||
allow_insecure: false
|
||||
|
||||
# Timeout to waiting for first data sending for sniffing. It is always 0 if dial_mode is ip. Set it higher is useful
|
||||
# in high latency LAN network.
|
||||
sniffing_timeout: 100ms
|
||||
|
||||
# TLS implementation. tls is to use Go's crypto/tls. utls is to use uTLS, which can imitate browser's Client Hello.
|
||||
tls_implementation: tls
|
||||
|
||||
# The Client Hello ID for uTLS to imitate. This takes effect only if tls_implementation is utls.
|
||||
# See more: https://github.com/daeuniverse/dae/blob/331fa23c16/component/outbound/transport/tls/utls.go#L17
|
||||
utls_imitate: chrome_auto
|
||||
}
|
||||
|
||||
# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/dns.md for full examples.
|
||||
dns {
|
||||
# For example, if ipversion_prefer is 4 and the domain name has both type A and type AAAA records, the dae will only
|
||||
# respond to type A queries and response empty answer to type AAAA queries.
|
||||
ipversion_prefer: 4
|
||||
|
||||
# Give a fixed ttl for domains. Zero means that dae will request to upstream every time and not cache DNS results
|
||||
# for these domains.
|
||||
#fixed_domain_ttl {
|
||||
# ddns.example.org: 10
|
||||
# test.example.org: 3600
|
||||
#}
|
||||
|
||||
upstream {
|
||||
# Value can be scheme://host:port, where the scheme can be tcp/udp/tcp+udp.
|
||||
# If host is a domain and has both IPv4 and IPv6 record, dae will automatically choose
|
||||
# IPv4 or IPv6 to use according to group policy (such as min latency policy).
|
||||
# Please make sure DNS traffic will go through and be forwarded by dae, which is REQUIRED for domain routing.
|
||||
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
||||
|
||||
alidns: 'udp://223.5.5.5:53'
|
||||
googledns: 'tcp+udp://8.8.8.8:53'
|
||||
}
|
||||
routing {
|
||||
# According to the request of dns query, decide to use which DNS upstream.
|
||||
# Match rules from top to bottom.
|
||||
request {
|
||||
# Lookup China mainland domains using alidns, otherwise googledns.
|
||||
qname(geosite:cn) -> alidns
|
||||
# fallback is also called default.
|
||||
fallback: googledns
|
||||
|
||||
# other custom rules
|
||||
qname(full:analytics.google.com) -> googledns # do not block google analytics(console)
|
||||
qname(regex: '.+\.nixos.org$') -> googledns
|
||||
qname(geosite:category-ads) -> reject
|
||||
qname(geosite:category-ads-all) -> reject
|
||||
qtype(aaaa) -> reject
|
||||
qname(regex: '.+\.linkedin$') -> googledns
|
||||
}
|
||||
|
||||
# According to the response of dns query, decide to accept or re-lookup using another DNS upstream.
|
||||
# Match rules from top to bottom.
|
||||
response {
|
||||
# Trusted upstream. Always accept its result.
|
||||
upstream(googledns) -> accept
|
||||
|
||||
# Possibly polluted(domain resolved to a private ip), re-lookup using googledns.
|
||||
ip(geoip:private) && !qname(geosite:cn) -> googledns
|
||||
|
||||
fallback: accept
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Node group (outbound).
|
||||
group {
|
||||
proxy {
|
||||
filter: name(keyword: 'Hong Kong')
|
||||
filter: name(keyword: '香港')
|
||||
filter: name(keyword: 'Singapore')
|
||||
filter: name(keyword: '新加坡')
|
||||
# Filter nodes and give a fixed latency offset to archive latency-based failover.
|
||||
# In this example, there is bigger possibility to choose US node even if original latency of US node is higher.
|
||||
filter: name(keyword: 'USA') [add_latency: -500ms]
|
||||
filter: name(keyword: '美国') [add_latency: -500ms]
|
||||
filter: name(keyword: 'UK') [add_latency: -300ms]
|
||||
# filter: name(keyword: '英国') [add_latency: -300ms]
|
||||
# filter: name(keyword: 'Japan') [add_latency: 300ms]
|
||||
# filter: name(keyword: '日本') [add_latency: 300ms]
|
||||
|
||||
# Other filters:
|
||||
# Filter nodes from the global node pool defined by the subscription and node section above.
|
||||
# filter: subtag(regex: '^my_', another_sub) && !name(keyword: 'ExpireAt:')
|
||||
# Filter nodes from the global node pool defined by tag.
|
||||
# filter: name('node_a','node_b')
|
||||
|
||||
# Select the node with min average of the last 10 latencies from the group for every connection.
|
||||
policy: min_avg10
|
||||
# Other policies:
|
||||
# random - Randomly select a node from the group for every connection.
|
||||
# fixed(0) - Select the first node from the group for every connection.
|
||||
# min - Select the node with min last latency from the group for every connection.
|
||||
# min_moving_avg - Select the node with min moving average of latencies from the group for every connection.
|
||||
}
|
||||
|
||||
media {
|
||||
filter: name(keyword: 'Hong Kong')
|
||||
filter: name(keyword: '香港')
|
||||
filter: name(keyword: 'Singapore')
|
||||
filter: name(keyword: '新加坡')
|
||||
filter: name(keyword: 'USA') [add_latency: -500ms]
|
||||
filter: name(keyword: '美国') [add_latency: -500ms]
|
||||
filter: name(keyword: 'UK') [add_latency: -300ms]
|
||||
filter: name(keyword: '英国') [add_latency: -300ms]
|
||||
filter: name(keyword: 'Japan') [add_latency: 300ms]
|
||||
filter: name(keyword: '日本') [add_latency: 300ms]
|
||||
|
||||
policy: min_avg10
|
||||
}
|
||||
|
||||
ssh-proxy {
|
||||
filter: name(keyword: 'UK')
|
||||
filter: name(keyword: '英国')
|
||||
policy: min_avg10
|
||||
}
|
||||
|
||||
sg {
|
||||
filter: name(keyword: 'Singapore')
|
||||
filter: name(keyword: '新加坡')
|
||||
policy: min_avg10
|
||||
}
|
||||
|
||||
usa {
|
||||
filter: name(keyword: 'USA')
|
||||
filter: name(keyword: '美国')
|
||||
policy: min_avg10
|
||||
}
|
||||
}
|
||||
|
||||
# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md for full examples.
|
||||
# Pname has the highest priority, so should be placed in the front.
|
||||
# Priority of other rules is the same as the order of the rules defined in this file.
|
||||
routing {
|
||||
### Preset rules.
|
||||
|
||||
# Network managers in localhost should be direct to
|
||||
# avoid false negative network connectivity check when binding to WAN.
|
||||
pname(NetworkManager) -> direct
|
||||
pname(systemd-networkd) -> direct
|
||||
|
||||
# Put it in the front to prevent broadcast, multicast and other packets that should be sent to the LAN from being
|
||||
# forwarded by the proxy.
|
||||
# "dip" means destination IP.
|
||||
dip(224.0.0.0/3, 'ff00::/8') -> direct
|
||||
|
||||
# This line allows you to access private addresses directly instead of via your proxy. If you really want to access
|
||||
# private addresses in your proxy host network, modify the below line.
|
||||
dip(geoip:private) -> direct
|
||||
|
||||
# --- Core rules ---#
|
||||
|
||||
# Disable HTTP3(QUIC) because it usually consumes too much cpu/mem resources.
|
||||
l4proto(udp) && dport(443) -> block
|
||||
|
||||
# Direct access to all Chinese mainland-related IP addresses
|
||||
dip(geoip:cn) -> direct
|
||||
domain(geosite:cn) -> direct
|
||||
|
||||
# Block ads
|
||||
domain(full:analytics.google.com) -> proxy # do not block google analytics(console)
|
||||
domain(geosite:category-ads) -> block
|
||||
domain(geosite:category-ads-all) -> block
|
||||
|
||||
# DNS
|
||||
dip(8.8.8.8, 8.8.4.4) -> proxy
|
||||
dip(223.5.5.5, 223.6.6.6) -> direct
|
||||
domain(full:dns.alidns.com) -> direct
|
||||
domain(full:dns.googledns.com) -> proxy
|
||||
domain(full:dns.opendns.com) -> proxy
|
||||
|
||||
# --- Rules for other commonly used sites ---#
|
||||
|
||||
# SSH - tcp port 22 is blocked by many proxy servers.
|
||||
dport(22) && !dip(geoip:cn) && !domain(geosite:cn) -> ssh-proxy
|
||||
|
||||
### OpenAI
|
||||
domain(geosite:openai) -> sg
|
||||
domain(regex:'.+\.openai$') -> sg
|
||||
|
||||
### Media
|
||||
domain(geosite:netflix) -> media
|
||||
|
||||
### Proxy
|
||||
domain(suffix: linkedin.com) -> proxy
|
||||
domain(keyword:'linkedin') -> proxy
|
||||
domain(regex:'.+\.linkedin\.com$') -> proxy
|
||||
domain(regex:'.+\.quay\.io$') -> proxy
|
||||
domain(regex:'.+\.notion\.so$') -> proxy
|
||||
domain(regex:'.+\.amazon\.com$') -> proxy
|
||||
domain(regex:'.+\.oracle\.com$') -> proxy
|
||||
domain(regex:'.+\.docker\.com$') -> proxy
|
||||
domain(regex:'.+\.kubernetes\.io$') -> proxy
|
||||
domain(regex:'.+\.nixos\.org$') -> proxy
|
||||
|
||||
domain(geosite:microsoft) -> proxy
|
||||
domain(geosite:linkedin) -> proxy
|
||||
domain(geosite:twitter) -> proxy
|
||||
domain(geosite:telegram) -> proxy
|
||||
domain(geosite:google) -> proxy
|
||||
domain(geosite:apple) -> proxy
|
||||
domain(geosite:category-container) -> proxy
|
||||
domain(geosite:category-dev) -> proxy
|
||||
domain(geosite:google-scholar) -> proxy
|
||||
domain(geosite:category-scholar-!cn) -> proxy
|
||||
|
||||
### Direct
|
||||
domain(regex:'.+\.edu\.cn$') -> direct
|
||||
domain(keyword:'baidu') -> direct
|
||||
domain(keyword:'bilibili') -> direct
|
||||
domain(keyword:'taobao') -> direct
|
||||
domain(keyword:'alibabadns') -> direct
|
||||
domain(keyword:'alicdn') -> direct
|
||||
domain(keyword:'tbcache') -> direct
|
||||
domain(keyword:'zhihu') -> direct
|
||||
domain(keyword:'douyu') -> direct
|
||||
domain(geosite:cloudflare-cn) -> direct
|
||||
|
||||
# --- Fallback rules ---#
|
||||
|
||||
# Access all other foreign sites
|
||||
domain(geosite:geolocation-!cn) -> proxy
|
||||
!dip(geoip:cn) -> proxy
|
||||
|
||||
fallback: direct
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user