Compare commits
1 Commits
3cab4fb812
...
174d546a39
| Author | SHA1 | Date | |
|---|---|---|---|
|
174d546a39
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,3 @@ result-*
|
|||||||
# Ignore automatically generated direnv output
|
# Ignore automatically generated direnv output
|
||||||
.direnv
|
.direnv
|
||||||
|
|
||||||
# Ignore generated seed ISOs
|
|
||||||
*.iso
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
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
39
dist/make-seed.sh
vendored
@@ -1,39 +0,0 @@
|
|||||||
#!/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
149
dist/run.sh
vendored
@@ -1,149 +0,0 @@
|
|||||||
#!/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"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772252606,
|
"lastModified": 1772160751,
|
||||||
"narHash": "sha256-SiIhFq4XbD3LmODQ2mTtakRBnjBn/KoSgAOId1cL1Ks=",
|
"narHash": "sha256-PXv9nrm8HHLGIU2B1XRjOvzlPW9sFdzbtWiJQ1wE8dM=",
|
||||||
"owner": "ryoppippi",
|
"owner": "ryoppippi",
|
||||||
"repo": "claude-code-overlay",
|
"repo": "claude-code-overlay",
|
||||||
"rev": "b1ebf027412136bbbe4202741c3d48721644bc4b",
|
"rev": "662bdbf5ea61fc3cde167bbe3686343a149ea6c6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -157,11 +157,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772408722,
|
"lastModified": 1769996383,
|
||||||
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -273,11 +273,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772380125,
|
"lastModified": 1771744638,
|
||||||
"narHash": "sha256-8C+y46xA9bxcchj9GeDPJaRUDApaA3sy2fhJr1bTbUw=",
|
"narHash": "sha256-EDLi+YAsEEAmMeZe1v6GccuGRbCkpSZp/+A6g+pivR8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "a07a44a839eb036e950bf397d9b782916f8dcab3",
|
"rev": "cb6c151f5c9db4df0b69d06894dc8484de1f16a0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -318,11 +318,11 @@
|
|||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772409903,
|
"lastModified": 1771891493,
|
||||||
"narHash": "sha256-yue9XaZ7WHOFJmm3DMEmrF536pHwGxTxh/xr0f1MzNU=",
|
"narHash": "sha256-L0OCnG8rsWJYZ3mzHSz0iENtlBXQjjcGgvMgsBqN14U=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "neovim-nightly-overlay",
|
"repo": "neovim-nightly-overlay",
|
||||||
"rev": "28962d176db883e4fda4b808e220051f376969da",
|
"rev": "7db85d094c68697fc36801bccdf015b4c2bdb274",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -334,11 +334,11 @@
|
|||||||
"neovim-src": {
|
"neovim-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772353308,
|
"lastModified": 1771885993,
|
||||||
"narHash": "sha256-k/3msPgpWW9CRFIp3nz6hJzV+GArXw4m35c0t6fKJK4=",
|
"narHash": "sha256-2c4H+5f0qhsp13Vx8pbsGiSRTHBJIfQaRAAUSHGEpgo=",
|
||||||
"owner": "neovim",
|
"owner": "neovim",
|
||||||
"repo": "neovim",
|
"repo": "neovim",
|
||||||
"rev": "563f9ef7994a35686419b4524cd772c97960dac1",
|
"rev": "d9d8c660fd5559d928c8870a21970a375674e310",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -365,11 +365,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-master": {
|
"nixpkgs-master": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772461137,
|
"lastModified": 1771932323,
|
||||||
"narHash": "sha256-5MFNMLcDmaXQbdGJVITwFTqJq3IVok4TSR/Oa/DbJys=",
|
"narHash": "sha256-3PadsTzuMJT/x0KmiD/Me1GG6rW8kaHoWVduSs0ue7o=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "388c66870001909259d1879acd2e3e1108c1854d",
|
"rev": "89bb5c5da7a857869cc88ef9b856bffdff8af264",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -381,11 +381,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772419343,
|
"lastModified": 1771482645,
|
||||||
"narHash": "sha256-QU3Cd5DJH7dHyMnGEFfPcZDaCAsJQ6tUD+JuUsYqnKU=",
|
"narHash": "sha256-MpAKyXfJRDTgRU33Hja+G+3h9ywLAJJNRq4Pjbb4dQs=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "93178f6a00c22fcdee1c6f5f9ab92f2072072ea9",
|
"rev": "724cf38d99ba81fbb4a347081db93e2e3a9bc2ae",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -397,11 +397,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772173633,
|
"lastModified": 1771423170,
|
||||||
"narHash": "sha256-MOH58F4AIbCkh6qlQcwMycyk5SWvsqnS/TCfnqDlpj4=",
|
"narHash": "sha256-K7Dg9TQ0mOcAtWTO/FX/FaprtWQ8BmEXTpLIaNRhEwU=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c0f3d81a7ddbc2b1332be0d8481a672b4f6004d6",
|
"rev": "bcc4a9d9533c033d806a46b37dc444f9b0da49dd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -413,11 +413,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772047000,
|
"lastModified": 1771714954,
|
||||||
"narHash": "sha256-7DaQVv4R97cii/Qdfy4tmDZMB2xxtyIvNGSwXBBhSmo=",
|
"narHash": "sha256-nhZJPnBavtu40/L2aqpljrfUNb2rxmWTmSjK2c9UKds=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "1267bb4920d0fc06ea916734c11b0bf004bbe17e",
|
"rev": "afbbf774e2087c3d734266c22f96fca2e78d3620",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -97,11 +97,7 @@
|
|||||||
# nixos-rebuild build-image --image-variant qemu --flake .#sandbox
|
# nixos-rebuild build-image --image-variant qemu --flake .#sandbox
|
||||||
sandbox = mkHost "sandbox" {
|
sandbox = mkHost "sandbox" {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
users = [ "gordaina" ];
|
users = [ "gorazd" ];
|
||||||
};
|
|
||||||
sandbox-aarch64 = mkHost "sandbox" {
|
|
||||||
system = "aarch64-linux";
|
|
||||||
users = [ "gordaina" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ in
|
|||||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
|
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-material-dark-medium.yaml";
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
|||||||
@@ -2,48 +2,59 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
inputs.self.nixosModules.vm-guest
|
inputs.self.nixosModules.vm-guest
|
||||||
inputs.self.nixosModules.seed-ssh
|
inputs.self.nixosModules.desktop
|
||||||
inputs.self.nixosModules.zsh
|
inputs.self.nixosModules.zsh
|
||||||
inputs.self.nixosModules.localisation
|
|
||||||
];
|
];
|
||||||
|
|
||||||
vm-guest = {
|
vm-guest.enable = true;
|
||||||
enable = true;
|
desktop.enable = true;
|
||||||
headless = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
seed-ssh = {
|
|
||||||
enable = true;
|
|
||||||
user = "gordaina";
|
|
||||||
};
|
|
||||||
|
|
||||||
zsh.enable = true;
|
zsh.enable = true;
|
||||||
|
|
||||||
localisation = {
|
programs.labwc.enable = true;
|
||||||
enable = true;
|
|
||||||
timeZone = "UTC";
|
# labwc stacking compositor with auto-login
|
||||||
defaultLocale = "en_US.UTF-8";
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
users = {
|
users = {
|
||||||
groups.gordaina = {
|
groups.gorazd = {
|
||||||
gid = 1000;
|
gid = 1000;
|
||||||
};
|
};
|
||||||
users.gordaina = {
|
users.gorazd = {
|
||||||
group = "gordaina";
|
group = "gorazd";
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
home = "/home/gordaina";
|
home = "/home/gorazd";
|
||||||
createHome = true;
|
createHome = true;
|
||||||
password = "sandbox";
|
password = "sandbox";
|
||||||
shell = pkgs.zsh;
|
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"wheel"
|
"wheel"
|
||||||
"users"
|
"users"
|
||||||
@@ -51,8 +62,8 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# 9p mounts — silently fail if shares not provided at runtime
|
# 9p mounts for host files
|
||||||
fileSystems."/home/gordaina/projects" = {
|
fileSystems."/home/gorazd/projects" = {
|
||||||
device = "projects";
|
device = "projects";
|
||||||
fsType = "9p";
|
fsType = "9p";
|
||||||
options = [
|
options = [
|
||||||
@@ -60,8 +71,6 @@
|
|||||||
"version=9p2000.L"
|
"version=9p2000.L"
|
||||||
"msize=65536"
|
"msize=65536"
|
||||||
"nofail"
|
"nofail"
|
||||||
"x-systemd.automount"
|
|
||||||
"x-systemd.device-timeout=2s"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,8 +82,6 @@
|
|||||||
"version=9p2000.L"
|
"version=9p2000.L"
|
||||||
"msize=65536"
|
"msize=65536"
|
||||||
"nofail"
|
"nofail"
|
||||||
"x-systemd.automount"
|
|
||||||
"x-systemd.device-timeout=2s"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,8 +93,6 @@
|
|||||||
"version=9p2000.L"
|
"version=9p2000.L"
|
||||||
"msize=65536"
|
"msize=65536"
|
||||||
"nofail"
|
"nofail"
|
||||||
"x-systemd.automount"
|
|
||||||
"x-systemd.device-timeout=2s"
|
|
||||||
"ro"
|
"ro"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -95,33 +100,32 @@
|
|||||||
# pre-auth claude-code from host config
|
# pre-auth claude-code from host config
|
||||||
systemd.services.claude-auth = {
|
systemd.services.claude-auth = {
|
||||||
description = "Copy claude-code credentials from host mount";
|
description = "Copy claude-code credentials from host mount";
|
||||||
after = [ "local-fs.target" ];
|
after = [
|
||||||
|
"mnt-host\\x2dclaude.mount"
|
||||||
|
"mnt-host\\x2dhome.mount"
|
||||||
|
];
|
||||||
|
requires = [
|
||||||
|
"mnt-host\\x2dclaude.mount"
|
||||||
|
"mnt-host\\x2dhome.mount"
|
||||||
|
];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStart = pkgs.writeShellScript "claude-auth" ''
|
ExecStart = pkgs.writeShellScript "claude-auth" ''
|
||||||
# skip if host mounts are not available
|
mkdir -p /home/gorazd/.claude
|
||||||
if ! mountpoint -q /mnt/host-claude && ! mountpoint -q /mnt/host-home; then
|
cp -a /mnt/host-claude/. /home/gorazd/.claude/
|
||||||
echo "no host mounts found, skipping"
|
cp /mnt/host-home/.claude.json /home/gorazd/.claude.json || true
|
||||||
exit 0
|
chown -R gorazd:gorazd /home/gorazd/.claude /home/gorazd/.claude.json
|
||||||
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; [
|
environment.systemPackages = with pkgs; [
|
||||||
claude-code
|
claude-code
|
||||||
git
|
labwc
|
||||||
|
sfwbar
|
||||||
|
foot
|
||||||
|
firefox
|
||||||
];
|
];
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
modulesPath,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
@@ -15,9 +14,5 @@
|
|||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
# x86_64: bios/grub, aarch64: uefi/systemd-boot
|
boot.loader.grub.device = lib.mkDefault "/dev/vda";
|
||||||
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,18 +17,6 @@ update:
|
|||||||
# update flake inputs, rebuild and switch
|
# update flake inputs, rebuild and switch
|
||||||
bump: update 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
|
# build installation iso
|
||||||
iso:
|
iso:
|
||||||
nixos-rebuild build-image --image-variant iso-installer --flake .#live-iso
|
nixos-rebuild build-image --image-variant iso-installer --flake .#live-iso
|
||||||
@@ -41,10 +29,32 @@ clean:
|
|||||||
sandbox-build:
|
sandbox-build:
|
||||||
nixos-rebuild build-image --image-variant qemu --flake .#sandbox
|
nixos-rebuild build-image --image-variant qemu --flake .#sandbox
|
||||||
|
|
||||||
# run sandbox VM
|
# run sandbox with GUI (ephemeral, changes discarded)
|
||||||
sandbox-run *ARGS:
|
sandbox-run:
|
||||||
bash dist/run.sh $(find -L result -name '*.qcow2' | head -1) {{ARGS}}
|
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
|
||||||
|
|
||||||
# ssh into running sandbox
|
# ssh into running sandbox
|
||||||
sandbox-ssh:
|
sandbox-ssh:
|
||||||
ssh -A -p 2222 gordaina@localhost
|
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}})"
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
lib:
|
lib:
|
||||||
|
|
||||||
# auto-discover nix modules from a directory
|
# import all .nix files in dir as attribute set
|
||||||
# - flat .nix files (excluding default.nix) are imported directly
|
|
||||||
# - subdirectories containing package.nix are imported via package.nix
|
|
||||||
dir:
|
dir:
|
||||||
let
|
let
|
||||||
readDir = builtins.readDir dir;
|
readDir = builtins.readDir dir;
|
||||||
|
files = lib.attrNames (
|
||||||
|
lib.filterAttrs (
|
||||||
|
name: type: type == "regular" && lib.hasSuffix ".nix" name && name != "default.nix"
|
||||||
|
) readDir
|
||||||
|
);
|
||||||
|
|
||||||
files = lib.filterAttrs (
|
packages = builtins.map (name: lib.removeSuffix ".nix" name) files;
|
||||||
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
|
in
|
||||||
lib.mapAttrs' (
|
lib.genAttrs packages (name: import (dir + "/${name}.nix"))
|
||||||
name: _: lib.nameValuePair (lib.removeSuffix ".nix" name) (import (dir + "/${name}"))
|
|
||||||
) files
|
|
||||||
// lib.mapAttrs (name: _: import (dir + "/${name}/package.nix")) dirs
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
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,19 +9,12 @@
|
|||||||
options = {
|
options = {
|
||||||
vm-guest = {
|
vm-guest = {
|
||||||
enable = lib.mkEnableOption "VM guest configuration";
|
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 {
|
config = lib.mkIf config.vm-guest.enable {
|
||||||
services.qemuGuest.enable = true;
|
services.qemuGuest.enable = true;
|
||||||
services.spice-vdagentd.enable = lib.mkIf (!config.vm-guest.headless) true;
|
services.spice-vdagentd.enable = true;
|
||||||
|
|
||||||
boot.kernelParams = lib.mkIf config.vm-guest.headless [ "console=ttyS0,115200" ];
|
|
||||||
|
|
||||||
# 9p for host file mounting
|
# 9p for host file mounting
|
||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "v0.4.2";
|
version = "v0.4.1";
|
||||||
in
|
in
|
||||||
pkgs.rustPlatform.buildRustPackage {
|
pkgs.rustPlatform.buildRustPackage {
|
||||||
pname = "ahab";
|
pname = "ahab";
|
||||||
@@ -12,10 +12,10 @@ pkgs.rustPlatform.buildRustPackage {
|
|||||||
owner = "janezicmatej";
|
owner = "janezicmatej";
|
||||||
repo = "ahab";
|
repo = "ahab";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "sha256-hJg6vRaqTu9a3fua2J/e6akdJQffAk6TBAzJRBD5qHQ=";
|
sha256 = "sha256-Y8UqZOskSlt8GrYem97yKXNbGkd6Ab7WRynKEA9w16E=";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoHash = "sha256-T/2+kxa5X2fmMQs023JN9ZDihExfYvPnunJ8b2Irwoo=";
|
cargoHash = "sha256-T5r+Og3+mHMsqCFGi+QzHdN2MgvPxzA/R+xu38I+lcg=";
|
||||||
|
|
||||||
buildType = "debug";
|
buildType = "debug";
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#!/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
|
let
|
||||||
pkgs = pkgs-master;
|
pkgs = pkgs-master;
|
||||||
version = "v1.27.1";
|
version = "e24855c";
|
||||||
in
|
in
|
||||||
pkgs.buildGoModule.override
|
pkgs.buildGoModule.override
|
||||||
{
|
{
|
||||||
@@ -16,10 +16,10 @@ pkgs.buildGoModule.override
|
|||||||
owner = "tkw1536";
|
owner = "tkw1536";
|
||||||
repo = "ggman";
|
repo = "ggman";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "sha256-z7zqV69rPYwtkm4ieF+FIssBsFbREvaYQzSF648DHK0=";
|
sha256 = "sha256-H78xtF7l5joX3/qDFaRIT4LyZpHmm6DMR4JIKzNO7c0=";
|
||||||
};
|
};
|
||||||
|
|
||||||
vendorHash = "sha256-5c5EgYjZXfexWMrUDS4fo46GCJBmFuWkw0cVqqGT7Ik=";
|
vendorHash = "sha256-w8NrOt0xtn+/gugJ4amzdJP70Y5KHe5DlhsEprycm3U=";
|
||||||
subPackages = [ "cmd/ggman" ];
|
subPackages = [ "cmd/ggman" ];
|
||||||
|
|
||||||
ldflags = [
|
ldflags = [
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/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, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "v0.3.1";
|
version = "v0.2.1";
|
||||||
in
|
in
|
||||||
pkgs.rustPlatform.buildRustPackage {
|
pkgs.rustPlatform.buildRustPackage {
|
||||||
pname = "todo-mcp";
|
pname = "todo-mcp";
|
||||||
@@ -12,10 +12,10 @@ pkgs.rustPlatform.buildRustPackage {
|
|||||||
owner = "janezicmatej";
|
owner = "janezicmatej";
|
||||||
repo = "todo-mcp";
|
repo = "todo-mcp";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "sha256-FLsPatHeWcDMLaGZS91aaXtZEful5frN2pqZkQN9vNs=";
|
sha256 = "sha256-BBL7PAgTdGR/+vEJmot8c8mgw5vq5Y/szud0YEiR1UY=";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoHash = "sha256-gdR4p5LIEMGBV3ikuuRZ5R8CYIjE1K2OnMJm7yo18Nw=";
|
cargoHash = "sha256-uAyD7Tj9qctDXQ5NkR6T/aItxRmd5WqIXr7NeOlCl8M=";
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgs.installShellFiles ];
|
nativeBuildInputs = [ pkgs.installShellFiles ];
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
72
users/gorazd/home-manager.nix
Normal file
72
users/gorazd/home-manager.nix
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
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 ]}"
|
||||||
|
];
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
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