/usr/lib/imh-ultrastack-common/venv/lib/python3.13/site-packages/ngxconf
NameSizeModeActions
__pycache__/-0755rm
builder.py318650644editdlrm
cli.py99970644editdlrm
control.py74070644editdlrm
cpfpm.py99180644editdlrm
fpm.py156450644editdlrm
masters.py67570644editdlrm
util.py132480644editdlrm
__init__.py66500644editdlrm
Edit: /usr/lib/imh-ultrastack-common/venv/lib/python3.13/site-packages/ngxconf/masters.py (6757B)
# vim: set ts=4 sw=4 expandtab syntax=python: """ ngxconf.masters FPM Masters: Supervisord XML-RPC Interface & Config Management Copyright (c) 2018-2020 InMotion Hosting, Inc. http://www.inmotionhosting.com/ @author J. Hipps """ # pylint: disable=invalid-name import os import logging from xmlrpc.client import ServerProxy import arrow try: from supervisor.xmlrpc import SupervisorTransport except ImportError: SupervisorTransport = None from ngxconf import __version__, __date__ from ngxconf.util import load_template, gconf logger = logging.getLogger('ngxconf') class Supervisor(object): """ Class for wrapping supervisord communications and managing PHP-FPM masters """ sockpath = None rpc = None connected = False template = None confpath = "/opt/ngxconf/supervisord/conf.d" def __init__(self, sockpath='/var/run/supervisord-fpm.sock'): self.sockpath = sockpath if SupervisorTransport is None: logger.error("supervisor module missing from imh-ultrastack-common venv at /usr/lib/imh-ultrastack-common/venv") else: self.connect() def connect(self): """ Initialize supervisord XMLRPC connection via UNIX socket """ try: self.rpc = ServerProxy('http://localhost', transport=SupervisorTransport(None, None, serverurl='unix://' + self.sockpath)) except Exception as e: logger.error("Failed to spawn XMLRPC connection to supervisord: %s", str(e)) self.connected = False return False # Check to ensure connection is established try: cstate = self.rpc.supervisor.getState() spid = self.rpc.supervisor.getPID() logger.debug("Connected to supervisord (pid %d) on %s [state: %s (%s)]", spid, self.sockpath, cstate['statename'], cstate['statecode']) except Exception as e: logger.error("Failed to connect to supervisord master at %s: %s", self.sockpath, str(e)) self.connected = False return False if cstate['statecode'] != 1: logger.warning("Supervisord is in state %s (%s)", cstate['statename'], cstate['statecode']) self.connected = True return True def update_config(self, reload_list=None): """ Reload supervisord configuration, and start/stop/restart process groups accordingly If @reload_list is set, it should be a list [] of vhosts that this function will ensure get restarted """ if not self.connected: logger.error("supervisord: Not connected, unable to reload config") return -1 try: added, changed, removed = self.rpc.supervisor.reloadConfig()[0] logger.debug("supervisord: reloadConfig: %d added / %d changed / %d removed", len(added), len(changed), len(removed)) except Exception as e: self.connected = False logger.error("supervisord: Failed to reload config: %s", str(e)) return -1 fails = 0 # ensure we have a connection self.rpc.supervisor.getState() changeset = set(changed) if reload_list: changeset.update(reload_list) changeset = changeset.difference(added) for tgroup in removed: logger.info("supervisord: ProcessGroup removed: %s", tgroup) try: self.rpc.supervisor.stopProcessGroup(tgroup) self.rpc.supervisor.removeProcessGroup(tgroup) changeset.discard(tgroup) except Exception: # Not counted as a failure, since it should already be removed pass for tgroup in changeset: logger.info("supervisord: ProcessGroup changed: %s", tgroup) try: self.rpc.supervisor.stopProcessGroup(tgroup) self.rpc.supervisor.removeProcessGroup(tgroup) self.rpc.supervisor.addProcessGroup(tgroup) self.rpc.supervisor.startProcessGroup(tgroup, False) except Exception as e: logger.error("Failed to change ProcessGroup %s: %s", tgroup, str(e)) fails += 1 for tgroup in added: logger.info("supervisord: ProcessGroup added: %s", tgroup) try: self.rpc.supervisor.addProcessGroup(tgroup) self.rpc.supervisor.startProcessGroup(tgroup, False) except Exception as e: logger.error("Failed to add ProcessGroup %s: %s", tgroup, str(e)) fails += 1 logger.info("supervisord: Reload complete (%d failures)", fails) return fails def get_info(self): """ Return status of all ProcessGroups """ return self.rpc.supervisor.getAllProcessInfo() def render_config(self, pgname, binpath, confpath): """ Render config file for ProcessGroup @pgname """ if not self.template: self.template = load_template('user_supervisor') outconf = os.path.join(self.confpath, pgname + '.conf') phpconf = os.path.join(gconf.fpm_conf_path, pgname + '.conf') # render with Jinja2 try: ttext = self.template.render(tstamp=arrow.now().format(), poolname=pgname, php_binpath=binpath, php_confpath=phpconf, ngxconf_ver="%s (%s)" % (__version__, __date__)) except Exception as e: logger.error("Failed to render supervisord template for %s: %s", pgname, str(e)) return False # write new include file try: with open(outconf, 'w') as f: f.write(ttext) logger.debug("Rendered supervisord config for %s to %s", pgname, outconf) except Exception as e: logger.error("Failed to render template to file %s: %s", outconf, str(e)) return False return True def restart_group(self, pgname): self.stop_group(pgname) return self.start_group(pgname) def stop_group(self, pgname): try: self.rpc.stopProccessGroup(pgname) except Exception as e: logger.error("Failed to stop ProcessGroup %s: %s", pgname, str(e)) return False return True def start_group(self, pgname): try: self.rpc.startProccessGroup(pgname) except Exception as e: logger.error("Failed to start ProcessGroup %s: %s", pgname, str(e)) return False return True