首页 > 技术文章 > A Python Environment Detector

darkmatter 2014-03-28 18:58 原文

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.

The application module, detapp.py:

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:

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:

  • Run shell command in Python and retrieve output and return code;

  • Use signal to limit the overall running time of commands on remote host over SSH;

  • The logging utility across multiple modules, notice the naming rules: .. So if you rename the module name, rename it's logger accordingly.

推荐阅读