feat: datcode
This commit is contained in:
commit
25bb67e958
66 changed files with 5821 additions and 0 deletions
130
bin/datcode
Executable file
130
bin/datcode
Executable file
|
|
@ -0,0 +1,130 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
instance=datcode
|
||||
script_path=$(readlink -f -- "$0")
|
||||
script_dir=$(CDPATH= cd -- "$(dirname -- "$script_path")" && pwd)
|
||||
root_dir=$(dirname -- "$script_dir")
|
||||
data_dir=$root_dir/data
|
||||
workdir=$(pwd -P)
|
||||
owns_vm=false
|
||||
mode=run
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
if [ "$#" -ne 1 ] || [ "$1" != update ]; then
|
||||
printf '%s\n' "usage: datcode [update]" >&2
|
||||
exit 2
|
||||
fi
|
||||
mode=update
|
||||
fi
|
||||
|
||||
if ! command -v limactl >/dev/null 2>&1; then
|
||||
printf '%s\n' "datcode: limactl is not installed or not in PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$mode" = run ]; then
|
||||
case "$workdir" in
|
||||
/dat | /dat/*) ;;
|
||||
*)
|
||||
printf '%s\n' "datcode: the working directory must be under /dat" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
mkdir -p \
|
||||
"$data_dir/config" \
|
||||
"$data_dir/share" \
|
||||
"$data_dir/state" \
|
||||
"$data_dir/tmux"
|
||||
|
||||
cleanup() {
|
||||
status=$?
|
||||
trap - EXIT HUP INT TERM
|
||||
|
||||
if [ "$owns_vm" = true ]; then
|
||||
vm_status=$(limactl list "$instance" --format '{{.Status}}' 2>/dev/null || true)
|
||||
if [ "$vm_status" = "Running" ]; then
|
||||
if ! limactl stop "$instance" >/dev/null 2>&1; then
|
||||
printf '%s\n' "datcode: graceful VM shutdown failed; forcing shutdown" >&2
|
||||
limactl stop --force "$instance" >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
trap 'exit 129' HUP
|
||||
trap 'exit 130' INT
|
||||
trap 'exit 143' TERM
|
||||
|
||||
start_vm() {
|
||||
owns_vm=true
|
||||
printf '%s\n' "datcode: starting VM (first boot can take several minutes)"
|
||||
limactl start --timeout=10m "$instance"
|
||||
}
|
||||
|
||||
if [ "$(limactl list "$instance" --quiet 2>/dev/null || true)" = "$instance" ]; then
|
||||
vm_status=$(limactl list "$instance" --format '{{.Status}}')
|
||||
if [ "$vm_status" != "Stopped" ]; then
|
||||
printf '%s\n' "datcode: instance is $vm_status; only one datcode session may run at a time" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
limactl create --tty=false --name="$instance" "$root_dir/lima.yaml"
|
||||
fi
|
||||
|
||||
if [ "$mode" = update ]; then
|
||||
limactl edit --tty=false --mount-only "$data_dir:w" "$instance"
|
||||
else
|
||||
case "$data_dir" in
|
||||
"$workdir" | "$workdir"/*)
|
||||
limactl edit --tty=false --mount-only "$workdir:w" "$instance"
|
||||
;;
|
||||
*)
|
||||
case "$workdir" in
|
||||
"$data_dir" | "$data_dir"/*)
|
||||
limactl edit --tty=false --mount-only "$data_dir:w" "$instance"
|
||||
;;
|
||||
*)
|
||||
limactl edit --tty=false \
|
||||
--mount-only "$workdir:w" \
|
||||
--mount-only "$data_dir:w" \
|
||||
"$instance"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
start_vm
|
||||
|
||||
if ! limactl shell --tty=false "$instance" /bin/bash -lc \
|
||||
'sudo -n docker info >/dev/null && command -v bun >/dev/null && command -v opencode >/dev/null && command -v tmux >/dev/null'; then
|
||||
printf '%s\n' "datcode: VM provisioning failed; inspect /var/log/cloud-init-output.log" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! limactl shell --tty=false "$instance" docker info >/dev/null; then
|
||||
printf '%s\n' "datcode: restarting VM to activate Docker group membership"
|
||||
limactl stop "$instance" >/dev/null
|
||||
start_vm
|
||||
fi
|
||||
|
||||
if ! limactl shell --tty=false "$instance" /bin/bash -lc \
|
||||
'docker info >/dev/null && command -v bun >/dev/null && command -v opencode >/dev/null && command -v tmux >/dev/null'; then
|
||||
printf '%s\n' "datcode: VM readiness check failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$mode" = update ]; then
|
||||
limactl shell "$instance" /bin/bash -lc \
|
||||
'export BUN_INSTALL="$HOME/.local"; exec bun install --global opencode-ai'
|
||||
else
|
||||
limactl shell --workdir "$workdir" "$instance" \
|
||||
/usr/bin/tmux new-session -A -s dat \
|
||||
/bin/bash -lc '/usr/local/bin/opencode; exec /bin/bash'
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue