使用Python 3脚本自动化Harbor镜像复制

news/2024/7/24 12:01:06 标签: python, 自动化, java

介绍:

在容器化应用程序的世界中,Docker镜像是构建和部署的核心。许多组织使用Harbor作为他们的镜像仓库管理解决方案。但有时候,需要将镜像从一个Harbor仓库复制到另一个,这可能会是一个繁琐的任务。为了简化这个过程,我们将介绍如何使用Python脚本来自动化这个任务。这个脚本将从源Harbor仓库中复制镜像,并将其推送到目标Harbor仓库,同时保留标签和元数据。

脚本概览:

在这个部分,我们将简要介绍脚本的基本结构和功能。该脚本使用Python的subprocess模块执行Curl命令来与Harbor API进行通信,并处理返回的JSON数据。它还利用Docker命令来拉取、标记、推送和删除镜像。

python3">import subprocess
import json
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 替换这里的Harbor仓库地址和凭据
harbor_url = "https://harbor.test.com"
harbor_name = "harbor.test.com"
username = "admin"
password = "Harbor12345"

# 替换为新仓库的地址和凭据
new_harbor_url = "https://harbor.test.com"
new_harbor_name = "harbor.test.com"
new_harbor_pro = "test"
new_username = "admin"
new_password = "Harbor12345"

# 执行Curl命令获取项目列表
try:
    curl_output = subprocess.check_output(
        f'curl --insecure -u "{username}:{password}" -X GET -H "Content-Type: application/json" {harbor_url}/api/v2.0/projects|jq', 
        shell=True
    ).decode('utf-8')
except subprocess.CalledProcessError as e:
    logging.error(f"获取项目列表时出错: {e}")
    exit(1)

# 将Curl命令的输出解析为JSON
try:
    projects = json.loads(curl_output)
except json.JSONDecodeError as e:
    logging.error(f"无法解析JSON数据: {e}")
    exit(1)

# 遍历项目列表
for project in projects:
    project_name = project["name"]
    
    # 执行Curl命令获取项目下的镜像列表
    try:
        curl_output = subprocess.check_output(
            f'curl --insecure -u "{username}:{password}" -X GET -H "Content-Type: application/json" {harbor_url}/api/v2.0/projects/{project_name}/repositories|jq', 
            shell=True
        ).decode('utf-8')
    except subprocess.CalledProcessError as e:
        logging.error(f"获取项目 {project_name} 的镜像列表时出错: {e}")
        continue

    # 将Curl命令的输出解析为JSON
    try:
        repositories = json.loads(curl_output)
    except json.JSONDecodeError as e:
        logging.error(f"无法解析项目 {project_name} 的镜像列表: {e}")
        continue

    # 遍历镜像列表
    for repo in repositories:
        repo_name = repo["name"]
        repo_name_new_repo_name = repo_name.split("/", 1)

        if len(repo_name_new_repo_name) > 1:
            # 如果成功分割出两部分,repo_name_new_repo_name[1] 将包含第一个斜杠之后的部分
            new_repo_name = repo_name_new_repo_name[1]
        else:
            # 如果没有斜杠或只有一个斜杠,将保持原始 repo_name
            new_repo_name = repo_name
        
        # 执行Curl命令获取镜像标签列表
        try:
            curl_output = subprocess.check_output(
                f'curl --insecure -u "{username}:{password}" -X GET -H "Content-Type: application/json" {harbor_url}/api/v2.0/projects/{project_name}/repositories/{new_repo_name}/artifacts', 
                shell=True
            ).decode('utf-8')
        except subprocess.CalledProcessError as e:
            logging.error(f"获取镜像 {repo_name} 标签列表时出错: {e}")
            continue

        # 提取标签信息
        try:
            artifacts = json.loads(curl_output)
            for image_info in artifacts:
                digest = image_info["digest"]
                tags = image_info["tags"]
                # 遍历每个标签并构建镜像地址
                for tag in tags:
                    tag_name = tag["name"]
                    source_image_url = f"{harbor_name}/{project_name}/{new_repo_name}:{tag_name}"
                    new_image_url = f"{new_harbor_name}/{new_harbor_pro}/{new_repo_name}:{tag_name}"
                    
                    # 拉取源镜像
                    try:
                        subprocess.check_call(
                            f'docker pull {source_image_url}',
                            shell=True
                        )
                    except subprocess.CalledProcessError as e:
                        logging.error(f"无法拉取镜像 {source_image_url}: {e}")
                        continue
                    
                    # 标记新的镜像地址
                    try:
                        subprocess.check_call(
                            f'docker tag {source_image_url} {new_image_url}',
                            shell=True
                        )
                    except subprocess.CalledProcessError as e:
                        logging.error(f"无法标记镜像 {new_image_url}: {e}")
                        continue
                    
                    # 推送新镜像到新仓库
                    try:
                        subprocess.check_call(
                            f'docker push {new_image_url}',
                            shell=True
                        )
                    except subprocess.CalledProcessError as e:
                        logging.error(f"无法推送镜像 {new_image_url}: {e}")
                        continue
                    
                    # 删除本地源镜像
                    try:
                        subprocess.check_call(
                            f'docker rmi {source_image_url}',
                            shell=True
                        )
                    except subprocess.CalledProcessError as e:
                        logging.error(f"无法删除本地镜像 {source_image_url}: {e}")
                        continue
                    
        except (json.JSONDecodeError) as e:
            logging.error(f"无法解析镜像 {repo_name} 的标签信息: {e}")
            continue

logging.info("镜像复制完成。")


配置和前提条件:

在运行脚本之前,您需要配置一些参数,包括源Harbor仓库的地址、凭据,以及目标Harbor仓库的地址和凭据。此外,确保您的系统上已经安装了docker和jq工具。

代码解释:

在这一部分,我们将详细解释脚本的每个部分,包括如何获取项目、镜像和标签信息,如何处理异常情况,以及如何执行Docker命令来操作镜像。

安全性注意事项:

由于涉及凭据和敏感信息,我们将讨论如何在脚本中安全处理这些信息,以防止泄漏。

使用示例:

我们将提供一个具体的示例,展示如何运行脚本以复制Harbor仓库中的镜像。示例还将包括示例命令和输出。

扩展和自定义:

如果您希望根据特定需求对脚本进行扩展或自定义,我们将提供一些建议和示例,以便您可以根据自己的需求进行修改。

总结:

最后,我们将总结脚本的优势和用途,强调自动化复制镜像的重要性,并鼓励读者在他们的工作中考虑使用这个脚本来简化镜像管理任务。


http://www.niftyadmin.cn/n/5034628.html

相关文章

22.2 JavaScript 常用操作

1. BOM操作 浏览器对象模型(BOM): 是JavaScript与浏览器交互的接口集合. 它提供了一组对象, 用于操作浏览器窗口, 历史记录, 文档等. BOM可以通过Javascript代码来访问和控制浏览器的功能和行为.BOM的核心对象是window对象, 它表示浏览器的窗口或框架. 通过window对象, 可以访…

Spring Boot 各版本的支持时间

1. Spring Boot 各版本的支持时间 Spring Boot 2.7 的版本,支持到2023-11-18,之后就要停止支持了。 按照官网的数据,3.0 的版本也是到2023年11月就停止支持了。如果要转到SpringBoot3,直接从3.1开始吧。到写这篇文章时&#xff…

Xcode14.3.1 真机调试iOS17的方法(无iOS17 DeviceSupport)

由于iOS17需要使用Xcode15 才能调试,而当前Xcode15都是beta,正式版还未出,那么要真机调试iOS17的方式一般有两种: 方法一: 一种是下载新的Xcode15 beta版 (但Xcode包一般比较大,好几个G&#…

工厂模式-(简单工厂模式)

首先看一下设计模式的六大原则 设计模式的六大原则 1、开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概…

【Django入门】第一个Django项目

Django,广为人知的Python Web框架,以其强大而又灵活的特点脱颖而出。其宣传口号是:“为完美主义者开发的框架”。这篇文章将为你揭示创建第一个Django项目的魔法以及Django项目的基本结构。 为什么选择Django? 在深入学习前&…

Kotlin | 在for、forEach循环中正确的使用break、continue

文章目录 for循环中使用break、continueLabel标签forEach中如何退出循环资料 Kotlin 有三种结构化跳转表达式: return:默认从最直接包围它的函数或者匿名函数返回。break:终止最直接包围它的循环。continue:继续下一次最直接包围…

Flutter的路由router-页面跳转

文章目录 概念介绍基本路由(Basic Routing)跳转到某个页面弹出页面 命名路由(Named Routing)第三方路由管理库(Third-Party Routing Libraries) Android原生的路由Intent-based Routing(基于Int…

肖sir__mysql之存储__007

mysql之存储 一、存储 1、什么是存储过程 定义:存储过程就是实现某个特定功能的sql语句的集合,编译后的存储过程会保存在数据库中,通过存储过程的名称可以反复的调用执行。 2、存储过程的优点? (1)存储创建后,可以反复的调用&am…