This commit is contained in:
@@ -155,6 +155,9 @@ main() {
|
||||
field_key=$(openssl rand -base64 32 | tr -d '\n')
|
||||
setup_code="KD-$(random_secret)"
|
||||
setup_hash=$(printf '%s' "$setup_code" | sha256sum | awk '{print $1}')
|
||||
# The Baota process manager does not own a restartable application unit.
|
||||
# Keep its updater files for diagnostics, but do not expose online update
|
||||
# actions until the panel lifecycle is integrated with the transaction state machine.
|
||||
write_env_file "$CONFIG_ROOT/kaidi.env" \
|
||||
SPRING_PROFILES_ACTIVE production \
|
||||
SERVER_ADDRESS 127.0.0.1 \
|
||||
@@ -174,7 +177,7 @@ main() {
|
||||
FINANCE_SETUP_ENV_FILE "$STATE_ROOT/setup/application.env" \
|
||||
FINANCE_SETUP_MARKER_FILE "$STATE_ROOT/setup/locked" \
|
||||
FINANCE_SETUP_RESTART_AFTER_COMPLETE true \
|
||||
FINANCE_UPDATE_ENABLED true \
|
||||
FINANCE_UPDATE_ENABLED false \
|
||||
UPDATE_RELEASE_BASE_URL '' \
|
||||
UPDATE_RELEASE_API_URL "$RELEASE_API_URL" \
|
||||
UPDATE_RELEASE_TOKEN '' \
|
||||
|
||||
+16
-4
@@ -51,7 +51,7 @@ is_managed_env_name() {
|
||||
FINANCE_SETUP_TOKEN_SHA256|FINANCE_SETUP_ENV_FILE|FINANCE_SETUP_MARKER_FILE|\
|
||||
FINANCE_SETUP_RESTART_AFTER_COMPLETE|FINANCE_UPDATE_ENABLED|\
|
||||
UPDATE_RELEASE_BASE_URL|UPDATE_RELEASE_API_URL|UPDATE_RELEASE_TOKEN|\
|
||||
UPDATE_REQUEST_FILE|UPDATE_STATUS_FILE|UPDATE_CURRENT_VERSION_FILE|APP_VERSION|KAIDI_PID_FILE)
|
||||
UPDATE_REQUEST_FILE|UPDATE_STATUS_FILE|UPDATE_CURRENT_VERSION_FILE|APP_VERSION|KAIDI_PID_FILE|KAIDI_JAVA_BIN)
|
||||
return 0
|
||||
;;
|
||||
*) return 1 ;;
|
||||
@@ -85,14 +85,23 @@ load_env_file() {
|
||||
|
||||
# The setup-generated runtime file has precedence over the base file. Non-empty
|
||||
# variables supplied by Baota have precedence over both; empty panel fields do not
|
||||
# mask the protected configuration written by the setup wizard.
|
||||
load_env_file "$RUNTIME_ENV_FILE"
|
||||
load_env_file "$CONFIG_FILE"
|
||||
# mask the protected configuration written by the setup wizard. The systemd unit
|
||||
# loads both files itself as root, then sets KAIDI_ENV_PRELOADED so the service
|
||||
# user never needs traversal permission for /etc/kaidi (which is intentionally
|
||||
# root-only).
|
||||
if [ "${KAIDI_ENV_PRELOADED:-false}" != true ]; then
|
||||
load_env_file "$RUNTIME_ENV_FILE"
|
||||
load_env_file "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
JAVA_BIN=${KAIDI_JAVA_BIN:-}
|
||||
if [ -z "$JAVA_BIN" ] && [ -n "${JAVA_HOME:-}" ]; then
|
||||
JAVA_BIN="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ -z "$JAVA_BIN" ] && [ -x /opt/kaidi/runtime/java/bin/java ]; then
|
||||
# Compatibility for installations created before external Java paths were persisted.
|
||||
JAVA_BIN=/opt/kaidi/runtime/java/bin/java
|
||||
fi
|
||||
if [ -z "$JAVA_BIN" ]; then
|
||||
JAVA_BIN=$(command -v java 2>/dev/null || true)
|
||||
fi
|
||||
@@ -102,6 +111,9 @@ if [[ "$JAVA_BIN" == */* ]]; then
|
||||
else
|
||||
command -v "$JAVA_BIN" >/dev/null 2>&1 || die "Java executable $JAVA_BIN is not available"
|
||||
fi
|
||||
JAVA_VERSION=$("$JAVA_BIN" -version 2>&1 | sed -n 's/.*version "\([0-9][0-9]*\).*/\1/p' | head -n 1)
|
||||
[[ "$JAVA_VERSION" =~ ^[0-9]+$ ]] && [ "$JAVA_VERSION" -ge 17 ] \
|
||||
|| die "Java 17 or newer is required"
|
||||
|
||||
export SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-production}
|
||||
export SERVER_ADDRESS=${SERVER_ADDRESS:-127.0.0.1}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
SPRING_PROFILES_ACTIVE=production
|
||||
SERVER_PORT=18080
|
||||
SERVER_ADDRESS=127.0.0.1
|
||||
SESSION_COOKIE_SECURE=false
|
||||
SESSION_COOKIE_SECURE=true
|
||||
|
||||
DB_URL=jdbc:mysql://127.0.0.1:3307/kaidi_finance?useUnicode=true&characterEncoding=utf8&connectionTimeZone=UTC&serverTimezone=UTC
|
||||
DB_USERNAME=kaidi
|
||||
DB_URL=jdbc:mysql://DB_HOST:DB_PORT/DB_NAME?useUnicode=true&characterEncoding=utf8&connectionTimeZone=UTC&serverTimezone=UTC
|
||||
DB_USERNAME=DB_USERNAME
|
||||
DB_PASSWORD=CHANGE_ME
|
||||
FIELD_ENCRYPTION_KEY=BASE64_32_BYTE_KEY
|
||||
|
||||
FILE_STORAGE_ROOT=/var/lib/kaidi/files
|
||||
FILE_STORAGE_TEMP=/var/lib/kaidi/tmp
|
||||
FILE_SCANNER_ENABLED=false
|
||||
FILE_SCANNER_ENABLED=true
|
||||
|
||||
FINANCE_BOOTSTRAP_ENABLED=false
|
||||
FINANCE_BOOTSTRAP_PASSWORD=
|
||||
|
||||
APP_VERSION=1.0.0-preview.9
|
||||
APP_VERSION=1.0.0-preview.31
|
||||
UPDATE_CURRENT_VERSION_FILE=/opt/kaidi/current/VERSION
|
||||
FINANCE_UPDATE_ENABLED=true
|
||||
# Use either a stable direct asset base URL or the public Gitea latest-release API.
|
||||
UPDATE_RELEASE_BASE_URL=
|
||||
UPDATE_RELEASE_API_URL=https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest
|
||||
UPDATE_RELEASE_TOKEN=READ_ONLY_GITEA_TOKEN
|
||||
UPDATE_RELEASE_TOKEN=
|
||||
UPDATE_REQUEST_FILE=/var/lib/kaidi-update/inbox/request.json
|
||||
UPDATE_STATUS_FILE=/var/lib/kaidi-update/status.json
|
||||
|
||||
@@ -5,7 +5,7 @@ umask 077
|
||||
|
||||
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
INSTALLER="$ROOT/deploy/install.sh"
|
||||
INSTALLER_SHA256=${KAIDI_INSTALLER_SHA256:-6256b05025aa314d4c02e7c0f5d2ca530f28ec5d10f833504b34c09ada6e02a5}
|
||||
INSTALLER_SHA256=${KAIDI_INSTALLER_SHA256:-6a454aff209e62d7ac75b7f97670d700ec05be710854a02136f41f55e82f9fa9}
|
||||
RELEASE_API_URL=${KAIDI_RELEASE_API_URL:-https://git.awaioi.com/api/v1/repos/ERP-Team/kaidi/releases/latest}
|
||||
PUBLIC_KEY_SHA256=${KAIDI_RELEASE_PUBLIC_KEY_SHA256:-807c6aec1dc3f7ce494db16aa9d763c66f292033c38f328afd0390d2715a8cd9}
|
||||
TOKEN_FILE=${KAIDI_RELEASE_TOKEN_FILE:-}
|
||||
|
||||
+40
-10
@@ -31,6 +31,7 @@ INSTALL_TRANSACTION_ARMED=false
|
||||
INSTALL_COMMITTED=false
|
||||
RELEASE_DIR=
|
||||
BACKUP_DIR=
|
||||
JAVA_BIN=
|
||||
JAVA_STAGED_DIR=
|
||||
JAVA_PREVIOUS_DIR=
|
||||
JAVA_ACTIVATED=false
|
||||
@@ -81,6 +82,15 @@ preflight_host() {
|
||||
esac
|
||||
[ "$host_bits" = "$expected_bits" ] \
|
||||
|| die "CPU architecture and userspace word size do not match: $HOST_ARCH/$host_bits-bit"
|
||||
if [ "$HOST_ARCH" = x86 ]; then
|
||||
getconf GNU_LIBC_VERSION >/dev/null 2>&1 \
|
||||
|| die "32-bit Linux deployment requires glibc; the downloaded i686 Java runtime is not compatible with musl"
|
||||
if ! for loader in /lib/ld-linux.so.2 /lib32/ld-linux.so.2 /lib/i386-linux-gnu/ld-linux.so.2; do
|
||||
[ -x "$loader" ] && break
|
||||
done; then
|
||||
die "32-bit Linux deployment requires the glibc loader /lib/ld-linux.so.2"
|
||||
fi
|
||||
fi
|
||||
[[ "$TRUSTED_PUBLIC_KEY_SHA256" =~ ^[0-9A-Fa-f]{64}$ ]] \
|
||||
|| die "Set KAIDI_RELEASE_PUBLIC_KEY_SHA256 to the trusted release public-key SHA-256"
|
||||
case "$REINSTALL" in
|
||||
@@ -209,6 +219,17 @@ install_packages() {
|
||||
fi
|
||||
}
|
||||
|
||||
preflight_runtime_commands() {
|
||||
local command_name
|
||||
for command_name in \
|
||||
awk bash chmod chown cp curl cut date find getconf getent grep gzip head id install jq journalctl \
|
||||
ln mktemp mv nologin openssl readlink rm runuser sed sha256sum sleep sort systemctl \
|
||||
systemd-analyze tar tr useradd usermod groupadd wc flock setsid; do
|
||||
command -v "$command_name" >/dev/null 2>&1 \
|
||||
|| die "Required command is missing after dependency preparation: $command_name"
|
||||
done
|
||||
}
|
||||
|
||||
azul_arch() {
|
||||
case "${HOST_ARCH:-$(normalized_host_arch)}" in
|
||||
x86_64) printf x86 ;;
|
||||
@@ -282,12 +303,13 @@ system_java_home() {
|
||||
|
||||
prepare_java() {
|
||||
local api java_metadata package_metadata package_uuid java_url java_sha256 actual_sha256 system_home java_line
|
||||
JAVA_BIN=
|
||||
JAVA_STAGED_DIR=
|
||||
if system_home=$(system_java_home); then
|
||||
JAVA_STAGED_DIR="$WORK_DIR/java.next"
|
||||
mkdir -p "$JAVA_STAGED_DIR"
|
||||
log "Copying existing Java 17 runtime from $system_home into the managed application directory"
|
||||
COPYFILE_DISABLE=1 cp -R "$system_home/." "$JAVA_STAGED_DIR/"
|
||||
java_line=$("$JAVA_STAGED_DIR/bin/java" -version 2>&1 | head -n 1)
|
||||
JAVA_BIN="$system_home/bin/java"
|
||||
java_line=$("$JAVA_BIN" -version 2>&1 | head -n 1) \
|
||||
|| die "The existing Java runtime cannot start on this host"
|
||||
log "Using existing Java 17+ runtime at $system_home"
|
||||
log "Local Java verified: $java_line"
|
||||
return 0
|
||||
fi
|
||||
@@ -312,11 +334,14 @@ prepare_java() {
|
||||
tar -xzf "$WORK_DIR/java.tar.gz" --strip-components=1 -C "$JAVA_STAGED_DIR"
|
||||
java_arch_matches_host "$JAVA_STAGED_DIR/bin/java" \
|
||||
|| die "Downloaded Java runtime architecture does not match $HOST_ARCH"
|
||||
java_line=$("$JAVA_STAGED_DIR/bin/java" -version 2>&1 | head -n 1)
|
||||
java_line=$("$JAVA_STAGED_DIR/bin/java" -version 2>&1 | head -n 1) \
|
||||
|| die "The downloaded Java runtime cannot start; verify glibc and the host architecture"
|
||||
JAVA_BIN="$APP_ROOT/runtime/java/bin/java"
|
||||
log "Downloaded Java verified: $java_line"
|
||||
}
|
||||
|
||||
activate_java() {
|
||||
[ -n "$JAVA_STAGED_DIR" ] || return 0
|
||||
mkdir -p "$APP_ROOT/runtime"
|
||||
JAVA_PREVIOUS_DIR="$WORK_DIR/java.previous"
|
||||
if [ -e "$APP_ROOT/runtime/java" ] || [ -L "$APP_ROOT/runtime/java" ]; then
|
||||
@@ -383,10 +408,12 @@ verify_service_access() {
|
||||
runuser -u "$SERVICE_USER" -- sh -c \
|
||||
'cd "$1" && test -r app.jar && test -r public/index.html' sh "$APP_ROOT/current" \
|
||||
|| die "$SERVICE_USER cannot traverse or read the active release"
|
||||
runuser -u "$SERVICE_USER" -- test -x "$APP_ROOT/runtime/java/bin/java" \
|
||||
|| die "$SERVICE_USER cannot execute the managed Java runtime"
|
||||
runuser -u "$SERVICE_USER" -- "$APP_ROOT/runtime/java/bin/java" -version >/dev/null 2>&1 \
|
||||
|| die "The managed Java runtime cannot execute as $SERVICE_USER"
|
||||
[ -n "$JAVA_BIN" ] && [ -x "$JAVA_BIN" ] \
|
||||
|| die "The selected Java runtime is unavailable at $JAVA_BIN"
|
||||
runuser -u "$SERVICE_USER" -- test -x "$JAVA_BIN" \
|
||||
|| die "$SERVICE_USER cannot execute the selected Java runtime"
|
||||
runuser -u "$SERVICE_USER" -- "$JAVA_BIN" -version >/dev/null 2>&1 \
|
||||
|| die "The selected Java runtime cannot execute as $SERVICE_USER"
|
||||
runuser -u "$SERVICE_USER" -- test -w "$STATE_ROOT/files" \
|
||||
|| die "$SERVICE_USER cannot write the file-storage directory"
|
||||
runuser -u "$SERVICE_USER" -- test -w "$UPDATE_STATE_ROOT/inbox" \
|
||||
@@ -828,6 +855,7 @@ validate_inputs
|
||||
configure_app_port
|
||||
preflight_host
|
||||
install_packages
|
||||
preflight_runtime_commands
|
||||
|
||||
BASE=${RELEASE_BASE_URL%/}
|
||||
WORK_DIR=$(mktemp -d)
|
||||
@@ -926,6 +954,7 @@ if [ "$SETUP_WIZARD" = true ]; then
|
||||
fi
|
||||
write_env_file_preserving_unknown "$CONFIG_ROOT/kaidi.env" \
|
||||
SPRING_PROFILES_ACTIVE production \
|
||||
KAIDI_JAVA_BIN "$JAVA_BIN" \
|
||||
SERVER_PORT "$APP_PORT" \
|
||||
SERVER_ADDRESS "$SERVER_ADDRESS" \
|
||||
SESSION_COOKIE_SECURE "$SESSION_COOKIE_SECURE" \
|
||||
@@ -963,6 +992,7 @@ write_env_file "$CONFIG_ROOT/update.env" \
|
||||
KAIDI_APP_ROOT "$APP_ROOT" \
|
||||
KAIDI_UPDATE_STATE_ROOT "$UPDATE_STATE_ROOT" \
|
||||
KAIDI_SERVICE_NAME kaidi-finance.service \
|
||||
KAIDI_JAVA_BIN "$JAVA_BIN" \
|
||||
KAIDI_HEALTH_URL "$HEALTH_URL" \
|
||||
KAIDI_APP_INDEX_URL "$APP_INDEX_URL" \
|
||||
KAIDI_DB_CONTAINER "${KAIDI_DB_CONTAINER:-}" \
|
||||
|
||||
@@ -11,8 +11,9 @@ User=kaidi
|
||||
Group=kaidi
|
||||
EnvironmentFile=/etc/kaidi/kaidi.env
|
||||
EnvironmentFile=-/var/lib/kaidi/setup/application.env
|
||||
Environment=KAIDI_ENV_PRELOADED=true
|
||||
WorkingDirectory=/opt/kaidi/current
|
||||
ExecStart=/opt/kaidi/runtime/java/bin/java -XX:MaxRAMPercentage=70 -Dfile.encoding=UTF-8 -jar /opt/kaidi/current/app.jar
|
||||
ExecStart=/opt/kaidi/current/ops/baota-start.sh
|
||||
SuccessExitStatus=143
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
+5
-3
@@ -19,6 +19,7 @@ RELEASE_API_URL=${UPDATE_RELEASE_API_URL:-}
|
||||
RELEASE_TOKEN=${UPDATE_RELEASE_TOKEN:-}
|
||||
CACHE_ROOT=${KAIDI_UPDATE_CACHE_ROOT:-$STATE_ROOT/cache}
|
||||
SERVICE_NAME=${KAIDI_SERVICE_NAME:-kaidi-finance.service}
|
||||
JAVA_BIN=${KAIDI_JAVA_BIN:-$APP_ROOT/runtime/java/bin/java}
|
||||
UPDATE_PATH_NAME=${KAIDI_UPDATE_PATH_NAME:-kaidi-update.path}
|
||||
PROCESS_MANAGER=${KAIDI_PROCESS_MANAGER:-systemd}
|
||||
PID_FILE=${KAIDI_PID_FILE:-/var/lib/kaidi/kaidi.pid}
|
||||
@@ -276,8 +277,9 @@ verify_release_access() {
|
||||
if [ "$PROCESS_MANAGER" = baota ]; then
|
||||
runuser -u "$SERVICE_USER" -- test -x "$release_dir/ops/baota-start.sh"
|
||||
else
|
||||
runuser -u "$SERVICE_USER" -- test -x "$APP_ROOT/runtime/java/bin/java" \
|
||||
&& runuser -u "$SERVICE_USER" -- "$APP_ROOT/runtime/java/bin/java" -version >/dev/null 2>&1
|
||||
runuser -u "$SERVICE_USER" -- test -x "$release_dir/ops/baota-start.sh" \
|
||||
&& runuser -u "$SERVICE_USER" -- test -x "$JAVA_BIN" \
|
||||
&& runuser -u "$SERVICE_USER" -- "$JAVA_BIN" -version >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1009,7 +1011,7 @@ if command -v restorecon >/dev/null 2>&1; then
|
||||
fi
|
||||
if ! verify_release_access "$RELEASE_DIR"; then
|
||||
rm -rf "$RELEASE_DIR"
|
||||
fail "Service user cannot access the release or managed Java runtime"
|
||||
fail "Service user cannot access the release or selected Java runtime"
|
||||
fi
|
||||
|
||||
PREVIOUS_TARGET=$(readlink "$APP_ROOT/current" 2>/dev/null || true)
|
||||
|
||||
Reference in New Issue
Block a user