/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/cli.py (9997B)
#!/opt/imh-python/bin/python3.9 # vim: set ts=4 sw=4 expandtab syntax=python: """ ngxconf.cli Command-line functions & CLI entry-point Copyright (c) 2017-2020 InMotion Hosting, Inc. http://www.inmotionhosting.com/ @author J. Hipps """ import sys import os import time import logging import logging.handlers from argparse import ArgumentParser, Action import yaml from ngxconf import builder, fpm, control from ngxconf.util import parse_user_default_conf, parse_profiles, get_profile, gconf, excepthook, NGXDumper from ngxconf import __version__, __date__ logger = logging.getLogger('ngxconf') class SafeStoreAction(Action): def __init__(self, option_strings, dest, nargs=None, **kwargs): super(SafeStoreAction, self).__init__(option_strings, dest, **kwargs) def __call__(self, parser, namespace, values, option_string=None): is_safe = False if 'SUDO_UID' in os.environ: if os.environ['SUDO_UID'] == '0': is_safe = True else: is_safe = False else: is_safe = True if is_safe: setattr(namespace, self.dest, values) else: print("ERROR: Attempted to set dangerous option as a non-root sudoer! Aborting.") sys.exit(249) def setup_logging(clevel=logging.INFO, flevel=logging.DEBUG, logfile='/var/log/ngxconf.log'): """ Setup logging """ logger.setLevel(logging.DEBUG) # Console con = logging.StreamHandler() con.setLevel(clevel) con_format = logging.Formatter("%(levelname)s: %(message)s") con.setFormatter(con_format) logger.addHandler(con) # File try: flog = logging.handlers.WatchedFileHandler(logfile) flog.setLevel(flevel) flog_format = logging.Formatter("[%(asctime)s] %(name)s (%(process)d): %(levelname)s: %(message)s") flog.setFormatter(flog_format) logger.addHandler(flog) except Exception as e: logger.warning("Failed to open logfile: %s", str(e)) def parse_cli(show_help=False): """ Parse CLI arguments """ parser = ArgumentParser(description="Nginx user configuration builder for cPanel") parser.set_defaults(rebuildall=False, force=False, reload=False, user=None, outfile=None, defaults=False, skipcheck=False, loglevel=logging.INFO, logfile='/var/log/ngxconf.log', nofpm=False, nohttpd=False) parser.add_argument('--rebuildall', '-R', action='store_true', help="Rebuild configuration for all users whose configuration has changed") parser.add_argument('--force', '-F', action='store_true', help="Force rebuild even if the configuration has not changed") parser.add_argument('--reload', '-r', action='store_true', help="Sends a SIGUSR2 signal to Nginx master process to reload the running config") parser.add_argument('--user', '-u', action='store', metavar="USER", help="Specify user. Configuration will only be built for this user") parser.add_argument('--defaults', action='store_true', help="Replace all of a user's config files with defaults") parser.add_argument('--skipcheck', action='store_true', help="Skip Nginx config validation") parser.add_argument('--nofpm', action='store_true', help="Skip PHP-FPM rebuild and reload") parser.add_argument('--skipfpmbuild', action='store_true', help="Do not trigger /scripts/php_fpm_config --rebuild") parser.add_argument('--nohttpd', action='store_true', help="Skip Apache HTTPd reload") parser.add_argument('--skiphttpdbuild', action='store_true', help="Do not trigger /scripts/rebuildhttpdconf") parser.add_argument('--fork', action='store_true', help="Fork into the background; suppress all messages to stderr") parser.add_argument('--showconf', action='store_true', help="Output combined global configuration") parser.add_argument('--showprofile', action='store', metavar="PROF_ID", help="Output combined profile by ID") parser.add_argument('--outfile', '-f', action='store', metavar="PATH", help="Specify output file when building configuration for a single user") parser.add_argument('--logfile', '-l', action=SafeStoreAction, metavar="PATH", help="Log output file") parser.add_argument('--debug', '-d', dest='loglevel', action='store_const', const=logging.DEBUG, help="Enable debug output") parser.add_argument('--version', '-v', action='version', version="%s (%s)" % (__version__, __date__)) if show_help: parser.print_help() sys.exit(1) return parser.parse_args() def do_fork(): """ When --fork is used, ngxconf will fork into the background to complete its task """ logger.info("Forking into background...") try: # first fork pid = os.fork() except Exception as e: logger.error("os.fork() failed, aborting: %s", str(e)) sys.exit(251) if (pid == 0): # become parent of session & process group os.setsid() try: # second fork pid = os.fork() except Exception as e: logger.error("os.fork() [2] failed, aborting: %s", str(e)) sys.exit(251) if pid: # ... and kill the other parent os._exit(0) logger.debug("Forked into background. PID: %d", os.getpid()) try: # Redirect stdout & stderr to /dev/null sys.stdout.flush() sys.stdout = open(os.devnull, 'w') sys.stderr.flush() sys.stderr = open(os.devnull, 'w') # Redirect console logger to /dev/null logger.handlers[0].stream = open(os.devnull, 'w') except Exception as e: logger.error("Failed to redirect output streams: %s", str(e)) else: # otherwise, kill the parent; _exit() so we don't mess with any # open file handles or streams logger.info("Background job running. Exiting main process (PID %d)", os.getpid()) os._exit(0) def _main(): """ Entry point """ sys.excepthook = excepthook args = parse_cli() # NGX-37: suppress all console messages by default when using --fork # to prevent cPanel programs from failing (since they try to parse # JSON via stderr for some stupid reason) if args.fork and args.loglevel == logging.INFO: args.loglevel = logging.FATAL setup_logging(clevel=args.loglevel, flevel=logging.DEBUG, logfile=args.logfile) start_run = time.time() # Parse global config and additional user config files if gconf.apply_user_default_config: udefs = parse_user_default_conf() else: udefs = None parse_profiles() if args.showconf: print("---") print(yaml.dump(gconf._conf, Dumper=NGXDumper, default_flow_style=False)) return 0 elif args.showprofile: tprofile = get_profile(args.showprofile) if tprofile is not None: print("---") print(yaml.dump(tprofile, Dumper=NGXDumper, default_flow_style=False)) return 0 else: logger.error("Unable to locate profile: '%s'", args.showprofile) return 2 # Check for pause file - skip rebuild if exists pause_file = '/var/ngxconf/conf_pause_rebuild' if os.path.exists(pause_file): logger.info("Pause file found at %s; skipping configuration rebuild", pause_file) return 0 if args.user: if args.rebuildall: logger.error("Options --rebuildall and --user are mutually-exclusive") sys.exit(1) if args.fork: do_fork() changes = builder.rebuild_user(args.user, force=args.force, outfile=args.outfile, defaults=args.defaults, skip_fpm=args.nofpm, userdef=udefs) elif args.rebuildall: if args.defaults and not args.force: logger.error("CAUTION: Use of --defaults with --rebuildall will obliterate all user-defined settings " "for all users! Use of --force is required. Aborting.") sys.exit(1) if args.fork: do_fork() changes = builder.rebuild_all(force=args.force, defaults=args.defaults, skip_fpm=args.nofpm, userdef=udefs) else: parse_cli(show_help=True) return 1 # Check if services need to be reloaded retval = 0 if not changes: retval = 2 else: # Rebuild PHP-FPM config/pools if changes were made, # then rebuild/reload Apache if args.force or len(changes['fpm']) > 0: single_user = False if args.rebuildall else True if gconf.fpm_management == 'ngxconf': fpm.commit(args.force, single_user=args.user) if not args.skiphttpdbuild: control.cp_rebuild_httpd_conf(reload=not args.nohttpd) elif gconf.fpm_management == 'cpanel' and not args.skipfpmbuild: control.rebuild_phpfpm() if args.reload: control.restart_phpfpm() if not args.skiphttpdbuild: control.cp_rebuild_httpd_conf(reload=not args.nohttpd) # Check/reload Nginx if changes were made if args.force or len(changes['nginx']) > 0: if not args.skipcheck: if not control.check_nginx(): retval = 3 # Reload will only trigger if --reload is used if args.reload: control.reload_nginx() tot_run = time.time() - start_run logger.info("Finished run in %02.02f seconds", tot_run) return retval if __name__ == '__main__': sys.exit(_main())