]>
Commit | Line | Data |
---|---|---|
2b60fce9 MT |
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") | |
1e0061eb MT |
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) | |
2b60fce9 MT |
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: | |
1e0061eb | 143 | sum += value |
2b60fce9 MT |
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): | |
fda98c60 | 160 | if not self.ping() or self.get() == "0": |
2b60fce9 MT |
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) | |
aaaff751 MT |
205 | # If there was no activity since 3 days -> continue... |
206 | if (time.time() - builder.state.time()) > 3*24*60*60: | |
207 | continue | |
2b60fce9 MT |
208 | builders.append(builder) |
209 | return builders |