]> git.ipfire.org Git - ipfire.org.git/blob - build/builder.py
Always check if the host is pingable before we send it to the childs.
[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 = c.fetchall()
119 c.close()
120 if sort: ret.sort()
121 return ret
122
123 def set(self, value):
124 #value = (value,)
125 c = self.db.cursor()
126 c.execute("INSERT INTO %(table)s(duration) VALUES('%(value)s')" \
127 % { "table" : "durations",
128 "value" : value, })
129 c.close()
130 self.db.commit()
131
132 def get_avg(self):
133 sum = 0
134 durations = self.get()
135 if not len(durations):
136 return None
137 for value in durations:
138 duration = int("%s" % value)
139 if duration < 3600:
140 continue
141 sum += duration
142 avg = sum / len(durations)
143 return avg
144
145 def get_eta(self, timestamp):
146 avg = self.get_avg()
147 if not avg:
148 return "N/A"
149 eta = int(timestamp) + avg
150 return time.ctime(eta)
151
152 class DistccConfig(DatabaseConfig):
153 def __init__(self, db, key, hostname):
154 DatabaseConfig.__init__(self, db, key)
155 self.hostname = hostname
156
157 def __str__(self):
158 if not self.ping():
159 return ""
160 return "%s:%s/4,lzo" % \
161 (socket.gethostbyname(self.hostname), self.get(),)
162
163 def ping(self):
164 if not self.hostname:
165 return False
166 return not os.system("ping -c1 -w1 %s &>/dev/null" % self.hostname)
167
168 def version(self):
169 return os.popen("distcc --version").readlines()
170
171 class Builder:
172 def __init__(self, config, uuid):
173 self.uuid = uuid
174 self.config = config
175 self.path = os.path.join(self.config['path']['db'], self.uuid)
176
177 if not os.access(self.path, os.R_OK):
178 try:
179 os.mkdir(self.path)
180 except:
181 pass
182
183 self.db = Database(self.path)
184
185 self.hostname = DatabaseConfig(self.db, "hostname")
186 self.state = DatabaseConfig(self.db, "state")
187 self.package = DatabaseConfig(self.db, "package")
188
189 self.duration = DurationsConfig(self.db)
190 self.distcc = DistccConfig(self.db, "distcc", self.hostname.get())
191
192 def set(self, key, value):
193 eval("self.%s.set(\"%s\")" % (key, value,))
194
195 def get(self, key):
196 return eval("self.%s.get()" % (key,))
197
198 def getAllBuilders():
199 builders = []
200 for uuid in os.listdir(config["path"]["db"]):
201 if uuid == "empty.txt": continue
202 builder = Builder(config, uuid)
203 builders.append(builder)
204 return builders