diff --git a/common/src/common/storage/factory.py b/common/src/common/storage/factory.py index fb746bc..1b152c1 100644 --- a/common/src/common/storage/factory.py +++ b/common/src/common/storage/factory.py @@ -57,8 +57,11 @@ def create_storage(config: dict[str, Any]) -> AnyStorageBackend: # 4 个目的化桶的名字(key for app.state.object_stores)。 -# 在 local 模式下对应 ``local_storage_base_dir/`` 子目录; -# 在 s3 模式下对应 ``settings.s3__bucket``。 +# 这些字符串作为 ``app.state.object_stores`` 的 dict key,也存入 +# ``StorageObjects.bucket_name`` / ``UploadSessions.bucket_name``。 +# 在 s3 模式下它们同时是真正的 S3 bucket 名;在 local 模式下它们只是 +# 与 s3 bucket 对应的标识符,真正的本地子目录由 ``build_storage_config`` +# 用 ``local_storage_base_dir/`` 拼装。 PURPOSE_BUCKETS: tuple[str, ...] = ("workspace", "version", "run_log", "trash") @@ -78,18 +81,19 @@ USAGE_TYPE_TO_PURPOSE: dict[str, str] = { def actual_bucket_name(purpose: str) -> str: - """把 purpose 名称解析成实际桶路径 / 名(runtime 数据会存在这个字符串里)。 + """把 purpose 名称解析成实际桶标识符(runtime 数据会存在这个字符串里)。 - - s3 模式:`settings.s3__bucket`(e.g. ``"versions"``) - - local 模式:`${local_storage_base_dir}/`(e.g. ``"/data/version"``) + local / s3 两种模式都返回 ``settings.s3__bucket`` 里配置的 + 字符串(如 ``"workspace"`` / ``"run-logs"``),因此两种模式下 + ``app.state.object_stores`` 的 key、``StorageObjects.bucket_name``、 + ``UploadSessions.bucket_name`` 都保持一致。 - 这是 ``app.state.object_stores`` 的 dict key——``UploadSessions.bucket_name`` - 和 ``StorageObjects.bucket_name`` 都存这个值,所以 dict 必须用这个串 - 做 key 才能在 ``object_stores[upload.bucket_name]`` 那里直接命中。 + local 模式下真正的本地文件系统布局由 ``build_storage_config`` 负责: + 它会把 ``local_storage_base_dir`` 与这里的 **purpose**(不是返回值) + 拼接,得到 ``create_storage`` 的 ``base_dir``。本函数只关心返回统一 + 的 bucket 标识符,不参与路径拼接。 """ from common.config import settings # 延迟 import 避免循环 - if settings.storage_backend == "local": - return str(Path(settings.local_storage_base_dir) / purpose) return getattr(settings, f"s3_{purpose}_bucket") @@ -97,16 +101,16 @@ def build_storage_uri(bucket_name: str, object_key: str) -> str: """根据 ``settings.storage_backend`` 构造对象的 storage_uri。 - s3 模式:``s3://{bucket_name}/{object_key}`` - - local 模式:``file://{absolute_bucket_path}/{object_key}`` + - local 模式:``file://{local_storage_base_dir}/{bucket_name}/{object_key}`` - local 模式下 ``bucket_name`` 是文件系统路径(见 ``actual_bucket_name``), - 不能直接用 ``s3://`` 前缀,否则会产生 ``s3:///data/version/...`` 这种 - 非法 URI。因此返回 ``file://`` URI,并把相对路径先转成绝对路径。 + ``bucket_name`` 是统一的 s3 风格 bucket 标识符(见 ``actual_bucket_name``), + 不是本地文件系统路径。local 模式下需要把它映射到 ``local_storage_base_dir`` + 下的子目录,再转成 ``file://`` URI,避免生成 ``s3:///data/...`` 这种非法 URI。 """ from common.config import settings # 延迟 import 避免循环 if settings.storage_backend == "local": - absolute_path = Path(bucket_name).absolute().as_posix() + absolute_path = (Path(settings.local_storage_base_dir) / bucket_name).resolve().as_posix() return f"file://{absolute_path}/{object_key}" return f"s3://{bucket_name}/{object_key}"