From 933091c9686e1c5f60595ef4b3053d8438e0e32e Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 12 Jun 2010 00:07:56 +0200 Subject: [PATCH] Removed old build tracker. --- build/builder.py | 278 ------------------------------------- build/constants.py | 59 -------- build/db/empty.txt | 0 build/index.py | 332 --------------------------------------------- build/rpc.py | 71 ---------- 5 files changed, 740 deletions(-) delete mode 100644 build/builder.py delete mode 100644 build/constants.py delete mode 100644 build/db/empty.txt delete mode 100644 build/index.py delete mode 100644 build/rpc.py diff --git a/build/builder.py b/build/builder.py deleted file mode 100644 index 73c643ae..00000000 --- a/build/builder.py +++ /dev/null @@ -1,278 +0,0 @@ -#!/usr/bin/python -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -############################################################################### - -import os -import sys -import time -import socket -import base64 -import shutil -from pysqlite2 import dbapi2 as sqlite - -sys.path.append(".") - -from constants import config - -class Database: - def __init__(self, path): - self.db = sqlite.connect(os.path.join(path, config["db_name"])) - c = self.cursor() - c.executescript(""" - create table if not exists config(key, value, date); - create table if not exists durations(duration); - """) - c.close() - - def __call__(self): - return self.cursor() - - def __del__(self): - self.commit() - self.db.close() - - def cursor(self): - return self.db.cursor() - - def commit(self): - self.db.commit() - -class DatabaseConfig: - def __init__(self, db, key, base64=0): - self.db = db - self.key = key - self.data = None - self.date = None - self.base64 = base64 - - def get(self): - if not self.data: - c = self.db.cursor() - c.execute("SELECT value FROM %(table)s WHERE key = '%(key)s'" \ - % { "table" : "config", - "key" : self.key, }) - try: - self.data = c.fetchone()[0] - except TypeError: - self.data = None - c.close() - return self.data - - __call__ = get - - def time(self): - if not self.date: - c = self.db.cursor() - c.execute("SELECT date FROM %(table)s WHERE key = '%(key)s'" \ - % { "table" : "config", - "key" : self.key, }) - try: - self.date = float("%s" % c.fetchone()[0]) - except TypeError: - self.date = None - c.close() - return self.date or float(0) - - def set(self, value): - if self.base64: - value = base64.b64decode(value) - #value = (value,) - c = self.db.cursor() - if not self.get(): - sql = "INSERT INTO %(table)s(key, value, date) VALUES('%(key)s', '%(value)s', '%(date)s')" \ - % { "table" : "config", - "key" : self.key, - "value" : value, - "date" : time.time(), } - - else: - sql = "UPDATE %(table)s SET value='%(value)s', date='%(date)s' WHERE key='%(key)s'" \ - % { "table" : "config", - "key" : self.key, - "value" : value, - "date" : time.time(), } - c.execute(sql) - c.close() - self.data = value - self.db.commit() - return """Set "%s" to "%s".""" % (self.key, self.data,) - -class DurationsConfig: - def __init__(self, db): - self.db = db - - def get(self, sort=0): - c = self.db.cursor() - c.execute("SELECT duration FROM durations") - ret = [] - for value in c.fetchall(): - value = int("%s" % value) - if value < 900: # 15min - continue - ret.append(value) - c.close() - if sort: ret.sort() - return ret - - def set(self, value): - #value = (value,) - c = self.db.cursor() - c.execute("INSERT INTO %(table)s(duration) VALUES('%(value)s')" \ - % { "table" : "durations", - "value" : value, }) - c.close() - self.db.commit() - return """Accepted build duration of %s seconds.""" % (value,) - - def get_avg(self): - sum = 0 - durations = self.get() - if not len(durations): - return None - for value in durations: - sum += value - avg = sum / len(durations) - return avg - - def get_eta(self, timestamp): - avg = self.get_avg() - if not avg: - return "N/A" - eta = int(timestamp) + avg - return time.ctime(eta) - -class DistccConfig(DatabaseConfig): - def __init__(self, db, key, hostname, jobs): - DatabaseConfig.__init__(self, db, key) - self.hostname = hostname - self.jobs = jobs - - def __str__(self): - if not self.ping() or self.get() == "0": - return "" - return "%s:%s/%s,lzo" % \ - (self.hostname, self.get(), self.jobs or "4",) - - def ping(self): - if not self.hostname: - return False - return not os.system("ping -c1 -w1 %s &>/dev/null" % self.hostname) - - def version(self): - return os.popen("distcc --version").readlines() - -class FileConfig: - def __init__(self, path, filetype): - self.filename = os.path.join(path, config["path"][filetype]) - - # Create the file if not existant - if not os.access(self.filename, os.R_OK): - f = open(self.filename, "w") - f.close() - - def get(self): - ret = [] - try: - f = open(self.filename) - ret = f.readlines() - f.close() - except: - pass - return ret or ["Log is empty."] - - __call__ = get - - def set(self, lines): - f = open(self.filename, "w") - for line in base64.b64decode(lines).split("\n"): - f.write("%s\n" % line.rstrip("\n")) - f.close() - return """Saved file content to %s.""" % (self.filename,) - -class Builder: - def __init__(self, config, uuid): - self.uuid = uuid - self.config = config - self.path = os.path.join(self.config['path']['db'], self.uuid) - - if not os.access(self.path, os.R_OK): - try: - os.mkdir(self.path) - except: - pass - - self.db = Database(self.path) - - self.hostname = DatabaseConfig(self.db, "hostname") - self.state = DatabaseConfig(self.db, "state") - self.package = DatabaseConfig(self.db, "package") - self.target = DatabaseConfig(self.db, "target") - self.toolchain= DatabaseConfig(self.db, "toolchain") - - self.duration = DurationsConfig(self.db) - self.jobs = DatabaseConfig(self.db, "jobs") - self.distcc = DistccConfig(self.db, "distcc", self.hostname(), self.jobs()) - self.cpu = DatabaseConfig(self.db, "cpu", base64=1) - self.machine = DatabaseConfig(self.db, "machine") - self.system = DatabaseConfig(self.db, "system", base64=1) - - self.log = FileConfig(self.path, "log") - - # If host was longer than 3 days in state compiling we set it as idle. - if self.state() == "compiling" and \ - (time.time() - self.state.time()) > 3*24*60*60: - self.state.set("idle") - - # If host is idle and distcc is not disabled we set it as distcc host. - if self.state() == "idle" and self.distcc() != "0": - self.state.set("distcc") - - # If host is longer than 24h in error state we set it as distcc host. - if self.state() == "error" and \ - (time.time() - self.state.time()) > 24*60*60: - self.state.set("distcc") - - # If host was longer than two weeks in distcc state we set it as unknown. - if self.state() == "error" and \ - (time.time() - self.state.time()) > 2*7*24*60*60: - self.state.set("unknown") - - # If host was longer than four weels in distcc state we delete it. - if self.state() in ("distcc", "unknown",) and \ - (time.time() - self.state.time()) > 4*7*24*60*60: - del self.db - shutil.rmtree(self.path) - - def set(self, key, value): - return eval("self.%s.set(\"%s\")" % (key, value,)) - - def get(self, key): - return eval("self.%s.get()" % (key,)) - -def getAllBuilders(age=0): - builders = [] - for uuid in os.listdir(config["path"]["db"]): - if uuid == "empty.txt": continue - builder = Builder(config, uuid) - # If there was no activity since "age" days -> continue... - if age and (time.time() - builder.state.time()) > age*24*60*60: - continue - builders.append(builder) - return builders diff --git a/build/constants.py b/build/constants.py deleted file mode 100644 index 846de0c9..00000000 --- a/build/constants.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/python -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -############################################################################### - -import os -import time - -POINTS_UNKNOWN = 0 -POINTS_IDLE = 1 -POINTS_DISTCC = 2 -POINTS_ERROR = 4 -POINTS_COMPILING = 8 - -config = { - "title" : "IPFire - Builder", - "nightly_url" : ("http://ftp.ipfire.org/pub/nightly-builds/", "http://www.rowie.at/upload/ipfire/builds/",), - "path" : { "db" : "db", "log" : "error.log", }, - "script" : os.environ['SCRIPT_NAME'], - "db_name" : "builder.db", -} - -statedesc = { - None : "", - "unknown" : "Dunno what the host is doing at the moment...", - "compiling" : "The host is really hard working at the moment...", - "error" : "Oops! The host had an error...", - "idle" : "The host is idle at the moment...", - "distcc" : "This host is waiting for distcc requests...", -} - -ping2class = { - True : "online", - False : "offline", -} - -state2style = { - None : "", - "compiling" : "background: #8C8; border: 1px solid #0e0;", - "distcc" : "background: #58c; border: 1px solid #8ac;", - "error" : "background: #c33; border: 1px solid #e00;", - "idle" : "background: #ddd; border: 1px solid #eee;", -} diff --git a/build/db/empty.txt b/build/db/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/build/index.py b/build/index.py deleted file mode 100644 index 3b30b966..00000000 --- a/build/index.py +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/python -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -############################################################################### - -import os -import sys -import time - -sys.path.append(".") - -from builder import Builder, getAllBuilders -from constants import * - -def format_time(seconds, use_hours=1): - if seconds is None or seconds < 0: - if use_hours: return '--:--:--' - else: return '--:--' - else: - seconds = int(seconds) - minutes = seconds / 60 - seconds = seconds % 60 - if use_hours: - hours = minutes / 60 - minutes = minutes % 60 - return '%02i:%02i:%02i' % (hours, minutes, seconds) - else: - return '%02i:%02i' % (minutes, seconds) - -class Site: - def __init__(self, config): - self.builders = None - self.config = config - print "Content-type: text/html" - print - - def __call__(self, builders=None): - self.builders = builders - print """ - - - %(title)s - - - - - """ - - self.content() - - print "\t\t\n" - - def content(self): - if self.builders: - print """\ -
""" - for builder in self.builders: - builder() - print """\ -
""" - -class Box: - def __init__(self, builder): - self.builder = builder - self.points = POINTS_UNKNOWN - - def __cmp__(self, other): - if self.points > other.points: - return -1 - elif self.points == other.points: - return 0 - elif self.points < other.points: - return 1 - - def __str__(self): - return """%(hostname)s""" % { "hostname" : self.builder.hostname(), } - - def open_bigbox(self): - print """
""" \ - % (self.builder.hostname(), state2style[self.builder.state()],) - - def open_infobox(self): - print """
""" - - def close_bigbox(self): - print """
""" - - close_infobox = close_bigbox - - def header(self): - print """

%(hostname)s [%(uuid)s]

""" \ - % { "hostname" : self.builder.hostname(), - "state" : self.builder.state(), - "uuid" : self.builder.uuid, } - - def package(self): - if self.builder.state() in [ "compiling", "error", ]: - print """\ -

%s

"""\ - % self.builder.package() - - def time(self): - print """

%s

""" \ - % time.ctime(float(self.builder.state.time())) - - def stateinfo(self): - print """

%s

""" \ - % statedesc[self.builder.state()] - - def durations(self): - print """

Average Build Duration: %s

""" \ - % format_time(self.builder.duration.get_avg()) - if self.builder.state() == "compiling": - print """

ETA: %s

""" \ - % self.builder.duration.get_eta(self.builder.state.time()) - - def distccinfo(self): - state = self.builder.distcc.ping() - port = self.builder.distcc() - if port == "0": - state = False - port = "disabled" - print """

Distcc: %s

""" \ - % (ping2class[state], port,) - - def log(self): - log = self.builder.log() - if log: - print """

""" - print "
".join(log) - print """

""" - - def footer(self): - print """""" \ - % (self.builder.system(), self.builder.cpu(), self.builder.machine(), self.builder.target(), self.builder.jobs(), self.builder.toolchain(),) - -class BoxCompiling(Box): - def __init__(self, builder): - Box.__init__(self, builder) - self.points = POINTS_COMPILING - - def __call__(self): - self.open_bigbox() - self.open_infobox() - self.distccinfo() - self.package() - self.time() - self.close_infobox() - self.header() - self.stateinfo() - self.durations() - self.footer() - self.close_bigbox() - -class BoxError(Box): - def __init__(self, builder): - Box.__init__(self, builder) - self.points = POINTS_ERROR - - def __call__(self): - self.open_bigbox() - self.open_infobox() - self.distccinfo() - self.package() - self.time() - self.close_infobox() - self.header() - self.stateinfo() - self.durations() - self.log() - self.footer() - self.close_bigbox() - -class BoxDistcc(Box): - def __init__(self, builder): - Box.__init__(self, builder) - self.points = POINTS_DISTCC - - def __call__(self): - self.open_bigbox() - self.open_infobox() - self.distccinfo() - self.time() - self.close_infobox() - self.header() - self.stateinfo() - self.durations() - self.footer() - self.close_bigbox() - -class BoxIdle(Box): - def __init__(self, builder): - Box.__init__(self, builder) - self.points = POINTS_IDLE - - def __call__(self): - self.open_bigbox() - self.open_infobox() - self.distccinfo() - self.time() - self.close_infobox() - self.header() - self.stateinfo() - self.durations() - self.footer() - self.close_bigbox() - -site = Site(config) - -boxes = [] -for builder in getAllBuilders(): - box = None - if builder.state() == "compiling": - box = BoxCompiling(builder) - elif builder.state() == "error": - box = BoxError(builder) - elif builder.state() == "idle": - box = BoxIdle(builder) - elif builder.state() == "distcc": - if builder.distcc() == "0": - continue - box = BoxDistcc(builder) - if box: - boxes.append(box) - -boxes.sort() -site(boxes) diff --git a/build/rpc.py b/build/rpc.py deleted file mode 100644 index c912ad71..00000000 --- a/build/rpc.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/python -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008,2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -############################################################################### - -import os -import sys -import cgi - -sys.path.append(".") - -from builder import Builder, getAllBuilders -from constants import config - -ALLOWED_ACTIONS_SET = ( "distcc", "duration", "hostname", "jobs", "log", "state", - "package", "target", "toolchain", "cpu", "machine", "system",) -ALLOWED_ACTIONS_GET = ( "distcc",) - -def run(uuid, action): - myself = Builder(config, uuid) - - if action == "get": - for key in ALLOWED_ACTIONS_GET: - if key == "distcc": - for value in data.getlist(key): - if value == "raw": - builders = getAllBuilders() - print "--randomize" - for builder in builders: - # Print "localhost" for ourself - if myself.uuid == builder.uuid: - print "localhost" - else: - if ((myself.toolchain() == builder.toolchain()) and \ - (myself.machine() == builder.machine()) and \ - (myself.target() == builder.target())): - print "%s" % (builder.distcc,) - - elif action == "set": - for key in ALLOWED_ACTIONS_SET: - for value in data.getlist(key): - print myself.set(key, value) - -data = cgi.FieldStorage() - -print "Status: 200 - OK" # We always send okay. -print - -try: - uuid = data.getfirst("uuid") - action = data.getfirst("action") - if uuid and action: - run(uuid, action) -except SystemExit: - pass -- 2.47.3