Import alt-mysql plugin
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
$pluginDir = dirname(__DIR__);
|
||||
require_once $pluginDir . '/exec/lib/Settings.php';
|
||||
require_once $pluginDir . '/exec/lib/DirectAdminUser.php';
|
||||
|
||||
function fail(string $message): void
|
||||
{
|
||||
fwrite(STDERR, "FAIL: {$message}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function assert_true(bool $condition, string $message): void
|
||||
{
|
||||
if (!$condition) {
|
||||
fail($message);
|
||||
}
|
||||
}
|
||||
|
||||
function assert_same($expected, $actual, string $message): void
|
||||
{
|
||||
if ($expected !== $actual) {
|
||||
fail($message . ' expected=' . var_export($expected, true) . ' actual=' . var_export($actual, true));
|
||||
}
|
||||
}
|
||||
|
||||
function load_settings(string $contents): Settings
|
||||
{
|
||||
$path = tempnam(sys_get_temp_dir(), 'altmysql-settings-');
|
||||
if ($path === false) {
|
||||
fail('cannot create temp settings file');
|
||||
}
|
||||
file_put_contents($path, $contents);
|
||||
$settings = Settings::load($path);
|
||||
unlink($path);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
function make_da_user(Settings $settings, array $userConf, array $packageConf): DirectAdminUser
|
||||
{
|
||||
$class = new ReflectionClass(DirectAdminUser::class);
|
||||
/** @var DirectAdminUser $user */
|
||||
$user = $class->newInstanceWithoutConstructor();
|
||||
foreach ([
|
||||
'username' => 'demo',
|
||||
'prefix' => 'demo_',
|
||||
'userConf' => $userConf,
|
||||
'packageConf' => $packageConf,
|
||||
'settings' => $settings,
|
||||
] as $property => $value) {
|
||||
$prop = $class->getProperty($property);
|
||||
$prop->setAccessible(true);
|
||||
$prop->setValue($user, $value);
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
$alwaysSettings = load_settings("always_enabled=1\nMYSQL_PLUGIN_DEFAULT_DB_LIMIT=5\n");
|
||||
assert_true($alwaysSettings->alwaysEnabled(), 'always_enabled=1 should be enabled');
|
||||
$alwaysUser = make_da_user($alwaysSettings, [
|
||||
'mysql_enabled' => 'no',
|
||||
'mysql' => '0',
|
||||
'plugins_deny' => 'alt-mysql',
|
||||
], []);
|
||||
assert_true($alwaysUser->hasPluginAccess(), 'always_enabled=1 should bypass per-user enable and plugin deny rules');
|
||||
assert_same(0, $alwaysUser->maxDatabases(), 'always_enabled=1 should make database limit unlimited');
|
||||
|
||||
$defaultSettings = load_settings("");
|
||||
assert_true($defaultSettings->alwaysEnabled(), 'always_enabled should default to enabled');
|
||||
$defaultUser = make_da_user($defaultSettings, [], []);
|
||||
assert_true($defaultUser->hasPluginAccess(), 'default always_enabled should grant access without custom package items');
|
||||
assert_same(0, $defaultUser->maxDatabases(), 'default always_enabled should make database limit unlimited');
|
||||
|
||||
$legacySettings = load_settings("always_enabled=0\nMYSQL_PLUGIN_DEFAULT_DB_LIMIT=5\n");
|
||||
assert_true(!$legacySettings->alwaysEnabled(), 'always_enabled=0 should disable automatic access');
|
||||
$legacyUser = make_da_user($legacySettings, [
|
||||
'mysql_enabled' => 'no',
|
||||
'mysql' => '0',
|
||||
], []);
|
||||
assert_true(!$legacyUser->hasPluginAccess(), 'always_enabled=0 should preserve per-user access checks');
|
||||
assert_same(0, $legacyUser->maxDatabases(), 'explicit mysql=0 remains zero in legacy mode');
|
||||
|
||||
echo "always_enabled_test: OK\n";
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
FILE="$PLUGIN_DIR/exec/lib/BackupQueueService.php"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if grep -Fq '$safeBase,' "$FILE"; then
|
||||
fail "BackupQueueService.php still references undefined safeBase"
|
||||
fi
|
||||
|
||||
echo "backup_queue_service_test: OK"
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
CPIF="$TMP_DIR/custom_package_items.conf"
|
||||
SETTINGS="$TMP_DIR/plugin-settings.conf"
|
||||
|
||||
ALT_MYSQL_TEST_ASSUME_ROOT=1 \
|
||||
ALT_MYSQL_TEST_ONLY_CUSTOM_PACKAGE_ITEMS=1 \
|
||||
ALT_MYSQL_CUSTOM_PACKAGE_ITEMS_CONF="$CPIF" \
|
||||
ALT_MYSQL_SETTINGS_FILE="$SETTINGS" \
|
||||
bash "$PLUGIN_DIR/scripts/install.sh" >/dev/null
|
||||
|
||||
[ -f "$CPIF" ] || fail "custom package items file was not created"
|
||||
if grep -Eq '^(mysql_enabled|mysql|umysql|mysql_max_databases|mysql_unlimited|umysql_max_databases)=' "$CPIF"; then
|
||||
cat "$CPIF" >&2
|
||||
fail "always_enabled=1 should not add per-user access or database limit custom fields"
|
||||
fi
|
||||
|
||||
cat > "$SETTINGS" <<'EOF'
|
||||
always_enabled=0
|
||||
EOF
|
||||
|
||||
ALT_MYSQL_TEST_ASSUME_ROOT=1 \
|
||||
ALT_MYSQL_TEST_ONLY_CUSTOM_PACKAGE_ITEMS=1 \
|
||||
ALT_MYSQL_CUSTOM_PACKAGE_ITEMS_CONF="$CPIF" \
|
||||
ALT_MYSQL_SETTINGS_FILE="$SETTINGS" \
|
||||
bash "$PLUGIN_DIR/scripts/install.sh" >/dev/null
|
||||
|
||||
grep -Fq 'mysql_enabled=' "$CPIF" || fail "always_enabled=0 should add mysql_enabled field"
|
||||
grep -Fq 'mysql=type=text' "$CPIF" || fail "always_enabled=0 should add mysql database limit input"
|
||||
grep -Fq 'umysql=type=checkbox' "$CPIF" || fail "always_enabled=0 should add unlimited checkbox"
|
||||
|
||||
echo "custom_package_items_test: OK"
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
INSTALLER="$PLUGIN_DIR/scripts/setup/custombuild_hooks_install.sh"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
CUSTOMBUILD_ROOT="$TMP_DIR/custombuild" bash "$INSTALLER" install >/dev/null
|
||||
|
||||
ROUND_HOOK="$TMP_DIR/custombuild/custom/hooks/roundcube/post/90-alt-mysql-repair.sh"
|
||||
PMA_HOOK="$TMP_DIR/custombuild/custom/hooks/phpmyadmin/post/90-alt-mysql-repair.sh"
|
||||
|
||||
[ -x "$ROUND_HOOK" ] || fail "Roundcube CustomBuild post hook not installed"
|
||||
[ -x "$PMA_HOOK" ] || fail "phpMyAdmin CustomBuild post hook not installed"
|
||||
grep -Fq "roundcube_repair_config.sh" "$ROUND_HOOK" || fail "Roundcube hook does not call repair"
|
||||
grep -Fq "roundcube_health_check.sh" "$ROUND_HOOK" || fail "Roundcube hook does not call health check"
|
||||
grep -Fq "phpmyadmin_repair.sh" "$PMA_HOOK" || fail "phpMyAdmin hook does not call repair"
|
||||
grep -Fq "phpmyadmin_health_check.sh" "$PMA_HOOK" || fail "phpMyAdmin hook does not call health check"
|
||||
|
||||
CUSTOMBUILD_ROOT="$TMP_DIR/custombuild" bash "$INSTALLER" uninstall >/dev/null
|
||||
|
||||
[ ! -e "$ROUND_HOOK" ] || fail "Roundcube CustomBuild post hook not removed"
|
||||
[ ! -e "$PMA_HOOK" ] || fail "phpMyAdmin CustomBuild post hook not removed"
|
||||
|
||||
echo "custombuild_hooks_install_test: OK"
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
INSTALLER="$PLUGIN_DIR/scripts/setup/da_integration_install.sh"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
mkdir -p "$TMP_DIR/custom"
|
||||
cat > "$TMP_DIR/custom/user_backup_compress_pre.sh" <<'EOF'
|
||||
#!/bin/bash
|
||||
echo existing
|
||||
EOF
|
||||
chmod 755 "$TMP_DIR/custom/user_backup_compress_pre.sh"
|
||||
|
||||
DA_CUSTOM_HOOK_DIR="$TMP_DIR/custom" bash "$INSTALLER" install >/dev/null
|
||||
|
||||
[ -f "$TMP_DIR/custom/user_backup_compress_pre.sh" ] || fail "dispatcher not created"
|
||||
grep -Fq "managed by DirectAdmin MySQL plugin hook dispatcher" "$TMP_DIR/custom/user_backup_compress_pre.sh" \
|
||||
|| fail "dispatcher marker missing"
|
||||
[ -f "$TMP_DIR/custom/user_backup_compress_pre.sh.d/00-existing.sh" ] || fail "existing hook not preserved"
|
||||
[ -L "$TMP_DIR/custom/user_backup_compress_pre.sh.d/10-alt-mysql.sh" ] || fail "alt backup hook link missing"
|
||||
[ -L "$TMP_DIR/custom/user_restore_post_pre_cleanup.sh.d/10-alt-mysql.sh" ] || fail "alt restore hook link missing"
|
||||
[ -L "$TMP_DIR/custom/database_create_pre.sh.d/20-alt-mysql-block-native-db.sh" ] || fail "native DB blocker link missing"
|
||||
|
||||
DA_CUSTOM_HOOK_DIR="$TMP_DIR/custom" bash "$INSTALLER" uninstall >/dev/null
|
||||
[ ! -e "$TMP_DIR/custom/user_backup_compress_pre.sh.d/10-alt-mysql.sh" ] || fail "alt backup hook link not removed"
|
||||
[ -f "$TMP_DIR/custom/user_backup_compress_pre.sh.d/00-existing.sh" ] || fail "preserved existing hook should remain"
|
||||
|
||||
echo "da_integration_install_test: OK"
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SCRIPT="$PLUGIN_DIR/scripts/install_db.sh"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ -x "$SCRIPT" ] || fail "scripts/install_db.sh is missing or not executable"
|
||||
[ ! -e "$PLUGIN_DIR/scripts/install-alt-mariadb.sh" ] || fail "old install-alt-mariadb.sh still exists"
|
||||
|
||||
grep -Fq 'apply_cli_args "$@"' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not call CLI argument parser"
|
||||
grep -Fq 'MARIADB_VERSION="$1"' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not accept MariaDB version as first argument"
|
||||
grep -Fq 'PORT="$2"' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not accept port as second argument"
|
||||
grep -Fq 'MARIADB_DIR="/usr/local/mariadb-$MARIADB_VERSION"' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not derive MariaDB directory from chosen version"
|
||||
grep -Fq 'validate_port' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not validate the chosen port"
|
||||
grep -Fq 'rerun_plugin_install_if_available' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not refresh plugin install.sh after DB install"
|
||||
grep -Fq 'SKIP_PLUGIN_INSTALL_REFRESH' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not allow explicitly skipping plugin refresh"
|
||||
grep -Fq '[[ $# -eq 0 ]]' "$SCRIPT" \
|
||||
|| fail "install_db.sh does not explicitly show usage when called without arguments"
|
||||
|
||||
if grep -Fq 'install-alt-mariadb.sh' "$SCRIPT"; then
|
||||
fail "install_db.sh still references old install-alt-mariadb.sh name"
|
||||
fi
|
||||
|
||||
set +e
|
||||
NO_ARGS_OUTPUT="$("$SCRIPT" 2>&1)"
|
||||
NO_ARGS_STATUS=$?
|
||||
set -e
|
||||
|
||||
[ "$NO_ARGS_STATUS" -eq 2 ] || fail "install_db.sh without arguments should exit with status 2, got $NO_ARGS_STATUS"
|
||||
printf '%s\n' "$NO_ARGS_OUTPUT" | grep -Fq 'Użycie:' \
|
||||
|| fail "install_db.sh without arguments does not print usage"
|
||||
printf '%s\n' "$NO_ARGS_OUTPUT" | grep -Fq '<MARIADB_VERSION> <PORT>' \
|
||||
|| fail "install_db.sh usage does not show required version and port"
|
||||
if printf '%s\n' "$NO_ARGS_OUTPUT" | grep -Fq 'Ten skrypt musi zostać uruchomiony jako root'; then
|
||||
fail "install_db.sh without arguments reaches root check instead of usage"
|
||||
fi
|
||||
|
||||
echo "install_db_cli_test: OK"
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
COMMON_FILE="$PLUGIN_DIR/scripts/setup/mysql_common.sh"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
mkdir -p "$TMP_DIR/mariadb/bin"
|
||||
touch "$TMP_DIR/mariadb/bin/mariadb" "$TMP_DIR/mariadb/bin/mariadb-dump" "$TMP_DIR/mariadb/bin/mariadb-admin" "$TMP_DIR/mariadb/bin/mariadb-upgrade"
|
||||
chmod 755 "$TMP_DIR/mariadb/bin/"*
|
||||
|
||||
cat > "$TMP_DIR/alt-mariadb.env" <<EOF
|
||||
SERVICE_NAME='alt-mariadb-test'
|
||||
MARIADB_DIR='$TMP_DIR/mariadb'
|
||||
DATADIR='$TMP_DIR/data'
|
||||
PORT='4407'
|
||||
SOCKET='$TMP_DIR/data/mariadb.sock'
|
||||
ALT_MYSQL_CONF='$TMP_DIR/alt-mysql.conf'
|
||||
ALT_MY_CNF='$TMP_DIR/alt-my.cnf'
|
||||
INSTANCE_CNF='$TMP_DIR/alt-mariadb.cnf'
|
||||
EOF
|
||||
|
||||
cat > "$TMP_DIR/alt-mysql.conf" <<EOF
|
||||
host=
|
||||
passwd=secret
|
||||
port=4407
|
||||
socket=$TMP_DIR/data/mariadb.sock
|
||||
user=da_admin
|
||||
EOF
|
||||
|
||||
cat > "$TMP_DIR/alt-my.cnf" <<EOF
|
||||
[client]
|
||||
user="da_admin"
|
||||
password="secret"
|
||||
socket="$TMP_DIR/data/mariadb.sock"
|
||||
EOF
|
||||
|
||||
cat > "$TMP_DIR/alt-mariadb.cnf" <<EOF
|
||||
[mariadb]
|
||||
basedir=$TMP_DIR/mariadb
|
||||
datadir=$TMP_DIR/data
|
||||
port=4407
|
||||
socket=$TMP_DIR/data/mariadb.sock
|
||||
EOF
|
||||
|
||||
MYSQL_PLUGIN_METADATA_FILE="$TMP_DIR/alt-mariadb.env"
|
||||
MYSQL_PLUGIN_CREDENTIALS_FILE="$TMP_DIR/alt-mysql.conf"
|
||||
MYSQL_PLUGIN_ALT_MY_CNF="$TMP_DIR/alt-my.cnf"
|
||||
MYSQL_PLUGIN_ALT_INSTANCE_CNF="$TMP_DIR/alt-mariadb.cnf"
|
||||
|
||||
# shellcheck source=../scripts/setup/mysql_common.sh
|
||||
source "$COMMON_FILE"
|
||||
|
||||
mysql_load_alt_runtime
|
||||
|
||||
[ "$MYSQL_ALT_SERVICE_NAME" = "alt-mariadb-test" ] || fail "service name not loaded"
|
||||
[ "$MYSQL_ALT_BASEDIR" = "$TMP_DIR/mariadb" ] || fail "basedir not loaded"
|
||||
[ "$MYSQL_ALT_DATADIR" = "$TMP_DIR/data" ] || fail "datadir not loaded"
|
||||
[ "$MYSQL_ALT_PORT" = "4407" ] || fail "port not loaded"
|
||||
[ "$MYSQL_ALT_SOCKET" = "$TMP_DIR/data/mariadb.sock" ] || fail "socket not loaded"
|
||||
[ "$(mysql_alt_binary mysql)" = "$TMP_DIR/mariadb/bin/mariadb" ] || fail "mysql alias binary not detected"
|
||||
[ "$(mysql_alt_binary mysqldump)" = "$TMP_DIR/mariadb/bin/mariadb-dump" ] || fail "mysqldump alias binary not detected"
|
||||
|
||||
mysql_load_alt_credentials
|
||||
[ "$MYSQL_USER" = "da_admin" ] || fail "credential user not loaded"
|
||||
[ "$MYSQL_PORT" = "4407" ] || fail "credential port not loaded"
|
||||
[ "$MYSQL_SOCKET" = "$TMP_DIR/data/mariadb.sock" ] || fail "credential socket not loaded"
|
||||
|
||||
echo "mysql_common_runtime_test: OK"
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SYNC_SCRIPT="$SCRIPT_DIR/scripts/setup/mysql_host_sync.sh"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert_contains() {
|
||||
local file="$1"
|
||||
local needle="$2"
|
||||
grep -Fq "$needle" "$file" || fail "Expected $file to contain: $needle"
|
||||
}
|
||||
|
||||
assert_not_contains() {
|
||||
local file="$1"
|
||||
local needle="$2"
|
||||
if grep -Fq "$needle" "$file"; then
|
||||
fail "Expected $file not to contain: $needle"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_line_count() {
|
||||
local expected="$1"
|
||||
local file="$2"
|
||||
local needle="$3"
|
||||
local actual
|
||||
actual="$(grep -Fxc "$needle" "$file" || true)"
|
||||
[ "$actual" = "$expected" ] || fail "Expected $expected occurrences of '$needle' in $file, got $actual"
|
||||
}
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmpdir"' EXIT
|
||||
|
||||
mkdir -p "$tmpdir/bin" "$tmpdir/csf"
|
||||
|
||||
cat > "$tmpdir/bin/mysql" <<'MYSQL'
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
printf '%s\n' \
|
||||
"198.51.100.10" \
|
||||
"203.0.113.20" \
|
||||
"localhost" \
|
||||
"bad-host-name"
|
||||
MYSQL
|
||||
chmod 755 "$tmpdir/bin/mysql"
|
||||
|
||||
cat > "$tmpdir/alt-mysql.conf" <<EOF
|
||||
host=localhost
|
||||
port=33033
|
||||
user=root
|
||||
password=secret
|
||||
database=mysql
|
||||
socket=$tmpdir/mysql.sock
|
||||
EOF
|
||||
|
||||
cat > "$tmpdir/alt-mariadb.cnf" <<'EOF'
|
||||
[client]
|
||||
port=33033
|
||||
|
||||
[mariadb]
|
||||
port=33033
|
||||
bind-address=127.0.0.1
|
||||
EOF
|
||||
|
||||
cat > "$tmpdir/csf/csf.allow" <<'EOF'
|
||||
# csf.allow
|
||||
EOF
|
||||
|
||||
cat > "$tmpdir/csf/csf.conf" <<'EOF'
|
||||
TCP_IN = "22,33030:33035,80,33033,443"
|
||||
TCP6_IN = "22,33033:33033"
|
||||
TCP_OUT = "22,80,33033,443"
|
||||
EOF
|
||||
|
||||
MYSQL_HOST_SYNC_ASSUME_ROOT=1 \
|
||||
MYSQL_HOST_SYNC_PLUGIN_SETTINGS="$tmpdir/missing-plugin-settings.conf" \
|
||||
MYSQL_HOST_SYNC_SKIP_CSF_RELOAD=1 \
|
||||
MYSQL_HOST_SYNC_SKIP_SERVICE_RESTART=1 \
|
||||
MYSQL_PLUGIN_CLIENT_BIN_DIR="$tmpdir/bin" \
|
||||
MYSQL_PLUGIN_CREDENTIALS_FILE="$tmpdir/alt-mysql.conf" \
|
||||
MYSQL_HOST_SYNC_INSTANCE_CNF="$tmpdir/alt-mariadb.cnf" \
|
||||
MYSQL_HOST_SYNC_CSF_DIR="$tmpdir/csf" \
|
||||
MYSQL_HOST_SYNC_CSF_ALLOW="$tmpdir/csf/csf.allow" \
|
||||
MYSQL_HOST_SYNC_CSF_CONF="$tmpdir/csf/csf.conf" \
|
||||
MYSQL_HOST_SYNC_MANAGED_ALLOW="$tmpdir/csf/alt-mysql-plugin.allow" \
|
||||
bash "$SYNC_SCRIPT" >/tmp/mysql_host_sync_test.out
|
||||
|
||||
assert_contains "$tmpdir/alt-mariadb.cnf" "bind-address=0.0.0.0"
|
||||
assert_contains "$tmpdir/csf/csf.allow" "Include $tmpdir/csf/alt-mysql-plugin.allow"
|
||||
assert_contains "$tmpdir/csf/alt-mysql-plugin.allow" "tcp|in|d=33033|s=198.51.100.10"
|
||||
assert_contains "$tmpdir/csf/alt-mysql-plugin.allow" "tcp|in|d=33033|s=203.0.113.20"
|
||||
assert_not_contains "$tmpdir/csf/alt-mysql-plugin.allow" "localhost"
|
||||
assert_not_contains "$tmpdir/csf/alt-mysql-plugin.allow" "bad-host-name"
|
||||
assert_contains "$tmpdir/csf/csf.conf" 'TCP_IN = "22,33030:33032,33034:33035,80,443"'
|
||||
assert_contains "$tmpdir/csf/csf.conf" 'TCP6_IN = "22"'
|
||||
assert_contains "$tmpdir/csf/csf.conf" 'TCP_OUT = "22,80,33033,443"'
|
||||
|
||||
MYSQL_HOST_SYNC_ASSUME_ROOT=1 \
|
||||
MYSQL_HOST_SYNC_PLUGIN_SETTINGS="$tmpdir/missing-plugin-settings.conf" \
|
||||
MYSQL_HOST_SYNC_SKIP_CSF_RELOAD=1 \
|
||||
MYSQL_HOST_SYNC_SKIP_SERVICE_RESTART=1 \
|
||||
MYSQL_PLUGIN_CLIENT_BIN_DIR="$tmpdir/bin" \
|
||||
MYSQL_PLUGIN_CREDENTIALS_FILE="$tmpdir/alt-mysql.conf" \
|
||||
MYSQL_HOST_SYNC_INSTANCE_CNF="$tmpdir/alt-mariadb.cnf" \
|
||||
MYSQL_HOST_SYNC_CSF_DIR="$tmpdir/csf" \
|
||||
MYSQL_HOST_SYNC_CSF_ALLOW="$tmpdir/csf/csf.allow" \
|
||||
MYSQL_HOST_SYNC_CSF_CONF="$tmpdir/csf/csf.conf" \
|
||||
MYSQL_HOST_SYNC_MANAGED_ALLOW="$tmpdir/csf/alt-mysql-plugin.allow" \
|
||||
bash "$SYNC_SCRIPT" >/tmp/mysql_host_sync_test_second.out
|
||||
|
||||
assert_line_count 1 "$tmpdir/csf/csf.allow" "Include $tmpdir/csf/alt-mysql-plugin.allow"
|
||||
|
||||
echo "mysql_host_sync_test: OK"
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SCRIPT="$PLUGIN_DIR/scripts/setup/mysql_upgrade.sh"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -Fq "rollback_upgrade()" "$SCRIPT" \
|
||||
|| fail "mysql_upgrade.sh does not define rollback_upgrade"
|
||||
grep -Fq "UPGRADE_COMMITTED=1" "$SCRIPT" \
|
||||
|| fail "mysql_upgrade.sh does not mark successful upgrades as committed"
|
||||
grep -Fq 'trap '\''code=$?; rollback_upgrade "$code"'\'' EXIT' "$SCRIPT" \
|
||||
|| fail "mysql_upgrade.sh does not run rollback on failed exit"
|
||||
grep -Fq "RESTORED_PREVIOUS_DIR" "$SCRIPT" \
|
||||
|| fail "mysql_upgrade.sh does not restore previous binary directory"
|
||||
grep -Fq "RESTORED_INSTANCE_CNF" "$SCRIPT" \
|
||||
|| fail "mysql_upgrade.sh does not restore previous instance config"
|
||||
|
||||
echo "mysql_upgrade_rollback_test: OK"
|
||||
@@ -0,0 +1,104 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
ARCHIVE="${1:-$(cd "$PLUGIN_DIR/.." && pwd)/1.2.10/alt-mysql.tar.gz}"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ -s "$ARCHIVE" ] || fail "archive does not exist or is empty: $ARCHIVE"
|
||||
|
||||
LIST="$(tar -tzf "$ARCHIVE")"
|
||||
printf '%s\n' "$LIST" | grep -Eq '^(\./)?plugin\.conf$' \
|
||||
|| fail "archive does not contain plugin.conf at tar root"
|
||||
if printf '%s\n' "$LIST" | grep -Eq '^(\./)?alt-mysql/'; then
|
||||
fail "archive contains parent alt-mysql directory"
|
||||
fi
|
||||
if printf '%s\n' "$LIST" | grep -Eiq 'postgres|postgresql|pgsql|phppgadmin'; then
|
||||
fail "archive contains PostgreSQL/phpPgAdmin leftovers"
|
||||
fi
|
||||
if printf '%s\n' "$LIST" | grep -Eq '^(\./)?tests/'; then
|
||||
fail "archive contains local test suite"
|
||||
fi
|
||||
if printf '%s\n' "$LIST" | grep -Eq '(^|/)\._[^/]+$|(^|/)\.DS_Store$|__MACOSX'; then
|
||||
fail "archive contains macOS AppleDouble or Finder metadata"
|
||||
fi
|
||||
printf '%s\n' "$LIST" | grep -Eq '^(\./)?scripts/setup/phpmyadmin_private_install\.sh$' \
|
||||
|| fail "archive does not contain private phpMyAdmin installer"
|
||||
printf '%s\n' "$LIST" | grep -Eq '^(\./)?scripts/install_db\.sh$' \
|
||||
|| fail "archive does not contain install_db.sh at scripts/"
|
||||
if printf '%s\n' "$LIST" | grep -Eq '(^|/)install-alt-mariadb\.sh$'; then
|
||||
fail "archive contains old install-alt-mariadb.sh"
|
||||
fi
|
||||
|
||||
CONF="$(tar -xOzf "$ARCHIVE" ./plugin.conf 2>/dev/null || tar -xOzf "$ARCHIVE" plugin.conf)"
|
||||
printf '%s\n' "$CONF" | grep -Fxq "name=alt-mysql" || fail "archive plugin name is not alt-mysql"
|
||||
printf '%s\n' "$CONF" | grep -Fxq "id=alt-mysql" || fail "archive plugin id is not alt-mysql"
|
||||
printf '%s\n' "$CONF" | grep -Fxq "version=1.2.10" || fail "archive plugin version is not 1.2.10"
|
||||
|
||||
SETTINGS="$(tar -xOzf "$ARCHIVE" ./plugin-settings.conf 2>/dev/null || tar -xOzf "$ARCHIVE" plugin-settings.conf)"
|
||||
printf '%s\n' "$SETTINGS" | grep -Fxq "PHPMYADMIN_INSTALL_DIR=/var/www/html/alt-mysql-phpmyadmin" \
|
||||
|| fail "archive settings do not point to private phpMyAdmin install dir"
|
||||
printf '%s\n' "$SETTINGS" | grep -Fxq "PHPMYADMIN_URL_PATH=/alt-mysql-phpmyadmin" \
|
||||
|| fail "archive settings do not point to private phpMyAdmin URL"
|
||||
printf '%s\n' "$SETTINGS" | grep -Fxq "always_enabled=1" \
|
||||
|| fail "archive settings do not enable always_enabled by default"
|
||||
|
||||
INSTALL_SCRIPT="$(tar -xOzf "$ARCHIVE" ./scripts/install.sh 2>/dev/null || tar -xOzf "$ARCHIVE" scripts/install.sh)"
|
||||
printf '%s\n' "$INSTALL_SCRIPT" | grep -Fq 'always_enabled()' \
|
||||
|| fail "archive install script does not read always_enabled"
|
||||
printf '%s\n' "$INSTALL_SCRIPT" | grep -Fq 'if always_enabled; then' \
|
||||
|| fail "archive install script does not hide custom package fields when always_enabled is on"
|
||||
|
||||
DB_INSTALLER="$(tar -xOzf "$ARCHIVE" ./scripts/install_db.sh 2>/dev/null || tar -xOzf "$ARCHIVE" scripts/install_db.sh)"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq 'apply_cli_args "$@"' \
|
||||
|| fail "archive install_db.sh does not apply positional arguments"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq 'MARIADB_VERSION="$1"' \
|
||||
|| fail "archive install_db.sh does not accept MariaDB version as first argument"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq 'PORT="$2"' \
|
||||
|| fail "archive install_db.sh does not accept TCP port as second argument"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq 'rerun_plugin_install_if_available' \
|
||||
|| fail "archive install_db.sh does not refresh plugin install.sh after DB setup"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq 'SKIP_PLUGIN_INSTALL_REFRESH' \
|
||||
|| fail "archive install_db.sh does not expose a test/maintenance escape hatch for plugin refresh"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq '[[ $# -eq 0 ]]' \
|
||||
|| fail "archive install_db.sh does not show usage when called without arguments"
|
||||
printf '%s\n' "$DB_INSTALLER" | grep -Fq '<MARIADB_VERSION> <PORT>' \
|
||||
|| fail "archive install_db.sh usage does not require version and port"
|
||||
|
||||
INSTALLER="$(tar -xOzf "$ARCHIVE" ./scripts/setup/phpmyadmin_install.sh 2>/dev/null || tar -xOzf "$ARCHIVE" scripts/setup/phpmyadmin_install.sh)"
|
||||
printf '%s\n' "$INSTALLER" | grep -Fq "\$cfg['Servers'][\$i]['SignonURL'] = da_mysql_phpmyadmin_signon_url(\$runtimeConfig);" \
|
||||
|| fail "archive phpMyAdmin installer does not configure SignonURL"
|
||||
printf '%s\n' "$INSTALLER" | grep -Fq 'SIGNON_URL_PAGE="${PHPMYADMIN_PRIVATE_DIR}/da_login.php"' \
|
||||
|| fail "archive phpMyAdmin installer does not create SignonURL page"
|
||||
printf '%s\n' "$INSTALLER" | grep -Fq 'DA_MYSQL_PHPMYADMIN_AUTH' \
|
||||
|| fail "archive phpMyAdmin installer does not create ticket-based da_login.php"
|
||||
printf '%s\n' "$INSTALLER" | grep -Fq 'da_mysql_signon_read_auth' \
|
||||
|| fail "archive phpMyAdmin installer does not isolate phpMyAdmin and SSO sessions"
|
||||
|
||||
OPEN_HANDLER="$(tar -xOzf "$ARCHIVE" ./exec/handlers/open_phpmyadmin.php 2>/dev/null || tar -xOzf "$ARCHIVE" exec/handlers/open_phpmyadmin.php)"
|
||||
printf '%s\n' "$OPEN_HANDLER" | grep -Fq 'phpmyadmin_health_check.sh' \
|
||||
|| fail "archive open phpMyAdmin handler does not run health check"
|
||||
printf '%s\n' "$OPEN_HANDLER" | grep -Fq 'phpmyadmin_repair.sh' \
|
||||
|| fail "archive open phpMyAdmin handler does not run repair before redirect"
|
||||
printf '%s\n' "$OPEN_HANDLER" | grep -Fq 'HTTP/1.1 302 Found' \
|
||||
|| fail "archive open phpMyAdmin raw handler does not emit an HTTP redirect"
|
||||
printf '%s\n' "$OPEN_HANDLER" | grep -Fq 'Location: ' \
|
||||
|| fail "archive open phpMyAdmin raw handler does not emit a Location header"
|
||||
if printf '%s\n' "$OPEN_HANDLER" | grep -Fq 'meta http-equiv="refresh"'; then
|
||||
fail "archive open phpMyAdmin raw handler still uses meta refresh"
|
||||
fi
|
||||
if printf '%s\n' "$OPEN_HANDLER" | grep -Fq 'Set-Cookie: '; then
|
||||
fail "archive open phpMyAdmin handler still tries to pass SSO through DirectAdmin PHP session cookie"
|
||||
fi
|
||||
|
||||
SSO_CLASS="$(tar -xOzf "$ARCHIVE" ./exec/lib/PhpMyAdminSso.php 2>/dev/null || tar -xOzf "$ARCHIVE" exec/lib/PhpMyAdminSso.php)"
|
||||
printf '%s\n' "$SSO_CLASS" | grep -Fq 'writeLoginTicket' \
|
||||
|| fail "archive phpMyAdmin SSO class does not write login tickets"
|
||||
printf '%s\n' "$SSO_CLASS" | grep -Fq '/da_login.php?' \
|
||||
|| fail "archive phpMyAdmin SSO class does not target da_login.php ticket flow"
|
||||
|
||||
echo "package_archive_test: OK"
|
||||
@@ -0,0 +1,149 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SCRIPT="$PLUGIN_DIR/scripts/setup/phpmyadmin_install.sh"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -Fq 'PHPMYADMIN_VERSION="${PHPMYADMIN_VERSION:-5.2.3}"' "$SCRIPT" \
|
||||
|| fail "phpMyAdmin default version is not 5.2.3"
|
||||
grep -Fq 'PHPMYADMIN_TARBALL_URL="${PHPMYADMIN_TARBALL_URL:-https://files.phpmyadmin.net/phpMyAdmin/5.2.3/phpMyAdmin-5.2.3-all-languages.tar.gz}"' "$SCRIPT" \
|
||||
|| fail "phpMyAdmin tarball URL is not the explicit 5.2.3 URL"
|
||||
|
||||
mkdir -p "$TMP_DIR/phpMyAdmin"
|
||||
cat > "$TMP_DIR/phpMyAdmin/config.inc.php" <<'PHP'
|
||||
<?php
|
||||
$cfg = [];
|
||||
PHP
|
||||
mkdir -p "$TMP_DIR/phpMyAdmin-source"
|
||||
cat > "$TMP_DIR/phpMyAdmin-source/index.php" <<'PHP'
|
||||
<?php
|
||||
echo 'private phpMyAdmin';
|
||||
PHP
|
||||
|
||||
PHPMYADMIN_EXISTING_DIR="$TMP_DIR/phpMyAdmin" \
|
||||
PHPMYADMIN_PRIVATE_DIR="$TMP_DIR/alt-mysql-phpmyadmin" \
|
||||
PHPMYADMIN_SOURCE_DIR="$TMP_DIR/phpMyAdmin-source" \
|
||||
PHPMYADMIN_INSTALL_ASSUME_ROOT=1 \
|
||||
bash "$SCRIPT" >/dev/null
|
||||
|
||||
PRIVATE_DIR="$TMP_DIR/alt-mysql-phpmyadmin"
|
||||
CONFIG_INC="$PRIVATE_DIR/config.inc.php"
|
||||
SIGNON_SCRIPT="$PRIVATE_DIR/da_signon.php"
|
||||
SIGNON_URL_PAGE="$PRIVATE_DIR/da_login.php"
|
||||
TICKET_DIR="$PRIVATE_DIR/runtime/tickets"
|
||||
SESSION_DIR="$TMP_DIR/sessions"
|
||||
|
||||
[ -r "$PRIVATE_DIR/index.php" ] || fail "private phpMyAdmin copy was not installed"
|
||||
[ -r "$CONFIG_INC" ] || fail "private phpMyAdmin config was not created"
|
||||
[ -r "$SIGNON_SCRIPT" ] || fail "signon script was not created"
|
||||
[ -r "$SIGNON_URL_PAGE" ] || fail "phpMyAdmin SignonURL page was not created"
|
||||
[ -d "$TICKET_DIR" ] || fail "phpMyAdmin ticket directory was not created"
|
||||
if grep -Fq "config.mysql.inc.php" "$TMP_DIR/phpMyAdmin/config.inc.php"; then
|
||||
fail "installer modified existing CustomBuild phpMyAdmin config"
|
||||
fi
|
||||
|
||||
SERVER_JSON="$(php -r '
|
||||
$_SERVER["HTTPS"] = "on";
|
||||
$_SERVER["HTTP_HOST"] = "panel.example.test";
|
||||
$cfg=[];
|
||||
include $argv[1];
|
||||
echo json_encode($cfg["Servers"][1] ?? []);
|
||||
' "$CONFIG_INC")"
|
||||
php -r '
|
||||
$server = json_decode($argv[1], true);
|
||||
if (($server["host"] ?? "") !== "127.0.0.1") {
|
||||
fwrite(STDERR, "host mismatch\n");
|
||||
exit(2);
|
||||
}
|
||||
if ((string)($server["port"] ?? "") !== "33033") {
|
||||
fwrite(STDERR, "port mismatch\n");
|
||||
exit(3);
|
||||
}
|
||||
if (($server["socket"] ?? "not-empty") !== "") {
|
||||
fwrite(STDERR, "socket mismatch\n");
|
||||
exit(4);
|
||||
}
|
||||
if (($server["SignonURL"] ?? "") !== "https://panel.example.test/alt-mysql-phpmyadmin/da_login.php") {
|
||||
fwrite(STDERR, "SignonURL mismatch\n");
|
||||
exit(5);
|
||||
}
|
||||
if (($server["LogoutURL"] ?? "") !== "https://panel.example.test/alt-mysql-phpmyadmin/da_login.php") {
|
||||
fwrite(STDERR, "LogoutURL mismatch\n");
|
||||
exit(6);
|
||||
}
|
||||
' "$SERVER_JSON" || fail "phpMyAdmin config does not target alt-mariadb TCP endpoint"
|
||||
grep -Fq 'return [$username, $password];' "$SIGNON_SCRIPT" \
|
||||
|| fail "signon script should return username/password only"
|
||||
php -d display_errors=1 -r 'set_error_handler(static function($errno, $errstr) { fwrite(STDERR, $errstr . "\n"); exit(9); }); $cfg=[]; include $argv[1]; include $argv[2];' "$CONFIG_INC" "$SIGNON_SCRIPT" \
|
||||
|| fail "phpMyAdmin config and signon script cannot be loaded in one PHP process"
|
||||
|
||||
mkdir -p "$SESSION_DIR"
|
||||
cat > "$TICKET_DIR/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.json" <<'JSON'
|
||||
{"version":1,"expires_at":4102444800,"auth":{"user":"da_tmp_phpmyadmin_test","password":"secret","db":"user_db"},"route":"/database/structure","db":"user_db"}
|
||||
JSON
|
||||
php -d display_errors=1 -d session.save_path="$SESSION_DIR" -r '
|
||||
$_GET["ticket"] = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||||
$_COOKIE["DA_MYSQL_PHPMYADMIN"] = "tickettest";
|
||||
$_SERVER["HTTPS"] = "on";
|
||||
$_SERVER["HTTP_HOST"] = "panel.example.test";
|
||||
include $argv[1];
|
||||
' "$SIGNON_URL_PAGE" >/tmp/altmysql-da-login-test.out 2>/tmp/altmysql-da-login-test.err \
|
||||
|| fail "da_login.php did not accept a valid ticket"
|
||||
[ ! -e "$TICKET_DIR/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.json" ] \
|
||||
|| fail "da_login.php did not consume the SSO ticket"
|
||||
php -d session.save_path="$SESSION_DIR" -r '
|
||||
session_name("DA_MYSQL_PHPMYADMIN");
|
||||
session_id("tickettest");
|
||||
session_start();
|
||||
$auth = $_SESSION["DA_MYSQL_PHPMYADMIN_AUTH"] ?? [];
|
||||
if (($auth["user"] ?? "") !== "da_tmp_phpmyadmin_test") {
|
||||
fwrite(STDERR, "session user mismatch\n");
|
||||
exit(2);
|
||||
}
|
||||
if (($auth["password"] ?? "") !== "secret") {
|
||||
fwrite(STDERR, "session password mismatch\n");
|
||||
exit(3);
|
||||
}
|
||||
if (($auth["db"] ?? "") !== "user_db") {
|
||||
fwrite(STDERR, "session db mismatch\n");
|
||||
exit(4);
|
||||
}
|
||||
' || fail "da_login.php did not create the phpMyAdmin signon session"
|
||||
php -d session.save_path="$SESSION_DIR" -r '
|
||||
session_name("DA_MYSQL_PHPMYADMIN");
|
||||
session_id("tickettest");
|
||||
session_start();
|
||||
$_SESSION["DA_MYSQL_PHPMYADMIN_AUTH"] = [
|
||||
"user" => "da_tmp_phpmyadmin_test",
|
||||
"password" => "secret",
|
||||
"db" => "user_db",
|
||||
];
|
||||
session_write_close();
|
||||
|
||||
session_name("phpmyadmin");
|
||||
session_id("pmaactive");
|
||||
session_start();
|
||||
$_SESSION["unrelated"] = "active phpMyAdmin session";
|
||||
$_COOKIE["DA_MYSQL_PHPMYADMIN"] = "tickettest";
|
||||
include $argv[1];
|
||||
[$username, $password] = get_login_credentials("ignored");
|
||||
if ($username !== "da_tmp_phpmyadmin_test") {
|
||||
fwrite(STDERR, "signon user mismatch with active phpMyAdmin session\n");
|
||||
exit(2);
|
||||
}
|
||||
if ($password !== "secret") {
|
||||
fwrite(STDERR, "signon password mismatch with active phpMyAdmin session\n");
|
||||
exit(3);
|
||||
}
|
||||
' "$SIGNON_SCRIPT" || fail "signon script cannot read SSO session while phpMyAdmin session is active"
|
||||
PHPMYADMIN_PRIVATE_DIR="$PRIVATE_DIR" bash "$PLUGIN_DIR/scripts/setup/phpmyadmin_health_check.sh" >/dev/null \
|
||||
|| fail "phpMyAdmin health check should pass for SignonURL-capable config"
|
||||
|
||||
echo "phpmyadmin_install_test: OK"
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ "$(basename "$PLUGIN_DIR")" = "alt-mysql" ] || fail "plugin directory name is not alt-mysql"
|
||||
grep -Fxq "name=alt-mysql" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf name is not alt-mysql"
|
||||
grep -Fxq "id=alt-mysql" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf id is not alt-mysql"
|
||||
grep -Fxq "version=1.2.10" "$PLUGIN_DIR/plugin.conf" || fail "plugin.conf version is not 1.2.10"
|
||||
grep -Fq "return '/CMD_PLUGINS/alt-mysql';" "$PLUGIN_DIR/exec/lib/AppContext.php" \
|
||||
|| fail "AppContext base URL is not alt-mysql"
|
||||
grep -Fq "\$pluginId = 'alt-mysql';" "$PLUGIN_DIR/exec/lib/DirectAdminUser.php" \
|
||||
|| fail "DirectAdmin plugin allow/deny id is not alt-mysql"
|
||||
|
||||
[ -x "$PLUGIN_DIR/scripts/install_db.sh" ] || fail "install_db.sh is not executable in scripts/"
|
||||
[ ! -e "$PLUGIN_DIR/scripts/install-alt-mariadb.sh" ] || fail "install-alt-mariadb.sh still exists in plugin scripts/"
|
||||
[ ! -e "$PLUGIN_DIR/../mysql-installer/install_db.sh" ] || fail "install_db.sh exists outside plugin scripts/"
|
||||
[ ! -e "$PLUGIN_DIR/../mysql-installer/install-alt-mariadb.sh" ] || fail "install-alt-mariadb.sh still exists outside plugin scripts/"
|
||||
|
||||
BAD_REFS="$(
|
||||
old_plugin_path="/usr/local/directadmin/plugins/"'mysql'
|
||||
old_cmd_path="/CMD_PLUGINS/"'mysql'
|
||||
find "$PLUGIN_DIR" -type f \
|
||||
! -path '*/tests/plugin_identity_test.sh' \
|
||||
! -path '*/data/*' \
|
||||
-exec grep -HnE "$old_plugin_path|$old_cmd_path" {} + || true
|
||||
)"
|
||||
[ -z "$BAD_REFS" ] || {
|
||||
printf '%s\n' "$BAD_REFS" >&2
|
||||
fail "old DirectAdmin plugin path references remain"
|
||||
}
|
||||
|
||||
LEGACY_REFS="$(
|
||||
legacy_sudoers="/etc/sudoers.d/directadmin-"'mysql'"-plugin"
|
||||
legacy_cron="/etc/cron.d/"'mysql'"-jobs"
|
||||
legacy_csf="/etc/csf/"'mysql'"-plugin.allow"
|
||||
find "$PLUGIN_DIR" -type f \
|
||||
! -path '*/tests/plugin_identity_test.sh' \
|
||||
! -path '*/data/*' \
|
||||
-exec grep -HnE "$legacy_sudoers|$legacy_cron|$legacy_csf" {} + || true
|
||||
)"
|
||||
[ -z "$LEGACY_REFS" ] || {
|
||||
printf '%s\n' "$LEGACY_REFS" >&2
|
||||
fail "legacy mysql plugin artifact references remain"
|
||||
}
|
||||
|
||||
echo "plugin_identity_test: OK"
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert_script_has_restore_rollback() {
|
||||
local file="$1"
|
||||
local label="$2"
|
||||
|
||||
grep -Fq "backup_alt_database_for_rollback" "$file" \
|
||||
|| fail "$label does not create a rollback dump before overwrite"
|
||||
grep -Fq "restore_alt_database_from_rollback" "$file" \
|
||||
|| fail "$label does not restore rollback dump after failed import"
|
||||
grep -Fq "trap cleanup_restore_rollback" "$file" \
|
||||
|| fail "$label does not cleanup rollback dump"
|
||||
}
|
||||
|
||||
assert_script_has_restore_rollback "$PLUGIN_DIR/scripts/restore_job.sh" "restore_job.sh"
|
||||
assert_script_has_restore_rollback "$PLUGIN_DIR/scripts/da-integration/alt_mysql_restore_payload.sh" "alt_mysql_restore_payload.sh"
|
||||
assert_script_has_restore_rollback "$PLUGIN_DIR/scripts/da-integration/da_restore_native_staging_to_alt_mysql.sh" "da_restore_native_staging_to_alt_mysql.sh"
|
||||
|
||||
echo "restore_rollback_safety_test: OK"
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SCRIPT="$PLUGIN_DIR/scripts/setup/roundcube_repair_config.sh"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
mkdir -p "$TMP_DIR/mariadb/bin" "$TMP_DIR/roundcube"
|
||||
cat > "$TMP_DIR/roundcube/config.inc.php" <<'PHP'
|
||||
<?php
|
||||
$config = [];
|
||||
PHP
|
||||
|
||||
cat > "$TMP_DIR/alt-mariadb.env" <<EOF
|
||||
SERVICE_NAME='alt-mariadb-test'
|
||||
MARIADB_DIR='$TMP_DIR/mariadb'
|
||||
DATADIR='$TMP_DIR/data'
|
||||
PORT='4407'
|
||||
SOCKET='$TMP_DIR/data/mariadb.sock'
|
||||
ALT_MYSQL_CONF='$TMP_DIR/alt-mysql.conf'
|
||||
ALT_MY_CNF='$TMP_DIR/alt-my.cnf'
|
||||
INSTANCE_CNF='$TMP_DIR/alt-mariadb.cnf'
|
||||
EOF
|
||||
|
||||
cat > "$TMP_DIR/alt-mysql.conf" <<EOF
|
||||
host=
|
||||
passwd=secret
|
||||
port=4407
|
||||
socket=$TMP_DIR/data/mariadb.sock
|
||||
user=da_admin
|
||||
EOF
|
||||
|
||||
cat > "$TMP_DIR/plugin-settings.conf" <<EOF
|
||||
MYSQL_PLUGIN_METADATA_FILE=$TMP_DIR/alt-mariadb.env
|
||||
MYSQL_PLUGIN_CREDENTIALS_FILE=$TMP_DIR/alt-mysql.conf
|
||||
MYSQL_PLUGIN_ALT_MY_CNF=$TMP_DIR/alt-my.cnf
|
||||
ROUNDCUBE_ENABLED=true
|
||||
ROUNDCUBE_DB_NAME=roundcube
|
||||
ROUNDCUBE_DB_USER=roundcube
|
||||
ROUNDCUBE_DB_PASSWORD_FILE=$TMP_DIR/alt-roundcube.conf
|
||||
ROUNDCUBE_CONFIG_FILE=$TMP_DIR/roundcube/config.inc.php
|
||||
ROUNDCUBE_CUSTOM_CONFIG_FILE=$TMP_DIR/custombuild/custom/roundcube/config.inc.php
|
||||
ROUNDCUBE_WRITE_CUSTOMBUILD_CONFIG=true
|
||||
ROUNDCUBE_ALT_DSN_MODE=tcp
|
||||
EOF
|
||||
|
||||
ROUNDCUBE_SETTINGS_FILE="$TMP_DIR/plugin-settings.conf" bash "$SCRIPT" >/dev/null
|
||||
|
||||
grep -Fq "BEGIN DIRECTADMIN MYSQL PLUGIN ROUNDCUBE" "$TMP_DIR/roundcube/config.inc.php" \
|
||||
|| fail "managed block missing"
|
||||
grep -Fq "127.0.0.1:4407/roundcube" "$TMP_DIR/roundcube/config.inc.php" \
|
||||
|| fail "alt endpoint not written"
|
||||
grep -Fq "BEGIN DIRECTADMIN MYSQL PLUGIN ROUNDCUBE" "$TMP_DIR/custombuild/custom/roundcube/config.inc.php" \
|
||||
|| fail "managed block missing from CustomBuild Roundcube config"
|
||||
grep -Fq "127.0.0.1:4407/roundcube" "$TMP_DIR/custombuild/custom/roundcube/config.inc.php" \
|
||||
|| fail "alt endpoint not written to CustomBuild Roundcube config"
|
||||
grep -Fq "password=" "$TMP_DIR/alt-roundcube.conf" || fail "password file not created"
|
||||
|
||||
ROUNDCUBE_SETTINGS_FILE="$TMP_DIR/plugin-settings.conf" bash "$SCRIPT" >/dev/null
|
||||
COUNT="$(grep -c "BEGIN DIRECTADMIN MYSQL PLUGIN ROUNDCUBE" "$TMP_DIR/roundcube/config.inc.php")"
|
||||
[ "$COUNT" = "1" ] || fail "managed block is not idempotent"
|
||||
CUSTOM_COUNT="$(grep -c "BEGIN DIRECTADMIN MYSQL PLUGIN ROUNDCUBE" "$TMP_DIR/custombuild/custom/roundcube/config.inc.php")"
|
||||
[ "$CUSTOM_COUNT" = "1" ] || fail "CustomBuild managed block is not idempotent"
|
||||
|
||||
echo "roundcube_repair_config_test: OK"
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once dirname(__DIR__) . '/exec/lib/Settings.php';
|
||||
|
||||
function assert_true(bool $condition, string $message): void
|
||||
{
|
||||
if (!$condition) {
|
||||
fwrite(STDERR, "FAIL: {$message}\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'mysql-plugin-settings-');
|
||||
if ($tmp === false) {
|
||||
fwrite(STDERR, "FAIL: cannot create temporary settings file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file_put_contents($tmp, <<<CONF
|
||||
allow_remote_hosts=1
|
||||
modify_server_configuration=0
|
||||
MYSQL_PLUGIN_ALLOW_REMOTE_HOSTS=0
|
||||
MYSQL_PLUGIN_MODIFY_SERVER_CONFIGURATION=0
|
||||
CONF);
|
||||
|
||||
$settings = Settings::load($tmp);
|
||||
@unlink($tmp);
|
||||
|
||||
assert_true($settings->allowRemoteHosts(), 'allow_remote_hosts=1 should enable remote hosts');
|
||||
assert_true(
|
||||
$settings->modifyServerConfiguration(),
|
||||
'allow_remote_hosts=1 should enable server synchronization even when modify_server_configuration=0'
|
||||
);
|
||||
|
||||
echo "settings_remote_hosts_test: OK\n";
|
||||
Reference in New Issue
Block a user