# Reads a value from the site config file. # $1 (domain): site domain name. # $@ (...): arguments passed to configGet. function siteConfigGet() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 shift configGet "$appDataPath/config/$domain.config" "$@" } # Writes a value to the site config file. # $1 (domain): site domain name. # $@ (...): arguments passed to configSet. function siteConfigSet() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 shift configSet "$appDataPath/config/$domain.config" "$@" } # Reads or sets a default value in the site config file. # $1 (domain): site domain name. # $@ (...): arguments passed to configGetOrSet. function siteConfigGetOrSet() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 shift configGetOrSet "$appDataPath/config/$domain.config" "$@" } # Reads or generates a new value in the site config file. # $1 (domain): site domain name. # $@ (...): arguments passed to configGetOrCreate. function siteConfigGetOrCreate() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 shift configGetOrCreate "$appDataPath/config/$domain.config" "$@" } # Creates a new site: validates uniqueness, provisions OLS/MariaDB/Redis/Postfix, and imports files and DB. # $1 (domain): site domain name. # $2 (sourceFiles): path to the site files directory or archive. # [$3] (sourceDatabase): path to a SQL dump file to import (optional). function siteAdd() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 local sourceFiles="$2" [[ -n "$sourceFiles" ]] || { appError "Source files not specified"; return 1; } [[ -e "$sourceFiles" ]] || { appError "Source files not found: $sourceFiles"; return 1; } local sourceDatabase="$3" if [[ -n "$sourceDatabase" && ! -f "$sourceDatabase" ]]; then appError "Source database not found: $sourceDatabase" return 1 fi local targetPath="$vhostsPath/$domain" [[ ! -e "$targetPath" ]] || { appError "The directory or file exists: $targetPath"; return 1; } # OpenLiteSpeed local vhostList aliasList error if ! run vhostList error openlitespeedVhostList all; then appError "Error retrieving vhost list: $error" return 1 elif listContains "$domain" "$vhostList"; then appError "Domain already exists in OpenLiteSpeed config: $domain" return 1 fi if ! run aliasList error openlitespeedAliasList; then appError "Error retrieving alias list: $error" return 1 elif listContains "$domain" "$aliasList"; then appError "Domain already exists in OpenLiteSpeed config (alias): $domain" return 1 fi # MariaDB local databaseName databaseUser databaseNameList databaseUserList databaseName=$(siteConfigGetOrSet "$domain" "databaseName" "$(mariadbDomain2id "$domain")") databaseUser=$(siteConfigGetOrSet "$domain" "databaseUser" "$(mariadbDomain2id "$domain")") if ! run databaseNameList error mariadbDatabaseListGet; then appError "Error retrieving MariaDB database list: $error" return 1 elif listContains "$databaseName" "$databaseNameList"; then appError "Database already exists in MariaDB: $databaseName" return 1 fi if ! run databaseUserList error mariadbUserListGet; then appError "Error retrieving MariaDB user list: $error" return 1 elif listContains "$databaseUser" "$databaseUserList"; then appError "User already exists in MariaDB: $databaseUser" return 1 fi # Redis local redisUser redisUserList redisUser=$(siteConfigGetOrSet "$domain" "redisUser" "$(redisDomain2id "$domain")") if ! run redisUserList error redisUserListGet; then appError "Error retrieving Redis user list: $error" return 1 elif listContains "$redisUser" "$redisUserList"; then appError "User already exists in Redis: $redisUser" return 1 fi # Postfix # TODO # TODO Check site in Postfix # TODO # Preparing and verifying the file source local tmpFiles="" local importFiles output rc if [[ -f "$sourceFiles" ]]; then tmpFiles=$(mktemp -d) || { appError "Failed to create temporary restore directory" return 1 } archiveExtract "$sourceFiles" "$tmpFiles" || { rm -rf -- "$tmpFiles" &>/dev/null return 1 } importFiles="$tmpFiles" else importFiles="$sourceFiles" fi # Preparing and Verifying the Database Source if [[ -n "$sourceDatabase" ]]; then local importDbName importDbUser importDbPass importDbName=$(uuidgen) || return 1 importDbUser=$(uuidgen) || return 1 importDbPass=$(uuidgen) || return 1 if ! runError error mariadbDatabaseUserSet "$importDbName" "$importDbUser" "$importDbPass"; then mariadbDatabaseRemove "$importDbName" mariadbUserRemove "$importDbUser" [[ -n "$tmpFiles" ]] && rm -rf -- "$tmpFiles" &>/dev/null appError "Failed to prepare tmp database" return 1 fi if ! run output error mariadbMasterImport "$importDbName" "$importDbUser" "$importDbPass" "$sourceDatabase"; then mariadbDatabaseRemove "$importDbName" mariadbUserRemove "$importDbUser" [[ -n "$tmpFiles" ]] && rm -rf -- "$tmpFiles" &>/dev/null appError "Failed to import tmp database: ${error:-$output}" return 1 fi mariadbDatabaseRemove "$importDbName" mariadbUserRemove "$importDbUser" fi function _siteAddRollback() { local message="$1" [[ -n "$tmpFiles" ]] && rm -rf -- "$tmpFiles" &>/dev/null appError "$message | Rollback..." siteRemove "$domain" || true } if ! runError error openlitespeedVhostRebuild "$domain"; then _siteAddRollback "Failed vhost rebuild (1): $error" return 1 fi if ! runError error cp -a "$importFiles/." "$targetPath/www/"; then _siteAddRollback "Failed copying files: $error" return 1 fi if ! runError error openlitespeedVhostRebuild "$domain"; then _siteAddRollback "Failed vhost rebuild (2): $error" return 1 fi if ! runError error openlitespeedConfigRebuild "$domain"; then _siteAddRollback "Failed OLS config rebuild: $error" return 1 fi if ! runError error systemHostAdd "$domain"; then _siteAddRollback "Failed add domain to hosts: $error" return 1 fi local databasePass databasePass=$(siteConfigGetOrCreate "$domain" "databasePass") if ! runError error mariadbDatabaseUserSet "$databaseName" "$databaseUser" "$databasePass"; then _siteAddRollback "Failed create user and database in MariaDB: $error" return 1 fi if [[ -n "$sourceDatabase" ]]; then if ! run output error mariadbMasterImport "$databaseName" "$databaseUser" "$databasePass" "$sourceDatabase"; then _siteAddRollback "Failed to import data in MariaDB: ${error:-$output}" return 1 fi fi local redisPass redisPass=$(siteConfigGetOrCreate "$domain" "redisPass") if ! runError error redisUserSet "$redisUser" "$redisPass"; then _siteAddRollback "Failed create user in Redis: $error" return 1 fi if ! runError error redisUserListSave; then _siteAddRollback "Failed update user list: $error" return 1 fi if ! runError error postfixDomainAdd "$domain"; then _siteAddRollback "Failed add domain in Postfix: $error" return 1 fi if ! runError error postfixPostmapRebuild; then _siteAddRollback "Failed postmap rebuild: $error" return 1 fi printf '%s' "$domain" } # Removes a site: deletes its DB, Redis user, Postfix domain, OLS config, files, and system user. # $1 (domain): site domain name. function siteRemove() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 if [[ -f "$appDataPath/config/$domain.config" ]]; then local databaseName databaseUser redisUser output error databaseName=$(siteConfigGet "$domain" "databaseName") if [[ -n "$databaseName" ]]; then runSilent mariadbDatabaseRemove "$databaseName" fi databaseUser=$(siteConfigGet "$domain" "databaseUser") if [[ -n "$databaseUser" ]]; then runSilent mariadbUserRemove "$databaseUser" fi redisUser=$(siteConfigGet "$domain" "redisUser") if [[ -n "$redisUser" ]]; then runSilent redisUserRemove "$redisUser" runSilent redisUserListSave fi fi runSilent postfixDomainRemove "$domain" runSilent postfixPostmapRebuild runSilent systemHostRemove "$domain" runSilent openlitespeedConfigRebuild "$domain" delete runSilent openlitespeedConfigEdit vhost_up "$domain" rm -f "$openlitespeedVhostsPath/$domain.conf" &>/dev/null rm -f "$openlitespeedVhostsPath/$domain.conf0" &>/dev/null rm -f "$openlitespeedVhostsPath/$domain.conf.txt" &>/dev/null rm -f "$appDataPath/config/$domain.config" &>/dev/null [[ -n "$domain" && "$domain" != "/" ]] && rm -rf "$vhostsPath/$domain" &>/dev/null local ug ug=$(domainToUser "$domain") if [[ -n "$ug" && "$ug" != "root" ]]; then if id "$ug" >/dev/null 2>&1; then runSilent userdel "$ug" fi if getent group "$ug" >/dev/null 2>&1; then runSilent groupdel "$ug" fi fi printf '%s' "$domain" } # Copies a site: exports source DB, creates target site, rebuilds WP config. # $1 (domain): source site domain name. # $2 (domainNew): target site domain name. function siteCopy() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 local domainNew domainNew=$(domainPrepare "$2") domainCheck "$domainNew" || return 1 if [[ "$domain" == "$domainNew" ]]; then appError "The domains match: $domain -> $domainNew" return 1 fi local vhostList if ! run vhostList error openlitespeedVhostList all; then appError "Error retrieving vhost list: $error" return 1 elif ! listContains "$domain" "$vhostList"; then appError "$domain: Not found in vhosts list" return 1 elif listContains "$domainNew" "$vhostList"; then appError "$domainNew: Found in vhosts list" return 1 fi local aliasList if ! run aliasList error openlitespeedAliasList; then appError "Error retrieving alias list: $error" return 1 elif listContains "$domainNew" "$aliasList"; then appError "$domainNew: Found in alias list" return 1 fi local databaseName databaseUser databasePass databaseFile databaseName=$(siteConfigGet "$domain" "databaseName") databaseUser=$(siteConfigGet "$domain" "databaseUser") databasePass=$(siteConfigGet "$domain" "databasePass") databaseFile=$(mktemp) || return 1 trap 'rm -f -- "$databaseFile"' RETURN if ! runError error mariadbMasterExport "$databaseUser" "$databasePass" "$databaseName" "$databaseFile"; then appError "$domain: Failed database export: $error" return 1 fi if ! runError error siteAdd "$domainNew" "$vhostsPath/$domain/www" "$databaseFile"; then appError "$domainNew: Create site: $error" return 1 fi rm -f -- "$databaseFile" if ! runError error wordpressDomainUpdate "$domainNew"; then appError "$domainNew: Failed config rebuild: $error" return 1 fi trap - RETURN printf '%s' "$domainNew" } # Renames a site by copying it to the new domain and removing the old one. # $1 (domain): current site domain name. # $2 (domainNew): new site domain name. function siteRename() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 local domainNew domainNew=$(domainPrepare "$2") domainCheck "$domainNew" || return 1 local error if ! runError error siteCopy "$domain" "$domainNew"; then appError "$error" return 1 fi local aliasList if run aliasList error openlitespeedVhostAlias "$domain" && [[ -n "$aliasList" ]]; then local -a aliases mapfile -t aliases <<< "$aliasList" openlitespeedAliasSet "$domain" openlitespeedAliasSet "$domainNew" "${aliases[@]}" fi runSilent siteRemove "$domain" || true printf '%s' "$domainNew" } # Resets all service passwords for a site and rebuilds MariaDB, Redis, Postfix, and WordPress config. # $1 (domain): site domain name. function sitePasswordReset() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 local error vhostList run vhostList error openlitespeedVhostList || { appError "Failed get list of virtual hosts: $error"; return 1; } listContains "$domain" "$vhostList" || { appError "Domain is not exists in OpenLiteSpeed config"; return 1; } local result=0 # reset passwords MariaDB local dbPass; dbPass=$(siteConfigGet "$domain" "databasePass") siteConfigSet "$domain" "databasePass" mariadbConfigRebuild "$domain" || { siteConfigSet "$domain" "databasePass" "$dbPass"; result=1; } # reset passwords Redis local redisPass; redisPass=$(siteConfigGet "$domain" "redisPass") siteConfigSet "$domain" "redisPass" redisConfigRebuild "$domain" || { siteConfigSet "$domain" "redisPass" "$redisPass"; result=1; } # reset passwords Postfix local postfixPass; postfixPass=$(siteConfigGet "$domain" "postfixPass") siteConfigSet "$domain" "postfixPass" postfixConfigRebuild "$domain" || { siteConfigSet "$domain" "postfixPass" "$postfixPass"; result=1; } # update Wordpress config wordpressConfigRebuild "$domain" || result=1 return $result } # Resets all service credentials (passwords and usernames) and rebuilds all service configs for a site. # $1 (domain): site domain name. function siteAuthReset() { local domain domain=$(domainPrepare "$1") domainCheck "$domain" || return 1 local error vhostList run vhostList error openlitespeedVhostList || { appError "Failed get list of virtual hosts: $error"; return 1; } listContains "$domain" "$vhostList" || { appError "Domain is not exists in OpenLiteSpeed config"; return 1; } local result=0 # reset passwords MariaDB local dbPass dbUser dbPass=$(siteConfigGet "$domain" "databasePass") dbUser=$(siteConfigGet "$domain" "databaseUser") siteConfigSet "$domain" "databasePass" siteConfigSet "$domain" "databaseUser" mariadbConfigRebuild "$domain" || { siteConfigSet "$domain" "databasePass" "$dbPass"; siteConfigSet "$domain" "databaseUser" "$dbUser"; result=1; } # reset passwords Redis local redisPass redisUser redisPass=$(siteConfigGet "$domain" "redisPass") redisUser=$(siteConfigGet "$domain" "redisUser") siteConfigSet "$domain" "redisPass" siteConfigSet "$domain" "redisUser" redisConfigRebuild "$domain" || { siteConfigSet "$domain" "redisPass" "$redisPass"; siteConfigSet "$domain" "redisUser" "$redisUser"; result=1; } # reset passwords Postfix local postfixPass postfixUser postfixPass=$(siteConfigGet "$domain" "postfixPass") postfixUser=$(siteConfigGet "$domain" "postfixUser") siteConfigSet "$domain" "postfixPass" siteConfigSet "$domain" "postfixUser" postfixConfigRebuild "$domain" || { siteConfigSet "$domain" "postfixPass" "$postfixPass"; siteConfigSet "$domain" "postfixUser" "$postfixUser"; result=1; } # update Wordpress config wordpressConfigRebuild "$domain" || result=1 return $result }