TracNav menu
-
How To
- Setup An Experiment
-
GUI
- Overview
- Options
- Controls
- Topology
-
Agents and Variables
- Overview
- Functions
- Scripting
- Topology
- Traffic
- Attacks
- Analysis
-
Development/Extending
- Overview
- Adding GUI Panels
- Adding Agent Types
Add an Agent Backend
Each node runs a single daemon process for receiving and processing events from the event system. An agent is a python module that is loaded by the daemon process. To add your own agent type, you need to create a python class that extends Agent or a subclass such as TrafgenAgent and then have that file placed in /usr/seer/backend/agents/ before calling experiment-setup.py.
Your class must define the class variable agenttype which represents the objecttype that your agent responds to.
Extending Agent
When extending the basic agent class, you need to call the Agent init method, register any variables that your agent can have set and then implement the methods that you need (The NODES variables is automatically setup for you). The Agent class will process incoming variable sets and then call configDone() followed by handleX() where X is an event type (SET is a special event and handleSET is never called).
The Agent class implements handleSTART() and handleSTOP() for basic usage. In this case, you just need to implement launchProgram() and place any process ids in self.pids. handleSTART() will call launchProgram() and handleSTOP() will kill any pids in self.pids.
A simple example class:
from seerplatform import spawn class MyAgent(agent.Agent): agenttype = 'MYTYPE' def __init__(self): agent.Agent.__init__(self) self.addVarType('src', 'cidr', None) self.addVarType('other', 'string', 'default) def configDone(self): # self.log is an interface to a standard python log object for this agent/group self.log.info("src is %s" % (self.getVar('src'))) self.log.info("other is %s" % (self.getVar('other'))) def launchProgram(self): self.pids.append(spawn("mycoolapp"))
If you would like different behavior for START or STOP events or a different event of your choosing you can simply provide your own implementation for them.
def handleSTART(self): # Do start stuff def handleSTOP(self): # Do stop stuff def handleDUMP(self): # Do something in response to a DUMP event
Agent instance variables
The Agent class has several internal variables and methods for your use:
| self.group | the group name for this instance |
| self.name | the node name this instance is running on |
| self.whiteboard | shared dict between all active agent groups |
| self.mystate | link to MyState object (see emulab.py) |
| self.log | link to a Logger object for this instance |
| self.setVar(key, val) | set the value of key to val |
| self.getVar(key) | get the value of key, will search 'node.key' and then 'key' |
| self.getGroupVar(key) | get the value of key, will only search 'key' |
| self.getNodeVar(key) | get the value of key, will only search 'node.key' |
| self.getOtherNodeVar(node, key) | get the value of key, will search 'othernode.key' then 'key' |
| self.myNodeMemberOf(arrayname) | check if node is located in the variable with key 'arrayname' |
| self.myIPMemberOf(arrayname) | check if any of node's IP addresses are located in the variable with key 'arrayname' |
| self.addVarType(key, type, default) | register a variable type that this agent will accept |
Extending TrafgenAgent
TrafgenAgent is designed for traffic generation agent and differs a bit from the basic Agent. It automatically registers the variables servers, think, sizes, autoquit. It also uses a different set of abstract methods: serverStart, serverStop, clientInit, clientStart.
serverStart() is called when:
- a START event is received and
- the local node is a member of servers and
- the same server is already running for another group
serverStop() is called when:
- a STOP event is received and
- the local node is a member of servers and
- this is the last group on this node that needs the server running
clientInit() is called when:
- initially upon a START event
clientExec(src, dst, size) is called when:
- the next think time has expired
An example is the video server agent. Note that when using TrafgenAgent, a new process group is created for you and forking occurs before clientExec so you don't need to fork on your own.
If you want to change part of the inner workings you can also override clientOneLoop(Source Pool, Destination Pool, Think, Sizes) to override the loop behavior or launchTrafficController to control all of the START behavior. However, if you are thinking of overriding launchTrafficController it may be better to just build off of Agent instead.
