Coverage for nova/virt/libvirt/config.py: 92%

2790 statements  

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

1# Copyright (C) 2012-2013 Red Hat, Inc. 

2# 

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

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

5# a copy of the License at 

6# 

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

8# 

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

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

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

12# License for the specific language governing permissions and limitations 

13# under the License. 

14 

15""" 

16Configuration for libvirt objects. 

17 

18Classes to represent the configuration of various libvirt objects 

19and support conversion to/from XML. These classes are solely concerned 

20by providing direct Object <-> XML document conversions. No policy or 

21operational decisions should be made by code in these classes. Such 

22policy belongs in the 'designer.py' module which provides simplified 

23helpers for populating up config object instances. 

24""" 

25 

26import time 

27import typing as ty 

28 

29from collections import OrderedDict 

30from lxml import etree 

31from oslo_log import log as logging 

32from oslo_utils import strutils 

33from oslo_utils import units 

34 

35from nova import exception 

36from nova.i18n import _ 

37from nova.objects import fields 

38from nova.pci import utils as pci_utils 

39from nova.virt import hardware 

40 

41LOG = logging.getLogger(__name__) 

42 

43# Namespace to use for Nova specific metadata items in XML 

44NOVA_NS = "http://openstack.org/xmlns/libvirt/nova/1.1" 

45 

46 

47def make_libvirt_device_alias(identifier): 

48 return 'ua-%s' % identifier 

49 

50 

51def parse_libvirt_device_alias(alias): 

52 if alias.startswith('ua-'): 

53 return alias.split('-', 1)[1] 

54 else: 

55 return alias 

56 

57 

58class LibvirtConfigObject(object): 

59 

60 def __init__(self, **kwargs): 

61 super(LibvirtConfigObject, self).__init__() 

62 

63 self.root_name = kwargs.pop("root_name") 

64 self.ns_prefix = kwargs.pop("ns_prefix", None) 

65 self.ns_uri = kwargs.pop("ns_uri", None) 

66 

67 # handle programmer error 

68 assert not kwargs 

69 

70 def _new_node(self, node_name, **kwargs): 

71 if self.ns_uri is None: 

72 return etree.Element(node_name, **kwargs) 

73 else: 

74 return etree.Element("{" + self.ns_uri + "}" + node_name, 

75 nsmap={self.ns_prefix: self.ns_uri}, 

76 **kwargs) 

77 

78 def _text_node(self, node_name, value, **kwargs): 

79 child = self._new_node(node_name, **kwargs) 

80 if value is not None: 

81 child.text = str(value) 

82 return child 

83 

84 def format_dom(self): 

85 return self._new_node(self.root_name) 

86 

87 def parse_str(self, xmlstr): 

88 try: 

89 self.parse_dom(etree.fromstring(xmlstr)) 

90 except etree.Error: 

91 LOG.debug("Failed to parse the libvirt XML: %s", xmlstr) 

92 raise 

93 

94 def parse_dom(self, xmldoc): 

95 if self.root_name != xmldoc.tag: 95 ↛ 96line 95 didn't jump to line 96 because the condition on line 95 was never true

96 msg = (_("Root element name should be '%(name)s' not '%(tag)s'") % 

97 {'name': self.root_name, 'tag': xmldoc.tag}) 

98 raise exception.InvalidInput(msg) 

99 

100 def to_xml(self, pretty_print=True): 

101 root = self.format_dom() 

102 xml_str = etree.tostring(root, encoding='unicode', 

103 pretty_print=pretty_print) 

104 return xml_str 

105 

106 @classmethod 

107 def parse_on_off_str(self, value: ty.Optional[str]) -> bool: 

108 if value is not None and value not in ('on', 'off'): 

109 msg = _( 

110 "Element should contain either 'on' or 'off'; " 

111 "found: '%(value)s'" 

112 ) 

113 raise exception.InvalidInput(msg % {'value': value}) 

114 

115 return value == 'on' 

116 

117 @classmethod 

118 def get_yes_no_str(self, value: bool) -> str: 

119 return 'yes' if value else 'no' 

120 

121 @classmethod 

122 def get_on_off_str(self, value: bool) -> str: 

123 return 'on' if value else 'off' 

124 

125 def __repr__(self): 

126 return self.to_xml(pretty_print=False) 

127 

128 

129class LibvirtConfigCaps(LibvirtConfigObject): 

130 

131 def __init__(self, **kwargs): 

132 super(LibvirtConfigCaps, self).__init__(root_name="capabilities", 

133 **kwargs) 

134 self.host = None 

135 self.guests = [] 

136 

137 def parse_dom(self, xmldoc): 

138 super(LibvirtConfigCaps, self).parse_dom(xmldoc) 

139 

140 for c in xmldoc: 

141 if c.tag == "host": 

142 host = LibvirtConfigCapsHost() 

143 host.parse_dom(c) 

144 self.host = host 

145 elif c.tag == "guest": 145 ↛ 140line 145 didn't jump to line 140 because the condition on line 145 was always true

146 guest = LibvirtConfigCapsGuest() 

147 guest.parse_dom(c) 

148 self.guests.append(guest) 

149 

150 def format_dom(self): 

151 caps = super(LibvirtConfigCaps, self).format_dom() 

152 

153 if self.host: 

154 caps.append(self.host.format_dom()) 

155 for g in self.guests: 

156 caps.append(g.format_dom()) 

157 

158 return caps 

159 

160 

161class LibvirtConfigDomainCaps(LibvirtConfigObject): 

162 

163 def __init__(self, **kwargs): 

164 super(LibvirtConfigDomainCaps, self).__init__( 

165 root_name="domainCapabilities", **kwargs) 

166 self._features = None 

167 self._machine = None 

168 self._alias = None 

169 self._devices = None 

170 self._os = None 

171 

172 def parse_dom(self, xmldoc): 

173 super(LibvirtConfigDomainCaps, self).parse_dom(xmldoc) 

174 

175 for c in xmldoc: 

176 if c.tag == "features": 

177 features = LibvirtConfigDomainCapsFeatures() 

178 features.parse_dom(c) 

179 self._features = features 

180 elif c.tag == "machine": 

181 self._machine = c.text 

182 elif c.tag == "devices": 

183 devices = LibvirtConfigDomainCapsDevices() 

184 devices.parse_dom(c) 

185 self._devices = devices 

186 elif c.tag == "os": 

187 os = LibvirtConfigDomainCapsOS() 

188 os.parse_dom(c) 

189 self._os = os 

190 

191 @property 

192 def features(self): 

193 if self._features is None: 

194 return [] 

195 return self._features.features 

196 

197 @property 

198 def machine_type(self): 

199 if self._machine is None: 199 ↛ 200line 199 didn't jump to line 200 because the condition on line 199 was never true

200 return "" 

201 return self._machine 

202 

203 @property 

204 def machine_type_alias(self): 

205 if self._alias is None: 

206 return self._machine 

207 return self._alias 

208 

209 @machine_type_alias.setter 

210 def machine_type_alias(self, alias): 

211 self._alias = alias 

212 

213 @property 

214 def devices(self): 

215 if self._devices is None: 215 ↛ 216line 215 didn't jump to line 216 because the condition on line 215 was never true

216 return [] 

217 return self._devices 

218 

219 @property 

220 def os(self): 

221 return self._os 

222 

223 

224class LibvirtConfigDomainCapsVideoModels(LibvirtConfigObject): 

225 

226 def __init__(self, **kwargs): 

227 super().__init__(root_name='video', **kwargs) 

228 self.supported = False 

229 self.models = set() 

230 

231 def parse_dom(self, xmldoc): 

232 super().parse_dom(xmldoc) 

233 

234 if xmldoc.get('supported') == 'yes': 234 ↛ 236line 234 didn't jump to line 236 because the condition on line 234 was always true

235 self.supported = True 

236 self.models = {str(node) for node in 

237 xmldoc.xpath("//enum[@name='modelType']/value/text()")} 

238 

239 

240class LibvirtConfigDomainCapsDiskBuses(LibvirtConfigObject): 

241 

242 def __init__(self, **kwargs): 

243 super().__init__(root_name='disk', **kwargs) 

244 self.supported = False 

245 self.buses = set() 

246 

247 def parse_dom(self, xmldoc): 

248 super(LibvirtConfigDomainCapsDiskBuses, self).parse_dom(xmldoc) 

249 

250 if xmldoc.get('supported') == 'yes': 250 ↛ 252line 250 didn't jump to line 252 because the condition on line 250 was always true

251 self.supported = True 

252 self.buses = {str(node) for node in 

253 xmldoc.xpath("//enum[@name='bus']/value/text()")} 

254 

255 

256class LibvirtConfigDomainCapsTpm(LibvirtConfigObject): 

257 

258 def __init__(self, **kwargs): 

259 super().__init__(root_name='tpm', **kwargs) 

260 self.supported = False 

261 self.models = [] 

262 self.backend_models = [] 

263 # TODO(tkajinam): Change default to [] once libvirt >= 8.6.0 is 

264 # required 

265 self.backend_versions = None 

266 

267 def parse_dom(self, xmldoc): 

268 super(LibvirtConfigDomainCapsTpm, self).parse_dom(xmldoc) 

269 

270 if xmldoc.get('supported'): 270 ↛ 272line 270 didn't jump to line 272 because the condition on line 270 was always true

271 self.supported = (xmldoc.get('supported') == 'yes') 

272 for c in xmldoc: 

273 if c.tag == 'enum': 273 ↛ 272line 273 didn't jump to line 272 because the condition on line 273 was always true

274 if c.get('name') == 'model': 

275 for c2 in c: 

276 if c2.tag == 'value': 276 ↛ 275line 276 didn't jump to line 275 because the condition on line 276 was always true

277 self.models.append(c2.text) 

278 if c.get('name') == 'backendModel': 

279 for c2 in c: 

280 if c2.tag == 'value': 280 ↛ 279line 280 didn't jump to line 279 because the condition on line 280 was always true

281 self.backend_models.append(c2.text) 

282 if c.get('name') == 'backendVersion': 

283 for c2 in c: 

284 if c2.tag == 'value': 284 ↛ 283line 284 didn't jump to line 283 because the condition on line 284 was always true

285 if self.backend_versions is None: 285 ↛ 287line 285 didn't jump to line 287 because the condition on line 285 was always true

286 self.backend_versions = [] 

287 self.backend_versions.append(c2.text) 

288 

289 

290class LibvirtConfigDomainCapsDevices(LibvirtConfigObject): 

291 DEVICE_PARSERS = { 

292 'video': LibvirtConfigDomainCapsVideoModels, 

293 'disk': LibvirtConfigDomainCapsDiskBuses, 

294 'tpm': LibvirtConfigDomainCapsTpm, 

295 } 

296 

297 def __init__(self, **kwargs): 

298 super().__init__(root_name='devices', **kwargs) 

299 self.devices = set() 

300 

301 def parse_dom(self, xmldoc): 

302 super().parse_dom(xmldoc) 

303 

304 for c in list(xmldoc): 

305 device = self.DEVICE_PARSERS.get(c.tag) 

306 if device: 

307 device = device() 

308 device.parse_dom(c) 

309 self.devices.add(device) 

310 

311 def _get_device(self, device_type): 

312 for device in self.devices: 

313 if type(device) is self.DEVICE_PARSERS.get(device_type): 

314 return device 

315 return None 

316 

317 @property 

318 def disk(self): 

319 return self._get_device('disk') 

320 

321 @property 

322 def video(self): 

323 return self._get_device('video') 

324 

325 @property 

326 def tpm(self): 

327 return self._get_device('tpm') 

328 

329 

330class LibvirtConfigDomainCapsFeatures(LibvirtConfigObject): 

331 

332 def __init__(self, **kwargs): 

333 super(LibvirtConfigDomainCapsFeatures, self).__init__( 

334 root_name="features", **kwargs) 

335 self.features = [] 

336 

337 def parse_dom(self, xmldoc): 

338 super(LibvirtConfigDomainCapsFeatures, self).parse_dom(xmldoc) 

339 

340 for c in xmldoc: 

341 feature = None 

342 if c.tag == "sev": 

343 feature = LibvirtConfigDomainCapsFeatureSev() 

344 if feature: 

345 feature.parse_dom(c) 

346 self.features.append(feature) 

347 

348 # There are many other features and domain capabilities, 

349 # but we don't need to regenerate the XML (it's read-only 

350 # data provided by libvirtd), so there's no point parsing 

351 # them until we actually need their values. 

352 

353 # For the same reason, we do not need a format_dom() method, but 

354 # it's a bug if this ever gets called and we inherited one from 

355 # the base class, so override that to watch out for accidental 

356 # calls. 

357 def format_dom(self): 

358 raise RuntimeError(_('BUG: tried to generate domainCapabilities XML')) 

359 

360 

361class LibvirtConfigDomainCapsFeatureSev(LibvirtConfigObject): 

362 

363 def __init__(self, **kwargs): 

364 super(LibvirtConfigDomainCapsFeatureSev, self).__init__( 

365 root_name='sev', **kwargs) 

366 self.supported = False 

367 self.cbitpos = None 

368 self.reduced_phys_bits = None 

369 self.max_guests = None 

370 self.max_es_guests = None 

371 

372 def parse_dom(self, xmldoc): 

373 super(LibvirtConfigDomainCapsFeatureSev, self).parse_dom(xmldoc) 

374 

375 if xmldoc.get('supported') == 'yes': 

376 self.supported = True 

377 

378 for c in list(xmldoc): 

379 if c.tag == 'reducedPhysBits': 

380 self.reduced_phys_bits = int(c.text) 

381 elif c.tag == 'cbitpos': 

382 self.cbitpos = int(c.text) 

383 elif c.tag == 'maxGuests': 

384 self.max_guests = int(c.text) 

385 elif c.tag == 'maxESGuests': 385 ↛ 378line 385 didn't jump to line 378 because the condition on line 385 was always true

386 self.max_es_guests = int(c.text) 

387 

388 

389class LibvirtConfigDomainCapsOS(LibvirtConfigObject): 

390 

391 def __init__(self, **kwargs): 

392 super().__init__(root_name='os', **kwargs) 

393 

394 self.supported = False 

395 self.loader_supported = None 

396 self.uefi_autoconfig_supported = None 

397 self.loader_paths = [] 

398 self.uefi_supported = None 

399 self.secure_boot_supported = None 

400 

401 def parse_dom(self, xmldoc): 

402 super().parse_dom(xmldoc) 

403 

404 self.supported = xmldoc.get('supported') 

405 

406 for c in xmldoc: 

407 self.loader_supported = c.get('supported') 

408 

409 if c.tag == 'enum': 

410 if c.get('name') == 'firmware': 410 ↛ 406line 410 didn't jump to line 406 because the condition on line 410 was always true

411 # theoretically we can also do autoconfiguration of BIOS 

412 # but it's unlikely that anything supports this yet 

413 self.uefi_autoconfig_supported = 'efi' in [ 

414 child.text for child in c if child.tag == 'value' 

415 ] 

416 elif c.tag == 'loader': 416 ↛ 406line 416 didn't jump to line 406 because the condition on line 416 was always true

417 for c2 in c: 

418 if c2.tag == 'value': 

419 self.loader_paths.append(c2.text) 

420 elif c2.tag == 'enum': 420 ↛ 417line 420 didn't jump to line 417 because the condition on line 420 was always true

421 if c2.get('name') == 'type': 

422 self.uefi_supported = 'pflash' in [ 

423 val.text for val in c2 if val.tag == 'value' 

424 ] 

425 elif c2.get('name') == 'secure': 

426 # we might want to ensure 'no' is also supported, 

427 # but a platform that only supports SB sounds odd 

428 self.secure_boot_supported = 'yes' in [ 

429 val.text for val in c2 if val.tag == 'value' 

430 ] 

431 

432 

433class LibvirtConfigCapsNUMATopology(LibvirtConfigObject): 

434 

435 def __init__(self, **kwargs): 

436 super(LibvirtConfigCapsNUMATopology, self).__init__( 

437 root_name="topology", 

438 **kwargs) 

439 

440 self.cells = [] 

441 

442 def parse_dom(self, xmldoc): 

443 super(LibvirtConfigCapsNUMATopology, self).parse_dom(xmldoc) 

444 

445 xmlcells = xmldoc[0] 

446 for xmlcell in xmlcells: 

447 cell = LibvirtConfigCapsNUMACell() 

448 cell.parse_dom(xmlcell) 

449 self.cells.append(cell) 

450 

451 def format_dom(self): 

452 topo = super(LibvirtConfigCapsNUMATopology, self).format_dom() 

453 

454 cells = etree.Element("cells") 

455 cells.set("num", str(len(self.cells))) 

456 topo.append(cells) 

457 

458 for cell in self.cells: 

459 cells.append(cell.format_dom()) 

460 

461 return topo 

462 

463 

464class LibvirtConfigCapsNUMACell(LibvirtConfigObject): 

465 

466 def __init__(self, **kwargs): 

467 super(LibvirtConfigCapsNUMACell, self).__init__(root_name="cell", 

468 **kwargs) 

469 

470 self.id = None 

471 self.memory = 0 

472 self.mempages = [] 

473 self.cpus = [] 

474 

475 def parse_dom(self, xmldoc): 

476 super(LibvirtConfigCapsNUMACell, self).parse_dom(xmldoc) 

477 

478 self.id = int(xmldoc.get("id")) 

479 for c in xmldoc: 

480 if c.tag == "memory": 

481 self.memory = int(c.text) 

482 elif c.tag == "pages": 

483 pages = LibvirtConfigCapsNUMAPages() 

484 pages.parse_dom(c) 

485 self.mempages.append(pages) 

486 elif c.tag == "cpus": 486 ↛ 479line 486 didn't jump to line 479 because the condition on line 486 was always true

487 for c2 in c: 

488 cpu = LibvirtConfigCapsNUMACPU() 

489 cpu.parse_dom(c2) 

490 self.cpus.append(cpu) 

491 

492 def format_dom(self): 

493 cell = super(LibvirtConfigCapsNUMACell, self).format_dom() 

494 

495 cell.set("id", str(self.id)) 

496 

497 mem = etree.Element("memory") 

498 mem.set("unit", "KiB") 

499 mem.text = str(self.memory) 

500 cell.append(mem) 

501 

502 for pages in self.mempages: 

503 cell.append(pages.format_dom()) 

504 

505 cpus = etree.Element("cpus") 

506 cpus.set("num", str(len(self.cpus))) 

507 for cpu in self.cpus: 

508 cpus.append(cpu.format_dom()) 

509 cell.append(cpus) 

510 

511 return cell 

512 

513 

514class LibvirtConfigCapsNUMACPU(LibvirtConfigObject): 

515 

516 def __init__(self, **kwargs): 

517 super(LibvirtConfigCapsNUMACPU, self).__init__(root_name="cpu", 

518 **kwargs) 

519 

520 self.id = None 

521 self.socket_id = None 

522 self.core_id = None 

523 self.siblings = None 

524 

525 def parse_dom(self, xmldoc): 

526 super(LibvirtConfigCapsNUMACPU, self).parse_dom(xmldoc) 

527 

528 self.id = int(xmldoc.get("id")) 

529 if xmldoc.get("socket_id") is not None: 529 ↛ 531line 529 didn't jump to line 531 because the condition on line 529 was always true

530 self.socket_id = int(xmldoc.get("socket_id")) 

531 if xmldoc.get("core_id") is not None: 531 ↛ 534line 531 didn't jump to line 534 because the condition on line 531 was always true

532 self.core_id = int(xmldoc.get("core_id")) 

533 

534 if xmldoc.get("siblings") is not None: 534 ↛ exitline 534 didn't return from function 'parse_dom' because the condition on line 534 was always true

535 self.siblings = hardware.parse_cpu_spec( 

536 xmldoc.get("siblings")) 

537 

538 def format_dom(self): 

539 cpu = super(LibvirtConfigCapsNUMACPU, self).format_dom() 

540 

541 cpu.set("id", str(self.id)) 

542 if self.socket_id is not None: 542 ↛ 544line 542 didn't jump to line 544 because the condition on line 542 was always true

543 cpu.set("socket_id", str(self.socket_id)) 

544 if self.core_id is not None: 544 ↛ 546line 544 didn't jump to line 546 because the condition on line 544 was always true

545 cpu.set("core_id", str(self.core_id)) 

546 if self.siblings is not None: 546 ↛ 550line 546 didn't jump to line 550 because the condition on line 546 was always true

547 cpu.set("siblings", 

548 hardware.format_cpu_spec(self.siblings)) 

549 

550 return cpu 

551 

552 

553class LibvirtConfigCapsNUMAPages(LibvirtConfigObject): 

554 

555 def __init__(self, **kwargs): 

556 super(LibvirtConfigCapsNUMAPages, self).__init__( 

557 root_name="pages", **kwargs) 

558 

559 self.size = None 

560 self.total = None 

561 

562 def parse_dom(self, xmldoc): 

563 super(LibvirtConfigCapsNUMAPages, self).parse_dom(xmldoc) 

564 

565 self.size = int(xmldoc.get("size")) 

566 self.total = int(xmldoc.text) 

567 

568 def format_dom(self): 

569 pages = super(LibvirtConfigCapsNUMAPages, self).format_dom() 

570 

571 pages.text = str(self.total) 

572 pages.set("size", str(self.size)) 

573 pages.set("unit", "KiB") 

574 

575 return pages 

576 

577 

578class LibvirtConfigCapsHost(LibvirtConfigObject): 

579 

580 def __init__(self, **kwargs): 

581 super(LibvirtConfigCapsHost, self).__init__(root_name="host", 

582 **kwargs) 

583 

584 self.cpu = None 

585 self.uuid = None 

586 self.topology = None 

587 

588 def parse_dom(self, xmldoc): 

589 super(LibvirtConfigCapsHost, self).parse_dom(xmldoc) 

590 

591 for c in xmldoc: 

592 if c.tag == "cpu": 

593 cpu = LibvirtConfigCPU() 

594 cpu.parse_dom(c) 

595 self.cpu = cpu 

596 elif c.tag == "uuid": 

597 self.uuid = c.text 

598 elif c.tag == "topology": 

599 self.topology = LibvirtConfigCapsNUMATopology() 

600 self.topology.parse_dom(c) 

601 

602 def format_dom(self): 

603 caps = super(LibvirtConfigCapsHost, self).format_dom() 

604 

605 if self.uuid: 

606 caps.append(self._text_node("uuid", self.uuid)) 

607 if self.cpu: 607 ↛ 609line 607 didn't jump to line 609 because the condition on line 607 was always true

608 caps.append(self.cpu.format_dom()) 

609 if self.topology: 

610 caps.append(self.topology.format_dom()) 

611 

612 return caps 

613 

614 

615class LibvirtConfigCapsGuest(LibvirtConfigObject): 

616 

617 def __init__(self, **kwargs): 

618 super(LibvirtConfigCapsGuest, self).__init__(root_name="guest", 

619 **kwargs) 

620 

621 self.arch = None 

622 self.ostype = None 

623 # Map domain types such as 'qemu' and 'kvm' to 

624 # LibvirtConfigCapsGuestDomain instances. 

625 self.domains = OrderedDict() 

626 self.default_domain = None 

627 

628 def parse_dom(self, xmldoc): 

629 super(LibvirtConfigCapsGuest, self).parse_dom(xmldoc) 

630 

631 for child in xmldoc: 

632 if child.tag == "os_type": 

633 self.ostype = child.text 

634 elif child.tag == "arch": 

635 self.parse_arch(child) 

636 

637 def parse_arch(self, xmldoc): 

638 self.arch = xmldoc.get("name") 

639 # NOTE(aspiers): The data relating to each <domain> element 

640 # under <arch> (such as <emulator> and many <machine> 

641 # elements) is structured in a slightly odd way. There is one 

642 # "default" domain such as 

643 # 

644 # <domain type='qemu'/> 

645 # 

646 # which has no child elements, and all its data is provided in 

647 # sibling elements. Then others such as 

648 # 

649 # <domain type='kvm'> 

650 # 

651 # will have their <emulator> and <machine> elements as 

652 # children. So we need to handle the two cases separately. 

653 self.default_domain = LibvirtConfigCapsGuestDomain() 

654 for child in xmldoc: 

655 if child.tag == "domain": 

656 if list(child): 

657 # This domain has children, so create a new instance, 

658 # parse it, and register it in the dict of domains. 

659 domain = LibvirtConfigCapsGuestDomain() 

660 domain.parse_dom(child) 

661 self.domains[domain.domtype] = domain 

662 else: 

663 # This is the childless <domain/> element for the 

664 # default domain 

665 self.default_domain.parse_domain(child) 

666 self.domains[self.default_domain.domtype] = \ 

667 self.default_domain 

668 else: 

669 # Sibling element of the default domain 

670 self.default_domain.parse_child(child) 

671 

672 def format_dom(self): 

673 caps = super(LibvirtConfigCapsGuest, self).format_dom() 

674 

675 if self.ostype is not None: 675 ↛ 677line 675 didn't jump to line 677 because the condition on line 675 was always true

676 caps.append(self._text_node("os_type", self.ostype)) 

677 if self.arch: 677 ↛ 681line 677 didn't jump to line 681 because the condition on line 677 was always true

678 arch = self.format_arch() 

679 caps.append(arch) 

680 

681 return caps 

682 

683 def format_arch(self): 

684 arch = etree.Element("arch", name=self.arch) 

685 

686 for c in self.default_domain.format_dom(): 

687 arch.append(c) 

688 arch.append(self._new_node("domain", type=self.default_domain.domtype)) 

689 

690 for domtype, domain in self.domains.items(): 

691 if domtype == self.default_domain.domtype: 

692 # We've already added this domain at the top level 

693 continue 

694 arch.append(domain.format_dom()) 

695 

696 return arch 

697 

698 

699class LibvirtConfigCapsGuestDomain(LibvirtConfigObject): 

700 def __init__(self, **kwargs): 

701 super(LibvirtConfigCapsGuestDomain, self).__init__( 

702 root_name="domain", **kwargs) 

703 

704 self.domtype = None 

705 

706 # Track <emulator> values, which we need in order to be able 

707 # to call virConnectGetDomainCapabilities() - typically 

708 # something like '/usr/bin/qemu-system-i386'. 

709 self.emulator = None 

710 

711 self.machines = {} 

712 self.aliases = {} 

713 

714 def parse_dom(self, xmldoc): 

715 super(LibvirtConfigCapsGuestDomain, self).parse_dom(xmldoc) 

716 

717 self.parse_domain(xmldoc) 

718 

719 for c in xmldoc: 

720 self.parse_child(c) 

721 

722 def parse_child(self, xmldoc): 

723 if xmldoc.tag == "emulator": 

724 self.emulator = xmldoc.text 

725 elif xmldoc.tag == "machine": 

726 self.parse_machine(xmldoc) 

727 

728 def parse_domain(self, xmldoc): 

729 self.domtype = xmldoc.get("type") 

730 if self.domtype is None: 730 ↛ 731line 730 didn't jump to line 731 because the condition on line 730 was never true

731 raise exception.InvalidInput( 

732 "Didn't find domain type in %s", xmldoc) 

733 

734 def parse_machine(self, xmldoc): 

735 if 'canonical' in xmldoc.attrib: 

736 self.aliases[xmldoc.text] = xmldoc.attrib 

737 else: 

738 self.machines[xmldoc.text] = xmldoc.attrib 

739 

740 def format_dom(self): 

741 domain = super(LibvirtConfigCapsGuestDomain, self).format_dom() 

742 

743 if self.domtype is not None: 743 ↛ 745line 743 didn't jump to line 745 because the condition on line 743 was always true

744 domain.set("type", self.domtype) 

745 if self.emulator is not None: 745 ↛ 747line 745 didn't jump to line 747 because the condition on line 745 was always true

746 domain.append(self._text_node("emulator", self.emulator)) 

747 for mach_type, machine in self.machines.items(): 

748 domain.append(self._text_node("machine", mach_type, **machine)) 

749 for alias, machine in self.aliases.items(): 

750 domain.append(self._text_node("machine", alias, **machine)) 

751 

752 return domain 

753 

754 

755class LibvirtConfigGuestTimer(LibvirtConfigObject): 

756 

757 def __init__(self, **kwargs): 

758 super(LibvirtConfigGuestTimer, self).__init__(root_name="timer", 

759 **kwargs) 

760 

761 self.name = "platform" 

762 self.track = None 

763 self.tickpolicy = None 

764 self.present = None 

765 

766 def format_dom(self): 

767 tm = super(LibvirtConfigGuestTimer, self).format_dom() 

768 

769 tm.set("name", self.name) 

770 if self.track is not None: 

771 tm.set("track", self.track) 

772 if self.tickpolicy is not None: 

773 tm.set("tickpolicy", self.tickpolicy) 

774 if self.present is not None: 

775 tm.set("present", self.get_yes_no_str(self.present)) 

776 

777 return tm 

778 

779 

780class LibvirtConfigGuestClock(LibvirtConfigObject): 

781 

782 def __init__(self, **kwargs): 

783 super(LibvirtConfigGuestClock, self).__init__(root_name="clock", 

784 **kwargs) 

785 

786 self.offset = "utc" 

787 self.adjustment = None 

788 self.timezone = None 

789 self.timers = [] 

790 

791 def format_dom(self): 

792 clk = super(LibvirtConfigGuestClock, self).format_dom() 

793 

794 clk.set("offset", self.offset) 

795 if self.adjustment: 

796 clk.set("adjustment", self.adjustment) 

797 elif self.timezone: 

798 clk.set("timezone", self.timezone) 

799 

800 for tm in self.timers: 

801 clk.append(tm.format_dom()) 

802 

803 return clk 

804 

805 def add_timer(self, tm): 

806 self.timers.append(tm) 

807 

808 

809class LibvirtConfigCPUFeature(LibvirtConfigObject): 

810 

811 def __init__(self, name=None, **kwargs): 

812 super(LibvirtConfigCPUFeature, self).__init__(root_name='feature', 

813 **kwargs) 

814 

815 self.name = name 

816 self.policy = "require" 

817 

818 def parse_dom(self, xmldoc): 

819 super(LibvirtConfigCPUFeature, self).parse_dom(xmldoc) 

820 

821 self.name = xmldoc.get("name") 

822 self.policy = xmldoc.get("policy", "require") 

823 

824 def format_dom(self): 

825 ft = super(LibvirtConfigCPUFeature, self).format_dom() 

826 

827 ft.set("name", self.name) 

828 

829 return ft 

830 

831 def __eq__(self, obj): 

832 return obj.name == self.name 

833 

834 def __ne__(self, obj): 

835 return obj.name != self.name 

836 

837 def __hash__(self): 

838 return hash(self.name) 

839 

840 

841class LibvirtConfigCPUMaxPhysAddr(LibvirtConfigObject): 

842 

843 def __init__(self, **kwargs): 

844 super(LibvirtConfigCPUMaxPhysAddr, self).__init__( 

845 root_name='maxphysaddr', **kwargs) 

846 

847 self.mode = None 

848 self.bits = None 

849 

850 def parse_dom(self, xmldoc): 

851 super(LibvirtConfigCPUMaxPhysAddr, self).parse_dom(xmldoc) 

852 

853 self.mode = xmldoc.get("mode") 

854 if xmldoc.get("bits") is not None: 

855 self.bits = int(xmldoc.get("bits")) 

856 

857 def format_dom(self): 

858 m = super(LibvirtConfigCPUMaxPhysAddr, self).format_dom() 

859 

860 m.set("mode", self.mode) 

861 

862 if self.bits: 

863 m.set("bits", str(self.bits)) 

864 

865 return m 

866 

867 

868class LibvirtConfigGuestCPUMaxPhysAddr(LibvirtConfigCPUMaxPhysAddr): 

869 pass 

870 

871 

872class LibvirtConfigCPU(LibvirtConfigObject): 

873 

874 def __init__(self, **kwargs): 

875 super(LibvirtConfigCPU, self).__init__(root_name='cpu', 

876 **kwargs) 

877 

878 self.arch = None 

879 self.vendor = None 

880 self.model = None 

881 

882 self.sockets = None 

883 self.cores = None 

884 self.threads = None 

885 

886 self.maxphysaddr = None 

887 

888 self.features = set() 

889 

890 def parse_dom(self, xmldoc): 

891 super(LibvirtConfigCPU, self).parse_dom(xmldoc) 

892 

893 for c in xmldoc: 

894 if c.tag == "arch": 

895 self.arch = c.text 

896 elif c.tag == "model": 

897 self.model = c.text 

898 elif c.tag == "vendor": 

899 self.vendor = c.text 

900 elif c.tag == "topology": 

901 self.sockets = int(c.get("sockets")) 

902 self.cores = int(c.get("cores")) 

903 self.threads = int(c.get("threads")) 

904 elif c.tag == "maxphysaddr": 

905 self.maxphysaddr = LibvirtConfigCPUMaxPhysAddr() 

906 self.maxphysaddr.parse_dom(c) 

907 elif c.tag == "feature": 

908 f = LibvirtConfigCPUFeature() 

909 f.parse_dom(c) 

910 if f.policy != "disable": 910 ↛ 893line 910 didn't jump to line 893 because the condition on line 910 was always true

911 self.add_feature(f) 

912 

913 def format_dom(self): 

914 cpu = super(LibvirtConfigCPU, self).format_dom() 

915 

916 if self.arch is not None: 

917 cpu.append(self._text_node("arch", self.arch)) 

918 if self.model is not None: 

919 cpu.append(self._text_node("model", self.model)) 

920 if self.vendor is not None: 

921 cpu.append(self._text_node("vendor", self.vendor)) 

922 

923 if (self.sockets is not None and 

924 self.cores is not None and 

925 self.threads is not None): 

926 top = etree.Element("topology") 

927 top.set("sockets", str(self.sockets)) 

928 top.set("cores", str(self.cores)) 

929 top.set("threads", str(self.threads)) 

930 cpu.append(top) 

931 

932 if self.maxphysaddr is not None: 

933 cpu.append(self.maxphysaddr.format_dom()) 

934 

935 # sorting the features to allow more predictable tests 

936 for f in sorted(self.features, key=lambda x: x.name): 

937 cpu.append(f.format_dom()) 

938 

939 return cpu 

940 

941 def add_feature(self, feat): 

942 self.features.add(feat) 

943 

944 

945class LibvirtConfigGuestCPUFeature(LibvirtConfigCPUFeature): 

946 

947 def __init__(self, name=None, policy="require", **kwargs): 

948 super(LibvirtConfigGuestCPUFeature, self).__init__(name, **kwargs) 

949 

950 self.policy = policy 

951 

952 def format_dom(self): 

953 ft = super(LibvirtConfigGuestCPUFeature, self).format_dom() 

954 

955 ft.set("policy", self.policy) 

956 

957 return ft 

958 

959 

960class LibvirtConfigGuestCPUNUMACell(LibvirtConfigObject): 

961 

962 def __init__(self, **kwargs): 

963 super(LibvirtConfigGuestCPUNUMACell, self).__init__(root_name="cell", 

964 **kwargs) 

965 self.id = None 

966 self.cpus = None 

967 self.memory = None 

968 self.memAccess = None 

969 

970 def parse_dom(self, xmldoc): 

971 if xmldoc.get("id") is not None: 971 ↛ 973line 971 didn't jump to line 973 because the condition on line 971 was always true

972 self.id = int(xmldoc.get("id")) 

973 if xmldoc.get("memory") is not None: 973 ↛ 975line 973 didn't jump to line 975 because the condition on line 973 was always true

974 self.memory = int(xmldoc.get("memory")) 

975 if xmldoc.get("cpus") is not None: 975 ↛ 977line 975 didn't jump to line 977 because the condition on line 975 was always true

976 self.cpus = hardware.parse_cpu_spec(xmldoc.get("cpus")) 

977 self.memAccess = xmldoc.get("memAccess") 

978 

979 def format_dom(self): 

980 cell = super(LibvirtConfigGuestCPUNUMACell, self).format_dom() 

981 

982 if self.id is not None: 982 ↛ 984line 982 didn't jump to line 984 because the condition on line 982 was always true

983 cell.set("id", str(self.id)) 

984 if self.cpus is not None: 984 ↛ 987line 984 didn't jump to line 987 because the condition on line 984 was always true

985 cell.set("cpus", 

986 hardware.format_cpu_spec(self.cpus)) 

987 if self.memory is not None: 987 ↛ 989line 987 didn't jump to line 989 because the condition on line 987 was always true

988 cell.set("memory", str(self.memory)) 

989 if self.memAccess is not None: 

990 cell.set("memAccess", self.memAccess) 

991 

992 return cell 

993 

994 

995class LibvirtConfigGuestCPUNUMA(LibvirtConfigObject): 

996 

997 def __init__(self, **kwargs): 

998 super(LibvirtConfigGuestCPUNUMA, self).__init__(root_name="numa", 

999 **kwargs) 

1000 

1001 self.cells = [] 

1002 

1003 def parse_dom(self, xmldoc): 

1004 super(LibvirtConfigGuestCPUNUMA, self).parse_dom(xmldoc) 

1005 

1006 for child in xmldoc: 

1007 if child.tag == "cell": 1007 ↛ 1006line 1007 didn't jump to line 1006 because the condition on line 1007 was always true

1008 cell = LibvirtConfigGuestCPUNUMACell() 

1009 cell.parse_dom(child) 

1010 self.cells.append(cell) 

1011 

1012 def format_dom(self): 

1013 numa = super(LibvirtConfigGuestCPUNUMA, self).format_dom() 

1014 

1015 for cell in self.cells: 

1016 numa.append(cell.format_dom()) 

1017 

1018 return numa 

1019 

1020 

1021class LibvirtConfigGuestCPU(LibvirtConfigCPU): 

1022 

1023 def __init__(self, **kwargs): 

1024 super(LibvirtConfigGuestCPU, self).__init__(**kwargs) 

1025 

1026 self.mode = None 

1027 self.match = "exact" 

1028 self.numa = None 

1029 self.maxphysaddr = None 

1030 

1031 def parse_dom(self, xmldoc): 

1032 super(LibvirtConfigGuestCPU, self).parse_dom(xmldoc) 

1033 self.mode = xmldoc.get('mode') 

1034 self.match = xmldoc.get('match') 

1035 for child in xmldoc: 

1036 if child.tag == "numa": 1036 ↛ 1037line 1036 didn't jump to line 1037 because the condition on line 1036 was never true

1037 numa = LibvirtConfigGuestCPUNUMA() 

1038 numa.parse_dom(child) 

1039 self.numa = numa 

1040 elif child.tag == "maxphysaddr": 1040 ↛ 1041line 1040 didn't jump to line 1041 because the condition on line 1040 was never true

1041 m = LibvirtConfigGuestCPUMaxPhysAddr() 

1042 m.parse_dom(child) 

1043 self.maxphysaddr = m 

1044 

1045 def format_dom(self): 

1046 cpu = super(LibvirtConfigGuestCPU, self).format_dom() 

1047 

1048 if self.mode: 

1049 cpu.set("mode", self.mode) 

1050 cpu.set("match", self.match) 

1051 if self.numa is not None: 

1052 cpu.append(self.numa.format_dom()) 

1053 

1054 return cpu 

1055 

1056 

1057class LibvirtConfigGuestSMBIOS(LibvirtConfigObject): 

1058 

1059 def __init__(self, **kwargs): 

1060 super(LibvirtConfigGuestSMBIOS, self).__init__(root_name="smbios", 

1061 **kwargs) 

1062 

1063 self.mode = "sysinfo" 

1064 

1065 def format_dom(self): 

1066 smbios = super(LibvirtConfigGuestSMBIOS, self).format_dom() 

1067 smbios.set("mode", self.mode) 

1068 

1069 return smbios 

1070 

1071 

1072class LibvirtConfigGuestSysinfo(LibvirtConfigObject): 

1073 

1074 def __init__(self, **kwargs): 

1075 super(LibvirtConfigGuestSysinfo, self).__init__(root_name="sysinfo", 

1076 **kwargs) 

1077 

1078 self.type = "smbios" 

1079 self.bios_vendor = None 

1080 self.bios_version = None 

1081 self.system_manufacturer = None 

1082 self.system_product = None 

1083 self.system_version = None 

1084 self.system_serial = None 

1085 self.system_uuid = None 

1086 self.system_family = None 

1087 

1088 def format_dom(self): 

1089 sysinfo = super(LibvirtConfigGuestSysinfo, self).format_dom() 

1090 

1091 sysinfo.set("type", self.type) 

1092 

1093 bios = etree.Element("bios") 

1094 system = etree.Element("system") 

1095 

1096 if self.bios_vendor is not None: 

1097 bios.append(self._text_node("entry", self.bios_vendor, 

1098 name="vendor")) 

1099 

1100 if self.bios_version is not None: 

1101 bios.append(self._text_node("entry", self.bios_version, 

1102 name="version")) 

1103 

1104 if self.system_manufacturer is not None: 

1105 system.append(self._text_node("entry", self.system_manufacturer, 

1106 name="manufacturer")) 

1107 

1108 if self.system_product is not None: 

1109 system.append(self._text_node("entry", self.system_product, 

1110 name="product")) 

1111 

1112 if self.system_version is not None: 

1113 system.append(self._text_node("entry", self.system_version, 

1114 name="version")) 

1115 

1116 if self.system_serial is not None: 

1117 system.append(self._text_node("entry", self.system_serial, 

1118 name="serial")) 

1119 

1120 if self.system_uuid is not None: 

1121 system.append(self._text_node("entry", self.system_uuid, 

1122 name="uuid")) 

1123 

1124 if self.system_family is not None: 

1125 system.append(self._text_node("entry", self.system_family, 

1126 name="family")) 

1127 

1128 if len(list(bios)) > 0: 

1129 sysinfo.append(bios) 

1130 

1131 if len(list(system)) > 0: 

1132 sysinfo.append(system) 

1133 

1134 return sysinfo 

1135 

1136 

1137class LibvirtConfigGuestDevice(LibvirtConfigObject): 

1138 

1139 def __init__(self, **kwargs): 

1140 super(LibvirtConfigGuestDevice, self).__init__(**kwargs) 

1141 

1142 @property 

1143 def uses_virtio(self): 

1144 return False 

1145 

1146 

1147class LibvirtConfigGuestVTPM(LibvirtConfigGuestDevice): 

1148 

1149 def __init__(self, vtpm_config, vtpm_secret_uuid, **kwargs): 

1150 super(LibvirtConfigGuestVTPM, self).__init__(root_name="tpm", **kwargs) 

1151 

1152 self.version = vtpm_config.version 

1153 self.model = vtpm_config.model 

1154 self.secret_uuid = vtpm_secret_uuid 

1155 

1156 def format_dom(self): 

1157 # <tpm model='$model'> 

1158 dev = super(LibvirtConfigGuestVTPM, self).format_dom() 

1159 dev.set("model", self.model) 

1160 # <backend type='emulator' version='$version'> 

1161 back = etree.Element("backend") 

1162 back.set("type", "emulator") 

1163 back.set("version", self.version) 

1164 # <encryption secret='$secret_uuid'/> 

1165 enc = etree.Element("encryption") 

1166 enc.set("secret", self.secret_uuid) 

1167 

1168 back.append(enc) 

1169 dev.append(back) 

1170 

1171 return dev 

1172 

1173 

1174class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice): 

1175 

1176 def __init__(self, **kwargs): 

1177 super(LibvirtConfigGuestDisk, self).__init__(root_name="disk", 

1178 **kwargs) 

1179 

1180 self.source_type = "file" 

1181 self.source_device = "disk" 

1182 self.driver_name = None 

1183 self.driver_format = None 

1184 self.driver_cache = None 

1185 self.driver_discard = None 

1186 self.driver_io = None 

1187 self.driver_iommu = False 

1188 self.source_path = None 

1189 self.source_protocol = None 

1190 self.source_name = None 

1191 self.source_hosts = [] 

1192 self.source_ports = [] 

1193 self.target_dev = None 

1194 self.target_path = None 

1195 self.target_bus = None 

1196 self.auth_username = None 

1197 self.auth_secret_type = None 

1198 self.auth_secret_uuid = None 

1199 self.serial = None 

1200 self.disk_read_bytes_sec = None 

1201 self.disk_read_iops_sec = None 

1202 self.disk_write_bytes_sec = None 

1203 self.disk_write_iops_sec = None 

1204 self.disk_total_bytes_sec = None 

1205 self.disk_total_iops_sec = None 

1206 self.disk_read_bytes_sec_max = None 

1207 self.disk_write_bytes_sec_max = None 

1208 self.disk_total_bytes_sec_max = None 

1209 self.disk_read_iops_sec_max = None 

1210 self.disk_write_iops_sec_max = None 

1211 self.disk_total_iops_sec_max = None 

1212 self.disk_size_iops_sec = None 

1213 self.logical_block_size = None 

1214 self.physical_block_size = None 

1215 self.readonly = False 

1216 self.shareable = False 

1217 self.snapshot = None 

1218 self.backing_store = None 

1219 self.device_addr = None 

1220 self.boot_order = None 

1221 self.mirror = None 

1222 self.volume_encryption = None 

1223 self.ephemeral_encryption = None 

1224 self.alias = None 

1225 

1226 def _format_iotune(self, dev): 

1227 iotune = etree.Element("iotune") 

1228 

1229 if self.disk_read_bytes_sec is not None: 

1230 iotune.append(self._text_node("read_bytes_sec", 

1231 self.disk_read_bytes_sec)) 

1232 

1233 if self.disk_read_iops_sec is not None: 

1234 iotune.append(self._text_node("read_iops_sec", 

1235 self.disk_read_iops_sec)) 

1236 

1237 if self.disk_write_bytes_sec is not None: 

1238 iotune.append(self._text_node("write_bytes_sec", 

1239 self.disk_write_bytes_sec)) 

1240 

1241 if self.disk_write_iops_sec is not None: 

1242 iotune.append(self._text_node("write_iops_sec", 

1243 self.disk_write_iops_sec)) 

1244 

1245 if self.disk_total_bytes_sec is not None: 

1246 iotune.append(self._text_node("total_bytes_sec", 

1247 self.disk_total_bytes_sec)) 

1248 

1249 if self.disk_total_iops_sec is not None: 

1250 iotune.append(self._text_node("total_iops_sec", 

1251 self.disk_total_iops_sec)) 

1252 

1253 if self.disk_read_bytes_sec_max is not None: 

1254 iotune.append(self._text_node("read_bytes_sec_max", 

1255 self.disk_read_bytes_sec_max)) 

1256 

1257 if self.disk_write_bytes_sec_max is not None: 

1258 iotune.append(self._text_node("write_bytes_sec_max", 

1259 self.disk_write_bytes_sec_max)) 

1260 

1261 if self.disk_total_bytes_sec_max is not None: 

1262 iotune.append(self._text_node("total_bytes_sec_max", 

1263 self.disk_total_bytes_sec_max)) 

1264 

1265 if self.disk_read_iops_sec_max is not None: 

1266 iotune.append(self._text_node("read_iops_sec_max", 

1267 self.disk_read_iops_sec_max)) 

1268 

1269 if self.disk_write_iops_sec_max is not None: 

1270 iotune.append(self._text_node("write_iops_sec_max", 

1271 self.disk_write_iops_sec_max)) 

1272 

1273 if self.disk_total_iops_sec_max is not None: 

1274 iotune.append(self._text_node("total_iops_sec_max", 

1275 self.disk_total_iops_sec_max)) 

1276 

1277 if self.disk_size_iops_sec is not None: 

1278 iotune.append(self._text_node("size_iops_sec", 

1279 self.disk_size_iops_sec)) 

1280 

1281 if len(iotune) > 0: 

1282 dev.append(iotune) 

1283 

1284 @property 

1285 def uses_virtio(self): 

1286 return 'virtio' == self.target_bus 

1287 

1288 def format_dom(self): 

1289 dev = super(LibvirtConfigGuestDisk, self).format_dom() 

1290 

1291 dev.set("type", self.source_type) 

1292 dev.set("device", self.source_device) 

1293 if any((self.driver_name, self.driver_format, self.driver_cache, 

1294 self.driver_discard, self.driver_iommu)): 

1295 drv = etree.Element("driver") 

1296 if self.driver_name is not None: 

1297 drv.set("name", self.driver_name) 

1298 if self.driver_format is not None: 

1299 drv.set("type", self.driver_format) 

1300 if self.driver_cache is not None: 

1301 drv.set("cache", self.driver_cache) 

1302 if self.driver_discard is not None: 

1303 drv.set("discard", self.driver_discard) 

1304 if self.driver_io is not None: 

1305 drv.set("io", self.driver_io) 

1306 if self.driver_iommu: 

1307 drv.set("iommu", "on") 

1308 dev.append(drv) 

1309 

1310 if self.alias: 

1311 alias = etree.Element("alias") 

1312 alias.set("name", self.alias) 

1313 dev.append(alias) 

1314 

1315 if self.source_type == "file": 

1316 source = etree.Element("source", file=self.source_path) 

1317 dev.append(source) 

1318 elif self.source_type == "block": 

1319 source = etree.Element("source", dev=self.source_path) 

1320 dev.append(source) 

1321 elif self.source_type == "mount": 1321 ↛ 1322line 1321 didn't jump to line 1322 because the condition on line 1321 was never true

1322 source = etree.Element("source", dir=self.source_path) 

1323 dev.append(source) 

1324 elif self.source_type == "network" and self.source_protocol: 

1325 source = etree.Element("source", protocol=self.source_protocol) 

1326 if self.source_name is not None: 

1327 source.set('name', self.source_name) 

1328 hosts_info = zip(self.source_hosts, self.source_ports) 

1329 for name, port in hosts_info: 

1330 host = etree.Element('host', name=name) 

1331 if port is not None: 

1332 host.set('port', port) 

1333 source.append(host) 

1334 dev.append(source) 

1335 

1336 if self.ephemeral_encryption: 

1337 # NOTE(melwitt): <encryption> should be a sub element of <source> 

1338 # in order to ensure the image uses encryption. 

1339 # See the following for more details: 

1340 # https://libvirt.org/formatdomain.html#hard-drives-floppy-disks-cdroms 

1341 # https://bugzilla.redhat.com/show_bug.cgi?id=1371022#c13 

1342 source.append(self.ephemeral_encryption.format_dom()) 

1343 

1344 if self.auth_secret_type is not None: 

1345 auth = etree.Element("auth") 

1346 auth.set("username", self.auth_username) 

1347 auth.append(etree.Element("secret", type=self.auth_secret_type, 

1348 uuid=self.auth_secret_uuid)) 

1349 dev.append(auth) 

1350 

1351 if self.source_type == "mount": 1351 ↛ 1352line 1351 didn't jump to line 1352 because the condition on line 1351 was never true

1352 dev.append(etree.Element("target", dir=self.target_path)) 

1353 else: 

1354 dev.append(etree.Element("target", dev=self.target_dev, 

1355 bus=self.target_bus)) 

1356 

1357 if self.serial is not None and self.source_device != 'lun': 

1358 dev.append(self._text_node("serial", self.serial)) 

1359 

1360 self._format_iotune(dev) 

1361 

1362 # Block size tuning 

1363 if (self.logical_block_size is not None or 

1364 self.physical_block_size is not None): 

1365 

1366 blockio = etree.Element("blockio") 

1367 if self.logical_block_size is not None: 1367 ↛ 1370line 1367 didn't jump to line 1370 because the condition on line 1367 was always true

1368 blockio.set('logical_block_size', self.logical_block_size) 

1369 

1370 if self.physical_block_size is not None: 1370 ↛ 1373line 1370 didn't jump to line 1373 because the condition on line 1370 was always true

1371 blockio.set('physical_block_size', self.physical_block_size) 

1372 

1373 dev.append(blockio) 

1374 

1375 if self.readonly: 

1376 dev.append(etree.Element("readonly")) 

1377 if self.shareable: 

1378 dev.append(etree.Element("shareable")) 

1379 

1380 if self.boot_order: 

1381 dev.append(etree.Element("boot", order=self.boot_order)) 

1382 

1383 if self.device_addr: 

1384 dev.append(self.device_addr.format_dom()) 

1385 

1386 if self.volume_encryption: 

1387 dev.append(self.volume_encryption.format_dom()) 

1388 

1389 return dev 

1390 

1391 def parse_dom(self, xmldoc): 

1392 super(LibvirtConfigGuestDisk, self).parse_dom(xmldoc) 

1393 

1394 self.source_type = xmldoc.get('type') 

1395 self.snapshot = xmldoc.get('snapshot') 

1396 

1397 for c in xmldoc: 

1398 if c.tag == 'driver': 

1399 self.driver_name = c.get('name') 

1400 self.driver_format = c.get('type') 

1401 self.driver_cache = c.get('cache') 

1402 self.driver_discard = c.get('discard') 

1403 self.driver_io = c.get('io') 

1404 self.driver_iommu = c.get('iommu', '') == "on" 

1405 elif c.tag == 'source': 

1406 if self.source_type == 'file': 

1407 self.source_path = c.get('file') 

1408 elif self.source_type == 'block': 

1409 self.source_path = c.get('dev') 

1410 elif self.source_type == 'mount': 1410 ↛ 1411line 1410 didn't jump to line 1411 because the condition on line 1410 was never true

1411 self.source_path = c.get('dir') 

1412 elif self.source_type == 'network': 1412 ↛ 1419line 1412 didn't jump to line 1419 because the condition on line 1412 was always true

1413 self.source_protocol = c.get('protocol') 

1414 self.source_name = c.get('name') 

1415 for sub in c: 

1416 if sub.tag == 'host': 1416 ↛ 1415line 1416 didn't jump to line 1415 because the condition on line 1416 was always true

1417 self.source_hosts.append(sub.get('name')) 

1418 self.source_ports.append(sub.get('port')) 

1419 for sub in c: 

1420 if sub.tag == 'encryption': 

1421 e = LibvirtConfigGuestDiskEncryption() 

1422 e.parse_dom(sub) 

1423 self.ephemeral_encryption = e 

1424 

1425 elif c.tag == 'serial': 

1426 self.serial = c.text 

1427 elif c.tag == 'target': 

1428 if self.source_type == 'mount': 1428 ↛ 1429line 1428 didn't jump to line 1429 because the condition on line 1428 was never true

1429 self.target_path = c.get('dir') 

1430 else: 

1431 self.target_dev = c.get('dev') 

1432 

1433 self.target_bus = c.get('bus', None) 

1434 elif c.tag == 'backingStore': 

1435 b = LibvirtConfigGuestDiskBackingStore() 

1436 b.parse_dom(c) 

1437 self.backing_store = b 

1438 elif c.tag == 'readonly': 

1439 self.readonly = True 

1440 elif c.tag == 'shareable': 

1441 self.shareable = True 

1442 elif c.tag == 'address': 

1443 obj = LibvirtConfigGuestDeviceAddress.parse_dom(c) 

1444 self.device_addr = obj 

1445 elif c.tag == 'boot': 

1446 self.boot_order = c.get('order') 

1447 elif c.tag == 'mirror': 

1448 m = LibvirtConfigGuestDiskMirror() 

1449 m.parse_dom(c) 

1450 self.mirror = m 

1451 elif c.tag == 'encryption': 1451 ↛ 1452line 1451 didn't jump to line 1452 because the condition on line 1451 was never true

1452 e = LibvirtConfigGuestDiskEncryption() 

1453 e.parse_dom(c) 

1454 self.volume_encryption = e 

1455 elif c.tag == 'alias': 

1456 self.alias = c.get('name') 

1457 

1458 

1459class LibvirtConfigGuestDiskBackingStore(LibvirtConfigObject): 

1460 def __init__(self, **kwargs): 

1461 super(LibvirtConfigGuestDiskBackingStore, self).__init__( 

1462 root_name="backingStore", **kwargs) 

1463 

1464 self.index = None 

1465 self.source_type = None 

1466 self.source_file = None 

1467 self.source_protocol = None 

1468 self.source_name = None 

1469 self.source_hosts = [] 

1470 self.source_ports = [] 

1471 self.driver_name = None 

1472 self.driver_format = None 

1473 self.backing_store = None 

1474 

1475 def parse_dom(self, xmldoc): 

1476 super(LibvirtConfigGuestDiskBackingStore, self).parse_dom(xmldoc) 

1477 

1478 self.source_type = xmldoc.get('type') 

1479 self.index = xmldoc.get('index') 

1480 

1481 for c in xmldoc: 

1482 if c.tag == 'driver': 

1483 self.driver_name = c.get('name') 

1484 self.driver_format = c.get('type') 

1485 elif c.tag == 'source': 

1486 self.source_file = c.get('file') 

1487 self.source_protocol = c.get('protocol') 

1488 self.source_name = c.get('name') 

1489 for d in c: 

1490 if d.tag == 'host': 1490 ↛ 1489line 1490 didn't jump to line 1489 because the condition on line 1490 was always true

1491 self.source_hosts.append(d.get('name')) 

1492 self.source_ports.append(d.get('port')) 

1493 elif c.tag == 'backingStore': 

1494 if len(c): 

1495 self.backing_store = LibvirtConfigGuestDiskBackingStore() 

1496 self.backing_store.parse_dom(c) 

1497 

1498 

1499class LibvirtConfigGuestSnapshotDisk(LibvirtConfigObject): 

1500 """Disk class for handling disk information in snapshots. 

1501 

1502 Similar to LibvirtConfigGuestDisk, but used to represent 

1503 disk entities in <domainsnapshot> structures rather than 

1504 real devices. These typically have fewer members, and 

1505 different expectations for which fields are required. 

1506 """ 

1507 

1508 def __init__(self, **kwargs): 

1509 super(LibvirtConfigGuestSnapshotDisk, self).__init__(root_name="disk", 

1510 **kwargs) 

1511 

1512 self.source_type = None 

1513 self.source_device = None 

1514 self.name = None 

1515 self.snapshot = None 

1516 self.driver_name = None 

1517 self.driver_format = None 

1518 self.driver_cache = None 

1519 self.source_path = None 

1520 self.source_protocol = None 

1521 self.source_name = None 

1522 self.source_hosts = [] 

1523 self.source_ports = [] 

1524 self.target_dev = None 

1525 self.target_path = None 

1526 self.target_bus = None 

1527 self.auth_username = None 

1528 self.auth_secret_type = None 

1529 self.auth_secret_uuid = None 

1530 self.serial = None 

1531 

1532 def format_dom(self): 

1533 dev = super(LibvirtConfigGuestSnapshotDisk, self).format_dom() 

1534 

1535 if self.name: 1535 ↛ 1537line 1535 didn't jump to line 1537 because the condition on line 1535 was always true

1536 dev.attrib['name'] = self.name 

1537 if self.snapshot: 1537 ↛ 1540line 1537 didn't jump to line 1540 because the condition on line 1537 was always true

1538 dev.attrib['snapshot'] = self.snapshot 

1539 

1540 if self.source_type: 

1541 dev.set("type", self.source_type) 

1542 

1543 if self.source_device: 1543 ↛ 1544line 1543 didn't jump to line 1544 because the condition on line 1543 was never true

1544 dev.set("device", self.source_device) 

1545 if (self.driver_name is not None or 

1546 self.driver_format is not None or 

1547 self.driver_cache is not None): 

1548 drv = etree.Element("driver") 

1549 if self.driver_name is not None: 

1550 drv.set("name", self.driver_name) 

1551 if self.driver_format is not None: 

1552 drv.set("type", self.driver_format) 

1553 if self.driver_cache is not None: 

1554 drv.set("cache", self.driver_cache) 

1555 dev.append(drv) 

1556 

1557 if self.source_type == "file": 

1558 dev.append(etree.Element("source", file=self.source_path)) 

1559 elif self.source_type == "block": 1559 ↛ 1560line 1559 didn't jump to line 1560 because the condition on line 1559 was never true

1560 dev.append(etree.Element("source", dev=self.source_path)) 

1561 elif self.source_type == "mount": 1561 ↛ 1562line 1561 didn't jump to line 1562 because the condition on line 1561 was never true

1562 dev.append(etree.Element("source", dir=self.source_path)) 

1563 elif self.source_type == "network": 

1564 source = etree.Element("source", protocol=self.source_protocol) 

1565 if self.source_name is not None: 1565 ↛ 1567line 1565 didn't jump to line 1567 because the condition on line 1565 was always true

1566 source.set('name', self.source_name) 

1567 hosts_info = zip(self.source_hosts, self.source_ports) 

1568 for name, port in hosts_info: 

1569 host = etree.Element('host', name=name) 

1570 if port is not None: 1570 ↛ 1572line 1570 didn't jump to line 1572 because the condition on line 1570 was always true

1571 host.set('port', port) 

1572 source.append(host) 

1573 dev.append(source) 

1574 

1575 if self.auth_secret_type is not None: 1575 ↛ 1576line 1575 didn't jump to line 1576 because the condition on line 1575 was never true

1576 auth = etree.Element("auth") 

1577 auth.set("username", self.auth_username) 

1578 auth.append(etree.Element("secret", type=self.auth_secret_type, 

1579 uuid=self.auth_secret_uuid)) 

1580 dev.append(auth) 

1581 

1582 if self.source_type == "mount": 1582 ↛ 1583line 1582 didn't jump to line 1583 because the condition on line 1582 was never true

1583 dev.append(etree.Element("target", dir=self.target_path)) 

1584 else: 

1585 if self.target_bus and self.target_dev: 1585 ↛ 1586line 1585 didn't jump to line 1586 because the condition on line 1585 was never true

1586 dev.append(etree.Element("target", dev=self.target_dev, 

1587 bus=self.target_bus)) 

1588 

1589 return dev 

1590 

1591 def parse_dom(self, xmldoc): 

1592 super(LibvirtConfigGuestSnapshotDisk, self).parse_dom(xmldoc) 

1593 

1594 self.source_type = xmldoc.get('type') 

1595 self.snapshot = xmldoc.get('snapshot') 

1596 

1597 for c in xmldoc: 

1598 if c.tag == 'driver': 

1599 self.driver_name = c.get('name') 

1600 self.driver_format = c.get('type') 

1601 self.driver_cache = c.get('cache') 

1602 elif c.tag == 'source': 

1603 if self.source_type == 'file': 

1604 self.source_path = c.get('file') 

1605 elif self.source_type == 'block': 

1606 self.source_path = c.get('dev') 

1607 elif self.source_type == 'mount': 

1608 self.source_path = c.get('dir') 

1609 elif self.source_type == 'network': 

1610 self.source_protocol = c.get('protocol') 

1611 self.source_name = c.get('name') 

1612 for sub in c: 

1613 if sub.tag == 'host': 

1614 self.source_hosts.append(sub.get('name')) 

1615 self.source_ports.append(sub.get('port')) 

1616 

1617 elif c.tag == 'serial': 

1618 self.serial = c.text 

1619 

1620 for c in xmldoc: 

1621 if c.tag == 'target': 

1622 if self.source_type == 'mount': 

1623 self.target_path = c.get('dir') 

1624 else: 

1625 self.target_dev = c.get('dev') 

1626 

1627 self.target_bus = c.get('bus', None) 

1628 

1629 

1630class LibvirtConfigGuestFilesys(LibvirtConfigGuestDevice): 

1631 

1632 def __init__(self, **kwargs): 

1633 super(LibvirtConfigGuestFilesys, self).__init__(root_name="filesystem", 

1634 **kwargs) 

1635 

1636 self.source_type = "mount" 

1637 self.accessmode = None 

1638 self.source_dir = None 

1639 self.source_file = None 

1640 self.source_dev = None 

1641 self.target_dir = "/" 

1642 self.driver_type = "loop" 

1643 self.driver_format = "raw" 

1644 

1645 def format_dom(self): 

1646 dev = super(LibvirtConfigGuestFilesys, self).format_dom() 

1647 

1648 dev.set("type", self.source_type) 

1649 if self.accessmode: 

1650 dev.set("accessmode", self.accessmode) 

1651 

1652 if self.source_type == "file": 

1653 dev.append(etree.Element("driver", type = self.driver_type, 

1654 format = self.driver_format)) 

1655 dev.append(etree.Element("source", file=self.source_file)) 

1656 elif self.source_type == "block": 

1657 dev.append(etree.Element("source", dev=self.source_dev)) 

1658 elif self.source_type == "mount" and self.driver_type == "virtiofs": 

1659 dev.append(etree.Element("driver", type=self.driver_type)) 

1660 dev.append(etree.Element("source", dir=self.source_dir)) 

1661 else: 

1662 dev.append(etree.Element("source", dir=self.source_dir)) 

1663 dev.append(etree.Element("target", dir=self.target_dir)) 

1664 

1665 return dev 

1666 

1667 def parse_dom(self, xmldoc): 

1668 super(LibvirtConfigGuestFilesys, self).parse_dom(xmldoc) 

1669 

1670 self.source_type = xmldoc.get('type') 

1671 self.accessmode = xmldoc.get('accessmode') 

1672 

1673 for c in xmldoc: 

1674 if c.tag == 'driver': 

1675 if self.source_type == 'file': 

1676 self.driver_type = c.get('type') 

1677 self.driver_format = c.get('format') 

1678 if self.source_type == 'mount': 

1679 self.driver_type = c.get('type') 

1680 elif c.tag == 'source': 

1681 if self.source_type == 'file': 

1682 self.source_file = c.get('file') 

1683 elif self.source_type == 'block': 

1684 self.source_dev = c.get('dev') 

1685 else: 

1686 self.source_dir = c.get('dir') 

1687 elif c.tag == 'target': 1687 ↛ 1673line 1687 didn't jump to line 1673 because the condition on line 1687 was always true

1688 self.target_dir = c.get('dir') 

1689 

1690 

1691class LibvirtConfigGuestDiskEncryptionSecret(LibvirtConfigObject): 

1692 def __init__(self, **kwargs): 

1693 super(LibvirtConfigGuestDiskEncryptionSecret, self).__init__( 

1694 root_name='diskencryptionsecret', **kwargs) 

1695 self.type = None 

1696 self.uuid = None 

1697 

1698 def parse_dom(self, xmldoc): 

1699 self.type = xmldoc.get('type') 

1700 self.uuid = xmldoc.get('uuid') 

1701 

1702 def format_dom(self): 

1703 obj = etree.Element("secret") 

1704 obj.set("type", self.type) 

1705 obj.set("uuid", self.uuid) 

1706 return obj 

1707 

1708 

1709class LibvirtConfigGuestDiskEncryption(LibvirtConfigObject): 

1710 """https://libvirt.org/formatstorageencryption.html 

1711 """ 

1712 

1713 def __init__(self, **kwargs): 

1714 super(LibvirtConfigGuestDiskEncryption, self).__init__( 

1715 root_name='diskencryption', **kwargs) 

1716 self.format = None 

1717 self.secret = None 

1718 

1719 def parse_dom(self, xmldoc): 

1720 self.format = xmldoc.get('format') 

1721 for c in xmldoc: 

1722 if c.tag == 'secret': 1722 ↛ 1721line 1722 didn't jump to line 1721 because the condition on line 1722 was always true

1723 m = LibvirtConfigGuestDiskEncryptionSecret() 

1724 m.parse_dom(c) 

1725 self.secret = m 

1726 

1727 def format_dom(self): 

1728 obj = etree.Element("encryption") 

1729 obj.set("format", self.format) 

1730 obj.append(self.secret.format_dom()) 

1731 

1732 return obj 

1733 

1734 

1735class LibvirtConfigGuestDiskMirror(LibvirtConfigObject): 

1736 

1737 def __init__(self, **kwargs): 

1738 super(LibvirtConfigGuestDiskMirror, self).__init__( 

1739 root_name='diskmirror', **kwargs) 

1740 self.ready = None 

1741 

1742 def parse_dom(self, xmldoc): 

1743 self.ready = xmldoc.get('ready') 

1744 

1745 

1746class LibvirtConfigGuestIDMap(LibvirtConfigObject): 

1747 

1748 def __init__(self, **kwargs): 

1749 if 'root_name' not in kwargs: 

1750 kwargs['root_name'] = 'id' 

1751 super(LibvirtConfigGuestIDMap, self).__init__(**kwargs) 

1752 self.start = 0 

1753 self.target = 0 

1754 self.count = 10000 

1755 

1756 def parse_dom(self, xmldoc): 

1757 self.start = int(xmldoc.get('start')) 

1758 self.target = int(xmldoc.get('target')) 

1759 self.count = int(xmldoc.get('count')) 

1760 

1761 def format_dom(self): 

1762 obj = super(LibvirtConfigGuestIDMap, self).format_dom() 

1763 

1764 obj.set("start", str(self.start)) 

1765 obj.set("target", str(self.target)) 

1766 obj.set("count", str(self.count)) 

1767 

1768 return obj 

1769 

1770 

1771class LibvirtConfigGuestUIDMap(LibvirtConfigGuestIDMap): 

1772 

1773 def __init__(self, **kwargs): 

1774 super(LibvirtConfigGuestUIDMap, self).__init__(root_name="uid", 

1775 **kwargs) 

1776 

1777 

1778class LibvirtConfigGuestGIDMap(LibvirtConfigGuestIDMap): 

1779 

1780 def __init__(self, **kwargs): 

1781 super(LibvirtConfigGuestGIDMap, self).__init__(root_name="gid", 

1782 **kwargs) 

1783 

1784 

1785class LibvirtConfigGuestDeviceAddress(LibvirtConfigObject): 

1786 def __init__(self, type=None, **kwargs): 

1787 super(LibvirtConfigGuestDeviceAddress, self).__init__( 

1788 root_name='address', **kwargs) 

1789 self.type = type 

1790 

1791 def format_dom(self): 

1792 xml = super(LibvirtConfigGuestDeviceAddress, self).format_dom() 

1793 xml.set("type", self.type) 

1794 return xml 

1795 

1796 @staticmethod 

1797 def parse_dom(xmldoc): 

1798 addr_type = xmldoc.get('type') 

1799 if addr_type == 'pci': 

1800 obj = LibvirtConfigGuestDeviceAddressPCI() 

1801 elif addr_type == 'drive': 

1802 obj = LibvirtConfigGuestDeviceAddressDrive() 

1803 else: 

1804 return None 

1805 obj.parse_dom(xmldoc) 

1806 return obj 

1807 

1808 

1809class LibvirtConfigGuestDeviceAddressDrive(LibvirtConfigGuestDeviceAddress): 

1810 def __init__(self, **kwargs): 

1811 super(LibvirtConfigGuestDeviceAddressDrive, self).\ 

1812 __init__(type='drive', **kwargs) 

1813 self.controller = None 

1814 self.bus = None 

1815 self.target = None 

1816 self.unit = None 

1817 

1818 def format_dom(self): 

1819 xml = super(LibvirtConfigGuestDeviceAddressDrive, self).format_dom() 

1820 

1821 if self.controller is not None: 1821 ↛ 1823line 1821 didn't jump to line 1823 because the condition on line 1821 was always true

1822 xml.set("controller", str(self.controller)) 

1823 if self.bus is not None: 

1824 xml.set("bus", str(self.bus)) 

1825 if self.target is not None: 

1826 xml.set("target", str(self.target)) 

1827 if self.unit is not None: 

1828 xml.set("unit", str(self.unit)) 

1829 

1830 return xml 

1831 

1832 def parse_dom(self, xmldoc): 

1833 self.controller = xmldoc.get('controller') 

1834 self.bus = xmldoc.get('bus') 

1835 self.target = xmldoc.get('target') 

1836 self.unit = xmldoc.get('unit') 

1837 

1838 def format_address(self): 

1839 return None 

1840 

1841 

1842class LibvirtConfigGuestDeviceAddressPCI(LibvirtConfigGuestDeviceAddress): 

1843 def __init__(self, **kwargs): 

1844 super(LibvirtConfigGuestDeviceAddressPCI, self).\ 

1845 __init__(type='pci', **kwargs) 

1846 self.domain = None 

1847 self.bus = None 

1848 self.slot = None 

1849 self.function = None 

1850 

1851 def format_dom(self): 

1852 xml = super(LibvirtConfigGuestDeviceAddressPCI, self).format_dom() 

1853 

1854 if self.domain is not None: 1854 ↛ 1856line 1854 didn't jump to line 1856 because the condition on line 1854 was always true

1855 xml.set("domain", str(self.domain)) 

1856 if self.bus is not None: 1856 ↛ 1858line 1856 didn't jump to line 1858 because the condition on line 1856 was always true

1857 xml.set("bus", str(self.bus)) 

1858 if self.slot is not None: 1858 ↛ 1860line 1858 didn't jump to line 1860 because the condition on line 1858 was always true

1859 xml.set("slot", str(self.slot)) 

1860 if self.function is not None: 1860 ↛ 1863line 1860 didn't jump to line 1863 because the condition on line 1860 was always true

1861 xml.set("function", str(self.function)) 

1862 

1863 return xml 

1864 

1865 def parse_dom(self, xmldoc): 

1866 self.domain = xmldoc.get('domain') 

1867 self.bus = xmldoc.get('bus') 

1868 self.slot = xmldoc.get('slot') 

1869 self.function = xmldoc.get('function') 

1870 

1871 def format_address(self): 

1872 if self.domain is not None: 1872 ↛ exitline 1872 didn't return from function 'format_address' because the condition on line 1872 was always true

1873 return pci_utils.get_pci_address(self.domain[2:], 

1874 self.bus[2:], 

1875 self.slot[2:], 

1876 self.function[2:]) 

1877 

1878 

1879class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice): 

1880 

1881 def __init__(self, **kwargs): 

1882 super(LibvirtConfigGuestInterface, self).__init__( 

1883 root_name="interface", 

1884 **kwargs) 

1885 

1886 self.net_type = None 

1887 self.target_dev = None 

1888 self.model = None 

1889 self.mac_addr = None 

1890 self.script = None 

1891 self.source_dev = None 

1892 self.source_mode = "private" 

1893 self.vporttype = None 

1894 self.vportparams = [] 

1895 self.filtername = None 

1896 self.filterparams = [] 

1897 self.driver_name = None 

1898 self.driver_iommu = False 

1899 self.driver_packed = False 

1900 self.vhostuser_mode = None 

1901 self.vhostuser_path = None 

1902 self.vhostuser_type = None 

1903 self.vhost_queues = None 

1904 self.vhost_rx_queue_size = None 

1905 self.vhost_tx_queue_size = None 

1906 self.vif_inbound_peak = None 

1907 self.vif_inbound_burst = None 

1908 self.vif_inbound_average = None 

1909 self.vif_outbound_peak = None 

1910 self.vif_outbound_burst = None 

1911 self.vif_outbound_average = None 

1912 self.vlan = None 

1913 self.device_addr = None 

1914 self.mtu = None 

1915 self.alias = None 

1916 

1917 def __eq__(self, other): 

1918 if not isinstance(other, LibvirtConfigGuestInterface): 1918 ↛ 1919line 1918 didn't jump to line 1919 because the condition on line 1918 was never true

1919 return False 

1920 

1921 # NOTE(arches) Skip checking target_dev for vhostuser 

1922 # vif type; target_dev is not a valid value for vhostuser. 

1923 # NOTE(gibi): For macvtap cases the domain has a target_dev 

1924 # generated by libvirt. It is not set by the vif driver code 

1925 # so it is not in config returned by the vif driver so we 

1926 # should not match on that. 

1927 return ( 

1928 self.mac_addr == other.mac_addr and 

1929 self.net_type == other.net_type and 

1930 self.source_dev == other.source_dev and 

1931 (self.net_type == 'vhostuser' or not self.target_dev or 

1932 self.target_dev == other.target_dev) and 

1933 self.vhostuser_path == other.vhostuser_path) 

1934 

1935 @property 

1936 def uses_virtio(self): 

1937 return 'virtio' == self.model 

1938 

1939 def format_dom(self): 

1940 dev = super(LibvirtConfigGuestInterface, self).format_dom() 

1941 

1942 dev.set("type", self.net_type) 

1943 if self.net_type == "hostdev": 

1944 dev.set("managed", "yes") 

1945 dev.append(etree.Element("mac", address=self.mac_addr)) 

1946 if self.model: 

1947 dev.append(etree.Element("model", type=self.model)) 

1948 

1949 drv_elem = None 

1950 if (self.driver_name or 

1951 self.driver_iommu or 

1952 self.driver_packed or 

1953 self.net_type == "vhostuser"): 

1954 

1955 drv_elem = etree.Element("driver") 

1956 if self.driver_name and self.net_type != "vhostuser": 

1957 # For vhostuser interface we should not set the driver name. 

1958 drv_elem.set("name", self.driver_name) 

1959 if self.driver_iommu: 

1960 drv_elem.set("iommu", "on") 

1961 if self.driver_packed: 

1962 drv_elem.set("packed", "on") 

1963 

1964 if drv_elem is not None: 

1965 if self.vhost_queues is not None: 

1966 drv_elem.set('queues', str(self.vhost_queues)) 

1967 if self.vhost_rx_queue_size is not None: 

1968 drv_elem.set('rx_queue_size', str(self.vhost_rx_queue_size)) 

1969 if self.vhost_tx_queue_size is not None: 

1970 drv_elem.set('tx_queue_size', str(self.vhost_tx_queue_size)) 

1971 

1972 if (drv_elem.get('name') or drv_elem.get('queues') or 

1973 drv_elem.get('rx_queue_size') or 

1974 drv_elem.get('tx_queue_size') or 

1975 drv_elem.get('iommu') or 

1976 drv_elem.get('packed')): 

1977 # Append the driver element into the dom only if name 

1978 # or queues or tx/rx or iommu attributes are set. 

1979 dev.append(drv_elem) 

1980 

1981 if self.net_type == "ethernet": 

1982 if self.script is not None: 1982 ↛ 1983line 1982 didn't jump to line 1983 because the condition on line 1982 was never true

1983 dev.append(etree.Element("script", path=self.script)) 

1984 if self.mtu is not None: 

1985 dev.append(etree.Element("mtu", size=str(self.mtu))) 

1986 elif self.net_type == "direct": 

1987 dev.append(etree.Element("source", dev=self.source_dev, 

1988 mode=self.source_mode)) 

1989 elif self.net_type == "vdpa": 1989 ↛ 1990line 1989 didn't jump to line 1990 because the condition on line 1989 was never true

1990 dev.append(etree.Element("source", dev=self.source_dev)) 

1991 elif self.net_type == "hostdev": 

1992 source_elem = etree.Element("source") 

1993 domain, bus, slot, func = \ 

1994 pci_utils.get_pci_address_fields(self.source_dev) 

1995 addr_elem = etree.Element("address", type='pci') 

1996 addr_elem.set("domain", "0x%s" % (domain)) 

1997 addr_elem.set("bus", "0x%s" % (bus)) 

1998 addr_elem.set("slot", "0x%s" % (slot)) 

1999 addr_elem.set("function", "0x%s" % (func)) 

2000 source_elem.append(addr_elem) 

2001 dev.append(source_elem) 

2002 elif self.net_type == "vhostuser": 

2003 dev.append(etree.Element("source", type=self.vhostuser_type, 

2004 mode=self.vhostuser_mode, 

2005 path=self.vhostuser_path)) 

2006 elif self.net_type == "bridge": 

2007 dev.append(etree.Element("source", bridge=self.source_dev)) 

2008 if self.script is not None: 2008 ↛ 2009line 2008 didn't jump to line 2009 because the condition on line 2008 was never true

2009 dev.append(etree.Element("script", path=self.script)) 

2010 if self.mtu is not None: 

2011 dev.append(etree.Element("mtu", size=str(self.mtu))) 

2012 else: 

2013 dev.append(etree.Element("source", bridge=self.source_dev)) 

2014 

2015 if self.vlan and self.net_type in ("direct", "hostdev"): 

2016 vlan_elem = etree.Element("vlan") 

2017 tag_elem = etree.Element("tag", id=str(self.vlan)) 

2018 vlan_elem.append(tag_elem) 

2019 dev.append(vlan_elem) 

2020 

2021 if self.target_dev is not None: 

2022 dev.append(etree.Element("target", dev=self.target_dev)) 

2023 

2024 if self.vporttype is not None: 

2025 vport = etree.Element("virtualport", type=self.vporttype) 

2026 for p in self.vportparams: 

2027 param = etree.Element("parameters") 

2028 param.set(p['key'], p['value']) 

2029 vport.append(param) 

2030 dev.append(vport) 

2031 

2032 if self.filtername is not None: 

2033 filter = etree.Element("filterref", filter=self.filtername) 

2034 for p in self.filterparams: 

2035 filter.append(etree.Element("parameter", 

2036 name=p['key'], 

2037 value=p['value'])) 

2038 dev.append(filter) 

2039 

2040 if self.vif_inbound_average or self.vif_outbound_average: 

2041 bandwidth = etree.Element("bandwidth") 

2042 if self.vif_inbound_average is not None: 2042 ↛ 2051line 2042 didn't jump to line 2051 because the condition on line 2042 was always true

2043 vif_inbound = etree.Element("inbound", 

2044 average=str(self.vif_inbound_average)) 

2045 if self.vif_inbound_peak is not None: 2045 ↛ 2047line 2045 didn't jump to line 2047 because the condition on line 2045 was always true

2046 vif_inbound.set("peak", str(self.vif_inbound_peak)) 

2047 if self.vif_inbound_burst is not None: 2047 ↛ 2049line 2047 didn't jump to line 2049 because the condition on line 2047 was always true

2048 vif_inbound.set("burst", str(self.vif_inbound_burst)) 

2049 bandwidth.append(vif_inbound) 

2050 

2051 if self.vif_outbound_average is not None: 2051 ↛ 2059line 2051 didn't jump to line 2059 because the condition on line 2051 was always true

2052 vif_outbound = etree.Element("outbound", 

2053 average=str(self.vif_outbound_average)) 

2054 if self.vif_outbound_peak is not None: 2054 ↛ 2056line 2054 didn't jump to line 2056 because the condition on line 2054 was always true

2055 vif_outbound.set("peak", str(self.vif_outbound_peak)) 

2056 if self.vif_outbound_burst is not None: 2056 ↛ 2058line 2056 didn't jump to line 2058 because the condition on line 2056 was always true

2057 vif_outbound.set("burst", str(self.vif_outbound_burst)) 

2058 bandwidth.append(vif_outbound) 

2059 dev.append(bandwidth) 

2060 

2061 return dev 

2062 

2063 def parse_dom(self, xmldoc): 

2064 super(LibvirtConfigGuestInterface, self).parse_dom(xmldoc) 

2065 

2066 self.net_type = xmldoc.get('type') 

2067 

2068 for c in xmldoc: 

2069 if c.tag == 'mac': 

2070 self.mac_addr = c.get('address') 

2071 elif c.tag == 'model': 

2072 self.model = c.get('type') 

2073 elif c.tag == 'driver': 

2074 self.driver_name = c.get('name') 

2075 self.driver_iommu = (c.get('iommu', '') == 'on') 

2076 self.driver_packed = (c.get('packed', '') == 'on') 

2077 self.vhost_queues = c.get('queues') 

2078 self.vhost_rx_queue_size = c.get('rx_queue_size') 

2079 self.vhost_tx_queue_size = c.get('tx_queue_size') 

2080 elif c.tag == 'source': 

2081 if self.net_type == 'direct': 

2082 self.source_dev = c.get('dev') 

2083 self.source_mode = c.get('mode', 'private') 

2084 elif self.net_type == 'vdpa': 2084 ↛ 2085line 2084 didn't jump to line 2085 because the condition on line 2084 was never true

2085 self.source_dev = c.get('dev') 

2086 elif self.net_type == 'vhostuser': 

2087 self.vhostuser_type = c.get('type') 

2088 self.vhostuser_mode = c.get('mode') 

2089 self.vhostuser_path = c.get('path') 

2090 elif self.net_type == 'hostdev': 

2091 for sub in c: 

2092 if sub.tag == 'address' and sub.get('type') == 'pci': 2092 ↛ 2091line 2092 didn't jump to line 2091 because the condition on line 2092 was always true

2093 # strip the 0x prefix on each attribute since 

2094 # format_dom puts them back on - note that 

2095 # LibvirtConfigGuestHostdevPCI does not do this... 

2096 self.source_dev = ( 

2097 pci_utils.get_pci_address( 

2098 sub.get('domain')[2:], 

2099 sub.get('bus')[2:], 

2100 sub.get('slot')[2:], 

2101 sub.get('function')[2:] 

2102 ) 

2103 ) 

2104 else: 

2105 self.source_dev = c.get('bridge') 

2106 elif c.tag == 'target': 

2107 self.target_dev = c.get('dev') 

2108 elif c.tag == 'script': 2108 ↛ 2109line 2108 didn't jump to line 2109 because the condition on line 2108 was never true

2109 self.script = c.get('path') 

2110 elif c.tag == 'vlan': 

2111 # NOTE(mriedem): The vlan element can have multiple tag 

2112 # sub-elements but we're currently only storing a single tag 

2113 # id in the vlan attribute. 

2114 for sub in c: 2114 ↛ 2068line 2114 didn't jump to line 2068 because the loop on line 2114 didn't complete

2115 if sub.tag == 'tag' and sub.get('id'): 2115 ↛ 2114line 2115 didn't jump to line 2114 because the condition on line 2115 was always true

2116 self.vlan = int(sub.get('id')) 

2117 break 

2118 elif c.tag == 'virtualport': 

2119 self.vporttype = c.get('type') 

2120 for sub in c: 

2121 if sub.tag == 'parameters': 2121 ↛ 2120line 2121 didn't jump to line 2120 because the condition on line 2121 was always true

2122 for k, v in dict(sub.attrib).items(): 

2123 self.add_vport_param(k, v) 

2124 elif c.tag == 'filterref': 

2125 self.filtername = c.get('filter') 

2126 for sub in c: 

2127 if sub.tag == 'parameter': 2127 ↛ 2126line 2127 didn't jump to line 2126 because the condition on line 2127 was always true

2128 self.add_filter_param(sub.get('name'), 

2129 sub.get('value')) 

2130 elif c.tag == 'bandwidth': 

2131 for sub in c: 

2132 # Note that only average is mandatory, burst and peak are 

2133 # optional (and all are ints). 

2134 if sub.tag == 'inbound': 

2135 self.vif_inbound_average = int(sub.get('average')) 

2136 if sub.get('burst'): 2136 ↛ 2138line 2136 didn't jump to line 2138 because the condition on line 2136 was always true

2137 self.vif_inbound_burst = int(sub.get('burst')) 

2138 if sub.get('peak'): 2138 ↛ 2131line 2138 didn't jump to line 2131 because the condition on line 2138 was always true

2139 self.vif_inbound_peak = int(sub.get('peak')) 

2140 elif sub.tag == 'outbound': 2140 ↛ 2131line 2140 didn't jump to line 2131 because the condition on line 2140 was always true

2141 self.vif_outbound_average = int(sub.get('average')) 

2142 if sub.get('burst'): 2142 ↛ 2144line 2142 didn't jump to line 2144 because the condition on line 2142 was always true

2143 self.vif_outbound_burst = int(sub.get('burst')) 

2144 if sub.get('peak'): 2144 ↛ 2131line 2144 didn't jump to line 2131 because the condition on line 2144 was always true

2145 self.vif_outbound_peak = int(sub.get('peak')) 

2146 elif c.tag == 'address': 

2147 obj = LibvirtConfigGuestDeviceAddress.parse_dom(c) 

2148 self.device_addr = obj 

2149 elif c.tag == 'mtu': 

2150 self.mtu = int(c.get('size')) 

2151 elif c.tag == 'alias': 2151 ↛ 2068line 2151 didn't jump to line 2068 because the condition on line 2151 was always true

2152 self.alias = c.get('name') 

2153 

2154 def add_filter_param(self, key, value): 

2155 self.filterparams.append({'key': key, 'value': value}) 

2156 

2157 def add_vport_param(self, key, value): 

2158 self.vportparams.append({'key': key, 'value': value}) 

2159 

2160 

2161class LibvirtConfigGuestInput(LibvirtConfigGuestDevice): 

2162 

2163 def __init__(self, **kwargs): 

2164 super(LibvirtConfigGuestInput, self).__init__(root_name="input", 

2165 **kwargs) 

2166 

2167 self.type = "tablet" 

2168 self.bus = "usb" 

2169 self.driver_iommu = False 

2170 

2171 def format_dom(self): 

2172 dev = super(LibvirtConfigGuestInput, self).format_dom() 

2173 

2174 dev.set("type", self.type) 

2175 dev.set("bus", self.bus) 

2176 if self.driver_iommu: 

2177 dev.append(etree.Element('driver', iommu="on")) 

2178 

2179 return dev 

2180 

2181 

2182class LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice): 

2183 

2184 def __init__(self, **kwargs): 

2185 super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics", 

2186 **kwargs) 

2187 

2188 self.type = "vnc" 

2189 self.autoport = True 

2190 self.keymap = None 

2191 self.listen = None 

2192 self.secure = None 

2193 

2194 self.image_compression = None 

2195 self.jpeg_compression = None 

2196 self.zlib_compression = None 

2197 self.playback_compression = None 

2198 self.streaming_mode = None 

2199 

2200 def format_dom(self): 

2201 dev = super(LibvirtConfigGuestGraphics, self).format_dom() 

2202 

2203 dev.set("type", self.type) 

2204 dev.set("autoport", self.get_yes_no_str(self.autoport)) 

2205 if self.keymap: 

2206 dev.set("keymap", self.keymap) 

2207 if self.listen: 2207 ↛ 2210line 2207 didn't jump to line 2210 because the condition on line 2207 was always true

2208 dev.set("listen", self.listen) 

2209 

2210 if self.type == "spice": 

2211 if self.image_compression is not None: 

2212 dev.append(etree.Element( 

2213 'image', compression=self.image_compression)) 

2214 if self.jpeg_compression is not None: 

2215 dev.append(etree.Element( 

2216 'jpeg', compression=self.jpeg_compression)) 

2217 if self.zlib_compression is not None: 

2218 dev.append(etree.Element( 

2219 'zlib', compression=self.zlib_compression)) 

2220 if self.playback_compression is not None: 

2221 dev.append(etree.Element( 

2222 'playback', compression=self.get_on_off_str( 

2223 self.playback_compression))) 

2224 if self.streaming_mode is not None: 

2225 dev.append(etree.Element( 

2226 'streaming', mode=self.streaming_mode)) 

2227 if self.secure: 

2228 for channel in ['main', 'display', 'inputs', 'cursor', 

2229 'playback', 'record', 'smartcard', 'usbredir']: 

2230 dev.append(etree.Element('channel', name=channel, 

2231 mode='secure')) 

2232 

2233 return dev 

2234 

2235 

2236class LibvirtConfigSeclabel(LibvirtConfigObject): 

2237 

2238 def __init__(self, **kwargs): 

2239 super(LibvirtConfigSeclabel, self).__init__(root_name="seclabel", 

2240 **kwargs) 

2241 self.type = 'dynamic' 

2242 self.baselabel = None 

2243 

2244 def format_dom(self): 

2245 seclabel = super(LibvirtConfigSeclabel, self).format_dom() 

2246 

2247 seclabel.set('type', self.type) 

2248 if self.baselabel: 

2249 seclabel.append(self._text_node("baselabel", self.baselabel)) 

2250 

2251 return seclabel 

2252 

2253 

2254class LibvirtConfigGuestVideo(LibvirtConfigGuestDevice): 

2255 

2256 def __init__(self, **kwargs): 

2257 super(LibvirtConfigGuestVideo, self).__init__(root_name="video", 

2258 **kwargs) 

2259 

2260 self.type = 'virtio' 

2261 self.vram = None 

2262 self.heads = None 

2263 self.driver_iommu = False 

2264 

2265 @property 

2266 def uses_virtio(self): 

2267 return 'virtio' == self.type 

2268 

2269 def format_dom(self): 

2270 dev = super(LibvirtConfigGuestVideo, self).format_dom() 

2271 

2272 model = etree.Element("model") 

2273 model.set("type", self.type) 

2274 

2275 if self.vram: 

2276 model.set("vram", str(self.vram)) 

2277 

2278 if self.heads: 

2279 model.set("heads", str(self.heads)) 

2280 

2281 dev.append(model) 

2282 

2283 if self.driver_iommu: 

2284 dev.append(etree.Element("driver", iommu="on")) 

2285 

2286 return dev 

2287 

2288 

2289class LibvirtConfigMemoryBalloon(LibvirtConfigGuestDevice): 

2290 def __init__(self, **kwargs): 

2291 super(LibvirtConfigMemoryBalloon, self).__init__( 

2292 root_name='memballoon', 

2293 **kwargs) 

2294 self.model = None 

2295 self.period = None 

2296 self.driver_iommu = False 

2297 

2298 @property 

2299 def uses_virtio(self): 

2300 return 'virtio' == self.model 

2301 

2302 def format_dom(self): 

2303 dev = super(LibvirtConfigMemoryBalloon, self).format_dom() 

2304 dev.set('model', str(self.model)) 

2305 if self.period is not None: 

2306 dev.append(etree.Element('stats', period=str(self.period))) 

2307 if self.driver_iommu: 

2308 dev.append(etree.Element('driver', iommu='on')) 

2309 return dev 

2310 

2311 

2312class LibvirtConfigGuestController(LibvirtConfigGuestDevice): 

2313 

2314 def __init__(self, **kwargs): 

2315 super(LibvirtConfigGuestController, 

2316 self).__init__(root_name="controller", **kwargs) 

2317 

2318 self.type = None 

2319 self.index = None 

2320 self.model = None 

2321 self.driver_iommu = False 

2322 

2323 @property 

2324 def uses_virtio(self): 

2325 model_is_virtio = 'virtio-scsi' == self.model 

2326 type_is_virtio = 'virtio-serial' == self.type 

2327 return model_is_virtio or type_is_virtio 

2328 

2329 def format_dom(self): 

2330 controller = super(LibvirtConfigGuestController, self).format_dom() 

2331 controller.set("type", self.type) 

2332 

2333 if self.index is not None: 2333 ↛ 2336line 2333 didn't jump to line 2336 because the condition on line 2333 was always true

2334 controller.set("index", str(self.index)) 

2335 

2336 if self.model: 

2337 controller.set("model", str(self.model)) 

2338 

2339 if self.driver_iommu: 

2340 controller.append(etree.Element("driver", iommu="on")) 

2341 

2342 return controller 

2343 

2344 

2345class LibvirtConfigGuestUSBHostController(LibvirtConfigGuestController): 

2346 

2347 def __init__(self, **kwargs): 

2348 super(LibvirtConfigGuestUSBHostController, self).__init__(**kwargs) 

2349 self.type = 'usb' 

2350 

2351 

2352class LibvirtConfigGuestPCIeRootController(LibvirtConfigGuestController): 

2353 

2354 def __init__(self, **kwargs): 

2355 super(LibvirtConfigGuestPCIeRootController, self).\ 

2356 __init__(**kwargs) 

2357 self.type = 'pci' 

2358 self.model = 'pcie-root' 

2359 

2360 

2361class LibvirtConfigGuestPCIeRootPortController(LibvirtConfigGuestController): 

2362 

2363 def __init__(self, **kwargs): 

2364 super(LibvirtConfigGuestPCIeRootPortController, self).\ 

2365 __init__(**kwargs) 

2366 self.type = 'pci' 

2367 self.model = 'pcie-root-port' 

2368 

2369 

2370class LibvirtConfigGuestHostdev(LibvirtConfigGuestDevice): 

2371 def __init__(self, **kwargs): 

2372 super(LibvirtConfigGuestHostdev, self).__init__( 

2373 root_name="hostdev", **kwargs, 

2374 ) 

2375 self.mode = None 

2376 self.type = None 

2377 # managed attribute is only used by PCI devices but mediated devices 

2378 # need to say managed=no 

2379 self.managed = "yes" 

2380 

2381 def format_dom(self): 

2382 dev = super(LibvirtConfigGuestHostdev, self).format_dom() 

2383 dev.set("mode", self.mode) 

2384 dev.set("type", self.type) 

2385 dev.set("managed", self.managed) 

2386 return dev 

2387 

2388 def parse_dom(self, xmldoc): 

2389 super(LibvirtConfigGuestHostdev, self).parse_dom(xmldoc) 

2390 self.mode = xmldoc.get('mode') 

2391 self.type = xmldoc.get('type') 

2392 self.managed = xmldoc.get('managed') 

2393 return list(xmldoc) 

2394 

2395 

2396class LibvirtConfigGuestHostdevPCI(LibvirtConfigGuestHostdev): 

2397 def __init__(self, **kwargs): 

2398 super(LibvirtConfigGuestHostdevPCI, self).\ 

2399 __init__(**kwargs) 

2400 

2401 self.mode = 'subsystem' 

2402 self.type = 'pci' 

2403 

2404 # These are returned from libvirt as hexadecimal strings with 0x prefix 

2405 # even if they have a different meaningful range: domain 16 bit, 

2406 # bus 8 bit, slot 5 bit, and function 3 bit 

2407 # On the other hand nova generates these values without the 0x prefix 

2408 self.domain = None 

2409 self.bus = None 

2410 self.slot = None 

2411 self.function = None 

2412 

2413 self.alias = None 

2414 

2415 def __eq__(self, other): 

2416 if not isinstance(other, LibvirtConfigGuestHostdevPCI): 2416 ↛ 2417line 2416 didn't jump to line 2417 because the condition on line 2416 was never true

2417 return False 

2418 

2419 # NOTE(gibi): nova generates hexa string without 0x prefix but 

2420 # libvirt uses that prefix when returns the config so we need to 

2421 # normalize the strings before comparison 

2422 return ( 

2423 int(self.domain, 16) == int(other.domain, 16) and 

2424 int(self.bus, 16) == int(other.bus, 16) and 

2425 int(self.slot, 16) == int(other.slot, 16) and 

2426 int(self.function, 16) == int(other.function, 16)) 

2427 

2428 def format_dom(self): 

2429 dev = super(LibvirtConfigGuestHostdevPCI, self).format_dom() 

2430 

2431 address = etree.Element( 

2432 "address", 

2433 domain=self.domain if self.domain.startswith('0x') 

2434 else '0x' + self.domain, 

2435 bus=self.bus if self.bus.startswith('0x') else '0x' + self.bus, 

2436 slot=self.slot if self.slot.startswith('0x') else '0x' + self.slot, 

2437 function=self.function if self.function.startswith('0x') 

2438 else '0x' + self.function) 

2439 source = etree.Element("source") 

2440 source.append(address) 

2441 dev.append(source) 

2442 return dev 

2443 

2444 def parse_dom(self, xmldoc): 

2445 childs = super(LibvirtConfigGuestHostdevPCI, self).parse_dom(xmldoc) 

2446 for c in childs: 

2447 if c.tag == "source": 

2448 for sub in c: 

2449 if sub.tag == 'address': 

2450 self.domain = sub.get('domain') 

2451 self.bus = sub.get('bus') 

2452 self.slot = sub.get('slot') 

2453 self.function = sub.get('function') 

2454 elif c.tag == 'alias': 

2455 self.alias = c.get('name') 

2456 

2457 

2458class LibvirtConfigGuestHostdevMDEV(LibvirtConfigGuestHostdev): 

2459 def __init__(self, **kwargs): 

2460 super(LibvirtConfigGuestHostdevMDEV, self).__init__(**kwargs) 

2461 

2462 self.mode = 'subsystem' 

2463 self.type = 'mdev' 

2464 self.managed = 'no' 

2465 

2466 # model attribute is only supported by mediated devices 

2467 self.model = 'vfio-pci' 

2468 self.uuid = None 

2469 

2470 def format_dom(self): 

2471 dev = super(LibvirtConfigGuestHostdevMDEV, self).format_dom() 

2472 if self.model: 2472 ↛ 2475line 2472 didn't jump to line 2475 because the condition on line 2472 was always true

2473 dev.set("model", self.model) 

2474 

2475 address = etree.Element("address", uuid=self.uuid) 

2476 source = etree.Element("source") 

2477 source.append(address) 

2478 dev.append(source) 

2479 return dev 

2480 

2481 def parse_dom(self, xmldoc): 

2482 children = super(LibvirtConfigGuestHostdevMDEV, self).parse_dom(xmldoc) 

2483 if xmldoc.get('model'): 2483 ↛ 2485line 2483 didn't jump to line 2485 because the condition on line 2483 was always true

2484 self.model = xmldoc.get('model') 

2485 for c in children: 2485 ↛ exitline 2485 didn't return from function 'parse_dom' because the loop on line 2485 didn't complete

2486 if c.tag == "source": 2486 ↛ 2485line 2486 didn't jump to line 2485 because the condition on line 2486 was always true

2487 for sub in c: 2487 ↛ 2485line 2487 didn't jump to line 2485 because the loop on line 2487 didn't complete

2488 if sub.tag == 'address': 2488 ↛ 2487line 2488 didn't jump to line 2487 because the condition on line 2488 was always true

2489 self.uuid = sub.get('uuid') 

2490 return 

2491 

2492 

2493class LibvirtConfigGuestCharBase(LibvirtConfigGuestDevice): 

2494 

2495 def __init__(self, **kwargs): 

2496 super(LibvirtConfigGuestCharBase, self).__init__(**kwargs) 

2497 

2498 self.type = "pty" 

2499 self.source_path = None 

2500 self.listen_port = None 

2501 self.listen_host = None 

2502 self.log = None 

2503 

2504 def format_dom(self): 

2505 dev = super(LibvirtConfigGuestCharBase, self).format_dom() 

2506 

2507 dev.set("type", self.type) 

2508 

2509 if self.type == "file": 

2510 dev.append(etree.Element("source", path=self.source_path)) 

2511 elif self.type == "unix": 

2512 dev.append(etree.Element("source", mode="bind", 

2513 path=self.source_path)) 

2514 elif self.type == "tcp": 

2515 dev.append(etree.Element("source", mode="bind", 

2516 host=self.listen_host, 

2517 service=str(self.listen_port))) 

2518 

2519 if self.log: 

2520 dev.append(self.log.format_dom()) 

2521 

2522 return dev 

2523 

2524 

2525class LibvirtConfigGuestChar(LibvirtConfigGuestCharBase): 

2526 

2527 def __init__(self, **kwargs): 

2528 super(LibvirtConfigGuestChar, self).__init__(**kwargs) 

2529 

2530 self.target_port = None 

2531 self.target_type = None 

2532 

2533 def format_dom(self): 

2534 dev = super(LibvirtConfigGuestChar, self).format_dom() 

2535 

2536 if self.target_port is not None or self.target_type is not None: 

2537 target = etree.Element("target") 

2538 if self.target_port is not None: 

2539 target.set("port", str(self.target_port)) 

2540 if self.target_type is not None: 

2541 target.set("type", self.target_type) 

2542 dev.append(target) 

2543 

2544 return dev 

2545 

2546 

2547class LibvirtConfigGuestCharDeviceLog(LibvirtConfigObject): 

2548 """Represents a sub-element to a character device.""" 

2549 

2550 def __init__(self, **kwargs): 

2551 super(LibvirtConfigGuestCharDeviceLog, self).__init__(root_name="log", 

2552 **kwargs) 

2553 self.file = None 

2554 self.append = "off" 

2555 

2556 def parse_dom(self, xmldoc): 

2557 super(LibvirtConfigGuestCharDeviceLog, self).parse_dom(xmldoc) 

2558 self.file = xmldoc.get("file") 

2559 self.append = xmldoc.get("append") 

2560 

2561 def format_dom(self): 

2562 log = super(LibvirtConfigGuestCharDeviceLog, self).format_dom() 

2563 log.set("file", self.file) 

2564 log.set("append", self.append) 

2565 return log 

2566 

2567 

2568class LibvirtConfigGuestSerial(LibvirtConfigGuestChar): 

2569 

2570 def __init__(self, **kwargs): 

2571 super(LibvirtConfigGuestSerial, self).__init__(root_name="serial", 

2572 **kwargs) 

2573 

2574 

2575class LibvirtConfigGuestConsole(LibvirtConfigGuestChar): 

2576 

2577 def __init__(self, **kwargs): 

2578 super(LibvirtConfigGuestConsole, self).__init__(root_name="console", 

2579 **kwargs) 

2580 

2581 

2582class LibvirtConfigGuestChannel(LibvirtConfigGuestCharBase): 

2583 

2584 def __init__(self, **kwargs): 

2585 super(LibvirtConfigGuestChannel, self).__init__(root_name="channel", 

2586 **kwargs) 

2587 

2588 self.target_type = "virtio" 

2589 self.target_name = None 

2590 

2591 def format_dom(self): 

2592 dev = super(LibvirtConfigGuestChannel, self).format_dom() 

2593 

2594 target = etree.Element("target", type=self.target_type) 

2595 if self.target_name is not None: 

2596 target.set("name", self.target_name) 

2597 dev.append(target) 

2598 

2599 return dev 

2600 

2601 

2602class LibvirtConfigGuestWatchdog(LibvirtConfigGuestDevice): 

2603 def __init__(self, **kwargs): 

2604 super(LibvirtConfigGuestWatchdog, self).__init__(root_name="watchdog", 

2605 **kwargs) 

2606 

2607 self.model = 'i6300esb' 

2608 self.action = 'reset' 

2609 

2610 def format_dom(self): 

2611 dev = super(LibvirtConfigGuestWatchdog, self).format_dom() 

2612 

2613 dev.set('model', self.model) 

2614 dev.set('action', self.action) 

2615 

2616 return dev 

2617 

2618 

2619class LibvirtConfigGuestCPUTuneVCPUPin(LibvirtConfigObject): 

2620 

2621 def __init__(self, **kwargs): 

2622 super(LibvirtConfigGuestCPUTuneVCPUPin, self).__init__( 

2623 root_name="vcpupin", 

2624 **kwargs) 

2625 

2626 self.id = None 

2627 self.cpuset = None 

2628 

2629 def format_dom(self): 

2630 root = super(LibvirtConfigGuestCPUTuneVCPUPin, self).format_dom() 

2631 

2632 root.set("vcpu", str(self.id)) 

2633 if self.cpuset is not None: 2633 ↛ 2637line 2633 didn't jump to line 2637 because the condition on line 2633 was always true

2634 root.set("cpuset", 

2635 hardware.format_cpu_spec(self.cpuset)) 

2636 

2637 return root 

2638 

2639 

2640class LibvirtConfigGuestCPUTuneEmulatorPin(LibvirtConfigObject): 

2641 

2642 def __init__(self, **kwargs): 

2643 super(LibvirtConfigGuestCPUTuneEmulatorPin, self).__init__( 

2644 root_name="emulatorpin", 

2645 **kwargs) 

2646 

2647 self.cpuset = None 

2648 

2649 def format_dom(self): 

2650 root = super(LibvirtConfigGuestCPUTuneEmulatorPin, self).format_dom() 

2651 

2652 if self.cpuset is not None: 2652 ↛ 2656line 2652 didn't jump to line 2656 because the condition on line 2652 was always true

2653 root.set("cpuset", 

2654 hardware.format_cpu_spec(self.cpuset)) 

2655 

2656 return root 

2657 

2658 

2659class LibvirtConfigGuestCPUTuneVCPUSched(LibvirtConfigObject): 

2660 

2661 def __init__(self, **kwargs): 

2662 super(LibvirtConfigGuestCPUTuneVCPUSched, self).__init__( 

2663 root_name="vcpusched", 

2664 **kwargs) 

2665 

2666 self.vcpus = None 

2667 self.scheduler = None 

2668 self.priority = None 

2669 

2670 def format_dom(self): 

2671 root = super(LibvirtConfigGuestCPUTuneVCPUSched, self).format_dom() 

2672 

2673 if self.vcpus is not None: 2673 ↛ 2676line 2673 didn't jump to line 2676 because the condition on line 2673 was always true

2674 root.set("vcpus", 

2675 hardware.format_cpu_spec(self.vcpus)) 

2676 if self.scheduler is not None: 2676 ↛ 2678line 2676 didn't jump to line 2678 because the condition on line 2676 was always true

2677 root.set("scheduler", self.scheduler) 

2678 if self.priority is not None: 2678 ↛ 2681line 2678 didn't jump to line 2681 because the condition on line 2678 was always true

2679 root.set("priority", str(self.priority)) 

2680 

2681 return root 

2682 

2683 

2684class LibvirtConfigGuestCPUTune(LibvirtConfigObject): 

2685 

2686 def __init__(self, **kwargs): 

2687 super(LibvirtConfigGuestCPUTune, self).__init__(root_name="cputune", 

2688 **kwargs) 

2689 self.shares = None 

2690 self.quota = None 

2691 self.period = None 

2692 self.vcpupin = [] 

2693 self.emulatorpin = None 

2694 self.vcpusched = [] 

2695 

2696 def format_dom(self): 

2697 root = super(LibvirtConfigGuestCPUTune, self).format_dom() 

2698 

2699 if self.shares is not None: 

2700 root.append(self._text_node("shares", str(self.shares))) 

2701 if self.quota is not None: 

2702 root.append(self._text_node("quota", str(self.quota))) 

2703 if self.period is not None: 

2704 root.append(self._text_node("period", str(self.period))) 

2705 

2706 if self.emulatorpin is not None: 

2707 root.append(self.emulatorpin.format_dom()) 

2708 for vcpu in self.vcpupin: 

2709 root.append(vcpu.format_dom()) 

2710 for sched in self.vcpusched: 

2711 root.append(sched.format_dom()) 

2712 

2713 return root 

2714 

2715 

2716class LibvirtConfigGuestMemoryBacking(LibvirtConfigObject): 

2717 

2718 def __init__(self, **kwargs): 

2719 super(LibvirtConfigGuestMemoryBacking, self).__init__( 

2720 root_name="memoryBacking", **kwargs) 

2721 

2722 self.hugepages = [] 

2723 self.sharedpages = True 

2724 self.locked = False 

2725 self.filesource = False 

2726 self.sharedaccess = False 

2727 self.allocateimmediate = False 

2728 self.discard = False 

2729 

2730 def format_dom(self): 

2731 root = super(LibvirtConfigGuestMemoryBacking, self).format_dom() 

2732 

2733 if self.hugepages: 

2734 hugepages = etree.Element("hugepages") 

2735 for item in self.hugepages: 

2736 hugepages.append(item.format_dom()) 

2737 root.append(hugepages) 

2738 if not self.sharedpages: 

2739 root.append(etree.Element("nosharepages")) 

2740 if self.locked: 

2741 root.append(etree.Element("locked")) 

2742 if self.filesource: 

2743 root.append(etree.Element("source", type="file")) 

2744 if self.sharedaccess: 

2745 root.append(etree.Element("access", mode="shared")) 

2746 if self.allocateimmediate: 

2747 root.append(etree.Element("allocation", mode="immediate")) 

2748 if self.discard: 

2749 root.append(etree.Element("discard")) 

2750 

2751 return root 

2752 

2753 

2754class LibvirtConfigGuestMemoryBackingPage(LibvirtConfigObject): 

2755 

2756 def __init__(self, **kwargs): 

2757 super(LibvirtConfigGuestMemoryBackingPage, self).__init__( 

2758 root_name="page", **kwargs) 

2759 

2760 self.size_kb = None 

2761 self.nodeset = None 

2762 

2763 def format_dom(self): 

2764 page = super(LibvirtConfigGuestMemoryBackingPage, self).format_dom() 

2765 

2766 page.set("size", str(self.size_kb)) 

2767 page.set("nodeset", hardware.format_cpu_spec(self.nodeset)) 

2768 page.set("unit", "KiB") 

2769 

2770 return page 

2771 

2772 

2773class LibvirtConfigGuestMemoryTune(LibvirtConfigObject): 

2774 

2775 def __init__(self, **kwargs): 

2776 super(LibvirtConfigGuestMemoryTune, self).__init__( 

2777 root_name="memtune", **kwargs) 

2778 

2779 self.hard_limit = None 

2780 self.soft_limit = None 

2781 self.swap_hard_limit = None 

2782 self.min_guarantee = None 

2783 

2784 def format_dom(self): 

2785 root = super(LibvirtConfigGuestMemoryTune, self).format_dom() 

2786 

2787 if self.hard_limit is not None: 

2788 root.append(self._text_node("hard_limit", 

2789 str(self.hard_limit), 

2790 unit="KiB")) 

2791 if self.soft_limit is not None: 

2792 root.append(self._text_node("soft_limit", 

2793 str(self.soft_limit), 

2794 unit="KiB")) 

2795 if self.swap_hard_limit is not None: 

2796 root.append(self._text_node("swap_hard_limit", 

2797 str(self.swap_hard_limit), 

2798 unit="KiB")) 

2799 if self.min_guarantee is not None: 

2800 root.append(self._text_node("min_guarantee", 

2801 str(self.min_guarantee), 

2802 unit="KiB")) 

2803 

2804 return root 

2805 

2806 

2807class LibvirtConfigGuestNUMATuneMemory(LibvirtConfigObject): 

2808 

2809 def __init__(self, **kwargs): 

2810 super(LibvirtConfigGuestNUMATuneMemory, self).__init__( 

2811 root_name="memory", **kwargs) 

2812 

2813 self.mode = "strict" 

2814 self.nodeset = [] 

2815 

2816 def format_dom(self): 

2817 root = super(LibvirtConfigGuestNUMATuneMemory, self).format_dom() 

2818 

2819 root.set("mode", self.mode) 

2820 root.set("nodeset", hardware.format_cpu_spec(self.nodeset)) 

2821 

2822 return root 

2823 

2824 

2825class LibvirtConfigGuestNUMATuneMemNode(LibvirtConfigObject): 

2826 

2827 def __init__(self, **kwargs): 

2828 super(LibvirtConfigGuestNUMATuneMemNode, self).__init__( 

2829 root_name="memnode", **kwargs) 

2830 

2831 self.cellid = 0 

2832 self.mode = "strict" 

2833 self.nodeset = [] 

2834 

2835 def format_dom(self): 

2836 root = super(LibvirtConfigGuestNUMATuneMemNode, self).format_dom() 

2837 

2838 root.set("cellid", str(self.cellid)) 

2839 root.set("mode", self.mode) 

2840 root.set("nodeset", hardware.format_cpu_spec(self.nodeset)) 

2841 

2842 return root 

2843 

2844 

2845class LibvirtConfigGuestNUMATune(LibvirtConfigObject): 

2846 

2847 def __init__(self, **kwargs): 

2848 super(LibvirtConfigGuestNUMATune, self).__init__( 

2849 root_name="numatune", **kwargs) 

2850 

2851 self.memory = None 

2852 self.memnodes = [] 

2853 

2854 def format_dom(self): 

2855 root = super(LibvirtConfigGuestNUMATune, self).format_dom() 

2856 

2857 if self.memory is not None: 

2858 root.append(self.memory.format_dom()) 

2859 for node in self.memnodes: 

2860 root.append(node.format_dom()) 

2861 

2862 return root 

2863 

2864 

2865class LibvirtConfigGuestFeature(LibvirtConfigObject): 

2866 

2867 def __init__(self, name, **kwargs): 

2868 super(LibvirtConfigGuestFeature, self).__init__(root_name=name, 

2869 **kwargs) 

2870 

2871 

2872class LibvirtConfigGuestFeatureACPI(LibvirtConfigGuestFeature): 

2873 

2874 def __init__(self, **kwargs): 

2875 super(LibvirtConfigGuestFeatureACPI, self).__init__("acpi", 

2876 **kwargs) 

2877 

2878 

2879class LibvirtConfigGuestFeatureAPIC(LibvirtConfigGuestFeature): 

2880 

2881 def __init__(self, **kwargs): 

2882 super(LibvirtConfigGuestFeatureAPIC, self).__init__("apic", 

2883 **kwargs) 

2884 

2885 

2886class LibvirtConfigGuestFeatureKvmHidden(LibvirtConfigGuestFeature): 

2887 

2888 def __init__(self, **kwargs): 

2889 super(LibvirtConfigGuestFeatureKvmHidden, self).__init__("kvm", 

2890 **kwargs) 

2891 

2892 def format_dom(self): 

2893 root = super(LibvirtConfigGuestFeatureKvmHidden, self).format_dom() 

2894 

2895 root.append(etree.Element("hidden", state="on")) 

2896 

2897 return root 

2898 

2899 

2900class LibvirtConfigGuestFeatureSMM(LibvirtConfigGuestFeature): 

2901 

2902 def __init__(self, **kwargs): 

2903 super(LibvirtConfigGuestFeatureSMM, self).__init__("smm", **kwargs) 

2904 

2905 def format_dom(self): 

2906 root = super(LibvirtConfigGuestFeatureSMM, self).format_dom() 

2907 

2908 root.append(etree.Element("smm", state="on")) 

2909 

2910 return root 

2911 

2912 

2913class LibvirtConfigGuestFeatureTCG(LibvirtConfigGuestFeature): 

2914 

2915 def __init__(self, cache_size, **kwargs): 

2916 super(LibvirtConfigGuestFeatureTCG, self).__init__("tcg", **kwargs) 

2917 

2918 self.cache_size = str(cache_size) 

2919 

2920 def format_dom(self): 

2921 root = super(LibvirtConfigGuestFeatureTCG, self).format_dom() 

2922 root.append(self._text_node("tb-cache", self.cache_size, 

2923 unit="MiB")) 

2924 

2925 return root 

2926 

2927 

2928class LibvirtConfigGuestFeaturePMU(LibvirtConfigGuestFeature): 

2929 

2930 def __init__(self, state, **kwargs): 

2931 super(LibvirtConfigGuestFeaturePMU, self).__init__("pmu", **kwargs) 

2932 # NOTE(sean-k-mooney): bool_from_string is needed to handle the raw 

2933 # flavor exta_sepc value. bool_from_string internally checks if the 

2934 # value is already a bool and returns it. As such it's safe to use 

2935 # with the image metadata property too, so we call it unconditionally. 

2936 self.state = strutils.bool_from_string(state) 

2937 

2938 def format_dom(self): 

2939 root = super(LibvirtConfigGuestFeaturePMU, self).format_dom() 

2940 root.attrib['state'] = "on" if self.state else "off" 

2941 return root 

2942 

2943 

2944class LibvirtConfigGuestFeatureIOAPIC(LibvirtConfigGuestFeature): 

2945 

2946 def __init__(self, **kwargs): 

2947 super().__init__("ioapic", **kwargs) 

2948 self.driver = "qemu" 

2949 

2950 def format_dom(self): 

2951 root = super().format_dom() 

2952 root.set('driver', self.driver) 

2953 return root 

2954 

2955 

2956class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature): 

2957 

2958 # QEMU requires at least this value to be set 

2959 MIN_SPINLOCK_RETRIES = 4095 

2960 # The spoofed vendor_id can be any alphanumeric string 

2961 SPOOFED_VENDOR_ID = "1234567890ab" 

2962 

2963 def __init__(self, **kwargs): 

2964 super(LibvirtConfigGuestFeatureHyperV, self).__init__("hyperv", 

2965 **kwargs) 

2966 

2967 self.relaxed = False 

2968 self.vapic = False 

2969 self.spinlocks = False 

2970 self.spinlock_retries = self.MIN_SPINLOCK_RETRIES 

2971 self.vpindex = False 

2972 self.runtime = False 

2973 self.synic = False 

2974 self.reset = False 

2975 self.frequencies = False 

2976 self.reenlightenment = False 

2977 self.tlbflush = False 

2978 self.ipi = False 

2979 self.evmcs = False 

2980 self.vendorid_spoof = False 

2981 self.vendorid = self.SPOOFED_VENDOR_ID 

2982 

2983 def format_dom(self): 

2984 root = super(LibvirtConfigGuestFeatureHyperV, self).format_dom() 

2985 

2986 if self.relaxed: 2986 ↛ 2988line 2986 didn't jump to line 2988 because the condition on line 2986 was always true

2987 root.append(etree.Element("relaxed", state="on")) 

2988 if self.vapic: 

2989 root.append(etree.Element("vapic", state="on")) 

2990 if self.spinlocks: 

2991 root.append(etree.Element("spinlocks", state="on", 

2992 retries=str(self.spinlock_retries))) 

2993 if self.vendorid_spoof: 

2994 root.append(etree.Element("vendor_id", state="on", 

2995 value=self.vendorid)) 

2996 if self.vpindex: 

2997 root.append(etree.Element('vpindex', state='on')) 

2998 if self.runtime: 

2999 root.append(etree.Element('runtime', state='on')) 

3000 if self.synic: 

3001 root.append(etree.Element('synic', state='on')) 

3002 if self.reset: 

3003 root.append(etree.Element('reset', state='on')) 

3004 if self.frequencies: 

3005 root.append(etree.Element('frequencies', state='on')) 

3006 if self.reenlightenment: 

3007 root.append(etree.Element('reenlightenment', state='on')) 

3008 if self.tlbflush: 

3009 root.append(etree.Element('tlbflush', state='on')) 

3010 if self.ipi: 

3011 root.append(etree.Element('ipi', state='on')) 

3012 if self.evmcs: 

3013 root.append(etree.Element('evmcs', state='on')) 

3014 

3015 return root 

3016 

3017 

3018class LibvirtConfigGuestSEVLaunchSecurity(LibvirtConfigObject): 

3019 

3020 def __init__(self, **kwargs): 

3021 super(LibvirtConfigGuestSEVLaunchSecurity, self).__init__( 

3022 root_name='launchSecurity', **kwargs) 

3023 

3024 self.cbitpos = None 

3025 self.reduced_phys_bits = None 

3026 

3027 def format_dom(self): 

3028 root = super(LibvirtConfigGuestSEVLaunchSecurity, self).format_dom() 

3029 

3030 root.set('type', 'sev') 

3031 policy = etree.Element('policy') 

3032 policy.text = '0x0033' # hardcoded default according to the spec 

3033 root.append(policy) 

3034 

3035 cbitpos = etree.Element('cbitpos') 

3036 cbitpos.text = str(self.cbitpos) 

3037 root.append(cbitpos) 

3038 

3039 reducedPhysBits = etree.Element('reducedPhysBits') 

3040 reducedPhysBits.text = str(self.reduced_phys_bits) 

3041 root.append(reducedPhysBits) 

3042 

3043 return root 

3044 

3045 

3046class LibvirtConfigGuestFeatureVMCoreInfo(LibvirtConfigGuestFeature): 

3047 

3048 def __init__(self, **kwargs): 

3049 super().__init__('vmcoreinfo', **kwargs) 

3050 

3051 

3052class LibvirtConfigGuest(LibvirtConfigObject): 

3053 

3054 def __init__(self, **kwargs): 

3055 super(LibvirtConfigGuest, self).__init__(root_name="domain", 

3056 **kwargs) 

3057 

3058 self.virt_type = None 

3059 self.uuid = None 

3060 self.name = None 

3061 self.memory = 500 * units.Mi 

3062 self.max_memory_size = None 

3063 self.max_memory_slots = 0 

3064 self.membacking = None 

3065 self.memtune = None 

3066 self.numatune = None 

3067 self.vcpus = 1 

3068 self.cpuset = None 

3069 self.cpu = None 

3070 self.cputune = None 

3071 self.features = [] 

3072 self.clock = None 

3073 self.sysinfo = None 

3074 self.os_type = None 

3075 self.os_loader = None 

3076 self.os_firmware = None 

3077 self.os_loader_type = None 

3078 self.os_loader_secure = None 

3079 self.os_loader_stateless = None 

3080 self.os_nvram = None 

3081 self.os_nvram_template = None 

3082 self.os_kernel = None 

3083 self.os_initrd = None 

3084 self.os_cmdline = None 

3085 self.os_init_env = {} 

3086 self.os_root = None 

3087 self.os_init_path = None 

3088 self.os_boot_dev = [] 

3089 self.os_smbios = None 

3090 self.os_arch = None 

3091 self.os_mach_type = None 

3092 self.os_bootmenu = False 

3093 self.devices = [] 

3094 self.metadata = [] 

3095 self.idmaps = [] 

3096 self.perf_events = [] 

3097 self.launch_security = None 

3098 

3099 def _format_basic_props(self, root): 

3100 root.append(self._text_node("uuid", self.uuid)) 

3101 root.append(self._text_node("name", self.name)) 

3102 root.append(self._text_node("memory", self.memory)) 

3103 if self.max_memory_size is not None: 

3104 max_memory = self._text_node("maxMemory", self.max_memory_size) 

3105 max_memory.set("slots", str(self.max_memory_slots)) 

3106 root.append(max_memory) 

3107 if self.membacking is not None: 

3108 root.append(self.membacking.format_dom()) 

3109 if self.memtune is not None: 

3110 root.append(self.memtune.format_dom()) 

3111 if self.numatune is not None: 

3112 root.append(self.numatune.format_dom()) 

3113 if self.cpuset is not None: 

3114 vcpu = self._text_node("vcpu", self.vcpus) 

3115 vcpu.set("cpuset", hardware.format_cpu_spec(self.cpuset)) 

3116 root.append(vcpu) 

3117 else: 

3118 root.append(self._text_node("vcpu", self.vcpus)) 

3119 

3120 if len(self.metadata) > 0: 

3121 metadata = etree.Element("metadata") 

3122 for m in self.metadata: 

3123 metadata.append(m.format_dom()) 

3124 root.append(metadata) 

3125 

3126 def _format_os(self, root): 

3127 os = etree.Element("os") 

3128 

3129 if self.os_firmware is not None: 

3130 os.set("firmware", self.os_firmware) 

3131 

3132 type_node = self._text_node("type", self.os_type) 

3133 if self.os_arch is not None: 

3134 type_node.set("arch", self.os_arch) 

3135 if self.os_mach_type is not None: 

3136 type_node.set("machine", self.os_mach_type) 

3137 os.append(type_node) 

3138 

3139 if self.os_kernel is not None: 

3140 os.append(self._text_node("kernel", self.os_kernel)) 

3141 

3142 if ( 

3143 self.os_loader is not None or 

3144 self.os_loader_type is not None or 

3145 self.os_loader_secure is not None or 

3146 self.os_loader_stateless is not None 

3147 ): 

3148 loader = self._text_node("loader", self.os_loader) 

3149 if self.os_loader_type is not None: 

3150 loader.set("type", self.os_loader_type) 

3151 loader.set("readonly", "yes") 

3152 if self.os_loader_secure is not None: 3152 ↛ 3155line 3152 didn't jump to line 3155 because the condition on line 3152 was always true

3153 loader.set( 

3154 "secure", self.get_yes_no_str(self.os_loader_secure)) 

3155 if self.os_loader_stateless is not None: 

3156 loader.set( 

3157 "stateless", self.get_yes_no_str(self.os_loader_stateless)) 

3158 os.append(loader) 

3159 

3160 if ( 

3161 self.os_nvram is not None or 

3162 self.os_nvram_template is not None 

3163 ): 

3164 nvram = self._text_node("nvram", self.os_nvram) 

3165 nvram.set("template", self.os_nvram_template) 

3166 os.append(nvram) 

3167 

3168 if self.os_initrd is not None: 

3169 os.append(self._text_node("initrd", self.os_initrd)) 

3170 if self.os_cmdline is not None: 

3171 os.append(self._text_node("cmdline", self.os_cmdline)) 

3172 if self.os_root is not None: 3172 ↛ 3173line 3172 didn't jump to line 3173 because the condition on line 3172 was never true

3173 os.append(self._text_node("root", self.os_root)) 

3174 if self.os_init_path is not None: 

3175 os.append(self._text_node("init", self.os_init_path)) 

3176 for name, value in self.os_init_env.items(): 

3177 initenv = self._text_node("initenv", value) 

3178 initenv.set("name", name) 

3179 os.append(initenv) 

3180 

3181 for boot_dev in self.os_boot_dev: 

3182 os.append(etree.Element("boot", dev=boot_dev)) 

3183 

3184 if self.os_smbios is not None: 

3185 os.append(self.os_smbios.format_dom()) 

3186 

3187 if self.os_bootmenu: 

3188 os.append(etree.Element("bootmenu", enable="yes")) 

3189 root.append(os) 

3190 

3191 def _format_features(self, root): 

3192 if len(self.features) > 0: 

3193 features = etree.Element("features") 

3194 for feat in self.features: 

3195 features.append(feat.format_dom()) 

3196 root.append(features) 

3197 

3198 def _format_devices(self, root): 

3199 if len(self.devices) == 0: 

3200 return 

3201 devices = etree.Element("devices") 

3202 for dev in self.devices: 

3203 devices.append(dev.format_dom()) 

3204 root.append(devices) 

3205 

3206 def _format_idmaps(self, root): 

3207 if len(self.idmaps) == 0: 

3208 return 

3209 idmaps = etree.Element("idmap") 

3210 for idmap in self.idmaps: 

3211 idmaps.append(idmap.format_dom()) 

3212 root.append(idmaps) 

3213 

3214 def _format_perf_events(self, root): 

3215 if len(self.perf_events) == 0: 

3216 return 

3217 perfs = etree.Element("perf") 

3218 for pe in self.perf_events: 

3219 event = etree.Element("event", name=pe, enabled="yes") 

3220 perfs.append(event) 

3221 root.append(perfs) 

3222 

3223 def _format_sev(self, root): 

3224 if self.launch_security is not None: 

3225 root.append(self.launch_security.format_dom()) 

3226 

3227 def format_dom(self): 

3228 root = super(LibvirtConfigGuest, self).format_dom() 

3229 

3230 root.set("type", self.virt_type) 

3231 

3232 self._format_basic_props(root) 

3233 

3234 if self.sysinfo is not None: 

3235 root.append(self.sysinfo.format_dom()) 

3236 

3237 self._format_os(root) 

3238 self._format_features(root) 

3239 

3240 if self.cputune is not None: 

3241 root.append(self.cputune.format_dom()) 

3242 

3243 if self.clock is not None: 

3244 root.append(self.clock.format_dom()) 

3245 

3246 if self.cpu is not None: 

3247 root.append(self.cpu.format_dom()) 

3248 

3249 self._format_devices(root) 

3250 

3251 self._format_idmaps(root) 

3252 

3253 self._format_perf_events(root) 

3254 

3255 self._format_sev(root) 

3256 

3257 return root 

3258 

3259 def _parse_basic_props(self, xmldoc): 

3260 # memmbacking, memtune, numatune, metadata are skipped just because 

3261 # corresponding config types do not implement parse_dom method 

3262 if xmldoc.tag == 'uuid': 

3263 self.uuid = xmldoc.text 

3264 elif xmldoc.tag == 'name': 

3265 self.name = xmldoc.text 

3266 elif xmldoc.tag == 'memory': 

3267 self.memory = int(xmldoc.text) 

3268 elif xmldoc.tag == 'vcpu': 

3269 self.vcpus = int(xmldoc.text) 

3270 if xmldoc.get('cpuset') is not None: 

3271 self.cpuset = hardware.parse_cpu_spec(xmldoc.get('cpuset')) 

3272 

3273 def _parse_os(self, xmldoc): 

3274 if xmldoc.get('firmware'): 3274 ↛ 3275line 3274 didn't jump to line 3275 because the condition on line 3274 was never true

3275 self.os_firmware = xmldoc.get('firmware') 

3276 

3277 # smbios is skipped just because LibvirtConfigGuestSMBIOS 

3278 # does not implement parse_dom method 

3279 for c in xmldoc: 

3280 if c.tag == 'type': 

3281 self.os_type = c.text 

3282 self.os_mach_type = c.get('machine') 

3283 elif c.tag == 'kernel': 

3284 self.os_kernel = c.text 

3285 elif c.tag == 'loader': 

3286 self.os_loader = c.text 

3287 if c.get('type') == 'pflash': 

3288 self.os_loader_type = 'pflash' 

3289 elif c.tag == 'initrd': 

3290 self.os_initrd = c.text 

3291 elif c.tag == 'cmdline': 

3292 self.os_cmdline = c.text 

3293 elif c.tag == 'root': 

3294 self.os_root = c.text 

3295 elif c.tag == 'init': 

3296 self.os_init_path = c.text 

3297 elif c.tag == 'boot': 

3298 self.os_boot_dev.append(c.get('dev')) 

3299 elif c.tag == 'bootmenu': 

3300 if c.get('enable') == 'yes': 3300 ↛ 3279line 3300 didn't jump to line 3279 because the condition on line 3300 was always true

3301 self.os_bootmenu = True 

3302 elif c.tag == 'initenv': 

3303 self.os_init_env[c.get('name')] = c.text 

3304 

3305 def parse_dom(self, xmldoc): 

3306 self.virt_type = xmldoc.get('type') 

3307 # Note: This cover only for: LibvirtConfigGuestDisks 

3308 # LibvirtConfigGuestFilesys 

3309 # LibvirtConfigGuestHostdevPCI 

3310 # LibvirtConfigGuestHostdevMDEV 

3311 # LibvirtConfigGuestInterface 

3312 # LibvirtConfigGuestUidMap 

3313 # LibvirtConfigGuestGidMap 

3314 # LibvirtConfigGuestCPU 

3315 # LibvirtConfigGuestVPMEM 

3316 # LibvirtConfigGuestIOMMU 

3317 for c in xmldoc: 

3318 if c.tag == 'devices': 

3319 for d in c: 

3320 if d.tag == 'disk': 

3321 obj = LibvirtConfigGuestDisk() 

3322 obj.parse_dom(d) 

3323 self.devices.append(obj) 

3324 elif d.tag == 'filesystem': 

3325 obj = LibvirtConfigGuestFilesys() 

3326 obj.parse_dom(d) 

3327 self.devices.append(obj) 

3328 elif d.tag == 'hostdev' and d.get('type') == 'pci': 

3329 obj = LibvirtConfigGuestHostdevPCI() 

3330 obj.parse_dom(d) 

3331 self.devices.append(obj) 

3332 elif d.tag == 'hostdev' and d.get('type') == 'mdev': 

3333 obj = LibvirtConfigGuestHostdevMDEV() 

3334 obj.parse_dom(d) 

3335 self.devices.append(obj) 

3336 elif d.tag == 'interface': 

3337 obj = LibvirtConfigGuestInterface() 

3338 obj.parse_dom(d) 

3339 self.devices.append(obj) 

3340 elif d.tag == 'memory' and d.get('model') == 'nvdimm': 3340 ↛ 3341line 3340 didn't jump to line 3341 because the condition on line 3340 was never true

3341 obj = LibvirtConfigGuestVPMEM() 

3342 obj.parse_dom(d) 

3343 self.devices.append(obj) 

3344 elif d.tag == 'iommu': 3344 ↛ 3345line 3344 didn't jump to line 3345 because the condition on line 3344 was never true

3345 obj = LibvirtConfigGuestIOMMU() 

3346 obj.parse_dom(d) 

3347 self.devices.append(obj) 

3348 if c.tag == 'idmap': 3348 ↛ 3349line 3348 didn't jump to line 3349 because the condition on line 3348 was never true

3349 for idmap in c: 

3350 obj = None 

3351 if idmap.tag == 'uid': 

3352 obj = LibvirtConfigGuestUIDMap() 

3353 elif idmap.tag == 'gid': 

3354 obj = LibvirtConfigGuestGIDMap() 

3355 

3356 if obj: 

3357 obj.parse_dom(idmap) 

3358 self.idmaps.append(obj) 

3359 elif c.tag == 'cpu': 

3360 obj = LibvirtConfigGuestCPU() 

3361 obj.parse_dom(c) 

3362 self.cpu = obj 

3363 elif c.tag == 'perf': 

3364 for p in c: 

3365 if p.get('enabled') and p.get('enabled') == 'yes': 

3366 self.add_perf_event(p.get('name')) 

3367 elif c.tag == 'os': 

3368 self._parse_os(c) 

3369 else: 

3370 self._parse_basic_props(c) 

3371 

3372 def add_feature(self, dev: LibvirtConfigGuestFeature) -> None: 

3373 self.features.append(dev) 

3374 

3375 def add_device(self, dev: LibvirtConfigGuestDevice) -> None: 

3376 self.devices.append(dev) 

3377 

3378 def add_perf_event(self, event): 

3379 self.perf_events.append(event) 

3380 

3381 def set_clock(self, clk): 

3382 self.clock = clk 

3383 

3384 

3385class LibvirtConfigGuestSnapshot(LibvirtConfigObject): 

3386 

3387 def __init__(self, **kwargs): 

3388 super(LibvirtConfigGuestSnapshot, self).__init__( 

3389 root_name="domainsnapshot", 

3390 **kwargs) 

3391 

3392 self.name = None 

3393 self.disks = [] 

3394 

3395 def format_dom(self): 

3396 ss = super(LibvirtConfigGuestSnapshot, self).format_dom() 

3397 

3398 if self.name: 

3399 ss.append(self._text_node("name", self.name)) 

3400 

3401 disks = etree.Element('disks') 

3402 

3403 for disk in self.disks: 

3404 disks.append(disk.format_dom()) 

3405 

3406 ss.append(disks) 

3407 

3408 return ss 

3409 

3410 def add_disk(self, disk): 

3411 self.disks.append(disk) 

3412 

3413 

3414class LibvirtConfigNodeDevice(LibvirtConfigObject): 

3415 """Libvirt Node Devices parser.""" 

3416 

3417 def __init__(self, **kwargs): 

3418 super(LibvirtConfigNodeDevice, self).__init__(root_name="device", 

3419 **kwargs) 

3420 self.name = None 

3421 self.parent = None 

3422 self.pci_capability = None 

3423 self.mdev_information = None 

3424 self.vdpa_capability = None 

3425 self.vpd_capability = None 

3426 

3427 def format_dom(self): 

3428 dev = super().format_dom() 

3429 if self.name: 

3430 dev.append(self._text_node('name', str(self.name))) 

3431 if self.parent: 

3432 dev.append(self._text_node('parent', str(self.parent))) 

3433 if self.mdev_information: 

3434 dev.append(self.mdev_information.format_dom()) 

3435 return dev 

3436 

3437 def parse_dom(self, xmldoc): 

3438 super(LibvirtConfigNodeDevice, self).parse_dom(xmldoc) 

3439 

3440 for c in xmldoc: 

3441 if c.tag == "name": 

3442 self.name = c.text 

3443 elif c.tag == "parent": 

3444 self.parent = c.text 

3445 elif c.tag == "capability" and c.get("type") in ['pci', 'net']: 

3446 pcicap = LibvirtConfigNodeDevicePciCap() 

3447 pcicap.parse_dom(c) 

3448 self.pci_capability = pcicap 

3449 elif c.tag == "capability" and c.get("type") in ['mdev']: 

3450 mdev_info = LibvirtConfigNodeDeviceMdevInformation() 

3451 mdev_info.parse_dom(c) 

3452 self.mdev_information = mdev_info 

3453 elif c.tag == "capability" and c.get("type") in ['vdpa']: 

3454 vdpa_caps = LibvirtConfigNodeDeviceVDPACap() 

3455 vdpa_caps.parse_dom(c) 

3456 self.vdpa_capability = vdpa_caps 

3457 

3458 

3459class LibvirtConfigNodeDeviceVDPACap(LibvirtConfigObject): 

3460 def __init__(self, **kwargs): 

3461 super().__init__( 

3462 root_name="capability", **kwargs) 

3463 self.dev_path = None 

3464 

3465 def parse_dom(self, xmldoc): 

3466 super().parse_dom(xmldoc) 

3467 for c in xmldoc: 

3468 if c.tag == "chardev": 3468 ↛ 3467line 3468 didn't jump to line 3467 because the condition on line 3468 was always true

3469 self.dev_path = c.text 

3470 

3471 

3472class LibvirtConfigNodeDevicePciCap(LibvirtConfigObject): 

3473 """Libvirt Node Devices pci capability parser.""" 

3474 

3475 def __init__(self, **kwargs): 

3476 super(LibvirtConfigNodeDevicePciCap, self).__init__( 

3477 root_name="capability", **kwargs) 

3478 self.domain = None 

3479 self.bus = None 

3480 self.slot = None 

3481 self.function = None 

3482 self.product = None 

3483 self.product_id = None 

3484 self.vendor = None 

3485 self.vendor_id = None 

3486 self.numa_node = None 

3487 self.fun_capability = [] 

3488 self.mdev_capability = [] 

3489 self.vpd_capability = None 

3490 self.interface = None 

3491 self.address = None 

3492 self.link_state = None 

3493 self.features = [] 

3494 

3495 def parse_dom(self, xmldoc): 

3496 super(LibvirtConfigNodeDevicePciCap, self).parse_dom(xmldoc) 

3497 

3498 for c in xmldoc: 

3499 if c.tag == "domain": 

3500 self.domain = int(c.text) 

3501 elif c.tag == "slot": 

3502 self.slot = int(c.text) 

3503 elif c.tag == "bus": 

3504 self.bus = int(c.text) 

3505 elif c.tag == "function": 

3506 self.function = int(c.text) 

3507 elif c.tag == "product": 

3508 self.product = c.text 

3509 self.product_id = int(c.get('id'), 16) 

3510 elif c.tag == "vendor": 

3511 self.vendor = c.text 

3512 self.vendor_id = int(c.get('id'), 16) 

3513 elif c.tag == "numa": 

3514 self.numa_node = int(c.get('node')) 

3515 elif c.tag == "interface": 

3516 self.interface = c.text 

3517 elif c.tag == "address": 

3518 self.address = c.text 

3519 elif c.tag == "link": 

3520 self.link_state = c.get('state') 

3521 elif c.tag == "feature": 

3522 self.features.append(c.get('name')) 

3523 elif c.tag == "capability" and c.get('type') in \ 

3524 ('virt_functions', 'phys_function'): 

3525 funcap = LibvirtConfigNodeDevicePciSubFunctionCap() 

3526 funcap.parse_dom(c) 

3527 self.fun_capability.append(funcap) 

3528 elif c.tag == "capability" and c.get('type') in ('mdev_types',): 

3529 mdevcap = LibvirtConfigNodeDeviceMdevCapableSubFunctionCap() 

3530 mdevcap.parse_dom(c) 

3531 self.mdev_capability.append(mdevcap) 

3532 elif c.tag == "capability" and c.get('type') in ('vpd',): 

3533 vpdcap = LibvirtConfigNodeDeviceVpdCap() 

3534 vpdcap.parse_dom(c) 

3535 self.vpd_capability = vpdcap 

3536 

3537 def pci_address(self): 

3538 return "%04x:%02x:%02x.%01x" % ( 

3539 self.domain, self.bus, self.slot, self.function) 

3540 

3541 

3542class LibvirtConfigNodeDevicePciSubFunctionCap(LibvirtConfigObject): 

3543 def __init__(self, **kwargs): 

3544 super(LibvirtConfigNodeDevicePciSubFunctionCap, self).__init__( 

3545 root_name="capability", **kwargs) 

3546 self.type = None 

3547 self.device_addrs = list() # list of tuple (domain,bus,slot,function) 

3548 

3549 def parse_dom(self, xmldoc): 

3550 super(LibvirtConfigNodeDevicePciSubFunctionCap, self).parse_dom(xmldoc) 

3551 self.type = xmldoc.get("type") 

3552 for c in xmldoc: 

3553 if c.tag == "address": 3553 ↛ 3552line 3553 didn't jump to line 3552 because the condition on line 3553 was always true

3554 self.device_addrs.append((int(c.get('domain'), 16), 

3555 int(c.get('bus'), 16), 

3556 int(c.get('slot'), 16), 

3557 int(c.get('function'), 16))) 

3558 

3559 

3560class LibvirtConfigNodeDeviceMdevCapableSubFunctionCap(LibvirtConfigObject): 

3561 def __init__(self, **kwargs): 

3562 super(LibvirtConfigNodeDeviceMdevCapableSubFunctionCap, self).__init__( 

3563 root_name="capability", **kwargs) 

3564 # mdev_types is a list of dictionaries where each item looks like: 

3565 # {'type': 'nvidia-11', 'name': 'GRID M60-0B', 'deviceAPI': 'vfio-pci', 

3566 # 'availableInstances': 16} 

3567 self.mdev_types = list() 

3568 

3569 def parse_dom(self, xmldoc): 

3570 super(LibvirtConfigNodeDeviceMdevCapableSubFunctionCap, 

3571 self).parse_dom(xmldoc) 

3572 for c in xmldoc: 

3573 if c.tag == "type": 3573 ↛ 3572line 3573 didn't jump to line 3572 because the condition on line 3573 was always true

3574 mdev_type = {'type': c.get('id')} 

3575 for e in c: 

3576 mdev_type[e.tag] = (int(e.text) 

3577 if e.tag == 'availableInstances' 

3578 else e.text) 

3579 self.mdev_types.append(mdev_type) 

3580 

3581 

3582class LibvirtConfigNodeDeviceMdevInformation(LibvirtConfigObject): 

3583 def __init__(self, **kwargs): 

3584 super(LibvirtConfigNodeDeviceMdevInformation, self).__init__( 

3585 root_name="capability", **kwargs) 

3586 self.type = None 

3587 self.iommu_group = None 

3588 self.uuid = None 

3589 

3590 def format_dom(self): 

3591 dev = super().format_dom() 

3592 dev.set('type', 'mdev') 

3593 if self.type: 3593 ↛ 3597line 3593 didn't jump to line 3597 because the condition on line 3593 was always true

3594 mdev_type = self._new_node('type') 

3595 mdev_type.set('id', self.type) 

3596 dev.append(mdev_type) 

3597 if self.uuid: 

3598 dev.append(self._text_node('uuid', self.uuid)) 

3599 if self.iommu_group: 3599 ↛ 3603line 3599 didn't jump to line 3603 because the condition on line 3599 was always true

3600 iommu_group = self._new_node('iommuGroup') 

3601 iommu_group.set('number', str(self.iommu_group)) 

3602 dev.append(iommu_group) 

3603 return dev 

3604 

3605 def parse_dom(self, xmldoc): 

3606 super(LibvirtConfigNodeDeviceMdevInformation, 

3607 self).parse_dom(xmldoc) 

3608 for c in xmldoc: 

3609 if c.tag == "type": 

3610 self.type = c.get('id') 

3611 if c.tag == "iommuGroup": 

3612 self.iommu_group = int(c.get('number')) 

3613 if c.tag == "uuid": 

3614 self.uuid = c.text 

3615 

3616 

3617class LibvirtConfigNodeDeviceVpdCap(LibvirtConfigObject): 

3618 

3619 def __init__(self, **kwargs): 

3620 super().__init__( 

3621 root_name="capability", **kwargs) 

3622 self._card_name = None 

3623 self._change_level = None 

3624 self._manufacture_id = None 

3625 self._part_number = None 

3626 self._serial_number = None 

3627 self._asset_tag = None 

3628 self._ro_vendor_fields = {} 

3629 self._rw_vendor_fields = {} 

3630 self._rw_system_fields = {} 

3631 

3632 @staticmethod 

3633 def _process_custom_field(fields_dict, field_element): 

3634 index = field_element.get('index') 

3635 if index: 3635 ↛ exitline 3635 didn't return from function '_process_custom_field' because the condition on line 3635 was always true

3636 fields_dict[index] = field_element.text 

3637 

3638 def _parse_ro_fields(self, fields_element): 

3639 for e in fields_element: 

3640 if e.tag == 'change_level': 

3641 self._change_level = e.text 

3642 elif e.tag == 'manufacture_id': 

3643 self._manufacture_id = e.text 

3644 elif e.tag == 'part_number': 

3645 self._part_number = e.text 

3646 elif e.tag == 'serial_number': 

3647 self._serial_number = e.text 

3648 elif e.tag == 'vendor_field': 3648 ↛ 3639line 3648 didn't jump to line 3639 because the condition on line 3648 was always true

3649 self._process_custom_field(self._ro_vendor_fields, e) 

3650 

3651 def _parse_rw_fields(self, fields_element): 

3652 for e in fields_element: 

3653 if e.tag == 'asset_tag': 

3654 self._asset_tag = e.text 

3655 elif e.tag == 'vendor_field': 

3656 self._process_custom_field(self._rw_vendor_fields, e) 

3657 elif e.tag == 'system_field': 3657 ↛ 3652line 3657 didn't jump to line 3652 because the condition on line 3657 was always true

3658 self._process_custom_field(self._rw_system_fields, e) 

3659 

3660 def parse_dom(self, xmldoc): 

3661 super(LibvirtConfigNodeDeviceVpdCap, self).parse_dom(xmldoc) 

3662 for c in xmldoc: 

3663 if c.tag == "name": 

3664 self._card_name = c.text 

3665 if c.tag == "fields": 

3666 access = c.get('access') 

3667 if access: 3667 ↛ 3662line 3667 didn't jump to line 3662 because the condition on line 3667 was always true

3668 if access == 'readonly': 

3669 self._parse_ro_fields(c) 

3670 elif access == 'readwrite': 3670 ↛ 3673line 3670 didn't jump to line 3673 because the condition on line 3670 was always true

3671 self._parse_rw_fields(c) 

3672 else: 

3673 continue 

3674 

3675 @property 

3676 def card_name(self): 

3677 return self._card_name 

3678 

3679 @property 

3680 def change_level(self): 

3681 return self._change_level 

3682 

3683 @property 

3684 def manufacture_id(self): 

3685 return self._manufacture_id 

3686 

3687 @property 

3688 def part_number(self): 

3689 return self._part_number 

3690 

3691 @property 

3692 def card_serial_number(self): 

3693 return self._serial_number 

3694 

3695 @property 

3696 def asset_tag(self): 

3697 return self._asset_tag 

3698 

3699 @property 

3700 def ro_vendor_fields(self): 

3701 return self._ro_vendor_fields 

3702 

3703 @property 

3704 def rw_vendor_fields(self): 

3705 return self._rw_vendor_fields 

3706 

3707 @property 

3708 def rw_system_fields(self): 

3709 return self._rw_system_fields 

3710 

3711 

3712class LibvirtConfigGuestRng(LibvirtConfigGuestDevice): 

3713 

3714 def __init__(self, **kwargs): 

3715 super(LibvirtConfigGuestRng, self).__init__(root_name="rng", 

3716 **kwargs) 

3717 

3718 self.device_model = 'virtio' 

3719 self.model = 'random' 

3720 self.backend = None 

3721 self.rate_period = None 

3722 self.rate_bytes = None 

3723 self.driver_iommu = False 

3724 

3725 @property 

3726 def uses_virtio(self): 

3727 return 'virtio' == self.device_model 

3728 

3729 def format_dom(self): 

3730 dev = super(LibvirtConfigGuestRng, self).format_dom() 

3731 dev.set('model', self.device_model) 

3732 

3733 backend = etree.Element("backend") 

3734 backend.set("model", self.model) 

3735 backend.text = self.backend 

3736 

3737 if self.rate_period and self.rate_bytes: 

3738 rate = etree.Element("rate") 

3739 rate.set("period", str(self.rate_period)) 

3740 rate.set("bytes", str(self.rate_bytes)) 

3741 dev.append(rate) 

3742 

3743 dev.append(backend) 

3744 

3745 if self.driver_iommu: 

3746 dev.append(etree.Element('driver', iommu="on")) 

3747 

3748 return dev 

3749 

3750 

3751class LibvirtConfigGuestMetaNovaInstance(LibvirtConfigObject): 

3752 

3753 def __init__(self): 

3754 super(LibvirtConfigGuestMetaNovaInstance, 

3755 self).__init__(root_name="instance", 

3756 ns_prefix="nova", 

3757 ns_uri=NOVA_NS) 

3758 

3759 self.package = None 

3760 self.flavor = None 

3761 self.name = None 

3762 self.creationTime = None 

3763 self.owner = None 

3764 self.roottype = None 

3765 self.rootid = None 

3766 self.ports = None 

3767 

3768 def format_dom(self): 

3769 meta = super(LibvirtConfigGuestMetaNovaInstance, self).format_dom() 

3770 

3771 pkg = self._new_node("package") 

3772 pkg.set("version", self.package) 

3773 meta.append(pkg) 

3774 if self.name is not None: 3774 ↛ 3776line 3774 didn't jump to line 3776 because the condition on line 3774 was always true

3775 meta.append(self._text_node("name", self.name)) 

3776 if self.creationTime is not None: 3776 ↛ 3780line 3776 didn't jump to line 3780 because the condition on line 3776 was always true

3777 timestr = time.strftime("%Y-%m-%d %H:%M:%S", 

3778 time.gmtime(self.creationTime)) 

3779 meta.append(self._text_node("creationTime", timestr)) 

3780 if self.flavor is not None: 3780 ↛ 3782line 3780 didn't jump to line 3782 because the condition on line 3780 was always true

3781 meta.append(self.flavor.format_dom()) 

3782 if self.owner is not None: 3782 ↛ 3785line 3782 didn't jump to line 3785 because the condition on line 3782 was always true

3783 meta.append(self.owner.format_dom()) 

3784 

3785 if self.roottype is not None and self.rootid is not None: 3785 ↛ 3790line 3785 didn't jump to line 3790 because the condition on line 3785 was always true

3786 root = self._new_node("root") 

3787 root.set("type", self.roottype) 

3788 root.set("uuid", str(self.rootid)) 

3789 meta.append(root) 

3790 if self.ports is not None: 3790 ↛ 3793line 3790 didn't jump to line 3793 because the condition on line 3790 was always true

3791 meta.append(self.ports.format_dom()) 

3792 

3793 return meta 

3794 

3795 

3796class LibvirtConfigGuestMetaNovaFlavor(LibvirtConfigObject): 

3797 

3798 def __init__(self): 

3799 super(LibvirtConfigGuestMetaNovaFlavor, 

3800 self).__init__(root_name="flavor", 

3801 ns_prefix="nova", 

3802 ns_uri=NOVA_NS) 

3803 

3804 self.name = None 

3805 self.memory = None 

3806 self.disk = None 

3807 self.swap = None 

3808 self.ephemeral = None 

3809 self.vcpus = None 

3810 

3811 def format_dom(self): 

3812 meta = super(LibvirtConfigGuestMetaNovaFlavor, self).format_dom() 

3813 meta.set("name", self.name) 

3814 if self.memory is not None: 3814 ↛ 3816line 3814 didn't jump to line 3816 because the condition on line 3814 was always true

3815 meta.append(self._text_node("memory", str(self.memory))) 

3816 if self.disk is not None: 3816 ↛ 3818line 3816 didn't jump to line 3818 because the condition on line 3816 was always true

3817 meta.append(self._text_node("disk", str(self.disk))) 

3818 if self.swap is not None: 3818 ↛ 3820line 3818 didn't jump to line 3820 because the condition on line 3818 was always true

3819 meta.append(self._text_node("swap", str(self.swap))) 

3820 if self.ephemeral is not None: 3820 ↛ 3822line 3820 didn't jump to line 3822 because the condition on line 3820 was always true

3821 meta.append(self._text_node("ephemeral", str(self.ephemeral))) 

3822 if self.vcpus is not None: 3822 ↛ 3824line 3822 didn't jump to line 3824 because the condition on line 3822 was always true

3823 meta.append(self._text_node("vcpus", str(self.vcpus))) 

3824 return meta 

3825 

3826 

3827class LibvirtConfigGuestMetaNovaOwner(LibvirtConfigObject): 

3828 

3829 def __init__(self): 

3830 super(LibvirtConfigGuestMetaNovaOwner, 

3831 self).__init__(root_name="owner", 

3832 ns_prefix="nova", 

3833 ns_uri=NOVA_NS) 

3834 

3835 self.userid = None 

3836 self.username = None 

3837 self.projectid = None 

3838 self.projectname = None 

3839 

3840 def format_dom(self): 

3841 meta = super(LibvirtConfigGuestMetaNovaOwner, self).format_dom() 

3842 if self.userid is not None and self.username is not None: 

3843 user = self._text_node("user", self.username) 

3844 user.set("uuid", self.userid) 

3845 meta.append(user) 

3846 if self.projectid is not None and self.projectname is not None: 

3847 project = self._text_node("project", self.projectname) 

3848 project.set("uuid", self.projectid) 

3849 meta.append(project) 

3850 return meta 

3851 

3852 

3853class LibvirtConfigSecret(LibvirtConfigObject): 

3854 

3855 def __init__(self): 

3856 super(LibvirtConfigSecret, 

3857 self).__init__(root_name="secret") 

3858 self.ephemeral = False 

3859 self.private = False 

3860 self.description = None 

3861 self.uuid = None 

3862 self.usage_type = None 

3863 self.usage_id = None 

3864 

3865 def format_dom(self): 

3866 root = super(LibvirtConfigSecret, self).format_dom() 

3867 root.set("ephemeral", self.get_yes_no_str(self.ephemeral)) 

3868 root.set("private", self.get_yes_no_str(self.private)) 

3869 if self.description is not None: 

3870 root.append(self._text_node("description", str(self.description))) 

3871 if self.uuid is not None: 

3872 root.append(self._text_node("uuid", str(self.uuid))) 

3873 usage = self._new_node("usage") 

3874 usage.set("type", self.usage_type) 

3875 if self.usage_type in ('ceph', 'vtpm'): 

3876 usage.append(self._text_node('name', str(self.usage_id))) 

3877 elif self.usage_type == 'iscsi': 

3878 usage.append(self._text_node('target', str(self.usage_id))) 

3879 elif self.usage_type == 'volume': 3879 ↛ 3881line 3879 didn't jump to line 3881 because the condition on line 3879 was always true

3880 usage.append(self._text_node('volume', str(self.usage_id))) 

3881 root.append(usage) 

3882 return root 

3883 

3884 

3885class LibvirtConfigGuestVPMEM(LibvirtConfigGuestDevice): 

3886 def __init__(self, **kwargs): 

3887 super(LibvirtConfigGuestVPMEM, self).__init__( 

3888 root_name="memory", **kwargs) 

3889 

3890 self.model = "nvdimm" 

3891 self.access = "shared" 

3892 self.source_path = "" 

3893 self.align_size = 0 

3894 self.pmem = True 

3895 

3896 self.target_size = 0 

3897 self.target_node = 0 

3898 self.label_size = 2 * units.Ki 

3899 

3900 def format_dom(self): 

3901 memory = super(LibvirtConfigGuestVPMEM, self).format_dom() 

3902 

3903 memory.set("model", self.model) 

3904 memory.set("access", self.access) 

3905 

3906 source = etree.Element("source") 

3907 source.append(self._text_node("path", self.source_path)) 

3908 source.append(self._text_node("alignsize", self.align_size)) 

3909 if self.pmem is True: 3909 ↛ 3912line 3909 didn't jump to line 3912 because the condition on line 3909 was always true

3910 source.append(etree.Element("pmem")) 

3911 

3912 target = etree.Element("target") 

3913 target.append(self._text_node("size", self.target_size)) 

3914 target.append(self._text_node("node", self.target_node)) 

3915 label = etree.Element("label") 

3916 label.append(self._text_node("size", self.label_size)) 

3917 target.append(label) 

3918 

3919 memory.append(source) 

3920 memory.append(target) 

3921 

3922 return memory 

3923 

3924 def parse_dom(self, xmldoc): 

3925 super(LibvirtConfigGuestVPMEM, self).parse_dom(xmldoc) 

3926 self.model = xmldoc.get("model") 

3927 self.access = xmldoc.get("access") 

3928 

3929 for c in list(xmldoc): 

3930 if c.tag == "source": 

3931 for sub in list(c): 

3932 if sub.tag == "path": 

3933 self.source_path = sub.text 

3934 if sub.tag == "alignsize": 

3935 self.align_size = sub.text 

3936 elif c.tag == "target": 

3937 for sub in list(c): 

3938 if sub.tag == "size": 

3939 self.target_size = sub.text 

3940 

3941 

3942class LibvirtConfigGuestIOMMU(LibvirtConfigGuestDevice): 

3943 """https://libvirt.org/formatdomain.html#iommu-devices""" 

3944 

3945 def __init__(self, **kwargs): 

3946 super().__init__(root_name="iommu", **kwargs) 

3947 

3948 self.model: str = fields.VIOMMUModel.AUTO 

3949 self.interrupt_remapping: bool = False 

3950 self.caching_mode: bool = False 

3951 self.eim: bool = False 

3952 self.iotlb: bool = False 

3953 

3954 def format_dom(self): 

3955 iommu = super().format_dom() 

3956 iommu.set("model", self.model) 

3957 

3958 driver = etree.Element("driver") 

3959 driver.set("intremap", self.get_on_off_str(self.interrupt_remapping)) 

3960 driver.set("caching_mode", self.get_on_off_str(self.caching_mode)) 

3961 

3962 # Set aw_bits to None when the Libvirt version not satisfy 

3963 # MIN_LIBVIRT_VIOMMU_AW_BITS in driver. When it's None, means it's not 

3964 # supported to have aw_bits. 

3965 if hasattr(self, "aw_bits"): 3965 ↛ 3967line 3965 didn't jump to line 3967 because the condition on line 3965 was always true

3966 driver.set("aw_bits", str(self.aw_bits)) 

3967 driver.set("eim", self.get_on_off_str(self.eim)) 

3968 driver.set("iotlb", self.get_on_off_str(self.iotlb)) 

3969 iommu.append(driver) 

3970 

3971 return iommu 

3972 

3973 def parse_dom(self, xmldoc): 

3974 super().parse_dom(xmldoc) 

3975 self.model = xmldoc.get("model") 

3976 

3977 driver = xmldoc.find("./driver") 

3978 if driver: 

3979 self.interrupt_remapping = self.parse_on_off_str( 

3980 driver.get("intremap")) 

3981 self.caching_mode = self.parse_on_off_str( 

3982 driver.get("caching_mode")) 

3983 if driver.get("aw_bits") is not None: 

3984 self.aw_bits = int(driver.get("aw_bits")) 

3985 self.iotlb = self.parse_on_off_str(driver.get("iotlb")) 

3986 self.eim = self.parse_on_off_str(driver.get("eim")) 

3987 

3988 

3989class LibvirtConfigGuestMetaNovaPorts(LibvirtConfigObject): 

3990 

3991 def __init__(self, ports=None): 

3992 super(LibvirtConfigGuestMetaNovaPorts, self).__init__( 

3993 root_name="ports", ns_prefix="nova", ns_uri=NOVA_NS) 

3994 

3995 self.ports = ports 

3996 

3997 def format_dom(self): 

3998 meta = self._new_node("ports") 

3999 for port in self.ports or []: 

4000 meta.append(port.format_dom()) 

4001 return meta 

4002 

4003 

4004class LibvirtConfigGuestMetaNovaPort(LibvirtConfigObject): 

4005 

4006 def __init__(self, uuid, ips=None): 

4007 super(LibvirtConfigGuestMetaNovaPort, self).__init__( 

4008 root_name="port", ns_prefix="nova", ns_uri=NOVA_NS) 

4009 

4010 self.uuid = uuid 

4011 self.ips = ips 

4012 

4013 def format_dom(self): 

4014 meta = self._new_node("port") 

4015 meta.set("uuid", str(self.uuid)) 

4016 for ip in self.ips or []: 

4017 meta.append(ip.format_dom()) 

4018 return meta 

4019 

4020 

4021class LibvirtConfigGuestMetaNovaIp(LibvirtConfigObject): 

4022 

4023 def __init__(self, ip_type, address, ip_version): 

4024 super(LibvirtConfigGuestMetaNovaIp, self).__init__( 

4025 root_name="ip", ns_prefix="nova", ns_uri=NOVA_NS) 

4026 

4027 self.ip_type = ip_type 

4028 self.address = address 

4029 self.ip_version = ip_version 

4030 

4031 def format_dom(self): 

4032 meta = self._new_node("ip") 

4033 meta.set("type", str(self.ip_type)) 

4034 meta.set("address", str(self.address)) 

4035 meta.set("ipVersion", str(self.ip_version)) 

4036 return meta