fgimian / paramiko-expect

A Python expect-like extension for the Paramiko SSH library which also supports tailing logs.
MIT License
205 stars 78 forks source link

Tail Stop_callback() Example? #54

Closed EdHunter87 closed 4 years ago

EdHunter87 commented 5 years ago

I am building a script to monitoring some build logs on a remote system when a user kicks off a build. I got the tail function working, and using a timeout function to stop it after X second of no input. I can see there is a stop_callback function that can break the tail function as well. This seems like a much cleaner way to do this. I can't seem to find any example that uses the stop_callback function, there there some place I can look for that?

My code:

    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(hostname, port=port, username=username, password=password)
        interact = SSHClientInteraction(client, timeout=10, display=False)
        interact.send('tail -f file.txt')
        interact.tail(timeout=60)
    except KeyboardInterrupt:
        print ('Ctrl+C interruption detected, stopping tail')
        client.close()
    except Exception:
        #traceback.print_exc()
        client.close()
    finally:
        try:
            client.close()
        except:
            pass

Thanks

EdHunter87 commented 5 years ago

I think I solved my own problem:

This will parse the file, and then based on the string end when it matches.

import traceback, paramiko, sys
from paramiko_expect import SSHClientInteraction

# Check current line, if match is found return True
def checkline(current_line):
    if current_line.startswith('Finished: '):
        return True
    else:
        return False

def main():
    # Varaiables
    hostname    = 'host'
    username    = user'
    password    = 'pass'
    keyFile     = '/path/to/rsa.key'
    port        = 22
    timeout     = 5
    jobName     = sys.argv[1]
    jobID       = sys.argv[2]

    """
        Create SSH connection with paramiko, then using paramiko_expect
        sent a tail command to look for the build file, and tail out
        **If a line starts with `Finished: ` the tail will break and close the connection
    """
    try:
        # Create SSH Connection
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        #client.connect(hostname, port=port, username=username, pkey=paramiko.RSAKey.from_private_key_file(keyFile)) # ! Getting `not a valid RSA private key file`
        client.connect(hostname, port=port, username=username, password=password)

        # Create Interactive session
        interact = SSHClientInteraction(client, timeout=10, display=False)

        # Send command to remote server
        interact.send('tail -f /var/lib/jenkins/jobs/CheckoutScripts/jobs/{}/builds/{}/log'.format(jobName, jobID))

        # Tail the output from the command that is send. 
        # Exit based on a a line format or no output received for 60 seconds
        interact.tail(stop_callback=checkline, timeout=60)

    # Exit Tail if user presses Ctrl+C
    except KeyboardInterrupt:
        print ('Ctrl+C interruption detected, stopping tail')
    # Print all other Expections
    except Exception:
        traceback.print_exc()
    finally:
        # Try to close ssh session gracefully
        try:
            print ("Gracefully closing Connection")
            client.close()
        # Otherwise just close script
        except:
            print ("Failed to exit gracefully")
            pass

if __name__ == '__main__':
    main()
fruch commented 4 years ago

If you want to add this as example of write it in the read, we would merge that PR. Meanwhile I'm closing those issue