# do all steps on all plcs
TRACE_FORMAT="TRACE: time=%(time)s plc=%(plcname)s step=%(stepname)s status=%(status)s force=%(force)s\n"
for (stepname,method,force) in all_step_infos:
+ if stepname.endswith('sfa') and (self.options.personality != 'linux32' or self.options.pldistro != 'onelab' or self.options.fcdistro != 'f8'):
+ utils.header("SFA testing currently not enabled on this dist.")
+ continue
for (spec,obj) in all_plcs:
plcname=spec['name']
from TestBox import TestBox
from TestSsh import TestSsh
from TestApiserver import TestApiserver
+from TestSliceSfa import TestSliceSfa
+from TestUserSfa import TestUserSfa
# step methods must take (self) and return a boolean (options is a member of the class)
actual.__doc__=method.__doc__
return actual
+def slice_mapper_options_sfa (method):
+ def actual(self):
+ test_plc=self
+ overall=True
+ slice_method = TestSliceSfa.__dict__[method.__name__]
+ for slice_spec in self.plc_spec['sfa']['slices_sfa']:
+ site_spec = self.locate_site (slice_spec['sitename'])
+ test_site = TestSite(self,site_spec)
+ test_slice=TestSliceSfa(test_plc,test_site,slice_spec)
+ if not slice_method(test_slice,self.options): overall=False
+ return overall
+ # restore the doc text
+ actual.__doc__=method.__doc__
+ return actual
+
SEP='<sep>'
class TestPlc:
# better use of time: do this now that the nodes are taking off
'plcsh_stress_test', SEP,
'nodes_ssh_debug', 'nodes_ssh_boot', 'check_slice', 'check_initscripts', SEP,
+ 'install_sfa', 'configure_sfa', 'import_sfa', 'start_sfa', SEP,
+ 'setup_sfa', 'add_sfa', 'update_sfa', SEP,
+ 'view_sfa', 'check_slice_sfa', 'delete_sfa', 'stop_sfa', SEP,
'check_tcp', 'check_hooks', SEP,
'force_gather_logs', 'force_local_post',
]
'PLC_MAIL_ENABLED',
'PLC_MAIL_SUPPORT_ADDRESS',
'PLC_DB_HOST',
+ 'PLC_DB_PASSWORD',
+ # Above line was added for integrating SFA Testing
'PLC_API_HOST',
'PLC_WWW_HOST',
'PLC_BOOT_HOST',
# populate runs the same utility without slightly different options
# in particular runs with --preserve (dont cleanup) and without --check
# also it gets run twice, once with the --foreign option for creating fake foreign entries
+
+ ### install_sfa_rpm
+ def install_sfa(self):
+ "yum install sfa, sfa-plc and sfa-client"
+ if self.options.personality == "linux32":
+ arch = "i386"
+ elif self.options.personality == "linux64":
+ arch = "x86_64"
+ else:
+ raise Exception, "Unsupported personality %r"%self.options.personality
+ return \
+ self.run_in_guest("yum -y install sfa")==0 and \
+ self.run_in_guest("yum -y install sfa-client")==0 and \
+ self.run_in_guest("yum -y install sfa-plc")==0
+ ###
+ def configure_sfa(self):
+ "run sfa-config-tty"
+ tmpname='%s.sfa-config-tty'%(self.name())
+ fileconf=open(tmpname,'w')
+ fileconf.write ('u\n')
+ for var in [ 'SFA_REGISTRY_ROOT_AUTH',
+ 'SFA_REGISTRY_LEVEL1_AUTH',
+ 'SFA_PLC_USER',
+ 'SFA_PLC_PASSWORD',
+ 'SFA_PLC_DB_HOST',
+ 'SFA_PLC_DB_USER',
+ 'SFA_PLC_DB_PASSWORD']:
+ fileconf.write ('%s\n'%(self.plc_spec['sfa'][var]))
+ fileconf.write('w\n')
+ fileconf.write('q\n')
+ fileconf.close()
+ utils.system('cat %s'%tmpname)
+ self.run_in_guest_piped('cat %s'%tmpname,'sfa-config-tty')
+ utils.system('rm %s'%tmpname)
+ return True
+
+ def import_sfa(self):
+ "sfa-import-plc"
+ auth=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']
+ self.run_in_guest('sfa-import-plc.py')
+ self.run_in_guest('cp /etc/sfa/authorities/%s/%s.pkey /etc/sfa/authorities/server.key'%(auth,auth))
+ return True
+
+ def start_sfa(self):
+ "service sfa start"
+ self.run_in_guest('service sfa start')
+ return True
+
+ def setup_sfa(self):
+ "sfi client configuration"
+ dir_name=".sfi"
+ if os.path.exists(dir_name):
+ utils.system('rm -rf %s'%dir_name)
+ utils.system('mkdir %s'%dir_name)
+ file_name=dir_name + os.sep + 'fake-pi1.pkey'
+ fileconf=open(file_name,'w')
+ fileconf.write (self.plc_spec['keys'][0]['private'])
+ fileconf.close()
+
+ file_name=dir_name + os.sep + 'sfi_config'
+ fileconf=open(file_name,'w')
+ SFI_AUTH=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']+".main"
+ fileconf.write ("SFI_AUTH='%s'"%SFI_AUTH)
+ fileconf.write('\n')
+ SFI_USER=SFI_AUTH+'.fake-pi1'
+ fileconf.write ("SFI_USER='%s'"%SFI_USER)
+ fileconf.write('\n')
+ fileconf.write ("SFI_REGISTRY='http://localhost:12345/'")
+ fileconf.write('\n')
+ fileconf.write ("SFI_SM='http://localhost:12347/'")
+ fileconf.write('\n')
+ fileconf.close()
+
+ file_name=dir_name + os.sep + 'person.xml'
+ fileconf=open(file_name,'w')
+ for record in self.plc_spec['sfa']['sfa_person_xml']:
+ person_record=record
+ fileconf.write(person_record)
+ fileconf.write('\n')
+ fileconf.close()
+
+ file_name=dir_name + os.sep + 'slice.xml'
+ fileconf=open(file_name,'w')
+ for record in self.plc_spec['sfa']['sfa_slice_xml']:
+ slice_record=record
+ #slice_record=self.plc_spec['sfa']['sfa_slice_xml']
+ fileconf.write(slice_record)
+ fileconf.write('\n')
+ fileconf.close()
+
+ file_name=dir_name + os.sep + 'slice.rspec'
+ fileconf=open(file_name,'w')
+ slice_rspec=''
+ for (key, value) in self.plc_spec['sfa']['sfa_slice_rspec'].items():
+ slice_rspec +=value
+ fileconf.write(slice_rspec)
+ fileconf.write('\n')
+ fileconf.close()
+ location = "root/"
+ remote="/vservers/%s/%s"%(self.vservername,location)
+ self.test_ssh.copy_abs(dir_name, remote, recursive=True)
+
+ #utils.system('cat %s'%tmpname)
+ utils.system('rm -rf %s'%dir_name)
+ return True
+
+ def add_sfa(self):
+ "run sfi.py add (on Registry) and sfi.py create (on SM) to form new objects"
+ test_plc=self
+ test_user_sfa=TestUserSfa(test_plc,self.plc_spec['sfa'])
+ success=test_user_sfa.add_user()
+
+ for slice_spec in self.plc_spec['sfa']['slices_sfa']:
+ site_spec = self.locate_site (slice_spec['sitename'])
+ test_site = TestSite(self,site_spec)
+ test_slice_sfa=TestSliceSfa(test_plc,test_site,slice_spec)
+ success1=test_slice_sfa.add_slice()
+ success2=test_slice_sfa.create_slice()
+ return success and success1 and success2
+
+ def update_sfa(self):
+ "run sfi.py update (on Registry) and sfi.py create (on SM) on existing objects"
+ test_plc=self
+ test_user_sfa=TestUserSfa(test_plc,self.plc_spec['sfa'])
+ success1=test_user_sfa.update_user()
+
+ for slice_spec in self.plc_spec['sfa']['slices_sfa']:
+ site_spec = self.locate_site (slice_spec['sitename'])
+ test_site = TestSite(self,site_spec)
+ test_slice_sfa=TestSliceSfa(test_plc,test_site,slice_spec)
+ success2=test_slice_sfa.update_slice()
+ return success1 and success2
+
+ def view_sfa(self):
+ "run sfi.py list and sfi.py show (both on Registry) and sfi.py slices and sfi.py resources (both on SM)"
+ auth=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']
+ return \
+ self.run_in_guest("sfi.py -d /root/.sfi/ list %s.main"%auth)==0 and \
+ self.run_in_guest("sfi.py -d /root/.sfi/ show %s.main"%auth)==0 and \
+ self.run_in_guest("sfi.py -d /root/.sfi/ slices")==0 and \
+ self.run_in_guest("sfi.py -d /root/.sfi/ resources")==0
+
+ @slice_mapper_options_sfa
+ def check_slice_sfa(self):
+ "tries to ssh-enter the SFA slice"
+ pass
+
+ def delete_sfa(self):
+ "run sfi.py delete (on SM), sfi.py remove (on Registry)"
+ test_plc=self
+ test_user_sfa=TestUserSfa(test_plc,self.plc_spec['sfa'])
+ success1=test_user_sfa.delete_user()
+ for slice_spec in self.plc_spec['sfa']['slices_sfa']:
+ site_spec = self.locate_site (slice_spec['sitename'])
+ test_site = TestSite(self,site_spec)
+ test_slice_sfa=TestSliceSfa(test_plc,test_site,slice_spec)
+ success2=test_slice_sfa.delete_slice()
+
+ return success1 and success2
+
+ def stop_sfa(self):
+ "service sfa stop"
+ self.run_in_guest('service sfa stop')
+ return True
+
def populate (self):
"creates random entries in the PLCAPI"
# install the stress-test in the plc image
except Exception,e:
print 'Could not localize plcs','--',e,'--','exiting'
sys.exit(1)
+ try:
+ plcs = self.localize_rspec(plcs,options)
+ except Exception,e:
+ print 'Could not localize RSpec','--',e,'--','exiting'
+ sys.exit(1)
return plcs
def localize_qemus (self,plcs,options):
def localize_nodes (self, plcs, options):
-
+
ip_pool = TestPoolIP (self.nodes_ip_pool(),options)
network_dict = self.network_dict()
def localize_plcs (self,plcs,options):
utils.header ("Turning configuration into a vserver-based one for onelab")
-
ip_pool = TestPoolIP (self.plcs_ip_pool(),options)
plc_counter=0
def trplc_list (self,plc):
TrackerPlc(plc.options,instances=self.max_plcs()).list()
return True
+
+ def localize_rspec (self,plcs,options):
+
+ utils.header ("Localize SFA Slice RSpec")
+
+ for plc in plcs:
+ for site in plc['sites']:
+ for node in site['nodes']:
+ plc['sfa']['sfa_slice_rspec']['part4'] = node['node_fields']['hostname']
+
+ return plcs
--- /dev/null
+import utils
+import os, os.path
+import datetime
+import time
+
+from TestKey import TestKey
+from TestUser import TestUser
+from TestNode import TestNode
+from TestSsh import TestSsh
+
+class TestSliceSfa:
+
+ def __init__ (self,test_plc,test_site,slice_spec):
+ self.test_plc=test_plc
+ self.test_site=test_site
+ #self.slice_spec=plc_spec_sfa['slices_sfa'][0]
+ self.slice_spec=slice_spec
+ self.test_ssh=TestSsh(self.test_plc.test_ssh)
+
+ def name(self):
+ return self.slice_spec['slice_fields']['name']
+
+ def locate_key(self):
+ for username,keyname in self.slice_spec['usernames']:
+ key_spec=self.test_plc.locate_key(keyname)
+ test_key=TestKey(self.test_plc,key_spec)
+ publickey=test_key.publicpath()
+ privatekey=test_key.privatepath()
+ if os.path.isfile(publickey) and os.path.isfile(privatekey):
+ found=True
+ return (found,privatekey)
+
+ def add_slice(self):
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ add slice.xml")==0
+
+ def create_slice(self):
+ auth=self.test_plc.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ create %s.main.sfaslicea1 slice.rspec"%auth)==0
+
+ def update_slice(self):
+ auth=self.test_plc.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ create %s.main.sfaslicea1 slice.rspec"%auth)==0
+
+ def delete_slice(self):
+ auth=self.test_plc.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ delete %s.main.sfaslicea1"%auth)
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ remove -t slice %s.main.sfaslicea1"%auth)==0
+
+ def check_slice_sfa(self,options,timeout_minutes=40,silent_minutes=4,period=15):
+ timeout = datetime.datetime.now()+datetime.timedelta(minutes=timeout_minutes)
+ graceout = datetime.datetime.now()+datetime.timedelta(minutes=silent_minutes)
+ # locate a key
+ (found,remote_privatekey)=self.locate_key()
+ if not found :
+ utils.header("WARNING: Cannot find a valid key for slice %s"%self.name())
+ return False
+
+ # convert nodenames to real hostnames
+ slice_spec = self.slice_spec
+ restarted=[]
+ tocheck=[]
+ for nodename in slice_spec['nodenames']:
+ (site_spec,node_spec) = self.test_plc.locate_node(nodename)
+ tocheck.append(node_spec['node_fields']['hostname'])
+
+ utils.header("checking ssh access into slice %s on nodes %r"%(self.name(),tocheck))
+ utils.header("max timeout is %d minutes, silent for %d minutes (period is %s)"%\
+ (timeout_minutes,silent_minutes,period))
+ while tocheck:
+ for hostname in tocheck:
+ (site_spec,node_spec) = self.test_plc.locate_hostname(hostname)
+ date_test_ssh = TestSsh (hostname,key=remote_privatekey,username=self.name())
+ if datetime.datetime.now() >= graceout:
+ utils.header('Trying to enter into slice %s@%s'%(self.name(),hostname))
+ # this can be ran locally as we have the key
+ date = date_test_ssh.run("echo hostname ; hostname; echo id; id; echo uname -a ; uname -a")==0
+ if date:
+ utils.header("Successfuly entered slice %s on %s"%(self.name(),hostname))
+ tocheck.remove(hostname)
+ else:
+ # real nodes will have been checked once in case they're up - skip if not
+ if TestNode.is_real_model(node_spec['node_fields']['model']):
+ utils.header("WARNING : Checking slice %s on real node %s skipped"%(self.name(),hostname))
+ tocheck.remove(hostname)
+ # nm restart after first failure, if requested
+ if options.forcenm and hostname not in restarted:
+ utils.header ("forcenm option : restarting nm on %s"%hostname)
+ restart_test_ssh=TestSsh(hostname,key="/etc/planetlab/root_ssh_key.rsa")
+ access=self.test_plc.run_in_guest(restart_test_ssh.actual_command('service nm restart'))
+ if (access==0):
+ utils.header('nm restarted on %s'%hostname)
+ else:
+ utils.header('Failed to restart nm on %s'%(hostname))
+ restarted.append(hostname)
+ if not tocheck:
+ # we're done
+ return True
+ if datetime.datetime.now() > timeout:
+ for hostname in tocheck:
+ utils.header("FAILURE to ssh into %s@%s"%(self.name(),hostname))
+ return False
+ # wait for the period
+ time.sleep (period)
+ # for an empty slice
+ return True
--- /dev/null
+import os, sys, time
+import xmlrpclib
+
+import utils
+
+class TestUserSfa:
+
+ def __init__ (self,test_plc,plc_spec_sfa):
+ self.test_plc=test_plc
+ self.spec_sfa=plc_spec_sfa
+
+ def name(self):
+ return self.user_spec['user_fields']['email']
+
+ def add_user (self):
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ add person.xml")==0
+
+ def update_user (self):
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ update person.xml")==0
+
+ def delete_user(self):
+ auth=self.spec_sfa['SFA_REGISTRY_ROOT_AUTH']
+ return \
+ self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ remove -t user %s.main.sfafakeuser1"%auth)==0
+
'PLC_MAIL_ENABLED':'true',
'PLC_MAIL_SUPPORT_ADDRESS' : 'thierry.parmentelat@sophia.inria.fr',
'PLC_DB_HOST' : 'deferred-myplc-hostname',
+ 'PLC_DB_PASSWORD' : 'test++',
'PLC_API_HOST' : 'deferred-myplc-hostname',
'PLC_WWW_HOST' : 'deferred-myplc-hostname',
'PLC_BOOT_HOST' : 'deferred-myplc-hostname',
'initscripts': initscripts(options,index),
'slices' : slices(options,index),
'tcp_test' : tcp_tests(options,index),
+ 'sfa' : sfa(options,index),
}
+def sfa (options,index) :
+ if index==1:
+ root_auth='plc'
+ else:
+ root_auth='ple'
+ return {
+ 'SFA_REGISTRY_ROOT_AUTH' : root_auth,
+ 'SFA_REGISTRY_LEVEL1_AUTH' : '',
+ 'SFA_PLC_USER' : 'root@test.onelab.eu',
+ 'SFA_PLC_PASSWORD' : 'test++',
+ 'SFA_PLC_DB_HOST':'localhost',
+ 'SFA_PLC_DB_USER' : 'pgsqluser',
+ 'SFA_PLC_DB_PASSWORD' : 'test++',
+ 'slices_sfa' : slices_sfa(options,index),
+ 'sfa_slice_xml' : sfa_slice_xml(options,index),
+ 'sfa_person_xml' : sfa_person_xml(options,index),
+ 'sfa_slice_rspec' : sfa_slice_rspec(options,index)
+ }
+
+def slices_sfa (options,index):
+ return [ { 'slice_fields': {'name':'main_sfaslicea1',
+ 'url':'http://foo%d@foo.com'%index,
+ 'description':'SFA-testing',
+ 'max_nodes':2,
+ },
+ 'usernames' : [ ('sfafakeuser1','key1') ],
+ 'nodenames' : all_nodenames(options,index),
+ 'sitename' : 'main',
+ }]
+
+def sfa_slice_xml(options,index):
+ if index==1:
+ hrn='plc.main.sfaslicea1'
+ researcher='plc.main.fake-pi1'
+ else:
+ hrn='ple.main.sfaslicea1'
+ researcher='ple.main.fake-pi1'
+
+ return ["""<record hrn="%s" type="slice" description="SFA-testing" url="http://anil.onelab.eu/"><researcher>%s</researcher></record>"""%(hrn, researcher)]
+
+def sfa_person_xml(options,index):
+ if index==1:
+ hrn='plc.main.sfafakeuser1'
+ else:
+ hrn='ple.main.sfafakeuser1'
+
+ return ["""<record email="sfafakeuser1@sophia.inria.fr" enabled="True" first_name="Anil" hrn="%s" last_name="Kumar" name="%s" type="user"><keys>%s</keys><role_ids>20</role_ids><role_ids>10</role_ids><site_ids>1</site_ids><roles>pi</roles><roles>admin</roles><sites>plc.main</sites></record>"""%(hrn,hrn,public_key)]
+
+def sfa_slice_rspec(options,index):
+ node_name='deferred'
+ if index==1:
+ netspec_name='\"plc\"'
+ else:
+ netspec_name='\"ple\"'
+
+ return { 'part1' : """<?xml version="1.0" ?><Rspec><networks><NetSpec name=""",
+ 'part2' : "%s"%netspec_name,
+ 'part3' : """><nodes><NodeSpec cpu_min="" cpu_pct="" cpu_share="" disk_max="" init_params="" name=\"""",
+ 'part4' : "%s"%node_name,
+ 'part5' : """\" start_time="" type=""><net_if><IfSpec init_params="" ip_spoof="" max_kbyte="" max_rate="" min_rate="" name="True" type="ipv4"/></net_if></NodeSpec></nodes></NetSpec></networks></Rspec>"""
+ }
+
def config (plc_specs,options):
result=plc_specs
for i in range (options.size):