185 lines
6.3 KiB
Bash
Executable File
185 lines
6.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Configure Chinese mirrors if USE_CHINA_MIRRORS is set
|
|
configure_china_mirrors() {
|
|
if [[ "$USE_CHINA_MIRRORS" == "1" || "${USE_CHINA_MIRRORS,,}" == "true" ]]; then
|
|
echo "Configuring Chinese mirrors for apt and pip..."
|
|
|
|
# Replace Ubuntu sources
|
|
if [[ -f /etc/apt/sources.list.d/ubuntu.sources ]]; then
|
|
sudo sed -i 's|http://archive.ubuntu.com/ubuntu/|https://mirrors.tuna.tsinghua.edu.cn/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources
|
|
sudo sed -i 's|http://security.ubuntu.com/ubuntu/|https://mirrors.tuna.tsinghua.edu.cn/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources
|
|
echo "Updated Ubuntu apt sources to use Chinese mirrors"
|
|
fi
|
|
|
|
# Configure npm registry to use Chinese mirror (npmmirror.com is the recommended mirror)
|
|
if command -v npm &> /dev/null; then
|
|
npm config set registry https://registry.npmmirror.com/
|
|
echo "Configured npm registry to use Chinese mirror (registry.npmmirror.com)"
|
|
fi
|
|
# Also set system-wide npm config for all users
|
|
sudo mkdir -p /etc/npm
|
|
echo "registry=https://registry.npmmirror.com/" | sudo tee /etc/npm/npmrc > /dev/null
|
|
# Set for root user as well (for when npm is installed later)
|
|
sudo mkdir -p /root/.npm
|
|
echo "registry=https://registry.npmmirror.com/" | sudo tee /root/.npmrc > /dev/null
|
|
echo "Configured npm registry to use Chinese mirror (registry.npmmirror.com)"
|
|
|
|
# Configure pip to use Chinese mirrors
|
|
sudo mkdir -p /etc/pip
|
|
echo "[global]
|
|
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
|
trusted-host = pypi.tuna.tsinghua.edu.cn" | sudo tee /etc/pip/pip.conf > /dev/null
|
|
echo "Configured pip to use Chinese mirrors"
|
|
|
|
echo "Chinese mirrors configuration completed"
|
|
fi
|
|
}
|
|
|
|
# Run mirror configuration early, before any apt/pip operations
|
|
configure_china_mirrors
|
|
|
|
if [[ "$UPDATE_APT" == "1" || "${UPDATE_APT,,}" == "true" ]]; then
|
|
# Gracefully update package lists if network is available
|
|
echo "Checking network connectivity..."
|
|
if ping -c 1 -W 5 8.8.8.8 >/dev/null 2>&1 || ping -c 1 -W 5 1.1.1.1 >/dev/null 2>&1; then
|
|
echo "Network detected, refreshing package lists..."
|
|
if sudo apt update; then
|
|
echo "Package lists updated successfully"
|
|
else
|
|
echo "Warning: apt update failed despite network connectivity"
|
|
echo "Falling back to cached package lists"
|
|
fi
|
|
else
|
|
echo "No network connectivity detected, using cached package lists"
|
|
fi
|
|
fi
|
|
|
|
# Global variables to track background processes
|
|
TAIL_PID=""
|
|
INIT_PID=""
|
|
|
|
term_handler() {
|
|
echo "Received termination signal (PID: $$), cleaning up..."
|
|
|
|
# First run user-defined exit commands (may gracefully shut down processes)
|
|
if [[ -n "$COMMAND_EXIT" ]]; then
|
|
echo "Running legacy COMMAND_EXIT..."
|
|
eval "$COMMAND_EXIT"
|
|
fi
|
|
|
|
# Then run numbered COMMAND_EXIT variables in order
|
|
for i in {01..99}; do
|
|
var_name="COMMAND_EXIT$i"
|
|
var_value="${!var_name}"
|
|
if [[ -n "$var_value" ]]; then
|
|
echo "Running $var_name..."
|
|
eval "$var_value"
|
|
fi
|
|
done
|
|
|
|
# Kill any still-running background processes if they didn't shut down gracefully
|
|
if [[ -n "$INIT_PID" ]]; then
|
|
if kill -0 "$INIT_PID" 2>/dev/null; then
|
|
echo "Init process still running, force killing: $INIT_PID"
|
|
kill "$INIT_PID" 2>/dev/null
|
|
else
|
|
echo "Init process already terminated gracefully"
|
|
fi
|
|
fi
|
|
|
|
# Kill the tail process if it's running
|
|
if [[ -n "$TAIL_PID" ]]; then
|
|
echo "Killing tail process: $TAIL_PID"
|
|
kill "$TAIL_PID" 2>/dev/null
|
|
fi
|
|
|
|
# Stop SSH service
|
|
echo "Stopping SSH service..."
|
|
sudo service ssh stop 2>/dev/null || true
|
|
|
|
echo "Cleanup completed, exiting..."
|
|
exit 0
|
|
}
|
|
|
|
# Debug: Show our PID and signal handling setup
|
|
echo "Entrypoint script starting with PID: $$"
|
|
echo "Setting up signal handlers..."
|
|
|
|
# Setup signal handlers for graceful shutdown
|
|
trap 'term_handler' SIGTERM SIGINT SIGQUIT
|
|
|
|
# Test signal handling is working
|
|
echo "Signal handlers registered. Testing with kill -0..."
|
|
|
|
# setup home directory for the current user. It is useful for attaching vscode with container.
|
|
user_name=$(whoami)
|
|
user_home="/home/$user_name"
|
|
sudo mkdir -p "$user_home"
|
|
sudo chown -R "$(id -u):$(id -g)" "$user_home"
|
|
cp -r /etc/skel/. "$user_home" 2>/dev/null || true
|
|
|
|
if [[ $LOG_FILE != "/dev/null" ]]; then
|
|
sudo touch "$LOG_FILE"
|
|
sudo chown -R "$(id -u):$(id -g)" "$LOG_FILE"
|
|
fi
|
|
|
|
echo "Starting SSH service..."
|
|
sudo service ssh start
|
|
|
|
# Run initialization commands (last one in background to allow signal handling)
|
|
# First collect all defined COMMAND_INIT variables
|
|
init_commands=()
|
|
if [[ -n "$COMMAND_INIT" ]]; then
|
|
init_commands+=("COMMAND_INIT")
|
|
fi
|
|
for i in {01..99}; do
|
|
var_name="COMMAND_INIT$i"
|
|
if [[ -n "${!var_name}" ]]; then
|
|
init_commands+=("$var_name")
|
|
fi
|
|
done
|
|
|
|
# Execute them: all synchronously except the last one
|
|
for ((i=0; i<${#init_commands[@]}; i++)); do
|
|
var_name="${init_commands[i]}"
|
|
var_value="${!var_name}"
|
|
|
|
if [[ $i -eq $((${#init_commands[@]} - 1)) ]]; then
|
|
# Last command - run in background to avoid blocking signals
|
|
echo "Running $var_name (final command) in background..."
|
|
eval "$var_value" &
|
|
INIT_PID=$!
|
|
echo "Background process started with PID: $INIT_PID"
|
|
else
|
|
# Not last - run synchronously to preserve expected behavior
|
|
echo "Running $var_name..."
|
|
eval "$var_value"
|
|
fi
|
|
done
|
|
|
|
# Start the main process loop
|
|
if [[ $LOG_FILE == "/dev/null" ]]; then
|
|
# If no log file, just wait for signals
|
|
echo "Container ready, waiting for signals..."
|
|
while true; do
|
|
sleep 1 &
|
|
wait $! || break
|
|
done
|
|
else
|
|
# If log file specified, tail it
|
|
echo "Container ready, tailing log file: $LOG_FILE"
|
|
tail -f "$LOG_FILE" &
|
|
TAIL_PID=$!
|
|
|
|
# Wait for the tail process or signals, but make it interruptible
|
|
while kill -0 $TAIL_PID 2>/dev/null; do
|
|
sleep 1 &
|
|
wait $! || break
|
|
done
|
|
fi
|
|
# This should never be reached, but if it is, exit gracefully
|
|
echo "Main loop exited unexpectedly"
|
|
exit 0
|
|
|