image.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from public import app
  2. from flask import Blueprint
  3. from libs.tools import json_response, JsonParser
  4. from libs.utils import Registry
  5. from apps.deploy.models import Image, ImageTag, App
  6. from libs.decorators import require_permission
  7. blueprint = Blueprint(__name__, __name__)
  8. @blueprint.route('/', methods=['GET'])
  9. @require_permission('publish_image_view | publish_app_add')
  10. def get():
  11. return json_response(Image.query.all())
  12. @blueprint.route('/add', methods=['POST'])
  13. @require_permission('publish_image_add')
  14. def add():
  15. form, error = JsonParser('name','desc','tag').parse()
  16. if error is None:
  17. image = Image.query.filter_by(name=form.name).first()
  18. if image:
  19. return json_response(message='该镜像名字已经存在。')
  20. tag = form.pop('tag')
  21. res = Image(**form).save()
  22. if res:
  23. ImageTag(image_id=res.id,name=tag).save()
  24. return json_response()
  25. return json_response(message='添加镜像失败,请稍后再试!')
  26. return json_response(message=error)
  27. @blueprint.route('/sync', methods=['POST'])
  28. @require_permission('publish_image_sync')
  29. def sync():
  30. reg = Registry(base_url=app.config['DOCKER_REGISTRY_SERVER'])
  31. images = reg.list_images()
  32. for image in images:
  33. image_tags = reg.list_tags(image)
  34. if image_tags:
  35. image_row = Image.upsert({'name': image}, name=image)
  36. else:
  37. continue
  38. for tag in image_tags:
  39. tag_digest = reg.get_tag_digest(image, tag)
  40. tag_created = reg.get_last_modify_date(image, tag)
  41. ImageTag.upsert({'image_id': image_row.id, 'name': tag}, image_id=image_row.id, name=tag, digest=tag_digest,
  42. created=tag_created)
  43. return json_response()
  44. @blueprint.route('/sync/<int:image_id>', methods=['POST'])
  45. @require_permission('publish_image_sync')
  46. def sync_one(image_id):
  47. reg = Registry(base_url=app.config['DOCKER_REGISTRY_SERVER'])
  48. image = Image.query.get_or_404(image_id)
  49. for tag in reg.list_tags(image.name):
  50. tag_digest = reg.get_tag_digest(image.name, tag)
  51. tag_created = reg.get_last_modify_date(image.name, tag)
  52. ImageTag.upsert({'image_id': image.id, 'name': tag}, image_id=image.id, name=tag, digest=tag_digest,
  53. created=tag_created)
  54. return json_response()
  55. @blueprint.route('/<int:img_id>', methods=['PUT'])
  56. @require_permission('publish_image_edit')
  57. def put(img_id):
  58. form, error = JsonParser('desc').parse()
  59. if error is None:
  60. image = Image.query.get_or_404(img_id)
  61. image.update(**form)
  62. return json_response()
  63. return json_response(message=error)
  64. @blueprint.route('/<int:img_id>', methods=['DELETE'])
  65. @require_permission('publish_image_del')
  66. def delete(img_id):
  67. image = Image.query.get_or_404(img_id)
  68. if image.tags:
  69. return json_response(message='删除该镜像所有标签后,才能删除该镜像。')
  70. used_app = App.query.filter_by(image_id=image.id).first()
  71. if used_app:
  72. return json_response(message='应用 %s 还在使用该镜像,请解除关联后再尝试删除该镜像。' % used_app.name)
  73. image.delete()
  74. return json_response()
  75. @blueprint.route('/<int:img_id>/tags/', methods=['GET'])
  76. @require_permission('publish_image_view')
  77. def tag_get(img_id):
  78. tags = ImageTag.query.filter_by(image_id=img_id).order_by(ImageTag.created.desc()).all()
  79. return json_response(tags)
  80. @blueprint.route('/<int:img_id>/tags/<int:tag_id>', methods=['DELETE'])
  81. @require_permission('publish_image_del')
  82. def tag_delete(img_id, tag_id):
  83. img = Image.query.get_or_404(img_id)
  84. tag = ImageTag.query.get_or_404(tag_id)
  85. reg = Registry(base_url=app.config['DOCKER_REGISTRY_SERVER'])
  86. reg.delete(img.name, tag.digest)
  87. tag.delete()
  88. return json_response()