~ubuntu-branches/ubuntu/vivid/ironic/vivid-updates

« back to all changes in this revision

Viewing changes to ironic/drivers/modules/ilo/deploy.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2015-03-30 11:14:57 UTC
  • mfrom: (1.2.6)
  • Revision ID: package-import@ubuntu.com-20150330111457-kr4ju3guf22m4vbz
Tags: 2015.1~b3-0ubuntu1
* New upstream release.
  + d/control: 
    - Align with upstream dependencies.
    - Add dh-python to build-dependencies.
    - Add psmisc as a dependency. (LP: #1358820)
  + d/p/fix-requirements.patch: Rediffed.
  + d/ironic-conductor.init.in: Fixed typos in LSB headers,
    thanks to JJ Asghar. (LP: #1429962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
import tempfile
19
19
 
20
20
from oslo_config import cfg
 
21
from oslo_utils import excutils
21
22
 
22
23
from ironic.common import boot_devices
 
24
from ironic.common import dhcp_factory
23
25
from ironic.common import exception
 
26
from ironic.common.glance_service import service_utils
24
27
from ironic.common.i18n import _
25
28
from ironic.common.i18n import _LE
26
29
from ironic.common.i18n import _LI
 
30
from ironic.common import image_service
27
31
from ironic.common import images
 
32
from ironic.common import keystone
28
33
from ironic.common import states
29
34
from ironic.common import swift
30
35
from ironic.conductor import task_manager
31
36
from ironic.conductor import utils as manager_utils
32
37
from ironic.drivers import base
33
38
from ironic.drivers.modules import agent
 
39
from ironic.drivers.modules import agent_base_vendor
34
40
from ironic.drivers.modules import deploy_utils
35
41
from ironic.drivers.modules.ilo import common as ilo_common
36
42
from ironic.drivers.modules import ipmitool
43
49
 
44
50
CONF = cfg.CONF
45
51
 
 
52
clean_opts = [
 
53
    cfg.IntOpt('clean_priority_erase_devices',
 
54
               help='Priority for erase devices clean step. If unset, '
 
55
                    'it defaults to 10. If set to 0, the step will be '
 
56
                    'disabled and will not run during cleaning.')
 
57
              ]
 
58
 
46
59
REQUIRED_PROPERTIES = {
47
60
    'ilo_deploy_iso': _("UUID (from Glance) of the deployment ISO. "
48
61
                    "Required.")
53
66
                group='pxe')
54
67
CONF.import_opt('swift_ilo_container', 'ironic.drivers.modules.ilo.common',
55
68
                group='ilo')
 
69
CONF.register_opts(clean_opts, group='ilo')
56
70
 
57
71
 
58
72
def _get_boot_iso_object_name(node):
66
80
def _get_boot_iso(task, root_uuid):
67
81
    """This method returns a boot ISO to boot the node.
68
82
 
69
 
    It chooses one of the two options in the order as below:
70
 
    1. Image deployed has a meta-property 'boot_iso' in Glance. This should
 
83
    It chooses one of the three options in the order as below:
 
84
    1. Does nothing if 'ilo_boot_iso' is present in node's instance_info.
 
85
    2. Image deployed has a meta-property 'boot_iso' in Glance. This should
71
86
       refer to the UUID of the boot_iso which exists in Glance.
72
 
    2. Generates a boot ISO on the fly using kernel and ramdisk mentioned in
 
87
    3. Generates a boot ISO on the fly using kernel and ramdisk mentioned in
73
88
       the image deployed. It uploads the generated boot ISO to Swift.
74
89
 
75
90
    :param task: a TaskManager instance containing the node to act on.
76
91
    :param root_uuid: the uuid of the root partition.
77
 
    :returns: the information about the boot ISO. Returns the information in
78
 
        the format 'glance:<glance-boot-iso-uuid>' or
79
 
        'swift:<swift-boot_iso-object-name>'.  In case of Swift, it is assumed
80
 
        that the object exists in CONF.ilo.swift_ilo_container.
 
92
    :returns: boot ISO URL. Should be either of below:
 
93
        * A Swift object - It should be of format 'swift:<object-name>'. It is
 
94
          assumed that the image object is present in
 
95
          CONF.ilo.swift_ilo_container;
 
96
        * A Glance image - It should be format 'glance://<glance-image-uuid>'
 
97
          or just <glance-image-uuid>;
 
98
        * An HTTP URL.
81
99
        On error finding the boot iso, it returns None.
82
100
    :raises: MissingParameterValue, if any of the required parameters are
83
101
        missing in the node's driver_info or instance_info.
85
103
        value in the node's driver_info or instance_info.
86
104
    :raises: SwiftOperationError, if operation with Swift fails.
87
105
    :raises: ImageCreationFailed, if creation of boot ISO failed.
 
106
    :raises: exception.ImageRefValidationFailed if ilo_boot_iso is not
 
107
        HTTP(S) URL.
88
108
    """
89
 
    # Option 1 - Check if user has provided a boot_iso in Glance.
90
109
    LOG.debug("Trying to get a boot ISO to boot the baremetal node")
 
110
 
 
111
    # Option 1 - Check if user has provided ilo_boot_iso in node's
 
112
    # instance_info
 
113
    if task.node.instance_info.get('ilo_boot_iso'):
 
114
        LOG.debug("Using ilo_boot_iso provided in node's instance_info")
 
115
        boot_iso = task.node.instance_info['ilo_boot_iso']
 
116
        if not service_utils.is_glance_image(boot_iso):
 
117
            try:
 
118
                image_service.HttpImageService().validate_href(boot_iso)
 
119
            except exception.ImageRefValidationFailed:
 
120
                with excutils.save_and_reraise_exception():
 
121
                    LOG.error(_LE("Virtual media deploy accepts only Glance "
 
122
                                  "images or HTTP(S) URLs as "
 
123
                                  "instance_info['ilo_boot_iso']. Either %s "
 
124
                                  "is not a valid HTTP(S) URL or is "
 
125
                                  "not reachable."), boot_iso)
 
126
        return task.node.instance_info['ilo_boot_iso']
 
127
 
 
128
    # Option 2 - Check if user has provided a boot_iso in Glance. If boot_iso
 
129
    # is a supported non-glance href execution will proceed to option 3.
91
130
    deploy_info = _parse_deploy_info(task.node)
92
131
 
93
132
    image_href = deploy_info['image_source']
94
 
    glance_properties = (
95
 
        images.get_glance_image_properties(task.context,
 
133
    image_properties = (
 
134
        images.get_image_properties(task.context,
96
135
            image_href, ['boot_iso', 'kernel_id', 'ramdisk_id']))
97
136
 
98
 
    boot_iso_uuid = glance_properties.get('boot_iso')
99
 
    kernel_uuid = glance_properties.get('kernel_id')
100
 
    ramdisk_uuid = glance_properties.get('ramdisk_id')
 
137
    boot_iso_uuid = image_properties.get('boot_iso')
 
138
    kernel_href = (task.node.instance_info.get('kernel') or
 
139
                   image_properties.get('kernel_id'))
 
140
    ramdisk_href = (task.node.instance_info.get('ramdisk') or
 
141
                    image_properties.get('ramdisk_id'))
101
142
 
102
143
    if boot_iso_uuid:
103
144
        LOG.debug("Found boot_iso %s in Glance", boot_iso_uuid)
104
 
        return 'glance:%s' % boot_iso_uuid
105
 
 
106
 
    # NOTE(faizan) For uefi boot_mode, operator should provide efi capable
107
 
    # boot-iso in glance
108
 
    if driver_utils.get_node_capability(task.node, 'boot_mode') == 'uefi':
109
 
        LOG.error(_LE("Unable to find boot_iso in Glance, required to deploy "
110
 
                      "node %(node)s in UEFI boot mode."),
111
 
                  {'node': task.node.uuid})
112
 
        return
113
 
 
114
 
    if not kernel_uuid or not ramdisk_uuid:
115
 
        LOG.error(_LE("Unable to find 'kernel_id' and 'ramdisk_id' in Glance "
116
 
                      "image %(image)s for generating boot ISO for %(node)s"),
 
145
        return boot_iso_uuid
 
146
 
 
147
    if not kernel_href or not ramdisk_href:
 
148
        LOG.error(_LE("Unable to find kernel or ramdisk for "
 
149
                      "image %(image)s to generate boot ISO for %(node)s"),
117
150
                  {'image': image_href, 'node': task.node.uuid})
118
151
        return
119
152
 
123
156
    # will require synchronisation across conductor nodes for the shared boot
124
157
    # ISO.  Such a synchronisation mechanism doesn't exist in ironic as of now.
125
158
 
126
 
    # Option 2 - Create boot_iso from kernel/ramdisk, upload to Swift
 
159
    # Option 3 - Create boot_iso from kernel/ramdisk, upload to Swift
127
160
    # and provide its name.
 
161
    deploy_iso_uuid = deploy_info['ilo_deploy_iso']
 
162
    boot_mode = driver_utils.get_node_capability(task.node, 'boot_mode')
128
163
    boot_iso_object_name = _get_boot_iso_object_name(task.node)
129
164
    kernel_params = CONF.pxe.pxe_append_params
130
165
    container = CONF.ilo.swift_ilo_container
132
167
    with tempfile.NamedTemporaryFile() as fileobj:
133
168
        boot_iso_tmp_file = fileobj.name
134
169
        images.create_boot_iso(task.context, boot_iso_tmp_file,
135
 
                kernel_uuid, ramdisk_uuid, root_uuid, kernel_params)
 
170
                               kernel_href, ramdisk_href,
 
171
                               deploy_iso_uuid, root_uuid,
 
172
                               kernel_params, boot_mode)
136
173
        swift_api = swift.SwiftAPI()
137
174
        swift_api.create_object(container, boot_iso_object_name,
138
 
                boot_iso_tmp_file)
 
175
                                boot_iso_tmp_file)
139
176
 
140
177
    LOG.debug("Created boot_iso %s in Swift", boot_iso_object_name)
141
178
 
143
180
 
144
181
 
145
182
def _clean_up_boot_iso_for_instance(node):
146
 
    """Deletes the boot ISO created in Swift for the instance.
 
183
    """Deletes the boot ISO if it was created in Swift for the instance.
147
184
 
148
185
    :param node: an ironic node object.
149
186
    """
 
187
    ilo_boot_iso = node.instance_info.get('ilo_boot_iso')
 
188
    if not (ilo_boot_iso and ilo_boot_iso.startswith('swift')):
 
189
        return
150
190
    swift_api = swift.SwiftAPI()
151
191
    container = CONF.ilo.swift_ilo_container
152
192
    boot_iso_object_name = _get_boot_iso_object_name(node)
208
248
    arguments for ramdisk in virtual media floppy, and then reboots the node.
209
249
 
210
250
    :param task: a TaskManager instance containing the node to act on.
211
 
    :param iso: a bootable ISO image to attach to.  The boot iso
212
 
        should be present in either Glance or in Swift. If present in
213
 
        Glance, it should be of format 'glance:<glance-image-uuid>'.
214
 
        If present in Swift, it should be of format 'swift:<object-name>'.
215
 
        It is assumed that object is present in CONF.ilo.swift_ilo_container.
 
251
    :param iso: a bootable ISO image href to attach to. Should be either
 
252
        of below:
 
253
        * A Swift object - It should be of format 'swift:<object-name>'.
 
254
          It is assumed that the image object is present in
 
255
          CONF.ilo.swift_ilo_container;
 
256
        * A Glance image - It should be format 'glance://<glance-image-uuid>'
 
257
          or just <glance-image-uuid>;
 
258
        * An HTTP URL.
216
259
    :param ramdisk_options: the options to be passed to the ramdisk in virtual
217
260
        media floppy.
218
261
    :raises: ImageCreationFailed, if it failed while creating the floppy image.
223
266
    manager_utils.node_power_action(task, states.REBOOT)
224
267
 
225
268
 
 
269
def _prepare_agent_vmedia_boot(task):
 
270
    """prepare for vmedia boot."""
 
271
 
 
272
    deploy_ramdisk_opts = agent.build_agent_options(task.node)
 
273
    deploy_iso = task.node.driver_info['ilo_deploy_iso']
 
274
    _reboot_into(task, deploy_iso, deploy_ramdisk_opts)
 
275
 
 
276
 
226
277
class IloVirtualMediaIscsiDeploy(base.DeployInterface):
227
278
 
228
279
    def get_properties(self):
234
285
        :param task: a TaskManager instance containing the node to act on.
235
286
        :raises: InvalidParameterValue, if some information is invalid.
236
287
        :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
237
 
            missing in the Glance image.
 
288
            missing in the Glance image or 'kernel' and 'ramdisk' not provided
 
289
            in instance_info for non-Glance image.
238
290
        """
239
291
        iscsi_deploy.validate(task)
240
292
 
241
 
        props = ['kernel_id', 'ramdisk_id']
242
293
        d_info = _parse_deploy_info(task.node)
243
 
        iscsi_deploy.validate_glance_image_properties(task.context, d_info,
244
 
                                                      props)
 
294
 
 
295
        if task.node.driver_internal_info.get('is_whole_disk_image'):
 
296
            props = []
 
297
        elif service_utils.is_glance_image(d_info['image_source']):
 
298
            props = ['kernel_id', 'ramdisk_id']
 
299
        else:
 
300
            props = ['kernel', 'ramdisk']
 
301
        iscsi_deploy.validate_image_properties(task.context, d_info, props)
245
302
        driver_utils.validate_boot_mode_capability(task.node)
 
303
        driver_utils.validate_boot_option_capability(task.node)
246
304
 
247
305
    @task_manager.require_exclusive_lock
248
306
    def deploy(self, task):
267
325
        iscsi_deploy.check_image_size(task)
268
326
 
269
327
        deploy_ramdisk_opts = iscsi_deploy.build_deploy_ramdisk_options(node)
 
328
        agent_opts = agent.build_agent_options(node)
 
329
        deploy_ramdisk_opts.update(agent_opts)
270
330
        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
271
331
        deploy_ramdisk_opts['BOOTIF'] = deploy_nic_mac
272
 
        deploy_iso_uuid = node.driver_info['ilo_deploy_iso']
273
 
        deploy_iso = 'glance:' + deploy_iso_uuid
 
332
        deploy_iso = node.driver_info['ilo_deploy_iso']
274
333
 
275
334
        _reboot_into(task, deploy_iso, deploy_ramdisk_opts)
276
335
 
295
354
        :param task: a TaskManager instance containing the node to act on.
296
355
        :raises: IloOperationError, if some operation on iLO failed.
297
356
        """
298
 
        boot_mode = driver_utils.get_node_capability(task.node, 'boot_mode')
299
 
        if boot_mode is not None:
300
 
            ilo_common.set_boot_mode(task.node, boot_mode)
301
 
        else:
302
 
            ilo_common.update_boot_mode_capability(task)
 
357
        ilo_common.update_boot_mode(task)
303
358
 
304
359
    def clean_up(self, task):
305
360
        """Clean up the deployment environment for the task's node.
346
401
            image.
347
402
        :raises: IloOperationError, if some operation on iLO fails.
348
403
        """
349
 
        deploy_ramdisk_opts = agent.build_agent_options(task.node)
350
 
        deploy_iso_uuid = task.node.driver_info['ilo_deploy_iso']
351
 
        deploy_iso = 'glance:' + deploy_iso_uuid
352
 
        _reboot_into(task, deploy_iso, deploy_ramdisk_opts)
 
404
        _prepare_agent_vmedia_boot(task)
353
405
 
354
406
        return states.DEPLOYWAIT
355
407
 
371
423
        node = task.node
372
424
        node.instance_info = agent.build_instance_info_for_deploy(task)
373
425
        node.save()
 
426
        ilo_common.update_boot_mode(task)
374
427
 
375
428
    def clean_up(self, task):
376
429
        """Clean up the deployment environment for this node.
389
442
        """
390
443
        pass
391
444
 
 
445
    def get_clean_steps(self, task):
 
446
        """Get the list of clean steps from the agent.
 
447
 
 
448
        :param task: a TaskManager object containing the node
 
449
        :returns: A list of clean step dictionaries
 
450
        """
 
451
        steps = deploy_utils.agent_get_clean_steps(task)
 
452
        if CONF.ilo.clean_priority_erase_devices:
 
453
            for step in steps:
 
454
                if (step.get('step') == 'erase_devices' and
 
455
                        step.get('interface') == 'deploy'):
 
456
                    # Override with operator set priority
 
457
                    step['priority'] = CONF.ilo.clean_priority_erase_devices
 
458
 
 
459
        return steps
 
460
 
 
461
    def execute_clean_step(self, task, step):
 
462
        """Execute a clean step asynchronously on the agent.
 
463
 
 
464
        :param task: a TaskManager object containing the node
 
465
        :param step: a clean step dictionary to execute
 
466
        :returns: states.CLEANING to signify the step will be completed async
 
467
        """
 
468
        return deploy_utils.agent_execute_clean_step(task, step)
 
469
 
 
470
    def prepare_cleaning(self, task):
 
471
        """Boot into the agent to prepare for cleaning."""
 
472
        # Create cleaning ports if necessary
 
473
        provider = dhcp_factory.DHCPFactory().provider
 
474
 
 
475
        # If we have left over ports from a previous cleaning, remove them
 
476
        if getattr(provider, 'delete_cleaning_ports', None):
 
477
            provider.delete_cleaning_ports(task)
 
478
 
 
479
        if getattr(provider, 'create_cleaning_ports', None):
 
480
            provider.create_cleaning_ports(task)
 
481
 
 
482
        _prepare_agent_vmedia_boot(task)
 
483
        # Tell the conductor we are waiting for the agent to boot.
 
484
        return states.CLEANING
 
485
 
 
486
    def tear_down_cleaning(self, task):
 
487
        """Clean up the PXE and DHCP files after cleaning."""
 
488
        manager_utils.node_power_action(task, states.POWER_OFF)
 
489
        # If we created cleaning ports, delete them
 
490
        provider = dhcp_factory.DHCPFactory().provider
 
491
        if getattr(provider, 'delete_cleaning_ports', None):
 
492
            provider.delete_cleaning_ports(task)
 
493
 
392
494
 
393
495
class IloPXEDeploy(pxe.PXEDeploy):
394
496
 
404
506
 
405
507
        :param task: a TaskManager instance containing the node to act on.
406
508
        """
407
 
        boot_mode = driver_utils.get_node_capability(task.node, 'boot_mode')
408
 
        if boot_mode is None:
409
 
            ilo_common.update_boot_mode_capability(task)
410
 
        else:
411
 
            ilo_common.set_boot_mode(task.node, boot_mode)
 
509
        ilo_common.update_boot_mode(task)
412
510
        super(IloPXEDeploy, self).prepare(task)
413
511
 
414
512
    def deploy(self, task):
452
550
 
453
551
class IloPXEVendorPassthru(pxe.VendorPassthru):
454
552
 
455
 
    @base.passthru(['POST'], method='pass_deploy_info')
456
 
    def _continue_deploy(self, task, **kwargs):
 
553
    @base.passthru(['POST'])
 
554
    def pass_deploy_info(self, task, **kwargs):
457
555
        manager_utils.node_set_boot_device(task, boot_devices.PXE, True)
458
 
        super(IloPXEVendorPassthru, self)._continue_deploy(task, **kwargs)
459
 
 
460
 
 
461
 
class VendorPassthru(base.VendorInterface):
 
556
        super(IloPXEVendorPassthru, self).pass_deploy_info(task, **kwargs)
 
557
 
 
558
 
 
559
class VendorPassthru(agent_base_vendor.BaseAgentVendor):
462
560
    """Vendor-specific interfaces for iLO deploy drivers."""
463
561
 
464
562
    def get_properties(self):
479
577
        :raises: InvalidParameterValue, if any of the parameters have invalid
480
578
            value.
481
579
        """
482
 
        iscsi_deploy.get_deploy_info(task.node, **kwargs)
483
 
 
484
 
    @base.passthru(['POST'], method='pass_deploy_info')
 
580
        if method == 'pass_deploy_info':
 
581
            iscsi_deploy.get_deploy_info(task.node, **kwargs)
 
582
 
 
583
    def _configure_vmedia_boot(self, task, root_uuid):
 
584
        """Configure vmedia boot for the node."""
 
585
        node = task.node
 
586
        boot_iso = _get_boot_iso(task, root_uuid)
 
587
        if not boot_iso:
 
588
            LOG.error(_LE("Cannot get boot ISO for node %s"), node.uuid)
 
589
            return
 
590
 
 
591
        ilo_common.setup_vmedia_for_boot(task, boot_iso)
 
592
        manager_utils.node_set_boot_device(task, boot_devices.CDROM)
 
593
 
 
594
        i_info = node.instance_info
 
595
        if not i_info.get('ilo_boot_iso'):
 
596
            i_info['ilo_boot_iso'] = boot_iso
 
597
            node.instance_info = i_info
 
598
 
 
599
    @base.passthru(['POST'])
485
600
    @task_manager.require_exclusive_lock
486
 
    def _continue_deploy(self, task, **kwargs):
 
601
    def pass_deploy_info(self, task, **kwargs):
487
602
        """Continues the iSCSI deployment from where ramdisk left off.
488
603
 
489
 
        Continues the iSCSI deployment from the conductor node, finds the
490
 
        boot ISO to boot the node, and sets the node to boot from boot ISO.
 
604
        This method continues the iSCSI deployment from the conductor node
 
605
        and writes the deploy image to the bare metal's disk.  After that,
 
606
        it does the following depending on boot_option for deploy:
 
607
        - If the boot_option requested for this deploy is 'local', then it
 
608
          sets the node to boot from disk (ramdisk installs the boot loader
 
609
          present within the image to the bare metal's disk).
 
610
        - If the boot_option requested is 'netboot' or no boot_option is
 
611
          requested, it finds/creates the boot ISO to boot the instance
 
612
          image, attaches the boot ISO to the bare metal and then sets
 
613
          the node to boot from CDROM.
491
614
 
492
615
        :param task: a TaskManager instance containing the node to act on.
493
616
        :param kwargs: kwargs containing parameters for iSCSI deployment.
496
619
        node = task.node
497
620
        task.process_event('resume')
498
621
 
 
622
        iwdi = node.driver_internal_info.get('is_whole_disk_image')
499
623
        ilo_common.cleanup_vmedia_boot(task)
500
 
        root_uuid = iscsi_deploy.continue_deploy(task, **kwargs)
 
624
        uuid_dict_returned = iscsi_deploy.continue_deploy(task, **kwargs)
 
625
        root_uuid_or_disk_id = uuid_dict_returned.get(
 
626
            'root uuid', uuid_dict_returned.get('disk identifier'))
501
627
 
502
 
        if not root_uuid:
 
628
        # TODO(rameshg87): It's not correct to return here as it will leave
 
629
        # the node in DEPLOYING state. This will be fixed in bug 1405519.
 
630
        if not root_uuid_or_disk_id:
503
631
            return
504
632
 
505
633
        try:
506
 
            boot_iso = _get_boot_iso(task, root_uuid)
507
 
 
508
 
            if not boot_iso:
509
 
                LOG.error(_LE("Cannot get boot ISO for node %s"), node.uuid)
510
 
                return
511
 
 
512
 
            ilo_common.setup_vmedia_for_boot(task, boot_iso)
513
 
            manager_utils.node_set_boot_device(task, boot_devices.CDROM)
514
 
 
515
 
            address = kwargs.get('address')
516
 
            deploy_utils.notify_deploy_complete(address)
 
634
            # For iscsi_ilo driver, we boot from disk everytime if the image
 
635
            # deployed is a whole disk image.
 
636
            if iscsi_deploy.get_boot_option(node) == "local" or iwdi:
 
637
                manager_utils.node_set_boot_device(task, boot_devices.DISK,
 
638
                                                   persistent=True)
 
639
            else:
 
640
                self._configure_vmedia_boot(task, root_uuid_or_disk_id)
 
641
 
 
642
            deploy_utils.notify_deploy_complete(kwargs.get('address'))
517
643
 
518
644
            LOG.info(_LI('Deployment to node %s done'), node.uuid)
519
 
 
520
 
            i_info = node.instance_info
521
 
            i_info['ilo_boot_iso'] = boot_iso
522
 
            node.instance_info = i_info
523
645
            task.process_event('done')
524
646
        except Exception as e:
525
647
            LOG.error(_LE('Deploy failed for instance %(instance)s. '
527
649
                      {'instance': node.instance_uuid, 'error': e})
528
650
            msg = _('Failed to continue iSCSI deployment.')
529
651
            deploy_utils.set_failed_state(task, msg)
 
652
 
 
653
    @task_manager.require_exclusive_lock
 
654
    def continue_deploy(self, task, **kwargs):
 
655
        """Method invoked when deployed with the IPA ramdisk.
 
656
 
 
657
        This method is invoked during a heartbeat from an agent when
 
658
        the node is in wait-call-back state. This deploys the image on
 
659
        the node and then configures the node to boot according to the
 
660
        desired boot option (netboot or localboot).
 
661
 
 
662
        :param task: a TaskManager object containing the node.
 
663
        :param kwargs: the kwargs passed from the heartbeat method.
 
664
        :raises: InstanceDeployFailure, if it encounters some error during
 
665
            the deploy.
 
666
        """
 
667
        task.process_event('resume')
 
668
        node = task.node
 
669
        LOG.debug('Continuing the deployment on node %s', node.uuid)
 
670
 
 
671
        ilo_common.cleanup_vmedia_boot(task)
 
672
 
 
673
        uuid_dict_returned = iscsi_deploy.do_agent_iscsi_deploy(task,
 
674
                                                                self._client)
 
675
        root_uuid = uuid_dict_returned.get('root uuid')
 
676
 
 
677
        if iscsi_deploy.get_boot_option(node) == "local":
 
678
            efi_system_part_uuid = uuid_dict_returned.get(
 
679
                'efi system partition uuid')
 
680
            self.configure_local_boot(
 
681
                task, root_uuid=root_uuid,
 
682
                efi_system_part_uuid=efi_system_part_uuid)
 
683
        else:
 
684
            # Agent vendorpassthru are made without auth token.
 
685
            # We require auth_token to talk to glance while building boot iso.
 
686
            task.context.auth_token = keystone.get_admin_auth_token()
 
687
            self._configure_vmedia_boot(task, root_uuid)
 
688
 
 
689
        self.reboot_and_finish_deploy(task)