mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.1 KiB
168 lines
5.1 KiB
#!/usr/bin/env python3 |
|
# coding: utf-8 |
|
|
|
import argparse |
|
import logging |
|
import shutil |
|
import subprocess |
|
import os |
|
import signal |
|
import tempfile |
|
|
|
from apps.libs.process.ssh import kill_ansible_ssh_process |
|
|
|
ANSIBLE_RUNNER_COMMAND = "ansible-runner" |
|
|
|
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
APPS_DIR = os.path.join(PROJECT_DIR, 'apps') |
|
TEMP_DIR = os.path.join(PROJECT_DIR, "tmp") |
|
|
|
DEFAULT_SHARE_DIR = os.path.join(PROJECT_DIR, "data", "share") |
|
DEFAULT_ANSIBLE_MODULES_DIR = os.path.join(APPS_DIR, "libs", "ansible", "modules") |
|
DEFAULT_CONTROL_SOCK_PATH = os.path.join(DEFAULT_SHARE_DIR, "control.sock") |
|
|
|
DEFAULT_TCP_LISTEN_ADDRESS = "0.0.0.0:7521" |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
os.chdir(APPS_DIR) |
|
|
|
|
|
class ReceptorService: |
|
def __init__(self): |
|
self.pid_file = os.path.join(TEMP_DIR, "receptor.pid") |
|
self.receptor_command = [ |
|
'receptor', |
|
'--local-only', |
|
'--node', 'id=primary', |
|
'--log-level', 'level=Error', |
|
'--control-service', |
|
'service=control', |
|
'tcplisten={}'.format(DEFAULT_TCP_LISTEN_ADDRESS), |
|
'--work-command', |
|
'worktype={}'.format(ANSIBLE_RUNNER_COMMAND), |
|
'command={}'.format(ANSIBLE_RUNNER_COMMAND), |
|
'params=worker', |
|
'allowruntimeparams=true', |
|
'--work-command', |
|
'worktype={}'.format("kill"), |
|
'command={}'.format("python"), |
|
"params={} kill".format(os.path.join(PROJECT_DIR, "receptor")), |
|
'allowruntimeparams=true' |
|
] |
|
|
|
|
|
@staticmethod |
|
def before_start(): |
|
os.makedirs(os.path.join(DEFAULT_SHARE_DIR), exist_ok=True) |
|
status_dir = os.path.join(tempfile.gettempdir(), "receptor") |
|
if os.path.exists(status_dir): |
|
shutil.rmtree(status_dir) |
|
|
|
def start(self): |
|
self.before_start() |
|
if os.path.exists(self.pid_file): |
|
with open(self.pid_file, 'r') as f: |
|
pid_str = f.read() |
|
try: |
|
pid = int(pid_str) |
|
os.kill(pid, 0) |
|
print("\n- Receptor service is already running.") |
|
return |
|
except ProcessLookupError: |
|
print("\n- PID file exists but process does not, starting Receptor...") |
|
except ValueError: |
|
print("\n- PID file is corrupted, starting Receptor...") |
|
os.remove(self.pid_file) |
|
|
|
os.environ.setdefault('ANSIBLE_LIBRARY', DEFAULT_ANSIBLE_MODULES_DIR) |
|
os.environ.update({'PYTHONPATH': APPS_DIR}) |
|
process = subprocess.Popen(self.receptor_command) |
|
with open(self.pid_file, 'w') as f: |
|
f.write(str(process.pid)) |
|
print("\n- Receptor service started successfully.") |
|
|
|
def exit_handler(signum, frame): |
|
process.terminate() |
|
process.kill() |
|
|
|
signal.signal(signal.SIGINT, exit_handler) |
|
signal.signal(signal.SIGTERM, exit_handler) |
|
process.wait() |
|
|
|
def stop(self): |
|
if not os.path.exists(self.pid_file): |
|
print("\n- Receptor service is not running.") |
|
return |
|
with open(self.pid_file, 'r') as f: |
|
pid = int(f.read()) |
|
try: |
|
os.kill(pid, signal.SIGTERM) |
|
os.remove(self.pid_file) |
|
print("\n- Receptor service stopped successfully.") |
|
except ProcessLookupError: |
|
print("\n- Failed to stop Receptor service: Process does not exist.") |
|
os.remove(self.pid_file) |
|
|
|
def restart(self): |
|
self.stop() |
|
self.start() |
|
|
|
def status(self): |
|
if os.path.exists(self.pid_file): |
|
with open(self.pid_file, 'r') as f: |
|
pid_str = f.read() |
|
try: |
|
pid = int(pid_str) |
|
os.kill(pid, 0) |
|
print("\n- Receptor service is running.") |
|
return |
|
except ProcessLookupError: |
|
print("\n- Receptor service is not running.") |
|
else: |
|
print("\n- Receptor service is not running.") |
|
|
|
|
|
def handle_receptor_action(args): |
|
action = args.action |
|
srv = ReceptorService() |
|
if action == "start": |
|
srv.start() |
|
elif action == 'stop': |
|
srv.stop() |
|
elif action == "restart": |
|
srv.restart() |
|
elif action == "status": |
|
srv.status() |
|
elif action == "kill": |
|
kill_progress_tree() |
|
|
|
|
|
def kill_progress_tree(pid=None): |
|
if not pid: |
|
try: |
|
pid_input = input() |
|
pid = int(pid_input) |
|
logger.info("progress {} will be kill".format(pid)) |
|
kill_ansible_ssh_process(pid) |
|
except Exception as e: |
|
logger.error(e) |
|
return |
|
|
|
|
|
if __name__ == '__main__': |
|
parser = argparse.ArgumentParser( |
|
description=""" |
|
Jumpserver receptor service control tools; |
|
""" |
|
) |
|
parser.add_argument( |
|
'action', type=str, |
|
choices=("start", "stop", "restart", "status", "kill"), |
|
help="Action to run" |
|
) |
|
|
|
# parser.add_argument('--pid', type=int, default=42, help='what PID you want to kill') |
|
|
|
args = parser.parse_args() |
|
handle_receptor_action(args)
|
|
|