Added ability to run containers in web browser
This commit is contained in:
31
html/api/docker.php
Executable file
31
html/api/docker.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
require_once "api.php";
|
||||
if (! $PRIVILEGE["docker"] and ! $PRIVILEGE["dockerAdmin"]) { // Makes sure that the person has the right privilege
|
||||
missingPrivilege($USERNAME);
|
||||
exit();
|
||||
}
|
||||
if (array_key_exists("containers", $_GET)) { // Will list all avaliable containers
|
||||
echo json_encode(dbRequest2("SELECT * FROM docker WHERE owner='$USERNAME' or action='stopped'"));
|
||||
} else if (array_key_exists("start", $_POST) and array_key_exists("image", $_POST)) { // Used to start a container and will return the password
|
||||
$id = $_POST["start"];
|
||||
$image = $OGPOST["image"];
|
||||
if (! dbRequest2("SELECT * FROM docker WHERE action='stopped' and ID='$id'")) { // Will check if the container can be started
|
||||
echo "Container does not exist or is used";
|
||||
http_response_code(404);
|
||||
} elseif (! dbRequest2("SELECT * FROM dockerImages WHERE realName=?", "*", [$image])) { // Will cheeck if the image exists
|
||||
echo "Image does not exist";
|
||||
http_response_code(404);
|
||||
} else { // Will start the image
|
||||
$password = $USERNAME;
|
||||
$password .= rand();
|
||||
$password = sanitize(substr(sha1($password), 5, 8));
|
||||
dbCommand("UPDATE docker SET action='starting', image='$image', password='$password' WHERE ID='$id'");
|
||||
writeLog(23, "$USERNAME is starting container with $image image and id $id and an IP of $address");
|
||||
echo $password;
|
||||
}
|
||||
} else if (array_key_exists("images", $_GET)) {
|
||||
echo json_encode(dbRequest2("SELECT * FROM dockerImages")); // Will list all available images
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo "Invalid command";
|
||||
}
|
||||
59
html/docker/index.js
Executable file
59
html/docker/index.js
Executable file
@@ -0,0 +1,59 @@
|
||||
function start(id) { // Used to start a container
|
||||
const ajax = new XMLHttpRequest();
|
||||
|
||||
ajax.onload = function() {
|
||||
if (ajax.status != 200) {
|
||||
JQerror(this.responseText);
|
||||
}
|
||||
update();
|
||||
}
|
||||
ajax.open("POST", `/api/docker.php`);
|
||||
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
ajax.send(`start=${id}&image=${$(`#${id}image`).val()}&key='${getCookie('user')}'`);
|
||||
}
|
||||
|
||||
function update() { // Used to update the table
|
||||
const ajax = new XMLHttpRequest();
|
||||
|
||||
ajax.onload = function() {
|
||||
if (ajax.status == 200) {
|
||||
let text = "<tr><th>ID</th><th>Status</th><th>Image</th><th>Password</th><th>Link</th></tr>";
|
||||
Object.values(JSON.parse(this.responseText)).forEach(element => {
|
||||
let password = "";
|
||||
let image = "";
|
||||
if (element["action"] == "started") {
|
||||
password = element["password"];
|
||||
}
|
||||
if (element["action"] == "started") { // Used to find the Human Readable name of the image
|
||||
image = "unknown";
|
||||
Object.values(images).forEach(element2 => {
|
||||
if (element2["realName"] == element["image"]) {
|
||||
image = element2["shortName"];
|
||||
}
|
||||
});
|
||||
} else if (element["action"] == "stopped") {
|
||||
image = "<select>"
|
||||
Object.values(images).forEach(element2 => {
|
||||
image += `<option id='${element["ID"]}image' value='${element2["realName"]}'>${element2["shortName"]}</option>`;
|
||||
});
|
||||
image += "</select>";
|
||||
}
|
||||
text += `<tr><td>${element["ID"]}</td><td>${element["action"]}</td><td>${image}</td><td>${password}</td><td>${element["link"]}</td>`;
|
||||
if (element["action"] == "stopped") { // Used to add button to start container
|
||||
text += `<td><button onclick='start("${element["ID"]}")'>Start</button></td>`;
|
||||
}
|
||||
text += "</tr>"
|
||||
});
|
||||
$("#docker").html(text);
|
||||
} else {
|
||||
JQerror(this.responseText);
|
||||
}
|
||||
}
|
||||
ajax.open("GET", `/api/docker.php?containers=get&key='${getCookie('user')}'`);
|
||||
ajax.send();
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
update();
|
||||
setInterval(update, 5000);
|
||||
});
|
||||
48
html/docker/index.php
Executable file
48
html/docker/index.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>
|
||||
Schaefer Family - Containers
|
||||
</title>
|
||||
<?php
|
||||
$DESCRIPTION = "A way to start a few VM and access them in a web browser";
|
||||
require_once '../include/all.php';
|
||||
?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php
|
||||
include '../include/menu.php';
|
||||
echo "<div class='main'>";
|
||||
if (! $USERNAME) {
|
||||
echo "<h2>You are not logged in redirecting...</h2>";
|
||||
header("Refresh:3; url=/login.php", true);
|
||||
http_response_code(401);
|
||||
} else if (! $PRIVILEGE["docker"]) {
|
||||
http_response_code(403);
|
||||
header("Refresh:3; url=/index.php", true);
|
||||
echo "<h2>Forbidden redirecting...</h2>";
|
||||
} else {
|
||||
$images = dbRequest2("SELECT * FROM dockerImages");
|
||||
echo "<script>var images=JSON.parse('";
|
||||
echo json_encode($images);
|
||||
echo "')</script>";
|
||||
?>
|
||||
<script type='text/javascript' src='index.js'></script>
|
||||
<h1>Run Containers</h1>
|
||||
<table>
|
||||
<tbody id='docker'>
|
||||
<tr>
|
||||
<th>ID</th><th>Status</th><th>Image</th><th>Password</th><th>Link</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -134,6 +134,7 @@ function dbRequest2($command, $result="*", $prepare=[])
|
||||
} else if ($length == 1) {
|
||||
$stmt = mysqli_prepare($connection, $command);
|
||||
$parameter1 = $prepare[0];
|
||||
echo $parameter1;
|
||||
mysqli_stmt_bind_param($stmt, "s", $parameter1);
|
||||
mysqli_stmt_execute($stmt);
|
||||
$response = mysqli_stmt_get_result($stmt);
|
||||
@@ -266,7 +267,7 @@ foreach ($_COOKIE as $pointer => $value) {
|
||||
// Removes all expired cookies from the database
|
||||
$Time = time();
|
||||
dbCommand("DELETE FROM cookies WHERE expire < $Time and expire != 0");
|
||||
$PRIVILEGELIST = ["root", "internet", "editUser", "deleteUser", "deleteElectricity", "deleteLog", "viewLog", "changeCredintials", "deleteElectricity", "deleteError", "restartServer", "updateServer", "serverStatus", "viewBackup", "restore"]; // A List of all possible privileges
|
||||
$PRIVILEGELIST = ["root", "internet", "editUser", "deleteUser", "deleteElectricity", "deleteLog", "viewLog", "changeCredintials", "deleteElectricity", "deleteError", "restartServer", "updateServer", "serverStatus", "viewBackup", "restore", "docker", "dockerAdmin"]; // A List of all possible privileges
|
||||
function noUser() { # Used to set everything up as if no yser is logged in
|
||||
global $USERNAME, $PRIVILEGE, $PRIVILEGELIST;
|
||||
$USERNAME = "";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
$MENUITEMS = [["Main Page", "/index.php"], ["Internet", "/internet/index.php"], ["Dice Game", "/diceGame/index.php"], ["Space 3", "/space3/index.php"], ["Electricity Log", "/electricity.php"], ["Floppy", "/floppy.php"], ["Soccer", "/soccer.php"], ["Golf", "/golf/index.php"], ["privilege", "viewLog", "/log/index.php", "Server Log"], ["privilege", "viewBackup", "/backup/index.php", "Backups"], ["Cookie Clicker Addon", "/cookieClicker/index.php"], ["user", "/usermenu/index.php", "User Menu"], ["user", "/usermenu/key.php", "Session Manager"], ["notUser", "/login.php", "Login/Signup"], ["user", "/login.php", "Logout"]];
|
||||
$MENUITEMS = [["Main Page", "/index.php"], ["Internet", "/internet/index.php"], ["Dice Game", "/diceGame/index.php"], ["Space 3", "/space3/index.php"], ["Electricity Log", "/electricity.php"], ["Floppy", "/floppy.php"], ["Soccer", "/soccer.php"], ["Golf", "/golf/index.php"], ["Docker Containers", "/docker/index.php"], ["privilege", "viewLog", "/log/index.php", "Server Log"], ["privilege", "viewBackup", "/backup/index.php", "Backups"], ["Cookie Clicker Addon", "/cookieClicker/index.php"], ["user", "/usermenu/index.php", "User Menu"], ["user", "/usermenu/key.php", "Session Manager"], ["notUser", "/login.php", "Login/Signup"], ["user", "/login.php", "Logout"]];
|
||||
echo "<div class='vertical-menu'>";
|
||||
function menuItem($link, $name)
|
||||
{
|
||||
|
||||
@@ -113,5 +113,35 @@
|
||||
"type": "22",
|
||||
"name": "Session created",
|
||||
"color": "#00ccff"
|
||||
},
|
||||
{
|
||||
"type": "23",
|
||||
"name": "Started Container",
|
||||
"color": "#660099"
|
||||
},
|
||||
{
|
||||
"type": "24",
|
||||
"name": "Stopped Container",
|
||||
"color": "#660099"
|
||||
},
|
||||
{
|
||||
"type": "25",
|
||||
"name": "Created Image",
|
||||
"color": "#660099"
|
||||
},
|
||||
{
|
||||
"type": "26",
|
||||
"name": "Deleted Image",
|
||||
"color": "#660099"
|
||||
},
|
||||
{
|
||||
"type": "27",
|
||||
"name": "Created Container",
|
||||
"color": "#660099"
|
||||
},
|
||||
{
|
||||
"type": "28",
|
||||
"name": "Deleted Container",
|
||||
"color": "#660099"
|
||||
}
|
||||
]
|
||||
@@ -179,7 +179,9 @@ def repair(): # Repairs all tables
|
||||
"space3likes" : [["id", 1], ["account", 0]],
|
||||
"golfGamePlayers" : [["gameID", 1], ["multiplier", 1], ["user", 0], ["points", 1], ["orderID", 1], ["lastMode", 0], ["upToDate", 6]],
|
||||
"golfGameCards" : [["gameID", 1], ["user", 0], ["card", 1], ["cardPlacement", 1], ["faceUp", 6]],
|
||||
"golfGame" : [["ID", 5], ["deck", 4], ["discard", 4], ["cardNumber", 1], ["flipNumber", 1], ["multiplierForFlip", 1], ["pointsToEnd", 1], ["name", 0], ["password", 0], ["players", 1], ["playersToStart", 1], ["currentPlayer", 1], ["turnStartTime", 1], ["locked", 6]]
|
||||
"golfGame" : [["ID", 5], ["deck", 4], ["discard", 4], ["cardNumber", 1], ["flipNumber", 1], ["multiplierForFlip", 1], ["pointsToEnd", 1], ["name", 0], ["password", 0], ["players", 1], ["playersToStart", 1], ["currentPlayer", 1], ["turnStartTime", 1], ["locked", 6]],
|
||||
"docker" : [["link", 0], ["action", 0], ["image", 0], ["password", 0], ["owner", 0], ["port", 1], ["ID", 0]],
|
||||
"dockerImages" : [["realName", 0], ["shortName", 0], ["description", 0]]
|
||||
}
|
||||
changedTables = []
|
||||
for x in databaseDict:
|
||||
@@ -245,9 +247,14 @@ def repair(): # Repairs all tables
|
||||
command("ALTER TABLE cookies ADD lastIP varchar(255) NULL")
|
||||
version = "v1.1"
|
||||
updatedVersions.append("v1.1")
|
||||
if versionNumber == "v1.1":
|
||||
createTable("docker", [["link", 0], ["action", 0], ["image", 0], ["password", 0], ["owner", 0], ["port", 1], ["ID", 0]])
|
||||
createTable("dockerImage", [["realName", 0], ["shortName", 0], ["description", 0]])
|
||||
version = "v2.0"
|
||||
updatedVersions.append("v2.0")
|
||||
# Fixes the version if it is invalid to the latest version
|
||||
if version != "v1.1":
|
||||
version = "v1.1"
|
||||
if version != "v2.0":
|
||||
version = "v2.0"
|
||||
except:
|
||||
1
|
||||
command("DELETE FROM information WHERE pointer='version'")
|
||||
|
||||
@@ -15,7 +15,12 @@ import os
|
||||
import datetime
|
||||
import sys
|
||||
import glob
|
||||
|
||||
try:
|
||||
import docker
|
||||
dockerClient = docker.from_env()
|
||||
skipDocker = False
|
||||
except:
|
||||
skipDocker = True
|
||||
|
||||
def error(e):
|
||||
return "".join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__))
|
||||
@@ -230,9 +235,11 @@ try:
|
||||
database.command("DELETE FROM golfGameCards WHERE NOT EXISTS (SELECT * FROM golfGame WHERE golfGameCards.gameID = golfGame.ID)") # Removes players from games that do not exist
|
||||
writeLog("Server maintenance ran succesfully.", 12)
|
||||
|
||||
# Will add to log if the GPIO library exists
|
||||
# Will add to log if a library could not be connected to
|
||||
if skipGPIO:
|
||||
writeLog("Could not import GPIO library", 9)
|
||||
if skipDocker:
|
||||
writeLog("Could not connect to docker", 9)
|
||||
while True: # will wait until connected to internet
|
||||
try:
|
||||
urllib.request.urlopen("https://google.com")
|
||||
@@ -341,6 +348,28 @@ try:
|
||||
# Will check every 2 seconds if the button is pressed and when it is show it on the led and then wait another second to verify that it is an actual press
|
||||
while True:
|
||||
time.sleep(2)
|
||||
# Will check if a docker container should be started or stopped.
|
||||
if not skipDocker:
|
||||
dockerList = database.trueSearch("SELECT * FROM docker")
|
||||
for x in dockerList:
|
||||
print(x)
|
||||
# Will check if the container has already been stopped
|
||||
id = x[6]
|
||||
if x[1] == "started":
|
||||
try:
|
||||
dockerClient.containers.get(id)
|
||||
except Exception:
|
||||
database.command(f"UPDATE docker SET action='stopped' WHERE ID='{id}'")
|
||||
writeLog(f"Container with id of {id} was stopped", 24)
|
||||
elif x[1] == "starting": # Will start all containers that are neccessary
|
||||
password = x[3]
|
||||
newID = dockerClient.containers.run(x[2], detach=True, ports={'80/tcp':x[5]}, remove=True, environment=[f"VNC_PASSWD={password}"]).attrs["Id"]
|
||||
database.command(f"UPDATE docker SET action='started', id='{newID}' WHERE ID='{id}'")
|
||||
writeLog(f"Container with id of {id} which changed to {newID} was started", 23)
|
||||
elif x[1] == "stopping": # Stops all containers that need to be stopped.
|
||||
dockerClient.containers.get(id).stop()
|
||||
database.command(f"UPDATE docker SET action='stopped' WHERE ID='{id}'")
|
||||
writeLog(f"Container with id of {id} was stopped", 24)
|
||||
if os.path.isfile(location + "restart.json"): # Used to restart the server
|
||||
writeLog("Server is being restarted", 12)
|
||||
os.remove(location + "restart.json")
|
||||
|
||||
Reference in New Issue
Block a user