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

70 commits

Author SHA1 Message Date
catborise
ee6b8d3e10 test: no seeded admin password, settings changed only for a test, no local libvirt by default
- create_admin had a branch for `"test" in sys.argv` that gave the admin
  the password "admin"; 17 places signed in with it, and failed silently
  with ADMIN_PASSWORD set in the environment. The tests now make their
  own superuser and force_login it, and the shipped code has no test
  branch: the test runner gives migrate a password (also when
  ADMIN_PASSWORD is set but empty), so no data/admin_password is written
  into the checkout.
- AccountsTestCase builds its rows in setUpTestData instead of
  setUpClass and deleting them by hand.
- accounts tests set OTP_ENABLED with override_settings instead of
  assigning settings (one assignment was never undone, so later tests in
  the process ran with OTP on), and undo their app_settings change. The
  OTP login class reloads the URLs again only after the setting is off.
- computes/tests/test_views.py reached the machine's own libvirt
  (localhost over the socket) when TEST_LIBVIRT_HOST was unset; its live
  tests now run only with TEST_LIBVIRT_HOST, like the other live tests,
  as the README says.
2026-11-06 13:48:03 +03:00
catborise
a4ea23004f chore(appsettings): one squashed migration for a new database
0001_initial to 0024_log_retention_setting are mostly RunPython steps
that added, renamed, re-chose and described setting rows since 2020. A
squashed migration now creates the table in its final shape and inserts
the 38 rows those steps leave; it replaces all 24, so a new database
runs it alone. The 24 stay beside it, as Django's squashing expects
until every installation has applied them: a database that applied
them all records the squashed one without running anything, and one
that stopped between them (an older release, or an upstream
installation) applies the rest of them first.

Checked:
- on a new database its rows equal the old chain's (name, key, value,
  choices, description of every row);
- on a copy of a running panel's database (all 24 applied) migrate
  plans nothing for appsettings;
- a database migrated by the old code to 0023 applies 0024 and then
  records the squashed migration, with the same 38 rows;
- makemigrations finds no change.

It inserts its rows on the database being migrated, as the replaced steps
do. The tests of the replaced steps stay, since an installation that stopped
between them still runs them; the two that checked a few rows' columns
became one that checks every row's columns and description, and a value is
one of its choices.
2026-11-06 13:47:23 +03:00
catborise
482f5bc16d fix(backup): TLS client certificates persist in Docker and are backed up
libvirt reads a TLS compute's client certificate from the panel user's
~/.pki/libvirt. In Docker that was /var/www/.pki inside the container,
so `docker compose up -d --build` dropped it and every TLS compute
stopped connecting; no backup held it on either install type, although
"Moving to a new machine" says the backup carries what the computes
accept, and the README never said where the certificates go.

Docker keeps /var/www/.pki in a webvirtcloud-pki volume, owned by
www-data and private like ~/.ssh; the backup copies ~/.pki into pki/;
the moving steps put it back; and "Adding a Compute Node" says where the
files go.
2026-11-06 09:12:34 +03:00
catborise
b2deb042e8 feat(operations): the Logs page's rows and expired sessions are removed
Nothing removed the Logs page's rows, which every action and every
failed login adds, or the database sessions past their expiry. The job
worker's housekeeping now deletes the rows older than Log Retention
Days, a new setting under Lists and pages (1-3650, 365 by default), and
the expired sessions.
2026-11-05 10:36:34 +03:00
catborise
777057cb19 feat(appsettings): the panel backs itself up every day
The only backups of the panel were the ones taken by hand before an
update. Now `manage.py backup` writes a new directory under backups/
with a consistent copy of the sqlite database (the backup API, while
the panel runs, checked with PRAGMA integrity_check), the secret key,
the worker's node_id, settings.py, the SSH keys of the panel's user
and, outside Docker, the commit. It keeps the newest 7 (--keep N) and
deletes older ones only after a good backup; a failed one leaves
nothing, and a second run while one runs fails. Files are mode 600,
directories 700: the database holds compute passwords and keys. With
PostgreSQL the database is left out.

It runs daily at 03:15: in Docker from the image's cron into a new
volume, webvirtcloud-backups; otherwise from webvirt-backup.timer,
which the installer and the manual steps install. A backup has the
layout of the update backups, so the restore steps take either.
2026-11-03 09:40:47 +03:00
catborise
9d57adc097 fix(locale): the VM page's and Settings page's messages show translated
The VM page's and the Settings page's views marked their messages with
gettext_noop, so every message they gave (a refused resize, a saved
setting, a QoS change, a busy VM) showed in English whatever the
language, though the catalogs translate them. They translate in the
request's language now; their module-level texts lazily. The Settings
page's group titles stay English in the view, as the page links them
by their slugs and translates them itself.

Two values went into translated messages as English codes: a job's
state ("... is running on this resource") and a QoS direction ("Remove
the inbound limit ..."). They are named as the pages name them.
2026-11-02 23:09:05 +03:00
catborise
763f1525ca feat(locale): the panel is translated into Simplified Chinese
The Chinese catalog had not been extracted since 2023: of the panel's
1749 messages, 878 were missing and 455 carried old fuzzy guesses, and
some of those marked done said something else ("Delete API token" read
"Delete SSH key").

Every message is translated again, with one glossary for the panel's
terms, placeholders and markup checked against the English, and the
panel offers Simplified Chinese again. The CI check covers it too.

One message of the VM page (the console password's help) never reached
any catalog: its escaped quotes cut it short at extraction. It is
written with single quotes now, and translated in both catalogs.
2026-11-02 23:03:09 +03:00
catborise
9f2cd664e6 feat(locale): the panel offers only the languages it is translated into
The language choice on the Settings page listed every language Django
knows, 99 of them. Six catalogs (Czech under the wrong code, German,
Spanish, French, Russian, Ukrainian) translated none of the panel's
messages, so choosing one of them, like most of the others, showed
English. The Turkish catalog lacked the four newest messages.

The panel now offers English and Turkish (LANGUAGES). The empty
catalogs and the English one, which has nothing to translate, are
removed. Turkish translates every message again. CI checks that the
offered catalogs translate every message and that their compiled
files are up to date; the README says how to update them.
2026-11-02 22:51:11 +03:00
catborise
9521c79733 feat(locale): the Turkish catalog covers the whole panel
The Turkish catalog had not been extracted since 2024: of the panel's
1727 messages, 817 were missing and 489 carried old fuzzy guesses, so
most pages, dialogs and messages showed in English, and some fuzzy
guesses said something else.

The catalog is extracted again (obsolete entries dropped) and every
message is translated, the earlier terms kept (Sanal Makine, Sunucu,
Depolama havuzu, Birim, Anlık görüntü), placeholders and markup checked
against the English. The Settings page's names and descriptions come
from the database through migrations that did not mark them for
translation; they are marked now (gettext_noop, the stored values
unchanged), so they are in the catalog too.
2026-10-31 21:56:24 +03:00
catborise
c0978419f2 feat(appsettings): the settings page with a group index, two columns and switches
The Settings page was one tall column of cards, a label column beside
every field and True/False chosen from a select. Now an index of the
groups stays beside the cards on a wide screen and wraps above them on
a phone; each group lays its fields out in two columns with the label
above; a True/False setting is a switch; each Save names its group.

A switch posts nothing when off, so a hidden False of the same name
comes first and a checked switch's True, posted last, wins: the view
and its was-KEY check stay as they are.
2026-10-31 18:10:05 +03:00
catborise
935a0e9bdc feat(instances): the top of a VM's page in one card
The top of a VM's page was one line of values between pipes, an icon for
the guest agent and a hidden snapshot count, then a row of big action
icons; the host links sat in a bar fixed to the bottom of the window,
over the content.

One card now holds it all (design chosen by the owner from four):
- the name with the state badge, the title under it, and where the VM
  is: its host and the host's VM list for administrators, the VM list
  for owners;
- OS details (with a connected guest agent) and Refresh;
- the guest agent's state in words and the snapshot count;
- CPU, memory, each disk with its device name and size, and the IPv4
  addresses, labelled;
- the page's sections as small labelled pills in the card's footer: one
  row from 992 px, wrapping below.

The page has no other heading: base.html's heading area is a block it
leaves out.

Each section below it (Power, Access, Resize, Snapshot, Settings, Stats,
Destroy) is a card of the same kind, so the page reads as one design
(owner's choice of two): its sub-tabs as a small underlined nav in the
card's header, its panes in the card's body without their own borders.
Buttons are of normal size in the theme's primary colour, and those that
cannot be undone (Power Cycle, Force Off, Destroy) in the danger colour.
The Stats charts lose their coloured borders. instance_tabs.js finds the
Settings tabs by their tablist role.

The bottom bar and its setting (VIEW_INSTANCE_DETAIL_BOTTOM_BAR) are
removed, and with it the CSS that kept the old Settings tabs on one line.
2026-10-29 22:46:24 +03:00
catborise
2e1f29961c fix(instances): a new VM's CPU is a mode or a model the host offers, checked by libvirt
- A named CPU model is written without check='none' and with
  fallback='forbid': libvirt checks before the start that the host runs
  it, and it is not swapped for another model.
- Mode maximum is written as that mode; it was written as a model named
  maximum.
- Model names up to 64 characters: the -noTSX and -IBRS models, the ones a
  mixed set of hosts needs, were refused at 20.
- The mode or model is checked against the host's capabilities when the VM
  is defined, from the page and the API alike; no CPU element (QEMU's
  oldest default CPU) is no longer offered.
- The default CPU mode setting offers the modes the new VM dialog has;
  no-model and custom, which matched none of them, become host-model.
2026-10-29 11:17:38 +03:00
catborise
5d8b7e3f61 fix(appsettings): a group saves what was edited, all of it or none, in one row
- A group sent all its fields, and the ones left as they were undid
  what another administrator had saved meanwhile. Each field now sends
  the value the page showed, and only a field edited since is saved.
- A database error partway left the group half saved. The group is now
  saved in one transaction, written as one audit row: "Settings: change
  Console Scale to True, Console Clip Viewport to True".
2026-10-26 10:12:53 +03:00
catborise
07a2e09c2f docs(appsettings): each setting's description says what it does
The descriptions were tooltips, many only repeating the setting's name
("Cpu modes", "Debug for user quotas"). Now shown under each field, they
say what the setting changes: what a new VM or disk gets, how the
console starts, what a page shows. A migration writes them.
2026-10-25 22:02:53 +03:00
catborise
632f5e15bd feat(appsettings): the Settings page groups its settings and saves a group at once
The page listed 37 settings by name, each its own form saved as soon as
its list or field changed, with the description only in a tooltip. It
now shows them in groups (New VM defaults, Disks, Clones, Console, VM
access and owners, Snapshots and jobs, Login, Lists and pages) with each
description under its field and the label tied to it. A group's Save
button saves its changed settings, or none when one is refused, and
says which were saved; number settings are number fields with their
range. Language and theme are under Appearance with their own buttons.
A setting in no group shows under Other.
2026-10-25 22:02:53 +03:00
catborise
7392a5b4d2 fix(appsettings): settings take only the values the panel can use
The Settings page saved whatever was posted, and some lists offered
values the panel cannot use:

- Quota Debug could not be turned off: "False" is a non-empty text and
  counted as on.
- VM Clone Name Prefix showed as a True/False list, so no prefix could
  be typed, and touching it set the prefix to True.
- Disk SCSI Controller listed " lsilogic" with a space, never shown as
  chosen, and virtio-blk, which is no SCSI controller.
- VM Machine Type listed x86_64, an architecture; VM CD-ROM Device
  listed virtio, a bus a CD-ROM cannot use.
- Logs per Page and Disk Owner UID/GID are read with int(): a letter
  broke the logs page and VM create.

A migration fixes the lists and moves a value they no longer offer to
the default (the clone prefix keeps its text). A listed setting now
takes one of its choices, and every number setting a whole number in
its range, checked before it is saved.
2026-10-25 22:02:53 +03:00
catborise
e04adec87b feat(logs): changes to users, groups, owners, flavors and settings are logged
The Logs page now records the panel's own records too: users (add,
change with the changed fields, delete, block, unblock, an admin's
password set, a user's own password change including the first-login
one, own profile edits), groups with their members and permissions,
VM owners from the accounts pages and from the VM page, OTP QR code
mails, flavors from web and API, app settings and the theme,
removed-VM records and SSH keys. No row carries a password or a key.

- A user is created in one transaction: when a VM named in
  NEW_USER_DEFAULT_INSTANCES is missing, no half-made user stays.
- The OTP mail checks the email address before it creates a device;
  without one it writes a failed row and makes no device.
- The VM page's owner rows read "VM web-1 owner bob: add" and
  "...: remove" instead of "Add owner: bob" and "Delete owner: 17"; a
  second owner refused by the single-owner setting is a failed row.
  Owner rows keep the VM's host and name, so the VM's log tab shows
  them.
- A setting or theme posted with its current value is no change and
  writes no row; the old free-text setting rows are gone.

Host-side objects (networks, storage, interfaces, secrets, filters)
follow in the next layer.
2026-10-23 11:10:24 +03:00
catborise
64057f8d05 fix(templates): icon-only buttons, selects and delete pages have accessible names
An accessibility scan (axe-core, WCAG 2 A/AA) of every page found 87
elements without a name. Icon-only buttons and links (the navbar's
administration menu on every page, the add/create buttons, the flavor
delete and back buttons) get a title, which is also their tooltip; the
labels of the language, architecture, chipset and filter selects point
at them; the memory bar is named. The shared delete confirmation page
had an empty <title> and heading, as no view passes "title": it says
"Delete <object>". The power-off form's aria-label was misspelled.
2026-10-19 16:15:06 +03:00
catborise
41468c700d build: the themes ship compiled, libsass is no longer installed
A theme change compiled Bootswatch with libsass (34 MB, upstream
deprecated) into two tracked files, which updates, rollbacks and new
Docker containers then reset. The 27 themes now ship as
static/css/themes/<theme>.min.css, built by "manage.py build_themes";
the Settings page only saves the theme name and every page links that
file (zephyr when no settings are in context, as on the 500 page).

libsass moves to dev/requirements.txt; a test checks that each shipped
file is its theme compiled from dev/scss. The "Theme SASS Path" setting
is removed, and the theme default "flaty", a typo that never applied,
becomes zephyr, the theme those installs showed. The update and
rollback steps restore an older version's rewritten theme files only
where they are modified.
2026-10-18 22:36:29 +03:00
catborise
34582d23f3 feat(operations): worker concurrency and job retention settings 2026-10-14 23:27:57 +03:00
catborise
5f8f7a8643 fix(instances): a snapshot needs free space in the VM's storage pools
A disk-only snapshot was taken without any space check, though its
overlays grow as the guest writes and a later delete merges them down;
a full pool pauses the guest and can leave the snapshot undeletable.
Only a memory snapshot was checked, for the memory alone.

Before a snapshot, each storage pool with a disk of the VM must have
free a share of those disks' virtual size (10%, at least 1 GiB), and
the pool of the memory file the VM's memory on top. Both values are on
the Settings page (Snapshot Free Percent, Snapshot Free Min GiB; 0
turns a rule off, an invalid value keeps the default). The pools are
refreshed first, and a failed refresh or an unreadable volume refuses
the snapshot instead of skipping the check; a disk in no pool is not
checked. Nothing is reserved: later writes can still fill a pool.
2026-10-13 13:27:39 +03:00
catborise
c55f52f025 test: each app keeps its tests in a tests package
131 test modules sat next to the code they test; instances alone had
51 of them beside views.py and utils.py. They move into a
tests/ package per app, and the JavaScript checks into
webvirtcloud/tests/js. Each non-empty tests.py becomes tests/test_views.py;
the empty generated stubs are removed.

Imports of the app's own modules become absolute, paths built from
__file__ go one level up, the live helper is instances.tests.livetest,
and coverage omits */tests/*. The suite discovers the same 960 tests as
before.
2026-10-12 15:17:30 +03:00
catborise
d4f04cbf1e build(deps): Bootstrap and Bootswatch 5.3.8
Bootstrap SCSS, the JS bundle and the Bootswatch themes go from 5.3.3 to
5.3.8 (bug fixes only), and wvc-main.min.css is recompiled from zephyr.
Bootswatch now gives table text the body color, and Lux drops card and
modal header borders.

Tests compile every theme with the pinned libsass and check that the
shipped CSS is zephyr from these sources. The update and rollback steps
put back the two files a theme change rewrites, or git refuses to pull
over them.
2026-10-12 08:44:31 +03:00
catborise
c23521bcf4 fix(appsettings): a theme change reaches the CSS nginx serves
nginx serves STATIC_ROOT (staticfiles/) since collectstatic moved there,
but the theme view wrote only static/css/wvc-main.min.css, so a new theme
showed up only after the next collectstatic. The view now also writes the
collected copy when collectstatic has run; the source copy stays so a
later collectstatic keeps the theme.
2026-10-12 08:36:43 +03:00
catborise
11fe2409f9 fix(instances): device edits fit every definition and device type
A volume of an LVM or iSCSI pool can be attached: by its own path, with
the format its volume reports (raw when the pool knows none). Detaching
a disk takes each definition's own description of it, so a disk only in
the persistent definition goes too. Every NIC type can be a boot device;
bridge and direct NICs were dropped from the boot order. The video model
is a value, never parsed as XML. QoS changes clear the page's read cache.

The NIC model "default" leaves the choice to libvirt instead of writing
model "default", and rt18139 is rtl8139: a VM with either did not start
(checked on a RHEL 10 host). A migration corrects the default NIC type
setting.
2026-10-09 18:13:23 +03:00
catborise
f889861e18 fix(migrations): a fresh PostgreSQL database migrates, and CI tests it
The first appsettings migrations insert the default rows with fixed ids,
which a PostgreSQL id sequence does not see; the login lockout migration,
the first to insert without an id, then collided with id 1. It now moves
the sequence past the existing rows first (a no-op on sqlite), which also
covers a database upgraded from any earlier migration. A test compute
password exceeded its 14-character column, which only PostgreSQL enforces.
2026-10-07 16:31:56 +03:00
catborise
e84db7542d fix(appsettings,vrtManager,storages): error handlers that hid the real failure
Reviewing the error handlers outside instances/ turned up three that masked or
swallowed the failure they caught:

- appsettings/settings.get_settings() runs on every request (middleware) and
  loads app_settings from the database. Its bare `except: pass` left `entries`
  unbound on a database error, so the next line raised UnboundLocalError
  instead; it also caught KeyboardInterrupt/SystemExit. It now catches
  DatabaseError and returns, keeping the already-loaded values.
- vrtManager.network.refresh_dhcp_leases raised a formatted string
  (`raise f"..."`), which Python rejects with TypeError, hiding the real
  DHCPLeases failure. It now raises util.OperationError, which the API/HTML
  error handling already renders as a libvirt error, and clears self.leases.
- storages.views.get_volumes caught libvirtError and answered 200 with an empty
  body, so the caller could not tell a failed pool read from an empty pool. It
  now returns 400 with the error.

The other broad handlers reviewed (appsettings/nwfilters/virtsecrets views,
storages/upload cleanup and recovery paths, vrtManager display getters) report
the error or are best-effort and were left as they are.

Tests: get_settings() survives a database error during the query and during
iteration without raising and still loads a real value; refresh_dhcp_leases
raises OperationError (keeping the cause) not TypeError; get_volumes returns 400
on a listing failure and the sorted volumes on success. The tests fail on the
previous code.
2026-10-07 11:29:45 +03:00
catborise
1016f745c2 fix(instances): a clone stays on the host of the VM it was made from
With "VM Clone Auto Migrate" on, a new clone was migrated to a random
compute, whatever storage, CPU or network that host had, and a failed
migration showed as a failed clone although the clone existed.

The setting and its code are removed; migration appsettings.0015
deletes the setting. A clone can be migrated afterwards like any VM.
The README's update notes list the migration changes: the migration
address, storage pools for the disk check, and this setting.
2026-10-06 15:58:35 +03:00
catborise
c2fea2aa39 feat(accounts): failed logins lock a user for the address they come from
Nothing limited failed logins: a password could be guessed at the speed
the server answers. django-axes (8.3.1, Django 5.2, Python 3.10-3.13)
now counts them.

- A user is locked for the address the failed logins come from
  (username and IP together), so an attacker cannot lock someone out
  from elsewhere and users behind one NAT address do not share a lock.
  A successful login resets the count. axes sits in front of every
  authentication: the login page with or without OTP, LDAP and the API.
- The number of failed logins (default 5) and the lock time in minutes
  (default 15) are on the Settings page (LOGIN_FAILURE_LIMIT,
  LOGIN_LOCKOUT_MINUTES, added by migration appsettings.0014) and apply
  at once; an invalid value falls back to the default. Unlock with
  "manage.py axes_reset_username <username>".
- Behind the bundled nginx every request comes from 127.0.0.1; the
  client address is read from X-Real-IP, which nginx sets, but only for
  requests from a loopback address or from LOGIN_TRUSTED_PROXIES, so a
  forged header does not escape a lock.

settings.py.template gets the app, middleware, backend and AXES_*
settings; README tells existing installations what to copy. Tests that
call client.login now pass a request, which the axes backend needs.
The new tests fail with axes disabled.
2026-10-06 11:05:03 +03:00
catborise
b0df124601 fix(appsettings): SASS_DIR must be a directory inside the project
The settings page lists the themes of SASS_DIR and writes wvc-main.scss
into it when the theme changes; the value could be any path, so a
superuser could make the app list and write files anywhere it may
(CodeQL py/path-injection).

SASS_DIR is now accepted only if it resolves to an existing directory
inside the project (the default is dev/scss). A stored value outside it
is not used: the page shows an error and offers no themes, so nothing
is written. Installations that keep their SCSS outside the project
need to move it under it.

The tests fail on the previous code for an absolute path, "../",
a path climbing out and a missing directory, and for a stored value
outside the project.
2026-10-06 08:48:51 +03:00
catborise
d816d8d09f fix(appsettings): the theme must be one of the themes in SASS_DIR
The settings page took the posted theme name as it came and wrote it
into the @import lines of wvc-main.scss and the compiled CSS: a name
with "../" or a quote imported files outside the themes directory
(CodeQL py/path-injection; the page is for superusers).

The name must now be one of the directories in SASS_DIR/wvc-themes, the
list the page already offers; anything else is refused with a message
and nothing is written. themes_list is empty when SASS_DIR has no
themes, so every name is refused then.

Checked with the real dev/scss: flatly is applied and compiled as
before, "../../etc" is refused and leaves the CSS alone. The test fails
on the previous code.
2026-10-06 08:02:05 +03:00
catborise
e5fda79f5a feat(console): VNC is the only console type
SPICE was removed earlier; its leftovers and the console type choice go
too:
- the console settings form, update_console and the backend no longer
  offer or change the type; an invalid console form now shows its
  errors instead of being ignored;
- the create form, the API serializer and create_instance no longer take
  a graphics type, new VMs get VNC; get_graphics_types and the graphics
  entries of the domain capabilities are gone;
- migration appsettings.0013 deletes QEMU_CONSOLE_DEFAULT_TYPE;
- a VM defined elsewhere with another graphics type gets "Console type
  ... is not supported".

The locale catalogs still reference the deleted SPICE templates in
source comments; regenerating them is left to the translation work.
2026-10-04 01:08:11 +03:00
catborise
b04f656d2b ci: replace super-linter with ruff
Super-linter ran from the unpinned :latest image and, because of
branches-ignore: [master], never on pull requests to master. Ruff now
checks syntax errors and pyflakes rules (E9, F) on every push and PR.

Fixes the existing findings: unused imports and variables, an unused
duplicate import in instances/tests.py, and the star import in
accounts/views.py. settings-dev.py keeps its star import of the base
settings.
2026-10-04 01:08:11 +03:00
catborise
fd5aa069be fix: track migrations; installs apply them instead of generating them
The *migrations/* ignore rule is removed. appsettings, computes and
logs pin default_auto_field to AutoField, so makemigrations --check
reports no pending BigAutoField migrations and existing installs need
no schema change.

The Vagrant provisioning no longer runs makemigrations, which created
install-specific migration files that conflict with the committed
history; it only runs migrate.
2026-10-04 01:08:11 +03:00
catborise
1227674d8f feat(security): implement P0 critical security fixes for API, console, and access control
- Computes API: mark password as write_only in ComputeSerializer, restrict ComputeViewSet and architectures to IsAdminUser.
- Instances API: enforce user ownership tenant isolation in InstanceViewSet.list, restrict MigrateViewSet and CreateInstanceViewSet to IsAdminUser, require IsAdminUser for mutating FlavorViewSet.
- Storage, Network, and Interface APIs: restrict StorageViewSet, VolumeViewSet, NetworkViewSet, InterfaceViewSet to IsAdminUser.
- AppSettings & NWFilters: protect appsettings and nwfilter views with @superuser_only (403 Forbidden for non-superusers).
- noVNC Console: sign tokens with TimestampSigner (salt='console.novnc', max_age=600), verify signature and user authorization in novncd with backward-compatible fallback for debug/test mode.
- Accounts: avoid hardcoded default admin password; generate cryptographically secure random password unless ADMIN_PASSWORD is set (preserve 'admin' in test runner).
- gstfsd daemon: bind to 127.0.0.1 by default instead of 0.0.0.0.
- Tests: added comprehensive test coverage for API security, token expiration/rejection, and view permissions (132 tests passing).
2026-09-27 10:50:09 +03:00
catborise
e980aca2ff feat(console): remove deprecated SPICE support in favor of noVNC
- Remove obsolete spice-html5 static assets and SPICE console templates
- Restrict default console types to VNC with migration 0012
- Filter out SPICE in VM creation form and backend capabilities
- Return friendly deprecation notice if legacy VM is opened with SPICE
- Clean up docs, architecture references, and libvirt-bootstrap scripts
2026-09-26 22:43:40 +03:00
catborise
c31ed28042 test: expand unit test coverage across admin, accounts, vrtManager, logs, appsettings, and datasource 2026-09-25 11:26:53 +03:00
catborise
765b759953 if nic type is default then make it virtio 2024-02-28 08:16:44 +03:00
MisterBlueBear
7e8c05fff9 Global setting for NIC type 2023-11-01 18:08:38 -04:00
cserma
3403d21fea log i18n fixes 2023-05-10 13:57:01 +03:00
catborise
e3fb820b50 update bootstrap&bootswatch 5.0.2 -> 5.2.2. Seperate bootswatch overrides for future update easiness 2023-01-23 08:25:44 +03:00
catborise
217e106c8b format python code with black 2022-11-02 08:54:35 +03:00
catborise
5f5bd379af make adding cd-rom optional while vm creating. Add default value for cd-rom bus 2022-09-07 13:46:50 +03:00
catborise
ea6524f79e add more default machine type and instance type 2022-09-05 15:39:41 +03:00
catborise
c804b2cde8 fix identation 2022-09-05 15:38:00 +03:00
Info-IIG
22ac6f1c60 Fix dependencies reference nonexistent in appsettings migrations 2022-06-30 09:48:47 +02:00
Info-IIG
421f17d5ca Added VM DRBD Status to appsettings 2022-06-29 15:08:07 +02:00
catborise
073b7b6717
Bootstrap5 (#17)
* Bootstrap5 migration
2021-07-07 14:12:38 +03:00
catborise
610efd5520 add host name for logs beside others 2021-05-31 11:39:09 +03:00
catborise
508e3609be lint with black python. convert f style strings to old one. some small fixes 2020-11-05 12:34:31 +03:00