feat:CISD初始化

This commit is contained in:
waner
2026-03-05 11:08:57 +08:00
parent 1bc24d4408
commit 1c254aaba9
61 changed files with 8948 additions and 59 deletions
+144
View File
@@ -0,0 +1,144 @@
#!/usr/bin/env bash
set -euo pipefail
# CISD init flow runner:
# status -> preview -> create task -> execute -> query steps -> failed step log
#
# Usage:
# chmod +x scripts/cisd_init_flow.sh
# REQUEST_JSON=/tmp/cisd-init-standard-rabbit.json ./scripts/cisd_init_flow.sh
#
# Optional env:
# BASE_URL=http://127.0.0.1:8080
# INTERNAL_TOKEN=change-me-internal-token
# OUT_DIR=/tmp/cisd-init-run
# FETCH_FAILED_STEP_LOG=true
BASE_URL="${BASE_URL:-http://127.0.0.1:8080}"
INTERNAL_TOKEN="${INTERNAL_TOKEN:-change-me-internal-token}"
REQUEST_JSON="${REQUEST_JSON:-}"
OUT_DIR="${OUT_DIR:-/tmp/cisd-init-run}"
FETCH_FAILED_STEP_LOG="${FETCH_FAILED_STEP_LOG:-true}"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-30}"
TS="$(date +%Y%m%d%H%M%S)"
RUN_DIR="${OUT_DIR}/run-${TS}"
require_cmd() {
local cmd="$1"
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "[FATAL] command missing: ${cmd}"
exit 1
fi
}
api_get() {
local path="$1"
curl -sS --max-time "${TIMEOUT_SECONDS}" \
-H "X-Internal-Token: ${INTERNAL_TOKEN}" \
"${BASE_URL}${path}"
}
api_post_json() {
local path="$1"
local body_file="$2"
curl -sS --max-time "${TIMEOUT_SECONDS}" \
-H "X-Internal-Token: ${INTERNAL_TOKEN}" \
-H "Content-Type: application/json" \
-X POST "${BASE_URL}${path}" \
-d @"${body_file}"
}
api_post_empty() {
local path="$1"
curl -sS --max-time "${TIMEOUT_SECONDS}" \
-H "X-Internal-Token: ${INTERNAL_TOKEN}" \
-X POST "${BASE_URL}${path}"
}
expect_success() {
local label="$1"
local file="$2"
if jq -e '.success == true and .code == 200' "${file}" >/dev/null 2>&1; then
echo "[PASS] ${label}"
else
echo "[FAIL] ${label}"
cat "${file}"
exit 2
fi
}
main() {
require_cmd curl
require_cmd jq
if [[ -z "${REQUEST_JSON}" ]]; then
echo "[FATAL] REQUEST_JSON is required"
echo "Example: REQUEST_JSON=/tmp/cisd-init-standard-rabbit.json ./scripts/cisd_init_flow.sh"
exit 1
fi
if [[ ! -f "${REQUEST_JSON}" ]]; then
echo "[FATAL] request file not found: ${REQUEST_JSON}"
exit 1
fi
mkdir -p "${RUN_DIR}"
echo "[INFO] run dir: ${RUN_DIR}"
echo "[INFO] base url: ${BASE_URL}"
echo "[STEP] device status"
api_get "/api/v1/device/status" | tee "${RUN_DIR}/01-device-status.json" >/dev/null
expect_success "device status" "${RUN_DIR}/01-device-status.json"
jq '.data | {presetProductType,presetVersion,presetSource}' "${RUN_DIR}/01-device-status.json" || true
echo "[STEP] init preview"
api_post_json "/api/v1/init/preview" "${REQUEST_JSON}" | tee "${RUN_DIR}/02-preview.json" >/dev/null
expect_success "init preview" "${RUN_DIR}/02-preview.json"
jq '.data | {resolvedProductType,presetVersion,stepCount,summary}' "${RUN_DIR}/02-preview.json" || true
echo "[STEP] create init task"
api_post_json "/api/v1/init/tasks" "${REQUEST_JSON}" | tee "${RUN_DIR}/03-create-task.json" >/dev/null
expect_success "create task" "${RUN_DIR}/03-create-task.json"
TASK_ID="$(jq -r '.data.taskId // empty' "${RUN_DIR}/03-create-task.json")"
if [[ -z "${TASK_ID}" ]]; then
echo "[FATAL] taskId missing in create task response"
cat "${RUN_DIR}/03-create-task.json"
exit 2
fi
echo "[INFO] task id: ${TASK_ID}"
echo "[STEP] execute init task"
api_post_empty "/api/v1/init/tasks/${TASK_ID}/execute" | tee "${RUN_DIR}/04-execute-task.json" >/dev/null
expect_success "execute task api call" "${RUN_DIR}/04-execute-task.json"
TASK_STATUS="$(jq -r '.data.status // empty' "${RUN_DIR}/04-execute-task.json")"
echo "[INFO] task status: ${TASK_STATUS}"
echo "[STEP] query task steps"
api_get "/api/v1/init/tasks/${TASK_ID}/steps" | tee "${RUN_DIR}/05-task-steps.json" >/dev/null
expect_success "query task steps" "${RUN_DIR}/05-task-steps.json"
jq -r '.data[] | "\(.stepNo)\t\(.stepCode)\t\(.status)\t\(.message // "")"' "${RUN_DIR}/05-task-steps.json" || true
if [[ "${FETCH_FAILED_STEP_LOG,,}" == "true" ]]; then
FAILED_STEP_NO="$(jq -r '.data[] | select(.status=="FAILED") | .stepNo' "${RUN_DIR}/05-task-steps.json" | head -n1 || true)"
if [[ -n "${FAILED_STEP_NO}" ]]; then
echo "[STEP] fetch failed step log: stepNo=${FAILED_STEP_NO}"
api_get "/api/v1/init/tasks/${TASK_ID}/steps/${FAILED_STEP_NO}/log" | tee "${RUN_DIR}/06-failed-step-log.json" >/dev/null || true
if jq -e '.success == true and .code == 200' "${RUN_DIR}/06-failed-step-log.json" >/dev/null 2>&1; then
jq -r '.data.content' "${RUN_DIR}/06-failed-step-log.json" > "${RUN_DIR}/06-failed-step.log.txt" || true
echo "[INFO] failed step log saved: ${RUN_DIR}/06-failed-step.log.txt"
else
echo "[WARN] failed step log API did not return success"
fi
fi
fi
if [[ "${TASK_STATUS}" == "SUCCESS" ]]; then
echo "[DONE] init flow completed successfully, taskId=${TASK_ID}"
exit 0
fi
echo "[DONE] init flow completed with non-success status=${TASK_STATUS}, taskId=${TASK_ID}"
exit 3
}
main "$@"
+173
View File
@@ -0,0 +1,173 @@
#!/usr/bin/env bash
set -euo pipefail
# CISD init on-host precheck.
# Usage:
# chmod +x scripts/cisd_init_precheck.sh
# ./scripts/cisd_init_precheck.sh
# Optional:
# PRODUCT_TYPE=ENTERPRISE ./scripts/cisd_init_precheck.sh
PRODUCT_TYPE="${PRODUCT_TYPE:-${TMS_CISD_PRESET_PRODUCT_TYPE:-UNKNOWN}}"
MODE="${TMS_INIT_EXECUTOR_MODE:-SIMULATE}"
LOG_DIR="${TMS_INIT_EXECUTOR_LOG_DIR:-/tmp/tms-init-logs}"
STANDARD_CPCONFIG_PATH="${TMS_INIT_EXECUTOR_STANDARD_CPCONFIG_PATH:-/home/cmep4i/cpconfig.cfg}"
DIRECT_DB_SCRIPT_DIR="${TMS_INIT_EXECUTOR_DIRECT_DB_SCRIPT_DIR:-/opt/CAE_Install_Base_Resource/DB}"
DIRECT_TLQ_INIT_CFG_DIR="${TMS_INIT_EXECUTOR_DIRECT_TLQ_INIT_CFG_DIR:-/opt/CAE_Install_App_Resource/CAE}"
APP_PATTERN_1="${TMS_INIT_EXECUTOR_STANDARD_RABBIT_APP_CONFIG_PATTERN_1:-/home/cmep4i/cmsp/application-prd*.properties}"
APP_PATTERN_2="${TMS_INIT_EXECUTOR_STANDARD_RABBIT_APP_CONFIG_PATTERN_2:-/home/cmep4i/cmtp/application-prd*.properties}"
RABBIT_CRED_ENCRYPT_ENABLED="${TMS_INIT_EXECUTOR_STANDARD_RABBIT_CREDENTIAL_ENCRYPT_ENABLED:-true}"
RABBIT_CRED_SECRET_KEY="${TMS_INIT_EXECUTOR_STANDARD_RABBIT_CREDENTIAL_SECRET_KEY:-ABCDEFGHIJKLMN1234567890}"
pass_count=0
warn_count=0
fail_count=0
pass() {
echo "[PASS] $1"
pass_count=$((pass_count + 1))
}
warn() {
echo "[WARN] $1"
warn_count=$((warn_count + 1))
}
fail() {
echo "[FAIL] $1"
fail_count=$((fail_count + 1))
}
check_cmd() {
local cmd="$1"
if command -v "$cmd" >/dev/null 2>&1; then
pass "command exists: ${cmd}"
else
fail "command missing: ${cmd}"
fi
}
check_file() {
local file="$1"
if [[ -f "$file" ]]; then
pass "file exists: ${file}"
else
fail "file missing: ${file}"
fi
}
check_dir() {
local dir="$1"
if [[ -d "$dir" ]]; then
pass "directory exists: ${dir}"
else
fail "directory missing: ${dir}"
fi
}
check_writable_dir() {
local dir="$1"
mkdir -p "$dir" 2>/dev/null || true
if [[ -d "$dir" && -w "$dir" ]]; then
pass "directory writable: ${dir}"
else
fail "directory not writable: ${dir}"
fi
}
check_pattern_match() {
local pattern="$1"
shopt -s nullglob
local matches=($pattern)
shopt -u nullglob
if (( ${#matches[@]} > 0 )); then
pass "pattern matched (${#matches[@]}): ${pattern}"
else
fail "pattern has no match: ${pattern}"
fi
}
check_product_type() {
case "$PRODUCT_TYPE" in
ENTERPRISE|INDIRECT|DIRECT)
pass "product type recognized: ${PRODUCT_TYPE}"
;;
*)
fail "product type invalid: ${PRODUCT_TYPE} (expected ENTERPRISE/INDIRECT/DIRECT)"
;;
esac
}
check_mode() {
if [[ "$MODE" == "LOCAL" ]]; then
pass "executor mode is LOCAL"
else
warn "executor mode is ${MODE}; on-host initialization should use LOCAL"
fi
}
check_encryption_config() {
local enabled_lower
enabled_lower="$(echo "$RABBIT_CRED_ENCRYPT_ENABLED" | tr '[:upper:]' '[:lower:]')"
if [[ "$enabled_lower" == "true" ]]; then
pass "rabbit app credential encryption is enabled"
if [[ -n "$RABBIT_CRED_SECRET_KEY" ]]; then
if [[ ${#RABBIT_CRED_SECRET_KEY} -eq 24 ]]; then
pass "rabbit credential secret key length is 24 (DESede)"
else
warn "rabbit credential secret key length is ${#RABBIT_CRED_SECRET_KEY}, expected 24"
fi
else
fail "rabbit credential secret key is empty"
fi
else
warn "rabbit app credential encryption disabled"
fi
}
check_standard_assets() {
check_file "$STANDARD_CPCONFIG_PATH"
check_file "/home/cmep4i/cpackage/toolsh/setfraq.sh"
check_file "/home/cmep4i/cpackage/toolsh/setftq.sh"
check_file "/home/cmep4i/cpackage/toolsh/setsql.sh"
check_file "/home/cmep4i/cpackage/toolsh/setsptp.sh"
check_pattern_match "$APP_PATTERN_1"
check_pattern_match "$APP_PATTERN_2"
check_cmd "rabbitmqctl"
check_cmd "rabbitmqadmin"
}
check_direct_assets() {
check_file "$STANDARD_CPCONFIG_PATH"
check_dir "$DIRECT_DB_SCRIPT_DIR"
check_file "$DIRECT_DB_SCRIPT_DIR/setsql.sh"
check_dir "$DIRECT_TLQ_INIT_CFG_DIR"
check_file "$DIRECT_TLQ_INIT_CFG_DIR/init_cfg.sh"
check_cmd "java"
check_cmd "rabbitmqctl"
}
main() {
echo "[INFO] CISD init precheck started"
echo "[INFO] PRODUCT_TYPE=${PRODUCT_TYPE}"
echo "[INFO] MODE=${MODE}"
echo "[INFO] LOG_DIR=${LOG_DIR}"
check_product_type
check_mode
check_writable_dir "$LOG_DIR"
check_encryption_config
if [[ "$PRODUCT_TYPE" == "DIRECT" ]]; then
check_direct_assets
else
check_standard_assets
fi
echo "[INFO] precheck summary: pass=${pass_count}, warn=${warn_count}, fail=${fail_count}"
if (( fail_count > 0 )); then
exit 2
fi
}
main "$@"
+118
View File
@@ -0,0 +1,118 @@
#!/usr/bin/env bash
set -euo pipefail
# PCIe real-card smoke test template for internal crypto APIs.
# Fill env vars below, then run:
# chmod +x scripts/pcie_realcard_smoke.sh
# ./scripts/pcie_realcard_smoke.sh
BASE_URL="${BASE_URL:-http://127.0.0.1:8080}"
INTERNAL_TOKEN="${INTERNAL_TOKEN:-change-me-internal-token}"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-15}"
# Common algorithm IDs (GM/T 0018 style)
ALG_SM3="${ALG_SM3:-1}" # digest/hmac
ALG_SM4_ECB="${ALG_SM4_ECB:-1025}" # 0x00000401, symmetric encrypt/decrypt
# Test payloads
PLAINTEXT_B64="${PLAINTEXT_B64:-dG1zLXBjaWUtc21va2U=}" # "tms-pcie-smoke"
KEY_16_B64="${KEY_16_B64:-MDEyMzQ1Njc4OWFiY2RlZg==}" # "0123456789abcdef"
IV_B64="${IV_B64:-}" # ECB can keep empty
pass_count=0
fail_count=0
require_cmd() {
local cmd="$1"
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "[FATAL] command not found: $cmd"
exit 1
fi
}
api_get() {
local path="$1"
curl -sS --max-time "${TIMEOUT_SECONDS}" \
-H "X-Internal-Token: ${INTERNAL_TOKEN}" \
"${BASE_URL}${path}"
}
api_post() {
local path="$1"
local body="$2"
curl -sS --max-time "${TIMEOUT_SECONDS}" \
-H "Content-Type: application/json" \
-H "X-Internal-Token: ${INTERNAL_TOKEN}" \
-X POST \
"${BASE_URL}${path}" \
-d "${body}"
}
assert_success() {
local name="$1"
local resp="$2"
if echo "${resp}" | jq -e '.success == true and .code == 200' >/dev/null 2>&1; then
echo "[PASS] ${name}"
pass_count=$((pass_count + 1))
else
echo "[FAIL] ${name}"
echo " response: ${resp}"
fail_count=$((fail_count + 1))
fi
}
run_case_get() {
local name="$1"
local path="$2"
local resp
resp="$(api_get "${path}")"
assert_success "${name}" "${resp}"
}
run_case_post() {
local name="$1"
local path="$2"
local body="$3"
local resp
resp="$(api_post "${path}" "${body}")"
assert_success "${name}" "${resp}"
}
main() {
require_cmd curl
require_cmd jq
echo "[INFO] BASE_URL=${BASE_URL}"
echo "[INFO] starting smoke tests..."
run_case_get "device-count" "/api/v1/device/crypto/device-count"
run_case_get "device-info" "/api/v1/device/crypto/device-info"
run_case_post "self-test" "/api/v1/device/crypto/self-test" "{}"
run_case_get "random-16" "/api/v1/device/crypto/random?length=16"
run_case_post "digest-sm3" "/api/v1/device/crypto/digest" "$(cat <<JSON
{"algId":${ALG_SM3},"dataBase64":"${PLAINTEXT_B64}","outBufferSize":64}
JSON
)"
run_case_post "hmac-sm3" "/api/v1/device/crypto/hmac" "$(cat <<JSON
{"algId":${ALG_SM3},"keyBase64":"${KEY_16_B64}","dataBase64":"${PLAINTEXT_B64}"}
JSON
)"
run_case_post "encrypt-plain-sm4" "/api/v1/device/crypto/encrypt/plain" "$(cat <<JSON
{"algId":${ALG_SM4_ECB},"keyBase64":"${KEY_16_B64}","ivBase64":"${IV_B64}","dataBase64":"${PLAINTEXT_B64}","outBufferSize":256}
JSON
)"
run_case_post "kek-generate-128" "/api/v1/device/crypto/kek/generate" '{"keyBits":128,"keyIndex":1}'
run_case_get "kek-status-1" "/api/v1/device/crypto/kek/status?keyIndex=1"
run_case_get "lmk-seed-mac" "/api/v1/device/crypto/lmk/seed-mac"
echo "[INFO] smoke tests completed: pass=${pass_count}, fail=${fail_count}"
if [ "${fail_count}" -gt 0 ]; then
exit 2
fi
}
main "$@"
Executable
+189
View File
@@ -0,0 +1,189 @@
#!/usr/bin/env bash
set -euo pipefail
# TMS runtime script for jar deployment.
# Commands:
# ./scripts/tms.sh start
# ./scripts/tms.sh stop
# ./scripts/tms.sh restart
# ./scripts/tms.sh status
#
# External config:
# ${APP_HOME}/config/application.yml
# ${APP_HOME}/config/application-${SPRING_PROFILES_ACTIVE}.yml
DEFAULT_APP_HOME="/home/tms"
APP_HOME="${APP_HOME:-${DEFAULT_APP_HOME}}"
APP_NAME="${APP_NAME:-tms-framework}"
RUN_DIR="${RUN_DIR:-${APP_HOME}/run}"
LOG_DIR="${LOG_DIR:-${APP_HOME}/logs}"
CONF_DIR="${CONF_DIR:-${APP_HOME}/config}"
PID_FILE="${PID_FILE:-${RUN_DIR}/${APP_NAME}.pid}"
OUT_LOG="${OUT_LOG:-${LOG_DIR}/${APP_NAME}.out.log}"
ERR_LOG="${ERR_LOG:-${LOG_DIR}/${APP_NAME}.err.log}"
SPRING_PROFILES_ACTIVE="${SPRING_PROFILES_ACTIVE:-prod}"
JAVA_BIN="${JAVA_BIN:-java}"
JAVA_OPTS="${JAVA_OPTS:- -Xms512m -Xmx1024m}"
ALLOW_MISSING_EXTERNAL_CONFIG="${ALLOW_MISSING_EXTERNAL_CONFIG:-false}"
JAR_PATH="${JAR_PATH:-${APP_HOME}/${APP_NAME}.jar}"
ensure_dirs() {
mkdir -p "${RUN_DIR}" "${LOG_DIR}" "${CONF_DIR}"
}
resolve_jar_path() {
if [[ -f "${JAR_PATH}" ]]; then
return 0
fi
local found
found="$(ls -1 "${APP_HOME}/target/${APP_NAME}"-*.jar 2>/dev/null | grep -vE '(sources|javadoc|original)' | head -n1 || true)"
if [[ -n "${found}" ]]; then
JAR_PATH="${found}"
return 0
fi
echo "[FATAL] jar not found. set JAR_PATH or place jar at ${APP_HOME}/${APP_NAME}.jar"
exit 1
}
check_external_config() {
local base_cfg="${CONF_DIR}/application.yml"
if [[ "${ALLOW_MISSING_EXTERNAL_CONFIG}" != "true" && ! -f "${base_cfg}" ]]; then
echo "[FATAL] external config missing: ${base_cfg}"
echo "Copy template: cp ${APP_HOME}/config/application.yml.example ${base_cfg}"
exit 1
fi
}
is_running() {
if [[ ! -f "${PID_FILE}" ]]; then
return 1
fi
local pid
pid="$(cat "${PID_FILE}")"
if [[ -z "${pid}" ]]; then
return 1
fi
if kill -0 "${pid}" >/dev/null 2>&1; then
return 0
fi
return 1
}
start_app() {
ensure_dirs
resolve_jar_path
check_external_config
if is_running; then
echo "[INFO] ${APP_NAME} already running, pid=$(cat "${PID_FILE}")"
return 0
fi
local cfg_location
cfg_location="optional:file:${CONF_DIR}/"
echo "[INFO] starting ${APP_NAME}"
echo "[INFO] app home: ${APP_HOME}"
echo "[INFO] jar path: ${JAR_PATH}"
echo "[INFO] profile: ${SPRING_PROFILES_ACTIVE}"
echo "[INFO] external config dir: ${CONF_DIR}"
# shellcheck disable=SC2086
nohup "${JAVA_BIN}" ${JAVA_OPTS} \
-jar "${JAR_PATH}" \
--spring.profiles.active="${SPRING_PROFILES_ACTIVE}" \
--spring.config.additional-location="${cfg_location}" \
>"${OUT_LOG}" 2>"${ERR_LOG}" &
local pid="$!"
echo "${pid}" > "${PID_FILE}"
sleep 1
if kill -0 "${pid}" >/dev/null 2>&1; then
echo "[INFO] started, pid=${pid}"
echo "[INFO] out log: ${OUT_LOG}"
echo "[INFO] err log: ${ERR_LOG}"
else
echo "[ERROR] start failed, check logs"
rm -f "${PID_FILE}"
exit 1
fi
}
stop_app() {
if ! is_running; then
echo "[INFO] ${APP_NAME} not running"
rm -f "${PID_FILE}" || true
return 0
fi
local pid
pid="$(cat "${PID_FILE}")"
echo "[INFO] stopping ${APP_NAME}, pid=${pid}"
kill "${pid}" >/dev/null 2>&1 || true
local i
for i in $(seq 1 20); do
if ! kill -0 "${pid}" >/dev/null 2>&1; then
rm -f "${PID_FILE}" || true
echo "[INFO] stopped"
return 0
fi
sleep 1
done
echo "[WARN] graceful stop timeout, force kill pid=${pid}"
kill -9 "${pid}" >/dev/null 2>&1 || true
rm -f "${PID_FILE}" || true
echo "[INFO] stopped(force)"
}
status_app() {
if is_running; then
echo "[INFO] ${APP_NAME} is running, pid=$(cat "${PID_FILE}")"
return 0
fi
echo "[INFO] ${APP_NAME} is not running"
return 1
}
usage() {
cat <<EOF
Usage: $0 {start|stop|restart|status}
Environment variables:
APP_HOME default: /home/tms
APP_NAME default: tms-framework
JAR_PATH default: <app_home>/tms-framework.jar
CONF_DIR default: <app_home>/config
RUN_DIR default: <app_home>/run
LOG_DIR default: <app_home>/logs
SPRING_PROFILES_ACTIVE default: prod
JAVA_BIN default: java
JAVA_OPTS default: -Xms512m -Xmx1024m
ALLOW_MISSING_EXTERNAL_CONFIG default: false
EOF
}
cmd="${1:-}"
case "${cmd}" in
start)
start_app
;;
stop)
stop_app
;;
restart)
stop_app
start_app
;;
status)
status_app
;;
*)
usage
exit 1
;;
esac