|
@@ -10,6 +10,7 @@ import logging
|
10
|
10
|
import re
|
11
|
11
|
import json
|
12
|
12
|
import configparser
|
|
13
|
+import signal
|
13
|
14
|
import subprocess
|
14
|
15
|
|
15
|
16
|
logging.basicConfig(level=logging.INFO)
|
|
@@ -176,7 +177,7 @@ def validate_names(names):
|
176
|
177
|
def get_pids():
|
177
|
178
|
if not os.path.isfile(PID_FILE):
|
178
|
179
|
return dict()
|
179
|
|
- with open(PID_FILE, 'r') as pdf:
|
|
180
|
+ with open(PID_FILE, 'r') as pfd:
|
180
|
181
|
return json.load(pfd)
|
181
|
182
|
|
182
|
183
|
##@brief Save a dict of pid
|
|
@@ -196,7 +197,7 @@ def get_pid(name):
|
196
|
197
|
|
197
|
198
|
##@brief Start an instance
|
198
|
199
|
#@param names list : instance name list
|
199
|
|
-def start_instance(names):
|
|
200
|
+def start_instances(names):
|
200
|
201
|
pids = get_pids()
|
201
|
202
|
store_datas = get_store_datas()
|
202
|
203
|
|
|
@@ -209,6 +210,17 @@ def start_instance(names):
|
209
|
210
|
curexec = subprocess.Popen(args)
|
210
|
211
|
pids[name] = curexec.pid
|
211
|
212
|
logging.info("Instance '%s' started. PID %d" % (name, curexec.pid))
|
|
213
|
+ save_pids(pids)
|
|
214
|
+
|
|
215
|
+def stop_instances(names):
|
|
216
|
+ pids = get_pids()
|
|
217
|
+ store_datas = get_store_datas()
|
|
218
|
+ for name in names:
|
|
219
|
+ if name not in pids:
|
|
220
|
+ logging.warning("The instance %s is not running" % name)
|
|
221
|
+ continue
|
|
222
|
+ pid = pids[name]
|
|
223
|
+ os.kill(pid, signal.SIGINT)
|
212
|
224
|
|
213
|
225
|
##@brief Check if instance are specified
|
214
|
226
|
def get_specified(args):
|
|
@@ -254,8 +266,11 @@ def list_instances(verbosity, batch):
|
254
|
266
|
def details_instance(name, verbosity, batch):
|
255
|
267
|
validate_names([name])
|
256
|
268
|
store_datas = get_store_datas()
|
|
269
|
+ pids = get_pids()
|
257
|
270
|
if not batch:
|
258
|
271
|
msg = "\t- '%s'" % name
|
|
272
|
+ if name in pids:
|
|
273
|
+ msg += ' [Run PID %d] ' % pids[name]
|
259
|
274
|
if verbosity > 0:
|
260
|
275
|
msg += ' path = "%s"' % store_datas[name]['path']
|
261
|
276
|
if verbosity > 1:
|
|
@@ -308,6 +323,9 @@ def get_parser():
|
308
|
323
|
actions.add_argument('-d', '--delete', action='store_const',
|
309
|
324
|
default=False, const=True,
|
310
|
325
|
help="Delete an instance with given name (see -n --name)")
|
|
326
|
+ actions.add_argument('-p', '--purge', action='store_const',
|
|
327
|
+ default=False, const=True,
|
|
328
|
+ help="Delete ALL instances")
|
311
|
329
|
actions.add_argument('-s', '--set-option', action='store_const',
|
312
|
330
|
default=False, const=True,
|
313
|
331
|
help="Use this flag to set options on instance")
|
|
@@ -354,8 +372,23 @@ if __name__ == '__main__':
|
354
|
372
|
exit(1)
|
355
|
373
|
for name in args.name:
|
356
|
374
|
new_instance(name)
|
|
375
|
+ elif args.purge:
|
|
376
|
+ print("Are you sure ? Yes/no ",)
|
|
377
|
+ rep = sys.stdin.read()
|
|
378
|
+ if rep == 'Yes':
|
|
379
|
+ store = get_store_datas()
|
|
380
|
+ for name in store:
|
|
381
|
+ delete_instance(name)
|
|
382
|
+ elif rep.lower() != 'no':
|
|
383
|
+ print("Expect exactly 'Yes' to confirm...")
|
|
384
|
+ exit()
|
357
|
385
|
elif args.delete:
|
358
|
386
|
#Instance deletion
|
|
387
|
+ if args.all:
|
|
388
|
+ parser.print_help()
|
|
389
|
+ print("\n use -p --purge instead of --delete --all",
|
|
390
|
+ file=sys.stderr)
|
|
391
|
+ exit(1)
|
359
|
392
|
if args.name is None:
|
360
|
393
|
parser.print_help()
|
361
|
394
|
print("\nAn instance name expected when creating an instance !",
|
|
@@ -415,5 +448,8 @@ or with -a)")
|
415
|
448
|
set_conf(name, args)
|
416
|
449
|
elif args.start:
|
417
|
450
|
names = get_specified(args)
|
418
|
|
- start_instance(names)
|
|
451
|
+ start_instances(names)
|
|
452
|
+ elif args.stop:
|
|
453
|
+ names = get_specified(args)
|
|
454
|
+ stop_instances(names)
|
419
|
455
|
|