Compare commits
18 Commits
cdeada1f86
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| bc410d8e09 | |||
| f0025dfde3 | |||
| 20c2bae21d | |||
| 54db6ce681 | |||
| fe57aa7f4a | |||
| cb6a6f9f46 | |||
| ed651788b4 | |||
| 90801ae7c7 | |||
| 2a14d62d83 | |||
| 4846c84d21 | |||
| fcfc996d3c | |||
| 5d7d490636 | |||
| a0e4d98402 | |||
| 54940016c5 | |||
| fa03b166a4 | |||
| a99ae65e59 | |||
| 7e407cb189 | |||
| edcf5b8eb9 |
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
||||
|
||||
@@ -30,4 +9,4 @@ print_info "Applying configuration for $HOSTNAME"
|
||||
|
||||
nix run nix-darwin -- switch --flake ".#$HOSTNAME" "${@:2}"
|
||||
|
||||
print_success "Configuration applied successfully"
|
||||
print_success "Configuration applied successfully"
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
||||
|
||||
@@ -34,4 +13,4 @@ if [[ -L ./result ]]; then
|
||||
unlink ./result
|
||||
fi
|
||||
|
||||
print_success "Build completed successfully"
|
||||
print_success "Build completed successfully"
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
||||
|
||||
@@ -45,4 +24,4 @@ if [[ -L ./result ]]; then
|
||||
unlink ./result
|
||||
fi
|
||||
|
||||
print_success "Build and switch completed successfully"
|
||||
print_success "Build and switch completed successfully"
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
print_info "Available generations:"
|
||||
darwin-rebuild --list-generations
|
||||
@@ -38,4 +17,4 @@ fi
|
||||
print_warning "Rolling back to generation $GEN_NUM..."
|
||||
darwin-rebuild switch --switch-generation "$GEN_NUM"
|
||||
|
||||
print_success "Rollback to generation $GEN_NUM complete"
|
||||
print_success "Rollback to generation $GEN_NUM complete"
|
||||
|
||||
23
apps/common.sh
Normal file
23
apps/common.sh
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[OK]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
HOSTNAME="${1:-$(hostname)}"
|
||||
|
||||
@@ -34,4 +13,4 @@ else
|
||||
nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
||||
fi
|
||||
|
||||
print_success "Configuration applied successfully"
|
||||
print_success "Configuration applied successfully"
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
HOSTNAME="${1:-$(hostname)}"
|
||||
|
||||
@@ -34,4 +13,4 @@ if [[ -L ./result ]]; then
|
||||
unlink ./result
|
||||
fi
|
||||
|
||||
print_success "Build completed successfully"
|
||||
print_success "Build completed successfully"
|
||||
|
||||
@@ -1,24 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
HOSTNAME="${1:-$(hostname)}"
|
||||
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}📘${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚡${NC} $1"
|
||||
}
|
||||
source "$(dirname "$0")/../common.sh"
|
||||
|
||||
print_info "Available generations:"
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
@@ -48,4 +27,4 @@ else
|
||||
/nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||
fi
|
||||
|
||||
print_success "Rollback to generation $GEN_NUM complete"
|
||||
print_success "Rollback to generation $GEN_NUM complete"
|
||||
|
||||
227
flake.lock
generated
227
flake.lock
generated
@@ -16,32 +16,13 @@
|
||||
"url": "https://tangled.org/@jakelazaroff.com/actor-typeahead"
|
||||
}
|
||||
},
|
||||
"beads": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765103675,
|
||||
"narHash": "sha256-PCsU2GwrPYFAE2KTCdk60E6ZTPRtgNdbPF+bzf8qi3Q=",
|
||||
"owner": "steveyegge",
|
||||
"repo": "beads",
|
||||
"rev": "08d8353619777dfdd4119477ca029689597cec60",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "steveyegge",
|
||||
"repo": "beads",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"blueprint": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-ai-tools",
|
||||
"llm-agents",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems_2"
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1763308703,
|
||||
@@ -96,11 +77,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765065051,
|
||||
"narHash": "sha256-b7W9WsvyMOkUScNxbzS45KEJp0iiqRPyJ1I3JBE+oEE=",
|
||||
"lastModified": 1765684049,
|
||||
"narHash": "sha256-svCS2r984qEowMT0y3kCrsD/m0J6zaF5I/UusS7QaH0=",
|
||||
"owner": "LnL7",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "7e22bf538aa3e0937effcb1cee73d5f1bcc26f79",
|
||||
"rev": "9b628e171bfaea1a3d1edf31eee46251e0fe4a33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -117,11 +98,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765326679,
|
||||
"narHash": "sha256-fTLX9kDwLr9Y0rH/nG+h1XG5UU+jBcy0PFYn5eneRX8=",
|
||||
"lastModified": 1765794845,
|
||||
"narHash": "sha256-YD5QWlGnusNbZCqR3pxG8tRxx9yUXayLZfAJRWspq2s=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "d64e5cdca35b5fad7c504f615357a7afe6d9c49e",
|
||||
"rev": "7194cfe5b7a3660726b0fe7296070eaef601cae9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -149,11 +130,11 @@
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1763759067,
|
||||
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
|
||||
"lastModified": 1765835352,
|
||||
"narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
|
||||
"rev": "a34fae9c08a15ad73f295041fec82323541400a9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -170,11 +151,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1763759067,
|
||||
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
|
||||
"lastModified": 1765495779,
|
||||
"narHash": "sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
|
||||
"rev": "5635c32d666a59ec9a55cab87e898889869f7b71",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -185,25 +166,7 @@
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
"systems": "systems_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694529238,
|
||||
@@ -219,9 +182,9 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_3": {
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_5"
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
@@ -239,7 +202,7 @@
|
||||
},
|
||||
"gomod2nix": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"tangled",
|
||||
"nixpkgs"
|
||||
@@ -266,11 +229,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765337252,
|
||||
"narHash": "sha256-HuWQp8fM25fyWflbuunQkQI62Hg0ecJxWD52FAgmxqY=",
|
||||
"lastModified": 1765860045,
|
||||
"narHash": "sha256-7Lxp/PfOy4h3QIDtmWG/EgycaswqRSkDX4DGtet14NE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "13cc1efd78b943b98c08d74c9060a5b59bf86921",
|
||||
"rev": "09de9577d47d8bffb11c449b6a3d24e32ac16c99",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -282,11 +245,11 @@
|
||||
"homebrew-cask": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1765436475,
|
||||
"narHash": "sha256-DFaPS71PknrRmGSJ7/acDHwvKDrj2SB85Lir6tpckus=",
|
||||
"lastModified": 1765872721,
|
||||
"narHash": "sha256-RBrwNiYWYca11tT78S9rN7mt3IemIHKjCcAiB0aM6I4=",
|
||||
"owner": "homebrew",
|
||||
"repo": "homebrew-cask",
|
||||
"rev": "723fa5c3329fb71daa1f258c2592da8a029d371e",
|
||||
"rev": "82be75e553faef02d3ec1bf19a5e7e20f5247ce9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -298,11 +261,11 @@
|
||||
"homebrew-core": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1765439003,
|
||||
"narHash": "sha256-akWPwBqM2QoCAulA+eE5G83KTkitMLZWHk0yW1AV3IM=",
|
||||
"lastModified": 1765878985,
|
||||
"narHash": "sha256-QO81/BHm6ZtV2KrXUXmd1bB0epdkRjTNf6yR7YGJPMo=",
|
||||
"owner": "homebrew",
|
||||
"repo": "homebrew-core",
|
||||
"rev": "689a992c97bffeb817e3b11939867e2080607f2f",
|
||||
"rev": "815c7ad127fcc2027c639fb9c93a211c1f2ff3c5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -377,6 +340,26 @@
|
||||
"url": "https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip"
|
||||
}
|
||||
},
|
||||
"llm-agents": {
|
||||
"inputs": {
|
||||
"blueprint": "blueprint",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765854155,
|
||||
"narHash": "sha256-yrECdmBoMhUAA8FqUJ1LbtDjuwn+38OkFgRrwbEq/DU=",
|
||||
"owner": "numtide",
|
||||
"repo": "llm-agents.nix",
|
||||
"rev": "9ee377d02d7e50e2903d9c7fa53138aebd9ae944",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "llm-agents.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"lucide-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -390,26 +373,6 @@
|
||||
"url": "https://github.com/lucide-icons/lucide/releases/download/0.536.0/lucide-icons-0.536.0.zip"
|
||||
}
|
||||
},
|
||||
"nix-ai-tools": {
|
||||
"inputs": {
|
||||
"blueprint": "blueprint",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765423017,
|
||||
"narHash": "sha256-ZXiMZWSet5gpnTGpc02JQHygDaaBwBEWzgUPx0YEm0c=",
|
||||
"owner": "numtide",
|
||||
"repo": "nix-ai-tools",
|
||||
"rev": "6a717d02c0ded2f96568da6a35ab74962cbbf807",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "nix-ai-tools",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-homebrew": {
|
||||
"inputs": {
|
||||
"brew-src": "brew-src"
|
||||
@@ -430,27 +393,27 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1760284886,
|
||||
"narHash": "sha256-TK9Kr0BYBQ/1P5kAsnNQhmWWKgmZXwUQr4ZMjCzWf2c=",
|
||||
"lastModified": 1765772535,
|
||||
"narHash": "sha256-aq+dQoaPONOSjtFIBnAXseDm9TUhIbe215TPmkfMYww=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cf3f5c4def3c7b5f1fc012b3d839575dbe552d43",
|
||||
"rev": "09b8fda8959d761445f12b55f380d90375a1d6bb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1761765539,
|
||||
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
|
||||
"lastModified": 1765674936,
|
||||
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
|
||||
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -461,27 +424,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1765270179,
|
||||
"narHash": "sha256-g2a4MhRKu4ymR4xwo+I+auTknXt/+j37Lnf0Mvfl1rE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "677fbe97984e7af3175b6c121f3c39ee5c8d62c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1765186076,
|
||||
"narHash": "sha256-hM20uyap1a0M9d344I692r+ik4gTMyj60cQWO+hAYP8=",
|
||||
"lastModified": 1765779637,
|
||||
"narHash": "sha256-KJ2wa/BLSrTqDjbfyNx70ov/HdgNBCBBSQP3BIzKnv4=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "addf7cf5f383a3101ecfba091b98d0a1263dc9b8",
|
||||
"rev": "1306659b587dc277866c7b69eb97e5f07864d8c4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -491,13 +438,13 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1765270179,
|
||||
"narHash": "sha256-g2a4MhRKu4ymR4xwo+I+auTknXt/+j37Lnf0Mvfl1rE=",
|
||||
"lastModified": 1765644376,
|
||||
"narHash": "sha256-yqHBL2wYGwjGL2GUF2w3tofWl8qO9tZEuI4wSqbCrtE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "677fbe97984e7af3175b6c121f3c39ee5c8d62c9",
|
||||
"rev": "23735a82a828372c4ef92c660864e82fbe2f5fbe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -507,7 +454,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1754800730,
|
||||
"narHash": "sha256-HfVZCXic9XLBgybP0318ym3cDnGwBs/+H5MgxFVYF4I=",
|
||||
@@ -526,15 +473,15 @@
|
||||
"nixvim": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_2",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"systems": "systems_3"
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765413189,
|
||||
"narHash": "sha256-CEXdMdYV6ETQF/ol8z2odP55b0P/+2UjZczNeBAxBOA=",
|
||||
"lastModified": 1765841289,
|
||||
"narHash": "sha256-LpkgAzXRlh+qxbRGIsSy5kOX1oOzlFlZeOt/QmITg5M=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixvim",
|
||||
"rev": "f61667b37eed4f17e19a38eb1d31f0b6be6e52a8",
|
||||
"rev": "bdc41e4133d4b9e2c0d4f85265d7cce889b55743",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -545,16 +492,15 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"beads": "beads",
|
||||
"darwin": "darwin",
|
||||
"disko": "disko",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"homebrew-cask": "homebrew-cask",
|
||||
"homebrew-core": "homebrew-core",
|
||||
"nix-ai-tools": "nix-ai-tools",
|
||||
"llm-agents": "llm-agents",
|
||||
"nix-homebrew": "nix-homebrew",
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixvim": "nixvim",
|
||||
"sops-nix": "sops-nix",
|
||||
"tangled": "tangled",
|
||||
@@ -589,11 +535,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765231718,
|
||||
"narHash": "sha256-qdBzo6puTgG4G2RHG0PkADg22ZnQo1JmSVFRxrD4QM4=",
|
||||
"lastModified": 1765836173,
|
||||
"narHash": "sha256-hWRYfdH2ONI7HXbqZqW8Q1y9IRbnXWvtvt/ONZovSNY=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "7fd1416aba1865eddcdec5bb11339b7222c2363e",
|
||||
"rev": "443a7f2e7e118c4fc63b7fae05ab3080dd0e5c63",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -675,21 +621,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_5": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"tangled": {
|
||||
"inputs": {
|
||||
"actor-typeahead-src": "actor-typeahead-src",
|
||||
@@ -707,11 +638,11 @@
|
||||
"sqlite-lib-src": "sqlite-lib-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1765368304,
|
||||
"narHash": "sha256-Q3JC5+FYtsKJU70WIhGhsAYWzu0CvUmmbdYhcFe46Pg=",
|
||||
"lastModified": 1765798691,
|
||||
"narHash": "sha256-doW3CIyCUIW3maX7sREt3GYH0Hjkc8jfTZl/tb1ctlE=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "a53d124ea4746109c1933f7adc72f0bde1309890",
|
||||
"revCount": 1731,
|
||||
"rev": "452a1b893015ef71c35c7a034e4af64483ad5669",
|
||||
"revCount": 1747,
|
||||
"type": "git",
|
||||
"url": "https://tangled.org/tangled.org/core"
|
||||
},
|
||||
@@ -723,7 +654,7 @@
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-ai-tools",
|
||||
"llm-agents",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
@@ -744,8 +675,8 @@
|
||||
"zjstatus": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flake-utils": "flake-utils_3",
|
||||
"nixpkgs": "nixpkgs_5",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
};
|
||||
nixvim.url = "github:nix-community/nixvim";
|
||||
zjstatus.url = "github:dj95/zjstatus";
|
||||
nix-ai-tools.url = "github:numtide/nix-ai-tools";
|
||||
beads.url = "github:steveyegge/beads";
|
||||
llm-agents.url = "github:numtide/llm-agents.nix";
|
||||
tangled = {
|
||||
url = "git+https://tangled.org/tangled.org/core";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
../../modules/core.nix
|
||||
../../modules/darwin.nix
|
||||
../../modules/darwin-syncthing.nix
|
||||
../../modules/darwin-system.nix
|
||||
../../modules/dock.nix
|
||||
../../modules/homebrew.nix
|
||||
../../modules/syncthing.nix
|
||||
../../modules/tailscale.nix
|
||||
../../profiles/core.nix
|
||||
../../profiles/darwin.nix
|
||||
../../profiles/dock.nix
|
||||
../../profiles/homebrew.nix
|
||||
../../profiles/syncthing.nix
|
||||
../../profiles/tailscale.nix
|
||||
inputs.sops-nix.darwinModules.sops
|
||||
];
|
||||
|
||||
@@ -35,29 +34,29 @@
|
||||
_module.args = {inherit user constants inputs;};
|
||||
imports = [
|
||||
inputs.nixvim.homeModules.nixvim
|
||||
../../modules/atuin.nix
|
||||
../../modules/bash.nix
|
||||
../../modules/bat.nix
|
||||
../../modules/direnv.nix
|
||||
../../modules/eza.nix
|
||||
../../modules/fish.nix
|
||||
../../modules/fzf.nix
|
||||
../../modules/ghostty.nix
|
||||
../../modules/git.nix
|
||||
../../modules/home.nix
|
||||
../../modules/jjui.nix
|
||||
../../modules/jujutsu.nix
|
||||
../../modules/lazygit.nix
|
||||
../../modules/mise.nix
|
||||
../../modules/neovim
|
||||
../../modules/opencode.nix
|
||||
../../modules/ripgrep.nix
|
||||
../../modules/ssh.nix
|
||||
../../modules/starship.nix
|
||||
../../modules/zellij.nix
|
||||
../../modules/zk.nix
|
||||
../../modules/zoxide.nix
|
||||
../../modules/zsh.nix
|
||||
../../profiles/atuin.nix
|
||||
../../profiles/bash.nix
|
||||
../../profiles/bat.nix
|
||||
../../profiles/direnv.nix
|
||||
../../profiles/eza.nix
|
||||
../../profiles/fish.nix
|
||||
../../profiles/fzf.nix
|
||||
../../profiles/ghostty.nix
|
||||
../../profiles/git.nix
|
||||
../../profiles/home.nix
|
||||
../../profiles/jjui.nix
|
||||
../../profiles/jujutsu.nix
|
||||
../../profiles/lazygit.nix
|
||||
../../profiles/mise.nix
|
||||
../../profiles/neovim
|
||||
../../profiles/opencode.nix
|
||||
../../profiles/ripgrep.nix
|
||||
../../profiles/ssh.nix
|
||||
../../profiles/starship.nix
|
||||
../../profiles/zellij.nix
|
||||
../../profiles/zk.nix
|
||||
../../profiles/zoxide.nix
|
||||
../../profiles/zsh.nix
|
||||
];
|
||||
fonts.fontconfig.enable = true;
|
||||
programs.git.settings.user.email = "christoph@tuist.dev";
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
../../modules/core.nix
|
||||
../../modules/darwin.nix
|
||||
../../modules/darwin-syncthing.nix
|
||||
../../modules/darwin-system.nix
|
||||
../../modules/dock.nix
|
||||
../../modules/homebrew.nix
|
||||
../../modules/syncthing.nix
|
||||
../../modules/tailscale.nix
|
||||
../../profiles/core.nix
|
||||
../../profiles/darwin.nix
|
||||
../../profiles/dock.nix
|
||||
../../profiles/homebrew.nix
|
||||
../../profiles/syncthing.nix
|
||||
../../profiles/tailscale.nix
|
||||
inputs.sops-nix.darwinModules.sops
|
||||
];
|
||||
|
||||
@@ -51,29 +50,29 @@
|
||||
_module.args = {inherit user constants inputs;};
|
||||
imports = [
|
||||
inputs.nixvim.homeModules.nixvim
|
||||
../../modules/atuin.nix
|
||||
../../modules/bash.nix
|
||||
../../modules/bat.nix
|
||||
../../modules/direnv.nix
|
||||
../../modules/eza.nix
|
||||
../../modules/fish.nix
|
||||
../../modules/fzf.nix
|
||||
../../modules/ghostty.nix
|
||||
../../modules/git.nix
|
||||
../../modules/home.nix
|
||||
../../modules/jjui.nix
|
||||
../../modules/jujutsu.nix
|
||||
../../modules/lazygit.nix
|
||||
../../modules/mise.nix
|
||||
../../modules/neovim
|
||||
../../modules/opencode.nix
|
||||
../../modules/ripgrep.nix
|
||||
../../modules/ssh.nix
|
||||
../../modules/starship.nix
|
||||
../../modules/zellij.nix
|
||||
../../modules/zk.nix
|
||||
../../modules/zoxide.nix
|
||||
../../modules/zsh.nix
|
||||
../../profiles/atuin.nix
|
||||
../../profiles/bash.nix
|
||||
../../profiles/bat.nix
|
||||
../../profiles/direnv.nix
|
||||
../../profiles/eza.nix
|
||||
../../profiles/fish.nix
|
||||
../../profiles/fzf.nix
|
||||
../../profiles/ghostty.nix
|
||||
../../profiles/git.nix
|
||||
../../profiles/home.nix
|
||||
../../profiles/jjui.nix
|
||||
../../profiles/jujutsu.nix
|
||||
../../profiles/lazygit.nix
|
||||
../../profiles/mise.nix
|
||||
../../profiles/neovim
|
||||
../../profiles/opencode.nix
|
||||
../../profiles/ripgrep.nix
|
||||
../../profiles/ssh.nix
|
||||
../../profiles/starship.nix
|
||||
../../profiles/zellij.nix
|
||||
../../profiles/zk.nix
|
||||
../../profiles/zoxide.nix
|
||||
../../profiles/zsh.nix
|
||||
];
|
||||
fonts.fontconfig.enable = true;
|
||||
programs.git.settings.user.email = "christoph@schmatzler.com";
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
./disk-config.nix
|
||||
./hardware-configuration.nix
|
||||
../../modules/core.nix
|
||||
../../modules/fail2ban.nix
|
||||
../../modules/gitea.nix
|
||||
../../modules/nixos.nix
|
||||
../../profiles/core.nix
|
||||
../../profiles/fail2ban.nix
|
||||
../../profiles/gitea.nix
|
||||
../../profiles/nixos.nix
|
||||
inputs.disko.nixosModules.disko
|
||||
];
|
||||
|
||||
@@ -27,22 +27,22 @@
|
||||
_module.args = {inherit user constants inputs;};
|
||||
imports = [
|
||||
inputs.nixvim.homeModules.nixvim
|
||||
../../modules/bash.nix
|
||||
../../modules/bat.nix
|
||||
../../modules/direnv.nix
|
||||
../../modules/eza.nix
|
||||
../../modules/fish.nix
|
||||
../../modules/fzf.nix
|
||||
../../modules/git.nix
|
||||
../../modules/home.nix
|
||||
../../modules/jjui.nix
|
||||
../../modules/jujutsu.nix
|
||||
../../modules/lazygit.nix
|
||||
../../modules/neovim
|
||||
../../modules/ripgrep.nix
|
||||
../../modules/ssh.nix
|
||||
../../modules/starship.nix
|
||||
../../modules/zoxide.nix
|
||||
../../profiles/bash.nix
|
||||
../../profiles/bat.nix
|
||||
../../profiles/direnv.nix
|
||||
../../profiles/eza.nix
|
||||
../../profiles/fish.nix
|
||||
../../profiles/fzf.nix
|
||||
../../profiles/git.nix
|
||||
../../profiles/home.nix
|
||||
../../profiles/jjui.nix
|
||||
../../profiles/jujutsu.nix
|
||||
../../profiles/lazygit.nix
|
||||
../../profiles/neovim
|
||||
../../profiles/ripgrep.nix
|
||||
../../profiles/ssh.nix
|
||||
../../profiles/starship.nix
|
||||
../../profiles/zoxide.nix
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
../../modules/core.nix
|
||||
../../modules/nixos.nix
|
||||
../../modules/syncthing.nix
|
||||
../../modules/tailscale.nix
|
||||
../../profiles/core.nix
|
||||
../../profiles/nixos.nix
|
||||
../../profiles/syncthing.nix
|
||||
../../profiles/tailscale.nix
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
];
|
||||
|
||||
@@ -23,33 +23,33 @@
|
||||
_module.args = {inherit user constants inputs;};
|
||||
imports = [
|
||||
inputs.nixvim.homeModules.nixvim
|
||||
../../modules/atuin.nix
|
||||
../../modules/bash.nix
|
||||
../../modules/bat.nix
|
||||
../../modules/direnv.nix
|
||||
../../modules/eza.nix
|
||||
../../modules/fish.nix
|
||||
../../modules/fzf.nix
|
||||
../../modules/git.nix
|
||||
../../modules/home.nix
|
||||
../../modules/jjui.nix
|
||||
../../modules/jujutsu.nix
|
||||
../../modules/lazygit.nix
|
||||
../../modules/mise.nix
|
||||
../../modules/neovim
|
||||
../../modules/opencode.nix
|
||||
../../modules/ripgrep.nix
|
||||
../../modules/ssh.nix
|
||||
../../modules/starship.nix
|
||||
../../modules/zellij.nix
|
||||
../../modules/zk.nix
|
||||
../../modules/zoxide.nix
|
||||
../../modules/zsh.nix
|
||||
../../profiles/atuin.nix
|
||||
../../profiles/bash.nix
|
||||
../../profiles/bat.nix
|
||||
../../profiles/direnv.nix
|
||||
../../profiles/eza.nix
|
||||
../../profiles/fish.nix
|
||||
../../profiles/fzf.nix
|
||||
../../profiles/git.nix
|
||||
../../profiles/home.nix
|
||||
../../profiles/jjui.nix
|
||||
../../profiles/jujutsu.nix
|
||||
../../profiles/lazygit.nix
|
||||
../../profiles/mise.nix
|
||||
../../profiles/neovim
|
||||
../../profiles/opencode.nix
|
||||
../../profiles/ripgrep.nix
|
||||
../../profiles/ssh.nix
|
||||
../../profiles/starship.nix
|
||||
../../profiles/zellij.nix
|
||||
../../profiles/zk.nix
|
||||
../../profiles/zoxide.nix
|
||||
../../profiles/zsh.nix
|
||||
];
|
||||
|
||||
home.packages = [
|
||||
inputs.beads.packages.${pkgs.system}.default
|
||||
inputs.nix-ai-tools.packages.${pkgs.system}.amp
|
||||
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.amp
|
||||
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.beads
|
||||
];
|
||||
|
||||
programs.git.settings.user.email = "christoph@schmatzler.com";
|
||||
@@ -142,14 +142,4 @@
|
||||
devices = ["tahani" "chidi"];
|
||||
};
|
||||
};
|
||||
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
virtualHosts."tahani.manticore-hippocampus.ts.net".extraConfig = ''
|
||||
respond "OK"
|
||||
'';
|
||||
};
|
||||
|
||||
# Allow Caddy to fetch Tailscale HTTPS certs
|
||||
services.tailscale.permitCertUid = "caddy";
|
||||
}
|
||||
|
||||
@@ -1,437 +0,0 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.services.syncthing;
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;
|
||||
|
||||
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
|
||||
|
||||
curlAddressArgs = path:
|
||||
if isUnixGui
|
||||
then "--unix-socket ${cfg.guiAddress} http://.${path}"
|
||||
else "${cfg.guiAddress}${path}";
|
||||
|
||||
devices = mapAttrsToList (_: device: device // {deviceID = device.id;}) cfg.settings.devices;
|
||||
anyAutoAccept = builtins.any (dev: dev.autoAcceptFolders) devices;
|
||||
|
||||
folders =
|
||||
mapAttrsToList (_: folder:
|
||||
folder
|
||||
// {
|
||||
devices = let
|
||||
folderDevices = folder.devices;
|
||||
in
|
||||
map (
|
||||
device:
|
||||
if builtins.isString device
|
||||
then {deviceId = cfg.settings.devices.${device}.id;}
|
||||
else if builtins.isAttrs device
|
||||
then {deviceId = cfg.settings.devices.${device.name}.id;} // device
|
||||
else throw "Invalid type for devices in folder; expected list or attrset."
|
||||
)
|
||||
folderDevices;
|
||||
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
|
||||
|
||||
jq = "${pkgs.jq}/bin/jq";
|
||||
updateConfig =
|
||||
pkgs.writers.writeBash "merge-syncthing-config" (
|
||||
''
|
||||
set -efu
|
||||
umask 0077
|
||||
|
||||
curl() {
|
||||
while
|
||||
! ${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)' \
|
||||
${cfg.configDir}/config.xml \
|
||||
>"$TMPDIR/api_key"
|
||||
do sleep 1; done
|
||||
(printf "X-API-Key: "; cat "$TMPDIR/api_key") >"$TMPDIR/headers"
|
||||
${pkgs.curl}/bin/curl -sSLk -H "@$TMPDIR/headers" \
|
||||
--retry 1000 --retry-delay 1 --retry-all-errors \
|
||||
"$@"
|
||||
}
|
||||
''
|
||||
+ (lib.pipe {
|
||||
devs = {
|
||||
new_conf_IDs = map (v: v.id) devices;
|
||||
GET_IdAttrName = "deviceID";
|
||||
override = cfg.overrideDevices;
|
||||
conf = devices;
|
||||
baseAddress = curlAddressArgs "/rest/config/devices";
|
||||
};
|
||||
dirs = {
|
||||
new_conf_IDs = map (v: v.id) folders;
|
||||
GET_IdAttrName = "id";
|
||||
override = cfg.overrideFolders;
|
||||
conf = folders;
|
||||
baseAddress = curlAddressArgs "/rest/config/folders";
|
||||
};
|
||||
} [
|
||||
(mapAttrs (
|
||||
conf_type: s:
|
||||
lib.pipe s.conf [
|
||||
(map (
|
||||
new_cfg: let
|
||||
jsonPreSecretsFile =
|
||||
pkgs.writeTextFile {
|
||||
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
|
||||
text = builtins.toJSON new_cfg;
|
||||
};
|
||||
injectSecretsJqCmd =
|
||||
{
|
||||
"devs" = "${jq} .";
|
||||
"dirs" = let
|
||||
folder = new_cfg;
|
||||
devicesWithSecrets =
|
||||
lib.pipe folder.devices [
|
||||
(lib.filter (device: (builtins.isAttrs device) && device ? encryptionPasswordFile))
|
||||
(map (device: {
|
||||
deviceId = device.deviceId;
|
||||
variableName = "secret_${builtins.hashString "sha256" device.encryptionPasswordFile}";
|
||||
secretPath = device.encryptionPasswordFile;
|
||||
}))
|
||||
];
|
||||
jqUpdates =
|
||||
map (device: ''
|
||||
.devices[] |= (
|
||||
if .deviceId == "${device.deviceId}" then
|
||||
del(.encryptionPasswordFile) |
|
||||
.encryptionPassword = ''$${device.variableName}
|
||||
else
|
||||
.
|
||||
end
|
||||
)
|
||||
'')
|
||||
devicesWithSecrets;
|
||||
jqRawFiles = map (device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}") devicesWithSecrets;
|
||||
in "${jq} ${lib.concatStringsSep " " jqRawFiles} ${lib.escapeShellArg (lib.concatStringsSep "|" (["."] ++ jqUpdates))}";
|
||||
}.${
|
||||
conf_type
|
||||
};
|
||||
in ''
|
||||
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
|
||||
''
|
||||
))
|
||||
(lib.concatStringsSep "\n")
|
||||
]
|
||||
+ lib.optionalString s.override ''
|
||||
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
|
||||
--argjson new_ids ${lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)} \
|
||||
--raw-output \
|
||||
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
|
||||
)"
|
||||
for id in ''${stale_${conf_type}_ids}; do
|
||||
>&2 echo "Deleting stale device: $id"
|
||||
curl -X DELETE ${s.baseAddress}/$id
|
||||
done
|
||||
''
|
||||
))
|
||||
builtins.attrValues
|
||||
(lib.concatStringsSep "\n")
|
||||
])
|
||||
+ (lib.pipe cleanedConfig [
|
||||
builtins.attrNames
|
||||
(lib.subtractLists ["folders" "devices"])
|
||||
(map (subOption: ''
|
||||
curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
|
||||
''))
|
||||
(lib.concatStringsSep "\n")
|
||||
])
|
||||
+ ''
|
||||
if curl ${curlAddressArgs "/rest/config/restart-required"} |
|
||||
${jq} -e .requiresRestart > /dev/null; then
|
||||
curl -X POST ${curlAddressArgs "/rest/system/restart"}
|
||||
fi
|
||||
''
|
||||
);
|
||||
in {
|
||||
options = {
|
||||
services.syncthing = {
|
||||
enable = mkEnableOption "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync";
|
||||
|
||||
cert =
|
||||
mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Path to the cert.pem file, which will be copied into Syncthing's configDir.";
|
||||
};
|
||||
|
||||
key =
|
||||
mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Path to the key.pem file, which will be copied into Syncthing's configDir.";
|
||||
};
|
||||
|
||||
overrideDevices =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to delete the devices which are not configured via the devices option.";
|
||||
};
|
||||
|
||||
overrideFolders =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = !anyAutoAccept;
|
||||
description = "Whether to delete the folders which are not configured via the folders option.";
|
||||
};
|
||||
|
||||
settings =
|
||||
mkOption {
|
||||
type =
|
||||
types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
options =
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "The options element contains all other global configuration options";
|
||||
type =
|
||||
types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
localAnnounceEnabled =
|
||||
mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "Whether to send announcements to the local LAN.";
|
||||
};
|
||||
globalAnnounceEnabled =
|
||||
mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "Whether to send announcements to the global discovery servers.";
|
||||
};
|
||||
relaysEnabled =
|
||||
mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "When true, relays will be connected to and potentially used for device to device connections.";
|
||||
};
|
||||
urAccepted =
|
||||
mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = "Whether the user has accepted to submit anonymous usage data.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
devices =
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "Peers/devices which Syncthing should communicate with.";
|
||||
type =
|
||||
types.attrsOf (types.submodule ({name, ...}: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
name =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The name of the device.";
|
||||
};
|
||||
id =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
description = "The device ID.";
|
||||
};
|
||||
autoAcceptFolders =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Automatically create or share folders that this device advertises at the default path.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
folders =
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "Folders which should be shared by Syncthing.";
|
||||
type =
|
||||
types.attrsOf (types.submodule ({name, ...}: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
enable =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to share this folder.";
|
||||
};
|
||||
path =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The path to the folder which should be shared.";
|
||||
};
|
||||
id =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The ID of the folder. Must be the same on all devices.";
|
||||
};
|
||||
label =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The label of the folder.";
|
||||
};
|
||||
type =
|
||||
mkOption {
|
||||
type = types.enum ["sendreceive" "sendonly" "receiveonly" "receiveencrypted"];
|
||||
default = "sendreceive";
|
||||
description = "Controls how the folder is handled by Syncthing.";
|
||||
};
|
||||
devices =
|
||||
mkOption {
|
||||
type =
|
||||
types.listOf (types.oneOf [
|
||||
types.str
|
||||
(types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
name =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
description = "The name of a device defined in the devices option.";
|
||||
};
|
||||
encryptionPasswordFile =
|
||||
mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = "Path to encryption password file.";
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
default = [];
|
||||
description = "The devices this folder should be shared with.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
description = "Extra configuration options for Syncthing.";
|
||||
};
|
||||
|
||||
guiAddress =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1:8384";
|
||||
description = "The address to serve the web interface at.";
|
||||
};
|
||||
|
||||
user =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = "syncthing";
|
||||
description = "The user to run Syncthing as.";
|
||||
};
|
||||
|
||||
group =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = "syncthing";
|
||||
description = "The group to run Syncthing under.";
|
||||
};
|
||||
|
||||
dataDir =
|
||||
mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/syncthing";
|
||||
description = "The path where synchronised directories will exist.";
|
||||
};
|
||||
|
||||
configDir =
|
||||
mkOption {
|
||||
type = types.path;
|
||||
default = cfg.dataDir + "/.config/syncthing";
|
||||
description = "The path where the settings and keys will exist.";
|
||||
};
|
||||
|
||||
openDefaultPorts =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the default ports in the firewall (not applicable on Darwin).";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "syncthing" {};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(cfg.overrideFolders && anyAutoAccept);
|
||||
message = "services.syncthing.overrideFolders will delete auto-accepted folders from the configuration, creating path conflicts.";
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = [cfg.package];
|
||||
|
||||
launchd.user.agents.syncthing = {
|
||||
serviceConfig = {
|
||||
ProgramArguments = [
|
||||
"${cfg.package}/bin/syncthing"
|
||||
"--no-browser"
|
||||
"--gui-address=${
|
||||
if isUnixGui
|
||||
then "unix://"
|
||||
else ""
|
||||
}${cfg.guiAddress}"
|
||||
"--config=${cfg.configDir}"
|
||||
"--data=${cfg.configDir}"
|
||||
];
|
||||
EnvironmentVariables = {
|
||||
STNORESTART = "yes";
|
||||
STNOUPGRADE = "yes";
|
||||
};
|
||||
KeepAlive = true;
|
||||
RunAtLoad = true;
|
||||
ProcessType = "Background";
|
||||
StandardOutPath = "${cfg.configDir}/syncthing.log";
|
||||
StandardErrorPath = "${cfg.configDir}/syncthing.log";
|
||||
};
|
||||
};
|
||||
|
||||
launchd.user.agents.syncthing-init =
|
||||
mkIf (cleanedConfig != {}) {
|
||||
serviceConfig = {
|
||||
ProgramArguments = ["${updateConfig}"];
|
||||
RunAtLoad = true;
|
||||
KeepAlive = false;
|
||||
ProcessType = "Background";
|
||||
StandardOutPath = "${cfg.configDir}/syncthing-init.log";
|
||||
StandardErrorPath = "${cfg.configDir}/syncthing-init.log";
|
||||
};
|
||||
};
|
||||
|
||||
system.activationScripts.syncthing =
|
||||
mkIf (cfg.cert != null || cfg.key != null) ''
|
||||
echo "Setting up Syncthing certificates..."
|
||||
mkdir -p ${cfg.configDir}
|
||||
${optionalString (cfg.cert != null) ''
|
||||
cp ${toString cfg.cert} ${cfg.configDir}/cert.pem
|
||||
chmod 644 ${cfg.configDir}/cert.pem
|
||||
''}
|
||||
${optionalString (cfg.key != null) ''
|
||||
cp ${toString cfg.key} ${cfg.configDir}/key.pem
|
||||
chmod 600 ${cfg.configDir}/key.pem
|
||||
''}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
system.defaults = {
|
||||
NSGlobalDomain = {
|
||||
# null equals "Light"
|
||||
AppleInterfaceStyle = null;
|
||||
AppleShowAllExtensions = true;
|
||||
ApplePressAndHoldEnabled = false;
|
||||
KeyRepeat = 2;
|
||||
InitialKeyRepeat = 15;
|
||||
"com.apple.mouse.tapBehavior" = 1;
|
||||
"com.apple.sound.beep.volume" = 0.0;
|
||||
"com.apple.sound.beep.feedback" = 0;
|
||||
};
|
||||
|
||||
dock = {
|
||||
autohide = true;
|
||||
show-recents = false;
|
||||
launchanim = true;
|
||||
orientation = "bottom";
|
||||
tilesize = 60;
|
||||
};
|
||||
|
||||
finder = {
|
||||
_FXShowPosixPathInTitle = false;
|
||||
};
|
||||
|
||||
trackpad = {
|
||||
Clicking = true;
|
||||
TrackpadThreeFingerDrag = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
constants,
|
||||
pkgs,
|
||||
user,
|
||||
...
|
||||
}: {
|
||||
system = {
|
||||
primaryUser = user;
|
||||
stateVersion = constants.stateVersions.darwin;
|
||||
};
|
||||
|
||||
nix = {
|
||||
settings.trusted-users = ["@admin" "${user}"];
|
||||
gc.interval = {
|
||||
Weekday = 0;
|
||||
Hour = 2;
|
||||
Minute = 0;
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${user} = {
|
||||
name = "${user}";
|
||||
home = "/Users/${user}";
|
||||
isHidden = false;
|
||||
shell = pkgs.fish;
|
||||
};
|
||||
|
||||
home-manager.useGlobalPkgs = true;
|
||||
}
|
||||
@@ -1,53 +1,437 @@
|
||||
{
|
||||
user,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
isDarwin = pkgs.stdenv.isDarwin;
|
||||
homeDir =
|
||||
if isDarwin
|
||||
then "/Users/${user}"
|
||||
else "/home/${user}";
|
||||
group =
|
||||
if isDarwin
|
||||
then "staff"
|
||||
else "users";
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.services.syncthing;
|
||||
settingsFormat = pkgs.formats.json {};
|
||||
cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;
|
||||
|
||||
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
|
||||
|
||||
curlAddressArgs = path:
|
||||
if isUnixGui
|
||||
then "--unix-socket ${cfg.guiAddress} http://.${path}"
|
||||
else "${cfg.guiAddress}${path}";
|
||||
|
||||
devices = mapAttrsToList (_: device: device // {deviceID = device.id;}) cfg.settings.devices;
|
||||
anyAutoAccept = builtins.any (dev: dev.autoAcceptFolders) devices;
|
||||
|
||||
folders =
|
||||
mapAttrsToList (_: folder:
|
||||
folder
|
||||
// {
|
||||
devices = let
|
||||
folderDevices = folder.devices;
|
||||
in
|
||||
map (
|
||||
device:
|
||||
if builtins.isString device
|
||||
then {deviceId = cfg.settings.devices.${device}.id;}
|
||||
else if builtins.isAttrs device
|
||||
then {deviceId = cfg.settings.devices.${device.name}.id;} // device
|
||||
else throw "Invalid type for devices in folder; expected list or attrset."
|
||||
)
|
||||
folderDevices;
|
||||
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
|
||||
|
||||
jq = "${pkgs.jq}/bin/jq";
|
||||
updateConfig =
|
||||
pkgs.writers.writeBash "merge-syncthing-config" (
|
||||
''
|
||||
set -efu
|
||||
umask 0077
|
||||
|
||||
curl() {
|
||||
while
|
||||
! ${pkgs.libxml2}/bin/xmllint \
|
||||
--xpath 'string(configuration/gui/apikey)' \
|
||||
${cfg.configDir}/config.xml \
|
||||
>"$TMPDIR/api_key"
|
||||
do sleep 1; done
|
||||
(printf "X-API-Key: "; cat "$TMPDIR/api_key") >"$TMPDIR/headers"
|
||||
${pkgs.curl}/bin/curl -sSLk -H "@$TMPDIR/headers" \
|
||||
--retry 1000 --retry-delay 1 --retry-all-errors \
|
||||
"$@"
|
||||
}
|
||||
''
|
||||
+ (lib.pipe {
|
||||
devs = {
|
||||
new_conf_IDs = map (v: v.id) devices;
|
||||
GET_IdAttrName = "deviceID";
|
||||
override = cfg.overrideDevices;
|
||||
conf = devices;
|
||||
baseAddress = curlAddressArgs "/rest/config/devices";
|
||||
};
|
||||
dirs = {
|
||||
new_conf_IDs = map (v: v.id) folders;
|
||||
GET_IdAttrName = "id";
|
||||
override = cfg.overrideFolders;
|
||||
conf = folders;
|
||||
baseAddress = curlAddressArgs "/rest/config/folders";
|
||||
};
|
||||
} [
|
||||
(mapAttrs (
|
||||
conf_type: s:
|
||||
lib.pipe s.conf [
|
||||
(map (
|
||||
new_cfg: let
|
||||
jsonPreSecretsFile =
|
||||
pkgs.writeTextFile {
|
||||
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
|
||||
text = builtins.toJSON new_cfg;
|
||||
};
|
||||
injectSecretsJqCmd =
|
||||
{
|
||||
"devs" = "${jq} .";
|
||||
"dirs" = let
|
||||
folder = new_cfg;
|
||||
devicesWithSecrets =
|
||||
lib.pipe folder.devices [
|
||||
(lib.filter (device: (builtins.isAttrs device) && device ? encryptionPasswordFile))
|
||||
(map (device: {
|
||||
deviceId = device.deviceId;
|
||||
variableName = "secret_${builtins.hashString "sha256" device.encryptionPasswordFile}";
|
||||
secretPath = device.encryptionPasswordFile;
|
||||
}))
|
||||
];
|
||||
jqUpdates =
|
||||
map (device: ''
|
||||
.devices[] |= (
|
||||
if .deviceId == "${device.deviceId}" then
|
||||
del(.encryptionPasswordFile) |
|
||||
.encryptionPassword = ''$${device.variableName}
|
||||
else
|
||||
.
|
||||
end
|
||||
)
|
||||
'')
|
||||
devicesWithSecrets;
|
||||
jqRawFiles = map (device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}") devicesWithSecrets;
|
||||
in "${jq} ${lib.concatStringsSep " " jqRawFiles} ${lib.escapeShellArg (lib.concatStringsSep "|" (["."] ++ jqUpdates))}";
|
||||
}.${
|
||||
conf_type
|
||||
};
|
||||
in ''
|
||||
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
|
||||
''
|
||||
))
|
||||
(lib.concatStringsSep "\n")
|
||||
]
|
||||
+ lib.optionalString s.override ''
|
||||
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
|
||||
--argjson new_ids ${lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)} \
|
||||
--raw-output \
|
||||
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
|
||||
)"
|
||||
for id in ''${stale_${conf_type}_ids}; do
|
||||
>&2 echo "Deleting stale device: $id"
|
||||
curl -X DELETE ${s.baseAddress}/$id
|
||||
done
|
||||
''
|
||||
))
|
||||
builtins.attrValues
|
||||
(lib.concatStringsSep "\n")
|
||||
])
|
||||
+ (lib.pipe cleanedConfig [
|
||||
builtins.attrNames
|
||||
(lib.subtractLists ["folders" "devices"])
|
||||
(map (subOption: ''
|
||||
curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
|
||||
''))
|
||||
(lib.concatStringsSep "\n")
|
||||
])
|
||||
+ ''
|
||||
if curl ${curlAddressArgs "/rest/config/restart-required"} |
|
||||
${jq} -e .requiresRestart > /dev/null; then
|
||||
curl -X POST ${curlAddressArgs "/rest/system/restart"}
|
||||
fi
|
||||
''
|
||||
);
|
||||
in {
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = !isDarwin;
|
||||
dataDir = "${homeDir}/.local/share/syncthing";
|
||||
configDir = "${homeDir}/.config/syncthing";
|
||||
user = "${user}";
|
||||
group = group;
|
||||
guiAddress = "0.0.0.0:8384";
|
||||
overrideFolders = true;
|
||||
overrideDevices = true;
|
||||
options = {
|
||||
services.syncthing = {
|
||||
enable = mkEnableOption "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync";
|
||||
|
||||
settings = {
|
||||
devices = {
|
||||
"tahani" = {
|
||||
id = "6B7OZZF-TEAMUGO-FBOELXP-Z4OY7EU-5ZHLB5T-V6Z3UDB-Q2DYR43-QBYW6QM";
|
||||
addresses = ["tcp://tahani:22000"];
|
||||
cert =
|
||||
mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Path to the cert.pem file, which will be copied into Syncthing's configDir.";
|
||||
};
|
||||
"jason" = {
|
||||
id = "42II2VO-QYPJG26-ZS3MB2I-AOPVZ67-JJNSE76-U54CO5Y-634A5OG-ECU4YQA";
|
||||
addresses = ["tcp://jason:22000"];
|
||||
};
|
||||
"chidi" = {
|
||||
id = "N7W6SUT-QO6J4BE-T3Y65SM-OFGYGNV-TGYBJPX-JVN4Z72-AENZ247-KWXOQA6";
|
||||
addresses = ["tcp://chidi:22000"];
|
||||
};
|
||||
};
|
||||
|
||||
folders = {
|
||||
"nixos-config" = {
|
||||
path = "${homeDir}/nixos-config";
|
||||
devices = ["tahani" "jason" "chidi"];
|
||||
key =
|
||||
mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Path to the key.pem file, which will be copied into Syncthing's configDir.";
|
||||
};
|
||||
};
|
||||
|
||||
options.globalAnnounceEnabled = false;
|
||||
overrideDevices =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to delete the devices which are not configured via the devices option.";
|
||||
};
|
||||
|
||||
overrideFolders =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = !anyAutoAccept;
|
||||
description = "Whether to delete the folders which are not configured via the folders option.";
|
||||
};
|
||||
|
||||
settings =
|
||||
mkOption {
|
||||
type =
|
||||
types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
options =
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "The options element contains all other global configuration options";
|
||||
type =
|
||||
types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
localAnnounceEnabled =
|
||||
mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "Whether to send announcements to the local LAN.";
|
||||
};
|
||||
globalAnnounceEnabled =
|
||||
mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "Whether to send announcements to the global discovery servers.";
|
||||
};
|
||||
relaysEnabled =
|
||||
mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = "When true, relays will be connected to and potentially used for device to device connections.";
|
||||
};
|
||||
urAccepted =
|
||||
mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = "Whether the user has accepted to submit anonymous usage data.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
devices =
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "Peers/devices which Syncthing should communicate with.";
|
||||
type =
|
||||
types.attrsOf (types.submodule ({name, ...}: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
name =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The name of the device.";
|
||||
};
|
||||
id =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
description = "The device ID.";
|
||||
};
|
||||
autoAcceptFolders =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Automatically create or share folders that this device advertises at the default path.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
folders =
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "Folders which should be shared by Syncthing.";
|
||||
type =
|
||||
types.attrsOf (types.submodule ({name, ...}: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
enable =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to share this folder.";
|
||||
};
|
||||
path =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The path to the folder which should be shared.";
|
||||
};
|
||||
id =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The ID of the folder. Must be the same on all devices.";
|
||||
};
|
||||
label =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = "The label of the folder.";
|
||||
};
|
||||
type =
|
||||
mkOption {
|
||||
type = types.enum ["sendreceive" "sendonly" "receiveonly" "receiveencrypted"];
|
||||
default = "sendreceive";
|
||||
description = "Controls how the folder is handled by Syncthing.";
|
||||
};
|
||||
devices =
|
||||
mkOption {
|
||||
type =
|
||||
types.listOf (types.oneOf [
|
||||
types.str
|
||||
(types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
name =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
description = "The name of a device defined in the devices option.";
|
||||
};
|
||||
encryptionPasswordFile =
|
||||
mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = "Path to encryption password file.";
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
default = [];
|
||||
description = "The devices this folder should be shared with.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
description = "Extra configuration options for Syncthing.";
|
||||
};
|
||||
|
||||
guiAddress =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1:8384";
|
||||
description = "The address to serve the web interface at.";
|
||||
};
|
||||
|
||||
user =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = "syncthing";
|
||||
description = "The user to run Syncthing as.";
|
||||
};
|
||||
|
||||
group =
|
||||
mkOption {
|
||||
type = types.str;
|
||||
default = "syncthing";
|
||||
description = "The group to run Syncthing under.";
|
||||
};
|
||||
|
||||
dataDir =
|
||||
mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/syncthing";
|
||||
description = "The path where synchronised directories will exist.";
|
||||
};
|
||||
|
||||
configDir =
|
||||
mkOption {
|
||||
type = types.path;
|
||||
default = cfg.dataDir + "/.config/syncthing";
|
||||
description = "The path where the settings and keys will exist.";
|
||||
};
|
||||
|
||||
openDefaultPorts =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the default ports in the firewall (not applicable on Darwin).";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "syncthing" {};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(cfg.overrideFolders && anyAutoAccept);
|
||||
message = "services.syncthing.overrideFolders will delete auto-accepted folders from the configuration, creating path conflicts.";
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = [cfg.package];
|
||||
|
||||
launchd.user.agents.syncthing = {
|
||||
serviceConfig = {
|
||||
ProgramArguments = [
|
||||
"${cfg.package}/bin/syncthing"
|
||||
"--no-browser"
|
||||
"--gui-address=${
|
||||
if isUnixGui
|
||||
then "unix://"
|
||||
else ""
|
||||
}${cfg.guiAddress}"
|
||||
"--config=${cfg.configDir}"
|
||||
"--data=${cfg.configDir}"
|
||||
];
|
||||
EnvironmentVariables = {
|
||||
STNORESTART = "yes";
|
||||
STNOUPGRADE = "yes";
|
||||
};
|
||||
KeepAlive = true;
|
||||
RunAtLoad = true;
|
||||
ProcessType = "Background";
|
||||
StandardOutPath = "${cfg.configDir}/syncthing.log";
|
||||
StandardErrorPath = "${cfg.configDir}/syncthing.log";
|
||||
};
|
||||
};
|
||||
|
||||
launchd.user.agents.syncthing-init =
|
||||
mkIf (cleanedConfig != {}) {
|
||||
serviceConfig = {
|
||||
ProgramArguments = ["${updateConfig}"];
|
||||
RunAtLoad = true;
|
||||
KeepAlive = false;
|
||||
ProcessType = "Background";
|
||||
StandardOutPath = "${cfg.configDir}/syncthing-init.log";
|
||||
StandardErrorPath = "${cfg.configDir}/syncthing-init.log";
|
||||
};
|
||||
};
|
||||
|
||||
system.activationScripts.syncthing =
|
||||
mkIf (cfg.cert != null || cfg.key != null) ''
|
||||
echo "Setting up Syncthing certificates..."
|
||||
mkdir -p ${cfg.configDir}
|
||||
${optionalString (cfg.cert != null) ''
|
||||
cp ${toString cfg.cert} ${cfg.configDir}/cert.pem
|
||||
chmod 644 ${cfg.configDir}/cert.pem
|
||||
''}
|
||||
${optionalString (cfg.key != null) ''
|
||||
cp ${toString cfg.key} ${cfg.configDir}/key.pem
|
||||
chmod 600 ${cfg.configDir}/key.pem
|
||||
''}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{inputs}: final: prev: {
|
||||
zjstatus = inputs.zjstatus.packages.${prev.system}.default;
|
||||
zjstatus = inputs.zjstatus.packages.${prev.stdenv.hostPlatform.system}.default;
|
||||
}
|
||||
|
||||
60
profiles/darwin.nix
Normal file
60
profiles/darwin.nix
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
constants,
|
||||
pkgs,
|
||||
user,
|
||||
...
|
||||
}: {
|
||||
system = {
|
||||
primaryUser = user;
|
||||
stateVersion = constants.stateVersions.darwin;
|
||||
|
||||
defaults = {
|
||||
NSGlobalDomain = {
|
||||
# null equals "Light"
|
||||
AppleInterfaceStyle = null;
|
||||
AppleShowAllExtensions = true;
|
||||
ApplePressAndHoldEnabled = false;
|
||||
KeyRepeat = 2;
|
||||
InitialKeyRepeat = 15;
|
||||
"com.apple.mouse.tapBehavior" = 1;
|
||||
"com.apple.sound.beep.volume" = 0.0;
|
||||
"com.apple.sound.beep.feedback" = 0;
|
||||
};
|
||||
|
||||
dock = {
|
||||
autohide = true;
|
||||
show-recents = false;
|
||||
launchanim = true;
|
||||
orientation = "bottom";
|
||||
tilesize = 60;
|
||||
};
|
||||
|
||||
finder = {
|
||||
_FXShowPosixPathInTitle = false;
|
||||
};
|
||||
|
||||
trackpad = {
|
||||
Clicking = true;
|
||||
TrackpadThreeFingerDrag = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nix = {
|
||||
settings.trusted-users = ["@admin" "${user}"];
|
||||
gc.interval = {
|
||||
Weekday = 0;
|
||||
Hour = 2;
|
||||
Minute = 0;
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${user} = {
|
||||
name = "${user}";
|
||||
home = "/Users/${user}";
|
||||
isHidden = false;
|
||||
shell = pkgs.fish;
|
||||
};
|
||||
|
||||
home-manager.useGlobalPkgs = true;
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
SAME_SITE = "strict";
|
||||
};
|
||||
api.ENABLE_SWAGGER = false;
|
||||
server.LANDING_PAGE = "explore";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
email = "christoph@schmatzler.com";
|
||||
};
|
||||
git = {
|
||||
sign-on-push = true;
|
||||
subprocess = true;
|
||||
write-change-id-header = true;
|
||||
};
|
||||
diff = {
|
||||
@@ -19,7 +21,9 @@
|
||||
diff-editor = ["nvim" "-c" "DiffEditor $left $right $output"];
|
||||
};
|
||||
aliases = {
|
||||
n = ["new"];
|
||||
tug = ["bookmark" "move" "--from" "closest_bookmark(@-)" "--to" "@-"];
|
||||
stack = ["log" "-r" "ancestors((trunk()..@)::bookmarks() | @, 2)"];
|
||||
retrunk = ["rebase" "-d" "trunk()"];
|
||||
};
|
||||
revset-aliases = {
|
||||
@@ -9,6 +9,7 @@
|
||||
./plugins/grug-far.nix
|
||||
./plugins/harpoon.nix
|
||||
./plugins/hunk.nix
|
||||
./plugins/jj-diffconflicts.nix
|
||||
./plugins/lsp.nix
|
||||
./plugins/mini.nix
|
||||
./plugins/oil.nix
|
||||
@@ -120,8 +120,9 @@
|
||||
# g - git
|
||||
{
|
||||
mode = "n";
|
||||
key = "<leader>gd";
|
||||
action = ":DiffviewOpen<CR>";
|
||||
key = "<leader>gc";
|
||||
action = ":JJDiffConflicts<CR>";
|
||||
options.desc = "Resolve conflicts";
|
||||
}
|
||||
{
|
||||
mode = "n";
|
||||
13
profiles/neovim/plugins/jj-diffconflicts.nix
Normal file
13
profiles/neovim/plugins/jj-diffconflicts.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{pkgs, ...}: {
|
||||
programs.nixvim.extraPlugins = [
|
||||
(pkgs.vimUtils.buildVimPlugin {
|
||||
name = "jj-diffconflicts";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "rafikdraoui";
|
||||
repo = "jj-diffconflicts";
|
||||
rev = "main";
|
||||
hash = "sha256-FXsLSYy+eli8VArUL8ZOiPtyOk4Q8TUYwobEefZPRII=";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -122,6 +122,7 @@
|
||||
}
|
||||
];
|
||||
};
|
||||
cmdline = {};
|
||||
comment = {};
|
||||
diff = {};
|
||||
extra = {};
|
||||
@@ -5,7 +5,7 @@
|
||||
}: {
|
||||
programs.opencode = {
|
||||
enable = true;
|
||||
package = inputs.nix-ai-tools.packages.${pkgs.system}.opencode;
|
||||
package = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.opencode;
|
||||
settings = {
|
||||
theme = "catppuccin";
|
||||
instructions = [
|
||||
@@ -20,4 +20,7 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
home.sessionVariables = {
|
||||
OPENCODE_EXPERIMENTAL_EXA = "true";
|
||||
};
|
||||
}
|
||||
@@ -33,6 +33,7 @@ with pkgs;
|
||||
sd
|
||||
sops
|
||||
sqlite
|
||||
tea
|
||||
tokei
|
||||
tree
|
||||
tree-sitter
|
||||
53
profiles/syncthing.nix
Normal file
53
profiles/syncthing.nix
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
user,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
isDarwin = pkgs.stdenv.isDarwin;
|
||||
homeDir =
|
||||
if isDarwin
|
||||
then "/Users/${user}"
|
||||
else "/home/${user}";
|
||||
group =
|
||||
if isDarwin
|
||||
then "staff"
|
||||
else "users";
|
||||
in {
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = !isDarwin;
|
||||
dataDir = "${homeDir}/.local/share/syncthing";
|
||||
configDir = "${homeDir}/.config/syncthing";
|
||||
user = "${user}";
|
||||
group = group;
|
||||
guiAddress = "0.0.0.0:8384";
|
||||
overrideFolders = true;
|
||||
overrideDevices = true;
|
||||
|
||||
settings = {
|
||||
devices = {
|
||||
"tahani" = {
|
||||
id = "6B7OZZF-TEAMUGO-FBOELXP-Z4OY7EU-5ZHLB5T-V6Z3UDB-Q2DYR43-QBYW6QM";
|
||||
addresses = ["tcp://tahani:22000"];
|
||||
};
|
||||
"jason" = {
|
||||
id = "42II2VO-QYPJG26-ZS3MB2I-AOPVZ67-JJNSE76-U54CO5Y-634A5OG-ECU4YQA";
|
||||
addresses = ["tcp://jason:22000"];
|
||||
};
|
||||
"chidi" = {
|
||||
id = "N7W6SUT-QO6J4BE-T3Y65SM-OFGYGNV-TGYBJPX-JVN4Z72-AENZ247-KWXOQA6";
|
||||
addresses = ["tcp://chidi:22000"];
|
||||
};
|
||||
};
|
||||
|
||||
folders = {
|
||||
"nixos-config" = {
|
||||
path = "${homeDir}/nixos-config";
|
||||
devices = ["tahani" "jason" "chidi"];
|
||||
};
|
||||
};
|
||||
|
||||
options.globalAnnounceEnabled = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user