How can I write a Chef provider that extends an existing provider?
Asked Answered
A

2

1

Cookbook A provides a LWRP that I would like to extend with a LWRP or HWRP in cookbook B, so that I could do something like the following, where provider_b would use the existing code/resources in provider_a and accept additional attributes it could use for it's own actions:

provider_a "A" do
    attr_from_a :value
end

provider_b "B" do
    attr_from_a :value
    attr_from_b :value
end

Is this possible, and is it still possible if I want to avoid editing cookbook A?

Abortionist answered 15/1, 2014 at 16:50 Comment(1)
There is no question here. This is just a statement with a contrived example and a poor explanation of what is trying to be achieved.Workingwoman
W
2

It sounds like you're trying to create a sub-resource of an existing LWRP, so you're not "wrapping" it - you're "extending it". The LWRP syntax makes this less than desirable, because the resources are dynamically compiled into Ruby classes at runtime.

You could switch to HWRPs (the new Jenkins cookbook is a good example that uses inheritance and OO to extend resources and share attributes). By their nature, LWRPs are not very extensible, since they are dynamically rebuilt and reloaded at runtime.

Workingwoman answered 16/1, 2014 at 3:30 Comment(2)
The jenkins cookbooks has some very useful example of the kind of thing I want to do (github.com/opscode-cookbooks/jenkins/blob/master/libraries/…). The existing provider is a LWRP in an external cookbook, so is it possible to extend a LWRP with a HWRP?Abortionist
Not very easily. You would need to figure out the classname of the LWRP, which is dynamically constructed at runtime. And then you'd need to extend it using a pure Ruby class. It's not easy and results in some seriously complex code.Workingwoman
N
3

I think the section about Custom LWRPs in the documentation and the tutorial linked at the end should help you.

EDIT: Okay, maybe looking at this LWRP or this LWRP goes a bit more into the right direction (as I think that's a very common pattern for LWRPs, I didn't go so much into detail). You can access the parameters using new_resource.param_a.

So something like this should work:

action :install do
  provider_a "A" do
    param_a new_resource.param_a
  end

  provider_b "B" do
    param_a new_resource.param_a
    param_b new_resource.param_b
  end
end
Nevillenevin answered 15/1, 2014 at 18:12 Comment(2)
Down-vote why? Because reading documentation can't be expected when posting to SO? ;-) Or what did I understand wrong?Nevillenevin
It's not the answerer's fault that your question is unclear :). I was writing a similar answer until your comment. Perhaps adding some additional examples and clarification to your question would help?Workingwoman
W
2

It sounds like you're trying to create a sub-resource of an existing LWRP, so you're not "wrapping" it - you're "extending it". The LWRP syntax makes this less than desirable, because the resources are dynamically compiled into Ruby classes at runtime.

You could switch to HWRPs (the new Jenkins cookbook is a good example that uses inheritance and OO to extend resources and share attributes). By their nature, LWRPs are not very extensible, since they are dynamically rebuilt and reloaded at runtime.

Workingwoman answered 16/1, 2014 at 3:30 Comment(2)
The jenkins cookbooks has some very useful example of the kind of thing I want to do (github.com/opscode-cookbooks/jenkins/blob/master/libraries/…). The existing provider is a LWRP in an external cookbook, so is it possible to extend a LWRP with a HWRP?Abortionist
Not very easily. You would need to figure out the classname of the LWRP, which is dynamically constructed at runtime. And then you'd need to extend it using a pure Ruby class. It's not easy and results in some seriously complex code.Workingwoman

© 2022 - 2024 — McMap. All rights reserved.