Server update 1.0

This commit is contained in:
Untriex Programming
2021-05-09 12:01:50 +02:00
parent 87d435c354
commit 60f6fcab55
25 changed files with 2065 additions and 973 deletions
+60 -41
View File
@@ -7,6 +7,9 @@ import engine
import requests
import uuid
import subprocess
import socket
import shutil
from pathlib import Path
from fastapi import FastAPI, Request, File, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
@@ -24,8 +27,6 @@ devs = {
"Samuel Šubika": {
"git": "https://github.com/JustSteel", "mail": "SteelSamko2000@gmail.com"}
}
check = engine.Scan()
check.check_to_go()
if check.state_list["error"]:
@@ -39,11 +40,26 @@ with open("settings.json", "r", encoding='utf-8') as f: # loading settings
with open("filesystem.json", "r", encoding='utf-8') as f: # loading filesystem
filesystem = json.load(f)
IP = settings["IP"]
ID = settings["ID"]
location = settings["location"]
time_to_save = settings["time_to_save"]
if settings["clear_cache_on_startup"]:
shutil.rmtree("cache")
os.mkdir("cache")
def get_my_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
IP = get_my_ip()
ID = filesystem["ID"]
location = filesystem["location"]
time_to_save = settings["time_to_save"]
settings["location"]
settings["ID"]
app = FastAPI() # init of FastAPI
origins = ["*", ]
@@ -68,12 +84,12 @@ heartbeat_table = settings["heartbeat_table"]
sensors = {}
messages = [] # {user: "", timestamp: time.Time(), message: ""}
heartbeat_table["ID"].append(ID)
heartbeat_table["IP"].append(IP)
heartbeat_table["location"].append(location)
heartbeat_table["file_system"].append(filesystem)
heartbeat_table["last_heartbeat"].append(time_to_heartbeat)
if ID not in heartbeat_table["ID"]:
heartbeat_table["ID"].append(ID)
heartbeat_table["IP"].append(IP)
heartbeat_table["location"].append(location)
heartbeat_table["file_system"].append(filesystem)
heartbeat_table["last_heartbeat"].append(time_to_heartbeat)
class ServerTable(BaseModel): # table of content for heartbeat request
@@ -111,24 +127,26 @@ def heartbeat(s_table: ServerTable, request: Request):
s_table.last_heartbeat[position]:
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(server_id)] = s_table.last_heartbeat[
position]
log.debug(f"updated {server_id}`s heartbeat to {s_table.last_heartbeat[position]}")
log.debug(f"updated {server_id}`s heartbeat to {s_table.last_heartbeat[position]}")
heartbeat_table["file_system"][heartbeat_table["ID"].index(server_id)] = s_table.file_system[
position]
elif server_id == ID:
log.debug(f"Updated my heartbeat from {s_table.last_heartbeat[position]} to {time_to_heartbeat}")
heartbeat_table["last_heartbeat"][heartbeat_table["ID"].index(ID)] = time_to_heartbeat
else:
heartbeat_table["ID"].append(s_table.ID[position])
log.message(f"Heartbeat from new server:\n ID: {server_id} IP: {request.client}")
heartbeat_table["ID"].append(int(s_table.ID[position]))
heartbeat_table["IP"].append(s_table.IP[position])
heartbeat_table["location"].append(s_table.location[position])
heartbeat_table["file_system"].append(s_table.file_system[position])
heartbeat_table["last_heartbeat"].append(s_table.last_heartbeat[position])
heartbeat_table["last_heartbeat"].append(int(s_table.last_heartbeat[position]))
log.debug(f"Created {server_id}`s heartbeat: {s_table.last_heartbeat[position]}")
except Exception as error:
log.error(f"heartbeat > {error}")
if heartbeat_table["ID"][heartbeat_table["IP"].index(request.client.host)] in offline:
offline.remove(heartbeat_table["ID"][heartbeat_table["IP"].index(request.client.host)])
log.message(f"{request.client.host} gone online")
log.warning(f"{request.client.host} gone online")
return heartbeat_table, {"ID": ID, "file_system": filesystem, "location": location}
@@ -136,13 +154,13 @@ def heartbeat(s_table: ServerTable, request: Request):
@app.get("/{IDx}/sensors")
def get_sensors(IDx: int, request: Request):
global sensors
log.message(f"sensor data sent to {request.client.host}:{request.client.port}")
log.debug(f"sensor data: {sensors}")
if IDx == ID:
log.debug(f"Sensor data sent to {request.client.host} :\n {sensors}")
return sensors
else:
try:
r = requests.get(f"""http://{heartbeat_table["IP"][heartbeat_table["ID"].index(IDx)]}:8000/{IDx}/sensors""")
log.debug(f"Sensor data from {IDx} sent to {request.client.host} :\n {r.json()}")
return r.json()
except Exception as error:
log.error(f"Sensor data download from {IDx} failed.\n ERROR: {error}")
@@ -157,9 +175,10 @@ def get_file(IDx: int, file: str, request: Request):
if os.path.isfile(f"files/{file}"):
return FileResponse(f"files/{file}")
else:
return f"File {file} does not exist."
log.warning(f"{request.client} tried to access file ({file}) that does not exist on this server.")
return f"ERROR: File {file} does not exist."
if IDx not in heartbeat_table["ID"]:
log.error(f"{request.client} tried to access id ({IDx}) that does not exist.")
log.warning(f"{request.client} tried to access id ({IDx}) that does not exist.")
return f"ERROR: {IDx} does not exist."
else:
if os.path.isdir(f"cache/{IDx}"):
@@ -174,19 +193,20 @@ def get_file(IDx: int, file: str, request: Request):
else:
log.debug(f"returning cached file cache/{IDx}{file}")
return FileResponse(f"cache/{IDx}/{file}")
elif sum(file.stat().st_size for file in Path("cache").rglob('*'))/1024**2 > settings["cache_size_mb"]:
shutil.rmtree("cache")
os.mkdir("cache")
log.message(f"""Clearing cache, because of limit of {settings["cache_size_mb"]}MB""")
os.mkdir(f"cache/{IDx}")
else:
os.mkdir(f"cache/{IDx}")
r = requests.get(f"http://{server_ip}:8000/files/{IDx}/{file}")
if "does not exist" in r.text:
log.error(f"{request.client} tried to access file ({file}) on id {IDx} that does not exist.")
log.warning(f"{request.client} tried to access file ({file}) on id {IDx} that does not exist.")
return f"ERROR: {file} does not exist."
log.message(f"Downloaded {file} from {server_ip}")
if ".txt" in file:
with open(f"cache/{IDx}/{file}", "wb") as save:
save.write(bytes(r.content))
else:
with open(f"cache/{IDx}/{file}", "wb") as save:
save.write(bytes(r.content))
with open(f"cache/{IDx}/{file}", "wb") as save:
save.write(bytes(r.content))
return FileResponse(f"cache/{IDx}/{file}")
@@ -195,8 +215,12 @@ def update_sensors(data: Sensor, request: Request, IDx: int):
global sensors
if IDx == ID:
if data.name in sensors:
log.message(f"{request.client.host} updated sensor {data.name} with value {data.value}")
sensors[data.name] = data.value
if not data.value:
log.message(f"{request.client.host} removed sensor {data.name}")
del sensors[data.name]
else:
log.message(f"{request.client.host} updated sensor {data.name} with value {data.value}")
sensors[data.name] = data.value
else:
log.warning(f"{request.client} created new sensor.\n SENSOR: {data}")
sensors[data.name] = data.value
@@ -228,20 +252,20 @@ def get_devices_list():
@app.get("/admin/get/{command}")
def admin_get(command: str):
def admin_get(command: str, request: Request):
log.message(f"{request.client} used admin command.")
if command == "get_updates":
return [update.get_version(), update.get_updates()]
if "update-" in command:
state = []
version = command.split("-")[1]
return "success"
for rpi in heartbeat_table["IP"]:
if rpi != IP:
r = requests.get(f"""http://{rpi}:8000/admin/get/update_one-{version}""")
if r.text.strip('"').split("\\n")[0] == "SUCCESS":
log.message(f"{rpi} was updated to {version}")
else:
log.warning(f"""{rpi} failed to update. Manual update may be needed for proper working of network.
log.error(f"""{rpi} failed to update. Manual update may be needed for proper working of network.
Response from server: {r.text}""")
state.append({rpi: r.text.strip('"').split("\\n")})
subprocess.check_output(f"""python3 system.py update -version {version}""")
@@ -249,9 +273,8 @@ def admin_get(command: str):
state.append({IP: "updated"})
return state
if "update_one-" in command:
return "success"
state = subprocess.check_output(["python3", "system.py", "update", "-version", f"""{command.split("-")[1]}"""])
log.warning(state.decode("utf-8"))
log.message(state.decode("utf-8"))
return state.decode("utf-8")
if command == "heartbeat_table":
return heartbeat_table
@@ -262,7 +285,6 @@ def admin_get(command: str):
@app.post("/admin/{id_server}/upload_file")
async def create_upload_file(id_server: int, uploaded_file: UploadFile = File(...), patch: str = ""):
file_location = f"{patch}{uploaded_file.filename}"
print(f"file location: {file_location}")
if id_server == ID:
with open(file_location, "wb+") as file_object:
file_object.write(uploaded_file.file.read())
@@ -316,7 +338,6 @@ def send_heartbeat(ip, id):
global heartbeat_table
log.message(f"""sending heartbeat to {ip}({"offline" if id in offline else "online"})""")
cache_request = requests.post(f"http://{ip}:8000/heartbeat", data=json.dumps(heartbeat_table))
print(cache_request.text)
heartbeat_table = dict(cache_request.json()[0])
log.debug(json.dumps(cache_request.json(), indent=4))
@@ -326,7 +347,7 @@ def mainloop():
while True:
for device_number, device_ID in enumerate(heartbeat_table["ID"]):
if device_ID != ID:
if heartbeat_table["last_heartbeat"][device_number] < 0:
if int(heartbeat_table["last_heartbeat"][device_number]) < 0:
try:
send_heartbeat(heartbeat_table["IP"][device_number], heartbeat_table["ID"][device_number])
except requests.exceptions.ConnectionError:
@@ -350,7 +371,7 @@ def mainloop():
try:
log.debug(
f"""{device_ID} : time to heartbeat : {heartbeat_table["last_heartbeat"][device_number]}""")
heartbeat_table["last_heartbeat"][device_number] -= 1
heartbeat_table["last_heartbeat"][device_number] = int(heartbeat_table["last_heartbeat"][device_number]) - 1
except IndexError:
pass
if time.time() - time_to_save > save_time and settings["save_table"]:
@@ -363,12 +384,10 @@ def mainloop():
time.sleep(1)
print(f"""Starting WikiSpot V{update.get_version()["version"]}""")
print(f"""Starting WikiSpot V{update.get_version()["version"]} on http://{IP}:8000""")
print("GitHub: https://github.com/Tucan444/Mabasej_Team")
print("Developers of this project: ")
for dev in devs:
print(f"""{dev}, GitHub: {devs[dev]["git"]}, mail: {devs[dev]["mail"]}""")
thread_1 = threading.Thread(target=mainloop, daemon=True)
thread_1.start()
# Todo settings for easy adding/editing files/id/text