def nginx_restart(nginx_ctl, nginx_conf): """Restarts the Nginx Server. .. todo:: Nginx restart is fatal if the configuration references non-existent SSL cert/key files. Remove references to /etc/letsencrypt before restart. :param str nginx_ctl: Path to the Nginx binary. """ try: proc = subprocess.Popen([nginx_ctl, "-c", nginx_conf, "-s", "reload"], env=util.env_no_snap_for_external_calls()) proc.communicate() if proc.returncode != 0: # Maybe Nginx isn't running # Write to temporary files instead of piping because of communication issues on Arch # https://github.com/certbot/certbot/issues/4324 with tempfile.TemporaryFile() as out: with tempfile.TemporaryFile() as err: nginx_proc = subprocess.Popen([nginx_ctl, "-c", nginx_conf], stdout=out, stderr=err, env=util.env_no_snap_for_external_calls()) nginx_proc.communicate() if nginx_proc.returncode != 0: # Enter recovery routine... raise errors.MisconfigurationError( "nginx restart failed:\n%s\n%s" % (out.read(), err.read())) except (OSError, ValueError): raise errors.MisconfigurationError("nginx restart failed") # Nginx can take a moment to recognize a newly added TLS SNI servername, so sleep # for a second. TODO: Check for expected servername and loop until it # appears or return an error if looping too long. time.sleep(1)
def nginx_restart(nginx_ctl, nginx_conf, sleep_duration): """Restarts the Nginx Server. .. todo:: Nginx restart is fatal if the configuration references non-existent SSL cert/key files. Remove references to /etc/letsencrypt before restart. :param str nginx_ctl: Path to the Nginx binary. :param str nginx_conf: Path to the Nginx configuration file. :param int sleep_duration: How long to sleep after sending the reload signal. """ try: reload_output = u"" # type: Text with tempfile.TemporaryFile() as out: proc = subprocess.Popen( [nginx_ctl, "-c", nginx_conf, "-s", "reload"], env=util.env_no_snap_for_external_calls(), stdout=out, stderr=out) proc.communicate() out.seek(0) reload_output = out.read().decode("utf-8") if proc.returncode != 0: logger.debug("nginx reload failed:\n%s", reload_output) # Maybe Nginx isn't running - try start it # Write to temporary files instead of piping because of communication issues on Arch # https://github.com/certbot/certbot/issues/4324 with tempfile.TemporaryFile() as out: nginx_proc = subprocess.Popen( [nginx_ctl, "-c", nginx_conf], stdout=out, stderr=out, env=util.env_no_snap_for_external_calls()) nginx_proc.communicate() if nginx_proc.returncode != 0: out.seek(0) # Enter recovery routine... raise errors.MisconfigurationError( "nginx restart failed:\n%s" % out.read().decode("utf-8")) except (OSError, ValueError): raise errors.MisconfigurationError("nginx restart failed") # Nginx can take a significant duration of time to fully apply a new config, depending # on size and contents (https://github.com/certbot/certbot/issues/7422). Lacking a way # to reliably identify when this process is complete, we provide the user with control # over how long Certbot will sleep after reloading the configuration. if sleep_duration > 0: time.sleep(sleep_duration)
def _get_runtime_cfg(command: List[str]) -> str: """ Get runtime configuration info. :param command: Command to run :returns: stdout from command """ try: proc = subprocess.run( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, check=False, env=util.env_no_snap_for_external_calls()) stdout, stderr = proc.stdout, proc.stderr except (OSError, ValueError): logger.error( "Error running command %s for runtime parameters!%s", command, os.linesep) raise errors.MisconfigurationError( "Error accessing loaded Apache parameters: {0}".format( command)) # Small errors that do not impede if proc.returncode != 0: logger.warning("Error in checking parameter list: %s", stderr) raise errors.MisconfigurationError( "Apache is unable to check whether or not the module is " "loaded because Apache is misconfigured.") return stdout
def _run_hook(cmd_name, shell_cmd): """Run a hook command. :param str cmd_name: the user facing name of the hook being run :param shell_cmd: shell command to execute :type shell_cmd: `list` of `str` or `str` :returns: stderr if there was any""" err, _ = misc.execute_command(cmd_name, shell_cmd, env=util.env_no_snap_for_external_calls()) return err
def _execute_hook(self, hook_name: str, achall_domain: str) -> Tuple[str, str]: returncode, err, out = misc.execute_command_status( self.option_name(hook_name), self.conf(hook_name), env=util.env_no_snap_for_external_calls() ) display_ops.report_executed_command( f"Hook '--manual-{hook_name}' for {achall_domain}", returncode, out, err) return err, out
def _run_hook(cmd_name: str, shell_cmd: str) -> str: """Run a hook command. :param str cmd_name: the user facing name of the hook being run :param shell_cmd: shell command to execute :type shell_cmd: `list` of `str` or `str` :returns: stderr if there was any""" returncode, err, out = misc.execute_command_status( cmd_name, shell_cmd, env=util.env_no_snap_for_external_calls()) display_ops.report_executed_command(f"Hook '{cmd_name}'", returncode, out, err) return err
def __init__(self, enforce_openssl_binary_usage: bool = False) -> None: self.broken = False self.use_openssl_binary = enforce_openssl_binary_usage or not ocsp if self.use_openssl_binary: if not util.exe_exists("openssl"): logger.info("openssl not installed, can't check revocation") self.broken = True return # New versions of openssl want -header var=val, old ones want -header var val test_host_format = subprocess.run(["openssl", "ocsp", "-header", "var", "val"], stdout=PIPE, stderr=PIPE, universal_newlines=True, check=False, env=util.env_no_snap_for_external_calls()) if "Missing =" in test_host_format.stderr: self.host_args = lambda host: ["Host=" + host] else: self.host_args = lambda host: ["Host", host]
def _nginx_version(self): """Return results of nginx -V :returns: version text :rtype: str :raises .PluginError: Unable to run Nginx version command """ try: proc = subprocess.Popen( [self.conf('ctl'), "-c", self.nginx_conf, "-V"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, env=util.env_no_snap_for_external_calls()) text = proc.communicate()[1] # nginx prints output to stderr except (OSError, ValueError) as error: logger.debug(str(error), exc_info=True) raise errors.PluginError("Unable to run %s -V" % self.conf('ctl')) return text
def _call(cls): from certbot.util import env_no_snap_for_external_calls return env_no_snap_for_external_calls()
def _execute_hook(self, hook_name): return misc.execute_command(self.option_name(hook_name), self.conf(hook_name), env=util.env_no_snap_for_external_calls())