-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtaskmaster.py
More file actions
154 lines (138 loc) · 5.74 KB
/
taskmaster.py
File metadata and controls
154 lines (138 loc) · 5.74 KB
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
from os import umask
from commands import *
import sys
import json
import threading
import signal
from pre_execution import *
from execution import *
import logging
conf_class = []
class config:
def __init__(self, param):
self.name = param[0]
self.cmd = param[1]
self.numprocs = param[2]
self.autostart = param[3]
self.autorestart = param[4]
self.starttime = param[5]
self.stoptime = param[6]
self.restartretries = param[7]
self.stopsig = param[8]
self.exitcodes = param[9]
self.workingdir = param[10]
self.umask = param[11]
self.stdout = param[12]
self.stderr = param[13]
self.env = param[14]
self.proc = None
self.status = None
self.checked = 0
self.thread = None
self.pid = 0
self.exitcode = "?"
self._hash = hash(self.hash_it())
def hash_it(self):
return (
str(self.name)+str(self.cmd)+str(self.numprocs)+str(self.autostart)+str(self.autorestart)+str(self.starttime)
+str(self.stoptime) + str(self.restartretries)+str(self.stopsig)+str(self.exitcodes)+str(self.workingdir)+str(self.umask)
+str(self.stdout)+str(self.env))
class parse:
def __init__(self, file_name):
self.file_name = file_name
self.json_data = self.open_file()
self.config_dict = []
self.config_class = self.parse_json()
self.validate_file()
def open_file(self):
try:
with open(self.file_name, "r") as file:
return (json.load(file))
except Exception as e:
print(e)
exit(1)
def parse_json(self):
self.config_class = []
for item in self.json_data:
self.config_dict = []
self.config_dict.append(item)
for cmd in self.json_data[item]:
self.config_dict.append(self.json_data[item][cmd])
for i in range(0, self.json_data[item]["numprocs"]):
self.config_class.append(config(self.config_dict))
return self.config_class
def param_error(self, cmd, value):
print("Parameter {0} has in invalid value {1}.".format(cmd, value))
exit(1)
def validate_file(self):
for command in self.config_class:
if not isinstance(command.cmd, str) :
return self.param_error("cmd", command.cmd)
if not isinstance(command.numprocs, int) :
return self.param_error("numprocs", command.numprocs)
if not isinstance(command.autostart, bool) :
return self.param_error("autostart", command.autostart)
if not isinstance(command.autorestart, str) :
return self.param_error("autorestart", command.autorestart)
if not isinstance(command.starttime, int) :
return self.param_error("starttime", command.starttime)
if not isinstance(command.stoptime, int) :
return self.param_error("stoptime", command.stoptime)
if not isinstance(command.restartretries, int) :
return self.param_error("restartretries", command.restartretries)
if not isinstance(command.stopsig, int) :
return self.param_error("stopsig", command.stopsig)
if not isinstance(command.exitcodes, list) and isinstance(command.exitcodes, str) is False :
return self.param_error("exitcodes", command.exitcodes)
if not isinstance(command.workingdir, str) :
return self.param_error("workingdir", command.workingdir)
if not isinstance(command.umask, str) :
return self.param_error("umask", command.umask)
if not isinstance(command.stdout, str) :
return self.param_error("stdout", command.stdout)
if not isinstance(command.stderr, str) :
return self.param_error("stderr", command.stderr)
if not isinstance(command.env, list) and isinstance(command.env, str) is False :
return self.param_error("env", command.env)
def deamon_loop(procs):
while (1):
for cmd in procs:
execution(cmd, "watch")
def handler(sig, frame):
logging.info("Signal handler triggred.")
commands("reload", conf_class)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python taskmaster.py config_file")
else:
logging.basicConfig(filename=f'{"log.txt"}', level=logging.DEBUG,
filemode='w',
format='%(asctime)s %(levelname)s\t%(message)s')
logging.info("Logging is Started.")
proc_class = []
cfile = parse(sys.argv[1])
logging.info("Config file is loaded sucessfully.")
cfile = pre_execution(cfile)
logging.info("Executing commands.")
for cmd in cfile.config_class:
execution(cmd, "execute")
j = 1
for i in range(0, len(cfile.config_class)):
cfile.config_class[i].name += "_" + str(j)
if j == cfile.config_class[i].numprocs:
j = 1
else:
j += 1
thread = threading.Thread(target=deamon_loop, args=[cfile.config_class], name='Thread-1')
thread.daemon = True
thread.start()
logging.info("Deamon started sucessfully.")
signal.signal(signal.SIGHUP, handler)
while (1):
conf_class = cfile.config_class
line = input(colors.bold + colors.cyan + "TaskMaster$ " + colors.endc)
if line == "":
continue
commands(line.rstrip(), cfile.config_class)
if line != "\n":
logging.info("Userinput: {0}".format(line))