4 # Copyright (C) 2008 Andrew Bartlett <abartlet@samba.org>
5 # Copyright (C) 2008-2010 Jelmer Vernooij <jelmer@samba.org>
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/>.
21 from buildfarm import setup_db
24 from storm.database import create_database
25 from storm.locals import Bool, Int, Unicode, RawStr
26 from storm.store import Store
30 class HostAlreadyExists(Exception):
31 """The specified host already exists."""
33 def __init__(self, name):
34 super(HostAlreadyExists, self).__init__()
38 class NoSuchHost(Exception):
39 """The specified host did not exist."""
41 def __init__(self, name):
42 super(NoSuchHost, self).__init__()
47 """A host in the buildfarm."""
49 def __init__(self, name, owner=None, owner_email=None, password=None, platform=None,
50 ssh_access=False, last_update=None, fqdn=None, join_time=None, permission=None):
53 self.owner = (owner, owner_email)
57 self.join_time = time.time()
59 self.join_time = join_time
60 self.permission = permission
61 self.password = password
62 self.platform = platform
63 self.ssh_access = ssh_access
64 self.last_update = last_update
67 def __cmp__(self, other):
68 return cmp(self.name, other.name)
71 class StormHost(Host):
72 __storm_table__ = "host"
74 name = Unicode(primary=True)
75 owner_name = Unicode(name="owner")
76 owner_email = Unicode()
81 permission = Unicode()
82 last_dead_mail = Int()
85 def _set_owner(self, value):
87 self.owner_name = None
88 self.owner_email = None
90 (self.owner_name, self.owner_email) = value
93 if self.owner_name is None:
96 return (self.owner_name, self.owner_email)
98 owner = property(_get_owner, _set_owner)
101 class HostDatabase(object):
104 def __init__(self, filename=None):
106 self.db = create_database("sqlite:")
108 self.db = create_database("sqlite:" + filename)
109 self.store = Store(self.db)
113 def createhost(self, name, platform=None, owner=None, owner_email=None, password=None, permission=None):
114 newhost = StormHost(unicode(name), owner=owner, owner_email=owner_email, password=password, permission=permission, platform=platform)
116 self.store.add(newhost)
118 except pysqlite2.dbapi2.IntegrityError:
119 raise HostAlreadyExists(name)
121 def deletehost(self, name):
122 host = self.host(name)
124 raise NoSuchHost(name)
125 self.store.remove(host)
128 return self.store.find(StormHost).order_by(StormHost.name)
130 def dead_hosts(self, age):
131 dead_time = time.time() - age
132 cursor = self.store.execute("SELECT host.name AS host, host.owner AS owner, host.owner_email AS owner_email, MAX(age) AS last_update FROM host LEFT JOIN build ON ( host.name == build.host) WHERE ifnull(last_dead_mail, 0) < %d AND ifnull(join_time, 0) < %d GROUP BY host.name having ifnull(MAX(age),0) < %d" % (dead_time, dead_time, dead_time))
134 yield Host(row[0], owner=row[1], owner_email=row[2], last_update=row[3])
137 cursor = self.store.execute("SELECT host.name AS host, host.owner AS owner, host.owner_email AS owner_email, MAX(age) AS last_update FROM host LEFT JOIN build ON ( host.name == build.host) GROUP BY host.name ORDER BY age")
139 yield Host(row[0], owner=row[1], owner_email=row[2], last_update=row[3])
141 def sent_dead_mail(self, host):
142 self.store.execute("UPDATE host SET last_dead_mail = ? WHERE name = ?", (int(time.time()), host))
145 def host(self, name):
146 return self.hosts().find(StormHost.name==name).one()
148 def update_platform(self, name, new_platform):
149 host = self.host(unicode(name))
151 raise NoSuchHost(name)
152 host.platform = new_platform
154 def update_owner(self, name, new_owner, new_owner_email):
155 cursor = self.store.execute(
156 "UPDATE host SET owner = ?, owner_email = ? WHERE name = ?", (new_owner,
157 new_owner_email, name))
158 if cursor.rowcount == 0:
159 raise NoSuchHost(name)
162 def create_rsync_secrets(self):
163 """Write out the rsyncd.secrets"""
164 yield "# rsyncd.secrets file\n"
165 yield "# automatically generated by textfiles.pl. DO NOT EDIT!\n\n"
167 for host in self.hosts():
169 yield "# %s, owner: %s <%s>\n" % (host.name, host.owner[0], host.owner[1])
171 yield "# %s, owner unknown\n" % (host.name,);
173 yield "%s:%s\n\n" % (host.name, host.password)
175 yield "# %s password is unknown\n\n" % host.name
177 def create_hosts_list(self):
178 """Write out the web/"""
180 for host in self.hosts():
181 yield "%s: %s\n" % (host.name.encode("utf-8"), host.platform.encode("utf-8"))