forked from tech-shrimp/docker_image_pusher
-
Notifications
You must be signed in to change notification settings - Fork 0
186 lines (160 loc) · 8.04 KB
/
docker.yaml
File metadata and controls
186 lines (160 loc) · 8.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
name: Docker
on:
workflow_dispatch:
push:
branches: [ main ]
env:
ALIYUN_REGISTRY: "${{ secrets.ALIYUN_REGISTRY }}"
ALIYUN_NAME_SPACE: "${{ secrets.ALIYUN_NAME_SPACE }}"
ALIYUN_REGISTRY_USER: "${{ secrets.ALIYUN_REGISTRY_USER }}"
ALIYUN_REGISTRY_PASSWORD: "${{ secrets.ALIYUN_REGISTRY_PASSWORD }}"
jobs:
build:
name: Pull
runs-on: ubuntu-latest
steps:
- name: Before freeing up disk space
run: |
echo "Before freeing up disk space"
echo "=============================================================================="
df -hT
echo "=============================================================================="
# 增加可用磁盘空间
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 2048
swap-size-mb: 128
remove-dotnet: 'true'
remove-haskell: 'true'
# 如果空间还是不够用,可以把以下开启,清理出更多空间
# remove-android: 'true'
# remove-codeql: 'true'
build-mount-path: '/var/lib/docker/'
- name: Restart docker
run: sudo service docker restart
- name: Free up disk space complete
run: |
echo "Free up disk space complete"
echo "=============================================================================="
df -hT
echo "=============================================================================="
- name: Checkout Code
uses: actions/checkout@v4
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push image Aliyun
run: |
docker login -u $ALIYUN_REGISTRY_USER -p $ALIYUN_REGISTRY_PASSWORD $ALIYUN_REGISTRY
# 数据预处理,判断镜像是否重名
declare -A duplicate_images
declare -A temp_map
# 记录需要做多平台合并的镜像:key 为“最终目标镜像名”(不带平台前缀),value 为各平台镜像列表
declare -A manifest_sources
declare -A manifest_count
while IFS= read -r line || [ -n "$line" ]; do
# 忽略空行与注释
[[ -z "$line" ]] && continue
if echo "$line" | grep -q '^\s*#'; then
continue
fi
# 获取镜像的完整名称,例如kasmweb/nginx:1.25.3(命名空间/镜像名:版本号)
image=$(echo "$line" | awk '{print $NF}')
# 将@sha256:等字符删除
image="${image%%@*}"
echo "image $image"
# 获取镜像名:版本号 例如nginx:1.25.3
image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}')
echo "image_name_tag $image_name_tag"
# 获取命名空间 例如kasmweb, 这里有种特殊情况 docker.io/nginx,把docker.io当成命名空间,也OK
name_space=$(echo "$image" | awk -F'/' '{if (NF==3) print $2; else if (NF==2) print $1; else print ""}')
echo "name_space: $name_space"
# 这里不要是空值影响判断
name_space="${name_space}_"
# 获取镜像名例如nginx
image_name=$(echo "$image_name_tag" | awk -F':' '{print $1}')
echo "image_name: $image_name"
# 如果镜像存在于数组中,则添加temp_map
if [[ -n "${temp_map[$image_name]}" ]]; then
# 如果temp_map已经存在镜像名,判断是不是同一命名空间
if [[ "${temp_map[$image_name]}" != $name_space ]]; then
echo "duplicate image name: $image_name"
duplicate_images[$image_name]="true"
fi
else
# 存镜像的命名空间
temp_map[$image_name]=$name_space
fi
done < images.txt
while IFS= read -r line || [ -n "$line" ]; do
# 忽略空行与注释
[[ -z "$line" ]] && continue
if echo "$line" | grep -q '^\s*#'; then
continue
fi
echo "docker pull $line"
docker pull $line
platform=$(echo "$line" | awk -F'--platform[ =]' '{if (NF>1) print $2}' | awk '{print $1}')
#platform=$(echo "$line" | awk -F'[= ]' '{print $2}' | awk -F'--platform' '{print $2}' | tr -d '[:space:]')
echo "platform is $platform"
# 如果存在架构信息 将架构信息拼到镜像名称前面
if [ -z "$platform" ]; then
platform_prefix=""
else
platform_prefix="${platform//\//_}_"
fi
echo "platform_prefix is $platform_prefix"
# 获取镜像的完整名称,例如kasmweb/nginx:1.25.3(命名空间/镜像名:版本号)
image=$(echo "$line" | awk '{print $NF}')
# 获取 镜像名:版本号 例如nginx:1.25.3
image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}')
# 获取命名空间 例如kasmweb 这里有种特殊情况 docker.io/nginx,把docker.io当成命名空间,也OK
name_space=$(echo "$image" | awk -F'/' '{if (NF==3) print $2; else if (NF==2) print $1; else print ""}')
# 获取镜像名例 例如nginx
image_name=$(echo "$image_name_tag" | awk -F':' '{print $1}')
name_space_prefix=""
# 如果镜像名重名
if [[ -n "${duplicate_images[$image_name]}" ]]; then
#如果命名空间非空,将命名空间加到前缀
if [[ -n "${name_space}" ]]; then
name_space_prefix="${name_space}_"
fi
fi
# 将@sha256:等字符删除
image_name_tag="${image_name_tag%%@*}"
new_image="$ALIYUN_REGISTRY/$ALIYUN_NAME_SPACE/$platform_prefix$name_space_prefix$image_name_tag"
echo "docker tag $image $new_image"
docker tag $image $new_image
echo "docker push $new_image"
docker push $new_image
# 仅对带 --platform 的镜像做多平台合并统计
if [ -n "$platform_prefix" ]; then
base_image="$ALIYUN_REGISTRY/$ALIYUN_NAME_SPACE/$name_space_prefix$image_name_tag"
manifest_sources["$base_image"]="${manifest_sources[$base_image]} $new_image"
manifest_count["$base_image"]=$(( ${manifest_count[$base_image]:-0} + 1 ))
fi
echo "开始清理磁盘空间"
echo "=============================================================================="
df -hT
echo "=============================================================================="
docker rmi $image
docker rmi $new_image
echo "磁盘空间清理完毕"
echo "=============================================================================="
df -hT
echo "=============================================================================="
done < images.txt
echo "开始创建并推送多平台 manifest(如有需要)"
for base_image in "${!manifest_sources[@]}"; do
count=${manifest_count[$base_image]}
if [ "$count" -lt 2 ]; then
echo "跳过 $base_image,仅检测到 $count 个平台"
continue
fi
echo "为 $base_image 创建 manifest, 包含平台镜像: ${manifest_sources[$base_image]}"
docker manifest create "$base_image" ${manifest_sources[$base_image]}
docker manifest push "$base_image"
docker manifest rm "$base_image" || true
done
echo "多平台 manifest 处理完成"
echo "结束"