154 lines
4.6 KiB
Python
Executable File
154 lines
4.6 KiB
Python
Executable File
#!/opt/sunpy3/bin/python3
|
|
#coding:utf-8
|
|
|
|
import os
|
|
import sys
|
|
import pwd
|
|
import sunhpc
|
|
import syslog
|
|
import shutil
|
|
import sunhpc.invoke
|
|
|
|
if sys.getdefaultencoding() != 'utf-8':
|
|
reload(sys)
|
|
sys.setdefaultencoding('utf-8')
|
|
|
|
def ttySize():
|
|
try:
|
|
(width, heigh) = shutil.get_terminal_size()
|
|
except:
|
|
width = 80
|
|
return width
|
|
|
|
os.environ['COLUMNS'] = str(ttySize())
|
|
syslog.openlog('SunhpcCMD', syslog.LOG_PID, syslog.LOG_LOCAL0)
|
|
|
|
try:
|
|
import sqlalchemy
|
|
import sunhpc.db.helper
|
|
|
|
database = sunhpc.db.helper.DatabaseHelper()
|
|
database.connect()
|
|
|
|
except ImportError:
|
|
raise
|
|
except sqlalchemy.exc.OperationalError:
|
|
raise
|
|
|
|
# 如果参数为空,应当主动赋值帮助,就当成sunhpc help命令.
|
|
if len(sys.argv) == 1:
|
|
args = [ 'list', 'help']
|
|
else:
|
|
args = sys.argv[1:]
|
|
#
|
|
# 如果这个sunhpc 没有参数, 则使用 sunhpc list help
|
|
# 否则, 使用第二个参数, 例如 sunhpc list
|
|
# 那么 args[0] = 永远指定第二个参数.
|
|
# 检查命令是否被圈引
|
|
# sunhpc aa bb -- 那么cmd=['aa']
|
|
# sunhpc "aa bb" -- 那么cmd=['aa','bb']
|
|
module = None
|
|
cmd = args[0].split()
|
|
|
|
# 一般不会执行这里.
|
|
# 只有命令参数带入引号,才会执行此处.
|
|
# 例如: sunhpc "aa bb" 而 sunhpc aa bb 则跳过此处.
|
|
if len(cmd) > 1:
|
|
s = 'sunhpc.commands.%s' % '.'.join(cmd)
|
|
# 此时模块路径应该是 sunhpc.commands.aa.bb
|
|
try:
|
|
# 如果没有此模块,则触发ModuleNotFoundError异常.
|
|
__import__(s)
|
|
|
|
# 如果模块存在,但是报错,应该是头部没有进行import 相关模块.
|
|
# 触发 NameError 异常.
|
|
module = eval(s)
|
|
|
|
# 设定变量,供后面for递减模块中args列表从第二个参数取值使用.
|
|
i = 1
|
|
except:
|
|
module = None
|
|
|
|
# 这里正式开始检查命令参数.
|
|
if not module:
|
|
# 递减sunhpc 参数.
|
|
for i in range(len(args), 0, -1):
|
|
s = 'sunhpc.commands.%s' % '.'.join(args[:i])
|
|
# sunhpc.commands.aa.bb
|
|
# sunhpc.commands.aa
|
|
try:
|
|
# 倒序检查模块是否存在.
|
|
__import__(s)
|
|
module = eval(s)
|
|
if module:
|
|
# 如果找到模块,那么其余的参数,就会作为模块参数提供给此模块.
|
|
break
|
|
except ImportError:
|
|
continue
|
|
|
|
# 如果没有找到提供的任何模块,则命令执行失败.
|
|
if not module:
|
|
print ('error - invalid sunhpc command "%s"' % args[0])
|
|
sys.exit(-1)
|
|
|
|
# 将模块路径重新转化成命令行形式格式.
|
|
# sunhpc.commands.aa.bb
|
|
# sunhpc commands aa bb 去除sunhpc commands.
|
|
# name = aa bb
|
|
name = ' '.join(s.split('.')[2:])
|
|
|
|
# 此时module已经找到相应的模块了.
|
|
# module = sunhpc.commands.aa.bb
|
|
|
|
try:
|
|
# 检查module模块是否有Command类,如果没有则触发 AttributeError 异常.
|
|
command = getattr(module, 'Command')(database)
|
|
except AttributeError:
|
|
# 没有Command类,则会执行到此处.到这里我们需要调用帮助信息.
|
|
#
|
|
# 此时的bb模块中没有Command类.
|
|
# 命令:sunhpc aa bb
|
|
# 已知module路径. sunhpc.commands.aa.bb
|
|
# 已经name变量, aa bb
|
|
#
|
|
# 导入sunhpc帮助模块
|
|
import sunhpc.commands.list.help
|
|
help = sunhpc.commands.list.help.Command(database)
|
|
# 将module路径转换成列表然后使用切片找出模块全路径和子路径.
|
|
fullmodpath = s.split('.')
|
|
submodpath = '/'.join(fullmodpath[2:])
|
|
|
|
# 执行Command类中run函数.第一个参数是字典,第二个是列表.
|
|
help.run({'subdir':submodpath}, [])
|
|
print (help.getText())
|
|
sys.exit(-1)
|
|
|
|
# 如果有Command类, 则执行主模块sunhpc.commands.__init__中的runWapper函数
|
|
# 两种用途
|
|
# 1, 收集命令参数并且转换成固定格式.
|
|
# 2, 开始执行命令入口函数.
|
|
# 如果触发自定义命令异常,则输出使用帮助信息.
|
|
if command.MustBeRoot and not (command.isRootUser() or command.isApacheUser()):
|
|
# 如果需要特权权限, 则需要提权操作.
|
|
os.system('sudo %s' % ' '.join(sys.argv))
|
|
else:
|
|
# 收集参数等信息,然后运行模块run函数,错误则触发CommandError异常.
|
|
# runWrapper是主模块中的Command类中的入口函数.
|
|
# name : 当前模块路径.
|
|
# args : 当前有效模块后面全部视为参数.
|
|
try:
|
|
command.runWrapper(name, args[i:])
|
|
text = command.getText()
|
|
if len(text) > 0:
|
|
print (text.rstrip())
|
|
if text[len(text)-1] != '\n':
|
|
print ()
|
|
except sunhpc.core.utils.CommandError as e:
|
|
msg = ' '.join(str(e).split())
|
|
#print ("\033[91m[errs] %s\033[0m" % msg)
|
|
print (msg)
|
|
print (command.usage())
|
|
exit(1)
|
|
|
|
syslog.closelog()
|