Use the same resource in two dependent classes

35 views
Skip to first unread message

zerozer...@gmail.com

unread,
Feb 17, 2014, 6:41:14 AM2/17/14
to puppet...@googlegroups.com
Hi,
I have this situation:

Class A: contains a File resource, and a Service resource which requires the File resource (the service needs to be restarted when the file changes).

Class B: will be applied only on a subset of machines where class A is applied, and it requires class A - resources belonging to class B must be applied only after resources from class A have been applied. Class B also contains some File resources, and after they are applied also the _same_ service from class A needs to be restarted.

How do you deal with this situation?

I cannot declare the same Service resource again in class B.
And I cannot declare the Service in class A as dependent from the File in class B.

Thanks for any suggestions.
Marco

Larry Fast

unread,
Feb 17, 2014, 2:36:08 PM2/17/14
to puppet...@googlegroups.com
Declaring the Service as a Virtual Resource might help but I'm not sure how you inject B's dependencies.
http://docs.puppetlabs.com/guides/virtual_resources.html   It might just require a Notify inside B.

Trevor Vaughan

unread,
Feb 17, 2014, 3:40:22 PM2/17/14
to puppet...@googlegroups.com
Can you just have Class B 'include' class A and then have the appropriate resources in Class B notify/require what you need from Class A?

If not, then you might need a Class C that provides the glue code using the relationship operators (->, ~>, etc...).

Trevor


--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/28c5d6ac-3bbe-490d-b174-d321d0bf7fc7%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Trevor Vaughan
Vice President, Onyx Point, Inc
(410) 541-6699
tvau...@onyxpoint.com

-- This account not approved for unencrypted proprietary information --

zerozer...@gmail.com

unread,
Feb 18, 2014, 6:35:29 AM2/18/14
to puppet...@googlegroups.com
On Monday, February 17, 2014 9:40:22 PM UTC+1, Trevor Vaughan wrote:

Can you just have Class B 'include' class A and then have the appropriate resources in Class B notify/require what you need from Class A?

Wouldn't this create a dependency cycle?

Class B, as I wrote, "requires" class A. I cannot just "include" it.
So the resource (service) contained in class A cannot be notified from a resource (file) contained in class B.
Right?

Marco

Nikola Petrov

unread,
Feb 18, 2014, 7:11:15 AM2/18/14
to puppet...@googlegroups.com
Hi Marco,

On Mon, Feb 17, 2014 at 03:41:14AM -0800, zerozer...@gmail.com wrote:
> Hi,
> I have this situation:
>
> Class A: contains a File resource, and a Service resource which requires
> the File resource (the service needs to be restarted when the file changes).
>
> Class B: will be applied only on a subset of machines where class A is
> applied, and it requires class A - resources belonging to class B must be
> applied only after resources from class A have been applied. Class B also
> contains some File resources, and after they are applied also the _same_
> service from class A needs to be restarted.

class A {
service {'myservice':
ensure => 'started',
}

file { '/etc/default/myservice.conf':
ensure => present,
notify => Service['myservice'],
template => '...',
}
}


class B {

file { '/etc/default/myservice.conf1':
notify => Service['myservice'], # note that this is sort of global
template => '...',
}

Class['A'] -> Class['B']
}

>
> How do you deal with this situation?
>
> I cannot declare the same Service resource again in class B.
> And I cannot declare the Service in class A as dependent from the File in
> class B.

Why do you need this? You can just use the name of the service which
will be sort of global to the catalog.

>
> Thanks for any suggestions.
> Marco


Sorry If I am missing something...


--
Nikola

Felix Frank

unread,
Feb 18, 2014, 7:18:36 AM2/18/14
to puppet...@googlegroups.com
Hi,

On 02/17/2014 12:41 PM, zerozer...@gmail.com wrote:
> resources belonging to class B must be applied only after resources from
> class A have been applied. Class B also contains some File resources,
> and after they are applied also the _same_ service from class A needs to
> be restarted.

this is a contradiction apparently - the service resource needs to be
applied after at least one resource in class B.

Can the service be moved to a class of its own, which is included and
notified by both A and B?

Regards,
Felix

zerozer...@gmail.com

unread,
Feb 18, 2014, 7:25:43 AM2/18/14
to puppet...@googlegroups.com
On Tuesday, February 18, 2014 1:11:15 PM UTC+1, nikolavp wrote:
 
class A {
    service {'myservice':
        ensure => 'started',
    }

    file { '/etc/default/myservice.conf':
        ensure => present,
        notify => Service['myservice'],
        template => '...',
    }
}


class B {

    file { '/etc/default/myservice.conf1':
        notify => Service['myservice'], #  note that this is sort of global
        template => '...',
    }

    Class['A'] -> Class['B']

Uhm, I expected the notify parameter to create a File ~> Service dependency, and so a Class['B'] -> Class ['A'] dependency which would create a loop with the other one, according to http://docs.puppetlabs.com/references/latest/metaparameter.html#notify : "[…notify…] it creates a dependency relationship like before".

Does it work instead? Maybe I should just try it. But time's up for today.

Thanks.
Marco

zerozer...@gmail.com

unread,
Feb 18, 2014, 7:26:47 AM2/18/14
to puppet...@googlegroups.com
On Tuesday, February 18, 2014 1:18:36 PM UTC+1, Felix.Frank wrote:
 
Can the service be moved to a class of its own, which is included and
notified by both A and B?

Indeed, maybe this is a clean and viable solution.
I'll look into it.
Thanks.

Nikola Petrov

unread,
Feb 18, 2014, 7:47:34 AM2/18/14
to puppet...@googlegroups.com
Hmm (shame) good point. Haven't tried the code. In that case I would
move the service(thingy) in a separate module with a define for a config
file with proper relationships there. Then A and B will both have
dependencies on that module and it(the new module) will handle the order
and dependencies.

I find this pattern far cleaner and when you think about it services are
just separate things so giving each of them a module makes sense.

--
Nikola

>
> Does it work instead? Maybe I should just try it. But time's up for today.
>
> Thanks.
> Marco
>
> --
> You received this message because you are subscribed to the Google Groups "Puppet Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/8ee53a6d-539b-4a2d-b023-a49ccd3c4961%40googlegroups.com.

jcbollinger

unread,
Feb 18, 2014, 9:24:39 AM2/18/14
to puppet...@googlegroups.com


There appears to be some confusion here between evaluation order and application order.  It is true that the code presented contains a dependency cycle, but it is a needless one.  Resource relationships such as are declared via the chaining operators and the before / require / notify / subscribe metaparameters influence order of application (on the client), but have nothing to do with the order of class evaluation during catalog compilation.  Class declarations affect which classes are evaluated and in what order during catalog compilation, but they do not directly affect the order in which resources are applied to the target node.

Class B should not declare Class['A'] -> Class['B'], because its declaration of File['/etc/default/myservice.conf1'] already expresses the whole application-order relationship between classes A and B.  In particular, it doesn't matter in which order the File resources declared by those classes are applied.  On the other hand, it is good form in cases like this for class B to 'include' class A because it needs the resources therein to be declared (but only if class A is not parameterized, or if it can be assumed to rely on defaults and/or automatic data binding).

With that said, there is some debate over whether it is ever appropriate for one class to declare relationships directly with resources declared by another.  Some argue that declared relationships should never cross class boundaries, and such a practice yields stability and ease of maintenance advantages over complete absence of discipline with respect to which relationships are declared.  Personally, though, I take a position between those extremes.  I prefer that relationships not cross class boundaries, but I'm relaxed about that when the classes involved belong to the same module.


John

Reply all
Reply to author
Forward
0 new messages