Ubuntu

Merge lp:~roadmr/ubuntu/lucid/checkbox/0.9.2 into lp:ubuntu/lucid/checkbox

Proposed by Daniel Manrique on 2011-06-22
Reviewer Review Type Date Requested Status
Stéphane Graber 2011-06-22 Approve on 2011-06-22
Review via email: mp+65556@code.launchpad.net

Description of the Change

This is to get the fixes to related bugs (10 of them) into an updated package for Lucid.

I went over the related bugs and updated them with the required information as per SRU procedure. I added this information in a comment so as to not clobber the existing descriptions.

I omitted providing minimum patches as I refer to the corresponding revisions from upstream that implement the proposed fixes, but if deemed necessary, I can produce and attach the patches.

Also I updated the changelog to target this to lucid-proposed as requested in the original merge.

Finally, I removed the fix for a bug we were unable to reproduce and thus lacks a proper SRU report.

This merge request should then supersede the following (though the only delta between these two should be removal of one bug fix, and updated changelog with lucid-proposed and my name as committer):

https://code.launchpad.net/~cr3/ubuntu/lucid/checkbox/0.9.2/+merge/28341

Thanks!

To post a comment you must log in.
Stéphane Graber (stgraber) wrote :

Uploaded to lucid-proposed.
Version number is fine as it's an "upstream" bugfix point release with no added feature (that I saw mentioned).

The only change I found weird for an SRU is the added Suggests but I don't see any case where they'd cause harm.

Thanks for preparing the upload.

review: Approve

Preview Diff

1=== modified file 'backend'
2--- backend 2010-03-07 15:05:44 +0000
3+++ backend 2011-06-22 19:41:15 +0000
4@@ -1,32 +1,41 @@
5 #!/usr/bin/python
6
7+import os
8 import sys
9
10 from optparse import OptionParser
11 from checkbox.lib.fifo import FifoReader, FifoWriter
12
13-from checkbox.job import Job
14+from checkbox.job import Job, FAIL
15
16
17 def main(args):
18 usage = "Usage: %prog INPUT OUTPUT"
19 parser = OptionParser(usage=usage)
20+ parser.add_option("-p", "--path",
21+ help="PATH variable to replace in the environment")
22 (options, args) = parser.parse_args(args)
23
24 if len(args) < 2:
25 parser.error("Missing INPUT and OUTPUT")
26
27+ if options.path:
28+ os.environ["PATH"] = options.path
29+
30 reader = FifoReader(args[0])
31 writer = FifoWriter(args[1])
32
33 while True:
34 try:
35 message = reader.read_object()
36- if message:
37+ if isinstance(message, dict) and "command" in message:
38 job = Job(message["command"], message.get("environ"),
39 message.get("timeout"))
40 result = job.execute()
41- writer.write_object(result)
42+ else:
43+ result = (FAIL, "", 0,)
44+
45+ writer.write_object(result)
46 except IOError, e:
47 break
48
49
50=== modified file 'checkbox/job.py'
51--- checkbox/job.py 2010-03-09 16:58:36 +0000
52+++ checkbox/job.py 2011-06-22 19:41:15 +0000
53@@ -89,7 +89,7 @@
54
55 duration = process.endtime - process.starttime
56
57- return (status, data, duration)
58+ return (status, data, duration,)
59
60
61 class JobStore(MessageStore):
62
63=== modified file 'checkbox/resource.py'
64--- checkbox/resource.py 2010-03-07 15:05:44 +0000
65+++ checkbox/resource.py 2011-06-22 19:41:15 +0000
66@@ -52,15 +52,16 @@
67 return self._try(other, lambda a, b: a != b)
68
69 def _try(self, other, function, until=True, default=False):
70+ found = False
71 for item in self._list:
72 if self._name in item:
73 value = self._convert(item[self._name])
74 if function(value, other) == until:
75 # Append item to list of results
76 self._list._map._results.append(item)
77- return until
78+ found = True
79
80- return default
81+ return until if found else default
82
83
84 class ResourceList(list):
85
86=== modified file 'checkbox/user_interface.py'
87--- checkbox/user_interface.py 2010-03-07 15:05:44 +0000
88+++ checkbox/user_interface.py 2011-06-22 19:41:15 +0000
89@@ -175,21 +175,26 @@
90 # with respectively -new-window and --new-window
91 try:
92 if os.getenv("DISPLAY") and \
93- subprocess.call(["pgrep", "-x", "-u", str(uid), "gnome-panel"],
94+ subprocess.call(["pgrep", "-x", "-u", str(uid), "gnome-panel|gconfd-2"],
95 stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
96 gct = subprocess.Popen(sudo_prefix + ["gconftool", "--get",
97 "/desktop/gnome/url-handlers/http/command"],
98 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
99- if gct.returncode == 0:
100+ if gct.wait() == 0:
101 preferred_browser = gct.communicate()[0]
102 browser = re.match("((firefox|seamonkey|flock)[^\s]*)", preferred_browser)
103 if browser:
104 subprocess.call(sudo_prefix + [browser.group(0), "-new-window", url])
105 sys.exit(0)
106+
107 browser = re.match("(epiphany[^\s]*)", preferred_browser)
108 if browser:
109 subprocess.call(sudo_prefix + [browser.group(0), "--new-window", url])
110 sys.exit(0)
111+
112+ subprocess.call(sudo_prefix + [preferred_browser % url], shell=True)
113+ sys.exit(0)
114+
115 if subprocess.call(sudo_prefix + ["gnome-open", url]) == 0:
116 sys.exit(0)
117 except OSError:
118
119=== modified file 'debian/changelog'
120--- debian/changelog 2010-03-07 15:05:44 +0000
121+++ debian/changelog 2011-06-22 19:41:15 +0000
122@@ -1,3 +1,19 @@
123+checkbox (0.9.2) lucid-proposed; urgency=low
124+
125+ New upstream release (LP: #567568):
126+ * Added referer when sending submissions to Launchpad (LP: #550973)
127+ * Added suggests to checkbox package in debian/control file (LP: #352740)
128+ * Fixed udev_resource script to be more resilient (LP: #556824)
129+ * Fixed cdimage_resource script to read casper.log (LP: #558728)
130+ * Fixed reporting all resources found for a job (LP: #560948)
131+ * Fixed stalling when using kdesudo to start backend (LP: #557443)
132+ * Fixed starting the appropriate default browser on UNR (LP: #563050)
133+ * Fixed opening the report with the gconf preferred browser (LP: #562580)
134+ * Fixed suspend_test to use relative time for wakealarm (LP: #349768)
135+ * Fixed backend not getting terminated upon closing (LP: #553328)
136+
137+ -- Daniel Manrique <daniel.manrique@canonical.com> Wed, 22 Jun 2011 14:18:08 -0400
138+
139 checkbox (0.9.1) lucid; urgency=low
140
141 New upstream release (LP: #548800):
142
143=== modified file 'debian/control'
144--- debian/control 2010-03-09 16:58:36 +0000
145+++ debian/control 2011-06-22 19:41:15 +0000
146@@ -15,6 +15,7 @@
147 Provides: hwtest
148 Depends: ${misc:Depends}, ${python:Depends}, debconf, udev
149 Recommends: dpkg, lsb-release, python-apport, python-apt, python-gst0.10
150+Suggests: checkbox-cli | checkbox-gtk
151 Conflicts: hwtest (<< 0.1-0ubuntu12)
152 XB-Python-Version: ${python:Versions}
153 Description: Checkbox System Testing
154
155=== modified file 'jobs/disk.txt.in'
156--- jobs/disk.txt.in 2010-03-07 15:05:44 +0000
157+++ jobs/disk.txt.in 2011-06-22 19:41:15 +0000
158@@ -1,7 +1,6 @@
159 plugin: manual
160 name: disk_test
161-user: root
162-command: disk_test
163+command: udev_resource | filter_templates -w "category=DISK" | awk -F': ' '$1 == "product" { print $2 }'
164 _description:
165 The following hard drives were detected:
166 .
167
168=== modified file 'jobs/local.txt.in'
169--- jobs/local.txt.in 2010-03-07 15:05:44 +0000
170+++ jobs/local.txt.in 2011-06-22 19:41:15 +0000
171@@ -59,7 +59,7 @@
172
173 name: dmesg
174 plugin: attachment
175-command: cat /var/log/dmesg
176+command: cat /var/log/dmesg | ansi_parser
177
178 name: dmi
179 plugin: attachment
180
181=== modified file 'jobs/resource.txt.in'
182--- jobs/resource.txt.in 2010-03-09 16:58:36 +0000
183+++ jobs/resource.txt.in 2011-06-22 19:41:15 +0000
184@@ -4,6 +4,7 @@
185
186 name: cdimage
187 plugin: resource
188+user: root
189 command: cdimage_resource
190
191 name: dpkg
192
193=== modified file 'plugins/backend_info.py'
194--- plugins/backend_info.py 2010-03-07 15:05:44 +0000
195+++ plugins/backend_info.py 2011-06-22 19:41:15 +0000
196@@ -18,7 +18,6 @@
197 #
198 import os
199 import shutil
200-import signal
201
202 from subprocess import call, PIPE
203 from tempfile import mkdtemp
204@@ -44,7 +43,12 @@
205 # Backend should run as early as possible
206 self._manager.reactor.call_on("gather", self.gather, -100)
207
208- def get_root_command(self, command):
209+ def get_command(self, *args):
210+ command = [self.command, "--path=%s" % os.environ["PATH"]]
211+
212+ return command + list(args)
213+
214+ def get_root_command(self, *args):
215 uid = os.getuid()
216 if uid == 0:
217 prefix = []
218@@ -59,17 +63,11 @@
219 stdout=PIPE, stderr=PIPE) == 0 and \
220 call(["pgrep", "-x", "-u", str(uid), "gnome-panel|gconfd-2"],
221 stdout=PIPE, stderr=PIPE) == 0:
222- prefix = ["gksu", "-k", "--"]
223+ prefix = ["gksu", "--"]
224 else:
225- prefix = ["sudo", "-E"]
226-
227- # Append PATH
228- prefix.append("PATH=%s" % os.environ["PATH"])
229-
230- # Extend command
231- prefix.extend(command)
232-
233- return prefix
234+ prefix = ["sudo"]
235+
236+ return prefix + self.get_command(*args)
237
238 def gather(self):
239 self.directory = mkdtemp(prefix="checkbox")
240@@ -82,8 +80,7 @@
241 self.parent_reader = FifoReader(child_output)
242
243 else:
244- command = [self.command, child_input, child_output]
245- root_command = self.get_root_command(command)
246+ root_command = self.get_root_command(child_input, child_output)
247 os.execvp(root_command[0], root_command)
248 # Should never get here
249
250@@ -95,10 +92,11 @@
251 self._manager.reactor.fire("message-result", *result)
252
253 def stop(self):
254- os.kill(self.pid, signal.SIGHUP)
255+ self.parent_writer.close()
256+ self.parent_reader.close()
257+ shutil.rmtree(self.directory)
258+
259 os.waitpid(self.pid, 0)
260
261- shutil.rmtree(self.directory)
262-
263
264 factory = BackendInfo
265
266=== added file 'plugins/begin_prompt.py'
267--- plugins/begin_prompt.py 1970-01-01 00:00:00 +0000
268+++ plugins/begin_prompt.py 2011-06-22 19:41:15 +0000
269@@ -0,0 +1,33 @@
270+#
271+# This file is part of Checkbox.
272+#
273+# Copyright 2010 Canonical Ltd.
274+#
275+# Checkbox is free software: you can redistribute it and/or modify
276+# it under the terms of the GNU General Public License as published by
277+# the Free Software Foundation, either version 3 of the License, or
278+# (at your option) any later version.
279+#
280+# Checkbox is distributed in the hope that it will be useful,
281+# but WITHOUT ANY WARRANTY; without even the implied warranty of
282+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
283+# GNU General Public License for more details.
284+#
285+# You should have received a copy of the GNU General Public License
286+# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
287+#
288+from checkbox.plugin import Plugin
289+
290+
291+class BeginPrompt(Plugin):
292+
293+ def register(self, manager):
294+ super(BeginPrompt, self).register(manager)
295+
296+ self._manager.reactor.call_on("prompt-begin", self.prompt_begin)
297+
298+ def prompt_begin(self, interface):
299+ self._manager.reactor.fire("begin")
300+
301+
302+factory = BeginPrompt
303
304=== modified file 'plugins/launchpad_exchange.py'
305--- plugins/launchpad_exchange.py 2010-03-07 15:05:44 +0000
306+++ plugins/launchpad_exchange.py 2011-06-22 19:41:15 +0000
307@@ -60,7 +60,8 @@
308 def register(self, manager):
309 super(LaunchpadExchange, self).register(manager)
310
311- self._headers = {}
312+ self._headers = {
313+ "Referer": self.transport_url}
314 self._form = {
315 "field.private": "False",
316 "field.contactable": "False",
317
318=== modified file 'plugins/persist_info.py'
319--- plugins/persist_info.py 2010-03-09 16:58:36 +0000
320+++ plugins/persist_info.py 2011-06-22 19:41:15 +0000
321@@ -33,14 +33,14 @@
322 self.persist = None
323
324 for (rt, rh) in [
325- ("prompt-begin", self.prompt_begin),
326+ ("begin", self.begin),
327 ("prompt-job", self.save)]:
328 self._manager.reactor.call_on(rt, rh, -100)
329
330 # Save persist data last
331 self._manager.reactor.call_on("stop", self.save, 1000)
332
333- def prompt_begin(self, interface):
334+ def begin(self):
335 self.persist = Persist(self.filename)
336 self._manager.reactor.fire("begin-persist", self.persist)
337
338
339=== modified file 'po/checkbox.pot'
340--- po/checkbox.pot 2010-03-07 15:05:44 +0000
341+++ po/checkbox.pot 2011-06-22 19:41:15 +0000
342@@ -8,7 +8,7 @@
343 msgstr ""
344 "Project-Id-Version: PACKAGE VERSION\n"
345 "Report-Msgid-Bugs-To: \n"
346-"POT-Creation-Date: 2010-04-01 17:14-0400\n"
347+"POT-Creation-Date: 2010-04-14 18:05-0400\n"
348 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
349 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
350 "Language-Team: LANGUAGE <LL@li.org>\n"
351@@ -68,13 +68,13 @@
352 msgstr ""
353
354 #. description
355-#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:17 ../jobs/network.txt.in:16
356+#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:16 ../jobs/network.txt.in:16
357 #: ../jobs/video.txt.in:26
358 msgid "$output"
359 msgstr ""
360
361 #. description
362-#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:5 ../jobs/network.txt.in:16
363+#: ../jobs/audio.txt.in:7 ../jobs/disk.txt.in:4 ../jobs/network.txt.in:16
364 #: ../jobs/video.txt.in:26
365 msgid "Is this correct?"
366 msgstr ""
367@@ -128,17 +128,17 @@
368 msgstr ""
369
370 #. description
371-#: ../jobs/disk.txt.in:5
372+#: ../jobs/disk.txt.in:4
373 msgid "The following hard drives were detected:"
374 msgstr ""
375
376 #. description
377-#: ../jobs/disk.txt.in:17
378+#: ../jobs/disk.txt.in:16
379 msgid "Disk benchmark:"
380 msgstr ""
381
382 #. description
383-#: ../jobs/disk.txt.in:17
384+#: ../jobs/disk.txt.in:16
385 msgid "Is this ok?"
386 msgstr ""
387
388@@ -693,12 +693,12 @@
389 "your system."
390 msgstr ""
391
392-#: ../plugins/launchpad_exchange.py:116
393+#: ../plugins/launchpad_exchange.py:117
394 #, python-format
395 msgid "Failed to process form: %s"
396 msgstr ""
397
398-#: ../plugins/launchpad_exchange.py:139
399+#: ../plugins/launchpad_exchange.py:140
400 #, python-format
401 msgid ""
402 "Failed to contact server. Please try\n"
403@@ -709,13 +709,13 @@
404 "https://launchpad.net/+hwdb/+submit"
405 msgstr ""
406
407-#: ../plugins/launchpad_exchange.py:148
408+#: ../plugins/launchpad_exchange.py:149
409 msgid ""
410 "Failed to upload to server,\n"
411 "please try again later."
412 msgstr ""
413
414-#: ../plugins/launchpad_exchange.py:160
415+#: ../plugins/launchpad_exchange.py:161
416 msgid "Information not posted to Launchpad."
417 msgstr ""
418
419
420=== removed file 'scripts/device_list'
421--- scripts/device_list 2010-03-07 15:05:44 +0000
422+++ scripts/device_list 1970-01-01 00:00:00 +0000
423@@ -1,168 +0,0 @@
424-#! /bin/sh -e
425-TYPE="$1"
426-
427-case $TYPE in
428- maybe-floppy)
429- logger -t list-devices "deprecated parameter maybe-floppy"
430- TYPE=floppy
431- ;;
432- cd|disk|partition|floppy|maybe-usb-floppy|usb-partition) ;;
433- *)
434- echo "Usage: $0 cd|disk|partition|floppy|maybe-usb-floppy|usb-partition" >&2
435- exit 2
436- ;;
437-esac
438-
439-if [ ! -d /sys/block ]; then
440- exit 0
441-fi
442-if type udevadm >/dev/null 2>&1; then
443- device_info () {
444- udevadm info -q "$1" -p "$2" 2>/dev/null
445- }
446-elif type udevinfo >/dev/null 2>&1; then
447- device_info () {
448- udevinfo -q "$1" -p "$2" 2>/dev/null
449- }
450-else
451- exit 0
452-fi
453-
454-device_name () {
455- local name
456- if ! name="$(device_info name "$1")"; then
457- name="$(printf %s "${1##*/}" | \
458- sed 's,!,/,g')"
459- fi
460- echo "/dev/$name"
461-}
462-
463-is_sataraid () {
464- grep -qs ^DMRAID- "$1/dm/uuid"
465-}
466-
467-is_sataraid_partition () {
468- # dmraid partitions are always slaved to another dm device
469- for slave in "$1"/slaves/dm-*; do
470- if [ -e "$slave" ]; then
471- return 0
472- fi
473- done
474- return 1
475-}
476-
477-if type dmraid >/dev/null 2>&1; then
478- raiddevs="$(dmraid -r -c || true)"
479-else
480- raiddevs=
481-fi
482-
483-# cloned-and-hacked from partman-base/init.d/parted
484-part_of_sataraid () {
485- local raiddev
486- for raiddev in $raiddevs; do
487- if [ "$(readlink -f "$raiddev")" = "$1" ]; then
488- return 0
489- fi
490- done
491- return 1
492-}
493-
494-syspaths=
495-scan_partition=false
496-case $TYPE in
497- partition)
498- for x in /sys/block/*/*[0-9]; do
499- [ -d "$x" ] || continue
500- syspaths="${syspaths:+$syspaths }$x"
501- done
502- for x in /sys/block/dm-*; do
503- [ -d "$x" ] || continue
504- (is_sataraid "$x" && is_sataraid_partition "$x") || continue
505- syspaths="${syspaths:+$syspaths }$x"
506- done
507- TYPE=disk
508- # Also allow misdetected USB devices
509- scan_partition=:
510- ;;
511- usb-partition)
512- for x in /sys/block/*/*; do
513- [ -d "$x" ] || continue
514- syspaths="${syspaths:+$syspaths }$x"
515- done
516- ;;
517- *)
518- for x in /sys/block/*; do
519- [ -d "$x" ] || continue
520- case $x in
521- /sys/block/dm-*)
522- if is_sataraid "$x" && is_sataraid_partition "$x"; then
523- continue
524- fi
525- ;;
526- *)
527- name="$(device_name "$x")"
528- if part_of_sataraid "$name"; then
529- continue
530- fi
531- ;;
532- esac
533- syspaths="${syspaths:+$syspaths }$x"
534- done
535- ;;
536-esac
537-for x in $syspaths; do
538- devpath="${x#/sys}"
539- match=false
540- case $TYPE in
541- floppy)
542- # TODO ugly special case for non-IDE floppies
543- case $devpath in
544- /block/fd[0-9]*)
545- match=:
546- ;;
547- esac
548- ;;
549- esac
550- if ! $match && [ "$TYPE" = cd ]; then
551- if device_info env "$devpath" | grep -q '^ID_CDROM='; then
552- match=:
553- fi
554- fi
555- if ! $match; then
556- if device_info env "$devpath" | grep -q "^ID_TYPE=$TYPE"; then
557- match=:
558- fi
559- fi
560- if ! $match && [ "$TYPE" = disk ]; then
561- case $devpath in
562- /block/cciss\!*|/block/ida\!*|/block/rd\!*|/block/mmcblk*)
563- match=:
564- ;;
565- /block/dm-*)
566- # for now, we only understand dmraid
567- if is_sataraid "/sys$devpath"; then
568- match=:
569- fi
570- ;;
571- esac
572- fi
573- # Some USB sticks and CD drives are misdetected as floppy
574- # This allows to scan for those
575- if ! $match && ( $scan_partition || [ "$TYPE" = maybe-usb-floppy ] ); then
576- if device_info env "$devpath" | grep -q '^ID_BUS=usb' && \
577- device_info env "$devpath" | grep -q '^ID_TYPE=floppy'; then
578- match=:
579- fi
580- fi
581- # Disk partitions, but only on USB drives
582- if ! $match && [ "$TYPE" = usb-partition ]; then
583- if device_info env "$devpath" | grep -q '^ID_BUS=usb' && \
584- device_info env "$devpath" | grep -q '^ID_TYPE=disk'; then
585- match=:
586- fi
587- fi
588- if $match; then
589- device_name "/sys$devpath"
590- fi
591-done
592
593=== removed file 'scripts/disk_test'
594--- scripts/disk_test 2010-03-07 15:05:44 +0000
595+++ scripts/disk_test 1970-01-01 00:00:00 +0000
596@@ -1,33 +0,0 @@
597-#!/usr/bin/python
598-
599-import os
600-import sys
601-
602-from subprocess import Popen, PIPE
603-
604-
605-def main(args):
606- directory = os.path.dirname(__file__)
607- script = os.path.join(directory, "device_list")
608- disk_devices_string = Popen([script, "disk"], stdout=PIPE).communicate()[0]
609- disk_devices_string = disk_devices_string.strip()
610-
611- if not disk_devices_string:
612- print "None"
613- else:
614- disk_devices = disk_devices_string.split("\n")
615- for disk_device in disk_devices:
616- disk = os.path.basename(disk_device)
617- model_path = "/sys/block/%s/device/model" % disk
618- model_file = open(model_path)
619- try:
620- model_name = model_file.read().strip()
621- print model_name
622- finally:
623- model_file.close()
624-
625- return 0
626-
627-
628-if __name__ == "__main__":
629- sys.exit(main(sys.argv[1:]))
630
631=== added file 'scripts/run_templates'
632--- scripts/run_templates 1970-01-01 00:00:00 +0000
633+++ scripts/run_templates 2011-06-22 19:41:15 +0000
634@@ -0,0 +1,142 @@
635+#!/usr/bin/env python
636+
637+import os
638+import re
639+import sys
640+import uuid
641+
642+from optparse import OptionParser
643+from subprocess import Popen, PIPE
644+
645+from checkbox.lib.template import Template
646+
647+
648+DEFAULT_INPUT = "-"
649+DEFAULT_OUTPUT = "-"
650+
651+COMMAND_TEMPLATE = """cat <<%(separator)s
652+%(input)s
653+%(separator)s"""
654+
655+
656+class Runner(object):
657+
658+ def __init__(self, input, output):
659+ self.input = input
660+ self.output = output
661+
662+ def get_args(self, record):
663+ return []
664+
665+ def get_env(self, record):
666+ env = dict(os.environ)
667+ env["NF"] = str(len(record))
668+
669+ return env
670+
671+ def process(self, args, shell=False):
672+ process = Popen(args, shell=shell, stdout=PIPE)
673+ records = self.process_output(process.stdout)
674+
675+ for nr, record in enumerate(records):
676+ args = self.get_args(record)
677+ env = self.get_env(record)
678+ env["NR"] = str(nr)
679+
680+ command_string = COMMAND_TEMPLATE % {
681+ "input": self.input,
682+ "separator": uuid.uuid4()}
683+ command = ["sh", "-c", command_string] + args
684+
685+ process = Popen(command,
686+ env=env,
687+ stdout=self.output)
688+ process.communicate()
689+
690+ def process_output(self, output):
691+ raise NotImplementedError
692+
693+
694+class LineRunner(Runner):
695+
696+ field_separator = r"\s+"
697+ record_separator = r"(?:\r?\n)"
698+
699+ def get_args(self, record):
700+ args = [record]
701+ args.extend(re.split(self.field_separator, record))
702+
703+ return args
704+
705+ def process_output(self, file):
706+ # Strip trailing separator
707+ data = re.sub(r"%s$" % self.record_separator, "", file.read())
708+
709+ return re.split(self.record_separator, data)
710+
711+
712+class TemplateRunner(Runner):
713+
714+ def get_env(self, record):
715+ env = super(TemplateRunner, self).get_env(record)
716+ env.update(record)
717+
718+ return env
719+
720+ def process_output(self, output):
721+ template = Template()
722+ return template.load_file(output)
723+
724+
725+def main(args):
726+ usage = "Usage: %prog [OPTIONS] [COMMAND]"
727+ parser = OptionParser(usage=usage)
728+ parser.add_option("-i", "--input",
729+ metavar="FILE",
730+ default=DEFAULT_INPUT,
731+ help="Input from the given file name, - for stdin")
732+ parser.add_option("-o", "--output",
733+ metavar="FILE",
734+ default=DEFAULT_OUTPUT,
735+ help="Output to the given file name, - for stdout")
736+ parser.add_option("-s", "--shell",
737+ action="store_true",
738+ help="Run the command as a shell script")
739+ parser.add_option("-t", "--template",
740+ action="store_true",
741+ help="Interpret the command output as a template")
742+ (options, args) = parser.parse_args(args)
743+
744+ # Default args to echo command
745+ if not args:
746+ args = ["echo"]
747+
748+ # Read input
749+ if options.input == "-":
750+ input = sys.stdin.read()
751+ else:
752+ input_file = open(options.input, "r")
753+ try:
754+ input = input_file.read()
755+ finally:
756+ input_file.close()
757+
758+ # Open output
759+ if options.output == "-":
760+ output_file = sys.stdout
761+ else:
762+ output_file = open(options.output, "w")
763+
764+ # Determine runner class
765+ if options.template:
766+ runner_class = TemplateRunner
767+ else:
768+ runner_class = LineRunner
769+
770+ runner = runner_class(input, output_file)
771+ runner.process(args, options.shell)
772+
773+ return 0
774+
775+if __name__ == "__main__":
776+ sys.exit(main(sys.argv[1:]))
777
778=== modified file 'scripts/suspend_test'
779--- scripts/suspend_test 2009-03-17 09:46:16 +0000
780+++ scripts/suspend_test 2011-06-22 19:41:15 +0000
781@@ -109,11 +109,10 @@
782 #
783 ctl='/sys/class/rtc/rtc0/wakealarm'
784 if [ -f "$ctl" ]; then
785- time=`date '+%s' -d "+ $timeout seconds"`
786 # Cancel any outstanding timers.
787 echo "0" >"$ctl"
788- # rtcN/wakealarm uses absolute time in seconds
789- echo "$time" >"$ctl"
790+ # rtcN/wakealarm can use relative time in seconds
791+ echo "+$timeout" >"$ctl"
792 return 0
793 fi
794 ctl='/proc/acpi/alarm'
795
796=== modified file 'scripts/udev_resource'
797--- scripts/udev_resource 2010-03-07 15:05:44 +0000
798+++ scripts/udev_resource 2011-06-22 19:41:15 +0000
799@@ -476,7 +476,7 @@
800 def devices(self):
801 devices = []
802 line_pattern = re.compile(r"(?P<key>\w):\s*(?P<value>.*)")
803- multi_pattern = re.compile(r"(?P<key>\w+)=(?P<value>.*)")
804+ multi_pattern = re.compile(r"(?P<key>[^=]+)=(?P<value>.*)")
805
806 output = Popen(COMMAND, stdout=PIPE, shell=True).communicate()[0]
807 for record in output.split("\n\n"):

Subscribers

People subscribed via source and target branches

to all changes: