]> git.donarmstrong.com Git - dak.git/blob - dak/admin.py
Remove old (and slow) code
[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 import daklib.archive
27 import daklib.gpg
28
29 from daklib import utils
30 from daklib.dbconn import *
31 from sqlalchemy.orm.exc import NoResultFound
32
33 ################################################################################
34
35 dispatch = {}
36 dryrun = False
37
38 ################################################################################
39 def warn(msg):
40     print >> sys.stderr, msg
41
42 def die(msg, exit_code=1):
43     print >> sys.stderr, msg
44     sys.exit(exit_code)
45
46 def die_arglen(args, args_needed, msg):
47     if len(args) < args_needed:
48         die(msg)
49
50 def usage(exit_code=0):
51     """Perform administrative work on the dak database."""
52
53     print """Usage: dak admin COMMAND
54 Perform administrative work on the dak database.
55
56   -h, --help          show this help and exit.
57   -n, --dry-run       don't do anything, just show what would have been done
58                       (only applies to add or rm operations).
59
60   Commands can use a long or abbreviated form:
61
62   config / c:
63      c db                   show db config
64      c db-shell             show db config in a usable form for psql
65      c NAME                 show option NAME as set in configuration table
66
67   keyring / k:
68      k list-all             list all keyrings
69      k list-binary          list all keyrings with a NULL source acl
70      k list-source          list all keyrings with a non NULL source acl
71      k add-buildd NAME ARCH...   add buildd keyring with upload permission
72                                  for the given architectures
73
74   architecture / a:
75      a list                 show a list of architectures
76      a rm ARCH              remove an architecture (will only work if
77                             no longer linked to any suites)
78      a add ARCH DESCRIPTION [SUITELIST]
79                             add architecture ARCH with DESCRIPTION.
80                             If SUITELIST is given, add to each of the
81                             suites at the same time
82
83   component:
84      component list         show a list of components
85      component rm COMPONENT remove a component (will only work if
86                             empty)
87      component add NAME DESCRIPTION ORDERING
88                             add component NAME with DESCRIPTION.
89                             Ordered at ORDERING.
90
91   suite / s:
92      s list [--print-archive]
93                             show a list of suites
94      s show SUITE           show config details for a suite
95      s add SUITE VERSION [ label=LABEL ] [ description=DESCRIPTION ]
96                          [ origin=ORIGIN ] [ codename=CODENAME ]
97                          [ signingkey=SIGNINGKEY ] [ archive=ARCHIVE ]
98                             add suite SUITE, version VERSION.
99                             label, description, origin, codename
100                             and signingkey are optional.
101
102      s add-all-arches SUITE VERSION... as "s add" but adds suite-architecture
103                             relationships for all architectures
104
105   suite-architecture / s-a:
106      s-a list               show the architectures for all suites
107      s-a list-suite ARCH    show the suites an ARCH is in
108      s-a list-arch SUITE    show the architectures in a SUITE
109      s-a add SUITE ARCH     add ARCH to suite
110      s-a rm SUITE ARCH      remove ARCH from suite (will only work if
111                             no packages remain for the arch in the suite)
112
113   suite-component / s-c:
114      s-c list               show the architectures for all suites
115      s-c list-suite COMPONENT
116                             show the suites a COMPONENT is in
117      s-c list-component SUITE
118                             show the components in a SUITE
119      s-c add SUITE COMPONENT
120                             add COMPONENT to suite
121      s-c rm SUITE COMPONENT remove component from suite (will only work if
122                             no packages remain for the component in the suite)
123
124   archive:
125      archive list           list all archives
126      archive add NAME ROOT DESCRIPTION [primary-mirror=MIRROR] [tainted=1]
127                             add archive NAME with path ROOT,
128                             primary mirror MIRROR.
129      archive rm NAME        remove archive NAME (will only work if there are
130                             no files and no suites in the archive)
131      archive rename OLD NEW rename archive OLD to NEW
132
133   version-check / v-c:
134      v-c list                        show version checks for all suites
135      v-c list-suite SUITE            show version checks for suite SUITE
136      v-c add SUITE CHECK REFERENCE   add a version check for suite SUITE
137      v-c rm SUITE CHECK REFERENCE    remove a version check
138        where
139          CHECK     is one of Enhances, MustBeNewerThan, MustBeOlderThan
140          REFERENCE is another suite name
141
142   change-component:
143      change-component SUITE COMPONENT source SOURCE...
144      change-component SUITE COMPONENT binary BINARY...
145          Move source or binary packages to a different component by copying
146          associated files and changing the overrides.
147
148   forget-signature FILE:    forget that we saw FILE
149 """
150     sys.exit(exit_code)
151
152 ################################################################################
153
154 def __architecture_list(d, args):
155     q = d.session().query(Architecture).order_by(Architecture.arch_string)
156     for j in q.all():
157         # HACK: We should get rid of source from the arch table
158         if j.arch_string == 'source': continue
159         print j.arch_string
160     sys.exit(0)
161
162 def __architecture_add(d, args):
163     die_arglen(args, 4, "E: adding an architecture requires a name and a description")
164     print "Adding architecture %s" % args[2]
165     suites = [str(x) for x in args[4:]]
166     if len(suites) > 0:
167         print "Adding to suites %s" % ", ".join(suites)
168     if not dryrun:
169         try:
170             s = d.session()
171             a = Architecture()
172             a.arch_string = str(args[2]).lower()
173             a.description = str(args[3])
174             s.add(a)
175             for sn in suites:
176                 su = get_suite(sn, s)
177                 if su is not None:
178                     a.suites.append(su)
179                 else:
180                     warn("W: Cannot find suite %s" % su)
181             s.commit()
182         except IntegrityError as e:
183             die("E: Integrity error adding architecture %s (it probably already exists)" % args[2])
184         except SQLAlchemyError as e:
185             die("E: Error adding architecture %s (%s)" % (args[2], e))
186     print "Architecture %s added" % (args[2])
187
188 def __architecture_rm(d, args):
189     die_arglen(args, 3, "E: removing an architecture requires at least a name")
190     print "Removing architecture %s" % args[2]
191     if not dryrun:
192         try:
193             s = d.session()
194             a = get_architecture(args[2].lower(), s)
195             if a is None:
196                 die("E: Cannot find architecture %s" % args[2])
197             s.delete(a)
198             s.commit()
199         except IntegrityError as e:
200             die("E: Integrity error removing architecture %s (suite-arch entries probably still exist)" % args[2])
201         except SQLAlchemyError as e:
202             die("E: Error removing architecture %s (%s)" % (args[2], e))
203     print "Architecture %s removed" % args[2]
204
205 def architecture(command):
206     args = [str(x) for x in command]
207     Cnf = utils.get_conf()
208     d = DBConn()
209
210     die_arglen(args, 2, "E: architecture needs at least a command")
211
212     mode = args[1].lower()
213     if mode == 'list':
214         __architecture_list(d, args)
215     elif mode == 'add':
216         __architecture_add(d, args)
217     elif mode == 'rm':
218         __architecture_rm(d, args)
219     else:
220         die("E: architecture command unknown")
221
222 dispatch['architecture'] = architecture
223 dispatch['a'] = architecture
224
225 ################################################################################
226
227 def component_list():
228     session = DBConn().session()
229     for component in session.query(Component).order_by(Component.component_name):
230         print "{0} ordering={1}".format(component.component_name, component.ordering)
231
232 def component_add(args):
233     (name, description, ordering) = args[0:3]
234
235     attributes = dict(
236         component_name=name,
237         description=description,
238         ordering=ordering,
239         )
240
241     for option in args[3:]:
242         (key, value) = option.split('=')
243         attributes[key] = value
244
245     session = DBConn().session()
246
247     component = Component()
248     for key, value in attributes.iteritems():
249         setattr(component, key, value)
250
251     session.add(component)
252     session.flush()
253
254     if dryrun:
255         session.rollback()
256     else:
257         session.commit()
258
259 def component_rm(name):
260     session = DBConn().session()
261     component = get_component(name, session)
262     session.delete(component)
263     session.flush()
264
265     if dryrun:
266         session.rollback()
267     else:
268         session.commit()
269
270 def component_rename(oldname, newname):
271     session = DBConn().session()
272     component = get_component(oldname, session)
273     component.component_name = newname
274     session.flush()
275
276     if dryrun:
277         session.rollback()
278     else:
279         session.commit()
280
281 def component(command):
282     mode = command[1]
283     if mode == 'list':
284         component_list()
285     elif mode == 'rename':
286         component_rename(command[2], command[3])
287     elif mode == 'add':
288         component_add(command[2:])
289     elif mode == 'rm':
290         component_rm(command[2])
291     else:
292         die("E: component command unknown")
293
294 dispatch['component'] = component
295
296 ################################################################################
297
298 def __suite_list(d, args):
299     s = d.session()
300     for j in s.query(Suite).join(Suite.archive).order_by(Archive.archive_name, Suite.suite_name).all():
301         if len(args) > 2 and args[2] == "--print-archive":
302             print "{0} {1}".format(j.archive.archive_name, j.suite_name)
303         else:
304             print "{0}".format(j.suite_name)
305
306 def __suite_show(d, args):
307     if len(args) < 2:
308         die("E: showing an suite entry requires a suite")
309
310     s = d.session()
311     su = get_suite(args[2].lower())
312     if su is None:
313         die("E: can't find suite entry for %s" % (args[2].lower()))
314
315     print su.details()
316
317 def __suite_add(d, args, addallarches=False):
318     die_arglen(args, 4, "E: adding a suite requires at least a name and a version")
319     suite_name = args[2].lower()
320     version = args[3]
321     rest = args[3:]
322
323     def get_field(field):
324         for varval in args:
325             if varval.startswith(field + '='):
326                 return varval.split('=')[1]
327         return None
328
329     print "Adding suite %s" % suite_name
330     if not dryrun:
331         try:
332             s = d.session()
333             suite = Suite()
334             suite.suite_name = suite_name
335             suite.overridecodename = suite_name
336             suite.version = version
337             suite.label = get_field('label')
338             suite.description = get_field('description')
339             suite.origin = get_field('origin')
340             suite.codename = get_field('codename')
341             signingkey = get_field('signingkey')
342             if signingkey is not None:
343                 suite.signingkeys = [signingkey.upper()]
344             archive_name = get_field('archive')
345             if archive_name is not None:
346                 suite.archive = get_archive(archive_name, s)
347             else:
348                 suite.archive = s.query(Archive).filter(~Archive.archive_name.in_(['build-queues', 'new', 'policy'])).one()
349             suite.srcformats = s.query(SrcFormat).all()
350             s.add(suite)
351             s.flush()
352         except IntegrityError as e:
353             die("E: Integrity error adding suite %s (it probably already exists)" % suite_name)
354         except SQLAlchemyError as e:
355             die("E: Error adding suite %s (%s)" % (suite_name, e))
356     print "Suite %s added" % (suite_name)
357
358     if addallarches:
359         arches = []
360         q = s.query(Architecture).order_by(Architecture.arch_string)
361         for arch in q.all():
362             suite.architectures.append(arch)
363             arches.append(arch.arch_string)
364
365         print "Architectures %s added to %s" % (','.join(arches), suite_name)
366
367     s.commit()
368
369 def __suite_rm(d, args):
370     die_arglen(args, 3, "E: removing a suite requires at least a name")
371     name = args[2]
372     print "Removing suite {0}".format(name)
373     if not dryrun:
374         try:
375             s = d.session()
376             su = get_suite(name.lower())
377             if su is None:
378                 die("E: Cannot find suite {0}".format(name))
379             s.delete(su)
380             s.commit()
381         except IntegrityError as e:
382             die("E: Integrity error removing suite {0} (suite-arch entries probably still exist)".format(name))
383         except SQLAlchemyError as e:
384             die("E: Error removing suite {0} ({1})".format(name, e))
385     print "Suite {0} removed".format(name)
386
387 def suite(command):
388     args = [str(x) for x in command]
389     Cnf = utils.get_conf()
390     d = DBConn()
391
392     die_arglen(args, 2, "E: suite needs at least a command")
393
394     mode = args[1].lower()
395
396     if mode == 'list':
397         __suite_list(d, args)
398     elif mode == 'show':
399         __suite_show(d, args)
400     elif mode == 'rm':
401         __suite_rm(d, args)
402     elif mode == 'add':
403         __suite_add(d, args, False)
404     elif mode == 'add-all-arches':
405         __suite_add(d, args, True)
406     else:
407         die("E: suite command unknown")
408
409 dispatch['suite'] = suite
410 dispatch['s'] = suite
411
412 ################################################################################
413
414 def __suite_architecture_list(d, args):
415     s = d.session()
416     for j in s.query(Suite).order_by(Suite.suite_name):
417         architectures = j.get_architectures(skipsrc = True, skipall = True)
418         print j.suite_name + ': ' + \
419               ', '.join([a.arch_string for a in architectures])
420
421 def __suite_architecture_listarch(d, args):
422     die_arglen(args, 3, "E: suite-architecture list-arch requires a suite")
423     suite = get_suite(args[2].lower(), d.session())
424     if suite is None:
425         die('E: suite %s is invalid' % args[2].lower())
426     a = suite.get_architectures(skipsrc = True, skipall = True)
427     for j in a:
428         print j.arch_string
429
430
431 def __suite_architecture_listsuite(d, args):
432     die_arglen(args, 3, "E: suite-architecture list-suite requires an arch")
433     architecture = get_architecture(args[2].lower(), d.session())
434     if architecture is None:
435         die("E: architecture %s is invalid" % args[2].lower())
436     for j in architecture.suites:
437         print j.suite_name
438
439
440 def __suite_architecture_add(d, args):
441     if len(args) < 3:
442         die("E: adding a suite-architecture entry requires a suite and arch")
443
444     s = d.session()
445
446     suite = get_suite(args[2].lower(), s)
447     if suite is None: die("E: Can't find suite %s" % args[2].lower())
448
449     for arch_name in args[3:]:
450         arch = get_architecture(arch_name.lower(), s)
451         if arch is None: die("E: Can't find architecture %s" % args[3].lower())
452
453         try:
454             suite.architectures.append(arch)
455             s.flush()
456         except IntegrityError as e:
457             die("E: Can't add suite-architecture entry (%s, %s) - probably already exists" % (args[2].lower(), arch_name))
458         except SQLAlchemyError as e:
459             die("E: Can't add suite-architecture entry (%s, %s) - %s" % (args[2].lower(), arch_name, e))
460
461         print "Added suite-architecture entry for %s, %s" % (args[2].lower(), arch_name)
462
463     if not dryrun:
464         s.commit()
465
466     s.close()
467
468 def __suite_architecture_rm(d, args):
469     if len(args) < 3:
470         die("E: removing an suite-architecture entry requires a suite and arch")
471
472     s = d.session()
473     if not dryrun:
474         try:
475             suite_name = args[2].lower()
476             suite = get_suite(suite_name, s)
477             if suite is None:
478                 die('E: no such suite %s' % suite_name)
479             arch_string = args[3].lower()
480             architecture = get_architecture(arch_string, s)
481             if architecture not in suite.architectures:
482                 die("E: architecture %s not found in suite %s" % (arch_string, suite_name))
483             suite.architectures.remove(architecture)
484             s.commit()
485         except IntegrityError as e:
486             die("E: Can't remove suite-architecture entry (%s, %s) - it's probably referenced" % (args[2].lower(), args[3].lower()))
487         except SQLAlchemyError as e:
488             die("E: Can't remove suite-architecture entry (%s, %s) - %s" % (args[2].lower(), args[3].lower(), e))
489
490     print "Removed suite-architecture entry for %s, %s" % (args[2].lower(), args[3].lower())
491
492
493 def suite_architecture(command):
494     args = [str(x) for x in command]
495     Cnf = utils.get_conf()
496     d = DBConn()
497
498     die_arglen(args, 2, "E: suite-architecture needs at least a command")
499
500     mode = args[1].lower()
501
502     if mode == 'list':
503         __suite_architecture_list(d, args)
504     elif mode == 'list-arch':
505         __suite_architecture_listarch(d, args)
506     elif mode == 'list-suite':
507         __suite_architecture_listsuite(d, args)
508     elif mode == 'add':
509         __suite_architecture_add(d, args)
510     elif mode == 'rm':
511         __suite_architecture_rm(d, args)
512     else:
513         die("E: suite-architecture command unknown")
514
515 dispatch['suite-architecture'] = suite_architecture
516 dispatch['s-a'] = suite_architecture
517
518 ################################################################################
519
520 def __suite_component_list(d, args):
521     s = d.session()
522     for j in s.query(Suite).order_by(Suite.suite_name):
523         components = j.components
524         print j.suite_name + ': ' + \
525               ', '.join([c.component_name for c in components])
526
527
528 def __suite_component_listcomponent(d, args):
529      die_arglen(args, 3, "E: suite-component list-component requires a suite")
530      suite = get_suite(args[2].lower(), d.session())
531      if suite is None:
532          die('E: suite %s is invalid' % args[2].lower())
533      for c in suite.components:
534          print c.component_name
535
536
537 def __suite_component_listsuite(d, args):
538      die_arglen(args, 3, "E: suite-component list-suite requires an component")
539      component = get_component(args[2].lower(), d.session())
540      if component is None:
541          die("E: component %s is invalid" % args[2].lower())
542      for s in component.suites:
543          print s.suite_name
544
545
546 def __suite_component_add(d, args):
547      if len(args) < 3:
548          die("E: adding a suite-component entry requires a suite and component")
549
550      s = d.session()
551
552      suite = get_suite(args[2].lower(), s)
553      if suite is None: die("E: Can't find suite %s" % args[2].lower())
554
555      for component_name in args[3:]:
556          component = get_component(component_name.lower(), s)
557          if component is None: die("E: Can't find component %s" % args[3].lower())
558
559          try:
560              suite.components.append(component)
561              s.flush()
562          except IntegrityError as e:
563              die("E: Can't add suite-component entry (%s, %s) - probably already exists" % (args[2].lower(), component_name))
564          except SQLAlchemyError as e:
565              die("E: Can't add suite-component entry (%s, %s) - %s" % (args[2].lower(), component_name, e))
566
567          print "Added suite-component entry for %s, %s" % (args[2].lower(), component_name)
568
569      if not dryrun:
570          s.commit()
571      s.close()
572
573 def __suite_component_rm(d, args):
574      if len(args) < 3:
575          die("E: removing an suite-component entry requires a suite and component")
576
577      s = d.session()
578      if not dryrun:
579          try:
580              suite_name = args[2].lower()
581              suite = get_suite(suite_name, s)
582              if suite is None:
583                  die('E: no such suite %s' % suite_name)
584              component_string = args[3].lower()
585              component = get_component(arch_string, s)
586              if component not in suite.components:
587                  die("E: component %s not found in suite %s" % (component_string, suite_name))
588              suite.components.remove(component)
589              s.commit()
590          except IntegrityError as e:
591              die("E: Can't remove suite-component entry (%s, %s) - it's probably referenced" % (args[2].lower(), args[3].lower()))
592          except SQLAlchemyError as e:
593              die("E: Can't remove suite-component entry (%s, %s) - %s" % (args[2].lower(), args[3].lower(), e))
594
595      print "Removed suite-component entry for %s, %s" % (args[2].lower(), args[3].lower())
596
597
598 def suite_component(command):
599     args = [str(x) for x in command]
600     Cnf = utils.get_conf()
601     d = DBConn()
602
603     die_arglen(args, 2, "E: suite-component needs at least a command")
604
605     mode = args[1].lower()
606
607     if mode == 'list':
608         __suite_component_list(d, args)
609     elif mode == 'list-component':
610         __suite_component_listcomponent(d, args)
611     elif mode == 'list-suite':
612         __suite_component_listsuite(d, args)
613     elif mode == 'add':
614         __suite_component_add(d, args)
615     # elif mode == 'rm':
616     #     __suite_architecture_rm(d, args)
617     else:
618         die("E: suite-component command unknown")
619
620 dispatch['suite-component'] = suite_component
621 dispatch['s-c'] = suite_component
622
623 ################################################################################
624
625 def archive_list():
626     session = DBConn().session()
627     for archive in session.query(Archive).order_by(Archive.archive_name):
628         print "{0} path={1} description={2} tainted={3}".format(archive.archive_name, archive.path, archive.description, archive.tainted)
629
630 def archive_add(args):
631     (name, path, description) = args[0:3]
632
633     attributes = dict(
634         archive_name=name,
635         path=path,
636         description=description,
637         )
638
639     for option in args[3:]:
640         (key, value) = option.split('=')
641         attributes[key] = value
642
643     session = DBConn().session()
644
645     archive = Archive()
646     for key, value in attributes.iteritems():
647         setattr(archive, key, value)
648
649     session.add(archive)
650     session.flush()
651
652     if dryrun:
653         session.rollback()
654     else:
655         session.commit()
656
657 def archive_rm(name):
658     session = DBConn().session()
659     archive = get_archive(name, session)
660     session.delete(archive)
661     session.flush()
662
663     if dryrun:
664         session.rollback()
665     else:
666         session.commit()
667
668 def archive_rename(oldname, newname):
669     session = DBConn().session()
670     archive = get_archive(oldname, session)
671     archive.archive_name = newname
672     session.flush()
673
674     if dryrun:
675         session.rollback()
676     else:
677         session.commit()
678
679 def archive(command):
680     mode = command[1]
681     if mode == 'list':
682         archive_list()
683     elif mode == 'rename':
684         archive_rename(command[2], command[3])
685     elif mode == 'add':
686         archive_add(command[2:])
687     elif mode == 'rm':
688         archive_rm(command[2])
689     else:
690         die("E: archive command unknown")
691
692 dispatch['archive'] = archive
693
694 ################################################################################
695
696 def __version_check_list(d):
697     session = d.session()
698     for s in session.query(Suite).order_by(Suite.suite_name):
699         __version_check_list_suite(d, s.suite_name)
700
701 def __version_check_list_suite(d, suite_name):
702     vcs = get_version_checks(suite_name)
703     for vc in vcs:
704         print "%s %s %s" % (suite_name, vc.check, vc.reference.suite_name)
705
706 def __version_check_add(d, suite_name, check, reference_name):
707     suite = get_suite(suite_name)
708     if not suite:
709         die("E: Could not find suite %s." % (suite_name))
710     reference = get_suite(reference_name)
711     if not reference:
712         die("E: Could not find reference suite %s." % (reference_name))
713
714     session = d.session()
715     vc = VersionCheck()
716     vc.suite = suite
717     vc.check = check
718     vc.reference = reference
719     session.add(vc)
720     session.commit()
721
722 def __version_check_rm(d, suite_name, check, reference_name):
723     suite = get_suite(suite_name)
724     if not suite:
725         die("E: Could not find suite %s." % (suite_name))
726     reference = get_suite(reference_name)
727     if not reference:
728         die("E: Could not find reference suite %s." % (reference_name))
729
730     session = d.session()
731     try:
732       vc = session.query(VersionCheck).filter_by(suite=suite, check=check, reference=reference).one()
733       session.delete(vc)
734       session.commit()
735     except NoResultFound:
736       print "W: version-check not found."
737
738 def version_check(command):
739     args = [str(x) for x in command]
740     Cnf = utils.get_conf()
741     d = DBConn()
742
743     die_arglen(args, 2, "E: version-check needs at least a command")
744     mode = args[1].lower()
745
746     if mode == 'list':
747         __version_check_list(d)
748     elif mode == 'list-suite':
749         if len(args) != 3:
750             die("E: version-check list-suite needs a single parameter")
751         __version_check_list_suite(d, args[2])
752     elif mode == 'add':
753         if len(args) != 5:
754             die("E: version-check add needs three parameters")
755         __version_check_add(d, args[2], args[3], args[4])
756     elif mode == 'rm':
757         if len(args) != 5:
758             die("E: version-check rm needs three parameters")
759         __version_check_rm(d, args[2], args[3], args[4])
760     else:
761         die("E: version-check command unknown")
762
763 dispatch['version-check'] = version_check
764 dispatch['v-c'] = version_check
765
766 ################################################################################
767
768 def show_config(command):
769     args = [str(x) for x in command]
770     cnf = utils.get_conf()
771
772     die_arglen(args, 2, "E: config needs at least a command")
773
774     mode = args[1].lower()
775
776     if mode == 'db':
777         connstr = ""
778         if cnf.has_key("DB::Service"):
779             # Service mode
780             connstr = "postgresql://service=%s" % cnf["DB::Service"]
781         elif cnf.has_key("DB::Host"):
782             # TCP/IP
783             connstr = "postgres://%s" % cnf["DB::Host"]
784             if cnf.has_key("DB::Port") and cnf["DB::Port"] != "-1":
785                 connstr += ":%s" % cnf["DB::Port"]
786             connstr += "/%s" % cnf["DB::Name"]
787         else:
788             # Unix Socket
789             connstr = "postgres:///%s" % cnf["DB::Name"]
790             if cnf["DB::Port"] and cnf["DB::Port"] != "-1":
791                 connstr += "?port=%s" % cnf["DB::Port"]
792         print connstr
793     elif mode == 'db-shell':
794         e = []
795         if cnf.has_key("DB::Service"):
796             e.append('PGSERVICE')
797             print "PGSERVICE=%s" % cnf["DB::Service"]
798         if cnf.has_key("DB::Name"):
799             e.append('PGDATABASE')
800             print "PGDATABASE=%s" % cnf["DB::Name"]
801         if cnf.has_key("DB::Host"):
802             print "PGHOST=%s" % cnf["DB::Host"]
803             e.append('PGHOST')
804         if cnf.has_key("DB::Port") and cnf["DB::Port"] != "-1":
805             print "PGPORT=%s" % cnf["DB::Port"]
806             e.append('PGPORT')
807         print "export " + " ".join(e)
808     elif mode == 'get':
809         print cnf.get(args[2])
810     else:
811         session = DBConn().session()
812         try:
813             o = session.query(DBConfig).filter_by(name = mode).one()
814             print o.value
815         except NoResultFound:
816             print "W: option '%s' not set" % mode
817
818 dispatch['config'] = show_config
819 dispatch['c'] = show_config
820
821 ################################################################################
822
823 def show_keyring(command):
824     args = [str(x) for x in command]
825     cnf = utils.get_conf()
826
827     die_arglen(args, 2, "E: keyring needs at least a command")
828
829     mode = args[1].lower()
830
831     d = DBConn()
832
833     q = d.session().query(Keyring).filter(Keyring.active == True)
834
835     if mode == 'list-all':
836         pass
837     elif mode == 'list-binary':
838         q = q.join(Keyring.acl).filter(ACL.allow_source == False)
839     elif mode == 'list-source':
840         q = q.join(Keyring.acl).filter(ACL.allow_source == True)
841     else:
842         die("E: keyring command unknown")
843
844     for k in q.all():
845         print k.keyring_name
846
847 def keyring_add_buildd(command):
848     name = command[2]
849     arch_names = command[3:]
850
851     session = DBConn().session()
852     arches = session.query(Architecture).filter(Architecture.arch_string.in_(arch_names))
853
854     acl = ACL()
855     acl.name = 'buildd-{0}'.format('+'.join(arch_names))
856     acl.architectures.update(arches)
857     acl.allow_new = True
858     acl.allow_binary = True
859     acl.allow_binary_only = True
860     acl.allow_hijack = True
861     session.add(acl)
862
863     k = Keyring()
864     k.keyring_name = name
865     k.acl = acl
866     k.priority = 10
867     session.add(k)
868
869     session.commit()
870
871 def keyring(command):
872     if command[1].startswith('list-'):
873         show_keyring(command)
874     elif command[1] == 'add-buildd':
875         keyring_add_buildd(command)
876     else:
877         die("E: keyring command unknown")
878
879 dispatch['keyring'] = keyring
880 dispatch['k'] = keyring
881
882 ################################################################################
883
884 def change_component_source(transaction, suite, component, source_names):
885     session = transaction.session
886
887     overrides = session.query(Override).filter(Override.package.in_(source_names)).filter_by(suite=suite).join(OverrideType).filter_by(overridetype='dsc')
888     for override in overrides:
889         print "Changing override for {0}".format(override.package)
890         override.component = component
891     session.flush()
892
893     sources = session.query(DBSource).filter(DBSource.source.in_(source_names)).filter(DBSource.suites.contains(suite))
894     for source in sources:
895         print "Copying {0}={1}".format(source.source, source.version)
896         transaction.copy_source(source, suite, component)
897
898 def change_component_binary(transaction, suite, component, binary_names):
899     session = transaction.session
900
901     overrides = session.query(Override).filter(Override.package.in_(binary_names)).filter_by(suite=suite).join(OverrideType).filter(OverrideType.overridetype.in_(['deb', 'udeb']))
902     for override in overrides:
903         print "Changing override for {0}".format(override.package)
904         override.component = component
905     session.flush()
906
907     binaries = session.query(DBBinary).filter(DBBinary.package.in_(binary_names)).filter(DBBinary.suites.contains(suite))
908     for binary in binaries:
909         print "Copying {0}={1} [{2}]".format(binary.package, binary.version, binary.architecture.arch_string)
910         transaction.copy_binary(binary, suite, component)
911     pass
912
913 def change_component(args):
914     with daklib.archive.ArchiveTransaction() as transaction:
915         session = transaction.session
916
917         suite = session.query(Suite).filter_by(suite_name=args[1]).one()
918         component = session.query(Component).filter_by(component_name=args[2]).one()
919
920         if args[3] == 'source':
921             change_component_source(transaction, suite, component, args[4:])
922         elif args[3] == 'binary':
923             change_component_binary(transaction, suite, component, args[4:])
924         else:
925             raise Exception("Can only move source or binary, not {0}".format(args[3]))
926
927         transaction.commit()
928
929 dispatch['change-component'] = change_component
930
931 ################################################################################
932
933 def forget_signature(args):
934     filename = args[1]
935     with open(filename, 'r') as fh:
936         data = fh.read()
937
938     session = DBConn().session()
939     keyrings = [ k.keyring_name for k in session.query(Keyring).filter_by(active=True).order_by(Keyring.priority) ]
940     signed_file = daklib.gpg.SignedFile(data, keyrings)
941     history = SignatureHistory.from_signed_file(signed_file).query(session)
942     if history is not None:
943         session.delete(history)
944         session.commit()
945     else:
946         print "Signature was not known to dak."
947     session.rollback()
948
949 dispatch['forget-signature'] = forget_signature
950
951 ################################################################################
952
953 def main():
954     """Perform administrative work on the dak database"""
955     global dryrun
956     Cnf = utils.get_conf()
957     arguments = [('h', "help", "Admin::Options::Help"),
958                  ('n', "dry-run", "Admin::Options::Dry-Run")]
959     for i in [ "help", "dry-run" ]:
960         if not Cnf.has_key("Admin::Options::%s" % (i)):
961             Cnf["Admin::Options::%s" % (i)] = ""
962
963     arguments = apt_pkg.parse_commandline(Cnf, arguments, sys.argv)
964
965     options = Cnf.subtree("Admin::Options")
966     if options["Help"] or len(arguments) < 1:
967         usage()
968     if options["Dry-Run"]:
969         dryrun = True
970
971     subcommand = str(arguments[0])
972
973     if subcommand in dispatch.keys():
974         dispatch[subcommand](arguments)
975     else:
976         die("E: Unknown command")
977
978 ################################################################################
979
980 if __name__ == '__main__':
981     main()