Skip to content

Commit

Permalink
Added restart button and method to interact with container. Resolves s…
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamedtaee committed May 26, 2024
1 parent 70173ff commit 83a2ac5
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 12 deletions.
47 changes: 46 additions & 1 deletion app/api/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import io
import os
import flask
import platform
import docker

bp = flask.Blueprint('api', __name__, url_prefix='/api')


@bp.route('/config/<name>', methods=['GET'])
@bp.route('/config/<name>', methods=['GET'])
def get_config(name: str):
"""
Reads the file with the corresponding name that was passed.
Expand Down Expand Up @@ -215,3 +217,46 @@ def enable_domain(name: str):
os.rename(os.path.join(config_path, _), os.path.join(config_path, _ + '.disabled'))

return flask.make_response({'success': True}), 200


def is_rhel():
try:
with open('/etc/os-release') as f:
os_release = f.read()
return 'rhel' in os_release.lower()
except FileNotFoundError:
return False


USE_SUDO_PODMAN = is_rhel()


def get_docker_client():
print("Platform: ", platform.system())
if USE_SUDO_PODMAN:
base_url = f'unix:///run/user/{os.getuid()}/podman/podman.sock'
elif platform.system() == "Windows":
base_url = 'npipe:////./pipe/docker_engine'
else:
base_url = 'unix://var/run/docker.sock'
return docker.DockerClient(base_url=base_url)


client = get_docker_client()


@bp.route('/restart-nginx', methods=['POST'])
def restart_nginx():
try:
container = client.containers.get('nginx')
container.restart()
except Exception as e:
return flask.jsonify({"message": f"Error: {e}"}), 500
return flask.jsonify({"message": "Nginx container restarted"}), 200


@bp.route('/status-nginx', methods=['GET'])
def status_nginx():
container = client.containers.get('nginx')
status = container.status
return flask.jsonify({"container": "nginx", "status": status}), 200
93 changes: 84 additions & 9 deletions app/static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,92 @@ textarea {
#main-container {
margin-top: 5em;
}

#domain {
display: none;
}

@media only screen and (max-width: 666px) {
[class*="mobile hidden"],
[class*="tablet only"]:not(.mobile),
[class*="computer only"]:not(.mobile),
[class*="large monitor only"]:not(.mobile),
[class*="widescreen monitor only"]:not(.mobile),
[class*="or lower hidden"] {
display: none !important;
}
}
[class*="mobile hidden"],
[class*="tablet only"]:not(.mobile),
[class*="computer only"]:not(.mobile),
[class*="large monitor only"]:not(.mobile),
[class*="widescreen monitor only"]:not(.mobile),
[class*="or lower hidden"] {
display: none !important;
}
}

.status-circle {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
}

.status-running {
background-color: limegreen;
}

.status-exited {
background-color: red;
}

.status-loading {
background-color: orange;
}

.status-paused {
background-color: grey;
}

.status-black {
background-color: black;
}

.restart-button {
margin-left: 10px;
padding: 5px 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}

.restart-button:hover {
background-color: #0056b3;
}

@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

.custom-spinner {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-bottom;
border: 0.25em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
animation: spin 0.75s linear infinite;
}

.custom-spinner-sm {
width: 1rem;
height: 1rem;
border-width: 0.2em;
}

.custom-spinner-lg {
width: 3rem;
height: 3rem;
border-width: 0.3em;
}
63 changes: 63 additions & 0 deletions app/static/nginxController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
document.addEventListener('DOMContentLoaded', function () {
setNginxStatusCircle();
});

function setNginxStatusCircle() {
const nginxStatusCircle = document.getElementById('nginx-status-circle');

fetch('/api/status-nginx')
.then(response => response.json())
.then(data => {
console.log(data);

const containerStatus = data.status;
console.log("Container status: " + containerStatus);
nginxStatusCircle.className = 'status-circle status-' + containerStatus;
return containerStatus;
});
}

let restartProcessComplete = true;

function restartStatusInterval() {
const nginxStatusCircle = document.getElementById('nginx-status-circle');
nginxStatusCircle.className = 'status-circle status-loading';

const intervalId = setInterval(() => {
if (restartProcessComplete) {
clearInterval(intervalId);
setNginxStatusCircle();
} else {
if (nginxStatusCircle.className === 'status-circle status-loading') {
nginxStatusCircle.className = 'status-circle status-black';
} else {
nginxStatusCircle.className = 'status-circle status-loading';
}
}
}, 300);
}


function restartNginx() {
restartProcessComplete = false;
restartStatusInterval();

const restartBtn = document.getElementById('nginx-restart-btn');
restartBtn.disabled = true;

const restartSpinner = document.getElementById('nginx-restart-btn-spinner');
restartSpinner.className = 'custom-spinner custom-spinner-sm';


fetch('/api/restart-nginx', {method: "POST"})
.then(response => response.json())
.then(data => {
console.log(data);
})
.finally(() => {
setNginxStatusCircle();
restartProcessComplete = true;
restartSpinner.className = '';
restartBtn.disabled = false;
});
}
12 changes: 11 additions & 1 deletion app/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
{{ moment.include_moment() }}
<script src="{{ url_for('static', filename='semantic.min.js') }}"></script>
<script src="{{ url_for('static', filename='custom.min.js') }}"></script>
<script src="{{ url_for('static', filename='custom.min.js') }}"></script> # update custom.js to minified version
<script src="{{ url_for('static', filename='nginxController.js') }}"></script>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='custom.css') }}">
</head>
<body>
Expand Down Expand Up @@ -40,6 +41,15 @@
Domains
</a>

<a class="item" id="nginx-status">
<span class="status-circle status-loading" id="nginx-status-circle"></span>
Nginx Status
<button class="restart-button" style="margin-left: 10px" onclick="restartNginx()" id="nginx-restart-btn" type="button">
<span class="" aria-hidden="true" id="nginx-restart-btn-spinner"></span>
<span role="status">Restart</span>
</button>
</a>

<div class="mobile hidden right item">
<div class="ui action input">
<input type="text" placeholder="example.com" id="add_domain">
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ services:
- "8080:8080"
volumes:
- nginx:/etc/nginx
- /var/run/docker.sock:/var/run/docker.sock

nginx:
container_name: nginx
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Flask~=3.0.3
gunicorn~=22.0.0
Flask-Moment~=1.0.5
Flask-Moment~=1.0.5
docker~=7.1.0

0 comments on commit 83a2ac5

Please sign in to comment.