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