python实现harbor镜像同步脚本

脚本注意事项:

1、脚本实现了harbor 仓库里面所有镜像扫描同步,其中脚本里面x.x.x.x 是docker  pull 的地址,y.y.y.y是docker  push 的地址 

2、 auth('admin','password') 是x.x.x.x  harbor 仓库的用户名和密码。

3、脚本里面涉及了三个日志文件,not_done.log 是同步失败的镜像日志,done.log 是同步成功的列表,info.log 记录整个脚本输出日志

4、脚本部署的机器必须同时docker  login 上面两个harbor 仓库

5、镜像同步的项目必须存在

import logging
import requests
import os
import subprocess

# 项目projects  url
url = 'http://x.x.x.x/api/v2.0/projects/'

# 存储项目名称
project_name = []

# 存储镜像,只有镜像路径
image_list = []

# 封装之后里面有镜像路径和tag
image_new_list = []

# 日志路径
current_path = os.path.dirname(os.path.abspath(__file__))
log_filename = current_path + '/' + 'info.log'
logging.basicConfig(filename=log_filename,
                    level=logging.INFO,
                    format='%(asctime)s \"%(filename)s\"[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt="%Y-%m-%d %H:%M:%S",
                    filemode='a')

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"
}


def get_project_name():
    response_project = requests.get(url, headers=headers, auth=('admin', 'password'), verify=False)
    # 返回结果是一个列表里面包含了很多字典
    response_list = response_project.json()
    # print(response_project.status_code)
    for dic in response_list:
        dicts = {}
        for name in dic:
            if name == 'name':
                dicts['name'] = dic[name]
            if name == 'repo_count':
                dicts['page'] = dic[name] // 1000 + 1
        project_name.append(dicts)
    # print(project_name)
    return project_name


# 获取镜像完成路径,传输参数:pr_name 是 project_name 是一个列表,返回镜像列表
def get_image_name(pr_name):
    for pro_name in pr_name:
        url_repositories = url + pro_name['name'] + '/repositories'
        params = {
            "page": pro_name['page'],
            "page_size": 100
        }
        response_repositories = requests.get(url_repositories, params=params, headers=headers,
                                             auth=('admin', 'password'),
                                             verify=False)
        list_response = response_repositories.json()
        # print(response_repositories.status_code)
        if len(list_response) == 0:
            continue
        else:
            for repositories_name in list_response:
                # print(repositories_name)
                image_list.append(repositories_name['name'])
        return image_list


pro_name = get_project_name()
# print(pro_name)
get_image_name(pro_name)


# print(image_list)


# get_tag 函数返回一个列表包含字典,字典里面是name 和 tag
def get_tag(images_list):
    list1 = []
    for names in images_list:
        index = names.find('/')
        p_name = names[:index]
        reps_name = names[index + 1:].replace('/', '%252F')
        tag_url = url + p_name + '/repositories/' + reps_name + '/artifacts'
        re = requests.get(tag_url, auth=('admin', 'password'))
        for di in re.json():
            dict_image = {'tag': []}
            for tag in di['tags']:
                dict_image['name'] = names
                dict_image['tag'].append(tag['name'])
            for tag in dict_image['tag']:
                image_new_list.append(dict_image['name'] + ':' + tag)
    return image_new_list


ll = get_tag(image_list)
print(ll)


# compare_list_with_file函数作用比较镜像列表和文件内容的不同地方,different_content存储不同的内容
def compare_list_with_file(images, file_path):
    # 读取文件内容
    with open(file_path, 'r') as file:
        file_content = file.read()
    different_content = []
    # 比较列表中的每个元素
    if images not in file_content:
        different_content.append(images)

    # 输出不同的内容
    return different_content


# 函数 sync 进行同步镜像,参数为镜像名称:tag 和 日志路径
def sync(image, logs_done,logs_not_done):
    destination_address = 'x.x.x.x/'
    source_address = 'y.y.y.y/'
    try:
        os.system('docker pull ' + source_address + image)
        os.system('docker tag ' + source_address + image + ' ' + destination_address + image)
        print('docker tag ' + source_address + image + ' ' + destination_address + image)
        os.system('docker push ' + destination_address + image)
        push = 'docker push ' + destination_address + image
        result_push = subprocess.run(push, shell=True)
        print(result_push.returncode)
        if result_push.returncode == 0:
            f = open(logs_done, 'a')
            f.write(image + '\n')
            f.close()
        else:
            f = open(logs_not_done, 'a')
            f.write(image + '\n')
            f.close()
        print('docker push ' + destination_address + image)
        os.system('docker rmi ' + destination_address + image)
        os.system('docker rmi ' + source_address + image)
        logging.info(image)
    except Exception as err:
        logging.error(err)


for images in image_new_list:
    current_path = os.path.dirname(os.path.abspath(__file__))
    log_done = current_path + '/' + 'done.log'
    logs_not_done = current_path + '/' + 'not_done.log'
    try:
        # if os.path.getsize(log_done) == 0:
        #     logging.info('正在进行全量同步!')
        #     sync(images, log_done)
        # else:
        different = compare_list_with_file(images, log_done)
        for diff in different:
            sync(diff, log_done,logs_not_done)
    except Exception as err:
        logging.error(err)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Python来操作Harbor。下面是一个使用Python脚本来删除Harbor仓库中不再需要的镜像的示例: ```python import requests # 设置Harbor的地址和登录信息 harbor_url = 'http://127.0.0.1' username = 'admin' password = 'Harbor12345' # 登录Harbor session = requests.Session() login_url = harbor_url + '/login' session.post(login_url, json={'username': username, 'password': password}) # 获取所有镜像仓库 repositories_url = harbor_url + '/api/v2.0/projects' response = session.get(repositories_url) repositories = response.json() # 遍历每个镜像仓库 for repository in repositories: repository_name = repository['name'] repository_id = repository['project_id'] # 获取仓库中的所有镜像 images_url = harbor_url + f'/api/v2.0/projects/{repository_id}/repositories' response = session.get(images_url) images = response.json() # 遍历每个镜像 for image in images: image_name = image['name'] image_id = image['id'] # 判断镜像是否需要删除,这里假设镜像名包含"old"的都需要删除 if 'old' in image_name: # 删除镜像 delete_url = harbor_url + f'/api/v2.0/projects/{repository_id}/repositories/{image_id}' session.delete(delete_url) print(f'Deleted image: {image_name} in repository: {repository_name}') # 退出登录 logout_url = harbor_url + '/logout' session.post(logout_url) ``` 这个脚本使用了Python的requests库来发送HTTP请求,实现了登录Harbor、获取镜像仓库、获取镜像和删除镜像的功能。你可以根据自己的需求修改判断镜像是否需要删除的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值