jina verze
This commit is contained in:
@@ -1,360 +0,0 @@
|
||||
# Executes a command inside the MariaDB master pod.
|
||||
# $@ (...): command and arguments to execute.
|
||||
function mariadbMasterExec() {
|
||||
k3sRun exec pod/"$mariadbMasterKube"-0 -c "$mariadbMasterKube" -- "$@"
|
||||
}
|
||||
|
||||
# Executes a command inside the MariaDB master pod with stdin attached (-i).
|
||||
# $@ (...): command and arguments to execute.
|
||||
function mariadbMasterExecI() {
|
||||
k3sRun exec -i pod/"$mariadbMasterKube"-0 -c "$mariadbMasterKube" -- "$@"
|
||||
}
|
||||
|
||||
# Executes a command inside the MariaDB slave pod.
|
||||
# $@ (...): command and arguments to execute.
|
||||
function mariadbSlaveExec() {
|
||||
k3sRun exec pod/"$mariadbSlaveKube"-0 -c "$mariadbSlaveKube" -- "$@"
|
||||
}
|
||||
|
||||
# Runs a SQL query as root against the specified MariaDB pod.
|
||||
# $1 (target): master|slave
|
||||
# $2 (query): SQL query.
|
||||
# [$3] (showColumn): pass "showColumn" to keep column headers.
|
||||
function mariadbRootQuery() {
|
||||
local target="$1" query="$2"
|
||||
[[ -n "$query" ]] || { appError "Query not specified"; return 1; }
|
||||
|
||||
local execFn
|
||||
case "$target" in
|
||||
master) execFn=mariadbMasterExec ;;
|
||||
slave) execFn=mariadbSlaveExec ;;
|
||||
*) appError "Unknown target: $target"; return 1 ;;
|
||||
esac
|
||||
|
||||
if [[ "${3-}" == "showColumn" ]]; then
|
||||
"$execFn" mariadb -uroot -p"$mariadbRootPass" -e "$query"
|
||||
else
|
||||
"$execFn" mariadb -uroot -p"$mariadbRootPass" -N -e "$query"
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs a SQL query as root against the MariaDB master pod.
|
||||
# $1 (query): SQL query.
|
||||
# [$2] (showColumn): pass "showColumn" to keep column headers.
|
||||
function mariadbMasterRootQuery() { mariadbRootQuery master "$@"; }
|
||||
# Runs a SQL query as root against the MariaDB slave pod.
|
||||
# $1 (query): SQL query.
|
||||
# [$2] (showColumn): pass "showColumn" to keep column headers.
|
||||
function mariadbSlaveRootQuery() { mariadbRootQuery slave "$@"; }
|
||||
|
||||
# Converts a domain name into a MariaDB-safe identifier (max 60 chars).
|
||||
# $1 (domain): domain name.
|
||||
function mariadbDomain2id() {
|
||||
domainToRandom "$1" 60
|
||||
}
|
||||
|
||||
# Reads the MariaDB root password from the Kubernetes secret.
|
||||
function mariadbRootPassSecretGet() {
|
||||
k3sRun get secret "$mariadbKube-secret" -o jsonpath="{.data.root-password}" --ignore-not-found | base64 -d
|
||||
}
|
||||
|
||||
# Saves the MariaDB root password from the Kubernetes secret to a local file.
|
||||
function mariadbRootPassSecretSave() {
|
||||
local password
|
||||
password="$(mariadbRootPassSecretGet)"
|
||||
[[ -n "$password" ]] && printf '%s\n' "$password" > "$appDataPath/$hostName.$mariadbKube"
|
||||
}
|
||||
|
||||
# Lists user-created MariaDB databases (system schemas excluded).
|
||||
function mariadbDatabaseListGet() {
|
||||
local output error
|
||||
run output error mariadbMasterRootQuery "SHOW DATABASES;" || { appError "$error"; return 1; }
|
||||
printf '%s\n' "$output" | awk '!/^(information_schema|performance_schema|mysql|sys)$/'
|
||||
}
|
||||
|
||||
# Lists MariaDB users with Host=% (root and replication_user excluded).
|
||||
function mariadbUserListGet() {
|
||||
local output error
|
||||
run output error mariadbMasterRootQuery "SELECT user FROM mysql.user WHERE Host = '%';" || { appError "$error"; return 1; }
|
||||
printf '%s\n' "$output" | awk '!/^(root|replication_user)$/'
|
||||
}
|
||||
|
||||
# Creates or updates a MariaDB database and user with full privileges.
|
||||
# Revokes privileges from any other users previously assigned to the same database.
|
||||
# $1 (database): database name.
|
||||
# $2 (username): database username.
|
||||
# $3 (password): database user password.
|
||||
function mariadbDatabaseUserSet() {
|
||||
local database="$1"
|
||||
[[ -n "$database" ]] || { appError "Database not specified"; return 1; }
|
||||
local username="$2"
|
||||
[[ -n "$username" ]] || { appError "Username not specified"; return 1; }
|
||||
local password="$3"
|
||||
[[ -n "$password" ]] || { appError "Password not specified"; return 1; }
|
||||
|
||||
mariadbMasterRootQuery "CREATE DATABASE IF NOT EXISTS \`$database\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS '$username'@'%' IDENTIFIED BY '$password'; ALTER USER '$username'@'%' IDENTIFIED BY '$password'; GRANT ALL PRIVILEGES ON \`$database\`.* TO '$username'@'%' WITH MAX_USER_CONNECTIONS 15;" || {
|
||||
appError "Create/update database user failed: database=$database username=$username"
|
||||
return 1
|
||||
}
|
||||
|
||||
local others
|
||||
others="$(mariadbMasterRootQuery "SELECT DISTINCT User, Host FROM mysql.db WHERE Db='$database' AND NOT (User='$username' AND Host='%');")"
|
||||
while IFS=$'\t' read -r u h; do
|
||||
[[ -z "$u" || -z "$h" ]] && continue
|
||||
mariadbMasterRootQuery "REVOKE ALL PRIVILEGES ON \`$database\`.* FROM '$u'@'$h';" || \
|
||||
appError "Revoke privileges failed: database=$database user=$u host=$h"
|
||||
done <<< "$others"
|
||||
}
|
||||
|
||||
# Checks whether a MariaDB database exists.
|
||||
# $1 (database): database name.
|
||||
function mariadbDatabaseExists() {
|
||||
local database="$1"
|
||||
[[ -n "$database" ]] || { appError "Database not specified"; return 1; }
|
||||
|
||||
local out
|
||||
out="$(mariadbMasterRootQuery "SHOW DATABASES LIKE '$database';" 2>/dev/null | tail -n 1 | tr -d '\r')"
|
||||
[[ "$out" == "$database" ]]
|
||||
}
|
||||
|
||||
# Removes a MariaDB database if it exists.
|
||||
# $1 (database): database name.
|
||||
function mariadbDatabaseRemove() {
|
||||
local database="$1"
|
||||
[[ -n "$database" ]] || { appError "Database not specified"; return 1; }
|
||||
mariadbMasterRootQuery "DROP DATABASE IF EXISTS \`$database\`;"
|
||||
}
|
||||
|
||||
# Removes a MariaDB user from all hosts.
|
||||
# $1 (username): MariaDB username.
|
||||
function mariadbUserRemove() {
|
||||
local username="$1"
|
||||
[[ -n "$username" ]] || { appError "Username not specified"; return 1; }
|
||||
|
||||
local hosts
|
||||
hosts="$(mariadbMasterRootQuery "SELECT Host FROM mysql.user WHERE User='$username';")"
|
||||
while read -r host; do
|
||||
mariadbMasterRootQuery "DROP USER IF EXISTS '$username'@'$host';"
|
||||
done <<< "$hosts"
|
||||
}
|
||||
|
||||
# Removes all tables from a MariaDB database.
|
||||
# $1 (database): database name.
|
||||
# $2 (username): database username.
|
||||
# $3 (password): database user password.
|
||||
function mariadbDatabaseClean() {
|
||||
local database="$1"
|
||||
[[ -n "$database" ]] || { appError "Database not specified"; return 1; }
|
||||
local username="$2"
|
||||
[[ -n "$username" ]] || { appError "Username not specified"; return 1; }
|
||||
local password="$3"
|
||||
[[ -n "$password" ]] || { appError "Password not specified"; return 1; }
|
||||
|
||||
local output error
|
||||
run output error mariadbMasterExec mariadb -u "$username" -p"$password" -N -e "SELECT CONCAT('DROP TABLE \`', table_name, '\`;') FROM information_schema.tables WHERE table_schema = '$database';" || { appError "$error"; return 1; }
|
||||
run output error mariadbMasterExec mariadb -u "$username" -p"$password" -e "USE \`$database\`; SET FOREIGN_KEY_CHECKS = 0; $output SET FOREIGN_KEY_CHECKS = 1;" || { appError "$error"; return 1; }
|
||||
}
|
||||
|
||||
# Base: runs mariadb-dump via the given exec function.
|
||||
# $1 (execFn): mariadbMasterExec|mariadbSlaveExec.
|
||||
# $2 (username), $3 (password), $4 (database|all).
|
||||
# [$5] (file): auto-generated if omitted.
|
||||
# [$6+] (...): optional mariadb-dump parameters.
|
||||
function mariadbExport() {
|
||||
local execFn="$1"
|
||||
[[ -n "$execFn" ]] || { appError "Exec function not specified"; return 1; }
|
||||
shift
|
||||
|
||||
local username="$1"
|
||||
[[ -n "$username" ]] || { appError "Username not specified"; return 1; }
|
||||
shift
|
||||
|
||||
local password="$1"
|
||||
[[ -n "$password" ]] || { appError "Password not specified"; return 1; }
|
||||
shift
|
||||
|
||||
local database="$1"
|
||||
[[ -n "$database" ]] || { appError "Database not specified"; return 1; }
|
||||
shift
|
||||
|
||||
local file="$1"
|
||||
if [[ -z "$file" ]]; then
|
||||
[[ "$database" == "all" ]] \
|
||||
&& file="$appDataPath/$mariadbMasterKube/${appDate}_${appTime}_full.sql.tar.gz" \
|
||||
|| file="$appDataPath/$mariadbMasterKube/${appDate}_${appTime}_$database.sql.tar.gz"
|
||||
fi
|
||||
shift
|
||||
|
||||
local -a params
|
||||
if [[ $# -gt 0 ]]; then
|
||||
params=("$@")
|
||||
local haveAll=false haveDatabases=false havePositional=false
|
||||
for a in "${params[@]}"; do
|
||||
case "$a" in
|
||||
--all-databases|-A) haveAll=true ;;
|
||||
--databases|-B) haveDatabases=true ;;
|
||||
-*) ;;
|
||||
*) havePositional=true ;;
|
||||
esac
|
||||
done
|
||||
if ! $haveAll && ! $haveDatabases && ! $havePositional; then
|
||||
[[ "$database" == "all" ]] && params+=(--all-databases) || params+=("$database")
|
||||
fi
|
||||
else
|
||||
if [[ "$database" == "all" ]]; then
|
||||
params=(--all-databases --single-transaction --quick --master-data=2 --routines --events)
|
||||
else
|
||||
params=("$database" --single-transaction --quick --routines --events)
|
||||
fi
|
||||
fi
|
||||
|
||||
local filePath fileBase fileSql
|
||||
filePath=$(dirname -- "$file")
|
||||
fileBase=$(basename -- "$file")
|
||||
case "$fileBase" in
|
||||
*.zip) fileSql="${fileBase%.zip}" ;;
|
||||
*.tar.gz) fileSql="${fileBase%.tar.gz}" ;;
|
||||
*) fileSql="$fileBase" ;;
|
||||
esac
|
||||
|
||||
mkdir -p -- "$filePath" || { appError "Failed to create directory: $filePath"; return 1; }
|
||||
rm -f -- "$filePath/$fileSql" "$filePath/$fileBase" &>/dev/null
|
||||
|
||||
local output error
|
||||
runShell output error "$execFn" mariadb-dump -u "$username" -p"$password" "${params[@]}" ">" "$filePath/$fileSql" || {
|
||||
rm -f -- "$filePath/$fileSql" &>/dev/null
|
||||
appError "Error creating dump: ${error:-$output}"
|
||||
return 1
|
||||
}
|
||||
|
||||
case "$fileBase" in
|
||||
*.zip|*.tar.gz|*.tgz)
|
||||
runError error archiveCreate "$filePath/$fileSql" "$file" || {
|
||||
rm -f -- "$filePath/$fileSql" "$filePath/$fileBase" &>/dev/null
|
||||
appError "Error creating archive dump: $error"
|
||||
return 1
|
||||
}
|
||||
rm -f -- "$filePath/$fileSql" &>/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
printf '%s' "$file"
|
||||
}
|
||||
|
||||
# Exports from the master pod.
|
||||
# $1 (username), $2 (password), $3 (database|all), [$4] (file), [$5+] (params)
|
||||
function mariadbMasterExport() {
|
||||
mariadbExport mariadbMasterExec "$@"
|
||||
}
|
||||
|
||||
# Exports using root credentials.
|
||||
# $1 (execFn), $2 (database|all), [$3] (file), [$4+] (params)
|
||||
function mariadbRootExport() {
|
||||
mariadbExport "$1" root "$mariadbRootPass" "${@:2}"
|
||||
}
|
||||
|
||||
# Exports from master using root credentials.
|
||||
# [$1] (database|all), [$2] (file), [$3+] (params)
|
||||
function mariadbMasterRootExport() {
|
||||
local target="${1:-all}"
|
||||
local file="${2:-$appDataPath/$mariadbMasterKube/${appDate}_${appTime}_full.sql.tar.gz}"
|
||||
mariadbRootExport mariadbMasterExec "$target" "$file" ${@:3}
|
||||
}
|
||||
|
||||
# Exports from slave using root credentials.
|
||||
# [$1] (database|all), [$2] (file)
|
||||
function mariadbSlaveRootExport() {
|
||||
local target="${1:-all}"
|
||||
local file="${2:-$appDataPath/$mariadbSlaveKube/${appDate}_${appTime}_full.sql.tar.gz}"
|
||||
mariadbRootExport mariadbSlaveExec "$target" "$file" --all-databases --single-transaction --quick --routines --events
|
||||
}
|
||||
|
||||
# Imports a MariaDB dump into a database.
|
||||
# Supports plain SQL, .zip and .tar.gz archives (must contain exactly one file).
|
||||
# $1 (database|all): target database, or "all" to import without selecting a database.
|
||||
# $2 (username): username used for import.
|
||||
# $3 (password): password used for import.
|
||||
# $4 (file): source dump file.
|
||||
function mariadbMasterImport() {
|
||||
local database="$1"
|
||||
[[ -n "$database" ]] || { appError "Database not specified"; return 1; }
|
||||
local username="$2"
|
||||
[[ -n "$username" ]] || { appError "Username not specified"; return 1; }
|
||||
local password="$3"
|
||||
[[ -n "$password" ]] || { appError "Password not specified"; return 1; }
|
||||
local file="$4"
|
||||
[[ -n "$file" ]] || { appError "File not specified"; return 1; }
|
||||
[[ -f "$file" ]] || { appError "File not found: $file"; return 1; }
|
||||
|
||||
local tmpFile
|
||||
if [[ "$file" == *.zip ]]; then
|
||||
local entriesRaw
|
||||
entriesRaw="$(unzip -Z1 "$file" 2>/dev/null)" || { appError "Not a valid zip archive: $file"; return 1; }
|
||||
|
||||
local -a entries=()
|
||||
mapfile -t entries < <(printf '%s\n' "$entriesRaw" | sed '/\/$/d')
|
||||
[[ ${#entries[@]} -eq 1 ]] || { appError "Archive must contain exactly one file: $file"; return 1; }
|
||||
|
||||
tmpFile="$(mktemp)" || { appError "Failed to create temporary file"; return 1; }
|
||||
unzip -p "$file" "${entries[0]}" > "$tmpFile" 2>/dev/null || {
|
||||
rm -f -- "$tmpFile"
|
||||
appError "Failed to extract ZIP archive"
|
||||
return 1
|
||||
}
|
||||
elif [[ "$file" == *.tar.gz ]]; then
|
||||
local entriesRaw
|
||||
entriesRaw="$(tar -tzf "$file" 2>/dev/null)" || { appError "Not a valid tar.gz archive: $file"; return 1; }
|
||||
|
||||
local -a entries=()
|
||||
mapfile -t entries < <(printf '%s\n' "$entriesRaw" | sed '/\/$/d')
|
||||
[[ ${#entries[@]} -eq 1 ]] || { appError "Archive must contain exactly one file: $file"; return 1; }
|
||||
|
||||
tmpFile="$(mktemp)" || { appError "Failed to create temporary file"; return 1; }
|
||||
tar -xOzf "$file" "${entries[0]}" > "$tmpFile" 2>/dev/null || {
|
||||
rm -f -- "$tmpFile"
|
||||
appError "Failed to extract tar.gz archive"
|
||||
return 1
|
||||
}
|
||||
else
|
||||
tmpFile="$file"
|
||||
fi
|
||||
|
||||
if [[ ! -s "$tmpFile" ]]; then
|
||||
[[ "$tmpFile" == "$file" ]] || rm -f -- "$tmpFile"
|
||||
appError "The SQL dump is empty"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local -a mariadbCmd=(mariadbMasterExecI mariadb -u "$username" -p"$password")
|
||||
[[ "$database" != "all" ]] && mariadbCmd+=("$database")
|
||||
|
||||
local output error
|
||||
runShell output error "${mariadbCmd[@]}" "<" "$tmpFile" ">" /dev/null || {
|
||||
[[ "$tmpFile" == "$file" ]] || rm -f -- "$tmpFile"
|
||||
appError "Import failed: ${error:-$output}"
|
||||
return 1
|
||||
}
|
||||
|
||||
[[ "$tmpFile" == "$file" ]] || rm -f -- "$tmpFile"
|
||||
}
|
||||
|
||||
# Imports a MariaDB dump using root credentials.
|
||||
# $1 (database|all): target database, or "all".
|
||||
# $2 (file): source dump file.
|
||||
function mariadbMasterRootImport() {
|
||||
mariadbMasterImport "$1" root "$mariadbRootPass" "${@:2}"
|
||||
}
|
||||
|
||||
# Creates or updates the MariaDB database and user for a site.
|
||||
# $1 (domain): site domain name.
|
||||
function mariadbConfigRebuild() {
|
||||
local domain
|
||||
domain=$(domainPrepare "$1")
|
||||
domainCheck "$domain" || return 1
|
||||
|
||||
local databaseName databaseUser databasePass
|
||||
databaseName=$(siteConfigGetOrSet "$domain" "databaseName" "$(mariadbDomain2id "$domain")")
|
||||
databaseUser=$(siteConfigGetOrSet "$domain" "databaseUser" "$(mariadbDomain2id "$domain")")
|
||||
databasePass=$(siteConfigGetOrCreate "$domain" "databasePass")
|
||||
mariadbDatabaseUserSet "$databaseName" "$databaseUser" "$databasePass" || return 1
|
||||
}
|
||||
Reference in New Issue
Block a user