mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 12:03:46 +00:00 
			
		
		
		
	These are available in Python ≥ 3.9. https://docs.python.org/3/library/stdtypes.html#str.removeprefix Signed-off-by: Anders Kaseorg <anders@zulip.com>
		
			
				
	
	
		
			78 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import socket
 | |
| import time
 | |
| from http.client import HTTPConnection
 | |
| from xmlrpc import client
 | |
| 
 | |
| from typing_extensions import override
 | |
| 
 | |
| 
 | |
| class UnixStreamHTTPConnection(HTTPConnection):
 | |
|     @override
 | |
|     def connect(self) -> None:
 | |
|         self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
 | |
|         connected = False
 | |
|         for i in range(2):
 | |
|             try:
 | |
|                 self.sock.connect(self.host)
 | |
|                 connected = True
 | |
|                 break
 | |
|             except FileNotFoundError:
 | |
|                 # Backoff and retry
 | |
|                 time.sleep(2**i)
 | |
|         if not connected:
 | |
|             raise Exception(
 | |
|                 "Failed to connect to supervisor -- check that it is running, by running 'service supervisor status'"
 | |
|             )
 | |
| 
 | |
| 
 | |
| class UnixStreamTransport(client.Transport):
 | |
|     def __init__(self, socket_path: str) -> None:
 | |
|         self.socket_path = socket_path
 | |
|         super().__init__()
 | |
| 
 | |
|     @override
 | |
|     def make_connection(self, host: tuple[str, dict[str, str]] | str) -> UnixStreamHTTPConnection:
 | |
|         return UnixStreamHTTPConnection(self.socket_path)
 | |
| 
 | |
| 
 | |
| def rpc() -> client.ServerProxy:
 | |
|     return client.ServerProxy(
 | |
|         "http://localhost", transport=UnixStreamTransport("/var/run/supervisor.sock")
 | |
|     )
 | |
| 
 | |
| 
 | |
| def list_supervisor_processes(
 | |
|     filter_names: list[str] | None = None, *, only_running: bool | None = None
 | |
| ) -> list[str]:
 | |
|     results = []
 | |
|     processes = rpc().supervisor.getAllProcessInfo()
 | |
|     assert isinstance(processes, list)
 | |
|     for process in processes:
 | |
|         if process["group"] != process["name"]:
 | |
|             name = f"{process['group']}:{process['name']}"
 | |
|         else:
 | |
|             name = process["name"]
 | |
| 
 | |
|         if filter_names:
 | |
|             match = False
 | |
|             for filter_name in filter_names:
 | |
|                 # zulip-tornado:* matches zulip-tornado:9800 and zulip-tornado
 | |
|                 if filter_name.endswith(":*") and (
 | |
|                     name.startswith(filter_name.removesuffix("*"))
 | |
|                     or name == filter_name.removesuffix(":*")
 | |
|                 ):
 | |
|                     match = True
 | |
|                     break
 | |
|                 if name == filter_name:
 | |
|                     match = True
 | |
|                     break
 | |
|             if not match:
 | |
|                 continue
 | |
| 
 | |
|         if only_running is None:
 | |
|             results.append(name)
 | |
|         elif only_running == (process["statename"] in ("RUNNING", "STARTING")):
 | |
|             results.append(name)
 | |
| 
 | |
|     return results
 |