diff --git a/.woodpecker/build-dev.yml b/.woodpecker/build-dev.yml new file mode 100644 index 0000000..2599f9f --- /dev/null +++ b/.woodpecker/build-dev.yml @@ -0,0 +1,24 @@ +when: + branch: dev + path: + include: [ '.woodpecker/build-dev.yml', 'Dockerfile', 'check.sh' ] + +pipeline: + build_and_publish_gitea: + image: woodpeckerci/plugin-docker-buildx + registry: git.narvas.tech + settings: + repo: vistanarvas/container-update-checker,git.narvas.tech/vista/container-update-checker + tag: dev + auto_tag: false + logins: + # Default DockerHub login + - registry: https://index.docker.io/v1/ + username: vistanarvas + password: + from_secret: DOCKERHUB_TOKEN + # Additional Gitea login + - registry: https://git.narvas.tech + username: vista + password: + from_secret: GITEA_TOKEN \ No newline at end of file diff --git a/.woodpecker/build.yml b/.woodpecker/build.yml index 12bfb61..8278458 100644 --- a/.woodpecker/build.yml +++ b/.woodpecker/build.yml @@ -1,3 +1,6 @@ +when: + branch: master + pipeline: check_self: # failure: ignore # this doesnt work diff --git a/Dockerfile b/Dockerfile index 534e8c1..b6b50e9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:latest -RUN apk add curl jq +RUN apk add --no-cache curl jq dateutils COPY check.sh /usr/local/bin/check RUN chmod +x /usr/local/bin/check diff --git a/README.md b/README.md index 5e321a3..b49f690 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,23 @@ check if a container needs rebuilding ## Environment variables -| Name | Requered | Comment -|-----------------|---------------------------------|--------- -| BASE | Yes | the image the Dockerfile is based on -| TARGET | Yes | the image thats based of `BASE` -| DOCKER_USERNAME | No
*used for private images* | the username for logging in into docker hub -| DOCKER_PASSWORD | No
*used for private images* | the password for logging in into docker hub
(*you probaly want to use a token here*) +| Name | Comment +|-------------------|----------- +| BASE | the image the Dockerfile is based on +| TARGET | the image thats based of `BASE` +| REGISTRY_USERNAME | the username for logging in into the registry
this is only requered of private repos +| REGISTRY_PASSWORD | the password for logging in into the registry
(*you probaly want to use a token here*) +| REGISTRY_API | the type of registry valid options are `docker` and `gitea`
Default: `docker` +| REGISTRY_URL | the url to the registry
Default: `https://hub.docker.com` +| BASE_REGISTRY_USERNAME | if left empty `REGISTRY_USERNAME` is used +| BASE_REGISTRY_PASSWORD | if left empty `REGISTRY_PASSWORD` is used +| BASE_REGISTRY_API | if left empty `REGISTRY_API` is used +| BASE_REGISTRY_URL | if left empty `REGISTRY_URL` is used +| TARGET_REGISTRY_USERNAME | if left empty `REGISTRY_USERNAME` is used +| TARGET_REGISTRY_PASSWORD | if left empty `REGISTRY_PASSWORD` is used +| TARGET_REGISTRY_API | if left empty `REGISTRY_API` is used +| TARGET_REGISTRY_URL | if left empty `REGISTRY_URL` is used + ## Exit codes diff --git a/check.sh b/check.sh index 4bce6ac..de44711 100644 --- a/check.sh +++ b/check.sh @@ -23,42 +23,128 @@ if [ -z "${TARGET}" ]; then exit 1 fi +if [ -z "${REGISTRY_USERNAME}" ] && [ -n "${DOCKER_USERNAME}" ]; then + REGISTRY_USERNAME="${DOCKER_USERNAME}" + echo "WARNING: DOCKER_USERNAME is deprecated and will be removed in the next version" + echo "you should switch to using REGISTRY_USERNAME" + echo "see the documentation for more info https://git.narvas.tech/vista/container-update-checker" +fi -# add "library/" if its a "official" docker image (it has no username) +if [ -z "${REGISTRY_PASSWORD}" ] && [ -n "${DOCKER_PASSWORD}" ]; then + REGISTRY_PASSWORD="${DOCKER_PASSWORD}" + echo "WARNING: DOCKER_PASSWORD is deprecated and will be removed in the next version" + echo "you should switch to using REGISTRY_PASSWORD" + echo "see the documentation for more info https://git.narvas.tech/vista/container-update-checker" +fi + +if [ -z "${BASE_REGISTRY_USERNAME}" ] && [ -n "${REGISTRY_USERNAME}" ]; then + BASE_REGISTRY_USERNAME="${REPO_USERNAME}" +fi + +if [ -z "${BASE_REGISTRY_PASSWORD}" ] && [ -n "${REGISTRY_PASSWORD}" ]; then + BASE_REGISTRY_PASSWORD="${REPO_PASSWORD}" +fi + +if [ -z "${TARGET_REGISTRY_USERNAME}" ] && [ -n "${REGISTRY_USERNAME}" ]; then + TARGET_REGISTRY_USERNAME="${REPO_USERNAME}" +fi + +if [ -z "${TARGET_REGISTRY_PASSWORD}" ] && [ -n "${REGISTRY_PASSWORD}" ]; then + TARGET_REGISTRY_PASSWORD="${REPO_PASSWORD}" +fi + +if [ -z "${REGISTRY_API}" ]; then + REGISTRY_API='docker' +fi + +if [ -z "${BASE_REGISTRY_API}" ]; then + BASE_REGISTRY_API="${REGISTRY_API}" +fi + +if [ -z "${TARGET_REGISTRY_API}" ]; then + TARGET_REGISTRY_API="${REGISTRY_API}" +fi + +if [ -z "${REGISTRY_URL}" ]; then + REGISTRY_URL="https://hub.docker.com" +fi + +if [ -z "${BASE_REGISTRY_URL}" ]; then + BASE_REGISTRY_URL="${REGISTRY_URL}" +fi + +if [ -z "${TARGET_REGISTRY_URL}" ]; then + TARGET_REGISTRY_URL="${REGISTRY_URL}" +fi + +# remove trailing / +BASE_REGISTRY_URL="${BASE_REGISTRY_URL%/}" +TARGET_REGISTRY_URL="${TARGET_REGISTRY_URL%/}" + +# add "library/" if its a "official" docker image (no username is provided) echo "${BASE}" | grep -q "/" || BASE="library/${BASE}" echo "${TARGET}" | grep -q "/" || TARGET="library/${TARGET}" -# if no tag is give default to latest +# if no tag is given default to latest echo "${BASE}" | grep -q ":" || BASE="${BASE}:latest" echo "${TARGET}" | grep -q ":" || TARGET="${TARGET}:latest" +# split repo into user reponame and tag +BASE_REPO_USER=$(echo "$BASE" | cut -d'/' -f1) +BASE_REPO_NAME=$(echo "$BASE" | cut -d'/' -f2 | cut -d':' -f1) +BASE_REPO_TAG=$(echo "$BASE" | cut -d':' -f2) -# move the tag to its own var and remove it from the repo name -BASE_TAG=$(echo "${BASE}" | sed 's/[^:]*://') -TARGET_TAG=$(echo "${TARGET}" | sed 's/[^:]*://') +TARGET_REPO_USER=$(echo "$TARGET" | cut -d'/' -f1) +TARGET_REPO_NAME=$(echo "$TARGET" | cut -d'/' -f2 | cut -d':' -f1) +TARGET_REPO_TAG=$(echo "$TARGET" | cut -d':' -f2) -BASE_REPO=$(echo "${BASE}" | sed 's/:.*//') -TARGET_REPO=$(echo "${TARGET}" | sed 's/:.*//') +BASE_HEADER="" +if [ "${BASE_REGISTRY_API}" = 'docker' ];then + if [ -n "${BASE_REGISTRY_USERNAME}" ] && [ -n "${BASE_REGISTRY_PASSWORD}" ]; then + TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d "{\"username\": \"${BASE_REGISTRY_USERNAME}\", \"password\": \"${BASE_REGISTRY_PASSWORD}\"}" "${BASE_REGISTRY_URL}/users/login/" | jq -r .token) + BASE_HEADER="Authorization: JWT ${TOKEN}" + fi + BASE_URL="${BASE_REGISTRY_URL}/v2/repositories/${BASE_REPO_USER}/${BASE_REPO_NAME}/tags/${BASE_REPO_TAG}" + +elif [ "${BASE_REGISTRY_API}" = 'gitea' ];then + if [ -n "${BASE_REGISTRY_PASSWORD}" ]; then + BASE_HEADER="Authorization: token ${BASE_REGISTRY_PASSWORD}" + fi + BASE_URL="${BASE_REGISTRY_URL}/api/v1/packages/${BASE_REPO_USER}/container/${BASE_REPO_NAME}/${BASE_REPO_TAG}" +fi -# build the url to the repo -BASE_URL="https://hub.docker.com/v2/repositories/${BASE_REPO}/tags/${BASE_TAG}" -TARGET_URL="https://hub.docker.com/v2/repositories/${TARGET_REPO}/tags/${TARGET_TAG}" +TARGET_HEADER="" +if [ "${TARGET_REGISTRY_API}" = 'docker' ];then + if [ -n "${TARGET_REGISTRY_USERNAME}" ] && [ -n "${TARGET_REGISTRY_PASSWORD}" ]; then + TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d "{\"username\": \"${TARGET_REGISTRY_USERNAME}\", \"password\": \"${TARGET_REGISTRY_PASSWORD}\"}" "${TARGET_REGISTRY_URL}/users/login/" | jq -r .token) + TARGET_HEADER="Authorization: JWT ${TOKEN}" + fi + TARGET_URL="${TARGET_REGISTRY_URL}/v2/repositories/${TARGET_REPO_USER}/${TARGET_REPO_NAME}/tags/${TARGET_REPO_TAG}" -# login if credentias are passed -HEADER="" -if [ -n "${DOCKER_USERNAME}" ] && [ -n "${DOCKER_PASSWORD}" ]; then - TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'"${DOCKER_USERNAME}"'", "password": "'"${DOCKER_PASSWORD}"'"}' https://hub.docker.com/v2/users/login/ | jq -r .token) - HEADER="Authorization: JWT ${TOKEN}" +elif [ "${TARGET_REGISTRY_API}" = 'gitea' ];then + if [ -n "${TARGET_REGISTRY_PASSWORD}" ]; then + TARGET_HEADER="Authorization: token ${TARGET_REGISTRY_PASSWORD}" + fi + TARGET_URL="${TARGET_REGISTRY_URL}/api/v1/packages/${TARGET_REPO_USER}/container/${TARGET_REPO_NAME}/${TARGET_REPO_TAG}" fi # compare the update time of the BASE and TARGET images -BASE_DATE=$(curl -s -H "${HEADER}" "${BASE_URL}" | jq -r .last_updated | sed 's/T/ /' | sed 's/\..*//' ) -TARGET_DATE=$(curl -s -H "${HEADER}" "${TARGET_URL}" | jq -r .last_updated | sed 's/T/ /' | sed 's/\..*//' ) +if [ "${BASE_REGISTRY_API}" = 'docker' ];then + BASE_DATE=$(curl -s -H "${BASE_HEADER}" "${BASE_URL}" | jq -r .last_updated) +elif [ "${BASE_REGISTRY_API}" = 'gitea' ];then + BASE_DATE=$(curl -s -H "${BASE_HEADER}" "${BASE_URL}" | jq -r .created_at) +fi -BASE_TIMESTAMP=$(date -d "${BASE_DATE}" +%s) -TARGET_TIMESTAMP=$(date -d "${TARGET_DATE}" +%s) +if [ "${TARGET_REGISTRY_API}" = 'docker' ];then + TARGET_DATE=$(curl -s -H "${TARGET_HEADER}" "${TARGET_URL}" | jq -r .last_updated) +elif [ "${TARGET_REGISTRY_API}" = 'gitea' ];then + TARGET_DATE=$(curl -s -H "${TARGET_HEADER}" "${TARGET_URL}" | jq -r .created_at) +fi + +BASE_TIMESTAMP=$(dateconv --format="%s" "${BASE_DATE}") +TARGET_TIMESTAMP=$(dateconv --format="%s" "${TARGET_DATE}") CLEAN_EXIT=true @@ -68,4 +154,4 @@ if [ "$BASE_TIMESTAMP" -le "$TARGET_TIMESTAMP" ]; then fi echo "$TARGET needs updating" -exit 0 \ No newline at end of file +exit 0