mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Fix non salt daemons support
This commit is contained in:
parent
e157459016
commit
113effec7b
1 changed files with 55 additions and 215 deletions
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue