kimi-code/packages/server-e2e/scripts/run-docker-e2e.sh
haozhe.yang 9770f22c93 feat(server)!: rename daemon to server with service management
- rename workspace package `@moonshot-ai/daemon` to `@moonshot-ai/server`\n- rename `@moonshot-ai/daemon-e2e` to `@moonshot-ai/server-e2e`\n- replace `kimi daemon` and `kimi web` with `kimi server run`\n- keep `kimi web` as alias for `kimi server run --open`\n- add `kimi server install/uninstall/start/stop/restart/status`\n  for launchd (darwin), systemd (linux), and schtasks (win32)\n- update dev scripts, kimi-web stub, documentation, and service naming checks\n\nBREAKING CHANGE: the `kimi daemon` command and `@moonshot-ai/daemon`\npackage are removed; use `kimi server` and `@moonshot-ai/server`.
2026-06-11 16:44:41 +08:00

187 lines
6.8 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_DIR="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
REPO_ROOT="$(cd -- "${PACKAGE_DIR}/../.." && pwd)"
workspace_slug="$(
basename -- "${REPO_ROOT}" \
| tr '[:upper:]' '[:lower:]' \
| tr -cs 'a-z0-9_.-' '-' \
| sed -e 's/^[^a-z0-9]*//' -e 's/[^a-z0-9]*$//' \
| cut -c1-48
)"
if [[ -z "${workspace_slug}" ]]; then
workspace_slug="workspace"
fi
workspace_hash="$(printf '%s' "${REPO_ROOT}" | cksum | awk '{print $1}')"
RUN_ID="${KIMI_SERVER_E2E_RUN_ID:-${workspace_slug}-${workspace_hash}}"
BASE_IMAGE="${KIMI_SERVER_E2E_BASE_IMAGE:-kimi-server-e2e-base:${RUN_ID}}"
IMAGE="${KIMI_SERVER_E2E_IMAGE:-kimi-server-e2e:${RUN_ID}}"
CONTAINER="${KIMI_SERVER_E2E_CONTAINER:-kimi-server-e2e-${RUN_ID}}"
STATE_ROOT="${KIMI_SERVER_E2E_STATE_ROOT:-${HOME}/.kimi-code-server-dev}"
PORT="${KIMI_SERVER_E2E_PORT:-7878}"
KIMI_HOME_HOST="${KIMI_SERVER_E2E_KIMI_HOME_HOST:-${STATE_ROOT}/docker-e2e/${RUN_ID}/kimi-code-home}"
KIMI_HOME_CONTAINER="/data/docker-e2e/kimi-code-home"
SEED_HOME_HOST="${KIMI_SERVER_E2E_SEED_KIMI_HOME_HOST:-${STATE_ROOT}/kimi-home/kimi-code-home}"
if [[ -n "${KIMI_SERVER_E2E_REPORT_DIR_HOST:-}" ]]; then
REPORT_DIR_HOST="${KIMI_SERVER_E2E_REPORT_DIR_HOST}"
REPORT_ROOT_HOST="$(dirname -- "${REPORT_DIR_HOST}")"
REPORT_DIR_NAME="$(basename -- "${REPORT_DIR_HOST}")"
else
REPORT_ROOT_HOST="${KIMI_SERVER_E2E_REPORT_ROOT_HOST:-${STATE_ROOT}/server-e2e-reports/docker/${RUN_ID}}"
REPORT_DIR_NAME="latest"
REPORT_DIR_HOST="${REPORT_ROOT_HOST}/${REPORT_DIR_NAME}"
fi
REPORT_ROOT_CONTAINER="/data/server-e2e-reports/docker"
REPORT_DIR_CONTAINER="${REPORT_ROOT_CONTAINER}/${REPORT_DIR_NAME}"
TMPDIR_CONTAINER="/data/docker-e2e/tmp"
NM_ROOT="${STATE_ROOT}/docker-e2e/${RUN_ID}/nm"
workspace_node_modules=(
"root:/workspace/kimi-code/node_modules"
"apps_kimi-code:/workspace/kimi-code/apps/kimi-code/node_modules"
"apps_kimi-web:/workspace/kimi-code/apps/kimi-web/node_modules"
"apps_vis:/workspace/kimi-code/apps/vis/node_modules"
"apps_vis_server:/workspace/kimi-code/apps/vis/server/node_modules"
"apps_vis_web:/workspace/kimi-code/apps/vis/web/node_modules"
"docs:/workspace/kimi-code/docs/node_modules"
"pkg_acp-adapter:/workspace/kimi-code/packages/acp-adapter/node_modules"
"pkg_agent-core:/workspace/kimi-code/packages/agent-core/node_modules"
"pkg_server:/workspace/kimi-code/packages/server/node_modules"
"pkg_server-e2e:/workspace/kimi-code/packages/server-e2e/node_modules"
"pkg_kaos:/workspace/kimi-code/packages/kaos/node_modules"
"pkg_kosong:/workspace/kimi-code/packages/kosong/node_modules"
"pkg_migration-legacy:/workspace/kimi-code/packages/migration-legacy/node_modules"
"pkg_node-sdk:/workspace/kimi-code/packages/node-sdk/node_modules"
"pkg_oauth:/workspace/kimi-code/packages/oauth/node_modules"
"pkg_protocol:/workspace/kimi-code/packages/protocol/node_modules"
"pkg_services:/workspace/kimi-code/packages/services/node_modules"
"pkg_telemetry:/workspace/kimi-code/packages/telemetry/node_modules"
)
mkdir -p "${STATE_ROOT}" "${KIMI_HOME_HOST}" "${REPORT_DIR_HOST}" "${NM_ROOT}"
for mount in "${workspace_node_modules[@]}"; do
mkdir -p "${NM_ROOT}/${mount%%:*}"
done
# Seed only auth/config into the isolated docker-e2e home. Never copy server
# locks, sessions, uploaded files, or reports from the compose server home.
if [[ -f "${SEED_HOME_HOST}/config.toml" && ! -f "${KIMI_HOME_HOST}/config.toml" ]]; then
cp "${SEED_HOME_HOST}/config.toml" "${KIMI_HOME_HOST}/config.toml"
fi
if [[ -d "${SEED_HOME_HOST}/credentials" && ! -d "${KIMI_HOME_HOST}/credentials" ]]; then
cp -R "${SEED_HOME_HOST}/credentials" "${KIMI_HOME_HOST}/credentials"
fi
if [[ "${KIMI_SERVER_E2E_SKIP_BUILD:-0}" != "1" ]]; then
docker build -t "${BASE_IMAGE}" -f "${REPO_ROOT}/Dockerfile" "${REPO_ROOT}"
docker build \
-t "${IMAGE}" \
-f "${PACKAGE_DIR}/Dockerfile" \
--build-arg "BASE_IMAGE=${BASE_IMAGE}" \
"${REPO_ROOT}"
fi
docker rm -f "${CONTAINER}" >/dev/null 2>&1 || true
read -r -d '' container_script <<'EOS' || true
set -euo pipefail
cd /workspace/kimi-code
mkdir -p "${KIMI_CODE_HOME}/server" "${KIMI_SERVER_E2E_REPORT_DIR}" "${TMPDIR}" /data/server-e2e-reports/docker
rm -f "${KIMI_CODE_HOME}/server/lock"
if [[ ! -e /workspace/kimi-code/node_modules/.modules.yaml || ! -e /workspace/kimi-code/packages/server-e2e/node_modules/ws ]]; then
echo "[server-e2e:docker] installing pnpm deps"
pnpm install --frozen-lockfile
else
echo "[server-e2e:docker] pnpm deps already present"
fi
server_log="/data/server-e2e-reports/docker/server.log"
: > "${server_log}"
echo "[server-e2e:docker] starting server on container-local ${KIMI_SERVER_URL}"
pnpm dev:server -- \
--host 127.0.0.1 \
--port "${KIMI_SERVER_E2E_PORT}" \
--log-level debug \
--debug-endpoints \
>"${server_log}" 2>&1 &
server_pid=$!
cleanup() {
status=$?
if kill -0 "${server_pid}" >/dev/null 2>&1; then
kill "${server_pid}" >/dev/null 2>&1 || true
wait "${server_pid}" >/dev/null 2>&1 || true
fi
exit "${status}"
}
trap cleanup EXIT INT TERM
ready=0
for attempt in $(seq 1 90); do
if curl -fsS "${KIMI_SERVER_URL}/api/v1/meta" >/tmp/server-meta.json 2>/tmp/server-curl.err; then
ready=1
echo "[server-e2e:docker] server ready: $(cat /tmp/server-meta.json)"
break
fi
if ! kill -0 "${server_pid}" >/dev/null 2>&1; then
echo "[server-e2e:docker] server exited before readiness" >&2
tail -n 200 "${server_log}" >&2 || true
exit 1
fi
sleep 1
done
if [[ "${ready}" != "1" ]]; then
echo "[server-e2e:docker] server did not become ready within 90s" >&2
cat /tmp/server-curl.err >&2 || true
tail -n 200 "${server_log}" >&2 || true
exit 1
fi
cd /workspace/kimi-code/packages/server-e2e
pnpm test:scenarios
EOS
docker_args=(
run
--rm
--init
--name "${CONTAINER}"
--workdir /workspace/kimi-code/packages/server-e2e
--env "KIMI_CODE_HOME=${KIMI_HOME_CONTAINER}"
--env "KIMI_SERVER_E2E_PORT=${PORT}"
--env "KIMI_SERVER_URL=http://127.0.0.1:${PORT}"
--env "KIMI_SERVER_E2E_REPORT_DIR=${REPORT_DIR_CONTAINER}"
--env "TMPDIR=${TMPDIR_CONTAINER}"
--env "TERM=xterm-256color"
--env "TZ=Asia/Shanghai"
--env "npm_config_store_dir=/workspace/kimi-code/node_modules/.pnpm-store"
--env "npm_config_package_import_method=copy"
--volume "${REPO_ROOT}:/workspace/kimi-code:ro"
--volume "${KIMI_HOME_HOST}:${KIMI_HOME_CONTAINER}"
--volume "${REPORT_ROOT_HOST}:${REPORT_ROOT_CONTAINER}"
)
for mount in "${workspace_node_modules[@]}"; do
docker_args+=(--volume "${NM_ROOT}/${mount%%:*}:${mount#*:}")
done
echo "[server-e2e:docker] running ${IMAGE} without host port publishing"
set +e
docker "${docker_args[@]}" "${IMAGE}" bash -lc "${container_script}"
status=$?
set -e
echo "[server-e2e:docker] report: ${REPORT_DIR_HOST}/index.html"
echo "[server-e2e:docker] server log: ${REPORT_ROOT_HOST}/server.log"
exit "${status}"