]>
Commit | Line | Data |
---|---|---|
e0edde6f | 1 | # Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. |
99155935 BP |
2 | # |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | # you may not use this file except in compliance with the License. | |
5 | # You may obtain a copy of the License at: | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, | |
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | # See the License for the specific language governing permissions and | |
13 | # limitations under the License. | |
14 | ||
8ea171ab RB |
15 | from __future__ import print_function |
16 | ||
99155935 BP |
17 | import getopt |
18 | import re | |
19 | import os | |
20 | import signal | |
21 | import sys | |
8cdf0349 | 22 | import uuid |
99155935 BP |
23 | |
24 | from ovs.db import error | |
25 | import ovs.db.idl | |
26 | import ovs.db.schema | |
27 | from ovs.db import data | |
3c057118 | 28 | import ovs.db.types |
99155935 BP |
29 | import ovs.ovsuuid |
30 | import ovs.poller | |
31 | import ovs.util | |
cb96c1b2 | 32 | import six |
99155935 | 33 | |
26bb0f31 | 34 | |
99155935 BP |
35 | def unbox_json(json): |
36 | if type(json) == list and len(json) == 1: | |
37 | return json[0] | |
38 | else: | |
39 | return json | |
40 | ||
26bb0f31 | 41 | |
99155935 | 42 | def do_default_atoms(): |
3c057118 RB |
43 | for type_ in ovs.db.types.ATOMIC_TYPES: |
44 | if type_ == ovs.db.types.VoidType: | |
99155935 BP |
45 | continue |
46 | ||
8cdf0349 | 47 | sys.stdout.write("%s: " % type_.to_string()) |
99155935 | 48 | |
8cdf0349 BP |
49 | atom = data.Atom.default(type_) |
50 | if atom != data.Atom.default(type_): | |
99155935 BP |
51 | sys.stdout.write("wrong\n") |
52 | sys.exit(1) | |
53 | ||
54 | sys.stdout.write("OK\n") | |
55 | ||
26bb0f31 | 56 | |
99155935 BP |
57 | def do_default_data(): |
58 | any_errors = False | |
59 | for n_min in 0, 1: | |
3c057118 RB |
60 | for key in ovs.db.types.ATOMIC_TYPES: |
61 | if key == ovs.db.types.VoidType: | |
99155935 | 62 | continue |
3c057118 RB |
63 | for value in ovs.db.types.ATOMIC_TYPES: |
64 | if value == ovs.db.types.VoidType: | |
99155935 BP |
65 | valueBase = None |
66 | else: | |
3c057118 RB |
67 | valueBase = ovs.db.types.BaseType(value) |
68 | type_ = ovs.db.types.Type(ovs.db.types.BaseType(key), | |
69 | valueBase, n_min, 1) | |
8cdf0349 | 70 | assert type_.is_valid() |
99155935 BP |
71 | |
72 | sys.stdout.write("key %s, value %s, n_min %d: " | |
73 | % (key.to_string(), value.to_string(), n_min)) | |
74 | ||
8cdf0349 BP |
75 | datum = data.Datum.default(type_) |
76 | if datum != data.Datum.default(type_): | |
99155935 BP |
77 | sys.stdout.write("wrong\n") |
78 | any_errors = True | |
79 | else: | |
80 | sys.stdout.write("OK\n") | |
81 | if any_errors: | |
82 | sys.exit(1) | |
83 | ||
26bb0f31 | 84 | |
99155935 BP |
85 | def do_parse_atomic_type(type_string): |
86 | type_json = unbox_json(ovs.json.from_string(type_string)) | |
3c057118 | 87 | atomic_type = ovs.db.types.AtomicType.from_json(type_json) |
8ea171ab | 88 | print(ovs.json.to_string(atomic_type.to_json(), sort_keys=True)) |
99155935 | 89 | |
26bb0f31 | 90 | |
99155935 BP |
91 | def do_parse_base_type(type_string): |
92 | type_json = unbox_json(ovs.json.from_string(type_string)) | |
3c057118 | 93 | base_type = ovs.db.types.BaseType.from_json(type_json) |
8ea171ab | 94 | print(ovs.json.to_string(base_type.to_json(), sort_keys=True)) |
99155935 | 95 | |
26bb0f31 | 96 | |
99155935 BP |
97 | def do_parse_type(type_string): |
98 | type_json = unbox_json(ovs.json.from_string(type_string)) | |
3c057118 | 99 | type_ = ovs.db.types.Type.from_json(type_json) |
8ea171ab | 100 | print(ovs.json.to_string(type_.to_json(), sort_keys=True)) |
99155935 | 101 | |
26bb0f31 | 102 | |
99155935 BP |
103 | def do_parse_atoms(type_string, *atom_strings): |
104 | type_json = unbox_json(ovs.json.from_string(type_string)) | |
3c057118 | 105 | base = ovs.db.types.BaseType.from_json(type_json) |
99155935 BP |
106 | for atom_string in atom_strings: |
107 | atom_json = unbox_json(ovs.json.from_string(atom_string)) | |
108 | try: | |
109 | atom = data.Atom.from_json(base, atom_json) | |
8ea171ab | 110 | print(ovs.json.to_string(atom.to_json())) |
f3068bff | 111 | except error.Error as e: |
64eb96a9 | 112 | print(e.args[0]) |
99155935 | 113 | |
26bb0f31 | 114 | |
99155935 BP |
115 | def do_parse_data(type_string, *data_strings): |
116 | type_json = unbox_json(ovs.json.from_string(type_string)) | |
3c057118 | 117 | type_ = ovs.db.types.Type.from_json(type_json) |
99155935 BP |
118 | for datum_string in data_strings: |
119 | datum_json = unbox_json(ovs.json.from_string(datum_string)) | |
8cdf0349 | 120 | datum = data.Datum.from_json(type_, datum_json) |
8ea171ab | 121 | print(ovs.json.to_string(datum.to_json())) |
99155935 | 122 | |
26bb0f31 | 123 | |
99155935 BP |
124 | def do_sort_atoms(type_string, atom_strings): |
125 | type_json = unbox_json(ovs.json.from_string(type_string)) | |
3c057118 | 126 | base = ovs.db.types.BaseType.from_json(type_json) |
99155935 BP |
127 | atoms = [data.Atom.from_json(base, atom_json) |
128 | for atom_json in unbox_json(ovs.json.from_string(atom_strings))] | |
8ea171ab RB |
129 | print(ovs.json.to_string([data.Atom.to_json(atom) |
130 | for atom in sorted(atoms)])) | |
99155935 | 131 | |
26bb0f31 | 132 | |
99155935 BP |
133 | def do_parse_column(name, column_string): |
134 | column_json = unbox_json(ovs.json.from_string(column_string)) | |
135 | column = ovs.db.schema.ColumnSchema.from_json(column_json, name) | |
8ea171ab | 136 | print(ovs.json.to_string(column.to_json(), sort_keys=True)) |
99155935 | 137 | |
26bb0f31 | 138 | |
c5f341ab BP |
139 | def do_parse_table(name, table_string, default_is_root_string='false'): |
140 | default_is_root = default_is_root_string == 'true' | |
99155935 BP |
141 | table_json = unbox_json(ovs.json.from_string(table_string)) |
142 | table = ovs.db.schema.TableSchema.from_json(table_json, name) | |
8ea171ab | 143 | print(ovs.json.to_string(table.to_json(default_is_root), sort_keys=True)) |
99155935 | 144 | |
26bb0f31 | 145 | |
99155935 BP |
146 | def do_parse_schema(schema_string): |
147 | schema_json = unbox_json(ovs.json.from_string(schema_string)) | |
148 | schema = ovs.db.schema.DbSchema.from_json(schema_json) | |
8ea171ab | 149 | print(ovs.json.to_string(schema.to_json(), sort_keys=True)) |
99155935 | 150 | |
26bb0f31 | 151 | |
99155935 BP |
152 | def print_idl(idl, step): |
153 | n = 0 | |
80c12152 SA |
154 | if "simple" in idl.tables: |
155 | simple_columns = ["i", "r", "b", "s", "u", "ia", | |
156 | "ra", "ba", "sa", "ua", "uuid"] | |
157 | simple = idl.tables["simple"].rows | |
cb96c1b2 | 158 | for row in six.itervalues(simple): |
80c12152 SA |
159 | s = "%03d:" % step |
160 | for column in simple_columns: | |
161 | if hasattr(row, column) and not (type(getattr(row, column)) | |
162 | is ovs.db.data.Atom): | |
163 | s += " %s=%s" % (column, getattr(row, column)) | |
164 | s = re.sub('""|,|u?\'', "", s) | |
165 | s = re.sub('UUID\(([^)]+)\)', r'\1', s) | |
166 | s = re.sub('False', 'false', s) | |
167 | s = re.sub('True', 'true', s) | |
168 | s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s) | |
169 | print(s) | |
170 | n += 1 | |
171 | ||
172 | if "link1" in idl.tables: | |
173 | l1 = idl.tables["link1"].rows | |
cb96c1b2 | 174 | for row in six.itervalues(l1): |
80c12152 SA |
175 | s = ["%03d: i=%s k=" % (step, row.i)] |
176 | if hasattr(row, "k") and row.k: | |
177 | s.append(str(row.k.i)) | |
178 | if hasattr(row, "ka"): | |
179 | s.append(" ka=[") | |
180 | s.append(' '.join(sorted(str(ka.i) for ka in row.ka))) | |
181 | s.append("] l2=") | |
182 | if hasattr(row, "l2") and row.l2: | |
183 | s.append(str(row.l2[0].i)) | |
184 | if hasattr(row, "uuid"): | |
185 | s.append(" uuid=%s" % row.uuid) | |
186 | print(''.join(s)) | |
187 | n += 1 | |
188 | ||
189 | if "link2" in idl.tables: | |
190 | l2 = idl.tables["link2"].rows | |
cb96c1b2 | 191 | for row in six.itervalues(l2): |
80c12152 SA |
192 | s = ["%03d:" % step] |
193 | s.append(" i=%s l1=" % row.i) | |
194 | if hasattr(row, "l1") and row.l1: | |
195 | s.append(str(row.l1[0].i)) | |
196 | if hasattr(row, "uuid"): | |
197 | s.append(" uuid=%s" % row.uuid) | |
198 | print(''.join(s)) | |
199 | n += 1 | |
8cdf0349 | 200 | |
99155935 BP |
201 | if not n: |
202 | print("%03d: empty" % step) | |
8cdf0349 | 203 | sys.stdout.flush() |
99155935 | 204 | |
26bb0f31 | 205 | |
99155935 | 206 | def substitute_uuids(json, symtab): |
25f599fb | 207 | if isinstance(json, six.string_types): |
99155935 BP |
208 | symbol = symtab.get(json) |
209 | if symbol: | |
210 | return str(symbol) | |
211 | elif type(json) == list: | |
212 | return [substitute_uuids(element, symtab) for element in json] | |
213 | elif type(json) == dict: | |
214 | d = {} | |
cb96c1b2 | 215 | for key, value in six.iteritems(json): |
99155935 BP |
216 | d[key] = substitute_uuids(value, symtab) |
217 | return d | |
218 | return json | |
219 | ||
26bb0f31 | 220 | |
99155935 | 221 | def parse_uuids(json, symtab): |
25f599fb RB |
222 | if (isinstance(json, six.string_types) |
223 | and ovs.ovsuuid.is_valid_string(json)): | |
99155935 BP |
224 | name = "#%d#" % len(symtab) |
225 | sys.stderr.write("%s = %s\n" % (name, json)) | |
226 | symtab[name] = json | |
227 | elif type(json) == list: | |
228 | for element in json: | |
229 | parse_uuids(element, symtab) | |
230 | elif type(json) == dict: | |
cb96c1b2 | 231 | for value in six.itervalues(json): |
99155935 BP |
232 | parse_uuids(value, symtab) |
233 | ||
26bb0f31 | 234 | |
8cdf0349 | 235 | def idltest_find_simple(idl, i): |
cb96c1b2 | 236 | for row in six.itervalues(idl.tables["simple"].rows): |
8cdf0349 BP |
237 | if row.i == i: |
238 | return row | |
239 | return None | |
240 | ||
26bb0f31 | 241 | |
8cdf0349 BP |
242 | def idl_set(idl, commands, step): |
243 | txn = ovs.db.idl.Transaction(idl) | |
244 | increment = False | |
80c12152 | 245 | fetch_cmds = [] |
d7d417fc | 246 | events = [] |
8cdf0349 BP |
247 | for command in commands.split(','): |
248 | words = command.split() | |
249 | name = words[0] | |
250 | args = words[1:] | |
251 | ||
d7d417fc TW |
252 | if name == "notifytest": |
253 | name = args[0] | |
254 | args = args[1:] | |
255 | old_notify = idl.notify | |
256 | ||
257 | def notify(event, row, updates=None): | |
1aa2bf92 | 258 | if updates: |
cb96c1b2 | 259 | upcol = list(updates._data.keys())[0] |
1aa2bf92 AW |
260 | else: |
261 | upcol = None | |
d7d417fc TW |
262 | events.append("%s|%s|%s" % (event, row.i, upcol)) |
263 | idl.notify = old_notify | |
264 | ||
265 | idl.notify = notify | |
266 | ||
8cdf0349 BP |
267 | if name == "set": |
268 | if len(args) != 3: | |
269 | sys.stderr.write('"set" command requires 3 arguments\n') | |
270 | sys.exit(1) | |
271 | ||
272 | s = idltest_find_simple(idl, int(args[0])) | |
273 | if not s: | |
274 | sys.stderr.write('"set" command asks for nonexistent i=%d\n' | |
275 | % int(args[0])) | |
276 | sys.exit(1) | |
277 | ||
278 | if args[1] == "b": | |
279 | s.b = args[2] == "1" | |
280 | elif args[1] == "s": | |
281 | s.s = args[2] | |
282 | elif args[1] == "u": | |
283 | s.u = uuid.UUID(args[2]) | |
284 | elif args[1] == "r": | |
285 | s.r = float(args[2]) | |
286 | else: | |
287 | sys.stderr.write('"set" comamnd asks for unknown column %s\n' | |
288 | % args[2]) | |
289 | sys.stderr.exit(1) | |
290 | elif name == "insert": | |
291 | if len(args) != 1: | |
292 | sys.stderr.write('"set" command requires 1 argument\n') | |
293 | sys.exit(1) | |
294 | ||
295 | s = txn.insert(idl.tables["simple"]) | |
296 | s.i = int(args[0]) | |
297 | elif name == "delete": | |
298 | if len(args) != 1: | |
299 | sys.stderr.write('"delete" command requires 1 argument\n') | |
300 | sys.exit(1) | |
301 | ||
302 | s = idltest_find_simple(idl, int(args[0])) | |
303 | if not s: | |
304 | sys.stderr.write('"delete" command asks for nonexistent i=%d\n' | |
305 | % int(args[0])) | |
306 | sys.exit(1) | |
307 | s.delete() | |
308 | elif name == "verify": | |
309 | if len(args) != 2: | |
310 | sys.stderr.write('"verify" command requires 2 arguments\n') | |
311 | sys.exit(1) | |
312 | ||
313 | s = idltest_find_simple(idl, int(args[0])) | |
314 | if not s: | |
315 | sys.stderr.write('"verify" command asks for nonexistent i=%d\n' | |
316 | % int(args[0])) | |
317 | sys.exit(1) | |
318 | ||
319 | if args[1] in ("i", "b", "s", "u", "r"): | |
320 | s.verify(args[1]) | |
321 | else: | |
322 | sys.stderr.write('"verify" command asks for unknown column ' | |
323 | '"%s"\n' % args[1]) | |
324 | sys.exit(1) | |
80c12152 SA |
325 | elif name == "fetch": |
326 | if len(args) != 2: | |
327 | sys.stderr.write('"fetch" command requires 2 argument\n') | |
328 | sys.exit(1) | |
329 | ||
330 | row = idltest_find_simple(idl, int(args[0])) | |
331 | if not row: | |
332 | sys.stderr.write('"fetch" command asks for nonexistent i=%d\n' | |
333 | % int(args[0])) | |
334 | sys.exit(1) | |
335 | ||
336 | column = args[1] | |
337 | row.fetch(column) | |
338 | fetch_cmds.append([row, column]) | |
8cdf0349 | 339 | elif name == "increment": |
94fbe1aa BP |
340 | if len(args) != 1: |
341 | sys.stderr.write('"increment" command requires 1 argument\n') | |
342 | sys.exit(1) | |
343 | ||
344 | s = idltest_find_simple(idl, int(args[0])) | |
345 | if not s: | |
346 | sys.stderr.write('"set" command asks for nonexistent i=%d\n' | |
347 | % int(args[0])) | |
8cdf0349 BP |
348 | sys.exit(1) |
349 | ||
94fbe1aa | 350 | s.increment("i") |
8cdf0349 BP |
351 | increment = True |
352 | elif name == "abort": | |
353 | txn.abort() | |
354 | break | |
355 | elif name == "destroy": | |
8ea171ab | 356 | print("%03d: destroy" % step) |
8cdf0349 BP |
357 | sys.stdout.flush() |
358 | txn.abort() | |
359 | return | |
225b582a IY |
360 | elif name == "linktest": |
361 | l1_0 = txn.insert(idl.tables["link1"]) | |
362 | l1_0.i = 1 | |
363 | l1_0.k = [l1_0] | |
364 | l1_0.ka = [l1_0] | |
365 | l1_1 = txn.insert(idl.tables["link1"]) | |
366 | l1_1.i = 2 | |
367 | l1_1.k = [l1_0] | |
368 | l1_1.ka = [l1_0, l1_1] | |
3b4c362f IY |
369 | elif name == 'getattrtest': |
370 | l1 = txn.insert(idl.tables["link1"]) | |
371 | i = getattr(l1, 'i', 1) | |
372 | assert i == 1 | |
373 | l1.i = 2 | |
374 | i = getattr(l1, 'i', 1) | |
375 | assert i == 2 | |
376 | l1.k = [l1] | |
8cdf0349 BP |
377 | else: |
378 | sys.stderr.write("unknown command %s\n" % name) | |
379 | sys.exit(1) | |
380 | ||
381 | status = txn.commit_block() | |
382 | sys.stdout.write("%03d: commit, status=%s" | |
383 | % (step, ovs.db.idl.Transaction.status_to_string(status))) | |
384 | if increment and status == ovs.db.idl.Transaction.SUCCESS: | |
385 | sys.stdout.write(", increment=%d" % txn.get_increment_new_value()) | |
d7d417fc TW |
386 | if events: |
387 | # Event notifications from operations in a single transaction are | |
388 | # not in a gauranteed order due to update messages being dicts | |
389 | sys.stdout.write(", events=" + ", ".join(sorted(events))) | |
8cdf0349 BP |
390 | sys.stdout.write("\n") |
391 | sys.stdout.flush() | |
392 | ||
26bb0f31 | 393 | |
8cdf0349 | 394 | def do_idl(schema_file, remote, *commands): |
bf42f674 | 395 | schema_helper = ovs.db.idl.SchemaHelper(schema_file) |
01dc1516 | 396 | if commands and commands[0].startswith("?"): |
80c12152 | 397 | readonly = {} |
01dc1516 | 398 | for x in commands[0][1:].split("?"): |
80c12152 | 399 | readonly = [] |
01dc1516 | 400 | table, columns = x.split(":") |
80c12152 SA |
401 | columns = columns.split(",") |
402 | for index, column in enumerate(columns): | |
403 | if column[-1] == '!': | |
404 | columns[index] = columns[index][:-1] | |
405 | readonly.append(columns[index]) | |
406 | schema_helper.register_columns(table, columns, readonly) | |
01dc1516 SA |
407 | commands = commands[1:] |
408 | else: | |
409 | schema_helper.register_all() | |
bf42f674 | 410 | idl = ovs.db.idl.Idl(remote, schema_helper) |
99155935 BP |
411 | |
412 | if commands: | |
413 | error, stream = ovs.stream.Stream.open_block( | |
414 | ovs.stream.Stream.open(remote)) | |
415 | if error: | |
416 | sys.stderr.write("failed to connect to \"%s\"" % remote) | |
417 | sys.exit(1) | |
418 | rpc = ovs.jsonrpc.Connection(stream) | |
419 | else: | |
420 | rpc = None | |
421 | ||
422 | symtab = {} | |
423 | seqno = 0 | |
424 | step = 0 | |
425 | for command in commands: | |
426 | if command.startswith("+"): | |
427 | # The previous transaction didn't change anything. | |
428 | command = command[1:] | |
429 | else: | |
430 | # Wait for update. | |
8cdf0349 | 431 | while idl.change_seqno == seqno and not idl.run(): |
99155935 BP |
432 | rpc.run() |
433 | ||
434 | poller = ovs.poller.Poller() | |
435 | idl.wait(poller) | |
436 | rpc.wait(poller) | |
437 | poller.block() | |
26bb0f31 | 438 | |
99155935 BP |
439 | print_idl(idl, step) |
440 | step += 1 | |
441 | ||
8cdf0349 | 442 | seqno = idl.change_seqno |
99155935 BP |
443 | |
444 | if command == "reconnect": | |
445 | print("%03d: reconnect" % step) | |
8cdf0349 | 446 | sys.stdout.flush() |
99155935 BP |
447 | step += 1 |
448 | idl.force_reconnect() | |
449 | elif not command.startswith("["): | |
450 | idl_set(idl, command, step) | |
451 | step += 1 | |
452 | else: | |
453 | json = ovs.json.from_string(command) | |
25f599fb | 454 | if isinstance(json, six.string_types): |
99155935 BP |
455 | sys.stderr.write("\"%s\": %s\n" % (command, json)) |
456 | sys.exit(1) | |
457 | json = substitute_uuids(json, symtab) | |
458 | request = ovs.jsonrpc.Message.create_request("transact", json) | |
459 | error, reply = rpc.transact_block(request) | |
460 | if error: | |
461 | sys.stderr.write("jsonrpc transaction failed: %s" | |
462 | % os.strerror(error)) | |
463 | sys.exit(1) | |
66eb76d0 EJ |
464 | elif reply.error is not None: |
465 | sys.stderr.write("jsonrpc transaction failed: %s" | |
466 | % reply.error) | |
467 | sys.exit(1) | |
468 | ||
99155935 BP |
469 | sys.stdout.write("%03d: " % step) |
470 | sys.stdout.flush() | |
471 | step += 1 | |
472 | if reply.result is not None: | |
473 | parse_uuids(reply.result, symtab) | |
474 | reply.id = None | |
475 | sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json())) | |
8cdf0349 | 476 | sys.stdout.flush() |
99155935 BP |
477 | |
478 | if rpc: | |
479 | rpc.close() | |
8cdf0349 | 480 | while idl.change_seqno == seqno and not idl.run(): |
99155935 BP |
481 | poller = ovs.poller.Poller() |
482 | idl.wait(poller) | |
483 | poller.block() | |
484 | print_idl(idl, step) | |
485 | step += 1 | |
486 | idl.close() | |
487 | print("%03d: done" % step) | |
488 | ||
26bb0f31 | 489 | |
af358237 OBY |
490 | def do_idl_passive(schema_file, remote, *commands): |
491 | symtab = {} | |
492 | step = 0 | |
493 | schema_helper = ovs.db.idl.SchemaHelper(schema_file) | |
494 | schema_helper.register_all() | |
495 | idl = ovs.db.idl.Idl(remote, schema_helper) | |
496 | ||
497 | while idl._session.rpc is None: | |
498 | idl.run() | |
499 | ||
500 | rpc = idl._session.rpc | |
501 | ||
502 | print_idl(idl, step) | |
503 | step += 1 | |
504 | ||
505 | for command in commands: | |
506 | json = ovs.json.from_string(command) | |
507 | if isinstance(json, six.string_types): | |
508 | sys.stderr.write("\"%s\": %s\n" % (command, json)) | |
509 | sys.exit(1) | |
510 | json = substitute_uuids(json, symtab) | |
511 | request = ovs.jsonrpc.Message.create_request("transact", json) | |
512 | error, reply = rpc.transact_block(request) | |
513 | if error: | |
514 | sys.stderr.write("jsonrpc transaction failed: %s" | |
515 | % os.strerror(error)) | |
516 | sys.exit(1) | |
517 | elif reply.error is not None: | |
518 | sys.stderr.write("jsonrpc transaction failed: %s" | |
519 | % reply.error) | |
520 | sys.exit(1) | |
521 | ||
522 | sys.stdout.write("%03d: " % step) | |
523 | sys.stdout.flush() | |
524 | step += 1 | |
525 | if reply.result is not None: | |
526 | parse_uuids(reply.result, symtab) | |
527 | reply.id = None | |
528 | sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json())) | |
529 | sys.stdout.flush() | |
530 | ||
531 | idl.close() | |
532 | print("%03d: done" % step) | |
533 | ||
534 | ||
99155935 | 535 | def usage(): |
8ea171ab | 536 | print("""\ |
99155935 BP |
537 | %(program_name)s: test utility for Open vSwitch database Python bindings |
538 | usage: %(program_name)s [OPTIONS] COMMAND ARG... | |
539 | ||
540 | The following commands are supported: | |
541 | default-atoms | |
542 | test ovsdb_atom_default() | |
543 | default-data | |
544 | test ovsdb_datum_default() | |
545 | parse-atomic-type TYPE | |
546 | parse TYPE as OVSDB atomic type, and re-serialize | |
547 | parse-base-type TYPE | |
548 | parse TYPE as OVSDB base type, and re-serialize | |
549 | parse-type JSON | |
550 | parse JSON as OVSDB type, and re-serialize | |
551 | parse-atoms TYPE ATOM... | |
552 | parse JSON ATOMs as atoms of TYPE, and re-serialize | |
553 | parse-atom-strings TYPE ATOM... | |
554 | parse string ATOMs as atoms of given TYPE, and re-serialize | |
555 | sort-atoms TYPE ATOM... | |
556 | print JSON ATOMs in sorted order | |
557 | parse-data TYPE DATUM... | |
558 | parse JSON DATUMs as data of given TYPE, and re-serialize | |
559 | parse-column NAME OBJECT | |
560 | parse column NAME with info OBJECT, and re-serialize | |
c5f341ab | 561 | parse-table NAME OBJECT [DEFAULT-IS-ROOT] |
99155935 BP |
562 | parse table NAME with info OBJECT |
563 | parse-schema JSON | |
564 | parse JSON as an OVSDB schema, and re-serialize | |
01dc1516 | 565 | idl SCHEMA SERVER [?T1:C1,C2...[?T2:C1,C2,...]...] [TRANSACTION...] |
8cdf0349 BP |
566 | connect to SERVER (which has the specified SCHEMA) and dump the |
567 | contents of the database as seen initially by the IDL implementation | |
568 | and after executing each TRANSACTION. (Each TRANSACTION must modify | |
99155935 | 569 | the database or this command will hang.) |
01dc1516 SA |
570 | By default, all columns of all tables are monitored. The "?" option |
571 | can be used to monitor specific Table:Column(s). The table and their | |
572 | columns are listed as a string of the form starting with "?": | |
573 | ?<table-name>:<column-name>,<column-name>,... | |
574 | e.g.: | |
575 | ?simple:b - Monitor column "b" in table "simple" | |
576 | Entries for multiple tables are seperated by "?": | |
577 | ?<table-name>:<column-name>,...?<table-name>:<column-name>,... | |
578 | e.g.: | |
579 | ?simple:b?link1:i,k - Monitor column "b" in table "simple", | |
580 | and column "i", "k" in table "link1" | |
80c12152 SA |
581 | Readonly columns: Suffixing a "!" after a column indicates that the |
582 | column is to be registered "readonly". | |
583 | e.g.: | |
584 | ?simple:i,b! - Register interest in column "i" (monitoring) and | |
585 | column "b" (readonly). | |
586 | ||
99155935 BP |
587 | |
588 | The following options are also available: | |
589 | -t, --timeout=SECS give up after SECS seconds | |
590 | -h, --help display this help message\ | |
8ea171ab | 591 | """ % {'program_name': ovs.util.PROGRAM_NAME}) |
99155935 BP |
592 | sys.exit(0) |
593 | ||
26bb0f31 | 594 | |
99155935 | 595 | def main(argv): |
99155935 BP |
596 | try: |
597 | options, args = getopt.gnu_getopt(argv[1:], 't:h', | |
598 | ['timeout', | |
599 | 'help']) | |
f3068bff | 600 | except getopt.GetoptError as geo: |
99155935 BP |
601 | sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg)) |
602 | sys.exit(1) | |
603 | ||
604 | for key, value in options: | |
605 | if key in ['-h', '--help']: | |
606 | usage() | |
607 | elif key in ['-t', '--timeout']: | |
608 | try: | |
609 | timeout = int(value) | |
610 | if timeout < 1: | |
611 | raise TypeError | |
612 | except TypeError: | |
613 | raise error.Error("value %s on -t or --timeout is not at " | |
614 | "least 1" % value) | |
615 | signal.alarm(timeout) | |
616 | else: | |
617 | sys.exit(0) | |
618 | ||
99155935 BP |
619 | if not args: |
620 | sys.stderr.write("%s: missing command argument " | |
621 | "(use --help for help)\n" % ovs.util.PROGRAM_NAME) | |
622 | sys.exit(1) | |
623 | ||
624 | commands = {"default-atoms": (do_default_atoms, 0), | |
625 | "default-data": (do_default_data, 0), | |
626 | "parse-atomic-type": (do_parse_atomic_type, 1), | |
627 | "parse-base-type": (do_parse_base_type, 1), | |
628 | "parse-type": (do_parse_type, 1), | |
629 | "parse-atoms": (do_parse_atoms, (2,)), | |
630 | "parse-data": (do_parse_data, (2,)), | |
631 | "sort-atoms": (do_sort_atoms, 2), | |
632 | "parse-column": (do_parse_column, 2), | |
c5f341ab | 633 | "parse-table": (do_parse_table, (2, 3)), |
99155935 | 634 | "parse-schema": (do_parse_schema, 1), |
af358237 OBY |
635 | "idl": (do_idl, (2,)), |
636 | "idl_passive": (do_idl_passive, (2,))} | |
99155935 BP |
637 | |
638 | command_name = args[0] | |
639 | args = args[1:] | |
603e325f | 640 | if command_name not in commands: |
99155935 BP |
641 | sys.stderr.write("%s: unknown command \"%s\" " |
642 | "(use --help for help)\n" % (ovs.util.PROGRAM_NAME, | |
643 | command_name)) | |
644 | sys.exit(1) | |
645 | ||
646 | func, n_args = commands[command_name] | |
647 | if type(n_args) == tuple: | |
648 | if len(args) < n_args[0]: | |
649 | sys.stderr.write("%s: \"%s\" requires at least %d arguments but " | |
650 | "only %d provided\n" | |
651 | % (ovs.util.PROGRAM_NAME, command_name, | |
652 | n_args, len(args))) | |
653 | sys.exit(1) | |
654 | elif type(n_args) == int: | |
655 | if len(args) != n_args: | |
656 | sys.stderr.write("%s: \"%s\" requires %d arguments but %d " | |
657 | "provided\n" | |
658 | % (ovs.util.PROGRAM_NAME, command_name, | |
659 | n_args, len(args))) | |
660 | sys.exit(1) | |
661 | else: | |
662 | assert False | |
663 | ||
664 | func(*args) | |
665 | ||
26bb0f31 | 666 | |
99155935 BP |
667 | if __name__ == '__main__': |
668 | try: | |
669 | main(sys.argv) | |
f3068bff | 670 | except error.Error as e: |
99155935 BP |
671 | sys.stderr.write("%s\n" % e) |
672 | sys.exit(1) |