Merge lp:~jeffmarcom/opencompute/add-checkbox-ocp-package into lp:opencompute/checkbox

Proposed by Jeff Marcom
Status: Merged
Approved by: Jeff Lane 
Approved revision: 2150
Merged at revision: 2143
Proposed branch: lp:~jeffmarcom/opencompute/add-checkbox-ocp-package
Merge into: lp:opencompute/checkbox
Diff against target: 649 lines (+547/-6)
10 files modified
bin/checkbox-ocp (+18/-0)
checkbox_ocp/cli_interface.py (+477/-0)
debian/changelog (+9/-2)
debian/checkbox-ocp.install (+3/-0)
debian/checkbox-ocp.links (+1/-0)
debian/checkbox-ocp.postinst (+7/-0)
debian/control (+10/-1)
debian/rules (+3/-1)
examples/checkbox-ocp.ini (+17/-0)
setup.py (+2/-2)
To merge this branch: bzr merge lp:~jeffmarcom/opencompute/add-checkbox-ocp-package
Reviewer Review Type Date Requested Status
Jeff Lane  Approve
Review via email: mp+181350@code.launchpad.net

Commit message

This adds a checkbox-ocp package to the list of built debian packages. This commit also bumps the overall changelog version to 1.16.6 so that it does not conflict with a previous checkbox installed package version.

Description of the change

This adds a checkbox-ocp package to the list of built debian packages. This commit also bumps the overall changelog version to 1.16.6 so that it does not conflict with a previous checkbox installed package version.

To post a comment you must log in.
2150. By Jeff Marcom

Updated checkbox-ocp.ini to call proper module interface

Signed-off-by: Jeff Marcom <email address hidden>

Revision history for this message
Jeff Lane  (bladernr) wrote :

Builds and seems to be ok.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'bin/checkbox-ocp'
--- bin/checkbox-ocp 1970-01-01 00:00:00 +0000
+++ bin/checkbox-ocp 2013-08-21 16:43:19 +0000
@@ -0,0 +1,18 @@
1#!/bin/bash
2
3export XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache}
4export CHECKBOX_DATA=${CHECKBOX_DATA:-.}
5export CHECKBOX_SHARE=${CHECKBOX_SHARE:-.}
6export CHECKBOX_OPTIONS=${CHECKBOX_OPTIONS:---whitelist-file=$CHECKBOX_SHARE/data/whitelists/opencompute-ready-local.whitelist}
7export PYTHONPATH=$PYTHONPATH:$CHECKBOX_SHARE
8
9if [ $CHECKBOX_DATA != '.' ]
10then
11 old_data=$HOME/.checkbox
12 if [ -d $old_data ] && [ ! -d $CHECKBOX_DATA ]
13 then
14 mv -f $old_data $CHECKBOX_DATA
15 fi
16fi
17
18python3 $CHECKBOX_SHARE/run "$@" $CHECKBOX_SHARE/configs/$(basename $0).ini
019
=== added directory 'checkbox_ocp'
=== added file 'checkbox_ocp/__init__.py'
=== added file 'checkbox_ocp/cli_interface.py'
--- checkbox_ocp/cli_interface.py 1970-01-01 00:00:00 +0000
+++ checkbox_ocp/cli_interface.py 2013-08-21 16:43:19 +0000
@@ -0,0 +1,477 @@
1#
2# This file is part of Checkbox.
3#
4# Copyright 2008 Canonical Ltd.
5#
6# Checkbox is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# Checkbox is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
18#
19import re
20import sys
21import string
22import termios
23
24from gettext import gettext as _
25
26from checkbox.user_interface import (UserInterface, ANSWER_TO_STATUS,
27 ALL_ANSWERS, YES_ANSWER, NO_ANSWER, SKIP_ANSWER)
28
29
30ANSWER_TO_OPTION = {
31 YES_ANSWER: _("yes"),
32 NO_ANSWER: _("no"),
33 SKIP_ANSWER: _("skip")}
34
35OPTION_TO_ANSWER = dict((o, a) for a, o in ANSWER_TO_OPTION.items())
36
37
38class CLIDialog:
39 """Command line dialog wrapper."""
40
41 def __init__(self, text):
42 self.text = text
43 self.visible = False
44
45 def put(self, text):
46 sys.stdout.write(text)
47 sys.stdout.flush()
48
49 def put_line(self, line):
50 self.put("%s\n" % line)
51
52 def put_newline(self):
53 self.put("\n")
54
55 def get(self, label=None, limit=1, separator=termios.CEOT):
56 if label is not None:
57 self.put_newline()
58 self.put(label)
59
60 fileno = sys.stdin.fileno()
61 saved_attributes = termios.tcgetattr(fileno)
62 attributes = termios.tcgetattr(fileno)
63 attributes[3] &= ~(termios.ICANON | termios.ECHO)
64 attributes[6][termios.VMIN] = 1
65 attributes[6][termios.VTIME] = 0
66 termios.tcsetattr(fileno, termios.TCSANOW, attributes)
67
68 input = []
69 escape = 0
70 try:
71 while len(input) < limit:
72 ch = sys.stdin.read(1)
73 if ord(ch) == separator:
74 break
75 elif ord(ch) == 0o33: # ESC
76 escape = 1
77 elif ord(ch) == termios.CERASE or ord(ch) == 0o10:
78 if len(input):
79 self.put("\010 \010")
80 del input[-1]
81 elif ord(ch) == termios.CKILL:
82 self.put("\010 \010" * len(input))
83 input = []
84 else:
85 if not escape:
86 input.append(ch)
87 self.put(ch)
88 elif escape == 1:
89 if ch == "[":
90 escape = 2
91 else:
92 escape = 0
93 elif escape == 2:
94 escape = 0
95 finally:
96 termios.tcsetattr(fileno, termios.TCSANOW, saved_attributes)
97
98 return "".join(input)
99
100 def show(self):
101 self.visible = True
102 self.put_newline()
103 self.put_line(self.text)
104
105
106class CLIChoiceDialog(CLIDialog):
107
108 def __init__(self, text):
109 super(CLIChoiceDialog, self).__init__(text)
110 self.keys = []
111 self.options = []
112
113 def get(self, *args, **kwargs):
114 response = super(CLIChoiceDialog, self).get(*args, **kwargs)
115 try:
116 return self.keys.index(response[0])
117 except ValueError:
118 return -1
119
120 def run(self, label=None, defaults=[]):
121 if not self.visible:
122 self.show()
123
124 try:
125 # Only one option
126 if len(self.keys) <= 1:
127 self.get(_("Press any key to continue..."))
128 return 0
129 # Multiple choices
130 while True:
131 self.put_newline()
132 for key, option in zip(self.keys, self.options):
133 default = "*" if option in defaults else " "
134 self.put_line("%s %s: %s" % (default, key, option))
135
136 response = self.get(_("Please choose (%s): ") %
137 ("/".join(self.keys)))
138 if response >= 0:
139 return response
140
141 if label is not None:
142 self.put_line(label)
143
144 except KeyboardInterrupt:
145 self.put_newline()
146 raise
147
148 def add_option(self, option, key=None):
149 if key is None:
150 keys = option.lower() + \
151 string.ascii_letters + \
152 string.digits + \
153 string.punctuation
154
155 keys = keys.replace(' ', '')
156 keys = keys.replace('+', '')
157
158 for key in keys:
159 if key not in self.keys:
160 break
161 self.keys.append(key)
162 self.options.append(option)
163
164
165class CLIReportDialog(CLIDialog):
166 """
167 Display test results
168 """
169 STATUS = {'pass': '{0}',
170 'fail': '{0}'}
171
172 def __init__(self, text, results):
173 super(CLIReportDialog, self).__init__(text)
174 self.results = results
175
176 def run(self):
177 """
178 Show root of the tree
179 and provide the ability to further display subtress
180 """
181 root = self.results
182 title = self.text
183 self._display(title, root)
184
185 def _is_suite(self, root):
186 """
187 Return True if root contains a suite
188 that is, a job containing other jobs
189 """
190 return all(issubclass(type(value), dict)
191 for value in root.values())
192
193 def _display(self, title, root):
194 """
195 Display dialog until user decides to exit
196 (recursively for subtrees)
197 """
198 while True:
199 self.put_newline()
200 self.put_newline()
201 self.put_line(title)
202 self.put_newline()
203
204 keys = []
205 options = []
206
207 def add_option(option, key=None):
208 """
209 Add option to list
210 and generate automatic key value
211 if not provided
212 """
213 if key is None:
214 key = string.ascii_lowercase[len(keys)]
215 keys.append(key)
216 options.append(option)
217
218 for job_name, job_data in sorted(root.items()):
219 if self._is_suite(job_data):
220 add_option(job_name)
221 self.put_line('{key}: {option}'
222 .format(key=keys[-1],
223 option=options[-1]))
224 else:
225 job_status = job_data.get('status')
226 status_string = (self.STATUS.get(job_status, '{0}')
227 .format(job_status))
228 self.put_line(' {name} [{status}]'
229 .format(name=job_name,
230 status=status_string))
231
232 add_option(_("Space when finished"), " ")
233 self.put_line('{key}: {option}'
234 .format(key=keys[-1],
235 option=options[-1]))
236
237 response = self.get(_("Please choose (%s): ") % ("/".join(keys)))
238
239 if response != ' ':
240 try:
241 selected_option = options[keys.index(response)]
242 except ValueError:
243 # Display again menu
244 continue
245
246 # Display new menu with the contents of the selected option
247 self._display(selected_option, root[selected_option])
248 else:
249 # Exit from this menu display
250 # (display again parent menu or exit)
251 break
252
253
254class CLITextDialog(CLIDialog):
255
256 limit = 255
257 separator = termios.CEOT
258
259 def run(self, label=None):
260 if not self.visible:
261 self.show()
262
263 self.put_newline()
264 try:
265 return self.get(label, self.limit, self.separator)
266 except KeyboardInterrupt:
267 self.put_newline()
268 raise
269
270
271class CLILineDialog(CLITextDialog):
272
273 limit = 80
274 separator = ord("\n")
275
276
277class Twirly(object):
278 def __init__(self):
279 self.index = 0
280 self.twirlies = "-\\|/"
281
282 def next(self):
283 next_twirly = self.twirlies[self.index]
284 self.index = (self.index + 1) % len(self.twirlies)
285 return next_twirly
286
287
288class CLIProgressDialog(CLIDialog):
289 """Command line progress dialog wrapper."""
290
291 def __init__(self, text):
292 super(CLIProgressDialog, self).__init__(text)
293 self.progress_count = 0
294 self.twirly = Twirly()
295
296 def set(self, progress=None):
297 self.progress_count = (self.progress_count + 1) % 5
298 if self.progress_count:
299 return
300
301 if progress != None:
302 self.put("\r%u%%" % (progress * 100))
303 else:
304 self.put("\b\b")
305 self.put(self.twirly.next())
306 self.put(" ")
307 sys.stdout.flush()
308
309
310class CLIInterface(UserInterface):
311
312 def _toggle_results(self, key, options, results):
313 if isinstance(results, dict):
314 if key in results:
315 del results[key]
316
317 elif key in options:
318 if isinstance(options[key], dict):
319 results[key] = {}
320 elif isinstance(options[key], (list, tuple)):
321 results[key] = []
322 else:
323 results[key] = None
324
325 for k in options[key]:
326 self._toggle_results(k, options[key], results[key])
327
328 elif isinstance(results, (list, tuple)):
329 if key in results:
330 results.remove(key)
331 elif key in options:
332 results.append(key)
333
334 def show_progress_start(self, text):
335 self.progress = CLIProgressDialog(text)
336 self.progress.show()
337
338 def show_progress_pulse(self):
339 self.progress.set()
340
341 def show_text(self, text, previous=None, next=None):
342 dialog = CLIChoiceDialog(text)
343 dialog.run()
344
345 def show_entry(self, text, value, showSubmitToHexr=False, label=None, previous=None, next=None):
346 dialog = CLILineDialog(text)
347
348 return (dialog.run(), False)
349
350 def show_check(self, text, options=[], default=[]):
351 dialog = CLIChoiceDialog(text)
352 for option in options:
353 dialog.add_option(option)
354
355 dialog.add_option(_("Space when finished"), " ")
356
357 results = default
358 while True:
359 response = dialog.run(defaults=results)
360 if response >= len(options):
361 break
362
363 result = options[response]
364 self._toggle_results(result, options, results)
365
366 return (results, False)
367
368 def show_radio(self, text, options=[], default=None):
369 dialog = CLIChoiceDialog(text)
370 for option in options:
371 dialog.add_option(option)
372
373 # Show options dialog
374 response = dialog.run()
375 return options[response]
376
377 def show_tree(self, text, options={}, default={}, deselect_warning=""):
378 keys = sorted(options.keys())
379
380 dialog = CLIChoiceDialog(text)
381 for option in keys:
382 dialog.add_option(option)
383
384 dialog.add_option(_("Combine with character above to expand node"),
385 "+")
386 dialog.add_option(_("Space when finished"), " ")
387
388 do_expand = False
389 results = default
390 while True:
391 response = dialog.run(defaults=results)
392 if response > len(options):
393 break
394
395 elif response == len(options):
396 response = dialog.get()
397 do_expand = True
398
399 else:
400 do_expand = False
401
402 # Invalid response
403 if response < 0:
404 continue
405
406 # Toggle results
407 result = keys[response]
408 if not do_expand:
409 self._toggle_results(result, options, results)
410 continue
411
412 # Expand tree
413 dialog.visible = False
414 if options[result]:
415 branch_results = results.get(result, {})
416 self.show_tree(result, options[result], branch_results)
417 if branch_results and result not in results:
418 results[result] = branch_results
419
420 return results
421
422 def show_report(self, text, results):
423 """
424 Show test case results in a tree hierarchy
425 """
426 dialog = CLIReportDialog(text, results)
427 dialog.run()
428
429 def show_test(self, test, runner):
430 options = list([ANSWER_TO_OPTION[a] for a in ALL_ANSWERS])
431 if "command" in test:
432 options.append(_("test"))
433
434 if re.search(r"\$output", test["description"]):
435 output = runner(test)[1]
436 else:
437 output = ""
438
439 while True:
440 # Show option dialog
441 description = string.Template(test["description"]).substitute({
442 "output": output.strip()})
443 dialog = CLIChoiceDialog(description)
444
445 for option in options:
446 dialog.add_option(option, option[0])
447
448 # Get option from dialog
449 response = dialog.run()
450 option = options[response]
451 if response < len(ALL_ANSWERS):
452 break
453
454 output = runner(test)[1]
455
456 options[-1] = _("test again")
457
458 answer = OPTION_TO_ANSWER[option]
459 if answer == NO_ANSWER:
460 text = _("Further information:")
461 dialog = CLITextDialog(text)
462 test["data"] = dialog.run(_("Please type here and press"
463 " Ctrl-D when finished:\n"))
464 else:
465 test["data"] = ""
466
467 test["status"] = ANSWER_TO_STATUS[answer]
468
469 def show_info(self, text, options=[], default=None):
470 return self.show_radio(text, options, default)
471
472 def show_error(self, primary_text,
473 secondary_text=None, detailed_text=None):
474 text = filter(None, [primary_text, secondary_text, detailed_text])
475 text = '\n'.join(text)
476 dialog = CLIChoiceDialog("Error: %s" % text)
477 dialog.run()
0478
=== modified file 'debian/changelog'
--- debian/changelog 2013-08-19 20:46:26 +0000
+++ debian/changelog 2013-08-21 16:43:19 +0000
@@ -1,4 +1,12 @@
1checkbox (0.16.6~OCP) UNRELEASED; urgency=low1checkbox (1.16.6~OCP) UNRELEASED; urgency=low
2
3 [ Jeff Marcom ]
4 * Added checkbox-ocp package
5
6 -- Jeff Marcom <jeff.marcom@canonical.com> Wed, 21 Aug 2013 12:20:24 -0400
7
8
9checkbox (0.16.6~OCPubuntu1) UNRELEASED; urgency=low
210
3 * INITIAL RELEASE:11 * INITIAL RELEASE:
4 based on checkbox 0.16.6 from lp:checkbox with modificiations specific to12 based on checkbox 0.16.6 from lp:checkbox with modificiations specific to
@@ -17,4 +25,3 @@
17 checkbox/tests/ - Cleaned up unit tests that were looking for things25 checkbox/tests/ - Cleaned up unit tests that were looking for things
18 removed in this merge.26 removed in this merge.
1927
20 -- Jeff Marcom <jeff.marcom@canonical.com> Wed, 31 Jul 2013 19:36:52 -0400
2128
=== added file 'debian/checkbox-ocp.install'
--- debian/checkbox-ocp.install 1970-01-01 00:00:00 +0000
+++ debian/checkbox-ocp.install 2013-08-21 16:43:19 +0000
@@ -0,0 +1,3 @@
1usr/bin/checkbox-ocp
2usr/lib/python*/*-packages/checkbox_ocp/*
3usr/share/checkbox/examples/checkbox-ocp.ini
04
=== added file 'debian/checkbox-ocp.links'
--- debian/checkbox-ocp.links 1970-01-01 00:00:00 +0000
+++ debian/checkbox-ocp.links 2013-08-21 16:43:19 +0000
@@ -0,0 +1,1 @@
1usr/share/man/man1/checkbox.1.gz usr/share/man/man1/checkbox-ocp.1.gz
02
=== added file 'debian/checkbox-ocp.postinst'
--- debian/checkbox-ocp.postinst 1970-01-01 00:00:00 +0000
+++ debian/checkbox-ocp.postinst 2013-08-21 16:43:19 +0000
@@ -0,0 +1,7 @@
1#! /bin/sh -e
2
3base_package="checkbox"
4. /usr/share/debconf/confmodule
5. /usr/share/checkbox/install/postinst
6
7#DEBHELPER#
08
=== modified file 'debian/control'
--- debian/control 2013-07-05 16:43:48 +0000
+++ debian/control 2013-08-21 16:43:19 +0000
@@ -47,7 +47,7 @@
47 python3-gi47 python3-gi
48Suggests: bonnie++,48Suggests: bonnie++,
49 bootchart,49 bootchart,
50 checkbox-cli | checkbox-gtk,50 checkbox-cli | checkbox-ocp, checkbox-gtk,
51 curl,51 curl,
52 ethtool,52 ethtool,
53 fwts,53 fwts,
@@ -80,6 +80,15 @@
80 .80 .
81 This package provides a command line interface for answering tests.81 This package provides a command line interface for answering tests.
8282
83Package: checkbox-ocp
84Architecture: all
85Depends: checkbox (>= ${source:Version}), ${misc:Depends}
86Description: Command line interface of checkbox for the Open Compute Project
87 This project provides an extensible interface for system testing on
88 Open Compute platforms.
89 .
90 This package provides a command line interface for answering tests.
91
83Package: checkbox-urwid92Package: checkbox-urwid
84Architecture: all93Architecture: all
85Depends: checkbox (>= ${source:Version}), python3-urwid, ${misc:Depends}94Depends: checkbox (>= ${source:Version}), python3-urwid, ${misc:Depends}
8695
=== modified file 'debian/rules'
--- debian/rules 2013-07-05 16:43:48 +0000
+++ debian/rules 2013-08-21 16:43:19 +0000
@@ -25,6 +25,7 @@
2525
26override_dh_installdeb:26override_dh_installdeb:
27 cp debian/checkbox.postrm debian/checkbox-cli.postrm27 cp debian/checkbox.postrm debian/checkbox-cli.postrm
28 cp debian/checkbox.postrm debian/checkbox-ocp.postrm
28 cp debian/checkbox.postrm debian/checkbox-urwid.postrm29 cp debian/checkbox.postrm debian/checkbox-urwid.postrm
29 cp debian/checkbox.postrm debian/checkbox-gtk.postrm30 cp debian/checkbox.postrm debian/checkbox-gtk.postrm
30 cp debian/checkbox.postrm debian/checkbox-qt.postrm31 cp debian/checkbox.postrm debian/checkbox-qt.postrm
@@ -34,6 +35,7 @@
34override_dh_installdocs:35override_dh_installdocs:
35 dh_installdocs -pcheckbox ./README 36 dh_installdocs -pcheckbox ./README
36 dh_installdocs -pcheckbox-cli ./README 37 dh_installdocs -pcheckbox-cli ./README
38 dh_installdocs -pcheckbox-ocp ./README
37 dh_installdocs -pcheckbox-urwid ./README 39 dh_installdocs -pcheckbox-urwid ./README
38 dh_installdocs -pcheckbox-gtk ./README 40 dh_installdocs -pcheckbox-gtk ./README
39 dh_installdocs -pcheckbox-qt ./README41 dh_installdocs -pcheckbox-qt ./README
@@ -42,6 +44,6 @@
4244
43override_dh_clean:45override_dh_clean:
44 -find . -name \*.mo -exec rm {} \;46 -find . -name \*.mo -exec rm {} \;
45 -rm -f debian/checkbox-cli.postrm debian/checkbox-urwid.postrm debian/checkbox-gtk.postrm debian/checkbox-qt.postrm debian/checkbox-hw-collection.postrm47 -rm -f debian/checkbox-cli.postrm debian/checkbox-ocp.postrm debian/checkbox-cli.postrmebian/checkbox-urwid.postrm debian/checkbox-gtk.postrm debian/checkbox-qt.postrm debian/checkbox-hw-collection.postrm
46 debconf-updatepo48 debconf-updatepo
47 dh_clean49 dh_clean
4850
=== added file 'examples/checkbox-ocp.ini'
--- examples/checkbox-ocp.ini 1970-01-01 00:00:00 +0000
+++ examples/checkbox-ocp.ini 2013-08-21 16:43:19 +0000
@@ -0,0 +1,17 @@
1[DEFAULT]
2
3# Space separated list of files to include as a dependency for the
4# CLI interface.
5includes = %(checkbox_share)s/configs/checkbox.ini
6
7[checkbox/plugins/user_interface]
8
9# Module where the user interface implementation is defined.
10interface_module = checkbox_ocp.cli_interface
11
12# Class implementing the UserInterface interface.
13interface_class = CLIInterface
14
15[checkbox/plugins]
16
17blacklist = hexr_prompt hexr_transport
018
=== modified file 'setup.py'
--- setup.py 2013-07-05 16:43:48 +0000
+++ setup.py 2013-08-21 16:43:19 +0000
@@ -266,8 +266,8 @@
266 ],266 ],
267 },267 },
268 scripts=[268 scripts=[
269 "bin/checkbox-cli", "bin/checkbox-gtk", "bin/checkbox-urwid",269 "bin/checkbox-cli", "bin/checkbox-ocp", "bin/checkbox-gtk",
270 "bin/checkbox-qt", "bin/checkbox-hw-collection"],270 "bin/checkbox-urwid", "bin/checkbox-qt", "bin/checkbox-hw-collection"],
271 packages=find_packages(),271 packages=find_packages(),
272 package_data={272 package_data={
273 "": ["cputable"]},273 "": ["cputable"]},

Subscribers

People subscribed via source and target branches