]> git.decadent.org.uk Git - dak.git/blob - dak/new_security_install.py
auto-decruft: Expand NVI in cmd line argument names
[dak.git] / dak / new_security_install.py
1 #!/usr/bin/env python
2
3 """
4 Do whatever is needed to get a security upload released
5
6 @contact: Debian FTP Master <ftpmaster@debian.org>
7 @copyright: 2010 Joerg Jaspert <joerg@debian.org>
8 @license: GNU General Public License version 2 or later
9 """
10
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
15
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25 ################################################################################
26
27
28 ################################################################################
29
30 import os
31 import sys
32 import time
33 import apt_pkg
34 import commands
35
36 from daklib import queue
37 from daklib import daklog
38 from daklib import utils
39 from daklib.dbconn import *
40 from daklib.regexes import re_taint_free
41 from daklib.config import Config
42
43 Options = None
44 Logger = None
45 Queue = None
46 changes = []
47
48 def usage():
49     print """Usage: dak security-install [OPTIONS] changesfiles
50 Do whatever there is to do for a security release
51
52     -h, --help                 show this help and exit
53     -n, --no-action            don't commit changes
54     -s, --sudo                 dont bother, used internally
55
56 """
57     sys.exit()
58
59
60 def spawn(command):
61     if not re_taint_free.match(command):
62         utils.fubar("Invalid character in \"%s\"." % (command))
63
64     if Options["No-Action"]:
65         print "[%s]" % (command)
66     else:
67         (result, output) = commands.getstatusoutput(command)
68         if (result != 0):
69             utils.fubar("Invocation of '%s' failed:\n%s\n" % (command, output), result)
70
71 ##################### ! ! ! N O T E ! ! !  #####################
72 #
73 # These functions will be reinvoked by semi-priveleged users, be careful not
74 # to invoke external programs that will escalate privileges, etc.
75 #
76 ##################### ! ! ! N O T E ! ! !  #####################
77
78 def sudo(arg, fn, exit):
79     if Options["Sudo"]:
80         os.spawnl(os.P_WAIT, "/usr/bin/sudo", "/usr/bin/sudo", "-u", "dak", "-H",
81                   "/usr/local/bin/dak", "new-security-install", "-"+arg)
82     else:
83         fn()
84     if exit:
85         quit()
86
87 def do_Approve(): sudo("A", _do_Approve, True)
88 def _do_Approve():
89     print "Locking unchecked"
90     lockfile='/srv/security-master.debian.org/lock/unchecked.lock'
91     spawn("lockfile -r42 {0}".format(lockfile))
92
93     try:
94         # 1. Install accepted packages
95         print "Installing accepted packages into security archive"
96         for queue in ("embargoed",):
97             spawn("dak process-policy {0}".format(queue))
98
99         # 3. Run all the steps that are needed to publish the changed archive
100         print "Domination"
101         spawn("dak dominate")
102         print "Updating Packages and Sources files... This may take a while, be patient"
103         spawn("/srv/security-master.debian.org/dak/config/debian-security/map.sh")
104         spawn("dak generate-packages-sources2 -a security")
105         print "Updating Release files..."
106         spawn("dak generate-releases -a security")
107         print "Triggering security mirrors... (this may take a while)"
108         spawn("/srv/security-master.debian.org/dak/config/debian-security/make-mirror.sh")
109         spawn("sudo -u archvsync -H /home/archvsync/signal_security")
110         print "Triggering metadata export for packages.d.o and other consumers"
111         spawn("/srv/security-master.debian.org/dak/config/debian-security/export.sh")
112     finally:
113         os.unlink(lockfile)
114         print "Lock released."
115
116 ########################################################################
117 ########################################################################
118
119 def main():
120     global Options, Logger, Queue, changes
121     cnf = Config()
122
123     Arguments = [('h', "Help",      "Security::Options::Help"),
124                  ('n', "No-Action", "Security::Options::No-Action"),
125                  ('c', 'Changesfile', "Security::Options::Changesfile"),
126                  ('s', "Sudo", "Security::Options::Sudo"),
127                  ('A', "Approve", "Security::Options::Approve")
128                  ]
129
130     for i in ["Help", "No-Action", "Changesfile", "Sudo", "Approve"]:
131         if not cnf.has_key("Security::Options::%s" % (i)):
132             cnf["Security::Options::%s" % (i)] = ""
133
134     changes_files = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
135
136     Options = cnf.subtree("Security::Options")
137     if Options['Help']:
138         usage()
139
140     changesfiles={}
141     for a in changes_files:
142         if not a.endswith(".changes"):
143             utils.fubar("not a .changes file: %s" % (a))
144         changesfiles[a]=1
145     changes = changesfiles.keys()
146
147     username = utils.getusername()
148     if username != "dak":
149         print "Non-dak user: %s" % username
150         Options["Sudo"] = "y"
151
152     if Options["No-Action"]:
153         Options["Sudo"] = ""
154
155     if not Options["Sudo"] and not Options["No-Action"]:
156         Logger = daklog.Logger("security-install")
157
158     session = DBConn().session()
159
160     # If we call ourselve to approve, we do just that and exit
161     if Options["Approve"]:
162         do_Approve()
163         sys.exit()
164
165     if len(changes) == 0:
166         utils.fubar("Need changes files as arguments")
167
168     # Yes, we could do this inside do_Approve too. But this way we see who exactly
169     # called it (ownership of the file)
170
171     acceptfiles={}
172     for change in changes:
173         dbchange=get_dbchange(os.path.basename(change), session)
174         # strip epoch from version
175         version=dbchange.version
176         version=version[(version.find(':')+1):]
177         acceptfilename="%s/COMMENTS/ACCEPT.%s_%s" % (os.path.dirname(os.path.abspath(changes[0])), dbchange.source, version)
178         acceptfiles[acceptfilename]=1
179
180     print "Would create %s now and then go on to accept this package, if you allow me to." % (acceptfiles.keys())
181     if Options["No-Action"]:
182         sys.exit(0)
183     else:
184         raw_input("Press Enter to continue")
185
186     for acceptfilename in acceptfiles.keys():
187         accept_file = file(acceptfilename, "w")
188         accept_file.write("OK\n")
189         accept_file.close()
190
191     do_Approve()
192
193
194 if __name__ == '__main__':
195     main()