Fix non salt daemons support

This commit is contained in:
Pedro Algarvio 2020-04-09 12:20:02 +01:00 committed by Daniel Wozniak
parent e157459016
commit 113effec7b

View file

@ -11,24 +11,19 @@ import logging
import os
import pprint
import shutil
import subprocess
import sys
import tempfile
import textwrap
import threading
import time
import psutil
import salt.ext.six as six
import salt.utils.files
import salt.utils.path
import salt.utils.yaml
from salt.fileserver import gitfs
from salt.pillar import git_pillar
from saltfactories.utils.processes.bases import FactoryDaemonScriptBase
from saltfactories.utils.processes.helpers import start_daemon as sf_start_daemon
from saltfactories.utils.processes.helpers import terminate_process
from saltfactories.utils.processes.salts import (
SaltDaemonScriptBase as _SaltDaemonScriptBase,
)
from tests.support.case import ModuleCase
from tests.support.helpers import (
get_unused_localhost_port,
@ -44,6 +39,12 @@ from tests.support.mock import patch
from tests.support.runtests import RUNTIME_VARS
from tests.support.unit import SkipTest
try:
import psutil
except ImportError:
pass
log = logging.getLogger(__name__)
USERNAME = "gitpillaruser"
@ -84,147 +85,28 @@ PROC_TIMEOUT = 10
def start_daemon(
daemon_cli_script_name,
daemon_config_dir,
daemon_check_port,
daemon_class,
fail_hard=False,
start_timeout=10,
slow_stop=True,
environ=None,
cwd=None,
max_attempts=3,
**kwargs
daemon_cli_script_name, daemon_class, config_dir=None, check_port=None
):
"""
Returns a running process daemon
"""
log.info("[%s] Starting %s", daemon_class.log_prefix, daemon_class.__name__)
attempts = 0
process = None
while attempts <= max_attempts: # pylint: disable=too-many-nested-blocks
attempts += 1
process = daemon_class(
str(daemon_config_dir),
daemon_check_port,
cli_script_name=daemon_cli_script_name,
slow_stop=slow_stop,
environ=environ,
cwd=cwd,
**kwargs
)
process.start()
if process.is_alive():
try:
connectable = process.wait_until_running(timeout=start_timeout)
if connectable is False:
connectable = process.wait_until_running(timeout=start_timeout / 2)
if connectable is False:
process.terminate()
if attempts >= max_attempts:
raise AssertionError(
"The {} has failed to confirm running status "
"after {} attempts".format(
daemon_class.__name__, attempts
)
)
continue
except Exception as exc: # pylint: disable=broad-except
log.exception("[%s] %s", daemon_class.log_prefix, exc, exc_info=True)
terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
if attempts >= max_attempts:
raise AssertionError(str(exc))
continue
# A little breathing before returning the process
time.sleep(0.5)
log.info(
"[%s] The %s is running after %d attempts",
daemon_class.log_prefix,
daemon_class.__name__,
attempts,
)
break
else:
terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
time.sleep(1)
continue
else:
if process is not None:
terminate_process(process.pid, kill_children=True, slow_stop=slow_stop)
raise AssertionError(
"The {} has failed to start after {} attempts".format(
daemon_class.__name__, attempts - 1
)
)
return process
return sf_start_daemon(
None,
daemon_cli_script_name,
daemon_class,
config_dir=config_dir,
check_port=check_port,
)
class SaltDaemonScriptBase(_SaltDaemonScriptBase):
def start(self):
"""
Start the daemon subprocess
"""
# Late import
log.info(
"[%s][%s] Starting DAEMON in CWD: %s",
self.log_prefix,
self.cli_display_name,
self.cwd,
)
proc_args = (
[self.get_script_path(self.cli_script_name)]
+ self.get_base_script_args()
+ self.get_script_args()
)
if sys.platform.startswith("win"):
# Windows needs the python executable to come first
proc_args.insert(0, sys.executable)
log.info(
"[%s][%s] Running '%s'...",
self.log_prefix,
self.cli_display_name,
" ".join(proc_args),
)
self.init_terminal(
proc_args,
env=self.environ,
cwd=self.cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
self._running.set()
if self._process_cli_output_in_thread:
process_output_thread = threading.Thread(
target=self._process_output_in_thread
)
process_output_thread.daemon = True
process_output_thread.start()
return True
class UwsgiDaemon(SaltDaemonScriptBase):
log_prefix = "uWSGI"
def __init__(self, config_dir, uwsgi_port, cli_script_name="uwsgi", **kwargs):
super(UwsgiDaemon, self).__init__(
None, # request
{"check_port": uwsgi_port}, # config
config_dir, # config_dir
None, # bin_dir_path
self.__class__.log_prefix, # log_prefix
cli_script_name=cli_script_name,
**kwargs
)
def get_script_path(self, script_name):
"""
Returns the path to the script to run
"""
return script_name
class UwsgiDaemon(FactoryDaemonScriptBase):
def __init__(self, *args, **kwargs):
config_dir = kwargs.pop("config_dir")
check_port = kwargs.pop("check_port")
super(UwsgiDaemon, self).__init__(*args, **kwargs)
self.config_dir = config_dir
self.check_port = check_port
self.log_prefix = "[uWSGI]"
def get_base_script_args(self):
"""
@ -236,38 +118,17 @@ class UwsgiDaemon(SaltDaemonScriptBase):
"""
Return a list of ports to check against to ensure the daemon is running
"""
return [self.config["check_port"]]
def get_salt_run_event_listener(self):
# Remove this method once pytest-salt get's past 2019.7.20
# Just return a class with a terminate method
class EV(object):
def terminate(self):
pass
return EV()
return [self.check_port]
class NginxDaemon(SaltDaemonScriptBase):
log_prefix = "Nginx"
def __init__(self, config_dir, nginx_port, cli_script_name="nginx", **kwargs):
super(NginxDaemon, self).__init__(
None, # request
{"check_port": nginx_port}, # config
config_dir, # config_dir
None, # bin_dir_path
self.__class__.log_prefix, # log_prefix
cli_script_name=cli_script_name,
**kwargs
)
def get_script_path(self, script_name):
"""
Returns the path to the script to run
"""
return script_name
class NginxDaemon(FactoryDaemonScriptBase):
def __init__(self, *args, **kwargs):
config_dir = kwargs.pop("config_dir")
check_port = kwargs.pop("check_port")
super(NginxDaemon, self).__init__(*args, **kwargs)
self.config_dir = config_dir
self.check_port = check_port
self.log_prefix = "[Nginx]"
def get_base_script_args(self):
"""
@ -279,38 +140,17 @@ class NginxDaemon(SaltDaemonScriptBase):
"""
Return a list of ports to check against to ensure the daemon is running
"""
return [self.config["check_port"]]
def get_salt_run_event_listener(self):
# Remove this method once pytest-salt get's past 2019.7.20
# Just return a class with a terminate method
class EV(object):
def terminate(self):
pass
return EV()
return [self.check_port]
class SshdDaemon(SaltDaemonScriptBase):
log_prefix = "SSHD"
def __init__(self, config_dir, sshd_port, cli_script_name="sshd", **kwargs):
super(SshdDaemon, self).__init__(
None, # request
{"check_port": sshd_port}, # config
config_dir, # config_dir
None, # bin_dir_path
self.__class__.log_prefix, # log_prefix
cli_script_name=cli_script_name,
**kwargs
)
def get_script_path(self, script_name):
"""
Returns the path to the script to run
"""
return script_name
class SshdDaemon(FactoryDaemonScriptBase):
def __init__(self, *args, **kwargs):
config_dir = kwargs.pop("config_dir")
check_port = kwargs.pop("check_port")
super(SshdDaemon, self).__init__(*args, **kwargs)
self.config_dir = config_dir
self.check_port = check_port
self.log_prefix = "[SSHD]"
def get_base_script_args(self):
"""
@ -322,16 +162,7 @@ class SshdDaemon(SaltDaemonScriptBase):
"""
Return a list of ports to check against to ensure the daemon is running
"""
return [self.config["check_port"]]
def get_salt_run_event_listener(self):
# Remove this method once pytest-salt get's past 2019.7.20
# Just return a class with a terminate method
class EV(object):
def terminate(self):
pass
return EV()
return [self.check_port]
class SaltClientMixin(ModuleCase):
@ -433,7 +264,10 @@ class SSHDMixin(SaltClientMixin, SaltReturnAssertsMixin):
cls.sshd_proc = None
if cls.sshd_proc is None:
cls.sshd_proc = start_daemon(
cls.sshd_bin, cls.sshd_config_dir, cls.sshd_port, SshdDaemon
cls.sshd_bin,
SshdDaemon,
config_dir=cls.sshd_config_dir,
check_port=cls.sshd_port,
)
log.info("%s: sshd started", cls.__name__)
except AssertionError:
@ -593,7 +427,10 @@ class WebserverMixin(SaltClientMixin, SaltReturnAssertsMixin):
cls.uwsgi_proc = None
if cls.uwsgi_proc is None:
cls.uwsgi_proc = start_daemon(
cls.uwsgi_bin, cls.config_dir, cls.uwsgi_port, UwsgiDaemon
cls.uwsgi_bin,
UwsgiDaemon,
config_dir=cls.config_dir,
check_port=cls.uwsgi_port,
)
log.info("%s: %s started", cls.__name__, cls.uwsgi_bin)
if cls.nginx_proc is not None:
@ -605,7 +442,10 @@ class WebserverMixin(SaltClientMixin, SaltReturnAssertsMixin):
cls.nginx_proc = None
if cls.nginx_proc is None:
cls.nginx_proc = start_daemon(
"nginx", cls.config_dir, cls.nginx_port, NginxDaemon
"nginx",
NginxDaemon,
config_dir=cls.config_dir,
check_port=cls.nginx_port,
)
log.info("%s: nginx started", cls.__name__)
except AssertionError: