Idempotent lwrp behaviour


#1

Hi all!

I’ve run into a problem, when I was trying to implement an lwrp, that does
something like the artifact_package resource in

The simplified base of the lwrp looks like:

use_inline_resources

action :install
custom_artifact_download_lwrp …
package …
end

I wanted to test its idempotency, to make sure no notification will be
propagated when the package is already installed. If any of the inner
resources inside the custom_artifact_download_lwrp resource was modified
(the file has been removed from the cache - we want to do periodic cleanup
there) the notification was sent out even if the package was already
installed. I wanted to force “mute” it somehow, because I want to avoid
restarting services needlessly. I’ve naively tried:

c = custom_artifact_download_lwrp
c.updated_by_last_action(false)

But after digging into the code I’ve realised I can not do this, since this
code runs before the resource collection is converged. So if a resource
gets modified the updated flag will be true and I cannot do anything about
it. Is there a way to do this?

Anyways, after reading the lwrp docs more closely, I’ve realized that I
should do a conditional before declaring any of my resources, so ended up
in doing this:

def skip_install?(name, version)
status = dpkg -s #{name}
status.lines.any? { |l| /^Status: install ok installed/.match l } &&
status.lines.any? { |l| /^Version: #{version}$/.match l }
end

action :install
unless skip_install?()
custom_artifact_download_lwrp …
package …
end
end

I’m wondering if there is a more appropriate way of checking package
availability, and wheter I’ve ended up doing this right or missing
something?

Thanks,
pepov


#2

Hi Pepov,

I’ll be honest that I’m having a hard time determining exactly where you’re
issue is based on what’s posted but… The package resource should not be
"updated_by_last_action" if the package is already installed and up to
date. This slide deck has a slide on “Nested Resources” that might be
applicable to what you are doing(and if not def worth knowing)
http://www.slideshare.net/geekbri/lwrp-presentation . It involves running
the nested resources in a new context and then checking that context to see
if resources have been updated or not. It’s a bit gross IMHO, and there
may be a better way of doing it, but it’s fairly straight forward.

I hope that helps and apologise if it does not :slight_smile:

-Greg

On Wed, Sep 10, 2014 at 12:31 AM, Peter Wilcsinszky <
peterwilcsinszky@gmail.com> wrote:

Hi all!

I’ve run into a problem, when I was trying to implement an lwrp, that does
something like the artifact_package resource in
https://github.com/RiotGames/artifact-cookbook

The simplified base of the lwrp looks like:

use_inline_resources

action :install
custom_artifact_download_lwrp …
package …
end

I wanted to test its idempotency, to make sure no notification will be
propagated when the package is already installed. If any of the inner
resources inside the custom_artifact_download_lwrp resource was modified
(the file has been removed from the cache - we want to do periodic cleanup
there) the notification was sent out even if the package was already
installed. I wanted to force “mute” it somehow, because I want to avoid
restarting services needlessly. I’ve naively tried:

c = custom_artifact_download_lwrp
c.updated_by_last_action(false)

But after digging into the code I’ve realised I can not do this, since
this code runs before the resource collection is converged. So if a
resource gets modified the updated flag will be true and I cannot do
anything about it. Is there a way to do this?

Anyways, after reading the lwrp docs more closely, I’ve realized that I
should do a conditional before declaring any of my resources, so ended up
in doing this:

def skip_install?(name, version)
status = dpkg -s #{name}
status.lines.any? { |l| /^Status: install ok installed/.match l } &&
status.lines.any? { |l| /^Version: #{version}$/.match l }
end

action :install
unless skip_install?()
custom_artifact_download_lwrp …
package …
end
end

I’m wondering if there is a more appropriate way of checking package
availability, and wheter I’ve ended up doing this right or missing
something?

Thanks,
pepov


#3

Hi Again,

It’s actually on page 14. The gist is that you check the resources after
converging the context for updated resources, then you set the outer
resources updated_by_last_action based on that.

Cheers,
-Greg

On Wed, Sep 10, 2014 at 11:26 AM, Greg Zapp greg.zapp@gmail.com wrote:

Hi Pepov,

I’ll be honest that I’m having a hard time determining exactly where
you’re issue is based on what’s posted but… The package resource should
not be “updated_by_last_action” if the package is already installed and up
to date. This slide deck has a slide on “Nested Resources” that might be
applicable to what you are doing(and if not def worth knowing)
http://www.slideshare.net/geekbri/lwrp-presentation . It involves
running the nested resources in a new context and then checking that
context to see if resources have been updated or not. It’s a bit gross
IMHO, and there may be a better way of doing it, but it’s fairly straight
forward.

I hope that helps and apologise if it does not :slight_smile:

-Greg

On Wed, Sep 10, 2014 at 12:31 AM, Peter Wilcsinszky <
peterwilcsinszky@gmail.com> wrote:

Hi all!

I’ve run into a problem, when I was trying to implement an lwrp, that
does something like the artifact_package resource in
https://github.com/RiotGames/artifact-cookbook

The simplified base of the lwrp looks like:

use_inline_resources

action :install
custom_artifact_download_lwrp …
package …
end

I wanted to test its idempotency, to make sure no notification will be
propagated when the package is already installed. If any of the inner
resources inside the custom_artifact_download_lwrp resource was modified
(the file has been removed from the cache - we want to do periodic cleanup
there) the notification was sent out even if the package was already
installed. I wanted to force “mute” it somehow, because I want to avoid
restarting services needlessly. I’ve naively tried:

c = custom_artifact_download_lwrp
c.updated_by_last_action(false)

But after digging into the code I’ve realised I can not do this, since
this code runs before the resource collection is converged. So if a
resource gets modified the updated flag will be true and I cannot do
anything about it. Is there a way to do this?

Anyways, after reading the lwrp docs more closely, I’ve realized that I
should do a conditional before declaring any of my resources, so ended up
in doing this:

def skip_install?(name, version)
status = dpkg -s #{name}
status.lines.any? { |l| /^Status: install ok installed/.match l } &&
status.lines.any? { |l| /^Version: #{version}$/.match l }
end

action :install
unless skip_install?()
custom_artifact_download_lwrp …
package …
end
end

I’m wondering if there is a more appropriate way of checking package
availability, and wheter I’ve ended up doing this right or missing
something?

Thanks,
pepov


#4

Hi Greg!

I’m trying to make things a bit more clear: The package resource does
exactly what it needs to do, I have problems with the download resource
right before it. The download resource uses remote_file to download a file
to a temporary location to make that file (.deb) available for my package
resource. No matter if the package resource is not updated because the
package was already installed, if the download resource downloads the file
again it will fire notifications and my outer services will be restarted
needlessly.

Thanks for the pointer, but I was already aware of that stuff (the updated?
method is deprecated now). I was just saying, that you can do
updated_by_last_action(true) because this value will not be changed if the
resource does not change, but you cannot set it to false, because if the
resource changes it will definitely update it to true. And if I’m right
this method should not have an option to set it to false (at least not a
public one) because it is confusing.

My current problem is, that I have to use my handrolled method to get the
package state before declaring my resources. Should I try to get this
information by loading the current resource at first?

On Wed, Sep 10, 2014 at 1:26 AM, Greg Zapp greg.zapp@gmail.com wrote:

Hi Pepov,

I’ll be honest that I’m having a hard time determining exactly where
you’re issue is based on what’s posted but… The package resource should
not be “updated_by_last_action” if the package is already installed and up
to date. This slide deck has a slide on “Nested Resources” that might be
applicable to what you are doing(and if not def worth knowing)
http://www.slideshare.net/geekbri/lwrp-presentation . It involves
running the nested resources in a new context and then checking that
context to see if resources have been updated or not. It’s a bit gross
IMHO, and there may be a better way of doing it, but it’s fairly straight
forward.

I hope that helps and apologise if it does not :slight_smile:

-Greg

On Wed, Sep 10, 2014 at 12:31 AM, Peter Wilcsinszky <
peterwilcsinszky@gmail.com> wrote:

Hi all!

I’ve run into a problem, when I was trying to implement an lwrp, that
does something like the artifact_package resource in
https://github.com/RiotGames/artifact-cookbook

The simplified base of the lwrp looks like:

use_inline_resources

action :install
custom_artifact_download_lwrp …
package …
end

I wanted to test its idempotency, to make sure no notification will be
propagated when the package is already installed. If any of the inner
resources inside the custom_artifact_download_lwrp resource was modified
(the file has been removed from the cache - we want to do periodic cleanup
there) the notification was sent out even if the package was already
installed. I wanted to force “mute” it somehow, because I want to avoid
restarting services needlessly. I’ve naively tried:

c = custom_artifact_download_lwrp
c.updated_by_last_action(false)

But after digging into the code I’ve realised I can not do this, since
this code runs before the resource collection is converged. So if a
resource gets modified the updated flag will be true and I cannot do
anything about it. Is there a way to do this?

Anyways, after reading the lwrp docs more closely, I’ve realized that I
should do a conditional before declaring any of my resources, so ended up
in doing this:

def skip_install?(name, version)
status = dpkg -s #{name}
status.lines.any? { |l| /^Status: install ok installed/.match l } &&
status.lines.any? { |l| /^Version: #{version}$/.match l }
end

action :install
unless skip_install?()
custom_artifact_download_lwrp …
package …
end
end

I’m wondering if there is a more appropriate way of checking package
availability, and wheter I’ve ended up doing this right or missing
something?

Thanks,
pepov