Files
steth/stetho/agent/common/utils.py
2016-01-15 02:03:55 +08:00

169 lines
5.4 KiB
Python

# Copyright 2015 UnitedStack, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import re
import time
import tempfile
import signal
import shlex
import subprocess
import platform
from threading import Timer
from stetho.agent.common import resource
from stetho.agent.common import log
LOG = log.get_logger()
def execute(cmd, shell=False, root=False, timeout=10):
try:
if root:
cmd.insert(0, 'sudo')
LOG.info(cmd)
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=shell)
timer = Timer(timeout, lambda proc: proc.kill(), [subproc])
timer.start()
subproc.wait()
stdcode = subproc.returncode
stdout = subproc.stdout.readlines()
stderr = subproc.stderr.readlines()
timer.cancel()
def list_strip(lines):
return [line.strip() for line in lines]
return stdcode, list_strip(stderr) if stdcode else list_strip(stdout)
except Exception as e:
LOG.error(e)
raise
def execute_wait(cmd, shell=False, root=False):
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=shell)
stdout, stderr = subproc.communicate()
stdcode = subproc.returncode
return stdcode, stdout, stderr
def create_deamon(cmd, shell=False, root=False):
"""Usage:
Create servcice process.
"""
try:
if root:
cmd.insert(0, 'sudo')
LOG.info(cmd)
subproc = subprocess.Popen(cmd, shell=shell, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
return subproc.pid
except Exception as e:
LOG.error(e)
raise
def kill_process_by_id(pid):
pid = int(pid)
os.kill(pid, signal.SIGILL)
os.waitpid(pid, 0)
def get_interface(interface):
"""Support Centos standard physical interface,
such as eth0.
"""
# Supported CentOS Version
supported_dists = ['7.0', '6.5']
def format_centos_7_0(inf):
pattern = r'<([A-Z]+)'
state = re.search(pattern, stdout[0]).groups()[0]
state = 'UP' if not cmp(state, 'UP') else 'DOWN'
inf.state = state
stdout.pop(0)
pattern = r'inet\s(.*)\s\snetmask\s(.*)\s\sbroadcast\s(.*)'
for line in stdout:
if line.startswith('inet '):
tmp = re.search(pattern, line).groups()
(inf.inet, inf.netmask, inf.broadcast) = tmp
stdout.remove(line)
break
for line in stdout:
if line.startswith('ether'):
inf.ether = line[6:23]
break
return stdcode, '', inf.make_dict()
def format_centos_6_5(inf):
pattern = r'HWaddr\s(.*)'
inf.ether = re.search(pattern, stdout[0]).groups()[0]
stdout.pop(0)
pattern = r'addr:(.*)\s\sBcast:(.*)\s\sMask:(.*)'
for line in stdout:
if line.startswith('inet '):
tmp = re.search(pattern, line).groups()
(inf.inet, inf.broadcast, inf.netmask) = tmp
stdout.remove(line)
break
inf.state = 'DOWN'
for line in stdout:
if 'RUNNING' in line:
state = line[:2]
state = 'UP' if not cmp(state, 'UP') else 'DOWN'
inf.state = state
break
return stdcode, '', inf.make_dict()
linux_dist = platform.linux_distribution()[1][:3]
if linux_dist in supported_dists:
try:
cmd = ['ifconfig', interface]
stdcode, stdout = execute(cmd)
inf = resource.Interface(interface)
if not cmp(linux_dist, '6.5'):
return format_centos_6_5(inf)
elif not cmp(linux_dist, '7.0'):
return format_centos_7_0(inf)
except Exception as e:
message = stdout.pop(0)
return stdcode, message, None
# Unsupported OS distribute
message = 'Unsupported OS distribute %s, only support for CentOS %s.'
message = message % (linux_dist, str(supported_dists))
return 1, message, None
def register_api(server, api_obj):
methods = dir(api_obj)
apis = filter(lambda m: not m.startswith('_'), methods)
[server.register_function(getattr(api_obj, api)) for api in apis]
LOG.info("Registered api %s" % apis)
def make_response(code=0, message='', data=dict()):
response = dict()
response['code'] = code
response['message'] = '' if message is None else message
response['data'] = dict() if data is None else data
return response
def replace_file(file_name, mode=0o644):
base_dir = os.path.dirname(os.path.abspath(file_name))
tmp_file = tempfile.NamedTemporaryFile('w+', dir=base_dir, delete=False)
os.chmod(tmp_file.name, mode)
os.rename(tmp_file.name, file_name)