blob: b5e2b095d7c07d4f6ef7e7a85222f53d0b5c7d1e [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Login driver to handle the login hurdle on the CPU uart console.
This driver exposes methods to login, logout, set password, and
username to login, and check if a session is logged in.
"""
import logging
import time
import pty_driver
class loginError(Exception):
"""Exception class for login errors."""
class login(pty_driver.ptyDriver):
""" Wrapper class around ptyDriver to handle communication
with the AP console.
"""
# This is a class level variable because each
# servo command runs on their own instance of
# dutMetadata. We share it across instances
# to allow for updating and retrieval.
# TODO(coconutruben): right now the defaults are hard coded
# into the driver. Evaluate if it makes more sense for the
# defaults to be set by the xml commands.
_login_info = {
'username' : 'root',
'password' : 'test0000'
}
def __init__(self, interface, params):
"""Initializes the login driver.
Args:
interface: A driver interface object. This is the AP uart interface.
params: A dictionary of parameters, but is ignored.
"""
super(login, self).__init__(interface, params)
self._logger.debug("")
def _Get_password(self):
""" Returns password currently used for login attempts. """
return self._login_info['password']
def _Set_password(self, value):
""" Set |value| as password for login attempts. """
self._login_info['password'] = value
def _Get_username(self):
""" Returns username currently used for login attempts. """
return self._login_info['username']
def _Set_username(self, value):
""" Set |value| as username for login attempts. """
self._login_info['username'] = value
def _Get_login(self):
""" Heuristic to determine if a session is logged in
on the CPU uart terminal.
Sends a newline to the terminal, and evaluates the output
to determine login status.
Returns:
True 1 a session is logged in, 0 otherwise.
"""
# TODO(coconutruben): currently, this assumes localhost as the
# host name, and a specific pattern for PS1. Make this more
# robust to OS changes by generating the regex based on the
# PS1 variable.
try:
self._issue_cmd_get_results([''], ['localhost.*\s+[#$]'])
return 1
except pty_driver.ptyError:
return 0
def _Set_login(self, value):
""" Login/out of a session on the CPU uart terminal.
Uses username and password stored in |_login_info| to
attempt login.
"""
# TODO(coconutruben): the login/logout logic fails silently and user has
# to call login command again to verify. Consider if raising an error on
# failure here is appropiate.
# TODO(coconutruben): the login sequence relies on timing currently.
# Consider if it would be more robust to use fdexpect code directly
# to see when to send the username, and the password.
if value == 1:
# 1 means login desired.
if not self._Get_login():
with self._open():
self._send([self._login_info['username'],
self._login_info['password']],
0.1, False)
time.sleep(0.1)
if value == 0:
# 0 means logout desired.
if self._Get_login():
self._issue_cmd(['exit'])