def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ if 'download_action' not in self.data: raise RuntimeError("Value for download_action is missing from %s" % self.name) if 'image' not in self.data['download_action']: raise RuntimeError("No image file setting from the download_action") command = self.get_common_data('qemu-command', 'command') command.extend(["-hda", self.data['download_action']['image']['file']]) self.logger.info("Boot command: %s" % ' '.join(command)) # initialise the first Connection object, a command line shell into the running QEMU. shell = ShellCommand(' '.join(command), self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) shell_connection.prompt_str = self.job.device['test_image_prompts'] shell_connection = super(CallQemuAction, self).run(shell_connection, args) # FIXME: tests with multiple boots need to be handled too. self.data['boot-result'] = 'failed' if self.errors else 'success' return shell_connection
def run(self, connection, args=None): """ qemu needs help to reboot after running the debian installer and typically the boot is quiet, so there is almost nothing to log. """ base_image = self.get_common_data('prepare-empty-image', 'output') self.sub_command.append('-drive format=raw,file=%s' % base_image) guest = self.get_common_data('guest', 'filename') if guest: self.logger.info("Extending command line for qcow2 test overlay") self.sub_command.append('-drive format=qcow2,file=%s,media=disk' % (os.path.realpath(guest))) # push the mount operation to the test shell pre-command to be run # before the test shell tries to execute. shell_precommand_list = [] mountpoint = self.data['lava_test_results_dir'] shell_precommand_list.append('mkdir %s' % mountpoint) shell_precommand_list.append('mount -L LAVA %s' % mountpoint) self.set_common_data('lava-test-shell', 'pre-command-list', shell_precommand_list) self.logger.info("Boot command: %s", ' '.join(self.sub_command)) shell = ShellCommand(' '.join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) shell_connection = super(IsoRebootAction, self).run(shell_connection, args) shell_connection.prompt_str = [INSTALLER_QUIET_MSG] self.wait(shell_connection) self.data['boot-result'] = 'failed' if self.errors else 'success' self.logger.debug("boot-result: %s", self.data['boot-result']) return shell_connection
def run(self, connection, args=None): # substitutions substitutions = {'{emptyimage}': self.get_common_data('prepare-empty-image', 'output')} sub_command = self.get_common_data('prepare-qemu-commands', 'sub_command') sub_command = substitute(sub_command, substitutions) command_line = ' '.join(sub_command) commands = [] # get the download args in run() image_arg = self.data['download_action']['iso'].get('image_arg', None) action_arg = self.data['download_action']['iso'].get('file', None) substitutions["{%s}" % 'iso'] = action_arg commands.append(image_arg) command_line += ' '.join(substitute(commands, substitutions)) preseed_file = self.get_common_data('file', 'preseed') if not preseed_file: raise JobError("Unable to identify downloaded preseed filename.") substitutions = {'{preseed}': preseed_file} append_args = self.get_common_data('prepare-qemu-commands', 'append') append_args = substitute([append_args], substitutions) command_line += ' '.join(append_args) self.logger.info(command_line) shell = ShellCommand(command_line, self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (sub_command[0], shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) shell_connection.prompt_str = self.get_common_data('prepare-qemu-commands', 'prompts') shell_connection = super(IsoCommandLine, self).run(shell_connection, args) return shell_connection
def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ # initialise the first Connection object, a command line shell into the running QEMU. self.logger.info("Boot command: %s", " ".join(self.sub_command)) shell = ShellCommand(" ".join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) if not shell_connection.prompt_str: shell_connection.prompt_str = self.parameters["prompts"] shell_connection = super(CallQemuAction, self).run(shell_connection, args) # FIXME: tests with multiple boots need to be handled too. self.data["boot-result"] = "failed" if self.errors else "success" return shell_connection
def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ # initialise the first Connection object, a command line shell into the running QEMU. self.logger.info("Boot command: %s", ' '.join(self.sub_command)) shell = ShellCommand(' '.join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError( "%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) shell_connection = super(MonitorQemuAction, self).run(shell_connection, args) # FIXME: the shell needs to wait for something # FIXME: tests with multiple boots need to be handled too. self.data['boot-result'] = 'failed' if self.errors else 'success' # FIXME: from here, go into the new test action. return shell_connection
def test_check_char(self): shell = ShellCommand("%s\n" % 'ls', Timeout('fake', 30), logger=logging.getLogger()) if shell.exitstatus: raise JobError("%s command exited %d: %s" % ('ls', shell.exitstatus, shell.readlines())) connection = ShellSession(self.job, shell) self.assertFalse(hasattr(shell, 'check_char')) self.assertTrue(hasattr(connection, 'check_char')) self.assertIsNotNone(connection.check_char)
def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ # initialise the first Connection object, a command line shell into the running QEMU. guest = self.get_common_data('guest', 'filename') if guest: self.logger.info("Extending command line for qcow2 test overlay") # interface is ide by default in qemu interface = self.job.device['actions']['deploy']['methods']['image']['parameters']['guest'].get('interface', 'ide') self.sub_command.append('-drive format=qcow2,file=%s,media=disk,if=%s' % (os.path.realpath(guest), interface)) # push the mount operation to the test shell pre-command to be run # before the test shell tries to execute. shell_precommand_list = [] mountpoint = self.data['lava_test_results_dir'] uuid = '/dev/disk/by-uuid/%s' % self.get_common_data('guest', 'UUID') shell_precommand_list.append('mkdir %s' % mountpoint) # prepare_guestfs always uses ext2 shell_precommand_list.append('mount %s -t ext2 %s' % (uuid, mountpoint)) # debug line to show the effect of the mount operation # also allows time for kernel messages from the mount operation to be processed. shell_precommand_list.append('ls -la %s/bin/lava-test-runner' % mountpoint) self.set_common_data('lava-test-shell', 'pre-command-list', shell_precommand_list) self.logger.info("Boot command: %s", ' '.join(self.sub_command)) shell = ShellCommand(' '.join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) if not shell_connection.prompt_str and self.parameters['method'] == 'qemu': shell_connection.prompt_str = self.parameters['prompts'] shell_connection = super(CallQemuAction, self).run(shell_connection, args) # FIXME: tests with multiple boots need to be handled too. self.data['boot-result'] = 'failed' if self.errors else 'success' return shell_connection
def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ # initialise the first Connection object, a command line shell into the running QEMU. guest = self.get_common_data('guest', 'filename') if guest: self.logger.info("Extending command line for qcow2 test overlay") self.sub_command.append('-drive format=qcow2,file=%s,media=disk' % (os.path.realpath(guest))) # push the mount operation to the test shell pre-command to be run # before the test shell tries to execute. shell_precommand_list = [] mountpoint = self.data['lava_test_results_dir'] shell_precommand_list.append('mkdir %s' % mountpoint) shell_precommand_list.append('mount -L LAVA %s' % mountpoint) self.set_common_data('lava-test-shell', 'pre-command-list', shell_precommand_list) self.logger.info("Boot command: %s", ' '.join(self.sub_command)) shell = ShellCommand(' '.join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError( "%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) if not shell_connection.prompt_str and self.parameters[ 'method'] == 'qemu': shell_connection.prompt_str = self.parameters['prompts'] shell_connection = super(CallQemuAction, self).run(shell_connection, args) # FIXME: tests with multiple boots need to be handled too. self.data['boot-result'] = 'failed' if self.errors else 'success' return shell_connection
def run(self, connection, args=None): if connection: self.logger.debug("Already connected") connection.prompt_str = self.parameters["prompts"] return connection command = self.job.device["commands"]["connect"][:] # local copy to retain idempotency. self.logger.info("%s Connecting to device using '%s'", self.name, command) signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command shell = ShellCommand("%s\n" % command, self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (command, shell.exitstatus, shell.readlines())) # ShellSession monitors the pexpect connection = ShellSession(self.job, shell) connection.connected = True connection = super(ConnectAdb, self).run(connection, args) connection.prompt_str = self.parameters["prompts"] self.data["boot-result"] = "failed" if self.errors else "success" return connection
def run(self, connection, args=None): if connection: self.logger.debug("Already connected") connection.prompt_str = self.job.device['test_image_prompts'] return connection command = self.job.device['commands']['connect'][:] # local copy to retain idempotency. self.logger.info("%s Connecting to device using '%s'", self.name, command) signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command shell = ShellCommand("%s\n" % command, self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (command, shell.exitstatus, shell.readlines())) # ShellSession monitors the pexpect connection = ShellSession(self.job, shell) connection.connected = True connection = super(ConnectDevice, self).run(connection, args) # append ser2net port to the prompt_str # FIXME: this improves speed but relies on using ser2net connection.prompt_str = self.job.device['test_image_prompts'].append('ser2net port') return connection
def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ # initialise the first Connection object, a command line shell into the running QEMU. guest = self.get_common_data('guest', 'filename') if guest: self.logger.info("Extending command line for qcow2 test overlay") self.sub_command.append('-drive format=qcow2,file=%s,media=disk' % (os.path.realpath(guest))) # push the mount operation to the test shell pre-command to be run # before the test shell tries to execute. shell_precommand_list = [] mountpoint = self.data['lava_test_results_dir'] shell_precommand_list.append('mkdir %s' % mountpoint) shell_precommand_list.append('mount -L LAVA %s' % mountpoint) self.set_common_data('lava-test-shell', 'pre-command-list', shell_precommand_list) self.logger.info("Boot command: %s", ' '.join(self.sub_command)) shell = ShellCommand(' '.join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) if not shell_connection.prompt_str: shell_connection.prompt_str = self.parameters['prompts'] shell_connection = super(CallQemuAction, self).run(shell_connection, args) # FIXME: tests with multiple boots need to be handled too. self.data['boot-result'] = 'failed' if self.errors else 'success' return shell_connection
def run(self, connection, args=None): if connection: self.logger.debug("Already connected") connection.prompt_str = self.job.device['test_image_prompts'] return connection command = self.job.device['commands'][ 'connect'][:] # local copy to retain idempotency. self.logger.info("%s Connecting to device using '%s'", self.name, command) signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command shell = ShellCommand("%s\n" % command, self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (command, shell.exitstatus, shell.readlines())) # ShellSession monitors the pexpect connection = ShellSession(self.job, shell) connection.connected = True connection = super(ConnectDevice, self).run(connection, args) # append ser2net port to the prompt_str # FIXME: this improves speed but relies on using ser2net connection.prompt_str = self.job.device['test_image_prompts'].append( 'ser2net port') return connection
def run(self, connection, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ if 'download_action' not in self.data: raise RuntimeError("Value for download_action is missing from %s" % self.name) if 'image' not in self.data['download_action']: raise RuntimeError( "No image file setting from the download_action") command = self.get_common_data('qemu-command', 'command') command.extend(["-hda", self.data['download_action']['image']['file']]) self.logger.info("Boot command: %s" % ' '.join(command)) # initialise the first Connection object, a command line shell into the running QEMU. shell = ShellCommand(' '.join(command), self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) shell_connection.prompt_str = self.job.device['test_image_prompts'] shell_connection = super(CallQemuAction, self).run(shell_connection, args) # FIXME: tests with multiple boots need to be handled too. self.data['boot-result'] = 'failed' if self.errors else 'success' return shell_connection
def run(self, connection, args=None): self._log("Boot command: %s" % ' '.join(self.command)) # initialise the first Connection object, a command line shell into the running QEMU. # ShellCommand wraps pexpect.spawn. shell = ShellCommand(' '.join(self.command), self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.command, shell.exitstatus, shell.readlines())) self._log("started a shell command") # CommandRunner expects a pexpect.spawn connection which is the return value # of target.device.power_on executed by boot in the old dispatcher. # # In the new pipeline, the pexpect.spawn is a ShellCommand and the # connection is a ShellSession. CommandRunner inside the ShellSession # turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() # to run commands issued *after* the device has booted. # pexpect.spawn is one of the raw_connection objects for a Connection class. shell_connection = ShellSession(self.job.device, shell) self.pipeline.run_actions(shell_connection) return shell_connection
def run(self, connection, max_end_time, args=None): """ CommandRunner expects a pexpect.spawn connection which is the return value of target.device.power_on executed by boot in the old dispatcher. In the new pipeline, the pexpect.spawn is a ShellCommand and the connection is a ShellSession. CommandRunner inside the ShellSession turns the ShellCommand into a runner which the ShellSession uses via ShellSession.run() to run commands issued *after* the device has booted. pexpect.spawn is one of the raw_connection objects for a Connection class. """ # initialise the first Connection object, a command line shell into the running QEMU. guest = self.get_namespace_data(action='apply-overlay-guest', label='guest', key='filename') # check for NFS if 'qemu-nfs' in self.methods and self.parameters.get('media', None) == 'nfs': self.logger.debug("Adding NFS arguments to kernel command line.") root_dir = self.get_namespace_data(action='extract-rootfs', label='file', key='nfsroot') self.substitutions["{NFSROOTFS}"] = root_dir params = self.methods['qemu-nfs']['parameters']['append'] # console=ttyAMA0 root=/dev/nfs nfsroot=10.3.2.1:/var/lib/lava/dispatcher/tmp/dirname,tcp,hard,intr ip=dhcp append = [ 'console=%s' % params['console'], 'root=/dev/nfs', '%s rw' % substitute([params['nfsrootargs']], self.substitutions)[0], "%s" % params['ipargs'] ] self.sub_command.append('--append') self.sub_command.append('"%s"' % ' '.join(append)) elif guest: self.logger.info("Extending command line for qcow2 test overlay") # interface is ide by default in qemu interface = self.job.device['actions']['deploy']['methods'][ 'image']['parameters']['guest'].get('interface', 'ide') self.sub_command.append( '-drive format=qcow2,file=%s,media=disk,if=%s' % (os.path.realpath(guest), interface)) # push the mount operation to the test shell pre-command to be run # before the test shell tries to execute. shell_precommand_list = [] mountpoint = self.get_namespace_data(action='test', label='results', key='lava_test_results_dir') uuid = '/dev/disk/by-uuid/%s' % self.get_namespace_data( action='apply-overlay-guest', label='guest', key='UUID') shell_precommand_list.append('mkdir %s' % mountpoint) # prepare_guestfs always uses ext2 shell_precommand_list.append('mount %s -t ext2 %s' % (uuid, mountpoint)) # debug line to show the effect of the mount operation # also allows time for kernel messages from the mount operation to be processed. shell_precommand_list.append('ls -la %s/bin/lava-test-runner' % mountpoint) self.set_namespace_data(action='test', label='lava-test-shell', key='pre-command-list', value=shell_precommand_list) self.logger.info("Boot command: %s", ' '.join(self.sub_command)) shell = ShellCommand(' '.join(self.sub_command), self.timeout, logger=self.logger) if shell.exitstatus: raise JobError( "%s command exited %d: %s" % (self.sub_command, shell.exitstatus, shell.readlines())) self.logger.debug("started a shell command") shell_connection = ShellSession(self.job, shell) shell_connection = super(CallQemuAction, self).run(shell_connection, max_end_time, args) self.set_namespace_data(action='shared', label='shared', key='connection', value=shell_connection) return shell_connection