Coverage for nova/virt/driver.py: 80%

369 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-17 15:08 +0000

1# Copyright 2011 Justin Santa Barbara 

2# All Rights Reserved. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); you may 

5# not use this file except in compliance with the License. You may obtain 

6# a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

13# License for the specific language governing permissions and limitations 

14# under the License. 

15 

16""" 

17Driver base-classes: 

18 

19 (Beginning of) the contract that compute drivers must follow, and shared 

20 types that support that contract 

21""" 

22 

23import dataclasses 

24import itertools 

25import sys 

26import time 

27import typing as ty 

28 

29import os_resource_classes as orc 

30import os_traits 

31 

32from oslo_log import log as logging 

33from oslo_utils import importutils 

34 

35import nova.conf 

36import nova.virt.node 

37 

38from nova import context as nova_context 

39from nova.i18n import _ 

40from nova.network import model as network_model 

41from nova import objects 

42from nova import version 

43from nova.virt import event as virtevent 

44 

45CONF = nova.conf.CONF 

46LOG = logging.getLogger(__name__) 

47 

48 

49@dataclasses.dataclass 

50class FlavorMeta: 

51 name: str 

52 memory_mb: int 

53 vcpus: int 

54 root_gb: int 

55 ephemeral_gb: int 

56 extra_specs: dict 

57 swap: int 

58 

59 

60@dataclasses.dataclass 

61class ImageMeta: 

62 id: str 

63 name: str 

64 properties: dict 

65 

66 

67@dataclasses.dataclass 

68class NovaInstanceMeta: 

69 name: str 

70 uuid: str 

71 

72 

73@dataclasses.dataclass 

74class OwnerMeta: 

75 userid: str 

76 username: str 

77 projectid: str 

78 projectname: str 

79 

80 

81@dataclasses.dataclass 

82class InstanceDriverMetadata: 

83 root_type: str 

84 root_id: str 

85 instance_meta: NovaInstanceMeta 

86 owner: OwnerMeta 

87 image: ImageMeta 

88 flavor: FlavorMeta 

89 network_info: network_model.NetworkInfo 

90 nova_package: str = dataclasses.field( 

91 default_factory=version.version_string_with_package) 

92 creation_time: float = dataclasses.field(default_factory=time.time) 

93 

94 

95def get_block_device_info(instance, block_device_mapping): 

96 """Converts block device mappings for an instance to driver format. 

97 

98 Virt drivers expect block device mapping to be presented in the format 

99 of a dict containing the following keys: 

100 

101 - root_device_name: device name of the root disk 

102 - image: An instance of DriverImageBlockDevice or None 

103 - ephemerals: a (potentially empty) list of DriverEphemeralBlockDevice 

104 instances 

105 - swap: An instance of DriverSwapBlockDevice or None 

106 - block_device_mapping: a (potentially empty) list of 

107 DriverVolumeBlockDevice or any of it's more 

108 specialized subclasses. 

109 """ 

110 from nova.virt import block_device as virt_block_device 

111 return { 

112 'root_device_name': instance.root_device_name, 

113 'image': virt_block_device.convert_local_images( 

114 block_device_mapping), 

115 'ephemerals': virt_block_device.convert_ephemerals( 

116 block_device_mapping), 

117 'block_device_mapping': 

118 virt_block_device.convert_all_volumes(*block_device_mapping), 

119 'swap': 

120 virt_block_device.get_swap( 

121 virt_block_device.convert_swap(block_device_mapping)) 

122 } 

123 

124 

125def block_device_info_get_root_device(block_device_info): 

126 block_device_info = block_device_info or {} 

127 return block_device_info.get('root_device_name') 

128 

129 

130def block_device_info_get_swap(block_device_info): 

131 block_device_info = block_device_info or {} 

132 return block_device_info.get('swap') or {'device_name': None, 

133 'swap_size': 0} 

134 

135 

136def swap_is_usable(swap): 

137 return swap and swap['device_name'] and swap['swap_size'] > 0 

138 

139 

140def block_device_info_get_image(block_device_info): 

141 block_device_info = block_device_info or {} 

142 # get_disk_mapping() supports block_device_info=None and thus requires that 

143 # we return a list here. 

144 image = block_device_info.get('image') or [] 

145 return image 

146 

147 

148def block_device_info_get_ephemerals(block_device_info): 

149 block_device_info = block_device_info or {} 

150 ephemerals = block_device_info.get('ephemerals') or [] 

151 return ephemerals 

152 

153 

154def block_device_info_get_mapping(block_device_info): 

155 block_device_info = block_device_info or {} 

156 block_device_mapping = block_device_info.get('block_device_mapping') or [] 

157 return block_device_mapping 

158 

159 

160def block_device_info_get_encrypted_disks( 

161 block_device_info: ty.Mapping[str, ty.Any], 

162) -> ty.List['nova.virt.block_device.DriverBlockDevice']: 

163 block_device_info = block_device_info or {} 

164 

165 # swap is a single device, not a list 

166 swap = block_device_info.get('swap') 

167 swap = [swap] if swap else [] 

168 

169 return [ 

170 driver_bdm for driver_bdm in itertools.chain( 

171 block_device_info.get('image', []), 

172 block_device_info.get('ephemerals', []), 

173 swap, 

174 ) 

175 if driver_bdm.get('encrypted') 

176 ] 

177 

178 

179# NOTE(aspiers): When adding new capabilities, ensure they are 

180# mirrored in ComputeDriver.capabilities, and that the corresponding 

181# values should always be standard traits in os_traits. If something 

182# isn't a standard trait, it doesn't need to be a compute node 

183# capability trait; and if it needs to be a compute node capability 

184# trait, it needs to be (made) standard, and must be prefixed with 

185# "COMPUTE_". 

186CAPABILITY_TRAITS_MAP = { 

187 "supports_attach_interface": os_traits.COMPUTE_NET_ATTACH_INTERFACE, 

188 "supports_device_tagging": os_traits.COMPUTE_DEVICE_TAGGING, 

189 "supports_tagged_attach_interface": 

190 os_traits.COMPUTE_NET_ATTACH_INTERFACE_WITH_TAG, 

191 "supports_tagged_attach_volume": os_traits.COMPUTE_VOLUME_ATTACH_WITH_TAG, 

192 "supports_extend_volume": os_traits.COMPUTE_VOLUME_EXTEND, 

193 "supports_multiattach": os_traits.COMPUTE_VOLUME_MULTI_ATTACH, 

194 "supports_trusted_certs": os_traits.COMPUTE_TRUSTED_CERTS, 

195 "supports_accelerators": os_traits.COMPUTE_ACCELERATORS, 

196 "supports_image_type_aki": os_traits.COMPUTE_IMAGE_TYPE_AKI, 

197 "supports_image_type_ami": os_traits.COMPUTE_IMAGE_TYPE_AMI, 

198 "supports_image_type_ari": os_traits.COMPUTE_IMAGE_TYPE_ARI, 

199 "supports_image_type_iso": os_traits.COMPUTE_IMAGE_TYPE_ISO, 

200 "supports_image_type_qcow2": os_traits.COMPUTE_IMAGE_TYPE_QCOW2, 

201 "supports_image_type_raw": os_traits.COMPUTE_IMAGE_TYPE_RAW, 

202 "supports_image_type_vdi": os_traits.COMPUTE_IMAGE_TYPE_VDI, 

203 "supports_image_type_vhd": os_traits.COMPUTE_IMAGE_TYPE_VHD, 

204 "supports_image_type_vhdx": os_traits.COMPUTE_IMAGE_TYPE_VHDX, 

205 "supports_image_type_vmdk": os_traits.COMPUTE_IMAGE_TYPE_VMDK, 

206 "supports_image_type_ploop": os_traits.COMPUTE_IMAGE_TYPE_PLOOP, 

207 "supports_migrate_to_same_host": os_traits.COMPUTE_SAME_HOST_COLD_MIGRATE, 

208 "supports_bfv_rescue": os_traits.COMPUTE_RESCUE_BFV, 

209 "supports_secure_boot": os_traits.COMPUTE_SECURITY_UEFI_SECURE_BOOT, 

210 "supports_socket_pci_numa_affinity": 

211 os_traits.COMPUTE_SOCKET_PCI_NUMA_AFFINITY, 

212 "supports_remote_managed_ports": os_traits.COMPUTE_REMOTE_MANAGED_PORTS, 

213 "supports_ephemeral_encryption": os_traits.COMPUTE_EPHEMERAL_ENCRYPTION, 

214 "supports_ephemeral_encryption_luks": 

215 os_traits.COMPUTE_EPHEMERAL_ENCRYPTION_LUKS, 

216 "supports_ephemeral_encryption_plain": 

217 os_traits.COMPUTE_EPHEMERAL_ENCRYPTION_PLAIN, 

218 "supports_address_space_passthrough": 

219 os_traits.COMPUTE_ADDRESS_SPACE_PASSTHROUGH, 

220 "supports_address_space_emulated": 

221 os_traits.COMPUTE_ADDRESS_SPACE_EMULATED, 

222 "supports_stateless_firmware": 

223 os_traits.COMPUTE_SECURITY_STATELESS_FIRMWARE, 

224 "supports_virtio_fs": os_traits.COMPUTE_STORAGE_VIRTIO_FS, 

225 "supports_mem_backing_file": os_traits.COMPUTE_MEM_BACKING_FILE, 

226} 

227 

228 

229def _check_image_type_exclude_list(capability, supported): 

230 """Enforce the exclusion list on image_type capabilities. 

231 

232 :param capability: The supports_image_type_foo capability being checked 

233 :param supported: The flag indicating whether the virt driver *can* 

234 support the given image type. 

235 :returns: True if the virt driver *can* support the image type and 

236 if it is not listed in the config to be excluded. 

237 """ 

238 image_type = capability.replace('supports_image_type_', '') 

239 return (supported and 

240 image_type not in CONF.compute.image_type_exclude_list) 

241 

242 

243class ComputeDriver(object): 

244 """Base class for compute drivers. 

245 

246 The interface to this class talks in terms of 'instances' (Amazon EC2 and 

247 internal Nova terminology), by which we mean 'running virtual machine' or 

248 domain (libvirt terminology). 

249 

250 An instance has an ID, which is the identifier chosen by Nova to represent 

251 the instance further up the stack. This is unfortunately also called a 

252 'name' elsewhere. As far as this layer is concerned, 'instance ID' and 

253 'instance name' are synonyms. 

254 

255 Note that the instance ID or name is not human-readable or 

256 customer-controlled -- it's an internal ID chosen by Nova. At the 

257 nova.virt layer, instances do not have human-readable names at all -- such 

258 things are only known higher up the stack. 

259 

260 Most virtualization platforms will also have their own identity schemes, 

261 to uniquely identify a VM or domain. These IDs must stay internal to the 

262 platform-specific layer, and never escape the connection interface. The 

263 platform-specific layer is responsible for keeping track of which instance 

264 ID maps to which platform-specific ID, and vice versa. 

265 

266 Some methods here take an instance of nova.compute.service.Instance. This 

267 is the data structure used by nova.compute to store details regarding an 

268 instance, and pass them into this layer. This layer is responsible for 

269 translating that generic data structure into terms that are specific to the 

270 virtualization platform. 

271 

272 """ 

273 

274 # NOTE(mriedem): When adding new capabilities, consider whether they 

275 # should also be added to CAPABILITY_TRAITS_MAP; if so, any new traits 

276 # must also be added to the os-traits library. 

277 capabilities = { 

278 "has_imagecache": False, 

279 "supports_evacuate": False, 

280 "supports_migrate_to_same_host": False, 

281 "supports_attach_interface": False, 

282 "supports_device_tagging": False, 

283 "supports_tagged_attach_interface": False, 

284 "supports_tagged_attach_volume": False, 

285 "supports_extend_volume": False, 

286 "supports_multiattach": False, 

287 "supports_trusted_certs": False, 

288 "supports_pcpus": False, 

289 "supports_accelerators": False, 

290 "supports_bfv_rescue": False, 

291 "supports_vtpm": False, 

292 "supports_secure_boot": False, 

293 "supports_socket_pci_numa_affinity": False, 

294 "supports_remote_managed_ports": False, 

295 "supports_address_space_passthrough": False, 

296 "supports_address_space_emulated": False, 

297 "supports_virtio_fs": False, 

298 "supports_mem_backing_file": False, 

299 

300 # Ephemeral encryption support flags 

301 "supports_ephemeral_encryption": False, 

302 "supports_ephemeral_encryption_luks": False, 

303 "supports_ephemeral_encryption_plain": False, 

304 

305 # Image type support flags 

306 "supports_image_type_aki": False, 

307 "supports_image_type_ami": False, 

308 "supports_image_type_ari": False, 

309 "supports_image_type_iso": False, 

310 "supports_image_type_qcow2": False, 

311 "supports_image_type_raw": False, 

312 "supports_image_type_vdi": False, 

313 "supports_image_type_vhd": False, 

314 "supports_image_type_vhdx": False, 

315 "supports_image_type_vmdk": False, 

316 "supports_image_type_ploop": False, 

317 } 

318 

319 # Indicates if this driver will rebalance nodes among compute service 

320 # hosts. This is really here for ironic and should not be used by any 

321 # other driver. 

322 rebalances_nodes = False 

323 

324 def __init__(self, virtapi): 

325 self.virtapi = virtapi 

326 self._compute_event_callback = None 

327 

328 def init_host(self, host): 

329 """Initialize anything that is necessary for the driver to function, 

330 including catching up with currently running VM's on the given host. 

331 """ 

332 # TODO(Vek): Need to pass context in for access to auth_token 

333 raise NotImplementedError() 

334 

335 def cleanup_host(self, host): 

336 """Clean up anything that is necessary for the driver gracefully stop, 

337 including ending remote sessions. This is optional. 

338 """ 

339 pass 

340 

341 def get_info(self, instance, use_cache=True): 

342 """Get the current status of an instance. 

343 

344 :param instance: nova.objects.instance.Instance object 

345 :param use_cache: boolean to indicate if the driver should be allowed 

346 to use cached data to return instance status. 

347 This only applies to drivers which cache instance 

348 state information. For drivers that do not use a 

349 cache, this parameter can be ignored. 

350 :returns: An InstanceInfo object 

351 """ 

352 # TODO(Vek): Need to pass context in for access to auth_token 

353 raise NotImplementedError() 

354 

355 @classmethod 

356 def get_instance_driver_metadata( 

357 cls, instance: 'nova.objects.instance.Instance', 

358 network_info: network_model.NetworkInfo 

359 ) -> InstanceDriverMetadata: 

360 """Get driver metadata from instance and network info 

361 

362 :param instance: nova.objects.instance.Instance 

363 :param network_info: instance network information 

364 :returns: InstanceDriverMetadata 

365 """ 

366 

367 instance_name = instance.display_name or instance.uuid 

368 system_meta = instance.system_metadata 

369 instance_meta = NovaInstanceMeta( 

370 str(instance_name), str(instance.uuid)) 

371 owner = OwnerMeta( 

372 userid=instance.user_id, 

373 username=system_meta.get('owner_user_name', 'N/A'), 

374 projectid=instance.project_id, 

375 projectname=system_meta.get('owner_project_name', 'N/A') 

376 ) 

377 flavor = FlavorMeta( 

378 name=instance.flavor.name, 

379 memory_mb=instance.flavor.memory_mb, 

380 vcpus=instance.flavor.vcpus, 

381 ephemeral_gb=instance.flavor.ephemeral_gb, 

382 root_gb=instance.flavor.root_gb, 

383 swap=instance.flavor.swap, 

384 extra_specs=instance.flavor.extra_specs, 

385 ) 

386 image = ImageMeta( 

387 id=instance.image_ref, 

388 name=system_meta.get('image_name'), 

389 properties=instance.image_meta.properties 

390 ) 

391 meta = InstanceDriverMetadata( 

392 instance_meta=instance_meta, 

393 owner=owner, 

394 flavor=flavor, 

395 image=image, 

396 root_type = 'image' if instance.image_ref else 'volume', 

397 root_id = instance.image_ref, 

398 creation_time = time.time(), 

399 network_info=network_info 

400 ) 

401 LOG.debug('InstanceDriverMetadata: %s', meta) 

402 return meta 

403 

404 def get_num_instances(self): 

405 """Return the total number of virtual machines. 

406 

407 Return the number of virtual machines that the hypervisor knows 

408 about. 

409 

410 .. note:: 

411 

412 This implementation works for all drivers, but it is 

413 not particularly efficient. Maintainers of the virt drivers are 

414 encouraged to override this method with something more 

415 efficient. 

416 """ 

417 return len(self.list_instances()) 

418 

419 def instance_exists(self, instance): 

420 """Checks existence of an instance on the host. 

421 

422 :param instance: The instance to lookup 

423 

424 Returns True if an instance with the supplied ID exists on 

425 the host, False otherwise. 

426 

427 .. note:: 

428 

429 This implementation works for all drivers, but it is 

430 not particularly efficient. Maintainers of the virt drivers are 

431 encouraged to override this method with something more 

432 efficient. 

433 """ 

434 try: 

435 return instance.uuid in self.list_instance_uuids() 

436 except NotImplementedError: 

437 return instance.name in self.list_instances() 

438 

439 def list_instances(self): 

440 """Return the names of all the instances known to the virtualization 

441 layer, as a list. 

442 """ 

443 # TODO(Vek): Need to pass context in for access to auth_token 

444 raise NotImplementedError() 

445 

446 def list_instance_uuids(self): 

447 """Return the UUIDS of all the instances known to the virtualization 

448 layer, as a list. 

449 """ 

450 raise NotImplementedError() 

451 

452 def rebuild(self, context, instance, image_meta, injected_files, 

453 admin_password, allocations, bdms, detach_block_devices, 

454 attach_block_devices, network_info=None, 

455 evacuate=False, block_device_info=None, 

456 preserve_ephemeral=False, accel_uuids=None, 

457 reimage_boot_volume=False): 

458 """Destroy and re-make this instance. 

459 

460 A 'rebuild' effectively purges all existing data from the system and 

461 remakes the VM with given 'metadata' and 'personalities'. 

462 

463 This base class method shuts down the VM, detaches all block devices, 

464 then spins up the new VM afterwards. It may be overridden by 

465 hypervisors that need to - e.g. for optimisations, or when the 'VM' 

466 is actually proxied and needs to be held across the shutdown + spin 

467 up steps. 

468 

469 :param context: security context 

470 :param instance: nova.objects.instance.Instance 

471 This function should use the data there to guide 

472 the creation of the new instance. 

473 :param nova.objects.ImageMeta image_meta: 

474 The metadata of the image of the instance. 

475 :param injected_files: User files to inject into instance. 

476 :param admin_password: Administrator password to set in instance. 

477 :param allocations: Information about resources allocated to the 

478 instance via placement, of the form returned by 

479 SchedulerReportClient.get_allocations_for_consumer. 

480 :param bdms: block-device-mappings to use for rebuild 

481 :param detach_block_devices: function to detach block devices. See 

482 nova.compute.manager.ComputeManager:_rebuild_default_impl for 

483 usage. 

484 :param attach_block_devices: function to attach block devices. See 

485 nova.compute.manager.ComputeManager:_rebuild_default_impl for 

486 usage. 

487 :param network_info: instance network information 

488 :param evacuate: True if the instance is being recreated on a new 

489 hypervisor - all the cleanup of old state is skipped. 

490 :param block_device_info: Information about block devices to be 

491 attached to the instance. 

492 :param preserve_ephemeral: True if the default ephemeral storage 

493 partition must be preserved on rebuild 

494 :param accel_uuids: Accelerator UUIDs. 

495 :param reimage_boot_volume: Re-image the volume backed instance. 

496 """ 

497 raise NotImplementedError() 

498 

499 def prepare_for_spawn(self, instance): 

500 """Prepare to spawn instance. 

501 

502 Perform any pre-flight checks, tagging, etc. that the virt driver 

503 must perform before executing the spawn process for a new instance. 

504 

505 :param instance: nova.objects.instance.Instance 

506 This function should use the data there to guide 

507 the creation of the new instance. 

508 """ 

509 pass 

510 

511 def failed_spawn_cleanup(self, instance): 

512 """Cleanup from the instance spawn. 

513 

514 Perform any hypervisor clean-up required should the spawn operation 

515 fail, such as the removal of tags that were added during the 

516 prepare_for_spawn method. 

517 

518 This method should be idempotent. 

519 

520 :param instance: nova.objects.instance.Instance 

521 This function should use the data there to guide 

522 the creation of the new instance. 

523 

524 """ 

525 pass 

526 

527 def spawn(self, context, instance, image_meta, injected_files, 

528 admin_password, allocations, network_info=None, 

529 block_device_info=None, power_on=True, accel_info=None): 

530 """Create a new instance/VM/domain on the virtualization platform. 

531 

532 Once this successfully completes, the instance should be 

533 running (power_state.RUNNING) if ``power_on`` is True, else the 

534 instance should be stopped (power_state.SHUTDOWN). 

535 

536 If this fails, any partial instance should be completely 

537 cleaned up, and the virtualization platform should be in the state 

538 that it was before this call began. 

539 

540 :param context: security context 

541 :param instance: nova.objects.instance.Instance 

542 This function should use the data there to guide 

543 the creation of the new instance. 

544 :param nova.objects.ImageMeta image_meta: 

545 The metadata of the image of the instance. 

546 :param injected_files: User files to inject into instance. 

547 :param admin_password: Administrator password to set in instance. 

548 :param allocations: Information about resources allocated to the 

549 instance via placement, of the form returned by 

550 SchedulerReportClient.get_allocations_for_consumer. 

551 :param network_info: instance network information 

552 :param block_device_info: Information about block devices to be 

553 attached to the instance. 

554 :param power_on: True if the instance should be powered on, False 

555 otherwise 

556 :param arqs: List of bound accelerator requests for this instance. 

557 [ 

558 {'uuid': $arq_uuid, 

559 'device_profile_name': $dp_name, 

560 'device_profile_group_id': $dp_request_group_index, 

561 'state': 'Bound', 

562 'device_rp_uuid': $resource_provider_uuid, 

563 'hostname': $host_nodename, 

564 'instance_uuid': $instance_uuid, 

565 'attach_handle_info': { # PCI bdf 

566 'bus': '0c', 'device': '0', 'domain': '0000', 'function': '0'}, 

567 'attach_handle_type': 'PCI' 

568 # or 'TEST_PCI' for Cyborg fake driver 

569 } 

570 ] 

571 Also doc'd in nova/accelerator/cyborg.py::get_arqs_for_instance() 

572 """ 

573 raise NotImplementedError() 

574 

575 def destroy(self, context, instance, network_info, block_device_info=None, 

576 destroy_disks=True, destroy_secrets=True): 

577 """Destroy the specified instance from the Hypervisor. 

578 

579 If the instance is not found (for example if networking failed), this 

580 function should still succeed. It's probably a good idea to log a 

581 warning in that case. 

582 

583 :param context: security context 

584 :param instance: Instance object as returned by DB layer. 

585 :param network_info: instance network information 

586 :param block_device_info: Information about block devices that should 

587 be detached from the instance. 

588 :param destroy_disks: Indicates if disks should be destroyed 

589 :param destroy_secrets: Indicates if secrets should be destroyed 

590 """ 

591 raise NotImplementedError() 

592 

593 def cleanup(self, context, instance, network_info, block_device_info=None, 

594 destroy_disks=True, migrate_data=None, destroy_vifs=True, 

595 destroy_secrets=True): 

596 """Cleanup the instance resources . 

597 

598 Instance should have been destroyed from the Hypervisor before calling 

599 this method. 

600 

601 :param context: security context 

602 :param instance: Instance object as returned by DB layer. 

603 :param network_info: instance network information 

604 :param block_device_info: Information about block devices that should 

605 be detached from the instance. 

606 :param destroy_disks: Indicates if disks should be destroyed 

607 :param migrate_data: implementation specific params 

608 :param destroy_vifs: Indicates if vifs should be unplugged 

609 :param destroy_secrets: Indicates if secrets should be destroyed 

610 """ 

611 raise NotImplementedError() 

612 

613 def reboot(self, context, instance, network_info, reboot_type, 

614 block_device_info=None, bad_volumes_callback=None, 

615 accel_info=None, share_info=None): 

616 """Reboot the specified instance. 

617 

618 After this is called successfully, the instance's state 

619 goes back to power_state.RUNNING. The virtualization 

620 platform should ensure that the reboot action has completed 

621 successfully even in cases in which the underlying domain/vm 

622 is paused or halted/stopped. 

623 

624 :param instance: nova.objects.instance.Instance 

625 :param network_info: instance network information 

626 :param reboot_type: Either a HARD or SOFT reboot 

627 :param block_device_info: Info pertaining to attached volumes 

628 :param bad_volumes_callback: Function to handle any bad volumes 

629 encountered 

630 :param accel_info: List of accelerator request dicts. The exact 

631 data struct is doc'd in nova/virt/driver.py::spawn(). 

632 """ 

633 raise NotImplementedError() 

634 

635 def get_console_output(self, context, instance): 

636 """Get console output for an instance 

637 

638 :param context: security context 

639 :param instance: nova.objects.instance.Instance 

640 """ 

641 raise NotImplementedError() 

642 

643 def get_vnc_console(self, context, instance): 

644 """Get connection info for a vnc console. 

645 

646 :param context: security context 

647 :param instance: nova.objects.instance.Instance 

648 

649 :returns: an instance of console.type.ConsoleVNC 

650 """ 

651 raise NotImplementedError() 

652 

653 def get_spice_console(self, context, instance): 

654 """Get connection info for a spice console. 

655 

656 :param context: security context 

657 :param instance: nova.objects.instance.Instance 

658 

659 :returns: an instance of console.type.ConsoleSpice 

660 """ 

661 raise NotImplementedError() 

662 

663 def get_serial_console(self, context, instance): 

664 """Get connection info for a serial console. 

665 

666 :param context: security context 

667 :param instance: nova.objects.instance.Instance 

668 

669 :returns: an instance of console.type.ConsoleSerial 

670 """ 

671 raise NotImplementedError() 

672 

673 def get_mks_console(self, context, instance): 

674 """Get connection info for a MKS console. 

675 

676 :param context: security context 

677 :param instance: nova.objects.instance.Instance 

678 

679 :returns an instance of console.type.ConsoleMKS 

680 """ 

681 raise NotImplementedError() 

682 

683 def get_diagnostics(self, instance): 

684 """Return diagnostics data about the given instance. 

685 

686 :param nova.objects.instance.Instance instance: 

687 The instance to which the diagnostic data should be returned. 

688 

689 :return: Has a big overlap to the return value of the newer interface 

690 :func:`get_instance_diagnostics` 

691 :rtype: dict 

692 """ 

693 # TODO(Vek): Need to pass context in for access to auth_token 

694 raise NotImplementedError() 

695 

696 def get_instance_diagnostics(self, instance): 

697 """Return diagnostics data about the given instance. 

698 

699 :param nova.objects.instance.Instance instance: 

700 The instance to which the diagnostic data should be returned. 

701 

702 :return: Has a big overlap to the return value of the older interface 

703 :func:`get_diagnostics` 

704 :rtype: nova.virt.diagnostics.Diagnostics 

705 """ 

706 raise NotImplementedError() 

707 

708 def get_all_volume_usage(self, context, compute_host_bdms): 

709 """Return usage info for volumes attached to vms on 

710 a given host.- 

711 """ 

712 raise NotImplementedError() 

713 

714 def get_host_ip_addr(self): 

715 """Retrieves the IP address of the host running compute service 

716 """ 

717 # TODO(Vek): Need to pass context in for access to auth_token 

718 raise NotImplementedError() 

719 

720 def attach_volume(self, context, connection_info, instance, mountpoint, 

721 disk_bus=None, device_type=None, encryption=None): 

722 """Attach the disk to the instance at mountpoint using info. 

723 

724 :raises TooManyDiskDevices: if the maximum allowed devices to attach 

725 to a single instance is exceeded. 

726 """ 

727 raise NotImplementedError() 

728 

729 def detach_volume(self, context, connection_info, instance, mountpoint, 

730 encryption=None): 

731 """Detach the disk attached to the instance.""" 

732 raise NotImplementedError() 

733 

734 def swap_volume(self, context, old_connection_info, new_connection_info, 

735 instance, mountpoint, resize_to): 

736 """Replace the volume attached to the given `instance`. 

737 

738 :param context: The request context. 

739 :param dict old_connection_info: 

740 The volume for this connection gets detached from the given 

741 `instance`. 

742 :param dict new_connection_info: 

743 The volume for this connection gets attached to the given 

744 'instance'. 

745 :param nova.objects.instance.Instance instance: 

746 The instance whose volume gets replaced by another one. 

747 :param str mountpoint: 

748 The mountpoint in the instance where the volume for 

749 `old_connection_info` is attached to. 

750 :param int resize_to: 

751 If the new volume is larger than the old volume, it gets resized 

752 to the given size (in Gigabyte) of `resize_to`. 

753 

754 :return: None 

755 """ 

756 raise NotImplementedError() 

757 

758 def extend_volume(self, context, connection_info, instance, 

759 requested_size): 

760 """Extend the disk attached to the instance. 

761 

762 :param context: The request context. 

763 :param dict connection_info: 

764 The connection for the extended volume. 

765 :param nova.objects.instance.Instance instance: 

766 The instance whose volume gets extended. 

767 :param int requested_size 

768 The requested new size of the volume in bytes 

769 

770 :return: None 

771 """ 

772 raise NotImplementedError() 

773 

774 def prepare_networks_before_block_device_mapping(self, instance, 

775 network_info): 

776 """Prepare networks before the block devices are mapped to instance. 

777 

778 Drivers who need network information for block device preparation can 

779 do some network preparation necessary for block device preparation. 

780 

781 :param nova.objects.instance.Instance instance: 

782 The instance whose networks are prepared. 

783 :param nova.network.model.NetworkInfoAsyncWrapper network_info: 

784 The network information of the given `instance`. 

785 """ 

786 pass 

787 

788 def clean_networks_preparation(self, instance, network_info): 

789 """Clean networks preparation when block device mapping is failed. 

790 

791 Drivers who need network information for block device preparaion should 

792 clean the preparation when block device mapping is failed. 

793 

794 :param nova.objects.instance.Instance instance: 

795 The instance whose networks are prepared. 

796 :param nova.network.model.NetworkInfoAsyncWrapper network_info: 

797 The network information of the given `instance`. 

798 """ 

799 pass 

800 

801 def attach_interface(self, context, instance, image_meta, vif): 

802 """Use hotplug to add a network interface to a running instance. 

803 

804 The counter action to this is :func:`detach_interface`. 

805 

806 :param context: The request context. 

807 :param nova.objects.instance.Instance instance: 

808 The instance which will get an additional network interface. 

809 :param nova.objects.ImageMeta image_meta: 

810 The metadata of the image of the instance. 

811 :param nova.network.model.VIF vif: 

812 The object which has the information about the interface to attach. 

813 

814 :raise nova.exception.NovaException: If the attach fails. 

815 

816 :return: None 

817 """ 

818 raise NotImplementedError() 

819 

820 def detach_interface(self, context, instance, vif): 

821 """Use hotunplug to remove a network interface from a running instance. 

822 

823 The counter action to this is :func:`attach_interface`. 

824 

825 :param context: The request context. 

826 :param nova.objects.instance.Instance instance: 

827 The instance which gets a network interface removed. 

828 :param nova.network.model.VIF vif: 

829 The object which has the information about the interface to detach. 

830 

831 :raise nova.exception.NovaException: If the detach fails. 

832 

833 :return: None 

834 """ 

835 raise NotImplementedError() 

836 

837 def migrate_disk_and_power_off(self, context, instance, dest, 

838 flavor, network_info, 

839 block_device_info=None, 

840 timeout=0, retry_interval=0): 

841 """Transfers the disk of a running instance in multiple phases, turning 

842 off the instance before the end. 

843 

844 :param nova.objects.instance.Instance instance: 

845 The instance whose disk should be migrated. 

846 :param str dest: 

847 The IP address of the destination host. 

848 :param nova.objects.flavor.Flavor flavor: 

849 The flavor of the instance whose disk get migrated. 

850 :param nova.network.model.NetworkInfo network_info: 

851 The network information of the given `instance`. 

852 :param dict block_device_info: 

853 Information about the block devices. 

854 :param int timeout: 

855 The time in seconds to wait for the guest OS to shutdown. 

856 :param int retry_interval: 

857 How often to signal guest while waiting for it to shutdown. 

858 

859 :return: A list of disk information dicts in JSON format. 

860 :rtype: str 

861 """ 

862 raise NotImplementedError() 

863 

864 def snapshot(self, context, instance, image_id, update_task_state): 

865 """Snapshots the specified instance. 

866 

867 :param context: security context 

868 :param instance: nova.objects.instance.Instance 

869 :param image_id: Reference to a pre-created image that will 

870 hold the snapshot. 

871 :param update_task_state: Callback function to update the task_state 

872 on the instance while the snapshot operation progresses. The 

873 function takes a task_state argument and an optional 

874 expected_task_state kwarg which defaults to 

875 nova.compute.task_states.IMAGE_SNAPSHOT. See 

876 nova.objects.instance.Instance.save for expected_task_state usage. 

877 """ 

878 raise NotImplementedError() 

879 

880 def finish_migration(self, context, migration, instance, disk_info, 

881 network_info, image_meta, resize_instance, 

882 allocations, block_device_info=None, power_on=True): 

883 """Completes a resize/migration. 

884 

885 :param context: the context for the migration/resize 

886 :param migration: the migrate/resize information 

887 :param instance: nova.objects.instance.Instance being migrated/resized 

888 :param disk_info: the newly transferred disk information 

889 :param network_info: instance network information 

890 :param nova.objects.ImageMeta image_meta: 

891 The metadata of the image of the instance. 

892 :param resize_instance: True if the instance is being resized, 

893 False otherwise 

894 :param allocations: Information about resources allocated to the 

895 instance via placement, of the form returned by 

896 SchedulerReportClient.get_allocs_for_consumer. 

897 :param block_device_info: instance volume block device info 

898 :param power_on: True if the instance should be powered on, False 

899 otherwise 

900 """ 

901 raise NotImplementedError() 

902 

903 def confirm_migration(self, context, migration, instance, network_info): 

904 """Confirms a resize/migration, destroying the source VM. 

905 

906 :param instance: nova.objects.instance.Instance 

907 """ 

908 raise NotImplementedError() 

909 

910 def finish_revert_migration(self, context, instance, network_info, 

911 migration, block_device_info=None, 

912 power_on=True): 

913 """Finish reverting a resize/migration. 

914 

915 :param context: the context for the finish_revert_migration 

916 :param instance: nova.objects.instance.Instance being migrated/resized 

917 :param network_info: instance network information 

918 :param migration: nova.objects.Migration for the migration 

919 :param block_device_info: instance volume block device info 

920 :param power_on: True if the instance should be powered on, False 

921 otherwise 

922 """ 

923 raise NotImplementedError() 

924 

925 def pause(self, instance): 

926 """Pause the given instance. 

927 

928 A paused instance doesn't use CPU cycles of the host anymore. The 

929 state of the VM could be stored in the memory or storage space of the 

930 host, depending on the underlying hypervisor technology. 

931 A "stronger" version of `pause` is :func:'suspend'. 

932 The counter action for `pause` is :func:`unpause`. 

933 

934 :param nova.objects.instance.Instance instance: 

935 The instance which should be paused. 

936 

937 :return: None 

938 """ 

939 # TODO(Vek): Need to pass context in for access to auth_token 

940 raise NotImplementedError() 

941 

942 def unpause(self, instance): 

943 """Unpause the given paused instance. 

944 

945 The paused instance gets unpaused and will use CPU cycles of the 

946 host again. The counter action for 'unpause' is :func:`pause`. 

947 Depending on the underlying hypervisor technology, the guest has the 

948 same state as before the 'pause'. 

949 

950 :param nova.objects.instance.Instance instance: 

951 The instance which should be unpaused. 

952 

953 :return: None 

954 """ 

955 # TODO(Vek): Need to pass context in for access to auth_token 

956 raise NotImplementedError() 

957 

958 def suspend(self, context, instance): 

959 """Suspend the specified instance. 

960 

961 A suspended instance doesn't use CPU cycles or memory of the host 

962 anymore. The state of the instance could be persisted on the host 

963 and allocate storage space this way. A "softer" way of `suspend` 

964 is :func:`pause`. The counter action for `suspend` is :func:`resume`. 

965 

966 :param nova.context.RequestContext context: 

967 The context for the suspend. 

968 :param nova.objects.instance.Instance instance: 

969 The instance to suspend. 

970 

971 :return: None 

972 """ 

973 raise NotImplementedError() 

974 

975 def resume( 

976 self, 

977 context, 

978 instance, 

979 network_info, 

980 block_device_info=None, 

981 share_info=None 

982 ): 

983 """resume the specified suspended instance. 

984 

985 The suspended instance gets resumed and will use CPU cycles and memory 

986 of the host again. The counter action for 'resume' is :func:`suspend`. 

987 Depending on the underlying hypervisor technology, the guest has the 

988 same state as before the 'suspend'. 

989 

990 :param nova.context.RequestContext context: 

991 The context for the resume. 

992 :param nova.objects.instance.Instance instance: 

993 The suspended instance to resume. 

994 :param nova.network.model.NetworkInfo network_info: 

995 Necessary network information for the resume. 

996 :param dict block_device_info: 

997 Instance volume block device info. 

998 :param nova.objects.share_mapping.ShareMapingList share_info 

999 optional list of share_mapping 

1000 

1001 :return: None 

1002 """ 

1003 raise NotImplementedError() 

1004 

1005 def resume_state_on_host_boot(self, context, instance, network_info, 

1006 share_info, block_device_info=None): 

1007 """resume guest state when a host is booted. 

1008 

1009 :param instance: nova.objects.instance.Instance 

1010 :param nova.network.model.NetworkInfo network_info: 

1011 Necessary network information for the resume. 

1012 :param share_info: a ShareMappingList containing the attached shares. 

1013 :param dict block_device_info: 

1014 The block device mapping of the instance. 

1015 """ 

1016 raise NotImplementedError() 

1017 

1018 def rescue(self, context, instance, network_info, image_meta, 

1019 rescue_password, block_device_info, share_info): 

1020 """Rescue the specified instance. 

1021 

1022 :param nova.context.RequestContext context: 

1023 The context for the rescue. 

1024 :param nova.objects.instance.Instance instance: 

1025 The instance being rescued. 

1026 :param nova.network.model.NetworkInfo network_info: 

1027 Necessary network information for the resume. 

1028 :param nova.objects.ImageMeta image_meta: 

1029 The metadata of the image of the instance. 

1030 :param rescue_password: new root password to set for rescue. 

1031 :param dict block_device_info: 

1032 The block device mapping of the instance. 

1033 :param nova.objects.share_mapping.ShareMapingList share_info 

1034 list of share_mapping 

1035 """ 

1036 raise NotImplementedError() 

1037 

1038 def unrescue( 

1039 self, 

1040 context: nova_context.RequestContext, 

1041 instance: 'objects.Instance', 

1042 ): 

1043 """Unrescue the specified instance. 

1044 

1045 :param context: security context 

1046 :param instance: nova.objects.instance.Instance 

1047 """ 

1048 raise NotImplementedError() 

1049 

1050 def power_off(self, instance, timeout=0, retry_interval=0): 

1051 """Power off the specified instance. 

1052 

1053 :param instance: nova.objects.instance.Instance 

1054 :param timeout: time to wait for GuestOS to shutdown 

1055 :param retry_interval: How often to signal guest while 

1056 waiting for it to shutdown 

1057 """ 

1058 raise NotImplementedError() 

1059 

1060 def power_on(self, context, instance, network_info, 

1061 block_device_info=None, accel_info=None, share_info=None): 

1062 """Power on the specified instance. 

1063 

1064 :param context: security context 

1065 :param instance: nova.objects.instance.Instance 

1066 :param network_info: instance network information 

1067 :param block_device_info: instance volume block device info 

1068 :param accel_info: List of accelerator request dicts. The exact 

1069 data struct is doc'd in nova/virt/driver.py::spawn(). 

1070 :param share_info: a ShareMappingList containing the attached shares. 

1071 """ 

1072 raise NotImplementedError() 

1073 

1074 def mount_share(self, context, instance, share_mapping): 

1075 """Mount a manila share to the compute node. 

1076 

1077 :param context: security context 

1078 :param instance: nova.objects.instance.Instance 

1079 :param share_mapping: nova.objects.share_mapping.ShareMapping object 

1080 that define the share 

1081 """ 

1082 raise NotImplementedError() 

1083 

1084 def umount_share(self, context, instance, share_mapping): 

1085 """Unmount a manila share from the compute node. 

1086 

1087 :param context: security context 

1088 :param instance: nova.objects.instance.Instance 

1089 :param share_mapping: nova.objects.share_mapping.ShareMapping object 

1090 that define the share 

1091 :returns: True if the mountpoint is still in used by another instance 

1092 """ 

1093 raise NotImplementedError() 

1094 

1095 def power_update_event(self, instance, target_power_state): 

1096 """Update power, vm and task states of the specified instance. 

1097 

1098 Note that the driver is expected to set the task_state of the 

1099 instance back to None. 

1100 

1101 :param instance: nova.objects.instance.Instance 

1102 :param target_power_state: The desired target power state for the 

1103 instance; possible values are "POWER_ON" 

1104 and "POWER_OFF". 

1105 """ 

1106 raise NotImplementedError() 

1107 

1108 def trigger_crash_dump(self, instance): 

1109 """Trigger crash dump mechanism on the given instance. 

1110 

1111 Stalling instances can be triggered to dump the crash data. How the 

1112 guest OS reacts in details, depends on the configuration of it. 

1113 

1114 :param nova.objects.instance.Instance instance: 

1115 The instance where the crash dump should be triggered. 

1116 

1117 :return: None 

1118 """ 

1119 raise NotImplementedError() 

1120 

1121 def soft_delete(self, instance): 

1122 """Soft delete the specified instance. 

1123 

1124 A soft-deleted instance doesn't allocate any resources anymore, but is 

1125 still available as a database entry. The counter action :func:`restore` 

1126 uses the database entry to create a new instance based on that. 

1127 

1128 :param nova.objects.instance.Instance instance: 

1129 The instance to soft-delete. 

1130 

1131 :return: None 

1132 """ 

1133 raise NotImplementedError() 

1134 

1135 def restore(self, instance): 

1136 """Restore the specified soft-deleted instance. 

1137 

1138 The restored instance will be automatically booted. The counter action 

1139 for `restore` is :func:`soft_delete`. 

1140 

1141 :param nova.objects.instance.Instance instance: 

1142 The soft-deleted instance which should be restored from the 

1143 soft-deleted data. 

1144 

1145 :return: None 

1146 """ 

1147 raise NotImplementedError() 

1148 

1149 @staticmethod 

1150 def _get_reserved_host_disk_gb_from_config(): 

1151 import nova.compute.utils as compute_utils # avoid circular import 

1152 return compute_utils.convert_mb_to_ceil_gb(CONF.reserved_host_disk_mb) 

1153 

1154 @staticmethod 

1155 def _get_allocation_ratios(inventory): 

1156 """Get the cpu/ram/disk allocation ratios for the given inventory. 

1157 

1158 This utility method is used to get the inventory allocation ratio 

1159 for VCPU, MEMORY_MB and DISK_GB resource classes based on the following 

1160 precedence: 

1161 

1162 * Use ``[DEFAULT]/*_allocation_ratio`` if set - this overrides 

1163 everything including externally set allocation ratios on the 

1164 inventory via the placement API 

1165 * Use ``[DEFAULT]/initial_*_allocation_ratio`` if a value does not 

1166 exist for a given resource class in the ``inventory`` dict 

1167 * Use what is already in the ``inventory`` dict for the allocation 

1168 ratio if the above conditions are false 

1169 

1170 :param inventory: dict, keyed by resource class, of inventory 

1171 information. 

1172 :returns: Return a dict, keyed by resource class, of allocation ratio 

1173 """ 

1174 keys = {'cpu': orc.VCPU, 

1175 'ram': orc.MEMORY_MB, 

1176 'disk': orc.DISK_GB} 

1177 result = {} 

1178 for res, rc in keys.items(): 

1179 attr = '%s_allocation_ratio' % res 

1180 conf_ratio = getattr(CONF, attr) 

1181 if conf_ratio: 

1182 result[rc] = conf_ratio 

1183 elif rc not in inventory: 

1184 result[rc] = getattr(CONF, 'initial_%s' % attr) 

1185 else: 

1186 result[rc] = inventory[rc]['allocation_ratio'] 

1187 return result 

1188 

1189 def update_provider_tree(self, provider_tree, nodename, allocations=None): 

1190 """Update a ProviderTree object with current resource provider and 

1191 inventory information. 

1192 

1193 When this method returns, provider_tree should represent the correct 

1194 hierarchy of nested resource providers associated with this compute 

1195 node, as well as the inventory, aggregates, and traits associated with 

1196 those resource providers. 

1197 

1198 Implementers of this interface are expected to set ``allocation_ratio`` 

1199 and ``reserved`` values for inventory records, which may be based on 

1200 configuration options, e.g. ``[DEFAULT]/cpu_allocation_ratio``, 

1201 depending on the driver and resource class. If not provided, allocation 

1202 ratio defaults to 1.0 and reserved defaults to 0 in placement. 

1203 

1204 :note: Renaming the root provider (by deleting it from provider_tree 

1205 and re-adding it with a different name) is not supported at this time. 

1206 

1207 See the developer reference documentation for more details: 

1208 

1209 https://docs.openstack.org/nova/latest/reference/update-provider-tree.html # noqa 

1210 

1211 :param nova.compute.provider_tree.ProviderTree provider_tree: 

1212 A nova.compute.provider_tree.ProviderTree object representing all 

1213 the providers in the tree associated with the compute node, and any 

1214 sharing providers (those with the ``MISC_SHARES_VIA_AGGREGATE`` 

1215 trait) associated via aggregate with any of those providers (but 

1216 not *their* tree- or aggregate-associated providers), as currently 

1217 known by placement. This object is fully owned by the 

1218 update_provider_tree method, and can therefore be modified without 

1219 locking/concurrency considerations. In other words, the parameter 

1220 is passed *by reference* with the expectation that the virt driver 

1221 will modify the object. Note, however, that it may contain 

1222 providers not directly owned/controlled by the compute host. Care 

1223 must be taken not to remove or modify such providers inadvertently. 

1224 In addition, providers may be associated with traits and/or 

1225 aggregates maintained by outside agents. The 

1226 `update_provider_tree`` method must therefore also be careful only 

1227 to add/remove traits/aggregates it explicitly controls. 

1228 :param nodename: 

1229 String name of the compute node (i.e. 

1230 ComputeNode.hypervisor_hostname) for which the caller is requesting 

1231 updated provider information. Drivers may use this to help identify 

1232 the compute node provider in the ProviderTree. Drivers managing 

1233 more than one node (e.g. ironic) may also use it as a cue to 

1234 indicate which node is being processed by the caller. 

1235 :param allocations: 

1236 Dict of allocation data of the form: 

1237 { $CONSUMER_UUID: { 

1238 # The shape of each "allocations" dict below is identical 

1239 # to the return from GET /allocations/{consumer_uuid} 

1240 "allocations": { 

1241 $RP_UUID: { 

1242 "generation": $RP_GEN, 

1243 "resources": { 

1244 $RESOURCE_CLASS: $AMOUNT, 

1245 ... 

1246 }, 

1247 }, 

1248 ... 

1249 }, 

1250 "project_id": $PROJ_ID, 

1251 "user_id": $USER_ID, 

1252 "consumer_generation": $CONSUMER_GEN, 

1253 }, 

1254 ... 

1255 } 

1256 If None, and the method determines that any inventory needs to be 

1257 moved (from one provider to another and/or to a different resource 

1258 class), the ReshapeNeeded exception must be raised. Otherwise, this 

1259 dict must be edited in place to indicate the desired final state of 

1260 allocations. Drivers should *only* edit allocation records for 

1261 providers whose inventories are being affected by the reshape 

1262 operation. 

1263 :raises ReshapeNeeded: If allocations is None and any inventory needs 

1264 to be moved from one provider to another and/or to a different 

1265 resource class. 

1266 :raises: ReshapeFailed if the requested tree reshape fails for 

1267 whatever reason. 

1268 """ 

1269 raise NotImplementedError() 

1270 

1271 def capabilities_as_traits(self): 

1272 """Returns this driver's capabilities dict where the keys are traits 

1273 

1274 Traits can only be standard compute capabilities traits from 

1275 the os-traits library. 

1276 

1277 :returns: dict, keyed by trait, of this driver's capabilities where the 

1278 values are booleans indicating if the driver supports the trait 

1279 

1280 """ 

1281 traits = {} 

1282 for capability, supported in self.capabilities.items(): 

1283 if capability.startswith('supports_image_type_'): 

1284 supported = _check_image_type_exclude_list(capability, 

1285 supported) 

1286 

1287 if capability in CAPABILITY_TRAITS_MAP: 

1288 traits[CAPABILITY_TRAITS_MAP[capability]] = supported 

1289 

1290 return traits 

1291 

1292 def get_available_resource(self, nodename): 

1293 """Retrieve resource information. 

1294 

1295 This method is called when nova-compute launches, and 

1296 as part of a periodic task that records the results in the DB. 

1297 

1298 :param nodename: 

1299 node which the caller want to get resources from 

1300 a driver that manages only one node can safely ignore this 

1301 :returns: Dictionary describing resources 

1302 """ 

1303 raise NotImplementedError() 

1304 

1305 def is_node_deleted(self, nodename): 

1306 """Check this compute node has been deleted. 

1307 

1308 This method is called when the compute manager notices that a 

1309 node that was previously reported as available is no longer 

1310 available. 

1311 In this case, we need to know if the node has actually been 

1312 deleted, or if it is simply no longer managed by this 

1313 nova-compute service. 

1314 If True is returned, the database and placement records will 

1315 be removed. 

1316 

1317 :param nodename: 

1318 node which the caller wants to check if its deleted 

1319 :returns: True if the node is safe to delete 

1320 """ 

1321 # For most driver, compute nodes should never get deleted 

1322 # during a periodic task, they are only deleted via the API 

1323 return False 

1324 

1325 def pre_live_migration(self, context, instance, block_device_info, 

1326 network_info, disk_info, migrate_data): 

1327 """Prepare an instance for live migration 

1328 

1329 :param context: security context 

1330 :param instance: nova.objects.instance.Instance object 

1331 :param block_device_info: instance block device information 

1332 :param network_info: instance network information 

1333 :param disk_info: instance disk information 

1334 :param migrate_data: a LiveMigrateData object 

1335 :returns: migrate_data modified by the driver 

1336 :raises TooManyDiskDevices: if the maximum allowed devices to attach 

1337 to a single instance is exceeded. 

1338 """ 

1339 raise NotImplementedError() 

1340 

1341 def live_migration(self, context, instance, dest, 

1342 post_method, recover_method, block_migration=False, 

1343 migrate_data=None): 

1344 """Live migration of an instance to another host. 

1345 

1346 :param context: security context 

1347 :param instance: 

1348 nova.db.main.models.Instance object 

1349 instance object that is migrated. 

1350 :param dest: destination host 

1351 :param post_method: 

1352 post operation method. 

1353 expected nova.compute.manager._post_live_migration. 

1354 :param recover_method: 

1355 recovery method when any exception occurs. 

1356 expected nova.compute.manager._rollback_live_migration. 

1357 :param block_migration: if true, migrate VM disk. 

1358 :param migrate_data: a LiveMigrateData object 

1359 

1360 """ 

1361 raise NotImplementedError() 

1362 

1363 def live_migration_force_complete(self, instance): 

1364 """Force live migration to complete 

1365 

1366 :param instance: Instance being live migrated 

1367 

1368 """ 

1369 raise NotImplementedError() 

1370 

1371 def live_migration_abort(self, instance): 

1372 """Abort an in-progress live migration. 

1373 

1374 :param instance: instance that is live migrating 

1375 

1376 """ 

1377 raise NotImplementedError() 

1378 

1379 def rollback_live_migration_at_source(self, context, instance, 

1380 migrate_data): 

1381 """Clean up source node after a failed live migration. 

1382 

1383 :param context: security context 

1384 :param instance: instance object that was being migrated 

1385 :param migrate_data: a LiveMigrateData object 

1386 """ 

1387 pass 

1388 

1389 def rollback_live_migration_at_destination(self, context, instance, 

1390 network_info, 

1391 block_device_info, 

1392 destroy_disks=True, 

1393 migrate_data=None): 

1394 """Clean up destination node after a failed live migration. 

1395 

1396 :param context: security context 

1397 :param instance: instance object that was being migrated 

1398 :param network_info: instance network information 

1399 :param block_device_info: instance block device information 

1400 :param destroy_disks: 

1401 if true, destroy disks at destination during cleanup 

1402 :param migrate_data: a LiveMigrateData object 

1403 

1404 """ 

1405 raise NotImplementedError() 

1406 

1407 def post_live_migration(self, context, instance, block_device_info, 

1408 migrate_data=None): 

1409 """Post operation of live migration at source host. 

1410 

1411 :param context: security context 

1412 :instance: instance object that was migrated 

1413 :block_device_info: instance block device information 

1414 :param migrate_data: a LiveMigrateData object 

1415 """ 

1416 pass 

1417 

1418 def post_live_migration_at_source(self, context, instance, network_info): 

1419 """Unplug VIFs from networks at source. 

1420 

1421 :param context: security context 

1422 :param instance: instance object reference 

1423 :param network_info: instance network information 

1424 """ 

1425 raise NotImplementedError(_("Hypervisor driver does not support " 

1426 "post_live_migration_at_source method")) 

1427 

1428 def post_live_migration_at_destination(self, context, instance, 

1429 network_info, 

1430 block_migration=False, 

1431 block_device_info=None): 

1432 """Post operation of live migration at destination host. 

1433 

1434 :param context: security context 

1435 :param instance: instance object that is migrated 

1436 :param network_info: instance network information 

1437 :param block_migration: if true, post operation of block_migration. 

1438 """ 

1439 raise NotImplementedError() 

1440 

1441 def check_instance_shared_storage_local(self, context, instance): 

1442 """Check if instance files located on shared storage. 

1443 

1444 This runs check on the destination host, and then calls 

1445 back to the source host to check the results. 

1446 

1447 :param context: security context 

1448 :param instance: nova.objects.instance.Instance object 

1449 """ 

1450 raise NotImplementedError() 

1451 

1452 def check_instance_shared_storage_remote(self, context, data): 

1453 """Check if instance files located on shared storage. 

1454 

1455 :param context: security context 

1456 :param data: result of check_instance_shared_storage_local 

1457 """ 

1458 raise NotImplementedError() 

1459 

1460 def check_instance_shared_storage_cleanup(self, context, data): 

1461 """Do cleanup on host after check_instance_shared_storage calls 

1462 

1463 :param context: security context 

1464 :param data: result of check_instance_shared_storage_local 

1465 """ 

1466 pass 

1467 

1468 def check_can_live_migrate_destination(self, context, instance, 

1469 src_compute_info, dst_compute_info, 

1470 block_migration=False, 

1471 disk_over_commit=False): 

1472 """Check if it is possible to execute live migration. 

1473 

1474 This runs checks on the destination host, and then calls 

1475 back to the source host to check the results. 

1476 

1477 :param context: security context 

1478 :param instance: nova.db.main.models.Instance 

1479 :param src_compute_info: Info about the sending machine 

1480 :param dst_compute_info: Info about the receiving machine 

1481 :param block_migration: if true, prepare for block migration 

1482 :param disk_over_commit: if true, allow disk over commit 

1483 :returns: a LiveMigrateData object (hypervisor-dependent) 

1484 """ 

1485 raise NotImplementedError() 

1486 

1487 def check_source_migrate_data_at_dest(self, ctxt, instance, migrate_data, 

1488 migration, limits, allocs): 

1489 """Runs the last checks on the destination after the source returned 

1490 the migrate_data. 

1491 

1492 :param ctxt: security context 

1493 :param instance: nova.db.main.models.Instance 

1494 :param migrate_data: result of check_can_live_migrate_source 

1495 :param migration: The Migration object for this live migration 

1496 :param limits: The SchedulerLimits object for this live migration 

1497 :param allocs: Allocations for this instance 

1498 :returns: a LibvirtLiveMigrateData object 

1499 :raises: MigrationPreCheckError 

1500 """ 

1501 return migrate_data 

1502 

1503 def post_claim_migrate_data(self, context, instance, migrate_data, claim): 

1504 """Returns migrate_data augmented with any information obtained from 

1505 the claim. Intended to run on the destination of a live-migration 

1506 operation, after resources have been claimed on it. 

1507 

1508 :param context: The request context. 

1509 :param instance: The instance being live-migrated. 

1510 :param migrate_data: The existing LiveMigrateData object for this live 

1511 migration. 

1512 :param claim: The MoveClaim that was made on the destination for this 

1513 live migration. 

1514 :returns: A LiveMigrateData object augmented with information obtained 

1515 from the Claim. 

1516 """ 

1517 return migrate_data 

1518 

1519 def cleanup_live_migration_destination_check(self, context, 

1520 dest_check_data): 

1521 """Do required cleanup on dest host after check_can_live_migrate calls 

1522 

1523 :param context: security context 

1524 :param dest_check_data: result of check_can_live_migrate_destination 

1525 """ 

1526 raise NotImplementedError() 

1527 

1528 def check_can_live_migrate_source(self, context, instance, 

1529 dest_check_data, block_device_info=None): 

1530 """Check if it is possible to execute live migration. 

1531 

1532 This checks if the live migration can succeed, based on the 

1533 results from check_can_live_migrate_destination. 

1534 

1535 :param context: security context 

1536 :param instance: nova.db.main.models.Instance 

1537 :param dest_check_data: result of check_can_live_migrate_destination 

1538 :param block_device_info: result of _get_instance_block_device_info 

1539 :returns: a LiveMigrateData object 

1540 """ 

1541 raise NotImplementedError() 

1542 

1543 def get_instance_disk_info(self, instance, 

1544 block_device_info=None): 

1545 """Retrieve information about actual disk sizes of an instance. 

1546 

1547 :param instance: nova.objects.Instance 

1548 :param block_device_info: 

1549 Optional; Can be used to filter out devices which are 

1550 actually volumes. 

1551 :return: 

1552 json strings with below format:: 

1553 

1554 "[{'path':'disk', 

1555 'type':'raw', 

1556 'virt_disk_size':'10737418240', 

1557 'backing_file':'backing_file', 

1558 'disk_size':'83886080' 

1559 'over_committed_disk_size':'10737418240'}, 

1560 ...]" 

1561 """ 

1562 raise NotImplementedError() 

1563 

1564 def set_admin_password(self, instance, new_pass): 

1565 """Set the root password on the specified instance. 

1566 

1567 :param instance: nova.objects.instance.Instance 

1568 :param new_pass: the new password 

1569 """ 

1570 raise NotImplementedError() 

1571 

1572 def inject_network_info(self, instance, nw_info): 

1573 """inject network info for specified instance.""" 

1574 # TODO(Vek): Need to pass context in for access to auth_token 

1575 pass 

1576 

1577 def poll_rebooting_instances(self, timeout, instances): 

1578 """Perform a reboot on all given 'instances'. 

1579 

1580 Reboots the given `instances` which are longer in the rebooting state 

1581 than `timeout` seconds. 

1582 

1583 :param int timeout: 

1584 The timeout (in seconds) for considering rebooting instances 

1585 to be stuck. 

1586 :param list instances: 

1587 A list of nova.objects.instance.Instance objects that have been 

1588 in rebooting state longer than the configured timeout. 

1589 

1590 :return: None 

1591 """ 

1592 # TODO(Vek): Need to pass context in for access to auth_token 

1593 raise NotImplementedError() 

1594 

1595 def host_power_action(self, action): 

1596 """Reboots, shuts down or powers up the host. 

1597 

1598 :param str action: 

1599 The action the host should perform. The valid actions are: 

1600 ""startup", "shutdown" and "reboot". 

1601 

1602 :return: The result of the power action 

1603 :rtype: str 

1604 """ 

1605 

1606 raise NotImplementedError() 

1607 

1608 def host_maintenance_mode(self, host, mode): 

1609 """Start/Stop host maintenance window. 

1610 

1611 On start, it triggers the migration of all instances to other hosts. 

1612 Consider the combination with :func:`set_host_enabled`. 

1613 

1614 :param str host: 

1615 The name of the host whose maintenance mode should be changed. 

1616 :param bool mode: 

1617 If `True`, go into maintenance mode. If `False`, leave the 

1618 maintenance mode. 

1619 

1620 :return: "on_maintenance" if switched to maintenance mode or 

1621 "off_maintenance" if maintenance mode got left. 

1622 :rtype: str 

1623 """ 

1624 

1625 raise NotImplementedError() 

1626 

1627 def set_host_enabled(self, enabled): 

1628 """Sets the ability of this host to accept new instances. 

1629 

1630 :param bool enabled: 

1631 If this is `True`, the host will accept new instances. If it is 

1632 `False`, the host won't accept new instances. 

1633 

1634 :return: If the host can accept further instances, return "enabled", 

1635 if further instances shouldn't be scheduled to this host, 

1636 return "disabled". 

1637 :rtype: str 

1638 """ 

1639 # TODO(Vek): Need to pass context in for access to auth_token 

1640 raise NotImplementedError() 

1641 

1642 def get_host_uptime(self): 

1643 """Returns the result of the time since start up of this hypervisor. 

1644 

1645 :return: A text which contains the uptime of this host since the 

1646 last boot. 

1647 :rtype: str 

1648 """ 

1649 # TODO(Vek): Need to pass context in for access to auth_token 

1650 raise NotImplementedError() 

1651 

1652 def plug_vifs(self, instance, network_info): 

1653 """Plug virtual interfaces (VIFs) into the given `instance` at 

1654 instance boot time. 

1655 

1656 The counter action is :func:`unplug_vifs`. 

1657 

1658 :param nova.objects.instance.Instance instance: 

1659 The instance which gets VIFs plugged. 

1660 :param nova.network.model.NetworkInfo network_info: 

1661 The object which contains information about the VIFs to plug. 

1662 

1663 :return: None 

1664 """ 

1665 # TODO(Vek): Need to pass context in for access to auth_token 

1666 raise NotImplementedError() 

1667 

1668 def unplug_vifs(self, instance, network_info): 

1669 """Unplug virtual interfaces (VIFs) from networks. 

1670 

1671 The counter action is :func:`plug_vifs`. 

1672 

1673 :param nova.objects.instance.Instance instance: 

1674 The instance which gets VIFs unplugged. 

1675 :param nova.network.model.NetworkInfo network_info: 

1676 The object which contains information about the VIFs to unplug. 

1677 

1678 :return: None 

1679 """ 

1680 raise NotImplementedError() 

1681 

1682 def get_host_cpu_stats(self): 

1683 """Get the currently known host CPU stats. 

1684 

1685 :returns: a dict containing the CPU stat info, eg: 

1686 

1687 | {'kernel': kern, 

1688 | 'idle': idle, 

1689 | 'user': user, 

1690 | 'iowait': wait, 

1691 | 'frequency': freq}, 

1692 

1693 where kern and user indicate the cumulative CPU time 

1694 (nanoseconds) spent by kernel and user processes 

1695 respectively, idle indicates the cumulative idle CPU time 

1696 (nanoseconds), wait indicates the cumulative I/O wait CPU 

1697 time (nanoseconds), since the host is booting up; freq 

1698 indicates the current CPU frequency (MHz). All values are 

1699 long integers. 

1700 

1701 """ 

1702 raise NotImplementedError() 

1703 

1704 def block_stats(self, instance, disk_id): 

1705 """Return performance counters associated with the given disk_id on the 

1706 given instance. These are returned as [rd_req, rd_bytes, wr_req, 

1707 wr_bytes, errs], where rd indicates read, wr indicates write, req is 

1708 the total number of I/O requests made, bytes is the total number of 

1709 bytes transferred, and errs is the number of requests held up due to a 

1710 full pipeline. 

1711 

1712 All counters are long integers. 

1713 

1714 This method is optional. On some platforms performance statistics can 

1715 be retrieved directly in aggregate form, without Nova having to do the 

1716 aggregation. On those platforms, this method is unused. 

1717 

1718 Note that this function takes an instance ID. 

1719 

1720 :param instance: nova.objects.Instance to get block storage statistics 

1721 :param disk_id: mountpoint name, e.g. "vda" 

1722 :returns: None if block statistics could not be retrieved, otherwise a 

1723 list of the form: [rd_req, rd_bytes, wr_req, wr_bytes, errs] 

1724 :raises: NotImplementedError if the driver does not implement this 

1725 method 

1726 """ 

1727 raise NotImplementedError() 

1728 

1729 def manage_image_cache(self, context, all_instances): 

1730 """Manage the driver's local image cache. 

1731 

1732 Some drivers chose to cache images for instances on disk. This method 

1733 is an opportunity to do management of that cache which isn't directly 

1734 related to other calls into the driver. The prime example is to clean 

1735 the cache and remove images which are no longer of interest. 

1736 

1737 :param all_instances: nova.objects.instance.InstanceList 

1738 """ 

1739 pass 

1740 

1741 def cache_image(self, context, image_id): 

1742 """Download an image into the cache. 

1743 

1744 Used by the compute manager in response to a request to pre-cache 

1745 an image on the compute node. If the driver implements an image cache, 

1746 it should implement this method as well and perform the same action 

1747 as it does during an on-demand base image fetch in response to a 

1748 spawn. 

1749 

1750 :returns: A boolean indicating whether or not the image was fetched. 

1751 True if it was fetched, or False if it already exists in 

1752 the cache. 

1753 :raises: An Exception on error 

1754 """ 

1755 raise NotImplementedError() 

1756 

1757 def get_volume_connector(self, instance): 

1758 """Get connector information for the instance for attaching to volumes. 

1759 

1760 Connector information is a dictionary representing the ip of the 

1761 machine that will be making the connection, the name of the iscsi 

1762 initiator and the hostname of the machine as follows:: 

1763 

1764 { 

1765 'ip': ip, 

1766 'initiator': initiator, 

1767 'host': hostname 

1768 } 

1769 

1770 """ 

1771 raise NotImplementedError() 

1772 

1773 def get_available_nodes(self, refresh=False): 

1774 """Returns nodenames of all nodes managed by the compute service. 

1775 

1776 This method is for multi compute-nodes support. If a driver supports 

1777 multi compute-nodes, this method returns a list of nodenames managed 

1778 by the service. Otherwise, this method should return 

1779 [hypervisor_hostname]. 

1780 """ 

1781 raise NotImplementedError() 

1782 

1783 def get_nodenames_by_uuid(self, refresh=False): 

1784 """Returns a dict of {uuid: nodename} for all managed nodes.""" 

1785 nodename = self.get_available_nodes()[0] 

1786 return {nova.virt.node.get_local_node_uuid(): nodename} 

1787 

1788 def node_is_available(self, nodename): 

1789 """Return whether this compute service manages a particular node.""" 

1790 if nodename in self.get_available_nodes(): 1790 ↛ 1793line 1790 didn't jump to line 1793 because the condition on line 1790 was always true

1791 return True 

1792 # Refresh and check again. 

1793 return nodename in self.get_available_nodes(refresh=True) 

1794 

1795 def instance_on_disk(self, instance): 

1796 """Checks access of instance files on the host. 

1797 

1798 :param instance: nova.objects.instance.Instance to lookup 

1799 

1800 Returns True if files of an instance with the supplied ID accessible on 

1801 the host, False otherwise. 

1802 

1803 .. note:: 

1804 Used in rebuild for HA implementation and required for validation 

1805 of access to instance shared disk files 

1806 """ 

1807 return False 

1808 

1809 def register_event_listener(self, callback): 

1810 """Register a callback to receive events. 

1811 

1812 Register a callback to receive asynchronous event 

1813 notifications from hypervisors. The callback will 

1814 be invoked with a single parameter, which will be 

1815 an instance of the nova.virt.event.Event class. 

1816 """ 

1817 

1818 self._compute_event_callback = callback 

1819 

1820 def emit_event(self, event): 

1821 """Dispatches an event to the compute manager. 

1822 

1823 Invokes the event callback registered by the 

1824 compute manager to dispatch the event. This 

1825 must only be invoked from a green thread. 

1826 """ 

1827 

1828 if not self._compute_event_callback: 1828 ↛ 1829line 1828 didn't jump to line 1829 because the condition on line 1828 was never true

1829 LOG.debug("Discarding event %s", str(event)) 

1830 return 

1831 

1832 if not isinstance(event, virtevent.Event): 

1833 raise ValueError( 

1834 _("Event must be an instance of nova.virt.event.Event")) 

1835 

1836 try: 

1837 LOG.debug("Emitting event %s", str(event)) 

1838 self._compute_event_callback(event) 

1839 except Exception as ex: 

1840 LOG.error("Exception dispatching event %(event)s: %(ex)s", 

1841 {'event': event, 'ex': ex}) 

1842 

1843 def delete_instance_files(self, instance): 

1844 """Delete any lingering instance files for an instance. 

1845 

1846 :param instance: nova.objects.instance.Instance 

1847 :returns: True if the instance was deleted from disk, False otherwise. 

1848 """ 

1849 return True 

1850 

1851 def volume_snapshot_create(self, context, instance, volume_id, 

1852 create_info): 

1853 """Snapshots volumes attached to a specified instance. 

1854 

1855 The counter action to this is :func:`volume_snapshot_delete` 

1856 

1857 :param nova.context.RequestContext context: 

1858 The security context. 

1859 :param nova.objects.instance.Instance instance: 

1860 The instance that has the volume attached 

1861 :param uuid volume_id: 

1862 Volume to be snapshotted 

1863 :param create_info: The data needed for nova to be able to attach 

1864 to the volume. This is the same data format returned by 

1865 Cinder's initialize_connection() API call. In the case of 

1866 doing a snapshot, it is the image file Cinder expects to be 

1867 used as the active disk after the snapshot operation has 

1868 completed. There may be other data included as well that is 

1869 needed for creating the snapshot. 

1870 """ 

1871 raise NotImplementedError() 

1872 

1873 def volume_snapshot_delete(self, context, instance, volume_id, 

1874 snapshot_id, delete_info): 

1875 """Deletes a snapshot of a volume attached to a specified instance. 

1876 

1877 The counter action to this is :func:`volume_snapshot_create` 

1878 

1879 :param nova.context.RequestContext context: 

1880 The security context. 

1881 :param nova.objects.instance.Instance instance: 

1882 The instance that has the volume attached. 

1883 :param uuid volume_id: 

1884 Attached volume associated with the snapshot 

1885 :param uuid snapshot_id: 

1886 The snapshot to delete. 

1887 :param dict delete_info: 

1888 Volume backend technology specific data needed to be able to 

1889 complete the snapshot. For example, in the case of qcow2 backed 

1890 snapshots, this would include the file being merged, and the file 

1891 being merged into (if appropriate). 

1892 

1893 :return: None 

1894 """ 

1895 raise NotImplementedError() 

1896 

1897 def default_root_device_name(self, instance, image_meta, root_bdm): 

1898 """Provide a default root device name for the driver. 

1899 

1900 :param nova.objects.instance.Instance instance: 

1901 The instance to get the root device for. 

1902 :param nova.objects.ImageMeta image_meta: 

1903 The metadata of the image of the instance. 

1904 :param nova.objects.BlockDeviceMapping root_bdm: 

1905 The description of the root device. 

1906 :raises TooManyDiskDevices: if the maximum allowed devices to attach 

1907 to a single instance is exceeded. 

1908 """ 

1909 raise NotImplementedError() 

1910 

1911 def default_device_names_for_instance(self, instance, root_device_name, 

1912 *block_device_lists): 

1913 """Default the missing device names in the block device mapping. 

1914 

1915 :raises TooManyDiskDevices: if the maximum allowed devices to attach 

1916 to a single instance is exceeded. 

1917 """ 

1918 raise NotImplementedError() 

1919 

1920 def get_device_name_for_instance(self, instance, 

1921 bdms, block_device_obj): 

1922 """Get the next device name based on the block device mapping. 

1923 

1924 :param instance: nova.objects.instance.Instance that volume is 

1925 requesting a device name 

1926 :param bdms: a nova.objects.BlockDeviceMappingList for the instance 

1927 :param block_device_obj: A nova.objects.BlockDeviceMapping instance 

1928 with all info about the requested block 

1929 device. device_name does not need to be set, 

1930 and should be decided by the driver 

1931 implementation if not set. 

1932 

1933 :returns: The chosen device name. 

1934 :raises TooManyDiskDevices: if the maximum allowed devices to attach 

1935 to a single instance is exceeded. 

1936 """ 

1937 raise NotImplementedError() 

1938 

1939 def is_supported_fs_format(self, fs_type): 

1940 """Check whether the file format is supported by this driver 

1941 

1942 :param fs_type: the file system type to be checked, 

1943 the validate values are defined at disk API module. 

1944 """ 

1945 # NOTE(jichenjc): Return False here so that every hypervisor 

1946 # need to define their supported file system 

1947 # type and implement this function at their 

1948 # virt layer. 

1949 return False 

1950 

1951 def quiesce(self, context, instance, image_meta): 

1952 """Quiesce the specified instance to prepare for snapshots. 

1953 

1954 If the specified instance doesn't support quiescing, 

1955 InstanceQuiesceNotSupported is raised. When it fails to quiesce by 

1956 other errors (e.g. agent timeout), NovaException is raised. 

1957 

1958 :param context: request context 

1959 :param instance: nova.objects.instance.Instance to be quiesced 

1960 :param nova.objects.ImageMeta image_meta: 

1961 The metadata of the image of the instance. 

1962 """ 

1963 raise NotImplementedError() 

1964 

1965 def unquiesce(self, context, instance, image_meta): 

1966 """Unquiesce the specified instance after snapshots. 

1967 

1968 If the specified instance doesn't support quiescing, 

1969 InstanceQuiesceNotSupported is raised. When it fails to quiesce by 

1970 other errors (e.g. agent timeout), NovaException is raised. 

1971 

1972 :param context: request context 

1973 :param instance: nova.objects.instance.Instance to be unquiesced 

1974 :param nova.objects.ImageMeta image_meta: 

1975 The metadata of the image of the instance. 

1976 """ 

1977 raise NotImplementedError() 

1978 

1979 def network_binding_host_id(self, context, instance): 

1980 """Get host ID to associate with network ports. 

1981 

1982 :param context: request context 

1983 :param instance: nova.objects.instance.Instance that the network 

1984 ports will be associated with 

1985 :returns: a string representing the host ID 

1986 """ 

1987 return instance.get('host') 

1988 

1989 def manages_network_binding_host_id(self): 

1990 """Compute driver manages port bindings. 

1991 

1992 Used to indicate whether or not the compute driver is responsible 

1993 for managing port binding details, such as the host_id. 

1994 By default the ComputeManager will manage port bindings and the 

1995 host_id associated with a binding using the network API. 

1996 However, some backends, like Ironic, will manage the port binding 

1997 host_id out-of-band and the compute service should not override what 

1998 is set by the backing hypervisor. 

1999 """ 

2000 return False 

2001 

2002 def cleanup_lingering_instance_resources(self, instance): 

2003 """Cleanup resources occupied by lingering instance. 

2004 

2005 For example, cleanup other specific resources or whatever we 

2006 add in the future. 

2007 

2008 :param instance: nova.objects.instance.Instance 

2009 :returns: True if the cleanup is successful, else false. 

2010 """ 

2011 return True 

2012 

2013 

2014def load_compute_driver(virtapi, compute_driver=None): 

2015 """Load a compute driver module. 

2016 

2017 Load the compute driver module specified by the compute_driver 

2018 configuration option or, if supplied, the driver name supplied as an 

2019 argument. 

2020 

2021 Compute drivers constructors take a VirtAPI object as their first object 

2022 and this must be supplied. 

2023 

2024 :param virtapi: a VirtAPI instance 

2025 :param compute_driver: a compute driver name to override the config opt 

2026 :returns: a ComputeDriver instance 

2027 """ 

2028 if not compute_driver: 

2029 compute_driver = CONF.compute_driver 

2030 

2031 if not compute_driver: 2031 ↛ 2032line 2031 didn't jump to line 2032 because the condition on line 2031 was never true

2032 LOG.error("Compute driver option required, but not specified") 

2033 sys.exit(1) 

2034 

2035 LOG.info("Loading compute driver '%s'", compute_driver) 

2036 try: 

2037 driver = importutils.import_object( 

2038 'nova.virt.%s' % compute_driver, 

2039 virtapi) 

2040 if isinstance(driver, ComputeDriver): 2040 ↛ 2042line 2040 didn't jump to line 2042 because the condition on line 2040 was always true

2041 return driver 

2042 raise ValueError() 

2043 except ImportError: 

2044 LOG.exception("Unable to load the virtualization driver") 

2045 sys.exit(1) 

2046 except ValueError: 

2047 LOG.exception("Compute driver '%s' from 'nova.virt' is not of type " 

2048 "'%s'", compute_driver, str(ComputeDriver)) 

2049 sys.exit(1)