f2a0dc4deae6b8e23bd11ae04421a2d7829f81f0
[tests.git] / system / TestPlc.py
1 # $Id$
2 import os, os.path
3 import datetime
4 import time
5 import sys
6 import xmlrpclib
7 import datetime
8 import traceback
9 from types import StringTypes
10
11 import utils
12 from TestSite import TestSite
13 from TestNode import TestNode
14 from TestUser import TestUser
15 from TestKey import TestKey
16 from TestSlice import TestSlice
17 from TestSliver import TestSliver
18 from TestBox import TestBox
19 from TestSsh import TestSsh
20
21 # step methods must take (self) and return a boolean (options is a member of the class)
22
23 def standby(minutes):
24     utils.header('Entering StandBy for %d mn'%minutes)
25     time.sleep(60*minutes)
26     return True
27
28 def standby_generic (func):
29     def actual(self):
30         minutes=int(func.__name__.split("_")[1])
31         return standby(minutes)
32     return actual
33
34 class TestPlc:
35
36     def __init__ (self,plc_spec,options):
37         self.plc_spec=plc_spec
38         self.options=options
39         self.test_ssh=TestSsh(self.plc_spec['hostname'],self.options.buildname)
40         try:
41             self.vserverip=plc_spec['vserverip']
42             self.vservername=plc_spec['vservername']
43             self.url="https://%s:443/PLCAPI/"%plc_spec['vserverip']
44             self.vserver=True
45         except:
46             self.vserver=False
47             self.url="https://%s:443/PLCAPI/"%plc_spec['hostname']
48 #        utils.header('Using API url %s'%self.url)
49         self.server=xmlrpclib.Server(self.url,allow_none=True)
50         
51     def name(self):
52         name=self.plc_spec['name']
53         if self.vserver:
54             return name+"[%s]"%self.vservername
55         else:
56             return name+"[chroot]"
57
58     def hostname(self):
59         return self.plc_spec['hostname']
60
61     def is_local (self):
62         return self.test_ssh.is_local()
63
64     # define the API methods on this object through xmlrpc
65     # would help, but not strictly necessary
66     def connect (self):
67         pass
68
69     def run_in_guest (self,command):
70         return self.test_ssh.run(self.host_to_guest(command))
71     
72     def run_in_host (self,command):
73         return self.test_ssh.run_in_buildname(command)
74
75     #command gets run in the chroot/vserver
76     def host_to_guest(self,command):
77         if self.vserver:
78             return "vserver %s exec %s"%(self.vservername,command)
79         else:
80             return "chroot /plc/root %s"%TestSsh.backslash_shell_specials(command)
81     
82     # copy a file to the myplc root image - pass in_data=True if the file must go in /plc/data
83     def copy_in_guest (self, localfile, remotefile, in_data=False):
84         if in_data:
85             chroot_dest="/plc/data"
86         else:
87             chroot_dest="/plc/root"
88         if self.is_local():
89             if not self.vserver:
90                 utils.system("cp %s %s/%s"%(localfile,chroot_dest,remotefile))
91             else:
92                 utils.system("cp %s /vservers/%s/%s"%(localfile,self.vservername,remotefile))
93         else:
94             if not self.vserver:
95                 utils.system("scp %s %s:%s/%s"%(localfile,self.hostname(),chroot_dest,remotefile))
96             else:
97                 utils.system("scp %s %s@/vservers/%s/%s"%(localfile,self.hostname(),self.vservername,remotefile))
98
99
100         # xxx quick n dirty
101     def run_in_guest_piped (self,local,remote):
102         return utils.system(local+" | "+self.test_ssh.actual_command(self.host_to_guest(remote)))
103
104     def auth_root (self):
105         return {'Username':self.plc_spec['PLC_ROOT_USER'],
106                 'AuthMethod':'password',
107                 'AuthString':self.plc_spec['PLC_ROOT_PASSWORD'],
108                 'Role' : self.plc_spec['role']
109                 }
110     def locate_site (self,sitename):
111         for site in self.plc_spec['sites']:
112             if site['site_fields']['name'] == sitename:
113                 return site
114             if site['site_fields']['login_base'] == sitename:
115                 return site
116         raise Exception,"Cannot locate site %s"%sitename
117         
118     def locate_node (self,nodename):
119         for site in self.plc_spec['sites']:
120             for node in site['nodes']:
121                 if node['name'] == nodename:
122                     return (site,node)
123         raise Exception,"Cannot locate node %s"%nodename
124         
125     def locate_hostname (self,hostname):
126         for site in self.plc_spec['sites']:
127             for node in site['nodes']:
128                 if node['node_fields']['hostname'] == hostname:
129                     return (site,node)
130         raise Exception,"Cannot locate hostname %s"%hostname
131         
132     def locate_key (self,keyname):
133         for key in self.plc_spec['keys']:
134             if key['name'] == keyname:
135                 return key
136         raise Exception,"Cannot locate key %s"%keyname
137
138     def locate_slice (self, slicename):
139         for slice in self.plc_spec['slices']:
140             if slice['slice_fields']['name'] == slicename:
141                 return slice
142         raise Exception,"Cannot locate slice %s"%slicename
143
144     # all different hostboxes used in this plc
145     def gather_hostBoxes(self):
146         # maps on sites and nodes, return [ (host_box,test_node) ]
147         tuples=[]
148         for site_spec in self.plc_spec['sites']:
149             test_site = TestSite (self,site_spec)
150             for node_spec in site_spec['nodes']:
151                 test_node = TestNode (self, test_site, node_spec)
152                 if not test_node.is_real():
153                     tuples.append( (test_node.host_box(),test_node) )
154         # transform into a dict { 'host_box' -> [ hostnames .. ] }
155         result = {}
156         for (box,node) in tuples:
157             if not result.has_key(box):
158                 result[box]=[node]
159             else:
160                 result[box].append(node)
161         return result
162                     
163     # a step for checking this stuff
164     def show_boxes (self):
165         for (box,nodes) in self.gather_hostBoxes().iteritems():
166             print box,":"," + ".join( [ node.name() for node in nodes ] )
167         return True
168
169     # make this a valid step
170     def kill_all_qemus(self):
171         for (box,nodes) in self.gather_hostBoxes().iteritems():
172             # this is the brute force version, kill all qemus on that host box
173             TestBox(box,self.options.buildname).kill_all_qemus()
174         return True
175
176     # make this a valid step
177     def list_all_qemus(self):
178         for (box,nodes) in self.gather_hostBoxes().iteritems():
179             # this is the brute force version, kill all qemus on that host box
180             TestBox(box,self.options.buildname).list_all_qemus()
181         return True
182
183     # kill only the right qemus
184     def list_qemus(self):
185         for (box,nodes) in self.gather_hostBoxes().iteritems():
186             # the fine-grain version
187             for node in nodes:
188                 node.list_qemu()
189         return True
190
191     # kill only the right qemus
192     def kill_qemus(self):
193         for (box,nodes) in self.gather_hostBoxes().iteritems():
194             # the fine-grain version
195             for node in nodes:
196                 node.kill_qemu()
197         return True
198
199     #################### step methods
200
201     ### uninstall
202     def uninstall_chroot(self):
203         self.run_in_host('service plc safestop')
204         #####detecting the last myplc version installed and remove it
205         self.run_in_host('rpm -e myplc')
206         ##### Clean up the /plc directory
207         self.run_in_host('rm -rf /plc/data')
208         ##### stop any running vservers
209         self.run_in_host('for vserver in $(ls -d /vservers/* | sed -e s,/vservers/,,) ; do case $vserver in vtest*) echo Shutting down vserver $vserver ; vserver $vserver stop ;; esac ; done')
210         return True
211
212     def uninstall_vserver(self):
213         self.run_in_host("vserver --silent %s delete"%self.vservername)
214         return True
215
216     def uninstall(self):
217         # if there's a chroot-based myplc running, and then a native-based myplc is being deployed
218         # it sounds safer to have the former uninstalled too
219         # now the vserver method cannot be invoked for chroot instances as vservername is required
220         if self.vserver:
221             self.uninstall_vserver()
222             self.uninstall_chroot()
223         else:
224             self.uninstall_chroot()
225         return True
226
227     ### install
228     def install_chroot(self):
229         # nothing to do
230         return True
231
232     def install_vserver(self):
233         # we need build dir for vtest-init-vserver
234         if self.is_local():
235             # a full path for the local calls
236             build_dir=os.path(sys.argv[0])+"/build"
237         else:
238             # use a standard name - will be relative to HOME 
239             build_dir="options.buildname"
240         # run checkout in any case - would do an update if already exists
241         build_checkout = "svn checkout %s %s"%(self.options.build_url,build_dir)
242         if self.run_in_host(build_checkout) != 0:
243             raise Exception,"Cannot checkout build dir"
244         # the repo url is taken from myplc-url 
245         # with the last two steps (i386/myplc...) removed
246         repo_url = self.options.myplc_url
247         for level in [ 'rpmname','arch' ]:
248             repo_url = os.path.dirname(repo_url)
249         create_vserver="%s/vtest-init-vserver.sh %s %s -- --interface eth0:%s"%\
250             (build_dir,self.vservername,repo_url,self.vserverip)
251         if self.run_in_host(create_vserver) != 0:
252             raise Exception,"Could not create vserver for %s"%self.vservername
253         return True
254
255     def install(self):
256         if self.vserver:
257             return self.install_vserver()
258         else:
259             return self.install_chroot()
260     
261     ### install_rpm
262     def cache_rpm(self,url,rpm):
263         cache_fetch="pwd;if [ -f %(rpm)s ] ; then echo Using cached rpm %(rpm)s ; else echo Fetching %(url)s ; curl -O %(url)s; fi"%locals()
264         id = self.run_in_host(cache_fetch)
265         if (id != 0):
266             raise Exception,"Could not get rpm from  %s"%url
267
268     def install_rpm_chroot(self):
269         url = self.options.myplc_url
270         rpm = os.path.basename(url)
271         self.cache_rpm(url,rpm)
272         utils.header('Installing the :  %s'%rpm)
273         self.run_in_host('rpm -Uvh '+rpm)
274         self.run_in_host('service plc mount')
275         return True
276
277     def install_rpm_vserver(self):
278         self.run_in_guest("yum -y install myplc-native")
279         return True
280
281     def install_rpm(self):
282         if self.vserver:
283             return self.install_rpm_vserver()
284         else:
285             return self.install_rpm_chroot()
286
287     ### 
288     def configure(self):
289         tmpname='%s.plc-config-tty'%(self.name())
290         fileconf=open(tmpname,'w')
291         for var in [ 'PLC_NAME',
292                      'PLC_ROOT_PASSWORD',
293                      'PLC_ROOT_USER',
294                      'PLC_MAIL_ENABLED',
295                      'PLC_MAIL_SUPPORT_ADDRESS',
296                      'PLC_DB_HOST',
297                      'PLC_API_HOST',
298                      'PLC_WWW_HOST',
299                      'PLC_BOOT_HOST',
300                      'PLC_NET_DNS1',
301                      'PLC_NET_DNS2']:
302             fileconf.write ('e %s\n%s\n'%(var,self.plc_spec[var]))
303         fileconf.write('w\n')
304         fileconf.write('q\n')
305         fileconf.close()
306         utils.system('cat %s'%tmpname)
307         self.run_in_guest_piped('cat %s'%tmpname,'plc-config-tty')
308         utils.system('rm %s'%tmpname)
309         return True
310
311     # the chroot install is slightly different to this respect
312     def start(self):
313         if self.vserver:
314             self.run_in_guest('service plc start')
315         else:
316             self.run_in_host('service plc start')
317         return True
318         
319     def stop(self):
320         if self.vserver:
321             self.run_in_guest('service plc stop')
322         else:
323             self.run_in_host('service plc stop')
324         return True
325         
326     # could use a TestKey class
327     def store_keys(self):
328         for key_spec in self.plc_spec['keys']:
329                 TestKey(self,key_spec).store_key()
330         return True
331
332     def clean_keys(self):
333         utils.system("rm -rf %s/keys/"%os.path(sys.argv[0]))
334
335     def sites (self):
336         return self.do_sites()
337     
338     def clean_sites (self):
339         return self.do_sites(action="delete")
340     
341     def do_sites (self,action="add"):
342         for site_spec in self.plc_spec['sites']:
343             test_site = TestSite (self,site_spec)
344             if (action != "add"):
345                 utils.header("Deleting site %s in %s"%(test_site.name(),self.name()))
346                 test_site.delete_site()
347                 # deleted with the site
348                 #test_site.delete_users()
349                 continue
350             else:
351                 utils.header("Creating site %s & users in %s"%(test_site.name(),self.name()))
352                 test_site.create_site()
353                 test_site.create_users()
354         return True
355
356     def nodes (self):
357         return self.do_nodes()
358     def clean_nodes (self):
359         return self.do_nodes(action="delete")
360
361     def do_nodes (self,action="add"):
362         for site_spec in self.plc_spec['sites']:
363             test_site = TestSite (self,site_spec)
364             if action != "add":
365                 utils.header("Deleting nodes in site %s"%test_site.name())
366                 for node_spec in site_spec['nodes']:
367                     test_node=TestNode(self,test_site,node_spec)
368                     utils.header("Deleting %s"%test_node.name())
369                     test_node.delete_node()
370             else:
371                 utils.header("Creating nodes for site %s in %s"%(test_site.name(),self.name()))
372                 for node_spec in site_spec['nodes']:
373                     utils.pprint('Creating node %s'%node_spec,node_spec)
374                     test_node = TestNode (self,test_site,node_spec)
375                     test_node.create_node ()
376         return True
377
378     # create nodegroups if needed, and populate
379     # no need for a clean_nodegroups if we are careful enough
380     def nodegroups (self):
381         # 1st pass to scan contents
382         groups_dict = {}
383         for site_spec in self.plc_spec['sites']:
384             test_site = TestSite (self,site_spec)
385             for node_spec in site_spec['nodes']:
386                 test_node=TestNode (self,test_site,node_spec)
387                 if node_spec.has_key('nodegroups'):
388                     nodegroupnames=node_spec['nodegroups']
389                     if isinstance(nodegroupnames,StringTypes):
390                         nodegroupnames = [ nodegroupnames ]
391                     for nodegroupname in nodegroupnames:
392                         if not groups_dict.has_key(nodegroupname):
393                             groups_dict[nodegroupname]=[]
394                         groups_dict[nodegroupname].append(test_node.name())
395         auth=self.auth_root()
396         for (nodegroupname,group_nodes) in groups_dict.iteritems():
397             try:
398                 self.server.GetNodeGroups(auth,{'name':nodegroupname})[0]
399             except:
400                 self.server.AddNodeGroup(auth,{'name':nodegroupname})
401             for node in group_nodes:
402                 self.server.AddNodeToNodeGroup(auth,node,nodegroupname)
403         return True
404
405     def all_hostnames (self) :
406         hostnames = []
407         for site_spec in self.plc_spec['sites']:
408             hostnames += [ node_spec['node_fields']['hostname'] \
409                            for node_spec in site_spec['nodes'] ]
410         return hostnames
411
412     # gracetime : during the first <gracetime> minutes nothing gets printed
413     def do_nodes_booted (self, minutes, gracetime=2):
414         # compute timeout
415         timeout = datetime.datetime.now()+datetime.timedelta(minutes=minutes)
416         graceout = datetime.datetime.now()+datetime.timedelta(minutes=gracetime)
417         # the nodes that haven't checked yet - start with a full list and shrink over time
418         tocheck = self.all_hostnames()
419         utils.header("checking nodes %r"%tocheck)
420         # create a dict hostname -> status
421         status = dict ( [ (hostname,'undef') for hostname in tocheck ] )
422         while tocheck:
423             # get their status
424             tocheck_status=self.server.GetNodes(self.auth_root(), tocheck, ['hostname','boot_state' ] )
425             # update status
426             for array in tocheck_status:
427                 hostname=array['hostname']
428                 boot_state=array['boot_state']
429                 if boot_state == 'boot':
430                     utils.header ("%s has reached the 'boot' state"%hostname)
431                 else:
432                     # if it's a real node, never mind
433                     (site_spec,node_spec)=self.locate_hostname(hostname)
434                     if TestNode.is_real_model(node_spec['node_fields']['model']):
435                         utils.header("WARNING - Real node %s in %s - ignored"%(hostname,boot_state))
436                         # let's cheat
437                         boot_state = 'boot'
438                     if datetime.datetime.now() > graceout:
439                         utils.header ("%s still in '%s' state"%(hostname,boot_state))
440                         graceout=datetime.datetime.now()+datetime.timedelta(1)
441                 status[hostname] = boot_state
442             # refresh tocheck
443             tocheck = [ hostname for (hostname,boot_state) in status.iteritems() if boot_state != 'boot' ]
444             if not tocheck:
445                 return True
446             if datetime.datetime.now() > timeout:
447                 for hostname in tocheck:
448                     utils.header("FAILURE due to %s in '%s' state"%(hostname,status[hostname]))
449                 return False
450             # otherwise, sleep for a while
451             time.sleep(15)
452         # only useful in empty plcs
453         return True
454
455     def nodes_booted(self):
456         return self.do_nodes_booted(minutes=0)
457     
458 #    #to scan and store the nodes's public keys and avoid to ask for confirmation when  ssh 
459 #    def scan_publicKeys(self,hostnames):
460 #        try:
461 #            temp_knownhosts="/root/known_hosts"
462 #            remote_knownhosts="/root/.ssh/known_hosts"
463 #            self.run_in_host("touch %s"%temp_knownhosts )
464 #            for hostname in hostnames:
465 #                utils.header("Scan Public %s key and store it in the known_host file(under the root image) "%hostname)
466 #                scan=self.run_in_host('ssh-keyscan -t rsa %s >> %s '%(hostname,temp_knownhosts))
467 #            #Store the public keys in the right root image
468 #            self.copy_in_guest(temp_knownhosts,remote_knownhosts,True)
469 #            #clean the temp keys file used
470 #            self.run_in_host('rm -f  %s '%temp_knownhosts )
471 #        except Exception, err:
472 #            print err
473             
474     def do_check_nodesSsh(self,minutes):
475         # compute timeout
476         timeout = datetime.datetime.now()+datetime.timedelta(minutes=minutes)
477         tocheck = self.all_hostnames()
478 #        self.scan_publicKeys(tocheck)
479         utils.header("checking Connectivity on nodes %r"%tocheck)
480         while tocheck:
481             for hostname in tocheck:
482                 # try to ssh in nodes
483                 node_test_ssh = TestSsh (hostname)
484                 access=self.run_in_guest(node_test_ssh.actual_command("date"))
485                 if not access:
486                     utils.header('The node %s is sshable -->'%hostname)
487                     # refresh tocheck
488                     tocheck.remove(hostname)
489                 else:
490                     # we will have tried real nodes once, in case they're up - but if not, just skip
491                     (site_spec,node_spec)=self.locate_hostname(hostname)
492                     if TestNode.is_real_model(node_spec['node_fields']['model']):
493                         utils.header ("WARNING : check ssh access into real node %s - skipped"%hostname)
494                         tocheck.remove(hostname)
495             if  not tocheck:
496                 return True
497             if datetime.datetime.now() > timeout:
498                 for hostname in tocheck:
499                     utils.header("FAILURE to ssh into %s"%hostname)
500                 return False
501             # otherwise, sleep for a while
502             time.sleep(15)
503         # only useful in empty plcs
504         return True
505         
506     def nodes_ssh(self):
507         return  self.do_check_nodesSsh(minutes=2)
508     
509     def bootcd (self):
510         for site_spec in self.plc_spec['sites']:
511             test_site = TestSite (self,site_spec)
512             for node_spec in site_spec['nodes']:
513                 test_node=TestNode (self,test_site,node_spec)
514                 test_node.prepare_area()
515                 test_node.create_boot_cd()
516                 test_node.configure_qemu()
517         return True
518
519     def do_check_initscripts(self):
520         for site_spec in self.plc_spec['sites']:
521                 test_site = TestSite (self,site_spec)
522                 test_node = TestNode (self,test_site,site_spec['nodes'])
523                 for slice_spec in self.plc_spec['slices']:
524                         test_slice=TestSlice (self,test_site,slice_spec)
525                         test_sliver=TestSliver(self,test_node,test_slice)
526                         init_status=test_sliver.get_initscript(slice_spec)
527                         if (not init_status):
528                                 return False
529                 return init_status
530             
531     def check_initscripts(self):
532             return self.do_check_initscripts()
533                     
534     def initscripts (self):
535         for initscript in self.plc_spec['initscripts']:
536             utils.pprint('Adding Initscript in plc %s'%self.plc_spec['name'],initscript)
537             self.server.AddInitScript(self.auth_root(),initscript['initscript_fields'])
538         return True
539
540     def slices (self):
541         return self.do_slices()
542
543     def clean_slices (self):
544         return self.do_slices("delete")
545
546     def do_slices (self,  action="add"):
547         for slice in self.plc_spec['slices']:
548             site_spec = self.locate_site (slice['sitename'])
549             test_site = TestSite(self,site_spec)
550             test_slice=TestSlice(self,test_site,slice)
551             if action != "add":
552                 utils.header("Deleting slices in site %s"%test_site.name())
553                 test_slice.delete_slice()
554             else:    
555                 utils.pprint("Creating slice",slice)
556                 test_slice.create_slice()
557                 utils.header('Created Slice %s'%slice['slice_fields']['name'])
558         return True
559         
560     def check_slices(self):
561         for slice_spec in self.plc_spec['slices']:
562             site_spec = self.locate_site (slice_spec['sitename'])
563             test_site = TestSite(self,site_spec)
564             test_slice=TestSlice(self,test_site,slice_spec)
565             status=test_slice.do_check_slice(self.options)
566             if (not status):
567                 return False
568         return status
569     
570     def start_nodes (self):
571         utils.header("Starting  nodes")
572         for site_spec in self.plc_spec['sites']:
573             TestSite(self,site_spec).start_nodes (self.options)
574         return True
575
576     def gather_all_logs (self):
577         # (1) get the plc's /var/log and store it locally in logs/<plcname>-var-log/*
578         # (2) get all the nodes qemu log and store it as logs/<node>-qemu.log
579         # (3) get the nodes /var/log and store is as logs/<node>-var-log/*
580         # (4) as far as possible get the slice's /var/log as logs/<slice>-<node>-var-log/*
581         # (1)
582         self.gather_logs ()
583         # (2) and (3)
584         for site_spec in self.plc_spec['sites']:
585             test_site = TestSite (self,site_spec)
586             for node_spec in site_spec['nodes']:
587                 TestNode(self,test_site,node_spec).gather_qemu_logs()
588                 TestNode(self,test_site,node_spec).gather_var_logs()
589         return True
590
591     def gather_logs (self):
592         utils.header("WARNING - Incomplete logs gathering TestPlc.gather_logs")
593
594
595     def check_tcp (self):
596         specs = self.plc_spec['tcp_test']
597         overall=True
598         for spec in specs:
599             utils.header ("WARNING : xxx check_tcp is underway, spec=%r"%spec)
600             port = spec['port']
601             # locate specs
602             (s_site,s_node) = self.locate_node(spec['server_node'])
603             s_slice = self.locate_slice (spec['server_slice'])
604             # build objects
605             s_test_site = TestSite (self, s_site)
606             s_test_node = TestNode (self, s_test_site,s_node)
607             # xxx the slice site is assumed to be the node site - mhh
608             s_test_slice = TestSlice (self, s_test_site, s_slice)
609             s_test_sliver = TestSliver (self, s_test_node, s_test_slice)
610             if not s_test_sliver.run_tcp_server(port):
611                 overall=False
612                 break
613
614             # idem for the client side
615             (c_site,c_node) = self.locate_node(spec['server_node'])
616             c_slice = self.locate_slice (spec['server_slice'])
617             # build objects
618             c_test_site = TestSite (self, c_site)
619             c_test_node = TestNode (self, c_test_site,c_node)
620             # xxx the slice site is assumed to be the node site - mhh
621             c_test_slice = TestSlice (self, c_test_site, c_slice)
622             c_test_sliver = TestSliver (self, c_test_node, c_test_slice)
623             if not c_test_sliver.run_tcp_client(s_test_node.name(),port):
624                 overall=False
625
626         return overall
627
628     
629     # returns the filename to use for sql dump/restore, using options.dbname if set
630     def dbfile (self, database):
631         # uses options.dbname if it is found
632         try:
633             name=self.options.dbname
634             if not isinstance(name,StringTypes):
635                 raise Exception
636         except:
637             t=datetime.datetime.now()
638             d=t.date()
639             name=str(d)
640         return "/root/%s-%s.sql"%(database,name)
641
642     def db_dump(self):
643         dump=self.dbfile("planetab4")
644         self.run_in_guest('pg_dump -U pgsqluser planetlab4 -f '+ dump)
645         utils.header('Dumped planetlab4 database in %s'%dump)
646         return True
647
648     def db_restore(self):
649         dump=self.dbfile("planetab4")
650         ##stop httpd service
651         self.run_in_guest('service httpd stop')
652         # xxx - need another wrapper
653         self.run_in_guest_piped('echo drop database planetlab4','psql --user=pgsqluser template1')
654         self.run_in_guest('createdb -U postgres --encoding=UNICODE --owner=pgsqluser planetlab4')
655         self.run_in_guest('psql -U pgsqluser planetlab4 -f '+dump)
656         ##starting httpd service
657         self.run_in_guest('service httpd start')
658
659         utils.header('Database restored from ' + dump)
660
661     @standby_generic 
662     def standby_1(): pass
663     @standby_generic 
664     def standby_2(): pass
665     @standby_generic 
666     def standby_3(): pass
667     @standby_generic 
668     def standby_4(): pass
669     @standby_generic 
670     def standby_5(): pass
671     @standby_generic 
672     def standby_6(): pass
673     @standby_generic 
674     def standby_7(): pass
675     @standby_generic 
676     def standby_8(): pass
677     @standby_generic 
678     def standby_9(): pass
679     @standby_generic 
680     def standby_10(): pass
681     @standby_generic 
682     def standby_11(): pass
683     @standby_generic 
684     def standby_12(): pass
685     @standby_generic 
686     def standby_13(): pass
687     @standby_generic 
688     def standby_14(): pass
689     @standby_generic 
690     def standby_15(): pass
691     @standby_generic 
692     def standby_16(): pass
693     @standby_generic 
694     def standby_17(): pass
695     @standby_generic 
696     def standby_18(): pass
697     @standby_generic 
698     def standby_19(): pass
699     @standby_generic 
700     def standby_20(): pass
701