214 lines
5.9 KiB
Bash
214 lines
5.9 KiB
Bash
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SCRIPT="$PLUGIN_DIR/scripts/setup/native_mariadb_port_takeover.sh"
|
|
TMP_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
setup_fixture() {
|
|
local dir="$1"
|
|
mkdir -p "$dir/bin" "$dir/my.cnf.d"
|
|
|
|
cat > "$dir/my.cnf" <<'EOF'
|
|
[client]
|
|
port=3306
|
|
|
|
[mysqld]
|
|
datadir=/var/lib/mysql
|
|
port=3306
|
|
socket=/var/lib/mysql/mysql.sock
|
|
EOF
|
|
|
|
cat > "$dir/mysql.conf" <<'EOF'
|
|
user=da_admin
|
|
passwd=secret
|
|
port=3306
|
|
socket=/var/lib/mysql/mysql.sock
|
|
host=
|
|
EOF
|
|
|
|
cat > "$dir/options.conf" <<'EOF'
|
|
mysql_inst=mariadb
|
|
mariadb=10.6
|
|
EOF
|
|
|
|
cat > "$dir/os-release" <<'EOF'
|
|
ID="almalinux"
|
|
VERSION_ID="9.4"
|
|
EOF
|
|
}
|
|
|
|
# run_takeover DIR
|
|
# Runs the script under test against the fixture already prepared at DIR
|
|
# (by a prior call to setup_fixture, possibly customized further by the
|
|
# scenario since) - writes stdout+stderr to "$DIR/run.out". Does NOT touch
|
|
# the fixture itself, so scenario-specific customizations made after
|
|
# setup_fixture (e.g. editing mysql.conf, swapping os-release) are preserved.
|
|
run_takeover() {
|
|
local dir="$1"
|
|
|
|
env \
|
|
NATIVE_TAKEOVER_LOG="$dir/takeover.log" \
|
|
NATIVE_MY_CNF="$dir/my.cnf" \
|
|
NATIVE_MY_CNF_D="$dir/my.cnf.d" \
|
|
NATIVE_MYSQL_CONF="$dir/mysql.conf" \
|
|
CUSTOMBUILD_OPTIONS_CONF="$dir/options.conf" \
|
|
OS_RELEASE_FILE="$dir/os-release" \
|
|
NEW_NATIVE_PORT="3307" \
|
|
DA_CLI_BIN="$dir/bin/da" \
|
|
PATH="$dir/bin:$PATH" \
|
|
bash "$SCRIPT" > "$dir/run.out" 2>&1
|
|
}
|
|
|
|
# --- Fake command stubs shared by scenarios; each scenario builds its own copies ---
|
|
write_common_stubs() {
|
|
local dir="$1"
|
|
local mode="${2:-happy}"
|
|
|
|
cat > "$dir/bin/id" <<'EOF'
|
|
#!/bin/bash
|
|
if [ "$1" = "-u" ]; then
|
|
echo 0
|
|
exit 0
|
|
fi
|
|
exit 1
|
|
EOF
|
|
chmod 755 "$dir/bin/id"
|
|
|
|
cat > "$dir/bin/da" <<EOF
|
|
#!/bin/bash
|
|
echo "\$*" >> "$dir/da_calls.log"
|
|
exit 0
|
|
EOF
|
|
chmod 755 "$dir/bin/da"
|
|
|
|
cat > "$dir/bin/mysql" <<EOF
|
|
#!/bin/bash
|
|
CURRENT_PORT_FILE="$dir/current_port"
|
|
requested_port=""
|
|
for arg in "\$@"; do
|
|
case "\$arg" in
|
|
--port=*) requested_port="\${arg#--port=}" ;;
|
|
esac
|
|
done
|
|
if [ "\$requested_port" = "\$(cat "\$CURRENT_PORT_FILE" 2>/dev/null || echo 3306)" ]; then
|
|
exit 0
|
|
fi
|
|
exit 1
|
|
EOF
|
|
chmod 755 "$dir/bin/mysql"
|
|
echo "3306" > "$dir/current_port"
|
|
|
|
cat > "$dir/bin/systemctl" <<EOF
|
|
#!/bin/bash
|
|
# mysql_service_name() (mysql_common.sh) probes "mysqld", then "mariadb", then
|
|
# "mysql" via 'systemctl list-unit-files <name>.service' and picks the first
|
|
# that succeeds - only mariadb.service "exists" here, matching a real
|
|
# AlmaLinux+MariaDB box where mysqld.service does not exist.
|
|
if [ "\$1" = "list-unit-files" ]; then
|
|
case "\$2" in
|
|
mariadb.service) exit 0 ;;
|
|
*) exit 1 ;;
|
|
esac
|
|
fi
|
|
|
|
echo "systemctl \$*" >> "$dir/systemctl_calls.log"
|
|
if [ "\$1" = "restart" ] && [ "\$2" = "mariadb" ] && [ "$mode" = "restart-fail" ]; then
|
|
exit 1
|
|
fi
|
|
if [ "\$1" = "restart" ] && [ "\$2" = "mariadb" ]; then
|
|
echo "3307" > "$dir/current_port"
|
|
fi
|
|
if [ "\$1" = "restart" ] && [ "\$2" = "directadmin" ] && [ "$mode" = "da-restart-fail" ]; then
|
|
exit 1
|
|
fi
|
|
exit 0
|
|
EOF
|
|
chmod 755 "$dir/bin/systemctl"
|
|
|
|
cat > "$dir/bin/ss" <<EOF
|
|
#!/bin/bash
|
|
current="\$(cat "$dir/current_port" 2>/dev/null || echo 3306)"
|
|
for arg in "\$@"; do
|
|
case "\$arg" in
|
|
*":\$current"*) echo header; echo occupied; exit 0 ;;
|
|
esac
|
|
done
|
|
exit 0
|
|
EOF
|
|
chmod 755 "$dir/bin/ss"
|
|
}
|
|
|
|
# --- Scenario 1: happy path ---
|
|
DIR="$TMP_DIR/happy"
|
|
setup_fixture "$DIR"
|
|
write_common_stubs "$DIR" happy
|
|
run_takeover "$DIR"
|
|
STATUS=$?
|
|
[ "$STATUS" -eq 0 ] || fail "happy path should exit 0, got $STATUS: $(cat "$DIR/run.out")"
|
|
grep -Fxq "port=3307" "$DIR/mysql.conf" || fail "happy path should leave mysql.conf on port 3307"
|
|
grep -Fq "build set mysql_inst no" "$DIR/da_calls.log" || fail "happy path should call da build set mysql_inst no"
|
|
grep -Fq "restart mariadb" "$DIR/systemctl_calls.log" || fail "happy path should restart mariadb"
|
|
grep -Fq "restart directadmin" "$DIR/systemctl_calls.log" || fail "happy path should restart directadmin"
|
|
|
|
# --- Scenario 2: already migrated (idempotent no-op) ---
|
|
DIR="$TMP_DIR/already"
|
|
setup_fixture "$DIR"
|
|
write_common_stubs "$DIR" happy
|
|
sed -i.orig 's/^port=3306$/port=3307/' "$DIR/mysql.conf"
|
|
run_takeover "$DIR"
|
|
STATUS=$?
|
|
[ "$STATUS" -eq 0 ] || fail "already-migrated case should exit 0, got $STATUS"
|
|
grep -Fq "build set" "$DIR/da_calls.log" 2>/dev/null && fail "already-migrated case should not touch CustomBuild settings"
|
|
|
|
# --- Scenario 3: OS guard rejection ---
|
|
DIR="$TMP_DIR/badose"
|
|
setup_fixture "$DIR"
|
|
write_common_stubs "$DIR" happy
|
|
cat > "$DIR/os-release" <<'EOF'
|
|
ID="cloudlinux"
|
|
VERSION_ID="8.9"
|
|
EOF
|
|
set +e
|
|
run_takeover "$DIR"
|
|
STATUS=$?
|
|
set -e
|
|
[ "$STATUS" -ne 0 ] || fail "CloudLinux should be refused, not exit 0"
|
|
grep -Fq "build set" "$DIR/da_calls.log" 2>/dev/null && fail "OS-guard rejection must not touch CustomBuild settings"
|
|
|
|
# --- Scenario 4: rollback when native restart fails ---
|
|
DIR="$TMP_DIR/restartfail"
|
|
setup_fixture "$DIR"
|
|
write_common_stubs "$DIR" restart-fail
|
|
set +e
|
|
run_takeover "$DIR"
|
|
STATUS=$?
|
|
set -e
|
|
[ "$STATUS" -ne 0 ] || fail "a failed native restart should not exit 0"
|
|
grep -Fxq "port=3306" "$DIR/mysql.conf" \
|
|
|| fail "mysql.conf should be rolled back to port 3306 after a failed native restart"
|
|
grep -Fq "build set mysql_inst mariadb" "$DIR/da_calls.log" \
|
|
|| fail "mysql_inst should be restored to mariadb after a failed native restart"
|
|
|
|
# --- Scenario 5: rollback when DirectAdmin restart fails ---
|
|
DIR="$TMP_DIR/darestartfail"
|
|
setup_fixture "$DIR"
|
|
write_common_stubs "$DIR" da-restart-fail
|
|
set +e
|
|
run_takeover "$DIR"
|
|
STATUS=$?
|
|
set -e
|
|
[ "$STATUS" -ne 0 ] || fail "a failed directadmin restart should not exit 0"
|
|
grep -Fxq "port=3306" "$DIR/mysql.conf" \
|
|
|| fail "mysql.conf should be rolled back to port 3306 after a failed directadmin restart"
|
|
grep -Fq "build set mysql_inst mariadb" "$DIR/da_calls.log" \
|
|
|| fail "mysql_inst should be restored to mariadb after a failed directadmin restart"
|
|
|
|
echo "native_mariadb_port_takeover_e2e_test: OK"
|