# -*- coding: utf-8 -*- ''' Support for Nginx This module uses the manager webapp to manage Apache Nginx webapps. If the manager webapp is not configured some of the functions won't work. :configuration: - Java bin path should be in default path - If ipv6 is enabled make sure you permit manager access to ipv6 interface "0:0:0:0:0:0:0:1" - If you are using Nginx.tar.gz it has to be installed or symlinked under ``/opt``, preferably using name Nginx - "Nginx.signal start/stop" works but it does not use the startup scripts ''' import os import re import subprocess import sys try: import wmi except: pass import json import time #內部調用模塊 if sys.platform.startswith('win'): SYSTEM = "windows" PKG_NAME = "nginx-1.8.1.zip" BASE_DIR = 'c:\\' MAIN_DIR = 'nginx' PKG_DIR = 'c:\\' else: SYSTEM = "linux" BASE_DIR = '/opt' PKG_DIR = '/opt' MAIN_DIR = 'nginx' OPENSSL_NAME = "openssl-1.0.1e.tar.gz" OPENSSL_DIR = "openssl-1.0.1e" ZLIB_NAME = "zlib-1.2.8.tar.gz" ZLIB_DIR = "zlib-1.2.8" PCRE_NAME = "pcre-8.21.tar.gz" PCRE_DIR = "pcre-8.21" def _send_message(message, jid=None): __salt__['exec_module.module_send_event'](message, jid=jid) def install(baseDir=None, port=None, package=None, dependPkg=[], jid=None, outputParam=[], execAccount=None, **kwargs): try: _send_message('start install in {}'.format(SYSTEM), jid=jid) if SYSTEM == 'linux': package_lists = ['libxml2','libxml2-dev','libxslt-devel','libxml2-devel','gd-devel','gcc'] lack_package_lists = [] if SYSTEM == 'linux': for i in package_lists: cmd = "rpm -q --qf '%{{NAME}}-%{{VERSION}}-%{{RELEASE}} (%{{ARCH}})\n' {}".format(i) out = utils_cmd.get_output(cmd)[0] if 'is not installed' or u'未安裝' in out: lack_package_lists.append(i) if lack_package_lists: return {"success": False, "message": u"lack depend packages: \n{}".format( ','.join(lack_package_lists))} ret, param = utils_errors.check_inputs(locals(), outs=['dependPkg', 'port']) if not ret: return {'success': False, 'message': 'input params error,please check input params:{}'.format(param)} if not os.path.exists(baseDir): os.mkdir(baseDir) filename = baseDir.split(os.sep)[-1].strip(os.sep) filepath = baseDir.split(filename)[0].strip(os.sep) if not package: raise InstallError(u'nginx install fail,package is null') if SYSTEM == "windows" and baseDir.endswith(":"): baseDir = baseDir + os.sep elif SYSTEM == "windows" and baseDir.endswith(":\\"): pass else: baseDir = baseDir.rstrip(os.sep) for package_item in package: if "nginx" in package_item: dir = MAIN_DIR nginx_install_path = utils_pack.unpack_tar(package_item, baseDir, path=dir) if not nginx_install_path: raise InstallError(u'nginx install fail!') utils.logger.info('nginx untar dir is :{}'.format(nginx_install_path)) _send_message(u"nginx untar success,installation process:30%", jid=jid) # untar path can't be install path nginx_temp_dir = nginx_install_path + '_temp' if os.path.exists(nginx_temp_dir): return {"success": False, "message": nginx_temp_dir + " exist!please delete this directory first!"} if SYSTEM == "linux": for dependPkg_item in dependPkg: result = '' if 'pcre' in dependPkg_item: if not __salt__['exec_module.detect'](baseDir, PCRE_DIR): pcre_path = utils_pack.unpack_tar(dependPkg_item, baseDir, path=dir) else: pcre_path = os.path.join(baseDir, PCRE_DIR) result = pcre_path elif 'openssl' in dependPkg_item: if not __salt__['exec_module.detect'](baseDir, OPENSSL_DIR): openssl_path = utils_pack.unpack_tar(dependPkg_item, baseDir, path=dir) else: openssl_path = os.path.join(baseDir, OPENSSL_DIR) result = openssl_path elif 'zlib' in dependPkg_item: if not __salt__['exec_module.detect'](baseDir, ZLIB_DIR): zlib_path = utils_pack.unpack_tar(dependPkg_item, baseDir, path=dir) else: zlib_path = os.path.join(baseDir, ZLIB_DIR) result = zlib_path if not result: raise InstallError(u'install fail!') _send_message(u"nginx depend package install success,installation process:80%", jid=jid) utils.logger.info(u"Nginx package success!") if port: __salt__['file.replace']('{0}/conf/nginx.conf'.format(nginx_install_path), 'listen \\s*\\d*;', 'listen {0};'.format(port)) __salt__['file.replace']('{0}/conf/nginx.conf'.format(nginx_install_path), '^#error_log logs/error.log;', 'error_log logs/error.log;') __salt__['file.replace']('{0}/conf/nginx.conf'.format(nginx_install_path), '^#pid logs/nginx.pid;', 'pid logs/nginx.pid;') os.rename(nginx_install_path, nginx_install_path + '_temp') configure = './configure --prefix={0}'.format(nginx_install_path) pcre = ' --with-pcre={0}'.format(pcre_path) zlib = ' --with-zlib={0}'.format(zlib_path) openssl = ' --with-openssl={0}'.format(openssl_path) other = ' --with-http_spdy_module --with-http_realip_module --with-http_addition_module' + \ ' --with-http_xslt_module --with-http_image_filter_module --with-http_sub_module' + \ ' --with-http_auth_request_module --with-http_stub_status_module --with-http_gzip_static_module' cmd = configure + pcre + zlib + openssl + other utils.logger.info(cmd) out = utils_cmd.get_output(cmd, cwd=nginx_install_path + '_temp') utils.logger.info(out) pattern = re.compile(r'./configure: error .*') for line_order in range(-1, -5, -1): match = pattern.match(out[line_order]) if match is not None: return {"success": False, "message": baseDir + "/" + PCRE_DIR + " not exist!"} out = __salt__['cmd.run_stdout']( 'make', cwd=nginx_install_path + '_temp', python_shell=False).splitlines() utils.logger.info(out) out = __salt__['cmd.run_stdout']( 'make install', cwd=nginx_install_path + '_temp', python_shell=False).splitlines() utils.logger.info(out) else: if port: cwd = os.path.join(baseDir, dir, 'conf\\nginx.conf') __salt__['file.replace']( cwd, 'listen \\s*\\d*;', 'listen {0};'.format(port)) install_path = json.dumps({'install_path': nginx_install_path}) return {"success": True, "message": u'Nginx install success,temp directory is {}_temp,you can remove it.'. format(nginx_install_path), 'outputParam': install_path} except InstallError as e: return _return_result(e, jid, status=False) except Exception as e: return {"success": False, "message": '{}'.format(e)} class ExecError(Exception): pass def _get_install_path(baseDir): path = os.path.join(baseDir, 'sbin') if not os.path.exists(path): path = utils_cmd.get_output('ls|grep nginx', cwd=baseDir) if path not in ('', None, []): path = path[0].strip('\n').strip('\r\n') path = os.path.join(baseDir, path, 'sbin') else: raise ExecError('{} has no nginx'.format(baseDir)) utils.logger.info(path) if not os.path.exists(path): raise ExecError('{} has no nginx'.format(baseDir)) install_dir = path.rstrip('/sbin') return install_dir def start(baseDir=None, outputParam=[], execAccount=None, **kwargs): try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {'success': False, 'message': 'input params error,please check input params:{}'.format(param)} cwd = _get_install_path(baseDir) utils.logger.info('install path:{}'.format(cwd)) if SYSTEM == "linux": cmd = '{0}/sbin/nginx -c {0}/conf/nginx.conf'.format(cwd) out, result = __salt__['exec_module.manageService']( SYSTEM, 'nginx', 'service.start', 'nginx', cmd) utils.logger.info('{}'.format(cmd)) else: cmd = 'start nginx.exe' proc = subprocess.Popen(cmd, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=None) time.sleep(3) c = wmi.WMI() for process in c.Win32_Process(): if "nginx" in process.Name: out = True break if out: return {"success": True, "message": 'Nginx start success!'} else: return {"success": False, "message": 'Nginx start fail,maybe the port has been used!'} except Exception as e: return {"success": False, "message": 'Nginx start fail:{}'.format(e)} def stop(baseDir=None, outputParam=[], execAccount=None, **kwargs): try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {'success': False, 'message': 'input params error,please check input params:{}'.format(param)} cwd = _get_install_path(baseDir) if SYSTEM == "linux": cmd = '{0}/sbin/nginx -s stop'.format(cwd) out, result = __salt__['exec_module.manageService']( SYSTEM, 'nginx', 'service.stop', 'nginx', cmd) else: c = wmi.WMI() out = True for process in c.Win32_Process(): if "nginx" in process.Name: out = False if out: return {"success": True, "message": u'Nginx is not running'} cmd = 'nginx -s quit' proc = utils_cmd.run_cmd(cmd, cwd=cwd, runas=execAccount) time.sleep(5) for process in c.Win32_Process(): if "nginx" in process.Name: out = False if out: cmd = 'nginx -s stop' outs = utils_cmd.get_output(cmd, cwd=cwd, runas=execAccount) out = "".join(outs) time.sleep(5) for process in c.Win32_Process(): if "nginx" in process.Name: out = False if out: return {"success": False, "message": u'stop nginx fail'} else: return {"success": True, "message": u'Nginx stop success!'} except Exception as e: return {"success": False, "message": 'stop nginx fail:{}'.format(e)} def restart(baseDir=None, jid=None, outputParam=[], execAccount=None, **kwargs): try: ret, param = utils_errors.check_inputs(locals()) if not ret: return {'success': False, 'message': 'input params error,please check input params:{}'.format(param)} cwd = _get_install_path(baseDir) if SYSTEM == "linux": cmd = '{0}/sbin/nginx -s reload'.format(cwd) out, result = __salt__['exec_module.manageService']( SYSTEM, 'nginx', 'service.restart', 'nginx', cmd) else: cmd = 'nginx -s reload' proc = utils_cmd.run_cmd(cmd, cwd=cwd, runas=execAccount) c = wmi.WMI() time.sleep(5) for process in c.Win32_Process(): if "nginx" in process.Name: out = True utils.logger.info('{}'.format(out)) if out: return {"success": True, "message": 'Nginx restart success!'} else: stop(baseDir=baseDir) res = start(baseDir=baseDir) utils.logger.info('{}'.format(res)) if res['success']: return {"success": True, "message": 'Nginx restart success!'} else: return {"success": False, "message": 'restart Nginx fail'} except Exception as e: return {"success": False, "message": 'restart Nginx fail:{}'.format(e)}