mirror of
				https://github.com/optim-enterprises-bv/Mailu.git
				synced 2025-10-31 18:18:05 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			81 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			2.9 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 exists("/run/dovecot/master.pid"):
 | |
|             print("Reloading a running dovecot")
 | |
|             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()
 | 
