host.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import json
  4. from flask import g
  5. from jimvc.models import app_config
  6. from jimvc.models import Database as db
  7. __author__ = 'James Iter'
  8. __date__ = '2017/9/19'
  9. __contact__ = 'james.iter.cn@gmail.com'
  10. __copyright__ = '(c) 2017 by James Iter.'
  11. class Host(object):
  12. def __init__(self):
  13. pass
  14. @staticmethod
  15. def alive_check(v):
  16. """
  17. 60 秒内没收到更新,作为判断 [计算节点] 是否在线的标准。包含了 [计算节点] 与 [控制节点] 间的时间差。
  18. """
  19. coupler_length = 60
  20. if 'timestamp' not in v:
  21. return v
  22. v['alive'] = False
  23. if v['timestamp'] + coupler_length >= g.ts:
  24. v['alive'] = True
  25. if 'threads_status' not in v:
  26. v['threads_status'] = {
  27. 'instruction_process_engine': {
  28. 'timestamp': 0
  29. },
  30. 'host_state_report_engine': {
  31. 'timestamp': 0
  32. },
  33. 'guest_creating_progress_report_engine': {
  34. 'timestamp': 0
  35. },
  36. 'guest_performance_collection_engine': {
  37. 'timestamp': 0
  38. },
  39. 'host_performance_collection_engine': {
  40. 'timestamp': 0
  41. }
  42. }
  43. v['threads_status']['instruction_process_engine']['alive'] = False
  44. if v['threads_status']['instruction_process_engine']['timestamp'] + coupler_length >= g.ts:
  45. v['threads_status']['instruction_process_engine']['alive'] = True
  46. v['threads_status']['host_state_report_engine']['alive'] = False
  47. if v['threads_status']['host_state_report_engine']['timestamp'] + coupler_length >= g.ts:
  48. v['threads_status']['host_state_report_engine']['alive'] = True
  49. v['threads_status']['guest_creating_progress_report_engine']['alive'] = False
  50. if v['threads_status']['guest_creating_progress_report_engine']['timestamp'] + coupler_length >= g.ts:
  51. v['threads_status']['guest_creating_progress_report_engine']['alive'] = True
  52. v['threads_status']['guest_performance_collection_engine']['alive'] = False
  53. if v['threads_status']['guest_performance_collection_engine']['timestamp'] + coupler_length >= g.ts:
  54. v['threads_status']['guest_performance_collection_engine']['alive'] = True
  55. v['threads_status']['host_performance_collection_engine']['alive'] = False
  56. if v['threads_status']['host_performance_collection_engine']['timestamp'] + coupler_length >= g.ts:
  57. v['threads_status']['host_performance_collection_engine']['alive'] = True
  58. return v
  59. @staticmethod
  60. def set_allocation_mode(hosts_name=None, random=True):
  61. if not isinstance(hosts_name, list):
  62. raise ValueError('The hosts_name must be a list.')
  63. if random:
  64. db.r.sadd(app_config['compute_nodes_of_allocation_by_nonrandom'], *hosts_name)
  65. else:
  66. db.r.srem(app_config['compute_nodes_of_allocation_by_nonrandom'], *hosts_name)
  67. @classmethod
  68. def get_all(cls):
  69. ret = list()
  70. compute_nodes_of_allocation_by_nonrandom = \
  71. list(db.r.smembers(app_config['compute_nodes_of_allocation_by_nonrandom']))
  72. for k, v in db.r.hgetall(app_config['hosts_info']).items():
  73. v = json.loads(v)
  74. v = cls.alive_check(v)
  75. v['node_id'] = k
  76. if v['hostname'] in compute_nodes_of_allocation_by_nonrandom:
  77. v['nonrandom'] = True
  78. else:
  79. v['nonrandom'] = False
  80. ret.append(v)
  81. if ret.__len__() > 1:
  82. ret.sort(key=lambda _k: _k['boot_time'])
  83. return ret
  84. @classmethod
  85. def get_available_hosts(cls, nonrandom=None):
  86. """
  87. :param nonrandom: {None, True, False}
  88. None for all;
  89. False for host can be allocation guest by random;
  90. True on the contrary.
  91. :return:
  92. """
  93. hosts = list()
  94. for host in cls.get_all():
  95. if not host['alive']:
  96. continue
  97. if nonrandom is not None and host['nonrandom'] != nonrandom:
  98. continue
  99. host['system_load_per_cpu'] = float(host['system_load'][0]) / host['cpu']
  100. hosts.append(host)
  101. hosts.sort(key=lambda _k: _k['system_load_per_cpu'])
  102. return hosts
  103. @staticmethod
  104. def get_lightest_host():
  105. # 负载最小的宿主机
  106. lightest_host = None
  107. for k, v in db.r.hgetall(app_config['hosts_info']).items():
  108. v = json.loads(v)
  109. if lightest_host is None:
  110. lightest_host = v
  111. if float(lightest_host['system_load'][0]) / lightest_host['cpu'] > \
  112. float(v['system_load'][0]) / v['cpu']:
  113. lightest_host = v
  114. return lightest_host