Add network daemon to manage VXLAN VNIs on hypervisors
This commit is contained in:
		
							
								
								
									
										11
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@@ -26,6 +26,17 @@ Description: Parallel Virtual Cluster virtualization daemon (Python 3)
 | 
			
		||||
 .
 | 
			
		||||
 This package installs the PVC virtualization daemon
 | 
			
		||||
 | 
			
		||||
Package: pvc-network-daemon
 | 
			
		||||
Architecture: all
 | 
			
		||||
Depends: pvc-daemon-common, python3-libvirt, ipmitool, libvirt-daemon-system
 | 
			
		||||
Suggests: pvc-client, pvc-virtualization-daemon
 | 
			
		||||
Description: Parallel Virtual Cluster network daemon (Python 3)
 | 
			
		||||
 The Parallel Virtual Cluster provides a management solution for QEMU/KVM virtual clusters,
 | 
			
		||||
 including full control of running VMs, definitions, and hypervisors (including fencing via
 | 
			
		||||
 IPMI). This package provides the daemon component for networking on a hypervisor node.
 | 
			
		||||
 .
 | 
			
		||||
 This package installs the PVC network daemon
 | 
			
		||||
 | 
			
		||||
Package: pvc-client
 | 
			
		||||
Architecture: all
 | 
			
		||||
Depends: python3-kazoo, python3-libvirt, python3-psutil, python3-click, python3-lxml
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								debian/pvc-network-daemon.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								debian/pvc-network-daemon.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
network-daemon/pvcnd.py usr/share/pvc
 | 
			
		||||
network-daemon/pvcnd.service lib/systemd/system
 | 
			
		||||
network-daemon/pvcnd.conf.sample etc/pvc
 | 
			
		||||
network-daemon/pvcnd usr/share/pvc
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/pvc-network-daemon.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/pvc-network-daemon.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
# Enable the servive
 | 
			
		||||
systemctl enable /lib/systemd/system/pvcnd.service
 | 
			
		||||
 | 
			
		||||
echo "The PVC network daemon has not been started. Create a config file at /etc/pvc/pvcnd.conf then start it."
 | 
			
		||||
							
								
								
									
										5
									
								
								debian/pvc-network-daemon.prerm
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								debian/pvc-network-daemon.prerm
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
# Disable the service
 | 
			
		||||
systemctl disable pvcnd.service
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								network-daemon/pvcnd.conf.sample
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								network-daemon/pvcnd.conf.sample
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
# pvcnd cluster configuration file example
 | 
			
		||||
#
 | 
			
		||||
# This configuration file specifies details for this node in PVC. Multiple host
 | 
			
		||||
# blocks can be added but only the one matching the current system hostname will
 | 
			
		||||
# be used by the local daemon. Default values apply to all hosts for any value
 | 
			
		||||
# not specifically overridden.
 | 
			
		||||
#
 | 
			
		||||
# The following values are required for each host or in a default section:
 | 
			
		||||
#    zookeeper: the IP+port of the Zookeper instance (defaults to 127.0.0.1:2181)
 | 
			
		||||
#    vni_dev: the lower-level network device to bind VNI to
 | 
			
		||||
#    vni_dev_ip: the IP address (CIDR) of the lower-level network device, used
 | 
			
		||||
#                by FRR to communicate with the route reflectors and pass routes
 | 
			
		||||
#                for VNI interfaces
 | 
			
		||||
#
 | 
			
		||||
# Copy this example to /etc/pvc/pvcnd.conf and edit to your needs
 | 
			
		||||
 | 
			
		||||
[default]
 | 
			
		||||
zookeeper = 127.0.0.1:2181
 | 
			
		||||
 | 
			
		||||
[myhost]
 | 
			
		||||
vni_dev = ens4
 | 
			
		||||
vni_dev_ip = 10.255.0.3/24
 | 
			
		||||
							
								
								
									
										23
									
								
								network-daemon/pvcnd.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								network-daemon/pvcnd.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
# pvcnd.py - Network daemon startup stub
 | 
			
		||||
# Part of the Parallel Virtual Cluster (PVC) system
 | 
			
		||||
#
 | 
			
		||||
#    Copyright (C) 2018  Joshua M. Boniface <joshua@boniface.me>
 | 
			
		||||
#
 | 
			
		||||
#    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
#    it under the terms of the GNU General Public License as published by
 | 
			
		||||
#    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
#    (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#    This program is distributed in the hope that it will be useful,
 | 
			
		||||
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#    GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#    You should have received a copy of the GNU General Public License
 | 
			
		||||
#    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
import pvcnd.Daemon
 | 
			
		||||
							
								
								
									
										15
									
								
								network-daemon/pvcnd.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								network-daemon/pvcnd.service
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
# Parallel Virtual Cluster network daemon unit file
 | 
			
		||||
[Unit]
 | 
			
		||||
Description = Parallel Virtual Cluster network daemon
 | 
			
		||||
After = network-online.target libvirtd.service zookeeper.service
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
Type = simple
 | 
			
		||||
WorkingDirectory = /usr/share/pvc
 | 
			
		||||
Environment = PYTHONUNBUFFERED=true
 | 
			
		||||
Environment = PVCVD_CONFIG_FILE=/etc/pvc/pvcnd.conf
 | 
			
		||||
ExecStart = /usr/share/pvc/pvcnd.py
 | 
			
		||||
Restart = on-failure
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy = multi-user.target
 | 
			
		||||
							
								
								
									
										223
									
								
								network-daemon/pvcnd/Daemon.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								network-daemon/pvcnd/Daemon.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,223 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
# Daemon.py - PVC hypervisor network daemon
 | 
			
		||||
# Part of the Parallel Virtual Cluster (PVC) system
 | 
			
		||||
#
 | 
			
		||||
#    Copyright (C) 2018  Joshua M. Boniface <joshua@boniface.me>
 | 
			
		||||
#
 | 
			
		||||
#    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
#    it under the terms of the GNU General Public License as published by
 | 
			
		||||
#    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
#    (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#    This program is distributed in the hope that it will be useful,
 | 
			
		||||
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#    GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#    You should have received a copy of the GNU General Public License
 | 
			
		||||
#    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
import kazoo.client
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import signal
 | 
			
		||||
import socket
 | 
			
		||||
import psutil
 | 
			
		||||
import configparser
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
import lib.ansiiprint as ansiiprint
 | 
			
		||||
import lib.zkhandler as zkhandler
 | 
			
		||||
 | 
			
		||||
import pvcnd.VXNetworkInstance as VXNetworkInstance
 | 
			
		||||
 | 
			
		||||
print(ansiiprint.bold() + "pvcnd - Parallel Virtual Cluster network daemon" + ansiiprint.end())
 | 
			
		||||
 | 
			
		||||
# Get the config file variable from the environment
 | 
			
		||||
try:
 | 
			
		||||
    pvcnd_config_file = os.environ['PVCND_CONFIG_FILE']
 | 
			
		||||
except:
 | 
			
		||||
    print('ERROR: The "PVCND_CONFIG_FILE" environment variable must be set before starting pvcnd.')
 | 
			
		||||
    exit(1)
 | 
			
		||||
 | 
			
		||||
myhostname = socket.gethostname()
 | 
			
		||||
myshorthostname = myhostname.split('.', 1)[0]
 | 
			
		||||
mydomainname = ''.join(myhostname.split('.', 1)[1:])
 | 
			
		||||
 | 
			
		||||
# Config values dictionary
 | 
			
		||||
config_values = [
 | 
			
		||||
    'zookeeper',
 | 
			
		||||
    'vni_dev',
 | 
			
		||||
    'vni_dev_ip',
 | 
			
		||||
]
 | 
			
		||||
def readConfig(pvcnd_config_file, myhostname):
 | 
			
		||||
    print('Loading configuration from file {}'.format(pvcnd_config_file))
 | 
			
		||||
 | 
			
		||||
    o_config = configparser.ConfigParser()
 | 
			
		||||
    o_config.read(pvcnd_config_file)
 | 
			
		||||
    config = {}
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        entries = o_config[myhostname]
 | 
			
		||||
    except:
 | 
			
		||||
        try:
 | 
			
		||||
            entries = o_config['default']
 | 
			
		||||
        except:
 | 
			
		||||
            print('ERROR: Config file is not valid!')
 | 
			
		||||
            exit(1)
 | 
			
		||||
 | 
			
		||||
    for entry in config_values:
 | 
			
		||||
        try:
 | 
			
		||||
            config[entry] = entries[entry]
 | 
			
		||||
        except:
 | 
			
		||||
            try:
 | 
			
		||||
                config[entry] = o_config['default'][entry]
 | 
			
		||||
            except:
 | 
			
		||||
                print('ERROR: Config file missing required value "{}" for this host!'.format(entry))
 | 
			
		||||
                exit(1)
 | 
			
		||||
 | 
			
		||||
    return config
 | 
			
		||||
 | 
			
		||||
config = readConfig(pvcnd_config_file, myhostname)
 | 
			
		||||
 | 
			
		||||
zk_conn = kazoo.client.KazooClient(hosts=config['zookeeper'])
 | 
			
		||||
try:
 | 
			
		||||
    print('Connecting to Zookeeper instance at {}'.format(config['zookeeper']))
 | 
			
		||||
    zk_conn.start()
 | 
			
		||||
except:
 | 
			
		||||
    print('ERROR: Failed to connect to Zookeeper!')
 | 
			
		||||
    exit(1)
 | 
			
		||||
 | 
			
		||||
# Handle zookeeper failures gracefully
 | 
			
		||||
def zk_listener(state):
 | 
			
		||||
    global zk_conn
 | 
			
		||||
    if state == kazoo.client.KazooState.SUSPENDED:
 | 
			
		||||
        ansiiprint.echo('Connection to Zookeeper list; retrying', '', 'e')
 | 
			
		||||
 | 
			
		||||
        while True:
 | 
			
		||||
            _zk_conn = kazoo.client.KazooClient(hosts=config['zookeeper'])
 | 
			
		||||
            try:
 | 
			
		||||
                _zk_conn.start()
 | 
			
		||||
                zk_conn = _zk_conn
 | 
			
		||||
                break
 | 
			
		||||
            except:
 | 
			
		||||
                time.sleep(1)
 | 
			
		||||
    elif state == kazoo.client.KazooState.CONNECTED:
 | 
			
		||||
        anisiprint.echo('Connection to Zookeeper started', '', 'o')
 | 
			
		||||
    else:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
zk_conn.add_listener(zk_listener)
 | 
			
		||||
 | 
			
		||||
# Cleanup function
 | 
			
		||||
def cleanup(signum, frame):
 | 
			
		||||
    ansiiprint.echo('Terminating daemon', '', 'e')
 | 
			
		||||
    # Close the Zookeeper connection
 | 
			
		||||
    try:
 | 
			
		||||
        zk_conn.stop()
 | 
			
		||||
        zk_conn.close()
 | 
			
		||||
    except:
 | 
			
		||||
        pass
 | 
			
		||||
    # Exit
 | 
			
		||||
    exit(0)
 | 
			
		||||
 | 
			
		||||
# Handle signals with cleanup
 | 
			
		||||
signal.signal(signal.SIGTERM, cleanup)
 | 
			
		||||
signal.signal(signal.SIGINT, cleanup)
 | 
			
		||||
signal.signal(signal.SIGQUIT, cleanup)
 | 
			
		||||
 | 
			
		||||
# What this daemon does:
 | 
			
		||||
#  1. Configure public networks dynamically on startup (e.g. bonding, vlans, etc.) from config
 | 
			
		||||
#   * no /etc/network/interfaces config for these - just mgmt interface via DHCP!
 | 
			
		||||
#  2. Watch ZK /networks
 | 
			
		||||
#  3. Provision required network interfaces when a network is added
 | 
			
		||||
#   a. create vxlan interface targeting local dev from config
 | 
			
		||||
#   b. create bridge interface
 | 
			
		||||
#   c. add vxlan to bridge
 | 
			
		||||
#   d. set interfaces up
 | 
			
		||||
#  4. Remove network interfaces when network disapears
 | 
			
		||||
 | 
			
		||||
# Zookeeper schema:
 | 
			
		||||
#   networks/
 | 
			
		||||
#       <VXLANID>/
 | 
			
		||||
#           ipnet <NETWORK-CIDR>  e.g. 10.101.0.0/24
 | 
			
		||||
#           gateway <IPADDR>      e.g. 10.101.0.1 [1]
 | 
			
		||||
#           routers <IPADDR-LIST> e.g. 10.101.0.2,10.101.0.3 [2]
 | 
			
		||||
#           dhcp <YES/NO>         e.g. YES [3]
 | 
			
		||||
#           reservations/
 | 
			
		||||
#               <HOSTNAME/DESCRIPTION>/
 | 
			
		||||
#                   address <IPADDR> e.g. 10.101.0.30
 | 
			
		||||
#                   mac <MACADDR>    e.g. ff:ff:fe:ab:cd:ef
 | 
			
		||||
#           fwrules/
 | 
			
		||||
#               <RULENAME>/
 | 
			
		||||
#                   description <DESCRIPTION>                  e.g. Allow HTTP from any to this net
 | 
			
		||||
#                   src <HOSTNAME/IPADDR/SUBNET/"any"/"this">  e.g. any
 | 
			
		||||
#                   dest <HOSTNAME/IPADDR/SUBNET/"any"/"this"> e.g. this
 | 
			
		||||
#                   port <PORT/RANGE/"any">                    e.g. 80
 | 
			
		||||
 | 
			
		||||
# Notes:          
 | 
			
		||||
# [1] becomes a VIP between the pair of routers in multi-router envs
 | 
			
		||||
# [2] becomes real addrs on the pair of routers in multi-router envs
 | 
			
		||||
# [2] should match gateway in single-router envs for consistency
 | 
			
		||||
# [3] enables or disables a DHCP subnet definition for the network
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Prepare underlying interface
 | 
			
		||||
if config['vni_dev_ip'] == 'dhcp':
 | 
			
		||||
    vni_dev = config['vni_dev']
 | 
			
		||||
    ansiiprint.echo('Configuring VNI parent device {} with DHCP IP'.format(vni_dev), '', 'o')
 | 
			
		||||
    os.system(
 | 
			
		||||
        'sudo ip link set {0} up'.format(
 | 
			
		||||
            vni_dev
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    os.system(
 | 
			
		||||
        'sudo dhclient {0}'.format(
 | 
			
		||||
            vni_dev
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
else:
 | 
			
		||||
    vni_dev = config['vni_dev']
 | 
			
		||||
    vni_dev_ip = config['vni_dev_ip']
 | 
			
		||||
    ansiiprint.echo('Configuring VNI parent device {} with IP {}'.format(vni_dev, vni_dev_ip), '', 'o')
 | 
			
		||||
    os.system(
 | 
			
		||||
        'sudo ip link set {0} up'.format(
 | 
			
		||||
            vni_dev
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    os.system(
 | 
			
		||||
        'sudo ip address add {0} dev {1}'.format(
 | 
			
		||||
            vni_dev_ip,
 | 
			
		||||
            vni_dev
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
# Prepare VNI list
 | 
			
		||||
t_vni = dict()
 | 
			
		||||
vni_list = []
 | 
			
		||||
 | 
			
		||||
@zk_conn.ChildrenWatch('/networks')
 | 
			
		||||
def updatenetworks(new_vni_list):
 | 
			
		||||
    global vni_list
 | 
			
		||||
    print(ansiiprint.blue() + 'Network list: ' + ansiiprint.end() + '{}'.format(' '.join(new_vni_list)))
 | 
			
		||||
    # Add new VNIs
 | 
			
		||||
    for vni in new_vni_list:
 | 
			
		||||
        if vni not in vni_list:
 | 
			
		||||
            vni_list.append(vni)
 | 
			
		||||
            t_vni[vni] = VXNetworkInstance.VXNetworkInstance(vni, zk_conn, config)
 | 
			
		||||
            t_vni[vni].createNetwork()
 | 
			
		||||
    # Remove deleted VNIs
 | 
			
		||||
    for vni in vni_list:
 | 
			
		||||
        if vni not in new_vni_list:
 | 
			
		||||
            vni_list.remove(vni)
 | 
			
		||||
            t_vni[vni].removeNetwork()
 | 
			
		||||
            
 | 
			
		||||
# Tick loop
 | 
			
		||||
while True:
 | 
			
		||||
    try:
 | 
			
		||||
        time.sleep(0.1)
 | 
			
		||||
    except:
 | 
			
		||||
        break
 | 
			
		||||
							
								
								
									
										89
									
								
								network-daemon/pvcnd/VXNetworkInstance.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								network-daemon/pvcnd/VXNetworkInstance.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
# VXNetworkInstance.py - Class implementing a PVC VM network and run by pvcnd
 | 
			
		||||
# Part of the Parallel Virtual Cluster (PVC) system
 | 
			
		||||
#
 | 
			
		||||
#    Copyright (C) 2018  Joshua M. Boniface <joshua@boniface.me>
 | 
			
		||||
#
 | 
			
		||||
#    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
#    it under the terms of the GNU General Public License as published by
 | 
			
		||||
#    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
#    (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#    This program is distributed in the hope that it will be useful,
 | 
			
		||||
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#    GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#    You should have received a copy of the GNU General Public License
 | 
			
		||||
#    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
import os, sys
 | 
			
		||||
import lib.ansiiprint as ansiiprint
 | 
			
		||||
import lib.zkhandler as zkhandler
 | 
			
		||||
 | 
			
		||||
class VXNetworkInstance():
 | 
			
		||||
    # Initialization function
 | 
			
		||||
    def __init__ (self, vni, zk_conn, config):
 | 
			
		||||
        self.vni = vni
 | 
			
		||||
        self.zk_conn = zk_conn
 | 
			
		||||
        self.vni_dev = config['vni_dev']
 | 
			
		||||
 | 
			
		||||
    def createNetwork(self):
 | 
			
		||||
        ansiiprint.echo('Creating VNI {} device on interface {}'.format(self.vni, self.vni_dev), '', 'o')
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo ip link add vxlan{0} type vxlan id {0} dstport 4789 dev {1} nolearning'.format(
 | 
			
		||||
                self.vni,
 | 
			
		||||
                self.vni_dev
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo brctl addbr br{0}'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo brctl addif br{0} vxlan{0}'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo ip link set vxlan{0} up'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo ip link set br{0} up'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def removeNetwork(self):
 | 
			
		||||
        ansiiprint.echo('Removing VNI {} device on interface {}'.format(self.vni, self.vni_dev), '', 'o')
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo ip link set br{0} down'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo ip link set vxlan{0} down'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo brctl delif br{0} vxlan{0}'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo brctl delbr br{0}'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        os.system(
 | 
			
		||||
            'sudo ip link delete vxlan{0}'.format(
 | 
			
		||||
                self.vni
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										0
									
								
								network-daemon/pvcnd/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								network-daemon/pvcnd/__init__.py
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user