Login Start

This commit is contained in:
Václav Španinger 2023-08-07 09:42:01 +02:00
parent aa51255715
commit c8d0a6a35a
5 changed files with 80 additions and 24 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
IP=0.0.0.0
PORT=99

View File

@ -1,13 +1,46 @@
from dotenv import load_dotenv
from flask import Flask, render_template from flask import Flask, render_template
from flask_apscheduler import APScheduler from flask_apscheduler import APScheduler
from flask_login import LoginManager
import docker import docker
from pprint import pprint
import time import time
import os
#DEBUG
from pprint import pprint
def calculate_cpu_percent(stats, status):
if (status != "running"):
return 0
cpu_count = len(stats["cpu_stats"]["cpu_usage"]["percpu_usage"])
cpu_percent = 0.0
cpu_delta = float(stats["cpu_stats"]["cpu_usage"]["total_usage"]) - \
float(stats["precpu_stats"]["cpu_usage"]["total_usage"])
system_delta = float(stats["cpu_stats"]["system_cpu_usage"]) - \
float(stats["precpu_stats"]["system_cpu_usage"])
if system_delta > 0.0:
cpu_percent = cpu_delta / system_delta * 100.0 * cpu_count
return round(cpu_percent, 2)
def calculate_ram_percent(stats, status):
if (status != "running"):
return 0
mem_used = stats["memory_stats"]["usage"] - stats["memory_stats"]["stats"]["cache"] + stats["memory_stats"]["stats"]["active_file"]
limit = stats['memory_stats']['limit']
return round(mem_used / limit * 100, 2)
client = docker.from_env() client = docker.from_env()
#login_manager = LoginManager()
app = Flask(__name__) app = Flask(__name__)
scheduler = APScheduler() scheduler = APScheduler()
load_dotenv()
#login_manager.init_app(app)
#https://flask-login.readthedocs.io/en/latest/
@app.route("/", methods=['GET']) @app.route("/", methods=['GET'])
def index(): def index():
@ -17,12 +50,13 @@ def index():
@app.route("/parts/modal/container/<container_id>", methods=['GET']) @app.route("/parts/modal/container/<container_id>", methods=['GET'])
def parts_container_modal(container_id): def parts_container_modal(container_id):
container = client.containers.get(container_id) container = client.containers.get(container_id)
stats = container.stats(stream=False)
#com.docker.extension.detailed-description
project = '' project = ''
if('com.docker.compose.project' in container.attrs['Config']['Labels']): if('com.docker.compose.project' in container.attrs['Config']['Labels']):
project = container.attrs['Config']['Labels']['com.docker.compose.project'] project = container.attrs['Config']['Labels']['com.docker.compose.project']
return render_template("container_modal.html", name=container.name, project=project, ports=container.attrs['NetworkSettings']['Ports'], status=container.status) return render_template("container_modal.html", name=container.name, project=project, ports=container.attrs['NetworkSettings']['Ports'], status=container.status, CPU=calculate_cpu_percent(stats, container.status) ,RAM =calculate_ram_percent(stats, container.status) )
@app.route("/api/<container_id>/<action>", methods=['DELETE', 'POST']) @app.route("/api/<container_id>/<action>", methods=['DELETE', 'POST'])
def api_stop_container(container_id, action): def api_stop_container(container_id, action):
@ -50,4 +84,4 @@ def scheduleTasks():
if __name__ == '__main__': if __name__ == '__main__':
#scheduler.add_job(id = 'scheduled_tasks', func=scheduleTasks, trigger="interval", seconds=3) #scheduler.add_job(id = 'scheduled_tasks', func=scheduleTasks, trigger="interval", seconds=3)
#scheduler.start() #scheduler.start()
app.run(host="0.0.0.0", port=99, debug=True) app.run(host=os.getenv('IP'), port=os.getenv('port'), debug=True)

View File

View File

@ -1,7 +1,21 @@
{{name}}</br> <div class="modal-header m-1">
{{project}}</br> <div class="modal-title">
{{status}}</br> <h5 class="mb-0">{{name}}</h5>
<small>{{project}}</small>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div>
<h5>Stats</h5>
{{status}}
<span class="badge rounded-pill text-bg-primary">{{CPU}}%</span>
<span class="badge rounded-pill text-bg-primary">{{RAM}}%</span>
</div><br>
<div>
<h5>Networking</h5>
{% for port in ports %} {% for port in ports %}
<a href="//127.0.0.1:{{ port.split(" /")[0] }}">{{ port.split("/")[0] }}</a> <a href="//127.0.0.1:{{ port.split(" /")[0] }}" target="_blank">{{ port.split("/")[0] }}</a>
{%endfor%} {%endfor%}
</div>
</div>

View File

@ -11,13 +11,13 @@
</style> </style>
</head> </head>
<body> <body data-bs-theme="dark">
<h1>{{title}}</h1>
<div class="container-fluid"> <div class="container-fluid">
<div class="row row-cols-auto bg-dark"> <h1>Containers</h1>
<div class="row row-cols-auto g-2">
{% for container in containers %} {% for container in containers %}
<div class="col-6 col-sm-4 col-md-4 col-lg-3 col-xxl-2 bg-light"> <div class="col-6 col-sm-4 col-md-4 col-lg-3 col-xxl-2">
<div class="square-item"> <div class="border h-100 p-3">
<div class="square-content" onclick="openModalForContainer('{{container.id}}')"> <div class="square-content" onclick="openModalForContainer('{{container.id}}')">
<!-- Content for the square item --> <!-- Content for the square item -->
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -28,14 +28,16 @@
<input class="form-check-input" type="checkbox" id="flexSwitchCheckReverse" <input class="form-check-input" type="checkbox" id="flexSwitchCheckReverse"
onclick="toggleContainer('{{container.id}}', '{{container.status}}', this, event);" {% if onclick="toggleContainer('{{container.id}}', '{{container.status}}', this, event);" {% if
container.status=="running" %} checked {% endif %}> container.status=="running" %} checked {% endif %}>
<label class="form-check-label" for="flexSwitchCheckReverse">isRunning</label> <label class="form-check-label d-none d-md-block " for="flexSwitchCheckReverse">isRunning</label>
</div> </div>
</div> </div>
<h4 class="text-nowrap">{{container.attrs['Config']['Labels']['com.docker.compose.project']}}</h4> <h4 class="text-truncate">{{container.attrs['Config']['Labels']['com.docker.compose.project']}}</h4>
<h5 class="text-truncate">{{container.name}}</h5> <h5 class="text-truncate">{{container.name}}</h5>
{% if container.status=="running" %}
{% for port in container.attrs['NetworkSettings']['Ports'] %} {% for port in container.attrs['NetworkSettings']['Ports'] %}
<a href="//127.0.0.1:{{ port.split(" /")[0] }}">{{ port.split("/")[0] }}</a> <a href="//127.0.0.1:{{ port.split(" /")[0] }}" target="_blank">{{ port.split("/")[0] }}</a>
{%endfor%} {%endfor%}
{%endif%}
</div> </div>
</div> </div>
</div> </div>
@ -45,14 +47,16 @@
<!-- Modal --> <!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog modal-fullscreen-sm-down">
<div class="modal-content"> <div class="modal-content">
<div class="modal-body">
<div class="spinner-border" role="status"> <div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
@ -82,11 +86,13 @@
xhttp.open(method, '/api/' + container_id + '/' + route, true); xhttp.open(method, '/api/' + container_id + '/' + route, true);
xhttp.send(); xhttp.send();
await new Promise(r => setTimeout(() => r(), 1000)); await new Promise(r => setTimeout(() => r(), 1500));
window.location.reload(); window.location.reload();
} }
function openModalForContainer(container_id) { function openModalForContainer(container_id) {
document.getElementById('exampleModal').getElementsByClassName('modal-content')[0].innerHTML = "<div class=\"modal-body\"><div class=\"spinner-border\" role=\"status\"><span class=\"visually-hidden\">Loading...</span></div></div>"
const myModal = new bootstrap.Modal('#exampleModal') const myModal = new bootstrap.Modal('#exampleModal')
myModal.show() myModal.show()