def _ejection_test(self, env): """Are we ejecting nodes whose images are no longer in the current image list? """ strategy = sps.SimpleProportionalStrategy() strategy.update_current_state(**env) directives = strategy.directives() if len(directives) == 0: directives = [sb.CacheNode('a', 'b', 'c')] ejection_directives = filter( lambda direct: isinstance(direct, sb.EjectNode), directives) ejected_node_uuids = sb.build_attribute_set(ejection_directives, 'node_uuid') for node in env['nodes']: # Make sure that cached nodes with invalid images are ejected. if node.cached_image_uuid == INVALID_IMAGE.uuid and node.cached: self.assertIn(node.node_uuid, ejected_node_uuids, ("A node with an invalid image UUID was not " "ejected from the cache. Node UUID: %s" % ( node.node_uuid))) # Ensure ejected nodes are marked as 'provisioned'. nodes_by_uuid = {node.node_uuid: node for node in env['nodes']} for node_uuid in ejected_node_uuids: self.assertTrue(nodes_by_uuid[node_uuid].provisioned) # Make sure the strategy is not trying to cache to ejected nodes. cache_directives = filter( lambda direct: isinstance(direct, sb.CacheNode), directives) cached_node_uuids = sb.build_attribute_set(cache_directives, 'node_uuid') self.assertEqual( 0, len(cached_node_uuids.intersection(ejected_node_uuids)), "One or more ejected nodes scheduled to cache immediately!")
def segregate_nodes(nodes, flavors): """Segregate nodes by flavor.""" nodes_by_flavor = {} for flavor in flavors: nodes_by_flavor[flavor.name] = [] flavor_names = sb.build_attribute_set(flavors, "name") for node in nodes: if node.flavor not in flavor_names: LOG.error( "Node '%(node)s'with unrecognized flavor '%(flavor)s " "detected. ", {"node": node.uuid, "flavor": node.flavor}, ) next nodes_by_flavor[node.flavor].append(node) return nodes_by_flavor
def segregate_nodes(nodes, flavors): """Segregate nodes by flavor.""" nodes_by_flavor = {} for flavor in flavors: nodes_by_flavor[flavor.name] = [] flavor_names = sb.build_attribute_set(flavors, 'name') for node in nodes: if node.flavor not in flavor_names: LOG.error( "Node '%(node)s'with unrecognized flavor '%(flavor)s " "detected. ", { 'node': node.uuid, 'flavor': node.flavor }) next nodes_by_flavor[node.flavor].append(node) return nodes_by_flavor
def update_current_state(self, nodes, images, flavors): # For now, flavors should remain static. # In the future we'll handle changing flavor profiles if needed, # but it seems unlikely that flavors will change often enough. self.flavor_diff = sb.find_flavor_differences(self.current_flavors, flavors) sb.log_flavor_differences(self.flavor_diff) self.current_flavors = flavors # Image differences are important because changed or retired # images should be ejected from the cache. self.image_diff = sb.find_image_differences(self.current_images, images) sb.log_image_differences(self.image_diff) self.current_images = images self.current_image_uuids = sb.build_attribute_set(images, "uuid") # We don't compare old node state versus new, because that would be # a relatively large and complicated task. Instead, we only rely on # the current state of nodes to inform ourselves whether we're meeting # our stated goals or not. self.current_nodes = nodes
def update_current_state(self, nodes, images, flavors): # For now, flavors should remain static. # In the future we'll handle changing flavor profiles if needed, # but it seems unlikely that flavors will change often enough. self.flavor_diff = sb.find_flavor_differences(self.current_flavors, flavors) sb.log_flavor_differences(self.flavor_diff) self.current_flavors = flavors # Image differences are important because changed or retired # images should be ejected from the cache. self.image_diff = sb.find_image_differences(self.current_images, images) sb.log_image_differences(self.image_diff) self.current_images = images self.current_image_uuids = sb.build_attribute_set(images, 'uuid') # We don't compare old node state versus new, because that would be # a relatively large and complicated task. Instead, we only rely on # the current state of nodes to inform ourselves whether we're meeting # our stated goals or not. self.current_nodes = nodes