]> git.decadent.org.uk Git - dak.git/blob - dak/admin.py
whitespace cleanup
[dak.git] / dak / admin.py
1 #!/usr/bin/env python
2
3 """Configure dak parameters in the database"""
4 # Copyright (C) 2009  Mark Hymers <mhy@debian.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 2 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, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 ################################################################################
21
22 import sys
23
24 import apt_pkg
25
26 from daklib import utils
27 from daklib.dbconn import *
28 from daklib.config import Config
29
30 ################################################################################
31
32 dispatch = {}
33 dryrun = False
34
35 ################################################################################
36 def warn(msg):
37     print >> sys.stderr, msg
38
39 def die(msg, exit_code=1):
40     print >> sys.stderr, msg
41     sys.exit(exit_code)
42
43 def die_arglen(args, args_needed, msg):
44     if len(args) < args_needed:
45         die(msg)
46
47 def usage(exit_code=0):
48     """Perform administrative work on the dak database."""
49
50     print """Usage: dak admin COMMAND
51 Perform administrative work on the dak database.
52
53   -h, --help          show this help and exit.
54   -n, --dry-run       don't do anything, just show what would have been done
55                       (only applies to add or rm operations).
56
57   Commands can use a long or abbreviated form:
58
59   architecture / a:
60      a list                 show a list of architectures
61      a rm ARCH              remove an architecture (will only work if
62                             no longer linked to any suites)
63      a add ARCH DESCRIPTION [SUITELIST]
64                             add architecture ARCH with DESCRIPTION.
65                             If SUITELIST is given, add to each of the
66                             suites at the same time
67
68   suite-architecture / s-a:
69      s-a list-suite ARCH    show the suites an ARCH is in
70      s-a list-arch SUITE    show the architectures in a SUITE
71      s-a add SUITE ARCH     add ARCH to suite
72      s-a rm SUITE ARCH      remove ARCH from suite (will only work if
73                             no packages remain for the arch in the suite)
74 """
75     sys.exit(exit_code)
76
77 ################################################################################
78
79 def __architecture_list(d, args):
80     q = d.session().query(Architecture).order_by('arch_string')
81     for j in q.all():
82         # HACK: We should get rid of source from the arch table
83         if j.arch_string == 'source': continue
84         print j.arch_string
85     sys.exit(0)
86
87 def __architecture_add(d, args):
88     die_arglen(args, 3, "E: adding an architecture requires a name and a description")
89     print "Adding architecture %s" % args[2]
90     suites = [str(x) for x in args[4:]]
91     print suites
92     if not dryrun:
93         try:
94             s = d.session()
95             a = Architecture()
96             a.arch_string = str(args[2]).lower()
97             a.description = str(args[3])
98             s.add(a)
99             for sn in suites:
100                 su = get_suite(sn ,s)
101                 if su is not None:
102                     archsu = SuiteArchitecture()
103                     archsu.arch_id = a.arch_id
104                     archsu.suite_id = su.suite_id
105                     s.add(archsu)
106                 else:
107                     warn("W: Cannot find suite %s" % su)
108             s.commit()
109         except IntegrityError, e:
110             die("E: Integrity error adding architecture %s (it probably already exists)" % args[2])
111         except SQLAlchemyError, e:
112             die("E: Error adding architecture %s (%s)" % (args[2], e))
113     print "Architecture %s added" % (args[2])
114
115 def __architecture_rm(d, args):
116     die_arglen(args, 3, "E: removing an architecture requires at least a name")
117     print "Removing architecture %s" % args[2]
118     if not dryrun:
119         try:
120             s = d.session()
121             a = get_architecture(args[2].lower(), s)
122             if a is None:
123                 die("E: Cannot find architecture %s" % args[2])
124             s.delete(a)
125             s.commit()
126         except IntegrityError, e:
127             die("E: Integrity error removing architecture %s (suite-arch entries probably still exist)" % args[2])
128         except SQLAlchemyError, e:
129             die("E: Error removing architecture %s (%s)" % (args[2], e))
130     print "Architecture %s removed" % args[2]
131
132 def architecture(command):
133     args = [str(x) for x in command]
134     Cnf = utils.get_conf()
135     d = DBConn()
136
137     die_arglen(args, 2, "E: architecture needs at least a command")
138
139     mode = args[1].lower()
140     if mode == 'list':
141         __architecture_list(d, args)
142     elif mode == 'add':
143         __architecture_add(d, args)
144     elif mode == 'rm':
145         __architecture_rm(d, args)
146     else:
147         die("E: architecture command unknown")
148
149 dispatch['architecture'] = architecture
150 dispatch['a'] = architecture
151
152 ################################################################################
153
154 def __suite_architecture_list(d, args):
155     s = d.session()
156     suites = s.query(Suite).all()
157     for j in s.query(Suite).order_by('suite_name').all():
158         print j.suite_name + ' ' + \
159               ','.join([a.architecture.arch_string for a in j.suitearchitectures])
160
161 def __suite_architecture_listarch(d, args):
162     die_arglen(args, 3, "E: suite-architecture list-arch requires a suite")
163     a = get_suite_architectures(args[2].lower())
164     for j in a:
165         # HACK: We should get rid of source from the arch table
166         if j.arch_string != 'source':
167             print j.arch_string
168
169
170 def __suite_architecture_listsuite(d, args):
171     die_arglen(args, 3, "E: suite-architecture list-suite requires an arch")
172     for j in get_architecture_suites(args[2].lower()):
173         print j.suite_name
174
175
176 def __suite_architecture_add(d, args):
177     if len(args) < 3:
178         die("E: adding a suite-architecture entry requires a suite and arch")
179
180     s = d.session()
181
182     suite = get_suite(args[2].lower(), s)
183     if suite is None: die("E: Can't find suite %s" % args[2].lower())
184
185     arch = get_architecture(args[3].lower(), s)
186     if arch is None: die("E: Can't find architecture %s" % args[3].lower())
187
188     if not dryrun:
189         try:
190             sa = SuiteArchitecture()
191             sa.arch_id = arch.arch_id
192             sa.suite_id = suite.suite_id
193             s.add(sa)
194             s.commit()
195         except IntegrityError, e:
196             die("E: Can't add suite-architecture entry (%s, %s) - probably already exists" % (args[2].lower(), args[3].lower()))
197         except SQLAlchemyError, e:
198             die("E: Can't add suite-architecture entry (%s, %s) - %s" % (args[2].lower(), args[3].lower(), e))
199
200     print "Added suite-architecture entry for %s, %s" % (args[2].lower(), args[3].lower())
201
202
203 def __suite_architecture_rm(d, args):
204     if len(args) < 3:
205         die("E: removing an suite-architecture entry requires a suite and arch")
206
207     s = d.session()
208     if not dryrun:
209         try:
210             sa = get_suite_architecture(args[2].lower(), args[3].lower(), s)
211             if sa is None:
212                 die("E: can't find suite-architecture entry for %s, %s" % (args[2].lower(), args[3].lower()))
213             s.delete(sa)
214             s.commit()
215         except IntegrityError, e:
216             die("E: Can't remove suite-architecture entry (%s, %s) - it's probably referenced" % (args[2].lower(), args[3].lower()))
217         except SQLAlchemyError, e:
218             die("E: Can't remove suite-architecture entry (%s, %s) - %s" % (args[2].lower(), args[3].lower(), e))
219
220     print "Removed suite-architecture entry for %s, %s" % (args[2].lower(), args[3].lower())
221
222
223 def suite_architecture(command):
224     args = [str(x) for x in command]
225     Cnf = utils.get_conf()
226     d = DBConn()
227
228     die_arglen(args, 2, "E: suite-architecture needs at least a command")
229
230     mode = args[1].lower()
231
232     if mode == 'list':
233         __suite_architecture_list(d, args)
234     elif mode == 'list-arch':
235         __suite_architecture_listarch(d, args)
236     elif mode == 'list-suite':
237         __suite_architecture_listsuite(d, args)
238     elif mode == 'add':
239         __suite_architecture_add(d, args)
240     elif mode == 'rm':
241         __suite_architecture_rm(d, args)
242     else:
243         die("E: suite-architecture command unknown")
244
245 dispatch['suite-architecture'] = suite_architecture
246 dispatch['s-a'] = suite_architecture
247
248 ################################################################################
249
250 def main():
251     """Perform administrative work on the dak database"""
252     global dryrun
253     Cnf = utils.get_conf()
254     arguments = [('h', "help", "Admin::Options::Help"),
255                  ('n', "dry-run", "Admin::Options::Dry-Run")]
256     for i in [ "help", "dry-run" ]:
257         if not Cnf.has_key("Admin::Options::%s" % (i)):
258             Cnf["Admin::Options::%s" % (i)] = ""
259
260     arguments = apt_pkg.ParseCommandLine(Cnf, arguments, sys.argv)
261
262     options = Cnf.SubTree("Admin::Options")
263     if options["Help"] or len(arguments) < 1:
264         usage()
265     if options["Dry-Run"]:
266         dryrun = True
267
268     subcommand = str(arguments[0])
269
270     if subcommand in dispatch.keys():
271         dispatch[subcommand](arguments)
272     else:
273         die("E: Unknown command")
274
275 ################################################################################
276
277 if __name__ == '__main__':
278     main()