1
2
3 """Microscopic modification and query tool for overrides in projectb"""
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 import os
29 import sys
30
31 import apt_pkg
32
33 from daklib import daklog, utils
34 from daklib.config import Config
35 from daklib.dbconn import (
36 DBConn,
37 get_override_type,
38 get_priority,
39 get_section,
40 get_suite,
41 )
42
43
44
45
46
47
49 answer = utils.input_or_exit("Continue (y/N)? ").lower()
50 if answer != "y":
51 print("Aborted.")
52 sys.exit(1)
53
54
56 print(
57 """Usage: dak override [OPTIONS] package [section] [priority]
58 Make microchanges or microqueries of the binary overrides
59
60 -h, --help show this help and exit
61 -c, --check check override compliance (deprecated)
62 -d, --done=BUG# send priority/section change as closure to bug#
63 -n, --no-action don't do anything
64 -s, --suite specify the suite to use
65 """
66 )
67 sys.exit(exit_code)
68
69
71 cnf = Config()
72
73 Arguments = [
74 ("h", "help", "Override::Options::Help"),
75 ("c", "check", "Override::Options::Check"),
76 ("d", "done", "Override::Options::Done", "HasArg"),
77 ("n", "no-action", "Override::Options::No-Action"),
78 ("s", "suite", "Override::Options::Suite", "HasArg"),
79 ]
80 for i in ["help", "check", "no-action"]:
81 key = "Override::Options::%s" % i
82 if key not in cnf:
83 cnf[key] = ""
84 if "Override::Options::Suite" not in cnf:
85 cnf["Override::Options::Suite"] = "unstable"
86
87 arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
88 Options = cnf.subtree("Override::Options")
89
90 if Options["Help"]:
91 usage()
92
93 session = DBConn().session()
94
95 if not arguments:
96 utils.fubar("package name is a required argument.")
97
98 package = arguments.pop(0)
99 suite_name = Options["Suite"]
100 if arguments and len(arguments) > 2:
101 utils.fubar("Too many arguments")
102
103 suite = get_suite(suite_name, session)
104 if suite is None:
105 utils.fubar("Unknown suite '{0}'".format(suite_name))
106
107 if arguments and len(arguments) == 1:
108
109 arg = arguments.pop()
110 q = session.execute(
111 """
112 SELECT ( SELECT COUNT(*) FROM section WHERE section = :arg ) AS secs,
113 ( SELECT COUNT(*) FROM priority WHERE priority = :arg ) AS prios
114 """,
115 {"arg": arg},
116 )
117 r = q.fetchall()
118 if r[0][0] == 1:
119 arguments = (arg, ".")
120 elif r[0][1] == 1:
121 arguments = (".", arg)
122 else:
123 utils.fubar("%s is not a valid section or priority" % (arg))
124
125
126 oldsection, oldsourcesection, oldpriority = None, None, None
127 for packagetype in ["source", "binary"]:
128 eqdsc = "!="
129 if packagetype == "source":
130 eqdsc = "="
131 q = session.execute(
132 """
133 SELECT priority.priority AS prio, section.section AS sect, override_type.type AS type
134 FROM override, priority, section, suite, override_type
135 WHERE override.priority = priority.id
136 AND override.type = override_type.id
137 AND override_type.type %s 'dsc'
138 AND override.section = section.id
139 AND override.package = :package
140 AND override.suite = suite.id
141 AND suite.suite_name = :suite_name
142 """
143 % (eqdsc),
144 {"package": package, "suite_name": suite_name},
145 )
146
147 if q.rowcount == 0:
148 continue
149 if q.rowcount > 1:
150 utils.fubar("%s is ambiguous. Matches %d packages" % (package, q.rowcount))
151
152 r = q.fetchone()
153 if packagetype == "binary":
154 oldsection = r[1]
155 oldpriority = r[0]
156 else:
157 oldsourcesection = r[1]
158 oldpriority = "optional"
159
160 if not oldpriority and not oldsourcesection:
161 utils.fubar("Unable to find package %s" % (package))
162
163 if oldsection and oldsourcesection and oldsection != oldsourcesection:
164
165 utils.warn(
166 "Source is in section '%s' instead of '%s'" % (oldsourcesection, oldsection)
167 )
168
169 if not oldsection:
170 oldsection = oldsourcesection
171
172 if not arguments:
173 print(
174 "%s is in section '%s' at priority '%s'"
175 % (package, oldsection, oldpriority)
176 )
177 sys.exit(0)
178
179
180 newsection, newpriority = arguments
181
182 if newsection == ".":
183 newsection = oldsection
184 if newpriority == ".":
185 newpriority = oldpriority
186
187 s = get_section(newsection, session)
188 if s is None:
189 utils.fubar("Supplied section %s is invalid" % (newsection))
190 newsecid = s.section_id
191
192 p = get_priority(newpriority, session)
193 if p is None:
194 utils.fubar("Supplied priority %s is invalid" % (newpriority))
195 newprioid = p.priority_id
196
197 if newpriority == oldpriority and newsection == oldsection:
198 print("I: Doing nothing")
199 sys.exit(0)
200
201 if Options["Check"]:
202 print("WARNING: Check option is deprecated by Debian Policy 4.0.1")
203
204
205 if Options["No-Action"]:
206 if newpriority != oldpriority:
207 print("I: Would change priority from %s to %s" % (oldpriority, newpriority))
208 if newsection != oldsection:
209 print("I: Would change section from %s to %s" % (oldsection, newsection))
210 if "Done" in Options:
211 print("I: Would also close bug(s): %s" % (Options["Done"]))
212
213 sys.exit(0)
214
215 if newpriority != oldpriority:
216 print("I: Will change priority from %s to %s" % (oldpriority, newpriority))
217
218 if newsection != oldsection:
219 print("I: Will change section from %s to %s" % (oldsection, newsection))
220
221 if "Done" not in Options:
222 pass
223
224 else:
225 print("I: Will close bug(s): %s" % (Options["Done"]))
226
227 game_over()
228
229 Logger = daklog.Logger("override")
230
231 dsc_otype_id = get_override_type("dsc").overridetype_id
232
233
234
235 if newpriority != oldpriority:
236 session.execute(
237 """
238 UPDATE override
239 SET priority = :newprioid
240 WHERE package = :package
241 AND override.type != :otypedsc
242 AND suite = (SELECT id FROM suite WHERE suite_name = :suite_name)""",
243 {
244 "newprioid": newprioid,
245 "package": package,
246 "otypedsc": dsc_otype_id,
247 "suite_name": suite_name,
248 },
249 )
250
251 Logger.log(["changed priority", package, oldpriority, newpriority])
252
253 if newsection != oldsection:
254 q = session.execute(
255 """
256 UPDATE override
257 SET section = :newsecid
258 WHERE package = :package
259 AND suite = (SELECT id FROM suite WHERE suite_name = :suite_name)""",
260 {"newsecid": newsecid, "package": package, "suite_name": suite_name},
261 )
262
263 Logger.log(["changed section", package, oldsection, newsection])
264
265 session.commit()
266
267 if "Done" in Options:
268 if "Dinstall::BugServer" not in cnf:
269 utils.warn(
270 "Asked to send Done message but Dinstall::BugServer is not configured"
271 )
272 Logger.close()
273 return
274
275 Subst = {}
276 Subst["__OVERRIDE_ADDRESS__"] = cnf["Dinstall::MyEmailAddress"]
277 Subst["__BUG_SERVER__"] = cnf["Dinstall::BugServer"]
278 bcc = []
279 if cnf.find("Dinstall::Bcc") != "":
280 bcc.append(cnf["Dinstall::Bcc"])
281 if bcc:
282 Subst["__BCC__"] = "Bcc: " + ", ".join(bcc)
283 else:
284 Subst["__BCC__"] = "X-Filler: 42"
285 if "Dinstall::PackagesServer" in cnf:
286 Subst["__CC__"] = (
287 "Cc: "
288 + package
289 + "@"
290 + cnf["Dinstall::PackagesServer"]
291 + "\nX-DAK: dak override"
292 )
293 else:
294 Subst["__CC__"] = "X-DAK: dak override"
295 Subst["__ADMIN_ADDRESS__"] = cnf["Dinstall::MyAdminAddress"]
296 Subst["__DISTRO__"] = cnf["Dinstall::MyDistribution"]
297 Subst["__WHOAMI__"] = utils.whoami()
298 Subst["__SOURCE__"] = package
299
300 summary = "Concerning package %s...\n" % (package)
301 summary += "Operating on the %s suite\n" % (suite_name)
302 if newpriority != oldpriority:
303 summary += "Changed priority from %s to %s\n" % (oldpriority, newpriority)
304 if newsection != oldsection:
305 summary += "Changed section from %s to %s\n" % (oldsection, newsection)
306 Subst["__SUMMARY__"] = summary
307
308 template = os.path.join(cnf["Dir::Templates"], "override.bug-close")
309 for bug in utils.split_args(Options["Done"]):
310 Subst["__BUG_NUMBER__"] = bug
311 mail_message = utils.TemplateSubst(Subst, template)
312 utils.send_mail(mail_message)
313 Logger.log(["closed bug", bug])
314
315 Logger.close()
316
317
318
319
320
321 if __name__ == "__main__":
322 main()
323