Support optional args for sessiond_spawn
[deliverable/lttng-ivc.git] / lttng_ivc / utils / utils.py
1 import signal
2 import hashlib
3 import os
4 import time
5 import socket
6
7 from lxml import etree
8 from contextlib import closing
9
10
11 def line_count(file_path):
12 line_count = 0
13 with open(file_path) as f:
14 for line in f:
15 line_count += 1
16 return line_count
17
18
19 def sha256_checksum(filename, block_size=65536):
20 sha256 = hashlib.sha256()
21 with open(filename, 'rb') as f:
22 for block in iter(lambda: f.read(block_size), b''):
23 sha256.update(block)
24 return sha256.hexdigest()
25
26
27 # TODO: timeout as a parameter or Settings
28 # TODO: Custom exception
29 def wait_for_file(path):
30 i = 0
31 timeout = 60
32 while not os.path.exists(path):
33 time.sleep(1)
34 i = i + 1
35 if i > timeout:
36 raise Exception("File still does not exists. Timeout expired")
37
38
39 # TODO: find better exception
40 def create_empty_file(path):
41 if os.path.exists(path):
42 raise Exception("Path already exist")
43 open(path, 'w').close()
44
45
46 def __dummy_sigusr1_handler():
47 pass
48
49
50 def sessiond_spawn(runtime, opt_args=""):
51 agent_port = find_free_port()
52 previous_handler = signal.signal(signal.SIGUSR1, __dummy_sigusr1_handler)
53 cmd = "lttng-sessiond -vvv --verbose-consumer -S --agent-tcp-port {}".format(agent_port)
54 cmd = " ".join([cmd, opt_args])
55 sessiond = runtime.spawn_subprocess(cmd)
56 signal.sigtimedwait({signal.SIGUSR1}, 60)
57 previous_handler = signal.signal(signal.SIGUSR1, previous_handler)
58 return sessiond
59
60
61 def relayd_spawn(runtime, url="localhost"):
62 """
63 Return a tuple (relayd_uuid, ctrl_port, data_port, live_port)
64 """
65 ports = find_multiple_free_port(3)
66 data_port = ports.pop()
67 ctrl_port = ports.pop()
68 live_port = ports.pop()
69
70 base_cmd = "lttng-relayd -vvv"
71 data_string = "-D tcp://{}:{}".format(url, data_port)
72 ctrl_string = "-C tcp://{}:{}".format(url, ctrl_port)
73 live_string = "-L tcp://{}:{}".format(url, live_port)
74
75 cmd = " ".join([base_cmd, data_string, ctrl_string, live_string])
76 relayd = runtime.spawn_subprocess(cmd)
77
78 # Synchronization based on verbosity since no -S is available for
79 # lttng-relayd yet.
80 log_path = runtime.get_subprocess_stderr_path(relayd)
81
82 # TODO: Move to settings.
83 ready_cue = "Listener accepting live viewers connections"
84 # TODO: Move to settings.
85 timeout = 60
86 ready = False
87 for i in range(timeout):
88 if file_contains(log_path, ready_cue):
89 ready = True
90 break
91 time.sleep(1)
92
93 if not ready:
94 # Cleanup is performed by runtime
95 raise Exception("Relayd readyness timeout expired")
96
97 return (relayd, ctrl_port, data_port, live_port)
98
99
100 def find_free_port():
101 # There is no guarantee that the port will be free at runtime but should be
102 # good enough
103 with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
104 s.bind(('', 0))
105 return s.getsockname()[1]
106
107
108 def find_multiple_free_port(number):
109 """
110 Return a list of supposedly free port
111 """
112 assert(number >= 0)
113 ports = []
114 while(len(ports) != number):
115 port = find_free_port()
116 if port in ports:
117 continue
118 ports.append(port)
119 return ports
120
121
122 def file_contains(file_path, list_of_string):
123 with open(file_path, 'r') as f:
124 for line in f:
125 for s in list_of_string:
126 if s in line:
127 return True
128
129
130 def find_dir(root, name):
131 """
132 Returns the absolute path or None.
133 """
134 abs_path = None
135 for base, dirs, files in os.walk(root):
136 for tmp in dirs:
137 if tmp.endswith(name):
138 abs_path = os.path.abspath(os.path.join(base, tmp))
139 return abs_path
140
141
142 def find_file(root, name):
143 """
144 Returns the absolute path or None.
145 """
146 abs_path = None
147 for base, dirs, files in os.walk(root):
148 for tmp in files:
149 if tmp.endswith(name):
150 abs_path = os.path.abspath(os.path.join(base, tmp))
151 return abs_path
152
153
154 def validate(xml_path, xsd_path):
155
156 xmlschema_doc = etree.parse(xsd_path)
157 xmlschema = etree.XMLSchema(xmlschema_doc)
158
159 xml_doc = etree.parse(xml_path)
160 result = xmlschema.validate(xml_doc)
161
162 return result
163
164 def xpath_query(xml_file, xpath):
165 """
166 Return a list of xml node corresponding to the xpath. The list can be of lenght
167 zero.
168 """
169 with open(xml_file, 'r') as f:
170 tree = etree.parse(f)
171 root = tree.getroot()
172 # Remove all namespace
173 # https://stackoverflow.com/questions/18159221/remove-namespace-and-prefix-from-xml-in-python-using-lxml
174 for elem in root.getiterator():
175 if not hasattr(elem.tag, 'find'):
176 continue
177 i = elem.tag.find('}')
178 if i >= 0:
179 elem.tag = elem.tag[i+1:]
180
181 return root.xpath(xpath)
This page took 0.032612 seconds and 5 git commands to generate.