Additional changes for purposes of templating

This commit is contained in:
Jonatan Rek 2025-01-21 16:26:48 +01:00
parent 610ef79690
commit 556fe5920e
4 changed files with 189 additions and 26 deletions

72
app.py
View File

@ -6,8 +6,7 @@ import threading
import time import time
from datetime import datetime, timezone from datetime import datetime, timezone
from socketserver import ThreadingMixIn from socketserver import ThreadingMixIn
from queue import Queue import os
import multiprocessing
# Define the target server to proxy requests to # Define the target server to proxy requests to
class ProxyHandler(http.server.BaseHTTPRequestHandler): class ProxyHandler(http.server.BaseHTTPRequestHandler):
@ -40,26 +39,28 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
def handle_request(self, method): def handle_request(self, method):
#print(self.headers.get('Host').split(":")[0]) #print(self.headers.get('Host').split(":")[0])
proxy_host_configuration = next(filter(lambda host: host['domain'] == self.headers.get('Host').split(":")[0], self.configuration['proxy_hosts'])) parsed_request_host = self.headers.get('Host')
if (':' in parsed_request_host):
parsed_request_host = parsed_request_host.split(":")[0]
proxy_host_configuration = next(filter(lambda host: host['domain'] == parsed_request_host, self.configuration['proxy_hosts']))
starting = False starting = False
for container in proxy_host_configuration['containers']: for container in proxy_host_configuration['containers']:
container_object = self.docker_client.containers.list(all=True, filters = { 'name' : container['container_name'] })[0] container_objects = self.docker_client.containers.list(all=True, filters = { 'name' : container['container_name'] })
if (container_objects == []):
self.send_404(proxy_host_configuration['domain'])
return
container_object = container_objects[0]
if (container_object.status != 'running'): if (container_object.status != 'running'):
print("starting container: {0}".format(container['container_name'])) print("starting container: {0}".format(container['container_name']))
container_object.start() container_object.start()
starting = True starting = True
if (starting == True): if (starting == True):
self.send_response(201) self.send_loading(proxy_host_configuration['proxy_load_seconds'], proxy_host_configuration['domain'])
self.send_header('Content-Type', 'text/plain')
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
self.send_header('refresh', proxy_host_configuration['proxy_timeout_seconds'])
self.end_headers()
self.wfile.write(bytes("starting container: {0} waiting for {1}s".format(container['container_name'], proxy_host_configuration['proxy_timeout_seconds']),"utf-8"))
self.wfile.flush()
return return
activity[proxy_host_configuration['domain']] = datetime.now(timezone.utc) activity[proxy_host_configuration['domain']] = datetime.now(timezone.utc)
@ -79,6 +80,48 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
conn.close() conn.close()
def send_404(self, service_name):
self.send_response(404)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
self.end_headers()
with open(os.path.dirname(os.path.realpath(__file__)) + '/templates/404.html', 'r') as file:
html = file.read()
html = html.replace("{{SERVICE}}", service_name)
self.wfile.write(bytes(html,"utf-8"))
self.wfile.flush()
def send_loading(self, wait_time, service_name):
self.send_response(201)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
self.send_header('refresh', wait_time)
self.end_headers()
with open(os.path.dirname(os.path.realpath(__file__)) + '/templates/wait.html', 'r') as file:
html = file.read()
self.wfile.write(bytes(html,"utf-8"))
#self.wfile.write(bytes("starting service: {0} waiting for {1}s".format(self.headers.get('Host').split(":")[0], proxy_host_configuration['proxy_timeout_seconds']),"utf-8"))
#self.wfile.write(bytes("\nlast started at: {0} ".format(activity[proxy_host_configuration['domain']]),"utf-8"))
self.wfile.flush()
def finish(self,*args,**kw):
try:
if not self.wfile.closed:
self.wfile.flush()
self.wfile.close()
except socket.error:
pass
self.rfile.close()
class ThreadedHTTPServer(ThreadingMixIn, http.server.HTTPServer): class ThreadedHTTPServer(ThreadingMixIn, http.server.HTTPServer):
"""Handle requests in a separate thread.""" """Handle requests in a separate thread."""
@ -97,6 +140,7 @@ class BackgroundTasks(threading.Thread):
sleep_time = apps['proxy_timeout_seconds'] sleep_time = apps['proxy_timeout_seconds']
for container in apps['containers']: for container in apps['containers']:
try:
container_object = self.docker_client.containers.get(container['container_name']) container_object = self.docker_client.containers.get(container['container_name'])
if (container_object.status == 'running'): if (container_object.status == 'running'):
@ -108,6 +152,8 @@ class BackgroundTasks(threading.Thread):
if(diff_seconds > apps['proxy_timeout_seconds']): if(diff_seconds > apps['proxy_timeout_seconds']):
print("stopping container: {0} ({1}) after {2}s".format(container['container_name'], container_object.id, diff_seconds)) print("stopping container: {0} ({1}) after {2}s".format(container['container_name'], container_object.id, diff_seconds))
container_object.stop() container_object.stop()
except docker.errors.NotFound:
pass
time.sleep(sleep_time) time.sleep(sleep_time)

View File

@ -1,9 +1,10 @@
proxy_port: 8888 proxy_port: 80
proxy_hosts: proxy_hosts:
- domain: wp.local - domain: wp.local
containers: containers:
- container_name: wp-dev-db-1 - container_name: wp-dev-db-1
- container_name: wp-dev-wordpress-1 - container_name: wp-dev-wordpress-1
proxy_host: localhost proxy_host: localhost
proxy_port: 80 proxy_port: 8888
proxy_timeout_seconds: 10 proxy_timeout_seconds: 10
proxy_load_seconds: 5

28
templates/404.html Normal file
View File

@ -0,0 +1,28 @@
<style>
.loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.spinner {
position: absolute;
top: 50%;
margin-top: -20px;
width: 100%;
height: 40px;
text-align: center;
font-size: 10px;
}
h1 {
font-size: 25px;
}
</style>
<div class="loading">
<div class="spinner">
<h1>Service <b>{{SERVICE}}</b> not found !!!</h1>
</div>
</div>

88
templates/wait.html Normal file
View File

@ -0,0 +1,88 @@
<style>
.loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.spinner {
position: absolute;
top: 50%;
left: 50%;
margin-top: -20px;
margin-left: -25px;
width: 50px;
height: 40px;
text-align: center;
font-size: 10px;
}
.spinner>div {
z-index: 999;
background-color: black;
height: 100%;
width: 6px;
display: inline-block;
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
animation: sk-stretchdelay 1.2s infinite ease-in-out;
}
.spinner .rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.spinner .rect3 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
.spinner .rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.spinner .rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
@-webkit-keyframes sk-stretchdelay {
0%,
40%,
100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes sk-stretchdelay {
0%,
40%,
100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}
</style>
<div class="loading">
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>