</category>
<!-- ======================================== -->
+ <category id="sfa_dummy">
+ <name></name>
+ <description>The settings for using SFA with a demmy testbed.</description>
+
+ <variablelist>
+ <variable id="url" type="string">
+ <name>XMLRPC URL</name>
+ <value>http://127.0.0.1:8080</value>
+ <description>URL for the Dummy Testbed xmlrpc API</description>
+ </variable>
+ </variablelist>
+ </category>
+
+ <!-- ======================================== -->
</variables>
'pl':'sfa_plc',
'openstack':'sfa_nova',
'fd':'sfa_federica',
- 'nitos':'sfa_nitos'
+ 'nitos':'sfa_nitos',
+ 'dummy':'sfa_dummy',
}
configuration={ \
'name':'sfa',
'sfa/client',
'sfa/planetlab',
'sfa/nitos',
+ 'sfa/dummy',
'sfa/openstack',
'sfa/federica',
'sfatables',
Group: Applications/System
Requires: sfa
+%package dummy
+Summary: the SFA layer around a Dummy Testbed
+Group: Applications/System
+Requires: sfa
+
%package sfatables
Summary: sfatables policy tool for SFA
Group: Applications/System
%files nitos
%{python_sitelib}/sfa/nitos
+%files dummy
+%{python_sitelib}/sfa/dummy
+
%files sfatables
/etc/sfatables/*
%{_bindir}/sfatables
--- /dev/null
+###################################### DUMMY TESTBED DRIVER FOR SFA ############################################
+
+In order to make easy the adoption of SFA by the testbed owners, we decided to implement this DUMMY TESTBED DRIVER FOR SFA which represent one flavour of SFA (dummy).
+
+Testbed owners deciding to wrap their testbed with SFA, can follow this small step-by-step guide to know how SFA works, how it interact with the testbed and what are the needed pieces to glue SFA and the testbed.
+
+
+STEP-BY-STEP GUIDE :
+
+1. Install SFA (http://svn.planet-lab.org/wiki/SFATutorialInstall#InstallingSFA)
+(On RPM based OS, the SFA sources go here : /usr/lib/python2.7/site-packages/sfa )
+
+2. Launch the Dummy testbed XML-RPC API:
+
+# python /usr/lib/python2.7/site-packages/sfa/dummy/dummy_testbed_api.py
+
+3. Configure SFA to the "dummy" flavour as follow :
+
+# sfa-config-tty
+Enter command (u for usual changes, w to save, ? for help) u
+== sfa_generic_flavour : [dummy] dummy ("dummy" flavour)
+== sfa_interface_hrn : [pla] pla (Choose your Authority name)
+== sfa_registry_root_auth : [pla] pla (Choose your Authority name)
+== sfa_registry_host : [localhost] localhost
+== sfa_aggregate_host : [localhost] localhost
+== sfa_sm_host : [localhost] localhost
+== sfa_db_host : [localhost] localhost
+== sfa_dummy_url : [http://127.0.0.1:8080]
+Enter command (u for usual changes, w to save, ? for help) w
+Wrote /etc/sfa/configs/site_config
+Merged
+ /etc/sfa/default_config.xml
+and /etc/sfa/configs/site_config
+into /etc/sfa/sfa_config
+You might want to type 'r' (restart sfa), 'R' (reload sfa) or 'q' (quit)
+Enter command (u for usual changes, w to save, ? for help) r
+==================== Stopping sfa
+Shutting down SFA [ OK ]
+==================== Starting sfa
+SFA: Checking for PostgreSQL server [ OK ]
+SFA: installing peer certs [ OK ]
+SFA: Registry [ OK ]
+SFA: Aggregate [ OK ]
+SFA: SliceMgr [ OK ]
+Enter command (u for usual changes, w to save, ? for help) q
+
+4. Add your user to the dummy testbed and attach it to a slice:
+
+Edit /usr/lib/python2.7/site-packages/sfa/dummy/dummy_testbed_api_client.py with your user info and run:
+
+# python /usr/lib/python2.7/site-packages/sfa/dummy/dummy_testbed_api_client.py
+
+5. Import Dummy testbed data to SFA (users, slices, nodes):
+
+# sfaadmin.py reg import_registry
+
+6. Configure you SFI client (http://svn.planet-lab.org/wiki/SFATutorialConfigureSFA#ConfigureSFAClientSFI)
+
+7. Make a test:
+update the following command with your already configured Authority name.
+
+# sfi.py list pla.dummy
+
+8. Now continue testing SFA, have a look at the dummy driver code and write your testbed driver for SFA... Enjoy.
+
+
# RPC functions definition
#GET
def GetTestbedInfo():
- return {'name': 'Dummy', 'longitude': 123456, 'latitude': 654321, 'domain':'dummy-testbed.org'}
+ return {'name': 'dummy', 'longitude': 123456, 'latitude': 654321, 'domain':'dummy-testbed.org'}
def GetNodes(filter={}):
global DB
--- /dev/null
+import xmlrpclib
+from datetime import datetime
+import time
+
+dummy_url = "http://localhost:8080"
+dummy_api = xmlrpclib.ServerProxy(dummy_url)
+
+# Edit the parameters with your user info:
+my_user_id = dummy_api.AddUser({'email': 'john.doe@test.net', 'user_name': 'john.doe', 'keys': ['copy here your ssh-rsa public key']})
+# Your user will be attached with the slice named : slice2 :
+dummy_api.AddUserToSlice({'slice_id': 2, 'user_id': my_user_id})
+
+
+print dummy_api.GetUsers()[-1]
+print dummy_api.GetSlices()[-1]
rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site['name'], node['hostname'])
rspec_node['component_name'] = node['hostname']
rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
- rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.driver.hrn, site['name']), 'authority+sa')
+ rspec_node['authority_id'] = hrn_to_urn(DummyXrn.site_hrn(self.driver.hrn, site['name']), 'authority+sa')
rspec_node['exclusive'] = 'false'
rspec_node['hardware_types'] = [HardwareType({'name': 'plab-pc'}),
HardwareType({'name': 'pc'})]
nodes = self.get_nodes(slice_xrn, slice, slivers, options)
rspec.version.add_nodes(nodes)
- rspec.version.add_links(links)
# add sliver defaults
default_sliver = slivers.get(None, [])
if default_sliver:
type=sfa_record['type']
pointer=sfa_record['pointer']
if type == 'user':
- self.shell.DeleteUser{'user_id': pointer})
+ self.shell.DeleteUser({'user_id': pointer})
elif type == 'slice':
- self.shell.DeleteSlice('slice_id': pointer)
+ self.shell.DeleteSlice({'slice_id': pointer})
elif type == 'node':
- self.shell.DeleteNode('node_id': pointer)
+ self.shell.DeleteNode({'node_id': pointer})
return True
slice = slices[0]
try:
- self.shell.DeleteSliceFromNodes({'slice_id': slice['slice_id'], 'node_ids': slice['node_ids'])
+ self.shell.DeleteSliceFromNodes({'slice_id': slice['slice_id'], 'node_ids': slice['node_ids']})
return True
except:
return False
'GetTestbedInfo', 'GetNodes', 'GetSlices', 'GetUsers',
'DeleteNode', 'DeleteSlice', 'DeleteUser', 'DeleteKey', 'DeleteUserFromSlice',
'DeleteSliceFromNodes',
- 'UpdateNode', 'UpdateSlice', 'UpdateUser'
+ 'UpdateNode', 'UpdateSlice', 'UpdateUser',
]
def __getattr__(self, name):
def func(*args, **kwds):
- if not name in direct_calls:
+ if not name in DummyShell.direct_calls:
raise Exception, "Illegal method call %s for DUMMY driver"%(name)
- result=getattr(self.proxy, actual_name)(*args, **kwds)
+ result=getattr(self.proxy, name)(*args, **kwds)
logger.debug('DummyShell %s returned ... '%(name))
return result
return func
# the importer class
def importer_class (self):
import sfa.importer.dummyimporter
- return sfa.importer.dummyimporter.PlImporter
+ return sfa.importer.dummyimporter.DummyImporter
# use the standard api class
def api_class (self):
from sfa.storage.alchemy import dbsession
from sfa.storage.model import RegRecord, RegAuthority, RegSlice, RegNode, RegUser, RegKey
-from sfa.dummy.dummyshell import PlShell
+from sfa.dummy.dummyshell import DummyShell
from sfa.dummy.dummyxrn import hostname_to_hrn, slicename_to_hrn, email_to_hrn, hrn_to_dummy_slicename
def _get_site_hrn(interface_hrn, site):
# Get all dummy TB public keys
keys = []
for user in users:
- keys.extend(user['keys'])
+ if 'keys' in user:
+ keys.extend(user['keys'])
# create a dict user_id -> [ keys ]
keys_by_person_id = {}
for user in users:
- keys_by_person_id[user['user_id']] = user['keys']
+ if 'keys' in user:
+ keys_by_person_id[user['user_id']] = user['keys']
# Get all dummy TB nodes
nodes = shell.GetNodes()
# create hash by node_id
for user in users:
user_hrn = email_to_hrn(site_hrn, user['email'])
# xxx suspicious again
- if len(person_hrn) > 64: person_hrn = person_hrn[:64]
+ if len(user_hrn) > 64: user_hrn = user_hrn[:64]
user_urn = hrn_to_urn(user_hrn, 'user')
user_record = self.locate_by_type_hrn ( 'user', user_hrn)
else:
user_record.reg_keys=[ RegKey (pubkey)]
self.logger.info("DummyImporter: updated person: %s" % user_record)
- user_record.email = person['email']
+ user_record.email = user['email']
dbsession.commit()
user_record.stale=False
except:
# import slices
for slice in slices:
- slice_hrn = slicename_to_hrn(interface_hrn, slice['slice_ame'])
+ slice_hrn = slicename_to_hrn(site_hrn, slice['slice_name'])
slice_record = self.locate_by_type_hrn ('slice', slice_hrn)
if not slice_record:
try: