-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
5 changed files
with
461 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
name: image-porter | ||
about: docker镜像搬运工 | ||
title: "[PORTER]" | ||
labels: porter | ||
assignees: '' | ||
|
||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
name: docker image mirror | ||
|
||
on: | ||
issues: | ||
types: [opened] | ||
|
||
env: | ||
RED: \033[1;31m | ||
GREEN: \033[1;32m | ||
YELLOW: \033[1;33m | ||
BLUE: \033[1;34m | ||
PURPLE: \033[1;35m | ||
CYAN: \033[1;36m | ||
BLANK: \033[0m | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
outputs: | ||
DOCKER_IMAGE: ${{ steps.pullIssuesPorter.outputs.DOCKER_IMAGE }} | ||
SUCCESS: ${{ steps.successCheck.outputs.SUCCESS }} | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Get porter issues | ||
id: pullIssuesPorter | ||
uses: actions/github-script@v7 | ||
with: | ||
github-token: ${{secrets.GITHUB_TOKEN}} | ||
script: | | ||
// 使用 title 获取镜像名和tag | ||
const title = context?.payload?.issue?.title; | ||
// 使用 body 获取其它参数 | ||
const body = context?.payload?.issue?.body || ''; | ||
const reg = new RegExp("\\[PORTER\\]", "g"); | ||
let docker_image = title.replace(reg, "").trim(); | ||
const issues_author = context?.payload?.issue?.user?.login; | ||
// 为了防止 image 不带tag,自动添加 latest | ||
if(!docker_image.includes(":")) { | ||
docker_image = `${docker_image}:latest` | ||
} | ||
let comment_body = ''; | ||
let is_error = false; | ||
if( docker_image.includes("@")){ | ||
is_error = true; | ||
comment_body = '@' + issues_author +' 拉取镜像不支持带摘要信息,请去除 @部分' | ||
}else{ | ||
comment_body = `构建进展,详见 [构建任务](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{github.run_id}})` | ||
} | ||
const issuesComment = await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
body: comment_body | ||
}); | ||
console.log("create issues comment resp:", issuesComment["status"]); | ||
if(is_error){ | ||
core.setFailed("Error"); | ||
}else if (!docker_image){ | ||
core.setFailed("No Images"); | ||
} | ||
core.setOutput('DOCKER_IMAGE', docker_image); | ||
core.setOutput('BUILD_ARGS', body); | ||
- name: Retrieve transfer image name | ||
id: transferImage | ||
run: | | ||
echo "${{ steps.pullIssuesPorter.outputs.DOCKER_IMAGE }}" > docker_images.list | ||
- name: Sync image | ||
id: syncImage | ||
shell: bash | ||
run: | | ||
bash jenkins_sync_docker_images.sh docker_images.list | ||
- name: Success check | ||
id: successCheck | ||
uses: actions/github-script@v7 | ||
if: ${{ success() }} | ||
with: | ||
github-token: ${{secrets.GITHUB_TOKEN}} | ||
script: | | ||
core.setOutput('SUCCESS', true); | ||
- name: Close Porter Issues | ||
id: closePorterIssues | ||
uses: actions/github-script@v7 | ||
if: ${{ always() }} | ||
with: | ||
github-token: ${{secrets.GITHUB_TOKEN}} | ||
script: | | ||
const issuesResponse = await github.rest.issues.update({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
state: 'closed' | ||
}); | ||
console.log("update issues resp:", issuesResponse["status"] == 200 ? "success" : "failed" ); | ||
let comment_body = `转换失败,详见 [构建任务](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${{github.run_id}})`; | ||
let success = String(${{ steps.successCheck.outputs.SUCCESS }}).toLowerCase() == "true"; | ||
console.log("is success?", success); | ||
let labels = []; | ||
if(success){ | ||
comment_body = "转换完成,请到你的 Harbor 仓库愉快使用吧 <br/>\n" | ||
labels=['success'] | ||
}else{ | ||
const jobsResponse = await github.request(`GET /repos/${context.repo.owner}/${context.repo.repo}/actions/runs/${{github.run_id}}/jobs`, { | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
run_id: ${{ github.run_id }} | ||
}); | ||
console.log("jobs",jobsResponse['data']); | ||
comment_body += "\n\n 日志:\n\n"; | ||
for(let job of jobsResponse['data']['jobs']){ | ||
comment_body += "- [" + job.name + "](" + job.html_url +")"; | ||
} | ||
labels = ['failure']; | ||
} | ||
// 创建 issues comment | ||
const issuesComment = await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
body: comment_body | ||
}); | ||
console.log("create issues comment resp:", issuesComment["status"] == 201 ? "success" : "failed" ); | ||
// 更新 issues label | ||
if(labels){ | ||
await github.rest.issues.addLabels({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
labels: labels | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
pipeline { | ||
options { | ||
// 流水线超时设置 | ||
timeout(time:1, unit: 'HOURS') | ||
//保持构建的最大个数 | ||
buildDiscarder(logRotator(numToKeepStr: '20')) | ||
} | ||
|
||
agent { | ||
label "hk-node" | ||
} | ||
|
||
environment { | ||
// 全局环境变量 | ||
// SRC_HARBOR_URL = "" // 源harbor地址 | ||
// SRC_HARBOR_CRE = credentials('') // 源harbor用户密码 | ||
// SRC_HARBOR_REGISTRY = "dev" // 源harbor项目仓库 | ||
DEST_HARBOR_URL = "harbor地址" // 目标harbor地址 | ||
DEST_HARBOR_CRE = credentials('harbor') // 目标harbor用户密码 | ||
// DEST_HARBOR_REGISTRY = "library" // 目标harbor项目仓库, 已使用input | ||
} | ||
|
||
parameters { | ||
// 多行文本输入 | ||
text(name: 'DOCKER_IMAGES', defaultValue: 'nginx:latest', description: '镜像列表, 一行一个') | ||
choice(name: 'DEST_HARBOR_REGISTRY', choices: 'library', description: '选择同步至仓库项目') | ||
} | ||
|
||
stages { | ||
stage('批量同步docker镜像') { | ||
steps { | ||
// 写入文件中 | ||
writeFile file: "docker_images.list", text: "$DOCKER_IMAGES\n", encoding: "UTF-8" | ||
ansiColor('xterm') { | ||
echo "#################### 同步镜像开始 ####################" | ||
sh """set +x | ||
/bin/bash jenkins_sync_docker_images.sh docker_images.list | ||
""" | ||
echo "#################### 同步镜像完成 ####################" | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# mirror-images | ||
|
||
利用“外网”节点同步镜像至私有 Harbor 仓库 | ||
|
||
## 使用 Jenkins | ||
|
||
## 使用 Github action | ||
请设置 action 环境变量 DEST_HARBOR_URL , secret DEST_HARBOR_CRE_USR 和 DEST_HARBOR_CRE_PSW | ||
通过新建 Issuse 触发 | ||
|
||
>标题建议为 `[PORTER]镜像名:tag` 的格式,例如`[PORTER]k8s.gcr.io/pause:3.6` | ||
>issues的内容设定为`skopeo copy`的参数,默认为空 | ||
其它参数可以参考:[skopeo copy](https://github.com/containers/skopeo/blob/main/docs/skopeo-copy.1.md) |
Oops, something went wrong.