我正在使用 python tufup 库来管理我的应用程序的更新,似乎我需要指定两个不同的 URL,但我很难从 docs/examples 中理解每个 URL 的配置位置/方式?或者我在这里误解了什么?
检查更新的 URL: 此 URL 是应用程序检查新版本或更新的位置。例如:“https://github.com/USER/PROJECT/releases/latest”(doc)
获取元数据和目标的 URL: 此 URL 是 tufup 客户端获取验证和应用更新所需的元数据和目标文件的位置。这些文件包括 root.json 和其他元数据文件。这个 URL(我假设)应该指向我控制的安全服务器。例如:“https://myCustomURL.com/verification_files”
这是我当前的配置:
__version__ = "0.1"
import customtkinter as ctk
import os, shutil, time
from pathlib import Path
from tufup.client import Client
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Define settings (these should ideally be in a separate settings.py file)
APP_NAME = "myAppName"
APP_VERSION = __version__
INSTALL_DIR = Path(os.getenv("INSTALL_DIR", Path.home() / "myAppName"))
METADATA_DIR = INSTALL_DIR / "metadata"
METADATA_BASE_URL = os.getenv("METADATA_BASE_URL", "https://myCustomURL.com/verification_files/metadata")
TARGET_DIR = INSTALL_DIR / "targets"
TARGET_BASE_URL = os.getenv("TARGET_BASE_URL", "https://myCustomURL.com/verification_files/targets")
TRUSTED_ROOT_SRC = Path(os.getenv("TRUSTED_ROOT_SRC", "update_repo/metadata/root.json"))
TRUSTED_ROOT_DST = METADATA_DIR / "root.json"
class App(ctk.CTk):
def __init__(self):
super().__init__()
# Check for updates
self.check_for_updates()
def progress_hook(self, bytes_downloaded: int, bytes_expected: int):
progress_percent = bytes_downloaded / bytes_expected * 100
time.sleep(0.2) # Simulate slow or large download
if progress_percent >= 100:
print("Download complete.")
def check_for_updates(self):
print("Checking for updates...")
try:
# Ensure directories exist
for dir_path in [INSTALL_DIR, METADATA_DIR, TARGET_DIR]:
dir_path.mkdir(exist_ok=True, parents=True)
# Ensure trusted root metadata exists
if not TRUSTED_ROOT_DST.exists():
if not TRUSTED_ROOT_SRC.exists():
raise FileNotFoundError(f"Trusted root metadata file not found: {TRUSTED_ROOT_SRC}")
shutil.copy(src=TRUSTED_ROOT_SRC, dst=TRUSTED_ROOT_DST)
print('Trusted root metadata copied to cache.')
# Create update client
client = Client(
app_name=APP_NAME,
app_install_dir=INSTALL_DIR,
current_version=APP_VERSION,
metadata_dir=METADATA_DIR,
metadata_base_url=METADATA_BASE_URL,
target_dir=TARGET_DIR,
target_base_url=TARGET_BASE_URL,
refresh_required=False,
)
# Perform update
new_update = client.check_for_updates(pre=None)
if new_update:
# Apply the update
client.download_and_apply_update(
skip_confirmation=True,
progress_hook=self.progress_hook,
purge_dst_dir=False,
exclude_from_purge=None,
log_file_name='install.log',
)
print("Update installed. Please restart the application.")
else:
print("You are up to date!")
except Exception as e:
print(f"Update check failed: {e}")
tufup包使用python-tuf来处理安全文件下载。
python-tuf
是 TUF(更新框架)的参考实现。 tufup
仅添加了一些处理版本化文件的逻辑,以及稍微更方便的界面。
A tufup client 的工作是检查新更新,下载更新存档(如果有),并将文件从该存档提取到某个目录中。
要实现此目的,
tufup
客户需要了解两件事:
在哪里可以找到可用更新列表:
可用更新列表位于由
targets.json
(使用 tufup
)生成的名为 python-tuf
的文件中。客户端将尝试从 metadata_base_url
中指定的 url 下载此文件。
在哪里可以找到实际的更新文件:
实际的更新文件包含在压缩的“档案”中,也是由
tufup
生成的,例如my-app-1.2.3.tar.gz
。这些文件使用 TUF 术语称为 [目标]。客户端将尝试从targets_base_url
中指定的url下载最新的更新存档。
重要的一点是:您(应用程序开发人员)必须确保这些文件可以在指定的网址下载。通常,这意味着您需要设置一台或多台服务器来提供 metadata 文件和 target 文件。
请注意,除了
targets.json
之外,tufup
(或实际上是 python-tuf
)还生成其他三种类型的 TUF 元数据 文件:root.json
、snapshot.json
和 timestamp.json
。所有四个元数据文件都需要可以从 metadata_base_url
中指定的 URL 下载。附加元数据文件用于安全目的。 TUF 规范详细解释了其工作原理。
tufup-example 自述文件展示了如何执行此操作以进行测试,并在
localhost
上提供文件。在 tufup-example settings 文件中,这些 url 指定为:
METADATA_BASE_URL = 'http://localhost:8000/metadata/'
TARGET_BASE_URL = 'http://localhost:8000/targets/'