Merge lp:~david-schwarz/lava-dispatcher/ssh_qemu_clients_v3 into lp:lava-dispatcher

Proposed by David Schwarz
Status: Merged
Merged at revision: 105
Proposed branch: lp:~david-schwarz/lava-dispatcher/ssh_qemu_clients_v3
Merge into: lp:lava-dispatcher
Diff against target: 1169 lines (+538/-255) (has conflicts)
20 files modified
config/hosts/localhost.json (+5/-0)
config/hosts/qemu1.json (+11/-0)
config/hosts/qemu2.json (+11/-0)
config/hosts/vs3.json (+6/-0)
config/hosts/vs8.json (+6/-0)
doc/qemu-ltp-job.json (+41/-0)
doc/ssh-ltp-job.json (+23/-0)
lava_dispatcher/__init__.py (+43/-14)
lava_dispatcher/actions/android_basic.py (+0/-1)
lava_dispatcher/actions/android_deploy.py (+55/-123)
lava_dispatcher/actions/deploy.py (+20/-41)
lava_dispatcher/actions/launch_control.py (+14/-21)
lava_dispatcher/actions/lava-test.py (+21/-45)
lava_dispatcher/android_client.py (+3/-3)
lava_dispatcher/client.py (+21/-7)
lava_dispatcher/config.py (+10/-0)
lava_dispatcher/qemu_client.py (+135/-0)
lava_dispatcher/qemu_config.py (+20/-0)
lava_dispatcher/ssh_client.py (+75/-0)
lava_dispatcher/ssh_config.py (+18/-0)
Text conflict in lava_dispatcher/__init__.py
To merge this branch: bzr merge lp:~david-schwarz/lava-dispatcher/ssh_qemu_clients_v3
Reviewer Review Type Date Requested Status
Linaro Validation Team Pending
Review via email: mp+70892@code.launchpad.net

Description of the change

This is a cleaner version of the ssh_qemu_clients feature branch--the older version was uploaded by mistake.

To post a comment you must log in.
Revision history for this message
Paul Larson (pwlars) wrote :

As discussed offline, I'd like to see about merging this with what Yongqin has been working on (https://code.launchpad.net/~liuyq0307/lava-dispatcher/test-client/+merge/69757) and make the config read from a file for the boards and specific machines. One general comment here... You seem to want the job to specify the type of client to use, but I'm betting that each test machine is only going to use pretty much one type of client. Can you envision a case where you might have a conmux client that you want to suddenly use as an ssh client? I don't think it typically makes sense, but if someone has a good reason why this might happen, let me know.

I think what we really want, is a directory containing config details for specific board types:
 - bootloader commands to send for booting to the test image
 - partition offsets
 - possibly even client type specific sections

and a config file listing the boards you have in your environment, and which board_type config to use, along with any specific information, or overrides for that individual system.

Revision history for this message
David Schwarz (david-schwarz) wrote :

I agree that the machine config rather than job should specify the
client type--particularly because it's entirely possible in our testing
that we may have a mix of different client types in a single
multi-target test job.

I was thinking of splitting the board and machine configs into separate
groups of files to help cut down duplication of common settings.
Machine config (currently in config/hosts in this branch) would include
any machine-specific configuration, including its board type:

panda01.conf:

[machine]
client_type = ssh
hostname = panda01
# References a board-specific config file
board_type = PandaBoard
ip_addr = 192.168.1.1
username = test1
password = test1
has_feature_x = yes

...then the board configuration file could include the information
common to all machines of a particular type, currently being stored in
the config.py Board classes:

PandaBoard.conf

[board]
uboot_cmds = yadda yadda
boot_part = 1
test_part = 2

David

Revision history for this message
David Schwarz (david-schwarz) wrote :

   Rereading, I believe we're proposing the same thing.

David

On 08/09/2011 04:46 PM, Paul Larson wrote:
> As discussed offline, I'd like to see about merging this with what Yongqin has been working on (https://code.launchpad.net/~liuyq0307/lava-dispatcher/test-client/+merge/69757) and make the config read from a file for the boards and specific machines. One general comment here... You seem to want the job to specify the type of client to use, but I'm betting that each test machine is only going to use pretty much one type of client. Can you envision a case where you might have a conmux client that you want to suddenly use as an ssh client? I don't think it typically makes sense, but if someone has a good reason why this might happen, let me know.
>
> I think what we really want, is a directory containing config details for specific board types:
> - bootloader commands to send for booting to the test image
> - partition offsets
> - possibly even client type specific sections
>
> and a config file listing the boards you have in your environment, and which board_type config to use, along with any specific information, or overrides for that individual system.

Revision history for this message
Paul Larson (pwlars) wrote :

Yep, exactly :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'config'
2=== added directory 'config/hosts'
3=== added file 'config/hosts/localhost.json'
4--- config/hosts/localhost.json 1970-01-01 00:00:00 +0000
5+++ config/hosts/localhost.json 2011-08-09 14:40:36 +0000
6@@ -0,0 +1,5 @@
7+{
8+ "board_name": "localhost",
9+ "board_type": "BeagleBoard",
10+ "hostname": "localhost"
11+}
12
13=== added file 'config/hosts/qemu1.json'
14--- config/hosts/qemu1.json 1970-01-01 00:00:00 +0000
15+++ config/hosts/qemu1.json 2011-08-09 14:40:36 +0000
16@@ -0,0 +1,11 @@
17+{
18+ "board_name": "qemu1",
19+ "board_type": "BeagleBoard",
20+ "hostname": "qemu1",
21+ "machine_type": "beagle",
22+ "qemu_macaddr": "52:54:00:12:34:56",
23+ "qemu_disk": "qemu/linaroDiskMaster",
24+ "vlan_number": 0,
25+ "boot_image": "qemu/startup.bin",
26+ "additional_options": "-nographic -no-reboot "
27+}
28
29=== added file 'config/hosts/qemu2.json'
30--- config/hosts/qemu2.json 1970-01-01 00:00:00 +0000
31+++ config/hosts/qemu2.json 2011-08-09 14:40:36 +0000
32@@ -0,0 +1,11 @@
33+{
34+ "board_name": "qemu2",
35+ "board_type": "BeagleBoard",
36+ "hostname": "qemu2",
37+ "machine_type": "beagle",
38+ "qemu_macaddr": "12:34:56:78:90:12",
39+ "qemu_disk": "qemu/linaroDiskMaster",
40+ "vlan_number": 0,
41+ "boot_image": "qemu/startup.bin",
42+ "additional_options": "-nographic -no-reboot "
43+}
44
45=== added file 'config/hosts/vs3.json'
46--- config/hosts/vs3.json 1970-01-01 00:00:00 +0000
47+++ config/hosts/vs3.json 2011-08-09 14:40:36 +0000
48@@ -0,0 +1,6 @@
49+{
50+ "board_name": "vs3",
51+ "hostname": "vs3",
52+ "username": "test",
53+ "password": "test"
54+}
55
56=== added file 'config/hosts/vs8.json'
57--- config/hosts/vs8.json 1970-01-01 00:00:00 +0000
58+++ config/hosts/vs8.json 2011-08-09 14:40:36 +0000
59@@ -0,0 +1,6 @@
60+{
61+ "board_name": "vs8",
62+ "hostname": "vs8",
63+ "username": "test",
64+ "password": "test"
65+}
66
67=== added file 'doc/qemu-ltp-job.json'
68--- doc/qemu-ltp-job.json 1970-01-01 00:00:00 +0000
69+++ doc/qemu-ltp-job.json 2011-08-09 14:40:36 +0000
70@@ -0,0 +1,41 @@
71+{
72+ "job_name": "qemu_ltp",
73+ "target": "qemu1",
74+ "target_type": "qemu",
75+ "timeout": 18000,
76+ "actions": [
77+ {
78+ "command": "deploy_linaro_image",
79+ "parameters":
80+ {
81+ "rootfs": "http://snapshots.linaro.org/11.05-daily/linaro-developer/20110208/0/images/tar/linaro-n-developer-tar-20110208-0.tar.gz",
82+ "hwpack": "http://snapshots.linaro.org/11.05-daily/linaro-hwpacks/panda/20110208/0/images/hwpack/hwpack_linaro-panda_20110208-0_armel_supported.tar.gz"
83+ }
84+ },
85+ {
86+ "command": "lava_test_install",
87+ "parameters":
88+ {
89+ "tests": ["ltp"]
90+ }
91+ },
92+ {
93+ "command": "boot_linaro_image"
94+ },
95+ {
96+ "command": "lava_test_run",
97+ "parameters":
98+ {
99+ "test_name": "ltp"
100+ }
101+ },
102+ {
103+ "command": "submit_results",
104+ "parameters":
105+ {
106+ "server": "http://validation.linaro.org/launch-control",
107+ "stream": "/anonymous/panda01-ltp/"
108+ }
109+ }
110+ ]
111+}
112
113=== added file 'doc/ssh-ltp-job.json'
114--- doc/ssh-ltp-job.json 1970-01-01 00:00:00 +0000
115+++ doc/ssh-ltp-job.json 2011-08-09 14:40:36 +0000
116@@ -0,0 +1,23 @@
117+{
118+ "job_name": "ssh_ltp",
119+ "target": "vs3",
120+ "target_type": "ssh",
121+ "timeout": 18000,
122+ "actions": [
123+ {
124+ "command": "lava_test_run",
125+ "parameters":
126+ {
127+ "test_name": "ltp"
128+ }
129+ },
130+ {
131+ "command": "submit_results",
132+ "parameters":
133+ {
134+ "server": "http://validation.linaro.org/launch-control",
135+ "stream": "/anonymous/panda01-ltp/"
136+ }
137+ }
138+ ]
139+}
140
141=== modified file 'lava_dispatcher/__init__.py'
142--- lava_dispatcher/__init__.py 2011-08-04 07:19:53 +0000
143+++ lava_dispatcher/__init__.py 2011-08-09 14:40:36 +0000
144@@ -29,6 +29,8 @@
145 from lava_dispatcher.actions import get_all_cmds
146 from lava_dispatcher.client import LavaClient, CriticalError, GeneralError
147 from lava_dispatcher.android_client import LavaAndroidClient
148+from lava_dispatcher.qemu_client import LavaQEMUClient
149+from lava_dispatcher.ssh_client import LavaSSHClient
150
151 __version__ = "0.1.0"
152
153@@ -36,19 +38,22 @@
154 def __init__(self, job_json):
155 self.job_status = 'pass'
156 self.load_job_data(job_json)
157- self.context = LavaContext(self.target, self.image_type)
158+ self.context = LavaContext(self.target, self.image_type, self.target_type)
159
160 def load_job_data(self, job_json):
161 self.job_data = json.loads(job_json)
162
163 @property
164 def target(self):
165- return self.job_data['target']
166+ return self.job_data.get('target')
167
168 @property
169 def image_type(self):
170- if self.job_data.has_key('image_type'):
171- return self.job_data['image_type']
172+ return self.job_data.get('image_type')
173+
174+ @property
175+ def target_type(self):
176+ return self.job_data.get('target_type')
177
178 def run(self):
179 lava_commands = get_all_cmds()
180@@ -65,19 +70,26 @@
181 metadata['target.hostname'] = self.target
182 self.context.test_data.add_metadata(metadata)
183 action = lava_commands[cmd['command']](self.context)
184+ except_str = ""
185 try:
186 status = 'fail'
187 action.run(**params)
188- except CriticalError, err:
189- raise err
190- except (pexpect.TIMEOUT, GeneralError), err:
191+ except CriticalError as err:
192+ except_str = str(err)
193+ raise
194+ except (pexpect.TIMEOUT, GeneralError) as err:
195+ except_str = str(err)
196 pass
197- except Exception, err:
198+ except Exception as err:
199+ except_str = str(err)
200 raise
201 else:
202 status = 'pass'
203 finally:
204+ err_msg = ""
205+ command = cmd['command']
206 if status == 'fail':
207+<<<<<<< TREE
208 err_msg = "Lava failed at action " + cmd['command'] \
209 + " with error: " + str(err) + "\n"
210 if cmd['command'] == 'lava_test_run':
211@@ -91,6 +103,18 @@
212 err_msg = ""
213 self.context.test_data.add_result(cmd['command'],
214 status, err_msg)
215+=======
216+ err_msg = "Lava failed at action %s with error: %s\n" %\
217+ (command, except_str)
218+ if command == 'lava_test_run':
219+ err_msg += "Lava failed on test: %s" %\
220+ params.get('test_name')
221+ exc_type, exc_value, exc_traceback = sys.exc_info()
222+ err_msg += repr(traceback.format_tb(exc_traceback))
223+ print >> sys.stderr, err_msg
224+ self.context.test_data.add_result(command, status, err_msg)
225+
226+>>>>>>> MERGE-SOURCE
227 except:
228 #Capture all user-defined and non-user-defined critical errors
229 self.context.test_data.job_status='fail'
230@@ -104,11 +128,16 @@
231
232
233 class LavaContext(object):
234- def __init__(self, target, image_type):
235- if image_type != "android":
236+ def __init__(self, target, image_type, target_type):
237+ if image_type == "android":
238+ self._client = LavaAndroidClient(target)
239+ elif target_type == "qemu":
240+ self._client = LavaQEMUClient(target)
241+ elif target_type == "ssh":
242+ self._client = LavaSSHClient(target)
243+ else:
244+ # conmux / serial
245 self._client = LavaClient(target)
246- else:
247- self._client = LavaAndroidClient(target)
248 self.test_data = LavaTestData()
249
250 @property
251@@ -143,8 +172,8 @@
252 self._job_status = status
253
254 def add_result(self, test_case_id, result, message=""):
255- result_data = { 'test_case_id': test_case_id, 'result': result \
256- , 'message': message}
257+ result_data = {'test_case_id': test_case_id, 'result': result, \
258+ 'message': message}
259 self._test_run['test_results'].append(result_data)
260
261 def add_attachment(self, attachment):
262
263=== modified file 'lava_dispatcher/actions/android_basic.py'
264--- lava_dispatcher/actions/android_basic.py 2011-06-27 04:55:08 +0000
265+++ lava_dispatcher/actions/android_basic.py 2011-08-09 14:40:36 +0000
266@@ -21,7 +21,6 @@
267
268 from lava_dispatcher.actions import BaseAndroidAction
269 from lava_dispatcher.client import OperationFailed
270-from lava_dispatcher.android_config import TESTER_STR
271 import time
272 import pexpect
273 import sys
274
275=== modified file 'lava_dispatcher/actions/android_deploy.py'
276--- lava_dispatcher/actions/android_deploy.py 2011-08-04 07:19:53 +0000
277+++ lava_dispatcher/actions/android_deploy.py 2011-08-09 14:40:36 +0000
278@@ -20,7 +20,7 @@
279 # along with this program; if not, see <http://www.gnu.org/licenses>.
280
281 from lava_dispatcher.actions import BaseAction
282-from lava_dispatcher.config import LAVA_IMAGE_TMPDIR, LAVA_IMAGE_URL, MASTER_STR
283+from lava_dispatcher.config import LAVA_IMAGE_TMPDIR, LAVA_IMAGE_URL
284 import os
285 import sys
286 import shutil
287@@ -101,156 +101,88 @@
288
289 def deploy_linaro_android_testboot(self, boottbz2):
290 client = self.client
291- client.run_shell_command(
292- 'mkfs.vfat /dev/disk/by-label/testboot -n testboot',
293- response = MASTER_STR)
294- client.run_shell_command(
295- 'udevadm trigger',
296- response = MASTER_STR)
297- client.run_shell_command(
298- 'mkdir -p /mnt/lava/boot',
299- response = MASTER_STR)
300- client.run_shell_command(
301- 'mount /dev/disk/by-label/testboot /mnt/lava/boot',
302- response = MASTER_STR)
303- client.run_shell_command(
304- 'wget -qO- %s |tar --numeric-owner -C /mnt/lava -xjf -' % boottbz2,
305- response = MASTER_STR)
306+ client.run_cmd_master('mkfs.vfat /dev/disk/by-label/testboot '
307+ '-n testboot')
308+ client.run_cmd_master('udevadm trigger')
309+ client.run_cmd_master('mkdir -p /mnt/lava/boot')
310+ client.run_cmd_master('mount /dev/disk/by-label/testboot '
311+ '/mnt/lava/boot')
312+ client.run_cmd_master('wget -qO- %s |tar --numeric-owner -C /mnt/lava -xjf -' % boottbz2)
313
314 self.recreate_uInitrd()
315
316- client.run_shell_command(
317- 'umount /mnt/lava/boot',
318- response = MASTER_STR)
319+ client.run_cmd_master('umount /mnt/lava/boot')
320
321 def recreate_uInitrd(self):
322 client = self.client
323- client.run_shell_command(
324- 'mkdir -p ~/tmp/',
325- response = MASTER_STR)
326- client.run_shell_command(
327- 'mv /mnt/lava/boot/uInitrd ~/tmp',
328- response = MASTER_STR)
329- client.run_shell_command(
330- 'cd ~/tmp/',
331- response = MASTER_STR)
332-
333- client.run_shell_command(
334- 'dd if=uInitrd of=uInitrd.data ibs=64 skip=1',
335- response = MASTER_STR)
336- client.run_shell_command(
337- 'mv uInitrd.data ramdisk.cpio.gz',
338- response = MASTER_STR)
339- client.run_shell_command(
340- 'gzip -d ramdisk.cpio.gz; cpio -i -F ramdisk.cpio',
341- response = MASTER_STR)
342- client.run_shell_command(
343- 'sed -i "/mount ext4 \/dev\/block\/mmcblk0p3/d" init.rc',
344- response = MASTER_STR)
345- client.run_shell_command(
346- 'sed -i "/mount ext4 \/dev\/block\/mmcblk0p5/d" init.rc',
347- response = MASTER_STR)
348- client.run_shell_command(
349- 'sed -i "s/mmcblk0p2/mmcblk0p5/g" init.rc',
350- response = MASTER_STR)
351- client.run_shell_command(
352- 'sed -i "/export PATH/a \ \ \ \ export PS1 root@linaro: " init.rc',
353- response = MASTER_STR)
354-
355- client.run_shell_command(
356+ client.run_cmd_master('mkdir -p ~/tmp/')
357+ client.run_cmd_master('mv /mnt/lava/boot/uInitrd ~/tmp')
358+ client.run_cmd_master('cd ~/tmp/')
359+
360+ client.run_cmd_master('mv uInitrd.data ramdisk.cpio.gz')
361+ client.run_cmd_master(
362+ 'gzip -d ramdisk.cpio.gz; cpio -i -F ramdisk.cpio')
363+ client.run_cmd_master(
364+ 'sed -i "/mount ext4 \/dev\/block\/mmcblk0p3/d" init.rc')
365+ client.run_cmd_master(
366+ 'sed -i "/mount ext4 \/dev\/block\/mmcblk0p5/d" init.rc')
367+ client.run_cmd_master('sed -i "s/mmcblk0p2/mmcblk0p5/g" init.rc')
368+ client.run_cmd_master(
369+ 'sed -i "/export PATH/a \ \ \ \ export PS1 root@linaro: " init.rc')
370+
371+ client.run_cmd_master(
372 'cpio -i -t -F ramdisk.cpio | cpio -o -H newc | \
373- gzip > ramdisk_new.cpio.gz',
374- response = MASTER_STR)
375+ gzip > ramdisk_new.cpio.gz')
376
377- client.run_shell_command(
378+ client.run_cmd_master(
379 'mkimage -A arm -O linux -T ramdisk -n "Android Ramdisk Image" \
380- -d ramdisk_new.cpio.gz uInitrd',
381- response = MASTER_STR)
382+ -d ramdisk_new.cpio.gz uInitrd')
383
384- client.run_shell_command(
385- 'cd -',
386- response = MASTER_STR)
387- client.run_shell_command(
388- 'mv ~/tmp/uInitrd /mnt/lava/boot/uInitrd',
389- response = MASTER_STR)
390- client.run_shell_command(
391- 'rm -rf ~/tmp',
392- response = MASTER_STR)
393+ client.run_cmd_master('cd -')
394+ client.run_cmd_master('mv ~/tmp/uInitrd /mnt/lava/boot/uInitrd')
395+ client.run_cmd_master('rm -rf ~/tmp')
396
397 def deploy_linaro_android_testrootfs(self, systemtbz2):
398 client = self.client
399- client.run_shell_command(
400- 'mkfs.ext4 -q /dev/disk/by-label/testrootfs -L testrootfs',
401- response = MASTER_STR)
402- client.run_shell_command(
403- 'udevadm trigger',
404- response = MASTER_STR)
405- client.run_shell_command(
406- 'mkdir -p /mnt/lava/system',
407- response = MASTER_STR)
408- client.run_shell_command(
409- 'mount /dev/disk/by-label/testrootfs /mnt/lava/system',
410- response = MASTER_STR)
411+ client.run_cmd_master(
412+ 'mkfs.ext4 -q /dev/disk/by-label/testrootfs -L testrootfs')
413+ client.run_cmd_master('udevadm trigger')
414+ client.run_cmd_master('mkdir -p /mnt/lava/system')
415+ client.run_cmd_master(
416+ 'mount /dev/disk/by-label/testrootfs /mnt/lava/system')
417 client.run_shell_command(
418 'wget -qO- %s |tar --numeric-owner -C /mnt/lava -xjf -' % systemtbz2,
419- response = MASTER_STR, timeout = 600)
420+ client.master_str, 600)
421
422 sed_cmd = "/dev_mount sdcard \/mnt\/sdcard/c dev_mount sdcard /mnt/sdcard 6 " \
423 "/devices/platform/omap/omap_hsmmc.0/mmc_host/mmc0"
424- client.run_shell_command(
425- 'sed -i "%s" /mnt/lava/system/etc/vold.fstab' % sed_cmd,
426- response = MASTER_STR)
427- client.run_shell_command(
428- 'umount /mnt/lava/system',
429- response = MASTER_STR)
430+ client.run_cmd_master(
431+ 'sed -i "%s" /mnt/lava/system/etc/vold.fstab' % sed_cmd)
432+ client.run_cmd_master('umount /mnt/lava/system')
433
434 def purge_linaro_android_sdcard(self):
435 client = self.client
436- client.run_shell_command(
437- 'mkfs.vfat /dev/disk/by-label/sdcard -n sdcard',
438- response = MASTER_STR)
439- client.run_shell_command(
440- 'udevadm trigger',
441- response = MASTER_STR)
442+ client.run_cmd_master('mkfs.vfat /dev/disk/by-label/sdcard -n sdcard')
443+ client.run_cmd_master('udevadm trigger')
444
445 def deploy_linaro_android_system(self, systemtbz2):
446 client = self.client
447- client.run_shell_command(
448- 'mkfs.ext4 -q /dev/disk/by-label/system -L system',
449- response = MASTER_STR)
450- client.run_shell_command(
451- 'udevadm trigger',
452- response = MASTER_STR)
453- client.run_shell_command(
454- 'mkdir -p /mnt/lava/system',
455- response = MASTER_STR)
456- client.run_shell_command(
457- 'mount /dev/disk/by-label/system /mnt/lava/system',
458- response = MASTER_STR)
459+ client.run_cmd_master('mkfs.ext4 -q /dev/disk/by-label/system -L system')
460+ client.run_cmd_master('udevadm trigger')
461+ client.run_cmd_master('mkdir -p /mnt/lava/system')
462+ client.run_cmd_master('mount /dev/disk/by-label/system /mnt/lava/system')
463 client.run_shell_command(
464 'wget -qO- %s |tar --numeric-owner -C /mnt/lava -xjf -' % systemtbz2,
465- response = MASTER_STR, timeout = 600)
466- client.run_shell_command(
467- 'umount /mnt/lava/system',
468- response = MASTER_STR)
469+ client.master_str, 600)
470+ client.run_cmd_master('umount /mnt/lava/system')
471
472 def deploy_linaro_android_data(self, datatbz2):
473 client = self.client
474- client.run_shell_command(
475- 'mkfs.ext4 -q /dev/disk/by-label/data -L data',
476- response = MASTER_STR)
477- client.run_shell_command(
478- 'udevadm trigger',
479- response = MASTER_STR)
480- client.run_shell_command(
481- 'mkdir -p /mnt/lava/data',
482- response = MASTER_STR)
483- client.run_shell_command(
484- 'mount /dev/disk/by-label/data /mnt/lava/data',
485- response = MASTER_STR)
486+ client.run_cmd_master('mkfs.ext4 -q /dev/disk/by-label/data -L data')
487+ client.run_cmd_master('udevadm trigger')
488+ client.run_cmd_master('mkdir -p /mnt/lava/data')
489+ client.run_cmd_master('mount /dev/disk/by-label/data /mnt/lava/data')
490 client.run_shell_command(
491 'wget -qO- %s |tar --numeric-owner -C /mnt/lava -xjf -' % datatbz2,
492- response = MASTER_STR, timeout = 600)
493- client.run_shell_command(
494- 'umount /mnt/lava/data',
495- response = MASTER_STR)
496+ client.master_str, 600)
497+ client.run_cmd_master('umount /mnt/lava/data')
498
499=== modified file 'lava_dispatcher/actions/deploy.py'
500--- lava_dispatcher/actions/deploy.py 2011-08-04 07:19:53 +0000
501+++ lava_dispatcher/actions/deploy.py 2011-08-09 14:40:36 +0000
502@@ -27,7 +27,7 @@
503 from tempfile import mkdtemp
504
505 from lava_dispatcher.actions import BaseAction
506-from lava_dispatcher.config import LAVA_IMAGE_TMPDIR, LAVA_IMAGE_URL, MASTER_STR
507+from lava_dispatcher.config import LAVA_IMAGE_TMPDIR, LAVA_IMAGE_URL
508 from lava_dispatcher.utils import download, download_with_cache
509 from lava_dispatcher.client import CriticalError
510
511@@ -126,9 +126,9 @@
512
513 image_file = os.path.join(tarball_dir, "lava.img")
514 board = client.board
515- cmd = ("sudo linaro-media-create --hwpack-force-yes --dev %s "
516- "--image_file %s --binary %s --hwpack %s --image_size 3G" % (
517- board.type, image_file, rootfs_path, hwpack_path))
518+ cmd = ("sudo linaro-media-create --hwpack-force-yes -dev %s "
519+ "--image_file %s --binary %s --hwpack %s --image_size 3G" %
520+ (board.type, image_file, rootfs_path, hwpack_path))
521 rc, output = getstatusoutput(cmd)
522 if rc:
523 shutil.rmtree(tarball_dir)
524@@ -152,46 +152,25 @@
525 def deploy_linaro_rootfs(self, rootfs):
526 client = self.client
527 print "Deploying linaro image"
528- client.run_shell_command(
529- 'mkfs.ext3 -q /dev/disk/by-label/testrootfs -L testrootfs',
530- response = MASTER_STR)
531- client.run_shell_command(
532- 'udevadm trigger',
533- response = MASTER_STR)
534- client.run_shell_command(
535- 'mkdir -p /mnt/root',
536- response = MASTER_STR)
537- client.run_shell_command(
538- 'mount /dev/disk/by-label/testrootfs /mnt/root',
539- response = MASTER_STR)
540+ client.run_cmd_master(
541+ 'mkfs.ext3 -q /dev/disk/by-label/testrootfs -L testrootfs')
542+ client.run_cmd_master('udevadm trigger')
543+ client.run_cmd_master('mkdir -p /mnt/root')
544+ client.run_cmd_master('mount /dev/disk/by-label/testrootfs /mnt/root')
545 client.run_shell_command(
546 'wget -qO- %s |tar --numeric-owner -C /mnt/root -xzf -' % rootfs,
547- response = MASTER_STR, timeout = 3600)
548- client.run_shell_command(
549- 'echo linaro > /mnt/root/etc/hostname',
550- response = MASTER_STR)
551- client.run_shell_command(
552- 'umount /mnt/root',
553- response = MASTER_STR)
554+ client.master_str, 3600)
555+ client.run_cmd_master('echo linaro > /mnt/root/etc/hostname')
556+ client.run_cmd_master('umount /mnt/root')
557
558 def deploy_linaro_bootfs(self, bootfs):
559 client = self.client
560- client.run_shell_command(
561- 'mkfs.vfat /dev/disk/by-label/testboot -n testboot',
562- response = MASTER_STR)
563- client.run_shell_command(
564- 'udevadm trigger',
565- response = MASTER_STR)
566- client.run_shell_command(
567- 'mkdir -p /mnt/boot',
568- response = MASTER_STR)
569- client.run_shell_command(
570- 'mount /dev/disk/by-label/testboot /mnt/boot',
571- response = MASTER_STR)
572- client.run_shell_command(
573- 'wget -qO- %s |tar --numeric-owner -C /mnt/boot -xzf -' % bootfs,
574- response = MASTER_STR)
575- client.run_shell_command(
576- 'umount /mnt/boot',
577- response = MASTER_STR)
578+ client.run_cmd_master(
579+ 'mkfs.vfat /dev/disk/by-label/testboot -n testboot')
580+ client.run_cmd_master('udevadm trigger')
581+ client.run_cmd_master('mkdir -p /mnt/boot')
582+ client.run_cmd_master('mount /dev/disk/by-label/testboot /mnt/boot')
583+ client.run_cmd_master(
584+ 'wget -qO- %s |tar --numeric-owner -C /mnt/boot -xzf -' % bootfs)
585+ client.run_cmd_master('umount /mnt/boot')
586
587
588=== modified file 'lava_dispatcher/actions/launch_control.py'
589--- lava_dispatcher/actions/launch_control.py 2011-06-27 04:55:08 +0000
590+++ lava_dispatcher/actions/launch_control.py 2011-08-09 14:40:36 +0000
591@@ -22,7 +22,7 @@
592
593 import json
594 from lava_dispatcher.actions import BaseAction
595-from lava_dispatcher.config import LAVA_RESULT_DIR, MASTER_STR, LAVA_SERVER_IP
596+from lava_dispatcher.config import LAVA_RESULT_DIR, LAVA_SERVER_IP
597 import socket
598 from threading import Thread
599 import time
600@@ -84,32 +84,26 @@
601 except:
602 client.boot_master_image()
603
604- client.run_shell_command(
605- 'mkdir -p /mnt/root', response = MASTER_STR)
606- client.run_shell_command(
607- 'mount /dev/disk/by-label/%s /mnt/root' % result_disk,
608- response = MASTER_STR)
609- client.run_shell_command(
610- 'mkdir -p /tmp/%s' % LAVA_RESULT_DIR, response = MASTER_STR)
611- client.run_shell_command(
612+ client.run_cmd_master('mkdir -p /mnt/root')
613+ client.run_cmd_master(
614+ 'mount /dev/disk/by-label/%s /mnt/root' % result_disk)
615+ client.run_cmd_master('mkdir -p /tmp/%s' % LAVA_RESULT_DIR)
616+ client.run_cmd_master(
617 'cp /mnt/root/%s/*.bundle /tmp/%s' % (LAVA_RESULT_DIR,
618- LAVA_RESULT_DIR), response = MASTER_STR)
619- client.run_shell_command('umount /mnt/root', response = MASTER_STR)
620+ LAVA_RESULT_DIR))
621+ client.run_cmd_master('umount /mnt/root')
622
623 #Upload bundle list-bundle.lst
624- client.run_shell_command('cd /tmp/%s' % LAVA_RESULT_DIR,
625- response = MASTER_STR)
626- client.run_shell_command('ls *.bundle > bundle.lst',
627- response = MASTER_STR)
628+ client.run_cmd_master('cd /tmp/%s' % LAVA_RESULT_DIR)
629+ client.run_cmd_master('ls *.bundle > bundle.lst')
630
631 t = ResultUploader()
632 t.start()
633 #XXX: Odd problem where we sometimes get stuck here. This is just
634 # a hacky workaround to see if it's a race
635 time.sleep(60)
636- client.run_shell_command(
637- 'cat bundle.lst |nc %s %d' % (LAVA_SERVER_IP, t.get_port()),
638- response = MASTER_STR)
639+ client.run_cmd_master('cat bundle.lst |nc %s %d' %
640+ (LAVA_SERVER_IP, t.get_port()))
641 t.join()
642
643 bundle_list = t.get_data().strip().splitlines()
644@@ -124,10 +118,9 @@
645 #XXX: Odd problem where we sometimes get stuck here. This is just
646 # a hacky workaround to see if it's a race
647 time.sleep(60)
648- client.run_shell_command(
649+ client.run_cmd_master(
650 'cat /tmp/%s/%s | nc %s %s' % (LAVA_RESULT_DIR, bundle,
651- LAVA_SERVER_IP, t.get_port()),
652- response = MASTER_STR)
653+ LAVA_SERVER_IP, t.get_port()))
654 t.join()
655 content = t.get_data()
656
657
658=== modified file 'lava_dispatcher/actions/lava-test.py'
659--- lava_dispatcher/actions/lava-test.py 2011-08-04 07:19:53 +0000
660+++ lava_dispatcher/actions/lava-test.py 2011-08-09 14:40:36 +0000
661@@ -25,7 +25,7 @@
662 import traceback
663 from lava_dispatcher.actions import BaseAction
664 from lava_dispatcher.client import OperationFailed
665-from lava_dispatcher.config import LAVA_RESULT_DIR, MASTER_STR, TESTER_STR
666+from lava_dispatcher.config import LAVA_RESULT_DIR
667
668
669 class cmd_lava_test_run(BaseAction):
670@@ -33,14 +33,13 @@
671 #Make sure in test image now
672 client = self.client
673 client.in_test_shell()
674- client.run_shell_command('mkdir -p %s' % LAVA_RESULT_DIR,
675- response=TESTER_STR)
676+ client.run_cmd_tester('mkdir -p %s' % LAVA_RESULT_DIR)
677 client.export_display()
678 bundle_name = test_name + "-" + datetime.now().strftime("%H%M%S")
679 client.run_shell_command(
680 'lava-test run %s -o %s/%s.bundle' % (
681 test_name, LAVA_RESULT_DIR, bundle_name),
682- response=TESTER_STR, timeout=timeout)
683+ client.tester_str, timeout)
684
685
686 class cmd_lava_test_install(BaseAction):
687@@ -57,65 +56,42 @@
688 client.boot_master_image()
689
690 #install bazaar in tester image
691- client.run_shell_command(
692- 'mkdir -p /mnt/root',
693- response=MASTER_STR)
694- client.run_shell_command(
695- 'mount /dev/disk/by-label/testrootfs /mnt/root',
696- response=MASTER_STR)
697- client.run_shell_command(
698- 'cp -f /mnt/root/etc/resolv.conf /mnt/root/etc/resolv.conf.bak',
699- response=MASTER_STR)
700- client.run_shell_command(
701- 'cp -L /etc/resolv.conf /mnt/root/etc',
702- response=MASTER_STR)
703+ client.run_cmd_master('mkdir -p /mnt/root')
704+ client.run_cmd_master('mount /dev/disk/by-label/testrootfs /mnt/root')
705+ client.run_cmd_master('cp -f /mnt/root/etc/resolv.conf '
706+ '/mnt/root/etc/resolv.conf.bak')
707+ client.run_cmd_master('cp -L /etc/resolv.conf /mnt/root/etc')
708 #eliminate warning: Can not write log, openpty() failed
709 # (/dev/pts not mounted?), does not work
710- client.run_shell_command(
711- 'mount --rbind /dev /mnt/root/dev',
712- response=MASTER_STR)
713- client.run_shell_command(
714- 'chroot /mnt/root apt-get update',
715- response=MASTER_STR)
716+ client.run_cmd_master('mount --rbind /dev /mnt/root/dev')
717+ client.run_cmd_master('chroot /mnt/root apt-get update')
718 #Install necessary packages for build lava-test
719 cmd = ('chroot /mnt/root apt-get -y install bzr usbutils python-apt '
720 'python-setuptools python-simplejson lsb-release')
721 client.run_shell_command(
722 cmd,
723- response=MASTER_STR, timeout=2400)
724- client.run_shell_command(
725- 'chroot /mnt/root bzr branch lp:lava-test',
726- response=MASTER_STR)
727- client.run_shell_command(
728- 'chroot /mnt/root sh -c "cd lava-test && python setup.py install"',
729- response=MASTER_STR)
730+ self.client.master_str, 2400)
731+ client.run_cmd_master('chroot /mnt/root bzr branch lp:lava-test')
732+ client.run_cmd_master('chroot /mnt/root sh -c '
733+ '"cd lava-test && python setup.py install"')
734
735 #Test if lava-test installed
736 try:
737 client.run_shell_command(
738 'chroot /mnt/root lava-test help',
739- response="list-tests", timeout=10)
740+ "list-tests", 10)
741 except:
742 tb = traceback.format_exc()
743 client.sio.write(tb)
744 raise OperationFailed("lava-test deployment failed")
745
746 for test in tests:
747- client.run_shell_command(
748- 'chroot /mnt/root lava-test install %s' % test,
749- response=MASTER_STR)
750+ client.run_cmd_master('chroot /mnt/root lava-test install %s' % test)
751 #clean up
752- client.run_shell_command(
753- 'cp -f /mnt/root/etc/resolv.conf.bak /mnt/root/etc/resolv.conf',
754- response=MASTER_STR)
755- client.run_shell_command(
756- 'rm -rf /mnt/root/lava-test',
757- response=MASTER_STR)
758+ client.run_cmd_master('cp -f /mnt/root/etc/resolv.conf.bak '
759+ '/mnt/root/etc/resolv.conf')
760+ client.run_cmd_master('rm -rf /mnt/root/lava-test')
761 cmd = ('cat /proc/mounts | awk \'{print $2}\' | grep "^/mnt/root/dev"'
762 '| sort -r | xargs umount')
763- client.run_shell_command(
764- cmd,
765- response=MASTER_STR)
766- client.run_shell_command(
767- 'umount /mnt/root',
768- response=MASTER_STR)
769+ client.run_cmd_master(cmd)
770+ client.run_cmd_master('umount /mnt/root')
771
772=== modified file 'lava_dispatcher/android_client.py'
773--- lava_dispatcher/android_client.py 2011-07-20 04:45:23 +0000
774+++ lava_dispatcher/android_client.py 2011-08-09 14:40:36 +0000
775@@ -42,7 +42,7 @@
776 """ Check that we are in a shell on the test image
777 """
778 self.proc.sendline("")
779- id = self.proc.expect([TESTER_STR , pexpect.TIMEOUT])
780+ id = self.proc.expect([self.tester_str , pexpect.TIMEOUT])
781 if id == 1:
782 raise OperationFailed
783
784@@ -109,7 +109,7 @@
785 network_interface = self.board.network_interface
786 try:
787 self.run_shell_command('netcfg %s dhcp' % \
788- network_interface, response = TESTER_STR, timeout = 60)
789+ network_interface, self.tester_str, 60)
790 except:
791 print "netcfg %s dhcp exception" % network_interface
792 return False
793@@ -120,7 +120,7 @@
794 self.proc.sendline('')
795 self.proc.sendline(cmd)
796 try:
797- id = self.proc.expect([ip_pattern, pexpect.EOF], timeout = 60)
798+ id = self.proc.expect([ip_pattern, pexpect.EOF], timeout=60)
799 except:
800 print "ifconfig can not match ip pattern"
801 return False
802
803=== modified file 'lava_dispatcher/client.py'
804--- lava_dispatcher/client.py 2011-07-21 16:47:16 +0000
805+++ lava_dispatcher/client.py 2011-08-09 14:40:36 +0000
806@@ -33,6 +33,8 @@
807
808 class LavaClient(object):
809 def __init__(self, hostname):
810+ self._master_str = MASTER_STR
811+ self._tester_str = TESTER_STR
812 cmd = "conmux-console %s" % hostname
813 self.sio = SerialIO(sys.stdout)
814 self.proc = pexpect.spawn(cmd, timeout=3600, logfile=self.sio)
815@@ -42,11 +44,19 @@
816 # will eventually come from the database
817 self.board = BOARDS[hostname]
818
819+ @property
820+ def master_str(self):
821+ return self._master_str
822+
823+ @property
824+ def tester_str(self):
825+ return self._tester_str
826+
827 def in_master_shell(self):
828 """ Check that we are in a shell on the master image
829 """
830 self.proc.sendline("")
831- id = self.proc.expect([MASTER_STR, pexpect.TIMEOUT])
832+ id = self.proc.expect([self.master_str, pexpect.TIMEOUT])
833 if id == 1:
834 raise OperationFailed
835
836@@ -54,7 +64,7 @@
837 """ Check that we are in a shell on the test image
838 """
839 self.proc.sendline("")
840- id = self.proc.expect([TESTER_STR, pexpect.TIMEOUT])
841+ id = self.proc.expect([self.tester_str, pexpect.TIMEOUT])
842 if id == 1:
843 raise OperationFailed
844
845@@ -109,11 +119,17 @@
846 if response:
847 self.proc.expect(response, timeout=timeout)
848
849+ def run_cmd_master(self, cmd):
850+ self.run_shell_command(cmd, self.master_str)
851+
852+ def run_cmd_tester(self, cmd):
853+ self.run_shell_command(cmd, self.tester_str)
854+
855 def check_network_up(self):
856 self.proc.sendline("LC_ALL=C ping -W4 -c1 %s" % LAVA_SERVER_IP)
857 id = self.proc.expect(["1 received", "0 received",
858 "Network is unreachable"], timeout=5)
859- self.proc.expect(MASTER_STR)
860+ self.proc.expect(self.master_str)
861 if id == 0:
862 return True
863 else:
864@@ -128,14 +144,12 @@
865
866 def export_display(self):
867 #export the display, ignore errors on non-graphical images
868- self.run_shell_command("su - linaro -c 'DISPLAY=:0 xhost local:'",
869- response=TESTER_STR)
870- self.run_shell_command("export DISPLAY=:0", response=TESTER_STR)
871+ self.run_cmd_tester("su - linaro -c 'DISPLAY=:0 xhost local:'")
872+ self.run_cmd_tester("export DISPLAY=:0")
873
874 def get_seriallog(self):
875 return self.sio.getvalue()
876
877-
878 class SerialIO(file):
879 def __init__(self, logfile):
880 self.serialio = StringIO()
881
882=== modified file 'lava_dispatcher/config.py'
883--- lava_dispatcher/config.py 2011-07-21 16:47:16 +0000
884+++ lava_dispatcher/config.py 2011-08-09 14:40:36 +0000
885@@ -18,6 +18,16 @@
886 # along
887 # with this program; if not, see <http://www.gnu.org/licenses>.
888
889+import json
890+import os
891+
892+def get_host(hostname):
893+ cfg_path = 'config/hosts/'
894+ cfg_file = cfg_path + hostname + '.json'
895+ host_file = os.path.join(os.curdir, cfg_file)
896+ with open(host_file, 'r') as fp:
897+ return json.load(fp)
898+
899 """
900 This is an ugly hack, the uboot commands for a given board type and the board
901 type of a test machine need to come from the device registry. This is an
902
903=== added file 'lava_dispatcher/qemu_client.py'
904--- lava_dispatcher/qemu_client.py 1970-01-01 00:00:00 +0000
905+++ lava_dispatcher/qemu_client.py 2011-08-09 14:40:36 +0000
906@@ -0,0 +1,135 @@
907+# Copyright (C) 2011 Calxeda, Inc.
908+#
909+# This file is part of LAVA Dispatcher.
910+#
911+# LAVA Dispatcher is free software; you can redistribute it and/or modify
912+# it under the terms of the GNU General Public License as published by
913+# the Free Software Foundation; either version 2 of the License, or
914+# (at your option) any later version.
915+#
916+# LAVA Dispatcher is distributed in the hope that it will be useful,
917+# but WITHOUT ANY WARRANTY; without even the implied warranty of
918+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
919+# GNU General Public License for more details.
920+#
921+# You should have received a copy of the GNU General Public License
922+# along with this program; if not, see <http://www.gnu.org/licenses>.
923+
924+import pexpect
925+import sys
926+from lava_dispatcher.config import get_host
927+from lava_dispatcher.client import LavaClient, SerialIO
928+from lava_dispatcher.qemu_config import QEMU_PATH, MASTER_STR, TESTER_STR
929+
930+
931+class LavaQEMUClient(LavaClient):
932+
933+ def __init__(self, hostname):
934+ self.sio = SerialIO(sys.stdout)
935+ self.hostname = hostname
936+ self.host_config = get_host(hostname)
937+
938+ self.start_qemu()
939+
940+ # Should U-Boot automatically to master image
941+ self.proc.expect("Starting kernel")
942+
943+ # will eventually come from the database
944+ self.board = self.board_type
945+ self._master_str = MASTER_STR
946+ self._tester_str = TESTER_STR
947+ self.in_master_shell()
948+
949+ @property
950+ def macaddr(self):
951+ return self.host_config.get('qemu_macaddr')
952+
953+ @property
954+ def disk(self):
955+ return self.host_config.get('qemu_disk')
956+
957+ @property
958+ def board_type(self):
959+ return self.host_config.get('board_type')
960+
961+ @property
962+ def vlan_number(self):
963+ return self.host_config.get('vlan_number')
964+
965+ @property
966+ def boot_image(self):
967+ return self.host_config.get('boot_image')
968+
969+ @property
970+ def machine_type(self):
971+ return self.host_config.get('machine_type')
972+
973+ @property
974+ def additional_options(self):
975+ return self.host_config.get('additional_options')
976+
977+ @property
978+ def network_arguments(self):
979+ if(self.vlan_number is not None and
980+ self.macaddr is not None):
981+ return ("-net nic,vlan=%d,macaddr=%s -net vde,vlan=%d " %
982+ (self.vlan_number, self.macaddr, self.vlan_number))
983+ else:
984+ return ""
985+
986+ @property
987+ def disk_arguments(self):
988+ if(self.disk is not None):
989+ return ('-drive id=disk,if=ide,file=%s '
990+ '-device ide-drive,drive=disk,bus=ide.0' % self.disk)
991+ else:
992+ return ""
993+
994+ def start_qemu(self):
995+ cmd = ("%sqemu-system-arm %s -M %s -kernel %s " %
996+ (QEMU_PATH, self.additional_options, self.machine_type,
997+ self.boot_image))
998+ cmd += self.network_arguments
999+ cmd += self.disk_arguments
1000+
1001+ print "Starting QEMU:\n\t%s\n\n" % cmd
1002+ self.proc = pexpect.spawn(cmd, timeout=7200, logfile=self.sio)
1003+ self.proc.delaybeforesend=1
1004+
1005+ def boot_master_image(self):
1006+ """ reboot the system, and check that we are in a master shell
1007+ """
1008+ self.hard_reboot()
1009+ try:
1010+ # Necessary to get past U-Boot
1011+ self.proc.expect("Starting kernel")
1012+ self.in_master_shell()
1013+ except:
1014+ raise
1015+
1016+ def boot_linaro_image(self):
1017+ """ Reboot the system to the test image
1018+ """
1019+ self.hard_reboot()
1020+ self.enter_uboot()
1021+ uboot_cmds = self.board.uboot_cmds
1022+ self.proc.sendline(uboot_cmds[0])
1023+ for cmd in uboot_cmd[1:]:
1024+ if self.board.type in ["mx51evk", "mx53loco"]:
1025+ self.proc.expect(">")
1026+ else:
1027+ self.proc.expect("#")
1028+ self.proc.sendline(cmd)
1029+ self.in_test_shell()
1030+
1031+ def soft_reboot(self):
1032+ # Assume soft reboot will not work
1033+ pass
1034+
1035+ def hard_reboot(self):
1036+ self.proc.sendline("reboot")
1037+ self.proc.expect([pexpect.TIMEOUT], timeout=60)
1038+ self.proc.sendcontrol('a')
1039+ self.proc.send('x')
1040+ self.start_qemu()
1041+
1042
1043=== added file 'lava_dispatcher/qemu_config.py'
1044--- lava_dispatcher/qemu_config.py 1970-01-01 00:00:00 +0000
1045+++ lava_dispatcher/qemu_config.py 2011-08-09 14:40:36 +0000
1046@@ -0,0 +1,20 @@
1047+# Copyright (C) 2011 Calxeda, Inc.
1048+#
1049+# This file is part of LAVA Dispatcher.
1050+#
1051+# LAVA Dispatcher is free software; you can redistribute it and/or modify
1052+# it under the terms of the GNU General Public License as published by
1053+# the Free Software Foundation; either version 2 of the License, or
1054+# (at your option) any later version.
1055+#
1056+# LAVA Dispatcher is distributed in the hope that it will be useful,
1057+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1058+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1059+# GNU General Public License for more details.
1060+#
1061+# You should have received a copy of the GNU General Public License
1062+# along with this program; if not, see <http://www.gnu.org/licenses>.
1063+
1064+from lava_dispatcher.config import MASTER_STR, TESTER_STR
1065+
1066+QEMU_PATH = ""
1067
1068=== added file 'lava_dispatcher/ssh_client.py'
1069--- lava_dispatcher/ssh_client.py 1970-01-01 00:00:00 +0000
1070+++ lava_dispatcher/ssh_client.py 2011-08-09 14:40:36 +0000
1071@@ -0,0 +1,75 @@
1072+# Copyright (C) 2011 Calxeda, Inc.
1073+#
1074+# This file is part of LAVA Dispatcher.
1075+#
1076+# LAVA Dispatcher is free software; you can redistribute it and/or modify
1077+# it under the terms of the GNU General Public License as published by
1078+# the Free Software Foundation; either version 2 of the License, or
1079+# (at your option) any later version.
1080+#
1081+# LAVA Dispatcher is distributed in the hope that it will be useful,
1082+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1083+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1084+# GNU General Public License for more details.
1085+#
1086+# You should have received a copy of the GNU General Public License
1087+# along with this program; if not, see <http://www.gnu.org/licenses>.
1088+
1089+import pexpect
1090+import sys
1091+from lava_dispatcher.client import LavaClient, SerialIO
1092+from lava_dispatcher.config import get_host
1093+import pxssh
1094+
1095+
1096+class LavaSSHClient(LavaClient):
1097+
1098+ def __init__(self, hostname):
1099+ self.sio = SerialIO(sys.stdout)
1100+ self.host_config = get_host(hostname)
1101+ try:
1102+ self.proc = pxssh.pxssh(logfile=self.sio)
1103+ self.proc.login(hostname, self.username, self.password)
1104+ self.proc.prompt()
1105+ except pxssh.ExceptionPxssh:
1106+ raise OperationFailed()
1107+
1108+ @property
1109+ def username(self):
1110+ return self.host_config['username']
1111+
1112+ @property
1113+ def password(self):
1114+ return self.host_config['password']
1115+
1116+ @property
1117+ def master_str(self):
1118+ return self.proc.PROMPT
1119+
1120+ @property
1121+ def tester_str(self):
1122+ return self.proc.PROMPT
1123+
1124+ def soft_reboot(self):
1125+ self.run_shell_command('reboot', sudo=True)
1126+
1127+ def hard_reboot(self):
1128+ """ No way to hard reboot through ssh """
1129+ msg = "hard_reboot is not supported by LavaSSHClient"
1130+ raise OperationFailed(msg)
1131+
1132+ def simple_command(self, cmd, timeout=5):
1133+ self.run_shell_command(cmd, timeout=timeout)
1134+
1135+ def run_shell_command(self, cmd, response=None, timeout=-1, sudo=False):
1136+ expectations = [pexpect.TIMEOUT if not response else response]
1137+ if sudo:
1138+ cmd = 'sudo ' + cmd
1139+ pw_req = "password for %s:" % self.get_username()
1140+ expectations.append(pw_req)
1141+
1142+ self.proc.sendline(cmd)
1143+ i = self.proc.expect(expectations, timeout=timeout)
1144+ if i != 0: # pexpect matched pw_req
1145+ self.proc.sendline(self.get_password())
1146+ self.proc.expect(expecting[:-1], timeout=timeout)
1147
1148=== added file 'lava_dispatcher/ssh_config.py'
1149--- lava_dispatcher/ssh_config.py 1970-01-01 00:00:00 +0000
1150+++ lava_dispatcher/ssh_config.py 2011-08-09 14:40:36 +0000
1151@@ -0,0 +1,18 @@
1152+# Copyright (C) 2011 Calxeda, Inc.
1153+#
1154+# This file is part of LAVA Dispatcher.
1155+#
1156+# LAVA Dispatcher is free software; you can redistribute it and/or modify
1157+# it under the terms of the GNU General Public License as published by
1158+# the Free Software Foundation; either version 2 of the License, or
1159+# (at your option) any later version.
1160+#
1161+# LAVA Dispatcher is distributed in the hope that it will be useful,
1162+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1163+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1164+# GNU General Public License for more details.
1165+#
1166+# You should have received a copy of the GNU General Public License
1167+# along with this program; if not, see <http://www.gnu.org/licenses>.
1168+
1169+CFG_PATH = 'config/hosts/'

Subscribers

People subscribed via source and target branches