sdk/other/updata_images.py

105 lines
3.5 KiB
Python
Raw Normal View History

2025-08-19 10:20:23 +00:00
#!/usr/bin/env python3
import requests, subprocess, os, uuid, datetime, csv
import client_config as config
# 获取或生成客户端 ID
def get_client_id():
if os.path.exists(config.CLIENT_ID_FILE):
return open(config.CLIENT_ID_FILE).read().strip()
cid = str(uuid.uuid4())
os.makedirs(os.path.dirname(config.CLIENT_ID_FILE) or ".", exist_ok=True)
open(config.CLIENT_ID_FILE,"w").write(cid)
return cid
# 读取本地 CSV
def read_csv(file_path):
if not os.path.exists(file_path):
return {}
with open(file_path, newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
return { row['image_name']: row for row in reader }
# 写入 CSV 文件
def write_csv(file_path, rows):
os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
with open(file_path,'w',newline='',encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=config.CLIENT_FIELDS)
writer.writeheader()
writer.writerows(rows)
# 获取服务器镜像列表
def get_server_images():
return requests.get(config.SERVER_API).json()
# 获取本地 Docker 镜像
def get_local_images():
output = subprocess.check_output(["docker","images","--format","{{.Repository}}:{{.Tag}}"]).decode()
local_images = {}
for line in output.strip().split("\n"):
if ":" in line:
name, tag = line.split(":",1)
local_images[name] = tag
return local_images
# 下载并加载镜像
def download_and_load(url):
os.makedirs(config.DOWNLOAD_DIR, exist_ok=True)
filename = os.path.join(config.DOWNLOAD_DIR, url.split("/")[-1])
print(f"下载镜像 {url}{filename}")
subprocess.run(["wget","-q","-O",filename,url],check=True)
print(f"加载镜像 {filename} 到 Docker")
subprocess.run(["docker","load","-i",filename],check=True)
# 上报客户端镜像状态
def report_to_server(client_id, images):
requests.post(config.CLIENT_UPDATE_API,json={"client_id":client_id,"images":images})
# 主函数
def main():
cid = get_client_id()
server_images = get_server_images()
local_images = get_local_images()
local_csv = read_csv(config.CLIENT_FILE)
report_data = []
for img in server_images:
name = img["image_name"]
tag = img["image_tag"]
server_time_str = img["last_updated"]
url = img["download_url"]
server_time = datetime.datetime.strptime(server_time_str, "%Y-%m-%d %H:%M:%S")
local_record = local_csv.get(name)
local_tag = local_images.get(name)
local_time = None
if local_record:
local_time = datetime.datetime.strptime(local_record["last_updated"], "%Y-%m-%d %H:%M:%S")
# 判断是否需要下载
need_update = False
if local_tag != tag:
need_update = True
elif local_time is None:
need_update = True
elif local_time < server_time:
need_update = True
if need_update:
print(f"[更新] {name}:{tag}")
download_and_load(url)
now_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
else:
print(f"[已最新] {name}:{tag}")
now_str = local_time.strftime("%Y-%m-%d %H:%M:%S") if local_time else server_time_str
report_data.append({"image_name":name,"image_tag":tag,"last_updated":now_str})
# 写本地 CSV
write_csv(config.CLIENT_FILE, report_data)
# 上报服务器
report_to_server(cid, report_data)
print("✅ 客户端镜像状态已上报服务器")
if __name__=="__main__":
main()