Merge lp:~sylvain-pineau/checkbox/bug1050920 into lp:checkbox
- bug1050920
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1718 |
Proposed branch: | lp:~sylvain-pineau/checkbox/bug1050920 |
Merge into: | lp:checkbox |
Diff against target: |
521 lines (+89/-193) 8 files modified
checkbox/parsers/udevadm.py (+19/-0) debian/changelog (+3/-0) jobs/mediacard.txt.in (+1/-1) jobs/resource.txt.in (+0/-6) scripts/memorycard_resource (+0/-143) scripts/optical_write_test (+4/-3) scripts/removable_storage_test (+29/-20) scripts/removable_storage_watcher (+33/-20) |
To merge this branch: | bzr merge lp:~sylvain-pineau/checkbox/bug1050920 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marc Tardif (community) | Needs Information | ||
Zygmunt Krynicki (community) | Approve | ||
Sylvain Pineau (community) | Needs Resubmitting | ||
Review via email: mp+124458@code.launchpad.net |
Commit message
Description of the change
This MR fixed the memorycard regexp flags and added the DriveVendor Udisks property to the re.search() string in removable_storage* scripts and the memorycard_resource job.
Marc Tardif (cr3) wrote : | # |
Marc Tardif (cr3) wrote : | # |
Note that one advantage to the shell script is that it doesn't require any crazy call to ioctl, and another advantage is that it doesn't need to run as root since udev_resource leverages udev that exposes some useful information.
Sylvain Pineau (sylvain-pineau) wrote : | # |
udev seems to offer the same results but to fully replace my crazy ioctl I would change your proposal like this:
export PATH=/usr/
run_templates -st "udev_resource | filter_templates -w 'driver=sd'" <<'EOF' \
| (egrep -qi '(SD|MMC|
&& echo 'reader: detected' \
|| echo 'reader: none'
$product $vendor
EOF
I will change my MR to reflect this very nice improvement, Thx
Marc Tardif (cr3) wrote : | # |
We might want to discuss ading the MEDIACARD category in the output of the udev_resource script. However, that really depends on how confident you are about this regular expression to distinguish disk devices from multicard devices: '(SD|MMC|
- 1676. By Sylvain Pineau
-
the memory_card resource job now uses udev_resource output
- 1677. By Sylvain Pineau
-
Merged from trunk
Sylvain Pineau (sylvain-pineau) wrote : | # |
I prefer to keep the memory_card resource job separated from udev_resource. We don't have yet enough feedback on how reliable the regexp is.
Zygmunt Krynicki (zyga) wrote : | # |
24 + run_templates -st "udev_resource | filter_templates -w 'driver=sd'" <<'EOF' \
25 + | (egrep -qi '(SD|MMC|
26 + && echo 'reader: detected' \
27 + || echo 'reader: none'
This is the kind of thing that deserves an API as it needs to be reused in various places
Zygmunt Krynicki (zyga) wrote : | # |
/me puts syntax nazi hat on
I'm pretty sure (just by looking at a few lines) that this is not PEP8 clean, would you mind fixing it please?
- 1678. By Sylvain Pineau
-
Move the card reader detection logic to udevadm.py
- 1679. By Sylvain Pineau
-
Merged from trunk
- 1680. By Sylvain Pineau
-
Revert unwanted changes to optical_write_test
- 1681. By Sylvain Pineau
-
PEP8 check
Sylvain Pineau (sylvain-pineau) wrote : | # |
/lib/udev/
The following drivers are supported: sdhci, sdhci-pci, mmc* and sd.
For sd, the parser checks the model name (aka product in udevadm.py) and the vendor name.
Nota: The code contains several pep8 fixes in removable_storage*
Zygmunt Krynicki (zyga) wrote : | # |
No objections to merge.
Looking at the delta I see two things that need fixing (but are unrelated to your change) - the one with namedtuple instead of dev[x] and the one where args.speed is not a integer (removable_
You may want to get a second opinion though as I'm temporarily out of precise systems that I can test this on
- 1682. By Sylvain Pineau
-
Check if the product field exists in _environment before checking sd driver devices
Marc Tardif (cr3) wrote : | # |
This looks very nice, thanks for taking the time to improve udev_resource, I now get this on my system:
path: /devices/
bus: scsi
category: CARDREADER
driver: sd
product: SAMSUNG MMCRE64G8MPP-0VA
Do you think we could import CARD_READER_RE from checkbox.
Sylvain Pineau (sylvain-pineau) wrote : | # |
@Marc, Matching an internal SSD drive will prevent it to be used for disks tests.
Could you please pastebin the output of udisks --show-info /dev/sdx (where x is your drive letter). Don't provide the output of an existing partition like sdb2, just sdb to have the drive properties.
I think we could use the rotational media udisks property to avoid them to be detected as card readers. My system reports the following info for a usb reader:
drive:
vendor: Generic
model: Ultra HS-SD/MMC
revision: 1.82
serial: 000000264001
WWN:
detachable: 1
can spindown: 0
rotational media: Yes, unknown rate
- 1683. By Sylvain Pineau
-
Card reader detection improved in udev parser, relying on udev properties first and finally and the regexp if not matches found.
- 1684. By Sylvain Pineau
-
Updated removable_storage* scripts with udevadm regexp
pep8 fixes
device property is now a namedtuple - 1685. By Sylvain Pineau
-
Merged from trunk
- 1686. By Sylvain Pineau
-
Change removable_
storage_ watcher permissions (+x) - 1687. By Sylvain Pineau
-
lint fixes
Sylvain Pineau (sylvain-pineau) wrote : | # |
I reworked a bit the udevadm parser section about card readers, to follow this schema: give priority to udev rules. First identify memorycard readers with ID_DRIVE_FLASH_SD and if not matches fallback to the regexp identification. When upstream patches will identify crazy usb readers, we could safely remove those lines.
Regexp used in removable_storage* scripts ar all imported from the udevadm parser.
The bug identifying SSD drives is fixed.
Preview Diff
1 | === modified file 'checkbox/parsers/udevadm.py' |
2 | --- checkbox/parsers/udevadm.py 2012-09-25 11:52:25 +0000 |
3 | +++ checkbox/parsers/udevadm.py 2012-10-01 07:54:21 +0000 |
4 | @@ -59,6 +59,9 @@ |
5 | r"^scsi:" |
6 | r"t-0x(?P<type>[%(hex)s]{2})" |
7 | % {"hex": string.hexdigits}) |
8 | +CARD_READER_RE = re.compile(r"SD|MMC|CF|MS|SM|xD|Card", re.I) |
9 | +GENERIC_RE = re.compile(r"Generic", re.I) |
10 | +FLASH_RE = re.compile(r"Flash", re.I) |
11 | |
12 | |
13 | class UdevadmDevice: |
14 | @@ -208,6 +211,22 @@ |
15 | if test_bit(Input.BTN_MOUSE, bitmask, self._bits): |
16 | return "MOUSE" |
17 | |
18 | + if self.driver: |
19 | + if self.driver.startswith("sdhci"): |
20 | + return "CARDREADER" |
21 | + |
22 | + if self.driver.startswith("mmc"): |
23 | + return "CARDREADER" |
24 | + |
25 | + if self.driver == "sd" and self.product: |
26 | + if any(FLASH_RE.search(k) for k in self._environment.keys()): |
27 | + return "CARDREADER" |
28 | + if any(d.bus == 'usb' for d in self._stack): |
29 | + if CARD_READER_RE.search(self.product): |
30 | + return "CARDREADER" |
31 | + if GENERIC_RE.search(self.vendor): |
32 | + return "CARDREADER" |
33 | + |
34 | if "ID_TYPE" in self._environment: |
35 | id_type = self._environment["ID_TYPE"] |
36 | |
37 | |
38 | === modified file 'debian/changelog' |
39 | --- debian/changelog 2012-09-28 16:29:41 +0000 |
40 | +++ debian/changelog 2012-10-01 07:54:21 +0000 |
41 | @@ -165,6 +165,9 @@ |
42 | * checkbox/parsers/udevadm.py: Improved wireless devices detection. |
43 | The wireless category is now set if the subsystem is equal to ieee80211 |
44 | (LP: #855382) |
45 | + * scripts/memorycard_resource, scripts/removable_storage_test, |
46 | + scripts/removable_storage_watcher: Fixed the memorycard regexp flags and |
47 | + add the DriveVendor Udisks property to the re.search() string (LP: #1050920) |
48 | |
49 | [Zygmunt Krynicki] |
50 | * Fixed simple duplicate 'the' mistakes (LP: #1040022) |
51 | |
52 | === modified file 'jobs/mediacard.txt.in' |
53 | --- jobs/mediacard.txt.in 2012-09-04 19:15:43 +0000 |
54 | +++ jobs/mediacard.txt.in 2012-10-01 07:54:21 +0000 |
55 | @@ -181,7 +181,7 @@ |
56 | user: root |
57 | requires: |
58 | package.name == 'udisks' |
59 | - memory_card.reader == 'detected' |
60 | + device.category == 'CARDREADER' |
61 | command: removable_storage_test --memorycard -l sdio usb scsi && removable_storage_test --memorycard sdio usb scsi |
62 | _description: |
63 | This is a fully automated version of mediacard/sd-automated and assumes that the |
64 | |
65 | === modified file 'jobs/resource.txt.in' |
66 | --- jobs/resource.txt.in 2012-09-06 09:42:43 +0000 |
67 | +++ jobs/resource.txt.in 2012-10-01 07:54:21 +0000 |
68 | @@ -100,9 +100,3 @@ |
69 | for e in `env | sed 's/=/:/g'`; do |
70 | echo $e | awk -F':' '{print tolower($1) ": " $2}' |
71 | done |
72 | - |
73 | -name: memory_card |
74 | -plugin: resource |
75 | -user: root |
76 | -command: memorycard_resource |
77 | -description: Create resource info for memorycard readers |
78 | |
79 | === removed file 'scripts/memorycard_resource' |
80 | --- scripts/memorycard_resource 2012-09-05 20:09:10 +0000 |
81 | +++ scripts/memorycard_resource 1970-01-01 00:00:00 +0000 |
82 | @@ -1,143 +0,0 @@ |
83 | -#!/usr/bin/python3 |
84 | -# |
85 | -# This file is part of Checkbox. |
86 | -# |
87 | -# Copyright 2012 Canonical Ltd. |
88 | -# |
89 | -# Checkbox is free software: you can redistribute it and/or modify |
90 | -# it under the terms of the GNU General Public License as published by |
91 | -# the Free Software Foundation, either version 3 of the License, or |
92 | -# (at your option) any later version. |
93 | -# |
94 | -# Checkbox is distributed in the hope that it will be useful, |
95 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
96 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
97 | -# GNU General Public License for more details. |
98 | -# |
99 | -# You should have received a copy of the GNU General Public License |
100 | -# along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
101 | -# |
102 | - |
103 | -import re |
104 | -import sys |
105 | -import fcntl |
106 | -import struct |
107 | -import ctypes |
108 | -from glob import glob |
109 | -from subprocess import call |
110 | - |
111 | - |
112 | -class sg_io_hdr(ctypes.Structure): |
113 | - """ |
114 | - Do ioctl's using Linux generic SCSI interface. |
115 | - """ |
116 | - SG_IO = 0x2285 |
117 | - |
118 | - _fields_ = [("interface_id", ctypes.c_int), |
119 | - ("dxfer_direction", ctypes.c_int), |
120 | - ("cmd_len", ctypes.c_ubyte), |
121 | - ("mx_sb_len", ctypes.c_ubyte), |
122 | - ("iovec_count", ctypes.c_ushort), |
123 | - ("dxfer_len", ctypes.c_int), |
124 | - ("dxferp", ctypes.c_char_p), |
125 | - ("cmdp", ctypes.c_char_p), |
126 | - ("sbp", ctypes.c_char_p), |
127 | - ("timeout", ctypes.c_uint), |
128 | - ("flags", ctypes.c_uint), |
129 | - ("pack_id", ctypes.c_int), |
130 | - ("usr_ptr", ctypes.c_char_p), |
131 | - ("status", ctypes.c_ubyte), |
132 | - ("masked_status", ctypes.c_ubyte), |
133 | - ("msg_status", ctypes.c_ubyte), |
134 | - ("sb_len_wr", ctypes.c_ubyte), |
135 | - ("host_status", ctypes.c_ushort), |
136 | - ("driver_status", ctypes.c_ushort), |
137 | - ("resid", ctypes.c_int), |
138 | - ("duration", ctypes.c_uint), |
139 | - ("info", ctypes.c_uint)] |
140 | - |
141 | - def __init__(self): |
142 | - self.interface_id = ord('S') |
143 | - self.dxfer_direction = 0 |
144 | - self.cmd_len = 0 |
145 | - self.mx_sb_len = 0 |
146 | - self.iovec_count = 0 |
147 | - self.dxfer_len = 0 |
148 | - self.dxferp = None |
149 | - self.cmdp = None |
150 | - self.timeout = 20000 |
151 | - self.flags = 0 |
152 | - self.pack_id = 0 |
153 | - self.usr_ptr = None |
154 | - self.status = 0 |
155 | - self.masked_status = 0 |
156 | - self.msg_status = 0 |
157 | - self.sb_len_wr = 0 |
158 | - self.host_status = 0 |
159 | - self.driver_status = 0 |
160 | - self.resid = 0 |
161 | - self.duration = 0 |
162 | - self.info = 0 |
163 | - |
164 | - |
165 | -def _get_sub_page(size, control_block, device): |
166 | - """ |
167 | - ioctl to retrieve a sub-page from the device. |
168 | - """ |
169 | - io_hdr = sg_io_hdr() |
170 | - io_hdr.dxfer_direction = -3 |
171 | - io_hdr.cmd_len = len(control_block) |
172 | - io_hdr.cmdp = control_block |
173 | - page_buffer = ctypes.create_string_buffer(size) |
174 | - io_hdr.dxfer_len = size |
175 | - io_hdr.dxferp = ctypes.cast(page_buffer, ctypes.c_char_p) |
176 | - |
177 | - i = -1 |
178 | - try: |
179 | - with open(device, 'r') as fd: |
180 | - i = fcntl.ioctl(fd, sg_io_hdr.SG_IO, io_hdr) |
181 | - except IOError: |
182 | - return None |
183 | - |
184 | - if i < 0: |
185 | - raise IOError("SG_IO ioctl error") |
186 | - |
187 | - if io_hdr.status != 0x00: |
188 | - raise IOError("io_hdr status is: %x" % io_hdr.status) |
189 | - |
190 | - if io_hdr.resid > 0: |
191 | - retsize = size - io_hdr.resid |
192 | - else: |
193 | - retsize = size |
194 | - |
195 | - return page_buffer[0:retsize] |
196 | - |
197 | - |
198 | -def inquire(device): |
199 | - """ |
200 | - Issue a SCSI INQUIRY command |
201 | - """ |
202 | - fields = '>BBBBBBBB8s16s4s20sBB8HH' |
203 | - fields_len = struct.calcsize(fields) |
204 | - control_block = struct.pack("BBBBBB", 0x12, 0, 0, 0, fields_len, 0) |
205 | - try: |
206 | - return _get_sub_page(fields_len, control_block, device)[8:32].decode() |
207 | - except TypeError: |
208 | - return '' |
209 | - |
210 | - |
211 | -def main(): |
212 | - pattern = re.compile('SD|MMC|CF|MS|SM|xD|Card|Generic') |
213 | - matches = [dev for dev in glob('/dev/sg*') if |
214 | - pattern.search(inquire(dev), re.I)] |
215 | - |
216 | - if matches or not call( |
217 | - "grep -q 'SDHCI controller found' /var/log/kern.log*", shell=True): |
218 | - print('reader: detected') |
219 | - else: |
220 | - print('reader: none') |
221 | - |
222 | - return 0 |
223 | - |
224 | -if __name__ == "__main__": |
225 | - sys.exit(main()) |
226 | |
227 | === modified file 'scripts/optical_write_test' |
228 | --- scripts/optical_write_test 2012-09-24 14:39:56 +0000 |
229 | +++ scripts/optical_write_test 2012-10-01 07:54:21 +0000 |
230 | @@ -68,14 +68,14 @@ |
231 | while true; do |
232 | sleep $INTERVAL |
233 | SLEEP_COUNT=`expr $SLEEP_COUNT + $INTERVAL` |
234 | - |
235 | + |
236 | mount $OPTICAL_DRIVE 2>&1 |egrep -q "already mounted" |
237 | rt=$? |
238 | if [ $rt -eq 0 ]; then |
239 | echo "Drive appears to be mounted now" |
240 | break |
241 | fi |
242 | - |
243 | + |
244 | # If they exceed the timeout limit, make a best effort to load the tray |
245 | # in the next steps |
246 | if [ $SLEEP_COUNT -ge $TIMEOUT ]; then |
247 | @@ -84,6 +84,7 @@ |
248 | fi |
249 | done |
250 | |
251 | + |
252 | echo "Deleting original data files ..." |
253 | rm -rf $SAMPLE_FILE |
254 | if [ ! -z "$(mount | grep $OPTICAL_DRIVE)" ]; then |
255 | @@ -130,7 +131,7 @@ |
256 | OPTICAL_DRIVE=$(readlink -f $1) |
257 | else |
258 | OPTICAL_DRIVE='/dev/sr0' |
259 | -fi |
260 | +fi |
261 | |
262 | create_working_dirs || failed "Failed to create working directories" |
263 | get_sample_data || failed "Failed to copy sample data" |
264 | |
265 | === modified file 'scripts/removable_storage_test' |
266 | --- scripts/removable_storage_test 2012-09-06 09:27:13 +0000 |
267 | +++ scripts/removable_storage_test 2012-10-01 07:54:21 +0000 |
268 | @@ -4,7 +4,6 @@ |
269 | import sys |
270 | import random |
271 | import os |
272 | -import re |
273 | import tempfile |
274 | import hashlib |
275 | import argparse |
276 | @@ -12,6 +11,7 @@ |
277 | import threading |
278 | import time |
279 | import collections |
280 | +from checkbox.parsers.udevadm import CARD_READER_RE, GENERIC_RE, FLASH_RE |
281 | |
282 | |
283 | class ActionTimer(): |
284 | @@ -142,7 +142,6 @@ |
285 | self.rem_disks_nm = {} |
286 | self.rem_disks_memory_cards = {} |
287 | self.rem_disks_memory_cards_nm = {} |
288 | - pattern = re.compile('SD|MMC|CF|MS|SM|xD|Card|Generic') |
289 | for dev in ud_manager.EnumerateDevices(): |
290 | device_obj = bus.get_object("org.freedesktop.UDisks", dev) |
291 | device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE) |
292 | @@ -150,20 +149,26 @@ |
293 | if not device_props.Get(udisks, "DeviceIsDrive"): |
294 | dev_bus = device_props.Get(udisks, "DriveConnectionInterface") |
295 | if dev_bus in args.device: |
296 | - parent_model = '' |
297 | + parent_model = parent_vendor = '' |
298 | if device_props.Get(udisks, "DeviceIsPartition"): |
299 | parent_obj = bus.get_object( |
300 | "org.freedesktop.UDisks", |
301 | device_props.Get(udisks, "PartitionSlave")) |
302 | parent_props = dbus.Interface( |
303 | parent_obj, dbus.PROPERTIES_IFACE) |
304 | - parent_model=parent_props.Get(udisks, "DriveModel") |
305 | + parent_model = parent_props.Get(udisks, "DriveModel") |
306 | + parent_vendor = parent_props.Get(udisks, "DriveVendor") |
307 | + parent_media = parent_props.Get(udisks, "DriveMedia") |
308 | if args.memorycard: |
309 | - if dev_bus != 'sdio' and not pattern.search( |
310 | - parent_model, re.I): |
311 | + if (dev_bus != 'sdio' |
312 | + and not FLASH_RE.search(parent_media) |
313 | + and not CARD_READER_RE.search(parent_model) |
314 | + and not GENERIC_RE.search(parent_vendor)): |
315 | continue |
316 | else: |
317 | - if pattern.search(parent_model, re.I): |
318 | + if (FLASH_RE.search(parent_media) |
319 | + or CARD_READER_RE.search(parent_model) |
320 | + or GENERIC_RE.search(parent_vendor)): |
321 | continue |
322 | dev_file = str(device_props.Get(udisks, "DeviceFile")) |
323 | dev_speed = str(device_props.Get(udisks, |
324 | @@ -178,7 +183,6 @@ |
325 | self.rem_disks_nm[dev_file] = None |
326 | self.rem_disks_memory_cards_nm[dev_file] = None |
327 | |
328 | - |
329 | def mount(self): |
330 | passed_mount = {} |
331 | |
332 | @@ -379,7 +383,8 @@ |
333 | print(" %s : %s : %s bits/s" % |
334 | (disk, mount_point, supported_speed), |
335 | end="") |
336 | - if (args.min_speed and int(args.min_speed) > int(supported_speed)): |
337 | + if (args.min_speed |
338 | + and int(args.min_speed) > int(supported_speed)): |
339 | print(" (Will not test it, speed is below %s bits/s)" % |
340 | args.min_speed, end="") |
341 | |
342 | @@ -387,9 +392,10 @@ |
343 | |
344 | print('-' * 20) |
345 | |
346 | - disks_eligible = {disk: disks_all[disk] for disk in disks_all \ |
347 | - if not args.min_speed or \ |
348 | - int(test.rem_disks_speed[disk]) >= int(args.min_speed) } |
349 | + disks_eligible = {disk: disks_all[disk] for disk in disks_all |
350 | + if not args.min_speed or |
351 | + int(test.rem_disks_speed[disk]) |
352 | + >= int(args.min_speed)} |
353 | write_sizes = [] |
354 | test_files = {} |
355 | # Generate our data file(s) |
356 | @@ -441,8 +447,9 @@ |
357 | test.clean_up(file) |
358 | total_write_time = sum(write_times) |
359 | avg_write_time = total_write_time / args.count |
360 | - avg_write_speed = ( |
361 | - total_write_size / total_write_time) / 1024 / 1024 |
362 | + avg_write_speed = (( |
363 | + total_write_size / total_write_time) |
364 | + / 1024 / 1024) |
365 | iteration_write_times.append(total_write_time) |
366 | print("\t[Iteration %s] Average Speed: %0.4f" |
367 | % (iteration, avg_write_speed)) |
368 | @@ -470,25 +477,27 @@ |
369 | "but there were errors" % args.count) |
370 | return 1 |
371 | elif len(disks_eligible) == 0: |
372 | - print("ERROR: No %s disks with speed higher than %s bits/s" % |
373 | - (args.device, args.min_speed), file=sys.stderr) |
374 | + print("ERROR: No %s disks with speed higher than %s bits/s" |
375 | + % (args.device, args.min_speed), file=sys.stderr) |
376 | return 1 |
377 | |
378 | else: |
379 | #Pass is not assured! |
380 | - if not args.pass_speed or avg_write_speed >= args.pass_speed: |
381 | + if (not args.pass_speed or |
382 | + avg_write_speed >= args.pass_speed): |
383 | return 0 |
384 | else: |
385 | print("FAIL: Average speed was lower than desired " |
386 | "pass speed of %s MB/s" % args.pass_speed) |
387 | return 1 |
388 | else: |
389 | - print("ERROR: No device being mounted successfully for testing, " |
390 | - "aborting", file=sys.stderr) |
391 | + print("ERROR: No device being mounted successfully " |
392 | + "for testing, aborting", file=sys.stderr) |
393 | return 1 |
394 | |
395 | else: # If we don't have removable drives attached and mounted |
396 | - print("ERROR: No removable drives were detected, aborting", file=sys.stderr) |
397 | + print("ERROR: No removable drives were detected, aborting", |
398 | + file=sys.stderr) |
399 | return 1 |
400 | |
401 | if __name__ == '__main__': |
402 | |
403 | === modified file 'scripts/removable_storage_watcher' |
404 | --- scripts/removable_storage_watcher 2012-09-25 09:20:00 +0000 |
405 | +++ scripts/removable_storage_watcher 2012-10-01 07:54:21 +0000 |
406 | @@ -3,14 +3,17 @@ |
407 | import argparse |
408 | import dbus |
409 | import logging |
410 | -import re |
411 | import sys |
412 | |
413 | from dbus.exceptions import DBusException |
414 | from gi.repository import GObject |
415 | |
416 | +from collections import namedtuple |
417 | from checkbox.dbus import connect_to_system_bus |
418 | from checkbox.dbus.udisks2 import UDisks2Model, UDisks2Observer |
419 | +from checkbox.parsers.udevadm import CARD_READER_RE, GENERIC_RE, FLASH_RE |
420 | + |
421 | +Properties = namedtuple('Properties', 'file bus speed model vendor media') |
422 | |
423 | |
424 | def is_udisks2_supported(system_bus): |
425 | @@ -89,33 +92,39 @@ |
426 | desired_bus_devices = [ |
427 | device |
428 | for device in changed_devices |
429 | - if device[1] in self._devices] |
430 | + if device.bus in self._devices] |
431 | logging.debug("Desired bus devices: %s", desired_bus_devices) |
432 | - pattern = re.compile('SD|MMC|CF|MS|SM|xD|Card|Generic') |
433 | for dev in desired_bus_devices: |
434 | if self._memorycard: |
435 | - if dev[1] != 'sdio' and not pattern.search(dev[3], re.I): |
436 | + if (dev.bus != 'sdio' |
437 | + and not FLASH_RE.search(dev.media) |
438 | + and not CARD_READER_RE.search(dev.model) |
439 | + and not GENERIC_RE.search(dev.vendor)): |
440 | logging.debug("The device does not seem to be a memory" |
441 | - " card (dev[1]: %r, dev[3]: %r), skipping", |
442 | - dev[1], dev[3]) |
443 | + " card (bus: %r, model: %r), skipping", |
444 | + dev.bus, dev.model) |
445 | return |
446 | - print(message % {'bus': 'memory card', 'file': dev[0]}) |
447 | + print(message % {'bus': 'memory card', 'file': dev.file}) |
448 | else: |
449 | - if pattern.search(dev[3], re.I): |
450 | + if (FLASH_RE.search(dev.media) |
451 | + or CARD_READER_RE.search(dev.model) |
452 | + or GENERIC_RE.search(dev.vendor)): |
453 | logging.debug("The device seems to be a memory" |
454 | - " card %s (dev[3]: %r), skipping", |
455 | - pattern, dev[3]) |
456 | + " card (bus: %r (model: %r), skipping", |
457 | + dev.bus, dev.model) |
458 | return |
459 | - print(message % {'bus': dev[1], 'file': dev[0]}) |
460 | + print(message % {'bus': dev.bus, 'file': dev.file}) |
461 | if self._minimum_speed: |
462 | - if dev[2] >= self._minimum_speed: |
463 | + if dev.speed >= self._minimum_speed: |
464 | print("with speed of %(speed)s bits/s " |
465 | "higher than %(min_speed)s bits/s" % |
466 | - {'speed': dev[2], 'min_speed': self._minimum_speed}) |
467 | + {'speed': dev.speed, |
468 | + 'min_speed': self._minimum_speed}) |
469 | else: |
470 | print("ERROR: speed of %(speed)s bits/s lower " |
471 | "than %(min_speed)s bits/s" % |
472 | - {'speed': dev[2], 'min_speed': self._minimum_speed}) |
473 | + {'speed': dev.speed, |
474 | + 'min_speed': self._minimum_speed}) |
475 | self._error = True |
476 | logging.debug("Device matches requirements, exiting event loop") |
477 | self._loop.quit() |
478 | @@ -189,11 +198,11 @@ |
479 | udisks = 'org.freedesktop.UDisks.Device' |
480 | _device_file = device_props.Get(udisks, |
481 | "DeviceFile") |
482 | - _device = device_props.Get(udisks, |
483 | + _bus = device_props.Get(udisks, |
484 | "DriveConnectionInterface") |
485 | _speed = device_props.Get(udisks, |
486 | "DriveConnectionSpeed") |
487 | - _parent_model = '' |
488 | + _parent_model = _parent_vendor = '' |
489 | |
490 | if device_props.Get(udisks, "DeviceIsPartition"): |
491 | parent_obj = self._bus.get_object( |
492 | @@ -202,13 +211,17 @@ |
493 | parent_props = dbus.Interface( |
494 | parent_obj, dbus.PROPERTIES_IFACE) |
495 | _parent_model = parent_props.Get(udisks, "DriveModel") |
496 | + _parent_vendor = parent_props.Get(udisks, "DriveVendor") |
497 | + _parent_media = parent_props.Get(udisks, "DriveMedia") |
498 | |
499 | if not device_props.Get(udisks, "DeviceIsDrive"): |
500 | - device = ( |
501 | + device = Properties( |
502 | str(_device_file), |
503 | - str(_device), |
504 | + str(_bus), |
505 | int(_speed), |
506 | - str(_parent_model)) |
507 | + str(_parent_model), |
508 | + str(_parent_vendor), |
509 | + str(_parent_media)) |
510 | existing_devices.append(device) |
511 | |
512 | except dbus.DBusException: |
513 | @@ -242,7 +255,7 @@ |
514 | # argument uses somewhat different strings. In particular we need to |
515 | # map 'ieee1394' to 'firewire' |
516 | # |
517 | - # See: http://udisks.freedesktop.org/docs/latest/gdbus-org.freedesktop.UDisks2.Drive.html#gdbus-property-org-freedesktop-UDisks2-Drive.ConnectionBus |
518 | + # See: http://goo.gl/jaUAa |
519 | # |
520 | # TODO: Report old unsupported possibilities that are still offered by |
521 | # the command-line interface. We also need samples to understand how |
Out of curiosity, what's the difference between the memorycard_resource and the existing udev_resource script? It looks like I can achieve pretty much the same thing with this shell script:
export PATH=/usr/ share/checkbox/ scripts: $PATH CF|MS|SM| xD|Card| Generic) ' || !grep -q 'SDHCI controller found' /var/log/kern.log*) \
run_templates -st "udev_resource | filter_templates -w 'driver=sd'" <<'EOF' \
| (egrep -vqi '(SD|MMC|
&& echo 'reader: detected' \
|| echo 'reader: none'
$product
EOF