diff mbox series

[ovs-dev] python: add IDL examples

Message ID 1529234674-68598-1-git-send-email-cpp.code.lv@gmail.com
State Changes Requested
Headers show
Series [ovs-dev] python: add IDL examples | expand

Commit Message

Toms Atteka June 17, 2018, 11:24 a.m. UTC
created sample python scripts, which helps to learn how to use OVSDB library

Signed-off-by: Toms Atteka <cpp.code@gmail.com>
---
 python/howto/IDL/delete_bridges.py |  70 +++++++++++++++++++++++++
 python/howto/IDL/insert_bridge.py  |  75 +++++++++++++++++++++++++++
 python/howto/IDL/ovs_monitor.py    | 102 +++++++++++++++++++++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100755 python/howto/IDL/delete_bridges.py
 create mode 100755 python/howto/IDL/insert_bridge.py
 create mode 100755 python/howto/IDL/ovs_monitor.py

Comments

Ben Pfaff June 19, 2018, 3:53 a.m. UTC | #1
On Sun, Jun 17, 2018 at 04:24:34AM -0700, Toms Atteka wrote:
> created sample python scripts, which helps to learn how to use OVSDB library
> 
> Signed-off-by: Toms Atteka <cpp.code@gmail.com>

Thanks for working on making it easier to understand how to use Open
vSwitch.

This doesn't build, because:

    The following files are in git but not the distribution:
    python/howto/IDL/delete_bridges.py
    python/howto/IDL/insert_bridge.py
    python/howto/IDL/ovs_monitor.py
    Makefile:6214: recipe for target 'dist-hook-git' failed

I think it would be good to ensure that flake8 runs on the new files
too.

Do you have an idea how these new files can be discoverable to users?  I
guess you decided that they should not be in the Documentation
directory.  Maybe there should at least be a pointer to them from the
documentation.  Maybe there should be a pointer to them from the IDL
sources.

Thanks,

Ben.
Toms Atteka June 19, 2018, 6:51 p.m. UTC | #2
Do we need licensing information in these sample files?

On Mon, Jun 18, 2018 at 8:53 PM, Ben Pfaff <blp@ovn.org> wrote:

> On Sun, Jun 17, 2018 at 04:24:34AM -0700, Toms Atteka wrote:
> > created sample python scripts, which helps to learn how to use OVSDB
> library
> >
> > Signed-off-by: Toms Atteka <cpp.code@gmail.com>
>
> Thanks for working on making it easier to understand how to use Open
> vSwitch.
>
> This doesn't build, because:
>
>     The following files are in git but not the distribution:
>     python/howto/IDL/delete_bridges.py
>     python/howto/IDL/insert_bridge.py
>     python/howto/IDL/ovs_monitor.py
>     Makefile:6214: recipe for target 'dist-hook-git' failed
>
> I think it would be good to ensure that flake8 runs on the new files
> too.
>
> Do you have an idea how these new files can be discoverable to users?


So far I am not really sure which would be the best way to do that.


> I guess you decided that they should not be in the Documentation
> directory.


From current structure documentation folder feels more like textual
information.


> Maybe there should at least be a pointer to them from the
> documentation.


I could add reference inside integration.rst below: "More information on
the python bindings is available at ``python/ovs/db/idl.py``."


> Maybe there should be a pointer to them from the IDL
> sources.
>
> Thanks,
>
> Ben.
>
Ben Pfaff June 19, 2018, 7:58 p.m. UTC | #3
On Tue, Jun 19, 2018 at 11:51:00AM -0700, Cpp Code wrote:
> Do we need licensing information in these sample files?
> 
> On Mon, Jun 18, 2018 at 8:53 PM, Ben Pfaff <blp@ovn.org> wrote:
> 
> > On Sun, Jun 17, 2018 at 04:24:34AM -0700, Toms Atteka wrote:
> > > created sample python scripts, which helps to learn how to use OVSDB
> > library
> > >
> > > Signed-off-by: Toms Atteka <cpp.code@gmail.com>
> >
> > Thanks for working on making it easier to understand how to use Open
> > vSwitch.
> >
> > This doesn't build, because:
> >
> >     The following files are in git but not the distribution:
> >     python/howto/IDL/delete_bridges.py
> >     python/howto/IDL/insert_bridge.py
> >     python/howto/IDL/ovs_monitor.py
> >     Makefile:6214: recipe for target 'dist-hook-git' failed
> >
> > I think it would be good to ensure that flake8 runs on the new files
> > too.
> >
> > Do you have an idea how these new files can be discoverable to users?
> 
> 
> So far I am not really sure which would be the best way to do that.
> 
> 
> > I guess you decided that they should not be in the Documentation
> > directory.
> 
> 
> From current structure documentation folder feels more like textual
> information.
> 
> 
> > Maybe there should at least be a pointer to them from the
> > documentation.
> 
> 
> I could add reference inside integration.rst below: "More information on
> the python bindings is available at ``python/ovs/db/idl.py``."

That could be helpful.

Maybe it would be worth writing a brief document about the Python IDL
for the Documentation directory?  It could point to the examples and
explain a little bit about them.
diff mbox series

Patch

diff --git a/python/howto/IDL/delete_bridges.py b/python/howto/IDL/delete_bridges.py
new file mode 100755
index 0000000..ff24107
--- /dev/null
+++ b/python/howto/IDL/delete_bridges.py
@@ -0,0 +1,70 @@ 
+#! /usr/bin/env python
+
+# This is a simple example to show how to delete bridges from OVSDB.
+
+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()
+
+
+
diff --git a/python/howto/IDL/insert_bridge.py b/python/howto/IDL/insert_bridge.py
new file mode 100755
index 0000000..cb0209e
--- /dev/null
+++ b/python/howto/IDL/insert_bridge.py
@@ -0,0 +1,75 @@ 
+#! /usr/bin/env python
+
+# 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.
+
+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()
+
+
+
diff --git a/python/howto/IDL/ovs_monitor.py b/python/howto/IDL/ovs_monitor.py
new file mode 100755
index 0000000..44c7117
--- /dev/null
+++ b/python/howto/IDL/ovs_monitor.py
@@ -0,0 +1,102 @@ 
+#! /usr/bin/env python
+
+# 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.
+
+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.
+                # to have multiple interfaces on a port one can add a bond:
+                # ovs-vsctl add-bond <bridge> <bond name> <list of interfaces>
+                (" (" + str(len(port_data.interfaces)) + ") ").ljust(5) +
+                Colors.END,
+                end=""
+            )
+        print()
+
+
+
+