xinwu cb4f56f72c launchpad bug 1537330, fix _is_active_nic
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
2016-02-12 18:51:44 -08:00

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