74 lines
2.2 KiB
Bash
74 lines
2.2 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ACTION="${1:-}"
|
|
AGENT="${2:-}"
|
|
TASK_ID="${3:-}"
|
|
BASE_REF="${4:-origin/main}"
|
|
|
|
ROOT="${AIOS_GITOPS_ROOT:-/data/aios-gitops}"
|
|
BARE="${AIOS_BARE_REPO:-$ROOT/repo.git}"
|
|
WORKTREES="${AIOS_WORKTREE_ROOT:-$ROOT/worktrees}"
|
|
RUNTIME_USER="${AIOS_RUNTIME_USER:-aiman}"
|
|
RUNTIME_GROUP="${AIOS_RUNTIME_GROUP:-gitops}"
|
|
|
|
usage() {
|
|
echo "usage: $0 create|remove <openclaw|chatgpt|controller> <task-id> [base-ref]" >&2
|
|
exit 64
|
|
}
|
|
|
|
[[ "$ACTION" =~ ^(create|remove)$ ]] || usage
|
|
[[ "$AGENT" =~ ^(openclaw|chatgpt|controller)$ ]] || usage
|
|
[[ "$TASK_ID" =~ ^[A-Za-z0-9._-]+$ ]] || {
|
|
echo "ERROR: invalid task id" >&2
|
|
exit 65
|
|
}
|
|
[[ "$(id -un)" == "$RUNTIME_USER" ]] || {
|
|
echo "ERROR: must run as $RUNTIME_USER" >&2
|
|
exit 66
|
|
}
|
|
[[ "$(id -gn)" == "$RUNTIME_GROUP" || " $(id -Gn) " == *" $RUNTIME_GROUP "* ]] || {
|
|
echo "ERROR: user must be in $RUNTIME_GROUP" >&2
|
|
exit 67
|
|
}
|
|
[[ "$(umask)" == "0002" || "$(umask)" == "002" ]] || {
|
|
echo "ERROR: umask must be 0002" >&2
|
|
exit 68
|
|
}
|
|
[[ -d "$BARE" ]] || {
|
|
echo "ERROR: bare repository missing: $BARE" >&2
|
|
exit 69
|
|
}
|
|
|
|
PATHNAME="$WORKTREES/$AGENT/$TASK_ID"
|
|
BRANCH="task/$AGENT/$TASK_ID"
|
|
|
|
case "$ACTION" in
|
|
create)
|
|
[[ ! -e "$PATHNAME" ]] || {
|
|
echo "ERROR: worktree already exists: $PATHNAME" >&2
|
|
exit 70
|
|
}
|
|
git --git-dir="$BARE" fetch --all --prune
|
|
git --git-dir="$BARE" worktree add -b "$BRANCH" "$PATHNAME" "$BASE_REF"
|
|
install -d -m 2775 "$PATHNAME/.agent/tasks/$AGENT" "$PATHNAME/.agent/results/$AGENT"
|
|
setfacl -m "u:${RUNTIME_USER}:rwx,g:${RUNTIME_GROUP}:rwx,m::rwx" "$PATHNAME"
|
|
find "$PATHNAME" -type d -exec chmod g+s {} +
|
|
find "$PATHNAME" -type d -exec \
|
|
setfacl -m "d:u:${RUNTIME_USER}:rwx,d:g:${RUNTIME_GROUP}:rwx,d:m::rwx" {} +
|
|
printf 'worktree: %s\nbranch: %s\nbase: %s\n' "$PATHNAME" "$BRANCH" "$BASE_REF"
|
|
;;
|
|
remove)
|
|
[[ -d "$PATHNAME" ]] || {
|
|
echo "ERROR: worktree not found: $PATHNAME" >&2
|
|
exit 71
|
|
}
|
|
[[ -z "$(git -C "$PATHNAME" status --porcelain)" ]] || {
|
|
echo "ERROR: worktree is not clean; retain for investigation" >&2
|
|
exit 72
|
|
}
|
|
git --git-dir="$BARE" worktree remove "$PATHNAME"
|
|
printf 'removed: %s\n' "$PATHNAME"
|
|
;;
|
|
esac
|