From fd7a0fef9256ae829a4288adc66ac06ed99abf2e Mon Sep 17 00:00:00 2001 From: BestCodes <106822363+The-Best-Codes@users.noreply.github.com> Date: Tue, 16 Jun 2026 13:51:05 -0500 Subject: [PATCH] fix: add hermit cleanup to uvx and jbang scripts (#9616) --- ui/desktop/src/bin/jbang | 70 +++++++++++++++++++++++-- ui/desktop/src/bin/node-setup-common.sh | 25 ++++++++- ui/desktop/src/bin/uvx | 70 +++++++++++++++++++++++-- 3 files changed, 157 insertions(+), 8 deletions(-) diff --git a/ui/desktop/src/bin/jbang b/ui/desktop/src/bin/jbang index 5456939a1..c06b64276 100755 --- a/ui/desktop/src/bin/jbang +++ b/ui/desktop/src/bin/jbang @@ -29,6 +29,34 @@ else RESOLVED_GOOSE_CONFIG_DIR="${HOME}/.config/goose" fi MCP_HERMIT_DIR="${RESOLVED_GOOSE_CONFIG_DIR}/mcp-hermit" +mkdir -p "${RESOLVED_GOOSE_CONFIG_DIR}" +HERMIT_SETUP_LOCK_DIR="${RESOLVED_GOOSE_CONFIG_DIR}/.mcp-hermit-setup.lock" +HERMIT_SETUP_LOCK_TIMEOUT=300 +HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s) +while ! mkdir "${HERMIT_SETUP_LOCK_DIR}" 2>/dev/null; do + if [ $(( $(date +%s) - HERMIT_SETUP_LOCK_STARTED_AT )) -ge "${HERMIT_SETUP_LOCK_TIMEOUT}" ]; then + log "Timed out waiting for ${HERMIT_SETUP_LOCK_DIR}; removing stale lock." + rm -rf "${HERMIT_SETUP_LOCK_DIR}" + HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s) + fi + sleep 0.1 +done +trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"; log "An error occurred. Exiting with status $?."' ERR +trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"' EXIT + +# One-time cleanup for existing Linux users to fix locking issues +CLEANUP_MARKER="${RESOLVED_GOOSE_CONFIG_DIR}/.mcp-hermit-cleanup-v1" +if [[ "$(uname -s)" == "Linux" ]] && [ ! -f "${CLEANUP_MARKER}" ]; then + log "Performing one-time cleanup of old mcp-hermit directory to fix locking issues." + if [ -d "${MCP_HERMIT_DIR}" ]; then + STALE_MCP_HERMIT_DIR="${MCP_HERMIT_DIR}.stale.$$" + mv "${MCP_HERMIT_DIR}" "${STALE_MCP_HERMIT_DIR}" + rm -rf "${STALE_MCP_HERMIT_DIR}" + log "Removed old mcp-hermit directory." + fi + touch "${CLEANUP_MARKER}" + log "Cleanup completed. Marker file created." +fi # Ensure mcp-hermit/bin exists log "Creating directory ${MCP_HERMIT_DIR}/bin if it does not exist." @@ -56,9 +84,41 @@ export HERMIT_STATE_DIR="${MCP_HERMIT_DIR}/cache" export PATH="${MCP_HERMIT_DIR}/bin:${PATH}" log "Updated PATH to include ${MCP_HERMIT_DIR}/bin." -# Initialize hermit -log "Initializing hermit." -hermit init >> "$LOG_FILE" +# Check if hermit environment is already initialized (only run init on first setup) +if [ ! -f "bin/activate-hermit" ]; then + log "Hermit environment not yet initialized. Setting up hermit." + + # Fix hermit self-update lock issues on Linux by using temp binary for init only + if [[ "$(uname -s)" == "Linux" ]]; then + log "Creating temp dir with bin subdirectory for hermit copy to avoid self-update locks." + HERMIT_TMP_DIR="/tmp/hermit_tmp_$$/bin" + mkdir -p "${HERMIT_TMP_DIR}" + cp "${MCP_HERMIT_DIR}/bin/hermit" "${HERMIT_TMP_DIR}/hermit" + chmod +x "${HERMIT_TMP_DIR}/hermit" + HERMIT_ORIGINAL_PATH="${PATH}" + export PATH="${HERMIT_TMP_DIR}:${PATH}" + HERMIT_CLEANUP_DIR="/tmp/hermit_tmp_$$" + fi + + # Initialize hermit + log "Initializing hermit." + hermit init >> "$LOG_FILE" + + # Clean up temp dir if it was created + if [[ -n "${HERMIT_CLEANUP_DIR:-}" ]]; then + log "Cleaning up temporary hermit binary directory." + export PATH="${HERMIT_ORIGINAL_PATH}" + rm -rf "${HERMIT_CLEANUP_DIR}" + fi +else + log "Hermit environment already initialized. Skipping init." +fi + +# Activate the environment with output redirected to log +if [[ "$(uname -s)" == "Linux" ]]; then + log "Activating hermit environment." + { . "bin/activate-hermit"; } >> "$LOG_FILE" 2>&1 +fi # Install OpenJDK using hermit log "Installing OpenJDK with hermit." @@ -77,6 +137,10 @@ log "hermit: $(which hermit)" log "java: $(which java)" log "jbang: $(which jbang)" +rm -rf "${HERMIT_SETUP_LOCK_DIR}" +trap 'log "An error occurred. Exiting with status $?."' ERR +trap - EXIT + # Check for custom registry settings log "Checking for GOOSE_JBANG_REGISTRY environment variable for custom jbang registry setup..." if [ -n "${GOOSE_JBANG_REGISTRY:-}" ] && curl -s --head --fail "$GOOSE_JBANG_REGISTRY" > /dev/null; then diff --git a/ui/desktop/src/bin/node-setup-common.sh b/ui/desktop/src/bin/node-setup-common.sh index 748dd63d4..9a3a29bc0 100755 --- a/ui/desktop/src/bin/node-setup-common.sh +++ b/ui/desktop/src/bin/node-setup-common.sh @@ -32,16 +32,31 @@ else RESOLVED_GOOSE_CONFIG_DIR="${HOME}/.config/goose" fi MCP_HERMIT_DIR="${RESOLVED_GOOSE_CONFIG_DIR}/mcp-hermit" +mkdir -p "${RESOLVED_GOOSE_CONFIG_DIR}" +HERMIT_SETUP_LOCK_DIR="${RESOLVED_GOOSE_CONFIG_DIR}/.mcp-hermit-setup.lock" +HERMIT_SETUP_LOCK_TIMEOUT=300 +HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s) +while ! mkdir "${HERMIT_SETUP_LOCK_DIR}" 2>/dev/null; do + if [ $(( $(date +%s) - HERMIT_SETUP_LOCK_STARTED_AT )) -ge "${HERMIT_SETUP_LOCK_TIMEOUT}" ]; then + log "Timed out waiting for ${HERMIT_SETUP_LOCK_DIR}; removing stale lock." + rm -rf "${HERMIT_SETUP_LOCK_DIR}" + HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s) + fi + sleep 0.1 +done +trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"; log "An error occurred. Exiting with status $?."' ERR +trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"' EXIT # One-time cleanup for existing Linux users to fix locking issues CLEANUP_MARKER="${RESOLVED_GOOSE_CONFIG_DIR}/.mcp-hermit-cleanup-v1" if [[ "$(uname -s)" == "Linux" ]] && [ ! -f "${CLEANUP_MARKER}" ]; then log "Performing one-time cleanup of old mcp-hermit directory to fix locking issues." if [ -d "${MCP_HERMIT_DIR}" ]; then - rm -rf "${MCP_HERMIT_DIR}" + STALE_MCP_HERMIT_DIR="${MCP_HERMIT_DIR}.stale.$$" + mv "${MCP_HERMIT_DIR}" "${STALE_MCP_HERMIT_DIR}" + rm -rf "${STALE_MCP_HERMIT_DIR}" log "Removed old mcp-hermit directory." fi - mkdir -p "${RESOLVED_GOOSE_CONFIG_DIR}" touch "${CLEANUP_MARKER}" log "Cleanup completed. Marker file created." fi @@ -91,6 +106,7 @@ if [ ! -f "bin/activate-hermit" ]; then mkdir -p "${HERMIT_TMP_DIR}" cp "${MCP_HERMIT_DIR}/bin/hermit" "${HERMIT_TMP_DIR}/hermit" chmod +x "${HERMIT_TMP_DIR}/hermit" + HERMIT_ORIGINAL_PATH="${PATH}" export PATH="${HERMIT_TMP_DIR}:${PATH}" HERMIT_CLEANUP_DIR="/tmp/hermit_tmp_$$" fi @@ -102,6 +118,7 @@ if [ ! -f "bin/activate-hermit" ]; then # Clean up temp dir if it was created if [[ -n "${HERMIT_CLEANUP_DIR:-}" ]]; then log "Cleaning up temporary hermit binary directory." + export PATH="${HERMIT_ORIGINAL_PATH}" rm -rf "${HERMIT_CLEANUP_DIR}" fi else @@ -124,6 +141,10 @@ log "hermit: $(which hermit)" log "node: $(which node)" log "npx: $(which npx)" +rm -rf "${HERMIT_SETUP_LOCK_DIR}" +trap 'log "An error occurred. Exiting with status $?."' ERR +trap - EXIT + log "Checking for GOOSE_NPM_REGISTRY and GOOSE_NPM_CERT environment variables for custom npm registry setup..." # Check if GOOSE_NPM_REGISTRY is set and accessible diff --git a/ui/desktop/src/bin/uvx b/ui/desktop/src/bin/uvx index 369adadaa..db6e0c067 100755 --- a/ui/desktop/src/bin/uvx +++ b/ui/desktop/src/bin/uvx @@ -29,6 +29,34 @@ else RESOLVED_GOOSE_CONFIG_DIR="${HOME}/.config/goose" fi MCP_HERMIT_DIR="${RESOLVED_GOOSE_CONFIG_DIR}/mcp-hermit" +mkdir -p "${RESOLVED_GOOSE_CONFIG_DIR}" +HERMIT_SETUP_LOCK_DIR="${RESOLVED_GOOSE_CONFIG_DIR}/.mcp-hermit-setup.lock" +HERMIT_SETUP_LOCK_TIMEOUT=300 +HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s) +while ! mkdir "${HERMIT_SETUP_LOCK_DIR}" 2>/dev/null; do + if [ $(( $(date +%s) - HERMIT_SETUP_LOCK_STARTED_AT )) -ge "${HERMIT_SETUP_LOCK_TIMEOUT}" ]; then + log "Timed out waiting for ${HERMIT_SETUP_LOCK_DIR}; removing stale lock." + rm -rf "${HERMIT_SETUP_LOCK_DIR}" + HERMIT_SETUP_LOCK_STARTED_AT=$(date +%s) + fi + sleep 0.1 +done +trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"; log "An error occurred. Exiting with status $?."' ERR +trap 'rm -rf "${HERMIT_SETUP_LOCK_DIR}"' EXIT + +# One-time cleanup for existing Linux users to fix locking issues +CLEANUP_MARKER="${RESOLVED_GOOSE_CONFIG_DIR}/.mcp-hermit-cleanup-v1" +if [[ "$(uname -s)" == "Linux" ]] && [ ! -f "${CLEANUP_MARKER}" ]; then + log "Performing one-time cleanup of old mcp-hermit directory to fix locking issues." + if [ -d "${MCP_HERMIT_DIR}" ]; then + STALE_MCP_HERMIT_DIR="${MCP_HERMIT_DIR}.stale.$$" + mv "${MCP_HERMIT_DIR}" "${STALE_MCP_HERMIT_DIR}" + rm -rf "${STALE_MCP_HERMIT_DIR}" + log "Removed old mcp-hermit directory." + fi + touch "${CLEANUP_MARKER}" + log "Cleanup completed. Marker file created." +fi # Ensure mcp-hermit/bin exists log "Creating directory ${MCP_HERMIT_DIR}/bin if it does not exist." @@ -62,9 +90,41 @@ log "Updated PATH to include ${MCP_HERMIT_DIR}/bin." log "Checking for hermit in PATH." which hermit >> "$LOG_FILE" -# Initialize hermit -log "Initializing hermit." -hermit init >> "$LOG_FILE" +# Check if hermit environment is already initialized (only run init on first setup) +if [ ! -f "bin/activate-hermit" ]; then + log "Hermit environment not yet initialized. Setting up hermit." + + # Fix hermit self-update lock issues on Linux by using temp binary for init only + if [[ "$(uname -s)" == "Linux" ]]; then + log "Creating temp dir with bin subdirectory for hermit copy to avoid self-update locks." + HERMIT_TMP_DIR="/tmp/hermit_tmp_$$/bin" + mkdir -p "${HERMIT_TMP_DIR}" + cp "${MCP_HERMIT_DIR}/bin/hermit" "${HERMIT_TMP_DIR}/hermit" + chmod +x "${HERMIT_TMP_DIR}/hermit" + HERMIT_ORIGINAL_PATH="${PATH}" + export PATH="${HERMIT_TMP_DIR}:${PATH}" + HERMIT_CLEANUP_DIR="/tmp/hermit_tmp_$$" + fi + + # Initialize hermit + log "Initializing hermit." + hermit init >> "$LOG_FILE" + + # Clean up temp dir if it was created + if [[ -n "${HERMIT_CLEANUP_DIR:-}" ]]; then + log "Cleaning up temporary hermit binary directory." + export PATH="${HERMIT_ORIGINAL_PATH}" + rm -rf "${HERMIT_CLEANUP_DIR}" + fi +else + log "Hermit environment already initialized. Skipping init." +fi + +# Activate the environment with output redirected to log +if [[ "$(uname -s)" == "Linux" ]]; then + log "Activating hermit environment." + { . "bin/activate-hermit"; } >> "$LOG_FILE" 2>&1 +fi # Initialize python >= 3.10 log "hermit install python 3.10" @@ -80,6 +140,10 @@ log "hermit: $(which hermit)" log "uv: $(which uv)" log "uvx: $(which uvx)" +rm -rf "${HERMIT_SETUP_LOCK_DIR}" +trap 'log "An error occurred. Exiting with status $?."' ERR +trap - EXIT + log "Checking for GOOSE_UV_REGISTRY environment variable for custom python/pip/UV registry setup..." # Check if GOOSE_UV_REGISTRY is set and accessible