1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00

fix(logging): the application log rotates into a bounded, auto-created directory

This commit is contained in:
catborise 2026-10-07 15:01:59 +03:00
parent bbb9f77cb1
commit 7405217466
3 changed files with 54 additions and 4 deletions

View file

@ -417,6 +417,8 @@ Failed logins are limited with `django-axes` (installed from `conf/requirements.
OTP, when enabled, is enforced only by the login form, so close the two doors that skip it. Delete the `path('api-auth/', include('rest_framework.urls', ...))` line from your `webvirtcloud/urls.py` (the DRF browsable-API login created a password-only session), and add `"DEFAULT_AUTHENTICATION_CLASSES": ["rest_framework.authentication.SessionAuthentication"]` to the `REST_FRAMEWORK` block in your `webvirtcloud/settings.py` (without it the API accepts HTTP Basic credentials, a password-only bypass). The API then needs a session from the login form; password-based programmatic access no longer works. After updating settings, end any sessions opened through the old doors so they do not keep OTP-free access (empty the `django_session` table, e.g. `python3 manage.py shell -c "from django.contrib.sessions.models import Session; Session.objects.all().delete()"`); everyone signs in again. OTP is per user: a user without a confirmed device signs in with the password alone.
The application log now rotates (10 MB × 5 files) and defaults to `data/webvirtcloud.log` (override with the `WEBVIRTCLOUD_LOG_FILE` env var). Existing installs: copy the `LOGGING` `default` handler from `webvirtcloud/settings.py.template` into your `webvirtcloud/settings.py` (it adds `maxBytes`, `backupCount`, and an absolute `filename`); the old unbounded `webvirtcloud.log` in the app directory can be removed.
Migration: where the hosts cannot resolve each other's host names, set each compute's **Migration address** (the compute's edit page) to the IP the other hosts reach it on for migrations. Define shared storage as a storage pool on every host: a VM migrates only when its disk, backing and ISO files and block devices are volumes of the destination's pools (network disks are not checked). The "VM Clone Auto Migrate" setting is removed (migration `appsettings.0015`); a clone stays on the host of the VM it was made from.
Migration `accounts.0007` transfers the first-login requirement from any existing

View file

@ -178,6 +178,12 @@ LOCALE_PATHS = [
"locale/",
]
# Resolve the application log path and make sure its directory exists, so a
# clean checkout, CI, or a Docker build (none of which create data/) does not
# fail when logging is configured.
WEBVIRTCLOUD_LOG_FILE = os.getenv("WEBVIRTCLOUD_LOG_FILE", str(BASE_DIR / "data" / "webvirtcloud.log"))
os.makedirs(os.path.dirname(WEBVIRTCLOUD_LOG_FILE), exist_ok=True)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
@ -192,10 +198,12 @@ LOGGING = {
'class': 'django.utils.log.AdminEmailHandler'
},
'default': {
'level':'INFO',
'class':'logging.handlers.RotatingFileHandler',
'filename': 'webvirtcloud.log',
'formatter':'standard',
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': WEBVIRTCLOUD_LOG_FILE,
'maxBytes': 10 * 1024 * 1024,
'backupCount': 5,
'formatter': 'standard',
},
},
'loggers': {

View file

@ -0,0 +1,40 @@
"""The app log is bounded (rotates) and written to a deterministic absolute
path, not the process working directory."""
import os
from django.conf import settings
from django.test import TestCase
class LoggingConfigTestCase(TestCase):
def test_default_handler_rotates(self):
handler = settings.LOGGING["handlers"]["default"]
self.assertEqual(handler["class"], "logging.handlers.RotatingFileHandler")
self.assertGreater(handler["maxBytes"], 0)
self.assertGreater(handler["backupCount"], 0)
def test_log_path_is_absolute_and_not_cwd(self):
handler = settings.LOGGING["handlers"]["default"]
self.assertTrue(os.path.isabs(handler["filename"]), handler["filename"])
def test_missing_log_directory_is_created_on_settings_import(self):
# A clean checkout / CI / Docker build may not have the log's parent dir;
# importing settings (logging config) must create it, not crash.
import subprocess
import sys
import tempfile
tmp = tempfile.mkdtemp()
log = os.path.join(tmp, "nested", "wvc.log")
env = {
**os.environ,
"WEBVIRTCLOUD_LOG_FILE": log,
"DJANGO_SETTINGS_MODULE": "webvirtcloud.settings",
}
result = subprocess.run(
[sys.executable, "-c", "import django; django.setup()"],
env=env, capture_output=True, text=True,
)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertTrue(os.path.isdir(os.path.dirname(log)), log)