Merge ~fourdollars/pc-enablement/+git/oem-scripts:master into ~oem-solutions-engineers/pc-enablement/+git/oem-scripts:master
- Git
- lp:~fourdollars/pc-enablement/+git/oem-scripts
- master
- Merge into master
Proposed by
Shih-Yuan Lee
Status: | Merged |
---|---|
Approved by: | Shih-Yuan Lee |
Approved revision: | 5f2b26c9833fef47f9124fc73869a0499b654bcf |
Merged at revision: | 1f693f0f12cf4a0ddf0d75d43353c62b89bb19ae |
Proposed branch: | ~fourdollars/pc-enablement/+git/oem-scripts:master |
Merge into: | ~oem-solutions-engineers/pc-enablement/+git/oem-scripts:master |
Diff against target: |
697 lines (+559/-37) 9 files modified
bootstrap-meta (+420/-0) debian/changelog (+14/-0) debian/tests/bootstrap-meta (+58/-0) debian/tests/control (+1/-0) mir-bug (+8/-37) oem-meta-package.sru.jinja2 (+24/-0) oem_scripts/LaunchpadLogin.py (+3/-0) oem_scripts/__init__.py (+30/-0) setup.py (+1/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Yuan-Chen Cheng (community) | Approve | ||
Review via email: mp+408091@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Shih-Yuan Lee (fourdollars) wrote : | # |
Revision history for this message
Yuan-Chen Cheng (ycheng-twn) wrote : | # |
Well, the code looks fine, however, there are some nice to have change:
1. For get meta pkg name from group and platform name, can we refactor so that it's a function call that can be re-use?
2. for project oem-priority, team name oem-solutions-
I mean something like:
OEM_TEAM = "oem-solutions-
person=
3. "focal" is hardcoded, it will be easier to be changed if it's a variable.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/bootstrap-meta b/bootstrap-meta |
2 | new file mode 100755 |
3 | index 0000000..03549a3 |
4 | --- /dev/null |
5 | +++ b/bootstrap-meta |
6 | @@ -0,0 +1,420 @@ |
7 | +#!/usr/bin/env python3 |
8 | +# -*- coding: utf-8 -*- |
9 | +# Copyright (C) 2021 Canonical Ltd. |
10 | +# Author: Shih-Yuan Lee (FourDollars) <sylee@canonical.com> |
11 | +# |
12 | +# This program is free software; you can redistribute it and/or modify |
13 | +# it under the terms of the GNU General Public License as published by |
14 | +# the Free Software Foundation; either version 3 of the License, or |
15 | +# (at your option) any later version. |
16 | +# |
17 | +# This program is distributed in the hope that it will be useful, |
18 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | +# GNU General Public License for more details. |
21 | +# |
22 | +# You should have received a copy of the GNU General Public License |
23 | +# along with this program; if not, write to the Free Software |
24 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25 | + |
26 | +import argparse |
27 | +import collections |
28 | +import jinja2 |
29 | +import json |
30 | +import oem_scripts |
31 | +import re |
32 | + |
33 | +from copy import copy |
34 | +from logging import info, warning, error |
35 | +from oem_scripts import SUBSCRIBER_LIST, TAG_LIST, remove_prefix, yes_or_ask |
36 | +from oem_scripts.LaunchpadLogin import LaunchpadLogin |
37 | +from oem_scripts.logging import setup_logging |
38 | + |
39 | + |
40 | +class BootstrapMeta(object): |
41 | + def __init__(self, platformJson, lp, kernel_meta): |
42 | + self.kernel_meta = kernel_meta |
43 | + self.lp = lp |
44 | + self.json = json.load(platformJson) |
45 | + self.project = self.json["project"] |
46 | + self.group = self.json["group"] |
47 | + self.platform = self.json["platform"] |
48 | + |
49 | + if self.json["project"] == "somerville": |
50 | + self.meta = "oem-somerville-" + self.json["platform"] + "-meta" |
51 | + elif self.json["project"] == "stella": |
52 | + self.meta = ( |
53 | + "oem-stella." |
54 | + + self.json["group"] |
55 | + + "." |
56 | + + self.json["platform"] |
57 | + + "-meta" |
58 | + ) |
59 | + elif self.json["project"] == "sutton": |
60 | + self.meta = ( |
61 | + "oem-sutton." |
62 | + + self.json["group"] |
63 | + + "." |
64 | + + self.json["platform"] |
65 | + + "-meta" |
66 | + ) |
67 | + else: |
68 | + raise Exception("Not supported") |
69 | + |
70 | + def create_bug(self, title, description, importance, status): |
71 | + project = lp.projects["oem-priority"] |
72 | + bug = self.lp.bugs.createBug( |
73 | + description=description, |
74 | + target=project, |
75 | + title=title, |
76 | + information_type="Public", |
77 | + tags=TAG_LIST, |
78 | + ) |
79 | + info("meta package public bug: " + bug.web_link) |
80 | + |
81 | + for task in bug.bug_tasks: |
82 | + task.status = status |
83 | + task.importance = importance |
84 | + # Assign to reporter by default |
85 | + task.assignee = lp.me |
86 | + task.lp_save() |
87 | + |
88 | + # Subscribe the oem-solutions-engineers |
89 | + bug.subscribe(person=lp.people["oem-solutions-engineers"]) |
90 | + bug.lp_save() |
91 | + |
92 | + return bug |
93 | + |
94 | + def _grouping_market_names(self, market_names: list, maxsplit=1) -> str: |
95 | + # Remove empty item |
96 | + while "" in market_names: |
97 | + market_names.remove("") |
98 | + tmp = collections.defaultdict(list) |
99 | + space_in_model = False |
100 | + try: |
101 | + for market_name in sorted(market_names): |
102 | + if maxsplit == 1: |
103 | + name, model = market_name.split(maxsplit=maxsplit) |
104 | + tmp[name].append(model) |
105 | + if " " in model: |
106 | + space_in_model = True |
107 | + elif maxsplit == 2: |
108 | + brand, name, model = market_name.split(maxsplit=maxsplit) |
109 | + tmp[brand + " " + name].append(model) |
110 | + if " " in model: |
111 | + space_in_model = True |
112 | + except ValueError: |
113 | + return ", ".join(sorted(market_names)) |
114 | + |
115 | + if space_in_model: |
116 | + return ", ".join( |
117 | + f"{name} {', '.join(models)}" for name, models in tmp.items() |
118 | + ) |
119 | + else: |
120 | + return ", ".join( |
121 | + f"{name} {'/'.join(models)}" for name, models in tmp.items() |
122 | + ) |
123 | + |
124 | + def parse_market_name(self): |
125 | + if self.project == "somerville": |
126 | + self.market_name = self._grouping_market_names(self.json["productnames"]) |
127 | + if not self.market_name.startswith("Dell "): |
128 | + self.market_name = "Dell " + self.market_name |
129 | + elif self.project == "stella": |
130 | + self.market_name = self._grouping_market_names( |
131 | + self.json["productnames"], maxsplit=2 |
132 | + ) |
133 | + self.market_name = remove_prefix(self.market_name, "HP ") |
134 | + if not self.market_name.startswith("HP "): |
135 | + self.market_name = "HP " + self.market_name |
136 | + elif self.project == "sutton": |
137 | + self.market_name = self._grouping_market_names(self.json["productnames"]) |
138 | + if not self.market_name.startswith("Lenovo "): |
139 | + self.market_name = "Lenovo " + self.market_name |
140 | + else: |
141 | + raise Exception("Not supported") |
142 | + |
143 | + |
144 | +class BootstrapMetaMIR(BootstrapMeta): |
145 | + def __init__(self, platformJson, lp, kernel_meta): |
146 | + super().__init__(platformJson, lp, kernel_meta) |
147 | + |
148 | + def _read_from_template(self, marketName, oemMetaPackage, kernelMeta): |
149 | + env = jinja2.Environment( |
150 | + loader=jinja2.FileSystemLoader(["./", "/usr/share/oem-scripts"]) |
151 | + ) |
152 | + template = env.get_template("oem-meta-package.mir.jinja2") |
153 | + return template.render( |
154 | + metaPkgName=self.market_name, |
155 | + branchName=self.branch, |
156 | + oemCodenameNogroup=self.project, |
157 | + deviceName=self.device_name, |
158 | + ) |
159 | + |
160 | + def create(self): |
161 | + title = f"[DRAFT][MIR] {self.meta}" |
162 | + description = "[DRAFT]" + self._read_from_template() |
163 | + super().create_bug( |
164 | + title, description, importance="Critical", status="Confirmed" |
165 | + ) |
166 | + |
167 | + def update(self): |
168 | + pass |
169 | + |
170 | + |
171 | +class BootstrapMetaSRU(BootstrapMeta): |
172 | + def __init__(self, platformJson, lp, kernel_meta, output): |
173 | + super().__init__(platformJson, lp, kernel_meta) |
174 | + self.parse_market_name() |
175 | + self.pattern = re.compile( |
176 | + rf".*Update the hardware support for .* in {self.meta}.*" |
177 | + ) |
178 | + self.output = output |
179 | + |
180 | + def _read_from_template(self): |
181 | + env = jinja2.Environment( |
182 | + loader=jinja2.FileSystemLoader(["./", "/usr/share/oem-scripts"]) |
183 | + ) |
184 | + template = env.get_template("oem-meta-package.sru.jinja2") |
185 | + return template.render( |
186 | + marketName=self.market_name, |
187 | + oemMetaPackage=self.meta, |
188 | + kernelMeta=self.kernel_meta, |
189 | + ) |
190 | + |
191 | + def create(self, importance="High", status="Confirmed"): |
192 | + project = lp.projects[f"ubuntu/focal/+source/{self.meta}"] |
193 | + tasks = project.searchTasks() |
194 | + for task in tasks: |
195 | + bug = task.bug |
196 | + if self.pattern.match(bug.title): |
197 | + if self.output: |
198 | + self.output.write(f"{bug.id}\n") |
199 | + if lp.service_root != "https://api.launchpad.net/": |
200 | + error(f'{bug.web_link} - "{bug.title}" has been created.') |
201 | + else: |
202 | + error(f'LP: #{bug.id} - "{bug.title}" has been created.') |
203 | + exit(1) |
204 | + title = ( |
205 | + f"[DRAFT] Update the hardware support for {self.market_name} in {self.meta}" |
206 | + ) |
207 | + description = "[DRAFT]" + self._read_from_template() |
208 | + bug = super().create_bug( |
209 | + title, description, importance=importance, status=status |
210 | + ) |
211 | + if self.output: |
212 | + self.output.write(f"{bug.id}\n") |
213 | + task = bug.addTask(target=lp.projects[f"ubuntu/+source/{self.meta}"]) |
214 | + task.status = "Won't Fix" |
215 | + task.lp_save() |
216 | + task = bug.addTask(target=lp.projects[f"ubuntu/focal/+source/{self.meta}"]) |
217 | + task.status = status |
218 | + task.importance = importance |
219 | + task.assignee = lp.me |
220 | + task.lp_save() |
221 | + |
222 | + def update(self, release=False, ready=False, yes=False): |
223 | + project = lp.projects[f"ubuntu/focal/+source/{self.meta}"] |
224 | + tasks = project.searchTasks() |
225 | + candidate = None |
226 | + for task in tasks: |
227 | + bug = task.bug |
228 | + if self.pattern.match(bug.title): |
229 | + if yes_or_ask( |
230 | + yes, |
231 | + f'Do you want to update LP: #{bug.id} - "{bug.title}" for {self.kernel_meta}?', |
232 | + ): |
233 | + candidate = bug |
234 | + |
235 | + if candidate is None: |
236 | + warning("Please use create-sru-bug to create the SRU bug first.") |
237 | + exit(1) |
238 | + else: |
239 | + bug = candidate |
240 | + if self.output: |
241 | + self.output.write(f"{bug.id}\n") |
242 | + |
243 | + bug.title = f"Update the hardware support for {self.market_name} in {self.meta}" |
244 | + bug.description = self._read_from_template() |
245 | + bug.lp_save() |
246 | + |
247 | + subscriptions = list(map(lambda x: x.person.name, bug.subscriptions)) |
248 | + tags = copy(bug.tags) |
249 | + if ready or release: |
250 | + for subscriber in SUBSCRIBER_LIST: |
251 | + if subscriber not in subscriptions: |
252 | + bug.subscribe(person=lp.people[subscriber]) |
253 | + if "oem-solutions-engineers" not in subscriptions: |
254 | + bug.subscribe(person=lp.people["oem-solutions-engineers"]) |
255 | + if release: |
256 | + if "oem-done-upload" not in tags: |
257 | + tags.append("oem-done-upload") |
258 | + if "oem-needs-upload" in tags: |
259 | + tags.remove("oem-needs-upload") |
260 | + if "ubuntu-desktop" not in subscriptions: |
261 | + bug.subscribe(person=lp.people["ubuntu-desktop"]) |
262 | + if "ubuntu-sponsors" in subscriptions: |
263 | + bug.unsubscribe(person=lp.people["ubuntu-sponsors"]) |
264 | + if "ubuntu-sru" not in subscriptions: |
265 | + bug.subscribe(person=lp.people["ubuntu-sru"]) |
266 | + elif ready: |
267 | + if "oem-done-upload" in tags: |
268 | + tags.remove("oem-done-upload") |
269 | + if "oem-needs-upload" not in tags: |
270 | + tags.append("oem-needs-upload") |
271 | + if "ubuntu-desktop" not in subscriptions: |
272 | + bug.subscribe(person=lp.people["ubuntu-desktop"]) |
273 | + if "ubuntu-sponsors" not in subscriptions: |
274 | + bug.subscribe(person=lp.people["ubuntu-sponsors"]) |
275 | + if "ubuntu-sru" in subscriptions: |
276 | + bug.unsubscribe(person=lp.people["ubuntu-sru"]) |
277 | + else: |
278 | + if "oem-done-upload" in tags: |
279 | + tags.remove("oem-done-upload") |
280 | + if "oem-needs-upload" in tags: |
281 | + tags.remove("oem-needs-upload") |
282 | + if "ubuntu-desktop" in subscriptions: |
283 | + bug.unsubscribe(person=lp.people["ubuntu-desktop"]) |
284 | + if "ubuntu-sponsors" in subscriptions: |
285 | + bug.unsubscribe(person=lp.people["ubuntu-sponsors"]) |
286 | + if "ubuntu-sru" in subscriptions: |
287 | + bug.unsubscribe(person=lp.people["ubuntu-sru"]) |
288 | + for tag in bug.tags: |
289 | + if tag.startswith("oem-scripts-"): |
290 | + if tag[len("oem-scripts-") :] != oem_scripts.__version__: |
291 | + tags.remove(tag) |
292 | + for tag in TAG_LIST: |
293 | + if tag not in tags: |
294 | + tags.append(tag) |
295 | + bug.tags = tags |
296 | + bug.lp_save() |
297 | + |
298 | + for task in bug.bug_tasks: |
299 | + if ( |
300 | + task.bug_target_name == "oem-priority" |
301 | + or task.bug_target_name == "oem-somerville-varys-meta (Ubuntu Focal)" |
302 | + ): |
303 | + if release: |
304 | + task.status = "In Progress" |
305 | + elif ready: |
306 | + task.status = "Triaged" |
307 | + else: |
308 | + task.status = "Confirmed" |
309 | + elif task.bug_target_name == "oem-somerville-varys-meta (Ubuntu)": |
310 | + task.status = "Won't Fix" |
311 | + task.lp_save() |
312 | + |
313 | + if lp.service_root != "https://api.launchpad.net/": |
314 | + info(f'{bug.web_link} - "{bug.title}" has been updated.') |
315 | + else: |
316 | + info(f'LP: #{bug.id} - "{bug.title}" has been updated.') |
317 | + |
318 | + |
319 | +parser = argparse.ArgumentParser( |
320 | + formatter_class=argparse.RawDescriptionHelpFormatter, |
321 | + epilog=""" |
322 | +examples: |
323 | + bootstrap-meta create-mir-bug platformJSON [WIP] |
324 | + bootstrap-meta update-mir-bug platformJSON [WIP] |
325 | + bootstrap-meta update-mir-git platformJSON [WIP] |
326 | + bootstrap-meta create-sru-bug platformJSON [--kernel linux-generic-hwe-20.04] |
327 | + bootstrap-meta update-sru-bug platformJSON [--kernel linux-generic-hwe-20.04] [--yes] [--ready|--release] |
328 | + bootstrap-meta update-sru-git platformJSON [WIP]""", |
329 | +) |
330 | + |
331 | +parser.add_argument("-d", "--debug", help="print debug messages", action="store_true") |
332 | +parser.add_argument( |
333 | + "-q", "--quiet", help="Don't print info messages", action="store_true" |
334 | +) |
335 | + |
336 | +subparsers = parser.add_subparsers(dest="subcommand") |
337 | + |
338 | +create_mir_bug = subparsers.add_parser("create-mir-bug", help="[-h] platformJSON") |
339 | +create_mir_bug.add_argument( |
340 | + "json", |
341 | + help="Specify the platform json of the OEM metapackage.", |
342 | + type=argparse.FileType("r", encoding="UTF-8"), |
343 | +) |
344 | + |
345 | +update_mir_bug = subparsers.add_parser("update-mir-bug", help="[-h] platformJSON") |
346 | +update_mir_bug.add_argument( |
347 | + "json", |
348 | + help="Specify the platform json of the OEM metapackage.", |
349 | + type=argparse.FileType("r", encoding="UTF-8"), |
350 | +) |
351 | + |
352 | +create_sru_bug = subparsers.add_parser("create-sru-bug", help="[-h] platformJSON") |
353 | +create_sru_bug.add_argument( |
354 | + "json", |
355 | + help="Specify the platform json of the OEM metapackage in Ubuntu archive.", |
356 | + type=argparse.FileType("r", encoding="UTF-8"), |
357 | +) |
358 | +create_sru_bug.add_argument( |
359 | + "--kernel", |
360 | + default="linux-generic-hwe-20.04", |
361 | + help="Specify the kernel meta of the OEM metapackage that is targeting on.", |
362 | +) |
363 | +create_sru_bug.add_argument( |
364 | + "-o", |
365 | + "--output", |
366 | + help="Specify a file name to write the bug number.", |
367 | + type=argparse.FileType("w", encoding="UTF-8"), |
368 | +) |
369 | + |
370 | +update_sru_bug = subparsers.add_parser( |
371 | + "update-sru-bug", |
372 | + help="[-h] platformJSON [--kernel linux-generic-hwe-20.04] [--yes] [--ready|--release]", |
373 | +) |
374 | +update_sru_bug.add_argument( |
375 | + "json", |
376 | + help="Specify the platform json of the OEM metapackage in Ubuntu archive.", |
377 | + type=argparse.FileType("r", encoding="UTF-8"), |
378 | +) |
379 | +update_sru_bug.add_argument( |
380 | + "--kernel", |
381 | + default="linux-generic-hwe-20.04", |
382 | + help="Specify the kernel meta of the OEM metapackage that is targeting on.", |
383 | +) |
384 | +update_sru_bug.add_argument( |
385 | + "--release", |
386 | + action="store_true", |
387 | + help="Update the bug when the OEM metapackage has been uploaded into the queue for releasing.", |
388 | +) |
389 | +update_sru_bug.add_argument( |
390 | + "--ready", |
391 | + action="store_true", |
392 | + help="Update the bug when the OEM metapackage is ready to upload.", |
393 | +) |
394 | +update_sru_bug.add_argument( |
395 | + "--yes", help="Say yes for all prompts.", action="store_true" |
396 | +) |
397 | +update_sru_bug.add_argument( |
398 | + "-o", |
399 | + "--output", |
400 | + help="Specify a file name to write the bug number.", |
401 | + type=argparse.FileType("w", encoding="UTF-8"), |
402 | +) |
403 | + |
404 | +args = parser.parse_args() |
405 | +setup_logging(debug=args.debug, quiet=args.quiet) |
406 | + |
407 | +if args.subcommand: |
408 | + login = LaunchpadLogin() |
409 | + lp = login.lp |
410 | + lp.service_root = login.service_root |
411 | + lp.service_version = login.service_version |
412 | + |
413 | +# if args.subcommand == "create-mir-bug": |
414 | +# mirbug = BootstrapMetaMIR(args.json, lp, args.kernel) |
415 | +# mirbug.create() |
416 | +# elif args.subcommand == "update-mir-bug": |
417 | +# mirbug = BootstrapMetaMIR(args.json, lp, args.kernel) |
418 | +# mirbug.update() |
419 | +if args.subcommand == "create-sru-bug": |
420 | + srubug = BootstrapMetaSRU(args.json, lp, args.kernel, args.output) |
421 | + srubug.create() |
422 | +elif args.subcommand == "update-sru-bug": |
423 | + srubug = BootstrapMetaSRU(args.json, lp, args.kernel, args.output) |
424 | + srubug.update(release=args.release, ready=args.ready, yes=args.yes) |
425 | +else: |
426 | + parser.print_help() |
427 | diff --git a/debian/changelog b/debian/changelog |
428 | index 4896fc6..6ef7544 100644 |
429 | --- a/debian/changelog |
430 | +++ b/debian/changelog |
431 | @@ -1,3 +1,17 @@ |
432 | +oem-scripts (1.12) UNRELEASED; urgency=medium |
433 | + |
434 | + * bootstrap-meta, |
435 | + debian/tests/bootstrap-meta, |
436 | + debian/tests/control, |
437 | + mir-bug, |
438 | + oem-meta-package.sru.jinja2, |
439 | + oem_scripts/LaunchpadLogin.py, |
440 | + oem_scripts/__init__.py, |
441 | + setup.py: Add the bootstrap-meta tool to deal with OEM metapackages SRU |
442 | + bugs. |
443 | + |
444 | + -- Shih-Yuan Lee (FourDollars) <sylee@canonical.com> Thu, 02 Sep 2021 14:55:10 +0800 |
445 | + |
446 | oem-scripts (1.11) focal; urgency=medium |
447 | |
448 | * debian/control, |
449 | diff --git a/debian/tests/bootstrap-meta b/debian/tests/bootstrap-meta |
450 | new file mode 100644 |
451 | index 0000000..f0ec33f |
452 | --- /dev/null |
453 | +++ b/debian/tests/bootstrap-meta |
454 | @@ -0,0 +1,58 @@ |
455 | +#!/bin/bash |
456 | + |
457 | +set -euo pipefail |
458 | +IFS=$'\n\t' |
459 | + |
460 | +export LAUNCHPAD_API="https://api.staging.launchpad.net/" |
461 | + |
462 | +cat > fossa-varys.json <<ENDLINE |
463 | +{ |
464 | + "group": "", |
465 | + "platform": "varys", |
466 | + "productnames": [ |
467 | + "Precision 5550" |
468 | + ], |
469 | + "project": "somerville" |
470 | +} |
471 | +ENDLINE |
472 | + |
473 | +cleanup() { |
474 | + echo "= cleanup =" |
475 | + if [ -f "bugid" ]; then |
476 | + BUG_ID=$(cat bugid) |
477 | + rm bugid |
478 | + fi |
479 | + if [ -f "$BUG_ID.json" ]; then |
480 | + jq -C -S < "$BUG_ID.json" |
481 | + rm "$BUG_ID.json" |
482 | + lp-bug cleanup --yes "$BUG_ID" |
483 | + fi |
484 | +} |
485 | + |
486 | +trap cleanup EXIT INT TERM |
487 | + |
488 | +bootstrap-meta create-sru-bug fossa-varys.json --kernel linux-oem-20.04 --output bugid |
489 | +BUG_ID=$(cat bugid) |
490 | +launchpad-api get "bugs/$BUG_ID" > "$BUG_ID.json" |
491 | +jq -r .description < "$BUG_ID.json" | grep "Precision 5550" |
492 | +jq -r .description < "$BUG_ID.json" | grep linux-oem-20.04 |
493 | +jq -r '.tags|join(" ")' < "$BUG_ID.json" | grep oem-meta-packages |
494 | + |
495 | +if bootstrap-meta create-sru-bug fossa-varys.json --kernel linux-oem-20.04 --output bugid; then |
496 | + echo "It is expected to return failed." |
497 | + exit 1 |
498 | +fi |
499 | + |
500 | +bootstrap-meta update-sru-bug fossa-varys.json --kernel linux-oem-20.04b --yes |
501 | +launchpad-api get "bugs/$BUG_ID" > "$BUG_ID.json" |
502 | +jq -r .description < "$BUG_ID.json" | grep linux-oem-20.04b |
503 | + |
504 | +bootstrap-meta update-sru-bug fossa-varys.json --kernel linux-oem-20.04c --yes --ready |
505 | +launchpad-api get "bugs/$BUG_ID" > "$BUG_ID.json" |
506 | +jq -r .description < "$BUG_ID.json" | grep linux-oem-20.04c |
507 | +jq -r '.tags|join(" ")' < "$BUG_ID.json" | grep oem-needs-upload |
508 | + |
509 | +bootstrap-meta update-sru-bug fossa-varys.json --kernel linux-oem-20.04d --yes --release |
510 | +launchpad-api get "bugs/$BUG_ID" > "$BUG_ID.json" |
511 | +jq -r .description < "$BUG_ID.json" | grep linux-oem-20.04d |
512 | +jq -r '.tags|join(" ")' < "$BUG_ID.json" | grep oem-done-upload |
513 | diff --git a/debian/tests/control b/debian/tests/control |
514 | index 1f9da74..a9a549d 100644 |
515 | --- a/debian/tests/control |
516 | +++ b/debian/tests/control |
517 | @@ -10,6 +10,7 @@ Tests: |
518 | Depends: @, ubuntu-dev-tools, git-buildpackage |
519 | |
520 | Tests: |
521 | + bootstrap-meta, |
522 | bug-bind, |
523 | get-private-ppa, |
524 | jq-lp, |
525 | diff --git a/mir-bug b/mir-bug |
526 | index d90e130..be49cb3 100755 |
527 | --- a/mir-bug |
528 | +++ b/mir-bug |
529 | @@ -33,23 +33,17 @@ import subprocess |
530 | from copy import copy |
531 | from glob import glob |
532 | from logging import debug, info, warning, error, critical |
533 | +from oem_scripts import ( |
534 | + SUBSCRIBER_LIST, |
535 | + TAG_LIST, |
536 | + ALLOWED_KERNEL_META_LIST, |
537 | + remove_prefix, |
538 | + yes_or_ask, |
539 | +) |
540 | from oem_scripts.LaunchpadLogin import LaunchpadLogin |
541 | from oem_scripts.logging import setup_logging |
542 | from tempfile import TemporaryDirectory |
543 | |
544 | -ALLOWED_KERNEL_META_LIST = ( |
545 | - "linux-oem-20.04c", |
546 | - "linux-oem-20.04b", |
547 | - "linux-oem-20.04", |
548 | - "linux-generic-hwe-20.04", |
549 | -) |
550 | -SUBSCRIBER_LIST = ("oem-solutions-engineers", "ubuntu-sponsors", "ubuntu-desktop") |
551 | -TAG_LIST = [ |
552 | - "oem-meta-packages", |
553 | - "oem-priority", |
554 | - f"oem-scripts-{oem_scripts.__version__}", |
555 | -] |
556 | - |
557 | parser = argparse.ArgumentParser( |
558 | formatter_class=argparse.RawDescriptionHelpFormatter, |
559 | epilog=""" |
560 | @@ -154,11 +148,6 @@ setup_logging(debug=args.debug, quiet=args.quiet) |
561 | pattern = re.compile(r".*\[MIR\]\W*oem-([^-]*)-(.*)-meta\W*") |
562 | |
563 | |
564 | -# Python 3.9 supports this. |
565 | -def remove_prefix(s, prefix): |
566 | - return s[len(prefix) :] if s.startswith(prefix) else s |
567 | - |
568 | - |
569 | def _grouping_market_names(market_names: list, maxsplit=1) -> str: |
570 | # Remove empty item |
571 | while "" in market_names: |
572 | @@ -345,20 +334,6 @@ def collect_bugs(lp, output): |
573 | output.write("\n") |
574 | |
575 | |
576 | -def yes_or_ask(yes: bool, message: str) -> bool: |
577 | - if yes: |
578 | - print(f"> \033[1;34m{message}\033[1;0m (y/n) y") |
579 | - return True |
580 | - while True: |
581 | - res = input(f"> \033[1;34m{message}\033[1;0m (y/n) ").lower() |
582 | - if res not in {"y", "n"}: |
583 | - continue |
584 | - if res == "y": |
585 | - return True |
586 | - else: |
587 | - return False |
588 | - |
589 | - |
590 | def update_bug( |
591 | lp, |
592 | bug_number: int, |
593 | @@ -713,11 +688,7 @@ def check_and_update_bug_subscriptions(lp, bug, update=False, yes=False) -> bool |
594 | else: |
595 | result = False |
596 | if args.ready: |
597 | - for subscriber in ( |
598 | - "oem-solutions-engineers", |
599 | - "ubuntu-sponsors", |
600 | - "ubuntu-desktop", |
601 | - ): |
602 | + for subscriber in SUBSCRIBER_LIST: |
603 | if subscriber not in subscriptions: |
604 | error(f"'{subscriber}' is not in the subscriptions.") |
605 | if update and yes_or_ask( |
606 | diff --git a/oem-meta-package.sru.jinja2 b/oem-meta-package.sru.jinja2 |
607 | new file mode 100644 |
608 | index 0000000..88f8661 |
609 | --- /dev/null |
610 | +++ b/oem-meta-package.sru.jinja2 |
611 | @@ -0,0 +1,24 @@ |
612 | +[Impact] |
613 | + |
614 | + * It should have no impact at all because these changes shall have been applied and verified in the corresponding OEM archive before this SRU process. |
615 | + |
616 | +[Test Plan] |
617 | + |
618 | +* Install Ubuntu 20.04.x LTS on {{ marketName }} and remove {{ oemMetaPackage }} manually if any. |
619 | + |
620 | + * Enable focal-proposed and execute the update-manager. |
621 | + |
622 | + * The update-manager should show "Hardware support for {{ marketName }}". If not, please change "When there are security updates" and "When there are other updates" in the Updates of software-properties-gtk to "Display immediately", install the older firefox by `sudo apt install firefox=75.0+build3-0ubuntu1` and reboot the system to wait for the update-manager pop up automatically. |
623 | + |
624 | + * After it installed {{ oemMetaPackage }} by update-manager and reboot the system, you should see the system booting from the {{ kernelMeta }} kernel. |
625 | + |
626 | +[Where problems could occur] |
627 | + |
628 | + * {{ oemMetaPackage }} is installed but it is not updated to the version in the corresponding OEM archive. |
629 | + |
630 | + * The update-manager didn't show "Hardware support for {{ marketName }}" at all. |
631 | + |
632 | +[Other Info] |
633 | + |
634 | + * You can see all {{ oemMetaPackage }} versions on https://people.ubuntu.com/~fourdollars/oem-meta-packages/. |
635 | + * I have used ppa:oem-solutions-engineers/oem-projects-meta to verify it before this SRU process. |
636 | diff --git a/oem_scripts/LaunchpadLogin.py b/oem_scripts/LaunchpadLogin.py |
637 | index 01bae8b..d2fa68e 100644 |
638 | --- a/oem_scripts/LaunchpadLogin.py |
639 | +++ b/oem_scripts/LaunchpadLogin.py |
640 | @@ -67,6 +67,9 @@ class LaunchpadLogin: |
641 | else: |
642 | service_root = "production" |
643 | |
644 | + self.service_root = lookup_service_root(service_root) |
645 | + self.service_version = version |
646 | + |
647 | oem_scripts_config_ini = os.path.join( |
648 | os.environ["HOME"], ".config/oem-scripts/config.ini" |
649 | ) |
650 | diff --git a/oem_scripts/__init__.py b/oem_scripts/__init__.py |
651 | index 2bfacd2..4052759 100644 |
652 | --- a/oem_scripts/__init__.py |
653 | +++ b/oem_scripts/__init__.py |
654 | @@ -1 +1,31 @@ |
655 | __version__ = "1.11" |
656 | + |
657 | +ALLOWED_KERNEL_META_LIST = ( |
658 | + "linux-oem-20.04c", |
659 | + "linux-oem-20.04b", |
660 | + "linux-oem-20.04", |
661 | + "linux-generic-hwe-20.04", |
662 | +) |
663 | + |
664 | +SUBSCRIBER_LIST = ("oem-solutions-engineers", "ubuntu-sponsors", "ubuntu-desktop") |
665 | + |
666 | +TAG_LIST = ["oem-meta-packages", "oem-priority", f"oem-scripts-{__version__}"] |
667 | + |
668 | + |
669 | +# Python 3.9 supports this. |
670 | +def remove_prefix(s, prefix): |
671 | + return s[len(prefix) :] if s.startswith(prefix) else s |
672 | + |
673 | + |
674 | +def yes_or_ask(yes: bool, message: str) -> bool: |
675 | + if yes: |
676 | + print(f"> \033[1;34m{message}\033[1;0m (y/n) y") |
677 | + return True |
678 | + while True: |
679 | + res = input(f"> \033[1;34m{message}\033[1;0m (y/n) ").lower() |
680 | + if res not in {"y", "n"}: |
681 | + continue |
682 | + if res == "y": |
683 | + return True |
684 | + else: |
685 | + return False |
686 | diff --git a/setup.py b/setup.py |
687 | index 81004d7..ace90b3 100644 |
688 | --- a/setup.py |
689 | +++ b/setup.py |
690 | @@ -34,6 +34,7 @@ Also there is a meta package oem-dev-tools that installs all scripts""", |
691 | author="Commercial Engineering", |
692 | author_email="commercial-engineering@canonical.com", |
693 | scripts=[ |
694 | + "bootstrap-meta", |
695 | "copyPackage.py", |
696 | "get-oem-auth-token", |
697 | "get-oemshare-auth-token", |
[BOT] 1.12-5f2b26c- in-docker- focal-summary. log collect- credentials PASS oem-scripts- auto PASS merge-proposal PASS insteadof- setting PASS from-iso. sh PASS verification PASS /paste. ubuntu. com/p/b7GVnfyvk N/ oem-scripts- 1.12-5f2b26c- in-docker- focal-complete. log
$ cat oem-scripts-
autopkgtest-
autopkgtest-
pkg-somerville-meta PASS
pkg-stella-meta PASS
pkg-sutton-meta PASS
bootstrap-meta PASS
bug-bind PASS
get-private-ppa PASS
jq-lp PASS
launchpad-api PASS
lp-bug PASS
oem-meta-packages PASS
pkg-list PASS
review-
run-autopkgtest PASS
setup-apt-dir PASS
mir-bug SKIP exit status 77 and marked as skippable
git-url-
lp-dl-attm PASS
recovery-
mir-bug-
https:/