Harbor同步仓库镜像到另一个仓库

文章目录

  • Harbor同步仓库镜像到另一个仓库
    • 清单文件-示例
    • 同步脚本-示例
    • 使用Python获取清单文件的示例

Harbor同步仓库镜像到另一个仓库

  • 因为近期有业务需求需要将一个Harbor仓库的所有镜像同步到另一个仓库,所以写了点脚本来处理

清单文件-示例

  • 提前准备镜像清单(CSV文件头“项目, artifact, tag, 哈希值”)
custom-images,docker-image-tmp,test-20220211171020,sha256:8ea34c3291aa5a28ef7b8de188023037f8ccc3a31287bd5a80d6e58be3714bc7
custom-images,imagetmp,test-20211230154117,sha256:05dbe98097d2a6b489a4b7095a416c838004246b6ebdf33d8389df47bc451d58
custom-images,flaskweb,test-20220510162600,sha256:5e3451fea2a66ba82887f8be8d0d1f421438e5b7cc435aac8475204b02fa8c50
custom-images,flaskweb,test-20211223164921,sha256:31e69778c25ff51bd5d29ad6cfb340a46d86a07212c8f6f4813f557598ac2e8e
  • 可以不要最后的哈希值
  • 生成该列表的Python样例脚本见文末

同步脚本-示例

  • Shell 脚本 transformer.sh
#! /bin/bash# 镜像清单。CSV格式,头:项目,artifact,Tag,哈希值
images_list_file=image_list.csv# Harbor镜像源仓库和推送的目标仓库
src_harbor=harbor.myai.com
tgt_harbor=harbor-internal.myai.com:44104
docker login -u admin -p NFW3xDVVa1ki ${src_harbor}
docker login -u aaas -p EML3G0zcV2Pv ${tgt_harbor}# 本地单独备份镜像的目录,不想保存的话请注释掉下面docker save部分的代码
output_dir=/data/ai/harbor-images# 开始处理
echo -e "\e[34m Start transmission: ${src_harbor} => ${tgt_harbor} \e[0m"while read line
do# 按行读取文本,开始解析echo -e "\e[34m Transfer ===> ${line} \e[0m"array=(${line//,/ })project=${array[0]}artifact=${array[1]}tag=${array[2]}# digest=${array[3]}# 拉取,保存,推送,清理image_url="${project}/${artifact}:${tag}"docker pull "${src_harbor}/${image_url}"docker save "${src_harbor}/${image_url}" -o "${output_dir}/${project}.${artifact}.${tag}.tar"docker tag "${src_harbor}/${image_url}" "${tgt_harbor}/${image_url}"docker push "${tgt_harbor}/${image_url}"docker rmi "${src_harbor}/${image_url}"docker rmi "${tgt_harbor}/${image_url}"done < $images_list_file# 结束处理
echo -e "\e[34m End transmission: ${src_harbor} => ${tgt_harbor} \e[0m"
  • 直接执行 $ bash transformer.sh
  • 后台执行 $ nohup ./transformer.sh 1>run.log 2>&1 &

使用Python获取清单文件的示例

  • 替换domain_urlcookie 后,直接执行该Python代码即可
import requests
import jsondomain_url = "http://1.1.1.1"
cookie = "rem-username=admin; _gorilla_csrf=MTcxxTA0NDI0N3xJbWcxY2tkREt2Vk1Wa3hIZG5sS01WWmhWVzR5YUU0MWVGQjNVMmtyYldaUWJYcEtWSGhaTkZaUFJsazlJZ289fHY6Uw-UXyL3iCnO_E4zkDoAgYj3QsEki0-dr0wmqb2i; sid=96e1f91f4c157a6f51489ca6962e2eb7"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"def req_root_list():url = f"{domain_url}/api/v2.0/projects"querystring = {"page": "1", "page_size": "25"}headers = {"cookie": cookie,"user-agent": user_agent,"accept": "application/json","accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6","cache-control": "no-cache","connection": "keep-alive","content-type": "application/json"}response = requests.request("GET", url, headers=headers, params=querystring)if response.status_code == 200:return json.loads(response.text)else:raise Exception("Error get_root_list")def req_project_list(project_name: str):url = f"{domain_url}/api/v2.0/projects/{project_name}/repositories"querystring = {"page_size": "15", "page": "1"}headers = {"cookie": cookie,"user-agent": user_agent,"accept": "application/json, text/plain, */*","accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6","connection": "keep-alive",}response = requests.request("GET", url, headers=headers, params=querystring)if response.status_code == 200:return json.loads(response.text)else:raise Exception("Error get_project_list")def req_artifacts_list(project_name: str, artifacts_name: str):url = f"{domain_url}/api/v2.0/projects/{project_name}/repositories/{artifacts_name}/artifacts"querystring = {"with_tag": "false","with_scan_overview": "true","with_label": "true","page_size": "15","page": "1",}headers = {"cookie": cookie,"user-agent": user_agent,"accept": "application/json, text/plain, */*","accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6","connection": "keep-alive","x-accept-vulnerabilities": "application/vnd.security.vulnerability.report; version=1.1, application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0",}response = requests.request("GET", url, headers=headers, params=querystring)if response.status_code == 200:return json.loads(response.text)else:raise Exception("Error get_artifacts_list")def req_tags_by_digest(project_name: str, artifacts_name: str, digest: str):url = f"{domain_url}/api/v2.0/projects/{project_name}/repositories/{artifacts_name}/artifacts/{digest}/tags"querystring = {"with_signature": "true","with_immutable_status": "true","page_size": "8","page": "1",}headers = {"cookie": cookie,"user-agent": user_agent,"accept": "application/json, text/plain, */*","accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6","connection": "keep-alive",}response = requests.request("GET", url, headers=headers, params=querystring)if response.status_code == 200:return json.loads(response.text)else:raise Exception("Error get_tag_by_digest")if __name__ == "__main__":# 获取Harbor根列表root_list = req_root_list()for r_item in root_list:project_name = r_item["name"]# 获取Harbor根下的项目内的列表project_list = req_project_list(project_name)for p_item in project_list:artifacts_name = p_item["name"].split("/")[1]# print(artifacts_name)artifacts_list = req_artifacts_list(project_name, artifacts_name)for a_item in artifacts_list:digest = a_item["digest"]tags = req_tags_by_digest(project_name, artifacts_name, digest)for tag in tags:tag_name = tag["name"]print(project_name + "/" + artifacts_name + ", " + tag_name + ", " + digest)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/8589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

事件组理论

文章目录 一、事件组理论 一、事件组理论 区别于之前的队列、信号量、互斥量只能用于单个事件&#xff0c;事件组用于多个事件 事件组结构体&#xff1a;用uxEventBits整数来代表多个事件&#xff0c;每一位代表一个事件。类似于GPIOx_IDR寄存器。 typedef struct EventGroupD…

JRT失控处理打印和演示

基于JRT完备的脚本化和打印基础&#xff0c;基于JRT的业务可以轻松的实现想要的打效果&#xff0c;这次以质控图的失控处理打印和月报打印来分享基于JRT的打印业务实现。 演示视频链接 失控报告打印 失控处理打印的虚拟M import JRT.Core.DataGrid.GridDto; import JRT.Co…

Konga域名配置多个路由

云原生API网关-Kong部署与konga基本使用 Nginx server{listen 443 ssl;location / {proxy_pass http://127.0.0.1:8100;}location /openApi {proxy_pass http://172.31.233.35:7100/openApi;} } Kong {"id": "f880b21c-f7e0-43d7-a2a9-221fe86d9231&q…

特化标准库中的类模板

以std::map和std::less作为载体说明如何特化标准库中的类模板。 std::map容器允许提供一个自定义的比较器。默认行为是让std::map使用一个模板类std::less<>&#xff0c;使用<运算符来比较键。如果想存储一个不能使用<进行比较的类型&#xff0c;可以为此类型特化…

通过AOP实现项目中业务服务降级功能

最近项目中需要增强系统的可靠性&#xff0c;比如某远程服务宕机或者网络抖动引起服务不可用&#xff0c;需要从本地或者其它地方获取业务数据&#xff0c;保证业务的连续稳定性等等。这里简单记录下业务实现&#xff0c;主要我们项目中调用远程接口失败时&#xff0c;需要从本…

Nest.js中使用任务调度

java中的xxl在nestJs中是有内置的任务调度nestjs/schedule npm install --save nestjs/schedule 在model中引入使用 在service中直接使用就行 具体间隔多久看官方配置 Task Scheduling | NestJS 中文文档 | NestJS 中文网

Python 的主要应用领域有哪些?

左手编程&#xff0c;右手年华。大家好&#xff0c;我是一点 公众号&#xff1a;一点sir&#xff0c;关注领取编程资料 Python&#xff0c;作为一种功能强大的编程语言&#xff0c;因其简洁易学的特性而广受开发者喜爱。以下是Python的几个主要应用领域&#xff1a; Web应用开…

稀疏数据在机器学习任务中的应用问题

什么是稀疏数据 在机器学习任务中&#xff0c;稀疏数据是指在大量数据中&#xff0c;只有少部分数据是有效或非零的情况。在稀疏数据集中&#xff0c;有大量的0值或者缺失值。 例如&#xff0c;在自然语言处理中&#xff0c;当我们使用"词袋"模型表示文本信息时&am…

微信小程序开发-数据事件绑定

&#x1f433;简介 数据绑定 数据绑定是一种将小程序中的数据与页面元素关联起来的技术&#xff0c;使得当数据变化时&#xff0c;页面元素能够自动更新。这通常使用特定的语法&#xff08;如双大括号 {{ }}&#xff09;来实现&#xff0c;以便在页面上展示动态数据。 事件绑…

小微公司可用的开源ERP系统

项目介绍 华夏ERP是基于SpringBoot框架和SaaS模式的企业资源规划&#xff08;ERP&#xff09;软件&#xff0c;旨在为中小企业提供开源且易用的ERP解决方案。它专注于提供进销存、财务和生产功能&#xff0c;涵盖了零售管理、采购管理、销售管理、仓库管理、财务管理、报表查询…

VALSE 2024 Workshop报告分享┆ 大规模自动驾驶仿真系统研究

视觉与学习青年学者研讨会&#xff08;VALSE&#xff09;旨在为从事计算机视觉、图像处理、模式识别与机器学习研究的中国青年学者提供一个广泛而深入的学术交流平台。该平台旨在促进国内青年学者的思想交流和学术合作&#xff0c;以期在相关领域做出显著的学术贡献&#xff0c…

【三】DRF序列化进阶

序列化器的定义与使用 多表关联序列化 【1】准备工作 # settings.py DATABASES {default: {# 数据库引擎选择使用MySQLENGINE: django.db.backends.mysql,# 指定数据库名字&#xff0c;需提前创建NAME: books,# 指定数据库用户名USER: root,# 指定数据库用户密码PASSWORD: …

[C/C++] -- 观察者模式

观察者模式是一种行为型设计模式&#xff0c;用于定义对象间的一种一对多的依赖关系&#xff0c;使得当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。 观察者模式涉及以下几个角色&#xff1a; 主题&#xff08;Subject&#xff09;&…

nodejs中与终端控制台交互

通过nodejs里提供的readline&#xff0c;做到与终端控制台交互 const fs require("fs"); // 与终端控制台交互 const readline require("readline");// 终端的输入输出 const r1 readline.createInterface({// 控制台输出output: process.stdout,// 控…

嵌入式学习69-C++(Opencv)

知识零碎&#xff1a; QT的两种编译模式 1.debug 调试模式 …

注册一家伊拉克公司的资料

伊拉克是石油出口大国&#xff0c;石油产业是国民经济的命脉。近年来&#xff0c;伊拉克政府致力于推进经济重建和多元化发展&#xff0c;努力减少对石油产业的依赖。然而&#xff0c;由于政治局势动荡和安全形势不稳定&#xff0c;伊拉克经济发展面临诸多挑战。 在伊拉克注册公…

时序图详解

1.这是iic总线在回应时候的时序图&#xff0c;data in代表eeprom收到数据&#xff0c;回stm32的ack&#xff0c;数据回应&#xff0c;data out代表stm32收到eeprom的消息&#xff0c;数据输出ack回应 2.交叉线 代表在这一次输出高电平&#xff0c;或者在这一次也可能输出低电…

运维平台权限与用户管理,赋能企业精细化运维

在当今高度信息化的时代&#xff0c;企业面临着越来越多的设备管理挑战。为了确保设备的高效运维和企业的信息安全&#xff0c;合理的用户分权与细致的管理显得尤为重要。监控易产品深知这一点&#xff0c;因此提供了强大的分权与用户管理功能&#xff0c;助力企业实现精细化运…

代码随想录算法训练营第四十六天

昨天媳妇发烧啦&#xff0c;和他一顿激烈讨论该不该母乳&#xff0c;目前一切良好&#xff0c;题目在单位做完了&#xff0c;但是有个地方想在家里测试一下。 139.单词拆分 要注意先背包后物品&#xff0c;并且物品是变化的&#xff0c;不是直接用wordDict #include <iostre…

探索STLport:C++标准模板库的开源实现

在C++编程的世界里,STL(标准模板库)是一个不可或缺的工具。它提供了许多用于数据结构、算法和其他重要功能的模板类和函数。然而,标准模板库的实现并非只有一种,而其中一个备受推崇的选择就是STLport。 官方下载: STLport: Welcome! STLport是什么? STLport是一个开…