guest.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import copy
  4. from flask import Blueprint
  5. from flask import request, g
  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 Config
  12. from models import GuestDisk
  13. from models import Rules
  14. from models import Utils
  15. from models import Guest
  16. from models import OSTemplate
  17. from models import GuestXML
  18. __author__ = 'James Iter'
  19. __date__ = '2017/3/22'
  20. __contact__ = 'james.iter.cn@gmail.com'
  21. __copyright__ = '(c) 2017 by James Iter.'
  22. blueprint = Blueprint(
  23. 'guest',
  24. __name__,
  25. url_prefix='/api/guest'
  26. )
  27. @Utils.dumps2response
  28. def r_create():
  29. args_rules = [
  30. Rules.CPU.value,
  31. Rules.MEMORY.value,
  32. Rules.OS_TEMPLATE_ID.value,
  33. Rules.DISKS.value,
  34. Rules.QUANTITY.value,
  35. Rules.NAME.value,
  36. Rules.PASSWORD.value,
  37. Rules.LEASE_TERM.value
  38. ]
  39. try:
  40. ret = dict()
  41. ret['state'] = ji.Common.exchange_state(20000)
  42. ji.Check.previewing(args_rules, request.json)
  43. if g.config is None:
  44. config = Config()
  45. config.id = 1
  46. config.get()
  47. g.config = config
  48. assert isinstance(g.config, Config)
  49. os_template = OSTemplate()
  50. os_template.id = request.json.get('os_template_id')
  51. if not os_template.exist():
  52. ret['state'] = ji.Common.exchange_state(40450)
  53. ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], ': ', os_template.id])
  54. return ret
  55. os_template.get()
  56. os_init_writes = OSInitWrite.get_by_filter(
  57. filter_str='os_init_id:in:' + os_template.os_init_id.__str__())
  58. if g.r.scard(app.config['ip_available_set']) < 1:
  59. ret['state'] = ji.Common.exchange_state(50350)
  60. return ret
  61. quantity = request.json.get('quantity')
  62. while quantity:
  63. quantity -= 1
  64. guest = Guest()
  65. guest.uuid = uuid4().__str__()
  66. guest.cpu = request.json.get('cpu')
  67. # 虚拟机内存单位默认KiB,所以这个乘1024的平方,使得用户填入的单位变为GiB
  68. guest.memory = request.json.get('memory') * 1024 * 1024
  69. guest.os_template_id = request.json.get('os_template_id')
  70. guest.name = request.json.get('name')
  71. guest.password = request.json.get('password')
  72. if guest.password is None or guest.password.__len__() < 1:
  73. guest.password = ji.Common.generate_random_code(length=16)
  74. while guest.name.__len__() < 1 or guest.exist_by('name'):
  75. guest.name = ji.Common.generate_random_code(length=8)
  76. guest.ip = g.r.spop(app.config['ip_available_set'])
  77. g.r.sadd(app.config['ip_used_set'], guest.ip)
  78. guest.network = g.config.vm_network
  79. guest.manage_network = g.config.vm_manage_network
  80. guest.vnc_port = g.r.spop(app.config['vnc_port_available_set'])
  81. g.r.sadd(app.config['vnc_port_used_set'], guest.vnc_port)
  82. guest.vnc_password = ji.Common.generate_random_code(length=16)
  83. guest_disks = list()
  84. guest_disks.append({'label': uuid4(), 'size': -1, 'format': 'qcow2'})
  85. for i, disk in enumerate(request.json.get('disks')):
  86. guest_disk = GuestDisk()
  87. guest_disk.size = disk.get('size')
  88. # TODO: 设定磁盘最大大小
  89. if not isinstance(guest_disk.size, int) or guest_disk.size < 1:
  90. continue
  91. guest_disk.guest_uuid = guest.uuid
  92. guest_disk.label = uuid4()
  93. guest_disk.sequence = i + 1
  94. guest_disk.format = 'qcow2'
  95. guest_disk.create()
  96. guest_disks.append({'label': guest_disk.label, 'size': guest_disk.size, 'format': guest_disk.format})
  97. guest.create()
  98. guest_xml = GuestXML(guest=guest, disks=guest_disks, g_config=g.config)
  99. guest_xml.get_domain()
  100. # 替换占位符为有效内容
  101. _os_init_writes = copy.deepcopy(os_init_writes)
  102. for k, v in _os_init_writes:
  103. _os_init_writes[k] = v.replace('{IP}', guest.ip).\
  104. replace('{HOSTNAME}', guest.name).\
  105. replace('{NETMASK}', g.config.netmask).\
  106. replace('{GATEWAY}', g.config.gateway).\
  107. replace('{DNS1}', g.config.dns1).\
  108. replace('{DNS2}', g.config.dns2)
  109. create_vm_msg = {
  110. 'uuid': guest.uuid,
  111. 'glusterfs_volume': g.config.glusterfs_volume,
  112. 'template_path': 'template_pool/' + os_template.name,
  113. 'guest_disks': guest_disks,
  114. 'writes': _os_init_writes,
  115. 'password': guest.password,
  116. 'xml': guest_xml.get_domain()
  117. }
  118. g.r.rpush(app.config['vm_create_queue'], json.dumps(create_vm_msg, ensure_ascii=False))
  119. return ret
  120. except ji.PreviewingError, e:
  121. return json.loads(e.message)