-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmirror.sh
executable file
·243 lines (187 loc) · 6.56 KB
/
mirror.sh
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/usr/bin/env bash
#
# CONFIGURATION
#
ECR_REGION="us-east-1"
IMAGES_LIST_FILE=./images.list
#
# TEXT COLORING VARS
#
RESET='\033[0m'
RED='\033[00;31m'
GREEN='\033[00;32m'
YELLOW='\033[00;33m'
LIGHTGRAY='\033[00;37m'
CYAN='\033[00;36m'
#
# MESSAGE HELPER FUNCTIONS
#
# printing current date for reference
function now {
echo -e "${CYAN} [TIME] now:" "$(date)" "$RESET"
}
# generic log/info/debug messages
function log {
echo -e "${LIGHTGRAY} [INFO]" "$1" "$RESET"
}
# success/ok messages
function ok {
echo -e "${GREEN} [SUCCESS]" "$1" "$RESET"
}
# warnings/resolvable issues
function warn {
echo -e "${YELLOW} [WARNING]" "$1" "$RESET"
}
# fatal errors -> terminates script
function err {
echo -e "${RED} [ERROR]" "$1" "$RESET"
exit 1
}
#
# REQUIREMENT CHECKER FUNCTIONS
#
# ensuring required environmental variables are present
function ensure_env_exists {
log "- env $1"
if [[ -z $( env | grep "${1}=" ) ]] ; then
err "env $1 does not exist, make sure to authenticate to awscli first!"
fi
}
# ensuring commands/binaries are present
function ensure_command_exists {
log "- $1"
if ! which "$1" 1>/dev/null 2>/dev/null ; then
err "$1 is not installed! please install it first!"
fi
}
# ensuring required files exist
function ensure_file_exists {
log "- $1"
if [[ ! -f $1 ]] ; then
erro "$1 does not exist! please create it first!"
fi
}
# ensuring docker daemon is running
function ensure_docker_daemon_running {
if ! docker info 1>/dev/null 2>/dev/null ; then
err "docker does not seem to be running! please start it first!"
fi
}
#
# ACTUALLY DOING STUFF BELOW
#
# instant fail on any error
set -e
# printing time here and there for reference
now
# ensuring AWS access credentials
log "ensuring required environmental variables exist..."
ensure_env_exists AWS_SESSION_TOKEN
ensure_env_exists AWS_ACCESS_KEY_ID
ensure_env_exists AWS_SECRET_ACCESS_KEY
ensure_env_exists AWS_ECR_ID
ok "all required env vars exists!"
# checking required files
log "checking if all required files exist..."
ensure_file_exists $IMAGES_LIST_FILE
ok "all required files exist!"
# checking required tools
log "checking if all the required tools are installed..."
ensure_command_exists awk
ensure_command_exists aws
ensure_command_exists curl
ensure_command_exists docker
ensure_command_exists jq
ok "all required tools are available!"
# checking docker daemon
log "checking if docker daemon is running..."
ensure_docker_daemon_running
ok "docker daemon is up!"
# checking if $IMAGES_LIST_FILE contains duplicates
IMAGES_LIST_LINES_COUNT=$( grep -c '[^[:space:]]' $IMAGES_LIST_FILE )
IMAGES_LIST_UNIQUE_LINES_COUNT=$( sort $IMAGES_LIST_FILE | uniq | grep -c '[^[:space:]]' )
if [[ ! $IMAGES_LIST_LINES_COUNT -eq $IMAGES_LIST_UNIQUE_LINES_COUNT ]] ; then
warn "$IMAGES_LIST_FILE seems to contain duplicates! ignoring..."
fi
now
# validating images list file and checking Docker Hub for availability
UNIQUE_REQUIRED_IMAGES=$( sort $IMAGES_LIST_FILE | uniq )
log "validating ${IMAGES_LIST_FILE} and checking their availability on Docker Hub..."
for UNIQUE_REQUIRED_IMAGE in ${UNIQUE_REQUIRED_IMAGES[@]} ; do
REPO=$( echo "$UNIQUE_REQUIRED_IMAGE" | awk -F':' '{print $1}' )
TAG=$( echo "$UNIQUE_REQUIRED_IMAGE" | awk -F':' '{print $2}' )
log "- ${REPO}:${TAG}"
if [[ -z $TAG ]] ; then
err "${UNIQUE_REQUIRED_IMAGE} has no tag defined, please define a static tag!"
fi
if [[ $TAG == "latest" || $TAG == "stable" ]] ; then
warn "${REPO} has 'latest' or 'stable' defined as its tag, change it to a static one!"
fi
if ! curl --silent -f -lSL "https://index.docker.io/v1/repositories/${REPO}/tags/${TAG}" 1>/dev/null 2>/dev/null ; then
warn "$REPO:$TAG does not exist on Docker Hub! mirroring would fail!"
fi
done
ok "${IMAGES_LIST_FILE} seems to be valid!"
now
# logging in to our ECR
log "logging in to our ECR via docker..."
aws ecr-public get-login-password --region $ECR_REGION | docker login --username AWS --password-stdin "public.ecr.aws/${AWS_ECR_ID}" > /dev/null
ok "docker login successful!"
# getting list of existing mirror repos
log "getting existing public repositories in our ECR..."
EXISTING_REPOS=$(aws ecr-public describe-repositories --region us-east-1 --out json | jq '.repositories[].repositoryName' | sed s/\"//g | sort )
for EXISTING_REPO in ${EXISTING_REPOS[@]} ; do
log " - $EXISTING_REPO"
done
ok "successfully got list of our already existing ECR repositories!"
now
# checking if all the required repos exist or not
UNIQUE_REQUIRED_REPOS=$( sort $IMAGES_LIST_FILE | awk -F':' '{print $1}' | uniq )
log "checking if all the required repositories already exist or not..."
for REQUIRED_REPO in ${UNIQUE_REQUIRED_REPOS[@]} ; do
log "- $REQUIRED_REPO"
FOUND=0
for EXISTING_REPO in ${EXISTING_REPOS[@]} ; do
if [[ "$EXISTING_REPO" == "$REQUIRED_REPO" ]] ; then
FOUND=1
fi
done
if [[ ! $FOUND -eq 1 ]] ; then
warn "${REQUIRED_REPO} repository does not exist! creating it..."
aws ecr-public create-repository --repository-name "$REQUIRED_REPO" --region "$ECR_REGION" 1>/dev/null
ok "$REQUIRED_REPO repository created!"
fi
done
ok "all the required repositories exist!"
now
# finally mirroring images
log "checking if all the required images are mirrored or not..."
UNIQUE_REQUIRED_IMAGES=$( sort $IMAGES_LIST_FILE | uniq )
for UNIQUE_REQUIRED_IMAGE in ${UNIQUE_REQUIRED_IMAGES[@]} ; do
REPO=$( echo "$UNIQUE_REQUIRED_IMAGE" | awk -F':' '{print $1}' )
TAG=$( echo "$UNIQUE_REQUIRED_IMAGE" | awk -F':' '{print $2}' )
log "- $REPO:$TAG"
EXISTING_IMAGES=$( aws ecr-public describe-images --repository-name "$REPO" --region "$ECR_REGION" --output json | jq '.imageDetails[].imageTags[]' | sed s/\"//g | sort )
FOUND=0
for EXISTING_IMAGE in ${EXISTING_IMAGES[@]} ; do
if [[ "$TAG" == "$EXISTING_IMAGE" ]] ; then
FOUND=1
fi
done
if [[ $FOUND -eq 0 ]] ; then
warn "$REPO:$TAG not mirrored yet! mirroring..."
log "downloading $REPO:$TAG from Docker Hub..."
now
if ! docker pull "${REPO}:${TAG}" ; then
err "could not download ${REPO}:${TAG} from Docker Hub, does it exist?"
fi
log "tagging and pushing it to our ECR..."
docker tag "${REPO}:${TAG}" "public.ecr.aws/${AWS_ECR_ID}/${REPO}:${TAG}"
now
docker push "public.ecr.aws/${AWS_ECR_ID}/${REPO}:${TAG}"
now
ok "$REPO:$TAG successfully mirrored to our ECR!"
fi
done
now
ok "everything is mirrored, job's done, bye!"