容易的linux自動化運維工具之add_job命令(三)

原文:https://www.3qos.com/article/101.htmlhtml

做者:容易  日期:2015-03-17java

備註:非本人贊成,請勿轉載python




add_job 接口代碼以下git

#-*- coding: UTF-8 -*-

__author__ = 'tiger'

#!/usr/bin/env python

import zmq, time, os

#import random

import subprocess

import logging, ConfigParser

from logging.handlers import RotatingFileHandler

  

#定義日誌函數

def mylog(logfile):

    rthandler = RotatingFileHandler(logfile, 'a', maxBytes=50 * 1024 * 1024, backupCount=3)

    formatter = logging.Formatter(

        '%(levelname)s %(thread)d %(threadName)s %(process)d %(funcName)s %(asctime)s %(filename)s[line:%(lineno)d] %(message)s',

        datefmt='%a, %d %b %Y %H:%M:%S')

    rthandler.setFormatter(formatter)

    log = logging.getLogger()

    log.setLevel(logging.INFO)

    log.addHandler(rthandler)

    return log

  

#定義IP檢查判斷IP是否正確

def ip_check(ip):

    q = ip.split('.')

    return len(q) == 4 and len(filter(lambda x: x >= 0 and x <= 255, \

                                      map(int, filter(lambda x: x.isdigit(), q)))) == 4

  

#配置讀取函數

def read_task(config_file):

    cfg = config_file

    config = ConfigParser.SafeConfigParser()

    config.read(cfg)

    #sections = config.sections()

    #生產任務ID

    job_id = int(time.time()) + 1

    #定義IP字典,記錄批量執行的IP地址

    ip_dic = {}

    #嘗試獲取相關配置變量

    try:

        master_sock = config.get("master", 'sock')

        ip_list = config.get("ip_list", 'ip').split(',')

        job_task = config.get("job_info", 'task')

    except Exception, err:

        print err

        return 0

    for i in ip_list:

        if ip_check(i):

            ip_dic[i] = 'N'

        else:

            print "ip error :%s" % i

            return 0

    #嘗試獲取任務的非必須變量,不存在設置相關默認值

    try:

        job_type = config.get("job_info", 'type')

    except:

        job_type = 'c'

  

    try:

        job_rundir = config.get("job_info", 'rundir')

    except:

        job_rundir = 'None'

  

    try:

        job_cmdtimeout = int(config.get("job_info", 'cmdtimeout'))

  

    except:

        job_cmdtimeout = 10

    try:

        job_jobtimeout = int(config.get("job_info", 'jobtimeout'))

    except:

        job_jobtimeout = 20

  

    if job_type == 's':

        try:

            job_env = config.get("job_info", 'env')

        except:

            job_env = 'sh'

        try:

            job_fileserver = config.get("job_info", 'fileserver')

        except:

            job_fileserver = 'http://192.168.0.227/ser/'

        job_info = {'id': job_id, 'type': job_type, 'task': job_task, 'jobtimeout': job_jobtimeout,

                    'cmdtimeout': job_cmdtimeout, 'env': job_env, 'fileserver': job_fileserver, 'rep_type': 'newtask',

                    'rundir': job_rundir}

    else:

        job_info = {'id': job_id, 'type': job_type, 'task': job_task, 'jobtimeout': job_jobtimeout,

                    'cmdtimeout': job_cmdtimeout, 'rep_type': 'newtask', 'rundir': job_rundir}

    return [ip_dic, job_info, master_sock]

#變量說明,id表明任務的id號是個自增數,根據當前時間生成,job_type表明任務的類別,c表明命令s表明腳本,job_task表明具體的命令,若是是任務

#類別是命令則執行執行,若是是腳本,客戶端將去根據腳本名去http服務器下載相關腳本,jobtimeout表明整個任務的超時時間,若是客戶端沒有在該事件內

#報告任務狀態則超時,cmdtimeout表明客戶端執行具體任務的超時時間,例如top命令若是不帶參數將永遠執行,cmdtimeout就是爲了不相似狀況

#job_env 表明任務的執行環境,一般只適用於執行腳本,job_fileserver 當任務類別是腳本時,下載腳本的http服務器地址和路徑,rep_type響應給客戶端的狀態

#若是響應的信息爲newtask,客戶端將知道是有新任務了,會嘗試獲取任務所需的其餘信息。rundir任務運行的具體路徑

  

def add_job(config_file, logfile):

    #定義平常函數

    log = mylog(logfile)

    #讀取配置文件

    cfg_info = read_task(config_file)

    #返回爲非0時,表示配置文件讀取成功而且符合預期。

    if cfg_info != 0:

        ip_dic = cfg_info[0]

        job_info = cfg_info[1]

        job_id = job_info['id']

        #task = [ip_dic, job_info]

        #生產請求信息,而且發送至master,請求添加新任務。

        task = {'req_type': 'addjob', 'job_info': job_info, 'iplist': ip_dic}

        #嘗試創建與master的鏈接而且發生相關信息等待響應

        sock_file = cfg_info[2]

        context = zmq.Context()

        socket = context.socket(zmq.REQ)

        socket.setsockopt(zmq.LINGER, 0)

        try:

            socket.connect(sock_file)

            socket.send_pyobj(task)

        except Exception, err:

            log.info("connect to master error " + str(err))

            print "connect to master error %s " % str(err)

        #等待請求響應

        report = socket.recv_pyobj()

        #打印響應信息

        print report

        #記錄到相關的日誌,關閉與master的鏈接

        log_file = report.split()[-1]

        log.info(report)

        socket.close()

        context.term()

        #嘗試讀取任務報告,直接使用系統本身帶的tail命令

        read_log = "tail -f " + log_file

        p = subprocess.Popen(read_log, shell=True, stdout=subprocess.PIPE,

                             stderr=subprocess.PIPE)

        returncode = p.poll()

        end_fag = 'job ' + str(job_id) + ' end'

        print '----------------------job report start--------------------------'

        while returncode is None:

            line = p.stdout.readline()

            returncode = p.poll()

            line = line.strip()

            print line

            if line == end_fag:

                break

        print '----------------------job report end---------------------------'

    else:

        return

  

#定義主函數設置相關運行目錄和配置文件名

def main():

    config_file = 'task.ini'

    logfile = 'log/oaos_add_job.log'

    homedir = os.getcwd()

    for i in ('log', 'run'):

        path = homedir + '/' + i

        if not os.path.exists(path):

            os.makedirs(path, 0755)

    add_job(config_file, logfile)

if __name__ == "__main__":

    main()

add_job的配置文件以下shell

#服務端簡單端口和地址
[master]
sock=tcp://192.168.4.194:7777服務器

#須要批量任務的IP地址列表,以逗號分隔
[ip_list]
ip=192.168.4.195,192.168.4.196,192.168.4.197,192.168.4.198dom

#任務信息
[job_info]socket

#任務類別,c表明命令s表明腳本type=c
task=ls -rlttcp

#命令或者腳本的超時時間
cmdtimeout=10函數

#整個任務的超時時間
jobtimeout=10

#命令或者腳本的默認執行環境,能夠是shell,java,python等根據實際需求去定義
env=sh

#假如任務須要發佈腳本,指定下載腳本的URL地址
fileserver=http://192.168.0.227/ser/

#執行腳本或命令時的默認目錄rundir=/root/

相關文章
相關標籤/搜索