def run(self, connection, args=None): if connection: self.logger.debug("Already connected") return connection signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command params = self._check_params() if self.valid: self.command = ['ssh'] self.command.extend(params['options']) command = self.command[:] # local copy for idempotency command.extend(['-i', self.identity_file]) if self.host: command.append("%s@%s" % (self.ssh_user, self.host)) else: # get from the protocol pass command_str = " ".join(str(item) for item in command) # use device data for destination self.logger.info("%s Connecting to device %s using '%s'", self.name, self.host, command_str) shell = ShellCommand("%s\n" % command_str, self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.command, shell.exitstatus, shell.readlines())) # SshSession monitors the pexpect connection = SShSession(self.job, shell) connection = super(ConnectSsh, self).run(connection, args) connection.prompt_str = self.job.device['test_image_prompts'] connection.connected = True self.wait(connection) self.data["boot-result"] = 'success' return 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): """ 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): """ 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 finalise_protocol(self, device=None): """Called by Finalize action to power down and clean up the assigned device. """ # Reboot devices that have adb serial number. if 'adb_serial_number' in device: reboot_cmd = "lxc-attach -n {0} -- adb reboot bootloader".format( self.lxc_name) self.logger.debug("%s protocol: executing '%s'", self.name, reboot_cmd) shell = ShellCommand("%s\n" % reboot_cmd, self.system_timeout, logger=self.logger) # execute the command. shell.expect(pexpect.EOF) if shell.exitstatus: self.logger.debug("%s command exited %d: %s", reboot_cmd, shell.exitstatus, shell.readlines()) # ShellCommand executes the destroy command cmd = "lxc-destroy -n {0} -f".format(self.lxc_name) self.logger.debug("%s protocol: executing '%s'", self.name, cmd) shell = ShellCommand("%s\n" % cmd, self.system_timeout, logger=self.logger) # execute the command. shell.expect(pexpect.EOF) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (cmd, shell.exitstatus, shell.readlines())) self.logger.debug("%s protocol finalised.", self.name)
def run(self, connection, args=None): if connection: self.logger.debug("Already connected") return connection signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command params = self._check_params() if self.valid: self.command = ['ssh'] self.command.extend(params['options']) command = self.command[:] # local copy for idempotency command.extend(['-i', self.identity_file]) if self.host: command.append("%s@%s" % (self.ssh_user, self.host)) else: # get from the protocol pass command_str = " ".join(str(item) for item in command) # use device data for destination self.logger.info("%s Connecting to device %s using '%s'", self.name, self.host, command_str) shell = ShellCommand("%s\n" % command_str, self.timeout) if shell.exitstatus: raise JobError("%s command exited %d: %s" % ( self.command, shell.exitstatus, shell.readlines())) # SshSession monitors the pexpect connection = SShSession(self.job, shell) connection = super(ConnectSsh, self).run(connection, args) connection.prompt_str = self.job.device['test_image_prompts'] connection.connected = True self.wait(connection) self.data["boot-result"] = 'success' return 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 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 finalise_protocol(self): # ShellCommand executes the destroy command cmd = "lxc-destroy -n {0} -f".format(self.lxc_name) self.logger.debug("%s protocol: executing '%s'", self.name, cmd) shell = ShellCommand("%s\n" % cmd, self.system_timeout, logger=self.logger) # execute the command. shell.expect(pexpect.EOF) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (cmd, shell.exitstatus, shell.readlines())) self.logger.debug("%s protocol finalised." % self.name)
def run(self, connection, args=None): if connection: self.logger.debug("Already connected") return connection signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command params = self._check_params() command = self.command[:] # local copy for idempotency overrides = self.get_common_data("prepare-scp-overlay", self.key) host_address = None if overrides: host_address = str( self.get_common_data("prepare-scp-overlay", overrides[0])) if host_address: self.logger.info( "Using common data to retrieve host_address for secondary connection." ) command_str = " ".join(str(item) for item in command) self.logger.info("%s Connecting to device %s using '%s'", self.name, host_address, command_str) command.append("%s@%s" % (self.ssh_user, host_address)) elif self.host and self.primary: self.logger.info( "Using device data host_address for primary connection.") command_str = " ".join(str(item) for item in command) self.logger.info("%s Connecting to device %s using '%s'", self.name, self.host, command_str) command.append("%s@%s" % (self.ssh_user, self.host)) else: raise JobError("Unable to identify host address. Primary? %s", self.primary) command_str = " ".join(str(item) for item in command) shell = ShellCommand("%s\n" % command_str, self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % (self.command, shell.exitstatus, shell.readlines())) # SshSession monitors the pexpect connection = SShSession(self.job, shell) connection = super(ConnectSsh, self).run(connection, args) connection.sendline('export PS1="%s"' % DEFAULT_SHELL_PROMPT) connection.prompt_str = [DEFAULT_SHELL_PROMPT] connection.connected = True self.wait(connection) self.data["boot-result"] = 'failed' if self.errors else 'success' 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. 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 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 finalise_protocol(self, device=None): """Called by Finalize action to power down and clean up the assigned device. """ # shutdown xnbd for the given device/job based in the port-number used try: self.logger.debug("%s cleanup", self.name) self.port = self.parameters['protocols']['lava-xnbd']['port'] nbd_cmd = "pkill -f xnbd-server.*%s" % (self.port) shell = ShellCommand("%s\n" % nbd_cmd, self.system_timeout, logger=self.logger) shell.expect(pexpect.EOF) except Exception as e: self.logger.debug(str(e)) self.logger.debug( "xnbd-finalize-protocol failed, but continuing anyway.")
def run(self, connection, max_end_time, args=None): if connection: self.logger.debug("Already connected") return connection # ShellCommand executes the connection command params = self._check_params() command = self.command[:] # local copy for idempotency overrides = None if self.key: overrides = self.get_namespace_data(action='prepare-scp-overlay', label="prepare-scp-overlay", key=self.key) host_address = None if overrides: host_address = str(self.get_namespace_data( action='prepare-scp-overlay', label="prepare-scp-overlay", key=overrides[0])) if host_address: self.logger.info("Using common data to retrieve host_address for secondary connection.") command_str = " ".join(str(item) for item in command) self.logger.info("%s Connecting to device %s using '%s'", self.name, host_address, command_str) command.append("%s@%s" % (self.ssh_user, host_address)) elif self.host and self.primary: self.logger.info("Using device data host_address for primary connection.") command_str = " ".join(str(item) for item in command) self.logger.info("%s Connecting to device %s using '%s'", self.name, self.host, command_str) command.append("%s@%s" % (self.ssh_user, self.host)) else: raise JobError("Unable to identify host address. Primary? %s", self.primary) command_str = " ".join(str(item) for item in command) shell = ShellCommand("%s\n" % command_str, self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % ( self.command, shell.exitstatus, shell.readlines())) # SshSession monitors the pexpect connection = SShSession(self.job, shell) connection = super(ConnectSsh, self).run(connection, max_end_time, args) connection.sendline('export PS1="%s"' % self.job.device.get_constant( 'default-shell-prompt')) connection.prompt_str = [self.job.device.get_constant( 'default-shell-prompt')] connection.connected = True self.wait(connection) res = 'failed' if self.errors else 'success' self.set_namespace_data(action='boot', label='shared', key='boot-result', value=res) self.set_namespace_data(action='shared', label='shared', key='connection', value=connection) return connection
def run(self, connection, args=None): if connection: self.logger.debug("Already connected") return connection signal.alarm(0) # clear the timeouts used without connections. # ShellCommand executes the connection command params = self._check_params() if self.valid: self.command = ['ssh'] self.command.extend(params['options']) command = self.command[:] # local copy for idempotency command.extend(['-i', self.identity_file]) overrides = self.get_common_data("prepare-scp-overlay", self.key) host_address = None if overrides: host_address = str(self.get_common_data("prepare-scp-overlay", overrides[0])) if host_address: self.logger.info("Using common data to retrieve host_address for secondary connection.") command_str = " ".join(str(item) for item in command) self.logger.info("%s Connecting to device %s using '%s'", self.name, host_address, command_str) command.append("%s@%s" % (self.ssh_user, host_address)) elif self.host and self.primary: self.logger.info("Using device data host_address for primary connection.") command_str = " ".join(str(item) for item in command) self.logger.info("%s Connecting to device %s using '%s'", self.name, self.host, command_str) command.append("%s@%s" % (self.ssh_user, self.host)) else: raise JobError("Unable to identify host address. Primary? %s", self.primary) command_str = " ".join(str(item) for item in command) shell = ShellCommand("%s\n" % command_str, self.timeout, logger=self.logger) if shell.exitstatus: raise JobError("%s command exited %d: %s" % ( self.command, shell.exitstatus, shell.readlines())) # SshSession monitors the pexpect connection = SShSession(self.job, shell) connection = super(ConnectSsh, self).run(connection, args) connection.sendline('export PS1="%s"' % DEFAULT_SHELL_PROMPT) connection.prompt_str = [DEFAULT_SHELL_PROMPT] connection.connected = True self.wait(connection) 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.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): 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, 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): 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") # 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: 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): telnet = ShellCommand(self.job.device.parameters['connection_command'], self.timeout) return Connection(self.job.device, telnet)
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
def finalise_protocol(self, device=None): """Called by Finalize action to power down and clean up the assigned device. """ # Reboot devices to bootloader if required, based on the availability # of power cycle option and adb_serial_number. # Do not reboot to bootloader if 'reboot_to_fastboot' is set to # 'false' in job definition. if self.fastboot_reboot: if 'adb_serial_number' in device and hasattr(device, 'power_state'): if device.power_state not in ['on', 'off']: reboot_cmd = "lxc-attach -n {0} -- adb reboot bootloader".format(self.lxc_name) self.logger.debug("%s protocol: executing '%s'", self.name, reboot_cmd) shell = ShellCommand("%s\n" % reboot_cmd, self.system_timeout, logger=self.logger) # execute the command. shell.expect(pexpect.EOF) if shell.exitstatus: self.logger.debug("%s command exited %d: %s", reboot_cmd, shell.exitstatus, shell.readlines()) else: self.logger.info("%s protocol: device not rebooting to fastboot", self.name) # Stop the container. self.logger.debug("%s protocol: issue stop", self.name) cmd = "lxc-stop -n {0} -k".format(self.lxc_name) shell = ShellCommand("%s\n" % cmd, self.system_timeout, logger=self.logger) # execute the command. shell.expect(pexpect.EOF) if shell.exitstatus: self.logger.debug( "%s command exited %d: %s" % (cmd, shell.exitstatus, shell.readlines())) # Check if the container should persist and skip destroying it. if self.persistence: self.logger.debug("%s protocol: persistence requested", self.name) else: self.logger.debug("%s protocol: destroy", self.name) if self.custom_lxc_path: abs_path = os.path.realpath(os.path.join(LXC_PATH, self.lxc_name)) cmd = "lxc-destroy -n {0} -f -P {1}".format( self.lxc_name, os.path.dirname(abs_path)) else: cmd = "lxc-destroy -n {0} -f".format(self.lxc_name) self.logger.debug("%s protocol: executing '%s'", self.name, cmd) shell = ShellCommand("%s\n" % cmd, self.system_timeout, logger=self.logger) # execute the command. shell.expect(pexpect.EOF) if shell.exitstatus: self.logger.debug( "%s command exited %d: %s" % (cmd, shell.exitstatus, shell.readlines())) if self.custom_lxc_path and not self.persistence: os.remove(os.path.join(LXC_PATH, self.lxc_name)) self.logger.debug("%s protocol finalised.", self.name)