From 36f1a8b00d3dbc45373919ef28954d296765f92c Mon Sep 17 00:00:00 2001 From: Qiufeng Date: Tue, 18 Aug 2026 19:50:14 +0800 Subject: [PATCH] fix: keep setup database config empty and isolate Baota mode --- .gitea/workflows/release.yml | 6 ++-- deploy/baota-init.sh | 50 ++++++++------------------------- deploy/install.sh | 11 ++++++-- scripts/test-install-fixture.sh | 24 ++++++++++++++++ 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 2be6a13..83eae75 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -126,8 +126,10 @@ jobs: - name: Publish Gitea release env: GITEA_TOKEN: ${{ secrets.RELEASE_GITEA_TOKEN }} - GITEA_SERVER_URL: ${{ github.server_url }} - GITEA_REPOSITORY: ${{ github.repository }} + # Gitea's runner leaves github.server_url/repository empty on some + # host-mode tag events; keep the release destination explicit. + GITEA_SERVER_URL: https://git.awaioi.com + GITEA_REPOSITORY: ERP-Team/kaidi GITEA_REF_NAME: ${{ steps.release_meta.outputs.ref }} GITEA_SHA: ${{ steps.release_meta.outputs.revision }} run: ./scripts/publish-gitea-release.sh diff --git a/deploy/baota-init.sh b/deploy/baota-init.sh index 927d2d4..c1cd378 100755 --- a/deploy/baota-init.sh +++ b/deploy/baota-init.sh @@ -9,7 +9,6 @@ CONFIG_ROOT=/etc/kaidi STATE_ROOT=/var/lib/kaidi UPDATE_STATE_ROOT=/var/lib/kaidi-update LOG_ROOT=/var/log/kaidi -UPDATER_ROOT=/opt/kaidi/bin PUBLIC_KEY_SHA256=807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9 RELEASE_API_URL=https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest INIT_ARMED=false @@ -29,7 +28,7 @@ rollback_initialization() { rm -f /etc/systemd/system/kaidi-update.service /etc/systemd/system/kaidi-update.path systemctl daemon-reload >/dev/null 2>&1 || true rm -f "$CONFIG_ROOT/kaidi.env" "$CONFIG_ROOT/update.env" \ - "$CONFIG_ROOT/release-public.pem" "$UPDATER_ROOT/update.sh" \ + "$CONFIG_ROOT/release-public.pem" \ "$UPDATE_STATE_ROOT/status.json" /root/kaidi-first-login.txt rm -f "$INIT_APP_ROOT/current.next" if [ -n "$INIT_RELEASE_ROOT" ] \ @@ -95,7 +94,7 @@ main() { [ "$(uname -s)" = Linux ] || die "Baota initialization only supports Linux" command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ] \ || die "systemd is required for the privileged background updater" - for command in find openssl setsid sha256sum; do + for command in find openssl sha256sum; do command -v "$command" >/dev/null 2>&1 || die "$command is required" done @@ -137,7 +136,7 @@ main() { INIT_ARMED=true ensure_service_identity - install -d -o root -g "$SERVICE_GROUP" -m 0750 "$app_root" "$releases_root" "$UPDATER_ROOT" + install -d -o root -g "$SERVICE_GROUP" -m 0750 "$app_root" "$releases_root" install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 0750 \ "$STATE_ROOT" "$STATE_ROOT/files" "$STATE_ROOT/tmp" "$LOG_ROOT" install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 0700 "$STATE_ROOT/setup" @@ -163,9 +162,11 @@ main() { SERVER_ADDRESS 127.0.0.1 \ SERVER_PORT "$app_port" \ SESSION_COOKIE_SECURE false \ - DB_URL 'jdbc:mysql://setup.invalid:3306/kaidi_finance' \ - DB_USERNAME setup_pending \ - DB_PASSWORD setup_pending \ + # The setup context has no datasource. Empty values avoid Baota treating + # a development placeholder as a real local MySQL dependency. + DB_URL '' \ + DB_USERNAME '' \ + DB_PASSWORD '' \ FIELD_ENCRYPTION_KEY "$field_key" \ FILE_STORAGE_ROOT "$STATE_ROOT/files" \ FILE_STORAGE_TEMP "$STATE_ROOT/tmp" \ @@ -187,39 +188,10 @@ main() { chown root:"$SERVICE_GROUP" "$CONFIG_ROOT/kaidi.env" chmod 0640 "$CONFIG_ROOT/kaidi.env" + # Baota owns the Java process in this mode. Do not install a second + # systemd updater; online update is intentionally systemd-only until the + # panel lifecycle can participate in the transaction state machine. install -m 0644 "$release_root/ops/release-public.pem" "$CONFIG_ROOT/release-public.pem" - install -m 0755 "$release_root/ops/update.sh" "$UPDATER_ROOT/update.sh" - write_env_file "$CONFIG_ROOT/update.env" \ - UPDATE_RELEASE_BASE_URL '' \ - UPDATE_RELEASE_API_URL "$RELEASE_API_URL" \ - UPDATE_RELEASE_TOKEN '' \ - UPDATE_REQUEST_FILE "$UPDATE_STATE_ROOT/inbox/request.json" \ - UPDATE_STATUS_FILE "$UPDATE_STATE_ROOT/status.json" \ - UPDATE_PUBLIC_KEY "$CONFIG_ROOT/release-public.pem" \ - KAIDI_APP_ROOT "$app_root" \ - KAIDI_UPDATE_STATE_ROOT "$UPDATE_STATE_ROOT" \ - KAIDI_PROCESS_MANAGER baota \ - KAIDI_PID_FILE "$STATE_ROOT/kaidi.pid" \ - KAIDI_RUNTIME_ENV_FILE "$STATE_ROOT/setup/application.env" \ - KAIDI_UPDATER_PATH "$UPDATER_ROOT/update.sh" \ - KAIDI_SERVICE_USER "$SERVICE_USER" \ - KAIDI_SERVICE_GROUP "$SERVICE_GROUP" \ - KAIDI_UPDATE_PATH_NAME kaidi-update.path \ - KAIDI_HEALTH_URL "http://127.0.0.1:$app_port/actuator/health" \ - KAIDI_APP_INDEX_URL "http://127.0.0.1:$app_port/" \ - KAIDI_DB_HOST setup.invalid \ - KAIDI_DB_PORT 3306 \ - KAIDI_DB_NAME kaidi_finance \ - KAIDI_DB_USERNAME setup_pending \ - KAIDI_DB_PASSWORD setup_pending - chmod 0600 "$CONFIG_ROOT/update.env" - - install -m 0644 "$release_root/ops/kaidi-update.service" /etc/systemd/system/kaidi-update.service - install -m 0644 "$release_root/ops/kaidi-update.path" /etc/systemd/system/kaidi-update.path - systemd-analyze verify /etc/systemd/system/kaidi-update.service /etc/systemd/system/kaidi-update.path >/dev/null \ - || die "The privileged update units failed validation" - systemctl daemon-reload - systemctl enable --now kaidi-update.path printf '{"state":"CURRENT","message":"Baota release is prepared","targetVersion":"%s","updatedAt":"%s"}\n' \ "$version" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$UPDATE_STATE_ROOT/status.json" diff --git a/deploy/install.sh b/deploy/install.sh index 25ca7ff..f5145fd 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -586,9 +586,11 @@ configure_database() { if [ "$SETUP_WIZARD" = true ]; then [ -z "${KAIDI_DB_URL:-}${KAIDI_DB_USERNAME:-}${KAIDI_DB_PASSWORD:-}" ] \ || die "Do not pass database credentials when KAIDI_SETUP_WIZARD=true; enter them in the browser wizard" - DB_URL='jdbc:mysql://setup.invalid:3306/kaidi_finance' - DB_USERNAME=setup_pending - DB_PASSWORD=setup_pending + # First-run mode does not create a datasource. Keep database fields empty + # so hosting panels cannot mistake a placeholder for a local MySQL service. + DB_URL= + DB_USERNAME= + DB_PASSWORD= return 0 fi if [ "$REINSTALL" = true ]; then @@ -613,6 +615,7 @@ configure_database() { database_host() { local endpoint host_port + [ -n "$DB_URL" ] || { printf ''; return; } endpoint=${DB_URL#jdbc:mysql://} host_port=${endpoint%%/*} printf '%s' "${KAIDI_DB_HOST:-${host_port%%:*}}" @@ -620,6 +623,7 @@ database_host() { database_port() { local endpoint host_port candidate + [ -n "$DB_URL" ] || { printf ''; return; } endpoint=${DB_URL#jdbc:mysql://} host_port=${endpoint%%/*} candidate=${host_port##*:} @@ -629,6 +633,7 @@ database_port() { database_name() { local endpoint name + [ -n "$DB_URL" ] || { printf ''; return; } endpoint=${DB_URL#jdbc:mysql://} name=${endpoint#*/} name=${name%%\?*} diff --git a/scripts/test-install-fixture.sh b/scripts/test-install-fixture.sh index 206ad50..a987286 100755 --- a/scripts/test-install-fixture.sh +++ b/scripts/test-install-fixture.sh @@ -24,6 +24,10 @@ mode_of() { sed -n '/^port_is_listening()/,/^}/p' "$ROOT/deploy/install.sh" sed -n '/^valid_app_port()/,/^}/p' "$ROOT/deploy/install.sh" sed -n '/^configure_app_port()/,/^}/p' "$ROOT/deploy/install.sh" + sed -n '/^configure_database()/,/^}/p' "$ROOT/deploy/install.sh" + sed -n '/^database_host()/,/^}/p' "$ROOT/deploy/install.sh" + sed -n '/^database_port()/,/^}/p' "$ROOT/deploy/install.sh" + sed -n '/^database_name()/,/^}/p' "$ROOT/deploy/install.sh" sed -n '/^is_semver()/,/^}/p' "$ROOT/deploy/install.sh" sed -n '/^write_env_file_preserving_unknown()/,/^}/p' "$ROOT/deploy/install.sh" sed -n '/^normalized_host_arch()/,/^}/p' "$ROOT/deploy/install.sh" @@ -47,6 +51,14 @@ source "$WORK/helpers.sh" export SETUP_WIZARD=true preflight_database || fail 'setup wizard database preflight returned a failure status' +REINSTALL=false +# shellcheck disable=SC2034 # Consumed by the extracted configure_database helper. +KAIDI_DB_URL='' KAIDI_DB_USERNAME='' KAIDI_DB_PASSWORD='' +configure_database +[ -z "$DB_URL$DB_USERNAME$DB_PASSWORD" ] \ + || fail 'setup wizard retained a fake database configuration' +[ -z "$(database_host)$(database_port)$(database_name)" ] \ + || fail 'setup wizard exposed placeholder database coordinates to the updater' mkdir -p "$WORK/mysql-bin" cat > "$WORK/mysql-bin/mysql" <<'SH' @@ -299,12 +311,24 @@ grep -Fq '[ "$APP_ROOT" = /opt/kaidi ]' "$ROOT/deploy/install.sh" \ || fail 'installer no longer rejects unsupported custom roots' grep -Fq '8.4.*) ;;' "$ROOT/deploy/install.sh" \ || fail 'installer no longer enforces MySQL 8.4.x' +! grep -Fq 'jdbc:mysql://setup.invalid' "$ROOT/deploy/install.sh" \ + || fail 'installer still writes a fake setup database URL' +! grep -Fq 'jdbc:mysql://setup.invalid' "$ROOT/deploy/baota-init.sh" \ + || fail 'Baota initializer still writes a fake setup database URL' +! grep -Fq 'KAIDI_DB_HOST setup.invalid' "$ROOT/deploy/baota-init.sh" \ + || fail 'Baota updater still points at a fake setup database host' +! grep -Fq 'systemctl enable --now kaidi-update.path' "$ROOT/deploy/baota-init.sh" \ + || fail 'Baota initializer still enables the systemd updater' +# shellcheck disable=SC2016 # Match literal initializer source. +! grep -Fq 'install -m 0644 "$release_root/ops/kaidi-update.service"' "$ROOT/deploy/baota-init.sh" \ + || fail 'Baota initializer still installs the systemd updater unit' grep -Fq '32-bit Linux deployment requires glibc' "$ROOT/deploy/install.sh" \ || fail 'installer does not reject unsupported musl 32-bit hosts before downloading Java' grep -Fq '32-bit Linux deployment requires the glibc loader' "$ROOT/deploy/install.sh" \ || fail 'installer does not reject a 32-bit host without the glibc loader' grep -Fq 'preflight_runtime_commands' "$ROOT/deploy/install.sh" \ || fail 'installer does not validate required runtime commands' +# shellcheck disable=SC2016 # Match literal installer source. grep -Fq 'KAIDI_MYSQLDUMP_BIN "${KAIDI_MYSQLDUMP_BIN:-}"' "$ROOT/deploy/install.sh" \ || fail 'installer does not preserve a custom mysqldump path for online updates' # shellcheck disable=SC2016 # Match literal installer source.