Actually use storm db.
[amitay/build-farm.git] / admin.py
1 #!/usr/bin/python
2 # Samba.org buildfarm
3 # Copyright (C) 2008 Andrew Bartlett <abartlet@samba.org>
4 # Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 from buildfarm import (
21     hostdb,
22     )
23 from buildfarm.sqldb import StormCachingBuildFarm
24 import commands
25 import os
26 import smtplib
27 import sys
28 import time
29 from email.MIMEText import MIMEText
30
31 buildfarm = StormCachingBuildFarm()
32
33 db = buildfarm.hostdb
34
35 def update_rsyncd_secrets():
36     temp_rsyncd_secrets = os.path.join(os.path.dirname(__file__), "../rsyncd.secrets.new")
37     f = open(temp_rsyncd_secrets, "w")
38     f.writelines(db.create_rsync_secrets())
39     f.close()
40
41     os.rename(temp_rsyncd_secrets, "../rsyncd.secrets")
42
43 def update_hosts_list():
44     temp_hosts_list_file = os.path.join(os.path.dirname(__file__), "web", "hosts.list.new")
45     f = open(temp_hosts_list_file, "w")
46     f.writelines(db.create_hosts_list())
47     f.close()
48
49     os.rename(temp_hosts_list_file, os.path.join(os.path.dirname(__file__), "web/hosts.list"))
50
51 dry_run = False
52
53 print "Samba Build farm management tool"
54 print "================================"
55
56 if len(sys.argv) > 1:
57     op = sys.argv[1]
58 else:
59     print "Add Machine to build farm:      add"
60     print "Remove Machine from build farm: remove"
61     print "Modify build farm account:      modify"
62     print "Print build farm host info:     info"
63     print "Print build farm host list:     list"
64
65     op = raw_input("Select Operation: [add] ").lower()
66
67     if op == "":
68         op = "add"
69
70 if op == "remove":
71     hostname = raw_input("Please enter hostname to delete: ")
72     try:
73         db.deletehost(hostname)
74     except hostdb.NoSuchHost, e:
75         print "No such host '%s'" % e.name
76         sys.exit(1)
77     else:
78         db.commit()
79         update_rsyncd_secrets()
80         update_hosts_list()
81 elif op == "modify":
82     hostname = raw_input("Please enter hostname to modify: ")
83     try:
84         host = db[hostname]
85     except hostdb.NoSuchHost, e:
86         print "No such host '%s'" % e.name
87         sys.exit(1)
88     print "Owner: %s <%s>" % host.owner
89     print "Platform: %s" % host.platform
90     print ""
91     mod_op = raw_input("Modify owner or platform: [platform] ")
92     if mod_op == "":
93         mod_op = "platform"
94     if mod_op == "platform":
95         platform = raw_input("Enter new platform: ")
96         host.update_platform(platform)
97         db.commit()
98     elif mod_op == "owner":
99         owner = raw_input("Enter new owner's name: ")
100         owner_email = raw_input("Enter new owner's e-mail address: ")
101         host.update_owner(owner, owner_email.decode("utf-8"))
102         db.commit()
103     else:
104         print "Unknown subcommand %s" % mod_op
105         sys.exit(1)
106     update_rsyncd_secrets()
107     update_hosts_list()
108 elif op == "add":
109     hostname = raw_input("Machine hostname: ")
110     try:
111         db[hostname]
112     except hostdb.NoSuchHost, e:
113         pass
114     else:
115         print "A host with the name %s already exists." % e.name
116         sys.exit(1)
117     platform = raw_input("Machine platform (eg Fedora 9 x86_64): ")
118     owner = raw_input("Machine Owner Name: ")
119     owner_email = raw_input("Machine Owner E-mail: ")
120     password = raw_input("Enter password: [generate random] ")
121     if password == "":
122         password = commands.getoutput("pwgen 16 1").strip()
123         print "Password will be: %s" % password
124     permission = []
125     print "Enter permission e-mail, finish with a ."
126     line = raw_input("")
127     while line != ".":
128         permission += line
129         line = raw_input("")
130
131     try:
132         db.createhost(hostname, platform.decode("utf-8"),
133             owner.decode("utf-8"), owner_email.decode("utf-8"),
134             password.decode("utf-8"),
135             "".join(permission).decode("utf-8", "replace"))
136     except hostdb.HostAlreadyExists, e:
137         print "A host with the name %s already exists." % e.name
138         sys.exit(1)
139     else:
140         db.commit()
141
142     body = """
143 Welcome to the Samba.org build farm.  
144
145 Your host %(hostname)s has been added to the Samba Build farm.  
146
147 We have recorded that it is running %(platform)s.  
148
149 If you have not already done so, please read:
150 http://build.samba.org/instructions.html
151
152 The password for your rsync .password file is %(password)s
153
154 An e-mail asking you to subscribe to the build-farmers mailing
155 list will arrive shortly.  Please ensure you maintain your 
156 subscription to this list while you have hosts in the build farm.
157
158 Thank you for your contribution to ensuring portability and quality
159 of Samba.org projects.
160
161
162 """ % { "hostname": hostname, "platform": platform, "password": password }
163
164     msg_notification = MIMEText(body)
165
166     # send the password in an e-mail to that address
167     msg_notification["Subject"] = "Your new build farm host %s" % hostname
168     msg_notification["To"] = "\"%s\" <%s>" % (owner, owner_email)
169     msg_notification["Bcc"] = "build@samba.org"
170     msg_notification["From"] = "\"Samba Build Farm\" <build@samba.org>"
171
172     msg_subscribe = MIMEText("""Please subscribe %s to the build-farmers mailing list
173
174 Thanks, your friendly Samba build farm administrator <build@samba.org>""" % owner)
175     msg_subscribe["From"] = "\"%s\" <%s>" % (owner, owner_email)
176     msg_subscribe["Subject"] = 'Subscribe to build-farmers mailing list'
177     msg_subscribe["To"] = 'build-farmers-join@lists.samba.org'
178
179     if dry_run:
180         print msg_notification
181     else:
182         s = smtplib.SMTP()
183         s.connect()
184         for msg in (msg_notification, msg_subscribe):
185             recipients = [msg["To"]]
186             if msg["Bcc"]:
187                 recipients.append(msg["Bcc"])
188             s.sendmail(msg["From"], recipients, msg.as_string())
189         s.quit()
190         update_rsyncd_secrets()
191         update_hosts_list()
192 elif op == "info":
193     hostname = raw_input("Hostname: ")
194     try:
195         host = db[hostname]
196     except hostdb.NoSuchHost, e:
197         print "No such host '%s'" % e.name
198         sys.exit(1)
199     if host.fqdn:
200         opt_fqdn = " (%s)" % host.fqdn
201     else:
202         opt_fqdn = ""
203     print "Host: %s%s" % (host.name, opt_fqdn)
204     print "Platform: %s" % host.platform
205     print "Owner: %s <%s>" % host.owner
206 elif op == "list":
207     for host in db.host_ages():
208         if host.last_update:
209             age = time.time() - host.last_update
210         else:
211             age = ""
212         print "%-12s %s" % (age, host.name)
213 else:
214     print "Unknown command %s" % op
215     sys.exit(1)