[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Ginger-dev-list] [wok] Move kimchi-specific network utilities to ginger
From: |
Lucio Correia |
Subject: |
[Ginger-dev-list] [wok] Move kimchi-specific network utilities to ginger |
Date: |
Fri, 10 Jul 2015 18:01:57 -0300 |
The modules network and netinfo are moved from wok to kimchi
plugin. Fix it by adding netinfo module and network functions
used by Ginger.
Signed-off-by: Lucio Correia <address@hidden>
---
models/Makefile.am | 1 +
models/interfaces.py | 2 +-
models/netinfo.py | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++
models/network.py | 8 ++-
4 files changed, 224 insertions(+), 3 deletions(-)
create mode 100644 models/netinfo.py
diff --git a/models/Makefile.am b/models/Makefile.am
index b88c6c1..bd18930 100644
--- a/models/Makefile.am
+++ b/models/Makefile.am
@@ -25,6 +25,7 @@ models_PYTHON = \
ibm_sep.py \
interfaces.py \
model.py \
+ netinfo.py \
network.py \
powermanagement.py \
sanadapters.py \
diff --git a/models/interfaces.py b/models/interfaces.py
index 58070cf..9bdf675 100644
--- a/models/interfaces.py
+++ b/models/interfaces.py
@@ -23,7 +23,7 @@ import lxml.etree as ET
from lxml.builder import E
from threading import Timer
-from wok import netinfo
+import netinfo
from wok.exception import InvalidParameter, NotFoundError, OperationFailed
from wok.xmlutils.utils import xpath_get_text
diff --git a/models/netinfo.py b/models/netinfo.py
new file mode 100644
index 0000000..390d2b8
--- /dev/null
+++ b/models/netinfo.py
@@ -0,0 +1,216 @@
+# Project Ginger
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import ethtool
+import glob
+import os
+
+
+NET_PATH = '/sys/class/net'
+NIC_PATH = '/sys/class/net/*/device'
+BRIDGE_PATH = '/sys/class/net/*/bridge'
+BONDING_PATH = '/sys/class/net/*/bonding'
+WLAN_PATH = '/sys/class/net/*/wireless'
+NET_BRPORT = '/sys/class/net/%s/brport'
+NET_MASTER = '/sys/class/net/%s/master'
+NET_STATE = '/sys/class/net/%s/carrier'
+PROC_NET_VLAN = '/proc/net/vlan/'
+BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
+BRIDGE_PORTS = '/sys/class/net/%s/brif'
+
+
+def wlans():
+ return [b.split('/')[-2] for b in glob.glob(WLAN_PATH)]
+
+
+def is_wlan(iface):
+ return iface in wlans()
+
+
+# FIXME if we do not want to list usb nic
+def nics():
+ return list(set([b.split('/')[-2] for b in glob.glob(NIC_PATH)]) -
+ set(wlans()))
+
+
+def is_nic(iface):
+ return iface in nics()
+
+
+def bondings():
+ return [b.split('/')[-2] for b in glob.glob(BONDING_PATH)]
+
+
+def is_bonding(iface):
+ return iface in bondings()
+
+
+def vlans():
+ return list(set([b.split('/')[-1]
+ for b in glob.glob(NET_PATH + '/*')]) &
+ set([b.split('/')[-1]
+ for b in glob.glob(PROC_NET_VLAN + '*')]))
+
+
+def is_vlan(iface):
+ return iface in vlans()
+
+
+def bridges():
+ return [b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)]
+
+
+def is_bridge(iface):
+ return iface in bridges()
+
+
+def all_interfaces():
+ return [d.rsplit("/", 1)[-1] for d in glob.glob(NET_PATH + '/*')]
+
+
+def slaves(bonding):
+ with open(BONDING_SLAVES % bonding) as bonding_file:
+ res = bonding_file.readline().split()
+ return res
+
+
+def ports(bridge):
+ return os.listdir(BRIDGE_PORTS % bridge)
+
+
+def is_brport(nic):
+ return os.path.exists(NET_BRPORT % nic)
+
+
+def is_bondlave(nic):
+ return os.path.exists(NET_MASTER % nic)
+
+
+def operstate(dev):
+ link_status = link_detected(dev)
+ return "down" if link_status == "n/a" else "up"
+
+
+def link_detected(dev):
+ # try to read interface carrier (link) status
+ try:
+ with open(NET_STATE % dev) as dev_file:
+ carrier = dev_file.readline().strip()
+ # when IOError is raised, interface is down
+ except IOError:
+ return "n/a"
+
+ # if value is 1, interface up with cable connected
+ # 0 corresponds to interface up with cable disconnected
+ return "yes" if carrier == '1' else "no"
+
+
+def get_vlan_device(vlan):
+ """ Return the device of the given VLAN. """
+ dev = None
+
+ if os.path.exists(PROC_NET_VLAN + vlan):
+ with open(PROC_NET_VLAN + vlan) as vlan_file:
+ for line in vlan_file:
+ if "Device:" in line:
+ dummy, dev = line.split()
+ break
+ return dev
+
+
+def get_bridge_port_device(bridge):
+ """Return the nics list that belongs to bridge."""
+ # br --- v --- bond --- nic1
+ if bridge not in bridges():
+ raise ValueError('unknown bridge %s' % bridge)
+ nics = []
+ for port in ports(bridge):
+ if port in vlans():
+ device = get_vlan_device(port)
+ if device in bondings():
+ nics.extend(slaves(device))
+ else:
+ nics.append(device)
+ if port in bondings():
+ nics.extend(slaves(port))
+ else:
+ nics.append(port)
+ return nics
+
+
+def aggregated_bridges():
+ return [bridge for bridge in bridges() if
+ (set(get_bridge_port_device(bridge)) & set(nics()))]
+
+
+def bare_nics():
+ "The nic is not a port of a bridge or a slave of bond."
+ return [nic for nic in nics() if not (is_brport(nic) or is_bondlave(nic))]
+
+
+def is_bare_nic(iface):
+ return iface in bare_nics()
+
+
+# The nic will not be exposed when it is a port of a bridge or
+# a slave of bond.
+# The bridge will not be exposed when all it's port are tap.
+def all_favored_interfaces():
+ return aggregated_bridges() + bare_nics() + bondings()
+
+
+def get_interface_type(iface):
+ # FIXME if we want to get more device type
+ # just support nic, bridge, bondings and vlan, for we just
+ # want to expose this 4 kinds of interface
+ try:
+ if is_nic(iface):
+ return "nic"
+ if is_bonding(iface):
+ return "bonding"
+ if is_bridge(iface):
+ return "bridge"
+ if is_vlan(iface):
+ return "vlan"
+ return 'unknown'
+ except IOError:
+ return 'unknown'
+
+
+def get_interface_info(iface):
+ if iface not in ethtool.get_devices():
+ raise ValueError('unknown interface: %s' % iface)
+
+ ipaddr = ''
+ netmask = ''
+ try:
+ ipaddr = ethtool.get_ipaddr(iface)
+ netmask = ethtool.get_netmask(iface)
+ except IOError:
+ pass
+
+ iface_link_detected = link_detected(iface)
+ iface_status = 'active' if iface_link_detected != "n/a" else "inactive"
+
+ return {'name': iface,
+ 'type': get_interface_type(iface),
+ 'status': iface_status,
+ 'link_detected': iface_link_detected,
+ 'ipaddr': ipaddr,
+ 'netmask': netmask}
diff --git a/models/network.py b/models/network.py
index 301a836..f4b64a5 100644
--- a/models/network.py
+++ b/models/network.py
@@ -19,13 +19,13 @@
from collections import namedtuple
+import ethtool
import libvirt
from ipaddr import IPv4Network
from threading import Timer
from interfaces import InterfaceModel
from wok.exception import OperationFailed
-from wok.network import get_dev_netaddr
from wok.utils import run_command
@@ -95,7 +95,11 @@ class NetworkModel(object):
def _save_gateway_changes(self, old_iface, old_gateway):
def save_config(conn, iface, gateway=None):
- n = IPv4Network(get_dev_netaddr(iface))
+ nic_info = ethtool.get_interfaces_info(iface)[0]
+ ipv4 = ''
+ if nic_info.ipv4_address:
+ ipv4 = "%s/%s" % (nic_info.ipv4_address, nic_info.ipv4_netmask)
+ n = IPv4Network(ipv4)
net_params = {'ipaddr': str(n.ip), 'netmask': str(n.netmask)}
if gateway:
net_params['gateway'] = gateway
--
1.7.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Ginger-dev-list] [wok] Move kimchi-specific network utilities to ginger,
Lucio Correia <=