= The Plug-in Skeleton = The federation distribution includes a functional skeleton that illustrates handling the [FeddPluginCalls interface calls] though it does not manipulate any external testbed. It does illustrate most of the support for creating plug-ins, including reading configuration files, creating access control databases that map to local permission structures, storing persistent state and allocating local resources. The skeleton merely assigns an non-negative integer to each request. The range of integers is set from a configuration file. This page describes how to set-up and run the skeleton plug-in, as well as what it does. First, [FeddDownload install] the fedd software and its dependencies. Then configure it as below. == Configuration == These are the steps to configure the skeleton: * Create a configuration directory that's readable by the user that the plugin will run as (probably your uid) * make subdirectories in it called {{{certs}}} and {{{userconf}}}. The {{{certs}}} directory must be writeable. * Copy [attachment:skel.conf] into thie configuration directory. * Copy [attachment:skel_access] into the configuration directory * [FeddConfig#MakingaFedidCertificate Create a certificate representing a fedid] in this directory. * Copy [attachment:guest.pem] to your local machine. It need not be in the configuration directory. * Follow the steps below to edit [attachment:skel.conf] for your installation. If you put the certificate you created above into {{{fedd.pem}}} all you need to do is change the first line to include the full pathname to your configuration directory. Something like: {{{ base: /my/config/directory }}} If you named the certificate something other than {{{fedd.pem}}}, you need to change the line that starts with {{{cert_file:}}} to point to your file. This means changing the pathname. For example if the certificate was called {{{mycert.pem}}} the line would change to: {{{ cert_file: %(base)s/mycert.pem }}} If the certificate you created has a password, that password must be included as the {{{cert_pwd}}} parameter. For example: {{{ cert_pwd: mypwd }}} In a real installation, including such passwords in the configuration file implies that the configuration file must be secured. The next sections explains the contents of the configuration files in more detail, but you can skip ahead to [FeddSkelPlugin#RunningTheSkeleton running the plug-in] if you perfer. == Configuration File Contents == The [attachment:skel.conf] file contains three sections, each set off by a section name in braces, e.g., {{{[access]}}}. We will explain this file section by section. === [DEFAULT] === The first section, {{{[DEFAULT]}}} contains parameters that will be expanded in later sections. The {{{base}}} parameter will be used in other pathnames, to avoid having to hard code each full pathname. In later sections,the {{{%(base)s}}} construction will expand to the contents of the {{{base}}}} parameter. This is a standard construction in a configuration file parsed by python's [http://docs.python.org/library/configparser.html ConfigParser] module. The value inside the {{{%()}}} is the variable to expand, which is followed by a single character for formatting. More information about these conventions is [http://docs.python.org/library/configparser.html available]. === [access] === The {{{[access]}}} section contains most of the plug-in configuration information. Field by field: '''project_priority: false''':: This means that if two [FeddAbout#GlobalIdentifiers:Three-levelNames three level names] match for the current request, give priority to the user match rather than the project match. Practically this has little effect on the skeleton. '''log_level: debug''':: Log messages at or above log.DEBUG level will be printed to stderr or a log file. '''access_state: %(base)s/skel_access.state''':: The persistent state of the plug-in will be stored in this file (skel_access.state in the base directory). The plug-in will create this file if it is not there and state needs to be stored. '''accessdb: %(base)s/skel_access''':: The access database is in skel_access in the base directory. We will discuss the contents of that file below. '''certdir: %(base)s/certs''':: This directory is used to store transient certificates. It should be readable only by the federation user. '''userconfdir: %(base)s/userconf''':: Used to store information about exported user configurations. Again, it should be readable only by the federation user. '''maxint: 3''':: The maximum integer that the skeleton will allocate is 3. This is not inclusive, so the skeleton will actually allocate from {0,1,2,}. A line of the form '''create_debug: true''' is commented out. When true, that parameter generally means that the plug-in will not make allocations when requests come in. Because the skeleton only manipulates its internal state, the parameter is not used. There are other common attributes in this section that are left as defaults in the example file, and [FeddConfig#AccessOptions defined elsewhere]. === [globals] === The two or three parameters in this section control overall operation of the plug-in, specifically what prinicpal ID (that is which [FeddAbout#GlobalIdentifiers:Fedids fedid]) it uses and what TCP port it provides services on. '''cert_file''' and '''cert_pwd''' select the X.509 certificate and encyrption password, if any, used to identify the plug-in. The '''services''' parameter controls which ports and transports are used. The sample file serves SOAP traffic on port 13230. [FeddConfig#GlobalOptions Other choices] are possible. The '''access_type''' parameter chooses the type of access controller to run, in this case '''skel''' for the skeleton controller. == The Access Database == The [attachment:skel_access access database] has only one entry in it, which allows access from a user '''guest''' in the '''testing''' project project when asserted by [FeddAbout#GlobalIdentifiers:Fedids fedid] b55205ac843c40ce9c9feb3b358bff782ed337fd. That fedid is the one asserted by the fedd experiment controller running at DETER. For testing plug-ins the DETER experiment controller will permit anyone connecting with the fedid encoded in the [attachment:guest.pem guest.pem] file to request operations with that three-level name. Once your plug-in does something interesting, you should reduce or eliminate the access rights of that user. The rest of the line gives that user access permissions and the local permission state '''Local_attr'''. This is more to show how to assign such allocations, which will be meaningful in real installations. For example, see the configurations of other plug-ins. == Running the Skeleton == To start the plug-in, assuming that the configuration files are in {{{/usr/local/etc/skel}}} run the command: {{{ $ fedd.py --config=/usr/local/etc/skel.conf --debug }}} This assumes you have properly installed fedd and that fedd.py is in your path. You will see a few log messages indicating that the access and state databases have been read or are not yet created. The easiest way to see the skeleton operate is to access it through the DETER experiment controller. To do that we need two things, permission to use an experiment controller and a way to tell that experiment controller where our skeleton is. Permission is handled by using the [attachment:guest.pem guest fedid certificate] on the DETER experiment controller. In order to tell that experiment controller where to find our skeleton, we use the '''--map''' parameter to [FeddCommands#fedd_create.py fedd_create.py]. Running a command like the following should cause DETER's experiment controller to start an experiment on the running skeleton: {{{ $ ./fedd_create.py --cert=./guest.pem --url=https://users.isi.deterlab.net:13232 --experiment_name=faber-test --file=./skel-only.tcl --map=skeleton:https://users.isi.deterlab.net:13230 }}} The '''--cert''' parameter must point to your local copy of [attachment:guest.pem], you can pick any '''--experiment_name''' you like, though names prefixed by you suername are less likely to collide with the names chosen by others, '''--file''' must point to an experiment description containing nodes destined for testbed "skeleton", again a local copy of [attachment:skel-only.tcl] is a good choice. Finally the '''--map''' parameter needs to map the "skeleton" testbed into your running skeleton's URI. The hostname part should be a globally reachable IP address or DNS name on which your controller is running and the port part should be the value in the '''services''' parameter in the '''[globals]''' section of the configuration file. If you are using the example file, the 13230 port is correct. The {{{fedd_create.py}}} command has run, you should see output similar to: {{{ Warning:Neither master/project nor services requested localname: faber-test fedid: b3af52e09614b7f4731361ae82c8d66dcf50ef12 status: starting }}} You needn't worry about the warning. The localname is the string by which you can access the experiment. If there was another experiment running on the DETER controller with the same name as you requested in the '''--experiment_name''' parameter, you would need to use the one returned. If you miss the name here, you can always retrieve it using the [FeddCommands#fedd_multistatus.py fedd_multistatus.py] command. In the window running the skeleton, you should see output similar to: {{{ 28 Jun 10 09:32:50 fedd.access [read_state]: No saved state: Can't open /users/faber/fedd-config/skel/skel_access.state: [Errno 2] No such file or directory: '/users/faber/fedd-config/skel/skel_access.state' 28 Jun 10 09:33:02 fedd.access [lookup_access] Checking access for (fedid(hexstr='b55205ac843c40ce9c9feb3b358bff782ed337fd'), u'testing', u'guest') 28 Jun 10 09:33:02 fedd.access [lookup_access] Access granted 28 Jun 10 09:33:02 fedd.access [RequestAccess] Access granted to (fedid(hexstr='b55205ac843c40ce9c9feb3b358bff782ed337fd'), u'testing', u'guest') with local creds Local_attr 28 Jun 10 09:33:02 fedd.access [generate_fedid] /usr/bin/openssl req -text -newkey rsa:2048 -keyout /tmp/key-gY474.pem -nodes -subj /CN=alloc -x509 -days 30 -out /tmp/certAJ3SiY.pem 28 Jun 10 09:33:02 fedd.access rv = 0 28 Jun 10 09:33:02 fedd.access Wrote state to /users/faber/fedd-config/skel/skel_access.state 28 Jun 10 09:33:02 fedd.access [RequestAccess] Returning allocation ID: 32b21906165aa76bbc629511b81b7504d01a0f20 28 Jun 10 09:33:02 fedd Successful SOAP request code 200 28 Jun 10 09:33:03 fedd.access Wrote state to /users/faber/fedd-config/skel/skel_access.state 28 Jun 10 09:33:03 fedd.access [StartSegment] Allocated 0 to 32b21906165aa76bbc629511b81b7504d01a0f20 28 Jun 10 09:33:03 fedd.access Wrote state to /users/faber/fedd-config/skel/skel_access.state 28 Jun 10 09:33:03 fedd Successful SOAP request code 200 }}} That's the output from a successful experiment creation on the skeleton. Notice the request for access from (b55205ac843c40ce9c9feb3b358bff782ed337fd, 'testing', 'guest') that is approved, the creation of the access principal and the saving of state all before the first {{{Successful SOAP request code 200}}} line. That is all output from a successful !RequestAccess call, and you can trace the !RequestAccess method in [source:fedd/trunk/federation/skeleton_access.py federation/skeleton_access.py]. The rest of the output is the successful !StartSegment call. To see the state of your experiment do the following. Make sure to give the '''--cert''' option. Without it the commands will either fail, or if you have a certificate in a standard emulab set-up, return confusing results. {{{ $ ./fedd_multistatus.py --cert=./guest.pem --url=http://users.isi.deterlab.net:13232 }}} Which outputs: {{{ faber-test:410964884311e3531bb8bcccb17922e4b090d905:active }}} The first two fields are the readable name and the fedid of the experiment, which will match the output from {{{fedd_create.py}}} not the ones in this document. The {{{fedd_multistatus.py}}} command only queries the experiment controller, so no changes to the skeleton log will be happen. Removing the experiment will exercise the !StopSegment and !ReleaseAccess methods of the skeleton. You can do this by running the command (again, use '''--cert''' and the experiment name returned by {{{fedd_create.py}}} and {{{fedd_multistatus.py}}} above): {{{ $ ./fedd_terminate.py --cert=./guest.pem --url=http://users.isi.deterlab.net:13232 --experiment_name=faber-test }}} This will not produce any output (on success) though the log on your skeleton controller should now include lines like: {{{ 28 Jun 10 09:39:42 fedd.access Terminate request for 32b21906165aa76bbc629511b81b7504d01a0f20 28 Jun 10 09:39:42 fedd.access Wrote state to /users/faber/fedd-config/skel/skel_access.state 28 Jun 10 09:39:42 fedd Successful SOAP request code 200 28 Jun 10 09:39:42 fedd.access [ReleaseAccess] deallocation requested for 32b21906165aa76bbc629511b81b7504d01a0f20 28 Jun 10 09:39:42 fedd.access [ReleaseAccess] Found allocation for 32b21906165aa76bbc629511b81b7504d01a0f20 28 Jun 10 09:39:42 fedd.access Wrote state to /users/faber/fedd-config/skel/skel_access.state 28 Jun 10 09:39:42 fedd.access [ReleaseAccess] Removing /users/faber/fedd-config/skel/certs/32b21906165aa76bbc629511b81b7504d01a0f20.pem 28 Jun 10 09:39:42 fedd Successful SOAP request code 200 }}} That shows how to run the skeleton and exercise its interfaces with well formed commands from the experiment controller. You can now begin customizing your plug-in.