Merge ~pieq/bugit/+git/qabro:fix-sosreport-dpkg-logs into bugit:master

Proposed by Pierre Equoy
Status: Superseded
Proposed branch: ~pieq/bugit/+git/qabro:fix-sosreport-dpkg-logs
Merge into: bugit:master
Diff against target: 364 lines (+154/-72)
9 files modified
dev/null (+0/-11)
patches/sosreport-dpkg-l.patch (+12/-0)
patches/sosreport-env-path-snap.patch (+14/-21)
qabro/__version__.py (+1/-1)
qabro/bug_assistant.py (+5/-1)
qabro/data/tags.json (+68/-0)
qabro/ui.py (+46/-37)
setup.py (+1/-0)
snap/snapcraft.yaml (+7/-1)
Reviewer Review Type Date Requested Status
OEM Services QA Pending
Review via email: mp+385631@code.launchpad.net

This proposal supersedes a proposal from 2020-06-12.

Description of the change

See commit message for more info

To test (on Ubuntu classic):

1. Run `snapcraft` from this branch to build a `qabro_0.13dev_amd64.snap` file
2. Install the snap:
    sudo snap install qabro_0.13dev_amd64.snap --devmode
3. Run sosreport from the snap:
    sudo qabro.sosreport
It will generate a /root/snap/qabro/common/sosreport-*.tar.gz archive

4. Copy the archive and modify the permissions, then open it to check the content of `sos_commands/dpkg/`:

    sudo cp /root/snap/qabro/common/sosreport-*.tar.gz /tmp
    sudo chown $USER:$USER /tmp/sosreport-*.tar.gz
    xdg-open /tmp/sosreport-*.tar.gz

You should find the list of packages installed on your system.

To post a comment you must log in.

Unmerged commits

8ffa378... by Pierre Equoy

Add dpkg and patch sosreport to provide proper `dpkg -l` logs

Until now, on classic systems, the list of packages installed (the
output of `dpkg -l`) was empty in the archive report generated by
sosreport.

This commit addresses the issue. The list of installed packages can now
be found in `sos_commands/dpkg/`.

LP: #1880071

d971493... by Pierre Equoy

Add features and vendors tag lists

We used to have our own list of "bug type" tags. We are now using two
up-to-date lists of features and vendors tags that are shared among
teams.

These two lists are shown in two columns under the text field to enter
tags. The user can select as many impacted features/vendors as required,
and this updates the list of tags submitted to Launchpad dynamically.

LP: #1880538, #1880071

a059e29... by Pierre Equoy

Cleanup code look

36143db... by Pierre Equoy

Update for sosreport 3.9

sosreport 3.9 is now available in the bionic-updates pocket, so we need
to make the following changes to be able to build QABro from now on:

- remove the apt-no-auth-conf patch (it's been merged in sosreport 3.9)
and remove it from the snapcraft recipe
- adapt the env-path-snap patch
- modify the way we retrieve the path to the .tar.gz archive generated
by sosreport

985f5a4... by Pierre Equoy

Bump to v0.13dev

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/patches/sosreport-apt-no-auth-conf.patch b/patches/sosreport-apt-no-auth-conf.patch
2deleted file mode 100644
3index b2c6514..0000000
4--- a/patches/sosreport-apt-no-auth-conf.patch
5+++ /dev/null
6@@ -1,11 +0,0 @@
7---- a/sos/plugins/apt.py
8-+++ /usr/share/sosreport/sos/plugins/apt.py
9-@@ -23,6 +23,8 @@
10- "/etc/apt", "/var/log/apt"
11- ])
12-
13-+ self.add_forbidden_path("/etc/apt/auth.conf")
14-+
15- self.add_cmd_output([
16- "apt-get check",
17- "apt-config dump",
18diff --git a/patches/sosreport-dpkg-l.patch b/patches/sosreport-dpkg-l.patch
19new file mode 100644
20index 0000000..c73c141
21--- /dev/null
22+++ b/patches/sosreport-dpkg-l.patch
23@@ -0,0 +1,12 @@
24+diff -u /tmp/sos-3.9/sos/plugins/dpkg.py usr/share/sosreport/sos/plugins/dpkg.py
25+--- /tmp/sos-3.9/sos/plugins/dpkg.py 2020-06-12 15:00:20.955904359 +0800
26++++ usr/share/sosreport/sos/plugins/dpkg.py 2020-06-12 15:01:18.930341885 +0800
27+@@ -19,7 +19,7 @@
28+ profiles = ('sysmgmt', 'packagemanager')
29+
30+ def setup(self):
31+- self.add_cmd_output("dpkg -l", root_symlink="installed-debs")
32++ self.add_cmd_output("dpkg -l --admindir=/var/lib/snapd/hostfs/var/lib/dpkg", root_symlink="installed-debs")
33+ if self.get_option("verify"):
34+ self.add_cmd_output("dpkg -V")
35+ self.add_cmd_output("dpkg -C")
36diff --git a/patches/sosreport-env-path-snap.patch b/patches/sosreport-env-path-snap.patch
37index b4f95c1..f20b1c8 100644
38--- a/patches/sosreport-env-path-snap.patch
39+++ b/patches/sosreport-env-path-snap.patch
40@@ -1,22 +1,15 @@
41-diff -ru /tmp/sos-3.5/sos/policies/ubuntu.py usr/share/sosreport/sos/policies/ubuntu.py
42---- /tmp/sos-3.5/sos/policies/ubuntu.py 2017-11-02 20:54:47.000000000 +0800
43-+++ usr/share/sosreport/sos/policies/ubuntu.py 2018-10-24 15:28:46.439206314 +0800
44-@@ -3,11 +3,18 @@
45- from sos.plugins import UbuntuPlugin, DebianPlugin
46- from sos.policies.debian import DebianPolicy
47-
48-+import os
49-
50- class UbuntuPolicy(DebianPolicy):
51- distro = "Ubuntu"
52- vendor = "Ubuntu"
53- vendor_url = "http://www.ubuntu.com/"
54-+ PATH = ("/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
55-+ ":/usr/local/sbin:/usr/local/bin"
56-+ ":$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$SNAP/usr/games"
57-+ ":$SNAP/usr/local/games:$SNAP/usr/local/sbin:$SNAP/usr/local/bin"
58-+ )
59+diff -u /tmp/sos-3.9/sos/policies/ubuntu.py usr/share/sosreport/sos/policies/ubuntu.py
60+--- /tmp/sos-3.9/sos/policies/ubuntu.py 2020-06-03 15:14:14.151559473 +0800
61++++ usr/share/sosreport/sos/policies/ubuntu.py 2020-06-03 15:17:11.178575436 +0800
62+@@ -11,7 +11,10 @@
63+ vendor = "Canonical"
64+ vendor_url = "https://www.ubuntu.com/"
65+ PATH = "/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games" \
66+- + ":/usr/local/sbin:/usr/local/bin:/snap/bin"
67++ + ":/usr/local/sbin:/usr/local/bin:/snap/bin" \
68++ + ":$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$SNAP/usr/games" \
69++ + ":$SNAP/usr/local/games:$SNAP/usr/local/sbin:$SNAP/usr/local/bin"
70 + PATH = os.path.expandvars(PATH)
71-
72- def __init__(self, sysroot=None):
73- super(UbuntuPolicy, self).__init__(sysroot=sysroot)
74+ _upload_url = "https://files.support.canonical.com/uploads/"
75+ _upload_user = "ubuntu"
76+ _upload_password = "ubuntu"
77diff --git a/qabro/__version__.py b/qabro/__version__.py
78index 0fe7cd3..a5c2cc5 100644
79--- a/qabro/__version__.py
80+++ b/qabro/__version__.py
81@@ -1,5 +1,5 @@
82 __title__ = 'qabro'
83-__version__ = '0.12'
84+__version__ = '0.13dev'
85 __description__ = 'Tool to generate a Launchpad bug report and attach useful logs (using sosreport and the like).'
86 __author__ = 'Pierre Equoy'
87 __author_email__ = 'pierre.equoy@canonical.com'
88diff --git a/qabro/bug_assistant.py b/qabro/bug_assistant.py
89index 1ab9532..a32fd96 100644
90--- a/qabro/bug_assistant.py
91+++ b/qabro/bug_assistant.py
92@@ -230,7 +230,11 @@ class AttachmentAssistant:
93 "sosreport", "--no-report", "--batch", "--tmp-dir",
94 home_dir, "-z", "gzip"]
95 output = subprocess.check_output(command).decode('utf-8')
96- archive_path = output.splitlines()[-6].strip()
97+ # sosreport outputs a summary that includes a line with a
98+ # path to the archive. We retrieve this:
99+ for line in output.splitlines():
100+ if ".tar.gz" in line:
101+ archive_path = line.strip()
102 print("Report generated: {}".format(archive_path))
103 command = ["sudo", "chown", "{}:{}".format(user, user), archive_path]
104 subprocess.check_call(command)
105diff --git a/qabro/data/tags.json b/qabro/data/tags.json
106new file mode 100644
107index 0000000..8a779a5
108--- /dev/null
109+++ b/qabro/data/tags.json
110@@ -0,0 +1,68 @@
111+[{
112+ "category": "features",
113+ "type": "public",
114+ "description": "Features",
115+ "tags": {
116+ "Audio": ["hwe-audio"],
117+ "Bluetooth": ["hwe-bluetooth"],
118+ "Brightness": ["hwe-brightness"],
119+ "CANBus": ["hwe-canbus"],
120+ "Camera": ["oem-camera"],
121+ "Checkbox": ["checkbox test-case"],
122+ "External Storage": ["oem-storage"],
123+ "Fingerprint Reader": ["hwe-fingerprint"],
124+ "Firmware": ["hwe-firmware"],
125+ "Full Disk Encryption": ["oem-fde"],
126+ "GPIO": ["hwe-gpio"],
127+ "Hotkeys": ["hwe-hotkeys"],
128+ "I2C": ["hwe-i2c"],
129+ "Install": ["hwe-installer"],
130+ "LED": ["hwe-led"],
131+ "Media Card": ["hwe-media"],
132+ "Missing driver": ["hwe-needs-driver"],
133+ "Model Assertion": ["oem-assertions"],
134+ "Model Pivot / Remodelling": ["oem-assertions"],
135+ "Networking (ethernet)": ["hwe-networking-ethernet", "oem-networking"],
136+ "Networking (modem)": ["hwe-networking-modem", "oem-networking"],
137+ "Networking (wifi)": ["hwe-networking-wifi", "oem-networking"],
138+ "Other Problem": ["oem-other"],
139+ "Performance": ["oem-performance"],
140+ "Power Management": ["hwe-suspend-resume"],
141+ "Power On/Off": ["hwe-powercycle"],
142+ "Recovery": ["oem-recovery"],
143+ "Secure Boot": ["oem-secureboot"],
144+ "Sensor": ["hwe-sensor"],
145+ "Serial Assertion": ["oem-assertions"],
146+ "Serial": ["hwe-serial"],
147+ "Snapd": ["oem-snapd"],
148+ "Store": ["oem-store"],
149+ "Stress": ["oem-stress"],
150+ "TPM": ["hwe-tpm"],
151+ "Touchpad": ["hwe-touchpad"],
152+ "Touchscreen": ["oem-touchscreen"],
153+ "Video": ["hwe-graphics"],
154+ "Watchdog": ["hwe-watchdog"],
155+ "Zigbee": ["hwe-zigbee"]
156+ }
157+ },
158+ {
159+ "category": "vendors",
160+ "type": "public",
161+ "description": "Vendors",
162+ "tags": {
163+ "AMD": ["ihv-amd"],
164+ "Atheros/Qualcomm": ["ihv-qualcomm-atheros"],
165+ "Gemalto": ["ihv-gemalto"],
166+ "Intel": ["ihv-intel"],
167+ "MTK": ["ihv-mtk"],
168+ "Marvell": ["ihv-marvell"],
169+ "Mighty Gecko": ["ihv-mightygecko"],
170+ "Nvidia": ["ihv-nvidia"],
171+ "Quectel": ["ihv-quectel"],
172+ "Realtek": ["ihv-realtek"],
173+ "Redpine": ["ihv-redpine"],
174+ "Sierra": ["ihv-sierra"],
175+ "Telegesis": ["ihv-telegesis"],
176+ "Telit": ["ihv-telit"]
177+ }
178+}]
179\ No newline at end of file
180diff --git a/qabro/ui.py b/qabro/ui.py
181index ab8a343..695b3ca 100644
182--- a/qabro/ui.py
183+++ b/qabro/ui.py
184@@ -1,8 +1,10 @@
185+import json
186+from pathlib import Path
187 import sys
188 import urwid
189
190-from qabro.bug_assistant import AttachmentAssistant, BugReport
191 from qabro.__version__ import __version__ as qversion, __title__ as qtitle
192+from qabro.bug_assistant import AttachmentAssistant, BugReport
193
194
195 class ReportScreen:
196@@ -11,7 +13,7 @@ class ReportScreen:
197 ('title', 'white', 'black', 'bold'),
198 ('key', 'yellow,bold', ''),
199 ('error', 'dark red,bold', ''),
200- ]
201+ ]
202
203 footer_text = [
204 qtitle + ' v' + qversion + ' ',
205@@ -26,31 +28,20 @@ class ReportScreen:
206 'Medium',
207 'High',
208 'Critical')
209- bug_types = {"Audio": "hwe-audio",
210- "Bluetooth": "hwe-bluetooth",
211- "Camera": "oem-camera",
212- "External storage": "oem-storage",
213- "Touchpad": "hwe-touchpad",
214- "Touchscreen": "oem-touchscreen",
215- "Install": "hwe-installer",
216- "Media Card": "hwe-media",
217- "Networking (ethernet)": "hwe-networking-ethernet",
218- "Networking (wifi)": "hwe-networking-wifi",
219- "Networking (modem)": "hwe-networking-modem",
220- "Power management": "hwe-suspend-resume",
221- "Checkbox": "checkbox test-case",
222- "Video": "hwe-graphics",
223- "Hotkeys": "hwe-hotkeys",
224- "Firmware": "hwe-firmware",
225- "Missing driver": "hwe-needs-driver",
226- "Performance": "oem-performance",
227- "Other problem": "oem-other"}
228
229 default_description = ("[Summary]\n\n"
230 "[Steps to reproduce]\n\n"
231 "[Expected result]\n\n"
232 "[Actual result]\n\n"
233 "[Failure rate]\n\n")
234+ with open(Path(__file__).parent / "data/tags.json") as f:
235+ _data = json.load(f)
236+ tags = dict()
237+ for d in _data:
238+ if d["category"] == "features":
239+ tags["features"] = d["tags"]
240+ elif d["category"] == "vendors":
241+ tags["vendors"] = d["tags"]
242
243 def __init__(self, project='', tags='', assignee=''):
244 # Adding standard info (CPU, BIOS, GPU, etc.) to the description
245@@ -60,7 +51,7 @@ class ReportScreen:
246
247 self._title = urwid.LineBox(urwid.Edit(), 'Bug Title')
248 self._description = urwid.LineBox(urwid.Edit(edit_text=self.default_description,
249- multiline=True),
250+ multiline=True),
251 "Description (including steps to reproduce)")
252 self._project = urwid.LineBox(urwid.Edit(edit_text=project), 'Project')
253 self._series = urwid.LineBox(urwid.Edit(), 'Series')
254@@ -70,17 +61,28 @@ class ReportScreen:
255 self._importance = []
256 for i in self.importances:
257 rb = urwid.RadioButton(self._importance, i, 'first True', None)
258- self._bug_type = []
259- for i in sorted(self.bug_types):
260- rb = urwid.RadioButton(self._bug_type, i, state=False,
261- on_state_change=self.add_tag)
262+ self._bug_features = []
263+ for feature in sorted(self.tags["features"]):
264+ cb = urwid.CheckBox(label=feature, state=False,
265+ on_state_change=self.toggle_tag,
266+ user_data=self.tags["features"])
267+ self._bug_features.append(cb)
268+ self._bug_vendors = []
269+ for vendor in sorted(self.tags["vendors"]):
270+ cb = urwid.CheckBox(label=vendor, state=False,
271+ on_state_change=self.toggle_tag,
272+ user_data=self.tags["vendors"])
273+ self._bug_vendors.append(cb)
274 self._assignee = urwid.LineBox(urwid.Edit(edit_text=assignee), 'Assigned To (Launchpad ID)')
275 self._tags = urwid.LineBox(urwid.Edit(edit_text=tags), 'Tags')
276 status_list = urwid.LineBox(urwid.Pile(self._status), 'Status')
277 importance_list = urwid.LineBox(urwid.Pile(self._importance), 'Importance')
278- bug_types_list = urwid.LineBox(urwid.Pile(self._bug_type), 'Bug Type')
279+ self.bug_features_list = urwid.LineBox(urwid.Pile(self._bug_features), 'Impacted Feature(s)')
280+ self.bug_vendors_list = urwid.LineBox(urwid.Pile(self._bug_vendors), 'Impacted Vendor(s)')
281 self.message = urwid.Text('')
282 self.footer = urwid.AttrMap(urwid.Text(self.footer_text), 'foot')
283+ self.bug_tags_lists = urwid.Columns([self.bug_features_list,
284+ self.bug_vendors_list])
285 self.pile = urwid.Pile([self.message,
286 self._title,
287 self._description,
288@@ -90,20 +92,27 @@ class ReportScreen:
289 importance_list,
290 self._assignee,
291 self._tags,
292- bug_types_list])
293+ self.bug_tags_lists])
294 self.view = urwid.Frame(urwid.Filler(self.pile, 'top'), footer=self.footer)
295
296- def add_tag(self, rb, state):
297+ def toggle_tag(self, cb, state, user_data):
298+ tags = user_data[cb.label]
299 if state:
300- # for the selected radio button
301- tag = self.bug_types[rb.label]
302- self._tags.base_widget.edit_text += ' ' + tag
303+ # if checkbox is ticked
304+ self._tags.base_widget.edit_text += ' ' + ' '.join(tags)
305 else:
306- # for the previously selected radio button
307- tag = self.bug_types[rb.label]
308- self._tags.base_widget.edit_text = self._tags.base_widget.edit_text.replace(tag, '')
309- # clean up the list of tags to remove unwanted white spaces
310- self._tags.base_widget.edit_text = " ".join(self._tags.base_widget.edit_text.split())
311+ # if checkbox is unticked
312+ for tag in tags:
313+ self._tags.base_widget.edit_text = self._tags.base_widget.edit_text.replace(tag, '')
314+ # clean up the list of tags to
315+ # - remove unwanted white spaces
316+ # - remove duplicated tags
317+ current_tags = self._tags.base_widget.edit_text.split()
318+ dedup_tags = []
319+ for tag in current_tags:
320+ if tag not in dedup_tags:
321+ dedup_tags.append(tag)
322+ self._tags.base_widget.edit_text = " ".join(dedup_tags)
323
324 def run(self):
325 """Run the urwid MainLoop."""
326diff --git a/setup.py b/setup.py
327index 9ca0a66..d01f071 100644
328--- a/setup.py
329+++ b/setup.py
330@@ -20,6 +20,7 @@ qabro is a tool to report bugs against Launchpad projects and
331 automatically attach relevent information to them (log files).
332 """,
333 packages=packages,
334+ package_data={'qabro': ['data/tags.json']},
335 entry_points={
336 'console_scripts': ['qabro = qabro.__init__:main']
337 },
338diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
339index e307ff0..de2580d 100644
340--- a/snap/snapcraft.yaml
341+++ b/snap/snapcraft.yaml
342@@ -43,6 +43,11 @@ parts:
343 - python3-urwid
344 - ubuntu-report
345
346+ dpkg:
347+ plugin: nil
348+ stage-packages:
349+ - dpkg
350+
351 sosreport:
352 after: [patches]
353 plugin: nil
354@@ -56,8 +61,9 @@ parts:
355 # variable used by sosreport to call other commands.
356 patch $SNAPCRAFT_PART_INSTALL/usr/share/sosreport/sos/policies/ubuntu.py $SNAPCRAFT_STAGE/patches/sosreport-env-path-snap.patch
357 # patches from YC Chen
358- patch $SNAPCRAFT_PART_INSTALL/usr/share/sosreport/sos/plugins/apt.py $SNAPCRAFT_STAGE/patches/sosreport-apt-no-auth-conf.patch
359 patch $SNAPCRAFT_PART_INSTALL/usr/share/sosreport/sos/plugins/apt.py $SNAPCRAFT_STAGE/patches/sosreport-apt-remove-user-pwd.patch
360+ # patch to be able to have data from `dpkg -l` command
361+ patch $SNAPCRAFT_PART_INSTALL/usr/share/sosreport/sos/plugins/dpkg.py $SNAPCRAFT_STAGE/patches/sosreport-dpkg-l.patch
362
363 sosreport-plugins:
364 after: [sosreport]

Subscribers

People subscribed via source and target branches

to all changes: