pull/32/merge
Apex Liu 2017-03-24 18:31:09 +00:00
parent bff60a1f74
commit 9b42a75e62
7 changed files with 1734 additions and 60 deletions

View File

@ -24,8 +24,6 @@ class BuilderBase:
def _build_web(self, base_path, dist, target_path):
cc.n('make Teleport Web package...')
# src_path = os.path.join(env.root_path, 'server', 'www', 'teleport')
# pkg_path = os.path.join(env.root_path, 'server', 'www', 'packages')
src_path = os.path.join(env.root_path, 'server', 'www')
pkg_path = os.path.join(src_path, 'packages')
tmp_path = os.path.join(base_path, '_tmp_web_')
@ -33,50 +31,15 @@ class BuilderBase:
if os.path.exists(tmp_path):
utils.remove(tmp_path)
# shutil.copytree(os.path.join(src_path, 'app'), os.path.join(tmp_path, 'app'))
shutil.copytree(os.path.join(src_path, 'teleport'), os.path.join(tmp_path, 'teleport'))
utils.remove(os.path.join(tmp_path, 'teleport', '.idea'))
# pkg_common = os.path.join(pkg_path, 'common')
# _s_path = os.listdir(pkg_common)
# for d in _s_path:
# s = os.path.join(pkg_common, d)
# t = os.path.join(tmp_path, 'app', d)
# if os.path.isdir(s):
# shutil.copytree(s, t)
# else:
# shutil.copy(s, t)
cc.n(' - copy packages...')
utils.copy_ex(pkg_path, os.path.join(tmp_path, 'packages'), 'packages-common')
utils.copy_ex(os.path.join(pkg_path, 'packages-{}'.format(dist)), os.path.join(tmp_path, 'packages', 'packages-{}'.format(dist)), ctx.bits_path)
# pkgs = ['packages-common', 'packages-{}'.format(dist)]
# for d in pkgs:
# s = os.path.join(pkg_path, d)
# t = os.path.join(tmp_path, 'packages', d)
# if os.path.isdir(s):
# shutil.copytree(s, t)
# else:
# shutil.copy(s, t)
makepyo.remove_cache(tmp_path)
# cc.n(' - copy static and view...')
# miscs = ['static', 'view', 'res', 'tools']
# for d in miscs:
# s = os.path.join(src_path, d)
# t = os.path.join(tmp_path, d)
# if os.path.isdir(s):
# shutil.copytree(s, t)
# else:
# shutil.copy(s, t)
# if not os.path.exists(os.path.join(tmp_path, 'static', 'download')):
# utils.makedirs(os.path.join(tmp_path, 'static', 'download'))
# utils.copy_file(os.path.join(env.root_path, 'dist'), os.path.join(tmp_path, 'static', 'download'), 'teleport-assist-win.zip')
shutil.copytree(tmp_path, os.path.join(target_path, 'www'))
utils.remove(tmp_path)
@ -110,7 +73,6 @@ class BuilderWin(BuilderBase):
utils.copy_ex(out_path, bin_path, 'tp_web.exe')
utils.copy_ex(out_path, bin_path, 'tp_core.exe')
utils.copy_ex(out_path, bin_path, 'tpssh.dll')
# utils.copy_ex(out_path, bin_path, 'pysrt')
utils.copy_ex(os.path.join(env.root_path, 'out', 'pysrt'), bin_path, (ctx.dist_path, 'pysrt'))
@ -130,11 +92,14 @@ class BuilderLinux(BuilderBase):
def __init__(self):
super().__init__()
self.name = 'teleport-server-linux-{}-{}'.format(ctx.bits_path, VER_TELEPORT_SERVER)
self._final_file = os.path.join(env.root_path, 'out', 'installer', '{}.tar.gz'.format(self.name))
self.dist_path = os.path.join(env.root_path, 'dist', ctx.dist, 'server')
self.base_path = os.path.join(env.root_path, 'out', 'installer', 'server')
self.base_path = os.path.join(env.root_path, 'out', 'installer')
self.base_tmp = os.path.join(self.base_path, '_tmp_')
self.tmp_path = os.path.join(self.base_tmp, self.name, 'data', 'teleport')
self.path_tmp = os.path.join(self.base_tmp, self.name)
self.path_tmp_data = os.path.join(self.path_tmp, 'data')
# self.server_path = os.path.join(env.root_path, 'dist', 'installer', ctx.dist, 'server')
# self.script_path = self.tmp_path = os.path.join(self.server_path, 'script')
@ -147,11 +112,11 @@ class BuilderLinux(BuilderBase):
if os.path.exists(self.base_tmp):
utils.remove(self.base_tmp)
self._build_web(self.base_path, 'linux', self.tmp_path)
self._build_web(self.base_path, 'linux', self.path_tmp_data)
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), ('web.ini.in', 'web.ini'))
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), ('core.ini.in', 'core.ini'))
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), 'tp_ssh_server.key')
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), ('web.ini.in', 'web.ini'))
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), ('core.ini.in', 'core.ini'))
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), 'tp_ssh_server.key')
# out_path = os.path.join(env.root_path, 'out', 'eom_ts', ctx.target_path, ctx.dist_path)
# out_path = os.path.join(env.root_path, 'out', 'eom_ts', ctx.bits_path, 'bin')
@ -159,7 +124,7 @@ class BuilderLinux(BuilderBase):
# utils.copy_file(out_path, bin_path, 'eom_ts')
out_path = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, 'bin')
bin_path = os.path.join(self.tmp_path, 'bin')
bin_path = os.path.join(self.path_tmp_data, 'bin')
utils.copy_ex(out_path, bin_path, 'tp_web')
utils.copy_ex(out_path, bin_path, 'tp_core')
utils.copy_ex(out_path, bin_path, 'libtpssh.so')
@ -171,30 +136,38 @@ class BuilderLinux(BuilderBase):
# utils.copy_ex(os.path.join(env.root_path, 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), 'ssl')
# utils.copy_ex(os.path.join(env.root_path, 'share', 'data'), os.path.join(self.tmp_path, 'tmp', 'data'), ('ts_db_release.db', 'ts_db.db'))
utils.copy_ex(os.path.join(env.root_path, 'server', 'share', 'data'), os.path.join(self.tmp_path, 'tmp', 'data'), 'main.sql')
# utils.copy_ex(os.path.join(env.root_path, 'server', 'share', 'data'), os.path.join(self.tmp_path, 'tmp', 'data'), 'main.sql')
# utils.make_zip(self.tmp_path, os.path.join(self.tmp_path, '..', 'eom_ts.zip'))
utils.make_targz(os.path.join(self.tmp_path, '..'), 'teleport', 'teleport.tar.gz')
utils.remove(self.tmp_path)
# utils.make_targz(os.path.join(self.tmp_path, '..'), 'teleport', 'teleport.tar.gz')
# utils.remove(self.tmp_path)
# make final installer.
cc.n('pack final server installer...')
# cc.n('pack final server installer...')
# out_file = os.path.join(env.root_path, 'dist', '{}.zip'.format(self.name))
out_file = os.path.join(env.root_path, 'out', 'installer', '{}.tar.gz'.format(self.name))
# out_file = os.path.join(env.root_path, 'out', 'installer', '{}.tar.gz'.format(self.name))
if os.path.exists(out_file):
utils.remove(out_file)
# if os.path.exists(out_file):
# utils.remove(out_file)
# # copy installer scripts.
for i in ['daemon', 'start.sh', 'stop.sh', 'status.sh']:
# for i in ['daemon_web', 'daemon_core', 'teleport.sh']:
shutil.copy(os.path.join(self.dist_path, 'script', i), os.path.abspath(os.path.join(self.tmp_path, '..', i)))
for i in ['install.sh', 'uninst.sh']:
shutil.copy(os.path.join(self.dist_path, 'script', i), os.path.abspath(os.path.join(self.tmp_path, '..', '..', i)))
# for i in ['daemon', 'start.sh', 'stop.sh', 'status.sh']:
# # for i in ['daemon_web', 'daemon_core', 'teleport.sh']:
# shutil.copy(os.path.join(self.dist_path, 'script', i), os.path.abspath(os.path.join(self.tmp_path, '..', i)))
# for i in ['install.sh', 'uninst.sh']:
# shutil.copy(os.path.join(self.dist_path, 'script', i), os.path.abspath(os.path.join(self.tmp_path, '..', '..', i)))
# 复制安装所需的脚本
utils.copy_ex(os.path.join(self.dist_path, 'script'), self.path_tmp, 'install.sh')
utils.copy_ex(os.path.join(self.dist_path, 'script'), self.path_tmp, 'uninst.sh')
utils.copy_ex(os.path.join(self.dist_path, 'script'), self.path_tmp, 'script')
utils.copy_ex(os.path.join(self.dist_path, 'script'), self.path_tmp, 'daemon')
# utils.make_zip(os.path.join(self.base_tmp, self.name), out_file)
utils.make_targz(self.base_tmp, self.name, out_file)
if os.path.exists(self._final_file):
utils.remove(self._final_file)
utils.make_targz(self.base_tmp, self.name, self._final_file)
# utils.remove(self.base_tmp)

View File

@ -40,8 +40,8 @@ def _check_download_file(file_name):
if 'Everything is Ok' in output:
return True
else:
cc.e('fixme.')
return False
cc.w('[fixme] how to check file on Linux?')
return True
def download_file(desc, url, target_path, file_name):

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-

View File

@ -0,0 +1,476 @@
# -*- coding: utf-8 -*-
import os
import sys
import platform
import traceback
__all__ = ['o', 'v', 'i', 'w', 'e', 'f']
# ======================================
# 颜色
# ======================================
CR_RESTORE = 0 # 恢复正常 - 浅灰色
# BOLD = "[1m" # 高亮显示
# UNDERSCORE = "[4m" # 下划线
# REVERSE = "[7m" # 反白显示
CR_BLACK = 1 # 黑色
CR_LIGHT_GRAY = 2 # 浅灰色 - 普通文字
CR_GRAY = 3 # 深灰色 - 捕获别的命令的输出
CR_WHITE = 4 # 白色
CR_RED = 5 # 红色
CR_GREEN = 6 # 绿色
CR_YELLOW = 7 # 黄色 - Windows平台称之为棕色(Brown)
CR_BLUE = 8 # 蓝色
CR_MAGENTA = 9 # 紫红
CR_CYAN = 10 # 青色
CR_LIGHT_RED = 11 # 亮红色 - 失败
CR_LIGHT_GREEN = 12 # 亮绿色 - 成功
CR_LIGHT_YELLOW = 13 # 亮黄色 - 重要
CR_LIGHT_BLUE = 14 # 亮蓝色 - 其实在黑色背景上还是比较深
CR_LIGHT_MAGENTA = 15 # 亮紫色 - 警告
CR_LIGHT_CYAN = 16 # 亮青色
CR_VERBOSE = CR_LIGHT_GRAY
CR_NORMAL = CR_WHITE
CR_INFO = CR_GREEN
CR_WARN = CR_LIGHT_YELLOW
CR_ERROR = CR_LIGHT_RED
COLORS = {
# 常量定义 Linux色彩 WinConsole色彩
CR_RESTORE: ('[0m', 7), # 7 = 浅灰色 - 普通文字
CR_BLACK: ('[0;30m', 0), # 0 = 黑色
CR_RED: ("[0;31m", 4), # 红色
CR_GREEN: ("[0;32m", 2), # 绿色
CR_YELLOW: ("[0;33m", 6), # 黄色 - Windows平台称之为棕色(Brown)
CR_BLUE: ("[0;34m", 1), # 蓝色
CR_MAGENTA: ("[0;35m", 5), # 紫红
CR_CYAN: ("[0;36m", 3), # 青色
CR_LIGHT_GRAY: ('[0;37m', 7), # 浅灰色 - 普通文字
CR_GRAY: ("[1;30m", 8), # 深灰色 - 捕获别的命令的输出
CR_LIGHT_RED: ("[1;31m", 12), # 亮红色 - 失败
CR_LIGHT_GREEN: ("[1;32m", 10), # 亮绿色 - 成功
CR_LIGHT_YELLOW: ("[1;33m", 14), # 亮黄色 - 重要
CR_LIGHT_BLUE: ("[1;34m", 9), # 亮蓝色 - 其实在黑色背景上还是比较深
CR_LIGHT_MAGENTA: ("[1;35m", 13), # 亮紫色 - 警告
CR_LIGHT_CYAN: ("[1;36m", 11), # 亮青色
CR_WHITE: ("[1;37m", 15) # 白色
}
class ColorConsole:
"""
:type _win_color : Win32ColorConsole
"""
def __init__(self):
# self._log_console = self._console_default # 输出到控制台的方式为None时表示不输出到控制台
# self._console_set_color = self._console_set_color_default
self._sep = ' '
self._end = '\n'
self._win_color = None
self.o = self._func_output
self.v = self._func_verbose
self.n = self._func_normal
self.i = self._func_info
self.w = self._func_warn
self.e = self._func_error
self.f = self._func_fail
if sys.stdout is None:
self.o = self._func_pass
self.v = self._func_pass
self.n = self._func_pass
self.i = self._func_pass
self.w = self._func_pass
self.e = self._func_pass
self.f = self._func_pass
# self._log_console = self._func_pass
# self._console_set_color = self._console_set_color_default
else:
# python2.7 on Ubuntu, sys.platform is 'linux2', so we use platform.system() instead.
_platform = platform.system().lower()
if _platform == 'linux' or _platform == 'darwin':
self._console_set_color = self._console_set_color_linux
self._console_restore_color = self._console_restore_color_linux
elif _platform == 'windows':
if 'TERM' in os.environ and os.environ['TERM'] in ['xterm']:
self._console_set_color = self._console_set_color_linux
self._console_restore_color = self._console_restore_color_linux
else:
self._win_color = Win32ColorConsole()
if self._win_color.available():
self._console_set_color = self._console_set_color_win
self._console_restore_color = self._console_restore_color_win
else:
self._console_set_color = self._func_pass
self._console_restore_color = self._func_pass
def set_default(self, *args, **kwargs):
if 'sep' in kwargs:
self._sep = kwargs['sep']
if 'end' in kwargs:
self._end = kwargs['end']
def _func_pass(self, *args, **kwargs):
# do nothing.
pass
def _func_output(self, *args, **kwargs):
sep = kwargs['sep'] if 'sep' in kwargs else self._sep
end = kwargs['end'] if 'end' in kwargs else self._end
first = True
for x in args:
if not first:
sys.stdout.writelines(sep)
if isinstance(x, tuple):
cl = x[0]
z = x[1:]
self._console_set_color(cl)
self._console_output(*z, sep='', end='')
sys.stdout.flush()
elif isinstance(x, str):
self._console_output(x, sep='', end='')
sys.stdout.flush()
else:
raise RuntimeError('Invalid param.')
sys.stdout.writelines(end)
self._console_restore_color()
sys.stdout.flush()
def _func_verbose(self, *args, **kwargs):
self._console_set_color(CR_VERBOSE)
self._console_output(*args, **kwargs)
self._console_restore_color()
sys.stdout.flush()
# 普通的日志数据
def _func_normal(self, *args, **kwargs):
self._console_set_color(CR_NORMAL)
self._console_output(*args, **kwargs)
self._console_restore_color()
sys.stdout.flush()
# 重要信息
def _func_info(self, *args, **kwargs):
self._console_set_color(CR_INFO)
self._console_output(*args, **kwargs)
self._console_restore_color()
sys.stdout.flush()
# 警告
def _func_warn(self, *args, **kwargs):
self._console_set_color(CR_WARN)
self._console_output(*args, **kwargs)
self._console_restore_color()
sys.stdout.flush()
def _func_error(self, *args, **kwargs):
self._console_set_color(CR_ERROR)
self._console_output(*args, **kwargs)
self._console_restore_color()
sys.stdout.flush()
def _func_fail(self, *args, **kwargs):
self._console_set_color(CR_ERROR)
self._console_output('[FAIL] ', end='')
self._console_output(*args, **kwargs)
_type, _value, _tb = sys.exc_info()
if _type is not None:
x = traceback.format_exception_only(_type, _value)
self._console_output('[EXCEPTION] ', end='')
self._console_output(x[0], end='')
x = traceback.extract_tb(_tb)
c = len(x)
self._console_set_color(CR_RED)
for i in range(0, c):
self._console_output(os.path.abspath(x[i][0]), '(', x[i][1], '): ', x[i][3], sep='')
else:
s = traceback.extract_stack()
c = len(s)
self._console_set_color(CR_RED)
for i in range(2, c):
self._console_output(' ', os.path.abspath(s[c - i - 1][0]), '(', s[c - i - 1][1], '): ', s[c - i - 1][3], sep='')
self._console_restore_color()
sys.stdout.flush()
# def _do_log(self, msg, color=None):
# self._log_console(msg, color)
#
# def _console_default(self, msg, color=None):
# if msg is None:
# return
#
# sys.stdout.writelines(msg)
# sys.stdout.flush()
#
# def _console_win(self, msg, color=None):
# if msg is None:
# return
#
# # 这里的问题很复杂,日常使用没有问题,但是当在工作机上使用时,部分内容是捕获另一个脚本执行的结果再输出
# # 如果结果中有中文,这里就会显示乱码。如果尝试编码转换,会抛出异常。目前暂时采用显示乱码的方式了。
#
# # if CONSOLE_WIN_CMD == self.console_type:
# # try:
# # _msg = unicode(msg, 'utf-8')
# # except:
# # _msg = msg
# # else:
# # _msg = msg
# # _msg = None
# # if isinstance(msg, unicode):
# # _msg = msg
# # else:
# # # _msg = unicode(msg, 'utf-8')
# # try:
# # _msg = unicode(msg, 'utf-8')
# # except:
# # _msg = unicode(msg, 'gb2312')
# # # _msg = msg
# #
# # # if CONSOLE_WIN_CMD == self.console_type:
# # # sys.stdout.writelines(msg.encode('gb2312'))
# # # else:
# # # sys.stdout.writelines(msg.encode('utf-8'))
# #
# #
# # # try:
# # # _msg = unicode(msg, 'utf-8')
# # # except:
# # _msg = msg
#
# if color is None:
# sys.stdout.writelines(msg)
# else:
# self._win_color.set_color(COLORS[color][1])
# sys.stdout.writelines(msg)
# sys.stdout.flush()
# self._win_color.set_color(COLORS[CR_RESTORE][1])
#
# sys.stdout.flush()
#
# def _console_linux(self, msg, cr=None):
# if msg is None:
# return
#
# if cr is None:
# sys.stdout.writelines(msg)
# else:
# sys.stdout.writelines('\x1B')
# sys.stdout.writelines(COLORS[cr][0])
# sys.stdout.writelines(msg)
# sys.stdout.writelines('\x1B[0m')
#
# sys.stdout.flush()
# def _console_set_color_default(self, cr=None):
# pass
def _console_set_color_win(self, cr=None):
if cr is None:
return
self._win_color.set_color(COLORS[cr][1])
sys.stdout.flush()
def _console_set_color_linux(self, cr=None):
if cr is None:
return
sys.stdout.writelines('\x1B')
sys.stdout.writelines(COLORS[cr][0])
sys.stdout.flush()
def _console_restore_color_win(self):
self._win_color.set_color(COLORS[CR_RESTORE][1])
sys.stdout.flush()
def _console_restore_color_linux(self):
sys.stdout.writelines('\x1B[0m')
sys.stdout.flush()
def _console_output(self, *args, **kwargs):
sep = kwargs['sep'] if 'sep' in kwargs else self._sep
end = kwargs['end'] if 'end' in kwargs else self._end
first = True
for x in args:
if not first:
sys.stdout.writelines(sep)
first = False
if isinstance(x, str):
sys.stdout.writelines(x)
continue
else:
sys.stdout.writelines(x.__str__())
sys.stdout.writelines(end)
sys.stdout.flush()
# def _test(self):
# self.log('###################', CR_RESTORE)
# self.log(' CR_RESTORE\n')
# self.log('###################', CR_BLACK)
# self.log(' CR_BLACK\n')
# self.log('###################', CR_LIGHT_GRAY)
# self.log(' CR_LIGHT_GRAY\n')
# self.log('###################', CR_GRAY)
# self.log(' CR_GRAY\n')
# self.log('###################', CR_WHITE)
# self.log(' CR_WHITE\n')
# self.log('###################', CR_RED)
# self.log(' CR_RED\n')
# self.log('###################', CR_GREEN)
# self.log(' CR_GREEN\n')
# self.log('###################', CR_YELLOW)
# self.log(' CR_YELLOW\n')
# self.log('###################', CR_BLUE)
# self.log(' CR_BLUE\n')
# self.log('###################', CR_MAGENTA)
# self.log(' CR_MAGENTA\n')
# self.log('###################', CR_CYAN)
# self.log(' CR_CYAN\n')
# self.log('###################', CR_LIGHT_RED)
# self.log(' CR_LIGHT_RED\n')
# self.log('###################', CR_LIGHT_GREEN)
# self.log(' CR_LIGHT_GREEN\n')
# self.log('###################', CR_LIGHT_YELLOW)
# self.log(' CR_LIGHT_YELLOW\n')
# self.log('###################', CR_LIGHT_BLUE)
# self.log(' CR_LIGHT_BLUE\n')
# self.log('###################', CR_LIGHT_MAGENTA)
# self.log(' CR_LIGHT_MAGENTA\n')
# self.log('###################', CR_LIGHT_CYAN)
# self.log(' CR_LIGHT_CYAN\n')
# # data = b'This is a test string and you can see binary format data here.'
# # self.bin('Binary Data:\n', data)
# # data = b''
# # self.bin('Empty binary\n', data)
# # self.bin('This is string\n\n', 'data')
#
# # self.d('This is DEBUG message.\n')
# self.v('This is VERBOSE message.\n')
# self.i('This is INFORMATION message.\n')
# self.w('This is WARNING message.\n')
# self.e('This is ERROR message.\n')
# self.f('This is FAIL message.\n')
#
# self.v('test auto\nsplit lines.\nYou should see\nmulti-lines.\n')
class Win32ColorConsole:
def __init__(self):
from ctypes import WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HANDLE, DWORD, WORD
self.__original_stderr = sys.stderr
self.__stdout = None
self.__SetConsoleTextAttribute = None
# Work around <http://bugs.python.org/issue6058>.
# codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
# Make Unicode console output work independently of the current code page.
# This also fixes <http://bugs.python.org/issue1602>.
# Credit to Michael Kaplan <http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx>
# and TZOmegaTZIOY
# <http://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>.
try:
# <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx>
# HANDLE WINAPI GetStdHandle(DWORD nStdHandle);
# returns INVALID_HANDLE_VALUE, NULL, or a valid handle
#
# <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx>
# DWORD WINAPI GetFileType(DWORD hFile);
#
# <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx>
# BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode);
STD_OUTPUT_HANDLE = DWORD(-11)
INVALID_HANDLE_VALUE = DWORD(-1).value
GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32))
self.__SetConsoleTextAttribute = WINFUNCTYPE(BOOL, HANDLE, WORD)(("SetConsoleTextAttribute", windll.kernel32))
self.__stdout = GetStdHandle(STD_OUTPUT_HANDLE)
if self.__stdout == INVALID_HANDLE_VALUE:
self.__stdout = None
except Exception as e:
self.__stdout = None
self._complain("exception %r while fixing up sys.stdout and sys.stderr\n" % (str(e),))
# If any exception occurs in this code, we'll probably try to print it on stderr,
# which makes for frustrating debugging if stderr is directed to our wrapper.
# So be paranoid about catching errors and reporting them to original_stderr,
# so that we can at least see them.
@staticmethod
def _complain(message):
# print >> self.__original_stderr, message if isinstance(message, str) else repr(message)
sys.stderr.writelines(message)
def available(self):
if self.__stdout is None or self.__SetConsoleTextAttribute is None:
return False
else:
return True
def set_color(self, color):
# if not self.available():
# return
self.__SetConsoleTextAttribute(self.__stdout, color)
_cc = ColorConsole()
del ColorConsole
def set_default(*args, **kwargs):
_cc.set_default(*args, **kwargs)
def o(*args, **kwargs):
_cc.o(*args, **kwargs)
def v(*args, **kwargs):
_cc.v(*args, **kwargs)
def n(*args, **kwargs):
_cc.n(*args, **kwargs)
def i(*args, **kwargs):
_cc.i(*args, **kwargs)
def w(*args, **kwargs):
_cc.w(*args, **kwargs)
def e(*args, **kwargs):
_cc.e(*args, **kwargs)
def f(*args, **kwargs):
_cc.f(*args, **kwargs)

View File

@ -0,0 +1,214 @@
# -*- coding: utf8 -*-
import os
import platform
import sys
import configparser
from . import colorconsole as cc
if platform.system().lower() == 'windows':
try:
import winreg
except ImportError:
cc.e('Can not load module `winreg`, so I can not locate toolchain for you.')
class Env(object):
BITS_32 = 32
BITS_64 = 64
def __init__(self):
_this_path = os.path.abspath(os.path.dirname(__file__))
self.root_path = os.path.abspath(os.path.join(_this_path, '..', '..'))
self.src_path = os.path.join(self.root_path, 'data')
self.bits = self.BITS_32
self.bits_str = 'x86'
_bits = platform.architecture()[0]
if _bits == '64bit':
self.bits = self.BITS_64
self.bits_str = 'x64'
self.is_win = False
self.is_win_x64 = False
self.is_linux = False
self.is_macos = False
_os = platform.system().lower()
self.plat = ''
if _os == 'windows':
self.is_win = True
self.plat = 'windows'
self.is_win_x64 = 'PROGRAMFILES(X86)' in os.environ
elif _os == 'linux':
self.is_linux = True
self.plat = 'linux'
elif _os == 'darwin':
self.is_macos = True
self.plat = 'macos'
def init(self, warn_miss_tool=False):
# if not self._load_config(warn_miss_tool):
# return False
return True
def _load_config(self, warn_miss_tool):
_cfg_file = os.path.join(self.root_path, 'config.ini')
if not os.path.exists(_cfg_file):
cc.e('can not load configuration.\n\nplease copy `config.ini.in` into `config.ini` and modify it to fit your condition and try again.')
return False
_cfg = configparser.ConfigParser()
_cfg.read(_cfg_file)
if 'external_ver' not in _cfg.sections() or 'toolchain' not in _cfg.sections():
cc.e('invalid configuration file: need `external_ver` and `toolchain` section.')
return False
_tmp = _cfg['external_ver']
try:
_v_openssl = _tmp['openssl'].split(',')
self.ver_openssl = _v_openssl[0].strip()
self.ver_openssl_number = _v_openssl[1].strip()
self.ver_libuv = _tmp['libuv']
self.ver_mbedtls = _tmp['mbedtls']
self.ver_sqlite = _tmp['sqlite']
self.ver_libssh = _tmp['libssh']
self.ver_jsoncpp = _tmp['jsoncpp']
self.ver_mongoose = _tmp['mongoose']
except KeyError:
cc.e('invalid configuration file: not all necessary external version are set.')
return False
_tmp = _cfg['toolchain']
if self.is_win:
if 'wget' in _tmp:
self.wget = _tmp['wget']
else:
self.wget = None
if self.wget is None or not os.path.exists(self.wget):
if warn_miss_tool:
cc.w(' - can not find `wget.exe`, you can get it at https://eternallybored.org/misc/wget/')
if '7z' in _tmp:
self.zip7 = _tmp['7z']
else:
self.zip7 = None
if self.zip7 is None or not os.path.exists(self.zip7):
if warn_miss_tool:
cc.w(' - can not find `7z.exe`, you can get it at http://www.7-zip.org')
if 'nasm' in _tmp:
self.nasm = _tmp['nasm']
else:
self.nasm = self._get_nasm()
if self.nasm is None or not os.path.exists(self.nasm):
if warn_miss_tool:
cc.w(' - can not locate `nasm`, so I can build openssl.')
if 'perl' in _tmp:
self.perl = _tmp['perl']
else:
self.perl = self._get_perl()
if self.perl is None or not os.path.exists(self.perl):
if warn_miss_tool:
cc.w(' - can not locate `perl`, so I can build openssl.')
self.visual_studio_path = self._get_visual_studio_path()
if self.visual_studio_path is None or not os.path.exists(self.visual_studio_path):
if warn_miss_tool:
cc.w(' - can not locate Visual Studio installation, so I can build openssl.')
if 'msbuild' in _tmp:
self.msbuild = _tmp['msbuild']
else:
self.msbuild = self._get_msbuild()
if self.msbuild is None or not os.path.exists(self.msbuild):
if warn_miss_tool:
cc.w(' - can not locate `MSBuild`, so I can build nothing.')
if 'nsis' in _tmp:
self.nsis = _tmp['nsis']
else:
self.nsis = self._get_nsis()
if self.nsis is None or not os.path.exists(self.nsis):
if warn_miss_tool:
cc.w(' - can not locate `nsis`, so I can not make installer.')
elif self.is_linux:
if 'cmake' in _tmp:
self.cmake = _tmp['cmake']
else:
self.cmake = '/usr/bin/cmake'
if not os.path.exists(self.cmake):
if warn_miss_tool:
cc.e(' - can not locate `cmake`, so I can not build binary from source.')
return True
def _get_msbuild(self):
# 14.0 = VS2015
# 12.0 = VS2012
# 4.0 = VS2008
chk = ['14.0', '12.0', '4.0']
p = None
for c in chk:
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\{}'.format(c), r'MSBuildToolsPath')
if p is not None:
break
return os.path.join(p[0], 'MSBuild.exe') if p is not None else None
def _get_visual_studio_path(self):
chk = ['14.0', '12.0', '4.0']
p = None
for c in chk:
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\VisualStudio\{}'.format(c), r'ShellFolder')
if p is not None:
break
return p[0] if p is not None else None
def _get_perl(self):
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\perl', 'BinDir')
return p[0] if p is not None else None
def _get_nasm(self):
p = self._winreg_read(winreg.HKEY_CURRENT_USER, r'SOFTWARE\nasm', '')
return os.path.join(p[0], 'nasm.exe') if p is not None else None
def _get_nsis(self):
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\NSIS\Unicode', '')
if p is None:
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\NSIS', '')
return os.path.join(p[0], 'makensis.exe') if p is not None else None
def _winreg_read(self, base, path, key):
try:
if self.is_win_x64:
hkey = winreg.CreateKeyEx(base, path, 0, winreg.KEY_READ | winreg.KEY_WOW64_32KEY)
else:
hkey = winreg.CreateKeyEx(base, path, 0, winreg.KEY_READ)
value = winreg.QueryValueEx(hkey, key)
return value
except OSError:
return None
env = Env()
del Env
if __name__ == '__main__':
pass

View File

@ -0,0 +1,290 @@
# -*- coding: utf8 -*-
import os
import platform
import shutil
import subprocess
import sys
import time
from . import colorconsole as cc
from .env import env
# from .configs import cfg
# try:
# CONFIG_FILE = os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')), 'config.ini')
# if not cfg.init(CONFIG_FILE):
# sys.exit(1)
# except:
# cc.e('can not load configuration.\n\nplease copy `config.ini.in` into `config.ini` and modify it to fit your condition and try again.')
# sys.exit(1)
# THIS_PATH = os.path.abspath(os.path.dirname(__file__))
# ROOT_PATH = os.path.abspath(os.path.join(THIS_PATH, '..'))
# def _check_download_file(file_name):
# if env.is_win:
# # use 7z to test integrity of downloaded
# ret, output = sys_exec('"{}" t "{}"'.format(env.zip7, file_name), False)
# if 'Everything is Ok' in output:
# return True
# else:
# cc.e('fixme.')
# return False
#
#
# def download_file(desc, url, target_path, file_name):
# cc.n('download {} ... '.format(desc), end='')
#
# local_file_name = os.path.join(target_path, file_name)
# if os.path.exists(local_file_name):
# if not _check_download_file(local_file_name):
# cc.w('already exists but broken, download it again...')
# else:
# cc.w('already exists, skip.')
# return True
#
# cc.v('')
# # 因为下载过程会在命令行显示进度所以不能使用subprocess.Popen()的方式捕获输出,会很难看!
# if env.is_win:
# cmd = '""{}" --no-check-certificate {} -O "{}""'.format(env.wget, url, local_file_name)
# os.system(cmd)
# elif env.is_linux:
# os.system('wget --no-check-certificate {} -O "{}"'.format(url, local_file_name))
# else:
# return False
#
# if not os.path.exists(local_file_name) or not _check_download_file(local_file_name):
# cc.e('downloading {} from {} failed.'.format(desc, url))
# return False
#
# return True
#
# def extension_suffixes():
# # imp.get_suffixes()
# # 返回3元组列表(suffix, mode, type), 获得特殊模块的描述
# # .suffix为文件后缀名;
# # mode为打开文件模式;
# # type为文件类型, 1代表PY_SOURCE, 2代表PY_COMPILED, 3代表C_EXTENSION
#
# EXTENSION_SUFFIXES = list()
# if cfg.is_py2:
# suf = imp.get_suffixes()
# for s in suf:
# if s[2] == 3:
# EXTENSION_SUFFIXES.append(s[0])
# else:
# EXTENSION_SUFFIXES = importlib.machinery.EXTENSION_SUFFIXES
#
# if cfg.dist == 'windows':
# if '.dll' not in EXTENSION_SUFFIXES:
# EXTENSION_SUFFIXES.append('.dll')
#
# elif cfg.dist == 'linux':
# if '.so' not in EXTENSION_SUFFIXES:
# EXTENSION_SUFFIXES.append('.so')
#
# elif cfg.dist == 'macos':
# raise RuntimeError('not support MacOS now.')
#
# return EXTENSION_SUFFIXES
def remove(*args):
path = os.path.join(*args)
cc.v(' - remove [%s] ... ' % path, end='')
if not os.path.exists(path):
cc.v('not exists, skip.')
return
for i in range(5):
cc.v('.', end='')
try:
if os.path.isdir(path):
shutil.rmtree(path, ignore_errors=True)
time.sleep(0.5)
else:
os.unlink(path)
except:
pass
if os.path.exists(path):
time.sleep(1)
else:
break
if os.path.exists(path):
cc.e('[failed]')
raise RuntimeError('')
else:
cc.i('[done]')
def makedirs(path, exist_ok=True):
if os.path.exists(path):
if not exist_ok:
raise RuntimeError('path already exists: %s' % path)
else:
return
for i in range(5):
try:
os.makedirs(path)
except:
time.sleep(1)
pass
if not os.path.exists(path):
time.sleep(1)
else:
break
if not os.path.exists(path):
raise RuntimeError('can not create: %s' % path)
# def copy_file(s_path, t_path, f_name, force=True):
# if isinstance(f_name, str):
# f_from = f_name
# f_to = f_name
# elif isinstance(f_name, tuple):
# f_from = f_name[0]
# f_to = f_name[1]
# else:
# raise RuntimeError('utils.copy_file() got invalid param.')
#
# s = os.path.join(s_path, f_from)
# t = os.path.join(t_path, f_to)
# if os.path.exists(t):
# if force:
# cc.v(' an exists version found, clean up...')
# remove(t)
# else:
# cc.w(' an exists version found, skip copy.')
# return
#
# if not os.path.exists(t_path):
# makedirs(t_path)
# cc.v('copy [%s]\n -> [%s]' % (s, t))
# shutil.copy(s, t)
def copy_ex(s_path, t_path, item_name=None, force=True):
if item_name is None:
s = s_path
t = t_path
else:
if isinstance(item_name, str):
f_from = item_name
f_to = item_name
elif isinstance(item_name, tuple):
f_from = item_name[0]
f_to = item_name[1]
else:
raise RuntimeError('utils.copy_ex() got invalid param.')
s = os.path.join(s_path, f_from)
t = os.path.join(t_path, f_to)
if os.path.exists(t):
if force:
remove(t)
else:
cc.w(t, 'already exists, skip copy.')
return
if os.path.isdir(s):
cc.v(' - copy [%s]\n -> [%s]' % (s, t))
shutil.copytree(s, t)
else:
if not os.path.exists(t_path):
os.makedirs(t_path)
cc.v(' - copy [%s]\n -> [%s]' % (s, t))
shutil.copy(s, t)
# def update_file(s_path, t_path, f_name):
# if isinstance(f_name, str):
# f_from = f_name
# f_to = f_name
# elif isinstance(f_name, tuple):
# f_from = f_name[0]
# f_to = f_name[1]
# else:
# raise RuntimeError('utils.update_file() got invalid param.')
#
# s = os.path.join(s_path, f_from)
# t = os.path.join(t_path, f_to)
# if not os.path.exists(s):
# cc.w('try update file `%s` but not exists, skip.' % f_from)
# return
#
# # TODO: check file MD5 and update time.
#
# if os.path.exists(t):
# remove(t)
#
# if not os.path.exists(t_path):
# makedirs(t_path)
# cc.v('update [%s]\n -> [%s]' % (s, t))
# shutil.copy(os.path.join(s_path, f_from), t)
def ensure_file_exists(filename):
if not os.path.exists(filename):
raise RuntimeError('file not exists: {}'.format(filename))
if not os.path.isfile(filename):
raise RuntimeError('path exists but not a file: {}'.format(filename))
# def root_path():
# return os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
# def python_exec():
# if not os.path.exists(sys.executable):
# raise RuntimeError('Can not locate Python execute file.')
# return sys.executable
def sys_exec(cmd, direct_output=False, output_codec=None):
if output_codec is None:
if env.is_win:
output_codec = 'gb2312'
else:
output_codec = 'utf8'
p = None
if env.is_win:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True)
else:
p = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True)
output = list()
f = p.stdout
while True:
line = f.readline()
if 0 == len(line):
break
line = line.rstrip('\r\n')
if direct_output:
cc.o((cc.CR_GRAY, line), end='\n')
output.append(line)
ret = p.wait()
return ret, output
if __name__ == '__main__':
# test()
pass

719
dist/linux/server/script/script/main.py vendored Normal file
View File

@ -0,0 +1,719 @@
# -*- coding: utf-8 -*-
import os
import sys
import time
from core.env import env
import core.colorconsole as cc
import core.utils as utils
WIN_CORE_SERVICE_NAME = 'EOM Teleport Core Service'
WIN_WEB_SERVICE_NAME = 'EOM Teleport Web Service'
class InstallerBase:
def __init__(self):
self._all_ok = True
self._err_msg = list()
self._is_installed = False
self._install_path = ''
self._config_path = ''
self._data_path = ''
self._log_path = ''
self._installed_ver_str = 'UNKNOWN'
self._current_ver = 'UNKNOWN'
self._def_install_path = ''
ver_file = os.path.join(env.root_path, 'data', 'www', 'teleport', 'app', 'eom_ver.py')
try:
with open(ver_file, 'r') as f:
x = f.readlines()
for i in x:
s = i.split('=', 1)
if 'TS_VER' == s[0].strip():
self._current_ver = s[1].strip()[1:-1]
break
except FileNotFoundError:
raise RuntimeError('Cannot detect installer version.')
def init(self):
_width = 79
cc.v('')
cc.v('[]{}[]'.format('=' * (_width - 4)))
_str = 'Teleport Server Installation'
cc.o((cc.CR_VERBOSE, ' | '), (cc.CR_INFO, _str), (cc.CR_VERBOSE, '{}|'.format(' ' * (_width - 5 - len(_str)))))
cc.v(' |{}|'.format('=' * (_width - 4)))
cc.o((cc.CR_VERBOSE, ' | ver: '), (cc.CR_NORMAL, self._current_ver), (cc.CR_VERBOSE, '{}|'.format(' ' * (_width - 13 - len(self._current_ver)))))
_str = 'author: apexliu@eomsoft.net'
cc.v(' | {}{}|'.format(_str, ' ' * (_width - 5 - len(_str))))
cc.v('[]{}[]'.format('=' * (_width - 4)))
cc.v('')
cc.v('Welcome to install Teleport Server!')
cc.v('')
# cc.v(' NOTICE: if you want to use the default settings, just press `Enter`...')
cc.o((cc.CR_VERBOSE, 'NOTICE: There are a few steps need you enter information or make choice,\n if you want to use the '), (cc.CR_WARN, 'default settings'), (cc.CR_VERBOSE, ', just press `Enter` key.'))
cc.o((cc.CR_VERBOSE, ' Otherwise you need enter the '), (cc.CR_NORMAL, 'highlight character'), (cc.CR_VERBOSE, ' to make choice.'))
cc.v('')
cc.v('')
cc.v('Prepare installation...')
self._check_installation()
self._check_installation_ver()
cc.v('')
def run(self):
if not self._is_installed:
self.install()
else:
cc.v('')
cc.v('Found teleport server have installed at `{}` already.'.format(self._install_path))
while True:
x = self._prompt_choice('What are you wanna to do?', [('upgrade', 2, True), ('uninstall', 0, False), ('quit', 0, False)])
x = x.lower()
if 'q' == x:
return
elif 'u' == x:
self.uninstall()
return
elif 'g' == x:
self._upgrade()
return
def install(self):
while True:
cc.v('')
self._install_path = self._prompt_input('Set installation path', self._def_install_path)
_use_always = False
if os.path.exists(self._install_path):
while True:
cc.v('')
x = self._prompt_choice('The target path `{}` has already exists,\ndo you want to use it anyway?'.format(self._install_path), [('Yes', 0, True), ('No', 0, False)])
x = x.lower()
if 'y' == x:
_use_always = True
break
elif 'n' == x:
break
if _use_always:
break
else:
break
self._config_path = os.path.join(self._install_path, 'etc')
self._data_path = os.path.join(self._install_path, 'data')
self._log_path = os.path.join(self._install_path, 'log')
utils.makedirs(self._install_path)
self._copy_files()
self._install_service()
self._start_service()
time.sleep(2)
self._check_service()
cc.v('\nall done..')
def uninstall(self):
if not self._is_installed:
return
_del_settings = False
while True:
cc.v('')
x = self._prompt_choice('Do you want to keep your database and settings?', [('Yes', 0, True), ('No', 0, False)])
x = x.lower()
if 'y' == x:
break
elif 'n' == x:
_del_settings = True
break
if _del_settings:
while True:
cc.v('')
x = self._prompt_choice('Seriously!! Are you sure to remove all data and settings?', [('Yes', 0, False), ('No', 0, True)])
x = x.lower()
if 'y' == x:
break
elif 'n' == x:
_del_settings = False
break
self._stop_service()
time.sleep(2)
self._uninstall_service()
self._delete_files(_del_settings)
cc.v('\nall done..')
pass
def _upgrade(self):
x = self._ver_compare(self._current_ver, self._installed_ver_str)
if x == 0:
while True:
cc.v('')
x = self._prompt_choice('The same version `{}` installed, are you sure to overwrite?'.format(self._current_ver), [('Yes', 0, False), ('No', 0, True)])
x = x.lower()
if 'y' == x:
break
elif 'n' == x:
return
elif x < 0:
while True:
cc.v('')
x = self._prompt_choice('A new version `{}` installed, rollback to old version `{}` may cause Teleport Server not functionally.\nAre you sure to rollback to old version?'.format(self._installed_ver_str, self._current_ver), [('Yes', 0, False), ('No', 0, True)])
x = x.lower()
if 'y' == x:
break
elif 'n' == x:
return
else:
while True:
cc.v('')
x = self._prompt_choice('Now upgrade from version `{}` to `{}`, \nAre you sure to upgrade to new version?'.format(self._installed_ver_str, self._current_ver), [('Yes', 0, False), ('No', 0, True)])
x = x.lower()
if 'y' == x:
break
elif 'n' == x:
return
while True:
cc.v('')
x = self._prompt_choice('Make sure you have backup your database and settings.\nAre you sure to continue?', [('Yes', 0, False), ('No', 0, True)])
x = x.lower()
if 'y' == x:
break
elif 'n' == x:
return
self._stop_service()
time.sleep(2)
self._uninstall_service()
self._delete_files(False)
time.sleep(1)
self._copy_files()
self._install_service()
self._start_service()
time.sleep(2)
self._check_service()
cc.v('All done.')
@staticmethod
def _prompt_choice(message, choices):
cc.v('{} ['.format(message), end='')
def_choice = ''
for i in range(len(choices)):
if i > 0:
cc.v('/', end='')
msg = choices[i][0]
idx = choices[i][1]
if choices[i][2]:
msg = msg.upper()
def_choice = msg[idx].lower()
cc.w(msg[:idx], end='')
cc.n(msg[idx], end='')
cc.w(msg[idx + 1:], end='')
else:
msg = msg.lower()
cc.v(msg[:idx], end='')
cc.n(msg[idx], end='')
cc.v(msg[idx + 1:], end='')
cc.v(']: ', end='')
try:
x = input().strip()
if len(x) == 0:
x = def_choice
except EOFError:
x = def_choice
return x
@staticmethod
def _prompt_input(message, def_value):
cc.v('{} ['.format(message), end='')
cc.w(def_value, end='')
cc.v(']: ', end='')
try:
x = input().strip()
if len(x) == 0:
x = def_value
except EOFError:
x = def_value
return x
@staticmethod
def _ver_compare(left, right):
l = left.split('.')
r = right.split('.')
len_l = len(l)
len_r = len(r)
if len_l < len_r:
for i in range(len_r - len_l):
l.append('0')
elif len_l > len_r:
for i in range(len_l - len_r):
r.append('0')
cnt = len(l)
for i in range(cnt):
if int(l[i] < r[i]):
return -1
elif int(l[i] > r[i]):
return 1
return 0
def _check_installation(self):
pass
def _check_installation_ver(self):
if not self._is_installed:
return
# try to get the installed version from www/teleport/app/eom_ver.py
cc.v(' - check installed version ... ', end='')
ver_file = os.path.join(self._install_path, 'www', 'teleport', 'app', 'eom_ver.py')
try:
with open(ver_file) as f:
x = f.readlines()
for i in x:
s = i.split('=', 1)
if 'TS_VER' == s[0].strip():
self._installed_ver_str = s[1].strip()[1:-1]
cc.i('[{}]'.format(self._installed_ver_str))
# self._installed_ver = self._ver_str_to_ver(self._installed_ver_str)
break
except FileNotFoundError:
cc.e('[failed]')
cc.e(' the installation maybe broken')
def _copy_files(self):
pass
def _delete_files(self, del_settings):
pass
def _install_service(self):
pass
def _start_service(self):
pass
def _stop_service(self):
pass
def _uninstall_service(self):
pass
def _check_service(self):
pass
class InstallerWin(InstallerBase):
def __init__(self):
super().__init__()
self._def_install_path = r'{}\teleport-server'.format(os.environ['SystemDrive'])
def _check_installation(self):
cc.o(' - check local installation ... ', end='')
_err, _ = utils.sys_exec(r'sc query "{}"'.format(WIN_CORE_SERVICE_NAME))
if 1060 == _err:
# core service not install
pass
else:
self._is_installed = True
_err, _o = utils.sys_exec(r'sc qc "{}"'.format(WIN_CORE_SERVICE_NAME))
if _err != 0:
raise RuntimeError('Can not get core service installation information.')
for i in _o:
_x = i.split(':', 1)
if 'BINARY_PATH_NAME' == _x[0].strip():
_path = _x[1].strip()
self._install_path = os.path.abspath(os.path.join(os.path.dirname(_path), '..'))
break
_err, _ = utils.sys_exec(r'sc query "{}"'.format(WIN_WEB_SERVICE_NAME))
if 1060 == _err:
# web service not install.
pass
else:
self._is_installed = True
_err, _o = utils.sys_exec(r'sc qc "{}"'.format(WIN_WEB_SERVICE_NAME))
if _err != 0:
raise RuntimeError('Can not get web service installation information.')
for i in _o:
_x = i.split(':', 1)
if 'BINARY_PATH_NAME' == _x[0].strip():
_path = _x[1].strip()
self._install_path = os.path.abspath(os.path.join(os.path.dirname(_path), '..'))
break
if self._is_installed:
cc.i('[exists]')
self._config_path = os.path.join(self._install_path, 'etc')
self._data_path = os.path.join(self._install_path, 'data')
self._log_path = os.path.join(self._install_path, 'log')
else:
cc.i('[not exists]')
return
def _copy_files(self):
utils.copy_ex(os.path.join(env.src_path, 'bin'), os.path.join(self._install_path, 'bin'))
utils.copy_ex(os.path.join(env.src_path, 'www'), os.path.join(self._install_path, 'www'))
if not os.path.exists(self._config_path):
utils.copy_ex(os.path.join(env.src_path, 'tmp', 'etc'), self._config_path)
def _delete_files(self, del_settings):
utils.remove(os.path.join(self._install_path, 'bin'))
utils.remove(os.path.join(self._install_path, 'www'))
if del_settings:
utils.remove(self._data_path)
utils.remove(self._config_path)
utils.remove(self._log_path)
# only remove the installation path when it empty.
os.rmdir(self._install_path)
def _install_service(self):
cc.o(' - install teleport core service ... ', end='')
_core = os.path.join(self._install_path, 'bin', 'tp_core.exe')
_err, _ = utils.sys_exec(r'"{}" -i'.format(_core))
if _err == 0 or _err == 1:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Install core service failed. error code: {}'.format(_err))
cc.o(' - install teleport web service ... ', end='')
_core = os.path.join(self._install_path, 'bin', 'tp_web.exe')
_err, _ = utils.sys_exec(r'"{}" -i'.format(_core))
if _err == 0 or _err == 1:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Install web service failed. error code: {}'.format(_err))
return True
def _start_service(self):
cc.o(' - start teleport core service ... ', end='')
_err, _o = utils.sys_exec(r'sc start "{}"'.format(WIN_CORE_SERVICE_NAME))
# print('start core', _err, _o)
if _err == 0:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Can not start core service.')
cc.o(' - start teleport web service ...', end='')
_err, _o = utils.sys_exec(r'sc start "{}"'.format(WIN_WEB_SERVICE_NAME))
# print('start web', _err, _o)
if _err == 0:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Can not start web service.')
def _stop_service(self):
cc.o(' - stop teleport core service ... ', end='')
_err, _o = utils.sys_exec(r'sc stop "{}"'.format(WIN_CORE_SERVICE_NAME))
# print('stop core', _err, _o)
if _err == 1060 or _err == 1062 or _err == 0:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Can not stop core service.')
cc.o(' - stop teleport web service ... ', end='')
_err, _o = utils.sys_exec(r'sc stop "{}"'.format(WIN_WEB_SERVICE_NAME))
# print('stop web', _err, _o)
if _err == 1060 or _err == 1062 or _err == 0:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Can not stop web service.')
def _uninstall_service(self):
cc.o(' - delete teleport core service ... ', end='')
_err, _o = utils.sys_exec(r'sc delete "{}"'.format(WIN_CORE_SERVICE_NAME))
# print('del core', _err, _o)
if _err == 1060 or _err == 0:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Can not uninstall core service.')
cc.o(' - delete teleport web service ... ', end='')
_err, _o = utils.sys_exec(r'sc delete "{}"'.format(WIN_WEB_SERVICE_NAME))
# print('del web', _err, _o)
if _err == 1060 or _err == 0:
cc.i('[done]')
else:
cc.e('[failed]')
raise RuntimeError('Can not uninstall web service.')
def _check_service(self):
cc.o(' - check teleport core service status ... ', end='')
_err, _o = utils.sys_exec(r'sc query "{}"'.format(WIN_CORE_SERVICE_NAME))
# print('chk core', _err, _o)
if _err == 1060 or _err == 0:
cc.i('[running]')
else:
cc.e('[not running]')
cc.o(' - check teleport web service status ... ', end='')
_err, _o = utils.sys_exec(r'sc delete "{}"'.format(WIN_WEB_SERVICE_NAME))
# print('chk web', _err, _o)
if _err == 1060 or _err == 0:
cc.i('[running]')
else:
cc.e('[not running]')
class InstallerLinux(InstallerBase):
def __init__(self):
super().__init__()
self._is_installed = False
self._install_path = ''
if env.is_win:
self._def_install_path = r'{}\teleport-server'.format(os.environ['SystemDrive'])
self._check_installation = self._check_installation_win
self._copy_files = self._copy_files_win
self._install_service = self._install_service_win
self._stop_service = self._stop_service_win
self._delete_service = self._delete_service_win
else:
self._def_install_path = r'/usr/local/eom/teleport'
self._check_installation = self._check_installation_linux
self._copy_files = self._copy_files_linux
self._install_service = self._install_service_linux
self._stop_service = self._stop_service_linux
self._delete_service = self._delete_service_linux
self._check_installation()
def init(self):
pass
# check if teleport server installed or not.
def run(self):
cc.v('')
cc.v('Welcome to install Teleport Server for Windows!')
if not self._is_installed:
self.install()
else:
cc.v('')
cc.v('Found teleport server already installed, now what are you want to do?')
while True:
x = self._prompt_choice('Please choice', [('Upgrade', 2, True), ('Uninstall', 0, False), ('Quit', 0, False)])
x = x.lower()
if 'q' == x:
return
elif 'u' == x:
self.uninstall()
return
elif 'g' == x:
self._upgrade()
return
def install(self):
cc.n('Notice: if you want to use the default settings, just press `Enter`...')
cc.v('')
self._install_path = self._prompt_input('Set installation path', self._def_install_path)
utils.makedirs(self._install_path)
# self._copy_files()
self._install_service()
pass
# if self._check_installation():
# self._install()
def uninstall(self):
if not self._is_installed:
return
self._stop_service()
self._delete_service()
cc.e('uninstall not implemented.')
pass
def _upgrade(self):
cc.e('upgrade not implemented.')
pass
@staticmethod
def _prompt_choice(message, choices):
cc.v('{} ['.format(message), end='')
def_choice = ''
# cc.v('(', end='')
for i in range(len(choices)):
if i > 0:
cc.v('/', end='')
msg = choices[i][0]
idx = choices[i][1]
if choices[i][2]:
def_choice = msg[idx]
cc.w(msg[:idx], end='')
cc.n(msg[idx], end='')
cc.w(msg[idx + 1:], end='')
else:
cc.v(msg[:idx], end='')
cc.n(msg[idx], end='')
cc.v(msg[idx + 1:], end='')
# cc.v(') ', end='')
# cc.v('[', end='')
# cc.w(def_choice, end='')
cc.v(']: ', end='')
try:
x = input().strip()
if len(x) == 0:
x = def_choice
except EOFError:
x = def_choice
return x
@staticmethod
def _prompt_input(message, def_value):
cc.v('{} ['.format(message), end='')
cc.w(def_value, end='')
cc.v(']: ', end='')
try:
x = input().strip()
if len(x) == 0:
x = def_value
except EOFError:
x = def_value
return x
def _check_installation_win(self):
_err, _ = utils.sys_exec(r'sc query "{}"'.format(WIN_CORE_SERVICE_NAME))
if 1060 == _err:
# core service not install
pass
else:
self._is_installed = True
_err, _o = utils.sys_exec(r'sc qc "{}"'.format(WIN_CORE_SERVICE_NAME))
if _err != 0:
raise RuntimeError('Can not get core service installation information.')
for i in _o:
_x = i.split(':', 1)
if 'BINARY_PATH_NAME' == _x[0].strip():
_path = _x[1].strip()
self._install_path = os.path.abspath(os.path.join(os.path.dirname(_path), '..'))
return
_err, _ = utils.sys_exec(r'sc query "{}"'.format(WIN_WEB_SERVICE_NAME))
if 1060 == _err:
# web service not install.
pass
else:
self._is_installed = True
_err, _o = utils.sys_exec(r'sc qc "{}"'.format(WIN_WEB_SERVICE_NAME))
if _err != 0:
raise RuntimeError('Can not get web service installation information.')
for i in _o:
_x = i.split(':', 1)
if 'BINARY_PATH_NAME' == _x[0].strip():
_path = _x[1].strip()
self._install_path = os.path.abspath(os.path.join(os.path.dirname(_path), '..'))
return
def _copy_files_win(self):
utils.copy_ex(os.path.join(env.src_path, 'bin'), os.path.join(self._install_path, 'bin'))
utils.copy_ex(os.path.join(env.src_path, 'www'), os.path.join(self._install_path, 'www'))
_tmp = os.path.join(self._install_path, 'etc')
if not os.path.exists(_tmp):
utils.copy_ex(os.path.join(env.src_path, 'etc'), _tmp)
def _install_service_win(self):
_core = os.path.join(self._install_path, 'bin', 'tp_core.exe')
_err, _o = utils.sys_exec(r'"{}" -i'.format(_core))
if _err == 0:
return True
elif _err == 1:
cc.v('Core service has been installed already.')
else:
cc.e('Install core service failed. error code: ', _err)
return False
def _stop_service_win(self):
_err, _o = utils.sys_exec(r'sc stop "{}"'.format(WIN_CORE_SERVICE_NAME))
if _err == 1060 or _err == 1062 or _err == 0:
# 1060 = 服务尚未安装
# 1062 = 服务尚未启动
# 0 = 操作成功
pass
else:
raise RuntimeError('Can not stop core service.')
_err, _o = utils.sys_exec(r'sc stop "{}"'.format(WIN_WEB_SERVICE_NAME))
if _err == 1060 or _err == 1062 or _err == 0:
pass
else:
raise RuntimeError('Can not stop web service.')
def _main():
cc.set_default(sep='', end='\n')
env.init()
if env.is_win:
_installer = InstallerWin()
elif env.is_linux:
_installer = InstallerLinux()
else:
raise RuntimeError('Sorry, teleport server does not support this platform yet.')
_installer.init()
if len(sys.argv) > 0:
_cmd = sys.argv[0].lower()
if 'uninstall' == _cmd:
_installer.uninstall()
return
_installer.run()
def main():
try:
_main()
except KeyboardInterrupt:
pass
except RuntimeError as err:
cc.v('')
cc.v('')
cc.e(err.__str__())
cc.v('')
except:
cc.f('got exception.')
return 0
if __name__ == '__main__':
main()