guest.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import copy
  4. from flask import Blueprint
  5. from flask import request
  6. import json
  7. from uuid import uuid4
  8. import jimit as ji
  9. from models import OSInitWrite
  10. from models.initialize import app
  11. from models import Database as db
  12. from models import Config
  13. from models import GuestDisk
  14. from models import Rules
  15. from models import Utils
  16. from models import Guest
  17. from models import OSTemplate
  18. from models import GuestXML
  19. __author__ = 'James Iter'
  20. __date__ = '2017/3/22'
  21. __contact__ = 'james.iter.cn@gmail.com'
  22. __copyright__ = '(c) 2017 by James Iter.'
  23. blueprint = Blueprint(
  24. 'guest',
  25. __name__,
  26. url_prefix='/api/guest'
  27. )
  28. @Utils.dumps2response
  29. def r_create():
  30. args_rules = [
  31. Rules.CPU.value,
  32. Rules.MEMORY.value,
  33. Rules.OS_TEMPLATE_ID.value,
  34. Rules.DISKS.value,
  35. Rules.QUANTITY.value,
  36. Rules.NAME.value,
  37. Rules.PASSWORD.value,
  38. Rules.LEASE_TERM.value
  39. ]
  40. try:
  41. ret = dict()
  42. ret['state'] = ji.Common.exchange_state(20000)
  43. ji.Check.previewing(args_rules, request.json)
  44. config = Config()
  45. config.id = 1
  46. config.get()
  47. os_template = OSTemplate()
  48. os_template.id = request.json.get('os_template_id')
  49. if not os_template.exist():
  50. ret['state'] = ji.Common.exchange_state(40450)
  51. ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], ': ', os_template.id])
  52. return ret
  53. os_template.get()
  54. os_init_writes, os_init_writes_count = OSInitWrite.get_by_filter(
  55. filter_str='os_init_id:in:' + os_template.os_init_id.__str__())
  56. if db.r.scard(app.config['ip_available_set']) < 1:
  57. ret['state'] = ji.Common.exchange_state(50350)
  58. return ret
  59. quantity = request.json.get('quantity')
  60. while quantity:
  61. quantity -= 1
  62. guest = Guest()
  63. guest.uuid = uuid4().__str__()
  64. guest.cpu = request.json.get('cpu')
  65. # 虚拟机内存单位,模板生成方法中已置其为GiB
  66. guest.memory = request.json.get('memory')
  67. guest.os_template_id = request.json.get('os_template_id')
  68. guest.name = request.json.get('name')
  69. guest.password = request.json.get('password')
  70. if guest.password is None or guest.password.__len__() < 1:
  71. guest.password = ji.Common.generate_random_code(length=16)
  72. while guest.name.__len__() < 1 or guest.exist_by('name'):
  73. guest.name = ji.Common.generate_random_code(length=8)
  74. guest.ip = db.r.spop(app.config['ip_available_set'])
  75. db.r.sadd(app.config['ip_used_set'], guest.ip)
  76. guest.network = config.vm_network
  77. guest.manage_network = config.vm_manage_network
  78. guest.vnc_port = db.r.spop(app.config['vnc_port_available_set'])
  79. db.r.sadd(app.config['vnc_port_used_set'], guest.vnc_port)
  80. guest.vnc_password = ji.Common.generate_random_code(length=16)
  81. guest_disks = list()
  82. guest_disks.append({'label': uuid4().__str__(), 'size': -1, 'format': 'qcow2'})
  83. for i, disk in enumerate(request.json.get('disks')):
  84. guest_disk = GuestDisk()
  85. guest_disk.size = disk.get('size')
  86. # TODO: 设定磁盘最大大小
  87. if not isinstance(guest_disk.size, int) or guest_disk.size < 1:
  88. continue
  89. guest_disk.guest_uuid = guest.uuid
  90. guest_disk.label = uuid4().__str__()
  91. guest_disk.sequence = i + 1
  92. guest_disk.format = 'qcow2'
  93. guest_disk.create()
  94. guest_disks.append({'label': guest_disk.label, 'size': guest_disk.size, 'format': guest_disk.format})
  95. guest_xml = GuestXML(guest=guest, disks=guest_disks, config=config)
  96. guest.xml = guest_xml.get_domain()
  97. guest.create()
  98. # 替换占位符为有效内容
  99. _os_init_writes = copy.deepcopy(os_init_writes)
  100. for k, v in enumerate(_os_init_writes):
  101. _os_init_writes[k]['content'] = v['content'].replace('{IP}', guest.ip).\
  102. replace('{HOSTNAME}', guest.name).\
  103. replace('{NETMASK}', config.netmask).\
  104. replace('{GATEWAY}', config.gateway).\
  105. replace('{DNS1}', config.dns1).\
  106. replace('{DNS2}', config.dns2)
  107. create_vm_msg = {
  108. 'uuid': guest.uuid,
  109. 'name': guest.name,
  110. 'glusterfs_volume': config.glusterfs_volume,
  111. 'template_path': 'template_pool/' + os_template.name,
  112. 'guest_disks': guest_disks,
  113. 'writes': _os_init_writes,
  114. 'password': guest.password,
  115. 'xml': guest_xml.get_domain()
  116. }
  117. db.r.rpush(app.config['vm_create_queue'], json.dumps(create_vm_msg, ensure_ascii=False))
  118. return ret
  119. except ji.PreviewingError, e:
  120. return json.loads(e.message)
  121. @Utils.dumps2response
  122. def r_reboot(uuid):
  123. args_rules = [
  124. Rules.UUID.value
  125. ]
  126. try:
  127. ji.Check.previewing(args_rules, {'uuid': uuid})
  128. guest = Guest()
  129. guest.uuid = uuid
  130. guest.get_by('uuid')
  131. message = {'action': 'reboot', 'uuid': uuid}
  132. Guest.emit_instruction(message=json.dumps(message))
  133. ret = dict()
  134. ret['state'] = ji.Common.exchange_state(20000)
  135. return ret
  136. except ji.PreviewingError, e:
  137. return json.loads(e.message)
  138. @Utils.dumps2response
  139. def r_force_reboot(uuid):
  140. args_rules = [
  141. Rules.UUID.value
  142. ]
  143. try:
  144. ji.Check.previewing(args_rules, {'uuid': uuid})
  145. guest = Guest()
  146. guest.uuid = uuid
  147. guest.get_by('uuid')
  148. message = {'action': 'force_reboot', 'uuid': uuid}
  149. Guest.emit_instruction(message=json.dumps(message))
  150. ret = dict()
  151. ret['state'] = ji.Common.exchange_state(20000)
  152. return ret
  153. except ji.PreviewingError, e:
  154. return json.loads(e.message)
  155. @Utils.dumps2response
  156. def r_shutdown(uuid):
  157. args_rules = [
  158. Rules.UUID.value
  159. ]
  160. try:
  161. ji.Check.previewing(args_rules, {'uuid': uuid})
  162. guest = Guest()
  163. guest.uuid = uuid
  164. guest.get_by('uuid')
  165. message = {'action': 'shutdown', 'uuid': uuid}
  166. Guest.emit_instruction(message=json.dumps(message))
  167. ret = dict()
  168. ret['state'] = ji.Common.exchange_state(20000)
  169. return ret
  170. except ji.PreviewingError, e:
  171. return json.loads(e.message)
  172. @Utils.dumps2response
  173. def r_force_shutdown(uuid):
  174. args_rules = [
  175. Rules.UUID.value
  176. ]
  177. try:
  178. ji.Check.previewing(args_rules, {'uuid': uuid})
  179. guest = Guest()
  180. guest.uuid = uuid
  181. guest.get_by('uuid')
  182. message = {'action': 'force_shutdown', 'uuid': uuid}
  183. Guest.emit_instruction(message=json.dumps(message))
  184. ret = dict()
  185. ret['state'] = ji.Common.exchange_state(20000)
  186. return ret
  187. except ji.PreviewingError, e:
  188. return json.loads(e.message)
  189. @Utils.dumps2response
  190. def r_boot(uuid):
  191. args_rules = [
  192. Rules.UUID.value
  193. ]
  194. try:
  195. ji.Check.previewing(args_rules, {'uuid': uuid})
  196. guest = Guest()
  197. guest.uuid = uuid
  198. guest.get_by('uuid')
  199. message = {'action': 'boot', 'uuid': uuid}
  200. Guest.emit_instruction(message=json.dumps(message))
  201. ret = dict()
  202. ret['state'] = ji.Common.exchange_state(20000)
  203. return ret
  204. except ji.PreviewingError, e:
  205. return json.loads(e.message)
  206. @Utils.dumps2response
  207. def r_suspend(uuid):
  208. args_rules = [
  209. Rules.UUID.value
  210. ]
  211. try:
  212. ji.Check.previewing(args_rules, {'uuid': uuid})
  213. guest = Guest()
  214. guest.uuid = uuid
  215. guest.get_by('uuid')
  216. message = {'action': 'suspend', 'uuid': uuid}
  217. Guest.emit_instruction(message=json.dumps(message))
  218. ret = dict()
  219. ret['state'] = ji.Common.exchange_state(20000)
  220. return ret
  221. except ji.PreviewingError, e:
  222. return json.loads(e.message)
  223. @Utils.dumps2response
  224. def r_resume(uuid):
  225. args_rules = [
  226. Rules.UUID.value
  227. ]
  228. try:
  229. ji.Check.previewing(args_rules, {'uuid': uuid})
  230. guest = Guest()
  231. guest.uuid = uuid
  232. guest.get_by('uuid')
  233. message = {'action': 'resume', 'uuid': uuid}
  234. Guest.emit_instruction(message=json.dumps(message))
  235. ret = dict()
  236. ret['state'] = ji.Common.exchange_state(20000)
  237. return ret
  238. except ji.PreviewingError, e:
  239. return json.loads(e.message)
  240. @Utils.dumps2response
  241. def r_delete(uuid):
  242. args_rules = [
  243. Rules.UUID.value
  244. ]
  245. try:
  246. ji.Check.previewing(args_rules, {'uuid': uuid})
  247. guest = Guest()
  248. guest.uuid = uuid
  249. guest.get_by('uuid')
  250. message = {'action': 'delete', 'uuid': uuid}
  251. Guest.emit_instruction(message=json.dumps(message))
  252. ret = dict()
  253. ret['state'] = ji.Common.exchange_state(20000)
  254. return ret
  255. except ji.PreviewingError, e:
  256. return json.loads(e.message)
  257. @Utils.dumps2response
  258. def r_disk_resize(uuid):
  259. args_rules = [
  260. Rules.UUID.value
  261. ]
  262. try:
  263. ji.Check.previewing(args_rules, {'uuid': uuid})
  264. guest = Guest()
  265. guest.uuid = uuid
  266. guest.get_by('uuid')
  267. message = {'action': 'disk-resize', 'uuid': uuid}
  268. Guest.emit_instruction(message=json.dumps(message))
  269. ret = dict()
  270. ret['state'] = ji.Common.exchange_state(20000)
  271. return ret
  272. except ji.PreviewingError, e:
  273. return json.loads(e.message)
  274. @Utils.dumps2response
  275. def r_attach_disk(uuid):
  276. args_rules = [
  277. Rules.UUID.value
  278. ]
  279. try:
  280. ji.Check.previewing(args_rules, {'uuid': uuid})
  281. guest = Guest()
  282. guest.uuid = uuid
  283. guest.get_by('uuid')
  284. message = {'action': 'attach-disk', 'uuid': uuid}
  285. Guest.emit_instruction(message=json.dumps(message))
  286. ret = dict()
  287. ret['state'] = ji.Common.exchange_state(20000)
  288. return ret
  289. except ji.PreviewingError, e:
  290. return json.loads(e.message)
  291. @Utils.dumps2response
  292. def r_detach_disk(uuid):
  293. args_rules = [
  294. Rules.UUID.value
  295. ]
  296. try:
  297. ji.Check.previewing(args_rules, {'uuid': uuid})
  298. guest = Guest()
  299. guest.uuid = uuid
  300. guest.get_by('uuid')
  301. message = {'action': 'detach-disk', 'uuid': uuid}
  302. Guest.emit_instruction(message=json.dumps(message))
  303. ret = dict()
  304. ret['state'] = ji.Common.exchange_state(20000)
  305. return ret
  306. except ji.PreviewingError, e:
  307. return json.loads(e.message)
  308. @Utils.dumps2response
  309. def r_migrate(uuid):
  310. args_rules = [
  311. Rules.UUID.value
  312. ]
  313. try:
  314. ji.Check.previewing(args_rules, {'uuid': uuid})
  315. guest = Guest()
  316. guest.uuid = uuid
  317. guest.get_by('uuid')
  318. message = {'action': 'migrate', 'uuid': uuid}
  319. Guest.emit_instruction(message=json.dumps(message))
  320. ret = dict()
  321. ret['state'] = ji.Common.exchange_state(20000)
  322. return ret
  323. except ji.PreviewingError, e:
  324. return json.loads(e.message)