[ovs-dev] [PATCH] python: add OVSDB IDL tutorial with examples

Toms Atteka cpp.code.lv at gmail.com
Mon Jul 9 13:42:06 UTC 2018


created tutorial on how to use OVSDB IDL Python library

Signed-off-by: Toms Atteka <cpp.code.lv at gmail.com>
---
 Documentation/automake.mk                    |   1 +
 Documentation/index.rst                      |   1 +
 Documentation/tutorials/index.rst            |   1 +
 Documentation/tutorials/ovsdb-idl-python.rst | 285 +++++++++++++++++++++++++++
 4 files changed, 288 insertions(+)
 create mode 100644 Documentation/tutorials/ovsdb-idl-python.rst

diff --git a/Documentation/automake.mk b/Documentation/automake.mk
index 2444794..34b6d32 100644
--- a/Documentation/automake.mk
+++ b/Documentation/automake.mk
@@ -28,6 +28,7 @@ DOC_SOURCE = \
 	Documentation/tutorials/ovn-openstack.rst \
 	Documentation/tutorials/ovn-sandbox.rst \
 	Documentation/tutorials/ovs-conntrack.rst \
+	Documentation/tutorials/ovsdb-idl-python.rst \
 	Documentation/topics/index.rst \
 	Documentation/topics/bonding.rst \
 	Documentation/topics/idl-compound-indexes.rst \
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 06602f7..e55fcd3 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -66,6 +66,7 @@ vSwitch? Start here.
   :doc:`tutorials/ovn-sandbox` |
   :doc:`tutorials/ovn-openstack` |
   :doc:`tutorials/ovs-conntrack`
+  :doc:`tutorials/ovsdb-idl-python`
 
 Deeper Dive
 -----------
diff --git a/Documentation/tutorials/index.rst b/Documentation/tutorials/index.rst
index ab90b7c..4fbb41e 100644
--- a/Documentation/tutorials/index.rst
+++ b/Documentation/tutorials/index.rst
@@ -44,3 +44,4 @@ vSwitch.
    ovn-sandbox
    ovn-openstack
    ovs-conntrack
+   ovsdb-idl-python
diff --git a/Documentation/tutorials/ovsdb-idl-python.rst b/Documentation/tutorials/ovsdb-idl-python.rst
new file mode 100644
index 0000000..894c6f8
--- /dev/null
+++ b/Documentation/tutorials/ovsdb-idl-python.rst
@@ -0,0 +1,285 @@
+..
+      Licensed under the Apache License, Version 2.0 (the "License"); you may
+      not use this file except in compliance with the License. You may obtain
+      a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+      WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+      License for the specific language governing permissions and limitations
+      under the License.
+
+      Convention for heading levels in Open vSwitch documentation:
+
+      =======  Heading 0 (reserved for the title in a document)
+      -------  Heading 1
+      ~~~~~~~  Heading 2
+      +++++++  Heading 3
+      '''''''  Heading 4
+
+      Avoid deeper levels because they do not render well.
+
+========================
+OVSDB IDL Python Library
+========================
+
+OVSDB Interface Definition Language Python Library allows manipulation of OVS
+instance through its definition inside DB file.
+
+This tutorial will provide basic sample on how to use library. Description on
+how particular parts work are added in comments in the code.
+
+Insert Bridge
+-------------
+
+This is a simple example to show how to insert bridge in OVSDB. Main thing is
+to understand that bridge should be inserted inside Open_vSwitch table not
+Bridge table. Bridges which are not inside Open_vSwitch gets automatically
+removed.::
+
+    #! /usr/bin/env python
+
+    import six
+    import ovs.db.idl
+
+    print("insert bridge example")
+
+    # define schema helper which will hold OVS DB structure
+    schema_helper = ovs.db.idl.SchemaHelper(
+        "/usr/share/openvswitch/vswitch.ovsschema"
+    )
+    # define which parts of schema we are interested in
+    schema_helper.register_columns(
+        "Open_vSwitch", ["bridges"]
+    )
+    schema_helper.register_columns(
+        "Bridge", ["name", "fail_mode"]
+    )
+
+    # define whether we want use UNIX socket or IP protocol
+    # remote = 'unix:/run/openvswitch/db.sock'
+    remote = 'tcp:127.0.0.1:12345'
+
+    # initialize DB object
+    idl = ovs.db.idl.Idl(remote, schema_helper)
+
+    # pull initial DB
+    # must be performed before any transaction
+    seq_no = idl.change_seqno
+    while True:
+        idl.run()
+
+        if seq_no == idl.change_seqno:
+            poller = ovs.poller.Poller()
+            idl.wait(poller)
+            poller.block()
+            continue
+
+        seq_no = idl.change_seqno
+        break
+
+    # start transaction
+    # action can only be done within transactions
+    # multiple actions can be done in transactions
+    txn = ovs.db.idl.Transaction(idl)
+
+    # create bridge row
+    bridge = txn.insert(idl.tables["Bridge"])
+    # specify unique name for bridge
+    bridge.name = "Main Bridge"
+    # other bridge fields can be specified here as well
+    bridge.fail_mode = "secure"
+
+    # bridge gets stored inside Open_vSwitch table
+    row = six.next(six.itervalues(idl.tables["Open_vSwitch"].rows))
+
+    # appending directly won't work:
+    # row.bridges.append(s)
+    # need to create new list
+    bridges = row.bridges
+    bridges.append(bridge)
+    row.bridges = bridges
+
+    # store changes in DB
+    txn.commit_block()
+
+    idl.close()
+
+Delete Bridges
+--------------
+
+This is a simple example to show how to delete bridges from OVSDB::
+
+    #! /usr/bin/env python
+
+    import six
+    import ovs.db.idl
+
+    print("delete empty bridges example")
+
+    # define schema helper which will hold OVS DB structure
+    schema_helper = ovs.db.idl.SchemaHelper(
+        "/usr/share/openvswitch/vswitch.ovsschema"
+    )
+    # define which parts of schema we are interested in
+    schema_helper.register_columns(
+        "Open_vSwitch", ["bridges"]
+    )
+    schema_helper.register_columns(
+        "Bridge", ["name", "ports"]
+    )
+    schema_helper.register_columns(
+        "Port", []
+    )
+
+    # define whether we want use UNIX socket or IP protocol
+    # remote = 'unix:/run/openvswitch/db.sock'
+    remote = 'tcp:127.0.0.1:12345'
+
+    # initialize DB object
+    idl = ovs.db.idl.Idl(remote, schema_helper)
+
+    # pull initial DB
+    # must be performed before any transaction
+    seq_no = idl.change_seqno
+    while True:
+        idl.run()
+
+        if seq_no == idl.change_seqno:
+            poller = ovs.poller.Poller()
+            idl.wait(poller)
+            poller.block()
+            continue
+
+        seq_no = idl.change_seqno
+        break
+
+    # start transaction
+    # action can only be done within transactions
+    # multiple actions can be done in transactions
+    txn = ovs.db.idl.Transaction(idl)
+
+    # all the references are stored in main table which holds single row
+    row = six.next(six.itervalues(idl.tables["Open_vSwitch"].rows))
+
+    # to remove bridges they must be skipped in the new list
+    # details in bridge table will be deleted automatically
+    bridges = []
+    for bridge in row.bridges:
+        print(bridge.ports)
+        if len(bridge.ports) > 0:
+            bridges.append(bridge)
+    row.bridges = bridges
+
+    # store changes in DB
+    txn.commit_block()
+
+    idl.close()
+
+OVS Monitor
+-----------
+
+This example is to show how to listen to changes in the OVSDB. After running
+the script one can run ovs-vsctl commands in different console and see how
+changes immediately gets reflected.::
+
+    #! /usr/bin/env python
+
+    from __future__ import print_function
+    import os
+    import six
+    import ovs.db.idl
+
+
+    # just for pretty printing
+    class Colors:
+        BLUE = '\033[94m'
+        YELLOW = '\033[93m'
+        END = '\033[0m'
+
+
+    # define schema helper which will hold OVS DB structure
+    schema_helper = ovs.db.idl.SchemaHelper(
+        "/usr/share/openvswitch/vswitch.ovsschema"
+    )
+    # define which parts of schema we are interested in
+    schema_helper.register_columns(
+        "Bridge", ["name", "ports"]
+    )
+    schema_helper.register_columns(
+        "Port", ["name", "interfaces"]
+    )
+    # its enough just to point to the table as we are not requiring details
+    schema_helper.register_columns(
+        "Interface", []
+    )
+
+    # define whether we want use UNIX socket or IP protocol
+    # remote = 'unix:/run/openvswitch/db.sock'
+    remote = 'tcp:127.0.0.1:12345'
+
+    # initialize DB object
+    idl = ovs.db.idl.Idl(remote, schema_helper)
+
+    # main pulling loop
+    seq_no = idl.change_seqno
+    while True:
+        idl.run()
+
+        # if table hasn't changed wait for changes
+        if seq_no == idl.change_seqno:
+            poller = ovs.poller.Poller()
+            idl.wait(poller)
+            poller.block()
+            continue
+
+        seq_no = idl.change_seqno
+
+        # clear screen
+        os.system('cls' if os.name == 'nt' else 'clear')
+        # pretty print header
+        print(
+            Colors.BLUE +
+            "bridge".ljust(24) +
+            Colors.YELLOW +
+            "ports (interface count)" +
+            Colors.END
+        )
+        print('-' * 80)
+        # iterate over all bridges
+        for bridge in six.itervalues(idl.tables["Bridge"].rows):
+            print(
+                Colors.BLUE +
+                (
+                    # we can access name because we have requested it above
+                    bridge.name[:16] +
+                    (" ..." if len(bridge.name) > 16 else "")
+                ).ljust(24) +
+                Colors.END,
+                end=""
+            )
+            # iterate over all ports in bridge
+            for port in bridge.ports:
+                # port data are stored in port table, bridge row has only
+                # references
+                port_data = idl.tables["Port"].rows[port.uuid]
+
+                print(
+                    Colors.YELLOW +
+                    (
+                        port.name[:8] + (" ..." if len(port.name) > 8 else "")
+                    ).ljust(12) +
+                    # we can get the count of interfaces for a port, but we
+                    # need to request interface table above.
+                    (" (" + str(len(port_data.interfaces)) + ") ").ljust(5) +
+                    Colors.END,
+                    end=""
+                )
+            print()
+
+To have multiple interfaces on a port one can add a bond::
+
+    ovs-vsctl add-bond <bridge> <bond name> <list of interfaces>
+
-- 
2.7.4



More information about the dev mailing list