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