harborv2.5仓库镜像清理脚本

1、脚本通过python调用api接口去删除镜像的,适用于harbor2.0的api接口,只保留镜像的最近的5个tag版本。


import requests
import logging

DATEFMT = '%Y/%m/%d %H:%M:%S'
FORMAT = '%(asctime)s %(levelname)s %(message)s'
# 设置保存路径、日志等级、样式、记录时间
logging.basicConfig(filename='cleanHarbor.log', filemode="w", level=logging.DEBUG, format=FORMAT, datefmt=DATEFMT)


class HarborApi(object):

    def __init__(self):
        url = "https://harbor.com"
        version = "v2.0"
        username = "admin"
        password = ""

        self.base_url = "{}/api/{}".format(url, version)
        self.auth_info = (username, password)

    def get_projects(self, page=1, page_size=15):
        """
        获取projects
        """
        # api_url = "{}/projects".format(self.base_url,)
        api_url = f"{self.base_url}/projects"
        payload = {
            'page': page,
            'page_size': page_size
        }
        r = requests.get(api_url, params=payload, auth=self.auth_info)
        if r.status_code == 200:
            data = {
                'list': r.json(),
                'total': int(r.headers.get('X-Total-Count'))
            }
            return data
        else:
            return False

    def get_all_repositories_name(self, project_name):
        """
        获取所有镜像库名称
        """
        page_size = 100
        r_data = self.get_repositories(
            project_name=project_name, page_size=page_size)
        # print(r_data)
        r_total = r_data.get('total')
        if r_total <= page_size:
            r_name_list = [i.get('name').split(
                f'{project_name}/')[1] for i in r_data.get('list')]
        else:
            r_page_count = int(r_total // page_size) + 1
            r_list = list()

            if r_page_count > 0:
                for page_num in range(1, r_page_count + 1):
                    tmp_r_data = self.get_repositories(
                        project_name=project_name, page=page_num, page_size=page_size)
                    r_list += tmp_r_data.get('list')
            r_name_list = [i.get('name').split(
                f'{project_name}/')[1] for i in r_list]
        return r_name_list

    # repositories
    def get_repositories(self, project_name, page=1, page_size=10):
        """
        获取repositories
        """
        api_url = f"{self.base_url}/projects/{project_name}/repositories"
        payload = {
            'page': page,
            'page_size': page_size
        }
        r = requests.get(api_url, params=payload, auth=self.auth_info)
        if r.status_code == 200:
            data = {
                'list': r.json(),
                'total': int(r.headers.get('X-Total-Count'))
            }
            return data
        else:
            return False

    # artifacts
    def get_artifacts(self, project_name, repository_name, page=1, page_size=10):
        """
        获取artifacts
        """
        # api_url = self.base_url + 'projects/' + \
        #     project_name + '/repositories/' + repository_name + '/artifacts'
        api_url = f"{self.base_url}/projects/{project_name}/repositories/{repository_name}/artifacts"
        payload = {
            'page': page,
            'page_size': page_size
        }
        r = requests.get(api_url, params=payload, auth=self.auth_info)
        if r.status_code == 200:
            data = {
                'list': r.json(),
                'total': int(r.headers.get('X-Total-Count'))
            }
            return data
        else:
            return False

    def get_artifacts_info(self, project_name, repository_name, page_size=100):
        """
        返回字典
        {
            2202: {
                'digest': 'sha256:42c81fef9bab44db198fb4123dc41a8511f491c0c5977803ad226184d0a8c93a',
                'tags': ['dev-20220902151655']
            },
            2200: {
                'digest': 'sha256:b8b98515dc61054fa19b74b7bb31f8414382585cdfff12c370c53d22b48a3021',
                'tags': ['dev-20220902150345']
            }
        }
        """
        a_data = self.get_artifacts(
            project_name=project_name, repository_name=repository_name, page_size=page_size)
        a_total = a_data.get('total')
        if a_total <= page_size:
            tmp_a_list = a_data.get('list')
        else:
            a_page_count = int(a_total // page_size) + 1
            tmp_a_list = list()
            if a_page_count > 0:
                for page_num in range(1, a_page_count + 1):
                    tmp_a_data = self.get_artifacts(
                        project_name=project_name, repository_name=repository_name, page=page_num, page_size=page_size)
                    tmp_a_list += tmp_a_data.get('list')
        a_dict = dict()
        tags_list = list()
        for artifact in tmp_a_list:
            if artifact['tags'] and len(artifact['tags']) >= 0:
                tags = [g['name'] for g in artifact.get('tags')]
                a_dict[artifact.get('id')] = {
                    'digest': artifact.get('digest'),
                    'tags': tags
                }
                tags_list += tags
        a_dict['tags'] = tags_list
        return a_dict

    def generate_delete_list(self, project_name, repository_name):
        """
        生成删除列表
        """
        save_max_num = 5

        a_data = self.get_artifacts_info(
            project_name=project_name, repository_name=repository_name)
        tags_list = a_data.get('tags')

        if len(tags_list) > save_max_num:
            del_tags_list = tags_list[5:]
        else:
            del_tags_list = []
        del_digest_list = list()
        for k, v in a_data.items():
            if type(v) is dict:
                if v.get('tags')[0] in del_tags_list:
                    del_digest_list.append(v.get('digest'))

        # print(len(tags_list),len(del_tags_list),len(del_digest_list))
        return del_digest_list

    # del artifacts
    def del_artifact(self, project_name, repository_name, digest):
        """
        删除镜像artifact
        curl -u admin:sajdhaksh -X DELETE "https://harbor.com/api/v2.0/projects/izu/repositories/izu-mrcar-workflow/artifacts/sha256:26249cff21efc04d7b696c4c86bbae88d4e042407471ff8951aa292d583c34ff"
        """
        api_url = f"{self.base_url}/projects/{project_name}/repositories/{repository_name}/artifacts/{digest}"
        r = requests.delete(api_url, auth=self.auth_info)
        if r.status_code == 200:
            return True
        else:
            return False

    def clean_artifact(self, project_name, repository_name):
        """
        自动清理空间
        1.获取所有仓库名称 get_all_repositories_name
        2.获取仓库内制品    get_artifacts_info
        3.只保留最近的5个tag
        4.删除制品
        """
        # if project_name != 'izu':
        #     return False
        del_digest_list = self.generate_delete_list(
            project_name=project_name, repository_name=repository_name)
        real_del_num = 0

        for digest in del_digest_list:
            result = self.del_artifact(
                project_name=project_name, repository_name=repository_name, digest=digest)
            if result:
                real_del_num += 1
        logging.info(
            f"项目:{project_name},仓库:{repository_name},总镜像数{5 + len(del_digest_list)},应删除{len(del_digest_list)},已删除{real_del_num}")
        return f"项目:{project_name},仓库:{repository_name},总镜像数{5 + len(del_digest_list)},应删除{len(del_digest_list)},已删除{real_del_num}"


if __name__ == '__main__':
    hb = HarborApi()
    #填写需要清理horbor的项目名
    project_names = ['', '']

    for project_name in project_names:
        r_name_list = hb.get_all_repositories_name(project_name=project_name)
        # print(len(r_name_list))
        for r_name in r_name_list:
            res = hb.clean_artifact(project_name=project_name, repository_name=r_name)
            print(res)

   

2、在harbor仓库里面系统管理-垃圾清理配置下定时清理规则

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值