Coverage for nova/virt/imagecache.py: 97%

56 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-24 11:16 +0000

1# Copyright 2013 OpenStack Foundation 

2# All Rights Reserved. 

3# 

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

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

6# a copy of the License at 

7# 

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

9# 

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

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

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

13# License for the specific language governing permissions and limitations 

14# under the License. 

15 

16from nova.compute import task_states 

17from nova.compute import vm_states 

18import nova.conf 

19from nova import objects 

20from nova.virt import block_device as driver_block_device 

21 

22CONF = nova.conf.CONF 

23 

24 

25class ImageCacheManager(object): 

26 """Base class for the image cache manager. 

27 

28 This class will provide a generic interface to the image cache manager. 

29 """ 

30 

31 def __init__(self): 

32 self.remove_unused_base_images = ( 

33 CONF.image_cache.remove_unused_base_images) 

34 self.resize_states = [task_states.RESIZE_PREP, 

35 task_states.RESIZE_MIGRATING, 

36 task_states.RESIZE_MIGRATED, 

37 task_states.RESIZE_FINISH] 

38 

39 def _get_base(self): 

40 """Returns the base directory of the cached images.""" 

41 raise NotImplementedError() 

42 

43 def _list_running_instances(self, context, all_instances): 

44 """List running instances (on all compute nodes). 

45 

46 This method returns a dictionary with the following keys: 

47 - used_images 

48 - instance_names 

49 - used_swap_images 

50 - used_ephemeral_images 

51 """ 

52 used_images = {} 

53 instance_names = set() 

54 used_swap_images = set() 

55 used_ephemeral_images = set() 

56 instance_bdms = objects.BlockDeviceMappingList.bdms_by_instance_uuid( 

57 context, [instance.uuid for instance in all_instances]) 

58 

59 for instance in all_instances: 

60 # NOTE(mikal): "instance name" here means "the name of a directory 

61 # which might contain an instance" and therefore needs to include 

62 # historical permutations as well as the current one. 

63 instance_names.add(instance.name) 

64 instance_names.add(instance.uuid) 

65 if (instance.task_state in self.resize_states or 

66 instance.vm_state == vm_states.RESIZED): 

67 instance_names.add(instance.name + '_resize') 

68 instance_names.add(instance.uuid + '_resize') 

69 

70 for image_key in ['image_ref', 'kernel_id', 'ramdisk_id']: 

71 image_ref_str = getattr(instance, image_key) 

72 if image_ref_str is None: 

73 continue 

74 local, remote, insts = used_images.get(image_ref_str, 

75 (0, 0, [])) 

76 if instance.host == CONF.host: 

77 local += 1 

78 else: 

79 remote += 1 

80 insts.append(instance.name) 

81 used_images[image_ref_str] = (local, remote, insts) 

82 

83 bdms = instance_bdms.get(instance.uuid) 

84 if bdms: 

85 swap = driver_block_device.convert_swap(bdms) 

86 if swap: 86 ↛ 89line 86 didn't jump to line 89 because the condition on line 86 was always true

87 swap_image = 'swap_' + str(swap[0]['swap_size']) 

88 used_swap_images.add(swap_image) 

89 ephemeral = driver_block_device.convert_ephemerals(bdms) 

90 if ephemeral: 

91 os_type = nova.privsep.fs.get_fs_type_for_os_type( 

92 instance.os_type) 

93 file_name = nova.privsep.fs.get_file_extension_for_os_type( 

94 os_type, CONF.default_ephemeral_format) 

95 ephemeral_gb = str(ephemeral[0]['size']) 

96 ephemeral_image = "ephemeral_%s_%s" % ( 

97 ephemeral_gb, file_name) 

98 used_ephemeral_images.add(ephemeral_image) 

99 

100 return {'used_images': used_images, 

101 'instance_names': instance_names, 

102 'used_swap_images': used_swap_images, 

103 'used_ephemeral_images': used_ephemeral_images} 

104 

105 def _scan_base_images(self, base_dir): 

106 """Scan base images present in base_dir and populate internal 

107 state. 

108 """ 

109 raise NotImplementedError() 

110 

111 def _age_and_verify_cached_images(self, context, all_instances, base_dir): 

112 """Ages and verifies cached images.""" 

113 

114 raise NotImplementedError() 

115 

116 def update(self, context, all_instances): 

117 """The cache manager. 

118 

119 This will invoke the cache manager. This will update the cache 

120 according to the defined cache management scheme. The information 

121 populated in the cached stats will be used for the cache management. 

122 """ 

123 raise NotImplementedError() 

124 

125 def get_disk_usage(self): 

126 """Return the size of the physical disk space used for the cache. 

127 

128 :returns: The disk space in bytes that is occupied from 

129 CONF.instances_path or zero if the cache directory is mounted 

130 to a different disk device. 

131 """ 

132 raise NotImplementedError()