mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
vswitchd: Add entity-relationship diagram to ovs-vswitchd.conf.db.5.
I've updated http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf with example output.
This commit is contained in:
parent
cfcef6b246
commit
f8d739a9fa
@ -81,6 +81,12 @@ following:
|
||||
|
||||
- pyuic4 from PyQt4 (http://www.riverbankcomputing.co.uk).
|
||||
|
||||
If you modify the vswitchd database schema, then the E-R diagram in
|
||||
the ovs-vswitchd.conf.db(5) manpage will be updated properly only if
|
||||
you have the following:
|
||||
|
||||
- "dot" from graphviz (http://www.graphviz.org/).
|
||||
|
||||
Installation Requirements
|
||||
-------------------------
|
||||
|
||||
|
@ -52,6 +52,7 @@ OVS_CHECK_PCRE
|
||||
OVS_CHECK_PYTHON
|
||||
OVS_CHECK_PYUIC4
|
||||
OVS_CHECK_OVSDBMONITOR
|
||||
OVS_CHECK_ER_DIAGRAMS
|
||||
OVS_CHECK_IF_PACKET
|
||||
OVS_CHECK_STRTOK_R
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec],
|
||||
|
@ -265,6 +265,32 @@ else:
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_PYTHON], [test "$HAVE_PYTHON" = yes])])
|
||||
|
||||
dnl Checks for dot.
|
||||
AC_DEFUN([OVS_CHECK_DOT],
|
||||
[AC_CACHE_CHECK(
|
||||
[for dot],
|
||||
[ovs_cv_dot],
|
||||
[dnl "dot" writes -V output to stderr:
|
||||
if (dot -V) 2>&1 | grep '^dot - [gG]raphviz version' >/dev/null 2>&1; then
|
||||
ovs_cv_dot=yes
|
||||
else
|
||||
ovs_cv_dot=no
|
||||
fi])])
|
||||
|
||||
dnl Check whether to build E-R diagrams.
|
||||
AC_DEFUN([OVS_CHECK_ER_DIAGRAMS],
|
||||
[AC_REQUIRE([OVS_CHECK_DOT])
|
||||
AC_REQUIRE([OVS_CHECK_PYTHON])
|
||||
AC_CACHE_CHECK(
|
||||
[whether to build E-R diagrams for database],
|
||||
[ovs_cv_er_diagrams],
|
||||
[if test $ovs_cv_dot != no && test $ovs_cv_python != no; then
|
||||
ovs_cv_er_diagrams=yes
|
||||
else
|
||||
ovs_cv_er_diagrams=no
|
||||
fi])
|
||||
AM_CONDITIONAL([BUILD_ER_DIAGRAMS], [test $ovs_cv_er_diagrams = yes])])
|
||||
|
||||
dnl Checks for pyuic4.
|
||||
AC_DEFUN([OVS_CHECK_PYUIC4],
|
||||
[AC_CACHE_CHECK(
|
||||
|
@ -117,4 +117,10 @@ noinst_SCRIPTS += ovsdb/ovsdb-doc
|
||||
DISTCLEANFILES += ovsdb/ovsdb-doc
|
||||
OVSDB_DOC = $(PYTHON) $(srcdir)/ovsdb/ovsdb-doc.in
|
||||
|
||||
# ovsdb-dot
|
||||
EXTRA_DIST += ovsdb/ovsdb-dot.in
|
||||
noinst_SCRIPTS += ovsdb/ovsdb-dot
|
||||
DISTCLEANFILES += ovsdb/ovsdb-dot
|
||||
OVSDB_DOT = $(PYTHON) $(srcdir)/ovsdb/ovsdb-dot.in
|
||||
|
||||
include ovsdb/ovsdbmonitor/automake.mk
|
||||
|
@ -213,10 +213,10 @@ Column Type
|
||||
s += body
|
||||
return s
|
||||
|
||||
def docsToNroff(schemaFile, xmlFile, title=None):
|
||||
def docsToNroff(schemaFile, xmlFile, erFile, title=None):
|
||||
schema = DbSchema.fromJson(json.load(open(schemaFile, "r")))
|
||||
doc = xml.dom.minidom.parse(xmlFile).documentElement
|
||||
|
||||
|
||||
schemaDate = os.stat(schemaFile).st_mtime
|
||||
xmlDate = os.stat(xmlFile).st_mtime
|
||||
d = date.fromtimestamp(max(schemaDate, xmlDate))
|
||||
@ -224,7 +224,10 @@ def docsToNroff(schemaFile, xmlFile, title=None):
|
||||
if title == None:
|
||||
title = schema.name
|
||||
|
||||
s = r'''.TH %s 5 "%s" "Open vSwitch" "Open vSwitch Manual"
|
||||
# Putting '\" pt as the first line tells "man" that the manpage
|
||||
# needs to be preprocessed by "pic" and "tbl".
|
||||
s = r''''\" pt
|
||||
.TH %s 5 "%s" "Open vSwitch" "Open vSwitch Manual"
|
||||
.\" -*- nroff -*-
|
||||
.de TQ
|
||||
. br
|
||||
@ -275,6 +278,24 @@ Table Purpose
|
||||
tableSummary += "%s\t%s\n" % (name, textToNroff(title))
|
||||
tableSummary += '.TE\n'
|
||||
s += tableSummary
|
||||
|
||||
if erFile:
|
||||
s += """
|
||||
.sp 1
|
||||
.SH "TABLE RELATIONSHIPS"
|
||||
.PP
|
||||
The following diagram shows the relationship among tables in the
|
||||
database. Each node represents a table. Each edge leads from the
|
||||
table that contains it and points to the table that its value
|
||||
represents. Edges are labeled with their column names.
|
||||
.RS -1in
|
||||
"""
|
||||
erStream = open(erFile, "r")
|
||||
for line in erStream:
|
||||
s += line + '\n'
|
||||
erStream.close()
|
||||
s += ".RE\n"
|
||||
|
||||
for node in tableNodes:
|
||||
s += tableToNroff(schema, node) + "\n"
|
||||
return s
|
||||
@ -288,6 +309,7 @@ where SCHEMA is an OVSDB schema in JSON format
|
||||
and XML is OVSDB documentation in XML format.
|
||||
|
||||
The following options are also available:
|
||||
--er-diagram=DIAGRAM.PIC include E-R diagram from DIAGRAM.PIC
|
||||
--title=TITLE use TITLE as title instead of schema name
|
||||
-h, --help display this help message
|
||||
-V, --version display version information\
|
||||
@ -298,14 +320,18 @@ if __name__ == "__main__":
|
||||
try:
|
||||
try:
|
||||
options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
|
||||
['title=', 'help', 'version'])
|
||||
['er-diagram=', 'title=',
|
||||
'help', 'version'])
|
||||
except getopt.GetoptError, geo:
|
||||
sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
|
||||
sys.exit(1)
|
||||
|
||||
er_diagram = None
|
||||
title = None
|
||||
for key, value in options:
|
||||
if key == '--title':
|
||||
if key == '--er-diagram':
|
||||
er_diagram = value
|
||||
elif key == '--title':
|
||||
title = value
|
||||
elif key in ['-h', '--help']:
|
||||
usage()
|
||||
@ -320,7 +346,7 @@ if __name__ == "__main__":
|
||||
sys.exit(1)
|
||||
|
||||
# XXX we should warn about undocumented tables or columns
|
||||
s = docsToNroff(args[0], args[1])
|
||||
s = docsToNroff(args[0], args[1], er_diagram)
|
||||
for line in s.split("\n"):
|
||||
line = line.strip()
|
||||
if len(line):
|
||||
|
87
ovsdb/ovsdb-dot.in
Executable file
87
ovsdb/ovsdb-dot.in
Executable file
@ -0,0 +1,87 @@
|
||||
#! @PYTHON@
|
||||
|
||||
from datetime import date
|
||||
import getopt
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, "@abs_top_srcdir@/ovsdb")
|
||||
import simplejson as json
|
||||
|
||||
from OVSDB import *
|
||||
|
||||
argv0 = sys.argv[0]
|
||||
|
||||
def printEdge(tableName, baseType, label):
|
||||
if baseType.refTable:
|
||||
options = {}
|
||||
options['label'] = '"%s"' % label
|
||||
if baseType.refType == 'weak':
|
||||
options['constraint'] = 'false'
|
||||
print "\t%s -> %s [%s];" % (
|
||||
tableName,
|
||||
baseType.refTable,
|
||||
', '.join(['%s=%s' % (k,v) for k,v in options.items()]))
|
||||
|
||||
def schemaToDot(schemaFile):
|
||||
schema = DbSchema.fromJson(json.load(open(schemaFile, "r")))
|
||||
|
||||
print "digraph %s {" % schema.name
|
||||
for tableName, table in schema.tables.iteritems():
|
||||
print '\tsize="6.5,4";'
|
||||
print '\tmargin="0";'
|
||||
print "\tnode [shape=box];"
|
||||
print "\t%s;" % tableName
|
||||
for columnName, column in table.columns.iteritems():
|
||||
if column.type.value:
|
||||
printEdge(tableName, column.type.key, "%s key" % columnName)
|
||||
printEdge(tableName, column.type.value, "%s value" % columnName)
|
||||
else:
|
||||
printEdge(tableName, column.type.key, columnName)
|
||||
print "}";
|
||||
|
||||
def usage():
|
||||
print """\
|
||||
%(argv0)s: compiles ovsdb schemas to graphviz format
|
||||
Prints a .dot file that "dot" can render to an entity-relationship diagram
|
||||
usage: %(argv0)s [OPTIONS] SCHEMA
|
||||
where SCHEMA is an OVSDB schema in JSON format
|
||||
|
||||
The following options are also available:
|
||||
-h, --help display this help message
|
||||
-V, --version display version information\
|
||||
""" % {'argv0': argv0}
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
try:
|
||||
options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
|
||||
['help', 'version'])
|
||||
except getopt.GetoptError, geo:
|
||||
sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
|
||||
sys.exit(1)
|
||||
|
||||
for key, value in options:
|
||||
if key in ['-h', '--help']:
|
||||
usage()
|
||||
elif key in ['-V', '--version']:
|
||||
print "ovsdb-dot (Open vSwitch) @VERSION@"
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
||||
if len(args) != 1:
|
||||
sys.stderr.write("%s: exactly 1 non-option argument required "
|
||||
"(use --help for help)\n" % argv0)
|
||||
sys.exit(1)
|
||||
|
||||
schemaToDot(args[0])
|
||||
|
||||
except Error, e:
|
||||
sys.stderr.write("%s: %s\n" % (argv0, e.msg))
|
||||
sys.exit(1)
|
||||
|
||||
# Local variables:
|
||||
# mode: python
|
||||
# End:
|
@ -46,13 +46,31 @@ vswitchd/vswitch-idl.ovsidl: $(VSWITCH_IDL_FILES)
|
||||
$(OVSDB_IDLC) -C $(srcdir) annotate $(VSWITCH_IDL_FILES) > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
# vswitch E-R diagram
|
||||
if BUILD_ER_DIAGRAMS
|
||||
$(srcdir)/vswitchd/vswitch.pic: ovsdb/ovsdb-dot.in vswitchd/vswitch.ovsschema
|
||||
$(OVSDB_DOT) $(srcdir)/vswitchd/vswitch.ovsschema \
|
||||
| dot -T pic \
|
||||
| sed -e "/^'/d" \
|
||||
-e '/^box attrs0/d' \
|
||||
-e 's/linethick = 0;/linethick = 1;/' \
|
||||
> $@.tmp
|
||||
mv $@.tmp $@
|
||||
else
|
||||
$(srcdir)/vswitchd/vswitch.pic: ovsdb/ovsdb-dot.in vswitchd/vswitch.ovsschema
|
||||
touch $@
|
||||
endif
|
||||
EXTRA_DIST += vswitchd/vswitch.pic
|
||||
|
||||
# vswitch schema documentation
|
||||
EXTRA_DIST += vswitchd/vswitch.xml
|
||||
dist_man_MANS += vswitchd/ovs-vswitchd.conf.db.5
|
||||
vswitchd/ovs-vswitchd.conf.db.5: \
|
||||
ovsdb/ovsdb-doc.in vswitchd/vswitch.xml vswitchd/vswitch.ovsschema
|
||||
ovsdb/ovsdb-doc.in vswitchd/vswitch.xml vswitchd/vswitch.ovsschema \
|
||||
$(srcdir)/vswitchd/vswitch.pic
|
||||
$(OVSDB_DOC) \
|
||||
--title="ovs-vswitchd.conf.db" \
|
||||
--er-diagram=$(srcdir)/vswitchd/vswitch.pic \
|
||||
$(srcdir)/vswitchd/vswitch.ovsschema \
|
||||
$(srcdir)/vswitchd/vswitch.xml > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
1017
vswitchd/vswitch.pic
Normal file
1017
vswitchd/vswitch.pic
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user