Добавить патч совместимости загрузки файлов
Этот коммит содержится в:
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
app_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path('/opt/virtuality/web/app.py')
|
||||
if not app_path.exists():
|
||||
raise SystemExit(f'app.py not found: {app_path}')
|
||||
|
||||
text = app_path.read_text()
|
||||
changed = []
|
||||
|
||||
safe_name_helper = r'''
|
||||
|
||||
def safe_upload_filename(filename: str, allowed_suffixes: tuple[str, ...], fallback_prefix: str) -> str | None:
|
||||
original = Path(filename or "").name.strip()
|
||||
suffix = Path(original).suffix.lower()
|
||||
if suffix not in allowed_suffixes:
|
||||
return None
|
||||
stem = Path(original).stem.strip()
|
||||
stem = re.sub(r"\s+", "-", stem)
|
||||
stem = re.sub(r"[^a-zA-Z0-9_.-]", "_", stem)
|
||||
stem = stem.strip("._-")
|
||||
if not stem:
|
||||
stem = fallback_prefix
|
||||
stem = stem[:120]
|
||||
name = f"{stem}{suffix}"
|
||||
if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9_.-]{0,180}\.[a-zA-Z0-9]{2,8}", name):
|
||||
name = f"{fallback_prefix}{suffix}"
|
||||
return name
|
||||
'''
|
||||
|
||||
if 'def safe_upload_filename(' not in text:
|
||||
marker = '\n\ndef safe_iso_filename(filename: str) -> str | None:'
|
||||
if marker not in text:
|
||||
raise SystemExit('safe_iso_filename marker not found')
|
||||
text = text.replace(marker, safe_name_helper + marker, 1)
|
||||
changed.append('safe upload filename helper added')
|
||||
else:
|
||||
changed.append('safe upload filename helper already present')
|
||||
|
||||
old_iso = r'''def safe_iso_filename(filename: str) -> str | None:
|
||||
name = Path(filename or "").name.strip().replace(" ", "-")
|
||||
name = re.sub(r"[^a-zA-Z0-9_.-]", "_", name)
|
||||
if not name.lower().endswith(".iso"):
|
||||
return None
|
||||
if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9_.-]{1,180}\.iso", name):
|
||||
return None
|
||||
return name
|
||||
'''
|
||||
new_iso = r'''def safe_iso_filename(filename: str) -> str | None:
|
||||
return safe_upload_filename(filename, (".iso",), "virtuality-iso")
|
||||
'''
|
||||
if old_iso in text:
|
||||
text = text.replace(old_iso, new_iso, 1)
|
||||
changed.append('ISO filename sanitizer relaxed')
|
||||
elif 'return safe_upload_filename(filename, (".iso",), "virtuality-iso")' in text:
|
||||
changed.append('ISO filename sanitizer already relaxed')
|
||||
else:
|
||||
changed.append('ISO filename sanitizer replacement skipped')
|
||||
|
||||
old_disk = r'''def safe_disk_image_filename(filename: str) -> str | None:
|
||||
name = Path(filename or "").name.strip().replace(" ", "-")
|
||||
name = re.sub(r"[^a-zA-Z0-9_.-]", "_", name)
|
||||
if not name.lower().endswith((".img", ".raw", ".qcow2")):
|
||||
return None
|
||||
if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9_.-]{1,180}\.(img|raw|qcow2)", name, re.IGNORECASE):
|
||||
return None
|
||||
return name
|
||||
'''
|
||||
new_disk = r'''def safe_disk_image_filename(filename: str) -> str | None:
|
||||
return safe_upload_filename(filename, (".img", ".raw", ".qcow2"), "virtuality-disk")
|
||||
'''
|
||||
if old_disk in text:
|
||||
text = text.replace(old_disk, new_disk, 1)
|
||||
changed.append('disk image filename sanitizer relaxed')
|
||||
elif 'return safe_upload_filename(filename, (".img", ".raw", ".qcow2"), "virtuality-disk")' in text:
|
||||
changed.append('disk image filename sanitizer already relaxed')
|
||||
else:
|
||||
changed.append('disk image filename sanitizer not found yet')
|
||||
|
||||
# Make upload errors more explicit when temp/filesystem fails after multipart parsing.
|
||||
text = text.replace(
|
||||
'"error": f"Ошибка загрузки ISO: {exc}"}, status_code=500)',
|
||||
'"error": f"Ошибка загрузки ISO: {exc}. Проверь свободное место, права на /var/lib/virtuality/iso и временный каталог /var/lib/virtuality/tmp."}, status_code=500)'
|
||||
)
|
||||
text = text.replace(
|
||||
'"error": f"Ошибка загрузки образа: {exc}"}, status_code=500)',
|
||||
'"error": f"Ошибка загрузки образа: {exc}. Проверь свободное место, права на /var/lib/virtuality/disk-images и временный каталог /var/lib/virtuality/tmp."}, status_code=500)'
|
||||
)
|
||||
changed.append('upload error messages clarified')
|
||||
|
||||
app_path.write_text(text)
|
||||
print('upload compatibility patch applied:')
|
||||
for item in changed:
|
||||
print(f'- {item}')
|
||||
Ссылка в новой задаче
Block a user