Compare commits

...

21 Commits

Author SHA1 Message Date
5978ced62a 更新 dockerfiles/cloudreve-aio.Dockerfile
Some checks failed
Sync Container Images / sync-images (push) Failing after 9m13s
2025-04-23 05:41:08 +00:00
7a69524e91 调整导入顺序,优化代码结构
All checks were successful
Sync Container Images / sync-images (push) Successful in 40s
2025-04-21 00:54:26 +08:00
ffc326a940 更新 cloudreve-aio Dockerfile,修正依赖项,移除多余的 vips-tools
All checks were successful
Sync Container Images / sync-images (push) Successful in 7m8s
2025-04-20 16:41:32 +08:00
aea3418854 更新 cloudreve-aio Dockerfile,添加 fftw-dev、lcms2-dev 和 libpng-dev 依赖项
All checks were successful
Sync Container Images / sync-images (push) Successful in 1m49s
2025-04-20 16:12:44 +08:00
0dc0e5e135 调整信号量大小,从 5 增加到 20,以提高并发任务的处理能力
All checks were successful
Sync Container Images / sync-images (push) Successful in 46s
2025-04-20 15:37:08 +08:00
44902487b0 更新 cloudreve-aio 的目标地址为 reg.liteyuki.icu/reedit/cloudreve-aio:latest
Some checks failed
Sync Container Images / sync-images (push) Has been cancelled
2025-04-20 15:36:40 +08:00
2147d48f6b 修正 Images 模型中的 source 字段,使其支持 None 值
Some checks failed
Sync Container Images / sync-images (push) Failing after 4m41s
2025-04-20 15:22:29 +08:00
450b83c3ef 添加 cloudreve-aio Dockerfile,更新同步任务以支持 Dockerfile 构建
Some checks failed
Sync Container Images / sync-images (push) Failing after 39s
2025-04-20 15:21:07 +08:00
364ee6e066 添加 test-pypi 依赖项,并更新 uv.lock 文件以包含新的源信息
Some checks failed
Sync Container Images / sync-images (push) Failing after 12m10s
2025-04-19 20:30:08 +08:00
eef8a9cbcb 优化任务传递逻辑,使用 partial 替代 lambda 以简化代码
All checks were successful
Sync Container Images / sync-images (push) Successful in 2m20s
2025-04-17 22:30:11 +08:00
862d8cf5f8 更换为群晖驱动器喜欢的partial
All checks were successful
Sync Container Images / sync-images (push) Successful in 1m0s
2025-04-17 22:26:52 +08:00
104a6822bc 修正限流机制,将信号量从 50 更改为 5,并优化任务传递逻辑以确保正确的参数传递
All checks were successful
Sync Container Images / sync-images (push) Successful in 2m47s
2025-04-17 22:16:51 +08:00
82517a10a7 优化异步任务处理,修复任务传递和返回值处理逻辑
All checks were successful
Sync Container Images / sync-images (push) Successful in 49s
2025-04-17 22:10:56 +08:00
4d671a283f 修正限流任务的实现,确保在调用时传递信号量参数
Some checks failed
Sync Container Images / sync-images (push) Failing after 43s
2025-04-17 22:07:06 +08:00
7b32044803 aaaa
Some checks failed
Sync Container Images / sync-images (push) Failing after 1m9s
2025-04-17 21:46:03 +08:00
46e94a5d84 修正打印逻辑,添加对拉取镜像时标签的输出
All checks were successful
Sync Container Images / sync-images (push) Successful in 1m6s
2025-04-17 21:43:00 +08:00
531ea9f1c2 修正限流机制,将信号量从 5 更改为 50,以支持更多并发任务执行
All checks were successful
Sync Container Images / sync-images (push) Successful in 1m22s
2025-04-17 21:40:43 +08:00
2c735de7e7 更改工作流运行环境,从 ubuntu-latest 更新为 liteyukios-latest
All checks were successful
Sync Container Images / sync-images (push) Successful in 58s
2025-04-17 21:37:03 +08:00
4bcca0b832 修正打印逻辑,添加对当前处理镜像的输出
Some checks failed
Sync Container Images / sync-images (push) Failing after 18s
2025-04-17 21:35:48 +08:00
f6034a32fc 修正任务完成信息的打印逻辑,移除重复输出
All checks were successful
Sync Container Images / sync-images (push) Successful in 2m20s
2025-04-17 21:28:00 +08:00
be652dfadd 优化任务处理逻辑,修正任务函数以确保正确执行 docker_pull、docker_tag 和 docker_push 操作 2025-04-17 21:27:42 +08:00
6 changed files with 83 additions and 30 deletions

View File

@@ -9,7 +9,7 @@ on:
jobs: jobs:
sync-images: sync-images:
runs-on: ubuntu-latest runs-on: [liteyukios-latest]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -0,0 +1,9 @@
FROM cloudreve/cloudreve:4.0.0-beta.6
# Install ffmpeg LibreOffice and VIPS
RUN apk add --no-cache \
ffmpeg \
libreoffice \
vips-tools \
&& rm -rf /var/cache/apk/*

View File

@@ -24,4 +24,7 @@ images:
- "20" - "20"
- "20-slim" - "20-slim"
- "18" - "18"
- "18-slim" - "18-slim"
- dockerfile: "./dockerfiles/cloudreve-aio.Dockerfile"
target: "reg.liteyuki.icu/reedit/cloudreve-aio:latest"

View File

@@ -9,3 +9,9 @@ dependencies = [
"pydantic>=2.11.3", "pydantic>=2.11.3",
"pyyaml>=6.0.2", "pyyaml>=6.0.2",
] ]
[[tool.uv.index]]
name = "liteyuki"
url = "https://git.liteyuki.icu/api/packages/snowykami/pypi/simple"
explicit = true

81
sync.py
View File

@@ -1,19 +1,20 @@
import asyncio import asyncio
from types import CoroutineType
from typing import Any, Awaitable, Callable, Coroutine
import aiofiles import aiofiles
import yaml import yaml
from typing import Any, Callable, Coroutine
from functools import partial
from pydantic import BaseModel from pydantic import BaseModel
class Config(BaseModel): class Config(BaseModel):
images: list["Images"] = [] images: list["Images"] = []
class Images(BaseModel): class Images(BaseModel):
source: str dockerfile: str | None = None
source: str | None = None
target: str target: str
tags: list[str] = [] tags: list[str] = []
async def run_command(command: str) -> int | None: async def run_command(command: str) -> int | None:
process = await asyncio.create_subprocess_shell( process = await asyncio.create_subprocess_shell(
command, command,
@@ -28,26 +29,52 @@ async def run_command(command: str) -> int | None:
print(f"[STDERR]\n{stderr.decode()}") print(f"[STDERR]\n{stderr.decode()}")
return process.returncode return process.returncode
async def docker_pull(image: str) -> int | None: async def docker_pull(image: str) -> int | None:
print(f"Pulling image {image}...") print(f"Pulling image {image}...")
return await run_command(f"docker pull {image}") return await run_command(f"docker pull {image}")
async def docker_tag(source: str, target: str) -> int | None: async def docker_tag(source: str, target: str) -> int | None:
print(f"Tagging image {source} as {target}...") print(f"Tagging image {source} as {target}...")
return await run_command(f"docker tag {source} {target}") return await run_command(f"docker tag {source} {target}")
async def docker_push(image: str) -> int | None: async def docker_push(image: str) -> int | None:
print(f"Pushing image {image}...") print(f"Pushing image {image}...")
return await run_command(f"docker push {image}") return await run_command(f"docker push {image}")
semaphore = asyncio.Semaphore(5) async def docker_build(dockerfile: str, target: str) -> int | None:
print(f"Building image from {dockerfile}...")
return await run_command(f"docker build -t {target} -f {dockerfile} .")
async def limited_task[T: Any](task: Callable[[], Coroutine[None, None, T]]) -> T: async def docker_sync_task(source: str, target: str) -> int | None:
print(f"Pulling image {source}...")
if r := await docker_pull(source):
if r != 0:
return r
if r := await docker_tag(source, target):
if r != 0:
return r
if r := await docker_push(target):
if r != 0:
return r
return 0
async def docker_build_task(dockerfile: str, target: str) -> int | None:
print(f"Building image from {dockerfile}...")
if r := await docker_build(dockerfile, target):
if r != 0:
return r
if r := await docker_push(target):
if r != 0:
return r
return 0
semaphore = asyncio.Semaphore(20)
async def limited_task[T: Any](semaphore: asyncio.Semaphore, task: Callable[[], Coroutine[None, None, T]]) -> T:
async with semaphore: async with semaphore:
return await task() return await task()
async def main(): async def main():
async with aiofiles.open('images.yaml', 'r') as file: async with aiofiles.open('images.yaml', 'r') as file:
config = await file.read() config = await file.read()
@@ -60,28 +87,26 @@ async def main():
tasks = [] tasks = []
for image in config.images: for image in config.images:
if len(image.tags) > 0: if image.dockerfile:
# 若有dockerfile提供則使用docker build
if len(image.tags) > 0:
# 若有tags提供則使用docker build和docker tag
for tag in image.tags:
tasks.append(limited_task(semaphore, partial(docker_build_task, image.dockerfile, f"{image.target}:{tag}")))
else:
tasks.append(limited_task(semaphore, partial(docker_build_task, image.dockerfile, image.target)))
elif len(image.tags) > 0:
# 若有tags提供則使用docker pull和docker tag
for tag in image.tags: for tag in image.tags:
async def task() -> int | None: tasks.append(limited_task(semaphore, partial(docker_sync_task, f"{image.source}:{tag}", f"{image.target}:{tag}")))
return (await docker_pull(f"{image.source}:{tag}")) \
or (await docker_pull(f"{image.source}:{tag}")) \
or (await docker_push(f"{image.target}:{tag}"))
tasks.append(limited_task(task))
else: else:
async def task() -> int | None: tasks.append(limited_task(semaphore, partial(docker_sync_task, image.source, image.target)))
return (await docker_pull(image.source)) \
or (await docker_pull(image.source)) \
or (await docker_push(image.target))
tasks.append(limited_task(task))
results = await asyncio.gather(*tasks) results = await asyncio.gather(*tasks)
print(tasks) failed_tasks = sum(1 for result in results if result is not None and result != 0)
failed_tasks = 0
for result in results:
if result is not None and result != 0:
failed_tasks += 1
print(f"{len(results)} tasks completed. {len(results) - failed_tasks} succeed, {failed_tasks} failed.") print(f"{len(results)} tasks completed. {len(results) - failed_tasks} succeed, {failed_tasks} failed.")
if failed_tasks > 0:
raise Exception(f"{failed_tasks} tasks failed.")
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())

10
uv.lock generated
View File

@@ -27,6 +27,7 @@ dependencies = [
{ name = "aiofiles" }, { name = "aiofiles" },
{ name = "pydantic" }, { name = "pydantic" },
{ name = "pyyaml" }, { name = "pyyaml" },
{ name = "test-pypi" },
] ]
[package.metadata] [package.metadata]
@@ -34,6 +35,7 @@ requires-dist = [
{ name = "aiofiles", specifier = ">=24.1.0" }, { name = "aiofiles", specifier = ">=24.1.0" },
{ name = "pydantic", specifier = ">=2.11.3" }, { name = "pydantic", specifier = ">=2.11.3" },
{ name = "pyyaml", specifier = ">=6.0.2" }, { name = "pyyaml", specifier = ">=6.0.2" },
{ name = "test-pypi", specifier = ">=0.1.1", index = "https://git.liteyuki.icu/api/packages/snowykami/pypi/simple" },
] ]
[[package]] [[package]]
@@ -119,6 +121,14 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
] ]
[[package]]
name = "test-pypi"
version = "0.1.1"
source = { registry = "https://git.liteyuki.icu/api/packages/snowykami/pypi/simple" }
wheels = [
{ url = "https://git.liteyuki.icu/api/packages/snowykami/pypi/files/test-pypi/0.1.1/test_pypi-0.1.1-py3-none-any.whl", hash = "sha256:b34310401079188a6b286cbf95c60c24c5ae950c7682e07cda7259d73c8b3b67" },
]
[[package]] [[package]]
name = "typing-extensions" name = "typing-extensions"
version = "4.13.2" version = "4.13.2"