also you should stop using the provider
property on resources as well.
instead of:
package "whatever" do
provider local_install? ? Chef::Provider::Dpkg :
Chef::Provider::Apt
end
on Chef-12 that will wind up with package selecting an
Chef::Resource::Apt resource and wrapping that around a Dpkg provider
when local_install? is set and then chef will output in the run
"apt_package[whatever] " even though its running dpkg. that
is fairly 'broken' but it was always broken since in Chef-11 you were
getting a vanilla Chef::Resource::Package with no support for any
specific Dpkg or Apt options. that provider option was also always
tight coupling to an internal chef class and was always bad as well (now
we can never ever change the names of those classes or we'll break the
world).
instead you should act more like:
if local_install?
dpkg_package "whatever" do
...
end
else
apt_package "whatever" do
...
end
end
you should have always been doing that in Chef-11 in order to reduce the
tight coupling and to construct the correct resource and do the correct
validation for the provider that you were using. the only problem with
this is that the block is replicated and generally has copypasta code
that we'd like to dry. the declare_resource API can fix that:
package_resource = local_install? ? :dpkg_package : :apt_package
declare_resource package_resource, "whatever" do
...
end
so....
TL;DR: write 1:1 resources with the new resources stuff and use
declare_resource to switch them dynamically.
On 10/09/2015 09:24 AM, Lamont Granquist wrote:
yeah, you want 1:1 mapping of resources and providers, and then wire
them up with provides. look at how the package resources use
yum_package resource+provider, apt_package resource+provider and then
wire themselves up to package on the DSL. the Chef::Resource::Package
resource is now an abstract base class that isn't wired up to 'package'
any more (its just used for code sharing). the objects that you can
really make are Chef::Resource::YumPackage and
Chef::Resource::AptPackage, and those always wrap
Chef::Provider::Yum and Chef::Provider::Apt.
the multiple-provider abstraction is really kind of deprecated (but not
really) because its a leaky abstraction. once you wind up sprouting
different validations that you want to do on the two different
providers, then you want to wrap them with 1:1 specific resources that
do the validation for the specific provider. the way that Chef 11
worked where you could get a vanilla Chef::Resource::Package that wraps
a Chef::Provider::Yum but you couldn't pass any of the
yum-specific options through that was mostly confusing -- there's
possibly a bit of utility there in being able to validate that the
package options you were using were valid across all platforms, but i
don't think anyone used it that way, and only the people who really
deeply thought about the classes you were instantiating.
and if you look at the service resources with the multiple providers
behind it, it is just a disaster. don't ever go down the road of
replicating those patterns. that source code should come with a big
warning that its an example of a chef antipattern.
On 10/09/2015 07:42 AM, Cassiano Leal wrote:
Hi list,
I’m having a look into the newly released Chef Client 12.5 and I
really like the new streamlined custom resources.
I couldn’t find information on how to deal with multiple providers in
this new model though. What’s the thought around that? Create
different custom resources for what used to be different providers?
Cheers!
Cassiano Leal