Pergunta

Background: To get practice I'm writing an application for work that will allow help desk users to grep | tail logs without requiring them to perform SSH/terminal work. These users are running on windows machines otherwise I'd use subprocess. Some of the servers use system accounts(and those are prefilled into the script), but the others require the user to enter credentials.

When the script(details below) is run and a user enters their credentials incorrectly the application hangs after throwing a 'No handlers could be found for logger "paramiko.transport"' error. When the user selects a option that does not have prefilled credentials they are prompted for a username and password. The credentials are appended to the appropriate list, the popup is destroyed and the log checking function is called. What might be causing the window to hang when the error is thrown, and what is the best method to handle such issues?

I have attempted to add logging.basicConfig(), but the application still hangs.

Full script: http://pastebin.com/TUvs92yN

When the user first hits the submit button the following is invoked:

lambda: credentials() if hosts[log.get()][0] in needs_pass else log_check()

If the host name is found in a list then the credentials box appears. After the user enters their username and password the submit_cred() function is called:

def submit_cred():
    if len(hosts[log.get()]) < 3:
        hosts[log.get()].append(username_prompt.get())
        hosts[log.get()].append(password_prompt.get())
    prompt.destroy()
    log_check()

This is where the trouble starts. If the credentials were correct the application displays the results as expected, but if not when log_check() is called after the window is destroyed an error is received and the application hangs. I attempted to handle authentication problems in the log_check(), but at this point it doesn't seem to get far enough for that to matter.

Foi útil?

Solução

I believe the issue is with your paramiko ssh connect method call. The method takes an optional timeout argument, but the timeout is set to None by default and is thus never returning. If you set this value to something more reasonable for the user, something like 5 seconds (you may want to set that a bit longer in practice):

# Verify connectivity/authenticate.
    try:
        ssh.connect(host, username=user, password=passwd, timeout=5)

Now you'll notice you'll hit your except clause. The exception message will be 'timed out' so you can add a check for that there.

Also, it's not a bad idea to wrap functions like that within a GUI in a Thread to prevent the whole app from freezing, it's pretty easy to implement. In your case, you could do something like rename your current log_check function to _log_check and then write a little wrapper like:

def log_check(self):
    t = Thread(target=_log_check)
    t.start()

Hope this helps!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top