forked from jumpserver/jumpserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
receptor
executable file
·168 lines (141 loc) · 5.1 KB
/
receptor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env python3
# coding: utf-8
import argparse
import logging
import os
import shutil
import signal
import subprocess
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)