first commit
This commit is contained in:
36
templates/backup.html
Normal file
36
templates/backup.html
Normal file
@@ -0,0 +1,36 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container">
|
||||
<table class="table">
|
||||
{% for lxc in list_snap_lxc %}
|
||||
<tr><td>
|
||||
<p class="fw-light">{{ lxc[0] }}</p>
|
||||
</td><td>
|
||||
{% for snap_lxc in lxc[1] %}
|
||||
<table class="table"><tr><th>
|
||||
{{ snap_lxc }}</th><th>
|
||||
<form action="/rest_snap_lxc" method="post"><input type="hidden" name="lxc_name" value="{{ lxc[0] }}"><button type="submit" class="btn btn-outline-secondary btn-hype" name="item" value="{{ snap_lxc }}" onclick="loading();"><i class="fa-solid fa-rotate-left"></i></button></form>
|
||||
</th><th>
|
||||
<form action="/del_snap_lxc" method="post"><input type="hidden" name="lxc_name" value="{{ lxc[0] }}"><button type="submit" class="btn btn-outline-danger btn-hype" name="item" value="{{ snap_lxc }}" onclick="loading();"><i class="fas fa-trash"></i</button></form>
|
||||
</th></tr></table>
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
{% for vm in list_snap_vm %}
|
||||
<tr><td>
|
||||
<p class="fw-light">{{ vm[0] }}</p>
|
||||
</td><td>
|
||||
{% for snap_vm in vm[1] %}
|
||||
<table class="table"><tr><th>
|
||||
{{ snap_vm }}</th><th>
|
||||
<button type="submit" class="btn btn-outline-secondary btn-hype" value="{{ snap }}" name="start" onclick="loading();"><i class="fa-solid fa-rotate-left"></i></button>
|
||||
</th><th>
|
||||
<button type="submit" class="btn btn-outline-danger btn-hype" value="{{ snap }}" name="start" onclick="loading();"><i class="fa-solid fa-trash"></i></button>
|
||||
</th></tr></table>
|
||||
{% endfor %}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
70
templates/build.html
Normal file
70
templates/build.html
Normal file
@@ -0,0 +1,70 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-cube"></i> - Build Container
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<form action="/creation" method="post">
|
||||
<label for="cnom">Name</label>
|
||||
<input type="text" id="cnom" name="nom" class="form-control" placeholder="Container" required><br>
|
||||
<label for="cip">Optional static IP</label>
|
||||
<input type="text" id="cip" name="ip" class="form-control" placeholder="192.168.XX.XX/YY"><br>
|
||||
<label for="oslist">OS</label>
|
||||
<select id="oslist" name="os" class="form-control">
|
||||
{%for dist in list_lxc_os %}
|
||||
<option value={{ dist[1] }}>{{ dist[0] }}</option>
|
||||
{%endfor%}
|
||||
</select><br>
|
||||
<button name="creation" class="btn btn-outline-secondary btn-hype" type="submit" onclick="loading();">Create</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa-solid fa-desktop"></i> - Create Virtual Server
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="/creationvm" method="post">
|
||||
<label for="nom">Name</label>
|
||||
<input type="text" name="vm_name" class="form-control" placeholder="Server" required><br>
|
||||
<label for="ram">Memory (in MiB)</label>
|
||||
<input type="text" name="ram" class="form-control" placeholder="1024" required><br>
|
||||
<label for="cpu">vCPU</label>
|
||||
<input type="text" name="cpu" class="form-control" placeholder="1" required><br>
|
||||
<label for="disk">Disk (in GB)</label>
|
||||
<input type="text" class="form-control" name="disk" placeholder="10" required><br>
|
||||
<label for="os">OS</label>
|
||||
<select id="profilelist" class="form-control" name="os" placeholder="Profile" required>
|
||||
{%for profile in list_profiles %}
|
||||
<option value={{ profile }}>{{ profile }}</option>
|
||||
{%endfor%}
|
||||
</select><br>
|
||||
<label for="iso">ISO</label>
|
||||
<select id="isolist" class="form-control" name="iso" required>
|
||||
{%for iso in list_iso %}
|
||||
<option value={{ iso[0] }}>{{ iso[0] }}</option>
|
||||
{%endfor%}
|
||||
</select><br>
|
||||
<label for="net">Network</label>
|
||||
<select id="netlist" class="form-control" name="net" required>
|
||||
{%for net in list_net %}
|
||||
<option value={{ net }}>{{ net }}</option>
|
||||
{%endfor%}
|
||||
</select><br>
|
||||
<button name="creation" class="btn btn-outline-secondary btn-hype" type="submit" onclick="loading();">Create</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
239
templates/index.html
Normal file
239
templates/index.html
Normal file
@@ -0,0 +1,239 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Hostname
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h1 class="display-6">{{ host.hostname }}</h1>
|
||||
Last boot : {{ host.boot_time }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
LXC
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h1 class="display-6" style="color:green">Up : {{ lxc_up }}</h1>
|
||||
<p style="color:red" class="fw-light">Down : {{ lxc_down }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
|
||||
<div class="card-header">
|
||||
VM
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h1 class="display-6" style="color:green">Up : {{ vm_up }}</h1>
|
||||
<p style="color:red" class="fw-light">Down : {{ vm_down }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- Monit -->
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Monitor
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="canvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Usage
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="fw-light">CPU</p>
|
||||
<div class="progress">
|
||||
<div id="cpubar" class="progress-bar progress-bar-striped" role="progressbar" style="width: {{ full['cpu']['percent'] }}%;" aria-valuenow={{ full['cpu']['percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full['cpu']['percent'] }}%</div>
|
||||
</div>
|
||||
<small class="form-text text-muted" id="cpudetail">
|
||||
user : {{ full['cpu']['time_user'] }} / nice : {{ full['cpu']['time_nice'] }} / system : {{ full['cpu']['time_system'] }} / idle : {{ full['cpu']['time_idle'] }} / iowait : {{ full['cpu']['time_iowait'] }} / irq : {{ full['cpu']['time_irq'] }} / softirq : {{ full['cpu']['time_softirq'] }} / steal : {{ full['cpu']['time_steal'] }} / guest : {{ full['cpu']['time_guest'] }} / guest nice : {{ full['cpu']['time_guest_nice'] }}
|
||||
</small>
|
||||
<br><br>
|
||||
<p class="fw-light">MEM</p>
|
||||
<div class="progress">
|
||||
<div id="membar" class="progress-bar bg-warning progress-bar-striped" role="progressbar" style="width: {{ full['mem']['percent'] }}%;" aria-valuenow={{ full['mem']['percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full['mem']['percent'] }}%</div>
|
||||
</div>
|
||||
<small class="form-text text-muted" id="memdetail">
|
||||
total : {{ full['mem']['total'] }} / available : {{ full['mem']['available'] }} / used : {{ full['mem']['used'] }} / free : {{ full['mem']['free'] }} / active : {{ full['mem']['active'] }} / inactive : {{ full['mem']['inactive'] }} / buffers : {{ full['mem']['buffers'] }} / cached : {{ full['mem']['cached'] }} / shared : {{ full['mem']['shared'] }} / slab : {{ full['mem']['slab'] }}
|
||||
</small>
|
||||
<br><br>
|
||||
<p class="fw-light">SWAP</p>
|
||||
<div class="progress">
|
||||
<div id="swapbar" class="progress-bar bg-danger progress-bar-striped" role="progressbar" style="width: {{ full['swap']['percent'] }}%;" aria-valuenow={{ full['swap']['percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full['swap']['percent'] }}%</div>
|
||||
</div>
|
||||
<small class="form-text text-muted" id="swapdetail">
|
||||
total : {{ full['swap']['total'] }} / used : {{ full['swap']['used'] }} / free : {{ full['swap']['free'] }} / sin : {{ full['swap']['sin'] }} / sout : {{ full['swap']['sout'] }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- Disk -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Disks
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% for key in full %}
|
||||
{% if key.startswith('disk_') %}
|
||||
<br>
|
||||
<p class="fw-light">{{ full[key]['mountpoint'] }}</p>
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-info" role="progressbar" style="width: {{ full[key]['size_percent'] }}%;" aria-valuenow={{ full[key]['size_percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full[key]['size_percent'] }}%</div>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
total : {{ full[key]['size_total'] }} / used : {{ full[key]['size_used'] }} / free : {{ full[key]['size_free'] }} / device : {{ full[key]['device'] }} / fstype : {{ full[key]['fstype'] }} / opt: {{ full[key]['opts'] }} / maxfile : {{ full[key]['maxfile'] }} / maxpath : {{ full[key]['maxpath'] }}
|
||||
</small>
|
||||
</br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Network
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table fw-light">
|
||||
<tr><td>Name</td><td>IPv4</td><td>Netmask v4</td><td>IPv6</td><td>Netmask v6</td><td>Sent</td><td>Received</td></tr>
|
||||
{% for key in full %}
|
||||
{% if key.startswith('net_') %}
|
||||
<tr><td>{{ full[key]['name'] }}</td><td>{{ full[key]['address_v4'] }}</td><td>{{ full[key]['netmask_v4'] }}</td><td>{{ full[key]['address_v6'] }}</td><td>{{ full[key]['netmask_v6'] }}</td><td>{{ full[key]['bytes_sent'] }}</td><td>{{ full[key]['bytes_recv'] }}</td><tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
const config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: Array(60).fill("0000-00-00 00:00:00"),
|
||||
datasets: [{
|
||||
label: "CPU %",
|
||||
backgroundColor: 'rgb(0, 191, 255)',
|
||||
borderColor: 'rgb(0, 191, 255)',
|
||||
data: Array(60).fill(null),
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
},{
|
||||
label: "Mem %",
|
||||
backgroundColor: 'rgb(255,200,20)',
|
||||
borderColor: 'rgb(255,200,20)',
|
||||
data: Array(60).fill(null),
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
},{
|
||||
label: "Swap %",
|
||||
backgroundColor: 'rgb(255, 20, 100)',
|
||||
borderColor: 'rgb(255, 20, 100)',
|
||||
data: Array(60).fill(null),
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
title: {
|
||||
display: false,
|
||||
},
|
||||
tooltips: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
hover: {
|
||||
mode: 'nearest',
|
||||
intersect: true
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
display: false,
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'Time'
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
display: true,
|
||||
scaleLabel: [{
|
||||
display: true,
|
||||
labelString: 'CPU'
|
||||
},{
|
||||
display: true,
|
||||
labelString: 'Mem'
|
||||
},{
|
||||
display: true,
|
||||
labelString: 'Swap'
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const context = document.getElementById('canvas').getContext('2d');
|
||||
const lineChart = new Chart(context, config);
|
||||
const source = new EventSource("/chart-ressources/");
|
||||
source.onmessage = function (event) {
|
||||
const data = JSON.parse(event.data);
|
||||
if (config.data.labels.length === 60) {
|
||||
config.data.labels.shift();
|
||||
config.data.datasets[0].data.shift();
|
||||
config.data.datasets[1].data.shift();
|
||||
config.data.datasets[2].data.shift();
|
||||
}
|
||||
config.data.labels.push(data.time);
|
||||
config.data.datasets[0].data.push(data.cpu_percent);
|
||||
config.data.datasets[1].data.push(data.mem_percent);
|
||||
config.data.datasets[2].data.push(data.swap_percent);
|
||||
lineChart.update();
|
||||
$("#cpubar").html(data.cpu_percent+"%");
|
||||
$("#membar").html(data.mem_percent+"%");
|
||||
$("#swapbar").html(data.swap_percent+"%");
|
||||
$("#cpudetail").html("user : "+data.cpu_time_user+" / nice : "+data.cpu_time_nice+" / system : "+data.cpu_time_system+" / idle : "+data.cpu_time_idle+" / iowait : "+data.cpu_time_iowait+" / irq : "+data.cpu_time_irq+" / softirq : "+data.cpu_time_softirq+" / steal : "+data.cpu_time_steal+" / guest : "+data.cpu_time_guest+" / guest nice : "+data.cpu_time_guest_nice);
|
||||
$("#swapdetail").html("total : "+data.swap_total+" / used : "+data.swap_used+" / free : "+data.swap_free+" / sin : "+data.swap_sin+" / sout : "+data.swap_sout);
|
||||
$("#memdetail").html("total : "+data.mem_total+" / available : "+data.mem_available+" / used : "+data.mem_used+" / free : "+data.mem_free+" / active : "+data.mem_active+" / inactive : "+data.mem_inactive+" / buffers : "+data.mem_buffers+" / cached : "+data.mem_cached+" / shared : "+data.mem_shared+" / slab : "+data.mem_slab);
|
||||
var element_cpubar = document.getElementById("cpubar");
|
||||
var element_membar = document.getElementById("membar");
|
||||
var element_swapbar = document.getElementById("swapbar");
|
||||
|
||||
var element_cpudetail = document.getElementById("cpudetail");
|
||||
|
||||
element_cpubar.style.width = data.cpu_percent+"%"
|
||||
element_membar.style.width = data.mem_percent+"%"
|
||||
element_swapbar.style.width = data.swap_percent+"%"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
63
templates/iso.html
Normal file
63
templates/iso.html
Normal file
@@ -0,0 +1,63 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
DropZone
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{{ url_for('upload_files') }}" class="dropzone" id="file-dropzone">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
ISO
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{%for iso in list_iso %}
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
{{ iso[0] }} ( {{ iso[1] }} )
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<form action="/deliso" method="post"><button type="submit" class="btn btn-outline-danger btn-hype" value="{{ iso[0] }}" name="fichier"><i class="fa fa-trash"></i></button></form>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
</div>
|
||||
</div>
|
||||
{%endfor%}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Mount ISO on Virtual Server
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<form action="/mountiso" method="post">
|
||||
<select id="isolist" class="form-control" name="iso" required>
|
||||
{%for iso in list_iso_mount %}
|
||||
<option value={{ iso[0] }}>{{ iso[0] }}</option>
|
||||
{%endfor%}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<select id="vmlist" class="form-control" name="vm" required>
|
||||
{%for vm in list_vm %}
|
||||
<option value={{ vm }}>{{ vm }}</option>
|
||||
{%endfor%}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<button name="mountiso" type="submit" class="btn btn-outline-success btn-hype"><i class="fa fa-check"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
158
templates/layout.html
Normal file
158
templates/layout.html
Normal file
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE html>
|
||||
<html data-bs-theme="dark">
|
||||
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Hype 2</title>
|
||||
|
||||
<link href="{{url_for('static', filename = 'bootstrap.min.css' )}}" rel="stylesheet">
|
||||
<link href="{{url_for('static', filename = 'Chart.min.css' )}}" rel="stylesheet" >
|
||||
<link href="{{url_for('static', filename = 'font-awesome/css/fontawesome.css')}}" rel="stylesheet">
|
||||
<link href="{{url_for('static', filename = 'font-awesome/css/brands.css')}}" rel="stylesheet">
|
||||
<link href="{{url_for('static', filename = 'font-awesome/css/solid.css')}}" rel="stylesheet">
|
||||
<link href="{{url_for('static', filename = 'style.css')}}" rel="stylesheet">
|
||||
<link href="{{url_for('static', filename = 'dropzone.min.css')}}" rel="stylesheet">
|
||||
|
||||
|
||||
<script src="{{url_for('static', filename = 'popper.min.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = 'bootstrap.bundle.min.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = 'jquery.min.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = 'Chart.min.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = 'dropzone.min.js')}}"></script>
|
||||
|
||||
<script src="{{url_for('static', filename = '/core/rfb.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/strings.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/element.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/logging.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/browser.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/int.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/events.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/eventtarget.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/display.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/inflator.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/deflator.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/gesturehandler.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/keyboard.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/util/cursor.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/websock.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/des.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/keysym.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/xtscancodes.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/encodings.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/decoders/raw.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/decoders/copyrect.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/decoders/hextile.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/decoders/rre.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/decoders/tight.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/decoders/tightpng.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/base64.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/inflate.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/zstream.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/deflate.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/util.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/utils/common.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/inffast.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/adler32.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/crc32.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/inftrees.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/keysymdef.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/vkeys.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/fixedkeys.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/core/input/domkeytable.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/trees.js')}}"></script>
|
||||
<script src="{{url_for('static', filename = '/vendor/pako/lib/zlib/messages.js')}}"></script>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Loading DIV -->
|
||||
<div id="loading"><center><img src="{{url_for('static', filename = 'logo.gif')}}"></center></div>
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
<!-- Pour le fun -->
|
||||
<div style="position:fixed;bottom:0;right:0">Version Beta 2.7</div>
|
||||
<!-- Alerting -->
|
||||
<script>
|
||||
var opacity=0;
|
||||
var intervalID=0;
|
||||
function fadeout(){
|
||||
setInterval(hide, 100);
|
||||
}
|
||||
|
||||
setTimeout(function(){
|
||||
fadeout();
|
||||
}, 3000);
|
||||
function hide(){
|
||||
var body=document.getElementById("alert");
|
||||
opacity = Number(window.getComputedStyle(body).getPropertyValue("opacity"))
|
||||
|
||||
if(opacity>0){
|
||||
opacity=opacity-0.1;
|
||||
body.style.opacity=opacity
|
||||
}
|
||||
else{
|
||||
clearInterval(intervalID);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<!-- Menu JS-->
|
||||
<script>
|
||||
var menu_btn = document.querySelector("#menu-btn");
|
||||
var sidebar = document.querySelector("#sidebar");
|
||||
var container = document.querySelector(".my-container");
|
||||
menu_btn.addEventListener("click", () => {
|
||||
sidebar.classList.toggle("active-nav");
|
||||
container.classList.toggle("active-cont");
|
||||
});
|
||||
</script>
|
||||
<!-- Loading -->
|
||||
<script type="text/javascript">// <![CDATA[
|
||||
function loading(){
|
||||
$("#loading").show();
|
||||
$("#content").hide();
|
||||
}
|
||||
// ]]>
|
||||
</script>
|
||||
<!-- DropZone -->
|
||||
<script>
|
||||
var myDropzone = new Dropzone("#file-dropzone", {
|
||||
maxFilesize: 10240, // 10Go in Mo
|
||||
timeout: 0,
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Alert JS -->
|
||||
<script>
|
||||
//Get the cookie related to theme
|
||||
var cookieValue = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("theme="))
|
||||
?.split("=")[1];
|
||||
// Appli the theme related to the cookie
|
||||
window.onload = function() {
|
||||
if (cookieValue == 'dark'){
|
||||
document.documentElement.setAttribute('data-bs-theme','dark')
|
||||
}
|
||||
else {
|
||||
document.documentElement.setAttribute('data-bs-theme','light')
|
||||
}
|
||||
}
|
||||
//Change the cookie and reload
|
||||
document.getElementById('btnSwitch').addEventListener('click',()=>{
|
||||
if (cookieValue == 'dark') {
|
||||
document.cookie = "theme=light";
|
||||
window.location.reload();
|
||||
}
|
||||
else {
|
||||
document.cookie = "theme=dark";
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
26
templates/login.html
Normal file
26
templates/login.html
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card px-5 py-5" id="form1">
|
||||
<h1 class="h1">Hype²</h1>
|
||||
<form action="/login" method="POST" class="form-group">
|
||||
<br><br>
|
||||
<div class="form-group">
|
||||
<input type="email" name="email" placeholder="Email" class="form-control">
|
||||
</div><br>
|
||||
<div class="form-group">
|
||||
<input type="password" name="password" placeholder="Password" class="form-control">
|
||||
</div><br>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-outline-info btn-hype">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-3 col-sm-12"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
52
templates/menu.html
Normal file
52
templates/menu.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<div class="side-navbar active-nav d-flex justify-content-between flex-wrap flex-column" id="sidebar">
|
||||
<ul class="nav flex-column text-dark w-100 ">
|
||||
<li class="nav-link">
|
||||
<h1 class="display-6">Hype²</h1>
|
||||
</li>
|
||||
<hr class="text-body">
|
||||
<li class="nav-link">
|
||||
<a class="nav-link text-body text-decoration-none fw-light" href="/"><i class="fa fa-pie-chart"></i> Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a class="nav-link text-body text-decoration-none fw-light" href="/state"><i class="fa fa-cubes"></i> State</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a class="nav-link text-body text-decoration-none fw-light" href="/build"><i class="fa fa-cogs"></i> Build</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a class="nav-link text-body text-decoration-none fw-light" href="/backup"><i class="fa fa-archive"></i> Backup</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a class="nav-link text-body text-decoration-none fw-light" href="/iso"><i class="fa-solid fa-compact-disc"></i> ISO</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a class="nav-link text-body text-decoration-none fw-light" href="/pool"><i class="fa-solid fa-hard-drive"></i> Pools</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="p-1 my-container active-cont">
|
||||
<nav class="navbar top-navbar px-5">
|
||||
<a class="btn border-0 text-body" id="menu-btn"><i class="fa fa-bars"></i></a>
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fa fa-user"></i> {{ current_user.username }}
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
|
||||
<li><a class="dropdown-item" href="/logout"><i class="fa fa-sign-out"></i> Logout</a></li>
|
||||
<li><a class="dropdown-item" href="/signup"><i class="fa fa-user-plus"></i> Add user</a></li>
|
||||
<li><a class="dropdown-item" href="/param"><i class="fa fa-gear"></i> Parameters</a></li>
|
||||
<li><a class="dropdown-item" style="cursor:pointer" id="btnSwitch"><i class="fa-solid fa-circle-half-stroke"></i> Theme</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</br>
|
||||
<!-- Safe pour que ce soit au format html, sinon, prit comme texte -->
|
||||
<div class="container">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div id="alert" class="alert alert-{{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</br>
|
||||
30
templates/param.html
Normal file
30
templates/param.html
Normal file
@@ -0,0 +1,30 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container fs-6"">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-cube"></i> List of users
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% for user in users_list %}
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<p class="fw-light">{{user[0]}}</p>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<p class="fw-light">{{user[1]}}</p>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<form action="/deluser" method="post"><input type="hidden" id="postId" name="username" value="{{user[0]}}" />
|
||||
<button type="submit" class="btn btn-outline-danger btn-hype" value="{{user[1]}}" name="email">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
39
templates/pool.html
Normal file
39
templates/pool.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container">
|
||||
{% for pool in list_pool_full %}
|
||||
{{ pool[0] }}<hr>
|
||||
<div class="progress">
|
||||
<div id="cpubar" class="progress-bar progress-bar-striped" role="progressbar" style="width: {{ pool[6] }}%;" aria-valuenow={{ pool[6] }} aria-valuemin="0" aria-valuemax="100">{{ pool[6] }}%</div>
|
||||
</div>
|
||||
<small class="form-text text-muted">
|
||||
UUID : {{ pool[1] }} / Active : {{ pool[2] }} / Total : {{ pool[3] }} / Used : {{ pool[4] }} / Free : {{ pool[5] }}
|
||||
</small>
|
||||
<table class="table">
|
||||
<tr><th>Name</th><th>Total</th><th>Used</th><th></th><th></th>
|
||||
{% for volume in pool[7] %}
|
||||
<tr>
|
||||
<td>{{ volume[0] }}</td>
|
||||
<td>{{ volume[1] }}</td>
|
||||
<td>{{ volume[2] }}</td>
|
||||
<td>
|
||||
<div class="progress">
|
||||
<div id="cpubar" class="progress-bar progress-bar-striped" role="progressbar" style="width: {{ volume[3] }}%;" aria-valuenow={{ volume[3] }} aria-valuemin="0" aria-valuemax="100">{{ volume[3] }}%</div>
|
||||
</div>
|
||||
|
||||
<td>{{ volume[3] }}%</td>
|
||||
<td>
|
||||
<form action="/del_volume" method="post">
|
||||
<input type="hidden" name="pool_name" value="{{ pool[0] }}">
|
||||
<button type="submit" class="btn btn-outline-danger btn-hype" name="volume_name" value="{{ volume[0] }}" onclick="loading();">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i></button></form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
126
templates/pyxterm.html
Normal file
126
templates/pyxterm.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
html {
|
||||
font-family: arial;
|
||||
}
|
||||
</style>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://unpkg.com/xterm@4.11.0/css/xterm.css"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<span style="font-size: small"
|
||||
>status:
|
||||
<span style="font-size: small" id="status">connecting...</span></span
|
||||
>
|
||||
|
||||
<div style="width: 100%; height: calc(100% - 50px)" id="terminal"></div>
|
||||
|
||||
<!-- xterm -->
|
||||
<script src="https://unpkg.com/xterm@4.11.0/lib/xterm.js"></script>
|
||||
<script src="https://unpkg.com/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.js"></script>
|
||||
<script src="https://unpkg.com/xterm-addon-web-links@0.4.0/lib/xterm-addon-web-links.js"></script>
|
||||
<script src="https://unpkg.com/xterm-addon-search@0.8.0/lib/xterm-addon-sear
|
||||
ch.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.min.js"></script>
|
||||
|
||||
<script>
|
||||
const term = new Terminal({
|
||||
cursorBlink: true,
|
||||
macOptionIsMeta: true,
|
||||
scrollback: true,
|
||||
});
|
||||
term.attachCustomKeyEventHandler(customKeyEventHandler);
|
||||
// https://github.com/xtermjs/xterm.js/issues/2941
|
||||
const fit = new FitAddon.FitAddon();
|
||||
term.loadAddon(fit);
|
||||
term.loadAddon(new WebLinksAddon.WebLinksAddon());
|
||||
term.loadAddon(new SearchAddon.SearchAddon());
|
||||
|
||||
term.open(document.getElementById("terminal"));
|
||||
fit.fit();
|
||||
term.resize(15, 50);
|
||||
console.log(`size: ${term.cols} columns, ${term.rows} rows`);
|
||||
fit.fit();
|
||||
term.writeln("Copy: [ctrl]+[shift]+[x] Paste: [ctrl]+[shift]+[v]");
|
||||
term.writeln('')
|
||||
term.onData((data) => {
|
||||
console.log("browser terminal received new data:", data);
|
||||
socket.emit("pty-input", { input: data });
|
||||
});
|
||||
|
||||
const socket = io.connect("/pty");
|
||||
const status = document.getElementById("status");
|
||||
|
||||
socket.on("pty-output", function (data) {
|
||||
console.log("new output received from server:", data.output);
|
||||
term.write(data.output);
|
||||
});
|
||||
|
||||
socket.on("connect", () => {
|
||||
fitToscreen();
|
||||
status.innerHTML =
|
||||
'<span style="background-color: lightgreen;">connected</span>';
|
||||
});
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
status.innerHTML =
|
||||
'<span style="background-color: #ff8383;">disconnected</span>';
|
||||
});
|
||||
|
||||
function fitToscreen() {
|
||||
fit.fit();
|
||||
const dims = { cols: term.cols, rows: term.rows };
|
||||
console.log("sending new dimensions to server's pty", dims);
|
||||
socket.emit("resize", dims);
|
||||
}
|
||||
|
||||
function debounce(func, wait_ms) {
|
||||
let timeout;
|
||||
return function (...args) {
|
||||
const context = this;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func.apply(context, args), wait_ms);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle copy and paste events
|
||||
*/
|
||||
function customKeyEventHandler(e) {
|
||||
if (e.type !== "keydown") {
|
||||
return true;
|
||||
}
|
||||
if (e.ctrlKey && e.shiftKey) {
|
||||
const key = e.key.toLowerCase();
|
||||
if (key === "v") {
|
||||
// ctrl+shift+v: paste whatever is in the clipboard
|
||||
navigator.clipboard.readText().then((toPaste) => {
|
||||
term.writeText(toPaste);
|
||||
});
|
||||
return false;
|
||||
} else if (key === "c" || key === "x") {
|
||||
// ctrl+shift+x: copy whatever is highlighted to clipboard
|
||||
|
||||
// 'x' is used as an alternate to 'c' because ctrl+c is taken
|
||||
// by the terminal (SIGINT) and ctrl+shift+c is taken by the browser
|
||||
// (open devtools).
|
||||
// I'm not aware of ctrl+shift+x being used by anything in the terminal
|
||||
// or browser
|
||||
const toCopy = term.getSelection();
|
||||
navigator.clipboard.writeText(toCopy);
|
||||
term.focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const wait_ms = 50;
|
||||
window.onresize = debounce(fitToscreen, wait_ms);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
29
templates/signup.html
Normal file
29
templates/signup.html
Normal file
@@ -0,0 +1,29 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card px-5 py-5" id="form1">
|
||||
<h1 class="display-6">Add user</h1><br><br>
|
||||
<form action="/signup" method="POST" class="form-group">
|
||||
<div class="form-group">
|
||||
<input type="text" name="username" placeholder="Username" class="form-control">
|
||||
</div><br>
|
||||
<div class="form-group">
|
||||
<input type="email" name="email" placeholder="Email" class="form-control">
|
||||
</div><br>
|
||||
<div class="form-group">
|
||||
<input type="password" name="password" placeholder="Password" class="form-control">
|
||||
</div><br>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-outline-info btn-hype">Add</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-3 col-sm-12"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
113
templates/state.html
Normal file
113
templates/state.html
Normal file
@@ -0,0 +1,113 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<div class="container fs-6"">
|
||||
<table class="table">
|
||||
<!-- Active LXC -->
|
||||
{% for act_lxc in activ_lxc %}
|
||||
<tr><td>
|
||||
<i class="fa fa-cube fa-lg"></i><i class="fa fa-check text-success"></i>
|
||||
</td><td>
|
||||
<p class="fw-light">{{act_lxc[0]}}</p>
|
||||
</td><td>
|
||||
<form action="/start_lxc" method="post"><button type="submit" class="btn btn-outline-success btn-hype disabled" value="{{ act_lxc[0] }}" name="start" onclick="loading();"><i class="fa fa-play" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/stop_lxc" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype" value="{{ act_lxc[0] }}" name="stop" onclick="loading();"><i class="fa fa-stop" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/console_lxc" method="post" target=”_blank”><button type="submit" class="btn btn-outline-info btn-hype" value="{{ act_lxc[0] }}" name="lxc_name" onclick="loading();"><i class="fa fa-terminal"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/destroy_lxc" method="post"><button type="submit" class="btn btn-outline-danger btn-hype disabled" value="{{ act_lxc[0] }}" name="destroy" onclick="loading();"><i class="fa fa-trash" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/snaplxc" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype disabled" value="{{ act_lxc[0] }}" name="snap" onclick="loading();"><i class="fa-solid fa-box-archive"></i></button></form>
|
||||
</td><td>
|
||||
</td><td>
|
||||
{{act_lxc[1]}}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
<!-- Inactive LXC -->
|
||||
{% for inact_lxc in inactiv_lxc %}
|
||||
<tr><td>
|
||||
<i class="fa fa-cube fa-lg"></i><i class="fa fa-times text-danger"></i>
|
||||
</td><td>
|
||||
<p class="fw-light">{{inact_lxc}}</p>
|
||||
</td><td>
|
||||
<form action="/start_lxc" method="post"><button type="submit" class="btn btn-outline-success btn-hype" value="{{ inact_lxc }}" name="start" onclick="loading();"><i class="fa fa-play" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/stop_lxc" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype disabled" value="{{ inact_lxc }}" name="stop" onclick="loading();"><i class="fa fa-stop" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/console_lxc" method="post"><button type="submit" class="btn btn-outline-info btn-hype disabled" value="{{ inact_lxc }}" name="lxc_name" onclick="loading();"><i class="fa fa-terminal" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/destroy_lxc" method="post"><button type="submit" class="btn btn-outline-danger btn-hype" value="{{ inact_lxc }}" name="destroy" onclick="loading();"><i class="fa fa-trash" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/snaplxc" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype" value="{{ inact_lxc }}" name="snap" onclick="loading();"><i class="fa-solid fa-box-archive"></i></button></form>
|
||||
</td><td>
|
||||
</td><td>
|
||||
-
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
<!-- Activ VM -->
|
||||
{% for act_vm in activ_vm %}
|
||||
<tr><td>
|
||||
<i class="fa fa-desktop fa-lg"></i><i class="fa fa-check text-success"></i>
|
||||
</td><td>
|
||||
<p class="fw-light">{{act_vm[0]}}</p>
|
||||
</td><td>
|
||||
<form action="/start_vm" method="post"><button type="submit" class="btn btn-outline-success btn-hype disabled" value="{{ act_vm[0] }}" name="start" onclick="loading();"><i class="fa fa-play" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/stop_vm" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype" value="{{ act_vm[0] }}" name="stop" onclick="loading();"><i class="fa fa-stop" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/console_vm" method="post"><button type="submit" class="btn btn-outline-info btn-hype" value="{{ act_vm[0] }}" name="vm_name" onclick="loading();"><i class="fa fa-terminal" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/destroy_vm" method="post"><button type="submit" class="btn btn-outline-danger btn-hype disabled" value="{{ act_vm[0] }}" name="destroy" onclick="loading();"><i class="fa fa-trash" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/snapvm" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype disabled" value="{{ act_vm[0] }}" name="snap" onclick="loading();"><i class="fa-solid fa-box-archive"></i></button></form>
|
||||
</td><td>
|
||||
{% if act_vm[1] == 1 %}
|
||||
<table class="table table-borderless"><tr><th>
|
||||
<i class="fa-solid fa-compact-disc"></i>
|
||||
</th><th><form action="/mountiso" method="post"><input type="hidden" id="postId" name="iso" value="" />
|
||||
<button type="submit" class="btn btn-outline-secondary btn-hype" value="{{act_vm[0]}}" name="vm" onclick="loading();">
|
||||
<i class="fa-solid fa-eject"></i></button></form>
|
||||
</th></tr></table>
|
||||
|
||||
{% else %}
|
||||
<i class="fa-solid fa-compact-disc" style="color:grey"></i>
|
||||
{% endif %}
|
||||
</td><td>
|
||||
{{act_vm[2]}}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
<!-- Inavtiv VM -->
|
||||
{% for inact_vm in inactiv_vm %}
|
||||
<tr><td>
|
||||
<i class="fa fa-desktop fa-lg"></i><i class="fa fa-times text-danger"></i>
|
||||
</td><td>
|
||||
<p class="fw-light">{{inact_vm[0]}}</p>
|
||||
</td><td>
|
||||
<form action="/start_vm" method="post"><button type="submit" class="btn btn-outline-success btn-hype" value="{{ inact_vm[0] }}" name="start"><i class="fa fa-play" aria-hidden="true" onclick="loading();"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/stop_vm" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype disabled" value="{{ inact_vm[0] }}" name="stop" onclick="loading();"><i class="fa fa-stop" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/console_vm" method="post"><button type="submit" class="btn btn-outline-info btn-hype disabled"><i class="fa fa-terminal" aria-hidden="true" onclick="loading();"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/destroy_vm" method="post"><button type="submit" class="btn btn-outline-danger btn-hype" value="{{ inact_vm[0] }}" name="destroy" onclick="loading();"><i class="fa fa-trash" aria-hidden="true"></i></button></form>
|
||||
</td><td>
|
||||
<form action="/snapvm" method="post"><button type="submit" class="btn btn-outline-secondary btn-hype" value="{{ inact_vm[0] }}" name="snap" onclick="loading();"><i class="fa-solid fa-box-archive"></i></button></form>
|
||||
|
||||
</td><td>
|
||||
{% if inact_vm[1] == 1 %}
|
||||
<table class="table table-borderless"><tr><th>
|
||||
<i class="fa-solid fa-compact-disc"></i>
|
||||
</th><th><form action="/mountiso" method="post"><input type="hidden" id="postId" name="iso" value="" />
|
||||
<button type="submit" class="btn btn-outline-secondary btn-hype" value="{{act_vm[0]}}" name="vm" onclick="loading();">
|
||||
<i class="fa-solid fa-eject"></i></button></form>
|
||||
</th></tr></table>
|
||||
{% else %}
|
||||
<i class="fa-solid fa-compact-disc" style="color:grey"></i>
|
||||
{% endif %}
|
||||
</td><td>
|
||||
-
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
8
templates/terminal.html
Normal file
8
templates/terminal.html
Normal file
@@ -0,0 +1,8 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<a href="/ter" target="_blank"><i class="fa-solid fa-expand"></i></a></br>
|
||||
|
||||
<iframe src="/ter" height=768px width=1024px class="embed-responsive-item" allowfullscreen></iframe>
|
||||
|
||||
{% endblock %}
|
||||
8
templates/vnc.html
Normal file
8
templates/vnc.html
Normal file
@@ -0,0 +1,8 @@
|
||||
{% extends 'layout.html' %}
|
||||
{% block content %}
|
||||
{% include 'menu.html' %}
|
||||
<a href="/vnc" target="_blank"><i class="fa-solid fa-expand"></i></a></br>
|
||||
|
||||
<iframe src="/vnc" height=768px width=1024px class="embed-responsive-item" allowfullscreen></iframe>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user