Files

193 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="$PROJECT_DIR/.env"
read_env_var() {
local key="$1"
if [ ! -f "$ENV_FILE" ]; then
return 0
fi
local line
line=$(grep -E "^${key}=" "$ENV_FILE" | tail -n 1 || true)
if [ -n "$line" ]; then
printf '%s' "${line#*=}"
fi
}
resolve_abs_path() {
local raw_path="$1"
if [[ "$raw_path" = /* ]]; then
printf '%s' "$raw_path"
return
fi
if command -v realpath >/dev/null 2>&1; then
realpath -m "$PROJECT_DIR/$raw_path"
return
fi
(cd "$PROJECT_DIR" && printf '%s/%s\n' "$PWD" "${raw_path#./}")
}
if [ -z "${GPU_TYPE:-}" ]; then
GPU_TYPE="$(read_env_var GPU_TYPE)"
fi
if [ -z "${GPU_TYPE:-}" ]; then
echo "ERROR: 'GPU_TYPE' is not defined!"
echo "Please set it in your shell (export GPU_TYPE=amd) or create an .env file."
exit 1
fi
case "$GPU_TYPE" in
amd|intel|nvidia)
COMPOSE_FILE="$PROJECT_DIR/compose.$GPU_TYPE.yaml"
;;
*)
echo "ERROR: Invalid GPU_TYPE '$GPU_TYPE'!"
echo "Allowed values are: amd, intel, nvidia"
exit 1
;;
esac
if [ ! -f "$COMPOSE_FILE" ]; then
echo "ERROR: The file '$COMPOSE_FILE' was not found!"
exit 1
fi
if [ -z "${CONTAINER_ENGINE:-}" ]; then
CONTAINER_ENGINE="$(read_env_var CONTAINER_ENGINE)"
fi
if [ -z "${CONTAINER_ENGINE:-}" ]; then
if command -v podman-compose >/dev/null 2>&1; then
CONTAINER_ENGINE="podman"
elif command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
CONTAINER_ENGINE="docker"
else
echo "ERROR: Neither podman-compose nor docker compose is available."
exit 1
fi
fi
case "$CONTAINER_ENGINE" in
podman)
COMPOSE_CMD=(podman-compose)
ENGINE_CMD=(podman)
;;
docker)
COMPOSE_CMD=(docker compose)
ENGINE_CMD=(docker)
;;
*)
echo "ERROR: Invalid CONTAINER_ENGINE '$CONTAINER_ENGINE'. Use 'podman' or 'docker'."
exit 1
;;
esac
if [ -z "${HOST_USER_ID:-}" ]; then
HOST_USER_ID="$(read_env_var HOST_USER_ID)"
fi
if [ -z "${HOST_USER_ID:-}" ]; then
HOST_USER_ID="$(id -u)"
fi
export HOST_USER_ID
if [ -z "${HOST_WORKSPACE_PATH:-}" ]; then
HOST_WORKSPACE_PATH="$(read_env_var HOST_WORKSPACE_PATH)"
fi
if [ -z "${HOST_WORKSPACE_PATH:-}" ]; then
HOST_WORKSPACE_PATH="./storage/workspace"
fi
export HOST_WORKSPACE_PATH
if [ -z "${HOST_REPOS_PATH:-}" ]; then
HOST_REPOS_PATH="$(read_env_var HOST_REPOS_PATH)"
fi
if [ -z "${HOST_REPOS_PATH:-}" ]; then
HOST_REPOS_PATH="$PROJECT_DIR"
fi
export HOST_REPOS_PATH
HOST_WORKSPACE_ABS="$(resolve_abs_path "$HOST_WORKSPACE_PATH")"
if [ "$CONTAINER_ENGINE" = "podman" ]; then
: "${HOST_DOCKER_SOCKET_PATH:=/run/user/${HOST_USER_ID}/podman/podman.sock}"
: "${HOST_DOCKER_SOCKET_MOUNT_OPTS:=:Z}"
: "${HOST_OPENCLAW_CONFIG_MOUNT_OPTS:=:ro,Z}"
: "${HOST_OPENCLAW_WORKSPACE_MOUNT_OPTS:=:Z}"
: "${HOST_REPOS_MOUNT_OPTS:=:Z}"
: "${HOST_RW_MOUNT_OPTS:=:Z,U}"
: "${OPENCLAW_SANDBOX_UIDSHIFT:=1}"
else
: "${HOST_DOCKER_SOCKET_PATH:=/var/run/docker.sock}"
: "${HOST_DOCKER_SOCKET_MOUNT_OPTS:=}"
: "${HOST_OPENCLAW_CONFIG_MOUNT_OPTS:=:ro}"
: "${HOST_OPENCLAW_WORKSPACE_MOUNT_OPTS:=}"
: "${HOST_REPOS_MOUNT_OPTS:=}"
: "${HOST_RW_MOUNT_OPTS:=}"
: "${OPENCLAW_SANDBOX_UIDSHIFT:=0}"
fi
: "${OPENCLAW_SANDBOX_HOST_WORKSPACE:=$HOST_WORKSPACE_ABS}"
: "${OPENCLAW_SANDBOX_CONTAINER_WORKSPACE:=/home/node/.openclaw/workspace}"
export HOST_DOCKER_SOCKET_PATH
export HOST_DOCKER_SOCKET_MOUNT_OPTS
export HOST_OPENCLAW_CONFIG_MOUNT_OPTS
export HOST_OPENCLAW_WORKSPACE_MOUNT_OPTS
export HOST_REPOS_MOUNT_OPTS
export HOST_RW_MOUNT_OPTS
export OPENCLAW_SANDBOX_UIDSHIFT
export OPENCLAW_SANDBOX_HOST_WORKSPACE
export OPENCLAW_SANDBOX_CONTAINER_WORKSPACE
compose() {
"${COMPOSE_CMD[@]}" -f "$COMPOSE_FILE" "$@"
}
build_sandbox_image() {
local sandbox_tag="localhost/ghostnet-openclaw_sandbox:latest"
echo "Building sandbox base image ($sandbox_tag) with ${ENGINE_CMD[*]}..."
"${ENGINE_CMD[@]}" build \
-t "$sandbox_tag" \
-f "$PROJECT_DIR/openclaw/sandbox/Containerfile" \
"$PROJECT_DIR/openclaw/sandbox"
}
COMMAND="${1:-}"
cd "$PROJECT_DIR"
case "$COMMAND" in
up)
echo "Starting Ghostnet ($GPU_TYPE) with $CONTAINER_ENGINE..."
build_sandbox_image
compose up -d
;;
down)
echo "Stopping Ghostnet ($GPU_TYPE) with $CONTAINER_ENGINE..."
compose down
;;
restart)
echo "Restarting Ghostnet ($GPU_TYPE) with $CONTAINER_ENGINE..."
compose restart
;;
logs)
compose logs -f
;;
attached)
echo "Checking for running instances..."
compose down > /dev/null 2>&1 || true
echo "Starting Ghostnet in foreground ($GPU_TYPE) with $CONTAINER_ENGINE..."
build_sandbox_image
compose up
;;
*)
echo "Usage: ./ghostnet.sh [up|down|restart|logs|attached]"
echo "Current environment: $GPU_TYPE"
echo "Container engine: $CONTAINER_ENGINE"
exit 1
;;
esac