1+ #! /bin/bash
2+
3+ KB_VERSION=${1:- 0.7.0-alpha.0}
4+ KB_HELM_REPO_INDEX_URL_BASE=https://apecloud.github.io/helm-charts
5+ KB_HELM_REPO_INDEX_URL=${KB_HELM_REPO_INDEX_URL_BASE} /index.yaml
6+
7+ # set -o errexit
8+ # set -o nounset
9+ # set -o pipefail
10+
11+ print_error () {
12+ echo " $1 " >&2
13+ }
14+
15+ # List of required commands
16+ required_cmds=(" curl" " helm" " jq" " yq" )
17+
18+ # Loop through the list of commands and check if they exist
19+ for cmd in " ${required_cmds[@]} " ; do
20+ if ! command -v " $cmd " & > /dev/null; then
21+ print_error " Error: '$cmd ' command not found"
22+ exit 1
23+ fi
24+ done
25+
26+ # Regular expression to match http or https
27+ regex=" ^(http|https)://.*"
28+
29+ # Get helm chart index
30+ echo " Processing helm chart index: ${KB_HELM_REPO_INDEX_URL} "
31+ kb_index_json=` curl ${KB_HELM_REPO_INDEX_URL} | yq eval -ojson`
32+ entries=` echo ${kb_index_json} | jq -r ' .entries | keys | .[]' `
33+
34+ chart_url_array=()
35+ image_array=()
36+ for entry in ${entries}
37+ do
38+ version=${KB_VERSION}
39+ url=" "
40+ helm_custom_args=" "
41+ images=" "
42+
43+ # specialized processor
44+ case ${entry} in
45+ # ignored entries
46+ " agamotto" | \
47+ " apecloud-mysql-cluster" | \
48+ " postgresql-cluster" | \
49+ " tdengine-cluster" | \
50+ " chaos-mesh" | \
51+ " chatgpt-retrieval-plugin" | \
52+ " clickhouse" | \
53+ " delphic" | \
54+ " etcd" | \
55+ " etcd-cluster" | \
56+ " kafka" | \
57+ " opensearch" | \
58+ " opensearch-cluster" | \
59+ " redis-demo" | \
60+ " prometheus-kubeblocks" | \
61+ " bytebase" )
62+ continue
63+ ;;
64+ " aws-load-balancer-controller" )
65+ helm_custom_args=" --set clusterName=clusterName"
66+ ;;
67+ " dt-platform" | " kubeblocks-csi-driver" )
68+ # following chart is missing from chart repo index
69+ version=" 0.1.0"
70+ # url=https://jihulab.com/api/v4/projects/85949/packages/helm/stable/charts/${entry}-${version}.tgz
71+ ;;
72+ " prometheus" )
73+ version=" 15.16.1"
74+ ;;
75+ esac
76+
77+ # compose helm chart URL
78+ if [ -z " ${url} " ]; then
79+ select_entry=` echo ${kb_index_json} | jq -r " .entries[\" ${entry} \" ][] | select(.version == \" ${version} \" )" `
80+ url=` echo ${select_entry} | jq -r ' .urls[0]' `
81+ if [ -z " $url " ]; then
82+ # choose latest version instead
83+ select_entry=` echo ${kb_index_json} | jq -r " .entries[\" ${entry} \" ][0]" `
84+ url=` echo ${select_entry} | jq -r ' .urls[0]' `
85+ version=` echo ${select_entry} | jq -r ' .version' `
86+ fi
87+ if ! [[ $url =~ $regex ]]; then
88+ url=${KB_HELM_REPO_INDEX_URL_BASE} /${url}
89+ fi
90+ fi
91+
92+ # extract images from helm templates
93+ if [ -z " ${images} " ]; then
94+ images=` helm template ${entry} ${url} ${helm_custom_args} | grep -e " image:" -e " chartsImage" | awk ' {print $2}' `
95+ fi
96+
97+ chart_url_array+=(${url} )
98+ print_error " processed entry=${entry} ; version=${version} ; url=${url} "
99+ for image in ${images}
100+ do
101+ image=" ${image// \" } "
102+ image_array+=(${image} )
103+ done
104+ done
105+
106+ print_error " "
107+
108+ # Convert array to set
109+ image_set=($( printf " %s\n" " ${image_array[@]} " | sort -u) )
110+
111+ # Convert to JSON
112+ chart_url_json_arr=" [$( printf ' "%s",' " ${chart_url_array[@]} " | sed ' s/,$//' ) ]"
113+ images_json_arr=" [$( printf ' "%s",' " ${image_set[@]} " | sed ' s/,$//' ) ]"
114+ json_out=" {\" chartURLs\" :${chart_url_json_arr} ,\" images\" :${images_json_arr} }"
115+ echo $json_out | jq -r ' .'
116+
117+ # Generata a daemonSet yaml to pre pull images on all nodes
118+
119+ # find kubeblocks-tools image
120+ KB_TOOLS_IMAGE=" "
121+ for image in " ${image_set[@]} " ; do
122+ if [[ " $image " =~ " kubeblocks-tools" ]]; then
123+ KB_TOOLS_IMAGE=$image
124+ fi
125+ done
126+
127+ whiteList=(kubeblocks mysql spilo mongo pgbouncer redis wal-g agamotto)
128+ cat << EOF > prepuller.yaml
129+ apiVersion: apps/v1
130+ kind: DaemonSet
131+ metadata:
132+ name: kubeblocks-image-prepuller
133+ spec:
134+ selector:
135+ matchLabels:
136+ name: kubeblocks-image-prepuller
137+ template:
138+ metadata:
139+ labels:
140+ name: kubeblocks-image-prepuller
141+ spec:
142+ volumes:
143+ - name: shared-volume
144+ emptyDir: {}
145+ initContainers:
146+ - name: pull-kb-tools
147+ image: ${KB_TOOLS_IMAGE}
148+ imagePullPolicy: IfNotPresent
149+ command: ["cp", "-r", "/usr/bin/kubectl", "/kb-tools/kubectl"]
150+ volumeMounts:
151+ - name: shared-volume
152+ mountPath: /kb-tools
153+ EOF
154+
155+ count=1
156+ for image in " ${image_set[@]} " ; do
157+ match=false
158+ for j in " ${whiteList[@]} " ; do
159+ if [[ " $image " =~ " $j " ]]; then
160+ match=true
161+ fi
162+ done
163+
164+ if ! $match ; then
165+ echo " skip image=${image} "
166+ continue
167+ fi
168+
169+ cat << EOF >> prepuller.yaml
170+ - name: pull-${count}
171+ image: ${image}
172+ imagePullPolicy: IfNotPresent
173+ command: ["/kb-tools/kubectl"]
174+ volumeMounts:
175+ - name: shared-volume
176+ mountPath: /kb-tools
177+ EOF
178+ count=$(( count+ 1 ))
179+ done
180+
181+ cat << EOF >> prepuller.yaml
182+ containers:
183+ - name: pause
184+ image: k8s.gcr.io/pause:3.2
185+ EOF
0 commit comments