Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
__version__ = "0.2.2"
__author__ = "M. Heuwes <m.heuwes@fz-juelich.de>"

import os
import json
import logging
import os

from tornado.web import authenticated
from tornado import web, ioloop
from tornado import ioloop, web

from nojava_ipmi_kvm.config import config, DEFAULT_CONFIG_FILEPATH
from nojava_ipmi_kvm import utils
Expand All @@ -26,6 +26,13 @@
config.read_config(CONFIG_PATH)


def server_labels():
labels = {}
for server_id in config.get_servers():
labels[server_id] = config[server_id].full_hostname
return labels


class MainHandler(BaseHandler):
@authenticated
@authorized
Expand All @@ -35,8 +42,10 @@ def get(self):
title="Remote KVM",
user=self.get_current_user(),
servers=config.get_servers(),
server_labels=server_labels(),
base_uri=WEBAPP_BASE,
websocket_uri="ws" + WEBAPP_BASE[4:],
version=__version__,
)

@authenticated
Expand All @@ -47,18 +56,17 @@ def post(self):
title="Remote KVM",
user=self.get_current_user(),
servers=config.get_servers(),
server_labels=server_labels(),
base_uri=WEBAPP_BASE,
websocket_uri="ws" + WEBAPP_BASE[4:],
server_name=json.dumps(self.get_body_argument("server_name")),
password=json.dumps(self.get_body_argument("password")),
resolution=json.dumps(self.get_body_argument("resolution")),
version=__version__,
)


def make_app():
"""
returns a tornado.web.Application
"""
settings = {
"template_path": "templates",
"static_path": "static",
Expand All @@ -71,7 +79,7 @@ def make_app():
}
return web.Application(
[web.url(r"/oauth/login", OAuth2LoginHandler), web.url(r"/", MainHandler), web.url(r"/kvm", KVMHandler)],
**settings
**settings,
)


Expand Down
195 changes: 195 additions & 0 deletions static/app.core.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
*,
*::before,
*::after {
box-sizing: border-box;
}

html,
body {
margin: 0;
min-height: 100%;
}

body {
font-family: Helvetica, Arial, sans-serif;
color: #222222;
background: #ffffff;
line-height: 1.5;
}

body.session-active {
overflow: hidden;
}

body.session-active .app-shell {
display: none;
}

.app-shell {
max-width: 1000px;
margin: 0 auto;
padding: 1.5rem 1.25rem;
}

.app-header h1 {
margin: 0 0 0.25rem;
font-size: 1.25rem;
}

.user-meta {
margin: 0 0 1rem;
color: #555555;
}

.app-footer {
margin-top: 1.5rem;
}

.status.is-busy {
display: flex;
align-items: center;
gap: 0.5rem;
}

.status-spinner {
width: 1rem;
height: 1rem;
border: 2px solid #104070;
border-right-color: transparent;
border-radius: 50%;
animation: kvm-spin 0.8s linear infinite;
}

@keyframes kvm-spin {
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: reduce) {
.status-spinner {
animation: none;
}
}

.form-grid {
display: grid;
grid-template-columns: 7.5rem 1fr;
gap: 0.5rem 1rem;
align-items: center;
}

.form-grid label {
font-size: 0.95rem;
}

.form-grid input,
.form-grid select {
width: 100%;
max-width: 20em;
padding: 0.4rem 0.5rem;
border: 1px solid #cccccc;
font: inherit;
}

.form-actions {
grid-column: 1 / -1;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.25rem;
}

.btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.25rem;
padding: 0 1rem;
border-radius: 4px;
border: 1px solid transparent;
font: inherit;
font-weight: 600;
cursor: pointer;
}

.btn:disabled {
opacity: 0.55;
cursor: not-allowed;
}

.btn-primary {
background: #1a5fb4;
color: #ffffff;
}

.btn-secondary {
background: #ffffff;
color: #222222;
border-color: #cccccc;
}

.status {
display: none;
margin-top: 0.75rem;
padding: 0.5rem 0.75rem;
border-radius: 4px;
font-size: 0.9rem;
}

.status.is-visible {
display: block;
}

.status.is-info,
.status.is-busy {
background: #e8f2ff;
color: #104070;
}

.status.is-error {
background: #fde8ea;
color: #c01c28;
}

.logs-panel {
margin-top: 1rem;
}

.logs-panel.is-empty {
display: none;
}

#logsul {
margin: 0;
padding: 0;
list-style: none;
font-family: ui-monospace, Menlo, Consolas, monospace;
font-size: 0.8rem;
color: #555555;
}

#logsul li.error-log {
color: #c01c28;
}

#container {
position: relative;
z-index: 100;
}

.kvm-iframe {
position: fixed;
inset: 0;
width: 100%;
height: 100%;
border: none;
margin: 0;
padding: 0;
z-index: 999999;
background: #000000;
}

.hidden {
display: none !important;
}
Loading