puppetlabs / puppetlabs/puppetlabs-docker
docker::image with image_tag=latest does not apply idempotently
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 94
- Forks
- 337
- Avg merge
- 11d 15h
- Merged PRs (30d)
- 2
Description
Describe the Bug
When using docker::image or docker::images with image_tag=latest puppet reports changes on evry puppet run.
Expected Behavior
I would expect docker::image to report changes only when the image digest is changed and a pull is really necessary.
Environment
- Version [5.10.1]
- Platform [RHEL7]
Additional Context
It looks like this bug was introduced in https://github.com/puppetlabs/puppetlabs-docker/pull/553 which created exec { $image_install }.
The right way to solve this would be to check if a pull is required and then do a pull.
We are using something like this
LOCAL_SHA="$(docker image ls --digests ${REGISTRY_HOST}:${REGISTRY_PORT}/${REGISTRY_PATH} --format '{{json . }}' | jq ". | select( .Tag == \"$TAG\" ) | .Digest" | tr -d '"')"
REMOTE_SHA="$(curl -sfH 'Accept: application/vnd.docker.distribution.manifest.v2+json' -I http://${REGISTRY_HOST}:${REGISTRY_PORT}/v2/${REGISTRY_PATH}/manifests/${TAG} | tr -d '\r' | grep 'Docker-Content-Digest' | awk '{print $2}')"
[[ "$LOCAL_SHA" != "$REMOTE_SHA" ]]
The curl in REMOTE_SHA does not use auth, and I'm not sure how to implement it with auth in the module.
Thats why I have not created i pull request.
We use the script like this in our profile class
`
$instances = lookup('docker::run_instance::instance', undef, undef, undef)
if $instances != undef {
contain docker::run_instance
Class['::docker'] -> Class['docker::run_instance']
}
if $instances != undef {
$instances.each |$key, $value| {
if $value['ensure'] != 'absent' {
$registry_host = $value['image'].split('/')[0].split(':')[0]
$registry_port = $value['image'].split('/')[0].split(':')[1]
$tag = $value['image'].split('/')[-1].split(':')[1]
$path = $value['image'].split('/').reduce |$memo, $value| {
if $memo =~ $registry_host {
if $value =~ $tag {
"${value.split(':')[0]}"
} else {
$value
}
} elsif $value =~ $tag {
"${memo}/${value.split(':')[0]}"
} else {
"${memo}/${value}"
}
}
exec {"${title} image digest changed ${key}":
command => 'echo',
path => ['/bin', '/usr/bin', '/usr/local/bin'],
onlyif => "docker-image-digest-changed.sh standalone ${$registry_host} ${$registry_port} ${$path} ${$tag}",
require => [
File['/usr/local/bin/docker-image-digest-changed.sh'],
],
notify => [
Exec["${title} docker rm ${key}"],
Exec["${title} docker pull ${$value['image']}"]
]
}
exec {"${title} docker rm ${key}":
command => "docker rm -f ${key}",
path => ['/bin', '/usr/bin'],
onlyif => "docker ps -a | awk '{print \$NF}' | grep -qw '${key}'",
refreshonly => true,
require => Exec["${title} docker pull ${$value['image']}"],
before => Docker::Run[$key],
}
# Multiple instanses could use the same image
if !defined(Exec["${title} docker pull ${$value['image']}"]) {
exec {"${title} docker pull ${$value['image']}":
command => "docker pull ${$value['image']}",
path => ['/bin', '/usr/bin'],
refreshonly => true,
}
}
}
}
}
`
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at docker::image and docker::images, then trace the exec { $image_install } introduced by PR #553. Review how image_tag=latest decides whether to pull, including the registry authentication concern described in the issue. Done means repeated Puppet runs report no changes when the digest is unchanged and pull only when it changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker
- Domain
- devops, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100