1
0
mirror of https://github.com/1C-Company/docker_fresh.git synced 2025-01-10 00:28:38 +02:00
docker_fresh/images/core/dumper.py
2020-04-07 17:03:09 +03:00

174 lines
5.9 KiB
Python

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import glob
import re
import os
import sys
import subprocess
import urllib
import json
import time
import uuid
# define regexps
regex_process_pid = re.compile(r'/([^/.]+?)\.(\d+?)\.(\d+?)\.core')
regex_offset = re.compile(r'#0\s+?([\dxa-f]+?)\s')
regex_extension_replacement = re.compile(r'\.zip$')
regex_extension_replacement2 = re.compile(r'\.core$')
# BEGIN helper functions------------------------------------------------------------------------------------------------
def write_to_log(msg):
msg = time.ctime() + ' ' + msg
print(msg)
def run_shell(cmd):
pipe = subprocess.PIPE
p = subprocess.Popen(cmd, shell=True, stdin=pipe, stdout=pipe, stderr=pipe, close_fds=True, cwd='/')
return p.stdout.read(), p.stderr.read()
def run_shell_get_result(cmd):
result = subprocess.call(cmd, shell=True)
return result
def check_size_static(core_file):
size_1 = os.path.getsize(core_file)
time.sleep(5)
size_2 = os.path.getsize(core_file)
return size_1 == size_2
# END helper functions--------------------------------------------------------------------------------------------------
# BEGIN prepare date----------------------------------------------------------------------------------------------------
def get_pid_process_ctime(core_file):
rez = regex_process_pid.search(core_file)
process = rez.groups()[0]
ctime = rez.groups()[1]
pid = rez.groups()[2]
return process, ctime, pid
def get_platform_offset(core_file, process):
# run gdb for getting offset of core
cmd = 'echo -e "bt\nexit" | gdb /opt/1C/v8.3/x86_64/' + process + ' ' + core_file
(gdb_result, gdb_error) = run_shell(cmd)
if not gdb_result:
offset = '000000000000'
platform = '8.3.0.0000'
write_to_log('cant work with gdb: ' + gdb_error)
else:
rez = regex_offset.search(gdb_result)
if rez is None:
offset = '000000000000'
else:
offset = rez.groups()[0]
offset = offset[6:-1]
# getting platform version
cmd = 'strings /opt/1C/v8.3/x86_64/' + process + """ | grep -oP '[8-9]\.[3-90]\.\d\d?\.\d{2,4}' """
(ver_result, ver_error) = run_shell(cmd)
if ver_result:
platform = ver_result.strip()
else:
platform = '8.3.0.0000'
return platform, offset
def get_creation_date_string(ctime):
ctime_sturct = time.localtime(int(ctime))
ctime_string = '_%.4d%.2d%.2d%.2d%.2d%.2d_' % (ctime_sturct[0], ctime_sturct[1], ctime_sturct[2], ctime_sturct[3],
ctime_sturct[4], ctime_sturct[5])
creation_date = '%.4d-%.2d-%.2dT%.2d:%.2d:%.2d' % (ctime_sturct[0], ctime_sturct[1], ctime_sturct[2],
ctime_sturct[3], ctime_sturct[4], ctime_sturct[5])
return ctime_string, creation_date
def get_file_name(process, platform, offset, ctime_string, pid):
return process + '_' + platform + '_' + offset + ctime_string + pid + '.core'
def get_file_size_hostname(core_file):
file_size = os.path.getsize(core_file)
hostname = os.uname()[1]
return file_size, hostname
def make_libs_tar(core_file, process):
if os.path.exists(libs_file):
os.remove(libs_file)
cmd = """echo -e "info shared\nq" | """
cmd += """ gdb /opt/1C/v8.3/x86_64/""" + process + " " + core_file + """ 2>/dev/null | """
cmd += """ grep 0x0000 | grep -v /opt/1C/v8.3 | grep -v ?? | perl -alne 'print $F[-1]' | """
cmd += """ while read file; do tar --dereference --append -f """ + libs_file + """ $file 2> /dev/null ; done"""
stdout, stderr = run_shell(cmd)
# Если стек не раскрылся, то создадим пустой файл
if not os.path.exists(libs_file):
cmd = 'touch ' + libs_file
run_shell_get_result(cmd)
if stderr:
write_to_log('cant work with gdb and make libs tar, result: ' + str(stderr))
if os.path.getsize(libs_file) == 0:
write_to_log('libs_file size = 0.')
def change_extension(core_gz_file):
core_gz_file = regex_extension_replacement.sub('.tar.gz', core_gz_file)
return regex_extension_replacement2.sub('.tar.gz', core_gz_file)
# END prepare date------------------------------------------------------------------------------------------------------
def gz_core_file(core_file, file_name):
# Костыль, меняем расшинерие на gz
core_gz_file = os.path.basename(file_name)
core_gz_file = change_extension(core_gz_file)
# Зипуем
cmd = 'cd {} && mv {} {} && '.format(cores_dir, core_file, file_name)
cmd += 'tar -czf {} {} {} 2>/dev/null && '.format(core_gz_file, file_name, libs_short_file)
cmd += 'rm -f {} && rm -f {}'.format(file_name, libs_short_file)
rez = run_shell_get_result(cmd)
# Если не получилось загзиповать, то выходим из процедуры
if rez:
write_to_log('cant work with tar')
return
# BEGIN main program ---------------------------------------------------------------------------------------------------
def work_with_dump(core_file):
while not check_size_static(core_file):
print('{} file size: {}'.format(core_file, os.path.getsize(core_file)))
process, ctime, pid = get_pid_process_ctime(core_file)
platform, offset = get_platform_offset(core_file, process)
ctime_string, creation_date = get_creation_date_string(ctime)
make_libs_tar(core_file, process)
file_name = get_file_name(process, platform, offset, ctime_string, pid)
gz_core_file(core_file, file_name)
cores_dir = '/tmp/cores/' # директория в которой должны лежать дампы
libs_short_file = 'libs.tar'
libs_file = os.path.join(cores_dir, 'libs.tar')
if __name__ == "__main__":
# finding core files
cores_path = cores_dir + '*.core*'
for file in glob.glob(cores_path):
work_with_dump(file)