
The detailed bug description is at https://bugs.launchpad.net/os-net-config/+bug/1537330 Since kilo, os-net-config starts to support linux bond. However, the addr_assign_type value of an active member interface of a linux bond is 3, but not 0. The consequence of this problem is that the linux bond member links are never considered as active, this further messes up the nicX to interface name mapping. This change checks if device directory exists, instead of checking the addr_assign_type value. This directory exists only when the interface is an actual physical interface. Change-Id: I8e4c95a2efa809fd236b07cbce1b81a2e774f858
107 lines
3.0 KiB
Python
107 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2014 Red Hat, 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 glob
|
|
import logging
|
|
import os
|
|
import re
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
_SYS_CLASS_NET = '/sys/class/net'
|
|
|
|
|
|
def write_config(filename, data):
|
|
with open(filename, 'w') as f:
|
|
f.write(str(data))
|
|
|
|
|
|
def get_file_data(filename):
|
|
if not os.path.exists(filename):
|
|
return ''
|
|
|
|
try:
|
|
with open(filename, 'r') as f:
|
|
return f.read()
|
|
except IOError:
|
|
logger.error("Error reading file: %s" % filename)
|
|
return ''
|
|
|
|
|
|
def interface_mac(name):
|
|
try:
|
|
with open('/sys/class/net/%s/address' % name, 'r') as f:
|
|
return f.read().rstrip()
|
|
except IOError:
|
|
logger.error("Unable to read mac address: %s" % name)
|
|
raise
|
|
|
|
|
|
def _is_active_nic(interface_name):
|
|
try:
|
|
if interface_name == 'lo':
|
|
return False
|
|
|
|
device_dir = _SYS_CLASS_NET + '/%s/device' % interface_name
|
|
has_device_dir = os.path.isdir(device_dir)
|
|
|
|
carrier = None
|
|
with open(_SYS_CLASS_NET + '/%s/carrier' % interface_name, 'r') as f:
|
|
carrier = int(f.read().rstrip())
|
|
|
|
address = None
|
|
with open(_SYS_CLASS_NET + '/%s/address' % interface_name, 'r') as f:
|
|
address = f.read().rstrip()
|
|
|
|
if has_device_dir and carrier == 1 and address:
|
|
return True
|
|
else:
|
|
return False
|
|
except IOError:
|
|
return False
|
|
|
|
|
|
def _natural_sort_key(s):
|
|
nsre = re.compile('([0-9]+)')
|
|
return [int(text) if text.isdigit() else text
|
|
for text in re.split(nsre, s)]
|
|
|
|
|
|
def ordered_active_nics():
|
|
embedded_nics = []
|
|
nics = []
|
|
for name in glob.iglob(_SYS_CLASS_NET + '/*'):
|
|
nic = name[(len(_SYS_CLASS_NET) + 1):]
|
|
if _is_active_nic(nic):
|
|
if nic.startswith('em') or nic.startswith('eth') or \
|
|
nic.startswith('eno'):
|
|
embedded_nics.append(nic)
|
|
else:
|
|
nics.append(nic)
|
|
# NOTE: we could just natural sort all active devices,
|
|
# but this ensures em, eno, and eth are ordered first
|
|
# (more backwards compatible)
|
|
return (sorted(embedded_nics, key=_natural_sort_key) +
|
|
sorted(nics, key=_natural_sort_key))
|
|
|
|
|
|
def diff(filename, data):
|
|
file_data = get_file_data(filename)
|
|
logger.debug("Diff file data:\n%s" % file_data)
|
|
logger.debug("Diff data:\n%s" % data)
|
|
# convert to string as JSON may have unicode in it
|
|
return not file_data == data
|