autoconf - fix remove event, generate config from nginx vars, more logs

This commit is contained in:
bunkerity 2021-03-26 15:18:35 +01:00
parent 533c2a1034
commit 7c4894d3b8
3 changed files with 78 additions and 39 deletions

View File

@ -11,6 +11,11 @@ class AutoConf :
self.__sites = {} self.__sites = {}
self.__config = Config(self.__swarm, api) 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) : def reload(self) :
return self.__config.reload(self.__instances) return self.__config.reload(self.__instances)
@ -38,6 +43,7 @@ class AutoConf :
self.__process_server(server, "start", id, name, labels) self.__process_server(server, "start", id, name, labels)
def process(self, obj, event) : def process(self, obj, event) :
utils.log("process - " + event)
(id, name, labels) = self.__get_infos(obj) (id, name, labels) = self.__get_infos(obj)
if "bunkerized-nginx.AUTOCONF" in labels : if "bunkerized-nginx.AUTOCONF" in labels :
self.__process_instance(obj, event, id, name, labels) self.__process_instance(obj, event, id, name, labels)
@ -60,9 +66,9 @@ class AutoConf :
self.__instances[id] = instance self.__instances[id] = instance
if self.__swarm and len(self.__instances) == 1 : if self.__swarm and len(self.__instances) == 1 :
if self.__config.initconf(self.__instances) : if self.__config.initconf(self.__instances) :
utils.log("[*] initial config succeeded") utils.log("[*] Initial config succeeded")
else : else :
utils.log("[!] initial config failed") utils.log("[!] Initial config failed")
utils.log("[*] bunkerized-nginx instance created : " + name + " / " + id) utils.log("[*] bunkerized-nginx instance created : " + name + " / " + id)
elif event == "start" : elif event == "start" :
self.__instances[id].reload() self.__instances[id].reload()
@ -82,6 +88,7 @@ class AutoConf :
def __process_server(self, instance, event, id, name, labels) : 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.")} vars = { k.replace("bunkerized-nginx.", "", 1) : v for k, v in labels.items() if k.startswith("bunkerized-nginx.")}
if event == "create" : if event == "create" :
utils.log("[*] Generating config for " + vars["SERVER_NAME"] + " ...")
if self.__config.generate(self.__instances, vars) : if self.__config.generate(self.__instances, vars) :
utils.log("[*] Generated config for " + vars["SERVER_NAME"]) utils.log("[*] Generated config for " + vars["SERVER_NAME"])
self.__servers[id] = instance self.__servers[id] = instance
@ -95,6 +102,7 @@ class AutoConf :
elif event == "start" : elif event == "start" :
if id in self.__servers : if id in self.__servers :
self.__servers[id].reload() self.__servers[id].reload()
utils.log("[*] Activating config for " + vars["SERVER_NAME"] + " ...")
if self.__config.activate(self.__instances, vars) : if self.__config.activate(self.__instances, vars) :
utils.log("[*] Activated config for " + vars["SERVER_NAME"]) utils.log("[*] Activated config for " + vars["SERVER_NAME"])
else : else :
@ -102,18 +110,22 @@ class AutoConf :
elif event == "die" : elif event == "die" :
if id in self.__servers : if id in self.__servers :
self.__servers[id].reload() self.__servers[id].reload()
utils.log("[*] Deactivating config for " + vars["SERVER_NAME"])
if self.__config.deactivate(self.__instances, vars) : if self.__config.deactivate(self.__instances, vars) :
utils.log("[*] Deactivated config for " + vars["SERVER_NAME"]) utils.log("[*] Deactivated config for " + vars["SERVER_NAME"])
else : else :
utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"]) utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"])
elif event == "destroy" or event == "remove" : elif event == "destroy" or event == "remove" :
utils.log(event)
if id in self.__servers : if id in self.__servers :
if self.__swarm : if self.__swarm :
utils.log("[*] Deactivating config for " + vars["SERVER_NAME"])
if self.__config.deactivate(self.__instances, vars) : if self.__config.deactivate(self.__instances, vars) :
utils.log("[*] Deactivated config for " + vars["SERVER_NAME"]) utils.log("[*] Deactivated config for " + vars["SERVER_NAME"])
else : else :
utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"]) utils.log("[!] Can't deactivate config for " + vars["SERVER_NAME"])
del self.__servers[id] del self.__servers[id]
utils.log("[*] Removing config for " + vars["SERVER_NAME"])
if self.__config.remove(vars) : if self.__config.remove(vars) :
utils.log("[*] Removed config for " + vars["SERVER_NAME"]) utils.log("[*] Removed config for " + vars["SERVER_NAME"])
else : else :

View File

@ -20,25 +20,42 @@ class Config :
var = var_value.split("=")[0] var = var_value.split("=")[0]
value = var_value.replace(var + "=", "", 1) value = var_value.replace(var + "=", "", 1)
vars[var] = value vars[var] = value
if self.globalconf(instances) :
i = 0 utils.log("[*] Generating global config ...")
started = False if not self.globalconf(instances) :
while i < 10 : utils.log("[!] Can't generate global config")
if self.__ping(instances) : return False
started = True utils.log("[*] Generated global config")
break
i = i + 1 if "SERVER_NAME" in vars and vars["SERVER_NAME"] != "" :
utils.log("[!] Waiting " + str(i) + " seconds before retrying to contact nginx instances") for server in vars["SERVER_NAME"].split(" ") :
time.sleep(i) vars_site = vars.copy()
if started : vars_site["SERVER_NAME"] = server
proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/jobs.sh", "nginx"], env=vars, capture_output=True) utils.log("[*] Generating config for " + vars["SERVER_NAME"] + " ...")
return proc.returncode == 0 if not self.generate(instances, vars_site) or not self.activate(instances, vars_site, reload=False) :
else : utils.log("[!] Can't generate/activate site config for " + server)
utils.log("[!] bunkerized-nginx instances are not started") 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 : else :
utils.log("[!] Can't generate global conf") utils.log("[!] bunkerized-nginx tasks are not started")
except Exception as e : except Exception as e :
traceback.print_exc()
utils.log("[!] Error while initializing config : " + str(e)) utils.log("[!] Error while initializing config : " + str(e))
return False return False
@ -54,12 +71,11 @@ class Config :
vars[var] = value vars[var] = value
proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/global-config.sh", "nginx"], env=vars, capture_output=True) proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/global-config.sh", "nginx"], env=vars, capture_output=True)
if proc.returncode == 0 : if proc.returncode == 0 :
with open("/etc/nginx/autoconf", "w") as f :
f.write("ok")
return True return True
else :
utils.log("[*] Error while generating global config : return code = " + str(proc.returncode))
except Exception as e : except Exception as e :
traceback.print_exc() utils.log("[!] Exception while generating global config : " + str(e))
utils.log("[!] Error while generating global config : " + str(e))
return False return False
def generate(self, instances, vars) : 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) 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 : 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) proc = subprocess.run(["/bin/su", "-s", "/opt/entrypoint/multisite-config.sh", "nginx"], env=vars_defaults, capture_output=True)
return proc.returncode == 0 if proc.returncode == 0 :
return 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 : except Exception as e :
traceback.print_exc() utils.log("[!] Exception while generating site config : " + str(e))
utils.log("[!] Error while generating site config : " + str(e))
return False return False
def activate(self, instances, vars) : def activate(self, instances, vars, reload=True) :
try : try :
# Check if file exists # Check if file exists
if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") :
@ -99,10 +115,13 @@ class Config :
# Include the server conf # Include the server conf
utils.replace_in_file("/etc/nginx/nginx.conf", "}", "include /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf;\n}") 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 : except Exception as e :
traceback.print_exc() utils.log("[!] Exception while activating config : " + str(e))
utils.log("[!] Error while activating config : " + str(e))
return False return False
def deactivate(self, instances, vars) : def deactivate(self, instances, vars) :
@ -115,14 +134,16 @@ class Config :
# Remove the include # Remove the include
utils.replace_in_file("/etc/nginx/nginx.conf", "include /etc/nginx/" + vars["SERVER_NAME"] + "/server.conf;\n", "") 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 : except Exception as e :
traceback.print_exc() utils.log("[!] Exception while deactivating config : " + str(e))
utils.log("[!] Error while deactivating config : " + str(e))
return False return False
def remove(self, instances, vars) : def remove(self, vars) :
try : try :
# Check if file exists # Check if file exists
if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") : if not os.path.isfile("/etc/nginx/" + vars["SERVER_NAME"] + "/server.conf") :
@ -134,6 +155,7 @@ class Config :
return True return True
except Exception as e : except Exception as e :
utils.log("[!] Error while deactivating config : " + str(e)) utils.log("[!] Error while deactivating config : " + str(e))
return False return False
def reload(self, instances) : def reload(self, instances) :
@ -149,7 +171,7 @@ class Config :
instance.reload() instance.reload()
# Reload via API # Reload via API
if self.__swarm : 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 name = instance.name
for task in instance.tasks() : for task in instance.tasks() :
if task["Status"]["State"] != "running" : if task["Status"]["State"] != "running" :

View File

@ -44,6 +44,7 @@ with lock :
# Process events received from Docker # Process events received from Docker
try : try :
utils.log("[*] Listening for Docker events ...")
for event in client.events(decode=True) : for event in client.events(decode=True) :
# Process only container/service events # Process only container/service events
@ -53,11 +54,15 @@ try :
# Get Container/Service object # Get Container/Service object
try : try :
if swarm : 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 : else :
server = client.containers.get(event["id"]) id = event["id"]
server = client.containers.get(id)
except docker.errors.NotFound as e : except docker.errors.NotFound as e :
continue server = autoconf.get_server(id)
if not server :
continue
# Process the event # Process the event
with lock : with lock :