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
|
#!/usr/bin/env python3.5
# -*- mode: python -*-
# Copyright 2012-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Script to start services, tail logs, and stop services at the end.
Service names should be provided on the command-line.
If a service name is preceded by a "+" (plus) it is started in the
foreground. For example, to start the `rackd` service in the background
and `regiond` in the foreground:
$ services/run rackd +regiond
It does not matter if a service name appears twice in the list. If the service
name appears once with a preceding "+" and once without, the "+" one takes
precedence, and that service will be started in the foreground. Only one
service may be started in the foreground.
If no service has a preceding "+" then all the services named are started and
their logs tailed.
"""
from contextlib import contextmanager
from os.path import join
from subprocess import (
CalledProcessError,
check_call,
)
from sys import (
argv,
stderr,
)
@contextmanager
def service(services):
started = []
try:
for service in services:
control(service, "start")
started.append(service)
yield
finally:
for service in started:
control(service, "stop")
def control(service, action):
stderr.write("--> %s `%s`\n" % (action.capitalize(), service))
return check_call(
("make", "--no-print-directory",
"services/%s/@%s" % (service, action)))
def tail_logs(services):
command = ["tail", "--follow=name", "--retry", "--"]
command.extend(
join("logs", service, "current")
for service in services)
check_call(command)
if __name__ == "__main__":
if len(argv) == 1:
raise SystemExit(__doc__)
services_bg = {name for name in argv[1:] if not name.startswith("+")}
services_fg = {name[1:] for name in argv[1:] if name.startswith("+")}
services_bg = services_bg - services_fg
service_fg = services_fg.pop() if services_fg else None
if len(services_fg) != 0:
raise SystemExit("Only zero or one foreground services permitted.")
try:
with service(services_bg):
if service_fg:
control(service_fg, "run")
else:
tail_logs(services_bg)
except CalledProcessError as error:
raise SystemExit(error.returncode)
except KeyboardInterrupt:
pass # Ignore.
|