views.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
  2. # Copyright: (c) <spug.dev@gmail.com>
  3. # Released under the AGPL-3.0 License.
  4. from django.views.generic import View
  5. from django.db.models import F
  6. from django.conf import settings
  7. from django_redis import get_redis_connection
  8. from libs import json_response, JsonParser, Argument, human_time, AttrDict
  9. from apps.repository.models import Repository
  10. from apps.deploy.models import DeployRequest
  11. from apps.repository.utils import dispatch
  12. from apps.app.models import Deploy
  13. from threading import Thread
  14. import json
  15. class RepositoryView(View):
  16. def get(self, request):
  17. deploy_id = request.GET.get('deploy_id')
  18. data = Repository.objects.annotate(
  19. app_name=F('app__name'),
  20. env_name=F('env__name'),
  21. created_by_user=F('created_by__nickname'))
  22. if deploy_id:
  23. data = data.filter(deploy_id=deploy_id, status='5')
  24. return json_response([x.to_view() for x in data])
  25. response = dict()
  26. for item in data:
  27. if item.app_id in response:
  28. response[item.app_id]['child'].append(item.to_view())
  29. else:
  30. tmp = item.to_view()
  31. tmp['child'] = [item.to_view()]
  32. response[item.app_id] = tmp
  33. return json_response(list(response.values()))
  34. def post(self, request):
  35. form, error = JsonParser(
  36. Argument('deploy_id', type=int, help='参数错误'),
  37. Argument('version', help='请输入构建版本'),
  38. Argument('extra', type=list, help='参数错误'),
  39. Argument('remarks', required=False)
  40. ).parse(request.body)
  41. if error is None:
  42. deploy = Deploy.objects.filter(pk=form.deploy_id).first()
  43. if not deploy:
  44. return json_response(error='未找到指定发布配置')
  45. form.extra = json.dumps(form.extra)
  46. form.spug_version = Repository.make_spug_version(deploy.id)
  47. rep = Repository.objects.create(
  48. app_id=deploy.app_id,
  49. env_id=deploy.env_id,
  50. created_by=request.user,
  51. **form)
  52. Thread(target=dispatch, args=(rep,)).start()
  53. return json_response(rep.to_view())
  54. return json_response(error=error)
  55. def patch(self, request):
  56. form, error = JsonParser(
  57. Argument('id', type=int, help='参数错误'),
  58. Argument('action', help='参数错误')
  59. ).parse(request.body)
  60. if error is None:
  61. rep = Repository.objects.filter(pk=form.id).first()
  62. if not rep:
  63. return json_response(error='未找到指定构建记录')
  64. if form.action == 'rebuild':
  65. Thread(target=dispatch, args=(rep,)).start()
  66. return json_response(rep.to_view())
  67. return json_response(error=error)
  68. def delete(self, request):
  69. form, error = JsonParser(
  70. Argument('id', type=int, help='请指定操作对象')
  71. ).parse(request.GET)
  72. if error is None:
  73. repository = Repository.objects.filter(pk=form.id).first()
  74. if not repository:
  75. return json_response(error='未找到指定构建记录')
  76. if repository.deployrequest_set.exists():
  77. return json_response(error='已关联发布申请无法删除')
  78. repository.delete()
  79. return json_response(error=error)
  80. def get_requests(request):
  81. form, error = JsonParser(
  82. Argument('repository_id', type=int, help='参数错误')
  83. ).parse(request.GET)
  84. if error is None:
  85. requests = []
  86. for item in DeployRequest.objects.filter(repository_id=form.repository_id):
  87. data = item.to_dict(selects=('id', 'name', 'created_at'))
  88. data['host_ids'] = json.loads(item.host_ids)
  89. data['status_alias'] = item.get_status_display()
  90. requests.append(data)
  91. return json_response(requests)
  92. def get_detail(request, r_id):
  93. repository = Repository.objects.filter(pk=r_id).first()
  94. if not repository:
  95. return json_response(error='未找到指定构建记录')
  96. rds, counter = get_redis_connection(), 0
  97. if repository.remarks == 'SPUG AUTO MAKE':
  98. req = repository.deployrequest_set.last()
  99. key = f'{settings.REQUEST_KEY}:{req.id}'
  100. else:
  101. key = f'{settings.BUILD_KEY}:{repository.spug_version}'
  102. data = rds.lrange(key, counter, counter + 9)
  103. response = AttrDict(data='', step=0, s_status='process', status=repository.status)
  104. while data:
  105. for item in data:
  106. counter += 1
  107. item = json.loads(item.decode())
  108. if item['key'] == 'local':
  109. if 'data' in item:
  110. response.data += item['data']
  111. if 'step' in item:
  112. response.step = item['step']
  113. if 'status' in item:
  114. response.status = item['status']
  115. data = rds.lrange(key, counter, counter + 9)
  116. response.index = counter
  117. if repository.status in ('0', '1'):
  118. response.data = f'{human_time()} 建立连接... ' + response.data
  119. elif not response.data:
  120. response.data = f'{human_time()} 读取数据... \r\n\r\n未读取到数据,Spug 仅保存最近2周的构建日志。'
  121. else:
  122. response.data = f'{human_time()} 读取数据... ' + response.data
  123. return json_response(response)