From f771ec43f1b3727274b567a99c24f57571bbf290 Mon Sep 17 00:00:00 2001 From: bunkerity Date: Thu, 8 Jul 2021 23:45:58 +0200 Subject: [PATCH] ui - init Instances class to support Linux and API for Docker/Swarm --- ui/Instances.py | 129 ++++++++++++++++++++++++++++++++++++++++++++ ui/requirements.txt | 3 ++ 2 files changed, 132 insertions(+) create mode 100644 ui/Instances.py create mode 100644 ui/requirements.txt diff --git a/ui/Instances.py b/ui/Instances.py new file mode 100644 index 0000000..c6daf63 --- /dev/null +++ b/ui/Instances.py @@ -0,0 +1,129 @@ +import docker, os, requests + +class Instances : + + def __init__(self, docker_host, api) : + try : + self.__docker = docker.DockerClient(base_url=docker_host) + except : + self.__docker = None + self.__api = api + + def __instance(self, name, type, status, data=None) : + instance = {} + instance["name"] = name + instance["type"] = type + instance["status"] = status + instance["data"] = data + + def __api_request(self, instance, order) : + result = True + hosts = [] + if instance["type"] == "container" : + hosts.append(instance["name"]) + elif instances["type"] == "service" : + for task in instance["data"].tasks() : + host = instance["name"] + "." + task["NodeID"] + "." + task["ID"] + hosts.append(host) + for host in hosts : + try : + req = requests.post("http://" + host + ":8080" + self.__api + order) + if not req or req.status_code != 200 or req.text != "ok" : + result = False + except : + result = False + + def get_instances(self) : + instances = [] + + # Docker instances (containers or services) + if self.__docker != None : + if self.__docker.swarm == None : + for instance in self.__docker.containers.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) : + name = instance.name + type = "container" + status = "down" + if instance.status == "running" : + status = "up" + instances.append(self.__instance(name, type, status, instance)) + else : + for instance in self.__docker.services.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) : + name = instance.name + type = "service" + status = "down" + desired_tasks = instance.attrs["ServiceStatus"]["DesiredTasks"] + running_tasks = instance.attrs["ServiceStatus"]["RunningTasks"] + if desired_tasks > 0 and (desired_tasks == running_tasks) : + status = "up" + instances.append(self.__instance(name, type, status, instance)) + + # Local instance + if os.path.exists("/usr/sbin/nginx") : + name = "local" + type = "local" + status = "down" + if os.path.exists("/tmp/nginx.pid") : + status = "up" + instances.append(self.__instance(name, type, status)) + + return instances + + def reload_instances(self) : + all_reload = True + for instance in self.get_instances() : + if instance["status"] == "down" : + all_reload = False + continue + if instance["type"] == "local" : + proc = subprocess.run(["/usr/sbin/nginx", "-s", "reload"], capture_output=True) + if proc.returncode != 0 : + all_reload = False + elif instance["type"] == "container" or instance["type"] == "service" : + all_reload = self.__api_request(instance, "/reload") + + return all_reload + + def reload_instance(self, instance) : + result = True + if instance["type"] == "local" : + instance["data"].kill(signal="SIGHUP") + elif instance["type"] == "container" or instance["type"] == "service" : + result = self.__api_request(instance, "/reload") + if result : + return "Instance " + instance["name"] + " has been reloaded." + return "Can't reload " + instance["name"] + + def start_instance(self, instance) : + result = True + if instance["type"] == "local" : + proc = subprocess.run(["/usr/sbin/nginx", "-g", "daemon on;"], capture_output=True) + result = proc.returncode == 0 + elif instance["type"] == "container" or instance["type"] == "service" : + result = self.__api_request(instance, "/start") + if result : + return "Instance " + instance["name"] + " has been started." + return "Can't start " + instance["name"] + + def stop_instance(self, instance) : + result = True + if instance["type"] == "local" : + proc = subprocess.run(["/usr/sbin/nginx", "-s", "quit"], capture_output=True) + result = proc.returncode == 0 + elif instance["type"] == "container" or instance["type"] == "service" : + result = self.__api_request(instance, "/stop") + if result : + return "Instance " + instance["name"] + " has been stopped." + return "Can't stop " + instance["name"] + + def restart_instance(self, instance) : + result = True + if instance["type"] == "local" : + proc = subprocess.run(["/usr/sbin/nginx", "-s", "quit"], capture_output=True) + if proc.returncode == 0 : + proc = subprocess.run(["/usr/sbin/nginx", "-g", "daemon on;"], capture_output=True) + result = proc.returncode == 0 + elif instance["type"] == "container" or instance["type"] == "service" : + result = self.__api_request(instance, "/restart") + if result : + return "Instance " + instance["name"] + " has been restarted." + return "Can't restart " + instance["name"] diff --git a/ui/requirements.txt b/ui/requirements.txt new file mode 100644 index 0000000..e4999bb --- /dev/null +++ b/ui/requirements.txt @@ -0,0 +1,3 @@ +flask +requests +docker