Files
SODEW/sodew-bash-main/libs/commands/worker.sh
T
2026-08-18 09:40:08 +02:00

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")
}