root / snf-image-host / helper-monitor.py @ 13965151
History | View | Annotate | Download (4.2 kB)
1 | f32664b2 | Nikos Skalkotos | #!/usr/bin/env python
|
---|---|---|---|
2 | f32664b2 | Nikos Skalkotos | |
3 | f32664b2 | Nikos Skalkotos | # Copyright (C) 2012 GRNET S.A.
|
4 | f32664b2 | Nikos Skalkotos | #
|
5 | f32664b2 | Nikos Skalkotos | # This program is free software; you can redistribute it and/or modify
|
6 | f32664b2 | Nikos Skalkotos | # it under the terms of the GNU General Public License as published by
|
7 | f32664b2 | Nikos Skalkotos | # the Free Software Foundation; either version 2 of the License, or
|
8 | f32664b2 | Nikos Skalkotos | # (at your option) any later version.
|
9 | f32664b2 | Nikos Skalkotos | #
|
10 | f32664b2 | Nikos Skalkotos | # This program is distributed in the hope that it will be useful, but
|
11 | f32664b2 | Nikos Skalkotos | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 | f32664b2 | Nikos Skalkotos | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13 | f32664b2 | Nikos Skalkotos | # General Public License for more details.
|
14 | f32664b2 | Nikos Skalkotos | #
|
15 | f32664b2 | Nikos Skalkotos | # You should have received a copy of the GNU General Public License
|
16 | f32664b2 | Nikos Skalkotos | # along with this program; if not, write to the Free Software
|
17 | f32664b2 | Nikos Skalkotos | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
18 | f32664b2 | Nikos Skalkotos | # 02110-1301, USA.
|
19 | f32664b2 | Nikos Skalkotos | |
20 | f32664b2 | Nikos Skalkotos | import sys |
21 | f32664b2 | Nikos Skalkotos | import os |
22 | f32664b2 | Nikos Skalkotos | import time |
23 | f32664b2 | Nikos Skalkotos | import json |
24 | f32664b2 | Nikos Skalkotos | import re |
25 | f32664b2 | Nikos Skalkotos | |
26 | f32664b2 | Nikos Skalkotos | LINESIZE = 512
|
27 | 13965151 | Nikos Skalkotos | BUFSIZE = 512
|
28 | f32664b2 | Nikos Skalkotos | PROGNAME = os.path.basename(sys.argv[0])
|
29 | f32664b2 | Nikos Skalkotos | STDERR_MAXLINES = 10
|
30 | f32664b2 | Nikos Skalkotos | MAXLINES = 100
|
31 | 0b51f509 | Nikos Skalkotos | MSG_TYPE = 'image-helper'
|
32 | f32664b2 | Nikos Skalkotos | |
33 | f32664b2 | Nikos Skalkotos | PROTOCOL = { |
34 | f32664b2 | Nikos Skalkotos | 'TASK_START': ('task-start', 'task'), |
35 | f32664b2 | Nikos Skalkotos | 'TASK_END': ('task-end', 'task'), |
36 | f32664b2 | Nikos Skalkotos | 'WARNING': ('warning', 'msg'), |
37 | f32664b2 | Nikos Skalkotos | 'STDERR': ('error', 'stderr'), |
38 | f32664b2 | Nikos Skalkotos | 'ERROR': ('error', 'msg')} |
39 | f32664b2 | Nikos Skalkotos | |
40 | f32664b2 | Nikos Skalkotos | |
41 | f32664b2 | Nikos Skalkotos | def error(msg): |
42 | 73dddd66 | Nikos Skalkotos | sys.stderr.write("HELPER-MONITOR ERROR: %s\n" % msg)
|
43 | f32664b2 | Nikos Skalkotos | sys.exit(1)
|
44 | f32664b2 | Nikos Skalkotos | |
45 | f32664b2 | Nikos Skalkotos | |
46 | f32664b2 | Nikos Skalkotos | def send(fd, msg_type, value): |
47 | f32664b2 | Nikos Skalkotos | subtype, value_name = PROTOCOL[msg_type] |
48 | f32664b2 | Nikos Skalkotos | |
49 | f32664b2 | Nikos Skalkotos | msg = {} |
50 | 0b51f509 | Nikos Skalkotos | msg['type'] = MSG_TYPE
|
51 | f32664b2 | Nikos Skalkotos | msg['subtype'] = subtype
|
52 | f32664b2 | Nikos Skalkotos | msg[value_name] = value |
53 | f32664b2 | Nikos Skalkotos | msg['timestamp'] = time.time()
|
54 | f32664b2 | Nikos Skalkotos | os.write(fd, "%s\n" % json.dumps(msg))
|
55 | f32664b2 | Nikos Skalkotos | |
56 | f32664b2 | Nikos Skalkotos | |
57 | f32664b2 | Nikos Skalkotos | if __name__ == "__main__": |
58 | f32664b2 | Nikos Skalkotos | usage = "Usage: %s <file-descriptor>\n" % PROGNAME
|
59 | f32664b2 | Nikos Skalkotos | |
60 | f32664b2 | Nikos Skalkotos | if len(sys.argv) != 2: |
61 | f32664b2 | Nikos Skalkotos | sys.stderr.write(usage) |
62 | f32664b2 | Nikos Skalkotos | sys.exit(1)
|
63 | f32664b2 | Nikos Skalkotos | |
64 | f32664b2 | Nikos Skalkotos | try:
|
65 | f32664b2 | Nikos Skalkotos | fd = int(sys.argv[1]) |
66 | f32664b2 | Nikos Skalkotos | except ValueError: |
67 | f32664b2 | Nikos Skalkotos | error("File descriptor is not an integer")
|
68 | f32664b2 | Nikos Skalkotos | |
69 | f32664b2 | Nikos Skalkotos | try:
|
70 | f32664b2 | Nikos Skalkotos | os.fstat(fd) |
71 | f32664b2 | Nikos Skalkotos | except OSError: |
72 | f32664b2 | Nikos Skalkotos | error("File descriptor is not valid")
|
73 | f32664b2 | Nikos Skalkotos | |
74 | f32664b2 | Nikos Skalkotos | lines_left = 0
|
75 | f32664b2 | Nikos Skalkotos | line_count = 0
|
76 | 13965151 | Nikos Skalkotos | stderr = ""
|
77 | 13965151 | Nikos Skalkotos | line = ""
|
78 | 13965151 | Nikos Skalkotos | while True: |
79 | 13965151 | Nikos Skalkotos | # Can't use sys.stdin.readline since I want unbuffered I/O
|
80 | 13965151 | Nikos Skalkotos | new_data = os.read(sys.stdin.fileno(), BUFSIZE) |
81 | 13965151 | Nikos Skalkotos | |
82 | 13965151 | Nikos Skalkotos | if not new_data: |
83 | 13965151 | Nikos Skalkotos | if not line: |
84 | 13965151 | Nikos Skalkotos | break
|
85 | 13965151 | Nikos Skalkotos | else:
|
86 | 13965151 | Nikos Skalkotos | new_data = '\n'
|
87 | 13965151 | Nikos Skalkotos | |
88 | 13965151 | Nikos Skalkotos | while True: |
89 | 13965151 | Nikos Skalkotos | split = new_data.split('\n', 1) |
90 | 13965151 | Nikos Skalkotos | line += split[0]
|
91 | 13965151 | Nikos Skalkotos | if len(split) == 1: |
92 | 13965151 | Nikos Skalkotos | if len(line) > LINESIZE: |
93 | 13965151 | Nikos Skalkotos | error("Line size exceeded the maximum allowed size")
|
94 | 13965151 | Nikos Skalkotos | break
|
95 | 13965151 | Nikos Skalkotos | |
96 | 13965151 | Nikos Skalkotos | new_data = split[1]
|
97 | f32664b2 | Nikos Skalkotos | |
98 | f32664b2 | Nikos Skalkotos | line_count += 1
|
99 | 13965151 | Nikos Skalkotos | if line_count >= MAXLINES + 1: |
100 | 13965151 | Nikos Skalkotos | error("Exceeded maximum allowed number of lines: %d." %
|
101 | 13965151 | Nikos Skalkotos | MAXLINES) |
102 | f32664b2 | Nikos Skalkotos | |
103 | f32664b2 | Nikos Skalkotos | if lines_left > 0: |
104 | 13965151 | Nikos Skalkotos | stderr += "%s\n" % line
|
105 | f32664b2 | Nikos Skalkotos | lines_left -= 1
|
106 | 13965151 | Nikos Skalkotos | if lines_left == 0: |
107 | 13965151 | Nikos Skalkotos | send(fd, "STDERR", stderr)
|
108 | 13965151 | Nikos Skalkotos | stderr = ""
|
109 | 13965151 | Nikos Skalkotos | line = ""
|
110 | 13965151 | Nikos Skalkotos | continue
|
111 | 13965151 | Nikos Skalkotos | |
112 | 13965151 | Nikos Skalkotos | line = line.strip() |
113 | 13965151 | Nikos Skalkotos | if len(line) == 0: |
114 | 13965151 | Nikos Skalkotos | continue
|
115 | 13965151 | Nikos Skalkotos | |
116 | 13965151 | Nikos Skalkotos | if line.startswith("STDERR:"): |
117 | 13965151 | Nikos Skalkotos | m = re.match("STDERR:(\d+):(.*)", line)
|
118 | 13965151 | Nikos Skalkotos | if not m: |
119 | 13965151 | Nikos Skalkotos | error("Invalid syntax for STDERR line")
|
120 | 13965151 | Nikos Skalkotos | try:
|
121 | 13965151 | Nikos Skalkotos | lines_left = int(m.group(1)) |
122 | 13965151 | Nikos Skalkotos | except ValueError: |
123 | 13965151 | Nikos Skalkotos | error("Second field in STDERR line must be an integer")
|
124 | 13965151 | Nikos Skalkotos | |
125 | 13965151 | Nikos Skalkotos | if lines_left > STDERR_MAXLINES:
|
126 | 13965151 | Nikos Skalkotos | error("Too many lines in the STDERR output")
|
127 | 13965151 | Nikos Skalkotos | elif lines_left < 0: |
128 | 13965151 | Nikos Skalkotos | error("Second field of STDERR: %d is invalid" % lines_left)
|
129 | 13965151 | Nikos Skalkotos | |
130 | 13965151 | Nikos Skalkotos | if lines_left > 0: |
131 | 13965151 | Nikos Skalkotos | stderr = m.group(2) + "\n" |
132 | 13965151 | Nikos Skalkotos | lines_left -= 1
|
133 | 13965151 | Nikos Skalkotos | |
134 | 13965151 | Nikos Skalkotos | if lines_left == 0: |
135 | 13965151 | Nikos Skalkotos | send(fd, "STDERR", stderr)
|
136 | 13965151 | Nikos Skalkotos | stderr = ""
|
137 | 13965151 | Nikos Skalkotos | elif line.startswith("TASK_START:") \ |
138 | 13965151 | Nikos Skalkotos | or line.startswith("TASK_END:") \ |
139 | 13965151 | Nikos Skalkotos | or line.startswith("WARNING:") \ |
140 | 13965151 | Nikos Skalkotos | or line.startswith("ERROR:"): |
141 | 13965151 | Nikos Skalkotos | (msg_type, _, value) = line.partition(':')
|
142 | 13965151 | Nikos Skalkotos | send(fd, msg_type, value) |
143 | 13965151 | Nikos Skalkotos | else:
|
144 | 13965151 | Nikos Skalkotos | error("Unknown command!")
|
145 | 13965151 | Nikos Skalkotos | |
146 | 13965151 | Nikos Skalkotos | # Remove the processed line
|
147 | 13965151 | Nikos Skalkotos | line = ""
|
148 | f32664b2 | Nikos Skalkotos | |
149 | f32664b2 | Nikos Skalkotos | # vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |