Merge ~sylvain-pineau/plainbox-provider-resource:snapd_resources into plainbox-provider-resource:master

Proposed by Sylvain Pineau
Status: Merged
Approved by: Sylvain Pineau
Approved revision: 2bfd08f5ba444ceea654cf999a4aa6f45cfd9ede
Merged at revision: 136a0de01735babd46fb830b43e85c53a914c2e1
Proposed branch: ~sylvain-pineau/plainbox-provider-resource:snapd_resources
Merge into: plainbox-provider-resource:master
Diff against target: 247 lines (+226/-0)
2 files modified
bin/snapd_resource (+176/-0)
jobs/resource.pxu (+50/-0)
Reviewer Review Type Date Requested Status
Sylvain Pineau (community) Approve
Maciej Kisielewski Needs Information
Review via email: mp+322186@code.launchpad.net

Description of the change

Addition of the snapd resources jobs for desktop test plans and submissions.

The dependency on python3-requests-unixsocket [1] is ensured thanks to a dummy package for Trusty in the dev/stable ppas.

[1] http://packages.ubuntu.com/xenial/python3-requests-unixsocket

To post a comment you must log in.
Revision history for this message
Maciej Kisielewski (kissiel) wrote :

> The dependency on python3-requests-unixsocket [1] is ensured thanks to a dummy package for Trusty in the dev/stable ppas.

I spooled up a fresh VM and installed everything from the dev ppa.
python3-requests-unixsocket didn't get installed.

After I installed it manually all jobs worked perfectly.

How this dependency is ensured? What am I doing wrong?

review: Needs Information
Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

weird, I expected the packaging meta-data unit to do the right job for packaging.

Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

I built the deb package for this provider locally and I can confirm the new dep is well written in the control file:

Package: plainbox-provider-resource-generic
Version: 0.31.0-1
Architecture: amd64
Maintainer: Checkbox Developers <email address hidden>
Installed-Size: 131
Depends: python3 (>= 3.2), python3-checkbox-support (>= 0.22), dmidecode, dpkg (>= 1.13), lsb-release, network-manager, udev, usbutils, python3-requests-unixsocket, libc6 (>= 2.4), libnl-3-200 (>= 3.2.7), libnl-genl-3-200 (>= 3.2.7)
Suggests: x11-server-utils, gconf2, xinput
Section: utils
Priority: optional
Homepage: http://launchpad.net/plainbox-provider-resource
Description: CheckBox generic resource jobs provider
 This package provides the generic resource jobs. It is used together
 alongside with PlainBox.
 .
 Jobs are smallest units of testing that can be performed by PlainBox.
 All jobs have an unique name. There are many types of jobs, some are fully
 automated others are fully manual.
 .
 Resources are collections of key-value data sets that are generated by
 special resource jobs. They are extensively used to indicate hardware or
 software dependencies. For example a bluetooth test may indicate it
 requires bluetooth hardware and appropriate software packages installed.

Once new builds will be available in the dev ppa, you'll see python3-requests-unixsocket installed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/bin/snapd_resource b/bin/snapd_resource
2new file mode 100755
3index 0000000..da0cac9
4--- /dev/null
5+++ b/bin/snapd_resource
6@@ -0,0 +1,176 @@
7+#!/usr/bin/env python3
8+# Copyright 2017 Canonical Ltd.
9+# All rights reserved.
10+#
11+# Written by:
12+# Authors: Jonathan Cave <jonathan.cave@canonical.com>
13+
14+import io
15+import logging
16+import sys
17+
18+from guacamole import Command
19+import requests
20+import requests_unixsocket
21+
22+
23+SNAPD_BASE_URL = 'http+unix://%2Frun%2Fsnapd.socket'
24+
25+
26+class SnapdQuery(Command):
27+
28+ def __init__(self):
29+ self._session = requests_unixsocket.Session()
30+
31+ def get(self, path):
32+ r = self._session.get(SNAPD_BASE_URL + path)
33+ if r.status_code != requests.codes.ok:
34+ logging.error("Got error {} attempting to access {}".format(
35+ r.status_code, path))
36+ sys.exit(1)
37+ return r
38+
39+
40+class AssertionQuery(SnapdQuery):
41+
42+ prefix = '/v2/assertions/'
43+
44+ def convert(self, assertion):
45+ """ Super naive Assertion parser
46+
47+ No attempt to handle assertions with a body. Discards signatures based
48+ on lack of colon characters.
49+ """
50+ data = self.get(self.prefix + assertion)
51+ count = int(data.headers['X-Ubuntu-Assertions-Count'])
52+ if count > 0:
53+ for line in io.StringIO(data.text):
54+ if line.strip() == "":
55+ print()
56+ if ':' in line:
57+ print(line.strip())
58+ return count
59+
60+
61+class ModelAssertion(AssertionQuery):
62+
63+ def invoked(self, ctx):
64+ count = self.convert('model')
65+ if count == 0:
66+ # Print a dummy assertion - not nice but really trick to use
67+ # plainbox resources without some defualt value
68+ print('type: model')
69+ print('authority-id: None')
70+ print('model: None')
71+ print()
72+
73+
74+class SerialAssertion(AssertionQuery):
75+
76+ def invoked(self, ctx):
77+ count = self.convert('serial')
78+ if count == 0:
79+ # Print a dummy assertion - not nice but really trick to use
80+ # plainbox resources without some defualt value
81+ print('type: serial')
82+ print('authority-id: None')
83+ print('serial: None')
84+ print()
85+
86+
87+class Assertions(Command):
88+
89+ sub_commands = (
90+ ('model', ModelAssertion),
91+ ('serial', SerialAssertion),
92+ )
93+
94+
95+class Snaps(SnapdQuery):
96+
97+ prefix = '/v2/snaps'
98+
99+ def invoked(self, ctx):
100+ data = self.get(self.prefix).json()
101+
102+ for snap in data['result']:
103+ def print_field(key):
104+ val = snap[key]
105+ if val != "":
106+ print("{}: {}".format(key, val))
107+ # Whitelist of information that is of interest
108+ keys = ['name', 'type', 'channel', 'version', 'revision',
109+ 'developer', 'install-date', 'confinement', 'devmode']
110+ for f in keys:
111+ print_field(f)
112+ print()
113+
114+
115+class InterfacesQuery(SnapdQuery):
116+
117+ prefix = '/v2/interfaces'
118+
119+
120+class Endpoints(InterfacesQuery):
121+
122+ def invoked(self, ctx):
123+ data = self.get(self.prefix).json()
124+
125+ for plug in data['result']['plugs']:
126+ def print_field(key):
127+ val = plug[key]
128+ if val != '':
129+ print('{}: {}'.format(key, val))
130+ keys = ['snap', 'interface']
131+ for f in keys:
132+ print_field(f)
133+ print('type: plug')
134+ print('name: {}'.format(plug['plug']))
135+ print()
136+
137+ for slot in data['result']['slots']:
138+ def print_field(key):
139+ val = slot[key]
140+ if val != '':
141+ print('{}: {}'.format(key, val))
142+ keys = ['snap', 'interface']
143+ for f in keys:
144+ print_field(f)
145+ print('type: slot')
146+ print('name: {}'.format(slot['slot']))
147+ print()
148+
149+
150+class Connections(InterfacesQuery):
151+
152+ def invoked(self, ctx):
153+ data = self.get(self.prefix).json()
154+
155+ if data['result']['plugs'] is not None:
156+ for plug in data['result']['plugs']:
157+ if 'connections' in plug:
158+ for con in plug['connections']:
159+ print('slot: {}:{}'.format(con['snap'], con['slot']))
160+ print('plug: {}:{}'.format(plug['snap'], plug['plug']))
161+ print()
162+
163+
164+class Interfaces(Command):
165+
166+ sub_commands = (
167+ ('endpoints', Endpoints),
168+ ('connections', Connections),
169+ )
170+
171+
172+class SnapdResource(Command):
173+
174+ sub_commands = (
175+ ('assertions', Assertions),
176+ ('snaps', Snaps),
177+ ('interfaces', Interfaces),
178+ )
179+
180+
181+if __name__ == '__main__':
182+ SnapdResource().main()
183diff --git a/jobs/resource.pxu b/jobs/resource.pxu
184index befc0dd..a7207d7 100644
185--- a/jobs/resource.pxu
186+++ b/jobs/resource.pxu
187@@ -61,6 +61,11 @@ unit: packaging meta-data
188 os-id: debian
189 Depends: usbutils
190
191+# This is for snapd_resource
192+unit: packaging meta-data
193+os-id: debian
194+Depends: python3-requests-unixsocket
195+
196 id: cpuinfo
197 estimated_duration: 0.37
198 plugin: resource
199@@ -332,3 +337,48 @@ _description: Generate an entry for each MIR integration tests
200 command:
201 for test in `mir_integration_tests --gtest_list_tests | sed -n '/\.$/s/\.$//p'`; do echo "category: integration"; echo "name: $test"; echo ""; done
202 for test in `mir_acceptance_tests --gtest_list_tests | sed -n '/\.$/s/\.$//p'`; do echo "category: acceptance"; echo "name: $test"; echo ""; done
203+
204+id: snap
205+estimated_duration: 1.1
206+plugin: resource
207+command:
208+ unset PYTHONUSERBASE
209+ snapd_resource snaps
210+_description: Generates a list of snap packages
211+_summary: Collect information about installed snap packages
212+
213+id: interface
214+estimated_duration: 1.1
215+plugin: resource
216+command:
217+ unset PYTHONUSERBASE
218+ snapd_resource interfaces endpoints
219+_description: Generates a list of interface declarations on the device
220+_summary: Collect information about interfaces
221+
222+id: connections
223+estimated_duration: 1.1
224+plugin: resource
225+command:
226+ unset PYTHONUSERBASE
227+ snapd_resource interfaces connections
228+_description: Generates a list of plug and slot connections on the device
229+_summary: Collect information about connections
230+
231+id: model_assertion
232+_summary: Collect model assertions on the device
233+_description:
234+ Queries the snapd REST API for model assertions present on the device.
235+plugin: resource
236+estimated_duration: 2.0
237+command:
238+ snapd_resource assertions model
239+
240+id: serial_assertion
241+_summary: Collect serial assertions on the device
242+_description:
243+ Queries the snapd REST API for serial assertions present on the device.
244+plugin: resource
245+estimated_duration: 2.0
246+command:
247+ snapd_resource assertions serial

Subscribers

People subscribed via source and target branches