PullPolicy:local-on-fail
What does this MR do?
The always/never pull-policies are mostly useful for administrators that want some (security) control over the pipelines.
However the if-not-present policy does something interesting, it tries to use a local container first, and pulls it if it does not exist.
This flow is very useful for 'build pipeline container' scenarios, where a pipeline could do a 'docker build -t $CI_PIPELINE_ID' container for the duration of a pipeline.
The downside of this flag is, that any existing container never gets updated without outside input. This means for example that a shellcheck container, is never updated unless the admin wipes the docker caches.
This commit introduces a fourth option: LocalOnFail
What this means, is that we first try to pull the image (similar to always for non-pipeline containers) and if that fails (will always happen for pipeline containers) tries to use a local container instead.
In essence, we get both scenario's 'always-if-not-present'.
Why was this MR needed?
The current available pull-policies are not adequate, especially when doing both remote images (the most common scenario) mixed with containers-per-pipeline (interesting for non-web-apps).
What's the best way to test this MR?
Test cases where added, but the best way is to create a simple pipeline, that does both linting, building a container, and see that the updated container (for the linter) gets used after cache expiry.
stages:
- lint
- build
- test
lint:
stage: lint
image: "shellcheck-alpine:stable"
script:
- shellcheck testscript.sh
build:
stage: build
image: "docker:stable"
script:
- docker build --pull --rm --tag "${CI_COMMIT_SHORT_SHA}:${CI_PIPELINE_ID}" "./"
test:
stage: test
image: "${CI_COMMIT_SHORT_SHA}:${CI_PIPELINE_ID}"
script:
- ./testscript.sh
FROM alpine:latest
COPY testscript.sh
#!/bin/sh
echo "Hello World"
exit 0
(the above is pseudo-code all written from head without actually testing or running it ;) sorry)
With the 'always' runner, the test stage will always fail, as we can't pull the pipeline container With the 'never' runner, the linter will fail With the 'if-not-present' everything works, but the linter image gets outdated quickly (as does the alpine:latest from the container)
With the new 'local-on-fail' policy, everything should work as expected; the linter is always up-to-date and the test can run the container created with build (internally the pull fails, but I don't think we'll see it).