The user provide the method to get result(command on remote host), the check standard(a callback function), and information about target host(ip and username), and a timeout of execution time optional, with the envdet module, you can get the result: if the command output obey the check standard.java
The application module, detapp.py:shell
import logging from envdet import rcmd logger = logging.getLogger('DetectApp') logger.setLevel(logging.DEBUG) fh = logging.FileHandler('detect.log') fh.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) fh.setFormatter(formatter) logger.addHandler(ch) logger.addHandler(fh) def isOracleJDK(str): return 'Java(TM)' in str res = rcmd('bvt', '10.0.2.47', 'java -version', isOracleJDK) logger.info('Check result:%s' % res)
The environment detection module, envdet.py:app
from subprocess import Popen, PIPE, STDOUT import signal import logging logger = logging.getLogger('DetectApp.envdet') def handler(signum, frame): logger.error('Signal handler called with signal: %d' % signum) raise IOError("Command execution timeout!") def rcmd(user, host, cmd, check_handler, timeout=10): signal.signal(signal.SIGALRM, handler) signal.alarm(timeout) cmdstr = "ssh %s@%s 'source /etc/profile;%s'" % (user, host, cmd) p = Popen(cmdstr, close_fds=True, shell=True, stdout=PIPE, stderr=STDOUT) fullres = line = '' while p.poll() is None: out = p.stdout.read(1) fullres = fullres + out if out=='\n': logger.debug(line) line = '' else: line = line + out logger.debug('----ret of cmd %s is: %d----' % (cmd, p.returncode)) return check_handler(fullres)
The technical points here are:ssh
Run shell command in Python and retrieve output and return code;ide
Use signal to limit the overall running time of commands on remote host over SSH;debug
The logging utility across multiple modules, notice the naming rules: