simplify HardwareManager comparison
This commit is contained in:
parent
ea588b264a
commit
802969b7dd
@ -23,4 +23,4 @@ teeth_agent.modes =
|
|||||||
decom = teeth_agent.decom:DecomMode
|
decom = teeth_agent.decom:DecomMode
|
||||||
|
|
||||||
teeth_agent.hardware_managers =
|
teeth_agent.hardware_managers =
|
||||||
base = teeth_agent.hardware:BaseHardwareManager
|
generic = teeth_agent.hardware:GenericHardwareManager
|
||||||
|
@ -14,57 +14,65 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from stevedore import enabled
|
import abc
|
||||||
|
|
||||||
|
from stevedore import extension
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
|
_global_manager = None
|
||||||
|
|
||||||
class BaseHardwareManager(object):
|
|
||||||
@staticmethod
|
class HardwareSupport(object):
|
||||||
def supports_hardware():
|
"""These are just guidelines to suggest values that might be returned by
|
||||||
return True
|
calls to `evaluate_hardware_support`. No HardwareManager in mainline
|
||||||
|
teeth-agent will ever offer a value greater than `MAINLINE`. Service
|
||||||
|
Providers should feel free to return values greater than SERVICE_PROVIDER
|
||||||
|
to distinguish between additional levels of support.
|
||||||
|
"""
|
||||||
|
NONE = 0
|
||||||
|
GENERIC = 1
|
||||||
|
MAINLINE = 2
|
||||||
|
SERVICE_PROVIDER = 3
|
||||||
|
|
||||||
|
|
||||||
|
class HardwareManager(object):
|
||||||
|
@abc.abstractmethod
|
||||||
|
def evaluate_hardware_support(cls):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_primary_mac_address(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GenericHardwareManager(HardwareManager):
|
||||||
|
def evaluate_hardware_support(cls):
|
||||||
|
return HardwareSupport.GENERIC
|
||||||
|
|
||||||
def get_primary_mac_address(self):
|
def get_primary_mac_address(self):
|
||||||
return open('/sys/class/net/eth0/address', 'r').read().strip('\n')
|
return open('/sys/class/net/eth0/address', 'r').read().strip('\n')
|
||||||
|
|
||||||
|
|
||||||
def extension_supports_hardware(extension):
|
def _compare_extensions(ext1, ext2):
|
||||||
return extension.plugin.supports_hardware()
|
mgr1 = ext1.obj
|
||||||
|
mgr2 = ext2.obj
|
||||||
|
return mgr1.evaluate_hardware_support() - mgr2.evaluate_hardware_support()
|
||||||
|
|
||||||
|
|
||||||
def load_hardware_manager():
|
def load_hardware_manager():
|
||||||
# The idea here is that there is an inheritance tree of Hardware Managers.
|
|
||||||
# For example:
|
|
||||||
#
|
|
||||||
# BaseHardwareManager
|
|
||||||
# / \
|
|
||||||
# SmallServerManager LargeServerManager
|
|
||||||
# / \ / \
|
|
||||||
# v1 v2 v1 v2
|
|
||||||
#
|
|
||||||
# In this hierarchy, any manager can claim to support the hardware, but any
|
|
||||||
# of its subclasses may supercede its claim. In cases where two managers
|
|
||||||
# with no ancestral relationship both claim to support the hardware, the
|
|
||||||
# result is undefined.
|
|
||||||
#
|
|
||||||
# NOTE(russellhaering): I don't know if this is actually a good idea, I
|
|
||||||
# just want to be able to have a base manager which
|
|
||||||
# tries to supply reasonable defaults, and be able to
|
|
||||||
# override it simply by installing an appropriate
|
|
||||||
# plugin.
|
|
||||||
log = structlog.get_logger()
|
log = structlog.get_logger()
|
||||||
selected_plugin = BaseHardwareManager
|
extension_manager = extension.ExtensionManager(
|
||||||
extension_manager = enabled.EnabledExtensionManager(
|
|
||||||
namespace='teeth_agent.hardware_managers',
|
namespace='teeth_agent.hardware_managers',
|
||||||
check_func=extension_supports_hardware)
|
invoke_on_load=True)
|
||||||
|
|
||||||
for extension in extension_manager:
|
# There will always be at least one extension available (the
|
||||||
plugin = extension.plugin
|
# GenericHardwareManager).
|
||||||
log.info('found qualified hardware manager',
|
preferred_extension = sorted(extension_manager, _compare_extensions)[0]
|
||||||
manager_name=plugin.__name__)
|
preferred_manager = preferred_extension.obj
|
||||||
if issubclass(plugin, selected_plugin):
|
|
||||||
selected_plugin = plugin
|
if preferred_manager.evaluate_hardware_support() <= 0:
|
||||||
|
raise RuntimeError('No suitable HardwareManager could be found')
|
||||||
|
|
||||||
log.info('selected hardware manager',
|
log.info('selected hardware manager',
|
||||||
manager_name=selected_plugin.__name__)
|
manager_name=preferred_extension.entry_point_target)
|
||||||
|
return preferred_manager
|
||||||
return selected_plugin()
|
|
||||||
|
@ -20,9 +20,9 @@ import unittest
|
|||||||
from teeth_agent import hardware
|
from teeth_agent import hardware
|
||||||
|
|
||||||
|
|
||||||
class TestBaseHardwareManager(unittest.TestCase):
|
class TestGenericHardwareManager(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.hardware = hardware.BaseHardwareManager()
|
self.hardware = hardware.GenericHardwareManager()
|
||||||
|
|
||||||
@mock.patch('__builtin__.open')
|
@mock.patch('__builtin__.open')
|
||||||
def test_decom_mode(self, mocked_open):
|
def test_decom_mode(self, mocked_open):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user