-# $Id$
+# Thierry Parmentelat <thierry.parmentelat@inria.fr>
+# Copyright (C) 2010 INRIA
+#
import os, os.path
import datetime
import time
actual.__doc__=method.__doc__
return actual
-def slice_mapper_options (method):
+def slice_mapper (method):
def actual(self):
overall=True
slice_method = TestSlice.__dict__[method.__name__]
actual.__doc__=method.__doc__
return actual
-def slice_mapper_options_sfa (method):
+def slice_sfa_mapper (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']:
+ for slice_spec in self.plc_spec['sfa']['sfa_slice_specs']:
site_spec = self.locate_site (slice_spec['sitename'])
test_site = TestSite(self,site_spec)
- test_slice=TestSliceSfa(test_plc,test_site,slice_spec)
+ test_slice=TestSliceSfa(self,test_site,slice_spec)
if not slice_method(test_slice,self.options): overall=False
return overall
# restore the doc text
'delete_vs','create_vs','install', 'configure', 'start', SEP,
'fetch_keys', 'store_keys', 'clear_known_hosts', SEP,
'initscripts', 'sites', 'nodes', 'slices', 'nodegroups', 'leases', SEP,
- 'reinstall_node', 'init_node','bootcd', 'configure_qemu', 'export_qemu',
- 'kill_all_qemus', 'start_node', SEP,
+ 'reinstall_node', 'init_node','bootcd', 'configure_qemu', 'export_qemu', 'kill_all_qemus', 'start_node', SEP,
+ 'install_sfa', 'configure_sfa', 'cross_configure_sfa', 'import_sfa', 'start_sfa', SEPSFA,
+ 'configure_sfi@1', 'add_user_sfa@1', 'add_sfa@1', 'create_sfa@1', SEPSFA,
+ 'update_sfa_user@1', 'update_sfa@1', 'view_sfa@1', SEPSFA,
# better use of time: do this now that the nodes are taking off
'plcsh_stress_test', SEP,
- 'install_sfa', 'configure_sfa', 'import_sfa', 'start_sfa', SEPSFA,
- 'setup_sfa', 'add_sfa', 'update_sfa', 'view_sfa', SEPSFA,
'nodes_ssh_debug', 'nodes_ssh_boot', 'check_slice', 'check_initscripts', SEPSFA,
- 'check_slice_sfa', 'delete_sfa', 'stop_sfa', SEPSFA,
+ 'check_slice_sfa@1', 'delete_sfa_user@1', 'delete_slice_sfa@1', SEPSFA,
'check_tcp', 'check_hooks', SEP,
'force_gather_logs', 'force_resources_post', SEP,
]
'clean_leases', 'list_leases', SEP,
'populate' , SEP,
'list_all_qemus', 'list_qemus', 'kill_qemus', SEP,
+ 'plcclean_sfa', 'dbclean_sfa', 'stop_sfa','uninstall_sfa', 'clean_sfi', SEP,
'db_dump' , 'db_restore', SEP,
'standby_1 through 20',SEP,
]
# this is originally for centos5 as recent SFAs won't build on this platformb
@staticmethod
def check_whether_build_has_sfa (rpms_url):
- retcod=os.system ("curl --silent %s/ | grep -q sfa"%rpms_url)
+ # warning, we're now building 'sface' so let's be a bit more picky
+ retcod=os.system ("curl --silent %s/ | grep -q sfa-"%rpms_url)
# full builds are expected to return with 0 here
if retcod!=0:
# move all steps containing 'sfa' from default_steps to other_steps
if self.options.fcdistro == "centos5":
self.run_in_guest("rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm")
+ # compute nodefamily
if self.options.personality == "linux32":
arch = "i386"
elif self.options.personality == "linux64":
arch = "x86_64"
else:
raise Exception, "Unsupported personality %r"%self.options.personality
-
nodefamily="%s-%s-%s"%(self.options.pldistro,self.options.fcdistro,arch)
- # try to install slicerepo - not fatal yet
- self.run_in_guest("yum -y install slicerepo-%s"%nodefamily)
-
- return \
- self.run_in_guest("yum -y install myplc")==0 and \
- self.run_in_guest("yum -y install noderepo-%s"%nodefamily)==0 and \
- self.run_in_guest("yum -y install bootstrapfs-%s-plain"%nodefamily)==0
+ pkgs_list=[]
+ pkgs_list.append ("slicerepo-%s"%nodefamily)
+ pkgs_list.append ("myplc")
+ pkgs_list.append ("noderepo-%s"%nodefamily)
+ pkgs_list.append ("bootstrapfs-%s-plain"%nodefamily)
+ pkgs_string=" ".join(pkgs_list)
+ self.run_in_guest("yum -y install %s"%pkgs_string)
+ return self.run_in_guest("rpm -q %s"%pkgs_string)==0
###
def configure(self):
tmpname='%s.plc-config-tty'%(self.name())
fileconf=open(tmpname,'w')
for var in [ 'PLC_NAME',
- 'PLC_ROOT_PASSWORD',
'PLC_ROOT_USER',
+ 'PLC_ROOT_PASSWORD',
+ 'PLC_SLICE_PREFIX',
'PLC_MAIL_ENABLED',
'PLC_MAIL_SUPPORT_ADDRESS',
'PLC_DB_HOST',
YEAR = 365*24*3600
@staticmethod
- def translate_timestamp (start,timestamp):
- if timestamp < TestPlc.YEAR: return start+timestamp
+ def translate_timestamp (start,grain,timestamp):
+ if timestamp < TestPlc.YEAR: return start+timestamp*grain
else: return timestamp
@staticmethod
"create leases (on reservable nodes only, use e.g. run -c default -c resa)"
now=int(time.time())
grain=self.apiserver.GetLeaseGranularity(self.auth_root())
- round_time=(now/grain)*grain
- start=round_time+grain
+ print 'API answered grain=',grain
+ start=(now/grain)*grain
+ start += grain
# find out all nodes that are reservable
nodes=self.all_reservable_nodenames()
if not nodes:
for lease_spec in self.plc_spec['leases']:
# skip the ones that come with a null slice id
if not lease_spec['slice']: continue
- lease_spec['t_from']=TestPlc.translate_timestamp(start,lease_spec['t_from'])
- lease_spec['t_until']=TestPlc.translate_timestamp(start,lease_spec['t_until'])
+ lease_spec['t_from']=TestPlc.translate_timestamp(start,grain,lease_spec['t_from'])
+ lease_spec['t_until']=TestPlc.translate_timestamp(start,grain,lease_spec['t_until'])
lease_addition=self.apiserver.AddLeases(self.auth_root(),nodes,
lease_spec['slice'],lease_spec['t_from'],lease_spec['t_until'])
if lease_addition['errors']:
def nodes_ssh_debug(self):
"Tries to ssh into nodes in debug mode with the debug ssh key"
- return self.check_nodes_ssh(debug=True,timeout_minutes=30,silent_minutes=5)
+ return self.check_nodes_ssh(debug=True,timeout_minutes=10,silent_minutes=5)
def nodes_ssh_boot(self):
"Tries to ssh into nodes in production mode with the root ssh key"
- return self.check_nodes_ssh(debug=False,timeout_minutes=30,silent_minutes=15)
+ return self.check_nodes_ssh(debug=False,timeout_minutes=40,silent_minutes=15)
@node_mapper
def init_node (self):
utils.header('Created Slice %s'%slice['slice_fields']['name'])
return True
- @slice_mapper_options
+ @slice_mapper
def check_slice(self):
"tries to ssh-enter the slice with the user key, to ensure slice creation"
pass
### 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 sfa-client sfa-plc sfa-sfatables")==0
+ # ignore yum retcod
+ self.run_in_guest("yum -y install sfa sfa-client sfa-plc sfa-sfatables")
+ return self.run_in_guest("rpm -q sfa sfa-client sfa-plc sfa-sfatables")==0
+
+ def dbclean_sfa(self):
+ "thoroughly wipes off the SFA database"
+ self.run_in_guest("sfa-nuke-plc.py")==0
+ return True
+
+ def plcclean_sfa(self):
+ "cleans the PLC entries that were created as a side effect of running the script"
+ # ignore result
+ sfa_spec=self.plc_spec['sfa']
+
+ slicename='%s_%s'%(sfa_spec['login_base'],sfa_spec['slicename'])
+ try: self.apiserver.DeleteSlice(self.auth_root(),slicename)
+ except: print "Slice %s already absent from PLC db"%slicename
+
+ username="%s@%s"%(sfa_spec['regularuser'],sfa_spec['domain'])
+ try: self.apiserver.DeletePerson(self.auth_root(),username)
+ except: print "User %s already absent from PLC db"%username
+
+ print "REMEMBER TO RUN import_sfa AGAIN"
+ return True
+
+ def uninstall_sfa(self):
+ "uses rpm to uninstall sfa - ignore result"
+ self.run_in_guest("rpm -e sfa sfa-sfatables sfa-client sfa-plc")
+ self.run_in_guest("rm -rf /var/lib/sfa")
+ self.run_in_guest("rm -rf /etc/sfa")
+ self.run_in_guest("rm -rf /var/log/sfa_access.log /var/log/sfa_import_plc.log /var/log/sfa.daemon")
+ # xxx tmp
+ self.run_in_guest("rpm -e --noscripts sfa-plc")
+ return True
+
+ ###
+ def confdir(self):
+ dirname="conf.%s"%self.plc_spec['name']
+ if not os.path.isdir(dirname):
+ utils.system("mkdir -p %s"%dirname)
+ if not os.path.isdir(dirname):
+ raise "Cannot create config dir for plc %s"%self.name()
+ return dirname
+
+ def conffile(self,filename):
+ return "%s/%s"%(self.confdir(),filename)
+ def confsubdir(self,dirname,clean):
+ subdirname="%s/%s"%(self.confdir(),dirname)
+ if clean:
+ utils.system("rm -rf %s"%subdirname)
+ if not os.path.isdir(subdirname):
+ utils.system("mkdir -p %s"%subdirname)
+ if not os.path.isdir(subdirname):
+ raise "Cannot create config subdir %s for plc %s"%(dirname,self.name())
+ return subdirname
+
+ def conffile_clean (self,filename):
+ filename=self.conffile(filename)
+ return utils.system("rm -rf %s"%filename)==0
+
###
def configure_sfa(self):
"run sfa-config-tty"
- tmpname='%s.sfa-config-tty'%(self.name())
+ tmpname=self.conffile("sfa-config-tty")
fileconf=open(tmpname,'w')
for var in [ 'SFA_REGISTRY_ROOT_AUTH',
- 'SFA_REGISTRY_LEVEL1_AUTH',
+ 'SFA_INTERFACE_HRN',
+# 'SFA_REGISTRY_LEVEL1_AUTH',
'SFA_REGISTRY_HOST',
'SFA_AGGREGATE_HOST',
'SFA_SM_HOST',
'SFA_PLC_DB_HOST',
'SFA_PLC_DB_USER',
'SFA_PLC_DB_PASSWORD',
- 'SFA_PLC_URL']:
+ 'SFA_PLC_URL',
+ ]:
fileconf.write ('e %s\n%s\n'%(var,self.plc_spec['sfa'][var]))
+ # the way plc_config handles booleans just sucks..
+ for var in ['SFA_API_DEBUG']:
+ val='false'
+ if self.plc_spec['sfa'][var]: val='true'
+ fileconf.write ('e %s\n%s\n'%(var,val))
fileconf.write('w\n')
fileconf.write('R\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 aggregate_xml_line(self):
+ return '<aggregate addr="%s" hrn="%s" port="12346"/>' % \
+ (self.vserverip,self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'])
+
+ def registry_xml_line(self):
+ return '<registry addr="%s" hrn="%s" port="12345"/>' % \
+ (self.vserverip,self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'])
+
+
+ # a cross step that takes all other plcs in argument
+ def cross_configure_sfa(self, other_plcs):
+ # of course with a single plc, other_plcs is an empty list
+ if not other_plcs:
+ return True
+ agg_fname=self.conffile("agg.xml")
+ file(agg_fname,"w").write("<aggregates>%s</aggregates>\n" % \
+ " ".join([ plc.aggregate_xml_line() for plc in other_plcs ]))
+ utils.header ("(Over)wrote %s"%agg_fname)
+ reg_fname=self.conffile("reg.xml")
+ file(reg_fname,"w").write("<registries>%s</registries>\n" % \
+ " ".join([ plc.registry_xml_line() for plc in other_plcs ]))
+ utils.header ("(Over)wrote %s"%reg_fname)
+ return self.test_ssh.copy_abs(agg_fname,'/vservers/%s/etc/sfa/aggregates.xml'%self.vservername)==0 \
+ and self.test_ssh.copy_abs(reg_fname,'/vservers/%s/etc/sfa/registries.xml'%self.vservername)==0
+
def import_sfa(self):
"sfa-import-plc"
auth=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']
"service sfa start"
return self.run_in_guest('service sfa start')==0
- def setup_sfa(self):
+ def configure_sfi(self):
+ sfa_spec=self.plc_spec['sfa']
"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'
+ dir_name=self.confsubdir("dot-sfi",clean=True)
+ file_name=dir_name + os.sep + sfa_spec['piuser'] + '.pkey'
fileconf=open(file_name,'w')
fileconf.write (self.plc_spec['keys'][0]['private'])
fileconf.close()
+ utils.header ("(Over)wrote %s"%file_name)
file_name=dir_name + os.sep + 'sfi_config'
fileconf=open(file_name,'w')
- SFI_AUTH=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']+".main"
+ SFI_AUTH="%s.%s"%(sfa_spec['SFA_REGISTRY_ROOT_AUTH'],sfa_spec['login_base'])
fileconf.write ("SFI_AUTH='%s'"%SFI_AUTH)
fileconf.write('\n')
- SFI_USER=SFI_AUTH+'.fake-pi1'
+ SFI_USER=SFI_AUTH + '.' + sfa_spec['piuser']
fileconf.write ("SFI_USER='%s'"%SFI_USER)
fileconf.write('\n')
- SFI_REGISTRY='http://' + self.plc_spec['sfa']['SFA_PLC_DB_HOST'] + ':12345/'
+ SFI_REGISTRY='http://' + sfa_spec['SFA_PLC_DB_HOST'] + ':12345/'
fileconf.write ("SFI_REGISTRY='%s'"%SFI_REGISTRY)
fileconf.write('\n')
- SFI_SM='http://' + self.plc_spec['sfa']['SFA_PLC_DB_HOST'] + ':12347/'
+ SFI_SM='http://' + sfa_spec['SFA_PLC_DB_HOST'] + ':12347/'
fileconf.write ("SFI_SM='%s'"%SFI_SM)
fileconf.write('\n')
fileconf.close()
+ utils.header ("(Over)wrote %s"%file_name)
file_name=dir_name + os.sep + 'person.xml'
fileconf=open(file_name,'w')
- for record in self.plc_spec['sfa']['sfa_person_xml']:
+ for record in sfa_spec['sfa_person_xml']:
person_record=record
fileconf.write(person_record)
fileconf.write('\n')
fileconf.close()
+ utils.header ("(Over)wrote %s"%file_name)
file_name=dir_name + os.sep + 'slice.xml'
fileconf=open(file_name,'w')
- for record in self.plc_spec['sfa']['sfa_slice_xml']:
+ for record in sfa_spec['sfa_slice_xml']:
slice_record=record
- #slice_record=self.plc_spec['sfa']['sfa_slice_xml']
+ #slice_record=sfa_spec['sfa_slice_xml']
fileconf.write(slice_record)
fileconf.write('\n')
+ utils.header ("(Over)wrote %s"%file_name)
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():
+ for (key, value) in sfa_spec['sfa_slice_rspec'].items():
slice_rspec +=value
fileconf.write(slice_rspec)
fileconf.write('\n')
fileconf.close()
- location = "root/"
+ utils.header ("(Over)wrote %s"%file_name)
+
+ # push to the remote root's .sfi
+ location = "root/.sfi"
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 clean_sfi (self):
+ self.run_in_guest("rm -rf /root/.sfi")
+ return True
+
+ def add_user_sfa(self):
+ return TestUserSfa(self).add_user()
+
+ @slice_sfa_mapper
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()
+ "run sfi.py add (on Registry)"
+ pass
- 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
+ @slice_sfa_mapper
+ def create_sfa(self):
+ "run sfi.py create (on SM) for 1st-time creation"
+ pass
+
+ def update_sfa_user(self):
+ return TestUserSfa(self).update_user()
+ @slice_sfa_mapper
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
+ "run sfi.py create (on SM) on existing object"
+ pass
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']
+ sfa_spec=self.plc_spec['sfa']
+ auth=sfa_spec['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/ list %s.%s"%(auth,sfa_spec['login_base']))==0 and \
+ self.run_in_guest("sfi.py -d /root/.sfi/ show %s.%s"%(auth,sfa_spec['login_base']))==0 and \
self.run_in_guest("sfi.py -d /root/.sfi/ slices")==0 and \
self.run_in_guest("sfi.py -d /root/.sfi/ resources -o resources")==0
- @slice_mapper_options_sfa
+ @slice_sfa_mapper
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()
+ def delete_sfa_user(self):
+ "run sfi.py delete (on SM) for user"
+ test_user_sfa=TestUserSfa(self)
+ return test_user_sfa.delete_user()
- return success1 and success2
+ @slice_sfa_mapper
+ def delete_sfa_slices(self):
+ "run sfi.py delete (on SM), sfi.py remove (on Registry) to clean slices"
+ pass
def stop_sfa(self):
"service sfa stop"
- return self.run_in_guest('service sfa stop')==0
+ self.run_in_guest('service sfa stop')==0
+ return True
def populate (self):
"creates random entries in the PLCAPI"