mirror of
https://github.com/netinvent/npbackup.git
synced 2025-10-29 06:46:26 +08:00
upgrade_server: Support server upgrade script
This commit is contained in:
parent
dd38702970
commit
6270dd3e90
3 changed files with 69 additions and 32 deletions
|
|
@ -26,6 +26,7 @@ from upgrade_server.models.files import (
|
|||
Arch,
|
||||
BuildType,
|
||||
Audience,
|
||||
Artefact,
|
||||
)
|
||||
from upgrade_server.models.oper import CurrentVersion
|
||||
import upgrade_server.crud as crud
|
||||
|
|
@ -179,6 +180,7 @@ async def current_version(
|
|||
"auto_upgrade_host_identity": auto_upgrade_host_identity,
|
||||
"installed_version": installed_version,
|
||||
"group": group,
|
||||
"artefact": None,
|
||||
"platform": platform.value,
|
||||
"arch": arch.value,
|
||||
"build": build_type.value,
|
||||
|
|
@ -224,27 +226,28 @@ async def current_version(
|
|||
|
||||
|
||||
@app.get(
|
||||
"/upgrades/{platform}/{arch}/{build_type}/{audience}",
|
||||
"/info/{artefact}/{platform}/{arch}/{build_type}/{audience}",
|
||||
response_model=Union[FileSend, dict],
|
||||
status_code=200,
|
||||
)
|
||||
@app.get(
|
||||
"/upgrades/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}",
|
||||
"/info/{artefact}/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}",
|
||||
response_model=Union[FileSend, dict],
|
||||
status_code=200,
|
||||
)
|
||||
@app.get(
|
||||
"/upgrades/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}",
|
||||
"/info/{artefact}/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}",
|
||||
response_model=Union[FileSend, dict],
|
||||
status_code=200,
|
||||
)
|
||||
@app.get(
|
||||
"/upgrades/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}/{group}",
|
||||
"/info/{artefact}/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}/{group}",
|
||||
response_model=Union[FileSend, dict],
|
||||
status_code=200,
|
||||
)
|
||||
async def upgrades(
|
||||
request: Request,
|
||||
artefact: Artefact,
|
||||
platform: Platform,
|
||||
arch: Arch,
|
||||
build_type: BuildType,
|
||||
|
|
@ -281,6 +284,7 @@ async def upgrades(
|
|||
"auto_upgrade_host_identity": auto_upgrade_host_identity,
|
||||
"installed_version": installed_version,
|
||||
"group": group,
|
||||
"artefact": artefact.value,
|
||||
"platform": platform.value,
|
||||
"arch": arch.value,
|
||||
"build": build_type.value,
|
||||
|
|
@ -304,6 +308,7 @@ async def upgrades(
|
|||
)
|
||||
|
||||
file = FileGet(
|
||||
artefact=artefact,
|
||||
platform=platform,
|
||||
arch=arch,
|
||||
build_type=build_type,
|
||||
|
|
@ -328,27 +333,28 @@ async def upgrades(
|
|||
|
||||
|
||||
@app.get(
|
||||
"/download/{platform}/{arch}/{build_type}/{audience}",
|
||||
"/download/{artefact}/{platform}/{arch}/{build_type}/{audience}",
|
||||
response_model=FileSend,
|
||||
status_code=200,
|
||||
)
|
||||
@app.get(
|
||||
"/download/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}",
|
||||
"/download/{artefact}/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}",
|
||||
response_model=FileSend,
|
||||
status_code=200,
|
||||
)
|
||||
@app.get(
|
||||
"/download/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}",
|
||||
"/download/{artefact}/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}",
|
||||
response_model=FileSend,
|
||||
status_code=200,
|
||||
)
|
||||
@app.get(
|
||||
"/download/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}/{group}",
|
||||
"/download/{artefact}/{platform}/{arch}/{build_type}/{audience}/{auto_upgrade_host_identity}/{installed_version}/{group}",
|
||||
response_model=FileSend,
|
||||
status_code=200,
|
||||
)
|
||||
async def download(
|
||||
request: Request,
|
||||
artefact: Artefact,
|
||||
platform: Platform,
|
||||
arch: Arch,
|
||||
build_type: BuildType,
|
||||
|
|
@ -385,6 +391,7 @@ async def download(
|
|||
"auto_upgrade_host_identity": auto_upgrade_host_identity,
|
||||
"installed_version": installed_version,
|
||||
"group": group,
|
||||
"artefact": artefact.value,
|
||||
"platform": platform.value,
|
||||
"arch": arch.value,
|
||||
"build": build_type.value,
|
||||
|
|
@ -408,6 +415,7 @@ async def download(
|
|||
)
|
||||
|
||||
file = FileGet(
|
||||
artefact=artefact,
|
||||
platform=platform,
|
||||
arch=arch,
|
||||
build_type=build_type,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ __intname__ = "npbackup.upgrade_server.crud"
|
|||
__author__ = "Orsiris de Jong"
|
||||
__copyright__ = "Copyright (C) 2023-2025 NetInvent"
|
||||
__license__ = "GPL-3.0-only"
|
||||
__build__ = "2025011601"
|
||||
__build__ = "2025012401"
|
||||
|
||||
|
||||
import os
|
||||
|
|
@ -61,16 +61,27 @@ def _get_path_from_target_id(target_id: ClientTargetIdentification) -> Tuple[str
|
|||
"""
|
||||
Determine specific or generic upgrade path depending on target_id sent by client
|
||||
|
||||
NPBackup filenames are
|
||||
npbackup-{platform}-{arch}-{build_type}-{audience}.{archive_extension}"
|
||||
If a specific sub path is found, we'll return that one, otherwise we'll return the default path
|
||||
|
||||
Possible archive names are:
|
||||
npbackup-{platform}-{arch}-{build_type}-{audience}.{archive_extension}
|
||||
|
||||
Possible upgrade script names are:
|
||||
npbackup-{platform}-{arch}-{build_type}-{audience}.sh
|
||||
npbackup-{platform}-{arch}-{build_type}-{audience}.cmd
|
||||
npbackup-{platform}.sh
|
||||
npbackup-{platform}.cmd
|
||||
|
||||
"""
|
||||
if target_id.platform.value == "windows":
|
||||
extension = "zip"
|
||||
archive_extension = "zip"
|
||||
script_extension = "cmd"
|
||||
else:
|
||||
extension = "tar.gz"
|
||||
archive_extension = "tar.gz"
|
||||
script_extension = "sh"
|
||||
|
||||
expected_filename = f"npbackup-{target_id.platform.value}-{target_id.arch.value}-{target_id.build_type.value}-{target_id.audience.value}.{extension}"
|
||||
expected_archive_filename = f"npbackup-{target_id.platform.value}-{target_id.arch.value}-{target_id.build_type.value}-{target_id.audience.value}.{archive_extension}"
|
||||
expected_script_filename = f"npbackup-{target_id.platform.value}-{target_id.arch.value}-{target_id.build_type.value}-{target_id.audience.value}.{script_extension}"
|
||||
|
||||
base_path = os.path.join(
|
||||
config_dict["upgrades"]["data_root"],
|
||||
|
|
@ -88,10 +99,12 @@ def _get_path_from_target_id(target_id: ClientTargetIdentification) -> Tuple[str
|
|||
base_path = possibile_sub_path
|
||||
break
|
||||
|
||||
archive_path = os.path.join(base_path, expected_filename)
|
||||
archive_path = os.path.join(base_path, expected_archive_filename)
|
||||
script_path = os.path.join(base_path, expected_script_filename)
|
||||
|
||||
version_file_path = os.path.join(base_path, "VERSION")
|
||||
|
||||
return version_file_path, archive_path
|
||||
return version_file_path, archive_path, script_path
|
||||
|
||||
|
||||
def store_host_info(destination: str, host_id: dict) -> None:
|
||||
|
|
@ -113,7 +126,7 @@ def get_current_version(
|
|||
target_id: ClientTargetIdentification,
|
||||
) -> Optional[CurrentVersion]:
|
||||
try:
|
||||
version_filename, _ = _get_path_from_target_id(target_id)
|
||||
version_filename, _, _ = _get_path_from_target_id(target_id)
|
||||
logger.info(f"Searching for version in {version_filename}")
|
||||
if os.path.isfile(version_filename):
|
||||
with open(version_filename, "r", encoding="utf-8") as fh:
|
||||
|
|
@ -131,14 +144,10 @@ def get_file(
|
|||
file: FileGet, content: bool = False
|
||||
) -> Optional[Union[FileSend, bytes, dict]]:
|
||||
|
||||
_, archive_path = _get_path_from_target_id(file)
|
||||
_, archive_path, script_path = _get_path_from_target_id(file)
|
||||
|
||||
logger.info(
|
||||
f"Searching for file {'info' if not content else 'content'} in {archive_path}"
|
||||
)
|
||||
if not os.path.isfile(archive_path):
|
||||
logger.info(f"No upgrade file found in {archive_path}")
|
||||
return {
|
||||
unknown_artefact = {
|
||||
"artefact": file.artefact.value,
|
||||
"arch": file.arch.value,
|
||||
"platform": file.platform.value,
|
||||
"build_type": file.build_type.value,
|
||||
|
|
@ -148,19 +157,33 @@ def get_file(
|
|||
"file_length": 0,
|
||||
}
|
||||
|
||||
with open(archive_path, "rb") as fh:
|
||||
bytes = fh.read()
|
||||
if file.artefact.value == "archive":
|
||||
artefact_path = archive_path
|
||||
elif file.artefact.value == "script":
|
||||
artefact_path = script_path
|
||||
else:
|
||||
logger.error(f"Unknown artefact type {file.artefact.value}")
|
||||
return unknown_artefact
|
||||
logger.info(
|
||||
f"Searching for file {'info' if not content else 'content'} in {artefact_path}"
|
||||
)
|
||||
if not os.path.isfile(artefact_path):
|
||||
logger.info(f"No upgrade file found in {artefact_path}")
|
||||
return unknown_artefact
|
||||
|
||||
with open(artefact_path, "rb") as fh:
|
||||
file_conten_bytes = fh.read()
|
||||
if content:
|
||||
return bytes
|
||||
length = len(bytes)
|
||||
sha256 = sha256sum_data(bytes)
|
||||
return file_conten_bytes
|
||||
length = len(file_conten_bytes)
|
||||
sha256 = sha256sum_data(file_conten_bytes)
|
||||
file_send = FileSend(
|
||||
arch=file.arch.value,
|
||||
platform=file.platform.value,
|
||||
build_type=file.build_type.value,
|
||||
audience=file.audience.value,
|
||||
sha256sum=sha256,
|
||||
filename=os.path.basename(archive_path),
|
||||
filename=os.path.basename(artefact_path),
|
||||
file_length=length,
|
||||
)
|
||||
return file_send
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ __intname__ = "npbackup.upgrade_server.models.files"
|
|||
__author__ = "Orsiris de Jong"
|
||||
__copyright__ = "Copyright (C) 2023-2025 NetInvent"
|
||||
__license__ = "GPL-3.0-only"
|
||||
__build__ = "2025011601"
|
||||
__build__ = "2025012401"
|
||||
|
||||
|
||||
from typing import Optional
|
||||
|
|
@ -15,6 +15,11 @@ from enum import Enum
|
|||
from pydantic import BaseModel, constr
|
||||
|
||||
|
||||
class Artefact(Enum):
|
||||
script = "script"
|
||||
archive = "archive"
|
||||
|
||||
|
||||
class Platform(Enum):
|
||||
windows = "windows"
|
||||
linux = "linux"
|
||||
|
|
@ -46,10 +51,11 @@ class ClientTargetIdentification(BaseModel):
|
|||
|
||||
|
||||
class FileGet(ClientTargetIdentification):
|
||||
pass
|
||||
artefact: Artefact
|
||||
|
||||
|
||||
class FileSend(ClientTargetIdentification):
|
||||
artefact: Artefact
|
||||
sha256sum: constr(min_length=64, max_length=64)
|
||||
filename: str
|
||||
file_length: int
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue