virtual resource realizing by require?

1,383 views
Skip to first unread message

Frederik Wagner

unread,
Feb 8, 2010, 10:59:42 AM2/8/10
to puppet...@googlegroups.com
Hi .*,

I'm wondering if there is a way to have a virtual resource realize
other virtual resources which it requires.

Background: I want to create a module which provides all possible
mountpoints from a NAS Filer as virtual resources, like @mount{xyz}.
These mounts depend on some directory which must exists, and should
only be created if the mount is realized (furthermore some nfs client
options are only needed to be set if a nfs mount takes place at all).

I would think that something like the following would do the job, but
it doesn't.

in some class:
@file{"/mountpoint": ensure => directory }

@mount{"/mountpoint":
...,
require => File["/mountpoint"]
}

in some other class:
Mount<| title == "/mountpoint" |>


What am I missing? Or is this not possible at all?

Thanks a lot,
Frederik

Aurelien Degremont

unread,
Feb 9, 2010, 3:32:08 AM2/9/10
to puppet...@googlegroups.com
Frederik Wagner a �crit :

Hello

I never really played with virtual ressources but it seems you forgot to also realize the file object for your mountpoint?

--
Aurelien Degremont
CEA

Frederik Wagner

unread,
Feb 9, 2010, 4:23:59 AM2/9/10
to puppet...@googlegroups.com
Hi Aurelien,

On Tue, Feb 9, 2010 at 9:32 AM, Aurelien Degremont
<aurelien....@cea.fr> wrote:
> Frederik Wagner a écrit :

this is exactly the point of my problem, I would like to automatically
realize all resources required by the mount without explicitly stating
it in the module realizing the mount. All requirements should be
encapsulated in the module providing the @mount.

Bye
Frederik

>
>
>
> --
> Aurelien Degremont
> CEA
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Users" group.
> To post to this group, send email to puppet...@googlegroups.com.
> To unsubscribe from this group, send email to
> puppet-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/puppet-users?hl=en.
>
>

Aurelien Degremont

unread,
Feb 9, 2010, 4:55:35 AM2/9/10
to puppet...@googlegroups.com
Frederik Wagner a �crit :

> Hi Aurelien,
>
> On Tue, Feb 9, 2010 at 9:32 AM, Aurelien Degremont
> <aurelien....@cea.fr> wrote:
>> Frederik Wagner a �crit :

You need to create your own type with a define


define mymount($mountpoint) {
file { $mountpoint:
ensure => "directory"
}

mount { $mountpoint:
require => File[$mountpoint],
}
}


@mymount{ "/mountpoint":
mountpoint => "/mountpoint"
}

Mymount<| title == "/mount_point" |>


Not sure, but i think this is the good way.


--
Aurelien Degremont
CEA

Thomas Bellman

unread,
Feb 9, 2010, 5:11:52 AM2/9/10
to puppet...@googlegroups.com
Frederik Wagner wrote:

> I would think that something like the following would do the job, but
> it doesn't.
>
> in some class:
> @file{"/mountpoint": ensure => directory }
>
> @mount{"/mountpoint":
> ...,
> require => File["/mountpoint"]
> }
>
> in some other class:
> Mount<| title == "/mountpoint" |>
>
> What am I missing? Or is this not possible at all?

It's not possible to do it that exact way. But, you can use a define:

define foomount($device, $fstype, ...)
{
File <| name == $name |>
mount { $name: ..., require => File[$name]; }
}

@file { "/mountpoint": ensure => directory; }

@foomount { "/mountpoint": ...; }

Foomount <| title == "/mountpoint" |>

Unless you really want to declare the virtual file resource in some
other place than where you define foomount, it probably makes more
sense to inline that in foomount, though:

define foomount($device, $fstype, ...)
{
file { $name: ensure => directory; }
mount { $name: ..., require => File[$name]; }
}

Hope this helps.


/Bellman

Frederik Wagner

unread,
Feb 9, 2010, 5:14:37 AM2/9/10
to puppet...@googlegroups.com
On Tue, Feb 9, 2010 at 10:55 AM, Aurelien Degremont
<aurelien....@cea.fr> wrote:
> Frederik Wagner a écrit :

>>
>> Hi Aurelien,
>>
>> On Tue, Feb 9, 2010 at 9:32 AM, Aurelien Degremont
>> <aurelien....@cea.fr> wrote:
>>>
>>> Frederik Wagner a écrit :

good idea and I was thining in a similar direction, but in this way
all the possible mounts are/must be created in the same way, i.e. in
this case a file + a moutn ressource.

I was looking for a generic way, let's say somthing like

@mount{"/mountpoint":
...,
require => File<| title == "/mountpoint"] |>
}

which would be great. The requirement is realized only when it is needed.

Bye,

Alan Barrett

unread,
Feb 9, 2010, 5:35:09 AM2/9/10
to puppet...@googlegroups.com
On Tue, 09 Feb 2010, Frederik Wagner wrote:
> >> @file{"/mountpoint": ensure => directory }
> >>
> >> @mount{"/mountpoint":
> >> ...,
> >> require => File["/mountpoint"]
> >> }
> >>
> >> in some other class:
> >> Mount<| title == "/mountpoint" |>
>
> I would like to automatically realize all resources required by the
> mount without explicitly stating it in the module realizing the
> mount. All requirements should be encapsulated in the module providing
> the @mount.

There is a feature request for this:
<http://projects.reductivelabs.com/issues/2084>. Until that is
implemented, I think you'll need to work around it using a define.

--apb (Alan Barrett)

Frederik Wagner

unread,
Feb 9, 2010, 6:11:06 AM2/9/10
to puppet...@googlegroups.com
On Tue, Feb 9, 2010 at 11:35 AM, Alan Barrett <a...@cequrux.com> wrote:
> On Tue, 09 Feb 2010, Frederik Wagner wrote:
>> >> @file{"/mountpoint": ensure => directory }
>> >>
>> >> @mount{"/mountpoint":
>> >> ...,
>> >> require => File["/mountpoint"]
>> >> }
>> >>
>> >> in some other class:
>> >> Mount<| title == "/mountpoint" |>
>>
>> I would like to automatically realize all resources required by the
>> mount without explicitly stating it in the module realizing the
>> mount. All requirements should be encapsulated in the module providing
>> the @mount.

thanks for the information!

> There is a feature request for this:
> <http://projects.reductivelabs.com/issues/2084>. Until that is
> implemented, I think you'll need to work around it using a define.

very good, i suppose there is no time schedule for this yet?

I just tried using the define, and hit a problem which I would avoid
(and actually need to avoid) by using the not implemented feature.
Realizing the virtual define across modules forces me to give the
namespace of the define explicitly, i.e. creating the virtual define
@mymount in a class nas-1::virtual (in the Module nas-1) forces me to
realize it in a second module as Nas-1::Virtual::Mymount<| |>, instead
of just Mymount<| |>.

But this I have to avoid - and would be avoided by the feature request
- since I use a versioning of the modules which should not be part of
the realize statement, as well as the modules should not know about
each others classnames anyway.

Any idea to work around this?

Thanks a whole lot!
Bye
Frederik


>
> --apb (Alan Barrett)

Alan Barrett

unread,
Feb 11, 2010, 4:42:35 AM2/11/10
to puppet...@googlegroups.com
On Tue, 09 Feb 2010, Frederik Wagner wrote:
> I just tried using the define, and hit a problem which I would avoid
> (and actually need to avoid) by using the not implemented feature.
> Realizing the virtual define across modules forces me to give the
> namespace of the define explicitly, i.e. creating the virtual define
> @mymount in a class nas-1::virtual (in the Module nas-1) forces me to
> realize it in a second module as Nas-1::Virtual::Mymount<| |>, instead
> of just Mymount<| |>.

Could you put the define in a common module, rather than a NAS-specific
module? For example:

/* In the "util" module */

define mymount ($mountpoint) {
realize File[$mountpoint]


mount { $mountpoint: require => File[$mountpoint], }
}

/* In the nas-1::virtual class */

@util::mymount { "foo": }

/* Wherever you want to instantiate the mount: */

include nas-1::virtual
realize Util::Mymount["foo"]

--apb (Alan Barrett)

Frederik Wagner

unread,
Feb 11, 2010, 5:12:37 AM2/11/10
to puppet...@googlegroups.com

yes, in principle, if it wouldn't be just for this generic Mymount
definition. Mymount is somehow just an extended redifinition of mount
where all parameters are passed.

But besides the required file resource some very nas-1 specific
editing in /etc/sysctl.conf etc. (via augeas) should be done.
Therefore any Mymount (there are multiple mountspoint on that filer)
should also realize an augeas resource which defenitly can not go into
the Util module. Do you see what I mean? The nas-1 module would be
like:

@augeas{ very specifig editing }

@file{ mountpoint }

@mount{ mountpoint: require => [realize Augeas, realize File] }

where - like you said - mount+file have a generic form which can end
up in a definition in "Util" but augeas has to stay in "nas-1".

As far as I see - and I was thinking quite a while about it - I really
end up needing the realization by require feature :-( or it's going to
be a intermodule dependency mess.

Thanks a lot,

Frederik Wagner

unread,
Feb 12, 2010, 4:23:30 AM2/12/10
to puppet...@googlegroups.com
Hi again,

I found a working for this problem! I hope this will work in more
complicated situations.

I copied the code of the realize-function to be of :type => :rvalue,
just additionally returning the resources it realized.
In this way I can use it as a input for the 'require' parameter, like

@resource_one{ name: ... }

@resource_two{ name:... , require => new_realize( Resource_one[name] ) }

realize Resource_two[name]

This works perfect for this simple case, resource_one is realize
automatically and before resource_two. That should be it. I go on
testing in a more complicated setup.

So wouldn't be a simple idea to just change the realize function (or
the '<| ... |>' operator) to return the resources it realised?

Bye,
Frederik

jcbollinger

unread,
Feb 12, 2010, 9:32:51 AM2/12/10
to Puppet Users

On Feb 12, 3:23 am, Frederik Wagner <fner...@googlemail.com> wrote:
> So wouldn't be a simple idea to just change the realize function (or
> the '<| ... |>' operator) to return the resources it realised?

I second this feature request, especially for the <| |> and <<| |>>
operators.


John

jcbollinger

unread,
Feb 12, 2010, 9:52:07 AM2/12/10
to Puppet Users

On Feb 12, 8:32 am, jcbollinger <John.Bollin...@stJude.org> wrote:
> I second this feature request, especially for the <| |> and <<| |>>
> operators.

In fact, I have logged a feature request in redmine, issue 3178.

John

Frederik Wagner

unread,
Feb 12, 2010, 10:23:37 AM2/12/10
to puppet...@googlegroups.com
Hi John,

perfect, thanks!

In the meantime I already found the flaw in the before mentioned
"simple" extension of the realize function:

The (virtual) requirements of virtual resources are evaluated, even if
the resource itself is not realized.
E.g. just including the following class test::virtual without
realizing resource_two would lead to a realization of resource_one!
:-(

class test::virtual {
@resource_one{ test: ...}

@resource_two{ test: ..., require => realize( Resource_one[test] ) }
}

Now I'm stuck again (and am lost where to start to look for the
solution in the sources of puppet ;-).

Bye,
Frederik

garima singh

unread,
Mar 23, 2017, 12:23:07 PM3/23/17
to Puppet Users, fne...@googlemail.com
Hi,

I was wondering if you could find a soultion to putting virtual resource as target to require metaparameter.

I have to ensure that some resource is run only when a particular virtual resource is run and successful.

Please let me know if you could find a solution to the issue.

Thanks,
Garima Singh

jcbollinger

unread,
Mar 24, 2017, 9:19:44 AM3/24/17
to Puppet Users, fne...@googlemail.com


On Thursday, March 23, 2017 at 11:23:07 AM UTC-5, garima singh wrote:
Hi,

I was wondering if you could find a soultion to putting virtual resource as target to require metaparameter.


There is no inherent problem with making a resource depend on a virtual resource.  It is syntactically valid, and in itself it is semantically valid.  The problem arises if that resource is never realized for the target machine, and I suppose that's the issue you want help with.

I have to ensure that some resource is run only when a particular virtual resource is run and successful.


Every concrete resource in the catalog is applied to the target machine.  If you want a given resource to not be applied under certain circumstances, then you must ensure that it is declared only virtually if at all.  Virtual resource realization does not cascade along dependencies; if you're looking for a way to make that happen, then you need to take a step back and re-think your approach.

Your best option may be to wrap [realization of] the two resources in question in a class or defined type, so that you can cause them to be realized as a pair.  You may realize the same virtual resource multiple times with no ill effects, but this does not achieve the result of realization of one resource causing realization of the other.

You might also consider restructuring your manifest set to avoid relying on virtual resources at all.  These days it's more conventional to rely on external data (i.e. Hiera) to drive decisions about which classes and resources to declare, and this can replace the decision of whether to realize a declared virtual resource with a decision of whether to declare an ordinary resource in the first place.


John

Reply all
Reply to author
Forward
0 new messages