Пример #1
0
def insertInstanceOnServer(instance_name, flavor_name, image_name,
                           server_name):
    alcServer = Hardware.objects(phySerName=server_name).first()
    selFlavor = Flavor.objects(flavorName=flavor_name).first()
    reqRam = selFlavor.ram
    reqDisks = selFlavor.numDisks
    reqvcpus = selFlavor.vcpus
    newInstance = Instance.objects(instanceName=instance_name).first()
    rckname = alcServer.rackAssigned.rackName
    if newInstance:
        newInstance.phySerName = alcServer.phySerName
        newInstance.imageName = image_name
        newInstance.flavorName = flavor_name
        newInstance.rackAssigned = rckname
        newInstance.save()
        print(f"instance '{instance_name}' updated")
    else:
        newInstance = Instance(instanceName=instance_name)
        newInstance.phySerName = alcServer.phySerName
        newInstance.imageName = image_name
        newInstance.flavorName = flavor_name
        newInstance.rackAssigned = rckname
        newInstance.save()
        print(f"instance '{instance_name}' created")

    alcServer.avMem = alcServer.avMem - reqRam
    alcServer.avNumDisks = alcServer.avNumDisks - reqDisks
    alcServer.avNumCores = alcServer.avNumCores - reqvcpus
    alcServer.instances = [newInstance]
    alcServer.save()
    print(
        f"hardware '{server_name}' on rack: '{alcServer.rackAssigned.rackName}' updated"
    )
Пример #2
0
def create_server_instance(instance_name, flavor, image):
    """Creates an instance named INSTANCE_NAME to be boot from
        IMAGE and configured as indicated in FLAVOR_NAME """
    logger.info(f"Got request to create a server with configuration:")
    logger.info(f"Instance name: {instance_name}")
    logger.info(f"Flavor name:   {flavor}")
    logger.info(f"Image name:    {image}")

    alcServer = getPhyServerAllocation(instance_name, image, flavor)

    if alcServer:
        selFlavor = Flavor.objects(flavorName=flavor).first()
        selImage = Image.objects(imageName=image).first()
        reqRam = selFlavor.ram
        reqDisks = selFlavor.numDisks
        reqvcpus = selFlavor.vcpus
        newInstance = Instance.objects(instanceName=instance_name).first()
        rckname = alcServer.rackAssigned.rackName
        if newInstance:
            newInstance.phySerName = alcServer.phySerName
            newInstance.imageName = image
            newInstance.flavorName = flavor
            newInstance.rackAssigned = rckname
            newInstance.save()
            logger.info(f"instance {instance_name} updated")
        else:
            newInstance = Instance(instanceName=instance_name)
            newInstance.phySerName = alcServer.phySerName
            newInstance.imageName = image
            newInstance.flavorName = flavor
            newInstance.rackAssigned = rckname
            newInstance.save()
            logger.info(f"instance {instance_name} created")

        alcServer.avMem = alcServer.avMem - reqRam
        alcServer.avNumDisks = alcServer.avNumDisks - reqDisks
        alcServer.avNumCores = alcServer.avNumCores - reqvcpus
        alcServer.save()
        alcServer.update(push__instances=newInstance)
        if selImage not in alcServer.rackAssigned.imgCache:
            alcServer.rackAssigned.update(push__imgCache=selImage)
            alcServer.rackAssigned.update(dec__avStorage=selImage.imageSize)

        print(
            f"Added to server {alcServer.phySerName} (on rack {alcServer.rackAssigned.rackName}) current memmory {alcServer.mem} availble memory {alcServer.avMem})"
        )
        logger.info(
            f"Added to server {alcServer.phySerName} (on rack {alcServer.rackAssigned.rackName}) current memmory {alcServer.mem} availble memory {alcServer.avMem})"
        )
        logger.info(
            f"SUCCESS: COMMAND: aggiestack server create --image {image} --flavor {flavor} {instance_name}"
        )
    else:
        logger.info(
            f"FAILED: COMMAND: aggiestack server create --image {image} --flavor {flavor} {instance_name}"
        )
Пример #3
0
def getPhyServerAllocation(instancename, image, flavor):
    mimage = Image.objects(imageName=image).first()
    mflavor = Flavor.objects(flavorName=flavor).first()
    if (mimage and mflavor):
        reqDisks = mflavor.numDisks
        reqRam = mflavor.ram
        reqvcpus = mflavor.vcpus
        # reqImagesize = mimage.imageSize # update later based on prof input
        avServers = Hardware.objects(
            avMem__gte=reqRam,
            avNumDisks__gte=reqDisks,
            avNumCores__gte=reqvcpus,
        )
        if avServers.count() == 0:
            logger.error(
                f"Insufficient storage on servers to host instance {instancename} with image {image} and flavor {flavor}"
            )
        for hrd in avServers:
            if (mimage in hrd.rackAssigned.imgCache):
                return hrd
        max_size = 0
        hw_with_max_size = None
        for hrd in avServers:
            if hrd.rackAssigned.avStorage >= max_size:
                max_size = hrd.rackAssigned.avStorage
                hw_with_max_size = hrd
        #logger.info(f"max_size: {max_size}, hw_with_max_size: {hw_with_max_size.rackAssigned.avStorage}")
        if hw_with_max_size:
            if max_size < mimage.imageSize:
                imagelist = hw_with_max_size.rackAssigned.imgCache
                logger.info(
                    f"evicting images from rack {hw_with_max_size.rackAssigned.rackName}"
                )
                #evict
                logger.info("evicting images: [ ")
                for image in imagelist:
                    logger.info(image.imageName, end=" ")
                    max_size += image.imageSize
                    hw_with_max_size.rackAssigned.avStorage += image.imageSize
                    hw_with_max_size.rackAssigned.imgCache.remove(image)
                    if max_size >= mimage.imageSize:
                        break
                logger.info("]")
            hw_with_max_size.rackAssigned.save()
            return hw_with_max_size
        #return avServers
    elif not mimage and not mflavor:
        logger.error(f"image {image} and flavor {flavor} doesn't exist")
    elif not mimage:
        logger.error(f"image {image} doesn't exist")
    else:
        logger.error(f"flavor {flavor} doesn't exist")
Пример #4
0
def show_flavors(context):
    flvList = Flavor.objects({})
    if flvList.first():
        for flv in flvList:
            print(
                f"Flavor Name: {flv.flavorName} Memory size:{flv.ram}  No of disks: {flv.numDisks} No of cores : {flv.vcpus}"
            )
        logger.info(
            "COMMAND: aggiestack show flavors - SUCCESS - printed configuration on console"
        )
    else:
        print("no flavors found")
        logger.info(
            "COMMAND: aggiestack show flavors - No Stored Flavor Configurations Found"
        )
Пример #5
0
def cli(context, machine_name, flavor):
    """Check if a machine can be hosted with a particular flavour'.
    Pass the machine name and flavour to check against as argument."""

    if (not context.admin_rights):
        my_logger.error('Can allow this operation only in admin mode')
        my_logger.info(
            f'FAILED: COMMAND:  aggiestack can_host {machine_name} {flavor}')
        return

    flavor_rep = Flavor.objects(flavorName=flavor).first()
    if flavor_rep is None:
        my_logger.error(
            f'Flavor with name {flavor} not found in configuration')
        my_logger.info(
            f'FAILED: COMMAND:  aggiestack admin can_host {machine_name} {flavor}'
        )
        return
    total_hardware_available = Hardware.objects({})
    if total_hardware_available is None:
        my_logger.error('Hardware not configured')
        my_logger.info(
            f'FAILED: COMMAND:  aggiestack admin can_host {machine_name} {flavor}'
        )
        return
    reqDisks = flavor_rep.numDisks
    reqRam = flavor_rep.ram
    reqvcpus = flavor_rep.vcpus
    hardware_available = Hardware.objects(avMem__gt=reqRam,
                                          avNumDisks__gt=reqDisks,
                                          avNumCores__gt=reqvcpus).first()
    if (hardware_available):
        print(
            f'Yes, you can host {machine_name} machine with the {flavor} flavor'
        )
        my_logger.info("SUCCESS: COMMAND : aggiestack admin can_host %s %s",
                       machine_name, flavor)
        return
    else:
        my_logger.error(f'Not enough server capacity to host {flavor}')
        my_logger.info(
            f'FAILED: COMMAND:  aggiestack admin can_host {machine_name} {flavor}'
        )
        return
Пример #6
0
def getPhyServerAllocation(image, flavor, rack_name=None):
    mimage = Image.objects(imageName=image).first()
    mflavor = Flavor.objects(flavorName=flavor).first()
    if (mimage and mflavor):
        reqDisks = mflavor.numDisks
        reqRam = mflavor.ram
        reqvcpus = mflavor.vcpus
        # reqImagesize = mimage.imageSize # update later based on prof input
        if not rack_name:
            avServers = Hardware.objects(avMem__gte=reqRam,
                                         avNumDisks__gte=reqDisks,
                                         avNumCores__gte=reqvcpus).first()
        else:
            avServers = Hardware.objects(avMem__gte=reqRam,
                                         avNumDisks__gte=reqDisks,
                                         avNumCores__gte=reqvcpus,
                                         rackAssigned__ne=rack_name).first()
        return avServers

    else:
        print("flavor or image doesnt exist")
Пример #7
0
def delete_server_instance(instance_name):
    logger.info(f"got request to delete instance {instance_name}")
    delInstance = Instance.objects(instanceName=instance_name).first()
    alcServer = Hardware.objects(phySerName=delInstance.phySerName).first()
    alcFlav = Flavor.objects(flavorName=delInstance.flavorName).first()
    if delInstance:
        logger.info("deleted instance {instance_name}")
        alcServer.avMem += alcFlav.ram
        alcServer.avNumDisks += alcFlav.numDisks
        alcServer.avNumCores += alcFlav.vcpus
        alcServer.save()
        alcServer.update(pull__instances=delInstance)
        delInstance.delete()
        logger.info(f" hardware server :{alcServer.phySerName} updated")
        logger.info(
            f"SUCCESS: COMMAND: aggiestack server delete {instance_name}")
    else:
        logger.error(
            "Instance doesn't exist. Enter a valid instance name to delete. Execute \"aggiestack server list\" for the list of instances "
        )
        logger.info(
            f"FAILED: COMMAND: aggiestack server delete {instance_name}")
Пример #8
0
def cli(context, rack_name):
    """
    Evacuates all the machines located on the same rack
    """

    if (not context.admin_rights):
        logger.error('Can allow this operation only in admin mode')
        logger.info(f'FAILED: COMMAND:  aggiestack evacuate {rack_name}')
        return

    logger.info(f"Got request to evacuate rack: {rack_name}")
    rack = Rack.objects(rackName=rack_name).first()
    if not rack:
        logger.error(f"Rack {rack_name} doesn't exist")
        logger.info(f'FAILED: COMMAND:  aggiestack evacuate {rack_name}')
        return
    rack_servers = Hardware.objects(rackAssigned=rack_name)
    logger.info(f"rack servers: '{rack_servers.count()}'")
    new_server_names = []
    old_server_names = []
    migrated_instance_names = []
    roll_back = False
    for server in rack_servers:
        if roll_back:
            break

        for instance in server.instances:
            logger.info(
                f"migrating instance '{instance.instanceName}' image: '{instance.imageName}' flavor: {instance.flavorName}"
            )
            new_server = utility.getPhyServerAllocation(
                instance.imageName, instance.flavorName, rack_name)
            if not new_server:
                logger.error(
                    f"cannot migrate instance: '{instance.instanceName}' image:'{instance.imageName}'"
                )
                roll_back = True
                break
            else:
                utility.insertInstanceOnServer(instance.instanceName,
                                               instance.flavorName,
                                               instance.imageName,
                                               new_server.phySerName)
                migrated_instance_names.append(instance.instanceName)
                old_server_names.append(server.phySerName)
                new_server_names.append(new_server.phySerName)

    if roll_back:
        logger.error(f'Cannot evacuate rack {rack_name}')
        logger.error("rolling back servers")
        for i in range(len(migrated_instance_names) - 1, -1, -1):
            logger.info(
                f"rolling back server: '{new_server_names[i]}' for instance: '{migrated_instance_names[i]}' to its previous server: '{old_server_names[i]}'"
            )
            # rolling back instance
            migrated_instance = Instance.objects(
                instanceName=migrated_instance_names[i]).first()
            migrated_instance.phySerName = old_server_names[i]
            migrated_instance.save()

            flavor = Flavor.objects(
                flavorName=migrated_instance.flavorName).first()
            image = Image.objects(
                imageName=migrated_instance.imageName).first()

            # rolling back the server to which instance it was assigned
            new_server = Hardware.objects(
                phySerName=new_server_names[i]).first()
            new_server.avMem += flavor.ram
            new_server.avNumDisks += flavor.numDisks
            new_server.avNumCores += flavor.vcpus
            new_server.instances.remove(migrated_instance)
            new_server.save()
        logger.info(f'FAILED: COMMAND: aggiestack admin evacuate {rack_name}')
    else:
        logger.info(f"migrated #'{len(migrated_instance_names)}' instances")
        for server in rack_servers:
            server.delete()
        logger.info(f"removed all servers from rack {rack_name}")
        rack = Rack.objects(rackName=rack_name).first()
        rack.delete()
        logger.info(f"evicted rack {rack_name}")
        logger.info(f'SUCCESS: COMMAND: aggiestack admin evacuate {rack_name}')
        logger.info(f'Successfully evacuated rack {rack_name}')
Пример #9
0
def cli(context, hardware, images, flavors):
    if hardware:
        check = check_hardware_pattern(open(hardware, 'r'))
        if check:
            logger.error("COMMAND: aggiestack config --hardware '%s' : %s",
                         hardware, check)
            logger.info(
                f"FAILED: COMMAND:  aggiestack config --hardware {hardware}")
            return
        else:
            input_content = utility.file_read(hardware)
            arg_hardware = hardware
            # reading rack information
            # handle update or duplicates!
            for i in range(1, int(input_content[0]) + 1):
                attrs = input_content[i].split(" ")
                logger.info("Racks parsed -- '%s'", attrs)
                rack = Rack.objects(rackName=attrs[0]).first()
                if not rack:
                    rack = Rack(rackName=attrs[0],
                                storageCapacity=attrs[1],
                                avStorage=attrs[1]).save()
                    logger.info("Inserted Rack: '%s'", attrs)
                else:
                    rack.avStorage += int(attrs[1]) - rack.storageCapacity
                    rack.storageCapacity = attrs[1]
                    rack.save()
                    logger.info("Updated Rack: '%s'", attrs)
            # reading hardware information
            # fails when no hardware is present after rack info
            for line in input_content[int(input_content[0]) + 2:]:
                attrs = line.split(" ")
                logger.info("Hardware parsed -- '%s'", attrs)
                rack = Rack.objects(rackName=attrs[1]).first()
                if rack:
                    hardware = Hardware.objects(phySerName=attrs[0]).first()
                    if not hardware:
                        hardware = Hardware(
                            phySerName=attrs[0],
                            rackAssigned=Rack.objects.get(rackName=attrs[1]),
                            ipAddress=attrs[2],
                            mem=attrs[3],
                            numDisks=attrs[4],
                            numCores=attrs[5],
                            avMem=attrs[3],
                            avNumDisks=attrs[4],
                            avNumCores=attrs[5])
                        hardware.save()
                        logger.info("Inserted Hardware: '%s'", attrs)
                    else:
                        hardware.phySerName = attrs[0]
                        hardware.rackAssigned = Rack.objects.get(
                            rackName=attrs[1])
                        hardware.avMem += int(attrs[3]) - hardware.mem
                        hardware.avNumDisks += int(
                            attrs[4]) - hardware.numDisks
                        hardware.avNumCores += int(
                            attrs[5]) - hardware.numCores
                        hardware.mem = attrs[3]
                        hardware.numDisks = attrs[4]
                        hardware.numCores = attrs[5]
                        hardware.save()
                        logger.info("Updated Hardware: '%s'", attrs)
            logger.info("SUCCESS: COMMAND: aggiestack config --hardware %s",
                        arg_hardware)

    elif images:
        # todo modify check function
        # check = check_image_pattern(open(images, 'r'))
        # remove this and below line after modifying check
        check = None
        if check:
            logger.error("COMMAND: aggiestack config --images '%s' : %s",
                         images, check)
            logger.info(
                f"FAILED: COMMAND:  aggiestack config --images {image}")
        else:
            input_content = utility.file_read(images)
            arg_image = images
            # write to mongo
            # handle update
            for line in input_content[1:]:
                attrs = line.split(" ")
                logger.info("Images parsed -- '%s'", attrs)
                image = Image.objects(imageName=attrs[0]).first()
                # confirm with dileep
                if not image:
                    image = Image(imageName=attrs[0],
                                  imageSize=attrs[1],
                                  imageLocation=attrs[2]).save()
                    logger.info("Inserted Image: '%s'", attrs)
                else:
                    image.imageSize = attrs[1]
                    image.imageLocation = attrs[2]
                    image.save()
                    logger.info("Updated Image: '%s'", attrs)
            logger.info("SUCCESS:  COMMAND: aggiestack config --images %s",
                        arg_image)

    elif flavors:
        check = check_flavor_pattern(open(flavors, 'r'))
        if check:
            logger.error("COMMAND: aggiestack config --flavor '%s' : %s",
                         flavors, check)
            logger.error(
                f"FAILED: COMMAND:  aggiestack config --flavor {flavor}")
        else:
            input_content = utility.file_read(flavors)
            arg_flavor = flavors
            # write to mongo
            # handle update, dont duplicate record
            for line in input_content[1:]:
                attrs = line.split(" ")
                logger.info("Flavor parsed -- '%s'", attrs)
                flavor = Flavor.objects(flavorName=attrs[0]).first()
                if not flavor:
                    flavor = Flavor(flavorName=attrs[0],
                                    ram=attrs[1],
                                    numDisks=attrs[2],
                                    vcpus=attrs[3]).save()
                    logger.info("Inserted Flavor: '%s'", attrs)
                else:
                    flavor.ram = attrs[1]
                    flavor.numDisks = attrs[2]
                    flavor.vcpus = attrs[3]
                    flavor.save()
                    logger.info("Updated Flavor: '%s'", attrs)
            logger.info("SUCCESS: COMMAND: aggiestack config --flavors %s",
                        arg_flavor)
    else:
        my_logger.error(
            'You must enter an argument with the config command. Check with --help for available options'
        )