Merge ~pieq/bugit/+git/qabro:fix-1832181-additional-info into bugit:master

Proposed by Pierre Equoy
Status: Superseded
Proposed branch: ~pieq/bugit/+git/qabro:fix-1832181-additional-info
Merge into: bugit:master
Diff against target: 255 lines (+115/-31)
6 files modified
qabro/__init__.py (+4/-3)
qabro/__version__.py (+1/-1)
qabro/bug_assistant.py (+34/-17)
qabro/ui.py (+1/-1)
qabro/utils.py (+67/-0)
snap/snapcraft.yaml (+8/-9)
Reviewer Review Type Date Requested Status
OEM Services QA Pending
Review via email: mp+368693@code.launchpad.net

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

This proposal has been superseded by a proposal from 2019-06-12.

Description of the change

Check related bug for more information.

Tested by building a snap and running it on:

- Desktop 18.04
- OEM Desktop 18.04
- Ubuntu Core 16

making sure:

- the manifest field is retrieved when using OEM images
- all the GPUs are shown when the device has more than one

Note: this branch includes the changes made in https://code.launchpad.net/~pieq/qabro/+git/qabro/+ref/move-to-base18

To post a comment you must log in.

Unmerged commits

f212b3c... by Pierre Equoy

Use layout section directly

This snap is now using base18, so the passthrough section is not needed
anymore.

9c2e635... by Pierre Equoy

Check for PCI class '03' to get GPUs

LP: #1832181

d1e9dd6... by Pierre Equoy

Get OEM manifest from system instead of calling ubuntu-report

ubuntu-report gets its OEM manifest information from file
/var/lib/ubuntu_dist_channel. In a snap runtime, this file is available
in /var/lib/snapd/hostfs. This commit uses the same way to access the
OEM manifest as ubuntu-report without actually calling ubuntu-report :)

LP: #1832181

2f06c24... by Pierre Equoy

Add SKU to Additional information section

SKU cannot be determined automatically, but it helps QA engineers to
have an empty line already here to input it.

LP: #1832181

ff30707... by Pierre Equoy

Bump to v0.11dev

7bb591b... by Pierre Equoy

Move to base18

1c2369e... by Pierre Equoy

Use snapd socket to retrieve snap information

core18 does not have access to the `snap` command; therefore, it is not
possible to run commands like `snap list` like we used to do. Instead,
snapcraft team recommends to use the socket to snapd in order to
communicate with snap.

This commit does so by implementing a snapdsocket class that
communicates with the snapd socket.

The snap_list.org attachment method is revamped to use this new class,
as well as the check for qabro's devmode when running the app.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/qabro/__init__.py b/qabro/__init__.py
2index 815374c..9c72446 100644
3--- a/qabro/__init__.py
4+++ b/qabro/__init__.py
5@@ -6,6 +6,7 @@ import sys
6
7 from qabro.bug_assistant import BugAssistant, BugReport
8 from qabro.ui import ReportScreen
9+from qabro.utils import snapdsocket
10
11
12 logger = logging.getLogger(__name__)
13@@ -20,10 +21,10 @@ def main():
14 sys.exit(("Cannot determine snap name. "
15 "Please install this tool using the snap command."))
16
17- output = subprocess.check_output(['snap', 'list', snap_name],
18- universal_newlines=True)
19+ ss = snapdsocket()
20+ qabro_snap_info = [e for e in ss.get_snaps() if e['name'] == 'qabro'][0]
21
22- if 'devmode' not in output:
23+ if not qabro_snap_info['devmode']:
24 sys.exit("This tool requires --devmode option to run properly.")
25
26 logfile = os.path.join(os.getenv('SNAP_USER_COMMON', '/tmp'), 'qabro.log')
27diff --git a/qabro/__version__.py b/qabro/__version__.py
28index 992265c..29033e1 100644
29--- a/qabro/__version__.py
30+++ b/qabro/__version__.py
31@@ -1,5 +1,5 @@
32 __title__ = 'qabro'
33-__version__ = '0.10.1'
34+__version__ = '0.11dev'
35 __description__ = 'Tool to generate a Launchpad bug report and attach useful logs (using sosreport and the like).'
36 __author__ = 'Pierre Equoy'
37 __author_email__ = 'pierre.equoy@canonical.com'
38diff --git a/qabro/bug_assistant.py b/qabro/bug_assistant.py
39index 209eb12..12f6df4 100644
40--- a/qabro/bug_assistant.py
41+++ b/qabro/bug_assistant.py
42@@ -1,8 +1,6 @@
43 import getpass
44-import json
45 import os
46 import re
47-import shutil
48 import subprocess
49 import sys
50 import tarfile
51@@ -11,6 +9,8 @@ from collections import Counter
52 from launchpadlib.launchpad import Launchpad
53 from launchpadlib.uris import LPNET_WEB_ROOT, STAGING_WEB_ROOT, QASTAGING_WEB_ROOT
54
55+from qabro.utils import snapdsocket
56+
57
58 class BugReport:
59 """Bug report.
60@@ -247,8 +247,21 @@ class AttachmentAssistant:
61 print("No $PATH defined. Cannot run sosreport!")
62
63 def attach_snaplist(self):
64- output = subprocess.check_output(['snap', 'list'])
65- self.attachments['snap_list.log'] = output
66+ print("Retrieving list of installed snaps...")
67+ sckt = snapdsocket()
68+ snaps = sckt.get_snaps()
69+ fmt = "{:<32}{:<16}{:<16}{:<16}{:<16}{:<16}"
70+ out = fmt.format("Name", "Version", "Revision",
71+ "Channel", "Devmode", "Confinement") + "\n"
72+ for snap in snaps:
73+ if snap["devmode"]:
74+ devmode = "yes"
75+ else:
76+ devmode = "no"
77+ out += fmt.format(snap["name"], snap["version"], snap["revision"],
78+ snap.get("tracking-channel", "-"), devmode,
79+ snap["confinement"]) + "\n"
80+ self.attachments["snap_list.log"] = out.encode()
81
82 def attach_last_checkbox_session(self):
83 """Archive the most recent Plainbox session available and add it to
84@@ -264,10 +277,10 @@ class AttachmentAssistant:
85 if os.path.exists(classic_path):
86 rootpath = classic_path
87 else:
88- out = subprocess.check_output(["snap", "list"]).decode('utf-8')
89- snap_name_list = [e for e in out.split() if 'checkbox' in e]
90- if snap_name_list:
91- snap_name = snap_name_list[0]
92+ ss = snapdsocket()
93+ snap_list = [e for e in ss.get_snaps() if 'checkbox' in e['name']]
94+ if snap_list:
95+ snap_name = snap_list[0]["name"]
96 sp = "/home/$USER/snap/{}/current/plainbox/sessions"
97 snap_path = os.path.expandvars(sp.format(snap_name))
98 if os.path.exists(snap_path):
99@@ -326,13 +339,16 @@ class AttachmentAssistant:
100 standard_info['Image'] = subprocess.check_output(
101 ['tail', '-n', '1', buildstamp]).decode(sys.stdout.encoding).strip()
102
103- if shutil.which("ubuntu-report"):
104- print("Retrieving Manifest information...")
105- report = subprocess.check_output(["ubuntu-report", "show"])
106- reportjson = json.loads(report)
107- manifest = reportjson.get("OEM").get("DCD")
108- if manifest:
109- standard_info["Manifest"] = manifest
110+ # This file hosts the OEM Manifest information we need
111+ # See: https://forum.snapcraft.io/t/read-access-to-a-file-in-var-lib-on-the-host/11766
112+ udc = '/var/lib/snapd/hostfs/var/lib/ubuntu_dist_channel'
113+ manifest = ''
114+ if os.path.isfile(udc):
115+ with open(udc) as f:
116+ dcd = f.read()
117+ manifest = re.search("^([^\s#]+)$", dcd, re.MULTILINE)[0]
118+ if manifest:
119+ standard_info["Manifest"] = manifest
120
121 p = os.getenv('PATH')
122
123@@ -351,11 +367,12 @@ class AttachmentAssistant:
124
125 standard_info['CPU'] = AttachmentAssistant.get_cpu_info()
126
127- lspci_output = (subprocess.check_output(['lspci'])
128+ lspci_output = (subprocess.check_output(['lspci', '-nn'])
129 .decode(sys.stdout.encoding)
130 .splitlines())
131+ # '03' is the PCI class for display controllers
132 standard_info['GPU'] = '\n'.join([line for line in lspci_output
133- if 'VGA' in line])
134+ if '[03' in line])
135
136 standard_info["kernel-version"] = (subprocess.check_output(["uname", "-r"])
137 .decode(sys.stdout.encoding)
138diff --git a/qabro/ui.py b/qabro/ui.py
139index 26f6bba..9303cc9 100644
140--- a/qabro/ui.py
141+++ b/qabro/ui.py
142@@ -56,7 +56,7 @@ class ReportScreen:
143 # Adding standard info (CPU, BIOS, GPU, etc.) to the description
144 std_info = AttachmentAssistant.get_standard_info()
145 std_info_str = '\n'.join(['{}: {}'.format(elt, std_info[elt]) for elt in std_info])
146- self.default_description += "[Additional information]\n" + std_info_str
147+ self.default_description += "[Additional information]\nSKU: \n" + std_info_str
148
149 self._title = urwid.LineBox(urwid.Edit(), 'Bug Title')
150 self._description = urwid.LineBox(urwid.Edit(edit_text=self.default_description,
151diff --git a/qabro/utils.py b/qabro/utils.py
152new file mode 100644
153index 0000000..af790eb
154--- /dev/null
155+++ b/qabro/utils.py
156@@ -0,0 +1,67 @@
157+#!/usr/bin/env python3
158+import socket, json, pprint
159+
160+class snapdsocket:
161+ def __init__(self, sock=None):
162+ if sock is None:
163+ self.sock = socket.socket(socket.AF_UNIX)
164+ else:
165+ self.sock = sock
166+ self.sock.settimeout(0.3)
167+
168+ def _connect(self):
169+ self.sock.connect("/run/snapd.socket")
170+
171+ def _send(self, msg):
172+ if type(msg) != "bytes":
173+ msg = msg.encode()
174+ self.sock.send(msg)
175+
176+ def _recv(self):
177+ chunks = []
178+ while True:
179+ try:
180+ chunk = self.sock.recv(2048)
181+ chunks.append(chunk.decode())
182+ except socket.timeout:
183+ break
184+ return ''.join(chunks)
185+
186+ def _close(self):
187+ self.sock.close()
188+
189+ def _get_json_response(self, response):
190+ begin = response.find('{')
191+ end = response.rfind('}') + 1
192+ return json.loads(response[begin:end])
193+
194+ def request(self, msg):
195+ self.__init__()
196+ self._connect()
197+ self._send(msg)
198+ raw_resp = self._recv()
199+ self._close()
200+ json_resp = self._get_json_response(raw_resp)
201+ return json_resp
202+
203+ def get_interfaces(self):
204+ req = "GET /v2/interfaces HTTP/1.1\r\nHost: localhost\r\n\r\n"
205+ json_resp = self.request(req)
206+ return json_resp['result']
207+
208+ def get_snaps(self):
209+ req = "GET /v2/snaps HTTP/1.1\r\nHost: localhost\r\n\r\n"
210+ json_resp = self.request(req)
211+ return json_resp['result']
212+
213+ def get_snap_names(self):
214+ req = "GET /v2/snaps HTTP/1.1\r\nHost: localhost\r\n\r\n"
215+ json_resp = self.request(req)
216+ snap_names = []
217+ for s in json_resp["result"]:
218+ snap_names.append(s["name"])
219+ return snap_names
220+
221+if __name__ == "__main__":
222+ sn = snapdsocket()
223+ pprint.pprint(sn.get_snaps())
224diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
225index 0a2ec6c..2c9982d 100644
226--- a/snap/snapcraft.yaml
227+++ b/snap/snapcraft.yaml
228@@ -4,6 +4,7 @@ adopt-info: qabro
229
230 grade: stable # must be 'stable' to release into candidate/stable channels
231 confinement: strict # use 'strict' once you have the right plugs and slots
232+base: core18
233
234 apps:
235 qabro:
236@@ -112,12 +113,10 @@ parts:
237 '*': patches/
238 prime: [-*]
239
240-# https://forum.snapcraft.io/t/snap-layouts/7207
241-passthrough:
242- layout:
243- /etc/sos.conf:
244- bind-file: $SNAP/etc/sos.conf
245- /var/lib/usbutils/usb.ids:
246- bind-file: $SNAP/var/lib/usbutils/usb.ids
247- /usr/share/alsa:
248- bind: $SNAP/usr/share/alsa
249+layout:
250+ /etc/sos.conf:
251+ bind-file: $SNAP/etc/sos.conf
252+ /var/lib/usbutils/usb.ids:
253+ bind-file: $SNAP/var/lib/usbutils/usb.ids
254+ /usr/share/alsa:
255+ bind: $SNAP/usr/share/alsa

Subscribers

People subscribed via source and target branches

to all changes: