21
21
import errno
22
22
import os
23
23
import re
24
+ import typing as ty
24
25
import uuid
25
26
26
27
import os_traits
29
30
from oslo_utils import fileutils
30
31
31
32
import nova .conf
33
+ from nova import context as nova_context
32
34
from nova .i18n import _
33
35
from nova import objects
34
36
from nova .objects import fields as obj_fields
39
41
from nova import utils
40
42
from nova .virt import images
41
43
from nova .virt .libvirt import config as vconfig
44
+ from nova .virt .libvirt import guest as libvirt_guest
42
45
from nova .virt .libvirt .volume import remotefs
43
46
44
47
CONF = nova .conf .CONF
96
99
TRAITS_CPU_MAPPING = {v : k for k , v in CPU_TRAITS_MAPPING .items ()}
97
100
98
101
99
- def create_image (disk_format , path , size ):
102
+ def create_image (
103
+ disk_format : str , path : str , size : ty .Union [str , int ],
104
+ ) -> None :
100
105
"""Create a disk image
101
106
102
107
:param disk_format: Disk image format (as known by qemu-img)
@@ -111,7 +116,9 @@ def create_image(disk_format, path, size):
111
116
processutils .execute ('qemu-img' , 'create' , '-f' , disk_format , path , size )
112
117
113
118
114
- def create_cow_image (backing_file , path , size = None ):
119
+ def create_cow_image (
120
+ backing_file : ty .Optional [str ], path : str , size : ty .Optional [int ] = None ,
121
+ ) -> None :
115
122
"""Create COW image
116
123
117
124
Creates a COW image with the given backing file
@@ -144,7 +151,9 @@ def create_cow_image(backing_file, path, size=None):
144
151
processutils .execute (* cmd )
145
152
146
153
147
- def create_ploop_image (disk_format , path , size , fs_type ):
154
+ def create_ploop_image (
155
+ disk_format : str , path : str , size : ty .Union [int , str ], fs_type : str ,
156
+ ) -> None :
148
157
"""Create ploop image
149
158
150
159
:param disk_format: Disk image format (as known by ploop)
@@ -165,7 +174,9 @@ def create_ploop_image(disk_format, path, size, fs_type):
165
174
nova .privsep .libvirt .ploop_init (size , disk_format , fs_type , disk_path )
166
175
167
176
168
- def pick_disk_driver_name (hypervisor_version , is_block_dev = False ):
177
+ def pick_disk_driver_name (
178
+ hypervisor_version : int , is_block_dev : bool = False ,
179
+ ) -> ty .Optional [str ]:
169
180
"""Pick the libvirt primary backend driver name
170
181
171
182
If the hypervisor supports multiple backend drivers we have to tell libvirt
@@ -221,7 +232,7 @@ def pick_disk_driver_name(hypervisor_version, is_block_dev=False):
221
232
return None
222
233
223
234
224
- def get_disk_size (path , format = None ):
235
+ def get_disk_size (path : str , format : ty . Optional [ str ] = None ) -> int :
225
236
"""Get the (virtual) size of a disk image
226
237
227
238
:param path: Path to the disk image
@@ -233,7 +244,9 @@ def get_disk_size(path, format=None):
233
244
return int (size )
234
245
235
246
236
- def get_disk_backing_file (path , basename = True , format = None ):
247
+ def get_disk_backing_file (
248
+ path : str , basename : bool = True , format : ty .Optional [str ] = None ,
249
+ ) -> ty .Optional [str ]:
237
250
"""Get the backing file of a disk image
238
251
239
252
:param path: Path to the disk image
@@ -246,9 +259,15 @@ def get_disk_backing_file(path, basename=True, format=None):
246
259
return backing_file
247
260
248
261
249
- def copy_image (src , dest , host = None , receive = False ,
250
- on_execute = None , on_completion = None ,
251
- compression = True ):
262
+ def copy_image (
263
+ src : str ,
264
+ dest : str ,
265
+ host : ty .Optional [str ] = None ,
266
+ receive : bool = False ,
267
+ on_execute : ty .Callable = None ,
268
+ on_completion : ty .Callable = None ,
269
+ compression : bool = True ,
270
+ ) -> None :
252
271
"""Copy a disk image to an existing directory
253
272
254
273
:param src: Source image
@@ -280,7 +299,8 @@ def copy_image(src, dest, host=None, receive=False,
280
299
compression = compression )
281
300
282
301
283
- def write_to_file (path , contents ):
302
+ # TODO(stephenfin): This is dumb; remove it.
303
+ def write_to_file (path : str , contents : str ) -> None :
284
304
"""Write the given contents to a file
285
305
286
306
:param path: Destination file
@@ -290,7 +310,9 @@ def write_to_file(path, contents):
290
310
f .write (contents )
291
311
292
312
293
- def chown_for_id_maps (path , id_maps ):
313
+ def chown_for_id_maps (
314
+ path : str , id_maps : ty .List [vconfig .LibvirtConfigGuestIDMap ],
315
+ ) -> None :
294
316
"""Change ownership of file or directory for an id mapped
295
317
environment
296
318
@@ -304,7 +326,9 @@ def chown_for_id_maps(path, id_maps):
304
326
nova .privsep .idmapshift .shift (path , uid_maps , gid_maps )
305
327
306
328
307
- def extract_snapshot (disk_path , source_fmt , out_path , dest_fmt ):
329
+ def extract_snapshot (
330
+ disk_path : str , source_fmt : str , out_path : str , dest_fmt : str ,
331
+ ) -> None :
308
332
"""Extract a snapshot from a disk image.
309
333
Note that nobody should write to the disk image during this operation.
310
334
@@ -322,7 +346,8 @@ def extract_snapshot(disk_path, source_fmt, out_path, dest_fmt):
322
346
compress = compress )
323
347
324
348
325
- def load_file (path ):
349
+ # TODO(stephenfin): This is dumb; remove it.
350
+ def load_file (path : str ) -> str :
326
351
"""Read contents of file
327
352
328
353
:param path: File to read
@@ -331,6 +356,8 @@ def load_file(path):
331
356
return fp .read ()
332
357
333
358
359
+ # TODO(stephenfin): Remove this; we have suitably powerful mocking abilities
360
+ # nowadays
334
361
def file_open (* args , ** kwargs ):
335
362
"""Open file
336
363
@@ -343,7 +370,7 @@ def file_open(*args, **kwargs):
343
370
return open (* args , ** kwargs )
344
371
345
372
346
- def find_disk (guest ) :
373
+ def find_disk (guest : libvirt_guest . Guest ) -> ty . Tuple [ str , ty . Optional [ str ]] :
347
374
"""Find root device path for instance
348
375
349
376
May be file or device
@@ -384,7 +411,7 @@ def find_disk(guest):
384
411
return (disk_path , disk_format )
385
412
386
413
387
- def get_disk_type_from_path (path ) :
414
+ def get_disk_type_from_path (path : str ) -> ty . Optional [ str ] :
388
415
"""Retrieve disk type (raw, qcow2, lvm, ploop) for given file."""
389
416
if path .startswith ('/dev' ):
390
417
return 'lvm'
@@ -398,7 +425,7 @@ def get_disk_type_from_path(path):
398
425
return None
399
426
400
427
401
- def get_fs_info (path ) :
428
+ def get_fs_info (path : str ) -> ty . Dict [ str , int ] :
402
429
"""Get free/used/total space info for a filesystem
403
430
404
431
:param path: Any dirent on the filesystem
@@ -412,12 +439,15 @@ def get_fs_info(path):
412
439
total = hddinfo .f_frsize * hddinfo .f_blocks
413
440
free = hddinfo .f_frsize * hddinfo .f_bavail
414
441
used = hddinfo .f_frsize * (hddinfo .f_blocks - hddinfo .f_bfree )
415
- return {'total' : total ,
416
- 'free' : free ,
417
- 'used' : used }
442
+ return {'total' : total , 'free' : free , 'used' : used }
418
443
419
444
420
- def fetch_image (context , target , image_id , trusted_certs = None ):
445
+ def fetch_image (
446
+ context : nova_context .RequestContext ,
447
+ target : str ,
448
+ image_id : str ,
449
+ trusted_certs : ty .Optional ['objects.TrustedCerts' ] = None ,
450
+ ) -> None :
421
451
"""Grab image.
422
452
423
453
:param context: nova.context.RequestContext auth request context
@@ -428,7 +458,12 @@ def fetch_image(context, target, image_id, trusted_certs=None):
428
458
images .fetch_to_raw (context , image_id , target , trusted_certs )
429
459
430
460
431
- def fetch_raw_image (context , target , image_id , trusted_certs = None ):
461
+ def fetch_raw_image (
462
+ context : nova_context .RequestContext ,
463
+ target : str ,
464
+ image_id : str ,
465
+ trusted_certs : ty .Optional ['objects.TrustedCerts' ] = None ,
466
+ ) -> None :
432
467
"""Grab initrd or kernel image.
433
468
434
469
This function does not attempt raw conversion, as these images will
@@ -442,7 +477,9 @@ def fetch_raw_image(context, target, image_id, trusted_certs=None):
442
477
images .fetch (context , image_id , target , trusted_certs )
443
478
444
479
445
- def get_instance_path (instance , relative = False ):
480
+ def get_instance_path (
481
+ instance : 'objects.Instance' , relative : bool = False ,
482
+ ) -> str :
446
483
"""Determine the correct path for instance storage.
447
484
448
485
This method determines the directory name for instance storage.
@@ -457,7 +494,10 @@ def get_instance_path(instance, relative=False):
457
494
return os .path .join (CONF .instances_path , instance .uuid )
458
495
459
496
460
- def get_instance_path_at_destination (instance , migrate_data = None ):
497
+ def get_instance_path_at_destination (
498
+ instance : 'objects.Instance' ,
499
+ migrate_data : ty .Optional ['objects.LibvirtLiveMigrateData' ] = None ,
500
+ ) -> str :
461
501
"""Get the instance path on destination node while live migration.
462
502
463
503
This method determines the directory name for instance storage on
@@ -484,7 +524,7 @@ def get_instance_path_at_destination(instance, migrate_data=None):
484
524
return instance_dir
485
525
486
526
487
- def get_arch (image_meta ) :
527
+ def get_arch (image_meta : 'objects.ImageMeta' ) -> str :
488
528
"""Determine the architecture of the guest (or host).
489
529
490
530
This method determines the CPU architecture that must be supported by
@@ -504,7 +544,7 @@ def get_arch(image_meta):
504
544
return obj_fields .Architecture .from_host ()
505
545
506
546
507
- def is_mounted (mount_path , source = None ):
547
+ def is_mounted (mount_path : str , source : ty . Optional [ str ] = None ) -> bool :
508
548
"""Check if the given source is mounted at given destination point."""
509
549
if not os .path .ismount (mount_path ):
510
550
return False
@@ -517,16 +557,16 @@ def is_mounted(mount_path, source=None):
517
557
return any (mnt [0 ] == source and mnt [1 ] == mount_path for mnt in mounts )
518
558
519
559
520
- def is_valid_hostname (hostname ) :
521
- return re .match (r"^[\w\-\.:]+$" , hostname )
560
+ def is_valid_hostname (hostname : str ) -> bool :
561
+ return bool ( re .match (r"^[\w\-\.:]+$" , hostname ) )
522
562
523
563
524
- def version_to_string (version ) :
564
+ def version_to_string (version : ty . Tuple [ int , int , int ]) -> str :
525
565
"""Returns string version based on tuple"""
526
566
return '.' .join ([str (x ) for x in version ])
527
567
528
568
529
- def cpu_features_to_traits (features ) :
569
+ def cpu_features_to_traits (features : ty . Set [ str ]) -> ty . Dict [ str , bool ] :
530
570
"""Returns this driver's CPU traits dict where keys are trait names from
531
571
CPU_TRAITS_MAPPING, values are boolean indicates whether the trait should
532
572
be set in the provider tree.
@@ -539,7 +579,7 @@ def cpu_features_to_traits(features):
539
579
return traits
540
580
541
581
542
- def get_cpu_model_from_arch (arch ) :
582
+ def get_cpu_model_from_arch (arch : str ) -> str :
543
583
mode = 'qemu64'
544
584
if arch == obj_fields .Architecture .I686 :
545
585
mode = 'qemu32'
@@ -552,7 +592,7 @@ def get_cpu_model_from_arch(arch):
552
592
return mode
553
593
554
594
555
- def get_machine_type (image_meta ) :
595
+ def get_machine_type (image_meta : 'objects.ImageMeta' ) -> ty . Optional [ str ] :
556
596
"""The guest machine type can be set as an image metadata property, or
557
597
otherwise based on architecture-specific defaults. If no defaults are
558
598
found then None will be returned. This will ultimately lead to QEMU using
@@ -565,7 +605,7 @@ def get_machine_type(image_meta):
565
605
return get_default_machine_type (get_arch (image_meta ))
566
606
567
607
568
- def get_default_machine_type (arch ) :
608
+ def get_default_machine_type (arch : str ) -> ty . Optional [ str ] :
569
609
# NOTE(lyarwood): Values defined in [libvirt]/hw_machine_type take
570
610
# precedence here if available for the provided arch.
571
611
for mapping in CONF .libvirt .hw_machine_type or {}:
@@ -595,21 +635,21 @@ def get_default_machine_type(arch):
595
635
return default_mtypes .get (arch )
596
636
597
637
598
- def mdev_name2uuid (mdev_name ) :
638
+ def mdev_name2uuid (mdev_name : str ) -> str :
599
639
"""Convert an mdev name (of the form mdev_<uuid_with_underscores>) to a
600
640
uuid (of the form 8-4-4-4-12).
601
641
"""
602
642
return str (uuid .UUID (mdev_name [5 :].replace ('_' , '-' )))
603
643
604
644
605
- def mdev_uuid2name (mdev_uuid ) :
645
+ def mdev_uuid2name (mdev_uuid : str ) -> str :
606
646
"""Convert an mdev uuid (of the form 8-4-4-4-12) to a name (of the form
607
647
mdev_<uuid_with_underscores>).
608
648
"""
609
649
return "mdev_" + mdev_uuid .replace ('-' , '_' )
610
650
611
651
612
- def get_flags_by_flavor_specs (flavor ) :
652
+ def get_flags_by_flavor_specs (flavor : 'objects.Flavor' ) -> ty . Set [ str ] :
613
653
req_spec = objects .RequestSpec (flavor = flavor )
614
654
resource_request = scheduler_utils .ResourceRequest (req_spec )
615
655
required_traits = resource_request .all_required_traits
0 commit comments