Exemple #1
0
class  AggregateState(object):

    MAX_VLAN_TAG = 10; # Maximum value for vlan tag
    PUBLIC_TAG = "public"
    FLAVOR_TAG = "flavor"
    VLAN_TAGS_TAG = "vlan_tags"
    PUBLIC_IP_ADDRESSES_TAG = "public_IP_addresses"
    FLAVOR_CAPACITIES_TAG = "flavor_capacities"
    PARAMETERS_TAG = "parameters"
    ARCHIVE_DIRECTORY_TAG = "archive_directory"

    # There are two initialization cases:
    # From scratch, using AggregateState constructor: 
    #    initialize from a JSON config file 
    # From a snapshot, using pickle.load
    #   initialize from a pickled version


    # Read config file from JSON config
    def __init__(self, config_filename):

        if config_filename is None: # For reconstructing from data feed
            return;

        config_file = open(config_filename);
        config_data = json.load(config_file);
        config_file.close()

        self._sequence_number = 1; # Counter of transactions and snapshots
        self._slivers_by_urn = dict(); # Map of slivers by their URN

        # Determine if (and where) we're dumping transaction snapshots
        # Create directory if doesn't already exist
        self._archive_directory = None;
        if config_data.has_key(self.ARCHIVE_DIRECTORY_TAG):
            self._archive_directory = config_data[self.ARCHIVE_DIRECTORY_TAG]
            if not os.path.exists(self._archive_directory):
                os.mkdir(self._archive_directory)

        # Parse all public VLAN tags
        self._public_vlan_tags = \
            list(int(i) for i in config_data[self.VLAN_TAGS_TAG])

        # Set up a manager for all VLAN tags
        # MAX_SLICES is maxint since a VLAN may be part of many links
        self._vlan_tag_manager = AllocationManager(sys.maxint);
        for tag in range(self.MAX_VLAN_TAG):
            attribs = {self.PUBLIC_TAG : tag in self._public_vlan_tags}
            self._vlan_tag_manager.register(tag, attribs)

        # Parse all public IP addresses
        self._public_ip_addresses = \
            list(i.encode('utf-8') \
                     for i in config_data[self.PUBLIC_IP_ADDRESSES_TAG]);

        # Set up a manager for public IP addresses
        # MAX_SLICES is 1, since an IP address can only be on one NIC
        self._ip_address_manager = AllocationManager(1);
        for ip in self._public_ip_addresses:
            self._ip_address_manager.register(ip);

        # Parse all flavor capacities
        self._flavor_capacities = dict();
        for fc in config_data[self.FLAVOR_CAPACITIES_TAG]:
            flavor_type = fc.keys()[0].encode('utf-8')
            flavor_capacity = int(fc[flavor_type])
            self._flavor_capacities[flavor_type] = flavor_capacity;

        # Set up a manager for flavor resources
        self._flavor_manager = AllocationManager(1);
        for key in self._flavor_capacities.keys():
            flavor_capacity = self._flavor_capacities[key];
            attrs = {self.FLAVOR_TAG : int(key)};
            for i in range(flavor_capacity):
                resource_name = str(key) + "-" + str(i);
                self._flavor_manager.register(resource_name, attrs);
        self._flavor_allocations = dict(); # sliver_urn => flavor instance

        # Set up parameters as read from config file
        self._parameters = dict();
        params = config_data[self.PARAMETERS_TAG]
        for key in params:
            value = params[key]
            self._parameters[key.encode('utf-8')] = value.encode('utf-8');
            
#        print self._public_vlan_tags
#        print self._public_ip_addresses
#        print self._flavor_capacities
#        print self._parameters


     # List of all currently defined slivers                 
    def getSlivers(self): 
        return self._slivers_by_urn.values()

    # Map of all currently defind slivers by URN
    def getSliversByURN(self):
        return self._slivers_by_urn

    # List of all currently unallocated flavors
    def getUnallocatedFlavors(self): 
        return self._flavor_manager.getResources(False);
     
     # List of all currently available VLAN tags (internal and public)       
    def getUnallocatedVLANTags(public_tag=True): 
        return self._vlan_tag_manager.getResources(False)
    
    # List of all currently unallocated public IP addresses    
    def getUnallocatedPublicIPAddresses(self): 
        attribs = {self.PUBLIC_TAG : public_tag};
        return self._ip_address_manager.getResources(false, attribs);

    # Map of flavor allocations to sliver_URN        
    def getAllocatedFlavors(self): 
        return self._flavor_manager.getResources(True);

    # Map of VLAN tag allocations to sliver_URN                     
    def getAllocatedVLANTags(public_tag=True): 
        attribs = {self.PUBLIC_TAG : public_tag};
        return self._vlan_tag_manager.getResources(True, attribs)
                                    
    # Map of allocated public IP addresses to sliver URN              
    def getAllocatedPublicIPAddresses(self): 
        return self._ip_address_manager.getResources(True);

    # Lookup value of aggregate configuration parameter (e.g. expiration) 
    def getParameter(self, param_name): 
        return self._parameters[param_name];

    # Update internal store of set of slivers (insert or replace) 
    # and update database                                               
    def writeSlivers(self, slivers, slice_urn): 

        # Loop over all slivers, and update for each
        for sliver in slivers:
            sliver_urn = sliver.getComponentID()

            # Remove the sliver if already exists
            if self._slivers_by_urn.has_key(sliver_urn):
                self.deleteSlivers([sliver]);

            # Insert new sliver into slivers list
            self._slivers_by_urn[sliver_urn] = sliver;

            # Update the vlan tag allocation record
            if isinstance(sliver, NetworkLink):
                vlan_tag = sliver.getVLANTag()
                self._vlan_tag_manager.allocate(vlan_tag, \
                                                    slice_urn, sliver_urn)

            # Update the public IP address allocation record
            if isinstance(sliver, NetworkInterface):
                ip_address = sliver.getIPAddress();
                if ip_address in self._public_ip_addresses:
                    self._ip_address_manager.allocate(ip_address, \
                                                          slice_urn, \
                                                          sliver_urn)

            # Update the flavor allocation record
            # If there aren't any more left raise an Assertion Error
            if isinstance(sliver, VirtualMachine):
                flavor = sliver.getFlavor();
                attrs = {self.FLAVOR_TAG : flavor}
                unallocated_of_flavor = \
                    self._flavor_manager.getResources(False, attrs)
                assert len(unallocated_of_flavor) > 0, \
                    "No Allocations left for flavor " + str(flavor)
                allocated_resource = unallocated_of_flavor[0]
                self._flavor_manager.allocate(allocated_resource, \
                                                  slice_urn, sliver_urn)
                self._flavor_allocations[sliver_urn] = allocated_resource

        # Update the database
        self.archive()


    # Remove slivers of given URNs and free all associated resources
    def deleteSlivers(self, slivers, slice_urn):   

        # Loop over all slivers, and update for each
        for sliver in slivers:
            sliver_urn = sliver.getComponentID();

            # Remove the given slivers from the slivers list
            assert self._slivers_by_urn.has_key(sliver_urn), \
                "sliver URN not defined: " + sliver_urn
            del self._slivers_by_urn[sliver_urn];

            # Update the vlan tag allocation counts
            if isinstance(sliver, NetworkLink):
                vlan_tag = sliver.getVLANTag()
                self._vlan_tag_manager.release(vlan_tag, \
                                                   slice_urn, sliver_urn)

            # Update the public IP address lists
            if isinstance(sliver, NetworkInterface):
                ip_address = sliver.getIPAddress();
                if ip_address in self._public_ip_addresses:
                    self._ip_address_manager.release(ip_address, \
                                                         slice_urn, sliver_urn)

        # Update the flavor allocation record
        if isinstance(sliver, VirtualMachine):
            flavor = sliver.getFlavor();
            assert self._flavor_allocations.has_key(sliver_urn), \
                "sliver has undefined flavor: " + str(flavor)
            allocated_resource = self._flavor_allocations[sliver_urn]
            self._flavor_manager.release(allocated_resource, \
                                             slice_urn, sliver_urn)
            del self._flavor_allocations[sliver_urn]

        # Update the database
        self.archive()

    # Save current state of AggregateState object to new pickle file
    # in archive directory
    def archive(self):
        if self._archive_directory is not None:
            filename = self._archive_directory + "/" + \
                "AggregateState-" + str(self._sequence_number) + ".dat"
            file = open(filename, 'wb')
            pickle.dump(self, file)
            file.close()

            filename2 = self._archive_directory + "/" + \
                "AggregateState-" + str(self._sequence_number) + ".json"
            Archiving.write_aggregate_state(filename2, self);
            
#            file = open(filename2, 'wb')
#            json.dump(self, file)
#            file.close()

            self._sequence_number = self._sequence_number + 1


    def __str__(self):
        flavors_image = str(self._flavor_manager.getResources(True))
        vlans_image = str(self._vlan_tag_manager.getResources(True))
        ips_image = str(self._ip_address_manager.getResources(True))
        return "#<GRAM Aggregate State: Flavors " + flavors_image + \
            " VLANs " + vlans_image + \
            " IPs " + ips_image + \
            ">";