From 4623a558bc5b118749905bd99a1f2f3edb506cb9 Mon Sep 17 00:00:00 2001 From: Ramakrishnan G Date: Sat, 21 Mar 2015 07:16:04 +0000 Subject: [PATCH] Add boot interface in Ironic This commit adds a new boot interface in Ironic which can be used by deploy drivers to set up the node to boot. Implements: blueprint new-boot-interface Change-Id: I0fdc0636c51a1b7803899dd09870806f1c81697e --- ironic/drivers/base.py | 88 ++++++++++++++++++++++++++ ironic/drivers/fake.py | 1 + ironic/drivers/modules/fake.py | 22 +++++++ ironic/tests/conductor/test_manager.py | 1 + 4 files changed, 112 insertions(+) diff --git a/ironic/drivers/base.py b/ironic/drivers/base.py index 3e7ff33c68..0419327704 100644 --- a/ironic/drivers/base.py +++ b/ironic/drivers/base.py @@ -88,6 +88,14 @@ class BaseDriver(object): """ standard_interfaces.append('management') + boot = None + """`Standard` attribute for boot related features. + + A reference to an instance of :class:BootInterface. + May be None, if unsupported by a driver. + """ + standard_interfaces.append('boot') + vendor = None """Attribute for accessing any vendor-specific extensions. @@ -324,6 +332,86 @@ class DeployInterface(BaseInterface): pass +@six.add_metaclass(abc.ABCMeta) +class BootInterface(object): + """Interface for boot-related actions.""" + + @abc.abstractmethod + def get_properties(self): + """Return the properties of the interface. + + :returns: dictionary of : entries. + """ + + @abc.abstractmethod + def validate(self, task): + """Validate the driver-specific info for booting. + + This method validates the driver-specific info for booting the + ramdisk and instance on the node. If invalid, raises an + exception; otherwise returns None. + + :param task: a task from TaskManager. + :returns: None + :raises: InvalidParameterValue + :raises: MissingParameterValue + """ + + @abc.abstractmethod + def prepare_ramdisk(self, task, ramdisk_params): + """Prepares the boot of Ironic ramdisk. + + This method prepares the boot of the deploy ramdisk after + reading relevant information from the node's database. + + :param task: a task from TaskManager. + :param ramdisk_params: the options to be passed to the ironic ramdisk. + Different implementations might want to boot the ramdisk in + different ways by passing parameters to them. For example, + * When DIB ramdisk is booted to deploy a node, it takes the + parameters iscsi_target_iqn, deployment_id, ironic_api_url, etc. + * When Agent ramdisk is booted to deploy a node, it takes the + parameters ipa-driver-name, ipa-api-url, root_device, etc. + Other implementations can make use of ramdisk_params to pass such + information. Different implementations of boot interface will + have different ways of passing parameters to the ramdisk. + :returns: None + """ + + @abc.abstractmethod + def clean_up_ramdisk(self, task): + """Cleans up the boot of ironic ramdisk. + + This method cleans up the environment that was setup for booting the + deploy ramdisk. + + :param task: a task from TaskManager. + :returns: None + """ + + @abc.abstractmethod + def prepare_instance(self, task): + """Prepares the boot of instance. + + This method prepares the boot of the instance after reading + relevant information from the node's database. + + :param task: a task from TaskManager. + :returns: None + """ + + @abc.abstractmethod + def clean_up_instance(self, task): + """Cleans up the boot of instance. + + This method cleans up the environment that was setup for booting + the instance. + + :param task: a task from TaskManager. + :returns: None + """ + + @six.add_metaclass(abc.ABCMeta) class PowerInterface(BaseInterface): """Interface for power-related actions.""" diff --git a/ironic/drivers/fake.py b/ironic/drivers/fake.py index 2b6586cc7e..5b58b82a8a 100644 --- a/ironic/drivers/fake.py +++ b/ironic/drivers/fake.py @@ -56,6 +56,7 @@ class FakeDriver(base.BaseDriver): def __init__(self): self.power = fake.FakePower() self.deploy = fake.FakeDeploy() + self.boot = fake.FakeBoot() self.a = fake.FakeVendorA() self.b = fake.FakeVendorB() diff --git a/ironic/drivers/modules/fake.py b/ironic/drivers/modules/fake.py index e7e152aad6..181627b5d2 100644 --- a/ironic/drivers/modules/fake.py +++ b/ironic/drivers/modules/fake.py @@ -54,6 +54,28 @@ class FakePower(base.PowerInterface): pass +class FakeBoot(base.BootInterface): + """Example implementation of a simple boot interface.""" + + def get_properties(self): + return {} + + def validate(self, task): + pass + + def prepare_ramdisk(self, task): + pass + + def clean_up_ramdisk(self, task): + pass + + def prepare_instance(self, task): + pass + + def clean_up_instance(self, task): + pass + + class FakeDeploy(base.DeployInterface): """Class for a fake deployment driver. diff --git a/ironic/tests/conductor/test_manager.py b/ironic/tests/conductor/test_manager.py index 21041439f2..95e959e7e8 100644 --- a/ironic/tests/conductor/test_manager.py +++ b/ironic/tests/conductor/test_manager.py @@ -2022,6 +2022,7 @@ class MiscTestCase(_ServiceSetUpMixin, _CommonMixIn, tests_db_base.DbTestCase): 'power': {'result': True}, 'inspect': {'result': True}, 'management': {'result': True}, + 'boot': {'result': True}, 'deploy': {'result': True}} self.assertEqual(expected, ret) mock_iwdi.assert_called_once_with(self.context, node.instance_info)