每日一题.PYTHON如何实现运维中类似SHELL的通用服务自启动脚本?

原文数据:

具体要求:

1.实现通用服务start/stop/status/restart操作

2.实现通用服务的自启动chkconfig [services] on

相关依赖:

yum -y install python python-devel
yum -y install python-setuptools
easy_install psutil

代码实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# chkconfig: - 85 15
# Authors: limanman
# Githubs: https://github.com/PyFansLi/
# 163Blog: http://my.oschina.net/pydevops/
# Purpose:
#
import os
import re
import sys
import psutil
import signal
import socket


def filter_process_info(process_name):
    '''Get process object with process_name.

    Args:
        process_name: process name
    Returns:
        process object
    Raises:
        None - not process found
    '''

    process = psutil.process_iter()
    for ps in process:
        if ps.name() == process_name:
            return ps


def show_usage(saction, process_name):
    argv_act = ''.join(sys.argv[1:])
    if argv_act not in saction.keys():
        process_name = process_name.lower()
        sys.exit('Usage: /etc/init.d/%s {start|stop|status|restart}' % (
                 process_name))
    return saction[argv_act]


def print_formated_rets(fuc_name, proc_name):
    total_width = 66
    status_width = 8
    info_width = total_width - status_width
    info_fmt = '%-*s%*s'
    info_rht = '[  OK  ]'
    info_lft = '%s %s:                                           ' % (
               fuc_name, proc_name)
    print info_fmt % (info_width, info_lft, status_width, info_rht)


def get_server_wanip(ip_file='/etc/motd'):
    """Get server wlan address.

    Args:
        ip_file: Distributed by saltstack ip file
        example:
            Lan_IP: x.x.x.x
            Wan_IP: x.x.x.x
    Returens:
        Wlan ip address
    Raises:
        IOError: [Errno 2] No such file or directory: ${ip_file}
    """

    if os.path.exists(ip_file):
        with open(ip_file) as fhandle:
            match = re.search(r'Wan_IP:\s+([0-9.]+)', fhandle.read())
            if match:
                cache_ip = match.group(1).strip()
            else:
                sys.exit('Found Error: Wan_IP not in %s, exit!' % (ip_file))
    else:
        sys.exit('Found Error: No such file %s, exit!' % (ip_file))
    return cache_ip


def resolve_srv_addr(domain='redis4status-p2p.domain.net'):
    """Resolve redis in various countries ip, and use the last one.

    Args:
        domain: The domain you whill resolve
    Returns:
        Domain ip address
    """

    socket_inf = socket.getaddrinfo(domain, None)
    socket_res = socket_inf[-1][-1][0]
    if socket_res:
        return socket_res
    else:
        resolve_srv_addr()


def start(proc_obj):
    global realprocpath
    global other_option

    locale_wanip = get_server_wanip()
    remote_resov = resolve_srv_addr()

    if proc_obj:
        process_name = proc_obj.name()
        print_formated_rets('Starting', process_name)
        return True

    other_option = other_option % (locale_wanip,
                                   locale_wanip, remote_resov)
    process_name = realprocpath.rpartition('/')[-1]
    os.system('%s %s &' % (realprocpath, other_option))

    if filter_process_info(process_name):
        print_formated_rets('Starting', process_name)
        return True


def stop(proc_obj):
    global realprocpath
    global other_option

    if not proc_obj:
        process_name = realprocpath.rpartition('/')[-1]
        print_formated_rets('Stopping', process_name)
        return True

    process_name = proc_obj.name()
    os.kill(int(proc_obj.pid), signal.SIGKILL)

    if not filter_process_info(process_name):
        print_formated_rets('Stopping', process_name)
        return True


def status(proc_obj):
    global realprocpath
    global other_option

    if proc_obj:
        process_id = proc_obj.pid
        process_name = proc_obj.name()
        print '%s (pid  %s) is running...' % (process_name, process_id)
    else:
        process_name = realprocpath.rpartition('/')[-1]
        print '%s is stopped' % (process_name)


def restart(proc_obj):
    stop_res = stop(proc_obj)
    # if stoped, you mast set proc_obj None to reget proc_obj
    if stop_res:
        proc_obj = None
        start(proc_obj)


def main():
    saction = {'start': start, 'stop': stop,
               'status': status, 'restart': restart}

    process_name = realprocpath.rpartition('/')
    process = filter_process_info(process_name[-1])
    daction = show_usage(saction, process_name[-1])

    # call process handler
    daction(process)


if __name__ == '__main__':
    """
    Parameter:
        -a:
            listening ip
        -b:
            listening port
        -c:
            listining ip
        -d:
            debug port(http://http://IP:3998/info)
        -e:
            remote redis ip
        -f:
            remote redis port
        -i:
            -1
        -j:
            manufacturer name, default General
        -k:
            server role, 0 for old proxy, 1 for jinping proxy,
            2 for new proxy with flow control
        -l:
            thread number, if lt 0 self-adaption, if eq 0 single thread, if gt
            0 multi thread, default singnal thread
        -m:
            State:Country:Province/City, example: Asia:China:BeiJing
    """
    # TODO([email protected]): Manually add some startup parameters
    realprocpath = '/xm-workspace/xm-apps/proxyserver/ProxyServer'
    other_option = ('-a %s -b 3999 -c %s -d 3998 -e %s -f 5123 -i -1 '
                    '-j General -k 0 -l 1000 -m Asia:China:BeiJing')
    main()

有图有像:

每日一题.PYTHON如何实现运维中类似SHELL的通用服务自启动脚本?_第1张图片

你可能感兴趣的:(每日一题.PYTHON如何实现运维中类似SHELL的通用服务自启动脚本?)