2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +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:
Ben Pfaff 2010-06-23 09:41:09 -07:00
parent cfcef6b246
commit f8d739a9fa
8 changed files with 1194 additions and 7 deletions

View File

@ -81,6 +81,12 @@ following:
- pyuic4 from PyQt4 (http://www.riverbankcomputing.co.uk). - 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 Installation Requirements
------------------------- -------------------------

View File

@ -52,6 +52,7 @@ OVS_CHECK_PCRE
OVS_CHECK_PYTHON OVS_CHECK_PYTHON
OVS_CHECK_PYUIC4 OVS_CHECK_PYUIC4
OVS_CHECK_OVSDBMONITOR OVS_CHECK_OVSDBMONITOR
OVS_CHECK_ER_DIAGRAMS
OVS_CHECK_IF_PACKET OVS_CHECK_IF_PACKET
OVS_CHECK_STRTOK_R OVS_CHECK_STRTOK_R
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec], AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec],

View File

@ -265,6 +265,32 @@ else:
fi fi
AM_CONDITIONAL([HAVE_PYTHON], [test "$HAVE_PYTHON" = yes])]) 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. dnl Checks for pyuic4.
AC_DEFUN([OVS_CHECK_PYUIC4], AC_DEFUN([OVS_CHECK_PYUIC4],
[AC_CACHE_CHECK( [AC_CACHE_CHECK(

View File

@ -117,4 +117,10 @@ noinst_SCRIPTS += ovsdb/ovsdb-doc
DISTCLEANFILES += ovsdb/ovsdb-doc DISTCLEANFILES += ovsdb/ovsdb-doc
OVSDB_DOC = $(PYTHON) $(srcdir)/ovsdb/ovsdb-doc.in 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 include ovsdb/ovsdbmonitor/automake.mk

View File

@ -213,10 +213,10 @@ Column Type
s += body s += body
return s return s
def docsToNroff(schemaFile, xmlFile, title=None): def docsToNroff(schemaFile, xmlFile, erFile, title=None):
schema = DbSchema.fromJson(json.load(open(schemaFile, "r"))) schema = DbSchema.fromJson(json.load(open(schemaFile, "r")))
doc = xml.dom.minidom.parse(xmlFile).documentElement doc = xml.dom.minidom.parse(xmlFile).documentElement
schemaDate = os.stat(schemaFile).st_mtime schemaDate = os.stat(schemaFile).st_mtime
xmlDate = os.stat(xmlFile).st_mtime xmlDate = os.stat(xmlFile).st_mtime
d = date.fromtimestamp(max(schemaDate, xmlDate)) d = date.fromtimestamp(max(schemaDate, xmlDate))
@ -224,7 +224,10 @@ def docsToNroff(schemaFile, xmlFile, title=None):
if title == None: if title == None:
title = schema.name 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 -*- .\" -*- nroff -*-
.de TQ .de TQ
. br . br
@ -275,6 +278,24 @@ Table Purpose
tableSummary += "%s\t%s\n" % (name, textToNroff(title)) tableSummary += "%s\t%s\n" % (name, textToNroff(title))
tableSummary += '.TE\n' tableSummary += '.TE\n'
s += tableSummary 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: for node in tableNodes:
s += tableToNroff(schema, node) + "\n" s += tableToNroff(schema, node) + "\n"
return s return s
@ -288,6 +309,7 @@ where SCHEMA is an OVSDB schema in JSON format
and XML is OVSDB documentation in XML format. and XML is OVSDB documentation in XML format.
The following options are also available: 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 --title=TITLE use TITLE as title instead of schema name
-h, --help display this help message -h, --help display this help message
-V, --version display version information\ -V, --version display version information\
@ -298,14 +320,18 @@ if __name__ == "__main__":
try: try:
try: try:
options, args = getopt.gnu_getopt(sys.argv[1:], 'hV', options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
['title=', 'help', 'version']) ['er-diagram=', 'title=',
'help', 'version'])
except getopt.GetoptError, geo: except getopt.GetoptError, geo:
sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
sys.exit(1) sys.exit(1)
er_diagram = None
title = None title = None
for key, value in options: for key, value in options:
if key == '--title': if key == '--er-diagram':
er_diagram = value
elif key == '--title':
title = value title = value
elif key in ['-h', '--help']: elif key in ['-h', '--help']:
usage() usage()
@ -320,7 +346,7 @@ if __name__ == "__main__":
sys.exit(1) sys.exit(1)
# XXX we should warn about undocumented tables or columns # 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"): for line in s.split("\n"):
line = line.strip() line = line.strip()
if len(line): if len(line):

87
ovsdb/ovsdb-dot.in Executable file
View 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:

View File

@ -46,13 +46,31 @@ vswitchd/vswitch-idl.ovsidl: $(VSWITCH_IDL_FILES)
$(OVSDB_IDLC) -C $(srcdir) annotate $(VSWITCH_IDL_FILES) > $@.tmp $(OVSDB_IDLC) -C $(srcdir) annotate $(VSWITCH_IDL_FILES) > $@.tmp
mv $@.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 # vswitch schema documentation
EXTRA_DIST += vswitchd/vswitch.xml EXTRA_DIST += vswitchd/vswitch.xml
dist_man_MANS += vswitchd/ovs-vswitchd.conf.db.5 dist_man_MANS += vswitchd/ovs-vswitchd.conf.db.5
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) \ $(OVSDB_DOC) \
--title="ovs-vswitchd.conf.db" \ --title="ovs-vswitchd.conf.db" \
--er-diagram=$(srcdir)/vswitchd/vswitch.pic \
$(srcdir)/vswitchd/vswitch.ovsschema \ $(srcdir)/vswitchd/vswitch.ovsschema \
$(srcdir)/vswitchd/vswitch.xml > $@.tmp $(srcdir)/vswitchd/vswitch.xml > $@.tmp
mv $@.tmp $@ mv $@.tmp $@

1017
vswitchd/vswitch.pic Normal file

File diff suppressed because it is too large Load Diff