]> git.ipfire.org Git - ipfire.org.git/blob - build/builder.py
Merge branch 'master' of /srv/git/ipfire.org
[ipfire.org.git] / build / builder.py
1 #!/usr/bin/python
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2008 Michael Tremer & Christian Schmidt #
6 # #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
11 # #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
16 # #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 # #
20 ###############################################################################
21
22 import os
23 import sys
24 import time
25 import socket
26 from pysqlite2 import dbapi2 as sqlite
27
28 sys.path.append(".")
29
30 from constants import config
31
32 class Database:
33 def __init__(self, path):
34 self.db = sqlite.connect(os.path.join(path, config["db_name"]))
35 c = self.cursor()
36 c.executescript("""
37 create table if not exists config(key, value, date);
38 create table if not exists durations(duration);
39 """)
40 c.close()
41
42 def __call__(self):
43 return self.cursor()
44
45 def __del__(self):
46 self.commit()
47 self.db.close()
48
49 def cursor(self):
50 return self.db.cursor()
51
52 def commit(self):
53 self.db.commit()
54
55 class DatabaseConfig:
56 def __init__(self, db, key):
57 self.db = db
58 self.key = key
59 self.data = None
60 self.date = None
61
62 def get(self):
63 if not self.data:
64 c = self.db.cursor()
65 c.execute("SELECT value FROM %(table)s WHERE key = '%(key)s'" \
66 % { "table" : "config",
67 "key" : self.key, })
68 try:
69 self.data = c.fetchone()[0]
70 except TypeError:
71 self.data = None
72 c.close()
73 return self.data
74
75 __call__ = get
76
77 def time(self):
78 if not self.date:
79 c = self.db.cursor()
80 c.execute("SELECT date FROM %(table)s WHERE key = '%(key)s'" \
81 % { "table" : "config",
82 "key" : self.key, })
83 try:
84 self.date = float("%s" % c.fetchone()[0])
85 except TypeError:
86 self.date = None
87 c.close()
88 return self.date or float(0)
89
90 def set(self, value):
91 #value = (value,)
92 c = self.db.cursor()
93 if not self.get():
94 sql = "INSERT INTO %(table)s(key, value, date) VALUES('%(key)s', '%(value)s', '%(date)s')" \
95 % { "table" : "config",
96 "key" : self.key,
97 "value" : value,
98 "date" : time.time(), }
99
100 else:
101 sql = "UPDATE %(table)s SET value='%(value)s', date='%(date)s' WHERE key='%(key)s'" \
102 % { "table" : "config",
103 "key" : self.key,
104 "value" : value,
105 "date" : time.time(), }
106 c.execute(sql)
107 c.close()
108 self.data = value
109 self.db.commit()
110
111 class DurationsConfig:
112 def __init__(self, db):
113 self.db = db
114
115 def get(self, sort=0):
116 c = self.db.cursor()
117 c.execute("SELECT duration FROM durations")
118 ret = []
119 for value in c.fetchall():
120 value = int("%s" % value)
121 if value < 5400: # 1,5h
122 continue
123 ret.append(value)
124 c.close()
125 if sort: ret.sort()
126 return ret
127
128 def set(self, value):
129 #value = (value,)
130 c = self.db.cursor()
131 c.execute("INSERT INTO %(table)s(duration) VALUES('%(value)s')" \
132 % { "table" : "durations",
133 "value" : value, })
134 c.close()
135 self.db.commit()
136
137 def get_avg(self):
138 sum = 0
139 durations = self.get()
140 if not len(durations):
141 return None
142 for value in durations:
143 sum += value
144 avg = sum / len(durations)
145 return avg
146
147 def get_eta(self, timestamp):
148 avg = self.get_avg()
149 if not avg:
150 return "N/A"
151 eta = int(timestamp) + avg
152 return time.ctime(eta)
153
154 class DistccConfig(DatabaseConfig):
155 def __init__(self, db, key, hostname):
156 DatabaseConfig.__init__(self, db, key)
157 self.hostname = hostname
158
159 def __str__(self):
160 if not self.ping() or self.get() == "0":
161 return ""
162 return "%s:%s/4,lzo" % \
163 (socket.gethostbyname(self.hostname), self.get(),)
164
165 def ping(self):
166 if not self.hostname:
167 return False
168 return not os.system("ping -c1 -w1 %s &>/dev/null" % self.hostname)
169
170 def version(self):
171 return os.popen("distcc --version").readlines()
172
173 class Builder:
174 def __init__(self, config, uuid):
175 self.uuid = uuid
176 self.config = config
177 self.path = os.path.join(self.config['path']['db'], self.uuid)
178
179 if not os.access(self.path, os.R_OK):
180 try:
181 os.mkdir(self.path)
182 except:
183 pass
184
185 self.db = Database(self.path)
186
187 self.hostname = DatabaseConfig(self.db, "hostname")
188 self.state = DatabaseConfig(self.db, "state")
189 self.package = DatabaseConfig(self.db, "package")
190
191 self.duration = DurationsConfig(self.db)
192 self.distcc = DistccConfig(self.db, "distcc", self.hostname.get())
193
194 def set(self, key, value):
195 eval("self.%s.set(\"%s\")" % (key, value,))
196
197 def get(self, key):
198 return eval("self.%s.get()" % (key,))
199
200 def getAllBuilders():
201 builders = []
202 for uuid in os.listdir(config["path"]["db"]):
203 if uuid == "empty.txt": continue
204 builder = Builder(config, uuid)
205 builders.append(builder)
206 return builders