mirror of
				https://github.com/optim-enterprises-bv/Mailu.git
				synced 2025-11-04 03:57:53 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			81 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env 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")
 | 
						|
        if os.path.exists("/run/dovecot/master.pid"):
 | 
						|
            print("Reloading a running dovecot")
 | 
						|
            os.system("doveadm 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()
 |