docs: def login(self, sendspec):
  		"""Logs the user in with the passed-in password and command.
  		Tracks the login. If used, used logout to log out again.
  		Assumes you are root when logging in, so no password required.
  		If not, override the default command for multi-level logins.
  		If passwords are required, see setup_prompt() and revert_prompt()
  
  		@type param:           see shutit_sendspec.ShutItSendSpec
  		@type sendspec:        shutit_sendspec.ShutItSendSpec
  		"""
  		user          = sendspec.user
  		command       = sendspec.send
  		prompt_prefix = sendspec.prompt_prefix
  		shutit = self.shutit
  		# We don't get the default expect here, as it's either passed in, or a base default regexp.
  		if isinstance(sendspec.password,str):
  			shutit_global.shutit_global_object.secret_words_set.add(sendspec.password)
  		r_id = shutit_util.random_id()
  		if prompt_prefix is None:
  			prompt_prefix = r_id
  		# Be helpful - if this looks like a command that requires a user, then suggest user provides one.
  		if user is None:
  			user = self.whoami()
  			if 'bash' not in command:
  				shutit.log('No user supplied to login function, so retrieving who I am (' + user + '). You may want to override.', level=logging.WARNING)
  		if ' ' in user:
  			self.shutit.fail('user has space in it - did you mean: login(command="' + user + '")?') # pragma: no cover
  		if self.shutit.build['delivery'] == 'bash' and command == 'su -':
  			# We want to retain the current working directory
  			command = 'su'
  		# If this is a su-type command, add the user, else assume user is in the command.
  		if command == 'su -' or command == 'su' or command == 'login':
  			send = command + ' ' + user
  		else:
  			send = command
  		login_expect = sendspec.expect or shutit_global.shutit_global_object.base_prompt
  		# We don't fail on empty before as many login programs mess with the output.
  		# In this special case of login we expect either the prompt, or 'user@' as this has been seen to work.
  		general_expect = [login_expect]
  		# Add in a match if we see user+ and then the login matches. Be careful not to match against 'user+@...password:'
  		general_expect = general_expect + [user+'@.*'+'[#$]']
  		# If not an ssh login, then we can match against user + @sign because it won't clash with 'user@adasdas password:'
  		if (sendspec.is_ssh != None and sendspec.is_ssh) or command.find('ssh ') != -1:
  			shutit.log('Assumed to be an ssh command, is_ssh: ' + str(sendspec.is_ssh) + ', command: ' + command, level=logging.DEBUG)
  			# If user@ already there, remove it, as it can conflict with password lines in ssh calls.
  			if user+'@' in general_expect:
  				general_expect.remove(user+'@')
  			# Adding the space to avoid commands which embed eg $(whoami) or ${var}
  			general_expect.append('.*[#$] ')
  			# Don't match 'Last login:' or 'Last failed login:'
  			send_dict={'ontinue connecting':['yes', False]}
  			if sendspec.password is not None:
  				send_dict.update({'assword:':[sendspec.password, True]})
  				send_dict.update({r'[^dt] login:':[sendspec.password, True]})
  		else:
  			send_dict={'ontinue connecting':['yes', False]}
  			if sendspec.password is not None:
  				send_dict.update({'assword:':[sendspec.password, True]})
  				send_dict.update({r'[^dt] login:':[sendspec.password, True]})
  				send_dict.update({user+'@':[sendspec.password, True]})
  		if user == 'bash' and command == 'su -':
  			shutit.log('WARNING! user is bash - if you see problems below, did you mean: login(command="' + user + '")?', level=logging.WARNING)
  		self.shutit.handle_note(sendspec.note,command=command + '\n\n[as user: "' + user + '"]',training_input=send)
  		echo = self.shutit.get_echo_override(sendspec.echo)
  		shutit.log('Logging in to new ShutIt environment.' + user, level=logging.DEBUG)
  		shutit.log('Logging in with command: ' + send + ' as user: ' + user, level=logging.DEBUG)
  		shutit.log('Login stack before login: ' + str(self.login_stack), level=logging.DEBUG)
  		# check_sudo - set to false if the password has been supplied.
  		check_sudo = False
  		if sendspec.password is None and send.strip().find('sudo') == 0:
  			check_sudo = True
  		res = self.multisend(ShutItSendSpec(self,
  		                                    send=send,
  		                                    send_dict=send_dict,
  		                                    expect=general_expect,
  		                                    check_exit=False,
  		                                    timeout=sendspec.timeout,
  		                                    fail_on_empty_before=False,
  		                                    escape=sendspec.escape,
  		                                    echo=echo,
  		                                    remove_on_match=True,
  		                                    nonewline=sendspec.nonewline,
  		                                    check_sudo=check_sudo,
  		                                    loglevel=sendspec.loglevel))
  		if res == -1:
  			# Should not get here as login should not be blocked.
  			assert False, shutit_util.print_debug()
  		# Setup prompt
  		if prompt_prefix != None:
  			self.setup_prompt(r_id,prefix=prompt_prefix,capture_exit_code=True)
  		else:
  			self.setup_prompt(r_id,capture_exit_code=True)
  		self.login_stack.append(r_id)
  		shutit.log('Login stack after login: ' + str(self.login_stack), level=logging.DEBUG)
  		if self.send_and_get_output(''' echo $SHUTIT_EC && unset SHUTIT_EC''', loglevel=logging.DEBUG, echo=False) != '0':
  			# TODO: remove just-added login stack item (since we failed to log in successfully)?
  			if sendspec.fail_on_fail: # pragma: no cover
  				self.shutit.fail('Login failure! You may want to re-run shutit with --echo or -l debug and scroll up to see what the problem was.')
  			else:
  				return False
  		if sendspec.go_home:
  			self.send(ShutItSendSpec(self,
  			                         send='cd',
  			                         check_exit=False,
  			                         echo=False,
  		                             ignore_background=True,
  			                         loglevel=sendspec.loglevel))
  		self.shutit.handle_note_after(note=sendspec.note,training_input=send)
  		return True