Add some basic usage documentation
This adds some basic usage documentation and a simple tutorial for ovsdbapp. Change-Id: I19583b439f0d8488e957265d89309abf08d307e7
This commit is contained in:
parent
d542e5cee1
commit
6f7aed7098
@ -1,7 +1,20 @@
|
|||||||
=====
|
==================
|
||||||
Usage
|
Library User Guide
|
||||||
=====
|
==================
|
||||||
|
|
||||||
To use ovsdbapp in a project::
|
This document describes OVSDBapp concepts and best practices to enable
|
||||||
|
writing effective OVSDBapp-based applications.
|
||||||
|
|
||||||
import ovsdbapp
|
Overview
|
||||||
|
--------
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
overview
|
||||||
|
|
||||||
|
Tutorial
|
||||||
|
--------
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
tutorial
|
||||||
|
48
doc/source/user/overview.rst
Normal file
48
doc/source/user/overview.rst
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
========
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
OVSDBapp is a library to make it easier to write applications that interact
|
||||||
|
with an Open vSwitch database server. It allows the user to separate support
|
||||||
|
for a particular OVSDB schema and the backend method of communication with the
|
||||||
|
OVSDB server.
|
||||||
|
|
||||||
|
OVSDBapp Concepts
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
API
|
||||||
|
The interface that an application will use for reading or modifying entries
|
||||||
|
in the OVS database. Whatever backend communication method is used, as long
|
||||||
|
as user code only accesses methods in this API, no user code should need to
|
||||||
|
be changed when swapping between backends.
|
||||||
|
Backend
|
||||||
|
The Backend handles the communication with Open vSwitch. Originally, there
|
||||||
|
were two OVSDBapp backends: 1) one that used the ovs-vsctl CLI utility to
|
||||||
|
interact with the OVS database and 2) one that maintains a persistent
|
||||||
|
connection to an OVSDB server using the python-ovs library. Currently, only
|
||||||
|
the python-ovs backend is being maintained.
|
||||||
|
Command
|
||||||
|
OVSDBapp uses the `Command Pattern`_ to isolate individual units of work
|
||||||
|
that will be run as part of an OVSDB transaction.
|
||||||
|
Event
|
||||||
|
OVSDB provides the ability to monitor database changes as they happen.
|
||||||
|
OVSDBapp backends each implement the :code:`RowEvent` and
|
||||||
|
:code:`RowEventHandler` to handle delivering these events to user code.
|
||||||
|
API Implementations:
|
||||||
|
The backend-specific implementation of an OVSDBapp API. Only this code
|
||||||
|
should need to be implemented to support a new backend. All other user
|
||||||
|
code should be backend-agnostic.
|
||||||
|
Schema
|
||||||
|
The OVSDB database schema for which the API is implemented. In current
|
||||||
|
ovsdbapp code, the schema and API are intrinsically linked in a
|
||||||
|
1:1 manner, but ultimately they are independent. User code could easily
|
||||||
|
define an API specific to their application that encompasses multiple
|
||||||
|
OVSDB schemas as long as the Backend supported it.
|
||||||
|
Transaction
|
||||||
|
An OVSDB transaction consisting of one or more Commands.
|
||||||
|
Virtual Environment
|
||||||
|
OVSDBapp supports running OVS and OVN services in a virtual environment.
|
||||||
|
This is primarily used for testing.
|
||||||
|
|
||||||
|
|
||||||
|
.. _Command Pattern: https://en.wikipedia.org/wiki/Command_pattern
|
127
doc/source/user/tutorial.rst
Normal file
127
doc/source/user/tutorial.rst
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
========
|
||||||
|
Tutorial
|
||||||
|
========
|
||||||
|
|
||||||
|
|
||||||
|
Open vSwitch Environment Setup
|
||||||
|
------------------------------
|
||||||
|
This tutorial will use the Open vSwitch sandbox environment from the OVS
|
||||||
|
source tree. For the sake of simplicity, we will build OVS without SSL support.
|
||||||
|
You will need git, C development tools, automake, autoconf, and libtool. See
|
||||||
|
the `Installing Open vSwitch`_ instructions for build requirements
|
||||||
|
and more detailed build instructions.
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
git clone https://github.com/openvswitch/ovs
|
||||||
|
cd ovs
|
||||||
|
./boot.sh
|
||||||
|
./configure --disable-ssl --enable-shared
|
||||||
|
export OVS_SRCDIR=`pwd`
|
||||||
|
make -j $(nproc) sandbox
|
||||||
|
|
||||||
|
Backend Setup
|
||||||
|
-------------
|
||||||
|
While the original ovs-vsctl -based backend required no setup, other backends
|
||||||
|
may. For example, the python-ovs IDL backend maintains a constant connection
|
||||||
|
to ovsdb-server and requires an IDL class to be instantiated and passed to
|
||||||
|
an OVSDBapp IDL backend Connection object.
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import os
|
||||||
|
from ovs.db import idl as ovs_idl
|
||||||
|
from ovsdbapp.backend.ovs_idl import connection
|
||||||
|
from ovsdbapp.schema.open_vswitch import impl_idl
|
||||||
|
|
||||||
|
src_dir = os.getenv("OVS_SRCDIR")
|
||||||
|
run_dir = os.getenv("OVS_RUNDIR", "/var/run/openvswitch")
|
||||||
|
schema_file = os.path.join(src_dir, "vswitchd", "vswitch.ovsschema")
|
||||||
|
db_sock = os.path.join(run_dir, "db.sock")
|
||||||
|
remote = f"unix:{db_sock}"
|
||||||
|
|
||||||
|
schema_helper = ovs_idl.SchemaHelper(schema_file)
|
||||||
|
schema_helper.register_all()
|
||||||
|
idl = ovs_idl.Idl(remote, schema_helper)
|
||||||
|
conn = connection.Connection(idl=idl, timeout=60)
|
||||||
|
|
||||||
|
api = impl_idl.OvsdbIdl(conn)
|
||||||
|
|
||||||
|
|
||||||
|
Using the API
|
||||||
|
-------------
|
||||||
|
Each API definition varies based on the schemas it supports and what the
|
||||||
|
app requires. There is built-in support for many common OVS and OVN-related
|
||||||
|
schemas, but it is possible that the APIs defined for these are not optimized
|
||||||
|
for a given app's use cases. It may often make sense for apps to define APIs
|
||||||
|
separate from those that are in ovsdbapp.
|
||||||
|
|
||||||
|
With that said, any api that inherits from ovsdbapp.api.API will at least
|
||||||
|
have methods defined for the standard generic OVSDB DB operations found
|
||||||
|
described in the `ovs-vsctl manpage`_ under Database Commands.
|
||||||
|
|
||||||
|
* list
|
||||||
|
* find
|
||||||
|
* get
|
||||||
|
* set
|
||||||
|
* add
|
||||||
|
* remove
|
||||||
|
* clear
|
||||||
|
* create
|
||||||
|
* destroy
|
||||||
|
|
||||||
|
They are all prefixed with db\_ (e.g. list becomes db_list) and have an
|
||||||
|
interface similar to that used by ovs-vsctl, ovn-nbctl, ovn-sbctl, etc.
|
||||||
|
db_list() and db_find() return results as lists of dicts with each dict
|
||||||
|
representing a row, with keys as the column names. Later versions added
|
||||||
|
db_list_rows() and db_find_rows() to return lists of RowView objects.
|
||||||
|
|
||||||
|
API commands that interact with the OVSDB server typically return an instance
|
||||||
|
of a subclass of ovsdbapp.api.Command. These objects hold the state of a
|
||||||
|
request that will be sent to an OVSDB server as part of a transaction. They
|
||||||
|
can be thought of as the equivalent of queries in SQL.
|
||||||
|
|
||||||
|
For a Command to be sent to the OVSDB server, it must be attached to a
|
||||||
|
transaction, and committed. For single commands, this can be done with
|
||||||
|
execute():
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
results = api.db_list("Open_vSwitch").execute(check_error=True)
|
||||||
|
|
||||||
|
This implicitly creates a transaction, adds the Command returned by db_list()
|
||||||
|
to that transaction, calls commit() on the transaction, and returns the result
|
||||||
|
that is stored on the Command object. It is the equivalent of:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
txn = api.create_transaction(check_error=True)
|
||||||
|
list_cmd = api.db_list("Open_vSwitch")
|
||||||
|
txn.add(list_cmd)
|
||||||
|
txn.commit()
|
||||||
|
results = list_cmd.result
|
||||||
|
|
||||||
|
That API also defines transaction(), a context manager, that makes
|
||||||
|
multi-command transactions easier.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
with api.transaction(check_error=True) as txn:
|
||||||
|
br_cmd = txn.add(api.db_create("Bridge", name="test-br"))
|
||||||
|
txn.add(api.db_add("Open_vSwitch", ".", "bridges", br_cmd))
|
||||||
|
|
||||||
|
There are some things to note with the above code. First, is that
|
||||||
|
Transaction.add() returns the Command object that is passed to it. In the case
|
||||||
|
of the db_create() command, the row it will create can be referenced in other
|
||||||
|
commands in the same transaction. Second, if a table is defined as having at
|
||||||
|
most one row, like the Open_vSwitch table, instead of passing its UUID, "."
|
||||||
|
can be passed. Lastly, note that we are creating a Bridge row and adding it to
|
||||||
|
the Open_vSwitch row's "bridges" field. The Bridge table is not set as a "root"
|
||||||
|
table in the Open_vSwitch schema. What this means is that if no row in a root
|
||||||
|
table references this Bridge, ovsdb-server will automatically clean up this
|
||||||
|
row. The Open_vSwitch table is a root table, so referencing the bridge in that
|
||||||
|
row prevents the bridge that was just created from being immediately removed.
|
||||||
|
|
||||||
|
.. _Installing Open vSwitch: https://docs.openvswitch.org/en/latest/intro/install/
|
||||||
|
.. _ovs-vsctl manpage: http://www.openvswitch.org/support/dist-docs/ovs-vsctl.8.html
|
Loading…
x
Reference in New Issue
Block a user