7 from types import StringTypes
10 from TestSite import TestSite
11 from TestNode import TestNode
12 from TestUser import TestUser
13 from TestKey import TestKey
15 # step methods must take (self, options) and return a boolean
19 def __init__ (self,plc_spec):
20 self.plc_spec=plc_spec
21 self.path=os.path.dirname(sys.argv[0])
23 self.vserverip=plc_spec['vserverip']
24 self.vservername=plc_spec['vservername']
25 self.url="https://%s:443/PLCAPI/"%plc_spec['vserverip']
29 self.url="https://%s:443/PLCAPI/"%plc_spec['hostname']
30 utils.header('Using API url %s'%self.url)
31 self.server=xmlrpclib.Server(self.url,allow_none=True)
34 name=self.plc_spec['name']
36 return name+"[%s]"%self.vservername
38 return name+"[chroot]"
40 # define the API methods on this object through xmlrpc
41 # would help, but not strictly necessary
45 # build the full command so command gets run in the chroot/vserver
46 def run_command(self,command):
48 return "vserver %s exec %s"%(self.vservername,command)
50 return "chroot /plc/root %s"%command
52 def ssh_command(self,command):
53 if self.plc_spec['hostname'] == "localhost":
56 return "ssh " + self.plc_spec['hostname'] + " " + command
58 def full_command(self,command):
59 return self.ssh_command(self.run_command(command))
61 def run_in_guest (self,command):
62 return utils.system(self.full_command(command))
63 def run_in_host (self,command):
64 return utils.system(self.ssh_command(command))
67 def run_in_guest_piped (self,local,remote):
68 return utils.system(local+" | "+self.full_command(command))
71 return {'Username':self.plc_spec['PLC_ROOT_USER'],
72 'AuthMethod':'password',
73 'AuthString':self.plc_spec['PLC_ROOT_PASSWORD'],
74 'Role' : self.plc_spec['role']
76 def locate_site (self,sitename):
77 for site in self.plc_spec['sites']:
78 if site['site_fields']['name'] == sitename:
80 if site['site_fields']['login_base'] == sitename:
82 raise Exception,"Cannot locate site %s"%sitename
84 def locate_key (self,keyname):
85 for key in self.plc_spec['keys']:
86 if key['name'] == keyname:
88 raise Exception,"Cannot locate key %s"%keyname
90 def kill_all_vmwares(self):
91 utils.header('Killing any running vmware or vmplayer instance')
92 utils.system('pgrep vmware | xargs -r kill')
93 utils.system('pgrep vmplayer | xargs -r kill ')
94 utils.system('pgrep vmware | xargs -r kill -9')
95 utils.system('pgrep vmplayer | xargs -r kill -9')
97 #################### step methods
100 def uninstall_chroot(self,options):
101 self.run_in_host('service plc safestop')
102 #####detecting the last myplc version installed and remove it
103 self.run_in_host('rpm -e myplc')
104 ##### Clean up the /plc directory
105 self.run_in_host('rm -rf /plc/data')
108 def uninstall_vserver(self,options):
109 self.run_in_host("vserver --silent %s delete"%self.vservername)
112 def uninstall(self,options):
114 return self.uninstall_vserver(options)
116 return self.uninstall_chroot(options)
119 def install_chroot(self,options):
123 # xxx this would not work with hostname != localhost as mylc-init-vserver was extracted locally
124 def install_vserver(self,options):
125 # we need build dir for vtest-init-vserver
126 build_dir=self.path+"/build"
127 if not os.path.isdir(build_dir):
128 if utils.system("svn checkout %s %s"%(options.build_url,build_dir)) != 0:
129 raise Exception,"Cannot checkout build dir"
130 # the repo url is taken from myplc-url
131 # with the last two steps (i386/myplc...) removed
132 repo_url = options.myplc_url
133 repo_url = os.path.dirname(repo_url)
134 repo_url = os.path.dirname(repo_url)
135 command="%s/vtest-init-vserver.sh %s %s -- --interface eth0:%s"%\
136 (build_dir,self.vservername,repo_url,self.vserverip)
137 if utils.system(command) != 0:
138 raise Exception,"Could not create vserver for %s"%self.vservername
139 # xxx temporary - initialize /etc/sysconfig/network
140 network="NETWORKING=yes\nHOSTNAME=%s\n"%self.plc_spec['vserverhostname']
141 file("/vservers/%s/etc/sysconfig/network"%self.vservername,"w").write(network)
144 def install(self,options):
146 return self.install_vserver(options)
148 return self.install_chroot(options)
151 def install_rpm_chroot(self,options):
152 utils.header('Installing from %s'%options.myplc_url)
153 url=options.myplc_url
154 utils.system('rpm -Uvh '+url)
155 utils.system('service plc mount')
158 def install_rpm_vserver(self,options):
159 self.run_in_guest("yum -y install myplc-native")
162 def install_rpm(self,options):
164 return self.install_rpm_vserver(options)
166 return self.install_rpm_chroot(options)
169 def configure(self,options):
170 tmpname='%s/%s.plc-config-tty'%(options.path,self.name())
171 fileconf=open(tmpname,'w')
172 for var in [ 'PLC_NAME',
176 'PLC_MAIL_SUPPORT_ADDRESS',
183 fileconf.write ('e %s\n%s\n'%(var,self.plc_spec[var]))
184 fileconf.write('w\n')
185 fileconf.write('q\n')
187 utils.system('cat %s'%tmpname)
188 self.run_in_guest('plc-config-tty < %s'%tmpname)
189 utils.system('rm %s'%tmpname)
192 # the chroot install is slightly different to this respect
193 def start(self, options):
195 self.run_in_guest('service plc start')
197 self.run_in_host('service plc start')
200 def stop(self, options):
202 self.run_in_guest('service plc stop')
204 self.run_in_host('service plc stop')
207 # could use a TestKey class
208 def store_keys(self, options):
209 for key_spec in self.plc_spec['keys']:
210 TestKey(self,key_spec).store_key()
213 def clean_keys(self, options):
214 utils.system("rm -rf %s/keys/"%self.path)
216 def sites (self,options):
217 return self.do_sites(options)
219 def clean_sites (self,options):
220 return self.do_sites(options,action="delete")
222 def do_sites (self,options,action="add"):
223 for site_spec in self.plc_spec['sites']:
224 test_site = TestSite (self,site_spec)
225 if (action != "add"):
226 utils.header("Deleting site %s in %s"%(test_site.name(),self.name()))
227 test_site.delete_site()
228 # deleted with the site
229 #test_site.delete_users()
232 utils.header("Creating site %s & users in %s"%(test_site.name(),self.name()))
233 test_site.create_site()
234 test_site.create_users()
237 def nodes (self, options):
238 return self.do_nodes(options)
239 def clean_nodes (self, options):
240 return self.do_nodes(options,action="delete")
242 def do_nodes (self, options,action="add"):
243 for site_spec in self.plc_spec['sites']:
244 test_site = TestSite (self,site_spec)
246 utils.header("Deleting nodes in site %s"%test_site.name())
247 for node_spec in site_spec['nodes']:
248 test_node=TestNode(self,test_site,node_spec)
249 utils.header("Deleting %s"%test_node.name())
250 test_node.delete_node()
252 utils.header("Creating nodes for site %s in %s"%(test_site.name(),self.name()))
253 for node_spec in site_spec['nodes']:
254 utils.show_spec('Creating node %s'%node_spec,node_spec)
255 test_node = TestNode (self,test_site,node_spec)
256 test_node.create_node ()
259 # create nodegroups if needed, and populate
260 # no need for a clean_nodegroups if we are careful enough
261 def nodegroups (self, options):
262 # 1st pass to scan contents
264 for site_spec in self.plc_spec['sites']:
265 test_site = TestSite (self,site_spec)
266 for node_spec in site_spec['nodes']:
267 test_node=TestNode (self,test_site,node_spec)
268 if node_spec.has_key('nodegroups'):
269 nodegroupnames=node_spec['nodegroups']
270 if isinstance(nodegroupnames,StringTypes):
271 nodegroupnames = [ nodegroupnames ]
272 for nodegroupname in nodegroupnames:
273 if not groups_dict.has_key(nodegroupname):
274 groups_dict[nodegroupname]=[]
275 groups_dict[nodegroupname].append(test_node.name())
276 auth=self.auth_root()
277 for (nodegroupname,group_nodes) in groups_dict.iteritems():
279 self.server.GetNodeGroups(auth,{'name':nodegroupname})[0]
281 self.server.AddNodeGroup(auth,{'name':nodegroupname})
282 for node in group_nodes:
283 self.server.AddNodeToNodeGroup(auth,node,nodegroupname)
286 def bootcd (self, options):
287 for site_spec in self.plc_spec['sites']:
288 test_site = TestSite (self,site_spec)
289 for node_spec in site_spec['nodes']:
290 test_node=TestNode (self,test_site,node_spec)
291 test_node.create_boot_cd(options.path)
294 def initscripts (self, options):
295 for initscript in self.plc_spec['initscripts']:
296 utils.show_spec('Adding Initscript in plc %s'%self.plc_spec['name'],initscript)
297 self.server.AddInitScript(self.auth_root(),initscript['initscript_fields'])
300 def slices (self, options):
301 return self.do_slices()
303 def clean_slices (self, options):
304 return self.do_slices("delete")
306 ### would need a TestSlice class
307 def do_slices (self, add_or_delete="add"):
308 for slice in self.plc_spec['slices']:
309 site_spec = self.locate_site (slice['sitename'])
310 test_site = TestSite(self,site_spec)
311 owner_spec = test_site.locate_user(slice['owner'])
312 auth = TestUser(self,test_site,owner_spec).auth()
313 slice_fields = slice['slice_fields']
314 slice_name = slice_fields['name']
315 if (add_or_delete == "delete"):
316 self.server.DeleteSlice(auth,slice_fields['name'])
317 utils.header("Deleted slice %s"%slice_fields['name'])
319 utils.show_spec("Creating slice",slice_fields)
320 self.server.AddSlice(auth,slice_fields)
321 utils.header('Created Slice %s'%slice_fields['name'])
322 for username in slice['usernames']:
323 user_spec=test_site.locate_user(username)
324 test_user=TestUser(self,test_site,user_spec)
325 self.server.AddPersonToSlice(auth, test_user.name(), slice_name)
328 for nodename in slice['nodenames']:
329 node_spec=test_site.locate_node(nodename)
330 test_node=TestNode(self,test_site,node_spec)
331 hostnames += [test_node.name()]
332 utils.header("Adding %r in %s"%(hostnames,slice_name))
333 self.server.AddSliceToNodes(auth, slice_name, hostnames)
334 if slice.has_key('initscriptname'):
335 isname=slice['initscriptname']
336 utils.header("Adding initscript %s in %s"%(isname,slice_name))
337 self.server.AddSliceAttribute(self.auth_root(), slice_name,
341 def start_nodes (self, options):
342 self.kill_all_vmwares()
343 utils.header("Starting vmware nodes")
344 for site_spec in self.plc_spec['sites']:
345 TestSite(self,site_spec).start_nodes (options)
348 def stop_nodes (self, options):
349 self.kill_all_vmwares ()
352 # returns the filename to use for sql dump/restore, using options.dbname if set
353 def dbfile (self, database, options):
354 # uses options.dbname if it is found
357 if not isinstance(name,StringTypes):
360 t=datetime.datetime.now()
363 return "/root/%s-%s.sql"%(database,name)
365 def db_dump(self, options):
367 dump=self.dbfile("planetab4",options)
368 self.run_in_guest('pg_dump -U pgsqluser planetlab4 -f '+ dump)
369 utils.header('Dumped planetlab4 database in %s'%dump)
372 def db_restore(self, options):
373 dump=self.dbfile("planetab4",options)
375 self.run_in_guest('service httpd stop')
376 # xxx - need another wrapper
377 self.run_in_guest_piped('echo drop database planetlab4','psql --user=pgsqluser template1')
378 self.run_in_guest('createdb -U postgres --encoding=UNICODE --owner=pgsqluser planetlab4')
379 self.run_in_guest('psql -U pgsqluser planetlab4 -f '+dump)
380 ##starting httpd service
381 self.run_in_guest('service httpd start')
383 utils.header('Database restored from ' + dump)