302 lines
11 KiB
Bash
302 lines
11 KiB
Bash
workerLabel="[Worker]"
|
|
taskStatusExecution="execution"
|
|
taskStatusSuccess="success"
|
|
taskStatusFailed="failed"
|
|
taskStatusWaiting="waiting"
|
|
taskStatusNew="new"
|
|
|
|
# Prepares worker agent directory and UUID file.
|
|
function cmdWorkerPreparation() {
|
|
printSection "Preparation..."
|
|
|
|
if [[ ! -f "$workerAgentPath/worker.py" ]]; then
|
|
mkdir -p "$workerAgentPath"
|
|
cp -f -- "$appAssetsPath/$workerKube/worker.py" "$workerAgentPath/worker.py"
|
|
fi
|
|
rm -f "$workerAgentPath/worker.uuid"
|
|
fileValueGetOrCreate "$workerAgentPath/worker.uuid" "$hostUuid" >/dev/null 2>&1 || {
|
|
printDotText "preparation" "$labelFail"
|
|
printDanger "Generation UUID failed";
|
|
return 1;
|
|
}
|
|
|
|
printDotText "preparation" "$labelDone"
|
|
}
|
|
|
|
# Renders the Worker Kubernetes YAML manifest via Helm.
|
|
function cmdWorkerYamlRender() {
|
|
local templateFile="templates/$workerKube.yaml"
|
|
|
|
printSection "Render YAML file | Helm"
|
|
printDotText "Template" "$appAssetsPath/k3s/$templateFile"
|
|
[[ -f "$appAssetsPath/k3s/$templateFile" ]] || {
|
|
printDanger "Template file not found"
|
|
return 1
|
|
}
|
|
|
|
local varsFile
|
|
varsFile=$(mktemp "/tmp/$workerKube.vars.XXXXXX.yaml") || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Create temp variables file"
|
|
return 1
|
|
}
|
|
printDotText "Variables" "$varsFile"
|
|
trap 'rm -f -- "$varsFile"' RETURN
|
|
cat > "$varsFile" <<EOF
|
|
workerHelm: true
|
|
namespace: $k3sNamespace
|
|
worker: $workerKube
|
|
workerAgentPath: $workerAgentPath
|
|
workerTasksPath: $workerTasksPath
|
|
workerUuid: $hostUuid
|
|
workerName: $workerName
|
|
workerPool: $workerPool
|
|
workerApiUrl: $workerApiUrl
|
|
workerApiGettingPause: $workerApiGettingPause
|
|
workerApiSendingPause: $workerApiSendingPause
|
|
EOF
|
|
|
|
printDotText "Result" "$workerYaml"
|
|
mkdir -p -- "$(dirname -- "$workerYaml")" || return 1
|
|
fileBackup "$workerYaml"
|
|
helm template stack "$appAssetsPath/k3s" -f "$varsFile" --show-only "$templateFile" > "$workerYaml" || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Render failed"
|
|
return 1
|
|
}
|
|
|
|
printDotText "render" "$labelDone"
|
|
}
|
|
|
|
function cmdWorkerUpdate() {
|
|
cmdWorkerYamlRender || return 1
|
|
cmdK3sYamlApplyEx "$workerYaml" || return 1
|
|
}
|
|
|
|
# Installs Worker into Kubernetes.
|
|
function cmdWorkerInstall() {
|
|
cmdWorkerPreparation || return 1
|
|
cmdWorkerYamlRender || return 1
|
|
cmdK3sYamlApplyEx "$workerYaml" || return 1
|
|
}
|
|
|
|
# Uninstalls Worker Kubernetes resources.
|
|
function cmdWorkerUninstall() {
|
|
"$k3sCmd" kubectl delete -f "$workerYaml"
|
|
}
|
|
|
|
# Executes one worker task described in an INI-like config file.
|
|
# $1 (taskFile): path to the task config file.
|
|
# [$2] (domain): override domain (read from task file if omitted).
|
|
function cmdWorkerTaskHandle() {
|
|
local taskFile="$1"
|
|
[[ -n "$taskFile" ]] || { printDanger "$workerLabel Task file not specified"; return 1; }
|
|
[[ -f "$taskFile" ]] || { printDanger "$workerLabel Task: $taskFile | File not found"; return 1; }
|
|
printInfo "$workerLabel Task: $taskFile"
|
|
|
|
local domain="$2"
|
|
[[ -n "$domain" ]] || domain=$(configGet "$taskFile" "domain")
|
|
|
|
local status
|
|
status=$(configGet "$taskFile" "status")
|
|
if [[ "$status" != "$taskStatusNew" && "$status" != "$taskStatusWaiting" ]]; then
|
|
printDanger "$workerLabel Task: $taskFile | Status not '$taskStatusNew' or '$taskStatusWaiting'"
|
|
return 1
|
|
fi
|
|
configSet "$taskFile" "status" "$taskStatusExecution"
|
|
configSet "$taskFile" "start" "$(date +%s)"
|
|
|
|
local action
|
|
action=$(configGet "$taskFile" "action")
|
|
printInfo "$workerLabel Action: $action"
|
|
case "$action" in
|
|
"copy")
|
|
local databaseUrl
|
|
databaseUrl=$(configGet "$taskFile" "database_url")
|
|
if ! run output error urlAccessible "$databaseUrl"; then
|
|
printDanger "$workerLabel URL database archive is invalid: $databaseUrl"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "URL database archive is invalid: $databaseUrl"
|
|
return 1
|
|
fi
|
|
|
|
local filesUrl
|
|
filesUrl=$(configGet "$taskFile" "files_url")
|
|
if ! run output error urlAccessible "$filesUrl"; then
|
|
printDanger "$workerLabel URL files archive is invalid: $filesUrl"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "URL files archive is invalid: $filesUrl"
|
|
return 1
|
|
fi
|
|
|
|
if [[ -z "$domain" ]]; then
|
|
domain=$(domainsListMark "$domainsList")
|
|
fi
|
|
if [[ -z "$domain" ]]; then
|
|
printDanger "$workerLabel Domain not specified or no domains available"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Domain not specified or no domains available"
|
|
return 1
|
|
else
|
|
configSet "$taskFile" "domain" "$domain"
|
|
fi
|
|
|
|
configSet "$taskFile" "status" "$taskStatusExecution"
|
|
|
|
mkdir -p "$workerFilesPath"
|
|
local fileName filesLocal databaseLocal
|
|
fileName="${domain}_$(uuidgen)"
|
|
|
|
databaseLocal="$workerFilesPath/$(urlLocalFileGen "$databaseUrl" "$fileName")"
|
|
printInfo "$workerLabel Download archive database --> $databaseLocal"
|
|
if ! run output error fileDownload "$databaseUrl" "$databaseLocal"; then
|
|
printDanger "$error"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "$error"
|
|
return 1
|
|
fi
|
|
|
|
filesLocal="$workerFilesPath/$(urlLocalFileGen "$filesUrl" "$fileName")"
|
|
printInfo "$workerLabel Download archive files --> $filesLocal"
|
|
if ! run output error fileDownload "$filesUrl" "$filesLocal"; then
|
|
printDanger "$error"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "$error"
|
|
return 1
|
|
fi
|
|
|
|
printInfo "$workerLabel Create site: $domain"
|
|
if ! run output error cmdSiteAddWordpress "$domain" "$filesLocal" "$databaseLocal"; then
|
|
printDanger "$error"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Error create site: $error"
|
|
return 1
|
|
else
|
|
cmdWordpressDomainUpdate "$domain"
|
|
cmdOpenlitespeedRestart
|
|
fi
|
|
;;
|
|
"pack")
|
|
local output error
|
|
local uuid="worker_$(uuidgen)"
|
|
|
|
if ! run vhostList error openlitespeedConfigVhostList; then
|
|
printDanger "Vhost list: $error"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Error getting list of virtual hosts"
|
|
return 1
|
|
elif ! listContains "$domain" "$vhostList"; then
|
|
printDanger "Vhost list: Domain is not exists in OpenLiteSpeed config"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Domain is not exists in OpenLiteSpeed config"
|
|
return 1
|
|
fi
|
|
|
|
if ! run output error backupSiteFiles "$domain" "$olsVhostsPath/$domain/www/$uuid"; then
|
|
printDanger "$error"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Error create files archive: $error"
|
|
return 1
|
|
fi
|
|
if ! run output error backupSiteDatabase "$domain" "$olsVhostsPath/$domain/www/$uuid.sql"; then
|
|
printDanger "$error"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Error create database archive: $error"
|
|
return 1
|
|
fi
|
|
|
|
configSet "$taskFile" "files_url" "https://$domain/$uuid.tar.gz"
|
|
configSet "$taskFile" "database_url" "https://$domain/$uuid.sql.tar.gz"
|
|
;;
|
|
"delete")
|
|
printSuccess "$workerLabel Action: Site delete..."
|
|
cmdSiteRemove "$domain"
|
|
cmdOpenlitespeedRestart
|
|
;;
|
|
"update")
|
|
domain=$(configGet "$taskFile" "domain")
|
|
if [[ -z "$domain" ]]; then
|
|
printDanger "$workerLabel Domain not specified"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Domain not specified"
|
|
return 1
|
|
fi
|
|
|
|
local domainList
|
|
domainList=$(postfixDomainList)
|
|
if ! listContains "$domain" "$domainList"; then
|
|
printDanger "$workerLabel Domain $domain not found"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Domain $domain not found"
|
|
return 1
|
|
fi
|
|
|
|
local postfixForwardTo
|
|
postfixForwardTo=$(configGet "$taskFile" "mail_forward_to")
|
|
siteConfigSet "$domain" "postfixForwardTo" "$postfixForwardTo"
|
|
postfixVirtualAliasSet "@$domain" "$postfixForwardTo"
|
|
postfixPostmapRebuild
|
|
;;
|
|
*)
|
|
printDanger "$workerLabel Unknown action: $action"
|
|
configSet "$taskFile" "status" "$taskStatusFailed"
|
|
configSet "$taskFile" "message" "Unknown action: $action"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
configSet "$taskFile" "status" "$taskStatusSuccess"
|
|
printSuccess "$workerLabel Action: $action | Success"
|
|
|
|
local taskFileBase
|
|
taskFileBase=$(basename -- "$taskFile")
|
|
mkdir -p "$appDataPath/worker-task" || true
|
|
cp -f -- "$taskFile" "$appDataPath/worker-task/$taskFileBase" 2>/dev/null || true
|
|
}
|
|
|
|
# Scans task dir and runs handler for tasks with status new or waiting.
|
|
function cmdWorkerObserver() {
|
|
local fileList error
|
|
run fileList error fileList "$workerTasksPath" f || { appError "$error"; return 1; }
|
|
while IFS= read -r file; do
|
|
local taskFile="$workerTasksPath/$file"
|
|
local status
|
|
status=$(configGet "$taskFile" "status")
|
|
if [[ "$status" == "$taskStatusNew" || "$status" == "$taskStatusWaiting" ]]; then
|
|
printSuccess "$workerLabel $file | Status: $status | Starting..."
|
|
cmdWorkerTaskHandle "$taskFile"
|
|
else
|
|
printInfo "$workerLabel $file | Status: $status | Skip"
|
|
fi
|
|
done < <(awk 'NF' <<< "$fileList")
|
|
}
|
|
|
|
# Lists worker tasks with action, status, and lifetime in seconds.
|
|
function cmdWorkerTaskList() {
|
|
local fileList error
|
|
run fileList error fileList "$workerTasksPath" f || {
|
|
printDanger "$error";
|
|
return 1;
|
|
}
|
|
|
|
local count=0
|
|
while IFS= read -r file; do
|
|
((count++))
|
|
local task=${file%.task}
|
|
local action status start
|
|
action=$(configGet "$workerTasksPath/$file" "action")
|
|
status=$(configGet "$workerTasksPath/$file" "status")
|
|
start=$(configGet "$workerTasksPath/$file" "start")
|
|
local live="?"
|
|
if [[ -n "$start" ]]; then
|
|
live=$(( $(date +%s) - start ))
|
|
fi
|
|
|
|
printSection "$task"
|
|
printDotText "file" "$file"
|
|
printDotText "action" "$action"
|
|
printDotText "status" "$status"
|
|
printDotText "live, sec" "$live"
|
|
done < <(awk 'NF' <<< "$fileList")
|
|
}
|