From 7c4894d3b827f492f121ed800ee856d97bbdba69 Mon Sep 17 00:00:00 2001 From: bunkerity Date: Fri, 26 Mar 2021 15:18:35 +0100 Subject: [PATCH] autoconf - fix remove event, generate config from nginx vars, more logs --- autoconf/AutoConf.py | 16 +++++++- autoconf/Config.py | 90 +++++++++++++++++++++++++++----------------- autoconf/app.py | 11 ++++-- 3 files changed, 78 insertions(+), 39 deletions(-) diff --git a/autoconf/AutoConf.py b/autoconf/AutoConf.py index a69db1f..f8ae018 100644 --- a/autoconf/AutoConf.py +++ b/autoconf/AutoConf.py @@ -11,6 +11,11 @@ class AutoConf : self.__sites = {} self.__config = Config(self.__swarm, api) + def get_server(self, id) : + if id in self.__servers : + return self.__servers[id] + return False + def reload(self) : return self.__config.reload(self.__instances) @@ -38,6 +43,7 @@ class AutoConf : self.__process_server(server, "start", id, name, labels) def process(self, obj, event) : + utils.log("process - " + event) (id, name, labels) = self.__get_infos(obj) if "bunkerized-nginx.AUTOCONF" in labels : self.__process_instance(obj, event, id, name, labels) @@ -60,9 +66,9 @@ class AutoConf : self.__instances[id] = instance if self.__swarm and len(self.__instances) == 1 : if self.__config.initconf(self.__instances) : - utils.log("[*] initial config succeeded") + utils.log("[*] Initial config succeeded") else : - utils.log("[!] initial config failed") + utils.log("[!] Initial config failed") utils.log("[*] bunkerized-nginx instance created : " + name + " / " + id) elif event == "start" : self.__instances[id].reload() @@ -82,6 +88,7 @@ class AutoConf : def __process_server(self, instance, event, id, name, labels) : vars = { k.replace("bunkerized-nginx.", "", 1) : v for k, v in labels.items() if k.startswith("bunkerized-nginx.")} if event == "create" : + utils.log("[*] Generating config for " + vars["SERVER_NAME"] + " ...") if self.__config.generate(self.__instances, vars) : utils.log("[*] Generated config for " + vars["SERVER_NAME"]) self.__servers[id] = instance @@ -95,6 +102,7 @@ class AutoConf : elif event == "start" : if id in self.__servers : self.__servers[id].reload() + utils.log("[*] Activating config for " + vars["SERVER_NAME"] + " ...") if self.__config.activate(self.__instances, vars) : utils.log("[*] Activated config for " + vars["SERVER_NAME"]) else : @@ -102,18 +110,22 @@ class AutoConf : elif event == "die" : if id in self.__servers : self.__servers[id].reload() + utils.log("[*] Deactivating config for " + vars["SERVER_NAME"]) if self.__config.deactivate(self.__instances, vars) : utils.log("[*] Deactivated config for " + vars["SERVER_NAME"]) else : utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"]) elif event == "destroy" or event == "remove" : + utils.log(event) if id in self.__servers : if self.__swarm : + utils.log("[*] Deactivating config for " + vars["SERVER_NAME"]) if self.__config.deactivate(self.__instances, vars) : utils.log("[*] Deactivated config for " + vars["SERVER_NAME"]) else : utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"]) del self.__servers[id] + utils.log("[*] Removing config for " + vars["SERVER_NAME"]) if self.__config.remove(vars) : utils.log("[*] Removed config for " + vars["SERVER_NAME"]) else : diff --git a/autoconf/Config.py b/autoconf/Config.py index 1cfe300..4ae7321 100644 --- a/autoconf/Config.py +++ b/autoconf/Config.py @@ -20,25 +20,42 @@ class Config : var = var_value.split("=")[0] value = var_value.replace(var + "=", "", 1) vars[var] = value - if self.globalconf(instances) : - i = 0 - started = False - while i < 10 : - if self.__ping(instances) : - started = True - break - i = i + 1 - utils.log("[!] Waiting " + str(i) + " seconds before retrying to contact nginx instances") - time.sleep(i) - if started : - proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/jobs.sh", "nginx"], env=vars, capture_output=True) - return proc.returncode == 0 - else : - utils.log("[!] bunkerized-nginx instances are not started") + + utils.log("[*] Generating global config ...") + if not self.globalconf(instances) : + utils.log("[!] Can't generate global config") + return False + utils.log("[*] Generated global config") + + if "SERVER_NAME" in vars and vars["SERVER_NAME"] != "" : + for server in vars["SERVER_NAME"].split(" ") : + vars_site = vars.copy() + vars_site["SERVER_NAME"] = server + utils.log("[*] Generating config for " + vars["SERVER_NAME"] + " ...") + if not self.generate(instances, vars_site) or not self.activate(instances, vars_site, reload=False) : + utils.log("[!] Can't generate/activate site config for " + server) + return False + utils.log("[*] Generated config for " + vars["SERVER_NAME"]) + with open("/etc/nginx/autoconf", "w") as f : + f.write("ok") + + utils.log("[*] Waiting for bunkerized-nginx tasks ...") + i = 1 + started = False + while i <= 10 : + time.sleep(i) + if self.__ping(instances) : + started = True + break + i = i + 1 + utils.log("[!] Waiting " + str(i) + " seconds before retrying to contact bunkerized-nginx tasks") + if started : + utils.log("[*] bunkerized-nginx tasks started") + proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/jobs.sh", "nginx"], env=vars, capture_output=True) + return proc.returncode == 0 else : - utils.log("[!] Can't generate global conf") + utils.log("[!] bunkerized-nginx tasks are not started") except Exception as e : - traceback.print_exc() utils.log("[!] Error while initializing config : " + str(e)) return False @@ -54,12 +71,11 @@ class Config : vars[var] = value proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/global-config.sh", "nginx"], env=vars, capture_output=True) if proc.returncode == 0 : - with open("/etc/nginx/autoconf", "w") as f : - f.write("ok") return True + else : + utils.log("[*] Error while generating global config : return code = " + str(proc.returncode)) except Exception as e : - traceback.print_exc() - utils.log("[!] Error while generating global config : " + str(e)) + utils.log("[!] Exception while generating global config : " + str(e)) return False def generate(self, instances, vars) : @@ -82,14 +98,14 @@ class Config : proc = subprocess.run(["/bin/su", "-s", "/bin/sh", "-c", "/opt/entrypoint/site-config.sh" + " " + vars["SERVER_NAME"], "nginx"], env=vars_defaults, capture_output=True) if proc.returncode == 0 and vars_defaults["MULTISITE"] == "yes" and self.__swarm : proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/multisite-config.sh", "nginx"], env=vars_defaults, capture_output=True) - return proc.returncode == 0 - return proc.returncode == 0 + if proc.returncode == 0 : + return True + utils.log("[!] Error while generating site config for " + vars["SERVER_NAME"] + " : return code = " + str(proc.returncode)) except Exception as e : - traceback.print_exc() - utils.log("[!] Error while generating site config : " + str(e)) + utils.log("[!] Exception while generating site config : " + str(e)) return False - def activate(self, instances, vars) : + def activate(self, instances, vars, reload=True) : try : # Check if file exists if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : @@ -99,10 +115,13 @@ class Config : # Include the server conf utils.replace_in_file("/etc/nginx/nginx.conf", "}", "include /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf;\n}") - return self.reload(instances) + # Reload + if not reload or self.reload(instances) : + return True + except Exception as e : - traceback.print_exc() - utils.log("[!] Error while activating config : " + str(e)) + utils.log("[!] Exception while activating config : " + str(e)) + return False def deactivate(self, instances, vars) : @@ -115,14 +134,16 @@ class Config : # Remove the include utils.replace_in_file("/etc/nginx/nginx.conf", "include /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf;\n", "") - return self.reload(instances) + # Reload + if self.reload(instances) : + return True except Exception as e : - traceback.print_exc() - utils.log("[!] Error while deactivating config : " + str(e)) + utils.log("[!] Exception while deactivating config : " + str(e)) + return False - def remove(self, instances, vars) : + def remove(self, vars) : try : # Check if file exists if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : @@ -134,6 +155,7 @@ class Config : return True except Exception as e : utils.log("[!] Error while deactivating config : " + str(e)) + return False def reload(self, instances) : @@ -149,7 +171,7 @@ class Config : instance.reload() # Reload via API if self.__swarm : - # Send POST request on http://serviceName.NodeID.TaskID:8000/reload + # Send POST request on http://serviceName.NodeID.TaskID:8000/action name = instance.name for task in instance.tasks() : if task["Status"]["State"] != "running" : diff --git a/autoconf/app.py b/autoconf/app.py index f0d204a..958758b 100644 --- a/autoconf/app.py +++ b/autoconf/app.py @@ -44,6 +44,7 @@ with lock : # Process events received from Docker try : + utils.log("[*] Listening for Docker events ...") for event in client.events(decode=True) : # Process only container/service events @@ -53,11 +54,15 @@ try : # Get Container/Service object try : if swarm : - server = client.services.get(service_id=event["Actor"]["ID"]) + id = service_id=event["Actor"]["ID"] + server = client.services.get(service_id=id) else : - server = client.containers.get(event["id"]) + id = event["id"] + server = client.containers.get(id) except docker.errors.NotFound as e : - continue + server = autoconf.get_server(id) + if not server : + continue # Process the event with lock :