Ensure network interface is up befure running DHCP server discovery.

It happened that the interface where DHCP servers are about to discover
was always up due to NetworkManager service. Since we are disabling it
we need to ensure that the interface is up.
Default routes deletion is now done by puppet.

Change-Id: Ieda8b67be8133bdc953ace2054aaa6db1ce949c0
Closes-Bug: #1543767
This commit is contained in:
Georgy Kibardin 2016-03-21 10:31:46 +03:00
parent b4be65dea9
commit 604c20a9bb
5 changed files with 48 additions and 36 deletions

View File

@ -133,6 +133,10 @@ def netmaskToCidr(netmask):
return sum([bin(int(x)).count('1') for x in netmask.split('.')])
def addr_in_cidr_notation(ip, netmask):
return str(netaddr.IPNetwork("{0}/{1}".format(ip, netmask)))
def duplicateIPExists(ip, iface, arping_bind=False):
"""Checks for duplicate IP addresses using arping.
@ -165,6 +169,7 @@ def search_external_dhcp(iface, timeout):
command = ["dhcpcheck", "discover", "--timeout", str(timeout), "-f",
"json", "--ifaces", iface]
try:
upIface(iface) # ensure iface is up
_, output, _ = execute(command)
data = json.loads(output.strip())
# FIXME(mattymo): Sometimes dhcpcheck prints json with keys, but no

View File

@ -87,6 +87,7 @@ class FuelSetup(object):
self.frame = None
self.screen = None
self.managediface = network.get_physical_ifaces()[0]
self.dns_might_have_changed = False
# Set to true to move all settings to end
self.globalsave = True
self.version = utils.get_fuel_version()

View File

@ -279,6 +279,18 @@ is accessible"}
def cancel(self, button):
ModuleHelper.cancel(self, button)
def resolv_conf_settings(self):
# Parse /etc/resolv.conf if it contains data
settings = {}
search, domain, nameservers = self.getDNS()
if search:
settings["DNS_SEARCH"] = search
if domain:
settings["DNS_DOMAIN"] = domain
if nameservers:
settings["DNS_UPSTREAM"] = nameservers
return settings
def load(self):
# Precedence of DNS information:
# Class defaults, fuelmenu default YAML, astute.yaml, uname,
@ -294,14 +306,7 @@ is accessible"}
except Exception:
log.warning("Unable to look up system hostname")
# Parse /etc/resolv.conf if it contains data
search, domain, nameservers = self.getDNS()
if search:
oldsettings["DNS_SEARCH"] = search
if domain:
oldsettings["DNS_DOMAIN"] = domain
if nameservers:
oldsettings["DNS_UPSTREAM"] = nameservers
oldsettings.update(self.resolv_conf_settings())
ModuleHelper.load_to_defaults(oldsettings,
self.defaults,
@ -361,7 +366,12 @@ is accessible"}
return ModuleHelper.get_default_gateway_linux()
def refresh(self):
pass
if self.parent.dns_might_have_changed:
settings = self.resolv_conf_settings()
for index, fieldname in enumerate(self.fields):
if fieldname in settings:
self.edits[index].set_edit_text(settings[fieldname])
self.parent.dns_might_have_changed = False
def screenUI(self):
return ModuleHelper.screenUI(self, self.header_content, self.fields,

View File

@ -28,7 +28,6 @@ from fuelmenu.common import network
from fuelmenu.common import puppet
from fuelmenu.common import replace
import fuelmenu.common.urwidwrapper as widget
from fuelmenu.common import utils
blank = urwid.Divider()
@ -231,6 +230,15 @@ class interfaces(urwid.WidgetWrap):
self.parent.footer.set_text("No errors found.")
return responses
def clear_gateways_except(self, iface):
return [{'type': "resource",
'class': "l23network::l3::ifconfig",
'name': name,
'params': {'ipaddr': network.addr_in_cidr_notation(
self.netsettings[name]['addr'],
self.netsettings[name]['netmask'])}}
for name in self.netsettings if name != iface]
def apply(self, args):
responses = self.check(args)
if responses is False:
@ -268,25 +276,24 @@ class interfaces(urwid.WidgetWrap):
'class': "l23network::l3::ifconfig",
'name': self.activeiface}
additionalclasses = []
if responses["onboot"].lower() == "no":
params = {"ipaddr": "none",
"gateway": ""}
elif responses["bootproto"] == "dhcp":
self.unset_gateway()
additionalclasses = self.clear_gateways_except(self.activeiface)
params = {"ipaddr": "dhcp"}
else:
cidr = network.netmaskToCidr(responses["netmask"])
params = {"ipaddr": "{0}/{1}".format(responses["ipaddr"], cidr),
cidr = network.addr_in_cidr_notation(responses["ipaddr"],
responses["netmask"])
params = {"ipaddr": cidr,
"check_by_ping": "none"}
if len(responses["gateway"]) > 1:
params["gateway"] = responses["gateway"]
self.unset_gateway()
if network.inSameSubnet(responses["ipaddr"],
self.get_default_gateway_linux(),
responses["netmask"]):
# Unset if clearing currently set gateway on same subnet
self.unset_gateway()
additionalclasses = self.clear_gateways_except(
self.activeiface)
puppetclasses.extend(additionalclasses)
l3ifconfig['params'] = params
puppetclasses.append(l3ifconfig)
self.log.info("Puppet data: %s" % (puppetclasses))
@ -300,6 +307,8 @@ class interfaces(urwid.WidgetWrap):
if gateway is None:
gateway = ""
self.fixEtcHosts()
if responses['bootproto'] == 'dhcp':
self.parent.dns_might_have_changed = True
except Exception as e:
self.log.error(e)
@ -323,20 +332,6 @@ class interfaces(urwid.WidgetWrap):
def get_default_gateway_linux(self):
return ModuleHelper.get_default_gateway_linux()
def unset_gateway(self):
"""Unset current gateway."""
command = "ip route del default dev $(ip ro | grep default"\
" | awk '{print $5}')"
if self.get_default_gateway_linux() is None:
return True
code, output, errout = utils.execute(command, shell=True)
if code != 0:
self.log.error("Unable to unset gateway")
self.log.info("Command was: {0}\nStderr: {1}\nStdout:".format(
command, output, errout))
self.parent.footer.set_text("Unable to unset gateway.")
return False
def radioSelectIface(self, current, state, user_data=None):
"""Update network details and display information."""
# This makes no sense, but urwid returns the previous object.

View File

@ -109,7 +109,8 @@ class TestUtils(unittest.TestCase):
def make_process_mock(self, return_code=0, retval=('stdout', 'stderr')):
process_mock = mock.Mock(
communicate=mock.Mock(return_value=retval))
communicate=mock.Mock(return_value=retval),
poll=mock.Mock(return_value=return_code))
process_mock.stdout = ['Stdout line 1', 'Stdout line 2']
process_mock.returncode = return_code
@ -125,7 +126,7 @@ class TestUtils(unittest.TestCase):
retval=(output, ''))
with patch.object(subprocess, 'Popen', return_value=process_mock):
data = network.search_external_dhcp(interface, timeout)
process_mock.communicate.assert_called_once_with(input=None)
process_mock.communicate.assert_called_with(input=None)
self.assertEqual(data, json.loads(output))
def test_search_external_dhcp_nodata(self):
@ -138,7 +139,7 @@ class TestUtils(unittest.TestCase):
retval=(output, ''))
with patch.object(subprocess, 'Popen', return_value=process_mock):
data = network.search_external_dhcp(interface, timeout)
process_mock.communicate.assert_called_once_with(input=None)
process_mock.communicate.assert_called_with(input=None)
self.assertEqual(data, [])
def test_search_external_dhcp_raises_exception(self):