feat: move report artifacts to OSS storage
This commit is contained in:
@@ -36,6 +36,8 @@ SHA256_RE = re.compile(r"^[0-9a-f]{64}$")
|
||||
SAFE_CODE_RE = re.compile(r"^[A-Z][A-Z0-9_]{0,63}$")
|
||||
LOCAL_STORAGE_PROVIDER = "local"
|
||||
LOCAL_BUCKET_ALIAS = "arr-project-root"
|
||||
OSS_STORAGE_PROVIDER = "oss"
|
||||
OSS_BUCKET_ALIAS = "arr-private"
|
||||
|
||||
|
||||
SOURCE_FACTS_SQL = """
|
||||
@@ -160,6 +162,8 @@ class FileMetadata:
|
||||
sha256: str
|
||||
byte_size: int
|
||||
mime_type: str
|
||||
storage_provider: str = LOCAL_STORAGE_PROVIDER
|
||||
bucket_alias: str = LOCAL_BUCKET_ALIAS
|
||||
|
||||
def validate(self) -> None:
|
||||
storage = PurePosixPath(self.storage_key)
|
||||
@@ -175,6 +179,12 @@ class FileMetadata:
|
||||
or not SHA256_RE.fullmatch(self.sha256)
|
||||
or self.byte_size <= 0
|
||||
or not self.mime_type.strip()
|
||||
or not isinstance(self.storage_provider, str)
|
||||
or self.storage_provider not in {"local", "local_fixture", "oss", "s3"}
|
||||
or not isinstance(self.bucket_alias, str)
|
||||
or not self.bucket_alias.strip()
|
||||
or "/" in self.bucket_alias
|
||||
or "\\" in self.bucket_alias
|
||||
):
|
||||
raise RepositoryError(
|
||||
ErrorCode.PUBLISH_FAILED,
|
||||
@@ -519,13 +529,23 @@ class PostgresReportRepository:
|
||||
def _published_artifact(row: Sequence[Any]) -> Optional[FileMetadata]:
|
||||
if row[3] is None:
|
||||
return None
|
||||
if len(row) >= 11:
|
||||
provider = str(row[4] or LOCAL_STORAGE_PROVIDER)
|
||||
bucket_alias = str(row[5] or LOCAL_BUCKET_ALIAS)
|
||||
filename_index, key_index, hash_index, size_index, mime_index = 6, 7, 8, 9, 10
|
||||
else:
|
||||
provider = LOCAL_STORAGE_PROVIDER
|
||||
bucket_alias = LOCAL_BUCKET_ALIAS
|
||||
filename_index, key_index, hash_index, size_index, mime_index = 4, 5, 6, 7, 8
|
||||
metadata = FileMetadata(
|
||||
file_kind=str(row[3]),
|
||||
original_filename=str(row[4]),
|
||||
storage_key=str(row[5]),
|
||||
sha256=str(row[6]),
|
||||
byte_size=int(row[7]),
|
||||
mime_type=str(row[8] or "application/octet-stream"),
|
||||
original_filename=str(row[filename_index]),
|
||||
storage_key=str(row[key_index]),
|
||||
sha256=str(row[hash_index]),
|
||||
byte_size=int(row[size_index]),
|
||||
mime_type=str(row[mime_index] or "application/octet-stream"),
|
||||
storage_provider=provider,
|
||||
bucket_alias=bucket_alias,
|
||||
)
|
||||
metadata.validate()
|
||||
return metadata
|
||||
@@ -544,6 +564,8 @@ class PostgresReportRepository:
|
||||
run.version_no,
|
||||
run.report_status,
|
||||
artifact.artifact_kind,
|
||||
artifact.storage_provider,
|
||||
artifact.bucket_alias,
|
||||
artifact.original_filename,
|
||||
artifact.object_key,
|
||||
artifact.sha256,
|
||||
@@ -660,7 +682,7 @@ class PostgresReportRepository:
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _ensure_local_artifact(cursor: Any, metadata: FileMetadata) -> int:
|
||||
def _ensure_artifact(cursor: Any, metadata: FileMetadata) -> int:
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
@@ -677,7 +699,7 @@ class PostgresReportRepository:
|
||||
AND object_version_id IS NULL
|
||||
FOR SHARE
|
||||
""",
|
||||
(LOCAL_STORAGE_PROVIDER, LOCAL_BUCKET_ALIAS, metadata.storage_key),
|
||||
(metadata.storage_provider, metadata.bucket_alias, metadata.storage_key),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
@@ -710,8 +732,8 @@ class PostgresReportRepository:
|
||||
""",
|
||||
(
|
||||
metadata.file_kind,
|
||||
LOCAL_STORAGE_PROVIDER,
|
||||
LOCAL_BUCKET_ALIAS,
|
||||
metadata.storage_provider,
|
||||
metadata.bucket_alias,
|
||||
metadata.storage_key,
|
||||
metadata.original_filename,
|
||||
metadata.sha256,
|
||||
@@ -782,8 +804,8 @@ class PostgresReportRepository:
|
||||
ErrorCode.PUBLISH_FAILED,
|
||||
"monthly report reservation identity changed",
|
||||
)
|
||||
workbook_artifact_id = self._ensure_local_artifact(cursor, artifact)
|
||||
result_artifact_id = self._ensure_local_artifact(cursor, result_json)
|
||||
workbook_artifact_id = self._ensure_artifact(cursor, artifact)
|
||||
result_artifact_id = self._ensure_artifact(cursor, result_json)
|
||||
if str(run[0]) in {"active", "superseded"}:
|
||||
cursor.execute(
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user