Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions docker/scripts/container_selection.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash

# ----- Constants -----
DOCKER_IMAGE_REPO=${DOCKER_IMAGE_REPO:="wheelos/apollo"}
GEOLOC=${GEOLOC:="cn"}
GEO_REGISTRY=""

function geo_specific_config() {
local geo="$1"
if [[ -z "${geo}" ]]; then
echo "Use default GeoLocation settings"
return
fi
echo "Setup geolocation specific configurations for ${geo}"

if [[ "${geo}" == "cn" ]]; then
echo "GeoLocation settings for Mainland China"
GEO_REGISTRY="registry.cn-hangzhou.aliyuncs.com"
else
echo "GeoLocation settings for ${geo} is not ready, fallback to default"
fi
}

# Function: Pull Docker image, check local cache first if requested
function docker_pull() {
local base_image_name="$1"
local __final_image_var_name="$2"

# Determine the pull candidate based on geolocation
local pull_candidate_image_name="${base_image_name}"
if [[ -n "${GEO_REGISTRY}" ]]; then
pull_candidate_image_name="${GEO_REGISTRY}/${base_image_name}"
fi

# Check if local image exists
if docker image inspect "${pull_candidate_image_name}" >/dev/null 2>&1; then
echo "Using local image '${pull_candidate_image_name}'."
else
echo "Starting pull of docker image '${pull_candidate_image_name}' ..."
if ! docker pull "${pull_candidate_image_name}"; then
echo "Failed to pull docker image: '${pull_candidate_image_name}'"
return 1
fi
fi

eval "${__final_image_var_name}='${pull_candidate_image_name}'" # Store the final image name
return 0
}

# Function: Determine image based on architecture and GPU usage
function determine_image() {
local arch="$1" # e.g., x86 or arm
local os_ver="$2" # e.g., 20.04
local gpu="$3" # e.g., true (for GPU) or false (for CPU)

# Construct the base image name using the specified format
local base_image_name="dev-${arch}-${os_ver}"
local image_name=""

# Append GPU or CPU suffix based on the input
if [[ "$gpu" == "true" ]]; then
image_name="${DOCKER_IMAGE_REPO}:${base_image_name}-gpu"
else
image_name="${DOCKER_IMAGE_REPO}:${base_image_name}-cpu"
fi

# Pull the Docker image or use the existing one
if ! docker_pull "${image_name}" "APOLLO_IMAGE"; then
echo "Failed to determine image."
exit 1
fi
}

# Main function to call from whl.sh
function select_container() {
local arch="$1"
local os_ver="$2"
local gpu="$3"

geo_specific_config "${GEOLOC}"
determine_image "${arch}" "${os_ver}" "${gpu}"
}

# Allow invocation of select_container from the command line for testing
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
select_container "$@"
fi
2 changes: 1 addition & 1 deletion docker/scripts/dev_start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ DOCKER_IMAGE_TAG=${DOCKER_IMAGE_TAG:=""} # Default empty
GEOLOC="" # Default: auto-detect ('us', 'cn', 'none')
SHM_SIZE="2G" # Default shared memory size
USE_LOCAL_IMAGE=1 # Flag to use local image (0 or 1)
CUSTOM_DIST="stable" # Apollo distribution (stable/testing)
CUSTOM_DIST="stable" # Apollo distribution (stable/test)
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says the supported values are "stable/test", but the actual CLI parsing and usage text in this script uses "stable/testing". Please align the comment with the real option name to avoid misleading users.

Suggested change
CUSTOM_DIST="stable" # Apollo distribution (stable/test)
CUSTOM_DIST="stable" # Apollo distribution (stable/testing)

Copilot uses AI. Check for mistakes.
USER_AGREED="no" # Flag for Apollo License Agreement ('yes' or 'no')
FORCE_PULL="no" # Flag to force pull the image

Expand Down
50 changes: 50 additions & 0 deletions docker/scripts/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
set -e

# 1. Dynamically create users identical to those on the host machine
USER_NAME=${USER_NAME:-apollo}
USER_ID=${USER_ID:-1000}
GROUP_ID=${GROUP_ID:-1000}

if ! getent group "$USER_NAME" >/dev/null; then
groupadd -g "$GROUP_ID" "$USER_NAME" 2>/dev/null || groupmod -g "$GROUP_ID" $(getent group "$GROUP_ID" | cut -d: -f1)
fi
Comment on lines +9 to +11
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The group creation fallback (groupadd ... || groupmod ...) does not guarantee that a group named $USER_NAME exists when the GID is already taken by a different group. Later commands (like chown "$USER_NAME":"$USER_NAME") can then fail with an invalid group. Prefer ensuring the group name exists (e.g., create the group with a different GID/name) or use the existing group name for ${GROUP_ID} and chown by numeric IDs.

Copilot uses AI. Check for mistakes.

if ! id -u "$USER_NAME" >/dev/null 2>&1; then
useradd -u "$USER_ID" -g "$GROUP_ID" -m -s /bin/bash "$USER_NAME"
echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
fi

# 2. Correct critical directory permissions
chown "$USER_NAME":"$USER_NAME" /apollo
Comment on lines +15 to +19
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entrypoint script appends a NOPASSWD:ALL rule for USER_NAME into /etc/sudoers, giving the application user full passwordless sudo inside the container. If any service or process running as this user is compromised, an attacker can trivially escalate to root in the container; in dev mode the core service is also started as privileged with host devices and host PID namespace, so root in the container can be leveraged to impact the host. Tighten this by avoiding NOPASSWD:ALL for the app user (or removing the sudoers entry entirely) and, if root is required, limiting sudo to a minimal set of commands while avoiding privileged where possible.

Suggested change
echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
fi
# 2. Correct critical directory permissions
chown "$USER_NAME":"$USER_NAME" /apollo
fi
# 2. Correct critical directory permissions
chown "$USER_NAME":"$USER_NAME" /apollo
chown "$USER_NAME":"$USER_NAME" /apollo

Copilot uses AI. Check for mistakes.
[ -d "/var/cache/bazel" ] && chown -R "$USER_NAME":"$USER_NAME" /var/cache/bazel

# 3. Load Apollo environment
# setup rc files
USER_HOME="$(getent passwd ${USER_NAME} | cut -d: -f6)"
cp /etc/skel/.{profile,bashrc,bash_logout} "${USER_HOME}/"
RCFILES_DIR="/opt/apollo/rcfiles"
if [[ -d "${RCFILES_DIR}" ]]; then
for entry in ${RCFILES_DIR}/*; do
rc=$(basename "${entry}")
if [[ "${rc}" = user.* ]]; then
cp -rf "${entry}" "${USER_HOME}/${rc##user}"
fi
done
fi
# Set user files ownership to current user, such as .bashrc, .profile, etc.
chown -R "${USER_ID}:${GROUP_ID}" ${USER_HOME}/.*
if [ -f "/apollo/cyber/setup.bash" ]; then
source /apollo/cyber/setup.bash
fi

# 4. Business logic branch
# If AUTO_BOOTSTRAP=true is set (usually for one-click startup in Dev mode)
if [[ "${AUTO_BOOTSTRAP}" == "true" ]]; then
echo "[Entrypoint] Auto-starting Dreamview..."
nohup bash /apollo/scripts/bootstrap.sh start > /apollo/data/log/bootstrap.log 2>&1 &
fi

# 5. Keep running the container
echo ">>> Container is ready for user: $USER_NAME"
exec tail -f /dev/null
Loading