autoconf - fix infinite lock and honor DOCKER_HOST env var
This commit is contained in:
parent
bc01427def
commit
5a26d06c87
@ -8,10 +8,10 @@ from logger import log
|
|||||||
|
|
||||||
class Config :
|
class Config :
|
||||||
|
|
||||||
def __init__(self, type, api_uri) :
|
def __init__(self, type, api_uri, lock=None) :
|
||||||
self.__type = type
|
self.__type = type
|
||||||
self.__api_uri = api_uri
|
self.__api_uri = api_uri
|
||||||
|
self.__lock = lock
|
||||||
|
|
||||||
def __jobs(self) :
|
def __jobs(self) :
|
||||||
log("config", "INFO", "starting jobs ...")
|
log("config", "INFO", "starting jobs ...")
|
||||||
@ -28,7 +28,13 @@ class Config :
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def gen(self, env) :
|
def gen(self, env) :
|
||||||
|
locked = False
|
||||||
try :
|
try :
|
||||||
|
# Lock
|
||||||
|
if self.__lock :
|
||||||
|
self.__lock.acquire()
|
||||||
|
locked = True
|
||||||
|
|
||||||
# Write environment variables to a file
|
# Write environment variables to a file
|
||||||
with open("/tmp/variables.env", "w") as f :
|
with open("/tmp/variables.env", "w") as f :
|
||||||
for k, v in env.items() :
|
for k, v in env.items() :
|
||||||
@ -37,6 +43,11 @@ class Config :
|
|||||||
# Call the generator
|
# Call the generator
|
||||||
proc = subprocess.run(["/bin/su", "-c", "/opt/bunkerized-nginx/gen/main.py --settings /opt/bunkerized-nginx/settings.json --templates /opt/bunkerized-nginx/confs --output /etc/nginx --variables /tmp/variables.env", "nginx"], capture_output=True)
|
proc = subprocess.run(["/bin/su", "-c", "/opt/bunkerized-nginx/gen/main.py --settings /opt/bunkerized-nginx/settings.json --templates /opt/bunkerized-nginx/confs --output /etc/nginx --variables /tmp/variables.env", "nginx"], capture_output=True)
|
||||||
|
|
||||||
|
# Unlock
|
||||||
|
if self.__lock :
|
||||||
|
self.__lock.release()
|
||||||
|
locked = False
|
||||||
|
|
||||||
# Print stdout/stderr
|
# Print stdout/stderr
|
||||||
stdout = proc.stdout.decode("ascii")
|
stdout = proc.stdout.decode("ascii")
|
||||||
stderr = proc.stderr.decode("ascii")
|
stderr = proc.stderr.decode("ascii")
|
||||||
@ -54,6 +65,8 @@ class Config :
|
|||||||
|
|
||||||
except Exception as e :
|
except Exception as e :
|
||||||
log("config", "ERROR", "exception while generating site config : " + traceback.format_exc())
|
log("config", "ERROR", "exception while generating site config : " + traceback.format_exc())
|
||||||
|
if locked :
|
||||||
|
self.__lock.release()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def reload(self, instances) :
|
def reload(self, instances) :
|
||||||
@ -121,6 +134,8 @@ class Config :
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def __api_call(self, instances, path) :
|
def __api_call(self, instances, path) :
|
||||||
|
if self.__lock :
|
||||||
|
self.__lock.acquire()
|
||||||
ret = True
|
ret = True
|
||||||
urls = []
|
urls = []
|
||||||
if self.__type == Controller.Type.SWARM :
|
if self.__type == Controller.Type.SWARM :
|
||||||
@ -146,4 +161,6 @@ class Config :
|
|||||||
else :
|
else :
|
||||||
log("config", "INFO", "failed API order to " + url)
|
log("config", "INFO", "failed API order to " + url)
|
||||||
ret = False
|
ret = False
|
||||||
|
if self.__lock :
|
||||||
|
self.__lock.release()
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class Type(Enum) :
|
|||||||
class Controller(ABC) :
|
class Controller(ABC) :
|
||||||
|
|
||||||
def __init__(self, type, api_uri=None, lock=None) :
|
def __init__(self, type, api_uri=None, lock=None) :
|
||||||
self._config = Config(type, api_uri)
|
self._config = Config(type, api_uri, lock)
|
||||||
self.lock = lock
|
self.lock = lock
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|||||||
@ -5,10 +5,9 @@ from logger import log
|
|||||||
|
|
||||||
class DockerController(Controller.Controller) :
|
class DockerController(Controller.Controller) :
|
||||||
|
|
||||||
def __init__(self) :
|
def __init__(self, docker_host) :
|
||||||
super().__init__(Controller.Type.DOCKER)
|
super().__init__(Controller.Type.DOCKER)
|
||||||
# TODO : honor env vars like DOCKER_HOST
|
self.__client = docker.DockerClient(base_url=docker_host)
|
||||||
self.__client = docker.DockerClient(base_url='unix:///var/run/docker.sock')
|
|
||||||
|
|
||||||
def __get_instances(self) :
|
def __get_instances(self) :
|
||||||
return self.__client.containers.list(filters={"label" : "bunkerized-nginx.AUTOCONF"})
|
return self.__client.containers.list(filters={"label" : "bunkerized-nginx.AUTOCONF"})
|
||||||
|
|||||||
@ -75,24 +75,20 @@ class IngressController(Controller.Controller) :
|
|||||||
def __watch_ingress(self) :
|
def __watch_ingress(self) :
|
||||||
w = watch.Watch()
|
w = watch.Watch()
|
||||||
for event in w.stream(self.__extensions_api.list_ingress_for_all_namespaces) :
|
for event in w.stream(self.__extensions_api.list_ingress_for_all_namespaces) :
|
||||||
self.lock.acquire()
|
|
||||||
new_env = self.get_env()
|
new_env = self.get_env()
|
||||||
if new_env != self.__old_env() :
|
if new_env != self.__old_env() :
|
||||||
if self.gen_conf(new_env, lock=False) :
|
if self.gen_conf(new_env, lock=False) :
|
||||||
self.__old_env = new_env.copy()
|
self.__old_env = new_env.copy()
|
||||||
log("CONTROLLER", "INFO", "successfully generated new configuration")
|
log("CONTROLLER", "INFO", "successfully generated new configuration")
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
def __watch_service(self) :
|
def __watch_service(self) :
|
||||||
w = watch.Watch()
|
w = watch.Watch()
|
||||||
for event in w.stream(self.__api.list_service_for_all_namespaces) :
|
for event in w.stream(self.__api.list_service_for_all_namespaces) :
|
||||||
self.lock.acquire()
|
|
||||||
new_env = self.get_env()
|
new_env = self.get_env()
|
||||||
if new_env != self.__old_env() :
|
if new_env != self.__old_env() :
|
||||||
if self.gen_conf(new_env, lock=False) :
|
if self.gen_conf(new_env, lock=False) :
|
||||||
self.__old_env = new_env.copy()
|
self.__old_env = new_env.copy()
|
||||||
log("CONTROLLER", "INFO", "successfully generated new configuration")
|
log("CONTROLLER", "INFO", "successfully generated new configuration")
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
def reload(self) :
|
def reload(self) :
|
||||||
return self._reload(self.__get_ingresses())
|
return self._reload(self.__get_ingresses())
|
||||||
|
|||||||
@ -7,10 +7,9 @@ import Controller
|
|||||||
|
|
||||||
class SwarmController(Controller.Controller) :
|
class SwarmController(Controller.Controller) :
|
||||||
|
|
||||||
def __init__(self, api_uri) :
|
def __init__(self, docker_host, api_uri) :
|
||||||
super().__init__(Controller.Type.SWARM, api_uri=api_uri, lock=Lock())
|
super().__init__(Controller.Type.SWARM, api_uri=api_uri, lock=Lock())
|
||||||
# TODO : honor env vars like DOCKER_HOST
|
self.__client = docker.DockerClient(base_url=docker_host)
|
||||||
self.__client = docker.DockerClient(base_url='unix:///var/run/docker.sock')
|
|
||||||
|
|
||||||
def __get_instances(self) :
|
def __get_instances(self) :
|
||||||
return self.__client.services.list(filters={"label" : "bunkerized-nginx.AUTOCONF"})
|
return self.__client.services.list(filters={"label" : "bunkerized-nginx.AUTOCONF"})
|
||||||
@ -45,7 +44,6 @@ class SwarmController(Controller.Controller) :
|
|||||||
for event in self.__client.events(decode=True, filters={"type": "service"}) :
|
for event in self.__client.events(decode=True, filters={"type": "service"}) :
|
||||||
new_env = self.get_env()
|
new_env = self.get_env()
|
||||||
if new_env != old_env :
|
if new_env != old_env :
|
||||||
self.lock.acquire()
|
|
||||||
log("controller", "INFO", "generating new configuration")
|
log("controller", "INFO", "generating new configuration")
|
||||||
if self.gen_conf(new_env) :
|
if self.gen_conf(new_env) :
|
||||||
old_env = new_env.copy()
|
old_env = new_env.copy()
|
||||||
@ -56,7 +54,6 @@ class SwarmController(Controller.Controller) :
|
|||||||
log("controller", "ERROR", "failed reload")
|
log("controller", "ERROR", "failed reload")
|
||||||
else :
|
else :
|
||||||
log("controller", "ERROR", "can't generate new configuration")
|
log("controller", "ERROR", "can't generate new configuration")
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
def reload(self) :
|
def reload(self) :
|
||||||
return self._reload(self.__get_instances())
|
return self._reload(self.__get_instances())
|
||||||
|
|||||||
@ -11,20 +11,21 @@ from IngressController import IngressController
|
|||||||
from logger import log
|
from logger import log
|
||||||
|
|
||||||
# Get variables
|
# Get variables
|
||||||
swarm = os.getenv("SWARM_MODE", "no") == "yes"
|
swarm = os.getenv("SWARM_MODE", "no") == "yes"
|
||||||
kubernetes = os.getenv("KUBERNETES_MODE", "no") == "yes"
|
kubernetes = os.getenv("KUBERNETES_MODE", "no") == "yes"
|
||||||
api_uri = os.getenv("API_URI", "")
|
api_uri = os.getenv("API_URI", "")
|
||||||
|
docker_host = os.getenv("DOCKER_HOST", "unix:///var/run/docker.sock")
|
||||||
|
|
||||||
# Instantiate the controller
|
# Instantiate the controller
|
||||||
if swarm :
|
if swarm :
|
||||||
log("autoconf", "INFO", "swarm mode detected")
|
log("autoconf", "INFO", "swarm mode detected")
|
||||||
controller = SwarmController(api_uri)
|
controller = SwarmController(docker_host, api_uri)
|
||||||
elif kubernetes :
|
elif kubernetes :
|
||||||
log("autoconf", "INFO", "kubernetes mode detected")
|
log("autoconf", "INFO", "kubernetes mode detected")
|
||||||
controller = IngressController(api_uri)
|
controller = IngressController(api_uri)
|
||||||
else :
|
else :
|
||||||
log("autoconf", "INFO", "docker mode detected")
|
log("autoconf", "INFO", "docker mode detected")
|
||||||
controller = DockerController()
|
controller = DockerController(docker_host)
|
||||||
|
|
||||||
# Run the reload server in background if needed
|
# Run the reload server in background if needed
|
||||||
if swarm or kubernetes :
|
if swarm or kubernetes :
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user