コード例 #1
0
def fnbMaybeLogCommand(sCommand):
    if os.path.isfile(g.sBrokerCommandLogFile):
        sTime = util.fnsGetTimeStamp() + " "
        with open(g.sBrokerCommandLogFile, "a") as fhBrokerCommandLog:
            fhBrokerCommandLog.write(sTime)
            fhBrokerCommandLog.write(sCommand + "\n")
        return True
    else:
        return False
コード例 #2
0
def fnbMaybeLogCommand(sCommand):
    if os.path.isfile(g.sBrokerCommandLogFile):
        sTime = util.fnsGetTimeStamp() + " "
        with open(g.sBrokerCommandLogFile, "a") as fhBrokerCommandLog:
            fhBrokerCommandLog.write(sTime)
            fhBrokerCommandLog.write(sCommand + "\n")
        return True
    else:
        return False
コード例 #3
0
def fnbMaybeLogCommand(sCommand):
    '''
        If there is a file into which broker commands are to be logged, 
         then append this command to the file.
    '''
    if os.path.isfile(g.sBrokerCommandLogFile):
        sTime = util.fnsGetTimeStamp() + " "
        with open(g.sBrokerCommandLogFile, "a") as fhBrokerCommandLog:
            fhBrokerCommandLog.write(sTime)
            fhBrokerCommandLog.write(sCommand + "\n")
        return True
    else:
        return False
コード例 #4
0
 def fnsInventNewServer(cls):
     '''Class method: Create another server on the fly.
     Use the info from some old one that is still alive to create
     a new one.  Change the long name to make it unique.  
     Return the new server ID.
     '''
     tnow = datetime.now()
     lLiveServerIDs = cls.fnlListLiveServerIDs()
     sServerID = lLiveServerIDs[0]
     cServer = G.dID2Server[sServerID]
     sNewName = (cServer.sName + "_" + util.fnsGetTimeStamp() + "_" +
                 tnow.strftime("%H%M%S.%f"))
     cNewServer = CServer(sNewName, cServer.nQual, cServer.nShelfSizeTB)
     lg.logInfo(
         "SERVER", "created new server|%s| name|%s| "
         "quality|%s| size|%s|TB svrlife|%.0f|" %
         (cNewServer.ID, sNewName, cNewServer.nQual,
          cNewServer.nShelfSizeTB, cNewServer.mfGetMyCurrentLife()))
     return cNewServer.ID
コード例 #5
0
def fntProcessOneInstruction(mysRunNumber, mydInstruction, mynSeed):
    ''' 
    Process one single instruction for one run.  
    Slightly convoluted logic required here.  
    If just testing today, print instruction contents but do not run it.
    If the instruction has already been processed, skip over it unless
     the user requires it to be redone.  
     ("Has been processed" = there is a MongoDB "done" record with the
     same key.  The key is the concatenation of all options and the 
     seed number.)
    The instruction is actually executed by some worker process at 
     sometime in the future.  We just queue the instruction for processing.
    '''
    sInstructionId = str(mydInstruction["_id"])

    # If this instruction has already been processed, maybe skip it.
    bIsItDone = g.mdb.fnbIsItDone(sInstructionId)
    if bIsItDone and not g.sRedo.startswith("Y"):
        # If the user has not insisted on redo, skip it.
        NTRC.ntracef(
            0, "MAIN", "proc skip item already done run|%s| "
            "id|%s| copies|%s| lifem|%s|" %
            (mysRunNumber, sInstructionId, mydInstruction["nCopies"],
             mydInstruction["nLifem"]))
    else:
        # If the user specifies, redo this case even if was done before.
        if g.sRedo.startswith("Y"):
            NTRC.ntracef(
                0, "MAIN", "proc force redo of run|%s| id|%s| " %
                (mysRunNumber, sInstructionId))

        # Well, maybe.  Could be listonly.
        if g.sListOnly.startswith("Y"):
            NTRC.ntracef(
                0, "MAIN", "proc ListOnly, item run|%s| "
                "ncopies|%s| lifem|%s| id|%s| dict|%s|" %
                (mysRunNumber, mydInstruction["nCopies"],
                 mydInstruction["nLifem"], sInstructionId,
                 list(util.fngSortDictItemsByKeys(mydInstruction))))
        else:
            # Okay, not listonly, therefore really do this instruction.
            mydInstruction["nRandomSeed"] = mynSeed
            NTRC.ntracef(
                0, "MAIN", "proc queue instr, item run|%s| "
                "ncopies|%s| lifem|%s| id|%s|" %
                (mysRunNumber, mydInstruction["nCopies"],
                 mydInstruction["nLifem"], sInstructionId))

            # Format commands to be executed by somebody.
            g.sShelfLogFileName = g.cFmt.msGentlyFormat(
                g.sShelfLogFileTemplate, mydInstruction, g, CG)
            g.lCommands = []
            for sTemplate in g.lTemplates:
                sCmd = g.cFmt.msGentlyFormat(sTemplate, mydInstruction, g, CG)
                g.lCommands.append(sCmd)

            # Where do files go, and what are they called.
            g.sActorLogDir = g.cFmt.msGentlyFormat(g.sActorLogDirTemplate,
                                                   mydInstruction, g, CG)

            # Record that this job will soon be running.
            mydInstruction["starttime"] = util.fnsGetTimeStamp()
            g.mdb.fndInsertProgressRecord(mydInstruction["_id"],
                                          mydInstruction)

            # Return the full instruction to caller, too.
            tThisInst = cworkers.tInstruction(cmdlist=g.lCommands,
                                              logname=g.sShelfLogFileName +
                                              "_case.log",
                                              logdir=g.sActorLogDir)

            # Send the instruction out to be done.  Just drop it in the
            #  queue (think of it as the outbox).
            #            g.qJobs.put(tThisInst)
            fnSendOneJobSlowly(tThisInst, g.qJobs)
            g.nCases += 1

            return tThisInst
コード例 #6
0
def fntProcessOneInstruction(mysRunNumber, mydInstruction, mynSeed):
    ''' 
    Process one single instruction for one run.  
    If just testing today, print instruction contents but do not run it.
    If the instruction has already been processed, skip over it unless
     the user requires it to be redone.  
    '''
    sInstructionId = str(mydInstruction["_id"])
    
    # If the user specifies, redo this case even if was done before.
    if g.sRedo.startswith("Y"):
        NTRC.ntracef(0,"MAIN","proc force redo for item id|%s|" 
            % (sInstructionId))
        # Delete the done record for this run, if there is one, 
        #  to make it appear that the run is new this time.  
        g.mdb.fndDeleteDoneRecord(sInstructionId)

    # If this instruction has already been processed, skip it.
    bIsItDone = g.mdb.fnbIsItDone(sInstructionId)
    if bIsItDone: 
        NTRC.ntracef(0,"MAIN","proc skip item already done run|%s| "
            "id|%s| copies|%s| lifem|%s|" 
            % (mysRunNumber, sInstructionId, mydInstruction["nCopies"],
            mydInstruction["nLifem"]))

    # Testing: Just dump out the instruction dictionary for this item.
    elif g.sListOnly.startswith("Y"):
        NTRC.ntracef(0,"MAIN","proc ListOnly, item run|%s| "
            "ncopies|%s| lifem|%s| id|%s| dict|%s|" 
            % (mysRunNumber, mydInstruction["nCopies"], mydInstruction["nLifem"],
            sInstructionId, list(util.fngSortDictItemsByKeys(mydInstruction))))

    # Real life: execute the instruction.  Well, put it in the list, anyway.  
    else:   
        mydInstruction["nRandomSeed"] = mynSeed

        # Format commands to be executed by actor.
        g.sShelfLogFileName = g.cFmt.msGentlyFormat(
                            g.sShelfLogFileTemplate, mydInstruction, g, CG)
        g.lCommands = []
        for sTemplate in g.lTemplates:
            sCmd = g.cFmt.msGentlyFormat(sTemplate, mydInstruction, g, CG)
            g.lCommands.append(sCmd)

        # Make instruction file for the actor.
        # BZZZT: This is probably irrelevant in newbroker.
        g.sActorCmdFileName = g.cFmt.msGentlyFormat(
                            g.sActorCmdFileTemplate, mydInstruction, g, CG)
        g.sActorCommand = g.cFmt.msGentlyFormat(
                            g.sActorCmdTemplate, mydInstruction, g, CG)
        g.sActorLogDir = g.cFmt.msGentlyFormat(
                            g.sActorLogDirTemplate, mydInstruction, g, CG)
        NTRC.ntracef(0, "MAIN", "proc main commands run|%s| "
            "ncopies|%s| lifem|%s| audit|%s| "
            "segs|%s|\n1-|%s|\n2-dir|%s| log|%s|" 
            % (mysRunNumber, mydInstruction["nCopies"], 
            mydInstruction["nLifem"], mydInstruction["nAuditFreq"], 
            mydInstruction["nAuditSegments"], 
            g.lCommands, g.sActorLogDir, g.sShelfLogFileName))
        # Create file for actor, maybe just comments.
        with open(g.sActorCmdFileName, 'w') as fhActorCmdFile:
            fhActorCmdFile.write(
                            "# ListActor command file, "
                            "automatically generated by broker.  "
                            "Do not edit.\n")
            for sCommand in g.lCommands:
                sLine = g.cFmt.fnsMaybeTest(sCommand, g)
                print(sLine, file=fhActorCmdFile)

        # Record that this job will soon be running.
        mydInstruction["starttime"] = util.fnsGetTimeStamp()
        g.mdb.fndInsertProgressRecord(mydInstruction["_id"], mydInstruction)
        
        # Return the full instruction.
        tThisInst = tInstruction(casedict=mydInstruction
                                , cmdlist=g.lCommands
                                , logname=g.sShelfLogFileName + "_case.log"
                                , logdir=g.sActorLogDir
                                , runid=mysRunNumber
                                )
        return tThisInst
コード例 #7
0
def fntProcessOneInstruction(mysRunNumber, mydInstruction, mynSeed):
    ''' 
    Process one single instruction for one run.  
    If just testing today, print instruction contents but do not run it.
    If the instruction has already been processed, skip over it unless
     the user requires it to be redone.  
    '''
    sInstructionId = str(mydInstruction["_id"])
    
    # If this instruction has already been processed, maybe skip it.
    bIsItDone = g.mdb.fnbIsItDone(sInstructionId)
    if bIsItDone and not g.sRedo.startswith("Y"): 
        # If the user has not insisted on redo, skip it.
        NTRC.ntracef(0,"MAIN","proc skip item already done run|%s| "
            "id|%s| copies|%s| lifem|%s|" 
            % (mysRunNumber, sInstructionId, mydInstruction["nCopies"],
            mydInstruction["nLifem"]))
    else:
        # If the user specifies, redo this case even if was done before.
        if g.sRedo.startswith("Y"): 
            NTRC.ntracef(0,"MAIN","proc force redo of run|%s| id|%s| " 
                % (mysRunNumber, sInstructionId))

        # Well, maybe.  Could be listonly.
        if g.sListOnly.startswith("Y"):
            NTRC.ntracef(0,"MAIN","proc ListOnly, item run|%s| "
                "ncopies|%s| lifem|%s| id|%s| dict|%s|" 
                % (mysRunNumber, mydInstruction["nCopies"], mydInstruction["nLifem"],
                sInstructionId, list(util.fngSortDictItemsByKeys(mydInstruction))))
        else:
            # Okay, really do this instruction.  
            mydInstruction["nRandomSeed"] = mynSeed
            NTRC.ntracef(0,"MAIN","proc queue instr, item run|%s| "
                "ncopies|%s| lifem|%s| id|%s|" 
                % (mysRunNumber, mydInstruction["nCopies"], mydInstruction["nLifem"],
                sInstructionId))

            # Format commands to be executed by actor.
            g.sShelfLogFileName = g.cFmt.msGentlyFormat(
                                g.sShelfLogFileTemplate, mydInstruction, g, CG)
            g.lCommands = []
            for sTemplate in g.lTemplates:
                sCmd = g.cFmt.msGentlyFormat(sTemplate, mydInstruction, g, CG)
                g.lCommands.append(sCmd)

            # Where do files go, and what are they called.
            g.sActorLogDir = g.cFmt.msGentlyFormat(
                                g.sActorLogDirTemplate, mydInstruction, g, CG)

            # Record that this job will soon be running.
            mydInstruction["starttime"] = util.fnsGetTimeStamp()
            g.mdb.fndInsertProgressRecord(mydInstruction["_id"], mydInstruction)
            
            # Return the full instruction.
            tThisInst = tInstruction(casedict=mydInstruction
                                    , cmdlist=g.lCommands
                                    , logname=g.sShelfLogFileName + "_case.log"
                                    , logdir=g.sActorLogDir
                                    , runid=mysRunNumber
                                    )

            # Send the instruction out to be done.
            g.qInstructions.put(tThisInst)
            
            if not g.thrStart.is_alive(): g.thrStart.start()
            if not g.thrEnd.is_alive(): g.thrEnd.start()

            return tThisInst
コード例 #8
0
def fntProcessOneInstruction(mysRunNumber, mydInstruction, mynSeed):
    ''' 
    Process one single instruction for one run.  
    If just testing today, print instruction contents but do not run it.
    If the instruction has already been processed, skip over it unless
     the user requires it to be redone.  
    '''
    sInstructionId = str(mydInstruction["_id"])

    # If this instruction has already been processed, maybe skip it.
    bIsItDone = g.mdb.fnbIsItDone(sInstructionId)
    if bIsItDone and not g.sRedo.startswith("Y"):
        # If the user has not insisted on redo, skip it.
        NTRC.ntracef(
            0, "MAIN", "proc skip item already done run|%s| "
            "id|%s| copies|%s| lifem|%s|" %
            (mysRunNumber, sInstructionId, mydInstruction["nCopies"],
             mydInstruction["nLifem"]))
    else:
        # If the user specifies, redo this case even if was done before.
        if g.sRedo.startswith("Y"):
            NTRC.ntracef(
                0, "MAIN", "proc force redo of run|%s| id|%s| " %
                (mysRunNumber, sInstructionId))

        # Well, maybe.  Could be listonly.
        if g.sListOnly.startswith("Y"):
            NTRC.ntracef(
                0, "MAIN", "proc ListOnly, item run|%s| "
                "ncopies|%s| lifem|%s| id|%s| dict|%s|" %
                (mysRunNumber, mydInstruction["nCopies"],
                 mydInstruction["nLifem"], sInstructionId,
                 list(util.fngSortDictItemsByKeys(mydInstruction))))
        else:
            # Okay, really do this instruction.
            mydInstruction["nRandomSeed"] = mynSeed
            NTRC.ntracef(
                0, "MAIN", "proc queue instr, item run|%s| "
                "ncopies|%s| lifem|%s| id|%s|" %
                (mysRunNumber, mydInstruction["nCopies"],
                 mydInstruction["nLifem"], sInstructionId))

            # Format commands to be executed by actor.
            g.sShelfLogFileName = g.cFmt.msGentlyFormat(
                g.sShelfLogFileTemplate, mydInstruction, g, CG)
            g.lCommands = []
            for sTemplate in g.lTemplates:
                sCmd = g.cFmt.msGentlyFormat(sTemplate, mydInstruction, g, CG)
                g.lCommands.append(sCmd)

            # Where do files go, and what are they called.
            g.sActorLogDir = g.cFmt.msGentlyFormat(g.sActorLogDirTemplate,
                                                   mydInstruction, g, CG)

            # Record that this job will soon be running.
            mydInstruction["starttime"] = util.fnsGetTimeStamp()
            g.mdb.fndInsertProgressRecord(mydInstruction["_id"],
                                          mydInstruction)

            # Return the full instruction.
            tThisInst = tInstruction(casedict=mydInstruction,
                                     cmdlist=g.lCommands,
                                     logname=g.sShelfLogFileName + "_case.log",
                                     logdir=g.sActorLogDir,
                                     runid=mysRunNumber)

            # Send the instruction out to be done.
            g.qInstructions.put(tThisInst)

            if not g.thrStart.is_alive(): g.thrStart.start()
            if not g.thrEnd.is_alive(): g.thrEnd.start()

            return tThisInst
コード例 #9
0
def mainsim_post():
#   C O L L E C T   D A T A 
    # Collect all the bloody data, one item at a time, grumble.
    sFamilyDir = request.forms.get("sFamilyDir")
    sSpecificDir = request.forms.get("sSpecificDir")
    sDatabaseName = request.forms.get("sDatabaseName")
    nRandomSeeds = request.forms.get("nRandomSeeds")

    lCopies= request.forms.getall("nCopies")

    lLifem = request.forms.getall("nLifem")
    nServerDefaultLife = request.forms.getall("nServerDefaultLife")

    nAuditFreq = request.forms.get("nAuditFreq")
    nAuditSegments = request.forms.get("nAuditSegments")
    sAuditType = request.forms.get("sAuditType")

    lGlitchFreq = request.forms.getall("nGlitchFreq")
    lGlitchImpact = request.forms.getall("nGlitchImpact")
    lGlitchMaxlife = request.forms.getall("nGlitchMaxlife")
    nGlitchSpan = request.forms.get("nGlitchSpan")
    nGlitchDecay = request.forms.get("nGlitchDecay")

    lShockFreq = request.forms.getall("nShockFreq")
    lShockImpact = request.forms.getall("nShockImpact")
    lShockSpan = request.forms.getall("nShockSpan")
    lShockMaxlife = request.forms.getall("nShockMaxlife")

    nDocuments = request.forms.getall("nDocuments")
    nDocSize = request.forms.get("nDocSize")
    nShelfSize = request.forms.get("nShelfSize")

    bShortLog = request.forms.get("bShortLog")

    nSimLength = request.forms.getall("nSimLength")
    nBandwidthMbps = request.forms.get("nBandwidthMbps")

    bRedo = request.forms.get("bRedo")
    bTestOnly = request.forms.get("bTestOnly")
    
    bRunDetached = request.forms.get("bRunDetached")
    sDetachedLogfile = request.forms.get("sDetachedLogfile")

    msg = "mainsim_post: NOT YET IMPLEMENTED"

#   F O R M   D I C T I O N A R Y   O F   S U B S T I T U T I O N S 
    # Make a dictionary to use to substitute params into CLI command.
    dVals = dict(sFamilyDir=sFamilyDir, sSpecificDir=sSpecificDir,

                sCopies=fnsQuoteMulti(lCopies),
                nServerDefaultLife=fnsQuoteMulti(nServerDefaultLife), 

                sLifem=fnsQuoteMulti(lLifem), 

                nAuditFreq=nAuditFreq, nAuditSegments=nAuditSegments, 
                sAuditType=sAuditType,

                sGlitchFreq=fnsQuoteMulti(lGlitchFreq), 
                sGlitchImpact=fnsQuoteMulti(lGlitchImpact), 
                sGlitchMaxlife=fnsQuoteMulti(lGlitchMaxlife), 
                nGlitchSpan=nGlitchSpan, 
                nGlitchDecay=nGlitchDecay, 

                bShortLog=bShortLog, 

                nSimLength=fnsQuoteMulti(nSimLength), 
                nBandwidthMbps=nBandwidthMbps, 
                nRandomSeeds=nRandomSeeds, 

                sShockFreq=fnsQuoteMulti(lShockFreq), 
                sShockImpact=fnsQuoteMulti(lShockImpact), 
                sShockSpan=fnsQuoteMulti(lShockSpan), 
                sShockMaxlife=fnsQuoteMulti(lShockMaxlife), 

                nDocSize=nDocSize, nShelfSize=nShelfSize, 
                nDocuments=fnsQuoteMulti(nDocuments),

                bRedo=bRedo,
                bTestOnly=bTestOnly, 
                sDatabaseName=sDatabaseName, 

                bRunDetached=bRunDetached,
                sDetachedLogfile=sDetachedLogfile,

                msg=msg
                )
    NTRC.ntrace(3,"proc first dict|%s|" % (dVals))

#  S P E C I A L   C A S E S   O F   I N T E R D E P E N D E N C E 
    # If the user specified a logfile for detached running, then 
    #  pretend that he remembered to check the box, too.
    if dVals["sDetachedLogfile"]:
        dVals["bRunDetached"] = True
    # If the user wants to run detached, we may have to supply 
    #  a default filename.
    # Be sure to add today's date to the default filename.
    if dVals["bRunDetached"] and not dVals["sDetachedLogfile"]:
        dVals["sDetachedLogfile"] = ("./BrokerDetachedLogfile"
                                + "_"
                                + util.fnsGetTimeStamp().split("_")[0]
                                + ".log")

#  A D D   E X T R A   S P E C I F I C   S T R I N G S 
    # If the user asks for a shortlog, add the option to the command.
    dVals["xshortlog"] = "--shortlog" if bShortLog else ""

    # If the user asks for a test list only, add that option to the command.
    dVals["xtestonly"] = "--listonly" if bTestOnly else ""

    # If the user asks for a rematch, add that option to the command.
    dVals["xredo"] = "--redo" if bRedo else ""

    # Format the Mongo range expression for nCopies
    dVals["xcopies"] = dVals["sCopies"]

    # Format the Mongo range expression for nLifem
    dVals["xlifem"] = dVals["sLifem"]
    NTRC.ntrace(3,"proc expanded dict|%s|" % (dVals))

    # If running detached with output to a log file, 
    #  specify append to file and detach process.
    if dVals["sDetachedLogfile"]:
        dVals["xLogfileExpr"] = (" >> " 
                                + dVals["sDetachedLogfile"]
                                + " &")
    else:
        dVals["xLogfileExpr"] = ""

#  S E L E C T   C O M M A N D  A N D   F O R M A T  I T
    # Do something with the form data
    sActualCli = cCmd.mGentlyFormat(sMainCommandStringToStdout, dVals)
#    sActualCli = cCmd.mGentlyFormat(sMainCommandStringTestOnly, dVals)
#    sActualCli = cCmd.mGentlyFormat(sMainCommandStringDumbTest, dVals)
    NTRC.ntrace(3,"proc actual cli|%s|" % (sActualCli))
    sPrefix = '''<html><body>
        <font face="Courier">\n
    '''
    sPrefix += '<br />'
    sPrefix += util.fnsGetTimeStamp()
    sPrefix += '  Working. . . \n'
    sPrefix += "<br />" + sActualCli + "<br />\n"
    sSuffix = '''
        </font>
        </body></html>
    '''
    sLinePrefix = '<br />'
    sLineSuffix = ''

#    return dVals         # DEBUG: return dict for visual inspection.

    sResult = fnValidateDirectories(dVals)
    if sResult:
        response.status = 300
        return sPrefix + sResult + sSuffix

    # Other validations go in here.

    if sResult == "":
    #  E X E C U T E   C L I   C M D ,   R E T U R N   R E S U L T S     
        return cCmd.mDoCmdGen(sPrefix, sSuffix, sLinePrefix, sLineSuffix, 
                sActualCli)
コード例 #10
0
def mainsim_post():
    #   C O L L E C T   D A T A
    # Collect all the bloody data, one item at a time, grumble.
    sFamilyDir = request.forms.get("sFamilyDir")
    sSpecificDir = request.forms.get("sSpecificDir")
    sDatabaseName = request.forms.get("sDatabaseName")
    nRandomSeeds = request.forms.get("nRandomSeeds")

    lCopies = request.forms.getall("nCopies")

    lLifem = request.forms.getall("nLifem")
    nServerDefaultLife = request.forms.getall("nServerDefaultLife")

    nAuditFreq = request.forms.get("nAuditFreq")
    nAuditSegments = request.forms.get("nAuditSegments")
    sAuditType = request.forms.get("sAuditType")

    lGlitchFreq = request.forms.getall("nGlitchFreq")
    lGlitchImpact = request.forms.getall("nGlitchImpact")
    lGlitchMaxlife = request.forms.getall("nGlitchMaxlife")
    nGlitchSpan = request.forms.get("nGlitchSpan")
    nGlitchDecay = request.forms.get("nGlitchDecay")

    lShockFreq = request.forms.getall("nShockFreq")
    lShockImpact = request.forms.getall("nShockImpact")
    lShockSpan = request.forms.getall("nShockSpan")
    lShockMaxlife = request.forms.getall("nShockMaxlife")

    nDocuments = request.forms.getall("nDocuments")
    nDocSize = request.forms.get("nDocSize")
    nShelfSize = request.forms.get("nShelfSize")

    bShortLog = request.forms.get("bShortLog")

    nSimLength = request.forms.getall("nSimLength")
    nBandwidthMbps = request.forms.get("nBandwidthMbps")

    bRedo = request.forms.get("bRedo")
    bTestOnly = request.forms.get("bTestOnly")

    bRunDetached = request.forms.get("bRunDetached")
    sDetachedLogfile = request.forms.get("sDetachedLogfile")

    msg = "mainsim_post: NOT YET IMPLEMENTED"

    #   F O R M   D I C T I O N A R Y   O F   S U B S T I T U T I O N S
    # Make a dictionary to use to substitute params into CLI command.
    dVals = dict(sFamilyDir=sFamilyDir,
                 sSpecificDir=sSpecificDir,
                 sCopies=fnsQuoteMulti(lCopies),
                 nServerDefaultLife=fnsQuoteMulti(nServerDefaultLife),
                 sLifem=fnsQuoteMulti(lLifem),
                 nAuditFreq=nAuditFreq,
                 nAuditSegments=nAuditSegments,
                 sAuditType=sAuditType,
                 sGlitchFreq=fnsQuoteMulti(lGlitchFreq),
                 sGlitchImpact=fnsQuoteMulti(lGlitchImpact),
                 sGlitchMaxlife=fnsQuoteMulti(lGlitchMaxlife),
                 nGlitchSpan=nGlitchSpan,
                 nGlitchDecay=nGlitchDecay,
                 bShortLog=bShortLog,
                 nSimLength=fnsQuoteMulti(nSimLength),
                 nBandwidthMbps=nBandwidthMbps,
                 nRandomSeeds=nRandomSeeds,
                 sShockFreq=fnsQuoteMulti(lShockFreq),
                 sShockImpact=fnsQuoteMulti(lShockImpact),
                 sShockSpan=fnsQuoteMulti(lShockSpan),
                 sShockMaxlife=fnsQuoteMulti(lShockMaxlife),
                 nDocSize=nDocSize,
                 nShelfSize=nShelfSize,
                 nDocuments=fnsQuoteMulti(nDocuments),
                 bRedo=bRedo,
                 bTestOnly=bTestOnly,
                 sDatabaseName=sDatabaseName,
                 bRunDetached=bRunDetached,
                 sDetachedLogfile=sDetachedLogfile,
                 msg=msg)
    NTRC.ntrace(3, "proc first dict|%s|" % (dVals))

    #  S P E C I A L   C A S E S   O F   I N T E R D E P E N D E N C E
    # If the user specified a logfile for detached running, then
    #  pretend that he remembered to check the box, too.
    if dVals["sDetachedLogfile"]:
        dVals["bRunDetached"] = True
    # If the user wants to run detached, we may have to supply
    #  a default filename.
    # Be sure to add today's date to the default filename.
    if dVals["bRunDetached"] and not dVals["sDetachedLogfile"]:
        dVals["sDetachedLogfile"] = ("./BrokerDetachedLogfile" + "_" +
                                     util.fnsGetTimeStamp().split("_")[0] +
                                     ".log")

#  A D D   E X T R A   S P E C I F I C   S T R I N G S
# If the user asks for a shortlog, add the option to the command.
    dVals["xshortlog"] = "--shortlog" if bShortLog else ""

    # If the user asks for a test list only, add that option to the command.
    dVals["xtestonly"] = "--listonly" if bTestOnly else ""

    # If the user asks for a rematch, add that option to the command.
    dVals["xredo"] = "--redo" if bRedo else ""

    # Format the Mongo range expression for nCopies
    dVals["xcopies"] = dVals["sCopies"]

    # Format the Mongo range expression for nLifem
    dVals["xlifem"] = dVals["sLifem"]
    NTRC.ntrace(3, "proc expanded dict|%s|" % (dVals))

    # If running detached with output to a log file,
    #  specify append to file and detach process.
    if dVals["sDetachedLogfile"]:
        dVals["xLogfileExpr"] = (" >> " + dVals["sDetachedLogfile"] + " &")
    else:
        dVals["xLogfileExpr"] = ""

#  S E L E C T   C O M M A N D  A N D   F O R M A T  I T
# Do something with the form data
    sActualCli = cCmd.mGentlyFormat(sMainCommandStringToStdout, dVals)
    #    sActualCli = cCmd.mGentlyFormat(sMainCommandStringTestOnly, dVals)
    #    sActualCli = cCmd.mGentlyFormat(sMainCommandStringDumbTest, dVals)
    NTRC.ntrace(3, "proc actual cli|%s|" % (sActualCli))
    sPrefix = '''<html><body>
        <font face="Courier">\n
    '''
    sPrefix += '<br />'
    sPrefix += util.fnsGetTimeStamp()
    sPrefix += '  Working. . . \n'
    sPrefix += "<br />" + sActualCli + "<br />\n"
    sSuffix = '''
        </font>
        </body></html>
    '''
    sLinePrefix = '<br />'
    sLineSuffix = ''

    #    return dVals         # DEBUG: return dict for visual inspection.

    sResult = fnValidateDirectories(dVals)
    if sResult:
        response.status = 300
        return sPrefix + sResult + sSuffix

    # Other validations go in here.

    if sResult == "":
        #  E X E C U T E   C L I   C M D ,   R E T U R N   R E S U L T S
        return cCmd.mDoCmdGen(sPrefix, sSuffix, sLinePrefix, sLineSuffix,
                              sActualCli)