]>
git.ipfire.org Git - ipfire.org.git/blob - build/builder.py
2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2008 Michael Tremer & Christian Schmidt #
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. #
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. #
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/>. #
20 ###############################################################################
28 from pysqlite2
import dbapi2
as sqlite
32 from constants
import config
35 def __init__(self
, path
):
36 self
.db
= sqlite
.connect(os
.path
.join(path
, config
["db_name"]))
39 create table if not exists config(key, value, date);
40 create table if not exists durations(duration);
52 return self
.db
.cursor()
58 def __init__(self
, db
, key
, base64
=0):
68 c
.execute("SELECT value FROM %(table)s WHERE key = '%(key)s'" \
69 % { "table" : "config",
72 self
.data
= c
.fetchone()[0]
83 c
.execute("SELECT date FROM %(table)s WHERE key = '%(key)s'" \
84 % { "table" : "config",
87 self
.date
= float("%s" % c
.fetchone()[0])
91 return self
.date
or float(0)
95 value
= base64
.b64decode(value
)
99 sql
= "INSERT INTO %(table)s(key, value, date) VALUES('%(key)s', '%(value)s', '%(date)s')" \
100 % { "table" : "config",
103 "date" : time
.time(), }
106 sql
= "UPDATE %(table)s SET value='%(value)s', date='%(date)s' WHERE key='%(key)s'" \
107 % { "table" : "config",
110 "date" : time
.time(), }
115 return """Set "%s" to "%s".""" % (self
.key
, self
.data
,)
117 class DurationsConfig
:
118 def __init__(self
, db
):
121 def get(self
, sort
=0):
123 c
.execute("SELECT duration FROM durations")
125 for value
in c
.fetchall():
126 value
= int("%s" % value
)
127 if value
< 900: # 15min
134 def set(self
, value
):
137 c
.execute("INSERT INTO %(table)s(duration) VALUES('%(value)s')" \
138 % { "table" : "durations",
142 return """Accepted build duration of %s seconds.""" % (value
,)
146 durations
= self
.get()
147 if not len(durations
):
149 for value
in durations
:
151 avg
= sum / len(durations
)
154 def get_eta(self
, timestamp
):
158 eta
= int(timestamp
) + avg
159 return time
.ctime(eta
)
161 class DistccConfig(DatabaseConfig
):
162 def __init__(self
, db
, key
, hostname
, jobs
):
163 DatabaseConfig
.__init
__(self
, db
, key
)
164 self
.hostname
= hostname
168 if not self
.ping() or self
.get() == "0":
170 return "%s:%s/%s,lzo \t# %s" % \
171 (socket
.gethostbyname(self
.hostname
), self
.get(), self
.jobs
or "4", self
.hostname
)
174 if not self
.hostname
:
176 return not os
.system("ping -c1 -w1 %s &>/dev/null" % self
.hostname
)
179 return os
.popen("distcc --version").readlines()
182 def __init__(self
, path
, filetype
):
183 self
.filename
= os
.path
.join(path
, config
["path"][filetype
])
185 # Create the file if not existant
186 if not os
.access(self
.filename
, os
.R_OK
):
187 f
= open(self
.filename
, "w")
193 f
= open(self
.filename
)
198 return ret
or ["Log is empty."]
202 def set(self
, lines
):
203 f
= open(self
.filename
, "w")
204 for line
in base64
.b64decode(lines
).split("\n"):
205 f
.write("%s\n" % line
.rstrip("\n"))
207 return """Saved file content to %s.""" % (self
.filename
,)
210 def __init__(self
, config
, uuid
):
213 self
.path
= os
.path
.join(self
.config
['path']['db'], self
.uuid
)
215 if not os
.access(self
.path
, os
.R_OK
):
221 self
.db
= Database(self
.path
)
223 self
.hostname
= DatabaseConfig(self
.db
, "hostname")
224 self
.state
= DatabaseConfig(self
.db
, "state")
225 self
.package
= DatabaseConfig(self
.db
, "package")
226 self
.target
= DatabaseConfig(self
.db
, "target")
228 self
.duration
= DurationsConfig(self
.db
)
229 self
.jobs
= DatabaseConfig(self
.db
, "jobs")
230 self
.distcc
= DistccConfig(self
.db
, "distcc", self
.hostname(), self
.jobs())
231 self
.cpu
= DatabaseConfig(self
.db
, "cpu", base64
=1)
232 self
.machine
= DatabaseConfig(self
.db
, "machine")
234 self
.log
= FileConfig(self
.path
, "log")
236 # If host was longer than 3 days in state compiling we set it as idle.
237 if self
.state() == "compiling" and \
238 (time
.time() - self
.state
.time()) > 3*24*60*60:
239 self
.state
.set("idle")
241 # If host is idle and distcc is not disabled we set it as distcc host.
242 if self
.state() == "idle" and self
.distcc() != "0":
243 self
.state
.set("distcc")
245 # If host is longer than 24h in error state we set it as distcc host.
246 if self
.state() == "error" and \
247 (time
.time() - self
.state
.time()) > 24*60*60:
248 self
.state
.set("distcc")
250 # If host was longer than two weeks in distcc state we set it as unknown.
251 if self
.state() == "error" and \
252 (time
.time() - self
.state
.time()) > 2*7*24*60*60:
253 self
.state
.set("unknown")
255 # If host was longer than four weels in distcc state we delete it.
256 if self
.state() in ("distcc", "unknown",) and \
257 (time
.time() - self
.state
.time()) > 4*7*24*60*60:
259 shutil
.rmtree(self
.path
)
261 def set(self
, key
, value
):
262 return eval("self.%s.set(\"%s\")" % (key
, value
,))
265 return eval("self.%s.get()" % (key
,))
267 def getAllBuilders(age
=0):
269 for uuid
in os
.listdir(config
["path"]["db"]):
270 if uuid
== "empty.txt": continue
271 builder
= Builder(config
, uuid
)
272 # If there was no activity since "age" days -> continue...
273 if age
and (time
.time() - builder
.state
.time()) > age
*24*60*60:
275 builders
.append(builder
)