after_created in LWRPs

Hi,

In our infrastructure we have had the need for some of our LWRPs to
take some action during the compile phase rather than the converge
phase. Mostly this involves publishing calculated values as attribute
data so a later resource can make use of the attribute data. We have
been doing this by overriding the after_created hook in resources. So
the question is … is this something anyone else is doing or is it
insanely bad in some way I can’t figure out just yet. Thoughts?

i.e. We a LWRP similar to ark that downloads and extracts archives and
optionally publishes the directory to which the archive will be
extracted as attribute data. We then use this attribute data in a
following resource definition. See [1]

[1] https://github.com/realityforge/chef-archive/blob/master/resources/default.rb#L116


Cheers,

Peter Donald

On Thursday, May 2, 2013 at 11:28 PM, Peter Donald wrote:

Hi,

In our infrastructure we have had the need for some of our LWRPs to
take some action during the compile phase rather than the converge
phase. Mostly this involves publishing calculated values as attribute
data so a later resource can make use of the attribute data. We have
been doing this by overriding the after_created hook in resources. So
the question is ... is this something anyone else is doing or is it
insanely bad in some way I can't figure out just yet. Thoughts?

i.e. We a LWRP similar to ark that downloads and extracts archives and
optionally publishes the directory to which the archive will be
extracted as attribute data. We then use this attribute data in a
following resource definition. See [1]

[1] chef-archive/resources/default.rb at master · realityforge/chef-archive · GitHub

--
Cheers,

Peter Donald
I'd advise not to rely on callbacks and side-effects like this. Someone who's not familiar with this is gonna have a bad time trying to figure out where the data comes from.

Why not use another LWRP or resource definition that wraps both?

Alternatively, you can ask your LWRP resource where it thinks the data should go, with something like:

resources("chef_archive[NAME]").base_directory

HTH,

--
Daniel DeLeo

Hi,

On Mon, May 6, 2013 at 1:53 AM, Daniel DeLeo dan@kallistec.com wrote:

I'd advise not to rely on callbacks and side-effects like this. Someone
who's not familiar with this is gonna have a bad time trying to figure out
where the data comes from.

That's not really a concern. There are plenty of things in our chef
environment that violate the naive phased model (i.e. chef_gem,
use_inline_resources in LWRPs etc). As long as there is clear
documentation I don't see it as an issue.

Why not use another LWRP or resource definition that wraps both?

We need the LWRP to define the attribute so it is accessible later in
the compile phase (it is used to configure the creation of other
resources during compile). A resource definition would be nice except
that in every case we want to notify if an action is taken.

Alternatively, you can ask your LWRP resource where it thinks the data
should go, with something like:

resources("chef_archive[NAME]").base_directory

Hmm ... that may be an option. We already add methods to the resource
that do the calculation ...

HTH,

Thanks!

--
Cheers,

Peter Donald

On Monday, May 6, 2013 at 9:35 PM, Peter Donald wrote:

Hi,

On Mon, May 6, 2013 at 1:53 AM, Daniel DeLeo <dan@kallistec.com (mailto:dan@kallistec.com)> wrote:

I'd advise not to rely on callbacks and side-effects like this. Someone
who's not familiar with this is gonna have a bad time trying to figure out
where the data comes from.

That's not really a concern. There are plenty of things in our chef
environment that violate the naive phased model (i.e. chef_gem,
use_inline_resources in LWRPs etc). As long as there is clear
documentation I don't see it as an issue.

You can of course do whatever works for your team, but my advice is to always write code such that when it breaks the path from the symptom to the cause is as obvious and direct as possible. Documentation is great, but in practice you usually need to spend some time debugging before it's even clear what docs you need to read. And of course docs can be incomplete or out of date, and this is usually not discovered until you're debugging behavior that differs from what the docs say it should be.

Why not use another LWRP or resource definition that wraps both?

We need the LWRP to define the attribute so it is accessible later in
the compile phase (it is used to configure the creation of other
resources during compile). A resource definition would be nice except
that in every case we want to notify if an action is taken.

Since a resource definition is a compile time macro, you can notify the resources that the definition evaluates to. For example, the old runit_service definition created a service resource you could notify. But this is ugly because it's non-obvious and restricts your options for changing the implementation later.

Thanks!

--
Cheers,

Peter Donald

--
Daniel DeLeo