316 lines
8.1 KiB
Python
316 lines
8.1 KiB
Python
"""Fuzzbunch Session handling
|
|
|
|
General class relationships. Currently Fuzzbunch only uses one session
|
|
with the session history being composed of session items.
|
|
|
|
Session
|
|
|
|
|
|-- SessionItem (Plugin - Evadefred)
|
|
|
|
|
|-- SessionInfo (label=History)
|
|
\-- SessionInfo (label=Contract)
|
|
|
|
For each SessionItem, Fuzzbunch maintains two lists of parameters:
|
|
* History - Input parameters
|
|
* Contract - Output parameters
|
|
"""
|
|
import uuid
|
|
import exception
|
|
import util
|
|
import os
|
|
|
|
__all__ = ['Session']
|
|
|
|
try:
|
|
DEFAULT_TMP = os.environ['TMP']
|
|
except KeyError:
|
|
DEFAULT_TMP = "/tmp"
|
|
|
|
HISTORY_STR = "History"
|
|
CONTRACT_STR = "Contract"
|
|
|
|
class SessionInfo:
|
|
"""Session info class. Contains a single set of parameters, either input
|
|
(History) or output (Contract) as a label.
|
|
|
|
label - label for this info item (Contract|History)
|
|
params - var,val parameter tuples
|
|
item - parent item reference
|
|
|
|
"""
|
|
def __init__(self, label, params, item):
|
|
self.item = item
|
|
self.label = label
|
|
self.params = util.iDict()
|
|
for p in params:
|
|
self.set(p[0], p)
|
|
|
|
"""
|
|
Printing
|
|
|
|
"""
|
|
def get_item_info(self):
|
|
return "%s - %d" % (self.item.name,self.item.id)
|
|
|
|
def __str__(self):
|
|
return "%s - %d" % (self.item.name,self.item.id)
|
|
|
|
def __repr__(self):
|
|
string = ">>> %d :: %s\n" % (self.item.id, self.item.name)
|
|
for v in self.params.itervalues():
|
|
string += " %s\n" % (str(v))
|
|
return string
|
|
|
|
"""
|
|
Marking
|
|
|
|
"""
|
|
def mark_used(self):
|
|
"""Mark the parent item as used"""
|
|
self.set_mark("USED")
|
|
|
|
def set_mark(self, value):
|
|
"""Mark the parent item"""
|
|
self.item.set_status(value)
|
|
|
|
"""
|
|
Labels
|
|
|
|
"""
|
|
def get_label(self):
|
|
"""Get the label for this info"""
|
|
return self.label
|
|
|
|
"""
|
|
Parameter access
|
|
|
|
"""
|
|
def set(self, var, val):
|
|
"""Add a parameter with value"""
|
|
self.params[var] = val
|
|
|
|
def get(self, var):
|
|
"""Get a parameter value"""
|
|
try:
|
|
return self.params[var]
|
|
except KeyError:
|
|
raise exception.CmdErr, "%s does not exist" % var
|
|
|
|
def get_paramlist(self):
|
|
"""Get a list of all parameter var,vals"""
|
|
return self.params.items()
|
|
|
|
|
|
class SessionItem(object):
|
|
"""Session item class. Contains info items which have the actual parameters
|
|
of the session. Items correspond to one execution of a given plugin and
|
|
maintain the state of the plugin execution. Possible states are
|
|
RUNNING - Plugin is still executing
|
|
FAIL - Plugin has failed
|
|
READY - Plugin is done executing and has generated a contract
|
|
USED - Item contract has been used by another plugin
|
|
"""
|
|
def __init__(self, name, id, description, sess):
|
|
self.sess = sess
|
|
self.name = name
|
|
self.id = id
|
|
self.description = description
|
|
self.status = "RUNNING"
|
|
self._contract = None
|
|
self._history = None # Ends up containing the running history of sessions with this name
|
|
|
|
def __str__(self):
|
|
"""The short view of what's going on"""
|
|
return "%s (%s)" % (self.name, self.status)
|
|
|
|
def __repr__(self):
|
|
"""All information about the SessionItem"""
|
|
string = "[%d] %s (%s)\n" % (self.id, self.name, self.status)
|
|
string += " Description : %s\n" % (self.description)
|
|
string += " Contract : %s\n" % (str(self.contract))
|
|
string += " History : %s\n" % (str(self.history))
|
|
return string
|
|
|
|
"""
|
|
Session Item Attributes
|
|
|
|
"""
|
|
def get_name(self):
|
|
"""Get the item name"""
|
|
return self.name
|
|
|
|
def get_description(self):
|
|
return self.description
|
|
|
|
def get_longname(self):
|
|
return self.name + " " + self.description
|
|
|
|
def history():
|
|
doc = "Session item history params"
|
|
def fget(self):
|
|
return self._history
|
|
def fset(self, value):
|
|
self._history = SessionInfo(HISTORY_STR, value, self)
|
|
return locals()
|
|
history = property(**history())
|
|
|
|
def contract():
|
|
doc = "Session item contract params"
|
|
def fget(self):
|
|
return self._contract
|
|
def fset(self, value):
|
|
self._contract = SessionInfo(CONTRACT_STR, value, self)
|
|
return locals()
|
|
contract = property(**contract())
|
|
|
|
def get_info(self):
|
|
return (util.Param(HISTORY_STR, self.history),
|
|
util.Param(CONTRACT_STR, self.contract))
|
|
|
|
"""
|
|
Directories
|
|
|
|
"""
|
|
def get_dirs(self):
|
|
"""Return session directories"""
|
|
return self.sess.get_dirs()
|
|
|
|
"""
|
|
Item status
|
|
|
|
"""
|
|
def is_ready(self):
|
|
if self.status == "READY":
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def is_failed(self):
|
|
if self.status == "FAIL":
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def get_status(self):
|
|
"""Get the item status"""
|
|
reason = ''
|
|
if self.is_failed():
|
|
try:
|
|
# This shouldn't happen, but weirder things have
|
|
for p in self.contract.get_paramlist():
|
|
if p.name.lower() == 'returncode':
|
|
reason = ' : ' + p.value.value
|
|
break
|
|
except:
|
|
# Still say we failed, but don't say why
|
|
pass
|
|
return self.status + reason
|
|
|
|
def set_status(self, status):
|
|
"""Set the status of the item"""
|
|
if status.upper() in ("RUNNING", "FAIL", "READY", "USED"):
|
|
self.status = status.upper()
|
|
else:
|
|
raise exception.CmdErr, "%s invalid status" % status
|
|
|
|
def mark_running(self):
|
|
self.set_status("RUNNING")
|
|
|
|
def mark_fail(self):
|
|
self.set_status("FAIL")
|
|
|
|
def mark_ready(self):
|
|
self.set_status("READY")
|
|
|
|
def mark_used(self):
|
|
self.set_status("USED")
|
|
|
|
"""
|
|
Contract Handling
|
|
|
|
"""
|
|
def has_opencontract(self):
|
|
if self.status in ("USED", "FAIL"):
|
|
return False
|
|
if self.status == "RUNNING":
|
|
return True
|
|
|
|
for p in self.contract.get_paramlist():
|
|
if p.name.lower() in ("connectedtcp", "rendezvous"):
|
|
return True
|
|
return False
|
|
|
|
def has_contract(self):
|
|
if self.contract:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
class Session:
|
|
"""Session class. Contains complete history (items) for a session."""
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.items = []
|
|
self.session_id = str(uuid.uuid4())
|
|
self.set_dirs(DEFAULT_TMP, DEFAULT_TMP)
|
|
|
|
def get_name(self):
|
|
"""Get the name of the session"""
|
|
return self.name
|
|
|
|
"""
|
|
Directories
|
|
|
|
"""
|
|
def set_dirs(self, base_dir, log_dir):
|
|
"""Set session directories"""
|
|
self.base_dir = os.path.normpath(base_dir)
|
|
self.log_dir = os.path.normpath(log_dir)
|
|
|
|
def get_dirs(self):
|
|
"""Return session directories"""
|
|
return (self.base_dir, self.log_dir)
|
|
|
|
"""
|
|
Single Item Access
|
|
|
|
"""
|
|
def add_item(self, name, description):
|
|
"""Add a new item to the session"""
|
|
id = len(self.items)
|
|
self.items.append(SessionItem(name, id, description, self))
|
|
return self.items[-1]
|
|
|
|
def get_item(self, index):
|
|
"""Get an item by index from the session"""
|
|
try:
|
|
return self.items[index]
|
|
except IndexError:
|
|
raise exception.CmdErr, "Bad index %d" % index
|
|
|
|
"""
|
|
Bulk access
|
|
|
|
"""
|
|
def get_itemlist(self):
|
|
"""Get all of the items in the session"""
|
|
return [util.Param(item.get_name(), item) for item in self.items]
|
|
|
|
"""
|
|
Contract Interface
|
|
|
|
"""
|
|
def get_contractlist(self):
|
|
return [item.contract
|
|
for item in self.items
|
|
if item.contract and item.is_ready()]
|
|
|
|
def get_contract(self, index):
|
|
"""Get a contract by index from the session"""
|
|
item = self.get_item(index)
|
|
if item.contract:
|
|
return item.contract
|
|
else:
|
|
raise exception.CmdErr, "Contract not available"
|
|
|