consolecallback read the VM's record with .get(): one deleted between
socketiod's accept and the worker's start ended with a Python traceback
in the user's terminal, which is the worker's stderr. It now says the VM
is no longer in the panel.
websockify's socket() connects without a timeout, so a console address
that does not answer held the console's process for the OS's TCP timeout
(some 2 minutes) before the page heard of it. novncd now connects with
CONNECT_TIMEOUT, then waits on the open connection as before.
The VNC page's token travels in the websocket URL, so nginx's access log
and anyone who saw the URL had it for 120 s, and it opened the console as
a bearer token. novncd now also wants the session cookie of the token's
user. Its refusals were a warning without a user or an address: they now
name the client address (nginx sends X-Real-IP to novncd too) and leave
a Logs row "VNC console refused: reason".
The token now names the console type it was made for: novncd accepts only
a VNC page's token and socketiod only a serial page's, so a VNC page's
token no longer opens the serial console without the VNC password.
A VNC session re-checks every 10 s, as the serial one did, that its user
may still open the console; a deactivated user or a removed owner loses
it. The check (may_still_open) moves to console.tokens for both daemons.
nginx ends a proxied websocket that sends nothing for 60 seconds, and the
VNC console sends nothing while the VM's screen stays the same: an idle
console, an installer's progress screen, closed after a minute and had to
be connected again. novncd now pings the browser every 30 seconds. The SSH
tunnel of an SSH compute sends a keepalive as often, for a firewall on the
way that ends idle connections.
When a VM stopped, its console's stream could end before the worker's
next check saw the VM shut off. The check then found no stream to drop and
said nothing, or, seeing the VM still running, opened the console again,
which libvirt refused, and the session ended. The worker now remembers
whether the VM ran at its last check, and a console that cannot be opened
again because the VM stopped meanwhile is a stop: the terminal says the VM
is not running and the console opens again when it starts. A new stream is
the console's before its callback is registered, which may end it at once.
The live serial test's VM now repeats its BIOS banner (it reboots right
after finding no boot disk), so a console attached late still gets one,
and the test waits for the superuser's console to show it before the VM
stops. A run of the whole live suite over the socket missed the banner of
the paused-then-resumed VM before.
The console pages carried style blocks for what Bootstrap 5.3 has:
- the page's column (flex, no padding, a #494949 background) is
d-flex flex-column p-0 bg-dark; its height stays 100dvh inline, as
vh-100 would run under a phone browser's bar;
- the VNC screen and the serial terminal fill the rest with
flex-grow-1, the screen overflow-hidden, the terminal bg-black; their
min-height: 0 stays inline (Bootstrap has no class for it);
- the rule centring the VNC canvas goes: noVNC centres its own canvas
and draws its own background.
The unused main_container id goes with its style block.
webvirtcloud.css still carried the upstream panel's rules for what
Bootstrap 5.3 has as utilities and components:
- the page's bottom space (body padding) is pb-5 on base.html's body,
and the console page no longer has to undo it;
- the VM page's action tabs (.action-button, .action-block with a
fixed 65px width) are text-center with a d-block icon; its tab panes
(#power ... #undefine, one rule each) mt-3;
- the bordered sub-tab panes (.tab-pane-bordered, a fixed #eee border
that dark themes could not change) border border-top-0 p-3;
- the search box and header buttons (.search, .btn-header) m-1 and
mt-1; the SSH key select (.keyselect) a form-select;
- the boot order list (.multipleselect, fixed size, #c0c0c0 border) a
list-group of form-check-input items; its unused .multipleselect-on
goes;
- table cells centred by a global rule are align-middle on each table.
Two rules against Bootstrap's behaviour go: menus opened on hover on
wide screens (Bootstrap opens them on a click, and keyboard and touch
users had no hover), and "a { outline: 0 }", which hid the keyboard
focus ring.
The paragraph and page-header margins and the 900px container stay
for a separate change: they set every page's layout.
"Type it" sent each character's keysym and let QEMU pick the key from
its own US map, with Shift added for the US shifted characters. A VM
on another layout got other characters: on Turkish Q, '"' typed 'İ',
'@' typed "'", and ğ, ü, ş, ı, ö, ç typed nothing.
The Clipboard dialog now asks for the VM's keyboard layout and
remembers it per browser. Each character is typed as the key that makes
it on that layout (its scancode), with Shift, AltGr or both (AltGr
first: pressed after Shift, the right Alt is Alt on the Linux console),
so the VM's own layout makes the character. The layout is fixed when
typing starts. Text with a character no key types on the layout is not
typed at all, and the dialog lists those characters: a password or a
command with a character left out would be a wrong one.
A layout is one file in console/layouts/: its name and, for each key,
the characters it types plainly, with Shift, with AltGr and with
Shift+AltGr. The view offers every file, US first. dev/console_layout.py
writes a file from the system's XKB data as libxkbcommon computes it
(through ctypes, no new dependency), mapping keys to DOM codes with
noVNC's table from QEMU's keycodemapdb; it lists the dead keys it leaves
out, and drops the keys the keyboard model lacks (the key left of Z on
US pc104 keyboards). English (US) and Turkish Q come with it; the
README says how to add one.
The serial page had a white strip of inline styles with an untranslated
status and a browser-default button above the terminal, sent input while
disconnected, sized the terminal only on window load and resize, and left
the keyboard elsewhere after the key menu. When a superuser opened a
console open in another window, its user saw "[An administrator opened
this console]" and a plain "disconnected".
- console-xterm.html shares the VNC page's bar: status badge (Connecting,
Connected, Disconnected, the server's refusal), Disconnect, then
Reconnect (a new page for a new token). The script is
static/js/console_serial.js; the token reaches it as json_script data.
- The terminal takes the keyboard on connect and after the key menu; input
is sent only while connected; it fits its box on connect and whenever
the box changes size (ResizeObserver).
- A console that writes nothing yet gets a dim local hint: press Enter.
- socketiod sends the displaced client "taken_over" with the superuser's
username; the page shows "Taken over by <name>" in the bar and the
terminal. The superuser is not asked first (owner's decision).
- Fullscreen uses the shared console_keys.js handler (keyboard lock).
The VM page offered a lite and a full VNC console. Lite lacked a clipboard,
display settings and a way to reconnect; full put noVNC's own side bar under
the panel's bar, with a Fullscreen item that called a function noVNC does
not have, status messages hidden behind the bar, saved noVNC settings that
overrode the Access tab's, connection settings that cannot apply, and a
Connect button that reused the page's two-minute token and failed.
console-vnc.html and static/js/console_vnc.js replace both, on noVNC's RFB
with Bootstrap controls, and keep what the full view did:
- Status in the bar (Connecting, Connected, Disconnected, Connection lost,
Could not connect, Authentication failed with the server's reason on
hover); Disconnect, then Reconnect, which loads the page again for a new
token.
- The VNC password in a dialog (with a username when the server asks for
one), not a browser prompt; without passwordless console it is not in
the page.
- Send key(s) gains Hold Ctrl / Alt / Windows (noVNC's extra keys).
- Clipboard: what the VM copies, sending text to the VM's clipboard, and
typing it key by key (new: works in firmware, installers and login
prompts; Shift for the characters a US keyboard shifts, 25 ms a key as
firmware drops faster keys, verified in a UEFI shell).
- View: scaling (none, fit, resize the VM's screen), clip, drag a clipped
screen, view only, dot cursor, quality, compression; it starts as
Settings > Console says (a touch screen starts fitted).
- A Keyboard item on touch devices (noVNC's on-screen keyboard input,
key events and Android's text-only input), Fullscreen with keyboard
lock, the bell.
Dropped with the full view: noVNC's websocket host/port/path, repeater ID
and log level (the panel fixes them), automatic reconnect (the token is
single use in time), XVP power buttons (QEMU has no XVP) and shared-mode off.
The bar is compact (about 45 px in the 850x600 window). The Access tab has
one Console button instead of the Lite/Full split and four switches, and
it and the VM list open one window per VM (opening it again reloads it).
A stopped VM, an unreachable or unsupported console and a disabled serial
console rendered the lite VNC page under the error: it connected to novncd
anyway, showed "Something went wrong" and offered keys, Scale and Send
CtrlAltDel for a console that was not there. A refused console was a bare
text 403 inside the popup.
- console-error.html: the console shell with the VM's name and the reason,
no menu and no script; a refused or unknown VM gets it with 403 and
without the VM's name, as before for everyone (no superuser exception).
- The view signs the console token only for a page that connects.
- console-menu.html: the Send key(s) menu and Fullscreen, included by the
console pages; the serial page lists only the keys it sends (the VNC
groups did nothing there).
- Every console window is titled "<VM> - Console".
- The lite page no longer takes a VNC password from its link.
- The shell lost its 850px x 600px corner radius (a grey arc on the
serial and error pages) and spans the window (container-fluid).
The page's "listens only on its host" check read the VM's next-start
definition, while novncd connects to the running VM's listener: after a
listen address change on a running VM, the page refused a console novncd
could reach, or let through one it could not. The page now reads the
running VM's listener, as novncd does, with the same loopback test, which
moves to vrtManager.util.
ssh's error output went to a pipe that nobody read while the console ran:
once it filled, ssh stopped and the console froze. It now goes to a
temporary file, read when the tunnel closes. Closing waits five seconds
for ssh to end and then kills it, instead of waiting for ever. The Tunnel
holds the ssh process and its error file together.
- The worker told why a console did not open or closed only in the user's
terminal (as users see errors: a host that cannot be reached is not
named). It now also logs the full reason to socketiod's own stderr, the
journal or docker logs, which socketiod hands it as a descriptor.
- A refused token says the link has expired or the user may no longer
open the console: a valid link for a user who lost access was told only
that it had expired.
- A send that takes nothing (0 bytes) waits like a busy stream instead of
spinning.
- socketiod wrote input to the worker's terminal while holding the
session's lock, and the write could wait for the worker; the output
forwarder needs that lock. A large paste into a guest that echoes it
could stop both for good. The terminal is now non-blocking: input is
written as far as the worker takes it, and the wait for room is outside
the lock.
- The terminal is raw from the start. Until the worker made it raw, it
kept at most one 4 KiB line of a paste, and the worker's own setraw
dropped what was typed meanwhile; the worker no longer sets it.
- A superuser's takeover ends the old worker, and waits for it, before
starting the new one: libvirt gives a VM's console to one at a time.
- A resize while the worker ends no longer raises.
A VM defined with QEMU's own VNC websocket (graphics websocket='...',
which the panel never sets) made the console page connect to that port on
the panel's host name: the port is on the compute, so the console did not
open unless the panel ran on that compute, and then it bypassed novncd and
the panel's console token. Such a VM has its ordinary VNC port too, and
novncd now reaches it there like any other VM.
- novncd and socketiod log to stderr: the journal on hosts, docker logs in
the container (runit no longer sends them to unrotated files under
/var/log). Django's settings gave them the panel's own log file, which
every process rotated on its own, and made novncd's -v and -d have no
effect; both work again.
- A refused console says why in the log: novncd's denials are warnings
(they were shown only with -v), socketiod logs each refusal and who
opened which VM's serial console.
- The README's serial console notes say what #228 changed (access
re-checked, superuser takeover, reasons) and where the logs are.
- The VM's console settings have no "Clear keymap" box: it wrote an empty
keymap attribute into the VM, and choosing Auto already removes the
keymap; that change is logged as "remove console keymap".
- The "Clip viewport" switch was labelled "View Clipboard".
- The full console page no longer fills the password field with "None"
for a VM without a console password.
The lite and the full console page each carried the same 150 lines that
send key combinations (Ctrl+Alt+Del, Ctrl+Alt+F1..F12, Alt+Tab, ...). They
now import static/js/console_keys.js, which binds the menu to the page's
RFB connection.
The console page is /console/<compute>/<uuid>/ with the view and display
options in the query. It was /console/?token=<compute>-<uuid>, a "token"
that was only the VM's address, parsed alongside a signed token that no
link ever sent. The list's console button takes the VM's UUID from the
database instead of asking libvirt for each row, and no longer defines a
global function per row.
- The fallbacks for websockify releases without ProxyRequestHandler and
for noVNC's old wsproxy are gone (websockify 0.13 is pinned), with the
Nova names, the per-connection mode switch and the traffic legend.
- The certificate option is gone: nginx ends TLS and novncd speaks plain
websockets on the loopback.
- The mixin is ConsoleClient and the handler ConsoleProxyHandler; the
CLI test that tested a copy of the parser instead of novncd's is
removed (novncd's own parser is tested).
- A console listening on a given address is reached on that address;
the compute's host name is used only for a wildcard listener (0.0.0.0,
::, none). It was always the host name, which may resolve to another
interface.
- ::1 and localhost count as loopback like 127.0.0.0/8: such a console
on a TCP or TLS host is refused instead of being tried on the host's
name.
- The console page says why such a console cannot open and what to change
(listen on all interfaces, or add the host over SSH) instead of a
generic connection error.
The console pages connect to /novncd/ on the address, scheme and port the
page itself was loaded from; nginx proxies it to novncd, which listens on
the loopback only. There is nothing to configure: the console works on
HTTPS (wss), behind another proxy and on any published port.
Before, the page connected to WS_PUBLIC_HOST/PORT/PATH, port 6080 by
default: straight to novncd, past nginx and without TLS, so an HTTPS panel
and a Docker container published on another port had no console until the
public port was set by hand, and novncd listened on every interface.
Gone: WS_PUBLIC_PORT, WS_PUBLIC_HOST, WS_PUBLIC_PATH and WS_CERT, the
installer's two public console questions and its 6080 firewall rule, the
Docker image's WS_PUBLIC_PORT and its init script lines, the manual
install's firewall rule for 6080 and nginx's unused /websockify location.
WS_HOST defaults to 127.0.0.1. A VM with a QEMU websocket port is still
reached on that port of the panel's host name (left for a separate
decision).
- The console worker learns whose session it is and checks every ten
seconds that the user may still open the console: an owner removed or a
user deactivated meanwhile loses it, with a line in the terminal. Access
was checked only when the session started, which could last for days.
- One console per VM: a console left open in a forgotten tab locked
everyone out, superusers included. A superuser's connection now takes
the console over, and the other window is told so.
- A paste reaches the VM whole: the non-blocking console stream takes it
in parts, or none while the VM is busy, and the rest was dropped. The
worker sends the rest until the VM has it, for at most five seconds.
- A libvirt error while the console is open (the host gone, the VM
undefined or migrated) ends the session with one line in the terminal
instead of a Python traceback; libvirt no longer prints its errors on
the terminal. Errors are shown as users see them elsewhere: a host that
cannot be reached is not named.
- The terminal says when the VM is not running and its console will open
when it starts. The terminal is raw before the console opens, and the
stream is dropped once when both threads see the VM stop.
- socketiod's handlers run on their own threads. A connection is now
admitted under a lock, so two at once can no longer both open a VM's
console or pass the session cap. A session's terminal is used and closed
only under its own lock while it is open: a closed descriptor's number,
taken again by a new session, never receives another session's input
or gives it the other's output.
- A refused connection says why: serial console off, the link expired,
the VM's console open in another window, too many consoles. The page
shows it instead of "refused".
- The page no longer retries on its own with a token that has expired
after two minutes; Reconnect loads a new page. Input the browser cannot
encode no longer raises in the daemon.
- The tunnel is `ssh -W` to the console's address or Unix socket: the
compute needs no nc and runs no shell. The old tunnel, copied from
virt-manager, built a shell script with the console's address and socket
path in it and eval'd it on the compute, and always passed "-p 22",
overriding a Port in the SSH configuration.
- On an SSH compute the console always goes through the tunnel, also when
it listens on a network address: it was sent there unencrypted.
- ssh never prompts (BatchMode) and gives up connecting after 10 seconds;
when it fails, what it said is logged. The tunnel ends with the session.
pty.fork returns an inheritable master descriptor, so each new console
worker, and the ssh it may start, held the terminals of every other open
session until it ended. A worker now closes every descriptor above its own
terminal before it starts.
- novncd takes the console token only from its websocket URL. The page
also put the token in a cookie, one for the whole browser, and novncd
preferred the cookie: with two consoles open, a tab that (re)connected
after another console was opened got that other VM.
- novncd opens the VM by its UUID, the VM the access check was made for,
not by its name, which another VM on the host may carry now.
- The lite VNC page took the proxy's host, port and path from its link. A
link naming another host made the page send that host a fresh signed
console token, which opened the VM's console for two minutes. The page
now uses only what the server gives it, like the full page.
- On a local-socket host, a VM whose console listens on 127.0.0.1 is
reached directly instead of being refused for want of an SSH tunnel.
- A shut-off VM's console says that the VM is not running instead of
failing with no reason.
Only an administrator chose whether the VNC console fits the remote
screen to the window (Settings, or ?scale= in the URL). A Scale switch
in the console menu now flips between fitted and 1:1 with scrollbars,
starting from that setting. On a phone, where noVNC takes the touch
screen as the mouse and the 1:1 view cannot be scrolled, it is the way
to see the whole screen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A user with the permission (and a superuser, who holds every permission)
gets the console password filled in, so noVNC does not ask for it; a
user without it must be asked, and the page must not hold the password.
The test covers both console views for an owner without and with the
permission and for a superuser.
A script built the console page's error alert as HTML text, with a broken
class attribute (role="alert" ended up in it), a close button without a
handler on a danger alert that never fades, and placed it above the
viewport-high console container, cutting off its bottom. The template now
renders the message (autoescaped) as a dismissible Bootstrap alert inside
the container, under the navbar; the log_* functions had no other caller.
console-base.html had no doctype, so the noVNC and serial console pages
rendered in quirks mode, where body and #main_container got their height
from the viewport. The console area overflowed the window: the full noVNC
page scrolled by the navbar height, the lite page's canvas and the serial
terminal ran below the bottom edge, hiding the last rows.
With the doctype, #main_container is a viewport-high flex column and the
console area (the noVNC container or the terminal) takes the space below
the navbar. Without that, the lite page's canvas collapsed to 0x0.
Rendered through every URL on libvirt's test driver, the pages had
duplicate IDs and markup browsers repaired silently:
- Each flavor modal's "Advanced" button toggled #flav-add-collapse, the
first modal's section; every modal now has its own. The flavor and
template copies of the custom tab's control IDs, and the template
tab's unused images input, are gone.
- The VM page's action icons and the XML editors were styled by
repeated IDs; they use classes.
- Modal forms opened inside modal-body and closed after modal-footer;
they wrap both. Stray end tags and duplicate attributes are removed,
paragraphs no longer hold modals or rows, table heads have a row, and
the create page closes its row and column.
- html lang is the active language instead of "en".
A test walks every URL as a superuser and fails on a repeated ID. The
console page still has no doctype: its full-height layout relies on
quirks mode and needs its own check.
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.
The serial console test names its compute and VM per connection type, so
the TCP and SSH host can be the same machine. The shut-off migration
fakes reset libvirt's last error first: a libvirtError takes the message
of an earlier real error in the thread, which a live test can leave.
eventlet is in maintenance mode. socketiod now runs python-socketio in
threading mode under gunicorn (one gthread worker, which holds the
sessions), with simple-websocket, already a python-engineio dependency.
gunicorn waits 1 s on stop: an open console never finishes, and its
worker ends when the pty closes. The forward loop waits in select
instead of polling, and a stopped worker is reaped by a blocking
waitpid. eventlet leaves the requirements.
The xterm console never connected: socketiod expected a different token
format, its worker had no compute credentials, one global console was
shared by every client and its output broadcast to all of them, and the
Docker image did not run socketiod at all.
- console/tokens.py: one authorize() for noVNC and socketiod; the signed
token is the only credential, checked at connect time.
- socketiod: one pty worker per client (consolecallback with the
instance id), one session per VM, a session cap, input and resize
checked; the parent never opens libvirt. The engine.io same-origin
check is on.
- consolecallback: opens the console with the compute's credentials and
exits with a message when it cannot.
- Docker runs socketiod as a runit service; nginx proxies /socket.io/
with Host and the scheme for the origin check. Supervisor and systemd
start it as well; WEBVIRTCLOUD_SERIAL_CONSOLE=1 enables it.
- Tests: token and session unit tests, socketiod as a process, and a
live test that reads SeaBIOS from a wvc-test VM on the TCP and SSH
hosts.
@xterm/xterm 6.0.0 and @xterm/addon-fit 0.11.0 replace xterm 3.6.0; the page reads typed and pasted input with onData, and no longer writes every key and all terminal output to the browser console. The unused fullscreen addon goes.
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.
When the serial console process exited on its own (a bad token, an
unreachable host, a killed consolecallback), the read task died on EIO
while fd and child_pid stayed set: the child was a zombie and every later
connection wrote to the dead pty until socketiod was restarted. A child
that failed before exec also returned into the server code and sent its
traceback to the client.
Now the read loop treats EOF/EIO as the end: it reaps the child, closes
the pty, tells the clients "[console closed]" and disconnects them, so
the next connection starts a new console. The child always leaves with
os._exit, also without a token; output is decoded incrementally, and the
unused imports are gone.
The web app (wsgi.py), novncd and socketiod set SIGCHLD to SIG_IGN at
import. The kernel then reaps every child at once, so subprocess loses
the exit status and a failing command reports 0, in the server and in
anything else run in that process: the test suite had to reset the
signal in two tests.
It was added in 2023 against one defunct bash per gunicorn worker and
per novncd. That bash came from the settings template of the time,
which ran .dec_ldap_pwd.sh with Popen and never waited for it; the
template stopped doing that in 561fedf. A settings.py still holding
that line leaves at most one zombie per process, not a growing number.
- wsgi.py, novncd, socketiod: the global SIG_IGN is removed. subprocess
reaps its own children, websockify installs its own SIGCHLD reaper
for novncd's connection processes, and novncd's SSH tunnels wait for
their ssh process.
- socketiod: the pty child execs consolecallback instead of running it
and then returning into the server's code; disconnect reaps that
child (waitpid) instead of any child (wait).
- The settings template drops its unused subprocess import; the two
test workarounds are removed.
New tests load the web app and novncd in a fresh interpreter and check
that SIGCHLD is untouched and a failing command still returns 1; both
fail on the previous code. A patched novncd in the test container
served five connections and left no child behind.
Comments, docstrings and live test names cited item IDs of a roadmap
that is not part of the repository. They now say what is meant, or
nothing where the sentence stands without them. Test assertions and
behavior are unchanged.
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.
Instance.proxy looked the domain up by its stored name. After a rename
or a name swap outside WebVirtCloud, an operation on one VM changed
another; after a VM was replaced under the same name, operations hit
the new VM.
wvmInstance takes the UUID and uses lookupByUUIDString, with no
fallback to the name: a missing UUID fails instead of picking another
domain. Every caller that has an Instance passes it: proxy, console,
quota, post-migration autostart and the VDI URL. Migration uses the
domain the proxy already resolved. getvvfile and the gstfsd requests
use the host's current name of that UUID.
Live tests cover a name swap and a VM replaced under the same name;
both fail on the previous code.
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.