From 7af23c7946746dccf831ebc75ed690da9f84ceda Mon Sep 17 00:00:00 2001 From: naumso Date: Mon, 17 Aug 2026 02:06:35 +0300 Subject: [PATCH] Update plugin.sh --- plugin.sh | 207 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 139 insertions(+), 68 deletions(-) diff --git a/plugin.sh b/plugin.sh index 0705fc3..7c83bcd 100755 --- a/plugin.sh +++ b/plugin.sh @@ -1,27 +1,49 @@ #!/busybox/sh set -euo pipefail +set -f export PATH=$PATH:/kaniko/ +NL=' +' + REGISTRY=${PLUGIN_REGISTRY:-index.docker.io} -if [ "${PLUGIN_USERNAME:-}" ] || [ "${PLUGIN_PASSWORD:-}" ]; then - - DOCKER_AUTH=`echo -n "${PLUGIN_USERNAME}:${PLUGIN_PASSWORD}" | base64 | tr -d "\n"` - +# strip leading/trailing spaces from a single list item +trim() { + t=$1 + while [ "${t# }" != "$t" ]; do t=${t# }; done + while [ "${t% }" != "$t" ]; do t=${t% }; done + printf '%s' "$t" +} + +if [ -n "${PLUGIN_USERNAME:-}" ] || [ -n "${PLUGIN_PASSWORD:-}" ]; then + if [ -z "${PLUGIN_USERNAME:-}" ] || [ -z "${PLUGIN_PASSWORD:-}" ]; then + echo "error: username and password must both be set (missing Drone secret?)" >&2 + exit 1 + fi + + DOCKER_AUTH=$(printf '%s' "${PLUGIN_USERNAME}:${PLUGIN_PASSWORD}" | base64 | tr -d "\n") + + # kaniko resolves Docker Hub credentials under the legacy key + # https://index.docker.io/v1/, so write it alongside the plain hostname + AUTHS="\"${REGISTRY}\": {\"auth\": \"${DOCKER_AUTH}\"}" + if [ "${REGISTRY}" = "index.docker.io" ]; then + AUTHS="${AUTHS}, + \"https://index.docker.io/v1/\": {\"auth\": \"${DOCKER_AUTH}\"}" + fi + cat > /kaniko/.docker/config.json < /kaniko/gcr.json export GOOGLE_APPLICATION_CREDENTIALS=/kaniko/gcr.json fi @@ -29,88 +51,137 @@ fi DOCKERFILE=${PLUGIN_DOCKERFILE:-Dockerfile} CONTEXT=${PLUGIN_CONTEXT:-$PWD} LOG=${PLUGIN_LOG:-info} -EXTRA_OPTS="" -if [[ -n "${PLUGIN_TARGET:-}" ]]; then - TARGET="--target=${PLUGIN_TARGET}" +# kaniko arguments accumulate in "$@" so that values containing spaces +# reach the executor as single arguments +set -- -v "${LOG}" --context="${CONTEXT}" --dockerfile="${DOCKERFILE}" + +if [ -n "${PLUGIN_TARGET:-}" ]; then + set -- "$@" --target="${PLUGIN_TARGET}" fi -if [[ "${PLUGIN_SKIP_TLS_VERIFY:-}" == "true" ]]; then - EXTRA_OPTS="--skip-tls-verify=true" +if [ "${PLUGIN_SKIP_TLS_VERIFY:-}" = "true" ]; then + set -- "$@" --skip-tls-verify=true fi -if [[ "${PLUGIN_CACHE:-}" == "true" ]]; then - CACHE="--cache=true" +if [ "${PLUGIN_SKIP_UNUSED_STAGES:-}" = "true" ]; then + set -- "$@" --skip-unused-stages=true fi -if [ -n "${PLUGIN_CACHE_REPO:-}" ]; then - CACHE_REPO="--cache-repo=${REGISTRY}/${PLUGIN_CACHE_REPO}" -fi - -if [ -n "${PLUGIN_CACHE_TTL:-}" ]; then - CACHE_TTL="--cache-ttl=${PLUGIN_CACHE_TTL}" +# snapshot_mode: full (default, most robust), redo (up to 50% faster: +# mtime, size, mode, uid, gid), time (fastest: mtime only) +if [ -n "${PLUGIN_SNAPSHOT_MODE:-}" ]; then + case "${PLUGIN_SNAPSHOT_MODE}" in + full|redo|time) + set -- "$@" --snapshot-mode="${PLUGIN_SNAPSHOT_MODE}" + ;; + *) + echo "error: snapshot_mode must be one of: full, redo, time (got '${PLUGIN_SNAPSHOT_MODE}')" >&2 + exit 1 + ;; + esac fi if [ -n "${PLUGIN_BUILD_ARGS:-}" ]; then - BUILD_ARGS=$(echo "${PLUGIN_BUILD_ARGS}" | tr ',' '\n' | while read build_arg; do echo "--build-arg=${build_arg}"; done) + IFS=",${NL}" + for build_arg in ${PLUGIN_BUILD_ARGS}; do + build_arg=$(trim "${build_arg}") + if [ -n "${build_arg}" ]; then + set -- "$@" --build-arg="${build_arg}" + fi + done + unset IFS fi if [ -n "${PLUGIN_BUILD_ARGS_FROM_ENV:-}" ]; then - BUILD_ARGS_FROM_ENV=$(echo "${PLUGIN_BUILD_ARGS_FROM_ENV}" | tr ',' '\n' | while read build_arg; do echo "--build-arg ${build_arg}=$(eval "echo \$$build_arg")"; done) -fi - -if [[ "${PLUGIN_SKIP_UNUSED_STAGES:-}" == "true" ]]; then - SKIP_UNUSED_STAGES="--skip-unused-stages=true" + IFS=",${NL}" + for env_name in ${PLUGIN_BUILD_ARGS_FROM_ENV}; do + env_name=$(trim "${env_name}") + if [ -z "${env_name}" ]; then + continue + fi + case "${env_name}" in + [0-9]*|*[!A-Za-z0-9_]*) + echo "warning: build_args_from_env: '${env_name}' is not a valid variable name, skipping" >&2 + continue + ;; + esac + if eval "[ -n \"\${${env_name}+set}\" ]"; then + eval "env_value=\${${env_name}}" + set -- "$@" --build-arg="${env_name}=${env_value}" + else + echo "warning: build_args_from_env: \$${env_name} is not set, skipping" >&2 + fi + done + unset IFS fi # auto_tag, if set auto_tag: true, auto generate .tags file # support format Major.Minor.Release or start with `v` # docker tags: Major, Major.Minor, Major.Minor.Release and latest -if [[ "${PLUGIN_AUTO_TAG:-}" == "true" ]]; then - TAG=$(echo "${DRONE_TAG:-}" |sed 's/^v//g') - part=$(echo "${TAG}" |tr '.' '\n' |wc -l) - # expect number - echo ${TAG} |grep -E "[a-z-]" &>/dev/null && isNum=1 || isNum=0 +if [ "${PLUGIN_AUTO_TAG:-}" = "true" ]; then + TAG=${DRONE_TAG:-} + TAG=${TAG#v} - if [ ! -n "${TAG:-}" ];then - echo "latest" > .tags - elif [ ${isNum} -eq 1 -o ${part} -gt 3 ];then - echo "${TAG},latest" > .tags - else - major=$(echo "${TAG}" |awk -F'.' '{print $1}') - minor=$(echo "${TAG}" |awk -F'.' '{print $2}') - release=$(echo "${TAG}" |awk -F'.' '{print $3}') - - major=${major:-0} - minor=${minor:-0} - release=${release:-0} - - echo "${major},${major}.${minor},${major}.${minor}.${release},latest" > .tags - fi + case "${TAG}" in + '') + echo "latest" > .tags + ;; + *[!0-9.]*|*.*.*.*|.*|*.|*..*) + # not a plain Major.Minor.Release version: use the tag as-is + echo "${TAG},latest" > .tags + ;; + *) + major=${TAG%%.*} + rest=${TAG#"${major}"}; rest=${rest#.} + minor=${rest%%.*} + rest=${rest#"${minor}"}; rest=${rest#.} + release=${rest} + + minor=${minor:-0} + release=${release:-0} + + echo "${major},${major}.${minor},${major}.${minor}.${release},latest" > .tags + ;; + esac fi +TAGS="" if [ -n "${PLUGIN_TAGS:-}" ]; then - DESTINATIONS=$(echo "${PLUGIN_TAGS}" | tr ',' '\n' | while read tag; do echo "--destination=${REGISTRY}/${PLUGIN_REPO}:${tag} "; done) + TAGS=${PLUGIN_TAGS} elif [ -f .tags ]; then - DESTINATIONS=$(cat .tags| tr ',' '\n' | while read tag; do echo "--destination=${REGISTRY}/${PLUGIN_REPO}:${tag} "; done) -elif [ -n "${PLUGIN_REPO:-}" ]; then - DESTINATIONS="--destination=${REGISTRY}/${PLUGIN_REPO}:latest" -else - DESTINATIONS="--no-push" - # Cache is not valid with --no-push - CACHE="" + TAGS=$(cat .tags) fi -/kaniko/executor -v ${LOG} \ - --context=${CONTEXT} \ - --dockerfile=${DOCKERFILE} \ - ${EXTRA_OPTS} \ - ${DESTINATIONS} \ - ${CACHE:-} \ - ${CACHE_TTL:-} \ - ${CACHE_REPO:-} \ - ${TARGET:-} \ - ${SKIP_UNUSED_STAGES:-} \ - ${BUILD_ARGS:-} \ - ${BUILD_ARGS_FROM_ENV:-} - \ No newline at end of file +if [ -n "${PLUGIN_REPO:-}" ]; then + if [ -n "${TAGS}" ]; then + IFS=",${NL}" + for tag in ${TAGS}; do + tag=$(trim "${tag}") + if [ -n "${tag}" ]; then + set -- "$@" --destination="${REGISTRY}/${PLUGIN_REPO}:${tag}" + fi + done + unset IFS + else + set -- "$@" --destination="${REGISTRY}/${PLUGIN_REPO}:latest" + fi + + if [ "${PLUGIN_CACHE:-}" = "true" ]; then + set -- "$@" --cache=true + fi + if [ -n "${PLUGIN_CACHE_REPO:-}" ]; then + set -- "$@" --cache-repo="${REGISTRY}/${PLUGIN_CACHE_REPO}" + fi + if [ -n "${PLUGIN_CACHE_TTL:-}" ]; then + set -- "$@" --cache-ttl="${PLUGIN_CACHE_TTL}" + fi +else + if [ -n "${TAGS}" ]; then + echo "warning: tags are set but repo is not, building with --no-push" >&2 + fi + # Cache is not valid with --no-push + set -- "$@" --no-push +fi + +exec /kaniko/executor "$@"