We have some older servers with the legacy Docker package installed from the distribution package repository. Either from manual installs
$ yum install docker
Or older manifests
package { 'docker':
ensure => present,
}
We want to migrate to the official Docker repository and packages via the "supported" puppetlabs-docker module.
include docker
However, the legacy Docker packages are not removed or otherwise managed by this new module!
[vagrant@localhost ~]$ sudo -i puppet apply -e 'include docker'
Notice: Compiled catalog for localhost.localdomain in environment production in 0.42 seconds
Notice: /Stage[main]/Docker::Repos/Yumrepo[docker]/ensure: created
Error: Execution of '/bin/yum -d 0 -e 0 -y install docker-ce' returned 1: Error: docker-ce conflicts with 2:docker-1.13.1-75.git8633870.el7.centos.x86_64
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
Error: /Stage[main]/Docker::Install/Package[docker]/ensure: change from 'purged' to 'present' failed: Execution of '/bin/yum -d 0 -e 0 -y install docker-ce' returned 1: Error: docker-ce conflicts with 2:docker-1.13.1-75.git8633870.el7.centos.x86_64
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
How do we make sure the legacy package is removed before installing the new package?
You want to start by ensuring the legacy package is absent.
package { 'docker':
ensure => absent,
}
But, you can't use Package['docker']
, because the new puppetlabs-docker module already declares it. You have to do something like this:
package { 'legacy-docker':
ensure => absent,
name => 'docker',
}
There are a number of legacy prerequisite packages that also need to be removed, too.
package { [
'docker-client',
'docker-client-latest',
'docker-common',
'docker-latest',
'docker-latest-logrotate',
'docker-logrotate',
'docker-selinux',
'docker-engine-selinux',
'docker-engine',
]:
ensure => absent,
}
So, all together, this ordering seems to work implicitly.
package { 'legacy-docker':
ensure => absent,
name => 'docker',
}
package { [
'docker-client',
'docker-client-latest',
'docker-common',
'docker-latest',
'docker-latest-logrotate',
'docker-logrotate',
'docker-selinux',
'docker-engine-selinux',
'docker-engine',
]:
ensure => absent,
}
include docker
Actually, this seems to cause problems on subsequent runs of the manifest... common second-level dependencies are removed!
Error: Execution of '/bin/rpm -e container-selinux-2.68-1.el7.noarch' returned 1: error: Failed dependencies:
container-selinux >= 2.9 is needed by (installed) docker-ce-18.06.1.ce-3.el7.x86_64
Error: /Stage[main]/Profile::Docker/Package[docker-selinux]/ensure: change from '2:2.68-1.el7' to 'absent' failed: Execution of '/bin/rpm -e container-selinux-2.68-1.el7.noarch' returned 1: error: Failed dependencies:
container-selinux >= 2.9 is needed by (installed) docker-ce-18.06.1.ce-3.el7.x86_64
Error: Execution of '/bin/rpm -e container-selinux-2.68-1.el7.noarch' returned 1: error: Failed dependencies:
container-selinux >= 2.9 is needed by (installed) docker-ce-18.06.1.ce-3.el7.x86_64
Error: /Stage[main]/Profile::Docker/Package[docker-engine-selinux]/ensure: change from '2:2.68-1.el7' to 'absent' failed: Execution of '/bin/rpm -e container-selinux-2.68-1.el7.noarch' returned 1: error: Failed dependencies:
container-selinux >= 2.9 is needed by (installed) docker-ce-18.06.1.ce-3.el7.x86_64
Well, the package resource doesn't have a refreshonly
kind of property, so we need to resort to an exec resource. Ugh.
package { 'legacy-docker':
ensure => absent,
name => 'docker',
notify => Exec['autoremove'],
}
exec { 'autoremove':
command => '/usr/bin/yum -y autoremove',
refreshonly => true,
}
include docker
This is... reasonable? The only thing might be ordering, you might explore explicit resource ordering using ->
.