fix: 兼容旧容器上传挂载别名

This commit is contained in:
chenpei 2026-08-15 18:31:21 +08:00
parent 2c7df1765b
commit 47f3b7e067
2 changed files with 44 additions and 5 deletions

View File

@ -155,7 +155,7 @@ describe('production video transcode drain gate', () => {
).status).not.toBe(0)
})
test('Docker Mounts 模拟拒绝 volume、错 source、只读和重复 /app/uploads', () => {
test('Docker Mounts 模拟拒绝 volume、错 source、只读和重复 /app/uploads;旧容器仅可用已解析到同一数据盘的别名', () => {
const bash = findBash()
expect(bash).not.toBeNull()
if (!bash) return
@ -177,6 +177,29 @@ describe('production video transcode drain gate', () => {
expect(run(
`/app/uploads\tbind\t${expectedSource}\ttrue\n/app/uploads\tbind\t${expectedSource}\ttrue`,
).status).not.toBe(0)
const legacySource = '/mnt/PoolOne/apps/youyidian-3d/uploads'
const aliasHelper = `
readlink() {
if [ "$3" = "${legacySource}" ]; then
printf '%s\\n' "${expectedSource}"
else
printf '%s\\n' "$3"
fi
}
${helper}`
const runWithResolvedAlias = (allowAlias: string) => runBashGate(
bash,
aliasHelper,
'uploads_container_mount_metadata_is_trusted "$EXPECTED_SOURCE" "$CASE_METADATA" "$ALLOW_ALIAS"',
{
EXPECTED_SOURCE: expectedSource,
CASE_METADATA: `/app/uploads\tbind\t${legacySource}\ttrue`,
ALLOW_ALIAS: allowAlias,
},
)
expect(runWithResolvedAlias('0').status).not.toBe(0)
expect(runWithResolvedAlias('1').status).toBe(0)
})
test('statfs 模拟必须拒绝宿主根盘签名和宿主/容器不一致', () => {

View File

@ -1212,6 +1212,7 @@ statfs_signatures_match() {
uploads_container_mount_metadata_is_trusted() {
local expected_source="$1"
local metadata="$2"
local allow_resolved_source_alias="${3:-0}"
local matching_metadata=""
local matching_count=""
local destination=""
@ -1219,6 +1220,8 @@ uploads_container_mount_metadata_is_trusted() {
local source=""
local read_write=""
local extra=""
local resolved_source=""
local resolved_expected_source=""
[ -n "$metadata" ] || return 1
case "$metadata" in *$'\r'*) return 1 ;; esac
@ -1229,7 +1232,17 @@ uploads_container_mount_metadata_is_trusted() {
IFS=$'\t' read -r destination mount_type source read_write extra <<< "$matching_metadata"
[ "$destination" = "/app/uploads" ] || return 1
[ "$mount_type" = "bind" ] || return 1
[ "$source" = "$expected_source" ] || return 1
if [ "$source" != "$expected_source" ]; then
# Old production containers were created before UPLOADS_MOUNT was
# canonicalised. They may retain the former path spelling in Docker
# metadata, while resolving to exactly the same verified ZFS dataset.
# This compatibility is for draining an existing container only; newly
# created candidates always use the canonical string above.
[ "$allow_resolved_source_alias" = "1" ] || return 1
resolved_source="$(readlink -f -- "$source")" || return 1
resolved_expected_source="$(readlink -f -- "$expected_source")" || return 1
[ "$resolved_source" = "$resolved_expected_source" ] || return 1
fi
[ "$read_write" = "true" ] || return 1
[ -z "$extra" ]
}
@ -1280,13 +1293,14 @@ container_uploads_mount_metadata() {
verify_container_uploads_mount_metadata() {
local name="$1"
local allow_resolved_source_alias="${2:-0}"
local metadata=""
if ! metadata="$(container_uploads_mount_metadata "$name")"; then
warn "Cannot inspect uploads mount metadata for container ${name}"
return 1
fi
if ! uploads_container_mount_metadata_is_trusted "$UPLOADS_MOUNT" "$metadata"; then
if ! uploads_container_mount_metadata_is_trusted "$UPLOADS_MOUNT" "$metadata" "$allow_resolved_source_alias"; then
warn "Container ${name} does not have exactly one trusted RW bind mount at /app/uploads"
return 1
fi
@ -1315,7 +1329,7 @@ verify_container_upload_dir_config() {
if [ "$count" = "0" ]; then
return 0
fi
if [ "$count" = "1" ] && [ "$value" = "/app/uploads" ]; then
if [ "$count" = "1" ] && { [ "$value" = "/app/uploads" ] || [ "$value" = "./uploads" ]; }; then
return 0
fi
warn "Existing container ${name} has an unsafe UPLOAD_DIR override"
@ -1354,7 +1368,9 @@ verify_container_uploads_statfs() {
verify_container_uploads_storage() {
local name="$1"
local require_exact="${2:-0}"
verify_container_uploads_mount_metadata "$name" || return 1
local allow_resolved_source_alias="0"
[ "$require_exact" = "1" ] || allow_resolved_source_alias="1"
verify_container_uploads_mount_metadata "$name" "$allow_resolved_source_alias" || return 1
verify_container_uploads_statfs "$name" || return 1
verify_container_upload_dir_runtime "$name" "$require_exact"
}