112 lines
4.2 KiB
Bash
Executable File
112 lines
4.2 KiB
Bash
Executable File
#!/bin/sh
|
||
set -eu
|
||
|
||
CONFIG_FILE=${DASHBOARD_UPDATE_CONFIG:-/etc/proxmox-dashboard/update.env}
|
||
STATUS_FILE=${DASHBOARD_UPDATE_STATUS_PATH:-/var/lib/proxmox-dashboard/update-status.json}
|
||
BINARY_PATH=${DASHBOARD_BINARY_PATH:-/usr/local/bin/proxmox-cpu-dashboard}
|
||
REQUEST_FILE=${DASHBOARD_UPDATE_REQUEST_PATH:-/var/lib/proxmox-dashboard/update-request}
|
||
|
||
if [ -f "$CONFIG_FILE" ]; then
|
||
# shellcheck disable=SC1090
|
||
. "$CONFIG_FILE"
|
||
fi
|
||
|
||
GITEA_URL=${GITEA_URL:-https://git.myown.center}
|
||
GITEA_REPOSITORY=${GITEA_REPOSITORY:-maxim/ProxmoxDash}
|
||
GITEA_TOKEN=${GITEA_TOKEN:-}
|
||
UPDATE_MODE=${UPDATE_MODE:-notify}
|
||
ASSET_NAME=${ASSET_NAME:-proxmox-dashboard-linux-amd64}
|
||
manual_request=false
|
||
if [ -f "$REQUEST_FILE" ]; then
|
||
manual_request=true
|
||
rm -f "$REQUEST_FILE"
|
||
fi
|
||
|
||
mkdir -p "$(dirname "$STATUS_FILE")"
|
||
tmp_dir=$(mktemp -d /tmp/proxmox-dashboard-update.XXXXXX)
|
||
trap 'rm -rf "$tmp_dir"' EXIT INT TERM
|
||
|
||
auth_header=""
|
||
if [ -n "$GITEA_TOKEN" ]; then
|
||
auth_header="Authorization: token $GITEA_TOKEN"
|
||
fi
|
||
|
||
api_get() {
|
||
if [ -n "$auth_header" ]; then
|
||
curl --fail --silent --show-error --location --header "$auth_header" "$1"
|
||
else
|
||
curl --fail --silent --show-error --location "$1"
|
||
fi
|
||
}
|
||
|
||
write_status() {
|
||
python3 - "$STATUS_FILE" "$1" "$2" "$3" "$4" "$5" "$6" <<'PY'
|
||
import datetime, json, os, sys, tempfile
|
||
path, current, available, state, mode, message, release_url = sys.argv[1:]
|
||
payload = {
|
||
"currentVersion": current,
|
||
"availableVersion": available,
|
||
"state": state,
|
||
"mode": mode,
|
||
"message": message,
|
||
"releaseUrl": release_url,
|
||
"checkedAt": datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
||
}
|
||
fd, temporary = tempfile.mkstemp(dir=os.path.dirname(path), prefix=".update-status-")
|
||
with os.fdopen(fd, "w") as stream:
|
||
json.dump(payload, stream)
|
||
os.chmod(temporary, 0o644)
|
||
os.replace(temporary, path)
|
||
PY
|
||
}
|
||
|
||
current_version=$($BINARY_PATH -version 2>/dev/null || printf 'dev')
|
||
release_json=$(api_get "$GITEA_URL/api/v1/repos/$GITEA_REPOSITORY/releases/latest")
|
||
printf '%s' "$release_json" > "$tmp_dir/release.json"
|
||
release_data=$(python3 - "$tmp_dir/release.json" "$ASSET_NAME" <<'PY'
|
||
import json, sys
|
||
release = json.load(open(sys.argv[1]))
|
||
asset_name = sys.argv[2]
|
||
assets = {item.get("name"): item.get("browser_download_url") for item in release.get("assets", [])}
|
||
binary = assets.get(asset_name, "")
|
||
checksum = assets.get(asset_name + ".sha256", "")
|
||
print(release.get("tag_name", ""))
|
||
print(release.get("html_url", ""))
|
||
print(binary)
|
||
print(checksum)
|
||
PY
|
||
)
|
||
latest_version=$(printf '%s\n' "$release_data" | sed -n '1p')
|
||
release_url=$(printf '%s\n' "$release_data" | sed -n '2p')
|
||
binary_url=$(printf '%s\n' "$release_data" | sed -n '3p')
|
||
checksum_url=$(printf '%s\n' "$release_data" | sed -n '4p')
|
||
|
||
if [ -z "$latest_version" ] || [ -z "$binary_url" ]; then
|
||
write_status "$current_version" "$latest_version" error "$UPDATE_MODE" "В свежем релизе не найден бинарник $ASSET_NAME." "$release_url"
|
||
exit 1
|
||
fi
|
||
|
||
newest=$(printf '%s\n%s\n' "$current_version" "$latest_version" | sort -V | tail -n 1)
|
||
if [ "$current_version" = "$latest_version" ] || [ "$newest" = "$current_version" ]; then
|
||
write_status "$current_version" "$latest_version" current "$UPDATE_MODE" "Установлена свежая версия." "$release_url"
|
||
exit 0
|
||
fi
|
||
|
||
if [ "$UPDATE_MODE" != "auto" ] && [ "$manual_request" != "true" ]; then
|
||
write_status "$current_version" "$latest_version" available "$UPDATE_MODE" "Доступна новая версия $latest_version." "$release_url"
|
||
exit 0
|
||
fi
|
||
|
||
write_status "$current_version" "$latest_version" installing "$UPDATE_MODE" "Скачиваем и проверяем $latest_version." "$release_url"
|
||
api_get "$binary_url" > "$tmp_dir/$ASSET_NAME"
|
||
if [ -n "$checksum_url" ]; then
|
||
api_get "$checksum_url" > "$tmp_dir/$ASSET_NAME.sha256"
|
||
(cd "$tmp_dir" && sha256sum -c "$ASSET_NAME.sha256")
|
||
fi
|
||
chmod 0755 "$tmp_dir/$ASSET_NAME"
|
||
file "$tmp_dir/$ASSET_NAME" | grep -q 'ELF 64-bit'
|
||
cp -p "$BINARY_PATH" "$BINARY_PATH.previous"
|
||
install -m 0755 "$tmp_dir/$ASSET_NAME" "$BINARY_PATH"
|
||
write_status "$latest_version" "$latest_version" updated "$UPDATE_MODE" "Обновление $latest_version установлено." "$release_url"
|
||
systemctl restart proxmox-cpu-dashboard.service
|