core.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. dever-manage tools
  5. name:Core.py
  6. author:rabin
  7. """
  8. import time
  9. import datetime
  10. import os
  11. import sys
  12. import getopt
  13. import ConfigParser
  14. import commands
  15. import re
  16. import subprocess
  17. import urlparse
  18. class Args(object):
  19. @classmethod
  20. def init(self):
  21. self.action = ''
  22. self.name = ''
  23. self.index = ''
  24. self.param = ''
  25. self.argv()
  26. @classmethod
  27. def argv(self):
  28. slen = len(sys.argv)
  29. if slen >= 2:
  30. self.action = sys.argv[1]
  31. if slen >= 3:
  32. self.name = sys.argv[2]
  33. if slen >= 4:
  34. self.param = sys.argv[3]
  35. self.options()
  36. if self.action == '':
  37. print 'action error'
  38. sys.exit()
  39. @classmethod
  40. def options(self):
  41. try:
  42. options, args = getopt.getopt(sys.argv[1:], "ha:n:p:", ['help', "action=", "name=", "param="])
  43. for name, value in options:
  44. if name in ('-h', '--help'):
  45. self.usage()
  46. elif name in ('-a', '--action'):
  47. self.method = value
  48. elif name in ('-n', '--name'):
  49. Args.name = value
  50. elif name in ('-p', '--param'):
  51. self.param = value
  52. except getopt.GetoptError:
  53. self.usage()
  54. @classmethod
  55. def usage(self):
  56. print File.read(Core.path, 'usage')
  57. sys.exit()
  58. class Env(object):
  59. dm_use = 'base.use'
  60. dm_store = 'base.store'
  61. dm_cluster = 'base.cluster'
  62. dm_dever = 'base.dever'
  63. dm_val = 'val.'
  64. data = {}
  65. @staticmethod
  66. def key(name):
  67. return name.split('.')
  68. @classmethod
  69. def init(self, name):
  70. if not self.data:
  71. self.data = Config.runtime()
  72. return self.key(name)
  73. @classmethod
  74. def read(self, name):
  75. key, name = self.init(name)
  76. if key in self.data and name in self.data[key]:
  77. return self.data[key][name]
  78. else:
  79. return False
  80. @classmethod
  81. def write(self, name, value):
  82. key, name = self.init(name)
  83. self.data[key][name] = value
  84. Config.runtime(key, name, value)
  85. return value
  86. @classmethod
  87. def use(self, value=None):
  88. if value:
  89. return self.write(self.dm_use, value)
  90. return self.read(self.dm_use)
  91. @classmethod
  92. def dever(self, value=None):
  93. if value:
  94. return self.write(self.dm_dever, value)
  95. return self.read(self.dm_dever)
  96. @classmethod
  97. def store(self, value=None):
  98. if value:
  99. return self.write(self.dm_store, value)
  100. return self.read(self.dm_store)
  101. @classmethod
  102. def cluster(self, value=None):
  103. if value:
  104. return self.write(self.dm_cluster, value)
  105. return self.read(self.dm_cluster)
  106. @classmethod
  107. def val(self, name='', value=None):
  108. #name = self.dm_val + name.capitalize()
  109. name = self.dm_val + name
  110. if value:
  111. return self.write(name, value)
  112. return self.read(name)
  113. class Config(object):
  114. @classmethod
  115. def runtime(self, key='', name='', value=''):
  116. runtime = Core.path + 'data/runtime.conf'
  117. if File.exists(runtime):
  118. config = ConfigParser.ConfigParser()
  119. config.read(runtime)
  120. if key and name:
  121. config.set(key, name, value)
  122. config.write(open(runtime, 'w'))
  123. else:
  124. result = {}
  125. for item in config.sections():
  126. result[item] = self.readOption(config, item)
  127. return result
  128. else:
  129. print runtime + ' is not exists'
  130. sys.exit()
  131. @classmethod
  132. def core(self, path):
  133. core = Core.path + path + 'core.conf'
  134. if File.exists(core):
  135. config = ConfigParser.ConfigParser()
  136. config.read(core)
  137. result = {}
  138. for item in config.sections():
  139. result[item] = self.readOption(config, item)
  140. return result
  141. else:
  142. print core + ' is not exists'
  143. sys.exit()
  144. @classmethod
  145. def read(self, path):
  146. if '-' in Args.name:
  147. temp = Args.name.split('-')
  148. Args.name = temp[0]
  149. Args.index = temp[1]
  150. filename = Core.path + path + 'conf/' + Args.name + '.conf'
  151. if File.exists(filename):
  152. config = ConfigParser.ConfigParser()
  153. config.read(filename)
  154. result = {}
  155. result['server'] = []
  156. result['config'] = {}
  157. result['base'] = {}
  158. for item in config.sections():
  159. if item == 'base':
  160. result['base'] = self.readOption(config, item)
  161. else:
  162. result['server'].append(item)
  163. result['config'][item] = self.readOption(config, item)
  164. result['base']['path'] = Core.replace('{base}', Core.path, result['base']['path'])
  165. return result
  166. else:
  167. print filename + ' is not exists'
  168. sys.exit()
  169. @staticmethod
  170. def readOption(config, type):
  171. value = config.options(type)
  172. result = {}
  173. for item in value:
  174. result[item] = config.get(type, item)
  175. return result
  176. class Alias(object):
  177. @classmethod
  178. def delete(self, config, name, cluster=False):
  179. result = self.get(config, name)
  180. for key in result:
  181. action = self.action(name, key)
  182. if action[0] != 'sh' and File.exists(action[1]):
  183. content = File.get(action[1])
  184. string = 'docker exec -it ' + name + ' ' + action[0] + ' $@'
  185. if string in content:
  186. content = content.replace(string, '')
  187. File.write(action[1], content.strip())
  188. if 'docker' not in content:
  189. Core.popen('rm -rf ' + action[1], bg=True)
  190. Core.popen('rm -rf ' + action[2], bg=True)
  191. #Core.popen('rm -rf ' + action[1], bg=True)
  192. #Core.popen('rm -rf ' + action[2], bg=True)
  193. @classmethod
  194. def add(self, config, name, content, type, cluster=False):
  195. result = self.get(config, name)
  196. for key in result:
  197. action = self.action(name, key)
  198. old = ''
  199. if File.exists(action[1]):
  200. old = File.get(action[1])
  201. env = '#!/usr/bin/env sh \nset -e\n'
  202. if type != 'call':
  203. dexec = 'docker exec -it ' + name + ' ' + action[0] + ' $@'
  204. if cluster:
  205. dexec = 'name=`ds name ' + name + '`\n'
  206. dexec = dexec + 'docker exec -it $name ' + action[0] + ' $@'
  207. if action[0] == 'sh':
  208. content = env + self.define(name, cluster) + \
  209. 'else\n' + \
  210. dexec + '\n' + \
  211. 'fi'
  212. elif old:
  213. content = dexec
  214. if content not in old:
  215. content = old + '\n' + content
  216. else:
  217. content = ''
  218. else:
  219. content = env + dexec
  220. else:
  221. content = env + ' $@'
  222. if content:
  223. File.write(action[1], content)
  224. Core.popen('ln -sf ' + action[1] + ' ' + action[2])
  225. @staticmethod
  226. def define(name, cluster=False):
  227. conf = ['logs', 'inspect', 'restart', 'stop', 'rm', 'rmb', 'run', 'uprun', 'show']
  228. result = ''
  229. for key in conf:
  230. control = 'elif'
  231. command = 'dm'
  232. if cluster:
  233. command = 'ds'
  234. shell = command + ' ' + key + ' ' + name + '\n'
  235. if key == 'logs':
  236. control = 'if'
  237. result = result + control + ' [ "$1" = "'+key+'" ];then\n' + shell
  238. return result
  239. @classmethod
  240. def get(self, config, name):
  241. self.path = Core.path + 'data/alias/'
  242. result = []
  243. default = 'sh->' + name
  244. if 'alias' in config:
  245. config['alias'] = config['alias'] + ',' + default
  246. if ',' in config['alias']:
  247. result = config['alias'].split(',');
  248. else:
  249. result = [config['alias']]
  250. else:
  251. result = [default]
  252. return result
  253. @classmethod
  254. def action(self, name, key):
  255. file = key
  256. if '->' in key:
  257. temp = key.split('->')
  258. key = temp[0]
  259. file = temp[1]
  260. link = '/usr/bin/' + file
  261. file = self.path + file
  262. return [key, file, link]
  263. class File(object):
  264. @staticmethod
  265. def write(file, content):
  266. if type(content) == list:
  267. content = "\r\n".join(content)
  268. handle = open(file, 'w')
  269. handle.write(content)
  270. handle.close()
  271. Core.popen('chmod +x ' + file)
  272. @staticmethod
  273. def read(path, name):
  274. handle = open(path + name, 'r')
  275. content = handle.read()
  276. handle.close()
  277. return content
  278. @staticmethod
  279. def get(file):
  280. handle = open(file, 'r')
  281. content = handle.read()
  282. handle.close()
  283. return content
  284. @staticmethod
  285. def getFiles(path):
  286. return os.listdir(path)
  287. @staticmethod
  288. def path():
  289. return os.path.split(os.path.realpath(__file__))[0] + '/'
  290. @staticmethod
  291. def cur():
  292. return os.getcwd()
  293. @staticmethod
  294. def exists(name):
  295. return os.path.exists(name)
  296. @staticmethod
  297. def rename(old, new):
  298. return os.rename(old, new)
  299. @staticmethod
  300. def remove(file):
  301. return os.remove(file)
  302. @staticmethod
  303. def mkdir(path):
  304. if File.exists(path) == False:
  305. os.mkdir(path)
  306. return path
  307. @staticmethod
  308. def mkdirs(path):
  309. if File.exists(path) == False:
  310. os.makedirs(path)
  311. return path
  312. @staticmethod
  313. def tmp():
  314. tmp = '/tmp/'
  315. if not File.exists(tmp):
  316. File.mkdir(tmp)
  317. return tmp
  318. class Git(object):
  319. @staticmethod
  320. def update(git, path):
  321. if git and File.exists(path) == False:
  322. Core.popen('git clone ' + git + ' ' + path)
  323. print 'init:' + path + ' finished!'
  324. else:
  325. file = path + '/' + '.git/'
  326. if not File.exists(file):
  327. tmp = File.tmp() + path
  328. Core.popen('git clone ' + git + ' ' + tmp + ' && cp -R ' + tmp + '/.git/ ' + file + ' && rm -rf ' + tmp)
  329. Core.popen('cd ' + path + ' && git pull')
  330. print 'update:' + path + ' finished!'
  331. @classmethod
  332. def set(self, git, path):
  333. Core.popen('cd ' + path + ' && git pull && git remote set-url origin ' + git, bg=True)
  334. @classmethod
  335. def add(self, git, path):
  336. Core.popen('cd ' + path + ' && git pull && git remote add origin ' + git, bg=True)
  337. @classmethod
  338. def push(self, path, branch, msg):
  339. if not msg:
  340. msg = 'edit'
  341. if not branch:
  342. branch = 'master'
  343. Core.popen('cd ' + path + ' && git pull && git commit -m "'+msg+'" * && git push -u origin ' + branch, True)
  344. class Service(object):
  345. @staticmethod
  346. def set(git, path):
  347. if File.exists(path) == False:
  348. Core.popen('git clone ' + git + ' ' + path, bg=True)
  349. print 'init:' + path + ' finished!'
  350. else:
  351. Core.popen('cd ' + path + ' && git pull', bg=True)
  352. print 'update:' + path + ' finished!'
  353. class Core(object):
  354. path = ''
  355. @classmethod
  356. def curl(self, url = '', param={}, method = 'get'):
  357. import requests
  358. if method == 'get':
  359. req = requests.get(url, params=param)
  360. else:
  361. req = requests.post(url, params=param)
  362. result = req.text
  363. return result
  364. @classmethod
  365. def getClass(self, name, path=''):
  366. obj = self.getObject(name, path)
  367. if path:
  368. if not hasattr(obj, name):
  369. print 'error ' + name
  370. sys.exit()
  371. obj = getattr(obj, name)
  372. name = name.capitalize()
  373. if not hasattr(obj, name):
  374. print 'error ' + name
  375. sys.exit()
  376. return getattr(obj, name)
  377. @staticmethod
  378. def getObject(name, path = ''):
  379. return __import__(path + name)
  380. @staticmethod
  381. def getMethod(obj, name):
  382. if not hasattr(obj, name):
  383. print 'error ' + name
  384. sys.exit()
  385. return getattr(obj, name)
  386. @classmethod
  387. def shell(self, command, sub=False, bg=False):
  388. shell = self.path + 'src/shell/' + command.replace('.', '/', 1)
  389. return self.popen(shell, sub, bg)
  390. @staticmethod
  391. def popen(command, sub=False, bg=False):
  392. string = command
  393. if bg == True:
  394. command = command + ' 1>/dev/null 2>&1 &'
  395. if sub == False:
  396. process = os.popen(command)
  397. output = process.read()
  398. process.close()
  399. return output
  400. else:
  401. popen = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
  402. output = ''
  403. print string
  404. while True:
  405. output = popen.stdout.readline()
  406. print output
  407. if popen.poll() is not None:
  408. break
  409. return output
  410. @classmethod
  411. def install(self, soft):
  412. print 'install ' + soft + '...'
  413. if soft == 'docker':
  414. self.shell('install.docker', True)
  415. else:
  416. self.shell('install.package ' + soft, True)
  417. @classmethod
  418. def check(self, soft):
  419. result = int(Core.popen('which '+soft+' | wc -l'))
  420. if result != 0:
  421. return 1
  422. else:
  423. self.install(soft)
  424. return 0
  425. @staticmethod
  426. def replace(old, new, string):
  427. if old in string:
  428. string = string.replace(old, new)
  429. return string
  430. @staticmethod
  431. def isset(v):
  432. try :
  433. type(eval(v))
  434. except :
  435. return 0
  436. else :
  437. return 1
  438. @staticmethod
  439. def ip(ifname = 'eth0'):
  440. return ''
  441. import socket, fcntl, struct
  442. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  443. inet = fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))
  444. ret = socket.inet_ntoa(inet[20:24])
  445. return ret