[node-patches] Change in ovirt-node[master]: network: Add better progress informations
fabiand at fedoraproject.org
fabiand at fedoraproject.org
Tue Dec 11 20:09:43 UTC 2012
Fabian Deutsch has uploaded a new change for review.
Change subject: network: Add better progress informations
......................................................................
network: Add better progress informations
Change-Id: Ic82202726dbed9c7369cb28ffb5eb092a2f8127b
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/config/defaults.py
M scripts/tui/src/ovirt/node/config/network.py
M scripts/tui/src/ovirt/node/setup/network_page.py
M scripts/tui/src/ovirt/node/utils/__init__.py
M scripts/tui/src/ovirt/node/utils/network.py
5 files changed, 208 insertions(+), 92 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/73/9973/1
diff --git a/scripts/tui/src/ovirt/node/config/defaults.py b/scripts/tui/src/ovirt/node/config/defaults.py
index 37e2c8b..b6084eb 100644
--- a/scripts/tui/src/ovirt/node/config/defaults.py
+++ b/scripts/tui/src/ovirt/node/config/defaults.py
@@ -303,24 +303,30 @@
FIXME this should be rewritten o allow more fine grained progress
informations
"""
- iface = self.retrieve()["iface"]
class ConfigureNIC(utils.Transaction.Element):
title = "Configuring NIC"
def prepare(self):
- self.logger.debug("Psuedo prewparing ovirtnode.Network")
+ self.logger.debug("Psuedo preparing ovirtnode.Network")
def commit(self):
from ovirtnode.network import Network as oNetwork
net = oNetwork()
- if iface:
- net.configure_interface()
+ net.configure_interface()
net.save_network_configuration()
+ #utils.AugeasWrapper.force_reload()
+
+ class ReloadNetworkConfiguration(utils.Transaction.Element):
+ title = "Reloading network configuration"
+
+ def commit(self):
utils.AugeasWrapper.force_reload()
- tx = utils.Transaction("Saving network configuration")
+
+ tx = utils.Transaction("Applying new network configuration")
tx.append(ConfigureNIC())
+ tx.append(ReloadNetworkConfiguration())
return tx
@@ -988,8 +994,8 @@
@NodeConfigFileSection.map_and_update_defaults_decorator
def update(self, pwauth, num_bytes, disable_aesni):
valid.Boolean()(pwauth)
- valid.Number()(num_bytes)
- valid.Boolean()(disable_aesni)
+ (valid.Number() | valid.Empty(or_none=True))(num_bytes)
+ (valid.Boolean() | valid.Empty(or_none=True))(disable_aesni)
return {
"OVIRT_SSH_PWAUTH": "yes" if pwauth else None,
"OVIRT_DISABLE_AES_NI": "true" if disable_aesni else None
@@ -1012,22 +1018,25 @@
ssh = utils.security.Ssh()
class ConfigurePasswordAuthentication(utils.Transaction.Element):
+ title = "Configuring SSH password authentication"
def commit(self):
ssh.password_authentication(pwauth)
class ConfigureStrongRNG(utils.Transaction.Element):
+ title = "Configuring strong RNG"
def commit(self):
ssh.strong_rng(num_bytes)
class ConfigureAESNI(utils.Transaction.Element):
+ title = "Configuring AES NI"
def commit(self):
ssh.disable_aesni(disable_aesni)
tx = utils.Transaction("Configuring SSH")
- if pwauth:
+ if pwauth in [True, False]:
tx.append(ConfigurePasswordAuthentication())
if num_bytes:
tx.append(ConfigureStrongRNG())
- if disable_aesni:
+ if disable_aesni in [True, False]:
tx.append(ConfigureAESNI())
return tx
diff --git a/scripts/tui/src/ovirt/node/config/network.py b/scripts/tui/src/ovirt/node/config/network.py
index 415b419..d280abc 100644
--- a/scripts/tui/src/ovirt/node/config/network.py
+++ b/scripts/tui/src/ovirt/node/config/network.py
@@ -40,6 +40,7 @@
A dict of (nic-name, nic-infos-dict)
"""
LOGGER.debug("Getting configuration for '%s'" % iface)
+ Augeas.force_reload()
info = {}
diff --git a/scripts/tui/src/ovirt/node/setup/network_page.py b/scripts/tui/src/ovirt/node/setup/network_page.py
index 2460a45..4cd9d91 100644
--- a/scripts/tui/src/ovirt/node/setup/network_page.py
+++ b/scripts/tui/src/ovirt/node/setup/network_page.py
@@ -145,11 +145,24 @@
self.logger.debug("Building NIC details dialog")
# Populate model with nic specific informations
iface = self._model["nics"]
+
self.logger.debug("Getting informations for NIC details page")
live = ovirt.node.utils.network.node_nics()[iface]
cfg = defaults.Network().retrieve()
- self.logger.debug(cfg)
+ self.logger.debug("live: %s" % live)
+ self.logger.debug("cfg: %s" % cfg)
+
+ ipaddr, netmask, gateway, vlanid = (cfg["ipaddr"], cfg["netmask"],
+ cfg["gateway"], cfg["vlanid"])
+
+ if cfg["bootproto"] == "dhcp":
+ nic = utils.network.NIC(live["bridge"])
+ routes = utils.network.Routes()
+ ipaddr, netmask, gateway, vlanid = (nic.ipv4_address().items() +
+ (routes.default(),) +
+ (nic.vlanid(),))
+
self._model.update({
"dialog.nic.iface": live["name"],
"dialog.nic.driver": live["driver"],
@@ -160,11 +173,13 @@
"dialog.nic.hwaddress": live["hwaddr"],
"dialog.nic.ipv4.bootproto": cfg["bootproto"],
- "dialog.nic.ipv4.address": cfg["ipaddr"] or "",
- "dialog.nic.ipv4.netmask": cfg["netmask"] or "",
- "dialog.nic.ipv4.gateway": cfg["gateway"] or "",
- "dialog.nic.vlanid": cfg["vlanid"] or "",
+ "dialog.nic.ipv4.address": ipaddr,
+ "dialog.nic.ipv4.netmask": netmask,
+ "dialog.nic.ipv4.gateway": gateway,
+ "dialog.nic.vlanid": vlanid,
})
+
+ self.logger.debug("model: %s" % self._model)
padd = lambda l: l.ljust(14)
dialog = self._build_dialog("dialog.nic", "NIC Details: %s" % iface, [
@@ -317,13 +332,17 @@
time.sleep(3)
d.close()
+ # Behaves like a page reload
+ return self.ui_content()
+
def _configure_nic(self, bootproto, ipaddr, netmask, gateway, vlanid):
vlanid = vlanid or None
model = defaults.Network()
iface = self._model["dialog.nic.iface"]
if bootproto == "none":
self.logger.debug("Configuring no networking")
- model.update(None, None, None, None, None, None)
+ name = iface + "-DISABLED"
+ model.update(name, None, None, None, None, None)
elif bootproto == "dhcp":
self.logger.debug("Configuring dhcp")
model.update(iface, "dhcp", None, None, None, vlanid)
diff --git a/scripts/tui/src/ovirt/node/utils/__init__.py b/scripts/tui/src/ovirt/node/utils/__init__.py
index c42342b..897298c 100644
--- a/scripts/tui/src/ovirt/node/utils/__init__.py
+++ b/scripts/tui/src/ovirt/node/utils/__init__.py
@@ -41,6 +41,12 @@
# self._aug = _augeas.Augeas() # Is broken
self._aug.set("/augeas/save/copy_if_rename_fails", "")
+ @staticmethod
+ def force_reload():
+ """Needs to be called when files were changed on-disk without using Aug
+ """
+ AugeasWrapper._aug.load()
+
def get(self, p, strip_quotes=False):
v = self._aug.get(p)
if v and strip_quotes:
@@ -63,6 +69,9 @@
def match(self, p):
return self._aug.match(p)
+ def load(self):
+ return self._aug.load()
+
def set_many(self, new_dict, basepath=""):
"""Set's many augpaths at once
diff --git a/scripts/tui/src/ovirt/node/utils/network.py b/scripts/tui/src/ovirt/node/utils/network.py
index 72bc868..b765ef0 100644
--- a/scripts/tui/src/ovirt/node/utils/network.py
+++ b/scripts/tui/src/ovirt/node/utils/network.py
@@ -18,23 +18,23 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import base
+from socket import inet_ntoa
+from struct import pack
+import glob
+import gudev
+import logging
+import os.path
+import ovirt.node.config.network
+import ovirt.node.utils.fs
+import ovirt.node.utils.process as process
+import re
"""
Some convenience functions related to networking
"""
-
-import os.path
-import logging
-import re
-import glob
-
-import ovirt.node.utils.process as process
-import ovirt.node.utils.fs
-import ovirt.node.config.network
-
LOGGER = logging.getLogger(__name__)
-
#
# Try to use NM if available
@@ -49,7 +49,6 @@
except Exception as e:
LOGGER.warning("NetworkManager support disabled: " +
"NM Client not found (%s)" % e)
-import gudev
class UnknownNicError(Exception):
@@ -78,6 +77,8 @@
def iface_information(iface, with_slow=True):
"""Retuns all system NICs (via udev)
+
+ FIXME move into NIC
Args:
nics: List of NIC names
@@ -143,11 +144,12 @@
def _slow_iface_information(iface):
info = {}
+ nic = NIC(iface)
# Current IP addresses
- info["addresses"] = nic_ip_addresses(iface)
+ info["addresses"] = nic.ip_addresses()
# Current link state
- info["link_detected"] = nic_link_detected(iface)
+ info["link_detected"] = nic.has_link()
return info
@@ -263,6 +265,8 @@
if info["is_vlan"]:
dst = info["vlan_parent"]
for k in ["bootproto", "ipaddr", "netmask", "gateway"]:
+ LOGGER.debug("Merging cfg %s from bridge %s into device %s" % (k,
+ bridge, slave))
node_infos[dst][k] = bridge_cfg[k] if k in bridge_cfg else None
LOGGER.debug("Node NICs: %s" % node_infos)
@@ -289,83 +293,133 @@
return bridges[0] if len(bridges) else None
-def nic_link_detected(iface):
- """Determin if L1 is up on a given interface
+class NIC(base.Base):
+ def __init__(self, iface):
+ self.iface = iface
+ super(NIC, self).__init__()
- >>> nic_link_detected("lo")
- True
+ def has_link(self):
+ """Determin if L1 is up on a given interface
- >>> iface = all_ifaces()[0]
- >>> cmd = "ip link set dev {dev} up ; ip link show {dev}".format(dev=iface)
- >>> has_carrier = "LOWER_UP" in process.pipe(cmd, without_retval=True)
- >>> has_carrier == nic_link_detected(iface)
- True
+ >>> NIC("lo").has_link()
+ True
- Args:
- iface: The interface to be checked
- Returns:
- True if L1 (the-link-is-up) is detected (depends on driver support)
- """
+ >>> iface = all_ifaces()[0]
+ >>> cmd = "ip link set dev {dev} up ;"
+ >>> cmd += "ip link show {dev}".format(dev=iface)
+ >>> has_carrier = "LOWER_UP" in process.pipe(cmd, without_retval=True)
+ >>> has_carrier == NIC(iface).has_link()
+ True
- if iface not in all_ifaces():
- raise UnknownNicError("Unknown network interface: '%s'" % iface)
+ Args:
+ iface: The interface to be checked
+ Returns:
+ True if L1 (the-link-is-up) is detected (depends on driver support)
+ """
- if is_nm_managed(iface):
+ if self.iface not in all_ifaces():
+ raise UnknownNicError("Unknown network interface: '%s'" %
+ self.iface)
+
+ if is_nm_managed(self.iface):
+ try:
+ device = _nm_client.get_device_by_iface(self.iface)
+ if device:
+ return device.get_carrier()
+ except:
+ LOGGER.debug("Failed to retrieve carrier with NM")
+
+ # Fallback
+ has_carrier = False
try:
- device = _nm_client.get_device_by_iface(iface)
- if device:
- return device.get_carrier()
+ with open("/sys/class/net/%s/carrier" % self.iface) as c:
+ content = c.read()
+ has_carrier = "1" in content
except:
- LOGGER.debug("Failed to retrieve carrier with NM")
+ LOGGER.debug("Carrier down for %s" % self.iface)
+ return has_carrier
- # Fallback
- has_carrier = False
- try:
- with open("/sys/class/net/%s/carrier" % iface) as c:
- content = c.read()
- has_carrier = "1" in content
- except:
- LOGGER.debug("Carrier down for %s" % iface)
- return has_carrier
+ def ipv4_address(self):
+ return self.ip_addresses(["inet"])["inet"]
+ def ipv6_address(self):
+ return self.ip_addresses(["inet6"])["inet6"]
-def nic_ip_addresses(iface, families=["inet", "inet6"]):
- """Get IP addresses for an iface
+ def ip_addresses(self, families=["inet", "inet6"]):
+ """Get IP addresses for an iface
- FIXME NM client.get_device_by_iface(iface).get_ip?_config()
- """
- if iface not in all_ifaces():
- raise UnknownNicError("Unknown network interface: '%s'" % iface)
+ FIXME NM client.get_device_by_iface(iface).get_ip?_config()
+ """
+ if self.iface not in all_ifaces():
+ raise UnknownNicError("Unknown network interface: '%s'" %
+ self.iface)
- addresses = {f: None for f in families}
+ addresses = {f: (None, None) for f in families}
- if False:
- # FIXME to hackish to convert addr - is_nm_managed(iface):
- device = _nm_client.get_device_by_iface(iface)
- LOGGER.debug("Got '%s' for '%s'" % (device, iface))
- if device:
- for family, cfgfunc, sf in [
- ("inet", device.get_ip4_config, socket.AF_INET),
- ("inet6", device.get_ip6_config, socket.AF_INET6)]:
- cfg = cfgfunc()
- if not cfg:
- LOGGER.debug("No %s configuration for %s" % (family,
- iface))
- break
- addrs = cfg.get_addresses()
- addr = addrs[0].get_address() if len(addrs) > 0 else None
- addresses[family] = _nm_address_to_str(sf, addr) if addr \
- else None
+ if False:
+ # FIXME to hackish to convert addr - is_nm_managed(iface):
+ device = _nm_client.get_device_by_iface(self.iface)
+ LOGGER.debug("Got '%s' for '%s'" % (device, self.iface))
+ if device:
+ for family, cfgfunc, sf in [
+ ("inet", device.get_ip4_config, socket.AF_INET),
+ ("inet6", device.get_ip6_config, socket.AF_INET6)]:
+ cfg = cfgfunc()
+ if not cfg:
+ LOGGER.debug("No %s configuration for %s" % (family,
+ self.iface))
+ break
+ addrs = cfg.get_addresses()
+ addr = addrs[0].get_address() if len(addrs) > 0 else None
+ addresses[family] = _nm_address_to_str(sf, addr) if addr \
+ else None
+ return addresses
+
+ # Fallback
+ cmd = "ip -o addr show {iface}".format(iface=self.iface)
+ for line in process.pipe(cmd, without_retval=True).split("\n"):
+ token = re.split("\s+", line)
+ if re.search("\sinet[6]?\s", line):
+ addr, mask = token[3].split("/")
+ family = token[2]
+ if family == "inet":
+ mask = calcDottedNetmask(mask)
+ addresses[family] = IPAddress(addr, mask)
+
return addresses
- # Fallback
- cmd = "ip -o addr show {dev}".format(dev=iface)
- for line in process.pipe(cmd, without_retval=True).split("\n"):
- token = re.split("\s+", line)
- if re.search("\sinet[6]?\s", line):
- addresses[token[2]] = token[3]
+ def vlanid(self):
+ vlanids = []
+ vcfg = "/proc/net/vlan/config"
+ pat = re.compile("([0-9]+)\s*\|\s*%s$" % self.iface)
+ if os.path.exists(vcfg):
+ try:
+ with open(vcfg) as f:
+ for line in f:
+ r = pat.search(line)
+ if r:
+ vlanids.append(r.groups[0])
+ except IOError as e:
+ self.logger.warning("Could not read vlan config: %s" %
+ e.message)
+ if len(vlanids) > 1:
+ self.logger.info("Found more than one (expected) vlan: %s" %
+ vlanids)
+ return vlanids[0] if vlanids else None
- return addresses
+
+class Routes(base.Base):
+ def default(self):
+ """Return the default gw of the system
+ """
+ # Fallback
+ gw = None
+ cmd = "ip route list"
+ for line in process.pipe(cmd, without_retval=True).split("\n"):
+ token = re.split("\s+", line)
+ if line.startswith("default via"):
+ gw = token[2]
+ return gw
def _nm_address_to_str(family, ipaddr):
@@ -382,10 +436,11 @@
iface = iface or node_bridge()
addresses = []
if iface:
- addresses = nic_ip_addresses(iface)
+ nic = NIC(iface)
+ addresses = nic.ip_addresses()
has_address = any([a != None for a in addresses.values()])
- if nic_link_detected(iface):
+ if nic.has_link():
status = "Connected (Link only, no IP)"
if has_address:
status = "Connected"
@@ -393,3 +448,26 @@
summary = (status, iface, addresses)
LOGGER.debug(summary)
return summary
+
+
+def calcDottedNetmask(mask):
+ """
+ http://code.activestate.com/recipes/576483/
+ >>> calcDottedNetmask(24)
+ '255.255.255.0'
+ """
+ mask = int(str(mask))
+ bits = 0xffffffff ^ (1 << 32 - mask) - 1
+ return inet_ntoa(pack('>I', bits))
+
+
+class IPAddress(base.Base):
+ def __init__(self, address, netmask):
+ self.address = address
+ self.netmask = netmask
+
+ def __str__(self):
+ return str(self.address)
+
+ def items(self):
+ return (self.address, self.netmask)
--
To view, visit http://gerrit.ovirt.org/9973
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic82202726dbed9c7369cb28ffb5eb092a2f8127b
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>
More information about the node-patches
mailing list