= Plugging In = The [source:fedd/trunk/federation/skeleton.py skeleton plugin] is not a real plug-in. It is one of the standard access controllers that ships with the fedd install. First we'll create a plug-in. A plug in is just python code that defines a class called {{{access}}} that accepts the same parameters to its initializer as the [source:fedd/trunk/federation/skeleton.py skeleton plugin]. These are a configuration object and an authorizer object (and the [source:fedd/trunk/federation/access.py standard plug-in base class] will handle the authorizer for you. It should also conform to the conventions in the skeleton with respect to setting up the {{{self.soap_services}}} and {{{self.xmlrpc_services}}} dicts, and handle the various [FeddPluginCalls plug-in calls]. An easy way to do this is to simply copy the skeleton into a file in another directory with a different name. Because you have moved this module relative to its current place in the hierarchy (it is no longer in the {{{federation}}} directory) you will have to modify the import paths at the beginning. Specifically change the lines: {{{ from util import * from fedid import fedid, generate_fedid from authorizer import authorizer from service_error import service_error from remote_service import xmlrpc_handler, soap_handler, service_caller import topdl from access import access_base }}} to: {{{ from federation.util import * from federation.fedid import fedid, generate_fedid from federation.authorizer import authorizer from federation.service_error import service_error from federation.remote_service import xmlrpc_handler, soap_handler, service_caller import federation.topdl as topdl from federation.access import access_base }}} That is, explicitly set the {{{federation.}}} scope for modules in {{{fedd}}}'s {{{federation}}} directory. The plugin sits outside the fedd code tree, so if it needs to use other code that lives in that tree, it must import from the {{{federation}}} package. It is also probably worthwhile to add a log message to the initializer so that you can tell your code ran. For example, add {{{ self.log.debug("This is my plugin module") }}} to the end of your {{{access.__init__(self, config, auth)}}} member. To dynamically load the plug-in you need to: * Create a directory readable by the user fedd will run as * Move your python plug-in code into there. Name the file something other than {{{emulab.py}}}, {{{dragon.py}}}, {{{protogeni.py}}}, {{{deter_internal.py}}} or {{{skel.py}}}. Make sure it can also be read by the fedd user. * Add your pathname to the '''module_path''' configuration variable in the '''[globals]''' section * Set the '''access_type''' to the name of your file (without the {{{.py}}}). If your plugin is in {{{/usr/home/faber/plugins/plug.py}}} then your configuration file should contain the following definitions in the {{{[globals]}}} section: {{{ module_path: /usr/home/faber/plugins access_type: plug }}} Run fedd with your modified configuration after '''--config''' and with '''--debug''' to see your log message: {{{ fedd.py --config=/home/faber/fedd/fedd.config --debug }}} and you should see something like: {{{ 29 Jun 10 19:33:29 fedd.access [read_state]: No saved state: Can't open /users/faber/fedd-config/skel2/skel_access.state: [Errno 2] No such file or directory: '/users/faber/fedd-config/skel2/skel_access.state' 29 Jun 10 19:33:29 fedd.access This is my plugin module }}}