X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=src%2Flink%2Fpexpect%2Fexamples%2Fmonitor.py;fp=src%2Flink%2Fpexpect%2Fexamples%2Fmonitor.py;h=e31b51b6d21008da8ae1b3aea15ba2915eb2be7b;hb=cd42b53c196672694396e695ae17fd94ba7d58b4;hp=0000000000000000000000000000000000000000;hpb=e9a8105a8f22404f4ac550d79954eaa6b7f5d8ff;p=progcomp10.git diff --git a/src/link/pexpect/examples/monitor.py b/src/link/pexpect/examples/monitor.py new file mode 100755 index 0000000..e31b51b --- /dev/null +++ b/src/link/pexpect/examples/monitor.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python + +""" This runs a sequence of commands on a remote host using SSH. It runs a +simple system checks such as uptime and free to monitor the state of the remote +host. + +./monitor.py [-s server_hostname] [-u username] [-p password] + -s : hostname of the remote server to login to. + -u : username to user for login. + -p : Password to user for login. + +Example: + This will print information about the given host: + ./monitor.py -s www.example.com -u mylogin -p mypassword + +It works like this: + Login via SSH (This is the hardest part). + Run and parse 'uptime'. + Run 'iostat'. + Run 'vmstat'. + Run 'netstat' + Run 'free'. + Exit the remote host. +""" + +import os, sys, time, re, getopt, getpass +import traceback +import pexpect + +# +# Some constants. +# +COMMAND_PROMPT = '[#$] ' ### This is way too simple for industrial use -- we will change is ASAP. +TERMINAL_PROMPT = '(?i)terminal type\?' +TERMINAL_TYPE = 'vt100' +# This is the prompt we get if SSH does not have the remote host's public key stored in the cache. +SSH_NEWKEY = '(?i)are you sure you want to continue connecting' + +def exit_with_usage(): + + print globals()['__doc__'] + os._exit(1) + +def main(): + + global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY + ###################################################################### + ## Parse the options, arguments, get ready, etc. + ###################################################################### + try: + optlist, args = getopt.getopt(sys.argv[1:], 'h?s:u:p:', ['help','h','?']) + except Exception, e: + print str(e) + exit_with_usage() + options = dict(optlist) + if len(args) > 1: + exit_with_usage() + + if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: + print "Help:" + exit_with_usage() + + if '-s' in options: + host = options['-s'] + else: + host = raw_input('hostname: ') + if '-u' in options: + user = options['-u'] + else: + user = raw_input('username: ') + if '-p' in options: + password = options['-p'] + else: + password = getpass.getpass('password: ') + + # + # Login via SSH + # + child = pexpect.spawn('ssh -l %s %s'%(user, host)) + i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password']) + if i == 0: # Timeout + print 'ERROR! could not login with SSH. Here is what SSH said:' + print child.before, child.after + print str(child) + sys.exit (1) + if i == 1: # In this case SSH does not have the public key cached. + child.sendline ('yes') + child.expect ('(?i)password') + if i == 2: + # This may happen if a public key was setup to automatically login. + # But beware, the COMMAND_PROMPT at this point is very trivial and + # could be fooled by some output in the MOTD or login message. + pass + if i == 3: + child.sendline(password) + # Now we are either at the command prompt or + # the login process is asking for our terminal type. + i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT]) + if i == 1: + child.sendline (TERMINAL_TYPE) + child.expect (COMMAND_PROMPT) + # + # Set command prompt to something more unique. + # + COMMAND_PROMPT = "\[PEXPECT\]\$ " + child.sendline ("PS1='[PEXPECT]\$ '") # In case of sh-style + i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10) + if i == 0: + print "# Couldn't set sh-style prompt -- trying csh-style." + child.sendline ("set prompt='[PEXPECT]\$ '") + i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10) + if i == 0: + print "Failed to set command prompt using sh or csh style." + print "Response was:" + print child.before + sys.exit (1) + + # Now we should be at the command prompt and ready to run some commands. + print '---------------------------------------' + print 'Report of commands run on remote host.' + print '---------------------------------------' + + # Run uname. + child.sendline ('uname -a') + child.expect (COMMAND_PROMPT) + print child.before + if 'linux' in child.before.lower(): + LINUX_MODE = 1 + else: + LINUX_MODE = 0 + + # Run and parse 'uptime'. + child.sendline ('uptime') + child.expect('up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])') + duration, users, av1, av5, av15 = child.match.groups() + days = '0' + hours = '0' + mins = '0' + if 'day' in duration: + child.match = re.search('([0-9]+)\s+day',duration) + days = str(int(child.match.group(1))) + if ':' in duration: + child.match = re.search('([0-9]+):([0-9]+)',duration) + hours = str(int(child.match.group(1))) + mins = str(int(child.match.group(2))) + if 'min' in duration: + child.match = re.search('([0-9]+)\s+min',duration) + mins = str(int(child.match.group(1))) + print + print 'Uptime: %s days, %s users, %s (1 min), %s (5 min), %s (15 min)' % ( + duration, users, av1, av5, av15) + child.expect (COMMAND_PROMPT) + + # Run iostat. + child.sendline ('iostat') + child.expect (COMMAND_PROMPT) + print child.before + + # Run vmstat. + child.sendline ('vmstat') + child.expect (COMMAND_PROMPT) + print child.before + + # Run free. + if LINUX_MODE: + child.sendline ('free') # Linux systems only. + child.expect (COMMAND_PROMPT) + print child.before + + # Run df. + child.sendline ('df') + child.expect (COMMAND_PROMPT) + print child.before + + # Run lsof. + child.sendline ('lsof') + child.expect (COMMAND_PROMPT) + print child.before + +# # Run netstat +# child.sendline ('netstat') +# child.expect (COMMAND_PROMPT) +# print child.before + +# # Run MySQL show status. +# child.sendline ('mysql -p -e "SHOW STATUS;"') +# child.expect (PASSWORD_PROMPT_MYSQL) +# child.sendline (password_mysql) +# child.expect (COMMAND_PROMPT) +# print +# print child.before + + # Now exit the remote host. + child.sendline ('exit') + index = child.expect([pexpect.EOF, "(?i)there are stopped jobs"]) + if index==1: + child.sendline("exit") + child.expect(EOF) + +if __name__ == "__main__": + + try: + main() + except Exception, e: + print str(e) + traceback.print_exc() + os._exit(1) +