def test_kernel_2(self): logfile = os.path.join(os.path.dirname(__file__), "kernel-2.txt") self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn("cat", [logfile]) message_list = LinuxKernelMessages.get_kernel_prompts() self.assertIsNotNone(message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[0][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[1][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[2][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[3][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[4][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[5][1], message_list) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures( connection, action=Action(), max_end_time=self.max_end_time, fail_msg="", ) self.assertEqual(len(list(results)), 14) message_list = LinuxKernelMessages.get_init_prompts() child = pexpect.spawn("cat", [logfile]) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures( connection, action=Action(), max_end_time=self.max_end_time, fail_msg="" ) self.assertEqual(len(list(results)), 13)
def test_kernel_4(self): logfile = os.path.join(os.path.dirname(__file__), 'kernel-4.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_init_prompts() self.assertIsNotNone(message_list) connection = FakeConnection(child, message_list) with self.assertRaises(JobError): results = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time)
def test_kernel_4(self): logfile = os.path.join(os.path.dirname(__file__), 'kernel-4.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_init_prompts() self.assertIsNotNone(message_list) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time) self.assertIn('Stack', results[0]['message'].decode('utf-8')) self.assertIn('Kernel panic', results[1]['message'].decode('utf-8'))
def run(self, prompt_list): if KERNEL_FREE_INIT_MSG in prompt_list: index = prompt_list.index(KERNEL_FREE_INIT_MSG) if len(prompt_list) > index: index += 1 self.existing_prompt = prompt_list[index:] else: self.existing_prompt = prompt_list[:] prompt_list = LinuxKernelMessages.get_init_prompts() super().run(prompt_list) return prompt_list
def test_kernel_4(self): logfile = os.path.join(os.path.dirname(__file__), 'kernel-4.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_init_prompts() self.assertIsNotNone(message_list) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures( connection, max_end_time=self.max_end_time) self.assertIn('Stack', results[0]['message'].decode('utf-8')) self.assertIn('Kernel panic', results[1]['message'].decode('utf-8'))
def run(self, prompt_list): if KERNEL_FREE_INIT_MSG in prompt_list: index = prompt_list.index(KERNEL_FREE_INIT_MSG) if len(prompt_list) > index: index += 1 self.existing_prompt = prompt_list[index:] else: self.existing_prompt = prompt_list[:] prompt_list = LinuxKernelMessages.get_init_prompts() super(Child, self).run(prompt_list) return prompt_list
def test_kernel_ramdisk_alert(self): logfile = os.path.join(os.path.dirname(__file__), 'kernel-3.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_init_prompts() self.assertIsNotNone(message_list) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time) self.assertEqual(len(list(results)), 1) self.assertIn('message', results[0]) self.assertIn('alert', results[0]) self.assertNotIn('success', results[0]) self.assertNotIn('panic', results[0])
def test_kernel_ramdisk_alert(self): logfile = os.path.join(os.path.dirname(__file__), 'kernel-3.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_init_prompts() self.assertIsNotNone(message_list) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures( connection, max_end_time=self.max_end_time) self.assertEqual(len(list(results)), 1) self.assertIn('message', results[0]) self.assertIn('alert', results[0]) self.assertNotIn('success', results[0]) self.assertNotIn('panic', results[0])
def test_kernel_2(self): logfile = os.path.join(os.path.dirname(__file__), 'kernel-2.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_kernel_prompts() self.assertIsNotNone(message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[0][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[1][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[2][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[3][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[4][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[5][1], message_list) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time) self.assertEqual(len(list(results)), 14) message_list = LinuxKernelMessages.get_init_prompts() child = pexpect.spawn('cat', [logfile]) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time) self.assertEqual(len(list(results)), 13)
def test_kernel_txt(self): """ The same logfile passes kernel boot and fails to find init - so the panic needs to be caught by InitMessages """ logfile = os.path.join(os.path.dirname(__file__), 'kernel-panic.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_kernel_prompts() self.assertIsNotNone(message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[0][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[1][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[2][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[3][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[4][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[5][1], message_list) connection = FakeConnection(child, message_list) result = LinuxKernelMessages.parse_failures( connection, max_end_time=self.max_end_time) self.assertEqual(len(result), 2) self.assertIn('success', result[0]) self.assertIn('panic', result[1]) self.assertEqual(result[0]['success'], KERNEL_FREE_UNUSED_MSG) self.assertEqual(result[1]['panic'], KERNEL_PANIC_MSG) self.assertEqual(len(result), 2) self.assertIn('panic', result[1]) self.assertIn('message', result[1]) self.assertTrue('Attempted to kill init' in str(result[1]['message'])) self.assertTrue('(unwind_backtrace) from' in str(result[1]['message'])) message_list = LinuxKernelMessages.get_init_prompts() child = pexpect.spawn('cat', [logfile]) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures( connection, max_end_time=self.max_end_time) self.assertEqual(len(results), 1) self.assertIn('panic', result[1]) self.assertIn('message', result[1]) self.assertTrue('Attempted to kill init' in str(result[1]['message'])) self.assertTrue('(unwind_backtrace) from' in str(result[1]['message']))
def test_kernel_txt(self): """ The same logfile passes kernel boot and fails to find init - so the panic needs to be caught by InitMessages """ logfile = os.path.join(os.path.dirname(__file__), 'kernel-panic.txt') self.assertTrue(os.path.exists(logfile)) child = pexpect.spawn('cat', [logfile]) message_list = LinuxKernelMessages.get_kernel_prompts() self.assertIsNotNone(message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[0][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[1][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[2][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[3][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[4][1], message_list) self.assertIn(LinuxKernelMessages.MESSAGE_CHOICES[5][1], message_list) connection = FakeConnection(child, message_list) result = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time) self.assertEqual(len(result), 2) self.assertIn('success', result[0]) self.assertIn('panic', result[1]) self.assertEqual(result[0]['success'], KERNEL_FREE_UNUSED_MSG) self.assertEqual(result[1]['panic'], KERNEL_PANIC_MSG) self.assertEqual(len(result), 2) self.assertIn('panic', result[1]) self.assertIn('message', result[1]) self.assertTrue('Attempted to kill init' in str(result[1]['message'])) self.assertTrue('(unwind_backtrace) from' in str(result[1]['message'])) message_list = LinuxKernelMessages.get_init_prompts() child = pexpect.spawn('cat', [logfile]) connection = FakeConnection(child, message_list) results = LinuxKernelMessages.parse_failures(connection, max_end_time=self.max_end_time) self.assertEqual(len(results), 1) self.assertIn('panic', result[1]) self.assertIn('message', result[1]) self.assertTrue('Attempted to kill init' in str(result[1]['message'])) self.assertTrue('(unwind_backtrace) from' in str(result[1]['message']))
def run(self, connection, max_end_time, args=None): # Prompts commonly include # - when logging such strings, # use lazy logging or the string will not be quoted correctly. if self.booting: kernel_start_message = self.parameters.get( 'parameters', {}).get( 'kernel-start-message', self.job.device.get_constant('kernel-start-message')) if kernel_start_message: connection.prompt_str = [kernel_start_message] if self.params and self.params.get('boot_message', None): self.logger.warning("boot_message is being deprecated in favour of kernel-start-message in constants") connection.prompt_str = [self.params.get('boot_message')] error_messages = self.job.device.get_constant('error-messages', prefix=self.method, missing_ok=True) if error_messages: connection.prompt_str = connection.prompt_str + error_messages res = self.wait(connection) if res != 0: raise InfrastructureError('matched a bootloader error message: %s' % connection.prompt_str[res]) def check_prompt_characters(chk_prompt): if not any([True for c in DISTINCTIVE_PROMPT_CHARACTERS if c in chk_prompt]): self.logger.warning(self.check_prompt_characters_warning, chk_prompt) connection = super(AutoLoginAction, self).run(connection, max_end_time, args) if not connection: return connection prompts = self.parameters.get('prompts', None) for prompt in prompts: check_prompt_characters(prompt) connection.prompt_str = LinuxKernelMessages.get_init_prompts() connection.prompt_str.extend(prompts) # linesep should come from deployment_data as from now on it is OS dependent linesep = self.get_namespace_data( action='deploy-device-env', label='environment', key='line_separator' ) connection.raw_connection.linesep = linesep if linesep else LINE_SEPARATOR self.logger.debug("Using line separator: #%r#", connection.raw_connection.linesep) # Skip auto login if the configuration is not found params = self.parameters.get('auto_login', None) if not params: self.logger.debug("No login prompt set.") self.force_prompt = True # If auto_login is not enabled, login will time out if login # details are requested. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time) if 'success' in self.results: check = self.results['success'] if LOGIN_TIMED_OUT_MSG in check or LOGIN_INCORRECT_MSG in check: raise JobError("auto_login not enabled but image requested login details.") # clear kernel message prompt patterns connection.prompt_str = list(self.parameters.get('prompts', [])) # already matched one of the prompts else: self.logger.info("Waiting for the login prompt") connection.prompt_str.append(params['login_prompt']) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time) if 'success' in self.results: if LOGIN_INCORRECT_MSG in self.results['success']: self.logger.warning("Login incorrect message matched before the login prompt. " "Please check that the login prompt is correct. Retrying login...") self.logger.debug("Sending username %s", params['username']) connection.sendline(params['username'], delay=self.character_delay) # clear the kernel_messages patterns connection.prompt_str = list(self.parameters.get('prompts', [])) if 'password_prompt' in params: self.logger.info("Waiting for password prompt") connection.prompt_str.append(params['password_prompt']) # This can happen if password_prompt is misspelled. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the password prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched prompt #%s: %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: raise JobError("Password prompt not matched, please update the job definition with the correct one.") self.logger.debug("Sending password %s", params['password']) connection.sendline(params['password'], delay=self.character_delay) # clear the Password pattern connection.prompt_str = list(self.parameters.get('prompts', [])) connection.prompt_str.append(LOGIN_INCORRECT_MSG) connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the login process to provide the prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched %s %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_INCORRECT_MSG: self.errors = LOGIN_INCORRECT_MSG raise JobError(LOGIN_INCORRECT_MSG) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: self.errors = LOGIN_TIMED_OUT_MSG raise JobError(LOGIN_TIMED_OUT_MSG) login_commands = params.get('login_commands', None) if login_commands is not None: self.logger.debug("Running login commands") for command in login_commands: connection.sendline(command) connection.prompt_str.extend([self.job.device.get_constant( 'default-shell-prompt')]) self.logger.debug("Setting shell prompt(s) to %s" % connection.prompt_str) # pylint: disable=logging-not-lazy connection.sendline('export PS1="%s"' % self.job.device.get_constant( 'default-shell-prompt'), delay=self.character_delay) return connection
def run(self, connection, max_end_time): def check_prompt_characters(chk_prompt): if not any([ True for c in DISTINCTIVE_PROMPT_CHARACTERS if c in chk_prompt ]): self.logger.warning(self.check_prompt_characters_warning, chk_prompt) connection = super().run(connection, max_end_time) if not connection: return connection prompts = self.parameters.get("prompts") for prompt in prompts: check_prompt_characters(prompt) connection.prompt_str = LinuxKernelMessages.get_init_prompts() connection.prompt_str.extend(prompts) # Needs to be added after the standard kernel message matches # FIXME: check behaviour if boot_message is defined too. failure = self.parameters.get("failure_message") if failure: self.logger.info("Checking for user specified failure message: %s", failure) if isinstance(connection.prompt_str, str): connection.prompt_str = [connection.prompt_str] connection.prompt_str.append(failure) # linesep should come from deployment_data as from now on it is OS dependent linesep = self.get_namespace_data(action="deploy-device-env", label="environment", key="line_separator") connection.raw_connection.linesep = linesep if linesep else LINE_SEPARATOR self.logger.debug("Using line separator: #%r#", connection.raw_connection.linesep) # Skip auto login if the configuration is not found params = self.parameters.get("auto_login") if not params: self.logger.debug("No login prompt set.") # If auto_login is not enabled, login will time out if login # details are requested. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time, failure) if "success" in self.results: check = self.results["success"] if LOGIN_TIMED_OUT_MSG in check or LOGIN_INCORRECT_MSG in check: raise JobError( "auto_login not enabled but image requested login details." ) # clear kernel message prompt patterns connection.prompt_str = list(self.parameters.get("prompts", [])) # already matched one of the prompts else: self.logger.info("Waiting for the login prompt") connection.prompt_str.append(params["login_prompt"]) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time, failure) if "success" in self.results: if LOGIN_INCORRECT_MSG in self.results["success"]: self.logger.warning( "Login incorrect message matched before the login prompt. " "Please check that the login prompt is correct. Retrying login..." ) self.logger.debug("Sending username %s", params["username"]) connection.sendline(params["username"], delay=self.character_delay) # clear the kernel_messages patterns connection.prompt_str = list(self.parameters.get("prompts", [])) if "password_prompt" in params: self.logger.info("Waiting for password prompt") connection.prompt_str.append(params["password_prompt"]) # This can happen if password_prompt is misspelled. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the password prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched prompt #%s: %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: raise JobError( "Password prompt not matched, please update the job definition with the correct one." ) self.logger.debug("Sending password %s", params["password"]) connection.sendline(params["password"], delay=self.character_delay) # clear the Password pattern connection.prompt_str = list(self.parameters.get( "prompts", [])) connection.prompt_str.append(LOGIN_INCORRECT_MSG) connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the login process to provide the prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched %s %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_INCORRECT_MSG: raise JobError(LOGIN_INCORRECT_MSG) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: raise JobError(LOGIN_TIMED_OUT_MSG) # clear the login patterns connection.prompt_str = list(self.parameters.get("prompts", [])) login_commands = params.get("login_commands") if login_commands is not None: self.logger.debug("Running login commands") for command in login_commands: connection.sendline(command) connection.wait() return connection
def run(self, connection, max_end_time): # Prompts commonly include # - when logging such strings, # use lazy logging or the string will not be quoted correctly. if self.booting: # Nexell extension params = self.parameters.get('auto_login') self.logger.debug("[SEOJI] keys: " + str(self.parameters.keys())) if 'username' in params: if params['username'] == 'nexell': self.logger.debug( "[SEOJI] pass checking kernel-start-message.") elif 'nexell_ext' in self.parameters.keys(): self.logger.debug( "[SEOJI] pass checking kernel-start-message.") else: kernel_start_message = self.parameters.get( 'parameters', {}).get( 'kernel-start-message', self.job.device.get_constant( 'kernel-start-message')) if kernel_start_message: connection.prompt_str = [kernel_start_message] self.logger.debug("[SEOJI] self.params: " + str(self.params)) self.logger.debug("[SEOJI] self.parameters: " + str(self.parameters)) if self.params and self.params.get('boot_message'): self.logger.warning( "boot_message is being deprecated in favour of kernel-start-message in constants" ) connection.prompt_str = [ self.params.get('boot_message') ] error_messages = self.job.device.get_constant( 'error-messages', prefix=self.method, missing_ok=True) if error_messages: if isinstance(connection.prompt_str, str): connection.prompt_str = [connection.prompt_str] connection.prompt_str = connection.prompt_str + error_messages if kernel_start_message: res = self.wait(connection) if res != 0: msg = "matched a bootloader error message: '%s' (%d)" % ( connection.prompt_str[res], res) raise InfrastructureError(msg) def check_prompt_characters(chk_prompt): if not any([ True for c in DISTINCTIVE_PROMPT_CHARACTERS if c in chk_prompt ]): self.logger.warning(self.check_prompt_characters_warning, chk_prompt) connection = super().run(connection, max_end_time) if not connection: return connection prompts = self.parameters.get('prompts') for prompt in prompts: check_prompt_characters(prompt) connection.prompt_str = LinuxKernelMessages.get_init_prompts() connection.prompt_str.extend(prompts) # Needs to be added after the standard kernel message matches # FIXME: check behaviour if boot_message is defined too. failure = self.parameters.get('failure_message') if failure: self.logger.info("Checking for user specified failure message: %s", failure) if isinstance(connection.prompt_str, str): connection.prompt_str = [connection.prompt_str] connection.prompt_str.append(failure) # linesep should come from deployment_data as from now on it is OS dependent linesep = self.get_namespace_data(action='deploy-device-env', label='environment', key='line_separator') connection.raw_connection.linesep = linesep if linesep else LINE_SEPARATOR self.logger.debug("Using line separator: #%r#", connection.raw_connection.linesep) # Skip auto login if the configuration is not found params = self.parameters.get('auto_login') if not params: self.logger.debug("No login prompt set.") self.force_prompt = True # If auto_login is not enabled, login will time out if login # details are requested. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time, failure) if 'success' in self.results: check = self.results['success'] if LOGIN_TIMED_OUT_MSG in check or LOGIN_INCORRECT_MSG in check: raise JobError( "auto_login not enabled but image requested login details." ) # clear kernel message prompt patterns connection.prompt_str = list(self.parameters.get('prompts', [])) # already matched one of the prompts else: self.logger.info("Waiting for the login prompt") connection.prompt_str.append(params['login_prompt']) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time, failure) if 'success' in self.results: if LOGIN_INCORRECT_MSG in self.results['success']: self.logger.warning( "Login incorrect message matched before the login prompt. " "Please check that the login prompt is correct. Retrying login..." ) self.logger.debug("Sending username %s", params['username']) connection.sendline(params['username'], delay=self.character_delay) # clear the kernel_messages patterns connection.prompt_str = list(self.parameters.get('prompts', [])) if 'password_prompt' in params: self.logger.info("Waiting for password prompt") connection.prompt_str.append(params['password_prompt']) # This can happen if password_prompt is misspelled. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the password prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched prompt #%s: %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: raise JobError( "Password prompt not matched, please update the job definition with the correct one." ) self.logger.debug("Sending password %s", params['password']) connection.sendline(params['password'], delay=self.character_delay) # clear the Password pattern connection.prompt_str = list(self.parameters.get( 'prompts', [])) connection.prompt_str.append(LOGIN_INCORRECT_MSG) connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the login process to provide the prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched %s %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_INCORRECT_MSG: self.errors = LOGIN_INCORRECT_MSG raise JobError(LOGIN_INCORRECT_MSG) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: self.errors = LOGIN_TIMED_OUT_MSG raise JobError(LOGIN_TIMED_OUT_MSG) login_commands = params.get('login_commands') if login_commands is not None: self.logger.debug("Running login commands") for command in login_commands: connection.sendline(command) return connection
def run(self, connection, max_end_time, args=None): # Prompts commonly include # - when logging such strings, # use lazy logging or the string will not be quoted correctly. if self.booting: kernel_start_message = self.parameters.get( 'parameters', {}).get( 'kernel-start-message', self.job.device.get_constant('kernel-start-message')) if kernel_start_message: connection.prompt_str = [kernel_start_message] if self.params and self.params.get('boot_message', None): self.logger.warning("boot_message is being deprecated in favour of kernel-start-message in constants") connection.prompt_str = [self.params.get('boot_message')] error_messages = self.job.device.get_constant('error-messages', prefix=self.method, missing_ok=True) if error_messages: if isinstance(connection.prompt_str, str): connection.prompt_str = [connection.prompt_str] connection.prompt_str = connection.prompt_str + error_messages res = self.wait(connection) if res != 0: raise InfrastructureError('matched a bootloader error message: %s' % connection.prompt_str[res]) def check_prompt_characters(chk_prompt): if not any([True for c in DISTINCTIVE_PROMPT_CHARACTERS if c in chk_prompt]): self.logger.warning(self.check_prompt_characters_warning, chk_prompt) connection = super(AutoLoginAction, self).run(connection, max_end_time, args) if not connection: return connection prompts = self.parameters.get('prompts', None) for prompt in prompts: check_prompt_characters(prompt) connection.prompt_str = LinuxKernelMessages.get_init_prompts() connection.prompt_str.extend(prompts) # linesep should come from deployment_data as from now on it is OS dependent linesep = self.get_namespace_data( action='deploy-device-env', label='environment', key='line_separator' ) connection.raw_connection.linesep = linesep if linesep else LINE_SEPARATOR self.logger.debug("Using line separator: #%r#", connection.raw_connection.linesep) # Skip auto login if the configuration is not found params = self.parameters.get('auto_login', None) if not params: self.logger.debug("No login prompt set.") self.force_prompt = True # If auto_login is not enabled, login will time out if login # details are requested. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time) if 'success' in self.results: check = self.results['success'] if LOGIN_TIMED_OUT_MSG in check or LOGIN_INCORRECT_MSG in check: raise JobError("auto_login not enabled but image requested login details.") # clear kernel message prompt patterns connection.prompt_str = list(self.parameters.get('prompts', [])) # already matched one of the prompts else: self.logger.info("Waiting for the login prompt") connection.prompt_str.append(params['login_prompt']) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time) if 'success' in self.results: if LOGIN_INCORRECT_MSG in self.results['success']: self.logger.warning("Login incorrect message matched before the login prompt. " "Please check that the login prompt is correct. Retrying login...") self.logger.debug("Sending username %s", params['username']) connection.sendline(params['username'], delay=self.character_delay) # clear the kernel_messages patterns connection.prompt_str = list(self.parameters.get('prompts', [])) if 'password_prompt' in params: self.logger.info("Waiting for password prompt") connection.prompt_str.append(params['password_prompt']) # This can happen if password_prompt is misspelled. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the password prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched prompt #%s: %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: raise JobError("Password prompt not matched, please update the job definition with the correct one.") self.logger.debug("Sending password %s", params['password']) connection.sendline(params['password'], delay=self.character_delay) # clear the Password pattern connection.prompt_str = list(self.parameters.get('prompts', [])) connection.prompt_str.append(LOGIN_INCORRECT_MSG) connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) # wait for the login process to provide the prompt index = self.wait(connection, max_end_time) if index: self.logger.debug("Matched %s %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_INCORRECT_MSG: self.errors = LOGIN_INCORRECT_MSG raise JobError(LOGIN_INCORRECT_MSG) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: self.errors = LOGIN_TIMED_OUT_MSG raise JobError(LOGIN_TIMED_OUT_MSG) login_commands = params.get('login_commands', None) if login_commands is not None: self.logger.debug("Running login commands") for command in login_commands: connection.sendline(command) connection.prompt_str.extend([self.job.device.get_constant( 'default-shell-prompt')]) self.logger.debug("Setting shell prompt(s) to %s" % connection.prompt_str) # pylint: disable=logging-not-lazy connection.sendline('export PS1="%s"' % self.job.device.get_constant( 'default-shell-prompt'), delay=self.character_delay) return connection
def run(self, connection, max_end_time): # Prompts commonly include # - when logging such strings, # use lazy logging or the string will not be quoted correctly. # Clean the connection session buffer, dirty data. try: connection.raw_connection.empty_buffer() except AttributeError: pass if self.booting: kernel_start_message = self.parameters.get('parameters', {}).get( 'kernel-start-message', self.job.device.get_constant('kernel-start-message')) if kernel_start_message: connection.prompt_str = [kernel_start_message] if self.params and self.params.get('boot_message'): self.logger.warning( "boot_message is being deprecated in favour of kernel-start-message in constants" ) connection.prompt_str = [self.params.get('boot_message')] error_messages = self.job.device.get_constant('error-messages', prefix=self.method, missing_ok=True) if error_messages: if isinstance(connection.prompt_str, str): connection.prompt_str = [connection.prompt_str] connection.prompt_str = connection.prompt_str + error_messages if kernel_start_message: res = self.wait(connection) if res != 0: raise InfrastructureError( 'matched a bootloader error message: %s' % connection.prompt_str[res]) def check_prompt_characters(chk_prompt): if not any([ True for c in DISTINCTIVE_PROMPT_CHARACTERS if c in chk_prompt ]): self.logger.warning(self.check_prompt_characters_warning, chk_prompt) connection = super().run(connection, max_end_time) if not connection: return connection prompts = self.parameters.get('prompts') for prompt in prompts: check_prompt_characters(prompt) connection.prompt_str = LinuxKernelMessages.get_init_prompts() connection.prompt_str.extend(prompts) # linesep should come from deployment_data as from now on it is OS dependent linesep = self.get_namespace_data(action='deploy-device-env', label='environment', key='line_separator') connection.raw_connection.linesep = linesep if linesep else LINE_SEPARATOR self.logger.debug("Using line separator: #%r#", connection.raw_connection.linesep) # Skip auto login if the configuration is not found params = self.parameters.get('auto_login') if not params: self.logger.debug("No login prompt set.") self.force_prompt = True # If auto_login is not enabled, login will time out if login # details are requested. connection.prompt_str.append(LOGIN_TIMED_OUT_MSG) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time) if 'success' in self.results: check = self.results['success'] if LOGIN_TIMED_OUT_MSG in check or LOGIN_INCORRECT_MSG in check: raise JobError( "auto_login not enabled but image requested login details." ) # clear kernel message prompt patterns connection.prompt_str = list(self.parameters.get('prompts', [])) # already matched one of the prompts else: self.logger.info("Waiting for the login prompt") connection.prompt_str.append(params['login_prompt']) connection.prompt_str.append(LOGIN_INCORRECT_MSG) # wait for a prompt or kernel messages self.check_kernel_messages(connection, max_end_time) if 'success' in self.results: if LOGIN_INCORRECT_MSG in self.results['success']: self.logger.warning( "Login incorrect message matched before the login prompt. " "Please check that the login prompt is correct. Retrying login..." ) count = int((max_end_time - time.time()) / 120) count = 1 if count < 1 else count for i in range(1, count + 1): waittime = int((max_end_time - time.time()) / count + time.time()) index = self.input_username_password(connection, waittime) if connection.prompt_str[index] not in [ LOGIN_INCORRECT_MSG, LOGIN_TIMED_OUT_MSG ]: break self.logger.debug("Matched %s %s", index, connection.prompt_str[index]) if connection.prompt_str[index] == LOGIN_INCORRECT_MSG: self.errors = LOGIN_INCORRECT_MSG raise JobError(LOGIN_INCORRECT_MSG) if connection.prompt_str[index] == LOGIN_TIMED_OUT_MSG: self.errors = LOGIN_TIMED_OUT_MSG raise JobError(LOGIN_TIMED_OUT_MSG) login_commands = params.get('login_commands') if login_commands is not None: self.logger.debug("Running login commands") for command in login_commands: connection.sendline(command) return connection