fix: 兼容旧容器上传挂载别名
This commit is contained in:
parent
2c7df1765b
commit
47f3b7e067
@ -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 模拟必须拒绝宿主根盘签名和宿主/容器不一致', () => {
|
||||
|
||||
@ -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"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user