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:
parent
cfcef6b246
commit
f8d739a9fa
@ -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
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
@ -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],
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -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
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
|
$(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
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