diff -Nru checkbox-0.9.1/backend checkbox-0.9.2/backend --- checkbox-0.9.1/backend 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/backend 2011-06-22 21:33:04.000000000 +0000 @@ -1,32 +1,41 @@ #!/usr/bin/python +import os import sys from optparse import OptionParser from checkbox.lib.fifo import FifoReader, FifoWriter -from checkbox.job import Job +from checkbox.job import Job, FAIL def main(args): usage = "Usage: %prog INPUT OUTPUT" parser = OptionParser(usage=usage) + parser.add_option("-p", "--path", + help="PATH variable to replace in the environment") (options, args) = parser.parse_args(args) if len(args) < 2: parser.error("Missing INPUT and OUTPUT") + if options.path: + os.environ["PATH"] = options.path + reader = FifoReader(args[0]) writer = FifoWriter(args[1]) while True: try: message = reader.read_object() - if message: + if isinstance(message, dict) and "command" in message: job = Job(message["command"], message.get("environ"), message.get("timeout")) result = job.execute() - writer.write_object(result) + else: + result = (FAIL, "", 0,) + + writer.write_object(result) except IOError, e: break diff -Nru checkbox-0.9.1/checkbox/job.py checkbox-0.9.2/checkbox/job.py --- checkbox-0.9.1/checkbox/job.py 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/checkbox/job.py 2011-06-22 21:33:04.000000000 +0000 @@ -89,7 +89,7 @@ duration = process.endtime - process.starttime - return (status, data, duration) + return (status, data, duration,) class JobStore(MessageStore): diff -Nru checkbox-0.9.1/checkbox/resource.py checkbox-0.9.2/checkbox/resource.py --- checkbox-0.9.1/checkbox/resource.py 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/checkbox/resource.py 2011-06-22 21:33:04.000000000 +0000 @@ -52,15 +52,16 @@ return self._try(other, lambda a, b: a != b) def _try(self, other, function, until=True, default=False): + found = False for item in self._list: if self._name in item: value = self._convert(item[self._name]) if function(value, other) == until: # Append item to list of results self._list._map._results.append(item) - return until + found = True - return default + return until if found else default class ResourceList(list): diff -Nru checkbox-0.9.1/checkbox/user_interface.py checkbox-0.9.2/checkbox/user_interface.py --- checkbox-0.9.1/checkbox/user_interface.py 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/checkbox/user_interface.py 2011-06-22 21:33:04.000000000 +0000 @@ -175,21 +175,26 @@ # with respectively -new-window and --new-window try: if os.getenv("DISPLAY") and \ - subprocess.call(["pgrep", "-x", "-u", str(uid), "gnome-panel"], + subprocess.call(["pgrep", "-x", "-u", str(uid), "gnome-panel|gconfd-2"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0: gct = subprocess.Popen(sudo_prefix + ["gconftool", "--get", "/desktop/gnome/url-handlers/http/command"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if gct.returncode == 0: + if gct.wait() == 0: preferred_browser = gct.communicate()[0] browser = re.match("((firefox|seamonkey|flock)[^\s]*)", preferred_browser) if browser: subprocess.call(sudo_prefix + [browser.group(0), "-new-window", url]) sys.exit(0) + browser = re.match("(epiphany[^\s]*)", preferred_browser) if browser: subprocess.call(sudo_prefix + [browser.group(0), "--new-window", url]) sys.exit(0) + + subprocess.call(sudo_prefix + [preferred_browser % url], shell=True) + sys.exit(0) + if subprocess.call(sudo_prefix + ["gnome-open", url]) == 0: sys.exit(0) except OSError: diff -Nru checkbox-0.9.1/debian/changelog checkbox-0.9.2/debian/changelog --- checkbox-0.9.1/debian/changelog 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/debian/changelog 2011-06-22 21:33:04.000000000 +0000 @@ -1,3 +1,19 @@ +checkbox (0.9.2) lucid-proposed; urgency=low + + New upstream release (LP: #567568): + * Added referer when sending submissions to Launchpad (LP: #550973) + * Added suggests to checkbox package in debian/control file (LP: #352740) + * Fixed udev_resource script to be more resilient (LP: #556824) + * Fixed cdimage_resource script to read casper.log (LP: #558728) + * Fixed reporting all resources found for a job (LP: #560948) + * Fixed stalling when using kdesudo to start backend (LP: #557443) + * Fixed starting the appropriate default browser on UNR (LP: #563050) + * Fixed opening the report with the gconf preferred browser (LP: #562580) + * Fixed suspend_test to use relative time for wakealarm (LP: #349768) + * Fixed backend not getting terminated upon closing (LP: #553328) + + -- Daniel Manrique Wed, 22 Jun 2011 14:18:08 -0400 + checkbox (0.9.1) lucid; urgency=low New upstream release (LP: #548800): diff -Nru checkbox-0.9.1/debian/control checkbox-0.9.2/debian/control --- checkbox-0.9.1/debian/control 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/debian/control 2011-06-22 21:33:04.000000000 +0000 @@ -15,6 +15,7 @@ Provides: hwtest Depends: ${misc:Depends}, ${python:Depends}, debconf, udev Recommends: dpkg, lsb-release, python-apport, python-apt, python-gst0.10 +Suggests: checkbox-cli | checkbox-gtk Conflicts: hwtest (<< 0.1-0ubuntu12) XB-Python-Version: ${python:Versions} Description: Checkbox System Testing diff -Nru checkbox-0.9.1/jobs/disk.txt.in checkbox-0.9.2/jobs/disk.txt.in --- checkbox-0.9.1/jobs/disk.txt.in 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/jobs/disk.txt.in 2011-06-22 21:33:04.000000000 +0000 @@ -1,7 +1,6 @@ plugin: manual name: disk_test -user: root -command: disk_test +command: udev_resource | filter_templates -w "category=DISK" | awk -F': ' '$1 == "product" { print $2 }' _description: The following hard drives were detected: . diff -Nru checkbox-0.9.1/jobs/local.txt.in checkbox-0.9.2/jobs/local.txt.in --- checkbox-0.9.1/jobs/local.txt.in 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/jobs/local.txt.in 2011-06-22 21:33:04.000000000 +0000 @@ -59,7 +59,7 @@ name: dmesg plugin: attachment -command: cat /var/log/dmesg +command: cat /var/log/dmesg | ansi_parser name: dmi plugin: attachment diff -Nru checkbox-0.9.1/jobs/resource.txt.in checkbox-0.9.2/jobs/resource.txt.in --- checkbox-0.9.1/jobs/resource.txt.in 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/jobs/resource.txt.in 2011-06-22 21:33:04.000000000 +0000 @@ -4,6 +4,7 @@ name: cdimage plugin: resource +user: root command: cdimage_resource name: dpkg diff -Nru checkbox-0.9.1/plugins/backend_info.py checkbox-0.9.2/plugins/backend_info.py --- checkbox-0.9.1/plugins/backend_info.py 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/plugins/backend_info.py 2011-06-22 21:33:04.000000000 +0000 @@ -18,7 +18,6 @@ # import os import shutil -import signal from subprocess import call, PIPE from tempfile import mkdtemp @@ -44,7 +43,12 @@ # Backend should run as early as possible self._manager.reactor.call_on("gather", self.gather, -100) - def get_root_command(self, command): + def get_command(self, *args): + command = [self.command, "--path=%s" % os.environ["PATH"]] + + return command + list(args) + + def get_root_command(self, *args): uid = os.getuid() if uid == 0: prefix = [] @@ -59,17 +63,11 @@ stdout=PIPE, stderr=PIPE) == 0 and \ call(["pgrep", "-x", "-u", str(uid), "gnome-panel|gconfd-2"], stdout=PIPE, stderr=PIPE) == 0: - prefix = ["gksu", "-k", "--"] + prefix = ["gksu", "--"] else: - prefix = ["sudo", "-E"] - - # Append PATH - prefix.append("PATH=%s" % os.environ["PATH"]) - - # Extend command - prefix.extend(command) + prefix = ["sudo"] - return prefix + return prefix + self.get_command(*args) def gather(self): self.directory = mkdtemp(prefix="checkbox") @@ -82,8 +80,7 @@ self.parent_reader = FifoReader(child_output) else: - command = [self.command, child_input, child_output] - root_command = self.get_root_command(command) + root_command = self.get_root_command(child_input, child_output) os.execvp(root_command[0], root_command) # Should never get here @@ -95,10 +92,11 @@ self._manager.reactor.fire("message-result", *result) def stop(self): - os.kill(self.pid, signal.SIGHUP) - os.waitpid(self.pid, 0) - + self.parent_writer.close() + self.parent_reader.close() shutil.rmtree(self.directory) + os.waitpid(self.pid, 0) + factory = BackendInfo diff -Nru checkbox-0.9.1/plugins/begin_prompt.py checkbox-0.9.2/plugins/begin_prompt.py --- checkbox-0.9.1/plugins/begin_prompt.py 1970-01-01 00:00:00.000000000 +0000 +++ checkbox-0.9.2/plugins/begin_prompt.py 2011-06-22 21:33:04.000000000 +0000 @@ -0,0 +1,33 @@ +# +# This file is part of Checkbox. +# +# Copyright 2010 Canonical Ltd. +# +# Checkbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Checkbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Checkbox. If not, see . +# +from checkbox.plugin import Plugin + + +class BeginPrompt(Plugin): + + def register(self, manager): + super(BeginPrompt, self).register(manager) + + self._manager.reactor.call_on("prompt-begin", self.prompt_begin) + + def prompt_begin(self, interface): + self._manager.reactor.fire("begin") + + +factory = BeginPrompt diff -Nru checkbox-0.9.1/plugins/launchpad_exchange.py checkbox-0.9.2/plugins/launchpad_exchange.py --- checkbox-0.9.1/plugins/launchpad_exchange.py 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/plugins/launchpad_exchange.py 2011-06-22 21:33:04.000000000 +0000 @@ -60,7 +60,8 @@ def register(self, manager): super(LaunchpadExchange, self).register(manager) - self._headers = {} + self._headers = { + "Referer": self.transport_url} self._form = { "field.private": "False", "field.contactable": "False", diff -Nru checkbox-0.9.1/plugins/persist_info.py checkbox-0.9.2/plugins/persist_info.py --- checkbox-0.9.1/plugins/persist_info.py 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/plugins/persist_info.py 2011-06-22 21:33:04.000000000 +0000 @@ -33,14 +33,14 @@ self.persist = None for (rt, rh) in [ - ("prompt-begin", self.prompt_begin), + ("begin", self.begin), ("prompt-job", self.save)]: self._manager.reactor.call_on(rt, rh, -100) # Save persist data last self._manager.reactor.call_on("stop", self.save, 1000) - def prompt_begin(self, interface): + def begin(self): self.persist = Persist(self.filename) self._manager.reactor.fire("begin-persist", self.persist) diff -Nru checkbox-0.9.1/po/checkbox.pot checkbox-0.9.2/po/checkbox.pot --- checkbox-0.9.1/po/checkbox.pot 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/po/checkbox.pot 2011-06-22 21:33:04.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-04-01 17:14-0400\n" +"POT-Creation-Date: 2010-04-14 18:05-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -68,13 +68,13 @@ msgstr "" #. description -#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:17 ../jobs/network.txt.in:16 +#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:16 ../jobs/network.txt.in:16 #: ../jobs/video.txt.in:26 msgid "$output" msgstr "" #. description -#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:5 ../jobs/network.txt.in:16 +#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:4 ../jobs/network.txt.in:16 #: ../jobs/video.txt.in:26 msgid "Is this correct?" msgstr "" @@ -128,17 +128,17 @@ msgstr "" #. description -#: ../jobs/disk.txt.in:5 +#: ../jobs/disk.txt.in:4 msgid "The following hard drives were detected:" msgstr "" #. description -#: ../jobs/disk.txt.in:17 +#: ../jobs/disk.txt.in:16 msgid "Disk benchmark:" msgstr "" #. description -#: ../jobs/disk.txt.in:17 +#: ../jobs/disk.txt.in:16 msgid "Is this ok?" msgstr "" @@ -693,12 +693,12 @@ "your system." msgstr "" -#: ../plugins/launchpad_exchange.py:116 +#: ../plugins/launchpad_exchange.py:117 #, python-format msgid "Failed to process form: %s" msgstr "" -#: ../plugins/launchpad_exchange.py:139 +#: ../plugins/launchpad_exchange.py:140 #, python-format msgid "" "Failed to contact server. Please try\n" @@ -709,13 +709,13 @@ "https://launchpad.net/+hwdb/+submit" msgstr "" -#: ../plugins/launchpad_exchange.py:148 +#: ../plugins/launchpad_exchange.py:149 msgid "" "Failed to upload to server,\n" "please try again later." msgstr "" -#: ../plugins/launchpad_exchange.py:160 +#: ../plugins/launchpad_exchange.py:161 msgid "Information not posted to Launchpad." msgstr "" diff -Nru checkbox-0.9.1/scripts/device_list checkbox-0.9.2/scripts/device_list --- checkbox-0.9.1/scripts/device_list 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/scripts/device_list 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -#! /bin/sh -e -TYPE="$1" - -case $TYPE in - maybe-floppy) - logger -t list-devices "deprecated parameter maybe-floppy" - TYPE=floppy - ;; - cd|disk|partition|floppy|maybe-usb-floppy|usb-partition) ;; - *) - echo "Usage: $0 cd|disk|partition|floppy|maybe-usb-floppy|usb-partition" >&2 - exit 2 - ;; -esac - -if [ ! -d /sys/block ]; then - exit 0 -fi -if type udevadm >/dev/null 2>&1; then - device_info () { - udevadm info -q "$1" -p "$2" 2>/dev/null - } -elif type udevinfo >/dev/null 2>&1; then - device_info () { - udevinfo -q "$1" -p "$2" 2>/dev/null - } -else - exit 0 -fi - -device_name () { - local name - if ! name="$(device_info name "$1")"; then - name="$(printf %s "${1##*/}" | \ - sed 's,!,/,g')" - fi - echo "/dev/$name" -} - -is_sataraid () { - grep -qs ^DMRAID- "$1/dm/uuid" -} - -is_sataraid_partition () { - # dmraid partitions are always slaved to another dm device - for slave in "$1"/slaves/dm-*; do - if [ -e "$slave" ]; then - return 0 - fi - done - return 1 -} - -if type dmraid >/dev/null 2>&1; then - raiddevs="$(dmraid -r -c || true)" -else - raiddevs= -fi - -# cloned-and-hacked from partman-base/init.d/parted -part_of_sataraid () { - local raiddev - for raiddev in $raiddevs; do - if [ "$(readlink -f "$raiddev")" = "$1" ]; then - return 0 - fi - done - return 1 -} - -syspaths= -scan_partition=false -case $TYPE in - partition) - for x in /sys/block/*/*[0-9]; do - [ -d "$x" ] || continue - syspaths="${syspaths:+$syspaths }$x" - done - for x in /sys/block/dm-*; do - [ -d "$x" ] || continue - (is_sataraid "$x" && is_sataraid_partition "$x") || continue - syspaths="${syspaths:+$syspaths }$x" - done - TYPE=disk - # Also allow misdetected USB devices - scan_partition=: - ;; - usb-partition) - for x in /sys/block/*/*; do - [ -d "$x" ] || continue - syspaths="${syspaths:+$syspaths }$x" - done - ;; - *) - for x in /sys/block/*; do - [ -d "$x" ] || continue - case $x in - /sys/block/dm-*) - if is_sataraid "$x" && is_sataraid_partition "$x"; then - continue - fi - ;; - *) - name="$(device_name "$x")" - if part_of_sataraid "$name"; then - continue - fi - ;; - esac - syspaths="${syspaths:+$syspaths }$x" - done - ;; -esac -for x in $syspaths; do - devpath="${x#/sys}" - match=false - case $TYPE in - floppy) - # TODO ugly special case for non-IDE floppies - case $devpath in - /block/fd[0-9]*) - match=: - ;; - esac - ;; - esac - if ! $match && [ "$TYPE" = cd ]; then - if device_info env "$devpath" | grep -q '^ID_CDROM='; then - match=: - fi - fi - if ! $match; then - if device_info env "$devpath" | grep -q "^ID_TYPE=$TYPE"; then - match=: - fi - fi - if ! $match && [ "$TYPE" = disk ]; then - case $devpath in - /block/cciss\!*|/block/ida\!*|/block/rd\!*|/block/mmcblk*) - match=: - ;; - /block/dm-*) - # for now, we only understand dmraid - if is_sataraid "/sys$devpath"; then - match=: - fi - ;; - esac - fi - # Some USB sticks and CD drives are misdetected as floppy - # This allows to scan for those - if ! $match && ( $scan_partition || [ "$TYPE" = maybe-usb-floppy ] ); then - if device_info env "$devpath" | grep -q '^ID_BUS=usb' && \ - device_info env "$devpath" | grep -q '^ID_TYPE=floppy'; then - match=: - fi - fi - # Disk partitions, but only on USB drives - if ! $match && [ "$TYPE" = usb-partition ]; then - if device_info env "$devpath" | grep -q '^ID_BUS=usb' && \ - device_info env "$devpath" | grep -q '^ID_TYPE=disk'; then - match=: - fi - fi - if $match; then - device_name "/sys$devpath" - fi -done diff -Nru checkbox-0.9.1/scripts/disk_test checkbox-0.9.2/scripts/disk_test --- checkbox-0.9.1/scripts/disk_test 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/scripts/disk_test 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -#!/usr/bin/python - -import os -import sys - -from subprocess import Popen, PIPE - - -def main(args): - directory = os.path.dirname(__file__) - script = os.path.join(directory, "device_list") - disk_devices_string = Popen([script, "disk"], stdout=PIPE).communicate()[0] - disk_devices_string = disk_devices_string.strip() - - if not disk_devices_string: - print "None" - else: - disk_devices = disk_devices_string.split("\n") - for disk_device in disk_devices: - disk = os.path.basename(disk_device) - model_path = "/sys/block/%s/device/model" % disk - model_file = open(model_path) - try: - model_name = model_file.read().strip() - print model_name - finally: - model_file.close() - - return 0 - - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff -Nru checkbox-0.9.1/scripts/run_templates checkbox-0.9.2/scripts/run_templates --- checkbox-0.9.1/scripts/run_templates 1970-01-01 00:00:00.000000000 +0000 +++ checkbox-0.9.2/scripts/run_templates 2011-06-22 21:33:04.000000000 +0000 @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +import os +import re +import sys +import uuid + +from optparse import OptionParser +from subprocess import Popen, PIPE + +from checkbox.lib.template import Template + + +DEFAULT_INPUT = "-" +DEFAULT_OUTPUT = "-" + +COMMAND_TEMPLATE = """cat <<%(separator)s +%(input)s +%(separator)s""" + + +class Runner(object): + + def __init__(self, input, output): + self.input = input + self.output = output + + def get_args(self, record): + return [] + + def get_env(self, record): + env = dict(os.environ) + env["NF"] = str(len(record)) + + return env + + def process(self, args, shell=False): + process = Popen(args, shell=shell, stdout=PIPE) + records = self.process_output(process.stdout) + + for nr, record in enumerate(records): + args = self.get_args(record) + env = self.get_env(record) + env["NR"] = str(nr) + + command_string = COMMAND_TEMPLATE % { + "input": self.input, + "separator": uuid.uuid4()} + command = ["sh", "-c", command_string] + args + + process = Popen(command, + env=env, + stdout=self.output) + process.communicate() + + def process_output(self, output): + raise NotImplementedError + + +class LineRunner(Runner): + + field_separator = r"\s+" + record_separator = r"(?:\r?\n)" + + def get_args(self, record): + args = [record] + args.extend(re.split(self.field_separator, record)) + + return args + + def process_output(self, file): + # Strip trailing separator + data = re.sub(r"%s$" % self.record_separator, "", file.read()) + + return re.split(self.record_separator, data) + + +class TemplateRunner(Runner): + + def get_env(self, record): + env = super(TemplateRunner, self).get_env(record) + env.update(record) + + return env + + def process_output(self, output): + template = Template() + return template.load_file(output) + + +def main(args): + usage = "Usage: %prog [OPTIONS] [COMMAND]" + parser = OptionParser(usage=usage) + parser.add_option("-i", "--input", + metavar="FILE", + default=DEFAULT_INPUT, + help="Input from the given file name, - for stdin") + parser.add_option("-o", "--output", + metavar="FILE", + default=DEFAULT_OUTPUT, + help="Output to the given file name, - for stdout") + parser.add_option("-s", "--shell", + action="store_true", + help="Run the command as a shell script") + parser.add_option("-t", "--template", + action="store_true", + help="Interpret the command output as a template") + (options, args) = parser.parse_args(args) + + # Default args to echo command + if not args: + args = ["echo"] + + # Read input + if options.input == "-": + input = sys.stdin.read() + else: + input_file = open(options.input, "r") + try: + input = input_file.read() + finally: + input_file.close() + + # Open output + if options.output == "-": + output_file = sys.stdout + else: + output_file = open(options.output, "w") + + # Determine runner class + if options.template: + runner_class = TemplateRunner + else: + runner_class = LineRunner + + runner = runner_class(input, output_file) + runner.process(args, options.shell) + + return 0 + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff -Nru checkbox-0.9.1/scripts/suspend_test checkbox-0.9.2/scripts/suspend_test --- checkbox-0.9.1/scripts/suspend_test 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/scripts/suspend_test 2011-06-22 21:33:04.000000000 +0000 @@ -109,11 +109,10 @@ # ctl='/sys/class/rtc/rtc0/wakealarm' if [ -f "$ctl" ]; then - time=`date '+%s' -d "+ $timeout seconds"` # Cancel any outstanding timers. echo "0" >"$ctl" - # rtcN/wakealarm uses absolute time in seconds - echo "$time" >"$ctl" + # rtcN/wakealarm can use relative time in seconds + echo "+$timeout" >"$ctl" return 0 fi ctl='/proc/acpi/alarm' diff -Nru checkbox-0.9.1/scripts/udev_resource checkbox-0.9.2/scripts/udev_resource --- checkbox-0.9.1/scripts/udev_resource 2010-04-02 00:12:30.000000000 +0000 +++ checkbox-0.9.2/scripts/udev_resource 2011-06-22 21:33:04.000000000 +0000 @@ -476,7 +476,7 @@ def devices(self): devices = [] line_pattern = re.compile(r"(?P\w):\s*(?P.*)") - multi_pattern = re.compile(r"(?P\w+)=(?P.*)") + multi_pattern = re.compile(r"(?P[^=]+)=(?P.*)") output = Popen(COMMAND, stdout=PIPE, shell=True).communicate()[0] for record in output.split("\n\n"):