1 # Thierry Parmentelat <thierry.parmentelat@inria.fr>
2 # Copyright (C) 2010 INRIA
7 from datetime import datetime, timedelta
12 from TestNode import TestNode
13 from TestUser import TestUser
14 from TestBoxQemu import TestBoxQemu
15 from TestSsh import TestSsh
17 from Completer import Completer, CompleterTask
18 from TestSlice import CompleterTaskSliceSsh
22 def __init__ (self, test_auth_sfa, slice_spec):
23 self.test_auth_sfa=test_auth_sfa
24 self.slice_spec=slice_spec
26 self.test_plc=self.test_auth_sfa.test_plc
29 return self.test_auth_sfa.obj_hrn(self.slice_spec['name'])
31 return self.test_auth_sfa.sfi_path()
33 # send back up to the TestAuthSfa
34 def sfi_path (self): return self.test_auth_sfa.sfi_path()
35 def rspec_style (self): return self.test_auth_sfa.rspec_style()
36 def sfi_pi(self,*args,**kwds): return self.test_auth_sfa.sfi_pi(*args, **kwds)
37 def sfi_user(self,*args,**kwds): return self.test_auth_sfa.sfi_user(*args, **kwds)
39 def discover_option(self):
40 if self.rspec_style()=='pg': return "-r GENI"
43 # those are step names exposed as methods of TestPlc, hence the _sfa
45 # needs to be run as pi
46 def sfa_register_slice(self,options):
47 "run sfi register (on Registry)"
48 sfi_command="register"
49 sfi_command += " --type slice"
50 sfi_command += " --xrn %s"%self.hrn()
51 for opt in self.slice_spec['register_options']:
52 sfi_command += " %s"%(opt)
53 return self.test_plc.run_in_guest(self.sfi_pi(sfi_command))==0
55 def sfa_renew_slice(self, options):
56 "run sfi renew (on Aggregates)"
57 # too_late = (datetime.now() + timedelta(weeks=52)).strftime("%Y-%m-%d")
58 one_month = (datetime.now() + timedelta(weeks=4)).strftime("%Y-%m-%d")
61 # we expect this to fail on too long term attemps, but to succeed otherwise
63 for ( renew_until, expected) in [ (too_late, False), (one_month, True) ] :
65 sfi_command += " %s"%self.hrn()
66 sfi_command += " %s"%renew_until
67 succeeded = self.test_plc.run_in_guest(self.sfi_user(sfi_command))==0
68 if succeeded!=expected:
69 utils.header ("Expecting success=%s, got %s"%(expected,succeeded))
70 # however it turns out sfi renew always returns fine....
72 # so for helping manual checks:
73 # xxx this should use sfa_get_expires below and actually check the expected result
74 sfi_command="show -k hrn -k expires %s"%self.hrn()
75 self.test_plc.run_in_guest(self.sfi_user(sfi_command))
78 def sfa_get_expires (self, options):
79 filename="%s.json"%self.hrn()
81 inplc_filename=os.path.join(self.sfi_path(),filename)
82 # /vservers/<>/root/sfi/... - cannot use os.path
83 inbox_filename="%s%s"%(self.test_plc.vm_root_in_host(),inplc_filename)
85 sfi_command += "-R %s --rawformat json"%inplc_filename
86 sfi_command += " status"
87 sfi_command += " %s"%self.hrn()
88 # cannot find it if sfi status returns an error
89 if self.test_plc.run_in_guest (self.sfi_user(sfi_command)) !=0: return
90 if self.test_plc.test_ssh.fetch(inbox_filename,filename)!=0: return
92 with file(filename) as f: status = json.loads(f.read())
94 sliver=value['geni_slivers'][0]
95 expires=sliver['geni_expires']
96 print " * expiration for %s (first sliver) -> %s"%(self.hrn(),expires)
101 # helper - filename to store a given result
102 def _resname (self,name,ext): return "%s.%s"%(name,ext)
103 def adfile (self): return self._resname("ad","rspec")
104 def reqfile (self): return self._resname("req","rspec")
105 def nodefile (self): return self._resname("nodes","txt")
108 def sfa_discover(self,options):
109 "discover resources into resouces_in.rspec"
110 return self.test_plc.run_in_guest(self.sfi_user(\
111 "resources %s -o %s/%s"% (self.discover_option(),self.sfi_path(),self.adfile())))==0
113 def sfa_rspec(self,options):
114 "invoke sfiListNodes and sfiAddSlivers to prepare a rspec"
116 "sfiListNodes.py -i %s/%s -o %s/%s"%(self.sfi_path(),self.adfile(),self.sfi_path(),self.nodefile()),
117 "sfiAddSliver.py -i %s/%s -n %s/%s -o %s/%s"%\
118 (self.sfi_path(),self.adfile(),self.sfi_path(),self.nodefile(),self.sfi_path(),self.reqfile()),
120 for command in commands:
121 if self.test_plc.run_in_guest(command)!=0: return False
124 def sfa_allocate(self,options):
125 "invoke run sfi allocate (on SM)"
126 command=self.sfi_user("allocate %s %s"%(self.hrn(),self.reqfile()))
127 return self.test_plc.run_in_guest(command)==0
129 def sfa_provision(self,options):
130 "invoke run sfi provision (on SM)"
131 command=self.sfi_user("provision %s"%(self.hrn()))
132 return self.test_plc.run_in_guest(command)==0
135 return "%s_%s"%(self.test_auth_sfa.login_base,self.slice_spec['name'])
137 # all local nodes in slice ?
138 def sfa_check_slice_plc (self,options):
139 "check the slices have been created at the plcs - all local nodes should be in slice"
140 slice=self.test_plc.apiserver.GetSlices(self.test_plc.auth_root(), self.plc_name())[0]
141 nodes=self.test_plc.apiserver.GetNodes(self.test_plc.auth_root(), {'peer_id':None})
144 if node['node_id'] in slice['node_ids']:
145 utils.header("local node %s found in slice %s"%(node['hostname'],slice['name']))
147 utils.header("ERROR - local node %s NOT FOUND in slice %s"%(node['hostname'],slice['name']))
151 # xxx historically this used to do the same as sfa-create-slice
152 # which was later on split into 3 distinct steps,
153 # and we can ignore the first that is about setting up the rspec
154 def sfa_update_slice(self,options):
155 "re-run sfi allocate and provision (on SM) on existing object"
156 return self.sfa_allocate(options) and self.sfa_provision(options)
159 def sfa_delete_slice(self,options):
161 self.test_plc.run_in_guest(self.sfi_pi("delete %s"%(self.hrn(),)))
162 return self.test_plc.run_in_guest(self.sfi_pi("remove -t slice %s"%(self.hrn(),)))==0
164 def locate_private_key(self):
165 return self.test_plc.locate_private_key_from_key_names ( [ self.slice_spec['key_name'] ] )
167 # check the resulting sliver
168 def ssh_slice_sfa(self,options,timeout_minutes=40,silent_minutes=0,period_seconds=15):
169 "tries to ssh-enter the SFA slice"
170 timeout = timedelta(minutes=timeout_minutes)
171 graceout = timedelta(minutes=silent_minutes)
172 period = timedelta(seconds=period_seconds)
174 private_key=self.locate_private_key()
176 utils.header("WARNING: Cannot find a valid key for slice %s"%self.name())
178 command="echo hostname ; hostname; echo id; id; echo uname -a ; uname -a"
181 slicename=self.plc_name()
182 dry_run = getattr(options,'dry_run',False)
183 for nodename in self.slice_spec['nodenames']:
184 (site_spec,node_spec) = self.test_plc.locate_node(nodename)
185 tasks.append( CompleterTaskSliceSsh(self.test_plc,node_spec['node_fields']['hostname'],
186 slicename,private_key,command,expected=True,dry_run=dry_run))
187 return Completer (tasks).run (timeout, graceout, period)