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:
parent
bbb9f77cb1
commit
7405217466
3 changed files with 54 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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': {
|
||||
|
|
|
|||
40
webvirtcloud/test_logging.py
Normal file
40
webvirtcloud/test_logging.py
Normal 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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue