Compare commits
8 Commits
174d546a39
...
3cab4fb812
| Author | SHA1 | Date | |
|---|---|---|---|
|
3cab4fb812
|
|||
|
d182532b34
|
|||
|
f743082fd4
|
|||
|
d813060f1e
|
|||
|
2ae02f0441
|
|||
|
8e749c9fff
|
|||
|
7f24c46ee2
|
|||
|
0af754704e
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,3 +5,6 @@ result-*
|
||||
# Ignore automatically generated direnv output
|
||||
.direnv
|
||||
|
||||
# Ignore generated seed ISOs
|
||||
*.iso
|
||||
|
||||
|
||||
69
.gitlab-ci.yml
Normal file
69
.gitlab-ci.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
stages:
|
||||
- build
|
||||
- upload
|
||||
- release
|
||||
|
||||
build-x86_64:
|
||||
stage: build
|
||||
image: ubuntu:24.04
|
||||
script:
|
||||
- apt-get update && apt-get install -y curl xz-utils sudo
|
||||
- curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux --no-confirm
|
||||
- . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
|
||||
- nix build .#nixosConfigurations.sandbox.config.system.build.image --out-link result-x86_64
|
||||
- cp $(find -L result-x86_64 -name '*.qcow2') sandbox-x86_64.qcow2
|
||||
artifacts:
|
||||
paths:
|
||||
- sandbox-x86_64.qcow2
|
||||
expire_in: 1 week
|
||||
|
||||
build-aarch64:
|
||||
stage: build
|
||||
image: ubuntu:24.04
|
||||
tags:
|
||||
- aarch64
|
||||
allow_failure: true
|
||||
script:
|
||||
- apt-get update && apt-get install -y curl xz-utils sudo
|
||||
- curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux --no-confirm
|
||||
- . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
|
||||
- nix build .#nixosConfigurations.sandbox-aarch64.config.system.build.image --out-link result-aarch64
|
||||
- cp $(find -L result-aarch64 -name '*.qcow2') sandbox-aarch64.qcow2
|
||||
artifacts:
|
||||
paths:
|
||||
- sandbox-aarch64.qcow2
|
||||
expire_in: 1 week
|
||||
|
||||
upload:
|
||||
stage: upload
|
||||
image: curlimages/curl:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- |
|
||||
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
|
||||
--upload-file sandbox-x86_64.qcow2 \
|
||||
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/sandbox/${CI_COMMIT_TAG}/sandbox-x86_64.qcow2"
|
||||
- |
|
||||
if [ -f sandbox-aarch64.qcow2 ]; then
|
||||
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
|
||||
--upload-file sandbox-aarch64.qcow2 \
|
||||
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/sandbox/${CI_COMMIT_TAG}/sandbox-aarch64.qcow2"
|
||||
fi
|
||||
|
||||
release:
|
||||
stage: release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- echo "Creating release $CI_COMMIT_TAG"
|
||||
release:
|
||||
tag_name: $CI_COMMIT_TAG
|
||||
description: "Sandbox VM $CI_COMMIT_TAG"
|
||||
assets:
|
||||
links:
|
||||
- name: sandbox-x86_64.qcow2
|
||||
url: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/sandbox/${CI_COMMIT_TAG}/sandbox-x86_64.qcow2"
|
||||
- name: sandbox-aarch64.qcow2
|
||||
url: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/sandbox/${CI_COMMIT_TAG}/sandbox-aarch64.qcow2"
|
||||
39
dist/make-seed.sh
vendored
Executable file
39
dist/make-seed.sh
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: make-seed.sh <pubkey-file> [output.iso]"
|
||||
echo "Creates a seed ISO with the given SSH public key."
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ "${1:-}" ] || usage
|
||||
|
||||
PUBKEY_FILE="$1"
|
||||
OUTPUT="${2:-seed.iso}"
|
||||
|
||||
if [ ! -f "$PUBKEY_FILE" ]; then
|
||||
echo "error: public key file not found: $PUBKEY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMPDIR"' EXIT
|
||||
|
||||
cp "$PUBKEY_FILE" "$TMPDIR/authorized_keys"
|
||||
|
||||
if command -v mkisofs >/dev/null 2>&1; then
|
||||
ISO_CMD="mkisofs"
|
||||
elif command -v genisoimage >/dev/null 2>&1; then
|
||||
ISO_CMD="genisoimage"
|
||||
else
|
||||
echo "error: mkisofs or genisoimage required"
|
||||
echo " linux: sudo apt install genisoimage"
|
||||
echo " macos: brew install cdrtools"
|
||||
echo " nix: nix shell nixpkgs#cdrtools"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$ISO_CMD" -quiet -V SEEDCONFIG -J -R -o "$OUTPUT" "$TMPDIR"
|
||||
|
||||
echo "seed ISO created: $OUTPUT"
|
||||
149
dist/run.sh
vendored
Executable file
149
dist/run.sh
vendored
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# defaults
|
||||
SSH_PORT=2222
|
||||
MEMORY=8G
|
||||
CPUS=4
|
||||
PROJECTS=""
|
||||
CLAUDE_DIR=""
|
||||
SSH_KEY=""
|
||||
SEED_ISO=""
|
||||
IMAGE=""
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: run.sh <image.qcow2> [options]
|
||||
|
||||
Options:
|
||||
--ssh-key <key.pub> SSH public key (auto-generates seed ISO)
|
||||
--seed-iso <iso> Pre-built seed ISO (alternative to --ssh-key)
|
||||
--projects <path> Mount host directory as ~/projects in VM
|
||||
--claude-dir <path> Mount host .claude directory for auth
|
||||
--memory <size> VM memory (default: 8G)
|
||||
--cpus <n> VM CPUs (default: 4)
|
||||
--ssh-port <port> SSH port forward (default: 2222)
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ "${1:-}" ] || usage
|
||||
|
||||
IMAGE="$1"
|
||||
shift
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--ssh-key) SSH_KEY="$2"; shift 2 ;;
|
||||
--seed-iso) SEED_ISO="$2"; shift 2 ;;
|
||||
--projects) PROJECTS="$2"; shift 2 ;;
|
||||
--claude-dir) CLAUDE_DIR="$2"; shift 2 ;;
|
||||
--memory) MEMORY="$2"; shift 2 ;;
|
||||
--cpus) CPUS="$2"; shift 2 ;;
|
||||
--ssh-port) SSH_PORT="$2"; shift 2 ;;
|
||||
*) echo "unknown option: $1"; usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -f "$IMAGE" ]; then
|
||||
echo "error: image not found: $IMAGE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# platform and accelerator detection
|
||||
ACCEL="tcg"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(uname -s)
|
||||
|
||||
case "$OS" in
|
||||
Linux)
|
||||
[ -r /dev/kvm ] && ACCEL="kvm"
|
||||
;;
|
||||
Darwin)
|
||||
ACCEL="hvf"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) QEMU_BIN="qemu-system-x86_64" ;;
|
||||
aarch64|arm64) QEMU_BIN="qemu-system-aarch64" ;;
|
||||
*) echo "error: unsupported architecture: $ARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# auto-generate seed ISO from SSH key
|
||||
CLEANUP_SEED=""
|
||||
if [ -n "$SSH_KEY" ] && [ -z "$SEED_ISO" ]; then
|
||||
SEED_ISO=$(mktemp /tmp/seed-XXXXXX.iso)
|
||||
CLEANUP_SEED="$SEED_ISO"
|
||||
bash "$SCRIPT_DIR/make-seed.sh" "$SSH_KEY" "$SEED_ISO"
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
[ -n "$CLEANUP_SEED" ] && rm -f "$CLEANUP_SEED"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# build qemu command
|
||||
QEMU_ARGS=(
|
||||
"$QEMU_BIN"
|
||||
-accel "$ACCEL"
|
||||
-m "$MEMORY"
|
||||
-smp "$CPUS"
|
||||
-drive "file=$IMAGE,format=qcow2,snapshot=on"
|
||||
-nic "user,hostfwd=tcp::${SSH_PORT}-:22"
|
||||
-nographic
|
||||
)
|
||||
|
||||
# aarch64-specific flags
|
||||
if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
||||
QEMU_ARGS+=(-machine virt -cpu host)
|
||||
|
||||
# uefi firmware
|
||||
EFI_CODE=""
|
||||
for p in \
|
||||
/opt/homebrew/share/qemu/edk2-aarch64-code.fd \
|
||||
/usr/local/share/qemu/edk2-aarch64-code.fd \
|
||||
/usr/share/qemu-efi-aarch64/QEMU_EFI.fd \
|
||||
/usr/share/AAVMF/AAVMF_CODE.fd; do
|
||||
[ -f "$p" ] && EFI_CODE="$p" && break
|
||||
done
|
||||
|
||||
if [ -z "$EFI_CODE" ]; then
|
||||
echo "error: aarch64 EFI firmware not found"
|
||||
echo " macos: brew install qemu"
|
||||
echo " linux: apt install qemu-efi-aarch64"
|
||||
exit 1
|
||||
fi
|
||||
QEMU_ARGS+=(-bios "$EFI_CODE")
|
||||
fi
|
||||
|
||||
# seed ISO
|
||||
if [ -n "$SEED_ISO" ]; then
|
||||
QEMU_ARGS+=(-drive "file=$SEED_ISO,format=raw,media=cdrom,readonly=on")
|
||||
fi
|
||||
|
||||
# 9p mounts
|
||||
if [ -n "$PROJECTS" ]; then
|
||||
QEMU_ARGS+=(
|
||||
-virtfs "local,path=$PROJECTS,mount_tag=projects,security_model=mapped-xattr,id=fs0"
|
||||
)
|
||||
fi
|
||||
|
||||
if [ -n "$CLAUDE_DIR" ]; then
|
||||
QEMU_ARGS+=(
|
||||
-virtfs "local,path=$CLAUDE_DIR,mount_tag=hostclaude,security_model=mapped-xattr,id=fs1"
|
||||
)
|
||||
# also mount parent home for .claude.json
|
||||
QEMU_ARGS+=(
|
||||
-virtfs "local,path=$(dirname "$CLAUDE_DIR"),mount_tag=hosthome,security_model=mapped-xattr,id=fs2,readonly=on"
|
||||
)
|
||||
fi
|
||||
|
||||
echo "---"
|
||||
echo "SSH: ssh -A -p $SSH_PORT gordaina@localhost"
|
||||
echo "Password: sandbox"
|
||||
echo "---"
|
||||
|
||||
exec "${QEMU_ARGS[@]}"
|
||||
54
flake.lock
generated
54
flake.lock
generated
@@ -89,11 +89,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772160751,
|
||||
"narHash": "sha256-PXv9nrm8HHLGIU2B1XRjOvzlPW9sFdzbtWiJQ1wE8dM=",
|
||||
"lastModified": 1772252606,
|
||||
"narHash": "sha256-SiIhFq4XbD3LmODQ2mTtakRBnjBn/KoSgAOId1cL1Ks=",
|
||||
"owner": "ryoppippi",
|
||||
"repo": "claude-code-overlay",
|
||||
"rev": "662bdbf5ea61fc3cde167bbe3686343a149ea6c6",
|
||||
"rev": "b1ebf027412136bbbe4202741c3d48721644bc4b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -157,11 +157,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"lastModified": 1772408722,
|
||||
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -273,11 +273,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771744638,
|
||||
"narHash": "sha256-EDLi+YAsEEAmMeZe1v6GccuGRbCkpSZp/+A6g+pivR8=",
|
||||
"lastModified": 1772380125,
|
||||
"narHash": "sha256-8C+y46xA9bxcchj9GeDPJaRUDApaA3sy2fhJr1bTbUw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "cb6c151f5c9db4df0b69d06894dc8484de1f16a0",
|
||||
"rev": "a07a44a839eb036e950bf397d9b782916f8dcab3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -318,11 +318,11 @@
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771891493,
|
||||
"narHash": "sha256-L0OCnG8rsWJYZ3mzHSz0iENtlBXQjjcGgvMgsBqN14U=",
|
||||
"lastModified": 1772409903,
|
||||
"narHash": "sha256-yue9XaZ7WHOFJmm3DMEmrF536pHwGxTxh/xr0f1MzNU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "neovim-nightly-overlay",
|
||||
"rev": "7db85d094c68697fc36801bccdf015b4c2bdb274",
|
||||
"rev": "28962d176db883e4fda4b808e220051f376969da",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -334,11 +334,11 @@
|
||||
"neovim-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1771885993,
|
||||
"narHash": "sha256-2c4H+5f0qhsp13Vx8pbsGiSRTHBJIfQaRAAUSHGEpgo=",
|
||||
"lastModified": 1772353308,
|
||||
"narHash": "sha256-k/3msPgpWW9CRFIp3nz6hJzV+GArXw4m35c0t6fKJK4=",
|
||||
"owner": "neovim",
|
||||
"repo": "neovim",
|
||||
"rev": "d9d8c660fd5559d928c8870a21970a375674e310",
|
||||
"rev": "563f9ef7994a35686419b4524cd772c97960dac1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -365,11 +365,11 @@
|
||||
},
|
||||
"nixpkgs-master": {
|
||||
"locked": {
|
||||
"lastModified": 1771932323,
|
||||
"narHash": "sha256-3PadsTzuMJT/x0KmiD/Me1GG6rW8kaHoWVduSs0ue7o=",
|
||||
"lastModified": 1772461137,
|
||||
"narHash": "sha256-5MFNMLcDmaXQbdGJVITwFTqJq3IVok4TSR/Oa/DbJys=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "89bb5c5da7a857869cc88ef9b856bffdff8af264",
|
||||
"rev": "388c66870001909259d1879acd2e3e1108c1854d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -381,11 +381,11 @@
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1771482645,
|
||||
"narHash": "sha256-MpAKyXfJRDTgRU33Hja+G+3h9ywLAJJNRq4Pjbb4dQs=",
|
||||
"lastModified": 1772419343,
|
||||
"narHash": "sha256-QU3Cd5DJH7dHyMnGEFfPcZDaCAsJQ6tUD+JuUsYqnKU=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "724cf38d99ba81fbb4a347081db93e2e3a9bc2ae",
|
||||
"rev": "93178f6a00c22fcdee1c6f5f9ab92f2072072ea9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -397,11 +397,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1771423170,
|
||||
"narHash": "sha256-K7Dg9TQ0mOcAtWTO/FX/FaprtWQ8BmEXTpLIaNRhEwU=",
|
||||
"lastModified": 1772173633,
|
||||
"narHash": "sha256-MOH58F4AIbCkh6qlQcwMycyk5SWvsqnS/TCfnqDlpj4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bcc4a9d9533c033d806a46b37dc444f9b0da49dd",
|
||||
"rev": "c0f3d81a7ddbc2b1332be0d8481a672b4f6004d6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -413,11 +413,11 @@
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1771714954,
|
||||
"narHash": "sha256-nhZJPnBavtu40/L2aqpljrfUNb2rxmWTmSjK2c9UKds=",
|
||||
"lastModified": 1772047000,
|
||||
"narHash": "sha256-7DaQVv4R97cii/Qdfy4tmDZMB2xxtyIvNGSwXBBhSmo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "afbbf774e2087c3d734266c22f96fca2e78d3620",
|
||||
"rev": "1267bb4920d0fc06ea916734c11b0bf004bbe17e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -97,7 +97,11 @@
|
||||
# nixos-rebuild build-image --image-variant qemu --flake .#sandbox
|
||||
sandbox = mkHost "sandbox" {
|
||||
system = "x86_64-linux";
|
||||
users = [ "gorazd" ];
|
||||
users = [ "gordaina" ];
|
||||
};
|
||||
sandbox-aarch64 = mkHost "sandbox" {
|
||||
system = "aarch64-linux";
|
||||
users = [ "gordaina" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ in
|
||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
|
||||
};
|
||||
|
||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
|
||||
@@ -2,59 +2,48 @@
|
||||
pkgs,
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
inputs.self.nixosModules.vm-guest
|
||||
inputs.self.nixosModules.desktop
|
||||
inputs.self.nixosModules.seed-ssh
|
||||
inputs.self.nixosModules.zsh
|
||||
inputs.self.nixosModules.localisation
|
||||
];
|
||||
|
||||
vm-guest.enable = true;
|
||||
desktop.enable = true;
|
||||
vm-guest = {
|
||||
enable = true;
|
||||
headless = true;
|
||||
};
|
||||
|
||||
seed-ssh = {
|
||||
enable = true;
|
||||
user = "gordaina";
|
||||
};
|
||||
|
||||
zsh.enable = true;
|
||||
|
||||
programs.labwc.enable = true;
|
||||
|
||||
# labwc stacking compositor with auto-login
|
||||
services.greetd =
|
||||
let
|
||||
labwc-session = pkgs.writeShellScript "labwc-session" ''
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export XDG_CURRENT_DESKTOP=labwc:wlroots
|
||||
# software renderer for qemu virtio-vga
|
||||
export WLR_RENDERER=pixman
|
||||
export WLR_DRM_NO_ATOMIC=1
|
||||
exec ${pkgs.labwc}/bin/labwc
|
||||
'';
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
settings = {
|
||||
default_session = {
|
||||
command = labwc-session;
|
||||
user = "gorazd";
|
||||
};
|
||||
initial_session = {
|
||||
command = labwc-session;
|
||||
user = "gorazd";
|
||||
};
|
||||
};
|
||||
};
|
||||
localisation = {
|
||||
enable = true;
|
||||
timeZone = "UTC";
|
||||
defaultLocale = "en_US.UTF-8";
|
||||
};
|
||||
|
||||
users = {
|
||||
groups.gorazd = {
|
||||
groups.gordaina = {
|
||||
gid = 1000;
|
||||
};
|
||||
users.gorazd = {
|
||||
group = "gorazd";
|
||||
users.gordaina = {
|
||||
group = "gordaina";
|
||||
uid = 1000;
|
||||
isNormalUser = true;
|
||||
home = "/home/gorazd";
|
||||
home = "/home/gordaina";
|
||||
createHome = true;
|
||||
password = "sandbox";
|
||||
shell = pkgs.zsh;
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"users"
|
||||
@@ -62,8 +51,8 @@
|
||||
};
|
||||
};
|
||||
|
||||
# 9p mounts for host files
|
||||
fileSystems."/home/gorazd/projects" = {
|
||||
# 9p mounts — silently fail if shares not provided at runtime
|
||||
fileSystems."/home/gordaina/projects" = {
|
||||
device = "projects";
|
||||
fsType = "9p";
|
||||
options = [
|
||||
@@ -71,6 +60,8 @@
|
||||
"version=9p2000.L"
|
||||
"msize=65536"
|
||||
"nofail"
|
||||
"x-systemd.automount"
|
||||
"x-systemd.device-timeout=2s"
|
||||
];
|
||||
};
|
||||
|
||||
@@ -82,6 +73,8 @@
|
||||
"version=9p2000.L"
|
||||
"msize=65536"
|
||||
"nofail"
|
||||
"x-systemd.automount"
|
||||
"x-systemd.device-timeout=2s"
|
||||
];
|
||||
};
|
||||
|
||||
@@ -93,6 +86,8 @@
|
||||
"version=9p2000.L"
|
||||
"msize=65536"
|
||||
"nofail"
|
||||
"x-systemd.automount"
|
||||
"x-systemd.device-timeout=2s"
|
||||
"ro"
|
||||
];
|
||||
};
|
||||
@@ -100,32 +95,33 @@
|
||||
# pre-auth claude-code from host config
|
||||
systemd.services.claude-auth = {
|
||||
description = "Copy claude-code credentials from host mount";
|
||||
after = [
|
||||
"mnt-host\\x2dclaude.mount"
|
||||
"mnt-host\\x2dhome.mount"
|
||||
];
|
||||
requires = [
|
||||
"mnt-host\\x2dclaude.mount"
|
||||
"mnt-host\\x2dhome.mount"
|
||||
];
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = pkgs.writeShellScript "claude-auth" ''
|
||||
mkdir -p /home/gorazd/.claude
|
||||
cp -a /mnt/host-claude/. /home/gorazd/.claude/
|
||||
cp /mnt/host-home/.claude.json /home/gorazd/.claude.json || true
|
||||
chown -R gorazd:gorazd /home/gorazd/.claude /home/gorazd/.claude.json
|
||||
# skip if host mounts are not available
|
||||
if ! mountpoint -q /mnt/host-claude && ! mountpoint -q /mnt/host-home; then
|
||||
echo "no host mounts found, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p /home/gordaina/.claude
|
||||
if mountpoint -q /mnt/host-claude; then
|
||||
cp -a /mnt/host-claude/. /home/gordaina/.claude/
|
||||
fi
|
||||
if mountpoint -q /mnt/host-home; then
|
||||
cp /mnt/host-home/.claude.json /home/gordaina/.claude.json || true
|
||||
fi
|
||||
chown -R gordaina:gordaina /home/gordaina/.claude /home/gordaina/.claude.json 2>/dev/null || true
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
claude-code
|
||||
labwc
|
||||
sfwbar
|
||||
foot
|
||||
firefox
|
||||
git
|
||||
];
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
@@ -14,5 +15,9 @@
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
boot.loader.grub.device = lib.mkDefault "/dev/vda";
|
||||
# x86_64: bios/grub, aarch64: uefi/systemd-boot
|
||||
boot.loader.grub.device = lib.mkIf pkgs.stdenv.hostPlatform.isx86_64 (lib.mkDefault "/dev/vda");
|
||||
boot.loader.grub.enable = lib.mkIf pkgs.stdenv.hostPlatform.isAarch64 false;
|
||||
boot.loader.systemd-boot.enable = lib.mkIf pkgs.stdenv.hostPlatform.isAarch64 true;
|
||||
boot.loader.efi.canTouchEfiVariables = lib.mkIf pkgs.stdenv.hostPlatform.isAarch64 true;
|
||||
}
|
||||
|
||||
42
justfile
42
justfile
@@ -17,6 +17,18 @@ update:
|
||||
# update flake inputs, rebuild and switch
|
||||
bump: update switch
|
||||
|
||||
# update a package to latest version
|
||||
update-package pkg:
|
||||
bash packages/{{pkg}}/update.sh
|
||||
|
||||
# update all packages with update scripts
|
||||
update-package-all:
|
||||
@for script in packages/*/update.sh; do bash "$script"; done
|
||||
|
||||
# build all packages and hosts
|
||||
build:
|
||||
nix flake check
|
||||
|
||||
# build installation iso
|
||||
iso:
|
||||
nixos-rebuild build-image --image-variant iso-installer --flake .#live-iso
|
||||
@@ -29,32 +41,10 @@ clean:
|
||||
sandbox-build:
|
||||
nixos-rebuild build-image --image-variant qemu --flake .#sandbox
|
||||
|
||||
# run sandbox with GUI (ephemeral, changes discarded)
|
||||
sandbox-run:
|
||||
nix shell nixpkgs#qemu -c qemu-system-x86_64 -enable-kvm -m 8G -smp 4 \
|
||||
-drive file=$(find -L result -name '*.qcow2' | head -1),format=qcow2,snapshot=on \
|
||||
-vga virtio -display gtk,zoom-to-fit=false \
|
||||
-device virtio-serial-pci \
|
||||
-chardev qemu-vdagent,id=ch1,name=vdagent,clipboard=on \
|
||||
-device virtserialport,chardev=ch1,id=ch1,name=com.redhat.spice.0 \
|
||||
-virtfs local,path=$HOME/git,mount_tag=projects,security_model=mapped-xattr,id=fs0 \
|
||||
-virtfs local,path=$HOME/.claude,mount_tag=hostclaude,security_model=mapped-xattr,id=fs1 \
|
||||
-virtfs local,path=$HOME,mount_tag=hosthome,security_model=mapped-xattr,id=fs2,readonly=on \
|
||||
-nic user,hostfwd=tcp::2222-:22
|
||||
|
||||
# run sandbox headless (ephemeral, changes discarded)
|
||||
sandbox-run-headless:
|
||||
nix shell nixpkgs#qemu -c qemu-system-x86_64 -enable-kvm -m 8G -smp 4 \
|
||||
-drive file=$(find -L result -name '*.qcow2' | head -1),format=qcow2,snapshot=on \
|
||||
-virtfs local,path=$HOME/git,mount_tag=projects,security_model=mapped-xattr,id=fs0 \
|
||||
-virtfs local,path=$HOME/.claude,mount_tag=hostclaude,security_model=mapped-xattr,id=fs1 \
|
||||
-virtfs local,path=$HOME,mount_tag=hosthome,security_model=mapped-xattr,id=fs2,readonly=on \
|
||||
-nic user,hostfwd=tcp::2222-:22 -nographic
|
||||
# run sandbox VM
|
||||
sandbox-run *ARGS:
|
||||
bash dist/run.sh $(find -L result -name '*.qcow2' | head -1) {{ARGS}}
|
||||
|
||||
# ssh into running sandbox
|
||||
sandbox-ssh:
|
||||
ssh -A -p 2222 gorazd@localhost
|
||||
|
||||
# hot-mount a host directory into the running sandbox
|
||||
sandbox-mount path:
|
||||
ssh -p 2222 gorazd@localhost "mkdir -p ~/mnt/$(basename {{path}}) && sshfs matej@10.0.2.2:{{path}} ~/mnt/$(basename {{path}})"
|
||||
ssh -A -p 2222 gordaina@localhost
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
lib:
|
||||
|
||||
# import all .nix files in dir as attribute set
|
||||
# auto-discover nix modules from a directory
|
||||
# - flat .nix files (excluding default.nix) are imported directly
|
||||
# - subdirectories containing package.nix are imported via package.nix
|
||||
dir:
|
||||
let
|
||||
readDir = builtins.readDir dir;
|
||||
files = lib.attrNames (
|
||||
lib.filterAttrs (
|
||||
name: type: type == "regular" && lib.hasSuffix ".nix" name && name != "default.nix"
|
||||
) readDir
|
||||
);
|
||||
|
||||
packages = builtins.map (name: lib.removeSuffix ".nix" name) files;
|
||||
files = lib.filterAttrs (
|
||||
name: type: type == "regular" && lib.hasSuffix ".nix" name && name != "default.nix"
|
||||
) readDir;
|
||||
|
||||
dirs = lib.filterAttrs (
|
||||
name: type: type == "directory" && builtins.pathExists (dir + "/${name}/package.nix")
|
||||
) readDir;
|
||||
in
|
||||
lib.genAttrs packages (name: import (dir + "/${name}.nix"))
|
||||
lib.mapAttrs' (
|
||||
name: _: lib.nameValuePair (lib.removeSuffix ".nix" name) (import (dir + "/${name}"))
|
||||
) files
|
||||
// lib.mapAttrs (name: _: import (dir + "/${name}/package.nix")) dirs
|
||||
|
||||
61
modules/nixos/seed-ssh.nix
Normal file
61
modules/nixos/seed-ssh.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
seed-ssh = {
|
||||
enable = lib.mkEnableOption "SSH key injection from seed ISO";
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "user to install authorized_keys for";
|
||||
};
|
||||
|
||||
label = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "SEEDCONFIG";
|
||||
description = "volume label of the seed ISO";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.seed-ssh.enable {
|
||||
systemd.services.seed-ssh = {
|
||||
description = "Install SSH authorized_keys from seed ISO";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart =
|
||||
let
|
||||
cfg = config.seed-ssh;
|
||||
inherit (cfg) user;
|
||||
inherit (config.users.users.${user}) home;
|
||||
in
|
||||
pkgs.writeShellScript "seed-ssh" ''
|
||||
DEVICE="/dev/disk/by-label/${cfg.label}"
|
||||
if [ ! -e "$DEVICE" ]; then
|
||||
echo "seed ISO not found, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
MOUNT=$(mktemp -d)
|
||||
mount -o ro "$DEVICE" "$MOUNT"
|
||||
|
||||
mkdir -p "${home}/.ssh"
|
||||
cp "$MOUNT/authorized_keys" "${home}/.ssh/authorized_keys"
|
||||
chmod 700 "${home}/.ssh"
|
||||
chmod 600 "${home}/.ssh/authorized_keys"
|
||||
chown -R ${user}:${user} "${home}/.ssh"
|
||||
|
||||
umount "$MOUNT"
|
||||
rmdir "$MOUNT"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -9,12 +9,19 @@
|
||||
options = {
|
||||
vm-guest = {
|
||||
enable = lib.mkEnableOption "VM guest configuration";
|
||||
headless = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "run without display, serial console only";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.vm-guest.enable {
|
||||
services.qemuGuest.enable = true;
|
||||
services.spice-vdagentd.enable = true;
|
||||
services.spice-vdagentd.enable = lib.mkIf (!config.vm-guest.headless) true;
|
||||
|
||||
boot.kernelParams = lib.mkIf config.vm-guest.headless [ "console=ttyS0,115200" ];
|
||||
|
||||
# 9p for host file mounting
|
||||
boot.initrd.availableKernelModules = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
version = "v0.4.1";
|
||||
version = "v0.4.2";
|
||||
in
|
||||
pkgs.rustPlatform.buildRustPackage {
|
||||
pname = "ahab";
|
||||
@@ -12,10 +12,10 @@ pkgs.rustPlatform.buildRustPackage {
|
||||
owner = "janezicmatej";
|
||||
repo = "ahab";
|
||||
rev = version;
|
||||
sha256 = "sha256-Y8UqZOskSlt8GrYem97yKXNbGkd6Ab7WRynKEA9w16E=";
|
||||
sha256 = "sha256-hJg6vRaqTu9a3fua2J/e6akdJQffAk6TBAzJRBD5qHQ=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-T5r+Og3+mHMsqCFGi+QzHdN2MgvPxzA/R+xu38I+lcg=";
|
||||
cargoHash = "sha256-T/2+kxa5X2fmMQs023JN9ZDihExfYvPnunJ8b2Irwoo=";
|
||||
|
||||
buildType = "debug";
|
||||
|
||||
62
packages/ahab/update.sh
Executable file
62
packages/ahab/update.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl jq nix-prefetch
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
PKG_FILE="$SCRIPT_DIR/package.nix"
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
extract_hash() {
|
||||
sed 's/\x1b\[[0-9;]*m//g' | grep 'got:' | tail -1 | grep -oP 'sha256-[A-Za-z0-9+/]+='
|
||||
}
|
||||
|
||||
echo "fetching latest version..."
|
||||
LATEST=$(curl -sf "https://git.janezic.dev/api/v1/repos/janezicmatej/ahab/tags?limit=1" | jq -r '.[0].name')
|
||||
CURRENT=$(grep 'version = ' "$PKG_FILE" | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
||||
|
||||
if [[ "$CURRENT" == "$LATEST" ]]; then
|
||||
echo "ahab already at $LATEST"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "updating ahab: $CURRENT -> $LATEST"
|
||||
|
||||
echo " prefetching source..."
|
||||
BASE32=$(nix-prefetch-url --unpack "https://git.janezic.dev/janezicmatej/ahab/archive/${LATEST}.tar.gz" 2>/dev/null)
|
||||
SRC_HASH=$(nix hash convert --to sri "sha256:$BASE32")
|
||||
echo " source: $SRC_HASH"
|
||||
|
||||
echo " computing cargo hash..."
|
||||
BUILD_OUTPUT=$(nix build --no-link --impure --expr "
|
||||
let
|
||||
pkgs = (builtins.getFlake \"path:$ROOT_DIR\").inputs.nixpkgs.legacyPackages.\${builtins.currentSystem};
|
||||
in pkgs.rustPlatform.fetchCargoVendor {
|
||||
src = pkgs.fetchFromGitea {
|
||||
domain = \"git.janezic.dev\";
|
||||
owner = \"janezicmatej\";
|
||||
repo = \"ahab\";
|
||||
rev = \"$LATEST\";
|
||||
hash = \"$SRC_HASH\";
|
||||
};
|
||||
hash = \"\";
|
||||
}
|
||||
" 2>&1) || true
|
||||
CARGO_HASH=$(echo "$BUILD_OUTPUT" | extract_hash) || true
|
||||
|
||||
if [[ -z "$CARGO_HASH" ]]; then
|
||||
echo " error: failed to compute cargo hash"
|
||||
echo "$BUILD_OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
echo " cargo: $CARGO_HASH"
|
||||
|
||||
OLD_SRC=$(grep 'sha256 = ' "$PKG_FILE" | grep -oP 'sha256-[A-Za-z0-9+/]+=')
|
||||
OLD_CARGO=$(grep 'cargoHash = ' "$PKG_FILE" | grep -oP 'sha256-[A-Za-z0-9+/]+=')
|
||||
|
||||
sed -i "s|version = \"$CURRENT\"|version = \"$LATEST\"|" "$PKG_FILE"
|
||||
sed -i "s|$OLD_SRC|$SRC_HASH|" "$PKG_FILE"
|
||||
sed -i "s|$OLD_CARGO|$CARGO_HASH|" "$PKG_FILE"
|
||||
|
||||
echo "ahab updated to $LATEST"
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
let
|
||||
pkgs = pkgs-master;
|
||||
version = "e24855c";
|
||||
version = "v1.27.1";
|
||||
in
|
||||
pkgs.buildGoModule.override
|
||||
{
|
||||
@@ -16,10 +16,10 @@ pkgs.buildGoModule.override
|
||||
owner = "tkw1536";
|
||||
repo = "ggman";
|
||||
rev = version;
|
||||
sha256 = "sha256-H78xtF7l5joX3/qDFaRIT4LyZpHmm6DMR4JIKzNO7c0=";
|
||||
sha256 = "sha256-z7zqV69rPYwtkm4ieF+FIssBsFbREvaYQzSF648DHK0=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-w8NrOt0xtn+/gugJ4amzdJP70Y5KHe5DlhsEprycm3U=";
|
||||
vendorHash = "sha256-5c5EgYjZXfexWMrUDS4fo46GCJBmFuWkw0cVqqGT7Ik=";
|
||||
subPackages = [ "cmd/ggman" ];
|
||||
|
||||
ldflags = [
|
||||
63
packages/ggman/update.sh
Executable file
63
packages/ggman/update.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl jq nix-prefetch
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
PKG_FILE="$SCRIPT_DIR/package.nix"
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
extract_hash() {
|
||||
sed 's/\x1b\[[0-9;]*m//g' | grep 'got:' | tail -1 | grep -oP 'sha256-[A-Za-z0-9+/]+='
|
||||
}
|
||||
|
||||
echo "fetching latest tag..."
|
||||
LATEST=$(curl -sf "https://api.github.com/repos/tkw1536/ggman/tags?per_page=1" | jq -r '.[0].name')
|
||||
CURRENT=$(grep 'version = ' "$PKG_FILE" | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
||||
|
||||
if [[ "$CURRENT" == "$LATEST" ]]; then
|
||||
echo "ggman already at $LATEST"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "updating ggman: $CURRENT -> $LATEST"
|
||||
|
||||
echo " prefetching source..."
|
||||
BASE32=$(nix-prefetch-url --unpack "https://github.com/tkw1536/ggman/archive/${LATEST}.tar.gz" 2>/dev/null)
|
||||
SRC_HASH=$(nix hash convert --to sri "sha256:$BASE32")
|
||||
echo " source: $SRC_HASH"
|
||||
|
||||
echo " computing vendor hash..."
|
||||
BUILD_OUTPUT=$(nix build --no-link --impure --expr "
|
||||
let
|
||||
pkgs = (builtins.getFlake \"path:$ROOT_DIR\").inputs.nixpkgs-master.legacyPackages.\${builtins.currentSystem};
|
||||
in (pkgs.buildGoModule.override { go = pkgs.go_1_26; } {
|
||||
pname = \"ggman\";
|
||||
version = \"$LATEST\";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = \"tkw1536\";
|
||||
repo = \"ggman\";
|
||||
rev = \"$LATEST\";
|
||||
hash = \"$SRC_HASH\";
|
||||
};
|
||||
vendorHash = \"\";
|
||||
}).goModules
|
||||
" 2>&1) || true
|
||||
VENDOR_HASH=$(echo "$BUILD_OUTPUT" | extract_hash) || true
|
||||
|
||||
if [[ -z "$VENDOR_HASH" ]]; then
|
||||
echo " error: failed to compute vendor hash"
|
||||
echo "$BUILD_OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
echo " vendor: $VENDOR_HASH"
|
||||
|
||||
OLD_SRC=$(grep 'sha256 = ' "$PKG_FILE" | grep -oP 'sha256-[A-Za-z0-9+/]+=')
|
||||
OLD_VENDOR=$(grep 'vendorHash = ' "$PKG_FILE" | grep -oP 'sha256-[A-Za-z0-9+/]+=')
|
||||
|
||||
sed -i "s|version = \"$CURRENT\"|version = \"$LATEST\"|" "$PKG_FILE"
|
||||
sed -i "s|$OLD_SRC|$SRC_HASH|" "$PKG_FILE"
|
||||
sed -i "s|$OLD_VENDOR|$VENDOR_HASH|" "$PKG_FILE"
|
||||
|
||||
echo "ggman updated to $LATEST"
|
||||
@@ -1,7 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
version = "v0.2.1";
|
||||
version = "v0.3.1";
|
||||
in
|
||||
pkgs.rustPlatform.buildRustPackage {
|
||||
pname = "todo-mcp";
|
||||
@@ -12,10 +12,10 @@ pkgs.rustPlatform.buildRustPackage {
|
||||
owner = "janezicmatej";
|
||||
repo = "todo-mcp";
|
||||
rev = version;
|
||||
sha256 = "sha256-BBL7PAgTdGR/+vEJmot8c8mgw5vq5Y/szud0YEiR1UY=";
|
||||
sha256 = "sha256-FLsPatHeWcDMLaGZS91aaXtZEful5frN2pqZkQN9vNs=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-uAyD7Tj9qctDXQ5NkR6T/aItxRmd5WqIXr7NeOlCl8M=";
|
||||
cargoHash = "sha256-gdR4p5LIEMGBV3ikuuRZ5R8CYIjE1K2OnMJm7yo18Nw=";
|
||||
|
||||
nativeBuildInputs = [ pkgs.installShellFiles ];
|
||||
|
||||
62
packages/todo-mcp/update.sh
Executable file
62
packages/todo-mcp/update.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl jq nix-prefetch
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
PKG_FILE="$SCRIPT_DIR/package.nix"
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
extract_hash() {
|
||||
sed 's/\x1b\[[0-9;]*m//g' | grep 'got:' | tail -1 | grep -oP 'sha256-[A-Za-z0-9+/]+='
|
||||
}
|
||||
|
||||
echo "fetching latest version..."
|
||||
LATEST=$(curl -sf "https://git.janezic.dev/api/v1/repos/janezicmatej/todo-mcp/tags?limit=1" | jq -r '.[0].name')
|
||||
CURRENT=$(grep 'version = ' "$PKG_FILE" | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
||||
|
||||
if [[ "$CURRENT" == "$LATEST" ]]; then
|
||||
echo "todo-mcp already at $LATEST"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "updating todo-mcp: $CURRENT -> $LATEST"
|
||||
|
||||
echo " prefetching source..."
|
||||
BASE32=$(nix-prefetch-url --unpack "https://git.janezic.dev/janezicmatej/todo-mcp/archive/${LATEST}.tar.gz" 2>/dev/null)
|
||||
SRC_HASH=$(nix hash convert --to sri "sha256:$BASE32")
|
||||
echo " source: $SRC_HASH"
|
||||
|
||||
echo " computing cargo hash..."
|
||||
BUILD_OUTPUT=$(nix build --no-link --impure --expr "
|
||||
let
|
||||
pkgs = (builtins.getFlake \"path:$ROOT_DIR\").inputs.nixpkgs.legacyPackages.\${builtins.currentSystem};
|
||||
in pkgs.rustPlatform.fetchCargoVendor {
|
||||
src = pkgs.fetchFromGitea {
|
||||
domain = \"git.janezic.dev\";
|
||||
owner = \"janezicmatej\";
|
||||
repo = \"todo-mcp\";
|
||||
rev = \"$LATEST\";
|
||||
hash = \"$SRC_HASH\";
|
||||
};
|
||||
hash = \"\";
|
||||
}
|
||||
" 2>&1) || true
|
||||
CARGO_HASH=$(echo "$BUILD_OUTPUT" | extract_hash) || true
|
||||
|
||||
if [[ -z "$CARGO_HASH" ]]; then
|
||||
echo " error: failed to compute cargo hash"
|
||||
echo "$BUILD_OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
echo " cargo: $CARGO_HASH"
|
||||
|
||||
OLD_SRC=$(grep 'sha256 = ' "$PKG_FILE" | grep -oP 'sha256-[A-Za-z0-9+/]+=')
|
||||
OLD_CARGO=$(grep 'cargoHash = ' "$PKG_FILE" | grep -oP 'sha256-[A-Za-z0-9+/]+=')
|
||||
|
||||
sed -i "s|version = \"$CURRENT\"|version = \"$LATEST\"|" "$PKG_FILE"
|
||||
sed -i "s|$OLD_SRC|$SRC_HASH|" "$PKG_FILE"
|
||||
sed -i "s|$OLD_CARGO|$CARGO_HASH|" "$PKG_FILE"
|
||||
|
||||
echo "todo-mcp updated to $LATEST"
|
||||
@@ -1,72 +0,0 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
packages = inputs.self.outputs.packages.${pkgs.stdenv.hostPlatform.system};
|
||||
in
|
||||
|
||||
{
|
||||
home.stateVersion = "24.11";
|
||||
|
||||
home.packages = [
|
||||
pkgs.git
|
||||
];
|
||||
|
||||
# labwc desktop menu (right-click)
|
||||
xdg.configFile."labwc/menu.xml".text = ''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openbox_menu>
|
||||
<menu id="root-menu" label="">
|
||||
<item label="Terminal"><action name="Execute"><command>foot</command></action></item>
|
||||
<item label="Firefox"><action name="Execute"><command>firefox</command></action></item>
|
||||
<item label="Files"><action name="Execute"><command>foot -e ranger</command></action></item>
|
||||
<separator />
|
||||
<item label="Reconfigure"><action name="Reconfigure" /></item>
|
||||
<item label="Exit"><action name="Exit" /></item>
|
||||
</menu>
|
||||
</openbox_menu>
|
||||
'';
|
||||
|
||||
# labwc autostart panel
|
||||
xdg.configFile."labwc/autostart".text = ''
|
||||
sfwbar &
|
||||
'';
|
||||
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
vimAlias = true;
|
||||
defaultEditor = true;
|
||||
|
||||
package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||
|
||||
extraPackages = with pkgs; [
|
||||
# runtime deps
|
||||
fzf
|
||||
ripgrep
|
||||
gnumake
|
||||
gcc
|
||||
luajit
|
||||
|
||||
lua-language-server
|
||||
nil
|
||||
nixd
|
||||
|
||||
nixpkgs-fmt
|
||||
stylua
|
||||
|
||||
];
|
||||
|
||||
extraWrapperArgs = [
|
||||
"--suffix"
|
||||
"LD_LIBRARY_PATH"
|
||||
":"
|
||||
"${lib.makeLibraryPath [ pkgs.stdenv.cc.cc.lib ]}"
|
||||
];
|
||||
|
||||
};
|
||||
}
|
||||
21
users/gordaina/home-manager.nix
Normal file
21
users/gordaina/home-manager.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home.stateVersion = "25.11";
|
||||
|
||||
home.packages = with pkgs; [
|
||||
git
|
||||
tmux
|
||||
ripgrep
|
||||
fd
|
||||
jq
|
||||
];
|
||||
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
vimAlias = true;
|
||||
defaultEditor = true;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user