mirror of
				https://github.com/DaoCloud/public-image-mirror.git
				synced 2025-11-01 06:19:36 +08:00 
			
		
		
		
	Merge pull request #87 from DaoCloud/update/image-filter
Update image-filter.sh
This commit is contained in:
		| @@ -1,78 +1,201 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| if [[ "${#}" -ne 0 && "$1" != "-" ]]; then | ||||
|     tmp=$(cat "${1}") | ||||
| else | ||||
|     tmp=$(cat) | ||||
| SITE="https://github.com/DaoCloud/public-image-mirror" | ||||
| URL_PREFIX="https://raw.githubusercontent.com/DaoCloud/public-image-mirror/main" | ||||
| DOMAIN_SUFFIX="m.daocloud.io" | ||||
| TMPDIR="${TMPDIR:-/tmp}/public-image-mirror" | ||||
|  | ||||
| # show the usage if arguments are provided | ||||
| function usage() { | ||||
|     echo "Usage: $0" | ||||
|     echo "  cat <resource-file.yaml> | $0 | kubectl apply -f -" | ||||
|     echo "  kubectl kustomize <kustomize-dir> | $0 | kubectl apply -f -" | ||||
|     echo | ||||
|     echo "For more information, please visit ${SITE}" | ||||
| } | ||||
|  | ||||
| if [[ $# -ne 0 ]]; then | ||||
|     usage >&2 | ||||
|     exit 1 | ||||
| fi | ||||
|  | ||||
| domains=( | ||||
|     cr.l5d.io | ||||
|     docker.elastic.co | ||||
|     docker.io | ||||
|     gcr.io | ||||
|     ghcr.io | ||||
|     k8s.gcr.io | ||||
|     mcr.microsoft.com | ||||
|     nvcr.io | ||||
|     quay.io | ||||
|     registry.jujucharms.com | ||||
|     rocks.canonical.com | ||||
| ) | ||||
|  | ||||
| SUFFIX=${SUFFIX:-"m.daocloud.io"} | ||||
|  | ||||
| function replace_domain() { | ||||
|     local domain="${1}" | ||||
|     IFS='.' read -ra arr <<<"${domain}" | ||||
|     local len=${#arr[@]} | ||||
|     if [[ "${len}" -eq 2 ]]; then | ||||
|         echo "${arr[0]}.${SUFFIX}" | ||||
|         return 0 | ||||
|     fi | ||||
|  | ||||
|     if [[ "${arr[0]}" == "registry" ]]; then | ||||
|         echo "${arr[1]}.${SUFFIX}" | ||||
|         return 0 | ||||
|     fi | ||||
|     if [[ "${arr[0]}" == "docker" ]]; then | ||||
|         echo "${arr[1]}.${SUFFIX}" | ||||
|         return 0 | ||||
|     fi | ||||
|     if [[ "${arr[0]}" == "cr" ]]; then | ||||
|         echo "${arr[1]}.${SUFFIX}" | ||||
|         return 0 | ||||
|     fi | ||||
|  | ||||
|     if [[ "${arr[0]}" =~ cr$ ]]; then | ||||
|         echo "${arr[0]}.${SUFFIX}" | ||||
|         return 0 | ||||
|     fi | ||||
|  | ||||
|     unset 'arr[${#arr[@]}-1]' | ||||
|  | ||||
|     IFS='-' | ||||
|     echo "${arr[*]}.${SUFFIX}" | ||||
|  | ||||
|     unset IFS | ||||
|     return 0 | ||||
| # output the log to stderr | ||||
| function log() { | ||||
|     local message="${*}" | ||||
|     echo "# $0: ${message}" >&2 | ||||
| } | ||||
|  | ||||
| function replace_all() { | ||||
|     tmp="${1}" | ||||
|     for line in ${domains[*]}; do | ||||
|         key="${line}" | ||||
|         val="$(replace_domain ${line})" | ||||
|         if [[ "${key}" == "" || "${val}" == "" ]]; then | ||||
|             continue | ||||
| # check the command exists | ||||
| function command_exists() { | ||||
|     local cmd="$1" | ||||
|     type "${cmd}" >/dev/null 2>&1 | ||||
| } | ||||
|  | ||||
| mkdir -p "${TMPDIR}" | ||||
|  | ||||
| # fetch the file or download the file if it does not exist | ||||
| function fetch() { | ||||
|     local file="${1}" | ||||
|  | ||||
|     # check local directory first | ||||
|     if [[ -f "${file}" ]]; then | ||||
|         cat "${file}" | ||||
|         return 0 | ||||
|     fi | ||||
|  | ||||
|     # check the cache directory | ||||
|     if [[ -s "${TMPDIR}/${file}" ]]; then | ||||
|         cat "${TMPDIR}/${file}" | ||||
|         return 0 | ||||
|     fi | ||||
|  | ||||
|     # download the file | ||||
|     local url="${2}" | ||||
|     log "Fetching ${file} from ${url} cache to ${TMPDIR}" | ||||
|     if command_exists wget; then | ||||
|         log wget "${url}" -c -O "${TMPDIR}/${file}" | ||||
|         wget "${url}" -c -O "${TMPDIR}/${file}" >&2 | ||||
|         cat "${TMPDIR}/${file}" | ||||
|     elif command_exists curl; then | ||||
|         log curl "${url}" -L -o "${TMPDIR}/${file}" | ||||
|         curl "${url}" -L -o "${TMPDIR}/${file}" >&2 | ||||
|         cat "${TMPDIR}/${file}" | ||||
|     else | ||||
|         log "Please install wget or curl to download the file and retry" | ||||
|         log "Or you can manually download the file ${url} and put it to ${TMPDIR}/${file}" | ||||
|         exit 1 | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # take the first column | ||||
| function first_column() { | ||||
|     cat | grep -v '^#' | awk '{print $1}' | ||||
| } | ||||
|  | ||||
| DOMAIN_LIST="$(fetch "domain.txt" "${URL_PREFIX}/domain.txt" | first_column)" | ||||
| MIRROR_LIST="$(fetch "mirror.txt" "${URL_PREFIX}/mirror.txt" | first_column)" | ||||
| EXCLUDE_LIST="$(fetch "exclude.txt" "${URL_PREFIX}/exclude.txt" | first_column)" | ||||
|  | ||||
| # check the tag are excluded | ||||
| function is_exclude() { | ||||
|     local tag="${1}" | ||||
|     for exclude in ${EXCLUDE_LIST}; do | ||||
|         if [[ "${tag}" =~ ${exclude} ]]; then | ||||
|             return 0 | ||||
|         fi | ||||
|         tmp="$(echo "${tmp}" | sed -e "s# ${key}# ${val}#g")" | ||||
|     done | ||||
|  | ||||
|     # Remove sha256 hash | ||||
|     tmp="$(echo "${tmp}" | sed -e "s#@sha256:[0-9a-f]\{64\}##g")" | ||||
|     echo "${tmp}" | ||||
|     return 1 | ||||
| } | ||||
|  | ||||
| # check the image is mirrored | ||||
| function is_mirror() { | ||||
|     local name="${1}" | ||||
|     for mirror in ${MIRROR_LIST}; do | ||||
|         if [[ "${name}" == "${mirror}" ]]; then | ||||
|             return 0 | ||||
|         fi | ||||
|     done | ||||
|     return 1 | ||||
| } | ||||
|  | ||||
| replace_all "${tmp}" | ||||
| # replace the prefix of the image | ||||
| function replace_image() { | ||||
|     local name="${1}" | ||||
|     for domain in ${DOMAIN_LIST}; do | ||||
|         old_prefix="${domain%%=*}" | ||||
|         new_prefix="${domain#*=}" | ||||
|         if [[ "${name}" =~ ^"${old_prefix}" ]]; then | ||||
|             echo "${name}" | sed "s#${old_prefix}#${new_prefix}#" | ||||
|             return | ||||
|         fi | ||||
|     done | ||||
|     echo "${name}" | ||||
| } | ||||
|  | ||||
| # completion the docker.io prefix | ||||
| function completion_for_docker_io() { | ||||
|     local name="${1}" | ||||
|     if [[ "${name}" =~ "." ]]; then | ||||
|         echo "${name}" | ||||
|     else | ||||
|         echo "docker.io/${name}" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # replace image prefix on the line | ||||
| function replace_line() { | ||||
|     local line="${1}" | ||||
|  | ||||
|     # get the image full name | ||||
|     local raw_image="$(echo "${line#*: }" | awk '{print $1}' | sed 's/"//g' | sed "s/'//g")" | ||||
|     local image="${raw_image}" | ||||
|     local image_name="" | ||||
|     local image_tag="" | ||||
|  | ||||
|     # remove the sha256 suffix | ||||
|     if [[ "${image}" =~ "@" ]]; then | ||||
|         image="${image%%@*}" | ||||
|     fi | ||||
|  | ||||
|     # split the image name and tag | ||||
|     if [[ "${image}" =~ ":" ]]; then | ||||
|         image_tag="${image#*:}" | ||||
|         image_name="${image%%:*}" | ||||
|     else | ||||
|         image_name="${image}" | ||||
|     fi | ||||
|  | ||||
|     # check the image is replaced | ||||
|     if [[ "${image_name}" =~ "${DOMAIN_SUFFIX}" ]]; then | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     # completion the docker.io prefix | ||||
|     image_name="$(completion_for_docker_io "${image_name}")" | ||||
|  | ||||
|     # check the image is mirrored | ||||
|     if ! is_mirror "${image_name}"; then | ||||
|         log "Image '${image}' is not synchronized yet, if you want please send a PR to add it on ${SITE}" | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     # check the tag is empty | ||||
|     if [[ "${image_tag}" == "" ]]; then | ||||
|         log "Image '${image}' must have a tag" | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     # check the tag is excluded | ||||
|     if is_exclude "${image_tag}"; then | ||||
|         log "Image '${image}' tag excludes out of synchronize" | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     # replace the prefix of the image | ||||
|     local new_image="$(replace_image "${image_name}"):${image_tag}" | ||||
|     local new_line=$(echo "${line}" | sed "s|${raw_image}|${new_image}|") | ||||
|  | ||||
|     log "Replace '${raw_image}' with '${new_image}'" | ||||
|  | ||||
|     echo "${new_line}" | ||||
| } | ||||
|  | ||||
| function main() { | ||||
|     local new_line | ||||
|     cat | while read line; do | ||||
|         if [[ "${line}" =~ "image: " || "${line}" =~ "image': " || "${line}" =~ 'image": ' ]]; then | ||||
|             new_line="$(replace_line "${line}")" | ||||
|             if [[ $? -eq 0 ]]; then | ||||
|                 echo "${new_line}" | ||||
|             else | ||||
|                 echo "${line}" | ||||
|             fi | ||||
|         else | ||||
|             echo "${line}" | ||||
|         fi | ||||
|     done | ||||
| } | ||||
|  | ||||
| IFS=$'\n' | ||||
|  | ||||
| main | ||||
|   | ||||
		Reference in New Issue
	
	Block a user