1
0
mirror of https://github.com/Mailu/Mailu.git synced 2025-05-29 23:07:50 +02:00
Mailu/core/nginx/certwatcher.py
Dario Ernst 09024c8008 Use environment variables for cert paths/names in nginx certwatcher
Previously, nginx certwatcher would only react to the hardcoded paths. It should have
honored the enviroment variables that are used by config.py too for this.

closes 
2020-03-07 17:17:17 +00:00

78 lines
2.8 KiB
Python
Executable File

#!/usr/bin/python3
"""
Certificate watcher which reloads nginx or reconfigures it, depending on what
happens to externally supplied certificates. Only executed by start.py in case
of TLS_FLAVOR=[mail, cert]
"""
from os.path import exists, split as path_split, join as path_join
from os import system, getenv
import time
from watchdog.observers.polling import PollingObserver
from watchdog.events import FileSystemEventHandler, FileDeletedEvent, \
FileCreatedEvent, FileModifiedEvent, FileMovedEvent
class ChangeHandler(FileSystemEventHandler):
"watchdog-handler listening on any event, executing the correct configuration/reload steps"
def __init__(self, cert_path, keypair_path):
"Initialize a new changehandler"""
super().__init__()
self.cert_path = cert_path
self.keypair_path = keypair_path
@staticmethod
def reload_nginx():
"merely reload nginx without re-configuring everything"
if exists("/var/run/nginx.pid"):
print("Reloading a running nginx")
system("nginx -s reload")
@staticmethod
def reexec_config():
"execute a reconfiguration of the system, which also reloads"
print("Reconfiguring system")
system("/config.py")
def on_any_event(self, event):
"event-listener checking if the affected files are the cert-files we're interested in"
if event.is_directory:
return
filename = event.src_path
if isinstance(event, FileMovedEvent):
filename = event.dest_path
if filename in [self.cert_path, self.keypair_path]:
# all cases except for FileModified need re-configure
if isinstance(event, (FileCreatedEvent, FileMovedEvent, FileDeletedEvent)):
ChangeHandler.reexec_config()
# file modification needs only a nginx reload without config.py
elif isinstance(event, FileModifiedEvent):
ChangeHandler.reload_nginx()
# cert files have been moved away, re-configure
elif isinstance(event, FileMovedEvent) and event.src_path in [self.cert_path, self.keypair_path]:
ChangeHandler.reexec_config()
if __name__ == '__main__':
cert_path = path_join("/certs/", getenv("TLS_CERT_FILENAME", default="cert.pem"))
cert_dir = path_split(cert_path)[0]
keypair_path = path_join("/certs/", getenv("TLS_KEYPAIR_FILENAME", default="key.pem"))
keypair_dir = path_split(keypair_path)[0]
observer = PollingObserver()
handler = ChangeHandler(cert_path, keypair_path)
observer.schedule(handler, cert_dir, recursive=False)
if keypair_dir != cert_dir:
observer.schedule(handler, keypair_dir, recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()