On Tue, Sep 29, 2026 at 10:31 PM Dumitru Ceara <[email protected]> wrote:

> On 9/24/26 7:55 AM, Ales Musil wrote:
> > The ovn-docker files were not updated for a very long time apart
> > from treewide adjustments. Let's remove the ovn-docker
> > utility files.
> >
> > Signed-off-by: Ales Musil <[email protected]>
> > ---
>
> Hi Ales,
>

Hi Dumitru,

thank you for the review.


>
> This needs a small adjustment:
> https://github.com/ovsrobot/ovn/actions/runs/35963558453
>
> This needs to be removed:
>
> https://github.com/ovn-kubernetes/ovn-kubernetes/blob/f1d5bcc05077d0f859cf7628aab507e06089b9e3/dist/images/Dockerfile.fedora#L79
>
> And also backported on the ovn-kubernetes stable branch (I'm working on
> bumping our CI to release-1.4).
>
> The rest of this patch looks good to me but I'll skip it for now.
>

I have posted https://github.com/ovn-kubernetes/ovn-kubernetes/pull/7022
to address that.


>
> Regards,
> Dumitru
>

Regards,
Ales


>
>
> >  Documentation/automake.mk                    |   2 -
> >  Documentation/howto/docker.rst               | 323 ---------
> >  Documentation/howto/index.rst                |   2 -
> >  Documentation/howto/openstack-containers.rst | 135 ----
> >  Documentation/intro/install/fedora.rst       |   2 +-
> >  NEWS                                         |   1 +
> >  debian/.gitignore                            |   1 -
> >  rhel/ovn-fedora.spec.in                      |  14 -
> >  utilities/.gitignore                         |   2 -
> >  utilities/automake.mk                        |   6 -
> >  utilities/ovn-docker-overlay-driver.in       | 442 ------------
> >  utilities/ovn-docker-underlay-driver.in      | 677 -------------------
> >  12 files changed, 2 insertions(+), 1605 deletions(-)
> >  delete mode 100644 Documentation/howto/docker.rst
> >  delete mode 100644 Documentation/howto/openstack-containers.rst
> >  delete mode 100755 utilities/ovn-docker-overlay-driver.in
> >  delete mode 100755 utilities/ovn-docker-underlay-driver.in
> >
> > diff --git a/Documentation/automake.mk b/Documentation/automake.mk
> > index b8187607e..79156fae0 100644
> > --- a/Documentation/automake.mk
> > +++ b/Documentation/automake.mk
> > @@ -38,11 +38,9 @@ DOC_SOURCE = \
> >       Documentation/topics/vif-plug-providers/index.rst \
> >       Documentation/topics/vif-plug-providers/vif-plug-providers.rst \
> >       Documentation/howto/index.rst \
> > -     Documentation/howto/docker.rst \
> >       Documentation/howto/firewalld.rst \
> >       Documentation/howto/ipsec.rst \
> >       Documentation/howto/ssl.rst \
> > -     Documentation/howto/openstack-containers.rst \
> >       Documentation/ref/index.rst \
> >       Documentation/faq/index.rst \
> >       Documentation/faq/contributing.rst \
> > diff --git a/Documentation/howto/docker.rst
> b/Documentation/howto/docker.rst
> > deleted file mode 100644
> > index 1ada1fa2c..000000000
> > --- a/Documentation/howto/docker.rst
> > +++ /dev/null
> > @@ -1,323 +0,0 @@
> > -..
> > -      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 OVN 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.
> > -
> > -===================================
> > -Open Virtual Networking With Docker
> > -===================================
> > -
> > -This document describes how to use Open Virtual Networking with Docker
> 1.9.0
> > -or later.
> > -
> > -.. important::
> > -
> > -  Requires Docker version 1.9.0 or later. Only Docker 1.9.0+ comes with
> support
> > -  for multi-host networking. Consult www.docker.com for instructions
> on how to
> > -  install Docker.
> > -
> > -.. note::
> > -
> > -  You must build and install Open vSwitch before proceeding with the
> below
> > -  guide. Refer to :doc:`/intro/install/index` for more information.
> > -
> > -Setup
> > ------
> > -
> > -For multi-host networking with OVN and Docker, Docker has to be started
> with a
> > -distributed key-value store. For example, if you decide to use consul
> as your
> > -distributed key-value store and your host IP address is ``$HOST_IP``,
> start
> > -your Docker daemon with::
> > -
> > -    $ docker daemon --cluster-store=consul://127.0.0.1:8500 \
> > -        --cluster-advertise=$HOST_IP:0
> > -
> > -OVN provides network virtualization to containers. OVN's integration
> with
> > -Docker currently works in two modes - the "underlay" mode or the
> "overlay"
> > -mode.
> > -
> > -In the "underlay" mode, OVN requires a OpenStack setup to provide
> container
> > -networking. In this mode, one can create logical networks and can have
> > -containers running inside VMs, standalone VMs (without having any
> containers
> > -running inside them) and physical machines connected to the same logical
> > -network. This is a multi-tenant, multi-host solution.
> > -
> > -In the "overlay" mode, OVN can create a logical network amongst
> containers
> > -running on multiple hosts. This is a single-tenant (extendable to
> multi-tenants
> > -depending on the security characteristics of the workloads), multi-host
> > -solution. In this mode, you do not need a pre-created OpenStack setup.
> > -
> > -For both the modes to work, a user has to install and start Open
> vSwitch in
> > -each VM/host that they plan to run their containers on.
> > -
> > -.. _docker-overlay:
> > -
> > -The "overlay" mode
> > -------------------
> > -
> > -.. note::
> > -
> > -  OVN in "overlay" mode needs a minimum Open vSwitch version of 2.5.
> > -
> > -1. Start the central components.
> > -
> > -  OVN architecture has a central component which stores your networking
> intent
> > -  in a database. On one of your machines, with an IP Address of
> > -  ``$CENTRAL_IP``, where you have installed and started Open vSwitch,
> you will
> > -  need to start some central components.
> > -
> > -  Start ovn-northd daemon. This daemon translates networking intent
> from Docker
> > -  stored in the OVN\_Northbound database to logical flows in
> ``OVN_Southbound``
> > -  database. For example::
> > -
> > -      $ /usr/share/ovn/scripts/ovn-ctl start_northd
> > -
> > -  With Open vSwitch version of 2.7 or greater, you need to run the
> following
> > -  additional commands (Please read the manpages of ovn-nb for more
> control
> > -  on the types of connection allowed.) ::
> > -
> > -      $ ovn-nbctl set-connection ptcp:6641
> > -      $ ovn-sbctl set-connection ptcp:6642
> > -
> > -2. One time setup
> > -
> > -   On each host, where you plan to spawn your containers, you will need
> to run
> > -   the below command once. You may need to run it again if your OVS
> database
> > -   gets cleared. It is harmless to run it again in any case::
> > -
> > -       $ ovs-vsctl set Open_vSwitch . \
> > -           external_ids:ovn-remote="tcp:$CENTRAL_IP:6642" \
> > -           external_ids:ovn-nb="tcp:$CENTRAL_IP:6641" \
> > -           external_ids:ovn-encap-ip=$LOCAL_IP \
> > -           external_ids:ovn-encap-type="$ENCAP_TYPE"
> > -
> > -   where:
> > -
> > -   ``$LOCAL_IP``
> > -     is the IP address via which other hosts can reach this host.  This
> acts as
> > -     your local tunnel endpoint.
> > -
> > -   ``$ENCAP_TYPE``
> > -     is the type of tunnel that you would like to use for overlay
> networking.
> > -     The options are ``geneve`` or ``vxlan``. Your kernel must have
> support for
> > -     your chosen ``$ENCAP_TYPE``.  You will need a minimum Linux kernel
> version
> > -     of 3.18 for ``geneve``.  You can verify whether you have the
> support in
> > -     your kernel as follows::
> > -
> > -         $ lsmod | grep $ENCAP_TYPE
> > -
> > -   In addition, each Open vSwitch instance in an OVN deployment needs a
> unique,
> > -   persistent identifier, called the ``system-id``.  If you install OVS
> from
> > -   distribution packaging for Open vSwitch (e.g. .deb or .rpm
> packages), or if
> > -   you use the ovs-ctl utility included with Open vSwitch, it
> automatically
> > -   configures a system-id.  If you start Open vSwitch manually, you
> should set
> > -   one up yourself. For example::
> > -
> > -       $ id_file=/etc/openvswitch/system-id.conf
> > -       $ test -e $id_file || uuidgen > $id_file
> > -       $ ovs-vsctl set Open_vSwitch . external_ids:system-id=$(cat
> $id_file)
> > -
> > -3. Start the ``ovn-controller``.
> > -
> > -   You need to run the below command on every boot::
> > -
> > -       $ /usr/share/ovn/scripts/ovn-ctl start_controller
> > -
> > -4. Start the Open vSwitch network driver.
> > -
> > -   By default Docker uses Linux bridge for networking. But it has
> support for
> > -   external drivers. To use Open vSwitch instead of the Linux bridge,
> you will
> > -   need to start the Open vSwitch driver.
> > -
> > -   The Open vSwitch driver uses the Python's flask module to listen to
> Docker's
> > -   networking api calls. So, if your host does not have Python's flask
> module,
> > -   install it::
> > -
> > -       $ sudo pip install Flask
> > -
> > -   Start the Open vSwitch driver on every host where you plan to create
> your
> > -   containers. Refer to the note on ``$OVS_PYTHON_LIBS_PATH`` that is
> used below
> > -   at the end of this document::
> > -
> > -       $ PYTHONPATH=$OVS_PYTHON_LIBS_PATH ovn-docker-overlay-driver
> --detach
> > -
> > -   .. note::
> > -
> > -     The ``$OVS_PYTHON_LIBS_PATH`` variable should point to the
> directory where
> > -     Open vSwitch Python modules are installed. If you installed Open
> vSwitch
> > -     Python modules via the Debian package of ``python-openvswitch`` or
> via pip
> > -     by running ``pip install ovs``, you do not need to specify the
> PATH. If
> > -     you installed it by following the instructions in
> > -     :doc:`/intro/install/general`, then you should specify the PATH.
> In this
> > -     case, the PATH depends on the options passed to ``./configure``.
> It is
> > -     usually either ``/usr/share/openvswitch/python`` or
> > -     ``/usr/local/share/openvswitch/python``
> > -
> > -Docker has inbuilt primitives that closely match OVN's logical switches
> and
> > -logical port concepts. Consult Docker's documentation for all the
> possible
> > -commands. Here are some examples.
> > -
> > -Create a logical switch
> > -~~~~~~~~~~~~~~~~~~~~~~~
> > -
> > -To create a logical switch with name 'foo', on subnet '192.168.1.0/24',
> run::
> > -
> > -    $ NID=`docker network create -d openvswitch --subnet=192.168.1.0/24
> foo`
> > -
> > -List all logical switches
> > -~~~~~~~~~~~~~~~~~~~~~~~~~
> > -
> > -::
> > -
> > -    $ docker network ls
> > -
> > -You can also look at this logical switch in OVN's northbound database by
> > -running the following command::
> > -
> > -    $ ovn-nbctl --db=tcp:$CENTRAL_IP:6640 ls-list
> > -
> > -Delete a logical switch
> > -~~~~~~~~~~~~~~~~~~~~~~~
> > -
> > -::
> > -
> > -    $ docker network rm bar
> > -
> > -
> > -Create a logical port
> > -~~~~~~~~~~~~~~~~~~~~~
> > -
> > -Docker creates your logical port and attaches it to the logical network
> in a
> > -single step. For example, to attach a logical port to network ``foo``
> inside
> > -container busybox, run::
> > -
> > -    $ docker run -itd --net=foo --name=busybox busybox
> > -
> > -List all logical ports
> > -~~~~~~~~~~~~~~~~~~~~~~
> > -
> > -Docker does not currently have a CLI command to list all logical ports
> but you
> > -can look at them in the OVN database by running::
> > -
> > -    $ ovn-nbctl --db=tcp:$CENTRAL_IP:6640 lsp-list $NID
> > -
> > -Create and attach a logical port to a running container
> > -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > -
> > -::
> > -
> > -    $ docker network create -d openvswitch --subnet=192.168.2.0/24 bar
> > -    $ docker network connect bar busybox
> > -
> > -Detach and delete a logical port from a running container
> > -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > -
> > -You can delete your logical port and detach it from a running container
> > -by running:
> > -
> > -::
> > -
> > -    $ docker network disconnect bar busybox
> > -
> > -.. _docker-underlay:
> > -
> > -The "underlay" mode
> > --------------------
> > -
> > -.. note::
> > -
> > -  This mode requires that you have a OpenStack setup pre-installed with
> > -  OVN providing the underlay networking.
> > -
> > -1. One time setup
> > -
> > -   A OpenStack tenant creates a VM with a single network interface (or
> multiple)
> > -   that belongs to management logical networks. The tenant needs to
> fetch the
> > -   port-id associated with the interface via which he plans to send the
> container
> > -   traffic inside the spawned VM. This can be obtained by running the
> below
> > -   command to fetch the 'id' associated with the VM::
> > -
> > -       $ nova list
> > -
> > -   and then by running::
> > -
> > -       $ neutron port-list --device_id=$id
> > -
> > -   Inside the VM, download the OpenStack RC file that contains the
> tenant
> > -   information (henceforth referred to as ``openrc.sh``). Edit the file
> and add the
> > -   previously obtained port-id information to the file by appending the
> following
> > -   line::
> > -
> > -       $ export OS_VIF_ID=$port_id
> > -
> > -   After this edit, the file will look something like::
> > -
> > -       #!/bin/bash
> > -       export OS_AUTH_URL=http://10.33.75.122:5000/v2.0
> > -       export OS_TENANT_ID=fab106b215d943c3bad519492278443d
> > -       export OS_TENANT_NAME="demo"
> > -       export OS_USERNAME="demo"
> > -       export OS_VIF_ID=e798c371-85f4-4f2d-ad65-d09dd1d3c1c9
> > -
> > -2. Create the Open vSwitch bridge
> > -
> > -   If your VM has one ethernet interface (e.g.: 'eth0'), you will need
> to add
> > -   that device as a port to an Open vSwitch bridge 'breth0' and move
> its IP
> > -   address and route related information to that bridge. (If it has
> multiple
> > -   network interfaces, you will need to create and attach an Open
> vSwitch
> > -   bridge for the interface via which you plan to send your container
> > -   traffic.)
> > -
> > -   If you use DHCP to obtain an IP address, then you should kill the
> DHCP
> > -   client that was listening on the physical Ethernet interface (e.g.
> eth0) and
> > -   start one listening on the Open vSwitch bridge (e.g. breth0).
> > -
> > -   Depending on your VM, you can make the above step persistent across
> reboots.
> > -   For example, if your VM is Debian/Ubuntu-based, read
> > -   `openvswitch-switch.README.Debian` found in `debian` folder. If your
> VM is
> > -   RHEL-based, refer to :doc:`/intro/install/fedora`.
> > -
> > -3. Start the Open vSwitch network driver
> > -
> > -   The Open vSwitch driver uses the Python's flask module to listen to
> Docker's
> > -   networking api calls. The driver also uses OpenStack's
> > -   ``python-neutronclient`` libraries. If your host does not have
> Python's
> > -   ``flask`` module or ``python-neutronclient`` you must install them.
> For
> > -   example::
> > -
> > -       $ pip install python-neutronclient
> > -       $ pip install Flask
> > -
> > -   Once installed, source the ``openrc`` file::
> > -
> > -       $ . ./openrc.sh
> > -
> > -   Start the network driver and provide your OpenStack tenant password
> when
> > -   prompted::
> > -
> > -       $ PYTHONPATH=$OVS_PYTHON_LIBS_PATH ovn-docker-underlay-driver \
> > -           --bridge breth0 --detach
> > -
> > -From here-on you can use the same Docker commands as described in
> > -`docker-overlay`_.
> > -
> > -Refer to the ovs-architecture man pages (``man ovn-architecture``) to
> > -understand OVN's architecture in detail.
> > diff --git a/Documentation/howto/index.rst
> b/Documentation/howto/index.rst
> > index 6f6c59482..dab3058be 100644
> > --- a/Documentation/howto/index.rst
> > +++ b/Documentation/howto/index.rst
> > @@ -45,6 +45,4 @@ OVN
> >  .. toctree::
> >     :maxdepth: 1
> >
> > -   docker
> > -   openstack-containers
> >     firewalld
> > diff --git a/Documentation/howto/openstack-containers.rst
> b/Documentation/howto/openstack-containers.rst
> > deleted file mode 100644
> > index b6911d19e..000000000
> > --- a/Documentation/howto/openstack-containers.rst
> > +++ /dev/null
> > @@ -1,135 +0,0 @@
> > -..
> > -      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 OVN 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.
> > -
> > -================================================
> > -Integration of Containers with OVN and OpenStack
> > -================================================
> > -
> > -Isolation between containers is weaker than isolation between VMs, so
> some
> > -environments deploy containers for different tenants in separate VMs as
> an
> > -additional security measure.  This document describes creation of
> containers
> > -inside VMs and how they can be made part of the logical networks
> securely.  The
> > -created logical network can include VMs, containers and physical
> machines as
> > -endpoints.  To better understand the proposed integration of containers
> with
> > -OVN and OpenStack, this document describes the end to end workflow with
> an
> > -example.
> > -
> > -* A OpenStack tenant creates a VM (say VM-A) with a single network
> interface
> > -  that belongs to a management logical network.  The VM is meant to host
> > -  containers.  OpenStack Nova chooses the hypervisor on which VM-A is
> created.
> > -
> > -* A Neutron port may have been created in advance and passed in to Nova
> with
> > -  the request to create a new VM.  If not, Nova will issue a request to
> Neutron
> > -  to create a new port.  The ID of the logical port from Neutron will
> also be
> > -  used as the vif-id for the virtual network interface (VIF) of VM-A.
> > -
> > -* When VM-A is created on a hypervisor, its VIF gets added to the Open
> vSwitch
> > -  integration bridge.  This creates a row in the Interface table of the
> > -  ``Open_vSwitch`` database.  As explained in the :doc:`integration
> guide
> > -  </topics/integration>`, the vif-id associated with the VM network
> interface
> > -  gets added in the ``external_ids:iface-id`` column of the newly
> created row
> > -  in the Interface table.
> > -
> > -* Since VM-A belongs to a logical network, it gets an IP address.  This
> IP
> > -  address is used to spawn containers (either manually or through
> container
> > -  orchestration systems) inside that VM and to monitor the health of the
> > -  created containers.
> > -
> > -* The vif-id associated with the VM's network interface can be obtained
> by
> > -  making a call to Neutron using tenant credentials.
> > -
> > -* This flow assumes a component called a "container network plugin".
> If you
> > -  take Docker as an example for containers, you could envision the
> plugin to be
> > -  either a wrapper around Docker or a feature of Docker itself that
> understands
> > -  how to perform part of this workflow to get a container connected to a
> > -  logical network managed by Neutron.  The rest of the flow refers to
> this
> > -  logical component that does not yet exist as the "container network
> plugin".
> > -
> > -* All the calls to Neutron will need tenant credentials.  These calls
> can
> > -  either be made from inside the tenant VM as part of a container
> network
> > -  plugin or from outside the tenant VM (if the tenant is not
> comfortable using
> > -  temporary Keystone tokens from inside the tenant VMs).  For
> simplicity, this
> > -  document explains the work flow using the former method.
> > -
> > -* The container hosting VM will need Open vSwitch installed in it.  The
> only
> > -  work for Open vSwitch inside the VM is to tag network traffic coming
> from
> > -  containers.
> > -
> > -* When a container needs to be created inside the VM with a container
> network
> > -  interface that is expected to be attached to a particular logical
> switch, the
> > -  network plugin in that VM chooses any unused VLAN (This VLAN tag only
> needs
> > -  to be unique inside that VM.  This limits the number of container
> interfaces
> > -  to 4096 inside a single VM).  This VLAN tag is stripped out in the
> hypervisor
> > -  by OVN and is only useful as a context (or metadata) for OVN.
> > -
> > -* The container network plugin then makes a call to Neutron to create a
> logical
> > -  port.  In addition to all the inputs that a call to create a port in
> Neutron
> > -  that are currently needed, it sends the vif-id and the VLAN tag as
> inputs.
> > -
> > -* Neutron in turn will verify that the vif-id belongs to the tenant in
> question
> > -  and then uses the OVN specific plugin to create a new row in the
> > -  Logical_Switch_Port table of the OVN Northbound Database.  Neutron
> responds
> > -  back with an IP address and MAC address for that network interface.
> So
> > -  Neutron becomes the IPAM system and provides unique IP and MAC
> addresses
> > -  across VMs and containers in the same logical network.
> > -
> > -* The Neutron API call above to create a logical port for the container
> could
> > -  add a relatively significant amount of time to container creation.
> However,
> > -  an optimization is possible here.  Logical ports could be created in
> advance
> > -  and reused by the container system doing container orchestration.
> Additional
> > -  Neutron API calls would only be needed if the port needs to be
> attached to a
> > -  different logical network.
> > -
> > -* When a container is eventually deleted, the network plugin in that VM
> may
> > -  make a call to Neutron to delete that port.  Neutron in turn will
> delete the
> > -  entry in the ``Logical_Switch_Port`` table of the OVN Northbound
> Database.
> > -
> > -As an example, consider Docker containers.  Since Docker currently does
> not
> > -have a network plugin feature, this example uses a hypothetical wrapper
> around
> > -Docker to make calls to Neutron.
> > -
> > -* Create a Logical switch::
> > -
> > -      $ ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f create
> network LS1
> > -
> > -  The above command will make a call to Neutron with the credentials to
> create
> > -  a logical switch.  The above is optional if the logical switch has
> already
> > -  been created from outside the VM.
> > -
> > -* List networks available to the tenant::
> > -
> > -      $ ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f list networks
> > -
> > -* Create a container and attach a interface to the previously created
> switch as
> > -  a logical port::
> > -
> > -      $ ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f
> --vif-id=$VIF_ID \
> > -          --network=LS1 run -d --net=none ubuntu:14.04 /bin/sh -c \
> > -          "while true; do echo hello world; sleep 1; done"
> > -
> > -  The above command will make a call to Neutron with all the inputs it
> > -  currently needs to create a logical port.  In addition, it passes the
> $VIF_ID
> > -  and a unused VLAN.  Neutron will add that information in OVN and
> return back
> > -  a MAC address and IP address for that interface.  ovn-docker will
> then create
> > -  a veth pair, insert one end inside the container as 'eth0' and the
> other end
> > -  as a port of a local OVS bridge as an access port of the chosen VLAN.
> > diff --git a/Documentation/intro/install/fedora.rst
> b/Documentation/intro/install/fedora.rst
> > index b1d2ea5df..b6ee88a4f 100644
> > --- a/Documentation/intro/install/fedora.rst
> > +++ b/Documentation/intro/install/fedora.rst
> > @@ -109,7 +109,7 @@ Then execute the following from the OVN source
> directory (in which
> >      $ make rpm-fedora
> >
> >  This will create the RPMs ``ovn``, ``ovn-central``, ``ovn-host``,
> > -``ovn-vtep``, ``ovn-docker``, and ``ovn-br-controller``, along with
> > +``ovn-vtep``, and ``ovn-br-controller``, along with
> >  their debuginfo variants.
> >
> >  You can also have the above commands automatically run the OVN unit
> > diff --git a/NEWS b/NEWS
> > index 3b41042b6..7f94d0b14 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -18,6 +18,7 @@ Post v26.09.0
> >         obsolete.
> >     - Removed OVN's ovs-bugtool plugin and helper scripts.
> >     - Removed ovn-sim utility scripts.
> > +   - Removed ovn-docker utility scripts.
> >
> >  OVN v26.09.0 - xxx xx xxxx
> >  --------------------------
> > diff --git a/debian/.gitignore b/debian/.gitignore
> > index 8873d381c..2fd03d861 100644
> > --- a/debian/.gitignore
> > +++ b/debian/.gitignore
> > @@ -10,5 +10,4 @@
> >  /ovn-controller-vtep
> >  /ovn-host
> >  /ovn-central
> > -/ovn-docker
> >  /tmp
> > diff --git a/rhel/ovn-fedora.spec.in b/rhel/ovn-fedora.spec.in
> > index e70c581e7..8c8b96050 100644
> > --- a/rhel/ovn-fedora.spec.in
> > +++ b/rhel/ovn-fedora.spec.in
> > @@ -111,16 +111,6 @@ Provides: openvswitch-ovn-vtep =
> %{?epoch:%{epoch}:}%{version}-%{release}
> >  %description vtep
> >  OVN vtep controller
> >
> > -%package docker
> > -Summary: Open Virtual Network support
> > -License: ASL 2.0
> > -Requires: ovn python3-openvswitch
> > -Obsoletes: openvswitch-ovn-docker
> > -Provides: openvswitch-ovn-docker =
> %{?epoch:%{epoch}:}%{version}-%{release}
> > -
> > -%description docker
> > -Docker network plugins for OVN.
> > -
> >  %package br-controller
> >  Summary: Open Virtual Network support
> >  License: ASL 2.0
> > @@ -528,10 +518,6 @@ fi
> >  %config(noreplace) %{_sysconfdir}/logrotate.d/ovn
> >  %{_unitdir}/[email protected]
> >
> > -%files docker
> > -%{_bindir}/ovn-docker-overlay-driver
> > -%{_bindir}/ovn-docker-underlay-driver
> > -
> >  %files central
> >  %{_bindir}/ovn-northd
> >  %{_bindir}/ovn-ic
> > diff --git a/utilities/.gitignore b/utilities/.gitignore
> > index eb98594b7..fa1bc272b 100644
> > --- a/utilities/.gitignore
> > +++ b/utilities/.gitignore
> > @@ -16,6 +16,4 @@
> >  /ovn-detrace.1
> >  /ovn-debug
> >  /ovn-debug.8
> > -/ovn-docker-overlay-driver
> > -/ovn-docker-underlay-driver
> >  /ovn-lib
> > diff --git a/utilities/automake.mk b/utilities/automake.mk
> > index 7d3f320dc..edf3fe9cd 100644
> > --- a/utilities/automake.mk
> > +++ b/utilities/automake.mk
> > @@ -18,16 +18,12 @@ MAN_ROOTS += \
> >      utilities/ovn-detrace.1.in
> >
> >  bin_SCRIPTS += \
> > -    utilities/ovn-docker-overlay-driver \
> > -    utilities/ovn-docker-underlay-driver \
> >      utilities/ovn_detrace.py
> >
> >  EXTRA_DIST += \
> >      utilities/ovn-ctl \
> >      utilities/ovn-lib.in \
> >      utilities/ovn-ctl.8.xml \
> > -    utilities/ovn-docker-overlay-driver.in \
> > -    utilities/ovn-docker-underlay-driver.in \
> >      utilities/ovn-nbctl.8.xml \
> >      utilities/ovn-sbctl.8.xml \
> >      utilities/ovn-ic-nbctl.8.xml \
> > @@ -48,8 +44,6 @@ EXTRA_DIST += \
> >  CLEANFILES += \
> >      utilities/ovn-ctl.8 \
> >      utilities/ovn-lib \
> > -    utilities/ovn-docker-overlay-driver \
> > -    utilities/ovn-docker-underlay-driver \
> >      utilities/ovn-nbctl.8 \
> >      utilities/ovn-sbctl.8 \
> >      utilities/ovn-ic-nbctl.8 \
> > diff --git a/utilities/ovn-docker-overlay-driver.in b/utilities/
> ovn-docker-overlay-driver.in
> > deleted file mode 100755
> > index f408bbdd8..000000000
> > --- a/utilities/ovn-docker-overlay-driver.in
> > +++ /dev/null
> > @@ -1,442 +0,0 @@
> > -#! @PYTHON3@
> > -# Copyright (C) 2015 Nicira, Inc.
> > -#
> > -# 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.
> > -
> > -import argparse
> > -import ast
> > -import atexit
> > -import json
> > -import os
> > -import random
> > -import re
> > -import shlex
> > -import subprocess
> > -import sys
> > -
> > -import ovs.dirs
> > -import ovs.util
> > -import ovs.daemon
> > -import ovs.vlog
> > -
> > -from flask import Flask, jsonify
> > -from flask import request, abort
> > -
> > -app = Flask(__name__)
> > -vlog = ovs.vlog.Vlog("ovn-docker-overlay-driver")
> > -
> > -OVN_BRIDGE = "br-int"
> > -OVN_NB = ""
> > -PLUGIN_DIR = "/etc/docker/plugins"
> > -PLUGIN_FILE = "/etc/docker/plugins/openvswitch.spec"
> > -
> > -
> > -def call_popen(cmd):
> > -    child = subprocess.Popen(cmd, stdout=subprocess.PIPE)
> > -    output = child.communicate()
> > -    if child.returncode:
> > -        raise RuntimeError("Fatal error executing %s" % (cmd))
> > -    if len(output) == 0 or output[0] == None:
> > -        output = ""
> > -    else:
> > -        output = output[0].strip()
> > -    return output
> > -
> > -
> > -def call_prog(prog, args_list):
> > -    cmd = [prog, "--timeout=5", "-vconsole:off"] + args_list
> > -    return call_popen(cmd)
> > -
> > -
> > -def ovs_vsctl(*args):
> > -    return call_prog("ovs-vsctl", list(args))
> > -
> > -
> > -def ovn_nbctl(*args):
> > -    args_list = list(args)
> > -    database_option = "%s=%s" % ("--db", OVN_NB)
> > -    args_list.insert(0, database_option)
> > -    return call_prog("ovn-nbctl", args_list)
> > -
> > -
> > -def cleanup():
> > -    if os.path.isfile(PLUGIN_FILE):
> > -        os.remove(PLUGIN_FILE)
> > -
> > -
> > -def ovn_init_overlay():
> > -    br_list = ovs_vsctl("list-br").split()
> > -    if OVN_BRIDGE not in br_list:
> > -        ovs_vsctl("--", "--may-exist", "add-br", OVN_BRIDGE,
> > -                  "--", "set", "bridge", OVN_BRIDGE,
> > -                  "external_ids:bridge-id=" + OVN_BRIDGE,
> > -                  "other-config:disable-in-band=true",
> "fail-mode=secure")
> > -
> > -    global OVN_NB
> > -    OVN_NB = ovs_vsctl("get", "Open_vSwitch", ".",
> > -                           "external_ids:ovn-nb").strip('"')
> > -    if not OVN_NB:
> > -        sys.exit("OVN central database's ip address not set")
> > -
> > -    ovs_vsctl("set", "open_vswitch", ".",
> > -              "external_ids:ovn-bridge=" + OVN_BRIDGE)
> > -
> > -
> > -def prepare():
> > -    parser = argparse.ArgumentParser()
> > -
> > -    ovs.vlog.add_args(parser)
> > -    ovs.daemon.add_args(parser)
> > -    args = parser.parse_args()
> > -    ovs.vlog.handle_args(args)
> > -    ovs.daemon.handle_args(args)
> > -    ovn_init_overlay()
> > -
> > -    if not os.path.isdir(PLUGIN_DIR):
> > -        os.makedirs(PLUGIN_DIR)
> > -
> > -    ovs.daemon.daemonize()
> > -    try:
> > -        fo = open(PLUGIN_FILE, "w")
> > -        fo.write("tcp://0.0.0.0:5000")
> > -        fo.close()
> > -    except Exception as e:
> > -        ovs.util.ovs_fatal(0, "Failed to write to spec file (%s)" %
> str(e),
> > -                           vlog)
> > -
> > -    atexit.register(cleanup)
> > -
> > -
> > [email protected]('/Plugin.Activate', methods=['POST'])
> > -def plugin_activate():
> > -    return jsonify({"Implements": ["NetworkDriver"]})
> > -
> > -
> > [email protected]('/NetworkDriver.GetCapabilities', methods=['POST'])
> > -def get_capability():
> > -    return jsonify({"Scope": "global"})
> > -
> > -
> > [email protected]('/NetworkDriver.DiscoverNew', methods=['POST'])
> > -def new_discovery():
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.DiscoverDelete', methods=['POST'])
> > -def delete_discovery():
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.CreateNetwork', methods=['POST'])
> > -def create_network():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    # NetworkID will have docker generated network uuid and it
> > -    # becomes 'name' in a OVN Logical switch record.
> > -    network = data.get("NetworkID", "")
> > -    if not network:
> > -        abort(400)
> > -
> > -    # Limit subnet handling to ipv4 till ipv6 usecase is clear.
> > -    ipv4_data = data.get("IPv4Data", "")
> > -    if not ipv4_data:
> > -        error = "create_network: No ipv4 subnet provided"
> > -        return jsonify({'Err': error})
> > -
> > -    subnet = ipv4_data[0].get("Pool", "")
> > -    if not subnet:
> > -        error = "create_network: no subnet in ipv4 data from libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    gateway_ip = ipv4_data[0].get("Gateway", "").rsplit('/', 1)[0]
> > -    if not gateway_ip:
> > -        error = "create_network: no gateway in ipv4 data from
> libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ovn_nbctl("ls-add", network, "--", "set", "Logical_Switch",
> > -                  network, "external_ids:subnet=" + subnet,
> > -                  "external_ids:gateway_ip=" + gateway_ip)
> > -    except Exception as e:
> > -        error = "create_network: ls-add %s" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.DeleteNetwork', methods=['POST'])
> > -def delete_network():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    try:
> > -        ovn_nbctl("ls-del", nid)
> > -    except Exception as e:
> > -        error = "delete_network: ls-del %s" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.CreateEndpoint', methods=['POST'])
> > -def create_endpoint():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    interface = data.get("Interface", "")
> > -    if not interface:
> > -        error = "create_endpoint: no interfaces structure supplied by "
> \
> > -                "libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    ip_address_and_mask = interface.get("Address", "")
> > -    if not ip_address_and_mask:
> > -        error = "create_endpoint: ip address not provided by libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    ip_address = ip_address_and_mask.rsplit('/', 1)[0]
> > -    mac_address_input = interface.get("MacAddress", "")
> > -    mac_address_output = ""
> > -
> > -    try:
> > -        ovn_nbctl("lsp-add", nid, eid)
> > -    except Exception as e:
> > -        error = "create_endpoint: lsp-add (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    if not mac_address_input:
> > -        mac_address = "02:%02x:%02x:%02x:%02x:%02x" %
> (random.randint(0, 255),
> > -
>  random.randint(0, 255),
> > -
>  random.randint(0, 255),
> > -
>  random.randint(0, 255),
> > -
>  random.randint(0, 255))
> > -    else:
> > -        mac_address = mac_address_input
> > -
> > -    try:
> > -        ovn_nbctl("lsp-set-addresses", eid,
> > -                  mac_address + " " + ip_address)
> > -    except Exception as e:
> > -        error = "create_endpoint: lsp-set-addresses (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    # Only return a mac address if one did not come as request.
> > -    mac_address_output = ""
> > -    if not mac_address_input:
> > -        mac_address_output = mac_address
> > -
> > -    return jsonify({"Interface": {
> > -                                    "Address": "",
> > -                                    "AddressIPv6": "",
> > -                                    "MacAddress": mac_address_output
> > -                                    }})
> > -
> > -
> > -def get_lsp_addresses(eid):
> > -    ret = ovn_nbctl("--if-exists", "get", "Logical_Switch_Port", eid,
> > -                    "addresses")
> > -    if not ret:
> > -        error = "endpoint not found in OVN database"
> > -        return (None, None, error)
> > -    addresses = ast.literal_eval(ret)
> > -    if len(addresses) == 0:
> > -        error = "unexpected return while fetching addresses"
> > -        return (None, None, error)
> > -    (mac_address, ip_address) = addresses[0].split()
> > -    return (mac_address, ip_address, None)
> > -
> > -
> > [email protected]('/NetworkDriver.EndpointOperInfo', methods=['POST'])
> > -def show_endpoint():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    try:
> > -        (mac_address, ip_address, error) = get_lsp_addresses(eid)
> > -        if error:
> > -            jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "show_endpoint: get Logical_Switch_Port addresses.
> (%s)" \
> > -                % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    veth_outside = eid[0:15]
> > -    return jsonify({"Value": {"ip_address": ip_address,
> > -                              "mac_address": mac_address,
> > -                              "veth_outside": veth_outside
> > -                              }})
> > -
> > -
> > [email protected]('/NetworkDriver.DeleteEndpoint', methods=['POST'])
> > -def delete_endpoint():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    try:
> > -        ovn_nbctl("lsp-del", eid)
> > -    except Exception as e:
> > -        error = "delete_endpoint: lsp-del %s" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.Join', methods=['POST'])
> > -def network_join():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    sboxkey = data.get("SandboxKey", "")
> > -    if not sboxkey:
> > -        abort(400)
> > -
> > -    # sboxkey is of the form: /var/run/docker/netns/CONTAINER_ID
> > -    vm_id = sboxkey.rsplit('/')[-1]
> > -
> > -    try:
> > -        (mac_address, ip_address, error) = get_lsp_addresses(eid)
> > -        if error:
> > -            jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "network_join: %s" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    veth_outside = eid[0:15]
> > -    veth_inside = eid[0:13] + "_c"
> > -    command = "ip link add %s type veth peer name %s" \
> > -              % (veth_inside, veth_outside)
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_join: failed to create veth pair (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    command = "ip link set dev %s address %s" \
> > -              % (veth_inside, mac_address)
> > -
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_join: failed to set veth mac address (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    command = "ip link set %s up" % (veth_outside)
> > -
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_join: failed to up the veth interface (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ovs_vsctl("add-port", OVN_BRIDGE, veth_outside)
> > -        ovs_vsctl("set", "interface", veth_outside,
> > -                  "external_ids:attached-mac=" + mac_address,
> > -                  "external_ids:iface-id=" + eid,
> > -                  "external_ids:vm-id=" + vm_id,
> > -                  "external_ids:iface-status=active")
> > -    except Exception as e:
> > -        error = "network_join: failed to create a port (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({"InterfaceName": {
> > -                                        "SrcName": veth_inside,
> > -                                        "DstPrefix": "eth"
> > -                                     },
> > -                    "Gateway": "",
> > -                    "GatewayIPv6": ""})
> > -
> > -
> > [email protected]('/NetworkDriver.Leave', methods=['POST'])
> > -def network_leave():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    veth_outside = eid[0:15]
> > -    command = "ip link delete %s" % (veth_outside)
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_leave: failed to delete veth pair (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ovs_vsctl("--if-exists", "del-port", veth_outside)
> > -    except Exception as e:
> > -        error = "network_leave: failed to delete port (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -if __name__ == '__main__':
> > -    prepare()
> > -    app.run(host='0.0.0.0')
> > diff --git a/utilities/ovn-docker-underlay-driver.in b/utilities/
> ovn-docker-underlay-driver.in
> > deleted file mode 100755
> > index 229418500..000000000
> > --- a/utilities/ovn-docker-underlay-driver.in
> > +++ /dev/null
> > @@ -1,677 +0,0 @@
> > -#! @PYTHON3@
> > -# Copyright (C) 2015 Nicira, Inc.
> > -#
> > -# 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.
> > -
> > -import argparse
> > -import atexit
> > -import getpass
> > -import json
> > -import os
> > -import re
> > -import shlex
> > -import subprocess
> > -import sys
> > -import time
> > -import uuid
> > -
> > -import ovs.dirs
> > -import ovs.util
> > -import ovs.daemon
> > -import ovs.unixctl.server
> > -import ovs.vlog
> > -
> > -from neutronclient.v2_0 import client
> > -from flask import Flask, jsonify
> > -from flask import request, abort
> > -
> > -app = Flask(__name__)
> > -vlog = ovs.vlog.Vlog("ovn-docker-underlay-driver")
> > -
> > -AUTH_STRATEGY = ""
> > -AUTH_URL = ""
> > -ENDPOINT_URL = ""
> > -OVN_BRIDGE = ""
> > -PASSWORD = ""
> > -PLUGIN_DIR = "/etc/docker/plugins"
> > -PLUGIN_FILE = "/etc/docker/plugins/openvswitch.spec"
> > -TENANT_ID = ""
> > -USERNAME = ""
> > -VIF_ID = ""
> > -
> > -
> > -def call_popen(cmd):
> > -    child = subprocess.Popen(cmd, stdout=subprocess.PIPE)
> > -    output = child.communicate()
> > -    if child.returncode:
> > -        raise RuntimeError("Fatal error executing %s" % (cmd))
> > -    if len(output) == 0 or output[0] == None:
> > -        output = ""
> > -    else:
> > -        output = output[0].strip()
> > -    return output
> > -
> > -
> > -def call_prog(prog, args_list):
> > -    cmd = [prog, "--timeout=5", "-vconsole:off"] + args_list
> > -    return call_popen(cmd)
> > -
> > -
> > -def ovs_vsctl(*args):
> > -    return call_prog("ovs-vsctl", list(args))
> > -
> > -
> > -def cleanup():
> > -    if os.path.isfile(PLUGIN_FILE):
> > -        os.remove(PLUGIN_FILE)
> > -
> > -
> > -def ovn_init_underlay(args):
> > -    global USERNAME, PASSWORD, TENANT_ID, AUTH_URL, AUTH_STRATEGY,
> VIF_ID
> > -    global OVN_BRIDGE
> > -
> > -    if not args.bridge:
> > -        sys.exit("OVS bridge name not provided")
> > -    OVN_BRIDGE = args.bridge
> > -
> > -    VIF_ID = os.environ.get('OS_VIF_ID', '')
> > -    if not VIF_ID:
> > -        sys.exit("env OS_VIF_ID not set")
> > -    USERNAME = os.environ.get('OS_USERNAME', '')
> > -    if not USERNAME:
> > -        sys.exit("env OS_USERNAME not set")
> > -    TENANT_ID = os.environ.get('OS_TENANT_ID', '')
> > -    if not TENANT_ID:
> > -        sys.exit("env OS_TENANT_ID not set")
> > -    AUTH_URL = os.environ.get('OS_AUTH_URL', '')
> > -    if not AUTH_URL:
> > -        sys.exit("env OS_AUTH_URL not set")
> > -    AUTH_STRATEGY = "keystone"
> > -
> > -    PASSWORD = os.environ.get('OS_PASSWORD', '')
> > -    if not PASSWORD:
> > -        PASSWORD = getpass.getpass()
> > -
> > -
> > -def prepare():
> > -    parser = argparse.ArgumentParser()
> > -    parser.add_argument('--bridge', help="The Bridge to which
> containers "
> > -                        "interfaces connect to.")
> > -
> > -    ovs.vlog.add_args(parser)
> > -    ovs.daemon.add_args(parser)
> > -    args = parser.parse_args()
> > -    ovs.vlog.handle_args(args)
> > -    ovs.daemon.handle_args(args)
> > -    ovn_init_underlay(args)
> > -
> > -    if not os.path.isdir(PLUGIN_DIR):
> > -        os.makedirs(PLUGIN_DIR)
> > -
> > -    ovs.daemon.daemonize()
> > -    try:
> > -        fo = open(PLUGIN_FILE, "w")
> > -        fo.write("tcp://127.0.0.1:5000")
> > -        fo.close()
> > -    except Exception as e:
> > -        ovs.util.ovs_fatal(0, "Failed to write to spec file (%s)" %
> str(e),
> > -                           vlog)
> > -
> > -    atexit.register(cleanup)
> > -
> > -
> > [email protected]('/Plugin.Activate', methods=['POST'])
> > -def plugin_activate():
> > -    return jsonify({"Implements": ["NetworkDriver"]})
> > -
> > -
> > [email protected]('/NetworkDriver.GetCapabilities', methods=['POST'])
> > -def get_capability():
> > -    return jsonify({"Scope": "global"})
> > -
> > -
> > [email protected]('/NetworkDriver.DiscoverNew', methods=['POST'])
> > -def new_discovery():
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.DiscoverDelete', methods=['POST'])
> > -def delete_discovery():
> > -    return jsonify({})
> > -
> > -
> > -def neutron_login():
> > -    try:
> > -        neutron = client.Client(username=USERNAME,
> > -                                password=PASSWORD,
> > -                                tenant_id=TENANT_ID,
> > -                                auth_url=AUTH_URL,
> > -                                endpoint_url=ENDPOINT_URL,
> > -                                auth_strategy=AUTH_STRATEGY)
> > -    except Exception as e:
> > -        raise RuntimeError("Failed to login into Neutron(%s)" % str(e))
> > -    return neutron
> > -
> > -
> > -def get_networkuuid_by_name(neutron, name):
> > -    param = {'fields': 'id', 'name': name}
> > -    ret = neutron.list_networks(**param)
> > -    if len(ret['networks']) > 1:
> > -        raise RuntimeError("More than one network for the given name")
> > -    elif len(ret['networks']) == 0:
> > -        network = None
> > -    else:
> > -        network = ret['networks'][0]['id']
> > -    return network
> > -
> > -
> > -def get_subnetuuid_by_name(neutron, name):
> > -    param = {'fields': 'id', 'name': name}
> > -    ret = neutron.list_subnets(**param)
> > -    if len(ret['subnets']) > 1:
> > -        raise RuntimeError("More than one subnet for the given name")
> > -    elif len(ret['subnets']) == 0:
> > -        subnet = None
> > -    else:
> > -        subnet = ret['subnets'][0]['id']
> > -    return subnet
> > -
> > -
> > [email protected]('/NetworkDriver.CreateNetwork', methods=['POST'])
> > -def create_network():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    # NetworkID will have docker generated network uuid and it
> > -    # becomes 'name' in a neutron network record.
> > -    network = data.get("NetworkID", "")
> > -    if not network:
> > -        abort(400)
> > -
> > -    # Limit subnet handling to ipv4 till ipv6 usecase is clear.
> > -    ipv4_data = data.get("IPv4Data", "")
> > -    if not ipv4_data:
> > -        error = "create_network: No ipv4 subnet provided"
> > -        return jsonify({'Err': error})
> > -
> > -    subnet = ipv4_data[0].get("Pool", "")
> > -    if not subnet:
> > -        error = "create_network: no subnet in ipv4 data from libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    gateway_ip = ipv4_data[0].get("Gateway", "").rsplit('/', 1)[0]
> > -    if not gateway_ip:
> > -        error = "create_network: no gateway in ipv4 data from
> libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        neutron = neutron_login()
> > -    except Exception as e:
> > -        error = "create_network: neutron login. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        if get_networkuuid_by_name(neutron, network):
> > -            error = "create_network: network has already been created"
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "create_network: neutron network uuid by name. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        body = {'network': {'name': network, 'admin_state_up': True}}
> > -        ret = neutron.create_network(body)
> > -        network_id = ret['network']['id']
> > -    except Exception as e:
> > -        error = "create_network: neutron net-create call. (%s)" % str(e)
> > -        return jsonify({'Err': error})
> > -
> > -    subnet_name = "docker-%s" % (network)
> > -
> > -    try:
> > -        body = {'subnet': {'network_id': network_id,
> > -                           'ip_version': 4,
> > -                           'cidr': subnet,
> > -                           'gateway_ip': gateway_ip,
> > -                           'name': subnet_name}}
> > -        created_subnet = neutron.create_subnet(body)
> > -    except Exception as e:
> > -        error = "create_network: neutron subnet-create call. (%s)" %
> str(e)
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.DeleteNetwork', methods=['POST'])
> > -def delete_network():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    try:
> > -        neutron = neutron_login()
> > -    except Exception as e:
> > -        error = "delete_network: neutron login. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        network = get_networkuuid_by_name(neutron, nid)
> > -        if not network:
> > -            error = "delete_network: failed in network by name. (%s)" %
> (nid)
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "delete_network: network uuid by name. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        neutron.delete_network(network)
> > -    except Exception as e:
> > -        error = "delete_network: neutron net-delete. (%s)" % str(e)
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -
> > -def reserve_vlan():
> > -    reserved_vlan = 0
> > -    vlans = ovs_vsctl("--if-exists", "get", "Open_vSwitch", ".",
> > -                      "external_ids:vlans").strip('"')
> > -    if not vlans:
> > -        reserved_vlan = 1
> > -        ovs_vsctl("set", "Open_vSwitch", ".",
> > -                  "external_ids:vlans=" + str(reserved_vlan))
> > -        return reserved_vlan
> > -
> > -    vlan_set = str(vlans).split(',')
> > -
> > -    for vlan in range(1, 4095):
> > -        if str(vlan) not in vlan_set:
> > -            vlan_set.append(str(vlan))
> > -            reserved_vlan = vlan
> > -            vlans = re.sub(r'[ \[\]\']', '', str(vlan_set))
> > -            ovs_vsctl("set", "Open_vSwitch", ".",
> > -                      "external_ids:vlans=" + vlans)
> > -            return reserved_vlan
> > -
> > -    if not reserved_vlan:
> > -        raise RuntimeError("No more vlans available on this host")
> > -
> > -
> > -def unreserve_vlan(reserved_vlan):
> > -    vlans = ovs_vsctl("--if-exists", "get", "Open_vSwitch", ".",
> > -                      "external_ids:vlans").strip('"')
> > -    if not vlans:
> > -        return
> > -
> > -    vlan_set = str(vlans).split(',')
> > -    if str(reserved_vlan) not in vlan_set:
> > -        return
> > -
> > -    vlan_set.remove(str(reserved_vlan))
> > -    vlans = re.sub(r'[ \[\]\']', '', str(vlan_set))
> > -    if vlans:
> > -        ovs_vsctl("set", "Open_vSwitch", ".", "external_ids:vlans=" +
> vlans)
> > -    else:
> > -        ovs_vsctl("remove", "Open_vSwitch", ".", "external_ids",
> "vlans")
> > -
> > -
> > -def create_port_underlay(neutron, network, eid, ip_address,
> mac_address):
> > -    reserved_vlan = reserve_vlan()
> > -    if mac_address:
> > -        body = {'port': {'network_id': network,
> > -                         'binding:profile': {'parent_name': VIF_ID,
> > -                                             'tag': int(reserved_vlan)},
> > -                         'mac_address': mac_address,
> > -                         'fixed_ips': [{'ip_address': ip_address}],
> > -                         'name': eid,
> > -                         'admin_state_up': True}}
> > -    else:
> > -        body = {'port': {'network_id': network,
> > -                         'binding:profile': {'parent_name': VIF_ID,
> > -                                             'tag': int(reserved_vlan)},
> > -                         'fixed_ips': [{'ip_address': ip_address}],
> > -                         'name': eid,
> > -                         'admin_state_up': True}}
> > -
> > -    try:
> > -        ret = neutron.create_port(body)
> > -        mac_address = ret['port']['mac_address']
> > -    except Exception as e:
> > -        unreserve_vlan(reserved_vlan)
> > -        raise RuntimeError("Failed in creation of neutron port (%s)." %
> str(e))
> > -
> > -    ovs_vsctl("set", "Open_vSwitch", ".",
> > -              "external_ids:" + eid + "_vlan=" + str(reserved_vlan))
> > -
> > -    return mac_address
> > -
> > -
> > -def get_endpointuuid_by_name(neutron, name):
> > -    param = {'fields': 'id', 'name': name}
> > -    ret = neutron.list_ports(**param)
> > -    if len(ret['ports']) > 1:
> > -        raise RuntimeError("More than one endpoint for the given name")
> > -    elif len(ret['ports']) == 0:
> > -        endpoint = None
> > -    else:
> > -        endpoint = ret['ports'][0]['id']
> > -    return endpoint
> > -
> > -
> > [email protected]('/NetworkDriver.CreateEndpoint', methods=['POST'])
> > -def create_endpoint():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    interface = data.get("Interface", "")
> > -    if not interface:
> > -        error = "create_endpoint: no interfaces supplied by libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    ip_address_and_mask = interface.get("Address", "")
> > -    if not ip_address_and_mask:
> > -        error = "create_endpoint: ip address not provided by libnetwork"
> > -        return jsonify({'Err': error})
> > -
> > -    ip_address = ip_address_and_mask.rsplit('/', 1)[0]
> > -    mac_address_input = interface.get("MacAddress", "")
> > -    mac_address_output = ""
> > -
> > -    try:
> > -        neutron = neutron_login()
> > -    except Exception as e:
> > -        error = "create_endpoint: neutron login. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        endpoint = get_endpointuuid_by_name(neutron, eid)
> > -        if endpoint:
> > -            error = "create_endpoint: Endpoint has already been created"
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "create_endpoint: endpoint uuid by name. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        network = get_networkuuid_by_name(neutron, nid)
> > -        if not network:
> > -            error = "Failed to get neutron network record for (%s)" %
> (nid)
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "create_endpoint: network uuid by name. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        mac_address = create_port_underlay(neutron, network, eid,
> ip_address,
> > -                                           mac_address_input)
> > -    except Exception as e:
> > -        error = "create_endpoint: neutron port-create (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    if not mac_address_input:
> > -        mac_address_output = mac_address
> > -
> > -    return jsonify({"Interface": {
> > -                                    "Address": "",
> > -                                    "AddressIPv6": "",
> > -                                    "MacAddress": mac_address_output
> > -                                    }})
> > -
> > -
> > [email protected]('/NetworkDriver.EndpointOperInfo', methods=['POST'])
> > -def show_endpoint():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    try:
> > -        neutron = neutron_login()
> > -    except Exception as e:
> > -        error = "%s" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        endpoint = get_endpointuuid_by_name(neutron, eid)
> > -        if not endpoint:
> > -            error = "show_endpoint: Failed to get endpoint by name"
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "show_endpoint: get endpoint by name. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ret = neutron.show_port(endpoint)
> > -        mac_address = ret['port']['mac_address']
> > -        ip_address = ret['port']['fixed_ips'][0]['ip_address']
> > -    except Exception as e:
> > -        error = "show_endpoint: show port (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    veth_outside = eid[0:15]
> > -    return jsonify({"Value": {"ip_address": ip_address,
> > -                              "mac_address": mac_address,
> > -                              "veth_outside": veth_outside
> > -                              }})
> > -
> > -
> > [email protected]('/NetworkDriver.DeleteEndpoint', methods=['POST'])
> > -def delete_endpoint():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    try:
> > -        neutron = neutron_login()
> > -    except Exception as e:
> > -        error = "delete_endpoint: neutron login (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    endpoint = get_endpointuuid_by_name(neutron, eid)
> > -    if not endpoint:
> > -        return jsonify({})
> > -
> > -    reserved_vlan = ovs_vsctl("--if-exists", "get", "Open_vSwitch", ".",
> > -                              "external_ids:" + eid +
> "_vlan").strip('"')
> > -    if reserved_vlan:
> > -        unreserve_vlan(reserved_vlan)
> > -        ovs_vsctl("remove", "Open_vSwitch", ".", "external_ids",
> > -                  eid + "_vlan")
> > -
> > -    try:
> > -        neutron.delete_port(endpoint)
> > -    except Exception as e:
> > -        error = "delete_endpoint: neutron port-delete. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -
> > [email protected]('/NetworkDriver.Join', methods=['POST'])
> > -def network_join():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    sboxkey = data.get("SandboxKey", "")
> > -    if not sboxkey:
> > -        abort(400)
> > -
> > -    # sboxkey is of the form: /var/run/docker/netns/CONTAINER_ID
> > -    vm_id = sboxkey.rsplit('/')[-1]
> > -
> > -    try:
> > -        neutron = neutron_login()
> > -    except Exception as e:
> > -        error = "network_join: neutron login. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    subnet_name = "docker-%s" % (nid)
> > -    try:
> > -        subnet = get_subnetuuid_by_name(neutron, subnet_name)
> > -        if not subnet:
> > -            error = "network_join: can't find subnet in neutron"
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "network_join: subnet uuid by name. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ret = neutron.show_subnet(subnet)
> > -        gateway_ip = ret['subnet']['gateway_ip']
> > -        if not gateway_ip:
> > -            error = "network_join: no gateway_ip for the subnet"
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "network_join: neutron show subnet. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        endpoint = get_endpointuuid_by_name(neutron, eid)
> > -        if not endpoint:
> > -            error = "network_join: Failed to get endpoint by name"
> > -            return jsonify({'Err': error})
> > -    except Exception as e:
> > -        error = "network_join: neutron endpoint by name. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ret = neutron.show_port(endpoint)
> > -        mac_address = ret['port']['mac_address']
> > -    except Exception as e:
> > -        error = "network_join: neutron show port. (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    veth_outside = eid[0:15]
> > -    veth_inside = eid[0:13] + "_c"
> > -    command = "ip link add %s type veth peer name %s" \
> > -              % (veth_inside, veth_outside)
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_join: failed to create veth pair. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    command = "ip link set dev %s address %s" \
> > -              % (veth_inside, mac_address)
> > -
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_join: failed to set veth mac address. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    command = "ip link set %s up" % (veth_outside)
> > -
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_join: failed to up the veth iface. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        reserved_vlan = ovs_vsctl("--if-exists", "get", "Open_vSwitch",
> ".",
> > -                                  "external_ids:" + eid +
> "_vlan").strip('"')
> > -        if not reserved_vlan:
> > -            error = "network_join: no reserved vlan for this endpoint"
> > -            return jsonify({'Err': error})
> > -        ovs_vsctl("add-port", OVN_BRIDGE, veth_outside, "tag=" +
> reserved_vlan)
> > -    except Exception as e:
> > -        error = "network_join: failed to create a OVS port. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({"InterfaceName": {
> > -                                        "SrcName": veth_inside,
> > -                                        "DstPrefix": "eth"
> > -                                     },
> > -                    "Gateway": gateway_ip,
> > -                    "GatewayIPv6": ""})
> > -
> > -
> > [email protected]('/NetworkDriver.Leave', methods=['POST'])
> > -def network_leave():
> > -    if not request.data:
> > -        abort(400)
> > -
> > -    data = json.loads(request.data)
> > -
> > -    nid = data.get("NetworkID", "")
> > -    if not nid:
> > -        abort(400)
> > -
> > -    eid = data.get("EndpointID", "")
> > -    if not eid:
> > -        abort(400)
> > -
> > -    veth_outside = eid[0:15]
> > -    command = "ip link delete %s" % (veth_outside)
> > -    try:
> > -        call_popen(shlex.split(command))
> > -    except Exception as e:
> > -        error = "network_leave: failed to delete veth pair. (%s)" %
> (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    try:
> > -        ovs_vsctl("--if-exists", "del-port", veth_outside)
> > -    except Exception as e:
> > -        error = "network_leave: Failed to delete port (%s)" % (str(e))
> > -        return jsonify({'Err': error})
> > -
> > -    return jsonify({})
> > -
> > -if __name__ == '__main__':
> > -    prepare()
> > -    app.run(host='127.0.0.1')
>
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to