deploy.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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.http.response import HttpResponseBadRequest, HttpResponseForbidden, HttpResponse
  5. from apps.setting.utils import AppSetting
  6. from apps.deploy.models import Deploy, DeployRequest
  7. from apps.repository.models import Repository
  8. from apps.repository.utils import dispatch as build_dispatch
  9. from apps.deploy.utils import dispatch as deploy_dispatch
  10. from threading import Thread
  11. import hashlib
  12. import hmac
  13. import json
  14. def auto_deploy(request, deploy_id, kind):
  15. if not _is_valid_token(request):
  16. return HttpResponseForbidden()
  17. try:
  18. body = json.loads(request.body)
  19. if not body['ref'].startswith('refs/'): # Compatible with gogs
  20. body['ref'] = 'refs/tags/' + body['ref']
  21. _, _kind, ref = body['ref'].split('/', 2)
  22. if kind == 'branch' and _kind == 'heads':
  23. commit_id = body['after']
  24. if commit_id != '0000000000000000000000000000000000000000' and ref == request.GET.get('name'):
  25. Thread(target=_dispatch, args=(deploy_id, ref, commit_id)).start()
  26. return HttpResponse(status=202)
  27. elif kind == 'tag' and _kind == 'tags':
  28. Thread(target=_dispatch, args=(deploy_id, ref)).start()
  29. return HttpResponse(status=202)
  30. return HttpResponse(status=204)
  31. except Exception as e:
  32. return HttpResponseBadRequest(e)
  33. def _is_valid_token(request):
  34. api_key = AppSetting.get_default('api_key')
  35. # Gitlab Gitee Aliyun(Codeup)
  36. token = request.headers.get('X-Gitlab-Token')
  37. token = token or request.headers.get('X-Gitee-Token')
  38. token = token or request.headers.get('X-Codeup-Token')
  39. if token:
  40. return token == api_key
  41. # Gogs Github
  42. token = request.headers.get('X-Gogs-Signature')
  43. token = token or request.headers.get('X-Hub-Signature-256', '').replace('sha256=', '')
  44. if token:
  45. return token == hmac.new(api_key.encode(), request.body, hashlib.sha256).hexdigest()
  46. return False
  47. def _dispatch(deploy_id, ref, commit_id=None):
  48. deploy = Deploy.objects.filter(pk=deploy_id).first()
  49. if not deploy:
  50. raise Exception(f'no such deploy id for {deploy_id}')
  51. if deploy.extend == '1':
  52. _deploy_extend_1(deploy, ref, commit_id)
  53. else:
  54. _deploy_extend_2(deploy, ref, commit_id)
  55. def _deploy_extend_1(deploy, ref, commit_id=None):
  56. if commit_id:
  57. extra = ['branch', ref, commit_id]
  58. version = f'{ref}#{commit_id[:6]}'
  59. else:
  60. extra = ['tag', ref, None]
  61. version = ref
  62. rep = Repository.objects.create(
  63. deploy=deploy,
  64. app_id=deploy.app_id,
  65. env_id=deploy.env_id,
  66. version=version,
  67. status='1',
  68. extra=json.dumps(extra),
  69. spug_version=Repository.make_spug_version(deploy.id),
  70. created_by=deploy.created_by)
  71. rep = build_dispatch(rep)
  72. if rep.status == '5':
  73. req = DeployRequest.objects.create(
  74. type='3',
  75. status='0' if deploy.is_audit else '2',
  76. deploy=deploy,
  77. repository=rep,
  78. name=rep.version,
  79. version=rep.version,
  80. spug_version=rep.spug_version,
  81. host_ids=deploy.host_ids,
  82. created_by=deploy.created_by
  83. )
  84. if req.status == '2':
  85. deploy_dispatch(req)
  86. def _deploy_extend_2(deploy, ref, commit_id=None):
  87. version = f'{ref}#{commit_id[:6]}' if commit_id else ref
  88. req = DeployRequest.objects.create(
  89. type='3',
  90. status='0' if deploy.is_audit else '2',
  91. deploy=deploy,
  92. name=version,
  93. version=version,
  94. spug_version=Repository.make_spug_version(deploy.id),
  95. host_ids=deploy.host_ids,
  96. created_by=deploy.created_by
  97. )
  98. if req.status == '2':
  99. deploy_dispatch(req)