Example #1
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.header("%r\n" % (update))
    
    # Make sure we need to create this chute (does it already exist)
    # TODO
#    chutePlan.addPlans(new, plangraph.TRAFFIC_SECURITY_CHECK, (security.checkTraffic, (chuteStor, new)))
   
    # First time, so generate the basic firewall rules in cache (key: 'osFirewallConfig')
    update.plans.addPlans(plangraph.TRAFFIC_GET_OS_FIREWALL, (config.firewall.getOSFirewallRules, ))

    # Get developer firewall rules (key: 'developerFirewallRules')
    update.plans.addPlans(plangraph.TRAFFIC_GET_DEVELOPER_FIREWALL, (config.firewall.getDeveloperFirewallRules, ))
            
    # Combine rules from above two fucntions, save to file
    todoPlan = (config.firewall.setOSFirewallRules, )
    abtPlan = (config.osconfig.revertConfig, "firewall")
    update.plans.addPlans(plangraph.TRAFFIC_SET_OS_FIREWALL, todoPlan, abtPlan)
    
    return None
Example #2
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.header("%r\n" % (update))
    
    # Make sure we need to create this chute (does it already exist)
    # TODO

#   # Check if the chute is new
#   # if(not old):
#   # convert cpu cgroups and add to lxcconfig (cached, key: 'cpuConfig')
#   chutePlan.addPlans(new, plangraph.RESOURCE_GET_VIRT_CPU, (new.getCpuConfigString, None))
#   
#   # convert mem cgroups and add to lxcconfig (cached, key: 'memConfig')
#   chutePlan.addPlans(new, plangraph.RESOURCE_GET_VIRT_MEM, (new.getMemConfigString, None))

#   # Generate a config file for wshaper, put in cache (key: 'osResourceConfig')
#   chutePlan.addPlans(new, plangraph.RESOURCE_GET_OS_CONFIG, (new.getOSResourceConfig, None))

#   # Make calls to configure the wshaper UCI file
#   todoPlan = (new.setOSResourceConfig, old)
#   abtPlan = (new.resetOSResourceConfig, None) 
#   chutePlan.addPlans(new, plangraph.RESOURCE_SET_VIRT_QOS, todoPlan, abtPlan)
#   
#   # Once all changes are made into UCI system, reload the wshaper daemon
#   todoPlan = (osenv.reloadQos, (chuteStor, new, True)) 
#   abtPlan = [(new.resetOSResourceConfig, None), (osenv.reloadQos, (chuteStor, new, False))]
#   chutePlan.addPlans(new, plangraph.RESOURCE_RELOAD_QOS, todoPlan, abtPlan)

    return None
Example #3
0
def executePlans(update):
    """
        Primary function that actually executes all the functions that were added to plans by all
        the exc modules. This function can heavily modify the OS/files/etc.. so the return value is
        very important.
        Returns:
            True in error : abortPlans function should be called
            False otherwise : everything is OK
    """
    out.header('Executing plans %r\n' % (update))
    # Finding the functions to call is actually done by a 'iterator' like function in the plangraph module
    while(True):
        # This function either returns None or a tuple just like generate added to it
        p = update.plans.getNextTodo()

        # No more to do?
        if(not p):
            break

        # Explode tuple otherwise
        func, args = p

        # We are in a try-except block so if func isn't callable that will catch it
        try:
            out.verbose('Calling %s\n' % (func))
            #
            # Call the function from the execution plan
            #
            # args may be empty, but we don't want to pass in a tuple if we don't need to
            # so this below explodes the args so if @args is (), then what is passed is @update
            skipme = func(*((update, ) + args))

        except Exception as e:
            out.exception(e, True) #, plans=str(update.plans)) # Removed because breaks new out.exception call
            update.responses.append({'exception': str(e), 'traceback': traceback.format_exc()})
            update.failure = str(e)
            return True

        # The functions we call here can return other functions, if they do these are functions that should
        # be skipped later on (for instance a set* function discovering it didn't change anything, later on
        # we shouldn't call the corresponding reload function)
        if(skipme):
            # These functions can return individual functions to skip, or a list of multiple functions
            if (not isinstance(skipme, list)):
                skipme = [skipme]

            for skip in skipme:
                out.warn('Identified a skipped function: %r\n' % (skip))
                update.plans.registerSkip(skip)

    # Now we are done
    return False
Example #4
0
def aggregatePlans(update):
    """
        Takes the PlanMap provided which can be a combination of changes for multiple
        different chutes and it puts things into a sane order and removes duplicates where
        possible.

        This keeps things like reloading networking from happening twice if 2 chutes make changes.

        Returns:
            A new PlanMap that should be executed
    """
    out.header('Aggregating plans\n')
    # For now we just order the plans and return a new list
    update.plans.sort()
Example #5
0
def generatePlans(update):
    """
    For an update object provided this function references the updateModuleList which lets all exc
    modules determine if they need to add functions to change the state of the system when new 
    chutes are added to the OS.

    Returns: True in error, as in we should stop with this update plan
    """
    out.header('Generating %r\n' % (update))

    # Iterate through the list provided for this update type
    for mod in update.updateModuleList:
        if(mod.generatePlans(update)):
            return True
Example #6
0
def abortPlans(update):
    """
        This function should be called if one of the Plan objects throws an Exception.
        It takes the PlanMap argument and calls the getNextAbort function just like executePlans does with todoPlans.
        This dynamically generates an abort plan list based on what plans were originally executed.
        Returns:
            True in error : This is really bad
            False otherwise : we were able to restore system state back to before the executeplans function was called
    """
    out.header('Aborting plans %r\n' % (update.plans))
    sameError = False
    while(True):
        # This function either returns None or a tuple just like generate added to it
        p = update.plans.getNextAbort()

        # No more to do?
        if(not p):
            break

        # Explode tuple otherwise
        func, args = p

        # We are in a try-except block so if func isn't callable that will catch it
        try:
            func(*((update, ) + args))

            # If the func is called without exception then clear the @sameError flag for the next function call
            sameError = False

        except Exception as e:
            # Since we are running this in an infinite loop if a major function throws an error
            # we could loop forever, so check for the error, which is only reset at the end of the loop
            if(sameError):
                return True
            update.responses.append({'exception': str(e), 'traceback': traceback.format_exc()})
            out.fatal('An abort function raised an exception!!! %r: %s\n%s\n' % (update.plans, str(e), traceback.format_exc()))
            sameError = True

    # Getting here we assume the system state has been restored using our abort plan
    return False
Example #7
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.header("%r\n" % (update))
    
    # Make sure we need to create this chute (does it already exist)
    # TODO

#   new = newChute
#   old = chuteStor.getChute(newChute.guid)
#   out.header("Generating Files Plan: %r\n" % (new))
#   
#   tok = new.getCache('updateToken')
#   if(tok and tok == 'STARTINGUP'):
#       starting = True
#   else:
#       starting = False

#   # The Chute uses libraries borrowed from the host, copy them
#   if(not old or starting):
#       chutePlan.addPlans(new, plangraph.FILES_COPY_FROM_OS, (new.copyEssentials, None))

#   # There are a few files (lxc_start.sh) that need to be copied from the /root/cXXXX/ dir into the mounted partition
#   if(not old or starting):
#       chutePlan.addPlans(new, plangraph.FILES_COPY_TO_MNT, (new.copyFilesToMount, None)) 
#   
#   # See if there is a change between the old.files and new.files
#   if(old and old.files == new.files and not starting):
#       return None

#   # Are there any files?
#   if(len(new.files) == 0):
#       return None
#   
#   # Otherwise, we have files to download, so check for proper format first
#   chutePlan.addPlans(new, plangraph.FILES_SECURITY_CHECK, (security.checkFiles, new))
#   
#   # Add plan to fetch the files
#   chutePlan.addPlans(new, plangraph.FILES_FETCH, (new.fetchFiles, None))
#   # Add plan to fetch the files
#   chutePlan.addPlans(new, plangraph.FILES_COPY_USER, (new.copyFiles, None))
#    

#   ##################
#   # This part is semi-complicated
#   # If a chute was running/frozen and then some files in the chute are updated, we need to restart the chute as the new binaries/files won't be currently used.
#   # This function will call the necessary lxc-start/stop commands
#   # NOTE: we only need to do this when an old chute exists and the state is running/frozen.
#   # Otherwise, the next lxc-start command will properly load the new binaries/data.
#   # If fetchFiles does not make any changes, it will skip this function 

#   if (old and (new.state == chute.STATE_RUNNING or new.state == chute.STATE_FROZEN)):
#       currChuteState = stats.getLxcState(new.getInternalName()) 
#       # We only want to reload when the chute is actually running
#       # Could be power cycled and chutes would be stopped
#       # In that case exc/state.py will handle that possibility, and start the chute
#       if (currChuteState == chute.STATE_RUNNING or currChuteState == chute.STATE_FROZEN):
#           chutePlan.addPlans(new, plangraph.STATE_FILES_STOP, (virt.fileStop, new))
#           chutePlan.addPlans(new, plangraph.STATE_FILES_START, (virt.fileStart, new))

    return None