fix paths
[tests.git] / system / Trackers.py
1 #!/usr/bin/python
2 # $Id$
3
4 import os
5
6 import utils
7 from TestSsh import TestSsh
8
9 # 2 types of trackers
10 # (*) plc trackers remembers the running myplcs
11 # (*) qemu trackers keeps track of the running qemu nodes
12 #
13 # trackers allow us to let the test run after the build has finished, 
14 # and to kill/stop the oldest instances later when we need space
15
16
17 #################### Tracker
18 class Tracker:
19     
20     def __init__ (self, options,filename, instances):
21         self.options=options
22         self.filename=filename
23         self.instances=instances
24         try:
25             tracks=file(self.filename).readlines()
26             tracks = [ track.strip() for track in tracks ]
27         except:
28             tracks=[]
29         self.tracks = [track for track in tracks if track]
30
31     def list (self):
32         try:
33             contents=file(self.filename).read()
34             print "==>",self.filename,"<=="
35             print contents
36         except:
37             print "xxxxxxxxxxxx",self.filename,"not found"
38
39     def store (self):
40         out = file(self.filename,'w')
41         for track in self.tracks:
42             out.write('%s\n'%(track))
43         out.close()
44
45     def record (self,track):
46         for already in self.tracks:
47             if already==track:
48                 print '%s is already included in %s'%(already,self.filename)
49                 return
50         if self.options.dry_run:
51             print 'dry_run: Tracker.record - skipping %s'%(track)
52             return
53         self.tracks.append( track )
54         print "Recorded %s in tracker %s"%(track,self.filename)
55
56     # this stops the instances currently attached with this test session and release tracker
57     def release (self,track):
58         for already in self.tracks:
59             if already==track:
60                 if self.options.dry_run:
61                     print 'dry_run: Tracker.release - skipping %s'%(track)
62                     return
63                 self.tracks.remove(track)
64                 print "Releasing %s in tracker %s"%(track,self.filename)
65                 command = self.stop_command (track)
66                 utils.header("Trackers.make_space track : %s"%command)
67                 utils.system(command)
68         print '%s was not found in %s'%(track,self.filename)
69         return
70
71     # this actually stops the old instances, so that the total fits in the number of instances 
72     def make_space (self):
73         # number of instances to stop
74         how_many=len(self.tracks)-self.instances
75         # nothing todo until we have more than keep_vservers in the tracker
76         if how_many <= 0:
77             print 'Tracker.make_space : limit %d not reached'%self.instances
78             return
79         to_stop = self.tracks[:how_many]
80         for track in to_stop:
81             command = self.stop_command (track)
82             utils.header("Trackers.make_space track : %s"%command)
83             utils.system(command)
84         if not self.options.dry_run:
85             self.tracks = self.tracks[how_many:]
86
87     # this stops ALL known instances
88     def cleanup (self):
89         for track in self.tracks:
90             command=self.stop_command(track)
91             utils.header("Trackers.cleanup track : %s"%command)
92             utils.system(command)
93         if not self.options.dry_run:
94             self.tracks=[]
95
96 class TrackerPlc (Tracker):
97     
98     DEFAULT_FILENAME=os.environ['HOME']+"/tracker-plcs"
99     # how many concurrent plcs are we keeping alive - adjust with the IP pool size
100     DEFAULT_MAX_INSTANCES = 12
101
102     def __init__ (self,options,filename=None,instances=0):
103         if not filename: filename=TrackerPlc.DEFAULT_FILENAME
104         if not instances: instances=TrackerPlc.DEFAULT_MAX_INSTANCES
105         Tracker.__init__(self,options,filename,instances)
106
107     def record (self, hostname, vservername):
108         Tracker.record (self,"%s@%s"%(hostname,vservername))
109
110     def release (self, hostname, vservername):
111         Tracker.release (self,"%s@%s"%(hostname,vservername))
112
113     def stop_command (self, track):
114         (hostname,vservername) = track.split('@')
115         return TestSsh(hostname).actual_command("vserver --silent %s stop"%vservername)
116         
117     def plcnames (self):
118         return [ self.plcname(track) for track in self.tracks ]
119
120     def plcname (self, track):
121         (hostname,vservername) = track.split('@')
122         return vservername.rsplit('-',1)[1]
123
124 class TrackerQemu (Tracker):
125
126     DEFAULT_FILENAME=os.environ['HOME']+"/tracker-qemus"
127     # how many concurrent plcs are we keeping alive - adjust with the IP pool size
128     DEFAULT_MAX_INSTANCES = 3
129
130     def __init__ (self,options,filename=None,instances=0):
131         if not filename: filename=TrackerQemu.DEFAULT_FILENAME
132         if not instances: instances=TrackerQemu.DEFAULT_MAX_INSTANCES
133         Tracker.__init__(self,options,filename,instances)
134
135     def record (self, hostname, buildname, nodename):
136         Tracker.record (self,"%s@%s@%s"%(hostname,buildname,nodename))
137
138     def release (self, hostname, buildname, nodename):
139         Tracker.release (self,"%s@%s@%s"%(hostname,buildname,nodename))
140
141     def stop_command (self, track):
142         (hostname,buildname,nodename) = track.split('@')
143         return TestSsh(hostname).actual_command("%s/qemu-%s/qemu-kill-node this"%(buildname,nodename))
144
145     def hostnames (self):
146         return [ self.hostname(track) for track in self.tracks ]
147
148     def hostname (self, track):
149         (hostname,buildname,nodename) = track.split('@')
150         return hostname
151
152     def nodenames (self):
153         return [ self.nodename(track) for track in self.tracks ]
154         
155     def nodename (self, track):
156         (hostname,buildname,nodename) = track.split('@')
157         return nodename
158